diff --git a/core/includes/image.inc b/core/includes/image.inc
index 9e2d06f..447500e 100644
--- a/core/includes/image.inc
+++ b/core/includes/image.inc
@@ -5,8 +5,7 @@
* API for manipulating images.
*/
-use Drupal\system\Plugin\ImageToolkitInterface;
-use Drupal\Component\Image\Image;
+use Drupal\Core\Image\ImageFile;
/**
* @defgroup image Image toolkits
@@ -44,8 +43,6 @@
*
* @param string $filepath
* String specifying the path of the image file.
- * @param \Drupal\system\Plugin\ImageToolkitInterface $toolkit
- * (optional) An image toolkit object to override the default.
*
* @return array
* FALSE, if the file could not be found or is not an image. Otherwise, a
@@ -55,276 +52,13 @@
* - "extension": Commonly used file extension for the image.
* - "mime_type": MIME type ('image/jpeg', 'image/gif', 'image/png').
* - "file_size": File size in bytes.
- */
-function image_get_info($filepath, ImageToolkitInterface $toolkit = NULL) {
- $details = FALSE;
- if (!is_file($filepath) && !is_uploaded_file($filepath)) {
- return $details;
- }
-
- if ($toolkit === NULL) {
- $toolkit = Drupal::service('image.toolkit');
- }
- if ($toolkit) {
- $image = new stdClass();
- $image->source = $filepath;
- $image->toolkit = $toolkit;
- $details = $toolkit->getInfo($image);
- if (isset($details) && is_array($details)) {
- $details['file_size'] = filesize($filepath);
- }
- }
-
- return $details;
-}
-
-/**
- * Scales an image to the exact width and height given.
- *
- * This function achieves the target aspect ratio by cropping the original image
- * equally on both sides, or equally on the top and bottom. This function is
- * useful to create uniform sized avatars from larger images.
- *
- * The resulting image always has the exact target dimensions.
- *
- * @param object $image
- * An image object returned by image_load().
- * @param int $width
- * The target width, in pixels.
- * @param int $height
- * The target height, in pixels.
- *
- * @return bool
- * TRUE on success, FALSE on failure.
- *
- * @see image_load()
- * @see image_resize()
- * @see image_crop()
- */
-function image_scale_and_crop($image, $width, $height) {
- $scale = max($width / $image->info['width'], $height / $image->info['height']);
- $x = ($image->info['width'] * $scale - $width) / 2;
- $y = ($image->info['height'] * $scale - $height) / 2;
-
- if (image_resize($image, $image->info['width'] * $scale, $image->info['height'] * $scale)) {
- return image_crop($image, $x, $y, $width, $height);
- }
- return FALSE;
-}
-
-/**
- * Scales image dimensions while maintaining aspect ratio.
*
* @deprecated as of Drupal 8.0. Use
- * \Drupal\Component\Image\Image::scaleDimensions() directly instead.
- *
- * @see image_scale()
+ * \Drupal\Core\Image\ImageFile::getFileInfo().
*/
-function image_dimensions_scale(array &$dimensions, $width = NULL, $height = NULL, $upscale = FALSE) {
- return Image::scaleDimensions($dimensions, $width, $height, $upscale);
-}
-
-/**
- * Scales an image while maintaining aspect ratio.
- *
- * The resulting image can be smaller for one or both target dimensions.
- *
- * @param object $image
- * An image object returned by image_load().
- * @param int $width
- * (optional) The target width, in pixels. This value is omitted then the
- * scaling will based only on the height value.
- * @param int $height
- * (optional) The target height, in pixels. This value is omitted then the
- * scaling will based only on the width value.
- * @param bool $upscale
- * (optional) Boolean indicating that files smaller than the dimensions will
- * be scaled up. This generally results in a low quality image.
- *
- * @return bool
- * TRUE on success, FALSE on failure.
- *
- * @see image_dimensions_scale()
- * @see image_load()
- * @see image_scale_and_crop()
- */
-function image_scale($image, $width = NULL, $height = NULL, $upscale = FALSE) {
- $dimensions = $image->info;
-
- // Scale the dimensions - if they don't change then just return success.
- if (!image_dimensions_scale($dimensions, $width, $height, $upscale)) {
- return TRUE;
- }
-
- return image_resize($image, $dimensions['width'], $dimensions['height']);
-}
-
-/**
- * Resizes an image to the given dimensions (ignoring aspect ratio).
- *
- * @param object $image
- * An image object returned by image_load().
- * @param int $width
- * The target width, in pixels.
- * @param int $height
- * The target height, in pixels.
- *
- * @return bool
- * TRUE on success, FALSE on failure.
- *
- * @see image_load()
- * @see \Drupal\system\Plugin\ImageToolkitInterface::resize()
- */
-function image_resize($image, $width, $height) {
- $width = (int) round($width);
- $height = (int) round($height);
-
- return $image->toolkit->resize($image, $width, $height);
-}
-
-/**
- * Rotates an image by the given number of degrees.
- *
- * @param $image
- * An image object returned by image_load().
- * @param int $degrees
- * The number of (clockwise) degrees to rotate the image.
- * @param string $background
- * (optional) An hexadecimal integer specifying the background color to use
- * for the uncovered area of the image after the rotation. E.g. 0x000000 for
- * black, 0xff00ff for magenta, and 0xffffff for white. For images that
- * support transparency, this will default to transparent. Otherwise it will
- * be white.
- *
- * @return bool
- * TRUE on success, FALSE on failure.
- *
- * @see image_load()
- * @see \Drupal\system\Plugin\ImageToolkitInterface::rotate()
- */
-function image_rotate($image, $degrees, $background = NULL) {
- return $image->toolkit->rotate($image, $degrees, $background);
-}
-
-/**
- * Crops an image to a rectangle specified by the given dimensions.
- *
- * @param $image
- * An image object returned by image_load().
- * @param int $x
- * The top left coordinate, in pixels, of the crop area (x axis value).
- * @param int $y
- * The top left coordinate, in pixels, of the crop area (y axis value).
- * @param int $width
- * The target width, in pixels.
- * @param int $height
- * The target height, in pixels.
- *
- * @return bool
- * TRUE on success, FALSE on failure.
- *
- * @see image_load()
- * @see image_scale_and_crop()
- * @see \Drupal\system\Plugin\ImageToolkitInterface::crop()
- */
-function image_crop($image, $x, $y, $width, $height) {
- $aspect = $image->info['height'] / $image->info['width'];
- if (empty($height)) $height = $width / $aspect;
- if (empty($width)) $width = $height * $aspect;
-
- $width = (int) round($width);
- $height = (int) round($height);
-
- return $image->toolkit->crop($image, $x, $y, $width, $height);
-}
-
-/**
- * Converts an image to grayscale.
- *
- * @param $image
- * An image object returned by image_load().
- *
- * @return bool
- * TRUE on success, FALSE on failure.
- *
- * @see image_load()
- * @see \Drupal\system\Plugin\ImageToolkitInterface::desaturate()
- */
-function image_desaturate($image) {
- return $image->toolkit->desaturate($image);
-}
-
-/**
- * Loads an image file and returns an image object.
- *
- * Any changes to the file are not saved until image_save() is called.
- *
- * @param string $file
- * Path to an image file.
- * @param \Drupal\system\Plugin\ImageToolkitInterface $toolkit
- * (optional) Image toolkit object to override the default.
- *
- * @return object
- * An image object or FALSE if there was a problem loading the file. The
- * image object has the following properties:
- * - 'source' - The original file path.
- * - 'info' - The array of information returned by image_get_info()
- * - 'toolkit' - The name of the image toolkit requested when the image was
- * loaded.
- * Image toolkits may add additional properties. The caller is advised not to
- * monkey about with them.
- *
- * @see image_save()
- * @see image_get_info()
- */
-function image_load($file, ImageToolkitInterface $toolkit = NULL) {
- if ($toolkit === NULL) {
- $toolkit = Drupal::service('image.toolkit');
- }
- if ($toolkit) {
- $image = new stdClass();
- $image->source = $file;
- $image->info = image_get_info($file, $toolkit);
- if (isset($image->info) && is_array($image->info)) {
- $image->toolkit = $toolkit;
- if ($toolkit->load($image)) {
- return $image;
- }
- }
- }
- return FALSE;
-}
-
-/**
- * Closes the image and saves the changes to a file.
- *
- * @param object $image
- * An image object returned by image_load(). The object's 'info' property
- * will be updated if the file is saved successfully.
- * @param $destination
- * (optional) Destination path where the image should be saved. If it is empty
- * the original image file will be overwritten.
- *
- * @return bool
- * TRUE on success, FALSE on failure.
- *
- * @see image_load()
- * @see \Drupal\system\Plugin\ImageToolkitInterface::save()
- */
-function image_save($image, $destination = NULL) {
- if (empty($destination)) {
- $destination = $image->source;
- }
- if ($return = $image->toolkit->save($image, $destination)) {
- // Clear the cached file size and refresh the image information.
- clearstatcache(TRUE, $destination);
- $image->info = image_get_info($destination, $image->toolkit);
-
- if (drupal_chmod($destination)) {
- return $return;
- }
- }
- return FALSE;
+function image_get_info($filepath) {
+ $image = new ImageFile($filepath);
+ return $image->getFileInfo();
}
/**
diff --git a/core/lib/Drupal/Core/Image/ImageFile.php b/core/lib/Drupal/Core/Image/ImageFile.php
new file mode 100644
index 0000000..3e914f5
--- /dev/null
+++ b/core/lib/Drupal/Core/Image/ImageFile.php
@@ -0,0 +1,439 @@
+source = $source;
+ }
+
+ /**
+ * Sets a value for a given key.
+ *
+ * @param string $key
+ * The key to set the value for.
+ * @param mixed $value
+ * The value to set for this key.
+ *
+ * @return self
+ * Returns this image file.
+ */
+ public function set($key, $value) {
+ $this->info[$key] = $value;
+ return $this;
+ }
+
+ /**
+ * Replaces the file info.
+ *
+ * @param array $info
+ * Information about this file.
+ *
+ * @return self
+ * Returns this image file.
+ */
+ public function setInfo(array $info) {
+ $this->info = $info;
+ return $this;
+ }
+
+ /**
+ * Retrieves specific information about this image file.
+ *
+ * @param string $key
+ * The key of the info to retrieve, e.g., 'height', 'width', 'extension',
+ * 'mime_type', 'file_size'.
+ *
+ * @return mixed|null
+ * The value requested, or NULL.
+ */
+ public function get($key) {
+ $info = $this->getInfo();
+ if (isset($info[$key])) {
+ return $info[$key];
+ }
+ return NULL;
+ }
+
+ /**
+ * Retrives all information about this image file.
+ *
+ * @return array
+ * An associative array of image file information.
+ */
+ public function getInfo() {
+ if (!$this->info) {
+ $this->processInfo();
+ }
+ return $this->info;
+ }
+
+ /**
+ * Sets the image file resource.
+ *
+ * @param resource $resource
+ * The image file handle.
+ *
+ * @return self
+ * Returns this image file.
+ */
+ public function setResource($resource) {
+ $this->resource = $resource;
+ return $this;
+ }
+
+ /**
+ * Determines if this image file has a resource set.
+ *
+ * @return bool
+ * TRUE if this image file has a resource set, FALSE otherwise.
+ */
+ public function hasResource() {
+ return (bool) $this->resource;
+ }
+
+ /**
+ * Retrieves the image file resource.
+ *
+ * @return resource
+ * The image file handle.
+ */
+ public function getResource() {
+ if (!$this->hasResource()) {
+ $this->processInfo();
+ $this->getToolkit()->load($this);
+ }
+ return $this->resource;
+ }
+
+ /**
+ * Sets the source path of the image file.
+ *
+ * @param string $source
+ * A string specifying the path of the image file.
+ *
+ * @return self
+ * Returns this image file.
+ */
+ public function setSource($source) {
+ $this->source = $source;
+ return $this;
+ }
+
+ /**
+ * Retrieves the source path of the image file.
+ *
+ * @return string
+ * The source path of the image file.
+ */
+ public function getSource() {
+ return $this->source;
+ }
+
+ /**
+ * Sets a custom image toolkit.
+ *
+ * @param \Drupal\system\Plugin\ImageToolkitInterface $toolkit
+ * The image toolkit to use for this image file.
+ *
+ * @return self
+ * Returns this image file.
+ */
+ public function setToolkit(ImageToolkitInterface $toolkit) {
+ $this->toolkit = $toolkit;
+ return $this;
+ }
+
+ /**
+ * Returns the image toolkit being used for this image file.
+ *
+ * If a custom toolkit was not specified, this will fallback to the default.
+ *
+ * @return \Drupal\system\Plugin\ImageToolkitInterface
+ * The image toolkit used for this image file.
+ */
+ protected function getToolkit() {
+ if (!$this->toolkit) {
+ $this->toolkit = \Drupal::service('image.toolkit');
+ }
+ return $this->toolkit;
+ }
+
+ /**
+ * Returns the ID of the image toolkit used for this image file.
+ *
+ * @return string
+ * The ID of the image toolkit.
+ */
+ public function getToolkitId() {
+ return $this->getToolkit()->getPluginId();
+ }
+
+ /**
+ * Gets details about an image.
+ *
+ * Drupal supports GIF, JPG and PNG file formats when used with the GD
+ * toolkit, and may support others, depending on which toolkits are
+ * installed.
+ *
+ * @return array|bool
+ * FALSE, if the file could not be found or is not an image. Otherwise, a
+ * keyed array containing information about the image:
+ * - "width": Width, in pixels.
+ * - "height": Height, in pixels.
+ * - "extension": Commonly used file extension for the image.
+ * - "mime_type": MIME type ('image/jpeg', 'image/gif', 'image/png').
+ * - "file_size": File size in bytes.
+ */
+ public function getFileInfo() {
+ if ($this->processInfo()) {
+ return $this->getInfo();
+ }
+ return FALSE;
+ }
+
+ /**
+ * Closes the image and saves the changes to a file.
+ *
+ * @param string|null $destination
+ * (optional) Destination path where the image should be saved. If it is empty
+ * the original image file will be overwritten.
+ *
+ * @return bool
+ * TRUE on success, FALSE on failure.
+ *
+ * @see \Drupal\system\Plugin\ImageToolkitInterface::save()
+ */
+ public function save($destination = NULL) {
+ if (empty($destination)) {
+ $destination = $this->getSource();
+ }
+ if ($return = $this->getToolkit()->save($this, $destination)) {
+ // Clear the cached file size and refresh the image information.
+ clearstatcache(TRUE, $destination);
+ $this->setSource($destination);
+ $this->processInfo();
+
+ if (drupal_chmod($destination)) {
+ return $return;
+ }
+ }
+ return FALSE;
+ }
+
+ /**
+ * Prepares the image information.
+ *
+ * @return bool
+ * FALSE, if the file could not be found or is not an image. Otherwise, the
+ * image information is populated.
+ */
+ protected function processInfo() {
+ $destination = $this->getSource();
+ if (!is_file($destination) && !is_uploaded_file($destination)) {
+ return FALSE;
+ }
+
+ if ($details = $this->getToolkit()->getInfo($this)) {
+ $details['file_size'] = filesize($destination);
+ $this->setInfo($details);
+ }
+ return TRUE;
+ }
+
+ /**
+ * Scales an image while maintaining aspect ratio.
+ *
+ * The resulting image can be smaller for one or both target dimensions.
+ *
+ * @param int $width
+ * (optional) The target width, in pixels. This value is omitted then the
+ * scaling will based only on the height value.
+ * @param int $height
+ * (optional) The target height, in pixels. This value is omitted then the
+ * scaling will based only on the width value.
+ * @param bool $upscale
+ * (optional) Boolean indicating that files smaller than the dimensions will
+ * be scaled up. This generally results in a low quality image.
+ *
+ * @return bool
+ * TRUE on success, FALSE on failure.
+ */
+ public function scale($width = NULL, $height = NULL, $upscale = FALSE) {
+ $dimensions = $this->getInfo();
+
+ // Scale the dimensions - if they don't change then just return success.
+ if (!Image::scaleDimensions($dimensions, $width, $height, $upscale)) {
+ return TRUE;
+ }
+
+ return $this->resize($dimensions['width'], $dimensions['height']);
+
+ }
+
+ /**
+ * Scales an image to the exact width and height given.
+ *
+ * This function achieves the target aspect ratio by cropping the original image
+ * equally on both sides, or equally on the top and bottom. This function is
+ * useful to create uniform sized avatars from larger images.
+ *
+ * The resulting image always has the exact target dimensions.
+ *
+ * @param int $width
+ * The target width, in pixels.
+ * @param int $height
+ * The target height, in pixels.
+ *
+ * @return bool
+ * TRUE on success, FALSE on failure.
+ */
+ public function scaleAndCrop($width, $height) {
+ $scale = max($width / $this->get('width'), $height / $this->get('height'));
+ $x = ($this->get('width') * $scale - $width) / 2;
+ $y = ($this->get('height') * $scale - $height) / 2;
+
+ if ($this->resize($this->get('width') * $scale, $this->get('height') * $scale)) {
+ return $this->crop($x, $y, $width, $height);
+ }
+ return FALSE;
+ }
+
+ /**
+ * Crops an image to a rectangle specified by the given dimensions.
+ *
+ * @param int $x
+ * The top left coordinate, in pixels, of the crop area (x axis value).
+ * @param int $y
+ * The top left coordinate, in pixels, of the crop area (y axis value).
+ * @param int $width
+ * The target width, in pixels.
+ * @param int $height
+ * The target height, in pixels.
+ *
+ * @return bool
+ * TRUE on success, FALSE on failure.
+ *
+ * @see \Drupal\system\Plugin\ImageToolkitInterface::crop()
+ */
+ function crop($x, $y, $width, $height) {
+ $aspect = $this->get('height') / $this->get('width');
+ if (empty($height)) $height = $width / $aspect;
+ if (empty($width)) $width = $height * $aspect;
+
+ $width = (int) round($width);
+ $height = (int) round($height);
+
+ return $this->getToolkit()->crop($this, $x, $y, $width, $height);
+ }
+
+ /**
+ * Resizes an image to the given dimensions (ignoring aspect ratio).
+ *
+ * @param int $width
+ * The target width, in pixels.
+ * @param int $height
+ * The target height, in pixels.
+ *
+ * @return bool
+ * TRUE on success, FALSE on failure.
+ *
+ * @see \Drupal\system\Plugin\ImageToolkitInterface::resize()
+ */
+ public function resize($width, $height) {
+ $width = (int) round($width);
+ $height = (int) round($height);
+
+ return $this->getToolkit()->resize($this, $width, $height);
+ }
+
+ /**
+ * Converts an image to grayscale.
+ *
+ * @return bool
+ * TRUE on success, FALSE on failure.
+ *
+ * @see \Drupal\system\Plugin\ImageToolkitInterface::desaturate()
+ */
+ public function desaturate() {
+ return $this->getToolkit()->desaturate($this);
+ }
+
+ /**
+ * Rotates an image by the given number of degrees.
+ *
+ * @param int $degrees
+ * The number of (clockwise) degrees to rotate the image.
+ * @param string $background
+ * (optional) An hexadecimal integer specifying the background color to use
+ * for the uncovered area of the image after the rotation. E.g. 0x000000 for
+ * black, 0xff00ff for magenta, and 0xffffff for white. For images that
+ * support transparency, this will default to transparent. Otherwise it will
+ * be white.
+ *
+ * @return bool
+ * TRUE on success, FALSE on failure.
+ *
+ * @see \Drupal\system\Plugin\ImageToolkitInterface::rotate()
+ */
+ public function rotate($degrees, $background = NULL) {
+ return $this->getToolkit()->rotate($this, $degrees, $background);
+ }
+
+}
diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index bcdb460..bbd5e11 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -5,11 +5,11 @@
* Defines a "managed_file" Form API field and a "file" field for Field module.
*/
+use Drupal\Core\Image\ImageFile;
use Drupal\file\Plugin\Core\Entity\File;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Template\Attribute;
use Symfony\Component\HttpFoundation\JsonResponse;
-use Drupal\file\FileUsage\DatabaseFileUsageBackend;
use Drupal\file\FileUsage\FileUsageInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
@@ -462,10 +462,11 @@ function file_validate_image_resolution(File $file, $maximum_dimensions = 0, $mi
list($width, $height) = explode('x', $maximum_dimensions);
if ($info['width'] > $width || $info['height'] > $height) {
// Try to resize the image to fit the dimensions.
- if ($image = image_load($file->getFileUri())) {
- image_scale($image, $width, $height);
- image_save($image);
- $file->filesize = $image->info['file_size'];
+ $image = new ImageFile($file->getFileUri());
+ if ($image->getResource()) {
+ $image->scale($width, $height);
+ $image->save();
+ $file->filesize = $image->get('file_size');
drupal_set_message(t('The image was resized to fit within the maximum allowed dimensions of %dimensions pixels.', array('%dimensions' => $maximum_dimensions)));
}
else {
diff --git a/core/modules/image/image.admin.inc b/core/modules/image/image.admin.inc
index 5111177..b15258f 100644
--- a/core/modules/image/image.admin.inc
+++ b/core/modules/image/image.admin.inc
@@ -7,7 +7,6 @@
use Drupal\Component\Utility\String;
use Drupal\image\ImageStyleInterface;
-use Symfony\Component\HttpFoundation\RedirectResponse;
/**
* Menu callback; Listing of all current image styles.
@@ -365,7 +364,7 @@ function theme_image_style_effects($variables) {
*
* @param $variables
* An associative array containing:
- * - style: \Drupal\image\ImageStyleInterface image style being previewed.
+ * - style: The image style array being previewed.
*
* @ingroup themeable
*/
@@ -391,9 +390,9 @@ function theme_image_style_preview($variables) {
$original_attributes['style'] = 'width: ' . $original_width . 'px; height: ' . $original_height . 'px;';
// Set up preview file information.
- $preview_file = $style->buildUri($original_path);
+ $preview_file = image_style_path($style->id(), $original_path);
if (!file_exists($preview_file)) {
- $style->createDerivative($original_path, $preview_file);
+ image_style_create_derivative($style, $original_path, $preview_file);
}
$preview_image = image_get_info($preview_file);
if ($preview_image['width'] > $preview_image['height']) {
diff --git a/core/modules/image/image.api.php b/core/modules/image/image.api.php
index 2909507..471f9fa 100644
--- a/core/modules/image/image.api.php
+++ b/core/modules/image/image.api.php
@@ -32,8 +32,8 @@ function hook_image_effect_info_alter(&$effects) {
* be cleared using this hook. This hook is called whenever a style is updated,
* deleted, or any effect associated with the style is update or deleted.
*
- * @param \Drupal\image\ImageStyleInterface $style
- * The image style object that is being flushed.
+ * @param Drupal\image\Plugin\Core\Entity\ImageStyle $style
+ * The image style array that is being flushed.
*/
function hook_image_style_flush($style) {
// Empty cached data that contains information about the style.
diff --git a/core/modules/image/image.install b/core/modules/image/image.install
index 1617e8c..58cf110 100644
--- a/core/modules/image/image.install
+++ b/core/modules/image/image.install
@@ -6,7 +6,6 @@
*/
use Drupal\Component\Uuid\Uuid;
-use Drupal\field\Plugin\Core\Entity\Field;
/**
* Implements hook_install().
diff --git a/core/modules/image/image.module b/core/modules/image/image.module
index 71bc42c..5387cc5 100644
--- a/core/modules/image/image.module
+++ b/core/modules/image/image.module
@@ -6,17 +6,14 @@
*/
use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Language\Language;
+use Drupal\Core\Image\ImageFile;
use Drupal\field\Plugin\Core\Entity\Field;
use Drupal\field\Plugin\Core\Entity\FieldInstance;
-use Drupal\image\ImageEffectInterface;
-use Drupal\image\ImageStyleInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
use Drupal\Component\Utility\Crypt;
-use Drupal\Component\Uuid\Uuid;
use Drupal\file\Plugin\Core\Entity\File;
use Drupal\image\Plugin\Core\Entity\ImageStyle;
use Drupal\field\FieldInterface;
@@ -361,7 +358,10 @@ function image_file_predelete(File $file) {
function image_path_flush($path) {
$styles = entity_load_multiple('image_style');
foreach ($styles as $style) {
- $style->flush($path);
+ $image_path = image_style_path($style->id(), $path);
+ if (file_exists($image_path)) {
+ file_unmanaged_delete($image_path);
+ }
}
}
@@ -405,16 +405,263 @@ function image_style_options($include_empty = TRUE) {
* After generating an image, transfer it to the requesting agent.
*
* @param $style
- * The image style.
- *
- * @todo: Remove this wrapper in https://drupal.org/node/1987712.
+ * The image style
*/
function image_style_deliver($style, $scheme) {
$args = func_get_args();
array_shift($args);
array_shift($args);
$target = implode('/', $args);
- return $style->deliver($scheme, $target);
+
+ // Check that the style is defined, the scheme is valid, and the image
+ // derivative token is valid. (Sites which require image derivatives to be
+ // generated without a token can set the
+ // 'image.settings:allow_insecure_derivatives' configuration to TRUE to bypass
+ // the latter check, but this will increase the site's vulnerability to
+ // denial-of-service attacks.)
+ $valid = !empty($style) && file_stream_wrapper_valid_scheme($scheme);
+ if (!config('image.settings')->get('allow_insecure_derivatives')) {
+ $image_derivative_token = Drupal::request()->query->get(IMAGE_DERIVATIVE_TOKEN);
+ $valid = $valid && isset($image_derivative_token) && $image_derivative_token === image_style_path_token($style->name, $scheme . '://' . $target);
+ }
+ if (!$valid) {
+ throw new AccessDeniedHttpException();
+ }
+
+ $image_uri = $scheme . '://' . $target;
+ $derivative_uri = image_style_path($style->id(), $image_uri);
+
+ // If using the private scheme, let other modules provide headers and
+ // control access to the file.
+ if ($scheme == 'private') {
+ if (file_exists($derivative_uri)) {
+ file_download($scheme, file_uri_target($derivative_uri));
+ }
+ else {
+ $headers = module_invoke_all('file_download', $image_uri);
+ if (in_array(-1, $headers) || empty($headers)) {
+ throw new AccessDeniedHttpException();
+ }
+ if (count($headers)) {
+ foreach ($headers as $name => $value) {
+ drupal_add_http_header($name, $value);
+ }
+ }
+ }
+ }
+
+ // Don't try to generate file if source is missing.
+ if (!file_exists($image_uri)) {
+ watchdog('image', 'Source image at %source_image_path not found while trying to generate derivative image at %derivative_path.', array('%source_image_path' => $image_uri, '%derivative_path' => $derivative_uri));
+ return new Response(t('Error generating image, missing source file.'), 404);
+ }
+
+ // Don't start generating the image if the derivative already exists or if
+ // generation is in progress in another thread.
+ $lock_name = 'image_style_deliver:' . $style->id() . ':' . Crypt::hashBase64($image_uri);
+ if (!file_exists($derivative_uri)) {
+ $lock_acquired = lock()->acquire($lock_name);
+ if (!$lock_acquired) {
+ // Tell client to retry again in 3 seconds. Currently no browsers are known
+ // to support Retry-After.
+ throw new ServiceUnavailableHttpException(3, t('Image generation in progress. Try again shortly.'));
+ }
+ }
+
+ // Try to generate the image, unless another thread just did it while we were
+ // acquiring the lock.
+ $success = file_exists($derivative_uri) || image_style_create_derivative($style, $image_uri, $derivative_uri);
+
+ if (!empty($lock_acquired)) {
+ lock()->release($lock_name);
+ }
+
+ if ($success) {
+ $image = new ImageFile($derivative_uri);
+ $uri = $image->getSource();
+ $headers = array(
+ 'Content-Type' => $image->get('mime_type'),
+ 'Content-Length' => $image->get('file_size'),
+ );
+ return new BinaryFileResponse($uri, 200, $headers);
+ }
+ else {
+ watchdog('image', 'Unable to generate the derived image located at %path.', array('%path' => $derivative_uri));
+ return new Response(t('Error generating image.'), 500);
+ }
+}
+
+/**
+ * Creates a new image derivative based on an image style.
+ *
+ * Generates an image derivative by creating the destination folder (if it does
+ * not already exist), applying all image effects defined in
+ * $style->getEffects(), and saving a cached version of the resulting image.
+ *
+ * @param $style
+ * An image style array.
+ * @param $source
+ * Path of the source file.
+ * @param $destination
+ * Path or URI of the destination file.
+ *
+ * @return
+ * TRUE if an image derivative was generated, or FALSE if the image derivative
+ * could not be generated.
+ *
+ * @see image_style_load()
+ */
+function image_style_create_derivative($style, $source, $destination) {
+ // Get the folder for the final location of this style.
+ $directory = drupal_dirname($destination);
+
+ // Build the destination folder tree if it doesn't already exist.
+ if (!file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
+ watchdog('image', 'Failed to create style directory: %directory', array('%directory' => $directory), WATCHDOG_ERROR);
+ return FALSE;
+ }
+
+ $image = new ImageFile($source);
+ if (!$image->getResource()) {
+ return FALSE;
+ }
+
+ foreach ($style->getEffects() as $effect) {
+ $effect->processEffect($image);
+ }
+
+ if (!$image->save($destination)) {
+ if (file_exists($destination)) {
+ watchdog('image', 'Cached image file %destination already exists. There may be an issue with your rewrite configuration.', array('%destination' => $destination), WATCHDOG_ERROR);
+ }
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * Determines the dimensions of the styled image.
+ *
+ * Applies all of an image style's effects to $dimensions.
+ *
+ * @param $style_name
+ * The name of the style to be applied.
+ * @param $dimensions
+ * Dimensions to be modified - an array with components width and height, in
+ * pixels.
+ */
+function image_style_transform_dimensions($style_name, array &$dimensions) {
+ $style = entity_load('image_style', $style_name);
+
+ foreach ($style->getEffects() as $effect) {
+ $effect->processDimensions($dimensions);
+ }
+}
+
+/**
+ * Returns the URL for an image derivative given a style and image path.
+ *
+ * @param $style_name
+ * The name of the style to be used with this image.
+ * @param $path
+ * The path to the image.
+ * @param $clean_urls
+ * (optional) Whether clean URLs are in use.
+ * @return
+ * The absolute URL where a style image can be downloaded, suitable for use
+ * in an tag. Requesting the URL will cause the image to be created.
+ * @see image_style_deliver()
+ */
+function image_style_url($style_name, $path, $clean_urls = NULL) {
+ $uri = image_style_path($style_name, $path);
+ // The token query is added even if the
+ // 'image.settings:allow_insecure_derivatives' configuration is TRUE, so that
+ // the emitted links remain valid if it is changed back to the default FALSE.
+ // However, sites which need to prevent the token query from being emitted at
+ // all can additionally set the 'image.settings:suppress_itok_output'
+ // configuration to TRUE to achieve that (if both are set, the security token
+ // will neither be emitted in the image derivative URL nor checked for in
+ // image_style_deliver()).
+ $token_query = array();
+ if (!config('image.settings')->get('suppress_itok_output')) {
+ $token_query = array(IMAGE_DERIVATIVE_TOKEN => image_style_path_token($style_name, file_stream_wrapper_uri_normalize($path)));
+ }
+
+ if ($clean_urls === NULL) {
+ // Assume clean URLs unless the request tells us otherwise.
+ $clean_urls = TRUE;
+ try {
+ $request = Drupal::request();
+ $clean_urls = $request->attributes->get('clean_urls');
+ }
+ catch (ServiceNotFoundException $e) {
+ }
+ }
+
+ // If not using clean URLs, the image derivative callback is only available
+ // with the script path. If the file does not exist, use url() to ensure
+ // that it is included. Once the file exists it's fine to fall back to the
+ // actual file path, this avoids bootstrapping PHP once the files are built.
+ if ($clean_urls === FALSE && file_uri_scheme($uri) == 'public' && !file_exists($uri)) {
+ $directory_path = file_stream_wrapper_get_instance_by_uri($uri)->getDirectoryPath();
+ return url($directory_path . '/' . file_uri_target($uri), array('absolute' => TRUE, 'query' => $token_query));
+ }
+
+ $file_url = file_create_url($uri);
+ // Append the query string with the token, if necessary.
+ if ($token_query) {
+ $file_url .= (strpos($file_url, '?') !== FALSE ? '&' : '?') . drupal_http_build_query($token_query);
+ }
+
+ return $file_url;
+}
+
+/**
+ * Generates a token to protect an image style derivative.
+ *
+ * This prevents unauthorized generation of an image style derivative,
+ * which can be costly both in CPU time and disk space.
+ *
+ * @param string $style_name
+ * The name of the image style.
+ * @param string $uri
+ * The URI of the image for this style, for example as returned by
+ * image_style_path().
+ *
+ * @return string
+ * An eight-character token which can be used to protect image style
+ * derivatives against denial-of-service attacks.
+ */
+function image_style_path_token($style_name, $uri) {
+ // Return the first eight characters.
+ return substr(Crypt::hmacBase64($style_name . ':' . $uri, drupal_get_private_key() . drupal_get_hash_salt()), 0, 8);
+}
+
+/**
+ * Returns the URI of an image when using a style.
+ *
+ * The path returned by this function may not exist. The default generation
+ * method only creates images when they are requested by a user's browser.
+ *
+ * @param $style_name
+ * The name of the style to be used with this image.
+ * @param $uri
+ * The URI or path to the image.
+ * @return
+ * The URI to an image style image.
+ * @see image_style_url()
+ */
+function image_style_path($style_name, $uri) {
+ $scheme = file_uri_scheme($uri);
+ if ($scheme) {
+ $path = file_uri_target($uri);
+ }
+ else {
+ $path = $uri;
+ $scheme = file_default_scheme();
+ }
+ return $scheme . '://styles/' . $style_name . '/' . $scheme . '/' . $path;
}
/**
@@ -438,15 +685,13 @@ function image_style_deliver($style, $scheme) {
* @ingroup themeable
*/
function theme_image_style($variables) {
- $style = entity_load('image_style', $variables['style_name']);
-
// Determine the dimensions of the styled image.
$dimensions = array(
'width' => $variables['width'],
'height' => $variables['height'],
);
- $style->transformDimensions($dimensions);
+ image_style_transform_dimensions($variables['style_name'], $dimensions);
// Add in the image style name as an HTML class.
$variables['attributes']['class'][] = 'image-style-' . drupal_html_class($variables['style_name']);
@@ -456,7 +701,7 @@ function theme_image_style($variables) {
'#width' => $dimensions['width'],
'#height' => $dimensions['height'],
'#attributes' => $variables['attributes'],
- '#uri' => $style->buildUrl($variables['uri']),
+ '#uri' => image_style_url($variables['style_name'], $variables['uri']),
);
if (isset($variables['alt'])) {
diff --git a/core/modules/image/lib/Drupal/image/ImageEffectInterface.php b/core/modules/image/lib/Drupal/image/ImageEffectInterface.php
index 2c13129..a9ee455 100644
--- a/core/modules/image/lib/Drupal/image/ImageEffectInterface.php
+++ b/core/modules/image/lib/Drupal/image/ImageEffectInterface.php
@@ -8,6 +8,7 @@
namespace Drupal\image;
use Drupal\Component\Plugin\PluginInspectionInterface;
+use Drupal\Core\Image\ImageFile;
/**
* Defines the interface for image effects.
@@ -17,13 +18,13 @@
/**
* Applies an image effect to the image object.
*
- * @param \stdClass $image
+ * @param \Drupal\Core\Image\ImageFile $image
* An image object returned by image_load().
*
* @return bool
* TRUE on success. FALSE if unable to perform the image effect on the image.
*/
- public function processEffect($image);
+ public function processEffect(ImageFile $image);
/**
* Determines the dimensions of the styled image.
diff --git a/core/modules/image/lib/Drupal/image/ImageStyleInterface.php b/core/modules/image/lib/Drupal/image/ImageStyleInterface.php
index 717be6a..f808eb6 100644
--- a/core/modules/image/lib/Drupal/image/ImageStyleInterface.php
+++ b/core/modules/image/lib/Drupal/image/ImageStyleInterface.php
@@ -16,104 +16,6 @@
interface ImageStyleInterface extends ConfigEntityInterface {
/**
- * Deliver an image derivative.
- *
- * Transfers a generated image derivative to the requesting agent. Modules may
- * implement this method to set different serve different image derivatives
- * from different stream wrappers or to customize different permissions on
- * each image style.
- *
- * @param string $scheme
- * The scheme name of the original image file stream wrapper ('public',
- * 'private', 'temporary', etc.).
- * @param string $target
- * The target part of the uri.
- *
- * @return \Symfony\Component\HttpFoundation\BinaryFileResponse|\Symfony\Component\HttpFoundation\Response
- * The image to be delivered.
- *
- * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
- * \Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException
- *
- * @todo: Move to controller after https://drupal.org/node/1987712.
- */
- public function deliver($scheme, $target);
-
- /**
- * Returns the URI of this image when using this style.
- *
- * The path returned by this function may not exist. The default generation
- * method only creates images when they are requested by a user's browser.
- * Modules may implement this method to decide where to place derivatives.
- *
- * @param string $uri
- * The URI or path to the original image.
- *
- * @return string
- * The URI to the image derivative for this style.
- */
- public function buildUri($uri);
-
- /**
- * Returns the URL of this image derivative for an original image path or URI.
- *
- * @param string $path
- * The path or URI to the original image.
- * @param mixed $clean_urls
- * (optional) Whether clean URLs are in use.
- *
- * @return string
- * The absolute URL where a style image can be downloaded, suitable for use
- * in an tag. Requesting the URL will cause the image to be created.
- *
- * @see \Drupal\image\ImageStyleInterface::deliver()
- */
- public function buildUrl($path, $clean_urls = NULL);
-
- /**
- * Flushes cached media for this style.
- *
- * @param string $path
- * (optional) The original image path or URI. If it's supplied, only this
- * image derivative will be flushed.
- *
- * @return self
- * This image style.
- */
- public function flush($path = NULL);
-
- /**
- * Creates a new image derivative based on this image style.
- *
- * Generates an image derivative applying all image effects and saving the
- * resulting image.
- *
- * @param string $original_uri
- * Original image file URI.
- * @param string $derivative_uri
- * Derivative image file URI.
- *
- * @return bool
- * TRUE if an image derivative was generated, or FALSE if the image
- * derivative could not be generated.
- */
- public function createDerivative($original_uri, $derivative_uri);
-
- /**
- * Determines the dimensions of this image style.
- *
- * Stores the dimensions of this image style into $dimensions associative
- * array. Implementations have to provide at least values to next keys:
- * - width: Integer with the derivative image width.
- * - height: Integer with the derivative image height.
- *
- * @param array $dimensions
- * Associative array passed by reference. Implementations have to store the
- * resulting width and height, in pixels.
- */
- public function transformDimensions(array &$dimensions);
-
- /**
* Returns a specific image effect.
*
* @param string $effect
@@ -127,12 +29,20 @@ public function getEffect($effect);
/**
* Returns the image effects for this style.
*
- * @return \Drupal\image\ImageEffectBag|\Drupal\image\ImageEffectInterface[]
+ * @return \Drupal\image\ImageEffectBag
* The image effect plugin bag.
*/
public function getEffects();
/**
+ * Flushes cached media for a style.
+ *
+ * @return self
+ * This image style.
+ */
+ public function flush();
+
+ /**
* Saves an image effect for this style.
*
* @param array $configuration
diff --git a/core/modules/image/lib/Drupal/image/Plugin/Core/Entity/ImageStyle.php b/core/modules/image/lib/Drupal/image/Plugin/Core/Entity/ImageStyle.php
index 71ef480..d8163c4 100644
--- a/core/modules/image/lib/Drupal/image/Plugin/Core/Entity/ImageStyle.php
+++ b/core/modules/image/lib/Drupal/image/Plugin/Core/Entity/ImageStyle.php
@@ -14,12 +14,6 @@
use Drupal\image\ImageEffectBag;
use Drupal\image\ImageEffectInterface;
use Drupal\image\ImageStyleInterface;
-use Drupal\Component\Utility\Crypt;
-use Drupal\Component\Utility\Url;
-use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\HttpFoundation\BinaryFileResponse;
-use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
-use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
/**
* Defines an image style configuration entity.
@@ -96,17 +90,11 @@ public function id() {
* {@inheritdoc}
*/
public function postSave(EntityStorageControllerInterface $storage_controller, $update = TRUE) {
- if ($update) {
- if (!empty($this->original) && $this->id() !== $this->original->id()) {
- // The old image style name needs flushing after a rename.
- $this->original->flush();
- // Update field instance settings if necessary.
- static::replaceImageStyle($this);
- }
- else {
- // Flush image style when updating without changing the name.
- $this->flush();
- }
+ if ($update && !empty($this->original) && $this->id() !== $this->original->id()) {
+ // The old image style name needs flushing after a rename.
+ $this->original->flush();
+ // Update field instance settings if necessary.
+ static::replaceImageStyle($this);
}
}
@@ -131,7 +119,7 @@ public static function postDelete(EntityStorageControllerInterface $storage_cont
/**
* Update field instance settings if the image style name is changed.
*
- * @param \Drupal\image\ImageStyleInterface $style
+ * @param \Drupal\image\Plugin\Core\Entity\ImageStyle $style
* The image style.
*/
protected static function replaceImageStyle(ImageStyle $style) {
@@ -169,164 +157,54 @@ protected static function replaceImageStyle(ImageStyle $style) {
/**
* {@inheritdoc}
- *
- * @todo: Move to controller after https://drupal.org/node/1987712.
*/
- public function deliver($scheme, $target) {
-
- // Check that the scheme is valid, and the image derivative token is valid.
- // (Sites which require image derivatives to be generated without a token
- // can set the 'image.settings:allow_insecure_derivatives' configuration to
- // TRUE to bypass the latter check, but this will increase the site's
- // vulnerability to denial-of-service attacks.)
- $valid = file_stream_wrapper_valid_scheme($scheme);
- if (!\Drupal::config('image.settings')->get('allow_insecure_derivatives')) {
- $image_derivative_token = \Drupal::request()->query->get(IMAGE_DERIVATIVE_TOKEN);
- $valid = $valid && isset($image_derivative_token) && $image_derivative_token === $this->getPathToken($scheme . '://' . $target);
- }
- if (!$valid) {
- throw new AccessDeniedHttpException();
- }
-
- $original_uri = $scheme . '://' . $target;
- $derivative_uri = $this->buildUri($original_uri);
- $headers_to_send = array();
- // If using the private scheme, let other modules provide headers and
- // control access to the file.
- if ($scheme == 'private') {
- if (file_exists($derivative_uri)) {
- file_download($scheme, file_uri_target($derivative_uri));
- }
- else {
- $headers = \Drupal::moduleHandler()->invokeAll('file_download', array($original_uri));
- if (in_array(-1, $headers) || empty($headers)) {
- throw new AccessDeniedHttpException();
- }
- if (count($headers)) {
- foreach ($headers as $name => $value) {
- $headers_to_send[$name] = $value;
- }
- }
- }
- }
-
- // Don't try to generate file if source is missing.
- if (!file_exists($original_uri)) {
- watchdog('image', 'Source image at %source_image_path not found while trying to generate derivative image at %derivative_path.', array('%source_image_path' => $original_uri, '%derivative_path' => $derivative_uri));
- return new Response(t('Error generating image, missing source file.'), 404);
- }
-
- // Don't start generating the image if the derivative already exists or if
- // generation is in progress in another thread.
- $lock_name = 'image_style_deliver:' . $this->id() . ':' . Crypt::hashBase64($original_uri);
- if (!file_exists($derivative_uri)) {
- $lock_acquired = \Drupal::lock()->acquire($lock_name);
- if (!$lock_acquired) {
- // Tell client to retry again in 3 seconds. Currently no browsers are
- // known to support Retry-After.
- throw new ServiceUnavailableHttpException(3, t('Image generation in progress. Try again shortly.'));
- }
- }
-
- // Try to generate the image, unless another thread just did it while we
- // were acquiring the lock.
- $success = file_exists($derivative_uri) || $this->createDerivative($original_uri, $derivative_uri);
-
- if (!empty($lock_acquired)) {
- \Drupal::lock()->release($lock_name);
- }
-
- if ($success) {
- $image = image_load($derivative_uri);
- $uri = $image->source;
- $headers = $headers_to_send + array(
- 'Content-Type' => $image->info['mime_type'],
- 'Content-Length' => $image->info['file_size'],
- );
- return new BinaryFileResponse($uri, 200, $headers);
- }
- else {
- watchdog('image', 'Unable to generate the derived image located at %path.', array('%path' => $derivative_uri));
- return new Response(t('Error generating image.'), 500);
- }
+ public function getEffect($effect) {
+ return $this->getEffects()->get($effect);
}
/**
* {@inheritdoc}
*/
- public function buildUri($uri) {
- $scheme = file_uri_scheme($uri);
- if ($scheme) {
- $path = file_uri_target($uri);
+ public function getEffects() {
+ if (!$this->effectsBag) {
+ $this->effectsBag = new ImageEffectBag(\Drupal::service('plugin.manager.image.effect'), $this->effects);
}
- else {
- $path = $uri;
- $scheme = file_default_scheme();
- }
- return $scheme . '://styles/' . $this->id() . '/' . $scheme . '/' . $path;
+ return $this->effectsBag;
}
/**
* {@inheritdoc}
*/
- public function buildUrl($path, $clean_urls = NULL) {
- $uri = $this->buildUri($path);
- // The token query is added even if the
- // 'image.settings:allow_insecure_derivatives' configuration is TRUE, so
- // that the emitted links remain valid if it is changed back to the default
- // FALSE. However, sites which need to prevent the token query from being
- // emitted at all can additionally set the
- // 'image.settings:suppress_itok_output' configuration to TRUE to achieve
- // that (if both are set, the security token will neither be emitted in the
- // image derivative URL nor checked for in
- // \Drupal\image\ImageStyleInterface::deliver()).
- $token_query = array();
- if (!\Drupal::config('image.settings')->get('suppress_itok_output')) {
- $token_query = array(IMAGE_DERIVATIVE_TOKEN => $this->getPathToken(file_stream_wrapper_uri_normalize($path)));
- }
-
- if ($clean_urls === NULL) {
- // Assume clean URLs unless the request tells us otherwise.
- $clean_urls = TRUE;
- try {
- $request = \Drupal::request();
- $clean_urls = $request->attributes->get('clean_urls');
- }
- catch (ServiceNotFoundException $e) {
- }
- }
-
- // If not using clean URLs, the image derivative callback is only available
- // with the script path. If the file does not exist, use url() to ensure
- // that it is included. Once the file exists it's fine to fall back to the
- // actual file path, this avoids bootstrapping PHP once the files are built.
- if ($clean_urls === FALSE && file_uri_scheme($uri) == 'public' && !file_exists($uri)) {
- $directory_path = file_stream_wrapper_get_instance_by_uri($uri)->getDirectoryPath();
- return url($directory_path . '/' . file_uri_target($uri), array('absolute' => TRUE, 'query' => $token_query));
- }
-
- $file_url = file_create_url($uri);
- // Append the query string with the token, if necessary.
- if ($token_query) {
- $file_url .= (strpos($file_url, '?') !== FALSE ? '&' : '?') . Url::buildQuery($token_query);
- }
-
- return $file_url;
+ public function saveImageEffect(array $configuration) {
+ $effect_id = $this->getEffects()->setConfig($configuration);
+ $this->save();
+ $this->flush();
+ return $effect_id;
}
/**
* {@inheritdoc}
*/
- public function flush($path = NULL) {
- // A specific image path has been provided. Flush only that derivative.
- if (isset($path)) {
- $derivative_uri = $this->buildUri($path);
- if (file_exists($derivative_uri)) {
- file_unmanaged_delete($derivative_uri);
- }
- return $this;
- }
+ public function deleteImageEffect(ImageEffectInterface $effect) {
+ $this->getEffects()->removeInstanceID($effect->getUuid());
+ $this->save();
+ $this->flush();
+ return $this;
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function getExportProperties() {
+ $properties = parent::getExportProperties();
+ $properties['effects'] = $this->getEffects()->sort()->export();
+ return $properties;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function flush() {
// Delete the style directory in each registered wrapper.
$wrappers = file_get_stream_wrappers(STREAM_WRAPPERS_WRITE_VISIBLE);
foreach ($wrappers as $wrapper => $wrapper_data) {
@@ -349,107 +227,4 @@ public function flush($path = NULL) {
return $this;
}
- /**
- * {@inheritdoc}
- */
- public function createDerivative($original_uri, $derivative_uri) {
- // Get the folder for the final location of this style.
- $directory = drupal_dirname($derivative_uri);
-
- // Build the destination folder tree if it doesn't already exist.
- if (!file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
- watchdog('image', 'Failed to create style directory: %directory', array('%directory' => $directory), WATCHDOG_ERROR);
- return FALSE;
- }
-
- if (!$image = image_load($original_uri)) {
- return FALSE;
- }
-
- foreach ($this->getEffects() as $effect) {
- $effect->processEffect($image);
- }
-
- if (!image_save($image, $derivative_uri)) {
- if (file_exists($derivative_uri)) {
- watchdog('image', 'Cached image file %destination already exists. There may be an issue with your rewrite configuration.', array('%destination' => $derivative_uri), WATCHDOG_ERROR);
- }
- return FALSE;
- }
-
- return TRUE;
- }
-
- /**
- * {@inheritdoc}
- */
- public function transformDimensions(array &$dimensions) {
- foreach ($this->getEffects() as $effect) {
- $effect->processDimensions($dimensions);
- }
- }
-
- /**
- * Generates a token to protect an image style derivative.
- *
- * This prevents unauthorized generation of an image style derivative,
- * which can be costly both in CPU time and disk space.
- *
- * @param string $uri
- * The URI of the image for this style, for example as returned by
- * \Drupal\image\ImageStyleInterface::buildUri().
- *
- * @return string
- * An eight-character token which can be used to protect image style
- * derivatives against denial-of-service attacks.
- */
- protected function getPathToken($uri) {
- // Return the first eight characters.
- return substr(Crypt::hmacBase64($this->id() . ':' . $uri, drupal_get_private_key() . drupal_get_hash_salt()), 0, 8);
- }
-
- /**
- * {@inheritdoc}
- */
- public function deleteImageEffect(ImageEffectInterface $effect) {
- $this->getEffects()->removeInstanceID($effect->getUuid());
- $this->save();
- return $this;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getEffect($effect) {
- return $this->getEffects()->get($effect);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getEffects() {
- if (!$this->effectsBag) {
- $this->effectsBag = new ImageEffectBag(\Drupal::service('plugin.manager.image.effect'), $this->effects);
- }
- return $this->effectsBag;
- }
-
- /**
- * {@inheritdoc}
- */
- public function saveImageEffect(array $configuration) {
- $effect_id = $this->getEffects()->setConfig($configuration);
- $this->save();
- return $effect_id;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getExportProperties() {
- $properties = parent::getExportProperties();
- $properties['effects'] = $this->getEffects()->sort()->export();
- return $properties;
- }
-
}
diff --git a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/CropImageEffect.php b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/CropImageEffect.php
index ae06d37..11cff96 100644
--- a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/CropImageEffect.php
+++ b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/CropImageEffect.php
@@ -8,6 +8,7 @@
namespace Drupal\image\Plugin\ImageEffect;
use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Image\ImageFile;
use Drupal\image\Annotation\ImageEffect;
/**
@@ -24,17 +25,17 @@ class CropImageEffect extends ResizeImageEffect {
/**
* {@inheritdoc}
*/
- public function processEffect($image) {
+ public function processEffect(ImageFile $image) {
// Set sane default values.
$this->configuration += array(
'anchor' => 'center-center',
);
list($x, $y) = explode('-', $this->configuration['anchor']);
- $x = image_filter_keyword($x, $image->info['width'], $this->configuration['width']);
- $y = image_filter_keyword($y, $image->info['height'], $this->configuration['height']);
- if (!image_crop($image, $x, $y, $this->configuration['width'], $this->configuration['height'])) {
- watchdog('image', 'Image crop failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->toolkit->getPluginId(), '%path' => $image->source, '%mimetype' => $image->info['mime_type'], '%dimensions' => $image->info['width'] . 'x' . $image->info['height']), WATCHDOG_ERROR);
+ $x = image_filter_keyword($x, $image->get('width'), $this->configuration['width']);
+ $y = image_filter_keyword($y, $image->get('height'), $this->configuration['height']);
+ if (!$image->crop($x, $y, $this->configuration['width'], $this->configuration['height'])) {
+ watchdog('image', 'Image crop failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->getToolkitId(), '%path' => $image->getSource(), '%mimetype' => $image->get('mime_type'), '%dimensions' => $image->get('width') . 'x' . $image->get('height')), WATCHDOG_ERROR);
return FALSE;
}
return TRUE;
diff --git a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/DesaturateImageEffect.php b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/DesaturateImageEffect.php
index b378f26..f2577c5 100644
--- a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/DesaturateImageEffect.php
+++ b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/DesaturateImageEffect.php
@@ -8,6 +8,7 @@
namespace Drupal\image\Plugin\ImageEffect;
use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Image\ImageFile;
use Drupal\image\Annotation\ImageEffect;
use Drupal\image\ImageEffectBase;
@@ -32,9 +33,9 @@ public function processDimensions(array &$dimensions) {
/**
* {@inheritdoc}
*/
- public function processEffect($image) {
- if (!image_desaturate($image)) {
- watchdog('image', 'Image desaturate failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->toolkit->getPluginId(), '%path' => $image->source, '%mimetype' => $image->info['mime_type'], '%dimensions' => $image->info['width'] . 'x' . $image->info['height']), WATCHDOG_ERROR);
+ public function processEffect(ImageFile $image) {
+ if (!$image->desaturate()) {
+ watchdog('image', 'Image desaturate failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->getToolkitId(), '%path' => $image->getSource(), '%mimetype' => $image->get('mime_type'), '%dimensions' => $image->get('width') . 'x' . $image->get('height')), WATCHDOG_ERROR);
return FALSE;
}
return TRUE;
diff --git a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ResizeImageEffect.php b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ResizeImageEffect.php
index a40f7d3..71ee0e4 100644
--- a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ResizeImageEffect.php
+++ b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ResizeImageEffect.php
@@ -8,6 +8,7 @@
namespace Drupal\image\Plugin\ImageEffect;
use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Image\ImageFile;
use Drupal\image\Annotation\ImageEffect;
use Drupal\image\ImageEffectBase;
@@ -25,9 +26,9 @@ class ResizeImageEffect extends ImageEffectBase {
/**
* {@inheritdoc}
*/
- public function processEffect($image) {
- if (!image_resize($image, $this->configuration['width'], $this->configuration['height'])) {
- watchdog('image', 'Image resize failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->toolkit->getPluginId(), '%path' => $image->source, '%mimetype' => $image->info['mime_type'], '%dimensions' => $image->info['width'] . 'x' . $image->info['height']), WATCHDOG_ERROR);
+ public function processEffect(ImageFile $image) {
+ if (!$image->resize($this->configuration['width'], $this->configuration['height'])) {
+ watchdog('image', 'Image resize failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->getToolkitId(), '%path' => $image->getSource(), '%mimetype' => $image->get('mime_type'), '%dimensions' => $image->get('width') . 'x' . $image->get('height')), WATCHDOG_ERROR);
return FALSE;
}
return TRUE;
diff --git a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/RotateImageEffect.php b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/RotateImageEffect.php
index b676d8d..053eac7 100644
--- a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/RotateImageEffect.php
+++ b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/RotateImageEffect.php
@@ -8,6 +8,7 @@
namespace Drupal\image\Plugin\ImageEffect;
use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Image\ImageFile;
use Drupal\image\Annotation\ImageEffect;
use Drupal\image\ImageEffectBase;
@@ -25,7 +26,7 @@ class RotateImageEffect extends ImageEffectBase {
/**
* {@inheritdoc}
*/
- public function processEffect($image) {
+ public function processEffect(ImageFile $image) {
// Set sane default values.
$this->configuration += array(
'degrees' => 0,
@@ -52,8 +53,8 @@ public function processEffect($image) {
$this->configuration['degrees'] = rand(-1 * $degrees, $degrees);
}
- if (!image_rotate($image, $this->configuration['degrees'], $this->configuration['bgcolor'])) {
- watchdog('image', 'Image rotate failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->toolkit->getPluginId(), '%path' => $image->source, '%mimetype' => $image->info['mime_type'], '%dimensions' => $image->info['width'] . 'x' . $image->info['height']), WATCHDOG_ERROR);
+ if (!$image->rotate($this->configuration['degrees'], $this->configuration['bgcolor'])) {
+ watchdog('image', 'Image rotate failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->getToolkitId(), '%path' => $image->getSource(), '%mimetype' => $image->get('mime_type'), '%dimensions' => $image->get('width') . 'x' . $image->get('height')), WATCHDOG_ERROR);
return FALSE;
}
return TRUE;
diff --git a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ScaleAndCropImageEffect.php b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ScaleAndCropImageEffect.php
index 9ee30f0..66fddf7 100644
--- a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ScaleAndCropImageEffect.php
+++ b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ScaleAndCropImageEffect.php
@@ -8,6 +8,7 @@
namespace Drupal\image\Plugin\ImageEffect;
use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Image\ImageFile;
use Drupal\image\Annotation\ImageEffect;
/**
@@ -24,9 +25,9 @@ class ScaleAndCropImageEffect extends ResizeImageEffect {
/**
* {@inheritdoc}
*/
- public function processEffect($image) {
- if (!image_scale_and_crop($image, $this->configuration['width'], $this->configuration['height'])) {
- watchdog('image', 'Image scale and crop failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->toolkit->getPluginId(), '%path' => $image->source, '%mimetype' => $image->info['mime_type'], '%dimensions' => $image->info['width'] . 'x' . $image->info['height']), WATCHDOG_ERROR);
+ public function processEffect(ImageFile $image) {
+ if (!$image->scaleAndCrop($this->configuration['width'], $this->configuration['height'])) {
+ watchdog('image', 'Image scale and crop failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->getToolkitId(), '%path' => $image->getSource(), '%mimetype' => $image->get('mime_type'), '%dimensions' => $image->get('width') . 'x' . $image->get('height')), WATCHDOG_ERROR);
return FALSE;
}
return TRUE;
diff --git a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ScaleImageEffect.php b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ScaleImageEffect.php
index 45a6724..577e4b7 100644
--- a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ScaleImageEffect.php
+++ b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ScaleImageEffect.php
@@ -9,6 +9,7 @@
use Drupal\Component\Image\Image;
use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Image\ImageFile;
use Drupal\image\Annotation\ImageEffect;
/**
@@ -25,7 +26,7 @@ class ScaleImageEffect extends ResizeImageEffect {
/**
* {@inheritdoc}
*/
- public function processEffect($image) {
+ public function processEffect(ImageFile $image) {
// Set sane default values.
$this->configuration += array(
'width' => NULL,
@@ -33,8 +34,8 @@ public function processEffect($image) {
'upscale' => FALSE,
);
- if (!image_scale($image, $this->configuration['width'], $this->configuration['height'], $this->configuration['upscale'])) {
- watchdog('image', 'Image scale failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->toolkit->getPluginId(), '%path' => $image->source, '%mimetype' => $image->info['mime_type'], '%dimensions' => $image->info['width'] . 'x' . $image->info['height']), WATCHDOG_ERROR);
+ if (!$image->scale($this->configuration['width'], $this->configuration['height'], $this->configuration['upscale'])) {
+ watchdog('image', 'Image scale failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->getToolkitId(), '%path' => $image->getSource(), '%mimetype' => $image->get('mime_type'), '%dimensions' => $image->get('width') . 'x' . $image->get('height')), WATCHDOG_ERROR);
return FALSE;
}
return TRUE;
diff --git a/core/modules/image/lib/Drupal/image/Tests/FileMoveTest.php b/core/modules/image/lib/Drupal/image/Tests/FileMoveTest.php
index 2fc0b68..f085f2d 100644
--- a/core/modules/image/lib/Drupal/image/Tests/FileMoveTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/FileMoveTest.php
@@ -39,9 +39,8 @@ function testNormal() {
// Create derivative image.
$styles = entity_load_multiple('image_style');
$style = image_style_load(key($styles));
- $original_uri = $file->getFileUri();
- $derivative_uri = $style->buildUri($original_uri);
- $style->createDerivative($original_uri, $derivative_uri);
+ $derivative_uri = image_style_path($style->id(), $file->getFileUri());
+ image_style_create_derivative($style, $file->getFileUri(), $derivative_uri);
// Check if derivative image exists.
$this->assertTrue(file_exists($derivative_uri), 'Make sure derivative image is generated successfully.');
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php
index f69f9b2..62a97c4 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageAdminStylesTest.php
@@ -36,7 +36,7 @@ function createSampleImage($style) {
$file_path = file_unmanaged_copy($file->uri);
}
- return $style->buildUrl($file_path) ? $file_path : FALSE;
+ return image_style_url($style->id(), $file_path) ? $file_path : FALSE;
}
/**
@@ -274,13 +274,9 @@ function testStyleReplacement() {
$nid = $this->uploadNodeImage($test_image, $field_name, 'article');
$node = node_load($nid);
- // Get node field original image URI.
- $fid = $node->get($field_name)->target_id;
- $original_uri = file_load($fid)->getFileUri();
-
// 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(image_style_url($style_name, file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'])->getFileUri()), 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->randomName(10));
@@ -292,10 +288,7 @@ function testStyleReplacement() {
$this->drupalPost($style_path . $style_name, $edit, t('Update style'));
$this->assertText(t('Changes to the style have been saved.'), format_string('Style %name was renamed to %new_name.', array('%name' => $style_name, '%new_name' => $new_style_name)));
$this->drupalGet('node/' . $nid);
-
- // Reload the image style using the new name.
- $style = entity_load('image_style', $new_style_name);
- $this->assertRaw($style->buildUrl($original_uri), 'Image displayed using style replacement style.');
+ $this->assertRaw(image_style_url($new_style_name, file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'])->getFileUri()), 'Image displayed using style replacement style.');
// Delete the style and choose a replacement style.
$edit = array(
@@ -305,9 +298,8 @@ function testStyleReplacement() {
$message = t('Style %name was deleted.', array('%name' => $new_style_label));
$this->assertRaw($message);
- $replacement_style = entity_load('image_style', 'thumbnail');
$this->drupalGet('node/' . $nid);
- $this->assertRaw($replacement_style->buildUrl($original_uri), 'Image displayed using style replacement style.');
+ $this->assertRaw(image_style_url('thumbnail', file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'])->getFileUri()), 'Image displayed using style replacement style.');
}
/**
@@ -371,13 +363,9 @@ function testConfigImport() {
$nid = $this->uploadNodeImage($test_image, $field_name, 'article');
$node = node_load($nid);
- // Get node field original image URI.
- $fid = $node->get($field_name)->target_id;
- $original_uri = file_load($fid)->getFileUri();
-
// 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(image_style_url($style_name, file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['target_id'])->getFileUri()), format_string('Image displayed using style @style.', array('@style' => $style_name)));
// Copy config to staging, and delete the image style.
$staging = $this->container->get('config.storage.staging');
@@ -389,5 +377,4 @@ function testConfigImport() {
$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.');
}
-
}
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageDimensionsTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageDimensionsTest.php
index 0ff6738..7f45aec 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageDimensionsTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageDimensionsTest.php
@@ -44,7 +44,7 @@ function testImageDimensions() {
$style = entity_create('image_style', array('name' => 'test', 'label' => 'Test'));
$style->save();
$generated_uri = 'public://styles/test/public/'. drupal_basename($original_uri);
- $url = $style->buildUrl($original_uri);
+ $url = image_style_url('test', $original_uri);
$variables = array(
'style_name' => 'test',
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
index e7775ad..c0f0cfd 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
@@ -112,7 +112,7 @@ function _testImageFieldFormatters($scheme) {
// Ensure the derivative image is generated so we do not have to deal with
// image style callback paths.
- $this->drupalGet(entity_load('image_style', 'thumbnail')->buildUrl($image_uri));
+ $this->drupalGet(image_style_url('thumbnail', $image_uri));
$image_info['uri'] = $image_uri;
$image_info['width'] = 100;
$image_info['height'] = 50;
@@ -124,7 +124,7 @@ function _testImageFieldFormatters($scheme) {
if ($scheme == 'private') {
// Log out and try to access the file.
$this->drupalLogout();
- $this->drupalGet(entity_load('image_style', 'thumbnail')->buildUrl($image_uri));
+ $this->drupalGet(image_style_url('thumbnail', $image_uri));
$this->assertResponse('403', 'Access denied to image style thumbnail as anonymous user.');
}
}
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php
index 7d0f054..47f7091 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php
@@ -15,11 +15,10 @@
*
* image.effects.inc:
* image_style_generate()
- * \Drupal\image\ImageStyleInterface::createDerivative()
+ * image_style_create_derivative()
*
* image.module:
* image_style_options()
- * \Drupal\image\ImageStyleInterface::flush()
* image_filter_keyword()
*/
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageStyleFlushTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageStyleFlushTest.php
index b5c3776..67cf051 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageStyleFlushTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageStyleFlushTest.php
@@ -34,8 +34,8 @@ function createSampleImage($style, $wrapper) {
// Make sure we have an image in our wrapper testing file directory.
$source_uri = file_unmanaged_copy($file->uri, $wrapper . '://');
// Build the derivative image.
- $derivative_uri = $style->buildUri($source_uri);
- $derivative = $style->createDerivative($source_uri, $derivative_uri);
+ $derivative_uri = image_style_path($style->id(), $source_uri);
+ $derivative = image_style_create_derivative($style, $source_uri, $derivative_uri);
return $derivative ? $derivative_uri : FALSE;
}
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageStylesPathAndUrlTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageStylesPathAndUrlTest.php
index 8629dfb..1b9e2db 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageStylesPathAndUrlTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageStylesPathAndUrlTest.php
@@ -9,7 +9,6 @@
use Drupal\simpletest\WebTestBase;
use Symfony\Component\HttpFoundation\Request;
-use Drupal\image\Plugin\Core\Entity\ImageStyle;
/**
* Tests the functions for generating paths and URLs for image styles.
@@ -23,7 +22,7 @@ class ImageStylesPathAndUrlTest extends WebTestBase {
*/
public static $modules = array('image', 'image_module_test');
- protected $style;
+ protected $style_name;
protected $image_info;
protected $image_filepath;
@@ -38,59 +37,55 @@ public static function getInfo() {
function setUp() {
parent::setUp();
- $this->style = entity_create('image_style', array('name' => 'style_foo', 'label' => $this->randomString()));
- $this->style->save();
+ $this->style_name = 'style_foo';
+ $style = entity_create('image_style', array('name' => $this->style_name, 'label' => $this->randomString()));
+ $style->save();
}
/**
- * Test \Drupal\image\Plugin\Core\Entity\ImageStyle::buildUri().
+ * Test image_style_path().
*/
function testImageStylePath() {
$scheme = 'public';
- $actual = $this->style->buildUri("$scheme://foo/bar.gif");
- $expected = "$scheme://styles/" . $this->style->id() . "/$scheme/foo/bar.gif";
+ $actual = image_style_path($this->style_name, "$scheme://foo/bar.gif");
+ $expected = "$scheme://styles/" . $this->style_name . "/$scheme/foo/bar.gif";
$this->assertEqual($actual, $expected, 'Got the path for a file URI.');
- $actual = $this->style->buildUri('foo/bar.gif');
- $expected = "$scheme://styles/" . $this->style->id() . "/$scheme/foo/bar.gif";
+ $actual = image_style_path($this->style_name, 'foo/bar.gif');
+ $expected = "$scheme://styles/" . $this->style_name . "/$scheme/foo/bar.gif";
$this->assertEqual($actual, $expected, 'Got the path for a relative file path.');
}
/**
- * Test \Drupal\image\Plugin\Core\Entity\ImageStyle::buildUrl() with a file
- * using the "public://" scheme.
+ * Test image_style_url() with a file using the "public://" scheme.
*/
function testImageStyleUrlAndPathPublic() {
$this->_testImageStyleUrlAndPath('public');
}
/**
- * Test \Drupal\image\Plugin\Core\Entity\ImageStyle::buildUrl() with a file
- * using the "private://" scheme.
+ * Test image_style_url() with a file using the "private://" scheme.
*/
function testImageStyleUrlAndPathPrivate() {
$this->_testImageStyleUrlAndPath('private');
}
/**
- * Test \Drupal\image\Plugin\Core\Entity\ImageStyle::buildUrl() with the
- * "public://" scheme and unclean URLs.
+ * Test image_style_url() with the "public://" scheme and unclean URLs.
*/
function testImageStylUrlAndPathPublicUnclean() {
$this->_testImageStyleUrlAndPath('public', FALSE);
}
/**
- * Test \Drupal\image\Plugin\Core\Entity\ImageStyle::buildUrl() with the
- * "private://" schema and unclean URLs.
+ * Test image_style_url() with the "private://" schema and unclean URLs.
*/
function testImageStyleUrlAndPathPrivateUnclean() {
$this->_testImageStyleUrlAndPath('private', FALSE);
}
/**
- * Tests \Drupal\image\Plugin\Core\Entity\ImageStyle::buildUrl() with a file
- * URL that has an extra slash in it.
+ * Tests image_style_url() with a file URL that has an extra slash in it.
*/
function testImageStyleUrlExtraSlash() {
$this->_testImageStyleUrlAndPath('public', TRUE, TRUE);
@@ -101,13 +96,13 @@ function testImageStyleUrlExtraSlash() {
*/
function testImageStyleUrlForMissingSourceImage() {
$non_existent_uri = 'public://foo.png';
- $generated_url = $this->style->buildUrl($non_existent_uri);
+ $generated_url = image_style_url($this->style_name, $non_existent_uri);
$this->drupalGet($generated_url);
$this->assertResponse(404, 'Accessing an image style URL with a source image that does not exist provides a 404 error response.');
}
/**
- * Tests \Drupal\image\Plugin\Core\Entity\ImageStyle::buildUrl().
+ * Tests image_style_url().
*/
function _testImageStyleUrlAndPath($scheme, $clean_url = TRUE, $extra_slash = FALSE) {
$request = $this->prepareRequestForGenerator($clean_url);
@@ -117,7 +112,7 @@ function _testImageStyleUrlAndPath($scheme, $clean_url = TRUE, $extra_slash = FA
config('system.file')->set('default_scheme', 'temporary')->save();
// Create the directories for the styles.
- $directory = $scheme . '://styles/' . $this->style->id();
+ $directory = $scheme . '://styles/' . $this->style_name;
$status = file_prepare_directory($directory, FILE_CREATE_DIRECTORY);
$this->assertNotIdentical(FALSE, $status, 'Created the directory for the generated images for the test style.');
@@ -132,9 +127,9 @@ function _testImageStyleUrlAndPath($scheme, $clean_url = TRUE, $extra_slash = FA
$this->assertNotIdentical(FALSE, $original_uri, 'Created the generated image file.');
// Get the URL of a file that has not been generated and try to create it.
- $generated_uri = $this->style->buildUri($original_uri);
+ $generated_uri = image_style_path($this->style_name, $original_uri);
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
- $generate_url = $this->style->buildUrl($original_uri, $clean_url);
+ $generate_url = image_style_url($this->style_name, $original_uri, $clean_url);
// Ensure that the tests still pass when the file is generated by accessing
// a poorly constructed (but still valid) file URL that has an extra slash
@@ -142,7 +137,7 @@ function _testImageStyleUrlAndPath($scheme, $clean_url = TRUE, $extra_slash = FA
if ($extra_slash) {
$modified_uri = str_replace('://', ':///', $original_uri);
$this->assertNotEqual($original_uri, $modified_uri, 'An extra slash was added to the generated file URI.');
- $generate_url = $this->style->buildUrl($modified_uri, $clean_url);
+ $generate_url = image_style_url($this->style_name, $modified_uri, $clean_url);
}
if (!$clean_url) {
$this->assertTrue(strpos($generate_url, 'index.php/') !== FALSE, 'When using non-clean URLS, the system path contains the script name.');
@@ -182,9 +177,9 @@ function _testImageStyleUrlAndPath($scheme, $clean_url = TRUE, $extra_slash = FA
// make sure that access is denied.
$file_noaccess = array_shift($files);
$original_uri_noaccess = file_unmanaged_copy($file_noaccess->uri, $scheme . '://', FILE_EXISTS_RENAME);
- $generated_uri_noaccess = $scheme . '://styles/' . $this->style->id() . '/' . $scheme . '/'. drupal_basename($original_uri_noaccess);
+ $generated_uri_noaccess = $scheme . '://styles/' . $this->style_name . '/' . $scheme . '/'. drupal_basename($original_uri_noaccess);
$this->assertFalse(file_exists($generated_uri_noaccess), 'Generated file does not exist.');
- $generate_url_noaccess = $this->style->buildUrl($original_uri_noaccess);
+ $generate_url_noaccess = image_style_url($this->style_name, $original_uri_noaccess);
$this->drupalGet($generate_url_noaccess);
$this->assertResponse(403, 'Confirmed that access is denied for the private image style.');
@@ -221,9 +216,9 @@ function _testImageStyleUrlAndPath($scheme, $clean_url = TRUE, $extra_slash = FA
// has not been created and try to create it. Check that the security token
// is not present in the URL but that the image is still accessible.
config('image.settings')->set('suppress_itok_output', TRUE)->save();
- $generated_uri = $this->style->buildUri($original_uri);
+ $generated_uri = image_style_path($this->style_name, $original_uri);
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
- $generate_url = $this->style->buildUrl($original_uri, $clean_url);
+ $generate_url = image_style_url($this->style_name, $original_uri, $clean_url);
$this->assertIdentical(strpos($generate_url, IMAGE_DERIVATIVE_TOKEN . '='), FALSE, 'The security token does not appear in the image style URL.');
$this->drupalGet($generate_url);
$this->assertResponse(200, 'Image was accessible at the URL with a missing token.');
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageThemeFunctionTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageThemeFunctionTest.php
index f0d540f..cd00cb1 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageThemeFunctionTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageThemeFunctionTest.php
@@ -41,7 +41,7 @@ function testImageFormatterTheme() {
// Create a style.
$style = entity_create('image_style', array('name' => 'test', 'label' => 'Test'));
$style->save();
- $url = $style->buildUrl($original_uri);
+ $url = image_style_url('test', $original_uri);
// Test using theme_image_formatter() without an image title, alt text, or
// link options.
@@ -84,7 +84,7 @@ function testImageStyleTheme() {
// Create a style.
$style = entity_create('image_style', array('name' => 'image_test', 'label' => 'Test'));
$style->save();
- $url = $style->buildUrl($original_uri);
+ $url = image_style_url('image_test', $original_uri);
$path = $this->randomName();
$element = array(
diff --git a/core/modules/image/tests/modules/image_module_test/lib/Drupal/image_module_test/Plugin/ImageEffect/NullTestImageEffect.php b/core/modules/image/tests/modules/image_module_test/lib/Drupal/image_module_test/Plugin/ImageEffect/NullTestImageEffect.php
index 158afb1..c5a9ad4 100644
--- a/core/modules/image/tests/modules/image_module_test/lib/Drupal/image_module_test/Plugin/ImageEffect/NullTestImageEffect.php
+++ b/core/modules/image/tests/modules/image_module_test/lib/Drupal/image_module_test/Plugin/ImageEffect/NullTestImageEffect.php
@@ -8,6 +8,7 @@
namespace Drupal\image_module_test\Plugin\ImageEffect;
use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Image\ImageFile;
use Drupal\image\Annotation\ImageEffect;
use Drupal\image\ImageEffectBase;
@@ -25,7 +26,7 @@ class NullTestImageEffect extends ImageEffectBase {
/**
* {@inheritdoc}
*/
- public function processEffect($image) {
+ public function processEffect(ImageFile $image) {
return TRUE;
}
diff --git a/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php b/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php
index 8009241..b79ad21 100644
--- a/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php
+++ b/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php
@@ -182,8 +182,7 @@ public function _testPictureFieldFormatters($scheme) {
$display->setComponent($field_name, $display_options)
->save();
- $large_style = entity_load('image_style', 'large');
- $this->drupalGet($large_style->buildUrl($image_uri));
+ $this->drupalGet(image_style_url('large', $image_uri));
$image_info['uri'] = $image_uri;
$image_info['width'] = 480;
$image_info['height'] = 240;
@@ -195,7 +194,7 @@ public function _testPictureFieldFormatters($scheme) {
if ($scheme == 'private') {
// Log out and try to access the file.
$this->drupalLogout();
- $this->drupalGet($large_style->buildUrl($image_uri));
+ $this->drupalGet(image_style_url('large', $image_uri));
$this->assertResponse('403', 'Access denied to image style thumbnail as anonymous user.');
}
}
diff --git a/core/modules/picture/picture.module b/core/modules/picture/picture.module
index 680f05c..deba3b0 100644
--- a/core/modules/picture/picture.module
+++ b/core/modules/picture/picture.module
@@ -225,7 +225,7 @@ function theme_picture($variables) {
// Fallback image, output as source with media query.
$sources[] = array(
- 'src' => entity_load('image_style', $variables['style_name'])->buildUrl($variables['uri']),
+ 'src' => image_style_url($variables['style_name'], $variables['uri']),
'dimensions' => picture_get_image_dimensions($variables),
);
@@ -244,7 +244,7 @@ function theme_picture($variables) {
// Only one image, use src.
if (count($new_sources) == 1) {
$sources[] = array(
- 'src' => entity_load('image_style', $new_sources[0]['style_name'])->buildUrl($new_sources[0]['uri']),
+ 'src' => image_style_url($new_sources[0]['style_name'], $new_sources[0]['uri']),
'dimensions' => picture_get_image_dimensions($new_sources[0]),
'media' => $breakpoint->mediaQuery,
);
@@ -253,7 +253,7 @@ function theme_picture($variables) {
// Multiple images, use srcset.
$srcset = array();
foreach ($new_sources as $new_source) {
- $srcset[] = entity_load('image_style', $new_source['style_name'])->buildUrl($new_source['uri']) . ' ' . $new_source['#multiplier'];
+ $srcset[] = image_style_url($new_source['style_name'], $new_source['uri']) . ' ' . $new_source['#multiplier'];
}
$sources[] = array(
'srcset' => implode(', ', $srcset),
@@ -338,7 +338,7 @@ function picture_get_image_dimensions($variables) {
'height' => $variables['height'],
);
- entity_load('image_style', $variables['style_name'])->transformDimensions($dimensions);
+ image_style_transform_dimensions($variables['style_name'], $dimensions);
return $dimensions;
}
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/ImageFieldAttributesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/ImageFieldAttributesTest.php
index a622a8c..338ddfb 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/ImageFieldAttributesTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/ImageFieldAttributesTest.php
@@ -101,7 +101,7 @@ function testNodeTeaser() {
// Construct the node and image URIs for testing.
$node_uri = url('node/' . $this->node->id(), array('absolute' => TRUE));
- $image_uri = entity_load('image_style', 'medium')->buildUrl($this->file->getFileUri());
+ $image_uri = image_style_url('medium', $this->file->getFileUri());
// Test relations from node to image.
$expected_value = array(
diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module
index 95c21f3..3c03d80 100644
--- a/core/modules/rdf/rdf.module
+++ b/core/modules/rdf/rdf.module
@@ -344,7 +344,7 @@ function rdf_preprocess_field(&$variables) {
// this field has a URI.
if (isset($item['entity']->uri)) {
if (!empty($element[$delta]['#image_style'])) {
- $variables['item_attributes'][$delta]['resource'] = entity_load('image_style', $element[$delta]['#image_style'])->buildUrl($item['entity']->getFileUri());
+ $variables['item_attributes'][$delta]['resource'] = image_style_url($element[$delta]['#image_style'], $item['entity']->getFileUri());
}
else {
$variables['item_attributes'][$delta]['resource'] = file_create_url($item['entity']->getFileUri());
diff --git a/core/modules/system/lib/Drupal/system/Plugin/ImageToolkit/GDToolkit.php b/core/modules/system/lib/Drupal/system/Plugin/ImageToolkit/GDToolkit.php
index 06cb4a6..70be018 100644
--- a/core/modules/system/lib/Drupal/system/Plugin/ImageToolkit/GDToolkit.php
+++ b/core/modules/system/lib/Drupal/system/Plugin/ImageToolkit/GDToolkit.php
@@ -10,6 +10,7 @@
use Drupal\Component\Plugin\PluginBase;
use Drupal\Component\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Image\ImageFile;
use Drupal\system\Plugin\ImageToolkitInterface;
/**
@@ -50,33 +51,33 @@ public function settingsFormSubmit($form, &$form_state) {
/**
* Implements \Drupal\system\Plugin\ImageToolkitInterface::resize().
*/
- public function resize($image, $width, $height) {
+ public function resize(ImageFile $image, $width, $height) {
$res = $this->createTmp($image, $width, $height);
- if (!imagecopyresampled($res, $image->resource, 0, 0, 0, 0, $width, $height, $image->info['width'], $image->info['height'])) {
+ if (!imagecopyresampled($res, $image->getResource(), 0, 0, 0, 0, $width, $height, $image->get('width'), $image->get('height'))) {
return FALSE;
}
- imagedestroy($image->resource);
+ imagedestroy($image->getResource());
// Update image object.
- $image->resource = $res;
- $image->info['width'] = $width;
- $image->info['height'] = $height;
+ $image->setResource($res);
+ $image->set('width', $width);
+ $image->set('height', $height);
return TRUE;
}
/**
* Implements \Drupal\system\Plugin\ImageToolkitInterface::rotate().
*/
- public function rotate($image, $degrees, $background = NULL) {
+ public function rotate(ImageFile $image, $degrees, $background = NULL) {
// PHP installations using non-bundled GD do not have imagerotate.
if (!function_exists('imagerotate')) {
- watchdog('image', 'The image %file could not be rotated because the imagerotate() function is not available in this PHP installation.', array('%file' => $image->source));
+ watchdog('image', 'The image %file could not be rotated because the imagerotate() function is not available in this PHP installation.', array('%file' => $image->getSource()));
return FALSE;
}
- $width = $image->info['width'];
- $height = $image->info['height'];
+ $width = $image->get('width');
+ $height = $image->get('height');
// Convert the hexadecimal background value to a color index value.
if (isset($background)) {
@@ -84,88 +85,89 @@ public function rotate($image, $degrees, $background = NULL) {
for ($i = 16; $i >= 0; $i -= 8) {
$rgb[] = (($background >> $i) & 0xFF);
}
- $background = imagecolorallocatealpha($image->resource, $rgb[0], $rgb[1], $rgb[2], 0);
+ $background = imagecolorallocatealpha($image->getResource(), $rgb[0], $rgb[1], $rgb[2], 0);
}
// Set the background color as transparent if $background is NULL.
else {
// Get the current transparent color.
- $background = imagecolortransparent($image->resource);
+ $background = imagecolortransparent($image->getResource());
// If no transparent colors, use white.
if ($background == 0) {
- $background = imagecolorallocatealpha($image->resource, 255, 255, 255, 0);
+ $background = imagecolorallocatealpha($image->getResource(), 255, 255, 255, 0);
}
}
// Images are assigned a new color palette when rotating, removing any
// transparency flags. For GIF images, keep a record of the transparent color.
- if ($image->info['extension'] == 'gif') {
- $transparent_index = imagecolortransparent($image->resource);
+ if ($image->get('extension') == 'gif') {
+ $transparent_index = imagecolortransparent($image->getResource());
if ($transparent_index != 0) {
- $transparent_gif_color = imagecolorsforindex($image->resource, $transparent_index);
+ $transparent_gif_color = imagecolorsforindex($image->getResource(), $transparent_index);
}
}
- $image->resource = imagerotate($image->resource, 360 - $degrees, $background);
+ $image->setResource(imagerotate($image->getResource(), 360 - $degrees, $background));
// GIFs need to reassign the transparent color after performing the rotate.
if (isset($transparent_gif_color)) {
- $background = imagecolorexactalpha($image->resource, $transparent_gif_color['red'], $transparent_gif_color['green'], $transparent_gif_color['blue'], $transparent_gif_color['alpha']);
- imagecolortransparent($image->resource, $background);
+ $background = imagecolorexactalpha($image->getResource(), $transparent_gif_color['red'], $transparent_gif_color['green'], $transparent_gif_color['blue'], $transparent_gif_color['alpha']);
+ imagecolortransparent($image->getResource(), $background);
}
- $image->info['width'] = imagesx($image->resource);
- $image->info['height'] = imagesy($image->resource);
+ $image->set('width', imagesx($image->getResource()));
+ $image->set('height', imagesy($image->getResource()));
return TRUE;
}
/**
* Implements \Drupal\system\Plugin\ImageToolkitInterface::crop().
*/
- public function crop($image, $x, $y, $width, $height) {
+ public function crop(ImageFile $image, $x, $y, $width, $height) {
$res = $this->createTmp($image, $width, $height);
- if (!imagecopyresampled($res, $image->resource, 0, 0, $x, $y, $width, $height, $width, $height)) {
+ if (!imagecopyresampled($res, $image->getResource(), 0, 0, $x, $y, $width, $height, $width, $height)) {
return FALSE;
}
// Destroy the original image and return the modified image.
- imagedestroy($image->resource);
- $image->resource = $res;
- $image->info['width'] = $width;
- $image->info['height'] = $height;
+ imagedestroy($image->getResource());
+ $image->setResource($res);
+ $image->set('width', $width);
+ $image->set('height', $height);
return TRUE;
}
/**
* Implements \Drupal\system\Plugin\ImageToolkitInterface::desaturate().
*/
- public function desaturate($image) {
+ public function desaturate(ImageFile $image) {
// PHP installations using non-bundled GD do not have imagefilter.
if (!function_exists('imagefilter')) {
- watchdog('image', 'The image %file could not be desaturated because the imagefilter() function is not available in this PHP installation.', array('%file' => $image->source));
+ watchdog('image', 'The image %file could not be desaturated because the imagefilter() function is not available in this PHP installation.', array('%file' => $image->getSource()));
return FALSE;
}
- return imagefilter($image->resource, IMG_FILTER_GRAYSCALE);
+ return imagefilter($image->getResource(), IMG_FILTER_GRAYSCALE);
}
/**
* Implements \Drupal\system\Plugin\ImageToolkitInterface::load().
*/
- public function load($image) {
- $extension = str_replace('jpg', 'jpeg', $image->info['extension']);
+ public function load(ImageFile $image) {
+ $extension = str_replace('jpg', 'jpeg', $image->get('extension'));
$function = 'imagecreatefrom' . $extension;
- if (function_exists($function) && $image->resource = $function($image->source)) {
- if (!imageistruecolor($image->resource)) {
+ if (function_exists($function) && $resource = $function($image->getSource())) {
+ $image->setResource($resource);
+ if (!imageistruecolor($resource)) {
// Convert indexed images to true color, so that filters work
// correctly and don't result in unnecessary dither.
- $new_image = $this->createTmp($image, $image->info['width'], $image->info['height']);
- imagecopy($new_image, $image->resource, 0, 0, 0, 0, $image->info['width'], $image->info['height']);
- imagedestroy($image->resource);
- $image->resource = $new_image;
+ $new_image = $this->createTmp($image, $image->get('width'), $image->get('height'));
+ imagecopy($new_image, $resource, 0, 0, 0, 0, $image->get('width'), $image->get('height'));
+ imagedestroy($resource);
+ $image->setResource($new_image);
}
- return (bool) $image->resource;
+ return (bool) $image->getResource();
}
return FALSE;
@@ -174,7 +176,7 @@ public function load($image) {
/**
* Implements \Drupal\system\Plugin\ImageToolkitInterface::save().
*/
- public function save($image, $destination) {
+ public function save(ImageFile $image, $destination) {
$scheme = file_uri_scheme($destination);
// Work around lack of stream wrapper support in imagejpeg() and imagepng().
if ($scheme && file_stream_wrapper_valid_scheme($scheme)) {
@@ -188,21 +190,21 @@ public function save($image, $destination) {
$destination = drupal_realpath($destination);
}
- $extension = str_replace('jpg', 'jpeg', $image->info['extension']);
+ $extension = str_replace('jpg', 'jpeg', $image->get('extension'));
$function = 'image' . $extension;
if (!function_exists($function)) {
return FALSE;
}
if ($extension == 'jpeg') {
- $success = $function($image->resource, $destination, config('system.image.gd')->get('jpeg_quality'));
+ $success = $function($image->getResource(), $destination, config('system.image.gd')->get('jpeg_quality'));
}
else {
// Always save PNG images with full transparency.
if ($extension == 'png') {
- imagealphablending($image->resource, FALSE);
- imagesavealpha($image->resource, TRUE);
+ imagealphablending($image->getResource(), FALSE);
+ imagesavealpha($image->getResource(), TRUE);
}
- $success = $function($image->resource, $destination);
+ $success = $function($image->getResource(), $destination);
}
// Move temporary local file to remote destination.
if (isset($permanent_destination) && $success) {
@@ -214,9 +216,9 @@ public function save($image, $destination) {
/**
* Implements \Drupal\system\Plugin\ImageToolkitInterface::getInfo().
*/
- public function getInfo($image) {
+ public function getInfo(ImageFile $image) {
$details = FALSE;
- $data = getimagesize($image->source);
+ $data = getimagesize($image->getSource());
if (isset($data) && is_array($data)) {
$extensions = array('1' => 'gif', '2' => 'jpg', '3' => 'png');
@@ -248,13 +250,13 @@ public function getInfo($image) {
public function createTmp($image, $width, $height) {
$res = imagecreatetruecolor($width, $height);
- if ($image->info['extension'] == 'gif') {
+ if ($image->get('extension') == 'gif') {
// Grab transparent color index from image resource.
- $transparent = imagecolortransparent($image->resource);
+ $transparent = imagecolortransparent($image->getResource());
if ($transparent >= 0) {
// The original must have a transparent color, allocate to the new image.
- $transparent_color = imagecolorsforindex($image->resource, $transparent);
+ $transparent_color = imagecolorsforindex($image->getResource(), $transparent);
$transparent = imagecolorallocate($res, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']);
// Flood with our new transparent color.
@@ -262,7 +264,7 @@ public function createTmp($image, $width, $height) {
imagecolortransparent($res, $transparent);
}
}
- elseif ($image->info['extension'] == 'png') {
+ elseif ($image->get('extension') == 'png') {
imagealphablending($res, FALSE);
$transparency = imagecolorallocatealpha($res, 0, 0, 0, 127);
imagefill($res, 0, 0, $transparency);
diff --git a/core/modules/system/lib/Drupal/system/Plugin/ImageToolkitInterface.php b/core/modules/system/lib/Drupal/system/Plugin/ImageToolkitInterface.php
index 0b22f3c..90bd15f 100644
--- a/core/modules/system/lib/Drupal/system/Plugin/ImageToolkitInterface.php
+++ b/core/modules/system/lib/Drupal/system/Plugin/ImageToolkitInterface.php
@@ -7,13 +7,16 @@
namespace Drupal\system\Plugin;
+use Drupal\Component\Plugin\PluginInspectionInterface;
+use Drupal\Core\Image\ImageFile;
+
/**
* Defines an interface for image toolkits.
*
* An image toolkit provides common image file manipulations like scaling,
* cropping, and rotating.
*/
-interface ImageToolkitInterface {
+interface ImageToolkitInterface extends PluginInspectionInterface {
/**
* Retrieves toolkit's settings form.
@@ -32,7 +35,7 @@ function settingsFormSubmit($form, &$form_state);
/**
* Scales an image to the specified size.
*
- * @param object $image
+ * @param \Drupal\Core\Image\ImageFile $image
* An image object. The $image->resource, $image->info['width'], and
* $image->info['height'] values will be modified by this call.
* @param int $width
@@ -42,15 +45,13 @@ function settingsFormSubmit($form, &$form_state);
*
* @return bool
* TRUE or FALSE, based on success.
- *
- * @see image_resize()
*/
- function resize($image, $width, $height);
+ function resize(ImageFile $image, $width, $height);
/**
* Rotates an image the given number of degrees.
*
- * @param object $image
+ * @param \Drupal\Core\Image\ImageFile $image
* An image object. The $image->resource, $image->info['width'], and
* $image->info['height'] values will be modified by this call.
* @param int $degrees
@@ -64,15 +65,13 @@ function resize($image, $width, $height);
*
* @return bool
* TRUE or FALSE, based on success.
- *
- * @see image_rotate()
*/
- function rotate($image, $degrees, $background = NULL);
+ function rotate(ImageFile $image, $degrees, $background = NULL);
/**
* Crops an image.
*
- * @param object $image
+ * @param \Drupal\Core\Image\ImageFile $image
* An image object. The $image->resource, $image->info['width'], and
* $image->info['height'] values will be modified by this call.
* @param int $x
@@ -89,56 +88,50 @@ function rotate($image, $degrees, $background = NULL);
*
* @see image_crop()
*/
- function crop($image, $x, $y, $width, $height);
+ function crop(ImageFile $image, $x, $y, $width, $height);
/**
* Converts an image resource to grayscale.
*
* Note that transparent GIFs loose transparency when desaturated.
*
- * @param object $image
+ * @param \Drupal\Core\Image\ImageFile $image
* An image object. The $image->resource value will be modified by this
* call.
*
* @return bool
* TRUE or FALSE, based on success.
- *
- * @see image_desaturate()
*/
- function desaturate($image);
+ function desaturate(ImageFile $image);
/**
* Creates an image resource from a file.
*
- * @param object $image
+ * @param \Drupal\Core\Image\ImageFile $image
* An image object. The $image->resource value will populated by this call.
*
* @return bool
* TRUE or FALSE, based on success.
- *
- * @see image_load()
*/
- function load($image);
+ function load(ImageFile $image);
/**
* Writes an image resource to a destination file.
*
- * @param object $image
+ * @param \Drupal\Core\Image\ImageFile $image
* An image object.
* @param string $destination
* A string file URI or path where the image should be saved.
*
* @return bool
* TRUE or FALSE, based on success.
- *
- * @see image_save()
*/
- function save($image, $destination);
+ function save(ImageFile $image, $destination);
/**
* Gets details about an image.
*
- * @param object $image
+ * @param \Drupal\Core\Image\ImageFile $image
* An image object.
*
* @return array
@@ -151,7 +144,7 @@ function save($image, $destination);
*
* @see image_get_info()
*/
- function getInfo($image);
+ function getInfo(ImageFile $image);
/**
* Verifies Image Toolkit is set up correctly.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitGdTest.php b/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitGdTest.php
index 624dc79..fb03c41 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitGdTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitGdTest.php
@@ -7,6 +7,7 @@
namespace Drupal\system\Tests\Image;
+use Drupal\Core\Image\ImageFile;
use Drupal\simpletest\DrupalUnitTestBase;
use Drupal\system\Plugin\ImageToolkitManager;
@@ -79,15 +80,15 @@ function colorsAreEqual($color_a, $color_b) {
/**
* Function for finding a pixel's RGBa values.
*/
- function getPixelColor($image, $x, $y) {
- $color_index = imagecolorat($image->resource, $x, $y);
+ function getPixelColor(ImageFile $image, $x, $y) {
+ $color_index = imagecolorat($image->getResource(), $x, $y);
- $transparent_index = imagecolortransparent($image->resource);
+ $transparent_index = imagecolortransparent($image->getResource());
if ($color_index == $transparent_index) {
return array(0, 0, 0, 127);
}
- return array_values(imagecolorsforindex($image->resource, $color_index));
+ return array_values(imagecolorsforindex($image->getResource(), $color_index));
}
/**
@@ -110,49 +111,49 @@ function testManipulations() {
// Setup a list of tests to perform on each type.
$operations = array(
'resize' => array(
- 'function' => 'resize',
+ 'method' => 'resize',
'arguments' => array(20, 10),
'width' => 20,
'height' => 10,
'corners' => $default_corners,
),
'scale_x' => array(
- 'function' => 'scale',
+ 'method' => 'scale',
'arguments' => array(20, NULL),
'width' => 20,
'height' => 10,
'corners' => $default_corners,
),
'scale_y' => array(
- 'function' => 'scale',
+ 'method' => 'scale',
'arguments' => array(NULL, 10),
'width' => 20,
'height' => 10,
'corners' => $default_corners,
),
'upscale_x' => array(
- 'function' => 'scale',
+ 'method' => 'scale',
'arguments' => array(80, NULL, TRUE),
'width' => 80,
'height' => 40,
'corners' => $default_corners,
),
'upscale_y' => array(
- 'function' => 'scale',
+ 'method' => 'scale',
'arguments' => array(NULL, 40, TRUE),
'width' => 80,
'height' => 40,
'corners' => $default_corners,
),
'crop' => array(
- 'function' => 'crop',
+ 'method' => 'crop',
'arguments' => array(12, 4, 16, 12),
'width' => 16,
'height' => 12,
'corners' => array_fill(0, 4, $this->white),
),
'scale_and_crop' => array(
- 'function' => 'scale_and_crop',
+ 'method' => 'scaleAndCrop',
'arguments' => array(10, 8),
'width' => 10,
'height' => 8,
@@ -164,28 +165,28 @@ function testManipulations() {
if (function_exists('imagerotate')) {
$operations += array(
'rotate_5' => array(
- 'function' => 'rotate',
+ 'method' => 'rotate',
'arguments' => array(5, 0xFF00FF), // Fuchsia background.
'width' => 42,
'height' => 24,
'corners' => array_fill(0, 4, $this->fuchsia),
),
'rotate_90' => array(
- 'function' => 'rotate',
+ 'method' => 'rotate',
'arguments' => array(90, 0xFF00FF), // Fuchsia background.
'width' => 20,
'height' => 40,
'corners' => array($this->transparent, $this->red, $this->green, $this->blue),
),
'rotate_transparent_5' => array(
- 'function' => 'rotate',
+ 'method' => 'rotate',
'arguments' => array(5),
'width' => 42,
'height' => 24,
'corners' => array_fill(0, 4, $this->transparent),
),
'rotate_transparent_90' => array(
- 'function' => 'rotate',
+ 'method' => 'rotate',
'arguments' => array(90),
'width' => 20,
'height' => 40,
@@ -198,7 +199,7 @@ function testManipulations() {
if (function_exists('imagefilter')) {
$operations += array(
'desaturate' => array(
- 'function' => 'desaturate',
+ 'method' => 'desaturate',
'arguments' => array(),
'height' => 20,
'width' => 40,
@@ -219,17 +220,17 @@ function testManipulations() {
foreach ($files as $file) {
foreach ($operations as $op => $values) {
// Load up a fresh image.
- $image = image_load(drupal_get_path('module', 'simpletest') . '/files/' . $file, $manager->createInstance('gd'));
+ $image = new ImageFile(drupal_get_path('module', 'simpletest') . '/files/' . $file, $manager->createInstance('gd'));
if (!$image) {
$this->fail(t('Could not load image %file.', array('%file' => $file)));
continue 2;
}
// All images should be converted to truecolor when loaded.
- $image_truecolor = imageistruecolor($image->resource);
+ $image_truecolor = imageistruecolor($image->getResource());
$this->assertTrue($image_truecolor, format_string('Image %file after load is a truecolor image.', array('%file' => $file)));
- if ($image->info['extension'] == 'gif') {
+ if ($image->get('extension') == 'gif') {
if ($op == 'desaturate') {
// Transparent GIFs and the imagefilter function don't work together.
$values['corners'][3][3] = 0;
@@ -237,11 +238,7 @@ function testManipulations() {
}
// Perform our operation.
- $function = 'image_' . $values['function'];
- $arguments = array();
- $arguments[] = &$image;
- $arguments = array_merge($arguments, $values['arguments']);
- call_user_func_array($function, $arguments);
+ call_user_func_array(array($image, $values['method']), $values['arguments']);
// To keep from flooding the test with assert values, make a general
// value for whether each group of values fail.
@@ -250,24 +247,24 @@ function testManipulations() {
$correct_colors = TRUE;
// Check the real dimensions of the image first.
- if (imagesy($image->resource) != $values['height'] || imagesx($image->resource) != $values['width']) {
+ if (imagesy($image->getResource()) != $values['height'] || imagesx($image->getResource()) != $values['width']) {
$correct_dimensions_real = FALSE;
}
// Check that the image object has an accurate record of the dimensions.
- if ($image->info['width'] != $values['width'] || $image->info['height'] != $values['height']) {
+ if ($image->get('width') != $values['width'] || $image->get('height') != $values['height']) {
$correct_dimensions_object = FALSE;
}
$directory = $this->public_files_directory .'/imagetest';
file_prepare_directory($directory, FILE_CREATE_DIRECTORY);
- image_save($image, $directory . '/' . $op . '.' . $image->info['extension']);
+ $image->save($directory . '/' . $op . '.' . $image->get('extension'));
$this->assertTrue($correct_dimensions_real, format_string('Image %file after %action action has proper dimensions.', array('%file' => $file, '%action' => $op)));
$this->assertTrue($correct_dimensions_object, format_string('Image %file object after %action action is reporting the proper height and width values.', array('%file' => $file, '%action' => $op)));
// JPEG colors will always be messed up due to compression.
- if ($image->info['extension'] != 'jpg') {
+ if ($image->get('extension') != 'jpg') {
// Now check each of the corners to ensure color correctness.
foreach ($values['corners'] as $key => $corner) {
// Get the location of the corner.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTest.php b/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTest.php
index 24e10b0..0713e3b 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTest.php
@@ -7,6 +7,7 @@
namespace Drupal\system\Tests\Image;
+use Drupal\Core\Image\ImageFile;
use Drupal\system\Plugin\ImageToolkitManager;
/**
@@ -37,9 +38,10 @@ function testGetAvailableToolkits() {
* Test the image_load() function.
*/
function testLoad() {
- $image = image_load($this->file, $this->toolkit);
+ $image = new ImageFile($this->file);
+ $image->setToolkit($this->toolkit)->getResource();
$this->assertTrue(is_object($image), 'Returned an object.');
- $this->assertEqual($this->toolkit, $image->toolkit, t('Image had toolkit set.'));
+ $this->assertEqual($this->toolkit->getPluginId(), $image->getToolkitId(), t('Image had toolkit set.'));
$this->assertToolkitOperationsCalled(array('load', 'get_info'));
}
@@ -47,7 +49,7 @@ function testLoad() {
* Test the image_save() function.
*/
function testSave() {
- $this->assertFalse(image_save($this->image), 'Function returned the expected value.');
+ $this->assertFalse($this->image->save(), 'Function returned the expected value.');
$this->assertToolkitOperationsCalled(array('save'));
}
@@ -55,7 +57,7 @@ function testSave() {
* Test the image_resize() function.
*/
function testResize() {
- $this->assertTrue(image_resize($this->image, 1, 2), 'Function returned the expected value.');
+ $this->assertTrue($this->image->resize(1, 2), 'Function returned the expected value.');
$this->assertToolkitOperationsCalled(array('resize'));
// Check the parameters.
@@ -69,7 +71,7 @@ function testResize() {
*/
function testScale() {
// TODO: need to test upscaling
- $this->assertTrue(image_scale($this->image, 10, 10), 'Function returned the expected value.');
+ $this->assertTrue($this->image->scale(10, 10), 'Function returned the expected value.');
$this->assertToolkitOperationsCalled(array('resize'));
// Check the parameters.
@@ -82,7 +84,7 @@ function testScale() {
* Test the image_scale_and_crop() function.
*/
function testScaleAndCrop() {
- $this->assertTrue(image_scale_and_crop($this->image, 5, 10), 'Function returned the expected value.');
+ $this->assertTrue($this->image->scaleAndCrop(5, 10), 'Function returned the expected value.');
$this->assertToolkitOperationsCalled(array('resize', 'crop'));
// Check the parameters.
@@ -98,7 +100,7 @@ function testScaleAndCrop() {
* Test the image_rotate() function.
*/
function testRotate() {
- $this->assertTrue(image_rotate($this->image, 90, 1), 'Function returned the expected value.');
+ $this->assertTrue($this->image->rotate(90, 1), 'Function returned the expected value.');
$this->assertToolkitOperationsCalled(array('rotate'));
// Check the parameters.
@@ -111,7 +113,7 @@ function testRotate() {
* Test the image_crop() function.
*/
function testCrop() {
- $this->assertTrue(image_crop($this->image, 1, 2, 3, 4), 'Function returned the expected value.');
+ $this->assertTrue($this->image->crop(1, 2, 3, 4), 'Function returned the expected value.');
$this->assertToolkitOperationsCalled(array('crop'));
// Check the parameters.
@@ -126,7 +128,7 @@ function testCrop() {
* Test the image_desaturate() function.
*/
function testDesaturate() {
- $this->assertTrue(image_desaturate($this->image), 'Function returned the expected value.');
+ $this->assertTrue($this->image->desaturate(), 'Function returned the expected value.');
$this->assertToolkitOperationsCalled(array('desaturate'));
// Check the parameters.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTestBase.php
index 80b1588..f2f8c39 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTestBase.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTestBase.php
@@ -7,6 +7,7 @@
namespace Drupal\system\Tests\Image;
+use Drupal\Core\Image\ImageFile;
use Drupal\simpletest\WebTestBase;
use Drupal\system\Plugin\ImageToolkitManager;
use stdClass;
@@ -23,8 +24,19 @@
*/
public static $modules = array('image_test');
+ /**
+ * @var \Drupal\system\Plugin\ImageToolkitInterface
+ */
protected $toolkit;
+
+ /**
+ * @var string
+ */
protected $file;
+
+ /**
+ * @var \Drupal\Core\Image\ImageFile
+ */
protected $image;
function setUp() {
@@ -40,10 +52,9 @@ function setUp() {
// Setup a dummy image to work with, this replicate image_load() so we
// can avoid calling it.
- $this->image = new stdClass();
- $this->image->source = $this->file;
- $this->image->info = image_get_info($this->file);
- $this->image->toolkit = $this->toolkit;
+ $this->image = new ImageFile($this->file);
+ $this->image->setToolkit($this->toolkit);
+ $this->image->setInfo(image_get_info($this->file));
// Clear out any hook calls.
$this->imageTestReset();
diff --git a/core/modules/system/tests/modules/image_test/lib/Drupal/image_test/Plugin/ImageToolkit/TestToolkit.php b/core/modules/system/tests/modules/image_test/lib/Drupal/image_test/Plugin/ImageToolkit/TestToolkit.php
index 12ebae7..8203b18 100644
--- a/core/modules/system/tests/modules/image_test/lib/Drupal/image_test/Plugin/ImageToolkit/TestToolkit.php
+++ b/core/modules/system/tests/modules/image_test/lib/Drupal/image_test/Plugin/ImageToolkit/TestToolkit.php
@@ -10,6 +10,7 @@
use Drupal\Component\Plugin\PluginBase;
use Drupal\Component\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Image\ImageFile;
use Drupal\system\Plugin\ImageToolkitInterface;
/**
@@ -38,7 +39,7 @@ public function settingsFormSubmit($form, &$form_state) {}
/**
* Implements \Drupal\system\Plugin\ImageToolkitInterface::getInfo().
*/
- public function getInfo($image) {
+ public function getInfo(ImageFile $image) {
$this->logCall('get_info', array($image));
return array();
}
@@ -46,7 +47,7 @@ public function getInfo($image) {
/**
* Implements \Drupal\system\Plugin\ImageToolkitInterface::load().
*/
- public function load($image) {
+ public function load(ImageFile $image) {
$this->logCall('load', array($image));
return $image;
}
@@ -54,7 +55,7 @@ public function load($image) {
/**
* Implements \Drupal\system\Plugin\ImageToolkitInterface::save().
*/
- public function save($image, $destination) {
+ public function save(ImageFile $image, $destination) {
$this->logCall('save', array($image, $destination));
// Return false so that image_save() doesn't try to chmod the destination
// file that we didn't bother to create.
@@ -64,7 +65,7 @@ public function save($image, $destination) {
/**
* Implements \Drupal\system\Plugin\ImageToolkitInterface::crop().
*/
- public function crop($image, $x, $y, $width, $height) {
+ public function crop(ImageFile $image, $x, $y, $width, $height) {
$this->logCall('crop', array($image, $x, $y, $width, $height));
return TRUE;
}
@@ -72,7 +73,7 @@ public function crop($image, $x, $y, $width, $height) {
/**
* Implements \Drupal\system\Plugin\ImageToolkitInterface::resize().
*/
- public function resize($image, $width, $height) {
+ public function resize(ImageFile $image, $width, $height) {
$this->logCall('resize', array($image, $width, $height));
return TRUE;
}
@@ -80,7 +81,7 @@ public function resize($image, $width, $height) {
/**
* Implements \Drupal\system\Plugin\ImageToolkitInterface::rotate().
*/
- public function rotate($image, $degrees, $background = NULL) {
+ public function rotate(ImageFile $image, $degrees, $background = NULL) {
$this->logCall('rotate', array($image, $degrees, $background));
return TRUE;
}
@@ -88,7 +89,7 @@ public function rotate($image, $degrees, $background = NULL) {
/**
* Implements \Drupal\system\Plugin\ImageToolkitInterface::desaturate().
*/
- public function desaturate($image) {
+ public function desaturate(ImageFile $image) {
$this->logCall('desaturate', array($image));
return TRUE;
}