/** * {@inheritdoc} */ public function setUp() { parent::setUp(); $this->configFactory = $this->getMock('Drupal\\Core\\Config\\ConfigFactoryInterface'); $this->configManager = $this->getMock('Drupal\\Core\\Config\\ConfigManagerInterface'); $this->configManager->expects($this->any())->method('getEntityTypeIdByName')->will($this->returnArgument(0)); vfsStream::setup('public://'); }
/** * Adds form elements to list affected configuration entities. * * @param array $form * The form array to add elements to. * @param string $type * The type of dependency being checked. Either 'module', 'theme', 'config' * or 'content'. * @param array $names * The specific names to check. If $type equals 'module' or 'theme' then it * should be a list of module names or theme names. In the case of 'config' * or 'content' it should be a list of configuration dependency names. * @param \Drupal\Core\Config\ConfigManagerInterface $config_manager * The config manager. * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. * * @see \Drupal\Core\Config\ConfigManagerInterface::getConfigEntitiesToChangeOnDependencyRemoval() */ protected function addDependencyListsToForm(array &$form, $type, array $names, ConfigManagerInterface $config_manager, EntityManagerInterface $entity_manager) { // Get the dependent entities. $dependent_entities = $config_manager->getConfigEntitiesToChangeOnDependencyRemoval($type, $names); $entity_types = array(); $form['entity_updates'] = array('#type' => 'details', '#title' => $this->t('Configuration updates'), '#description' => $this->t('The listed configuration will be updated.'), '#open' => TRUE, '#access' => FALSE); foreach ($dependent_entities['update'] as $entity) { /** @var \Drupal\Core\Config\Entity\ConfigEntityInterface $entity */ $entity_type_id = $entity->getEntityTypeId(); if (!isset($form['entity_updates'][$entity_type_id])) { $entity_type = $entity_manager->getDefinition($entity_type_id); // Store the ID and label to sort the entity types and entities later. $label = $entity_type->getLabel(); $entity_types[$entity_type_id] = $label; $form['entity_updates'][$entity_type_id] = array('#theme' => 'item_list', '#title' => $label, '#items' => array()); } $form['entity_updates'][$entity_type_id]['#items'][$entity->id()] = $entity->label() ?: $entity->id(); } if (!empty($dependent_entities['update'])) { $form['entity_updates']['#access'] = TRUE; // Add a weight key to the entity type sections. asort($entity_types, SORT_FLAG_CASE); $weight = 0; foreach ($entity_types as $entity_type_id => $label) { $form['entity_updates'][$entity_type_id]['#weight'] = $weight; // Sort the list of entity labels alphabetically. ksort($form['entity_updates'][$entity_type_id]['#items'], SORT_FLAG_CASE); $weight++; } } $form['entity_deletes'] = array('#type' => 'details', '#title' => $this->t('Configuration deletions'), '#description' => $this->t('The listed configuration will be deleted.'), '#open' => TRUE, '#access' => FALSE); foreach ($dependent_entities['delete'] as $entity) { $entity_type_id = $entity->getEntityTypeId(); if (!isset($form['entity_deletes'][$entity_type_id])) { $entity_type = $entity_manager->getDefinition($entity_type_id); // Store the ID and label to sort the entity types and entities later. $label = $entity_type->getLabel(); $entity_types[$entity_type_id] = $label; $form['entity_deletes'][$entity_type_id] = array('#theme' => 'item_list', '#title' => $label, '#items' => array()); } $form['entity_deletes'][$entity_type_id]['#items'][$entity->id()] = $entity->label() ?: $entity->id(); } if (!empty($dependent_entities['delete'])) { $form['entity_deletes']['#access'] = TRUE; // Add a weight key to the entity type sections. asort($entity_types, SORT_FLAG_CASE); $weight = 0; foreach ($entity_types as $entity_type_id => $label) { if (isset($form['entity_deletes'][$entity_type_id])) { $form['entity_deletes'][$entity_type_id]['#weight'] = $weight; // Sort the list of entity labels alphabetically. ksort($form['entity_deletes'][$entity_type_id]['#items'], SORT_FLAG_CASE); $weight++; } } } }
/** * Loads configuration from storage into a property. */ protected function initConfigCollection($reset = FALSE) { if ($reset || empty($this->configCollection)) { $config_collection = []; $config_types = $this->listConfigTypes(); $dependency_manager = $this->configManager->getConfigDependencyManager(); foreach (array_keys($config_types) as $config_type) { $config = $this->listConfigByType($config_type); foreach ($config as $item_name => $label) { $name = $this->getFullName($config_type, $item_name); $data = $this->configStorage->read($name); // Compute dependent config. $dependent_list = $dependency_manager->getDependentEntities('config', $name); $dependents = array(); foreach ($dependent_list as $config_name => $item) { if (!isset($dependents[$config_name])) { $dependents[$config_name] = $config_name; } // Grab any dependent graph paths. if (isset($item['reverse_paths'])) { foreach ($item['reverse_paths'] as $dependent_name => $value) { if ($value && !isset($dependents[$dependent_name])) { $dependents[$dependent_name] = $dependent_name; } } } } $config_collection[$name] = ['name' => $name, 'name_short' => $item_name, 'label' => $label, 'type' => $config_type, 'data' => $data, 'dependents' => array_keys($dependents), 'subdirectory' => InstallStorage::CONFIG_INSTALL_DIRECTORY, 'package_excluded' => []]; } } $this->setConfigCollection($config_collection); } }
/** * {@inheritdoc} */ public function updateExtension($type, $name, array $changelist = array(), $safe_only = TRUE) { // If no change list was passed, load one. if (empty($changelist)) { $changelist = $this->configSyncLister->getExtensionChangelist($type, $name, $safe_only); } // Process create changes. if (!empty($changelist['create'])) { foreach ($changelist['create'] as $item_name) { if (!($entity_type = $this->configManager->getEntityTypeIdByName($name))) { $entity_type = 'system.simple'; } $this->configRevert->import($entity_type, $item_name); } } // Process update changes. if (!empty($changelist['update'])) { foreach ($changelist['update'] as $item_name) { if (!($entity_type = $this->configManager->getEntityTypeIdByName($name))) { $entity_type = 'system.simple'; } $this->configRevert->revert($entity_type, $item_name); } } // Refresh the configuration snapshot. $this->configSyncSnapshotter->createExtensionSnapshot($type, $name); }
/** * Loads configuration from storage into a property. */ protected function initConfigCollection($reset = FALSE) { if ($reset || empty($this->configCollection)) { $config_collection = []; $config_types = $this->listConfigTypes(); $dependency_manager = $this->configManager->getConfigDependencyManager(); // List configuration provided by installed features. $existing_config = $this->listExistingConfig(TRUE); foreach (array_keys($config_types) as $config_type) { $config = $this->listConfigByType($config_type); foreach ($config as $item_name => $label) { $name = $this->getFullName($config_type, $item_name); $data = $this->configStorage->read($name); // Compute dependent config. $dependent_list = $dependency_manager->getDependentEntities('config', $name); $dependents = array(); foreach ($dependent_list as $config_name => $item) { if (!isset($dependents[$config_name])) { $dependents[$config_name] = $config_name; } // Grab any dependent graph paths. if (isset($item['reverse_paths'])) { foreach ($item['reverse_paths'] as $dependent_name => $value) { if ($value && !isset($dependents[$dependent_name])) { $dependents[$dependent_name] = $dependent_name; } } } } $config_collection[$name] = new ConfigurationItem($name, $data, ['shortName' => $item_name, 'label' => $label, 'type' => $config_type, 'dependents' => array_keys($dependents), 'subdirectory' => InstallStorage::CONFIG_INSTALL_DIRECTORY, 'package' => '', 'extensionProvided' => NULL, 'providingFeature' => isset($existing_config[$name]) ? $existing_config[$name] : NULL, 'packageExcluded' => []]); } } $this->setConfigCollection($config_collection); } }
/** * Generates and adds files to a given package or profile. */ protected function addPackageFiles(Package $package) { $config_collection = $this->getConfigCollection(); // Always add .info.yml and .features.yml files. $this->addInfoFile($package); // Only add files if there is at least one piece of configuration present. if ($package->getConfig()) { // Add configuration files. foreach ($package->getConfig() as $name) { $config = $config_collection[$name]; $data = $config->getData(); // The _core is site-specific, so don't export it. unset($data['_core']); // The UUID is site-specfic, so don't export it. if ($entity_type_id = $this->configManager->getEntityTypeIdByName($name)) { unset($data['uuid']); } $config->setData($data); // User roles include all permissions currently assigned to them. To // avoid extraneous additions, reset permissions. if ($config->getType() == 'user_role') { $data = $config->getData(); // Unset and not empty permissions data to prevent loss of configured // role permissions in the event of a feature revert. unset($data['permissions']); $config->setData($data); } $package->appendFile(['filename' => $config->getName() . '.yml', 'subdirectory' => $config->getSubdirectory(), 'string' => Yaml::encode($config->getData())], $name); } } }
/** * Loads configuration from storage into a property. */ protected function initConfigCollection($reset = FALSE) { if ($reset || empty($this->configCollection)) { $config_collection = []; $config_types = $this->listConfigTypes(); $dependency_manager = $this->configManager->getConfigDependencyManager(); foreach (array_keys($config_types) as $config_type) { $config = $this->listConfigByType($config_type); foreach ($config as $item_name => $label) { $name = $this->getFullName($config_type, $item_name); $data = $this->configStorage->read($name); // Compute dependent config. $dependent_list = $dependency_manager->getDependentEntities('config', $name); $dependents = array(); foreach ($dependent_list as $config_name => $item) { if (!isset($dependents[$config_name])) { $dependents[$config_name] = $config_name; } // Grab the dependent graph paths. foreach ($item['paths'] as $dependent_name => $value) { if ($value && !isset($dependents[$dependent_name])) { $dependents[$dependent_name] = $dependent_name; } } } $config_collection[$name] = ['name' => $name, 'name_short' => $item_name, 'label' => $label, 'type' => $config_type, 'data' => $data, 'dependents' => array_keys($dependents)]; } } $this->setConfigCollection($config_collection); } }
/** * {@inheritdoc} */ public function build(FacetInterface $facet, array $results) { $field_identifier = $facet->getFieldIdentifier(); $entity = 'node'; // Support multiple entities when using Search API. if ($facet->getFacetSource() instanceof SearchApiFacetSourceInterface) { $index = $facet->getFacetSource()->getIndex(); $field = $index->getField($field_identifier); $entity = str_replace('entity:', '', $field->getDatasourceId()); } // If it's an entity base field, we find it in the field definitions. // We don't have access to the bundle via SearchApiFacetSourceInterface, so // we check the entity's base fields only. $base_fields = $this->entityFieldManager->getFieldDefinitions($entity, ''); // This only works for configurable fields. $config_entity_name = sprintf('field.storage.%s.%s', $entity, $field_identifier); if (isset($base_fields[$field_identifier])) { $field = $base_fields[$field_identifier]; } elseif ($this->configManager->loadConfigEntityByName($config_entity_name) !== NULL) { $field = $this->configManager->loadConfigEntityByName($config_entity_name); } if ($field) { $function = $field->getSetting('allowed_values_function'); if (empty($function)) { $allowed_values = $field->getSetting('allowed_values'); } else { $allowed_values = ${$function}($field); } if (is_array($allowed_values)) { /** @var \Drupal\facets\Result\ResultInterface $result */ foreach ($results as &$result) { if (isset($allowed_values[$result->getRawValue()])) { $result->setDisplayValue($allowed_values[$result->getRawValue()]); } } } } return $results; }
/** * Ensures bundles that will be deleted are not in use. * * @param \Drupal\Core\Config\ConfigImporterEvent $event * The config import event. */ public function onConfigImporterValidate(ConfigImporterEvent $event) { foreach ($event->getChangelist('delete') as $config_name) { // Get the config entity type ID. This also ensure we are dealing with a // configuration entity. if ($entity_type_id = $this->configManager->getEntityTypeIdByName($config_name)) { $entity_type = $this->entityManager->getDefinition($entity_type_id); // Does this entity type define a bundle of another entity type. if ($bundle_of = $entity_type->getBundleOf()) { // Work out if there are entities with this bundle. $bundle_of_entity_type = $this->entityManager->getDefinition($bundle_of); $bundle_id = ConfigEntityStorage::getIDFromConfigName($config_name, $entity_type->getConfigPrefix()); $entity_query = $this->entityManager->getStorage($bundle_of)->getQuery(); $entity_ids = $entity_query->condition($bundle_of_entity_type->getKey('bundle'), $bundle_id)->accessCheck(FALSE)->range(0, 1)->execute(); if (!empty($entity_ids)) { $entity = $this->entityManager->getStorage($entity_type_id)->load($bundle_id); $event->getConfigImporter()->logError($this->t('Entities exist of type %entity_type and %bundle_label %bundle. These entities need to be deleted before importing.', array('%entity_type' => $bundle_of_entity_type->getLabel(), '%bundle_label' => $bundle_of_entity_type->getBundleLabel(), '%bundle' => $entity->label()))); } } } } }
/** * Creates configuration in a collection based on the provided list. * * @param string $collection * The configuration collection. * @param array $config_to_install * A list of configuration object names to create. */ protected function createConfiguration($collection, array $config_to_install) { // Order the configuration to install in the order of dependencies. $data = $this->getSourceStorage($collection)->readMultiple($config_to_install); $config_entity_support = $this->configManager->supportsConfigurationEntities($collection); if ($config_entity_support) { $dependency_manager = new ConfigDependencyManager(); $config_to_install = $dependency_manager->setData($data)->sortAll(); } // Remove configuration that already exists in the active storage. $config_to_install = array_diff($config_to_install, $this->getActiveStorage($collection)->listAll()); foreach ($config_to_install as $name) { // Allow config factory overriders to use a custom configuration object if // they are responsible for the collection. $overrider = $this->configManager->getConfigCollectionInfo()->getOverrideService($collection); if ($overrider) { $new_config = $overrider->createConfigObject($name, $collection); } else { $new_config = new Config($name, $this->getActiveStorage($collection), $this->eventDispatcher, $this->typedConfig); } if ($data[$name] !== FALSE) { $new_config->setData($data[$name]); } if ($config_entity_support && ($entity_type = $this->configManager->getEntityTypeIdByName($name))) { // If we are syncing do not create configuration entities. Pluggable // configuration entities can have dependencies on modules that are // not yet enabled. This approach means that any code that expects // default configuration entities to exist will be unstable after the // module has been enabled and before the config entity has been // imported. if ($this->isSyncing) { continue; } $entity_storage = $this->configManager->getEntityManager()->getStorage($entity_type); // It is possible that secondary writes can occur during configuration // creation. Updates of such configuration are allowed. if ($this->getActiveStorage($collection)->exists($name)) { $id = $entity_storage->getIDFromConfigName($name, $entity_storage->getEntityType()->getConfigPrefix()); $entity = $entity_storage->load($id); foreach ($new_config->get() as $property => $value) { $entity->set($property, $value); } $entity->save(); } else { $entity_storage->create($new_config->get())->save(); } } else { $new_config->save(); } } }
/** * {@inheritdoc} */ public function uninstall(array $theme_list) { $extension_config = $this->configFactory->getEditable('core.extension'); $theme_config = $this->configFactory->getEditable('system.theme'); $list = $this->themeHandler->listInfo(); foreach ($theme_list as $key) { if (!isset($list[$key])) { throw new \InvalidArgumentException("Unknown theme: {$key}."); } if ($key === $theme_config->get('default')) { throw new \InvalidArgumentException("The current default theme {$key} cannot be uninstalled."); } if ($key === $theme_config->get('admin')) { throw new \InvalidArgumentException("The current admin theme {$key} cannot be uninstalled."); } // Base themes cannot be uninstalled if sub themes are installed, and if // they are not uninstalled at the same time. // @todo https://www.drupal.org/node/474684 and // https://www.drupal.org/node/1297856 themes should leverage the module // dependency system. if (!empty($list[$key]->sub_themes)) { foreach ($list[$key]->sub_themes as $sub_key => $sub_label) { if (isset($list[$sub_key]) && !in_array($sub_key, $theme_list, TRUE)) { throw new \InvalidArgumentException("The base theme {$key} cannot be uninstalled, because theme {$sub_key} depends on it."); } } } } $this->cssCollectionOptimizer->deleteAll(); $current_theme_data = $this->state->get('system.theme.data', array()); foreach ($theme_list as $key) { // The value is not used; the weight is ignored for themes currently. $extension_config->clear("theme.{$key}"); // Update the current theme data accordingly. unset($current_theme_data[$key]); // Reset theme settings. $theme_settings =& drupal_static('theme_get_setting'); unset($theme_settings[$key]); // Remove all configuration belonging to the theme. $this->configManager->uninstall('theme', $key); } // 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); // @todo Remove system_list(). $this->themeHandler->refreshInfo(); $this->resetSystem(); $this->moduleHandler->invokeAll('themes_uninstalled', [$theme_list]); }
/** * Shows diff of specified configuration file. * * @param string $source_name * The name of the configuration file. * @param string $target_name * (optional) The name of the target configuration file if different from * the $source_name. * @param string $collection * (optional) The configuration collection name. Defaults to the default * collection. * * @return string * Table showing a two-way diff between the active and staged configuration. */ public function diff($source_name, $target_name = NULL, $collection = NULL) { if (!isset($collection)) { $collection = StorageInterface::DEFAULT_COLLECTION; } $diff = $this->configManager->diff($this->targetStorage, $this->sourceStorage, $source_name, $target_name, $collection); $this->diffFormatter->show_header = FALSE; $build = array(); $build['#title'] = t('View changes of @config_file', array('@config_file' => $source_name)); // Add the CSS for the inline diff. $build['#attached']['css'][] = drupal_get_path('module', 'system') . '/css/system.diff.css'; $build['diff'] = array('#type' => 'table', '#header' => array(array('data' => t('Old'), 'colspan' => '2'), array('data' => t('New'), 'colspan' => '2')), '#rows' => $this->diffFormatter->format($diff)); $build['back'] = array('#type' => 'link', '#attributes' => array('class' => array('dialog-cancel')), '#title' => "Back to 'Synchronize configuration' page.", '#href' => 'admin/config/development/configuration'); return $build; }
/** * Shows diff of specified configuration file. * * @param string $source_name * The name of the configuration file. * @param string $target_name * (optional) The name of the target configuration file if different from * the $source_name. * @param string $collection * (optional) The configuration collection name. Defaults to the default * collection. * * @return string * Table showing a two-way diff between the active and staged configuration. */ public function diff($source_name, $target_name = NULL, $collection = NULL) { if (!isset($collection)) { $collection = StorageInterface::DEFAULT_COLLECTION; } $diff = $this->configManager->diff($this->targetStorage, $this->sourceStorage, $source_name, $target_name, $collection); $this->diffFormatter->show_header = FALSE; $build = array(); $build['#title'] = t('View changes of @config_file', array('@config_file' => $source_name)); // Add the CSS for the inline diff. $build['#attached']['library'][] = 'system/diff'; $build['diff'] = array('#type' => 'table', '#header' => array(array('data' => t('Active'), 'colspan' => '2'), array('data' => t('Staged'), 'colspan' => '2')), '#rows' => $this->diffFormatter->format($diff)); $build['back'] = array('#type' => 'link', '#attributes' => array('class' => array('dialog-cancel')), '#title' => "Back to 'Synchronize configuration' page.", '#url' => Url::fromRoute('config.sync')); return $build; }
/** * Finds pre-existing configuration objects for the provided extension. * * Extensions can not be installed if configuration objects exist in the * active storage with the same names. This can happen in a number of ways, * commonly: * - if a user has created configuration with the same name as that provided * by the extension. * - if the extension provides default configuration that does not depend on * it and the extension has been uninstalled and is about to the * reinstalled. * * @return array * Array of configuration object names that already exist keyed by * collection. */ protected function findPreExistingConfiguration(StorageInterface $storage) { $existing_configuration = array(); // Gather information about all the supported collections. $collection_info = $this->configManager->getConfigCollectionInfo(); foreach ($collection_info->getCollectionNames() as $collection) { $config_to_create = array_keys($this->getConfigToCreate($storage, $collection)); $active_storage = $this->getActiveStorages($collection); foreach ($config_to_create as $config_name) { if ($active_storage->exists($config_name)) { $existing_configuration[$collection][] = $config_name; } } } return $existing_configuration; }
/** * {@inheritdoc} */ public function buildForm(array $form, array &$form_state) { // Retrieve the list of modules from the key value store. $account = $this->currentUser()->id(); $this->modules = $this->keyValueExpirable->get($account); // Prevent this page from showing when the module list is empty. if (empty($this->modules)) { return new RedirectResponse('/admin/modules/uninstall'); } $data = system_rebuild_module_data(); $form['text']['#markup'] = '<p>' . $this->t('The following modules will be completely uninstalled from your site, and <em>all data from these modules will be lost</em>!') . '</p>'; $form['modules'] = array('#theme' => 'item_list', '#items' => array_map(function ($module) use($data) { return $data[$module]->info['name']; }, $this->modules)); $form['entities'] = array('#type' => 'details', '#title' => $this->t('Configuration deletions'), '#description' => $this->t('The listed configuration will be deleted.'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#access' => FALSE); // Get the dependent entities. $entity_types = array(); $dependent_entities = $this->configManager->findConfigEntityDependentsAsEntities('module', $this->modules); foreach ($dependent_entities as $entity) { $entity_type_id = $entity->getEntityTypeId(); if (!isset($form['entities'][$entity_type_id])) { $entity_type = $this->entityManager->getDefinition($entity_type_id); // Store the ID and label to sort the entity types and entities later. $label = $entity_type->getLabel(); $entity_types[$entity_type_id] = $label; $form['entities'][$entity_type_id] = array('#theme' => 'item_list', '#title' => $label, '#items' => array()); } $form['entities'][$entity_type_id]['#items'][] = $entity->label(); } if (!empty($dependent_entities)) { $form['entities']['#access'] = TRUE; // Add a weight key to the entity type sections. asort($entity_types, SORT_FLAG_CASE); $weight = 0; foreach ($entity_types as $entity_type_id => $label) { $form['entities'][$entity_type_id]['#weight'] = $weight; // Sort the list of entity labels alphabetically. sort($form['entities'][$entity_type_id]['#items'], SORT_FLAG_CASE); $weight++; } } return parent::buildForm($form, $form_state); }
/** * Gets and sorts configuration data from the source and target storages. */ protected function getAndSortConfigData($collection) { $source_storage = $this->getSourceStorage($collection); $target_storage = $this->getTargetStorage($collection); $target_names = $target_storage->listAll(); $source_names = $source_storage->listAll(); $this->targetData[$collection] = $target_storage->readMultiple($target_names); $this->sourceData[$collection] = $source_storage->readMultiple($source_names); // If the collection only supports simple configuration do not use // configuration dependencies. if ($this->configManager->supportsConfigurationEntities($collection)) { $dependency_manager = new ConfigDependencyManager(); $this->targetNames[$collection] = $dependency_manager->setData($this->targetData[$collection])->sortAll(); $this->sourceNames[$collection] = $dependency_manager->setData($this->sourceData[$collection])->sortAll(); } else { $this->targetNames[$collection] = $target_names; $this->sourceNames[$collection] = $source_names; } }
/** * Imports a configuration entity rename. * * @param string $collection * The configuration collection. * @param string $rename_name * The rename configuration name, as provided by * \Drupal\Core\Config\StorageComparer::createRenameName(). * * @throws \Drupal\Core\Entity\EntityStorageException * Thrown if the data is owned by an entity type, but the entity storage * does not support imports. * * @return bool * TRUE if the configuration was imported as a configuration entity. FALSE * otherwise. * * @see \Drupal\Core\Config\ConfigImporter::createRenameName() */ protected function importInvokeRename($collection, $rename_name) { $names = $this->storageComparer->extractRenameNames($rename_name); $entity_type_id = $this->configManager->getEntityTypeIdByName($names['old_name']); $old_config = new Config($names['old_name'], $this->storageComparer->getTargetStorage($collection), $this->eventDispatcher, $this->typedConfigManager); if ($old_data = $this->storageComparer->getTargetStorage($collection)->read($names['old_name'])) { $old_config->initWithData($old_data); } $data = $this->storageComparer->getSourceStorage($collection)->read($names['new_name']); $new_config = new Config($names['new_name'], $this->storageComparer->getTargetStorage($collection), $this->eventDispatcher, $this->typedConfigManager); if ($data !== FALSE) { $new_config->setData($data); } $entity_storage = $this->configManager->getEntityManager()->getStorage($entity_type_id); // Call to the configuration entity's storage to handle the configuration // change. if (!$entity_storage instanceof ImportableEntityStorageInterface) { throw new EntityStorageException(SafeMarkup::format('The entity storage "@storage" for the "@entity_type" entity type does not support imports', array('@storage' => get_class($entity_storage), '@entity_type' => $entity_type_id))); } $entity_storage->importRename($names['old_name'], $new_config, $old_config); $this->setProcessedConfiguration($collection, 'rename', $rename_name); return TRUE; }
/** * @covers ::delete * @covers ::doDelete */ public function testDelete() { // Dependencies are tested in // \Drupal\Tests\config\Kernel\ConfigDependencyTest. $this->configManager->expects($this->any())->method('getConfigEntitiesToChangeOnDependencyRemoval')->willReturn(['update' => [], 'delete' => [], 'unchanged' => []]); $entities = array(); $configs = array(); $config_map = array(); foreach (array('foo', 'bar') as $id) { $entity = $this->getMockEntity(array('id' => $id)); $entities[] = $entity; $config_object = $this->getMockBuilder('Drupal\\Core\\Config\\Config')->disableOriginalConstructor()->getMock(); $config_object->expects($this->once())->method('delete'); $configs[] = $config_object; $config_map[] = array("the_config_prefix.{$id}", $config_object); } $this->cacheTagsInvalidator->expects($this->once())->method('invalidateTags')->with(array($this->entityTypeId . '_list')); $this->configFactory->expects($this->exactly(2))->method('getEditable')->will($this->returnValueMap($config_map)); $this->moduleHandler->expects($this->at(0))->method('invokeAll')->with('test_entity_type_predelete'); $this->moduleHandler->expects($this->at(1))->method('invokeAll')->with('entity_predelete'); $this->moduleHandler->expects($this->at(2))->method('invokeAll')->with('test_entity_type_predelete'); $this->moduleHandler->expects($this->at(3))->method('invokeAll')->with('entity_predelete'); $this->moduleHandler->expects($this->at(4))->method('invokeAll')->with('test_entity_type_delete'); $this->moduleHandler->expects($this->at(5))->method('invokeAll')->with('entity_delete'); $this->moduleHandler->expects($this->at(6))->method('invokeAll')->with('test_entity_type_delete'); $this->moduleHandler->expects($this->at(7))->method('invokeAll')->with('entity_delete'); $this->entityStorage->delete($entities); }
/** * @param string $entity_type_id * * @return \Drupal\Core\Config\Entity\ConfigEntityStorageInterface */ protected function getStorage($entity_type_id) { return $this->configManager->getEntityManager()->getStorage($entity_type_id); }
/** * Creates a config snapshot. * * @param \Drupal\Core\Config\ConfigImporterEvent $event * The Event to process. */ public function onConfigImporterImport(ConfigImporterEvent $event) { $this->configManager->createSnapshot($this->sourceStorage, $this->snapshotStorage); }
/** * Returns the original language code for this shipped configuration. * * @param string $name * The configuration name. * * @return null|string * Language code of the default configuration for $name. If the default * configuration data for $name did not contain a language code, it is * assumed to be English. The return value is NULL if no such default * configuration exists. */ public function getDefaultConfigLangcode($name) { // Config entities that do not have the 'default_config_hash' cannot be // shipped configuration regardless of whether there is a name match. // configurable_language entities are a special case since they can be // translated regardless of whether they are shipped if they in the standard // language list. $config_entity_type = $this->configManager->getEntityTypeIdByName($name); if (!$config_entity_type || $config_entity_type === 'configurable_language' || !empty($this->configFactory->get($name)->get('_core.default_config_hash'))) { $shipped = $this->defaultConfigStorage->read($name); if (!empty($shipped)) { return !empty($shipped['langcode']) ? $shipped['langcode'] : 'en'; } } return NULL; }