diff --git a/core/modules/image/image.module b/core/modules/image/image.module index 7be1abd..b963a45 100644 --- a/core/modules/image/image.module +++ b/core/modules/image/image.module @@ -349,55 +349,6 @@ function image_file_predelete(File $file) { } /** - * Implements hook_image_style_update(). - */ -function image_image_style_update(ImageStyle $style) { - if ($style->id() != $style->getOriginalID()) { - $instances = field_read_instances(); - // Loop through all fields searching for image fields. - foreach ($instances as $instance) { - if ($instance['widget']['module'] == 'image') { - $view_modes = entity_get_view_modes($instance['entity_type']); - $view_modes = array('default') + array_keys($view_modes); - foreach ($view_modes as $view_mode) { - $display = entity_get_display($instance['entity_type'], $instance['bundle'], $view_mode); - $display_options = $display->getComponent($instance['field_name']); - - // Check if the formatter involves an image style. - if ($display_options && $display_options['type'] == 'image' && $display_options['settings']['image_style'] == $style->getOriginalID()) { - // Update display information for any instance using the image - // style that was just deleted. - $display_options['settings']['image_style'] = $style->id(); - $display->setComponent($instance['field_name'], $display_options) - ->save(); - } - } - if ($instance['widget']['settings']['preview_image_style'] == $style->getOriginalID()) { - $instance['widget']['settings']['preview_image_style'] = $style->id(); - field_update_instance($instance); - } - } - } - } -} - -/** - * Implements hook_image_style_delete(). - */ -function image_image_style_delete(ImageStyle $style) { - // Flush cached media for the style. - image_style_flush($style); - // Check whether field instance settings need to be updated. - // In case no replacement style was specified, all image fields that are using - // the deleted style are left in a broken state. - if ($new_id = $style->get('replacementID')) { - // The deleted ID is still set as originalID. - $style->set('name', $new_id); - image_image_style_update($style); - } -} - -/** * Implements hook_field_delete_field(). */ function image_field_delete_field($field) { @@ -543,23 +494,6 @@ function image_style_load($name) { } /** - * Implements hook_image_style_load. - */ -function image_image_style_load($styles) { - foreach ($styles as $style) { - if (!empty($style->effects)) { - foreach ($style->effects as $ieid => $effect) { - $definition = image_effect_definition_load($effect['name']); - $effect = array_merge($definition, $effect); - $style->effects[$ieid] = $effect; - } - // Sort effects by weight. - uasort($style->effects, 'drupal_sort_weight'); - } - } -} - -/** * Gets an array of image styles suitable for using as select list options. * * @param $include_empty diff --git a/core/modules/image/lib/Drupal/image/ImageStyleStorageController.php b/core/modules/image/lib/Drupal/image/ImageStyleStorageController.php index 80db53f..4bbbbde 100644 --- a/core/modules/image/lib/Drupal/image/ImageStyleStorageController.php +++ b/core/modules/image/lib/Drupal/image/ImageStyleStorageController.php @@ -10,6 +10,7 @@ use Drupal\Core\Config\Entity\ConfigStorageController; use Drupal\Core\Config\Config; use Drupal\Core\Entity\EntityInterface; +use Drupal\image\Plugin\Core\Entity\ImageStyle; /** * Defines a controller class for image styles. @@ -17,19 +18,21 @@ class ImageStyleStorageController extends ConfigStorageController { /** - * Overrides \Drupal\Core\Config\Entity\ConfigStorageController::importDelete(). + * Overrides \Drupal\Core\Config\Entity\ConfigStorageController::attachLoad(). */ - public function importDelete($name, Config $new_config, Config $old_config) { - $id = static::getIDFromConfigName($name, $this->entityInfo['config_prefix']); - $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); + protected function attachLoad(&$queried_entities, $revision_id = FALSE) { + foreach ($queried_entities as $style) { + if (!empty($style->effects)) { + foreach ($style->effects as $ieid => $effect) { + $definition = image_effect_definition_load($effect['name']); + $effect = array_merge($definition, $effect); + $style->effects[$ieid] = $effect; + } + // Sort effects by weight. + uasort($style->effects, 'drupal_sort_weight'); + } + } + parent::attachLoad($queried_entities, $revision_id); } /** @@ -37,8 +40,64 @@ public function importDelete($name, Config $new_config, Config $old_config) { */ protected function postSave(EntityInterface $entity, $update) { if ($update && !empty($entity->original) && $entity->{$this->idKey} !== $entity->original->{$this->idKey}) { - // The old imagestyle name needs flushing after a rename. + // The old image style name needs flushing after a rename. image_style_flush($entity->original); + // Update field instance settings if necessary. + $this->replaceImageStyle($entity); + } + } + + /** + * Overrides \Drupal\Core\Config\Entity\ConfigStorageController::postDelete(). + */ + protected function postDelete($entities) { + foreach ($entities as $style) { + // Flush cached media for the deleted style. + image_style_flush($style); + // Check whether field instance settings need to be updated. + // In case no replacement style was specified, all image fields that are + // using the deleted style are left in a broken state. + if ($new_id = $style->get('replacementID')) { + // The deleted ID is still set as originalID. + $style->set('name', $new_id); + $this->replaceImageStyle($style); + } + } + } + + /** + * Update field instance settings if the image style name is changed. + * + * @param ImageStyle $style + * The image style. + */ + protected function replaceImageStyle(ImageStyle $style) { + if ($style->id() != $style->getOriginalID()) { + $instances = field_read_instances(); + // Loop through all fields searching for image fields. + foreach ($instances as $instance) { + if ($instance['widget']['module'] == 'image') { + $view_modes = entity_get_view_modes($instance['entity_type']); + $view_modes = array('default') + array_keys($view_modes); + foreach ($view_modes as $view_mode) { + $display = entity_get_display($instance['entity_type'], $instance['bundle'], $view_mode); + $display_options = $display->getComponent($instance['field_name']); + + // Check if the formatter involves an image style. + if ($display_options && $display_options['type'] == 'image' && $display_options['settings']['image_style'] == $style->getOriginalID()) { + // Update display information for any instance using the image + // style that was just deleted. + $display_options['settings']['image_style'] = $style->id(); + $display->setComponent($instance['field_name'], $display_options) + ->save(); + } + } + if ($instance['widget']['settings']['preview_image_style'] == $style->getOriginalID()) { + $instance['widget']['settings']['preview_image_style'] = $style->id(); + field_update_instance($instance); + } + } + } } } diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php index 84a5ed458..4cb1dca 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php @@ -333,4 +333,43 @@ function testEditEffect() { $this->assertText(t('Scale 12x19')); } + /** + * Tests image style configuration import that does a delete. + */ + function testConfigImport() { + // Create a new style. + $style_name = strtolower($this->randomName(10)); + $style_label = $this->randomString(); + $style = entity_create('image_style', array('name' => $style_name, 'label' => $style_label)); + $style->save(); + + // Create an image field that uses the new style. + $field_name = strtolower($this->randomName(10)); + $this->createImageField($field_name, 'article'); + entity_get_display('node', 'article', 'default') + ->setComponent($field_name, array( + 'type' => 'image', + 'settings' => array('image_style' => $style_name), + )) + ->save(); + + // Create a new node with an image attached. + $test_image = current($this->drupalGetTestFiles('image')); + $nid = $this->uploadNodeImage($test_image, $field_name, 'article'); + $node = node_load($nid); + + // Test that image is displayed using newly created style. + $this->drupalGet('node/' . $nid); + $this->assertRaw(image_style_url($style_name, file_load($node->{$field_name}[LANGUAGE_NOT_SPECIFIED][0]['fid'])->uri), format_string('Image displayed using style @style.', array('@style' => $style_name))); + + // Write empty manifest to staging. + $manifest_data = config('manifest.image.style')->get(); + unset($manifest_data[$style_name]); + $staging = $this->container->get('config.storage.staging'); + $staging->write('manifest.image.style', $manifest_data); + config_import(); + + $this->assertFalse(entity_load('image_style', $style_name), 'Style deleted after config import.'); + $this->assertEqual($this->getImageCount($style), 0, 'Image style was flushed after being deleted by config import.'); + } }