Commit 31d4f1b0 authored by webchick's avatar webchick

Issue #1806178 by tim.plunkett, beejeebus: Remove code duplication for...

Issue #1806178 by tim.plunkett, beejeebus: Remove code duplication for hook_config_import_()*() implementations of config entities.
parent e42ba769
......@@ -253,12 +253,10 @@ function config_import_invoke_owner(array $config_changes, StorageInterface $sou
// handle dependencies correctly.
foreach (array('delete', 'create', 'change') as $op) {
foreach ($config_changes[$op] as $key => $name) {
// Extract owner from configuration object name.
$module = strtok($name, '.');
// Check whether the module implements hook_config_import() and ask it to
// handle the configuration change.
// Call to the configuration entity's storage controller to handle the
// configuration change.
$handled_by_module = FALSE;
if (module_exists($module) && module_hook($module, 'config_import_' . $op)) {
if ($entity_type = config_get_entity_type_by_name($name)) {
$old_config = new Config($name, $target_storage);
$old_config->load();
......@@ -268,7 +266,8 @@ function config_import_invoke_owner(array $config_changes, StorageInterface $sou
$new_config->setData($data);
}
$handled_by_module = module_invoke($module, 'config_import_' . $op, $name, $new_config, $old_config);
$method = 'import' . ucfirst($op);
$handled_by_module = entity_get_controller($entity_type)->$method($name, $new_config, $old_config);
}
if (!empty($handled_by_module)) {
unset($config_changes[$op][$key]);
......@@ -297,3 +296,19 @@ function config_get_module_config_entities($module) {
return ($entity_info['module'] == $module) && is_subclass_of($entity_info['class'], 'Drupal\Core\Config\Entity\ConfigEntityInterface');
});
}
/**
* Returns the entity type of a configuration object.
*
* @param string $name
* The configuration object name.
*
* @return string|null
* Either the entity type name, or NULL if none match.
*/
function config_get_entity_type_by_name($name) {
$entities = array_filter(entity_get_info(), function($entity_info) use ($name) {
return (isset($entity_info['config_prefix']) && strpos($name, $entity_info['config_prefix'] . '.') === 0);
});
return key($entities);
}
......@@ -11,6 +11,7 @@
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityMalformedException;
use Drupal\Core\Entity\EntityStorageControllerInterface;
use Drupal\Core\Config\Config;
/**
* Defines the storage controller class for configuration entities.
......@@ -425,4 +426,76 @@ protected function invokeHook($hook, EntityInterface $entity) {
public function getQueryServicename() {
throw new \LogicException('Querying configuration entities is not supported.');
}
/**
* Create configuration upon synchronizing configuration changes.
*
* This callback is invoked when configuration is synchronized between storages
* and allows a module to take over the synchronization of configuration data.
*
* @param string $name
* The name of the configuration object.
* @param \Drupal\Core\Config\Config $new_config
* A configuration object containing the new configuration data.
* @param \Drupal\Core\Config\Config $old_config
* A configuration object containing the old configuration data.
*/
public function importCreate($name, Config $new_config, Config $old_config) {
$entity = $this->create($new_config->get());
$entity->save();
return TRUE;
}
/**
* Update configuration upon synchronizing configuration changes.
*
* This callback is invoked when configuration is synchronized between storages
* and allows a module to take over the synchronization of configuration data.
*
* @param string $name
* The name of the configuration object.
* @param \Drupal\Core\Config\Config $new_config
* A configuration object containing the new configuration data.
* @param \Drupal\Core\Config\Config $old_config
* A configuration object containing the old configuration data.
*/
public function importChange($name, Config $new_config, Config $old_config) {
list(, , $id) = explode('.', $name);
$entities = $this->load(array($id));
$entity = $entities[$id];
$entity->original = clone $entity;
foreach ($old_config->get() as $property => $value) {
$entity->original->$property = $value;
}
foreach ($new_config->get() as $property => $value) {
$entity->$property = $value;
}
$entity->save();
return TRUE;
}
/**
* Delete configuration upon synchronizing configuration changes.
*
* This callback is invoked when configuration is synchronized between storages
* and allows a module to take over the synchronization of configuration data.
*
* @param string $name
* The name of the configuration object.
* @param \Drupal\Core\Config\Config $new_config
* A configuration object containing the new configuration data.
* @param \Drupal\Core\Config\Config $old_config
* A configuration object containing the old configuration data.
*/
public function importDelete($name, Config $new_config, Config $old_config) {
list(, , $id) = explode('.', $name);
$entities = $this->load(array($id));
$entity = $entities[$id];
$entity->delete();
return TRUE;
}
}
......@@ -11,116 +11,3 @@
* @todo Overall description of the configuration system.
* @}
*/
/**
* Create configuration upon synchronizing configuration changes.
*
* This callback is invoked when configuration is synchronized between storages
* and allows a module to take over the synchronization of configuration data.
*
* Modules should implement this callback if they manage configuration data
* (such as image styles, node types, or fields) which needs to be
* prepared and passed through module API functions to properly handle a
* configuration change.
*
* @param string $name
* The name of the configuration object.
* @param Drupal\Core\Config\Config $new_config
* A configuration object containing the new configuration data.
* @param Drupal\Core\Config\Config $old_config
* A configuration object containing the old configuration data.
*/
function hook_config_import_create($name, $new_config, $old_config) {
// Only configuration entities require custom handling. Any other module
// settings can be synchronized directly.
if (strpos($name, 'config_test.dynamic.') !== 0) {
return FALSE;
}
$config_test = entity_create('config_test', $new_config->get());
$config_test->save();
return TRUE;
}
/**
* Update configuration upon synchronizing configuration changes.
*
* This callback is invoked when configuration is synchronized between storages
* and allows a module to take over the synchronization of configuration data.
*
* Modules should implement this callback if they manage configuration data
* (such as image styles, node types, or fields) which needs to be
* prepared and passed through module API functions to properly handle a
* configuration change.
*
* @param string $name
* The name of the configuration object.
* @param Drupal\Core\Config\Config $new_config
* A configuration object containing the new configuration data.
* @param Drupal\Core\Config\Config $old_config
* A configuration object containing the old configuration data.
*/
function hook_config_import_change($name, $new_config, $old_config) {
// Only configuration entities require custom handling. Any other module
// settings can be synchronized directly.
if (strpos($name, 'config_test.dynamic.') !== 0) {
return FALSE;
}
// @todo Make this less ugly.
list($entity_type) = explode('.', $name);
$entity_info = entity_get_info($entity_type);
$id = substr($name, strlen($entity_info['config_prefix']) + 1);
$config_test = entity_load('config_test', $id);
// Store the original config, and iterate through each property to store it.
$config_test->original = clone $config_test;
foreach ($old_config->get() as $property => $value) {
$config_test->original->$property = $value;
}
// Iterate through each property of the new config, copying it to the test
// object.
foreach ($new_config->get() as $property => $value) {
$config_test->$property = $value;
}
$config_test->save();
return TRUE;
}
/**
* Delete configuration upon synchronizing configuration changes.
*
* This callback is invoked when configuration is synchronized between storages
* and allows a module to take over the synchronization of configuration data.
*
* Modules should implement this callback if they manage configuration data
* (such as image styles, node types, or fields) which needs to be
* prepared and passed through module API functions to properly handle a
* configuration change.
*
* @param string $name
* The name of the configuration object.
* @param Drupal\Core\Config\Config $new_config
* A configuration object containing the new configuration data.
* @param Drupal\Core\Config\Config $old_config
* A configuration object containing the old configuration data.
*/
function hook_config_import_delete($name, $new_config, $old_config) {
// Only configuration entities require custom handling. Any other module
// settings can be synchronized directly.
if (strpos($name, 'config_test.dynamic.') !== 0) {
return FALSE;
}
// @todo image_style_delete() supports the notion of a "replacement style"
// to be used by other modules instead of the deleted style. Essential!
// But that is impossible currently, since the config system only knows
// about deleted and added changes. Introduce an 'old_ID' key within
// config objects as a standard?
list($entity_type) = explode('.', $name);
$entity_info = entity_get_info($entity_type);
$id = substr($name, strlen($entity_info['config_prefix']) + 1);
config_test_delete($id);
return TRUE;
}
......@@ -9,68 +9,6 @@
require_once dirname(__FILE__) . '/config_test.hooks.inc';
/**
* Implements hook_config_import_create().
*/
function config_test_config_import_create($name, $new_config, $old_config) {
if (strpos($name, 'config_test.dynamic.') !== 0) {
return FALSE;
}
// Set a global value we can check in test code.
$GLOBALS['hook_config_import'] = __FUNCTION__;
$config_test = entity_create('config_test', $new_config->get());
$config_test->save();
return TRUE;
}
/**
* Implements hook_config_import_change().
*/
function config_test_config_import_change($name, $new_config, $old_config) {
if (strpos($name, 'config_test.dynamic.') !== 0) {
return FALSE;
}
// Set a global value we can check in test code.
$GLOBALS['hook_config_import'] = __FUNCTION__;
// @todo Make this less ugly.
list(, , $id) = explode('.', $name);
$config_test = entity_load('config_test', $id);
// Store the original config, and iterate through each property to store it.
$config_test->original = clone $config_test;
foreach ($old_config->get() as $property => $value) {
$config_test->original->$property = $value;
}
// Iterate through each property of the new config, copying it to the test
// object.
foreach ($new_config->get() as $property => $value) {
$config_test->$property = $value;
}
$config_test->save();
return TRUE;
}
/**
* Implements hook_config_import_delete().
*/
function config_test_config_import_delete($name, $new_config, $old_config) {
if (strpos($name, 'config_test.dynamic.') !== 0) {
return FALSE;
}
// Set a global value we can check in test code.
$GLOBALS['hook_config_import'] = __FUNCTION__;
// @todo Make this less ugly.
list(, , $id) = explode('.', $name);
$config_test = entity_load('config_test', $id);
$config_test->delete();
return TRUE;
}
/**
* Entity URI callback.
*
......@@ -197,4 +135,4 @@ function config_test_cache_flush() {
$GLOBALS['hook_cache_flush'] = __FUNCTION__;
return array();
}
\ No newline at end of file
}
<?php
/**
* @file
* Contains \Drupal\config_test\ConfigTestStorageController.
*/
namespace Drupal\config_test;
use Drupal\Core\Config\Entity\ConfigStorageController;
use Drupal\Core\Config\Config;
/**
* @todo.
*/
class ConfigTestStorageController extends ConfigStorageController {
/**
* Overrides \Drupal\Core\Config\Entity\ConfigStorageController::importCreate().
*/
public function importCreate($name, Config $new_config, Config $old_config) {
// Set a global value we can check in test code.
$GLOBALS['hook_config_import'] = __METHOD__;
return parent::importCreate($name, $new_config, $old_config);
}
/**
* Overrides \Drupal\Core\Config\Entity\ConfigStorageController::importChange().
*/
public function importChange($name, Config $new_config, Config $old_config) {
// Set a global value we can check in test code.
$GLOBALS['hook_config_import'] = __METHOD__;
return parent::importChange($name, $new_config, $old_config);
}
/**
* Overrides \Drupal\Core\Config\Entity\ConfigStorageController::importDelete().
*/
public function importDelete($name, Config $new_config, Config $old_config) {
// Set a global value we can check in test code.
$GLOBALS['hook_config_import'] = __METHOD__;
return parent::importDelete($name, $new_config, $old_config);
}
}
......@@ -18,7 +18,7 @@
* id = "config_test",
* label = @Translation("Test configuration"),
* module = "config_test",
* controller_class = "Drupal\Core\Config\Entity\ConfigStorageController",
* controller_class = "Drupal\config_test\ConfigTestStorageController",
* list_controller_class = "Drupal\Core\Config\Entity\ConfigEntityListController",
* form_controller_class = {
* "default" = "Drupal\config_test\ConfigTestFormController"
......
......@@ -173,56 +173,6 @@ function _contact_personal_tab_access($account) {
return user_access('access user contact forms');
}
/**
* Implements MODULE_config_import_create().
*/
function contact_config_import_create($name, $new_config, $old_config) {
if (strpos($name, 'contact.category.') !== 0) {
return FALSE;
}
$category = entity_create('contact_category', $new_config->get());
$category->save();
return TRUE;
}
/**
* Implements MODULE_config_import_change().
*/
function contact_config_import_change($name, $new_config, $old_config) {
if (strpos($name, 'contact.category.') !== 0) {
return FALSE;
}
list(, , $id) = explode('.', $name);
$category = entity_load('contact_category', $id);
$category->original = clone $category;
foreach ($old_config->get() as $property => $value) {
$category->original->$property = $value;
}
foreach ($new_config->get() as $property => $value) {
$category->$property = $value;
}
$category->save();
return TRUE;
}
/**
* Implements MODULE_config_import_delete().
*/
function contact_config_import_delete($name, $new_config, $old_config) {
if (strpos($name, 'contact.category.') !== 0) {
return FALSE;
}
list(, , $id) = explode('.', $name);
entity_delete_multiple('contact_category', array($id));
return TRUE;
}
/**
* Implements hook_entity_info().
*/
......
......@@ -502,65 +502,6 @@ function image_path_flush($path) {
}
}
/**
* Implements hook_config_import_create().
*/
function image_config_import_create($name, $new_config, $old_config) {
// Only image styles require custom handling. Any other module settings can be
// synchronized directly.
if (strpos($name, 'image.style.') !== 0) {
return FALSE;
}
$style = entity_create('image_style', $new_config->get());
$style->save();
return TRUE;
}
/**
* Implements hook_config_import_change().
*/
function image_config_import_change($name, $new_config, $old_config) {
// Only image styles require custom handling. Any other module settings can be
// synchronized directly.
if (strpos($name, 'image.style.') !== 0) {
return FALSE;
}
list(, , $id) = explode('.', $name);
$style = entity_load('image_style', $id);
$style->original = clone $style;
foreach ($old_config->get() as $property => $value) {
$style->original->$property = $value;
}
foreach ($new_config->get() as $property => $value) {
$style->$property = $value;
}
$style->save();
return TRUE;
}
/**
* Implements MODULE_config_import_delete().
*/
function image_config_import_delete($name, $new_config, $old_config) {
// Only image styles require custom handling. Any other module settings can be
// synchronized directly.
if (strpos($name, 'image.style.') !== 0) {
return FALSE;
}
// @todo image_style_delete() supports the notion of a "replacement style"
// to be used by other modules instead of the deleted style. Essential!
// But that is impossible currently, since the config system only knows
// about deleted and added changes. Introduce an 'old_ID' key within
// config objects as a standard?
list(, , $id) = explode('.', $name);
$style = entity_load('image_style', $id);
return image_style_delete($style);
}
/**
* Loads an ImageStyle object.
*
......
<?php
/**
* @file
* Contains \Drupal\image\ImageStyleStorageController.
*/
namespace Drupal\image;
use Drupal\Core\Config\Entity\ConfigStorageController;
use Drupal\Core\Config\Config;
/**
* Defines a controller class for image styles.
*/
class ImageStyleStorageController extends ConfigStorageController {
/**
* Overrides \Drupal\Core\Config\Entity\ConfigStorageController::importDelete().
*/
public function importDelete($name, Config $new_config, Config $old_config) {
list(, , $id) = explode('.', $name);
$entities = $this->load(array($id));
$entity = $entities[$id];
// @todo image_style_delete() supports the notion of a "replacement style"
// to be used by other modules instead of the deleted style. Essential!
// But that is impossible currently, since the config system only knows
// about deleted and added changes. Introduce an 'old_ID' key within
// config objects as a standard?
return image_style_delete($entity);
}
}
......@@ -18,7 +18,7 @@
* id = "image_style",
* label = @Translation("Image style"),
* module = "image",
* controller_class = "Drupal\Core\Config\Entity\ConfigStorageController",
* controller_class = "Drupal\image\ImageStyleStorageController",
* uri_callback = "image_style_uri",
* config_prefix = "image.style",
* entity_keys = {
......
......@@ -78,19 +78,6 @@ function views_pre_render_view_element($element) {
return $element;
}
/**
* Implements hook_config_import_create().
*/
function views_config_import_create($name, $new_config, $old_config) {
if (strpos($name, 'views.view.') !== 0) {
return FALSE;
}
$view = entity_create('view', $new_config->get());
$view->save();
return TRUE;
}
/**
* Implement hook_theme(). Register views theming functions.
*/
......@@ -2072,22 +2059,6 @@ function views_array_key_plus($array) {
return $array;
}
/**
* Implements hook_config_import_delete().
*/
function views_config_import_delete($name, $new_config, $old_config) {
// Only image styles require custom handling. Any other module settings can be
// synchronized directly.
if (strpos($name, 'views.view.') !== 0) {
return FALSE;
}
list(, , $id) = explode('.', $name);
$view = entity_load('view', $id);
entity_delete($view);
return TRUE;
}
/**
* Set a cached item in the views cache.
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment