diff --git a/core/modules/image/config/image.style.large.yml b/core/modules/image/config/image.style.large.yml index e4f2e1f..d5602bf 100644 --- a/core/modules/image/config/image.style.large.yml +++ b/core/modules/image/config/image.style.large.yml @@ -1,10 +1,10 @@ name: large effects: - image_scale_480_480_1: + ddd73aa7-4bd6-4c85-b600-bdf2b1628d1d: name: image_scale data: width: '480' height: '480' upscale: '1' weight: '0' - ieid: image_scale_480_480_1 + ieid: ddd73aa7-4bd6-4c85-b600-bdf2b1628d1d diff --git a/core/modules/image/config/image.style.medium.yml b/core/modules/image/config/image.style.medium.yml index 17196b4..a0b2d78 100644 --- a/core/modules/image/config/image.style.medium.yml +++ b/core/modules/image/config/image.style.medium.yml @@ -1,10 +1,10 @@ name: medium effects: - image_scale_220_220_1: + bddf0d06-42f9-4c75-a700-a33cafa25ea0: name: image_scale data: width: '220' height: '220' upscale: '1' weight: '0' - ieid: image_scale_220_220_1 + ieid: bddf0d06-42f9-4c75-a700-a33cafa25ea0 diff --git a/core/modules/image/config/image.style.thumbnail.yml b/core/modules/image/config/image.style.thumbnail.yml index 2e6b9c4..f4cf3b5 100644 --- a/core/modules/image/config/image.style.thumbnail.yml +++ b/core/modules/image/config/image.style.thumbnail.yml @@ -1,10 +1,10 @@ name: thumbnail effects: - image_scale_100_100_1: + 1cfec298-8620-4749-b100-ccb6c4500779: name: image_scale data: width: '100' height: '100' upscale: '1' weight: '0' - ieid: image_scale_100_100_1 + ieid: 1cfec298-8620-4749-b100-ccb6c4500779 diff --git a/core/modules/image/image.admin.inc b/core/modules/image/image.admin.inc index d0ef114..b399fba 100644 --- a/core/modules/image/image.admin.inc +++ b/core/modules/image/image.admin.inc @@ -326,7 +326,15 @@ function image_style_delete_form_submit($form, &$form_state) { * @see image_effect_form_submit() */ function image_effect_form($form, &$form_state, $style, $effect) { - if (!empty($effect['data'])) { + // If there's no configuration for this image effect, return to + // the image style page. + if (!isset($effect['form callback'])) { + drupal_goto('admin/config/media/image-styles/edit/' . $style['name']); + } + $form_state['image_style'] = $style; + $form_state['image_effect'] = $effect; + + if (!empty($effect['ieid'])) { $title = t('Edit %label effect', array('%label' => $effect['label'])); } else{ @@ -334,18 +342,19 @@ function image_effect_form($form, &$form_state, $style, $effect) { } drupal_set_title($title, PASS_THROUGH); - $form_state['image_style'] = $style; - $form_state['image_effect'] = $effect; - - // If no configuration for this image effect, return to the image style page. - if (!isset($effect['form callback'])) { - drupal_goto('admin/config/media/image-styles/edit/' . $style['name']); - } - - $form['#tree'] = TRUE; $form['#attached']['css'][drupal_get_path('module', 'image') . '/image.admin.css'] = array(); + $form['ieid'] = array( + '#type' => 'value', + '#value' => !empty($effect['ieid']) ? $effect['ieid'] : NULL, + ); + $form['name'] = array( + '#type' => 'value', + '#value' => $effect['name'], + ); + $form['data'] = call_user_func($effect['form callback'], $effect['data']); + $form['data']['#tree'] = TRUE; // Check the URL for a weight, then the image effect, otherwise use default. $form['weight'] = array( @@ -353,10 +362,10 @@ function image_effect_form($form, &$form_state, $style, $effect) { '#value' => isset($_GET['weight']) ? intval($_GET['weight']) : (isset($effect['weight']) ? $effect['weight'] : count($style['effects'])), ); - $form['actions'] = array('#tree' => FALSE, '#type' => 'actions'); + $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array( '#type' => 'submit', - '#value' => isset($effect['ieid']) ? t('Update effect') : t('Add effect'), + '#value' => !empty($effect['ieid']) ? t('Update effect') : t('Add effect'), ); $form['actions']['cancel'] = array( '#type' => 'link', @@ -371,12 +380,11 @@ function image_effect_form($form, &$form_state, $style, $effect) { * Submit handler for updating an image effect. */ function image_effect_form_submit($form, &$form_state) { - $effect = array( - 'name' => $form_state['image_effect']['name'], - 'data' => $form_state['values']['data'], - 'weight' => $form_state['values']['weight'], - ); + form_state_values_clean($form_state); + + $effect = $form_state['values']; image_effect_save($form_state['image_style']['name'], $effect); + drupal_set_message(t('The image effect was successfully applied.')); $form_state['redirect'] = 'admin/config/media/image-styles/edit/' . $form_state['image_style']['name']; } @@ -633,12 +641,10 @@ function theme_image_style_effects($variables) { $row[] = array('data' => '', 'colspan' => 2); } - if (!isset($form[$key]['#access']) || $form[$key]['#access']) { - $rows[] = array( - 'data' => $row, - 'class' => !empty($form[$key]['weight']['#access']) || $key == 'new' ? array('draggable') : array(), - ); - } + $rows[] = array( + 'data' => $row, + 'class' => array('draggable'), + ); } $header = array( diff --git a/core/modules/image/image.module b/core/modules/image/image.module index 23ceb95..e3ef529 100644 --- a/core/modules/image/image.module +++ b/core/modules/image/image.module @@ -8,6 +8,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Drupal\Component\Uuid\Uuid; use Drupal\Core\File\File; /** @@ -1106,33 +1107,30 @@ function image_effect_load($ieid, $style_name) { /** * Save an image effect. * - * @param $style_name + * @param string $style_name * The image style this effect belongs to. - * @param $effect - * An image effect array. - * @return - * An image effect array. In the case of a new effect, 'ieid' will be set. + * @param array $effect + * An image effect array. Passed by reference. + * + * @return array + * The saved image effect array. The 'ieid' key will be set for the effect. */ -function image_effect_save($style_name, $effect) { +function image_effect_save($style_name, &$effect) { $config = config('image.style.' . $style_name); - if (!isset($effect['ieid']) || empty($effect['ieid'])) { - // We need to generate the ieid and save the new effect. - // The machine name is all the elements of the data array concatenated - // together, delimited by underscores. - $effect['ieid'] = $effect['name']; - foreach ($effect['data'] as $key => $value) { - $effect['ieid'] .= '_' . $value; - } - // @todo The machine name must not use any special non-alphanumeric - // characters, and may also not contain dots/periods, as that is the - // config system's nested key syntax. - $effect['ieid'] = preg_replace('@[^a-zA-Z0-9_-]@', '', $effect['ieid']); + // Generate a unique image effect ID for a new effect. + if (empty($effect['ieid'])) { + $uuid = new Uuid(); + $effect['ieid'] = $uuid->generate(); } $config->set('effects.' . $effect['ieid'], $effect); $config->save(); + + // Flush all derivatives that exist for this style, so they are regenerated + // with the new or updated effect. $style = image_style_load($style_name); image_style_flush($style); + return $effect; } diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php index 12d845c..f2f8b0b 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php @@ -258,4 +258,41 @@ class ImageAdminStylesTest extends ImageFieldTestBase { $this->drupalGet('node/' . $nid); $this->assertRaw(image_style_url('thumbnail', file_load($node->{$field_name}[LANGUAGE_NOT_SPECIFIED][0]['fid'])->uri), t('Image displayed using style replacement style.')); } + + /** + * Verifies that editing an image effect does not cause it to be duplicated. + */ + function testEditEffect() { + // Add a scale effect. + $this->drupalGet('admin/config/media/image-styles/add'); + $this->drupalPost(NULL, array('name' => 'test_style_effect_edit'), t('Create new style')); + $this->drupalPost(NULL, array('new' => 'image_scale_and_crop'), t('Add')); + $this->drupalPost(NULL, array('data[width]' => '300', 'data[height]' => '200'), t('Add effect')); + $this->assertText(t('Scale and crop 300x200')); + + // There should normally be only one edit link on this page initially. + $this->clickLink(t('edit')); + $this->drupalPost(NULL, array('data[width]' => '360', 'data[height]' => '240'), t('Update effect')); + $this->assertText(t('Scale and crop 360x240')); + + // Check that the previous effect is replaced. + $this->assertNoText(t('Scale and crop 300x200')); + + // Add another scale effect. + $this->drupalGet('admin/config/media/image-styles/add'); + $this->drupalPost(NULL, array('name' => 'test_style_scale_edit_scale'), t('Create new style')); + $this->drupalPost(NULL, array('new' => 'image_scale'), t('Add')); + $this->drupalPost(NULL, array('data[width]' => '12', 'data[height]' => '19'), t('Add effect')); + + // Edit the scale effect that was just added. + $this->clickLink(t('edit')); + $this->drupalPost(NULL, array('data[width]' => '24', 'data[height]' => '19'), t('Update effect')); + $this->drupalPost(NULL, array('new' => 'image_scale'), t('Add')); + + // Add another scale effect and make sure both exist. + $this->drupalPost(NULL, array('data[width]' => '12', 'data[height]' => '19'), t('Add effect')); + $this->assertText(t('Scale 24x19')); + $this->assertText(t('Scale 12x19')); + } + }