Update to Drupal 8.0.3. For more information, see https://www.drupal.org/drupal-8.0.3-release-notes

This commit is contained in:
Pantheon Automation 2016-02-03 14:56:31 -08:00 committed by Greg Anderson
parent 10f9f7fbde
commit 9db4fae9a7
202 changed files with 3806 additions and 760 deletions

View file

@ -36,6 +36,7 @@ use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
* "flush" = "Drupal\image\Form\ImageStyleFlushForm"
* },
* "list_builder" = "Drupal\image\ImageStyleListBuilder",
* "storage" = "Drupal\image\ImageStyleStorage",
* },
* admin_permission = "administer image styles",
* config_prefix = "style",
@ -58,13 +59,6 @@ use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
*/
class ImageStyle extends ConfigEntityBase implements ImageStyleInterface, EntityWithPluginCollectionInterface {
/**
* The name of the image style to use as replacement upon delete.
*
* @var string
*/
protected $replacementID;
/**
* The name of the image style.
*
@ -128,17 +122,13 @@ class ImageStyle extends ConfigEntityBase implements ImageStyleInterface, Entity
public static function postDelete(EntityStorageInterface $storage, array $entities) {
parent::postDelete($storage, $entities);
/** @var \Drupal\image\ImageStyleInterface[] $entities */
foreach ($entities as $style) {
// Flush cached media for the deleted style.
$style->flush();
// Check whether field 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 (!$style->isSyncing() && $new_id = $style->getReplacementID()) {
// The deleted ID is still set as originalID.
$style->setName($new_id);
static::replaceImageStyle($style);
}
// Clear the replacement ID, if one has been previously stored.
/** @var \Drupal\image\ImageStyleStorageInterface $storage */
$storage->clearReplacementId($style->id());
}
}
@ -380,7 +370,9 @@ class ImageStyle extends ConfigEntityBase implements ImageStyleInterface, Entity
* {@inheritdoc}
*/
public function getReplacementID() {
return $this->get('replacementID');
/** @var \Drupal\image\ImageStyleStorageInterface $storage */
$storage = $this->entityTypeManager()->getStorage($this->getEntityTypeId());
return $storage->getReplacementId($this->id());
}
/**

View file

@ -15,6 +15,13 @@ use Drupal\Core\Form\FormStateInterface;
*/
class ImageStyleDeleteForm extends EntityDeleteForm {
/**
* Replacement options.
*
* @var array
*/
protected $replacementOptions;
/**
* {@inheritdoc}
*/
@ -25,20 +32,28 @@ class ImageStyleDeleteForm extends EntityDeleteForm {
* {@inheritdoc}
*/
public function getDescription() {
return $this->t('If this style is in use on the site, you may select another style to replace it. All images that have been generated for this style will be permanently deleted.');
if (count($this->getReplacementOptions()) > 1) {
return $this->t('If this style is in use on the site, you may select another style to replace it. All images that have been generated for this style will be permanently deleted. If no replacement style is selected, the dependent configurations might need manual reconfiguration.');
}
return $this->t('All images that have been generated for this style will be permanently deleted. The dependent configurations might need manual reconfiguration.');
}
/**
* {@inheritdoc}
*/
public function form(array $form, FormStateInterface $form_state) {
$replacement_styles = array_diff_key(image_style_options(), array($this->entity->id() => ''));
$form['replacement'] = array(
'#title' => $this->t('Replacement style'),
'#type' => 'select',
'#options' => $replacement_styles,
'#empty_option' => $this->t('No replacement, just delete'),
);
$replacement_styles = $this->getReplacementOptions();
// If there are non-empty options in the list, allow the user to optionally
// pick up a replacement.
if (count($replacement_styles) > 1) {
$form['replacement'] = [
'#type' => 'select',
'#title' => $this->t('Replacement style'),
'#options' => $replacement_styles,
'#empty_option' => $this->t('- No replacement -'),
'#weight' => -5,
];
}
return parent::form($form, $form_state);
}
@ -47,9 +62,27 @@ class ImageStyleDeleteForm extends EntityDeleteForm {
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->entity->set('replacementID', $form_state->getValue('replacement'));
// Save a selected replacement in the image style storage. It will be used
// later, in the same request, when resolving dependencies.
if ($replacement = $form_state->getValue('replacement')) {
/** @var \Drupal\image\ImageStyleStorageInterface $storage */
$storage = $this->entityTypeManager->getStorage($this->entity->getEntityTypeId());
$storage->setReplacementId($this->entity->id(), $replacement);
}
parent::submitForm($form, $form_state);
}
/**
* Returns a list of image style replacement options.
*
* @return array
* An option list suitable for the form select '#options'.
*/
protected function getReplacementOptions() {
if (!isset($this->replacementOptions)) {
$this->replacementOptions = array_diff_key(image_style_options(), [$this->getEntity()->id() => '']);
}
return $this->replacementOptions;
}
}

View file

@ -17,8 +17,14 @@ interface ImageStyleInterface extends ConfigEntityInterface {
/**
* Returns the replacement ID.
*
* @return string
* The name of the image style to use as replacement upon delete.
* @return string|null
* The replacement image style ID or NULL if no replacement has been
* selected.
*
* @deprecated in Drupal 8.0.x, will be removed before Drupal 9.0.x. Use
* \Drupal\image\ImageStyleStorageInterface::getReplacementId() instead.
*
* @see \Drupal\image\ImageStyleStorageInterface::getReplacementId()
*/
public function getReplacementID();
@ -70,6 +76,7 @@ interface ImageStyleInterface extends ConfigEntityInterface {
* in an <img> tag. Requesting the URL will cause the image to be created.
*
* @see \Drupal\image\Controller\ImageStyleDownloadController::deliver()
* @see file_url_transform_relative()
*/
public function buildUrl($path, $clean_urls = NULL);

View file

@ -91,9 +91,9 @@ class ImageStyleListBuilder extends ConfigEntityListBuilder {
*/
public function render() {
$build = parent::render();
$build['#empty'] = $this->t('There are currently no styles. <a href=":url">Add a new one</a>.', array(
$build['table']['#empty'] = $this->t('There are currently no styles. <a href=":url">Add a new one</a>.', [
':url' => $this->urlGenerator->generateFromRoute('image.style_add'),
));
]);
return $build;
}

View file

@ -0,0 +1,51 @@
<?php
/**
* @file
* Contains \Drupal\image\ImageStyleStorage.
*/
namespace Drupal\image;
use Drupal\Core\Config\Entity\ConfigEntityStorage;
/**
* Storage controller class for "image style" configuration entities.
*/
class ImageStyleStorage extends ConfigEntityStorage implements ImageStyleStorageInterface {
/**
* Image style replacement memory storage.
*
* This value is not stored in the backend. It's used during the deletion of
* an image style to save the replacement image style in the same request. The
* value is used later, when resolving dependencies.
*
* @var string[]
*
* @see \Drupal\image\Form\ImageStyleDeleteForm::submitForm()
*/
protected $replacement = [];
/**
* {@inheritdoc}
*/
public function setReplacementId($name, $replacement) {
$this->replacement[$name] = $replacement;
}
/**
* {@inheritdoc}
*/
public function getReplacementId($name) {
return isset($this->replacement[$name]) ? $this->replacement[$name] : NULL;
}
/**
* {@inheritdoc}
*/
public function clearReplacementId($name) {
unset($this->replacement[$name]);
}
}

View file

@ -0,0 +1,57 @@
<?php
/**
* @file
* Contains \Drupal\image\ImageStyleStorageInterface.
*/
namespace Drupal\image;
/**
* Interface for storage controller for "image style" configuration entities.
*/
interface ImageStyleStorageInterface {
/**
* Stores a replacement ID for an image style being deleted.
*
* The method stores a replacement style to be used by the configuration
* dependency system when a image style is deleted. The replacement style is
* replacing the deleted style in other configuration entities that are
* depending on the image style being deleted.
*
* @param string $name
* The ID of the image style to be deleted.
* @param string $replacement
* The ID of the image style used as replacement.
*/
public function setReplacementId($name, $replacement);
/**
* Retrieves the replacement ID of a deleted image style.
*
* The method is retrieving the value stored by ::setReplacementId().
*
* @param string $name
* The ID of the image style to be replaced.
*
* @return string|null
* The ID of the image style used as replacement, if there's any, or NULL.
*
* @see \Drupal\image\ImageStyleStorageInterface::setReplacementId()
*/
public function getReplacementId($name);
/**
* Clears a replacement ID from the storage.
*
* The method clears the value previously stored with ::setReplacementId().
*
* @param string $name
* The ID of the image style to be replaced.
*
* @see \Drupal\image\ImageStyleStorageInterface::setReplacementId()
*/
public function clearReplacementId($name);
}

View file

@ -14,6 +14,7 @@ use Drupal\Core\Link;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\image\Entity\ImageStyle;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Cache\Cache;
@ -41,7 +42,7 @@ class ImageFormatter extends ImageFormatterBase implements ContainerFactoryPlugi
/**
* The image style entity storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
* @var \Drupal\image\ImageStyleStorageInterface
*/
protected $imageStyleStorage;
@ -199,9 +200,16 @@ class ImageFormatter extends ImageFormatterBase implements ContainerFactoryPlugi
}
foreach ($files as $delta => $file) {
$cache_contexts = array();
if (isset($link_file)) {
$image_uri = $file->getFileUri();
// @todo Wrap in file_url_transform_relative(). This is currently
// impossible. As a work-around, we currently add the 'url.site' cache
// context to ensure different file URLs are generated for different
// sites in a multisite setup, including HTTP and HTTPS versions of the
// same site. Fix in https://www.drupal.org/node/2646744.
$url = Url::fromUri(file_create_url($image_uri));
$cache_contexts[] = 'url.site';
}
$cache_tags = Cache::mergeTags($cache_tags, $file->getCacheTags());
@ -219,6 +227,7 @@ class ImageFormatter extends ImageFormatterBase implements ContainerFactoryPlugi
'#url' => $url,
'#cache' => array(
'tags' => $cache_tags,
'contexts' => $cache_contexts,
),
);
}
@ -226,4 +235,41 @@ class ImageFormatter extends ImageFormatterBase implements ContainerFactoryPlugi
return $elements;
}
/**
* {@inheritdoc}
*/
public function calculateDependencies() {
$dependencies = parent::calculateDependencies();
$style_id = $this->getSetting('image_style');
/** @var \Drupal\image\ImageStyleInterface $style */
if ($style_id && $style = ImageStyle::load($style_id)) {
// If this formatter uses a valid image style to display the image, add
// the image style configuration entity as dependency of this formatter.
$dependencies[$style->getConfigDependencyKey()][] = $style->getConfigDependencyName();
}
return $dependencies;
}
/**
* {@inheritdoc}
*/
public function onDependencyRemoval(array $dependencies) {
$changed = parent::onDependencyRemoval($dependencies);
$style_id = $this->getSetting('image_style');
/** @var \Drupal\image\ImageStyleInterface $style */
if ($style_id && $style = ImageStyle::load($style_id)) {
if (!empty($dependencies[$style->getConfigDependencyKey()][$style->getConfigDependencyName()])) {
$replacement_id = $this->imageStyleStorage->getReplacementId($style_id);
// If a valid replacement has been provided in the storage, replace the
// image style with the replacement and signal that the formatter plugin
// settings were updated.
if ($replacement_id && ImageStyle::load($replacement_id)) {
$this->setSetting('image_style', $replacement_id);
$changed = TRUE;
}
}
}
return $changed;
}
}

View file

@ -12,6 +12,7 @@ use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Form\FormStateInterface;
use Drupal\file\Entity\File;
use Drupal\file\Plugin\Field\FieldWidget\FileWidget;
use Drupal\image\Entity\ImageStyle;
/**
* Plugin implementation of the 'image_image' widget.
@ -273,4 +274,49 @@ class ImageWidget extends FileWidget {
}
}
/**
* {@inheritdoc}
*/
public function calculateDependencies() {
$dependencies = parent::calculateDependencies();
$style_id = $this->getSetting('preview_image_style');
/** @var \Drupal\image\ImageStyleInterface $style */
if ($style_id && $style = ImageStyle::load($style_id)) {
// If this widget uses a valid image style to display the preview of the
// uploaded image, add that image style configuration entity as dependency
// of this widget.
$dependencies[$style->getConfigDependencyKey()][] = $style->getConfigDependencyName();
}
return $dependencies;
}
/**
* {@inheritdoc}
*/
public function onDependencyRemoval(array $dependencies) {
$changed = parent::onDependencyRemoval($dependencies);
$style_id = $this->getSetting('preview_image_style');
/** @var \Drupal\image\ImageStyleInterface $style */
if ($style_id && $style = ImageStyle::load($style_id)) {
if (!empty($dependencies[$style->getConfigDependencyKey()][$style->getConfigDependencyName()])) {
/** @var \Drupal\image\ImageStyleStorageInterface $storage */
$storage = \Drupal::entityManager()->getStorage($style->getEntityTypeId());
$replacement_id = $storage->getReplacementId($style_id);
// If a valid replacement has been provided in the storage, replace the
// preview image style with the replacement.
if ($replacement_id && ImageStyle::load($replacement_id)) {
$this->setSetting('preview_image_style', $replacement_id);
}
// If there's no replacement or the replacement is invalid, disable the
// image preview.
else {
$this->setSetting('preview_image_style', '');
}
// Signal that the formatter plugin settings were updated.
$changed = TRUE;
}
}
return $changed;
}
}

View file

@ -8,6 +8,7 @@
namespace Drupal\image\Tests;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\image\Entity\ImageStyle;
use Drupal\image\ImageStyleInterface;
use Drupal\node\Entity\Node;
@ -273,6 +274,19 @@ class ImageAdminStylesTest extends ImageFieldTestBase {
$this->assertFalse(ImageStyle::load($style_name), format_string('Image style %style successfully deleted.', array('%style' => $style->label())));
// Test empty text when there are no image styles.
// Delete all image styles.
foreach (ImageStyle::loadMultiple() as $image_style) {
$image_style->delete();
}
// Confirm that the empty text is correct on the image styles page.
$this->drupalGet($admin_path);
$this->assertRaw(t('There are currently no styles. <a href=":url">Add a new one</a>.', [
':url' => \Drupal::url('image.style_add'),
]));
}
/**
@ -307,7 +321,7 @@ class ImageAdminStylesTest extends ImageFieldTestBase {
// Test that image is displayed using newly created style.
$this->drupalGet('node/' . $nid);
$this->assertRaw($style->buildUrl($original_uri), format_string('Image displayed using style @style.', array('@style' => $style_name)));
$this->assertRaw(file_url_transform_relative($style->buildUrl($original_uri)), format_string('Image displayed using style @style.', array('@style' => $style_name)));
// Rename the style and make sure the image field is updated.
$new_style_name = strtolower($this->randomMachineName(10));
@ -322,7 +336,7 @@ class ImageAdminStylesTest extends ImageFieldTestBase {
// Reload the image style using the new name.
$style = ImageStyle::load($new_style_name);
$this->assertRaw($style->buildUrl($original_uri), 'Image displayed using style replacement style.');
$this->assertRaw(file_url_transform_relative($style->buildUrl($original_uri)), 'Image displayed using style replacement style.');
// Delete the style and choose a replacement style.
$edit = array(
@ -334,7 +348,7 @@ class ImageAdminStylesTest extends ImageFieldTestBase {
$replacement_style = ImageStyle::load('thumbnail');
$this->drupalGet('node/' . $nid);
$this->assertRaw($replacement_style->buildUrl($original_uri), 'Image displayed using style replacement style.');
$this->assertRaw(file_url_transform_relative($replacement_style->buildUrl($original_uri)), 'Image displayed using style replacement style.');
}
/**
@ -441,11 +455,16 @@ class ImageAdminStylesTest extends ImageFieldTestBase {
// Test that image is displayed using newly created style.
$this->drupalGet('node/' . $nid);
$this->assertRaw($style->buildUrl($original_uri), format_string('Image displayed using style @style.', array('@style' => $style_name)));
$this->assertRaw(file_url_transform_relative($style->buildUrl($original_uri)), format_string('Image displayed using style @style.', array('@style' => $style_name)));
// Copy config to sync, and delete the image style.
$sync = $this->container->get('config.storage.sync');
$active = $this->container->get('config.storage');
// Remove the image field from the display, to avoid a dependency error
// during import.
EntityViewDisplay::load('node.article.default')
->removeComponent($field_name)
->save();
$this->copyConfig($active, $sync);
$sync->delete('image.style.' . $style_name);
$this->configImporter()->import();

View file

@ -41,7 +41,7 @@ class ImageDimensionsTest extends WebTestBase {
$style = entity_create('image_style', array('name' => 'test', 'label' => 'Test'));
$style->save();
$generated_uri = 'public://styles/test/public/'. \Drupal::service('file_system')->basename($original_uri);
$url = $style->buildUrl($original_uri);
$url = file_url_transform_relative($style->buildUrl($original_uri));
$variables = array(
'#theme' => 'image_style',
@ -70,7 +70,7 @@ class ImageDimensionsTest extends WebTestBase {
$style->save();
$this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="120" height="60" alt="" class="image-style-test" />');
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
$this->drupalGet($url);
$this->drupalGet($this->getAbsoluteUrl($url));
$this->assertResponse(200, 'Image was generated at the URL.');
$this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.');
$image_file = $image_factory->get($generated_uri);
@ -91,7 +91,7 @@ class ImageDimensionsTest extends WebTestBase {
$style->save();
$this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="60" height="120" alt="" class="image-style-test" />');
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
$this->drupalGet($url);
$this->drupalGet($this->getAbsoluteUrl($url));
$this->assertResponse(200, 'Image was generated at the URL.');
$this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.');
$image_file = $image_factory->get($generated_uri);
@ -113,7 +113,7 @@ class ImageDimensionsTest extends WebTestBase {
$style->save();
$this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="45" height="90" alt="" class="image-style-test" />');
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
$this->drupalGet($url);
$this->drupalGet($this->getAbsoluteUrl($url));
$this->assertResponse(200, 'Image was generated at the URL.');
$this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.');
$image_file = $image_factory->get($generated_uri);
@ -135,7 +135,7 @@ class ImageDimensionsTest extends WebTestBase {
$style->save();
$this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="45" height="90" alt="" class="image-style-test" />');
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
$this->drupalGet($url);
$this->drupalGet($this->getAbsoluteUrl($url));
$this->assertResponse(200, 'Image was generated at the URL.');
$this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.');
$image_file = $image_factory->get($generated_uri);
@ -153,7 +153,7 @@ class ImageDimensionsTest extends WebTestBase {
$style->save();
$this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="45" height="90" alt="" class="image-style-test" />');
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
$this->drupalGet($url);
$this->drupalGet($this->getAbsoluteUrl($url));
$this->assertResponse(200, 'Image was generated at the URL.');
$this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.');
$image_file = $image_factory->get($generated_uri);
@ -174,7 +174,7 @@ class ImageDimensionsTest extends WebTestBase {
$style->save();
$this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" alt="" class="image-style-test" />');
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
$this->drupalGet($url);
$this->drupalGet($this->getAbsoluteUrl($url));
$this->assertResponse(200, 'Image was generated at the URL.');
$this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.');
@ -194,7 +194,7 @@ class ImageDimensionsTest extends WebTestBase {
$style->save();
$this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="30" height="30" alt="" class="image-style-test" />');
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
$this->drupalGet($url);
$this->drupalGet($this->getAbsoluteUrl($url));
$this->assertResponse(200, 'Image was generated at the URL.');
$this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.');
$image_file = $image_factory->get($generated_uri);
@ -215,7 +215,7 @@ class ImageDimensionsTest extends WebTestBase {
$style->save();
$this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" alt="" class="image-style-test" />');
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
$this->drupalGet($url);
$this->drupalGet($this->getAbsoluteUrl($url));
$this->assertResponse(200, 'Image was generated at the URL.');
$this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.');
@ -251,10 +251,10 @@ class ImageDimensionsTest extends WebTestBase {
];
// PNG original image. Should be resized to 100x100.
$generated_uri = 'public://styles/test_uri/public/'. \Drupal::service('file_system')->basename($original_uri);
$url = $style->buildUrl($original_uri);
$url = file_url_transform_relative($style->buildUrl($original_uri));
$this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="100" height="100" alt="" class="image-style-test-uri" />');
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
$this->drupalGet($url);
$this->drupalGet($this->getAbsoluteUrl($url));
$this->assertResponse(200, 'Image was generated at the URL.');
$this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.');
$image_file = $image_factory->get($generated_uri);
@ -264,11 +264,11 @@ class ImageDimensionsTest extends WebTestBase {
$file = $files[1];
$original_uri = file_unmanaged_copy($file->uri, 'public://', FILE_EXISTS_RENAME);
$generated_uri = 'public://styles/test_uri/public/'. \Drupal::service('file_system')->basename($original_uri);
$url = $style->buildUrl($original_uri);
$url = file_url_transform_relative($style->buildUrl($original_uri));
$variables['#uri'] = $original_uri;
$this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="50" height="50" alt="" class="image-style-test-uri" />');
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
$this->drupalGet($url);
$this->drupalGet($this->getAbsoluteUrl($url));
$this->assertResponse(200, 'Image was generated at the URL.');
$this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.');
$image_file = $image_factory->get($generated_uri);

View file

@ -127,6 +127,8 @@ class ImageFieldDisplayTest extends ImageFieldTestBase {
$default_output = '<a href="' . file_create_url($image_uri) . '">' . $renderer->renderRoot($image) . '</a>';
$this->drupalGet('node/' . $nid);
$this->assertCacheTag($file->getCacheTags()[0]);
// @todo Remove in https://www.drupal.org/node/2646744.
$this->assertCacheContext('url.site');
$cache_tags_header = $this->drupalGetHeader('X-Drupal-Cache-Tags');
$this->assertTrue(!preg_match('/ image_style\:/', $cache_tags_header), 'No image style cache tag found.');
$this->assertRaw($default_output, 'Image linked to file formatter displaying correctly on full node view.');
@ -165,7 +167,7 @@ class ImageFieldDisplayTest extends ImageFieldTestBase {
'//a[@href=:path]/img[@src=:url and @alt=:alt and @width=:width and @height=:height]',
array(
':path' => $node->url(),
':url' => file_create_url($image['#uri']),
':url' => file_url_transform_relative(file_create_url($image['#uri'])),
':width' => $image['#width'],
':height' => $image['#height'],
':alt' => $alt,
@ -256,7 +258,7 @@ class ImageFieldDisplayTest extends ImageFieldTestBase {
$node = $node_storage->load($nid);
$file = $node->{$field_name}->entity;
$url = file_create_url(ImageStyle::load('medium')->buildUrl($file->getFileUri()));
$url = file_url_transform_relative(file_create_url(ImageStyle::load('medium')->buildUrl($file->getFileUri())));
$this->assertTrue($this->cssSelect('img[width=40][height=20][class=image-style-medium][src="' . $url . '"]'));
// Add alt/title fields to the image and verify that they are displayed.

View file

@ -66,9 +66,11 @@ abstract class ImageFieldTestBase extends WebTestBase {
* @param array $field_settings
* A list of instance settings that will be added to the instance defaults.
* @param array $widget_settings
* A list of widget settings that will be added to the widget defaults.
* Widget settings to be added to the widget defaults.
* @param array $formatter_settings
* Formatter settings to be added to the formatter defaults.
*/
function createImageField($name, $type_name, $storage_settings = array(), $field_settings = array(), $widget_settings = array()) {
function createImageField($name, $type_name, $storage_settings = array(), $field_settings = array(), $widget_settings = array(), $formatter_settings = array()) {
entity_create('field_storage_config', array(
'field_name' => $name,
'entity_type' => 'node',
@ -95,7 +97,10 @@ abstract class ImageFieldTestBase extends WebTestBase {
->save();
entity_get_display('node', $type_name, 'default')
->setComponent($name)
->setComponent($name, array(
'type' => 'image',
'settings' => $formatter_settings,
))
->save();
return $field_config;

View file

@ -0,0 +1,86 @@
<?php
/**
* @file
* Contains \Drupal\image\Tests\ImageStyleDeleteTest.
*/
namespace Drupal\image\Tests;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
/**
* Tests image style deletion using the UI.
*
* @group image
*/
class ImageStyleDeleteTest extends ImageFieldTestBase {
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Create an image field 'foo' having the image style 'medium' as widget
// preview and as formatter.
$this->createImageField('foo', 'page', [], [], ['preview_image_style' => 'medium'], ['image_style' => 'medium']);
}
/**
* Tests image style deletion.
*/
public function testDelete() {
$this->drupalGet('admin/config/media/image-styles/manage/medium/delete');
// Checks that the 'replacement' select element is displayed.
$this->assertFieldByName('replacement');
// Checks that UI messages are correct.
$this->assertRaw(t('If this style is in use on the site, you may select another style to replace it. All images that have been generated for this style will be permanently deleted. If no replacement style is selected, the dependent configurations might need manual reconfiguration.'));
$this->assertNoRaw(t('All images that have been generated for this style will be permanently deleted. The dependent configurations might need manual reconfiguration.'));
// Delete 'medium' image style but replace it with 'thumbnail'. This style
// is involved in 'node.page.default' display view and form.
$this->drupalPostForm(NULL, ['replacement' => 'thumbnail'], t('Delete'));
/** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $view_display */
$view_display = EntityViewDisplay::load('node.page.default');
// Checks that the formatter setting is replaced.
if ($this->assertNotNull($component = $view_display->getComponent('foo'))) {
$this->assertIdentical($component['settings']['image_style'], 'thumbnail');
}
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
$form_display = EntityFormDisplay::load('node.page.default');
// Check that the widget setting is replaced.
if ($this->assertNotNull($component = $form_display->getComponent('foo'))) {
$this->assertIdentical($component['settings']['preview_image_style'], 'thumbnail');
}
$this->drupalGet('admin/config/media/image-styles/manage/thumbnail/delete');
// Checks that the 'replacement' select element is displayed.
$this->assertFieldByName('replacement');
// Checks that UI messages are correct.
$this->assertRaw(t('If this style is in use on the site, you may select another style to replace it. All images that have been generated for this style will be permanently deleted. If no replacement style is selected, the dependent configurations might need manual reconfiguration.'));
$this->assertNoRaw(t('All images that have been generated for this style will be permanently deleted. The dependent configurations might need manual reconfiguration.'));
// Delete 'thumbnail' image style. Provide no replacement.
$this->drupalPostForm(NULL, [], t('Delete'));
$view_display = EntityViewDisplay::load('node.page.default');
// Checks that the formatter setting is disabled.
$this->assertNull($view_display->getComponent('foo'));
$this->assertNotNull($view_display->get('hidden')['foo']);
// Checks that widget setting is preserved with the image preview disabled.
$form_display = EntityFormDisplay::load('node.page.default');
$this->assertNotNull($widget = $form_display->getComponent('foo'));
$this->assertIdentical($widget['settings']['preview_image_style'], '');
// Now, there's only one image style configured on the system: 'large'.
$this->drupalGet('admin/config/media/image-styles/manage/large/delete');
// Checks that the 'replacement' select element is not displayed.
$this->assertNoFieldByName('replacement');
// Checks that UI messages are correct.
$this->assertNoRaw(t('If this style is in use on the site, you may select another style to replace it. All images that have been generated for this style will be permanently deleted. If no replacement style is selected, the dependent configurations might need manual reconfiguration.'));
$this->assertRaw(t('All images that have been generated for this style will be permanently deleted. The dependent configurations might need manual reconfiguration.'));
}
}

View file

@ -74,7 +74,7 @@ class ImageThemeFunctionTest extends WebTestBase {
// Create a style.
$style = entity_create('image_style', array('name' => 'test', 'label' => 'Test'));
$style->save();
$url = $style->buildUrl($original_uri);
$url = file_url_transform_relative($style->buildUrl($original_uri));
// Create a test entity with the image field set.
$entity = entity_create('entity_test');
@ -136,7 +136,7 @@ class ImageThemeFunctionTest extends WebTestBase {
// Create a style.
$style = entity_create('image_style', array('name' => 'image_test', 'label' => 'Test'));
$style->save();
$url = $style->buildUrl($original_uri);
$url = file_url_transform_relative($style->buildUrl($original_uri));
// Create the base element that we'll use in the tests below.
$base_element = array(

View file

@ -0,0 +1,59 @@
<?php
/**
* @file
* Contains \Drupal\image\Tests\Update\ImageUpdateTest.
*/
namespace Drupal\image\Tests\Update;
use Drupal\system\Tests\Update\UpdatePathTestBase;
/**
* Tests Image update path.
*
* @group image
*/
class ImageUpdateTest extends UpdatePathTestBase {
/**
* {@inheritdoc}
*/
protected function setDatabaseDumpFiles() {
$this->databaseDumpFiles = [
__DIR__ . '/../../../../system/tests/fixtures/update/drupal-8-rc1.bare.standard.php.gz',
];
}
/**
* Tests image_post_update_image_style_dependencies().
*
* @see image_post_update_image_style_dependencies()
*/
public function testPostUpdateImageStylesDependencies() {
$view = 'core.entity_view_display.node.article.default';
$form = 'core.entity_form_display.node.article.default';
// Check that view display 'node.article.default' doesn't depend on image
// style 'image.style.large'.
$dependencies = $this->config($view)->get('dependencies.config');
$this->assertFalse(in_array('image.style.large', $dependencies));
// Check that form display 'node.article.default' doesn't depend on image
// style 'image.style.thumbnail'.
$dependencies = $this->config($form)->get('dependencies.config');
$this->assertFalse(in_array('image.style.thumbnail', $dependencies));
// Run updates.
$this->runUpdates();
// Check that view display 'node.article.default' depend on image style
// 'image.style.large'.
$dependencies = $this->config($view)->get('dependencies.config');
$this->assertTrue(in_array('image.style.large', $dependencies));
// Check that form display 'node.article.default' depend on image style
// 'image.style.thumbnail'.
$dependencies = $this->config($view)->get('dependencies.config');
$this->assertTrue(in_array('image.style.large', $dependencies));
}
}