Issue #2432791 by alexpott, vijaycs85, tim.plunkett, joshtaylor, Fabianx, Berdir, yched, bojanz: Skip Config::save schema validation of config data for trusted data.
parent
f8f024e3aa
commit
e0aae8c26a
|
|
@ -1215,8 +1215,9 @@ function file_directory_temp() {
|
|||
// everything to use slash which is supported on all platforms.
|
||||
$temporary_directory = str_replace('\\', '/', $temporary_directory);
|
||||
}
|
||||
// Save the path of the discovered directory.
|
||||
$config->set('path.temporary', $temporary_directory)->save();
|
||||
// Save the path of the discovered directory. Do not check config schema on
|
||||
// save.
|
||||
$config->set('path.temporary', (string) $temporary_directory)->save(TRUE);
|
||||
}
|
||||
|
||||
return $temporary_directory;
|
||||
|
|
|
|||
|
|
@ -619,9 +619,9 @@ function drupal_install_system($install_state) {
|
|||
// Ensure default language is saved.
|
||||
if (isset($install_state['parameters']['langcode'])) {
|
||||
\Drupal::configFactory()->getEditable('system.site')
|
||||
->set('langcode', $install_state['parameters']['langcode'])
|
||||
->set('default_langcode', $install_state['parameters']['langcode'])
|
||||
->save();
|
||||
->set('langcode', (string) $install_state['parameters']['langcode'])
|
||||
->set('default_langcode', (string) $install_state['parameters']['langcode'])
|
||||
->save(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -179,10 +179,12 @@ function drupal_required_modules() {
|
|||
function module_set_weight($module, $weight) {
|
||||
$extension_config = \Drupal::configFactory()->getEditable('core.extension');
|
||||
if ($extension_config->get("module.$module") !== NULL) {
|
||||
// Pre-cast the $weight to an integer so that we can save this without using
|
||||
// schema. This is a performance improvement for module installation.
|
||||
$extension_config
|
||||
->set("module.$module", $weight)
|
||||
->set("module.$module", (int) $weight)
|
||||
->set('module', module_config_sort($extension_config->get('module')))
|
||||
->save();
|
||||
->save(TRUE);
|
||||
|
||||
// Prepare the new module list, sorted by weight, including filenames.
|
||||
// @see \Drupal\Core\Extension\ModuleHandler::install()
|
||||
|
|
|
|||
|
|
@ -203,22 +203,24 @@ class Config extends StorableConfigBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save() {
|
||||
public function save($has_trusted_data = FALSE) {
|
||||
// Validate the configuration object name before saving.
|
||||
static::validateName($this->name);
|
||||
|
||||
// If there is a schema for this configuration object, cast all values to
|
||||
// conform to the schema.
|
||||
if ($this->typedConfigManager->hasConfigSchema($this->name)) {
|
||||
// Ensure that the schema wrapper has the latest data.
|
||||
$this->schemaWrapper = NULL;
|
||||
foreach ($this->data as $key => $value) {
|
||||
$this->data[$key] = $this->castValue($key, $value);
|
||||
if (!$has_trusted_data) {
|
||||
if ($this->typedConfigManager->hasConfigSchema($this->name)) {
|
||||
// Ensure that the schema wrapper has the latest data.
|
||||
$this->schemaWrapper = NULL;
|
||||
foreach ($this->data as $key => $value) {
|
||||
$this->data[$key] = $this->castValue($key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach ($this->data as $key => $value) {
|
||||
$this->validateValue($key, $value);
|
||||
else {
|
||||
foreach ($this->data as $key => $value) {
|
||||
$this->validateValue($key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -229,6 +231,9 @@ class Config extends StorableConfigBase {
|
|||
$this->isNew = FALSE;
|
||||
$this->eventDispatcher->dispatch(ConfigEvents::SAVE, new ConfigCrudEvent($this));
|
||||
$this->originalData = $this->data;
|
||||
// Potentially configuration schema could have changed the underlying data's
|
||||
// types.
|
||||
$this->resetOverriddenData();
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
@ -302,4 +307,5 @@ class Config extends StorableConfigBase {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -304,11 +304,11 @@ class ConfigInstaller implements ConfigInstallerInterface {
|
|||
$entity = $entity_storage->createFromStorageRecord($new_config->get());
|
||||
}
|
||||
if ($entity->isInstallable()) {
|
||||
$entity->save();
|
||||
$entity->trustData()->save();
|
||||
}
|
||||
}
|
||||
else {
|
||||
$new_config->save();
|
||||
$new_config->save(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,6 +105,13 @@ abstract class ConfigEntityBase extends Entity implements ConfigEntityInterface
|
|||
*/
|
||||
protected $third_party_settings = array();
|
||||
|
||||
/**
|
||||
* Trust supplied data and not use configuration schema on save.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $trustedData = FALSE;
|
||||
|
||||
/**
|
||||
* Overrides Entity::__construct().
|
||||
*/
|
||||
|
|
@ -265,22 +272,31 @@ abstract class ConfigEntityBase extends Entity implements ConfigEntityInterface
|
|||
*/
|
||||
public function toArray() {
|
||||
$properties = array();
|
||||
$config_name = $this->getEntityType()->getConfigPrefix() . '.' . $this->id();
|
||||
$definition = $this->getTypedConfig()->getDefinition($config_name);
|
||||
if (!isset($definition['mapping'])) {
|
||||
throw new SchemaIncompleteException(SafeMarkup::format('Incomplete or missing schema for @config_name', array('@config_name' => $config_name)));
|
||||
/** @var \Drupal\Core\Config\Entity\ConfigEntityTypeInterface $entity_type */
|
||||
$entity_type = $this->getEntityType();
|
||||
|
||||
$properties_to_export = $entity_type->getPropertiesToExport();
|
||||
if (empty($properties_to_export)) {
|
||||
$config_name = $entity_type->getConfigPrefix() . '.' . $this->id();
|
||||
$definition = $this->getTypedConfig()->getDefinition($config_name);
|
||||
if (!isset($definition['mapping'])) {
|
||||
throw new SchemaIncompleteException(SafeMarkup::format('Incomplete or missing schema for @config_name', array('@config_name' => $config_name)));
|
||||
}
|
||||
$properties_to_export = array_combine(array_keys($definition['mapping']), array_keys($definition['mapping']));
|
||||
}
|
||||
$id_key = $this->getEntityType()->getKey('id');
|
||||
foreach (array_keys($definition['mapping']) as $name) {
|
||||
|
||||
$id_key = $entity_type->getKey('id');
|
||||
foreach ($properties_to_export as $property_name => $export_name) {
|
||||
// Special handling for IDs so that computed compound IDs work.
|
||||
// @see \Drupal\Core\Entity\EntityDisplayBase::id()
|
||||
if ($name == $id_key) {
|
||||
$properties[$name] = $this->id();
|
||||
if ($property_name == $id_key) {
|
||||
$properties[$export_name] = $this->id();
|
||||
}
|
||||
else {
|
||||
$properties[$name] = $this->get($name);
|
||||
$properties[$export_name] = $this->get($property_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($this->third_party_settings)) {
|
||||
unset($properties['third_party_settings']);
|
||||
}
|
||||
|
|
@ -328,7 +344,7 @@ abstract class ConfigEntityBase extends Entity implements ConfigEntityInterface
|
|||
throw new ConfigDuplicateUUIDException(SafeMarkup::format('Attempt to save a configuration entity %id with UUID %uuid when this entity already exists with UUID %original_uuid', array('%id' => $this->id(), '%uuid' => $this->uuid(), '%original_uuid' => $original->uuid())));
|
||||
}
|
||||
}
|
||||
if (!$this->isSyncing()) {
|
||||
if (!$this->isSyncing() && !$this->trustedData) {
|
||||
// Ensure the correct dependencies are present. If the configuration is
|
||||
// being written during a configuration synchronization then there is no
|
||||
// need to recalculate the dependencies.
|
||||
|
|
@ -572,4 +588,28 @@ abstract class ConfigEntityBase extends Entity implements ConfigEntityInterface
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function trustData() {
|
||||
$this->trustedData = TRUE;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasTrustedData() {
|
||||
return $this->trustedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save() {
|
||||
$return = parent::save();
|
||||
$this->trustedData = FALSE;
|
||||
return $return;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -203,4 +203,27 @@ interface ConfigEntityInterface extends EntityInterface, ThirdPartySettingsInter
|
|||
*/
|
||||
public function isInstallable();
|
||||
|
||||
/**
|
||||
* Sets that the data should be trusted.
|
||||
*
|
||||
* If the data is trusted then dependencies will not be calculated on save and
|
||||
* schema will not be used to cast the values. Generally this is only used
|
||||
* during module and theme installation. Once the config entity has been saved
|
||||
* the data will no longer be marked as trusted. This is an optimization for
|
||||
* creation of configuration during installation.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @see \Drupal\Core\Config\ConfigInstaller::createConfiguration()
|
||||
*/
|
||||
public function trustData();
|
||||
|
||||
/**
|
||||
* Gets whether on not the data is trusted.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the configuration data is trusted, FALSE if not.
|
||||
*/
|
||||
public function hasTrustedData();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -256,7 +256,19 @@ class ConfigEntityStorage extends EntityStorageBase implements ConfigEntityStora
|
|||
|
||||
// Retrieve the desired properties and set them in config.
|
||||
$config->setData($this->mapToStorageRecord($entity));
|
||||
$config->save();
|
||||
$config->save($entity->hasTrustedData());
|
||||
|
||||
// Update the entity with the values stored in configuration. It is possible
|
||||
// that configuration schema has casted some of the values.
|
||||
if (!$entity->hasTrustedData()) {
|
||||
$data = $this->mapFromStorageRecords(array($config->get()));
|
||||
$updated_entity = current($data);
|
||||
|
||||
foreach (array_keys($config->get()) as $property) {
|
||||
$value = $updated_entity->get($property);
|
||||
$entity->set($property, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return $is_new ? SAVED_NEW : SAVED_UPDATED;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,22 @@ class ConfigEntityType extends EntityType implements ConfigEntityTypeInterface {
|
|||
*/
|
||||
protected $static_cache = FALSE;
|
||||
|
||||
/**
|
||||
* The list of configuration entity properties to export from the annotation.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $config_export = [];
|
||||
|
||||
/**
|
||||
* The result of merging config_export annotation with the defaults.
|
||||
*
|
||||
* This is stored on the class so that it does not have to be recalculated.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $mergedConfigExport = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
|
|
@ -146,4 +162,32 @@ class ConfigEntityType extends EntityType implements ConfigEntityTypeInterface {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPropertiesToExport() {
|
||||
if (!empty($this->config_export)) {
|
||||
if (empty($this->mergedConfigExport)) {
|
||||
// Always add default properties to be exported.
|
||||
$this->mergedConfigExport = [
|
||||
'uuid' => 'uuid',
|
||||
'langcode' => 'langcode',
|
||||
'status' => 'status',
|
||||
'dependencies' => 'dependencies',
|
||||
'third_party_settings' => 'third_party_settings',
|
||||
];
|
||||
foreach ($this->config_export as $property => $name) {
|
||||
if (is_numeric($property)) {
|
||||
$this->mergedConfigExport[$name] = $name;
|
||||
}
|
||||
else {
|
||||
$this->mergedConfigExport[$property] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->mergedConfigExport;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,4 +61,13 @@ interface ConfigEntityTypeInterface extends EntityTypeInterface {
|
|||
*/
|
||||
public function getConfigPrefix();
|
||||
|
||||
/**
|
||||
* Gets the config entity properties to export if declared on the annotation.
|
||||
*
|
||||
* @return array|NULL
|
||||
* The properties to export or NULL if they can not be determine from the
|
||||
* config entity type annotation.
|
||||
*/
|
||||
public function getPropertiesToExport();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class ImmutableConfig extends Config {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save() {
|
||||
public function save($has_trusted_data = FALSE) {
|
||||
throw new ImmutableConfigException(SafeMarkup::format('Can not save immutable configuration !name. Use \Drupal\Core\Config\ConfigFactoryInterface::getEditable() to retrieve a mutable configuration object', ['!name' => $this->getName()]));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,11 +66,18 @@ abstract class StorableConfigBase extends ConfigBase {
|
|||
/**
|
||||
* Saves the configuration object.
|
||||
*
|
||||
* @param bool $has_trusted_data
|
||||
* Set to TRUE is the configuration data has already been checked to ensure
|
||||
* it conforms to schema. Generally this is only used during module and
|
||||
* theme installation.
|
||||
*
|
||||
* Must invalidate the cache tags associated with the configuration object.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @see \Drupal\Core\Config\ConfigInstaller::createConfiguration()
|
||||
*/
|
||||
abstract public function save();
|
||||
abstract public function save($has_trusted_data = FALSE);
|
||||
|
||||
/**
|
||||
* Deletes the configuration object.
|
||||
|
|
|
|||
|
|
@ -25,7 +25,13 @@ use Drupal\Core\Datetime\DateFormatInterface;
|
|||
* "label" = "label"
|
||||
* },
|
||||
* admin_permission = "administer site configuration",
|
||||
* list_cache_tags = { "rendered" }
|
||||
* list_cache_tags = { "rendered" },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "label",
|
||||
* "locked",
|
||||
* "pattern",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
class DateFormat extends ConfigEntityBase implements DateFormatInterface {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,14 @@ use Drupal\Core\Form\FormStateInterface;
|
|||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
* "status" = "status"
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "targetEntityType",
|
||||
* "bundle",
|
||||
* "mode",
|
||||
* "content",
|
||||
* "hidden",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -33,6 +33,12 @@ use Drupal\Core\Entity\EntityFormModeInterface;
|
|||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
* "label" = "label"
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "label",
|
||||
* "targetEntityType",
|
||||
* "cache",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -24,6 +24,14 @@ use Drupal\Core\Entity\EntityDisplayBase;
|
|||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
* "status" = "status"
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "targetEntityType",
|
||||
* "bundle",
|
||||
* "mode",
|
||||
* "content",
|
||||
* "hidden",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -35,6 +35,12 @@ use Drupal\Core\Entity\EntityViewModeInterface;
|
|||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
* "label" = "label"
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "label",
|
||||
* "targetEntityType",
|
||||
* "cache",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -155,10 +155,12 @@ class ModuleInstaller implements ModuleInstallerInterface {
|
|||
// exceptions if the configuration is not valid.
|
||||
$config_installer->checkConfigurationToInstall('module', $module);
|
||||
|
||||
// Save this data without checking schema. This is a performance
|
||||
// improvement for module installation.
|
||||
$extension_config
|
||||
->set("module.$module", 0)
|
||||
->set('module', module_config_sort($extension_config->get('module')))
|
||||
->save();
|
||||
->save(TRUE);
|
||||
|
||||
// Prepare the new module list, sorted by weight, including filenames.
|
||||
// This list is used for both the ModuleHandler and DrupalKernel. It
|
||||
|
|
@ -385,8 +387,9 @@ class ModuleInstaller implements ModuleInstallerInterface {
|
|||
// Remove the schema.
|
||||
drupal_uninstall_schema($module);
|
||||
|
||||
// Remove the module's entry from the config.
|
||||
\Drupal::configFactory()->getEditable('core.extension')->clear("module.$module")->save();
|
||||
// Remove the module's entry from the config. Don't check schema when
|
||||
// uninstalling a module since we are only clearing a key.
|
||||
\Drupal::configFactory()->getEditable('core.extension')->clear("module.$module")->save(TRUE);
|
||||
|
||||
// Update the module handler to remove the module.
|
||||
// The current ModuleHandler instance is obsolete with the kernel rebuild
|
||||
|
|
|
|||
|
|
@ -260,10 +260,11 @@ class ThemeHandler implements ThemeHandlerInterface {
|
|||
// configuration then stop installing.
|
||||
$this->configInstaller->checkConfigurationToInstall('theme', $key);
|
||||
|
||||
// The value is not used; the weight is ignored for themes currently.
|
||||
// The value is not used; the weight is ignored for themes currently. Do
|
||||
// not check schema when saving the configuration.
|
||||
$extension_config
|
||||
->set("theme.$key", 0)
|
||||
->save();
|
||||
->save(TRUE);
|
||||
|
||||
// Add the theme to the current list.
|
||||
// @todo Remove all code that relies on $status property.
|
||||
|
|
@ -358,7 +359,9 @@ class ThemeHandler implements ThemeHandlerInterface {
|
|||
$this->configManager->uninstall('theme', $key);
|
||||
|
||||
}
|
||||
$extension_config->save();
|
||||
// Don't check schema when uninstalling a theme since we are only clearing
|
||||
// keys.
|
||||
$extension_config->save(TRUE);
|
||||
$this->state->set('system.theme.data', $current_theme_data);
|
||||
|
||||
$this->resetSystem();
|
||||
|
|
|
|||
|
|
@ -28,6 +28,20 @@ use Drupal\Core\Field\FieldException;
|
|||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
* "label" = "label"
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "field_name",
|
||||
* "entity_type",
|
||||
* "bundle",
|
||||
* "label",
|
||||
* "description",
|
||||
* "required",
|
||||
* "translatable",
|
||||
* "default_value",
|
||||
* "default_value_callback",
|
||||
* "settings",
|
||||
* "field_type",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -260,14 +260,14 @@ class SiteConfigureForm extends ConfigFormBase {
|
|||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
$this->config('system.site')
|
||||
->set('name', $form_state->getValue('site_name'))
|
||||
->set('mail', $form_state->getValue('site_mail'))
|
||||
->save();
|
||||
->set('name', (string) $form_state->getValue('site_name'))
|
||||
->set('mail', (string) $form_state->getValue('site_mail'))
|
||||
->save(TRUE);
|
||||
|
||||
$this->config('system.date')
|
||||
->set('timezone.default', $form_state->getValue('date_default_timezone'))
|
||||
->set('country.default', $form_state->getValue('site_default_country'))
|
||||
->save();
|
||||
->set('timezone.default', (string) $form_state->getValue('date_default_timezone'))
|
||||
->set('country.default', (string) $form_state->getValue('site_default_country'))
|
||||
->save(TRUE);
|
||||
|
||||
$account_values = $form_state->getValue('account');
|
||||
|
||||
|
|
@ -281,7 +281,7 @@ class SiteConfigureForm extends ConfigFormBase {
|
|||
if ($update_status_module[2]) {
|
||||
// Reset the configuration factory so it is updated with the new module.
|
||||
$this->resetConfigFactory();
|
||||
$this->config('update.settings')->set('notification.emails', array($account_values['mail']))->save();
|
||||
$this->config('update.settings')->set('notification.emails', array($account_values['mail']))->save(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -130,20 +130,29 @@ class StaticMenuLinkOverrides implements StaticMenuLinkOverridesInterface {
|
|||
public function saveOverride($id, array $definition) {
|
||||
// Only allow to override a specific subset of the keys.
|
||||
$expected = array(
|
||||
'menu_name' => 1,
|
||||
'parent' => 1,
|
||||
'weight' => 1,
|
||||
'expanded' => 1,
|
||||
'enabled' => 1,
|
||||
'menu_name' => '',
|
||||
'parent' => '',
|
||||
'weight' => 0,
|
||||
'expanded' => FALSE,
|
||||
'enabled' => FALSE,
|
||||
);
|
||||
// Filter the overrides to only those that are expected.
|
||||
$definition = array_intersect_key($definition, $expected);
|
||||
// Ensure all values are set.
|
||||
$definition = $definition + $expected;
|
||||
if ($definition) {
|
||||
// Cast keys to avoid config schema during save.
|
||||
$definition['menu_name'] = (string) $definition['menu_name'];
|
||||
$definition['parent'] = (string) $definition['parent'];
|
||||
$definition['weight'] = (int) $definition['weight'];
|
||||
$definition['expanded'] = (bool) $definition['expanded'];
|
||||
$definition['enabled'] = (bool) $definition['enabled'];
|
||||
|
||||
$id = static::encodeId($id);
|
||||
$all_overrides = $this->getConfig()->get('definitions');
|
||||
// Combine with any existing data.
|
||||
$all_overrides[$id] = $definition + $this->loadOverride($id);
|
||||
$this->getConfig()->set('definitions', $all_overrides)->save();
|
||||
$this->getConfig()->set('definitions', $all_overrides)->save(TRUE);
|
||||
}
|
||||
return array_keys($definition);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,16 @@ use Drupal\Core\Entity\EntityStorageInterface;
|
|||
* links = {
|
||||
* "delete-form" = "/admin/structure/block/manage/{block}/delete",
|
||||
* "edit-form" = "/admin/structure/block/manage/{block}"
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "theme",
|
||||
* "region",
|
||||
* "weight",
|
||||
* "provider",
|
||||
* "plugin",
|
||||
* "settings",
|
||||
* "visibility",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -38,6 +38,12 @@ use Drupal\block_content\BlockContentTypeInterface;
|
|||
* "delete-form" = "/admin/structure/block/block-content/manage/{block_content_type}/delete",
|
||||
* "edit-form" = "/admin/structure/block/block-content/manage/{block_content_type}",
|
||||
* "collection" = "/admin/structure/block/block-content/types",
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "label",
|
||||
* "revision",
|
||||
* "description",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- book
|
||||
enforced:
|
||||
module:
|
||||
- book
|
||||
|
|
|
|||
|
|
@ -38,6 +38,12 @@ use Drupal\comment\CommentTypeInterface;
|
|||
* "edit-form" = "/admin/structure/comment/manage/{comment_type}",
|
||||
* "add-form" = "/admin/structure/comment/types/add",
|
||||
* "collection" = "/admin/structure/comment/types",
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "label",
|
||||
* "target_entity_type_id",
|
||||
* "description",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -275,6 +275,14 @@ class ConfigCRUDTest extends KernelTestBase {
|
|||
$this->assertIdentical($config->get(), $data);
|
||||
$this->assertIdentical($storage->read($name), $data);
|
||||
|
||||
// Test that schema type enforcement can be overridden by trusting the data.
|
||||
$this->assertIdentical(99, $config->get('int'));
|
||||
$config->set('int', '99')->save(TRUE);
|
||||
$this->assertIdentical('99', $config->get('int'));
|
||||
// Test that re-saving without testing the data enforces the schema type.
|
||||
$config->save();
|
||||
$this->assertIdentical($data, $config->get());
|
||||
|
||||
// Test that setting an unsupported type for a config object with a schema
|
||||
// fails.
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,15 @@ use Drupal\simpletest\KernelTestBase;
|
|||
*/
|
||||
class ConfigEntityUnitTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Exempt from strict schema checking.
|
||||
*
|
||||
* @see \Drupal\Core\Config\Testing\ConfigSchemaChecker
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $strictConfigSchema = FALSE;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
|
|
@ -89,6 +98,20 @@ class ConfigEntityUnitTest extends KernelTestBase {
|
|||
foreach ($entities as $entity) {
|
||||
$this->assertIdentical($entity->get('style'), $style, 'The loaded entity has the correct style value specified.');
|
||||
}
|
||||
|
||||
// Test that schema type enforcement can be overridden by trusting the data.
|
||||
$entity = $this->storage->create(array(
|
||||
'id' => $this->randomMachineName(),
|
||||
'label' => $this->randomString(),
|
||||
'style' => 999
|
||||
));
|
||||
$entity->save();
|
||||
$this->assertIdentical('999', $entity->style);
|
||||
$entity->style = 999;
|
||||
$entity->trustData()->save();
|
||||
$this->assertIdentical(999, $entity->style);
|
||||
$entity->save();
|
||||
$this->assertIdentical('999', $entity->style);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class ConfigInstallTest extends KernelTestBase {
|
|||
|
||||
// Ensure that schema provided by modules that are not installed is not
|
||||
// available.
|
||||
$this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.schema_in_install'), 'Configuration schema for config_schema_test.schema_in_install does not exist.');
|
||||
$this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema does not exist.');
|
||||
|
||||
// Install the test module.
|
||||
$this->installModules(array('config_test'));
|
||||
|
|
@ -80,16 +80,12 @@ class ConfigInstallTest extends KernelTestBase {
|
|||
$this->installConfig(array('config_schema_test'));
|
||||
|
||||
// After module installation the new schema should exist.
|
||||
$this->assertTrue(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.schema_in_install'), 'Configuration schema for config_schema_test.schema_in_install exists.');
|
||||
|
||||
// Ensure that data type casting is applied during config installation.
|
||||
$config = $this->config('config_schema_test.schema_in_install');
|
||||
$this->assertIdentical($config->get('integer'), 1);
|
||||
$this->assertTrue(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema exists.');
|
||||
|
||||
// Test that uninstalling configuration removes configuration schema.
|
||||
$this->config('core.extension')->set('module', array())->save();
|
||||
\Drupal::service('config.manager')->uninstall('module', 'config_test');
|
||||
$this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.schema_in_install'), 'Configuration schema for config_schema_test.schema_in_install does not exist.');
|
||||
$this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema does not exist.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -209,6 +209,7 @@ class ConfigSchemaTest extends KernelTestBase {
|
|||
|
||||
$this->assertEqual($definition, $expected, 'Retrieved the right metadata for the first effect of image.style.medium');
|
||||
|
||||
$a = \Drupal::config('config_test.dynamic.third_party');
|
||||
$test = \Drupal::service('config.typed')->get('config_test.dynamic.third_party')->get('third_party_settings.config_schema_test');
|
||||
$definition = $test->getDataDefinition()->toArray();
|
||||
$expected = array();
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
integer: '1'
|
||||
|
|
@ -125,14 +125,6 @@ config_schema_test.schema_data_types:
|
|||
sequence:
|
||||
- type: boolean
|
||||
|
||||
config_schema_test.schema_in_install:
|
||||
label: 'Schema test data with parenting'
|
||||
type: config_object
|
||||
mapping:
|
||||
integer:
|
||||
type: integer
|
||||
label: 'Integer'
|
||||
|
||||
config_schema_test_integer:
|
||||
type: integer
|
||||
label: 'Config test integer'
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ array: []
|
|||
boolean: true
|
||||
exp: 1.2e+34
|
||||
float: 3.14159
|
||||
float_as_integer: 1
|
||||
float_as_integer: !!float 1
|
||||
hex: 0xC
|
||||
int: 99
|
||||
octal: 0775
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@ id: override
|
|||
label: Default
|
||||
weight: 0
|
||||
protected_property: Default
|
||||
status: 1
|
||||
status: true
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ id: override_unmet
|
|||
label: Default
|
||||
weight: 0
|
||||
protected_property: Default
|
||||
status: 1
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- tour
|
||||
|
|
|
|||
|
|
@ -36,6 +36,13 @@ use Drupal\contact\ContactFormInterface;
|
|||
* "delete-form" = "/admin/structure/contact/manage/{contact_form}/delete",
|
||||
* "edit-form" = "/admin/structure/contact/manage/{contact_form}",
|
||||
* "collection" = "/admin/structure/contact",
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "label",
|
||||
* "recipients",
|
||||
* "reply",
|
||||
* "weight",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -18,6 +18,12 @@ use Drupal\editor\EditorInterface;
|
|||
* label = @Translation("Text Editor"),
|
||||
* entity_keys = {
|
||||
* "id" = "format"
|
||||
* },
|
||||
* config_export = {
|
||||
* "format",
|
||||
* "editor",
|
||||
* "settings",
|
||||
* "image_upload",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -28,6 +28,20 @@ use Drupal\field\FieldConfigInterface;
|
|||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
* "label" = "label"
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "field_name",
|
||||
* "entity_type",
|
||||
* "bundle",
|
||||
* "label",
|
||||
* "description",
|
||||
* "required",
|
||||
* "translatable",
|
||||
* "default_value",
|
||||
* "default_value_callback",
|
||||
* "settings",
|
||||
* "field_type",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -30,6 +30,19 @@ use Drupal\field\FieldStorageConfigInterface;
|
|||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
* "label" = "id"
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "field_name",
|
||||
* "entity_type",
|
||||
* "type",
|
||||
* "settings",
|
||||
* "module",
|
||||
* "locked",
|
||||
* "cardinality",
|
||||
* "translatable",
|
||||
* "indexes",
|
||||
* "persist_with_no_fields",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class FieldConfigEntityUnitTest extends UnitTestCase {
|
|||
/**
|
||||
* The entity type used for testing.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
* @var \Drupal\Core\Config\Entity\ConfigEntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $entityType;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,13 +18,6 @@ use Drupal\Tests\UnitTestCase;
|
|||
*/
|
||||
class FieldStorageConfigEntityUnitTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* The entity type used for testing.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $entityType;
|
||||
|
||||
/**
|
||||
* The entity manager used for testing.
|
||||
*
|
||||
|
|
@ -64,7 +57,7 @@ class FieldStorageConfigEntityUnitTest extends UnitTestCase {
|
|||
*/
|
||||
public function testCalculateDependencies() {
|
||||
// Create a mock entity type for FieldStorageConfig.
|
||||
$fieldStorageConfigentityType = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface');
|
||||
$fieldStorageConfigentityType = $this->getMock('\Drupal\Core\Config\Entity\ConfigEntityTypeInterface');
|
||||
$fieldStorageConfigentityType->expects($this->any())
|
||||
->method('getProvider')
|
||||
->will($this->returnValue('field'));
|
||||
|
|
|
|||
|
|
@ -116,10 +116,10 @@ class EntityDisplayTest extends KernelTestBase {
|
|||
$display->setComponent('component_3');
|
||||
$display->setComponent('component_1');
|
||||
$display->setComponent('component_2');
|
||||
$display->removeComponent('name');
|
||||
$display->save();
|
||||
$components = array_keys($display->getComponents());
|
||||
$expected = array ( 0 => 'component_1', 1 => 'component_2', 2 => 'component_3',);
|
||||
// The name field is not configurable so will be added automatically.
|
||||
$expected = array ( 0 => 'component_1', 1 => 'component_2', 2 => 'component_3', 'name');
|
||||
$this->assertIdentical($components, $expected);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ display:
|
|||
delta_first_last: false
|
||||
multi_type: separator
|
||||
separator: ', '
|
||||
field_api_classes: 0
|
||||
field_api_classes: false
|
||||
plugin_id: field
|
||||
entity_type: file
|
||||
entity_field: filename
|
||||
|
|
|
|||
|
|
@ -41,6 +41,13 @@ use Drupal\filter\Plugin\FilterInterface;
|
|||
* links = {
|
||||
* "edit-form" = "/admin/config/content/formats/manage/{filter_format}",
|
||||
* "disable" = "/admin/config/content/formats/manage/{filter_format}/disable"
|
||||
* },
|
||||
* config_export = {
|
||||
* "name",
|
||||
* "format",
|
||||
* "weight",
|
||||
* "roles",
|
||||
* "filters",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- forum
|
||||
enforced:
|
||||
module:
|
||||
- forum
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- forum
|
||||
enforced:
|
||||
module:
|
||||
- forum
|
||||
|
|
|
|||
|
|
@ -48,6 +48,11 @@ use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
|||
* "edit-form" = "/admin/config/media/image-styles/manage/{image_style}",
|
||||
* "delete-form" = "/admin/config/media/image-styles/manage/{image_style}/delete",
|
||||
* "collection" = "/admin/config/media/image-styles",
|
||||
* },
|
||||
* config_export = {
|
||||
* "name",
|
||||
* "label",
|
||||
* "effects",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -50,13 +50,16 @@ class LanguageConfigOverride extends StorableConfigBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save() {
|
||||
// @todo Use configuration schema to validate.
|
||||
// https://drupal.org/node/2270399
|
||||
// Perform basic data validation.
|
||||
foreach ($this->data as $key => $value) {
|
||||
$this->validateValue($key, $value);
|
||||
public function save($has_trusted_data = FALSE) {
|
||||
if (!$has_trusted_data) {
|
||||
// @todo Use configuration schema to validate.
|
||||
// https://drupal.org/node/2270399
|
||||
// Perform basic data validation.
|
||||
foreach ($this->data as $key => $value) {
|
||||
$this->validateValue($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
$this->storage->write($this->name, $this->data);
|
||||
// Invalidate the cache tags not only when updating, but also when creating,
|
||||
// because a language config override object uses the same cache tag as the
|
||||
|
|
|
|||
|
|
@ -4,3 +4,6 @@ status: true
|
|||
langcode: en
|
||||
type: node
|
||||
plugin: node_promote_action
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
|
|
|
|||
|
|
@ -4,3 +4,6 @@ status: true
|
|||
langcode: en
|
||||
type: node
|
||||
plugin: node_publish_action
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
|
|
|
|||
|
|
@ -37,6 +37,15 @@ use Drupal\node\NodeTypeInterface;
|
|||
* "edit-form" = "/admin/structure/types/manage/{node_type}",
|
||||
* "delete-form" = "/admin/structure/types/manage/{node_type}/delete",
|
||||
* "collection" = "/admin/structure/types",
|
||||
* },
|
||||
* config_export = {
|
||||
* "name",
|
||||
* "type",
|
||||
* "description",
|
||||
* "help",
|
||||
* "new_revision",
|
||||
* "preview_mode",
|
||||
* "display_submitted",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -110,4 +110,11 @@ class ListFloatItem extends ListItemBase {
|
|||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static function castAllowedValue($value) {
|
||||
return (float) $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,4 +73,11 @@ class ListIntegerItem extends ListItemBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static function castAllowedValue($value) {
|
||||
return (int) $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -314,11 +314,24 @@ abstract class ListItemBase extends FieldItemBase implements OptionsProviderInte
|
|||
$label = static::structureAllowedValues($label);
|
||||
}
|
||||
$structured_values[] = array(
|
||||
'value' => $value,
|
||||
'value' => static::castAllowedValue($value),
|
||||
'label' => $label,
|
||||
);
|
||||
}
|
||||
return $structured_values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a value to the correct type.
|
||||
*
|
||||
* @param mixed $value
|
||||
* The value to cast.
|
||||
*
|
||||
* @return mixed
|
||||
* The casted value.
|
||||
*/
|
||||
protected static function castAllowedValue($value) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,4 +75,11 @@ class ListStringItem extends ListItemBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static function castAllowedValue($value) {
|
||||
return (string) $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ type: list_float
|
|||
settings:
|
||||
allowed_values:
|
||||
-
|
||||
value: 0
|
||||
value: !!float 0
|
||||
label: Zero
|
||||
-
|
||||
value: 0.5
|
||||
|
|
|
|||
|
|
@ -20,6 +20,13 @@ use Drupal\rdf\RdfMappingInterface;
|
|||
* config_prefix = "mapping",
|
||||
* entity_keys = {
|
||||
* "id" = "id"
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "targetEntityType",
|
||||
* "bundle",
|
||||
* "types",
|
||||
* "fieldMappings",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -47,6 +47,14 @@ use Drupal\search\SearchPageInterface;
|
|||
* "label" = "label",
|
||||
* "weight" = "weight",
|
||||
* "status" = "status"
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "label",
|
||||
* "path",
|
||||
* "weight",
|
||||
* "plugin",
|
||||
* "configuration",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ function shortcut_install() {
|
|||
// Theme settings are not configuration entities and cannot depend on modules
|
||||
// so to set a module-specific setting, we need to set it with logic.
|
||||
if (\Drupal::service('theme_handler')->themeExists('seven')) {
|
||||
\Drupal::configFactory()->getEditable('seven.settings')->set('third_party_settings.shortcut.module_link', TRUE)->save();
|
||||
\Drupal::configFactory()->getEditable('seven.settings')->set('third_party_settings.shortcut.module_link', TRUE)->save(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -64,6 +64,6 @@ function shortcut_uninstall() {
|
|||
// Theme settings are not configuration entities and cannot depend on modules
|
||||
// so to unset a module-specific setting, we need to unset it with logic.
|
||||
if (\Drupal::service('theme_handler')->themeExists('seven')) {
|
||||
\Drupal::configFactory()->getEditable('seven.settings')->clear('third_party_settings.shortcut.module_link')->save();
|
||||
\Drupal::configFactory()->getEditable('seven.settings')->clear('third_party_settings.shortcut.module_link')->save(TRUE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -415,7 +415,7 @@ function shortcut_themes_installed($theme_list) {
|
|||
// Theme settings are not configuration entities and cannot depend on modules
|
||||
// so to set a module-specific setting, we need to set it with logic.
|
||||
if (\Drupal::moduleHandler()->moduleExists('shortcut')) {
|
||||
\Drupal::configFactory()->getEditable('seven.settings')->set('third_party_settings.shortcut.module_link', TRUE)->save();
|
||||
\Drupal::configFactory()->getEditable('seven.settings')->set('third_party_settings.shortcut.module_link', TRUE)->save(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,10 @@ use Drupal\shortcut\ShortcutSetInterface;
|
|||
* "delete-form" = "/admin/config/user-interface/shortcut/manage/{shortcut_set}/delete",
|
||||
* "edit-form" = "/admin/config/user-interface/shortcut/manage/{shortcut_set}",
|
||||
* "collection" = "/admin/config/user-interface/shortcut",
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "label",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -24,6 +24,13 @@ use Drupal\Component\Plugin\ConfigurablePluginInterface;
|
|||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
* "label" = "label"
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "label",
|
||||
* "type",
|
||||
* "plugin",
|
||||
* "configuration",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -24,6 +24,12 @@ use Drupal\system\MenuInterface;
|
|||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
* "label" = "label"
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "label",
|
||||
* "description",
|
||||
* "locked",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -665,7 +665,7 @@ function system_install() {
|
|||
if (!$site->get('name')) {
|
||||
$site->set('name', 'Drupal');
|
||||
}
|
||||
$site->save();
|
||||
$site->save(TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ langcode: en
|
|||
locked: false
|
||||
pattern: 'U'
|
||||
dependencies:
|
||||
theme:
|
||||
- test_basetheme
|
||||
enforced:
|
||||
theme:
|
||||
- test_basetheme
|
||||
|
|
|
|||
|
|
@ -41,6 +41,13 @@ use Drupal\taxonomy\VocabularyInterface;
|
|||
* "overview-form" = "/admin/structure/taxonomy/manage/{taxonomy_vocabulary}/overview",
|
||||
* "edit-form" = "/admin/structure/taxonomy/manage/{taxonomy_vocabulary}",
|
||||
* "collection" = "/admin/structure/taxonomy",
|
||||
* },
|
||||
* config_export = {
|
||||
* "name",
|
||||
* "vid",
|
||||
* "description",
|
||||
* "hierarchy",
|
||||
* "weight",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -24,6 +24,13 @@ use Drupal\tour\TourInterface;
|
|||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
* "label" = "label"
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "label",
|
||||
* "module",
|
||||
* "routes",
|
||||
* "tips",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -567,7 +567,7 @@ display:
|
|||
delta_first_last: false
|
||||
multi_type: separator
|
||||
separator: ', '
|
||||
field_api_classes: 0
|
||||
field_api_classes: false
|
||||
plugin_id: field
|
||||
entity_type: user
|
||||
entity_field: mail
|
||||
|
|
|
|||
|
|
@ -40,6 +40,13 @@ use Drupal\user\RoleInterface;
|
|||
* "edit-form" = "/admin/people/roles/manage/{user_role}",
|
||||
* "edit-permissions-form" = "/admin/people/permissions/{user_role}",
|
||||
* "collection" = "/admin/people/roles",
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "label",
|
||||
* "weight",
|
||||
* "is_admin",
|
||||
* "permissions",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -988,7 +988,7 @@ function user_user_role_insert(RoleInterface $role) {
|
|||
),
|
||||
'plugin' => 'user_add_role_action',
|
||||
));
|
||||
$action->save();
|
||||
$action->trustData()->save();
|
||||
}
|
||||
$remove_id = 'user_remove_role_action.' . $role->id();
|
||||
if (!entity_load('action', $remove_id)) {
|
||||
|
|
@ -1001,7 +1001,7 @@ function user_user_role_insert(RoleInterface $role) {
|
|||
),
|
||||
'plugin' => 'user_remove_role_action',
|
||||
));
|
||||
$action->save();
|
||||
$action->trustData()->save();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1149,7 +1149,7 @@ function user_role_grant_permissions($rid, array $permissions = array()) {
|
|||
foreach ($permissions as $permission) {
|
||||
$role->grantPermission($permission);
|
||||
}
|
||||
$role->save();
|
||||
$role->trustData()->save();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1170,7 +1170,7 @@ function user_role_revoke_permissions($rid, array $permissions = array()) {
|
|||
foreach ($permissions as $permission) {
|
||||
$role->revokePermission($permission);
|
||||
}
|
||||
$role->save();
|
||||
$role->trustData()->save();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -29,6 +29,17 @@ use Drupal\views\ViewEntityInterface;
|
|||
* "id" = "id",
|
||||
* "label" = "label",
|
||||
* "status" = "status"
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "label",
|
||||
* "module",
|
||||
* "description",
|
||||
* "tag",
|
||||
* "base_table",
|
||||
* "base_field",
|
||||
* "core",
|
||||
* "display",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2293,7 +2293,7 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
|
|||
$cache_plugin->alterCacheMetadata($is_cacheable, $cache_contexts);
|
||||
}
|
||||
|
||||
return [$is_cacheable, $cache_contexts];
|
||||
return [(bool) $is_cacheable, $cache_contexts];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1285,4 +1285,18 @@ class ViewUI implements ViewEntityInterface {
|
|||
return $this->storage->getThirdPartyProviders();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function trustData() {
|
||||
return $this->storage->trustData();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasTrustedData() {
|
||||
return $this->storage->hasTrustedData();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@
|
|||
*/
|
||||
function minimal_install() {
|
||||
// Disable the user pictures on nodes.
|
||||
\Drupal::configFactory()->getEditable('system.theme.global')->set('features.node_user_picture', FALSE)->save();
|
||||
\Drupal::configFactory()->getEditable('system.theme.global')->set('features.node_user_picture', FALSE)->save(TRUE);
|
||||
|
||||
// Allow visitor account creation, but with administrative approval.
|
||||
\Drupal::configFactory()->getEditable('user.settings')->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)->save();
|
||||
\Drupal::configFactory()->getEditable('user.settings')->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)->save(TRUE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@ function standard_install() {
|
|||
\Drupal::service('entity.definition_update_manager')->applyUpdates();
|
||||
|
||||
// Set front page to "node".
|
||||
\Drupal::configFactory()->getEditable('system.site')->set('page.front', 'node')->save();
|
||||
\Drupal::configFactory()->getEditable('system.site')->set('page.front', 'node')->save(TRUE);
|
||||
|
||||
// Allow visitor account creation with administrative approval.
|
||||
$user_settings = \Drupal::configFactory()->getEditable('user.settings');
|
||||
$user_settings->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)->save();
|
||||
$user_settings->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)->save(TRUE);
|
||||
|
||||
// Enable default permissions for system roles.
|
||||
user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, array('access comments'));
|
||||
|
|
@ -41,7 +41,7 @@ function standard_install() {
|
|||
// Enable the Contact link in the footer menu.
|
||||
/** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */
|
||||
$menu_link_manager = \Drupal::service('plugin.manager.menu.link');
|
||||
$menu_link_manager->updateDefinition('contact.site_page', array('enabled' => 1));
|
||||
$menu_link_manager->updateDefinition('contact.site_page', array('enabled' => TRUE));
|
||||
|
||||
user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, array('access site-wide contact form'));
|
||||
user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, array('access site-wide contact form'));
|
||||
|
|
@ -67,5 +67,5 @@ function standard_install() {
|
|||
$shortcut->save();
|
||||
|
||||
// Enable the admin theme.
|
||||
\Drupal::configFactory()->getEditable('node.settings')->set('use_admin_theme', '1')->save();
|
||||
\Drupal::configFactory()->getEditable('node.settings')->set('use_admin_theme', TRUE)->save(TRUE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,5 +23,5 @@ function standard_form_install_configure_form_alter(&$form, FormStateInterface $
|
|||
*/
|
||||
function standard_form_install_configure_submit($form, FormStateInterface $form_state) {
|
||||
$site_mail = $form_state->getValue('site_mail');
|
||||
ContactForm::load('feedback')->setRecipients([$site_mail])->save();
|
||||
ContactForm::load('feedback')->setRecipients([$site_mail])->trustData()->save();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ id: override
|
|||
label: Override
|
||||
weight: 0
|
||||
protected_property: Default
|
||||
status: 1
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- tour
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ id: override_unmet
|
|||
label: Override
|
||||
weight: 0
|
||||
protected_property: Default
|
||||
status: 1
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- dblog
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class ConfigEntityBaseUnitTest extends UnitTestCase {
|
|||
/**
|
||||
* The entity type used for testing.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
* @var \Drupal\Core\Config\Entity\ConfigEntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $entityType;
|
||||
|
||||
|
|
@ -463,9 +463,52 @@ class ConfigEntityBaseUnitTest extends UnitTestCase {
|
|||
* @covers ::toArray
|
||||
*/
|
||||
public function testToArray() {
|
||||
$this->typedConfigManager->expects($this->never())
|
||||
->method('getDefinition');
|
||||
$this->entityType->expects($this->any())
|
||||
->method('getPropertiesToExport')
|
||||
->willReturn(['id' => 'configId', 'dependencies' => 'dependencies']);
|
||||
$properties = $this->entity->toArray();
|
||||
$this->assertInternalType('array', $properties);
|
||||
$this->assertEquals(array('configId' => $this->entity->id(), 'dependencies' => array()), $properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::toArray
|
||||
*/
|
||||
public function testToArrayIdKey() {
|
||||
$entity = $this->getMockForAbstractClass('\Drupal\Core\Config\Entity\ConfigEntityBase', [[], $this->entityTypeId], '', TRUE, TRUE, TRUE, ['id', 'get']);
|
||||
$entity->expects($this->atLeastOnce())
|
||||
->method('id')
|
||||
->willReturn($this->id);
|
||||
$entity->expects($this->once())
|
||||
->method('get')
|
||||
->with('dependencies')
|
||||
->willReturn([]);
|
||||
$this->typedConfigManager->expects($this->never())
|
||||
->method('getDefinition');
|
||||
$this->entityType->expects($this->any())
|
||||
->method('getPropertiesToExport')
|
||||
->willReturn(['id' => 'configId', 'dependencies' => 'dependencies']);
|
||||
$this->entityType->expects($this->once())
|
||||
->method('getKey')
|
||||
->with('id')
|
||||
->willReturn('id');
|
||||
$properties = $entity->toArray();
|
||||
$this->assertInternalType('array', $properties);
|
||||
$this->assertEquals(['configId' => $entity->id(), 'dependencies' => []], $properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::toArray
|
||||
*/
|
||||
public function testToArraySchemaFallback() {
|
||||
$this->typedConfigManager->expects($this->once())
|
||||
->method('getDefinition')
|
||||
->will($this->returnValue(array('mapping' => array('id' => '', 'dependencies' => ''))));
|
||||
$this->entityType->expects($this->any())
|
||||
->method('getPropertiesToExport')
|
||||
->willReturn([]);
|
||||
$properties = $this->entity->toArray();
|
||||
$this->assertInternalType('array', $properties);
|
||||
$this->assertEquals(array('id' => $this->entity->id(), 'dependencies' => array()), $properties);
|
||||
|
|
@ -477,6 +520,9 @@ class ConfigEntityBaseUnitTest extends UnitTestCase {
|
|||
* @expectedException \Drupal\Core\Config\Schema\SchemaIncompleteException
|
||||
*/
|
||||
public function testToArrayFallback() {
|
||||
$this->entityType->expects($this->any())
|
||||
->method('getPropertiesToExport')
|
||||
->willReturn([]);
|
||||
$this->entity->toArray();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class ConfigEntityStorageTest extends UnitTestCase {
|
|||
/**
|
||||
* The entity type.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
* @var \Drupal\Core\Config\Entity\ConfigEntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $entityType;
|
||||
|
||||
|
|
@ -279,6 +279,9 @@ class ConfigEntityStorageTest extends UnitTestCase {
|
|||
->method('setData');
|
||||
$config_object->expects($this->once())
|
||||
->method('save');
|
||||
$config_object->expects($this->atLeastOnce())
|
||||
->method('get')
|
||||
->willReturn([]);
|
||||
|
||||
$this->cacheTagsInvalidator->expects($this->once())
|
||||
->method('invalidateTags')
|
||||
|
|
@ -343,6 +346,9 @@ class ConfigEntityStorageTest extends UnitTestCase {
|
|||
->method('setData');
|
||||
$config_object->expects($this->once())
|
||||
->method('save');
|
||||
$config_object->expects($this->atLeastOnce())
|
||||
->method('get')
|
||||
->willReturn([]);
|
||||
|
||||
$this->cacheTagsInvalidator->expects($this->once())
|
||||
->method('invalidateTags')
|
||||
|
|
@ -408,6 +414,9 @@ class ConfigEntityStorageTest extends UnitTestCase {
|
|||
->method('setData');
|
||||
$config_object->expects($this->once())
|
||||
->method('save');
|
||||
$config_object->expects($this->atLeastOnce())
|
||||
->method('get')
|
||||
->willReturn([]);
|
||||
|
||||
$this->cacheTagsInvalidator->expects($this->once())
|
||||
->method('invalidateTags')
|
||||
|
|
@ -546,6 +555,9 @@ class ConfigEntityStorageTest extends UnitTestCase {
|
|||
->will($this->returnValue(TRUE));
|
||||
$config_object->expects($this->once())
|
||||
->method('save');
|
||||
$config_object->expects($this->atLeastOnce())
|
||||
->method('get')
|
||||
->willReturn([]);
|
||||
|
||||
$this->cacheTagsInvalidator->expects($this->once())
|
||||
->method('invalidateTags')
|
||||
|
|
|
|||
|
|
@ -131,4 +131,60 @@ class ConfigEntityTypeTest extends UnitTestCase {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::getPropertiesToExport
|
||||
*
|
||||
* @dataProvider providerGetPropertiesToExport
|
||||
*/
|
||||
public function testGetPropertiesToExport($definition, $expected) {
|
||||
$entity_type = $this->setUpConfigEntityType($definition);
|
||||
$properties_to_export = $entity_type->getPropertiesToExport();
|
||||
$this->assertSame($expected, $properties_to_export);
|
||||
|
||||
// Ensure the method is idempotent.
|
||||
$properties_to_export = $entity_type->getPropertiesToExport();
|
||||
$this->assertSame($expected, $properties_to_export);
|
||||
}
|
||||
|
||||
public function providerGetPropertiesToExport() {
|
||||
$data = [];
|
||||
$data[] = [
|
||||
[],
|
||||
NULL,
|
||||
];
|
||||
|
||||
$data[] = [
|
||||
[
|
||||
'config_export' => [
|
||||
'id',
|
||||
'custom_property' => 'customProperty',
|
||||
],
|
||||
],
|
||||
[
|
||||
'uuid' => 'uuid',
|
||||
'langcode' => 'langcode',
|
||||
'status' => 'status',
|
||||
'dependencies' => 'dependencies',
|
||||
'third_party_settings' => 'third_party_settings',
|
||||
'id' => 'id',
|
||||
'custom_property' => 'customProperty',
|
||||
],
|
||||
];
|
||||
|
||||
$data[] = [
|
||||
[
|
||||
'config_export' => [
|
||||
'id',
|
||||
],
|
||||
'mergedConfigExport' => [
|
||||
'random_key' => 'random_key',
|
||||
],
|
||||
],
|
||||
[
|
||||
'random_key' => 'random_key',
|
||||
],
|
||||
];
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,11 +114,15 @@ class StaticMenuLinkOverridesTest extends UnitTestCase {
|
|||
->with('definitions')
|
||||
->will($this->returnValue(array()));
|
||||
|
||||
$definition_save_1 = array('definitions' => array('test1' => array('parent' => 'test0')));
|
||||
$definition_save_1 = array(
|
||||
'definitions' => array(
|
||||
'test1' => array('parent' => 'test0', 'menu_name' => '', 'weight' => 0, 'expanded' => FALSE, 'enabled' => FALSE)
|
||||
)
|
||||
);
|
||||
$definitions_save_2 = array(
|
||||
'definitions' => array(
|
||||
'test1' => array('parent' => 'test0'),
|
||||
'test1__la___ma' => array('parent' => 'test1')
|
||||
'test1' => array('parent' => 'test0', 'menu_name' => '', 'weight' => 0, 'expanded' => FALSE, 'enabled' => FALSE),
|
||||
'test1__la___ma' => array('parent' => 'test1', 'menu_name' => '', 'weight' => 0, 'expanded' => FALSE, 'enabled' => FALSE)
|
||||
)
|
||||
);
|
||||
$config->expects($this->at(2))
|
||||
|
|
|
|||
Loading…
Reference in New Issue