Issue #2211227 by mondrake, xjm | fietserwin: Refactor image and imagetoolkit: isExisting, isSupported, supportedTypes, getMimeType.
parent
22fc66d5e4
commit
ae8eb106ef
|
@ -20,11 +20,11 @@ use Drupal\Core\ImageToolkit\ImageToolkitInterface;
|
|||
class Image implements ImageInterface {
|
||||
|
||||
/**
|
||||
* String specifying the path of the image file.
|
||||
* Path of the image file.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $source;
|
||||
protected $source = '';
|
||||
|
||||
/**
|
||||
* An image toolkit object.
|
||||
|
@ -33,26 +33,19 @@ class Image implements ImageInterface {
|
|||
*/
|
||||
protected $toolkit;
|
||||
|
||||
/**
|
||||
* Image type represented by a PHP IMAGETYPE_* constant (e.g. IMAGETYPE_JPEG).
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* File size in bytes.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $fileSize = 0;
|
||||
protected $fileSize;
|
||||
|
||||
/**
|
||||
* If this image file has been processed.
|
||||
* If this image object is valid.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $processed = FALSE;
|
||||
protected $valid = FALSE;
|
||||
|
||||
/**
|
||||
* Constructs a new Image object.
|
||||
|
@ -67,30 +60,21 @@ class Image implements ImageInterface {
|
|||
$this->toolkit = $toolkit;
|
||||
if ($source) {
|
||||
$this->source = $source;
|
||||
$this->processInfo();
|
||||
$this->parseFile();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isSupported() {
|
||||
return in_array($this->getType(), $this->toolkit->supportedTypes());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isExisting() {
|
||||
$this->processInfo();
|
||||
return $this->processed;
|
||||
public function isValid() {
|
||||
return $this->valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHeight() {
|
||||
$this->processInfo();
|
||||
return $this->toolkit->getHeight($this);
|
||||
}
|
||||
|
||||
|
@ -98,7 +82,6 @@ class Image implements ImageInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getWidth() {
|
||||
$this->processInfo();
|
||||
return $this->toolkit->getWidth($this);
|
||||
}
|
||||
|
||||
|
@ -106,32 +89,14 @@ class Image implements ImageInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFileSize() {
|
||||
$this->processInfo();
|
||||
return $this->fileSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getType() {
|
||||
$this->processInfo();
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMimeType() {
|
||||
$this->processInfo();
|
||||
return $this->type ? image_type_to_mime_type($this->type) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setSource($source) {
|
||||
$this->source = $source;
|
||||
return $this;
|
||||
return $this->toolkit->getMimeType($this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -152,7 +117,6 @@ class Image implements ImageInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getToolkit() {
|
||||
$this->processInfo();
|
||||
return $this->toolkit;
|
||||
}
|
||||
|
||||
|
@ -160,14 +124,17 @@ class Image implements ImageInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function save($destination = NULL) {
|
||||
if (empty($destination)) {
|
||||
$destination = $this->getSource();
|
||||
// Return immediately if the image is not valid.
|
||||
if (!$this->isValid()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$destination = $destination ?: $this->getSource();
|
||||
if ($return = $this->toolkit->save($this, $destination)) {
|
||||
// Clear the cached file size and refresh the image information.
|
||||
clearstatcache(TRUE, $destination);
|
||||
$this->setSource($destination);
|
||||
$this->processInfo();
|
||||
$this->fileSize = filesize($destination);
|
||||
$this->source = $destination;
|
||||
|
||||
// @todo Use File utility when https://drupal.org/node/2050759 is in.
|
||||
if ($this->chmod($destination)) {
|
||||
|
@ -178,7 +145,7 @@ class Image implements ImageInterface {
|
|||
}
|
||||
|
||||
/**
|
||||
* Prepares the image information.
|
||||
* Determines if a file contains a valid image.
|
||||
*
|
||||
* Drupal supports GIF, JPG and PNG file formats when used with the GD
|
||||
* toolkit, and may support others, depending on which toolkits are
|
||||
|
@ -188,23 +155,11 @@ class Image implements ImageInterface {
|
|||
* FALSE, if the file could not be found or is not an image. Otherwise, the
|
||||
* image information is populated.
|
||||
*/
|
||||
protected function processInfo() {
|
||||
if ($this->processed) {
|
||||
return TRUE;
|
||||
protected function parseFile() {
|
||||
if ($this->valid = $this->toolkit->parseFile($this)) {
|
||||
$this->fileSize = filesize($this->source);
|
||||
}
|
||||
|
||||
$destination = $this->getSource();
|
||||
if (!is_file($destination) && !is_uploaded_file($destination)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ($details = $this->toolkit->getInfo($this)) {
|
||||
$this->type = $details['type'];
|
||||
$this->fileSize = filesize($destination);
|
||||
|
||||
$this->processed = TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
return $this->valid;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -227,22 +182,23 @@ class Image implements ImageInterface {
|
|||
*/
|
||||
public function __call($method, $arguments) {
|
||||
// @todo Temporary to avoid that legacy GD setResource(), getResource(),
|
||||
// hasResource() methods moved to GD toolkit in #2103621, and setWidth(),
|
||||
// setHeight() methods moved to ImageToolkitInterface in #2196067 get
|
||||
// hasResource() methods moved to GD toolkit in #2103621, setWidth(),
|
||||
// setHeight() methods moved to ImageToolkitInterface in #2196067,
|
||||
// getType() method moved to GDToolkit in #2211227 get
|
||||
// invoked from this class anyway through the magic __call. Will be
|
||||
// removed through https://drupal.org/node/2110499, when
|
||||
// removed through https://drupal.org/node/2073759, when
|
||||
// call_user_func_array() will be replaced by
|
||||
// $this->toolkit->apply($name, $this, $arguments).
|
||||
if (in_array($method, array('setResource', 'getResource', 'hasResource', 'setWidth', 'setHeight'))) {
|
||||
throw new \BadMethodCallException();
|
||||
if (in_array($method, array('setResource', 'getResource', 'hasResource', 'setWidth', 'setHeight', 'getType'))) {
|
||||
throw new \BadMethodCallException($method);
|
||||
}
|
||||
if (is_callable(array($this->toolkit, $method))) {
|
||||
// @todo In https://drupal.org/node/2110499, call_user_func_array() will
|
||||
// @todo In https://drupal.org/node/2073759, call_user_func_array() will
|
||||
// be replaced by $this->toolkit->apply($name, $this, $arguments).
|
||||
array_unshift($arguments, $this);
|
||||
return call_user_func_array(array($this->toolkit, $method), $arguments);
|
||||
}
|
||||
throw new \BadMethodCallException();
|
||||
throw new \BadMethodCallException($method);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -90,4 +90,23 @@ class ImageFactory {
|
|||
$toolkit_id = $toolkit_id ?: $this->toolkitId;
|
||||
return new Image($this->toolkitManager->createInstance($toolkit_id), $source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the image file extensions supported by the toolkit.
|
||||
*
|
||||
* @param string|null $toolkit_id
|
||||
* (optional) The ID of the image toolkit to use for checking, or NULL
|
||||
* to use the current toolkit.
|
||||
*
|
||||
* @return array
|
||||
* An array of supported image file extensions (e.g. png/jpeg/gif).
|
||||
*
|
||||
* @see \Drupal\Core\ImageToolkit\ImageToolkitInterface::getSupportedExtensions()
|
||||
*/
|
||||
public function getSupportedExtensions($toolkit_id = NULL) {
|
||||
$toolkit_id = $toolkit_id ?: $this->toolkitId;
|
||||
$definition = $this->toolkitManager->getDefinition($toolkit_id);
|
||||
return call_user_func($definition['class'] . '::getSupportedExtensions');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,20 +13,12 @@ namespace Drupal\Core\Image;
|
|||
interface ImageInterface {
|
||||
|
||||
/**
|
||||
* Checks if the image format is supported.
|
||||
* Checks if the image is valid.
|
||||
*
|
||||
* @return bool
|
||||
* Returns TRUE if the image format is supported by the toolkit.
|
||||
* TRUE if the image object contains a valid image, FALSE otherwise.
|
||||
*/
|
||||
public function isSupported();
|
||||
|
||||
/**
|
||||
* Checks if the image is existing.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the image exists and is a valid image, FALSE otherwise.
|
||||
*/
|
||||
public function isExisting();
|
||||
public function isValid();
|
||||
|
||||
/**
|
||||
* Returns the height of the image.
|
||||
|
@ -47,20 +39,11 @@ interface ImageInterface {
|
|||
/**
|
||||
* Returns the size of the image file.
|
||||
*
|
||||
* @return int
|
||||
* The size of the file in bytes, or 0 if the file is invalid.
|
||||
* @return int|null
|
||||
* The size of the file in bytes, or NULL if the image is invalid.
|
||||
*/
|
||||
public function getFileSize();
|
||||
|
||||
/**
|
||||
* Returns the type of the image.
|
||||
*
|
||||
* @return int
|
||||
* The image type represented by a PHP IMAGETYPE_* constant (e.g.
|
||||
* IMAGETYPE_JPEG).
|
||||
*/
|
||||
public function getType();
|
||||
|
||||
/**
|
||||
* Returns the MIME type of the image file.
|
||||
*
|
||||
|
@ -70,22 +53,12 @@ interface ImageInterface {
|
|||
*/
|
||||
public function getMimeType();
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Retrieves the source path of the image file.
|
||||
*
|
||||
* @return string
|
||||
* The source path of the image file.
|
||||
* The source path of the image file. An empty string if the source is
|
||||
* not set.
|
||||
*/
|
||||
public function getSource();
|
||||
|
||||
|
|
|
@ -185,19 +185,15 @@ interface ImageToolkitInterface extends PluginInspectionInterface {
|
|||
public function scaleAndCrop(ImageInterface $image, $width, $height);
|
||||
|
||||
/**
|
||||
* Gets details about an image.
|
||||
* Determines if a file contains a valid image.
|
||||
*
|
||||
* @param \Drupal\Core\Image\ImageInterface $image
|
||||
* An image object.
|
||||
*
|
||||
* @return array
|
||||
* If the file could not be found or is not an image, an empty array;
|
||||
* otherwise, a keyed array containing information about the image:
|
||||
* - "type": Image type represented as an IMAGETYPE_* constant.
|
||||
*
|
||||
* @see \Drupal\Core\Image\ImageInterface::processInfo()
|
||||
* @return bool
|
||||
* TRUE if the file could be found and is an image, FALSE otherwise.
|
||||
*/
|
||||
public function getInfo(ImageInterface $image);
|
||||
public function parseFile(ImageInterface $image);
|
||||
|
||||
/**
|
||||
* Returns the height of the image.
|
||||
|
@ -221,6 +217,18 @@ interface ImageToolkitInterface extends PluginInspectionInterface {
|
|||
*/
|
||||
public function getWidth(ImageInterface $image);
|
||||
|
||||
/**
|
||||
* Returns the MIME type of the image file.
|
||||
*
|
||||
* @param \Drupal\Core\Image\ImageInterface $image
|
||||
* An image object.
|
||||
*
|
||||
* @return string
|
||||
* The MIME type of the image file, or an empty string if the image is
|
||||
* invalid.
|
||||
*/
|
||||
public function getMimeType(ImageInterface $image);
|
||||
|
||||
/**
|
||||
* Gets toolkit requirements in a format suitable for hook_requirements().
|
||||
*
|
||||
|
@ -244,12 +252,11 @@ interface ImageToolkitInterface extends PluginInspectionInterface {
|
|||
public static function isAvailable();
|
||||
|
||||
/**
|
||||
* Returns a list of image types supported by the toolkit.
|
||||
* Returns a list of image file extensions supported by the toolkit.
|
||||
*
|
||||
* @return array
|
||||
* An array of available image types. An image type is represented by a PHP
|
||||
* IMAGETYPE_* constant (e.g. IMAGETYPE_JPEG, IMAGETYPE_PNG, etc.).
|
||||
* An array of supported image file extensions (e.g. png/jpeg/gif).
|
||||
*/
|
||||
public static function supportedTypes();
|
||||
public static function getSupportedExtensions();
|
||||
|
||||
}
|
||||
|
|
|
@ -410,7 +410,7 @@ function file_validate_size(File $file, $file_limit = 0, $user_limit = 0) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks that the file is recognized by Image::getInfo() as an image.
|
||||
* Checks that the file is recognized as a valid image.
|
||||
*
|
||||
* @param \Drupal\file\File $file
|
||||
* A file entity.
|
||||
|
@ -423,13 +423,11 @@ function file_validate_size(File $file, $file_limit = 0, $user_limit = 0) {
|
|||
function file_validate_is_image(File $file) {
|
||||
$errors = array();
|
||||
|
||||
$image = \Drupal::service('image.factory')->get($file->getFileUri());
|
||||
if (!$image->isSupported()) {
|
||||
$extensions = array();
|
||||
foreach ($image->getToolkit()->supportedTypes() as $image_type) {
|
||||
$extensions[] = Unicode::strtoupper(image_type_to_extension($image_type));
|
||||
}
|
||||
$errors[] = t('Image type not supported. Allowed types: @types.', array('@types' => implode(', ', $extensions)));
|
||||
$image_factory = \Drupal::service('image.factory');
|
||||
$image = $image_factory->get($file->getFileUri());
|
||||
if (!$image->isValid()) {
|
||||
$supported_extensions = $image_factory->getSupportedExtensions();
|
||||
$errors[] = t('Image type not supported. Allowed types: %types', array('%types' => implode(' ', $supported_extensions)));
|
||||
}
|
||||
|
||||
return $errors;
|
||||
|
@ -464,21 +462,19 @@ function file_validate_image_resolution(File $file, $maximum_dimensions = 0, $mi
|
|||
// Check first that the file is an image.
|
||||
$image_factory = \Drupal::service('image.factory');
|
||||
$image = $image_factory->get($file->getFileUri());
|
||||
if ($image->isSupported()) {
|
||||
if ($image->isValid()) {
|
||||
if ($maximum_dimensions) {
|
||||
// Check that it is smaller than the given dimensions.
|
||||
list($width, $height) = explode('x', $maximum_dimensions);
|
||||
if ($image->getWidth() > $width || $image->getHeight() > $height) {
|
||||
// Try to resize the image to fit the dimensions.
|
||||
$image = $image_factory->get($file->getFileUri());
|
||||
if ($image->isExisting()) {
|
||||
$image->scale($width, $height);
|
||||
if ($image->scale($width, $height)) {
|
||||
$image->save();
|
||||
$file->filesize = $image->getFileSize();
|
||||
drupal_set_message(t('The image was resized to fit within the maximum allowed dimensions of %dimensions pixels.', array('%dimensions' => $maximum_dimensions)));
|
||||
}
|
||||
else {
|
||||
$errors[] = t('The image is too large; the maximum dimensions are %dimensions pixels.', array('%dimensions' => $maximum_dimensions));
|
||||
$errors[] = t('The image exceeds the maximum allowed dimensions and an attempt to resize it failed.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,6 +91,12 @@ class ValidatorTest extends FileManagedUnitTestBase {
|
|||
$this->assertTrue($image->getWidth() <= 10, 'Image scaled to correct width.', 'File');
|
||||
$this->assertTrue($image->getHeight() <= 5, 'Image scaled to correct height.', 'File');
|
||||
|
||||
// Once again, now with negative width and height to force an error.
|
||||
copy('core/misc/druplicon.png', 'temporary://druplicon.png');
|
||||
$this->image->setFileUri('temporary://druplicon.png');
|
||||
$errors = file_validate_image_resolution($this->image, '-10x-5');
|
||||
$this->assertEqual(count($errors), 1, 'An error reported for an oversized image that can not be scaled down.', 'File');
|
||||
|
||||
drupal_unlink('temporary://druplicon.png');
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -184,7 +184,7 @@ function image_file_download($uri) {
|
|||
|
||||
// Check that the file exists and is an image.
|
||||
$image = \Drupal::service('image.factory')->get($uri);
|
||||
if ($image->isSupported()) {
|
||||
if ($image->isValid()) {
|
||||
// Check the permissions of the original to grant access to this image.
|
||||
$headers = \Drupal::moduleHandler()->invokeAll('file_download', array($original_uri));
|
||||
// Confirm there's at least one module granting access and none denying access.
|
||||
|
|
|
@ -276,7 +276,7 @@ class ImageStyle extends ConfigEntityBase implements ImageStyleInterface, Entity
|
|||
}
|
||||
|
||||
$image = \Drupal::service('image.factory')->get($original_uri);
|
||||
if (!$image->isExisting()) {
|
||||
if (!$image->isValid()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -303,7 +303,7 @@ class ImageItem extends FileItem {
|
|||
// Determine the dimensions if necessary.
|
||||
if (empty($width) || empty($height)) {
|
||||
$image = \Drupal::service('image.factory')->get($this->entity->getFileUri());
|
||||
if ($image->isSupported()) {
|
||||
if ($image->isValid()) {
|
||||
$this->width = $image->getWidth();
|
||||
$this->height =$image->getHeight();
|
||||
}
|
||||
|
|
|
@ -166,7 +166,7 @@ class ImageWidget extends FileWidget {
|
|||
}
|
||||
else {
|
||||
$image = \Drupal::service('image.factory')->get($file->getFileUri());
|
||||
if ($image->isExisting()) {
|
||||
if ($image->isValid()) {
|
||||
$variables['width'] = $image->getWidth();
|
||||
$variables['height'] = $image->getHeight();
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\system\Plugin\ImageToolkit;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Image\ImageInterface;
|
||||
use Drupal\Core\ImageToolkit\ImageToolkitBase;
|
||||
use Drupal\Component\Utility\Image as ImageUtility;
|
||||
|
@ -28,6 +29,13 @@ class GDToolkit extends ImageToolkitBase {
|
|||
*/
|
||||
protected $resource;
|
||||
|
||||
/**
|
||||
* Image type represented by a PHP IMAGETYPE_* constant (e.g. IMAGETYPE_JPEG).
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* Sets the GD image resource.
|
||||
*
|
||||
|
@ -86,7 +94,11 @@ class GDToolkit extends ImageToolkitBase {
|
|||
$width = (int) round($width);
|
||||
$height = (int) round($height);
|
||||
|
||||
$res = $this->createTmp($image->getType(), $width, $height);
|
||||
if ($width <= 0 || $height <= 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$res = $this->createTmp($this->getType(), $width, $height);
|
||||
|
||||
if (!imagecopyresampled($res, $this->getResource(), 0, 0, 0, 0, $width, $height, $this->getWidth($image), $this->getHeight($image))) {
|
||||
return FALSE;
|
||||
|
@ -129,7 +141,7 @@ class GDToolkit extends ImageToolkitBase {
|
|||
|
||||
// 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->getType() == IMAGETYPE_GIF) {
|
||||
if ($this->getType() == IMAGETYPE_GIF) {
|
||||
$transparent_index = imagecolortransparent($this->getResource());
|
||||
if ($transparent_index != 0) {
|
||||
$transparent_gif_color = imagecolorsforindex($this->getResource(), $transparent_index);
|
||||
|
@ -159,7 +171,11 @@ class GDToolkit extends ImageToolkitBase {
|
|||
$width = (int) round($width);
|
||||
$height = (int) round($height);
|
||||
|
||||
$res = $this->createTmp($image->getType(), $width, $height);
|
||||
if ($width <= 0 || $height <= 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$res = $this->createTmp($this->getType(), $width, $height);
|
||||
|
||||
if (!imagecopyresampled($res, $this->getResource(), 0, 0, $x, $y, $width, $height, $width, $height)) {
|
||||
return FALSE;
|
||||
|
@ -221,31 +237,28 @@ class GDToolkit extends ImageToolkitBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates a resource from a file.
|
||||
* Loads a GD resource from a file.
|
||||
*
|
||||
* @param string $source
|
||||
* String specifying the path of the image file.
|
||||
* @param array $details
|
||||
* An array of image details.
|
||||
* @param \Drupal\Core\Image\ImageInterface $image
|
||||
* An image object.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE or FALSE, based on success.
|
||||
*/
|
||||
protected function load($source, array $details) {
|
||||
$function = 'imagecreatefrom' . image_type_to_extension($details['type'], FALSE);
|
||||
if (function_exists($function) && $resource = $function($source)) {
|
||||
protected function load($image) {
|
||||
$function = 'imagecreatefrom' . image_type_to_extension($this->getType(), FALSE);
|
||||
if (function_exists($function) && $resource = $function($image->getSource())) {
|
||||
$this->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($details['type'], imagesx($resource), imagesy($resource));
|
||||
$new_image = $this->createTmp($this->getType(), imagesx($resource), imagesy($resource));
|
||||
imagecopy($new_image, $resource, 0, 0, 0, 0, imagesx($resource), imagesy($resource));
|
||||
imagedestroy($resource);
|
||||
$this->setResource($new_image);
|
||||
}
|
||||
return (bool) $this->getResource();
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -266,16 +279,16 @@ class GDToolkit extends ImageToolkitBase {
|
|||
$destination = drupal_realpath($destination);
|
||||
}
|
||||
|
||||
$function = 'image' . image_type_to_extension($image->getType(), FALSE);
|
||||
$function = 'image' . image_type_to_extension($this->getType(), FALSE);
|
||||
if (!function_exists($function)) {
|
||||
return FALSE;
|
||||
}
|
||||
if ($image->getType() == IMAGETYPE_JPEG) {
|
||||
if ($this->getType() == IMAGETYPE_JPEG) {
|
||||
$success = $function($this->getResource(), $destination, \Drupal::config('system.image.gd')->get('jpeg_quality'));
|
||||
}
|
||||
else {
|
||||
// Always save PNG images with full transparency.
|
||||
if ($image->getType() == IMAGETYPE_PNG) {
|
||||
if ($this->getType() == IMAGETYPE_PNG) {
|
||||
imagealphablending($this->getResource(), FALSE);
|
||||
imagesavealpha($this->getResource(), TRUE);
|
||||
}
|
||||
|
@ -291,15 +304,14 @@ class GDToolkit extends ImageToolkitBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getInfo(ImageInterface $image) {
|
||||
$details = array();
|
||||
$data = getimagesize($image->getSource());
|
||||
|
||||
if (isset($data) && is_array($data) && in_array($data[2], static::supportedTypes())) {
|
||||
$details['type'] = $data[2];
|
||||
$this->load($image->getSource(), $details);
|
||||
public function parseFile(ImageInterface $image) {
|
||||
$data = @getimagesize($image->getSource());
|
||||
if ($data && in_array($data[2], static::supportedTypes())) {
|
||||
$this->setType($data[2]);
|
||||
$this->load($image);
|
||||
return (bool) $this->getResource();
|
||||
}
|
||||
return $details;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -370,6 +382,40 @@ class GDToolkit extends ImageToolkitBase {
|
|||
return $this->getResource() ? imagesy($this->getResource()) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the PHP type of the image.
|
||||
*
|
||||
* @return int
|
||||
* The image type represented by a PHP IMAGETYPE_* constant (e.g.
|
||||
* IMAGETYPE_JPEG).
|
||||
*/
|
||||
public function getType() {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the PHP type of the image.
|
||||
*
|
||||
* @param int $type
|
||||
* The image type represented by a PHP IMAGETYPE_* constant (e.g.
|
||||
* IMAGETYPE_JPEG).
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public function setType($type) {
|
||||
if (in_array($type, static::supportedTypes())) {
|
||||
$this->type = $type;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMimeType(ImageInterface $image) {
|
||||
return $this->getType() ? image_type_to_mime_type($this->getType()) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -402,7 +448,22 @@ class GDToolkit extends ImageToolkitBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function supportedTypes() {
|
||||
public static function getSupportedExtensions() {
|
||||
$extensions = array();
|
||||
foreach (static::supportedTypes() as $image_type) {
|
||||
$extensions[] = Unicode::strtolower(image_type_to_extension($image_type, FALSE));
|
||||
}
|
||||
return $extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of image types supported by the toolkit.
|
||||
*
|
||||
* @return array
|
||||
* An array of available image types. An image type is represented by a PHP
|
||||
* IMAGETYPE_* constant (e.g. IMAGETYPE_JPEG, IMAGETYPE_PNG, etc.).
|
||||
*/
|
||||
protected static function supportedTypes() {
|
||||
return array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -247,7 +247,7 @@ class ToolkitGdTest extends DrupalUnitTestBase {
|
|||
$image_truecolor = imageistruecolor($toolkit->getResource());
|
||||
$this->assertTrue($image_truecolor, String::format('Image %file after load is a truecolor image.', array('%file' => $file)));
|
||||
|
||||
if ($image->getType() == IMAGETYPE_GIF) {
|
||||
if ($image->getToolkit()->getType() == IMAGETYPE_GIF) {
|
||||
if ($op == 'desaturate') {
|
||||
// Transparent GIFs and the imagefilter function don't work together.
|
||||
$values['corners'][3][3] = 0;
|
||||
|
@ -274,14 +274,14 @@ class ToolkitGdTest extends DrupalUnitTestBase {
|
|||
|
||||
$directory = $this->public_files_directory .'/imagetest';
|
||||
file_prepare_directory($directory, FILE_CREATE_DIRECTORY);
|
||||
$file_path = $directory . '/' . $op . image_type_to_extension($image->getType());
|
||||
$file_path = $directory . '/' . $op . image_type_to_extension($image->getToolkit()->getType());
|
||||
$image->save($file_path);
|
||||
|
||||
$this->assertTrue($correct_dimensions_real, String::format('Image %file after %action action has proper dimensions.', array('%file' => $file, '%action' => $op)));
|
||||
$this->assertTrue($correct_dimensions_object, String::format('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->getType() != IMAGETYPE_JPEG) {
|
||||
if ($image->getToolkit()->getType() != IMAGETYPE_JPEG) {
|
||||
// Now check each of the corners to ensure color correctness.
|
||||
foreach ($values['corners'] as $key => $corner) {
|
||||
// Get the location of the corner.
|
||||
|
|
|
@ -38,7 +38,7 @@ class ToolkitTest extends ToolkitTestBase {
|
|||
$image = $this->getImage();
|
||||
$this->assertTrue(is_object($image), 'Returned an object.');
|
||||
$this->assertEqual($image->getToolkitId(), 'test', 'Image had toolkit set.');
|
||||
$this->assertToolkitOperationsCalled(array('load', 'get_info'));
|
||||
$this->assertToolkitOperationsCalled(array('parseFile'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -68,7 +68,7 @@ abstract class ToolkitTestBase extends WebTestBase {
|
|||
*/
|
||||
protected function getImage() {
|
||||
$image = $this->imageFactory->get($this->file, 'test');
|
||||
$this->assertTrue($image->isExisting(), 'Image was loaded.');
|
||||
$this->assertTrue($image->isValid(), 'Image was loaded.');
|
||||
return $image;
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ abstract class ToolkitTestBase extends WebTestBase {
|
|||
function imageTestReset() {
|
||||
// Keep track of calls to these operations
|
||||
$results = array(
|
||||
'load' => array(),
|
||||
'parseFile' => array(),
|
||||
'save' => array(),
|
||||
'settings' => array(),
|
||||
'resize' => array(),
|
||||
|
@ -124,9 +124,9 @@ abstract class ToolkitTestBase extends WebTestBase {
|
|||
* Gets an array of calls to the test toolkit.
|
||||
*
|
||||
* @return array
|
||||
* An array keyed by operation name ('load', 'save', 'settings', 'resize',
|
||||
* 'rotate', 'crop', 'desaturate') with values being arrays of parameters
|
||||
* passed to each call.
|
||||
* An array keyed by operation name ('parseFile', 'save', 'settings',
|
||||
* 'resize', 'rotate', 'crop', 'desaturate') with values being arrays of
|
||||
* parameters passed to each call.
|
||||
*/
|
||||
function imageTestGetAllCalls() {
|
||||
return \Drupal::state()->get('image_test.results') ?: array();
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\image_test\Plugin\ImageToolkit;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Image\ImageInterface;
|
||||
use Drupal\Core\ImageToolkit\ImageToolkitBase;
|
||||
|
||||
|
@ -20,6 +21,13 @@ use Drupal\Core\ImageToolkit\ImageToolkitBase;
|
|||
*/
|
||||
class TestToolkit extends ImageToolkitBase {
|
||||
|
||||
/**
|
||||
* Image type represented by a PHP IMAGETYPE_* constant (e.g. IMAGETYPE_JPEG).
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* The width of the image.
|
||||
*
|
||||
|
@ -62,35 +70,16 @@ class TestToolkit extends ImageToolkitBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getInfo(ImageInterface $image) {
|
||||
$this->logCall('get_info', array($image));
|
||||
|
||||
$details = array();
|
||||
$data = getimagesize($image->getSource());
|
||||
|
||||
if (isset($data) && is_array($data) && in_array($data[2], static::supportedTypes())) {
|
||||
$details['type'] = $data[2];
|
||||
public function parseFile(ImageInterface $image) {
|
||||
$this->logCall('parseFile', array($image));
|
||||
$data = @getimagesize($image->getSource());
|
||||
if ($data && in_array($data[2], static::supportedTypes())) {
|
||||
$this->setType($data[2]);
|
||||
$this->width = $data[0];
|
||||
$this->height = $data[1];
|
||||
$this->load($image->getSource(), $details);
|
||||
return TRUE;
|
||||
}
|
||||
return $details;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mimick loading the image from a file.
|
||||
*
|
||||
* @param string $source
|
||||
* String specifying the path of the image file.
|
||||
* @param array $details
|
||||
* An array of image details.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE or FALSE, based on success.
|
||||
*/
|
||||
protected function load($source, array $details) {
|
||||
$this->logCall('load', array($source, $details));
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -155,8 +144,8 @@ class TestToolkit extends ImageToolkitBase {
|
|||
* Stores the values passed to a toolkit call.
|
||||
*
|
||||
* @param string $op
|
||||
* One of the image toolkit operations: 'get_info', 'load', 'save',
|
||||
* 'settings', 'resize', 'rotate', 'crop', 'desaturate'.
|
||||
* One of the image toolkit operations: 'parseFile', 'save', 'settings',
|
||||
* 'resize', 'rotate', 'crop', 'desaturate'.
|
||||
* @param array $args
|
||||
* Values passed to hook.
|
||||
*
|
||||
|
@ -183,6 +172,40 @@ class TestToolkit extends ImageToolkitBase {
|
|||
return $this->height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the image.
|
||||
*
|
||||
* @return int
|
||||
* The image type represented by a PHP IMAGETYPE_* constant (e.g.
|
||||
* IMAGETYPE_JPEG).
|
||||
*/
|
||||
public function getType() {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the PHP type of the image.
|
||||
*
|
||||
* @param int $type
|
||||
* The image type represented by a PHP IMAGETYPE_* constant (e.g.
|
||||
* IMAGETYPE_JPEG).
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public function setType($type) {
|
||||
if (in_array($type, static::supportedTypes())) {
|
||||
$this->type = $type;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMimeType(ImageInterface $image) {
|
||||
return $this->getType() ? image_type_to_mime_type($this->getType()) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -193,7 +216,22 @@ class TestToolkit extends ImageToolkitBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function supportedTypes() {
|
||||
public static function getSupportedExtensions() {
|
||||
$extensions = array();
|
||||
foreach (static::supportedTypes() as $image_type) {
|
||||
$extensions[] = Unicode::strtolower(image_type_to_extension($image_type, FALSE));
|
||||
}
|
||||
return $extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of image types supported by the toolkit.
|
||||
*
|
||||
* @return array
|
||||
* An array of available image types. An image type is represented by a PHP
|
||||
* IMAGETYPE_* constant (e.g. IMAGETYPE_JPEG, IMAGETYPE_PNG, etc.).
|
||||
*/
|
||||
protected static function supportedTypes() {
|
||||
return array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF);
|
||||
}
|
||||
|
||||
|
|
|
@ -88,10 +88,10 @@ class ImageTest extends UnitTestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Tests \Drupal\Core\Image\Image::getType().
|
||||
* Tests \Drupal\Core\Image\Image::getToolkit()->getType().
|
||||
*/
|
||||
public function testGetType() {
|
||||
$this->assertEquals($this->image->getType(), IMAGETYPE_PNG);
|
||||
$this->assertEquals($this->image->getToolkit()->getType(), IMAGETYPE_PNG);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -102,22 +102,13 @@ class ImageTest extends UnitTestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Tests \Drupal\Core\Image\Image::isExisting().
|
||||
* Tests \Drupal\Core\Image\Image::isValid().
|
||||
*/
|
||||
public function testIsExisting() {
|
||||
$this->assertTrue($this->image->isExisting());
|
||||
public function testIsValid() {
|
||||
$this->assertTrue($this->image->isValid());
|
||||
$this->assertTrue(is_readable($this->image->getSource()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests \Drupal\Core\Image\Image::setSource().
|
||||
*/
|
||||
public function testSetSource() {
|
||||
$source = __DIR__ . '/../../../../../misc/grippie.png';
|
||||
$this->image->setSource($source);
|
||||
$this->assertEquals($this->image->getSource(), $source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests \Drupal\Core\Image\Image::getToolkitId().
|
||||
*/
|
||||
|
@ -172,13 +163,14 @@ class ImageTest extends UnitTestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Tests \Drupal\Core\Image\Image::processInfo().
|
||||
* Tests \Drupal\Core\Image\Image::parseFile().
|
||||
*/
|
||||
public function testProcessInfoFails() {
|
||||
public function testParseFileFails() {
|
||||
$toolkit = $this->getToolkitMock();
|
||||
$image = new Image($toolkit, 'magic-foobars.png');
|
||||
|
||||
$this->assertFalse($image->isExisting());
|
||||
$this->assertFalse($image->isValid());
|
||||
$this->assertFalse($image->save());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue