diff --git a/core/includes/common.inc b/core/includes/common.inc index 4829751..2075af9 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -3083,7 +3083,6 @@ function _drupal_bootstrap_code() { require_once __DIR__ . '/tablesort.inc'; require_once __DIR__ . '/file.inc'; require_once __DIR__ . '/unicode.inc'; - require_once __DIR__ . '/image.inc'; require_once __DIR__ . '/form.inc'; require_once __DIR__ . '/mail.inc'; require_once __DIR__ . '/ajax.inc'; diff --git a/core/includes/image.inc b/core/includes/image.inc deleted file mode 100644 index 447500e..0000000 --- a/core/includes/image.inc +++ /dev/null @@ -1,66 +0,0 @@ -getFileInfo(); -} - -/** - * @} End of "defgroup image". - */ diff --git a/core/lib/Drupal/Core/Image/ImageFile.php b/core/lib/Drupal/Core/Image/ImageFile.php index 3e914f5..564c9da 100644 --- a/core/lib/Drupal/Core/Image/ImageFile.php +++ b/core/lib/Drupal/Core/Image/ImageFile.php @@ -104,24 +104,14 @@ public function setInfo(array $info) { * 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; + + if (isset($this->info[$key])) { + return $this->info[$key]; + } + return NULL; } /** @@ -241,9 +231,9 @@ public function getToolkitId() { * - "mime_type": MIME type ('image/jpeg', 'image/gif', 'image/png'). * - "file_size": File size in bytes. */ - public function getFileInfo() { + public function getInfo() { if ($this->processInfo()) { - return $this->getInfo(); + return $this->info; } return FALSE; } @@ -316,7 +306,10 @@ protected function processInfo() { * TRUE on success, FALSE on failure. */ public function scale($width = NULL, $height = NULL, $upscale = FALSE) { - $dimensions = $this->getInfo(); + $dimensions = array( + 'width' => $this->get('width'), + 'height' => $this->get('height'), + ); // Scale the dimensions - if they don't change then just return success. if (!Image::scaleDimensions($dimensions, $width, $height, $upscale)) { diff --git a/core/modules/file/file.module b/core/modules/file/file.module index bbd5e11..2ddeb7a 100644 --- a/core/modules/file/file.module +++ b/core/modules/file/file.module @@ -408,7 +408,7 @@ function file_validate_size(File $file, $file_limit = 0, $user_limit = 0) { } /** - * Checks that the file is recognized by image_get_info() as an image. + * Checks that the file is recognized by ImageFile::getInfo() as an image. * * @param Drupal\file\File $file * A file entity. @@ -421,7 +421,8 @@ function file_validate_size(File $file, $file_limit = 0, $user_limit = 0) { function file_validate_is_image(File $file) { $errors = array(); - $info = image_get_info($file->getFileUri()); + $image = new ImageFile($file->getFileUri()); + $info = $image->getInfo(); if (!$info || empty($info['extension'])) { $errors[] = t('Only JPEG, PNG and GIF images are allowed.'); } @@ -456,7 +457,8 @@ function file_validate_image_resolution(File $file, $maximum_dimensions = 0, $mi $errors = array(); // Check first that the file is an image. - if ($info = image_get_info($file->getFileUri())) { + $image = new ImageFile($file->getFileUri()); + if ($info = $image->getInfo()) { if ($maximum_dimensions) { // Check that it is smaller than the given dimensions. list($width, $height) = explode('x', $maximum_dimensions); diff --git a/core/modules/file/lib/Drupal/file/Tests/ValidatorTest.php b/core/modules/file/lib/Drupal/file/Tests/ValidatorTest.php index 8012c4d..9af755d 100644 --- a/core/modules/file/lib/Drupal/file/Tests/ValidatorTest.php +++ b/core/modules/file/lib/Drupal/file/Tests/ValidatorTest.php @@ -7,6 +7,8 @@ namespace Drupal\file\Tests; +use Drupal\Core\Image\ImageFile; + /** * This will run tests against the file validation functions (file_validate_*). */ @@ -87,9 +89,9 @@ function testFileValidateImageResolution() { $errors = file_validate_image_resolution($this->image, '10x5'); $this->assertEqual(count($errors), 0, 'No errors should be reported when an oversized image can be scaled down.', 'File'); - $info = image_get_info($this->image->getFileUri()); - $this->assertTrue($info['width'] <= 10, 'Image scaled to correct width.', 'File'); - $this->assertTrue($info['height'] <= 5, 'Image scaled to correct height.', 'File'); + $image = new ImageFile($this->image->getFileUri()); + $this->assertTrue($image->get('width') <= 10, 'Image scaled to correct width.', 'File'); + $this->assertTrue($image->get('height') <= 5, 'Image scaled to correct height.', 'File'); drupal_unlink('temporary://druplicon.png'); } diff --git a/core/modules/image/image.admin.inc b/core/modules/image/image.admin.inc index cb32ad9..39c40df 100644 --- a/core/modules/image/image.admin.inc +++ b/core/modules/image/image.admin.inc @@ -6,6 +6,7 @@ */ use Drupal\Component\Utility\String; +use Drupal\Core\Image\ImageFile; use Drupal\image\ImageStyleInterface; /** @@ -377,7 +378,8 @@ function theme_image_style_preview($variables) { // Set up original file information. $original_path = $sample_image; - $original_image = image_get_info($original_path); + $original_image = new ImageFile($original_path); + $original_image = $original_image->getInfo(); if ($original_image['width'] > $original_image['height']) { $original_width = min($original_image['width'], $sample_width); $original_height = round($original_width / $original_image['width'] * $original_image['height']); @@ -394,7 +396,8 @@ function theme_image_style_preview($variables) { if (!file_exists($preview_file)) { $style->createDerivative($original_path, $preview_file); } - $preview_image = image_get_info($preview_file); + $preview_image = new ImageFile($preview_file); + $preview_image = $preview_image->getInfo(); if ($preview_image['width'] > $preview_image['height']) { $preview_width = min($preview_image['width'], $sample_width); $preview_height = round($preview_width / $preview_image['width'] * $preview_image['height']); diff --git a/core/modules/image/image.field.inc b/core/modules/image/image.field.inc index 9609960..8dece3d 100644 --- a/core/modules/image/image.field.inc +++ b/core/modules/image/image.field.inc @@ -7,6 +7,7 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Image\ImageFile; /** * Implements hook_field_info(). @@ -226,13 +227,11 @@ function _image_field_resolution_validate($element, &$form_state) { * Implements hook_field_presave(). */ function image_field_presave(EntityInterface $entity, $field, $instance, $langcode, &$items) { - // Determine the dimensions if necessary. foreach ($items as &$item) { if (!isset($item['width']) || !isset($item['height'])) { - $info = image_get_info(file_load($item['target_id'])->getFileUri()); - - if (is_array($info)) { + $image = new ImageFile(file_load($item['target_id'])->getFileUri()); + if ($info = $image->getInfo()) { $item['width'] = $info['width']; $item['height'] = $info['height']; } @@ -301,9 +300,8 @@ function image_field_widget_process($element, &$form_state, $form) { $variables['height'] = $element['#value']['height']; } else { - $info = image_get_info($file->getFileUri()); - - if (is_array($info)) { + $image = new ImageFile($file->getFileUri()); + if ($info = $image->getInfo()) { $variables['width'] = $info['width']; $variables['height'] = $info['height']; } diff --git a/core/modules/image/image.module b/core/modules/image/image.module index ef5ffbe..315f064 100644 --- a/core/modules/image/image.module +++ b/core/modules/image/image.module @@ -6,6 +6,7 @@ */ use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Image\ImageFile; use Drupal\field\Plugin\Core\Entity\Field; use Drupal\field\Plugin\Core\Entity\FieldInstance; use Drupal\file\Plugin\Core\Entity\File; @@ -298,7 +299,8 @@ function image_file_download($uri) { $original_uri = file_uri_scheme($uri) . '://' . implode('/', $args); // Check that the file exists and is an image. - if ($info = image_get_info($uri)) { + $image = new ImageFile($uri); + if ($info = $image->getInfo()) { // Check the permissions of the original to grant access to this image. $headers = module_invoke_all('file_download', $original_uri); // Confirm there's at least one module granting access and none denying access. diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageDimensionsTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageDimensionsTest.php index 0ff6738..da013be 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageDimensionsTest.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageDimensionsTest.php @@ -7,6 +7,7 @@ namespace Drupal\image\Tests; +use Drupal\Core\Image\ImageFile; use Drupal\simpletest\WebTestBase; /** @@ -53,9 +54,9 @@ function testImageDimensions() { 'height' => 20, ); // Verify that the original image matches the hard-coded values. - $image_info = image_get_info($original_uri); - $this->assertEqual($image_info['width'], $variables['width']); - $this->assertEqual($image_info['height'], $variables['height']); + $image_file = new ImageFile($original_uri); + $this->assertEqual($image_file->get('width'), $variables['width']); + $this->assertEqual($image_file->get('height'), $variables['height']); // Scale an image that is wider than it is high. $effect = array( @@ -75,9 +76,9 @@ function testImageDimensions() { $this->drupalGet($url); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); - $image_info = image_get_info($generated_uri); - $this->assertEqual($image_info['width'], 120); - $this->assertEqual($image_info['height'], 60); + $image_file = new ImageFile($generated_uri); + $this->assertEqual($image_file->get('width'), 120); + $this->assertEqual($image_file->get('height'), 60); // Rotate 90 degrees anticlockwise. $effect = array( @@ -96,9 +97,9 @@ function testImageDimensions() { $this->drupalGet($url); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); - $image_info = image_get_info($generated_uri); - $this->assertEqual($image_info['width'], 60); - $this->assertEqual($image_info['height'], 120); + $image_file = new ImageFile($generated_uri); + $this->assertEqual($image_file->get('width'), 60); + $this->assertEqual($image_file->get('height'), 120); // Scale an image that is higher than it is wide (rotated by previous effect). $effect = array( @@ -118,9 +119,9 @@ function testImageDimensions() { $this->drupalGet($url); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); - $image_info = image_get_info($generated_uri); - $this->assertEqual($image_info['width'], 45); - $this->assertEqual($image_info['height'], 90); + $image_file = new ImageFile($generated_uri); + $this->assertEqual($image_file->get('width'), 45); + $this->assertEqual($image_file->get('height'), 90); // Test upscale disabled. $effect = array( @@ -140,9 +141,9 @@ function testImageDimensions() { $this->drupalGet($url); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); - $image_info = image_get_info($generated_uri); - $this->assertEqual($image_info['width'], 45); - $this->assertEqual($image_info['height'], 90); + $image_file = new ImageFile($generated_uri); + $this->assertEqual($image_file->get('width'), 45); + $this->assertEqual($image_file->get('height'), 90); // Add a desaturate effect. $effect = array( @@ -158,9 +159,9 @@ function testImageDimensions() { $this->drupalGet($url); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); - $image_info = image_get_info($generated_uri); - $this->assertEqual($image_info['width'], 45); - $this->assertEqual($image_info['height'], 90); + $image_file = new ImageFile($generated_uri); + $this->assertEqual($image_file->get('width'), 45); + $this->assertEqual($image_file->get('height'), 90); // Add a random rotate effect. $effect = array( @@ -199,9 +200,9 @@ function testImageDimensions() { $this->drupalGet($url); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); - $image_info = image_get_info($generated_uri); - $this->assertEqual($image_info['width'], 30); - $this->assertEqual($image_info['height'], 30); + $image_file = new ImageFile($generated_uri); + $this->assertEqual($image_file->get('width'), 30); + $this->assertEqual($image_file->get('height'), 30); // Rotate to a non-multiple of 90 degrees. $effect = array( diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldValidateTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldValidateTest.php index 1cd0ce9..3aa81b9 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldValidateTest.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldValidateTest.php @@ -7,6 +7,8 @@ namespace Drupal\image\Tests; +use Drupal\Core\Image\ImageFile; + /** * Test class to check for various validations. */ @@ -37,11 +39,11 @@ function testResolution() { $image_that_is_too_big = FALSE; $image_that_is_too_small = FALSE; foreach ($this->drupalGetTestFiles('image') as $image) { - $info = image_get_info($image->uri); - if ($info['width'] > $max_resolution) { + $image_file = new ImageFile($image->uri); + if ($image_file->get('width') > $max_resolution) { $image_that_is_too_big = $image; } - if ($info['width'] < $min_resolution) { + if ($image_file->get('width') < $min_resolution) { $image_that_is_too_small = $image; } if ($image_that_is_too_small && $image_that_is_too_big) { diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageItemTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageItemTest.php index 5e7472f..8b28fa4 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageItemTest.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageItemTest.php @@ -9,6 +9,7 @@ use Drupal\Core\Entity\Field\FieldInterface; use Drupal\Core\Entity\Field\FieldItemInterface; +use Drupal\Core\Image\ImageFile; use Drupal\field\Tests\FieldUnitTestBase; /** @@ -78,9 +79,9 @@ public function testImageItem() { $this->assertEqual($entity->image_test->target_id, $this->image->id()); $this->assertEqual($entity->image_test->alt, $alt); $this->assertEqual($entity->image_test->title, $title); - $info = image_get_info('public://example.jpg'); - $this->assertEqual($entity->image_test->width, $info['width']); - $this->assertEqual($entity->image_test->height, $info['height']); + $image = new ImageFile('public://example.jpg'); + $this->assertEqual($entity->image_test->width, $image->get('width')); + $this->assertEqual($entity->image_test->height, $image->get('height')); $this->assertEqual($entity->image_test->entity->id(), $this->image->id()); $this->assertEqual($entity->image_test->entity->uuid(), $this->image->uuid()); @@ -98,9 +99,9 @@ public function testImageItem() { $entity->save(); $this->assertEqual($entity->image_test->entity->id(), $image2->id()); $this->assertEqual($entity->image_test->entity->getFileUri(), $image2->getFileUri()); - $info = image_get_info('public://example-2.jpg'); - $this->assertEqual($entity->image_test->width, $info['width']); - $this->assertEqual($entity->image_test->height, $info['height']); + $image = new ImageFile('public://example-2.jpg'); + $this->assertEqual($entity->image_test->width, $image->get('width')); + $this->assertEqual($entity->image_test->height, $image->get('height')); $this->assertEqual($entity->image_test->alt, $new_alt); // Check that the image item can be set to the referenced file directly. diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageStylesPathAndUrlTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageStylesPathAndUrlTest.php index cae45d7..c9be258 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageStylesPathAndUrlTest.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageStylesPathAndUrlTest.php @@ -7,6 +7,7 @@ namespace Drupal\image\Tests; +use Drupal\Core\Image\ImageFile; use Drupal\simpletest\WebTestBase; use Symfony\Component\HttpFoundation\Request; @@ -153,9 +154,9 @@ function doImageStyleUrlAndPathTests($scheme, $clean_url = TRUE, $extra_slash = $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); $this->assertRaw(file_get_contents($generated_uri), 'URL returns expected file.'); - $generated_image_info = image_get_info($generated_uri); - $this->assertEqual($this->drupalGetHeader('Content-Type'), $generated_image_info['mime_type'], 'Expected Content-Type was reported.'); - $this->assertEqual($this->drupalGetHeader('Content-Length'), $generated_image_info['file_size'], 'Expected Content-Length was reported.'); + $image = new ImageFile($generated_uri); + $this->assertEqual($this->drupalGetHeader('Content-Type'), $image->get('mime_type'), 'Expected Content-Type was reported.'); + $this->assertEqual($this->drupalGetHeader('Content-Length'), $image->get('file_size'), 'Expected Content-Length was reported.'); if ($scheme == 'private') { $this->assertEqual($this->drupalGetHeader('Expires'), 'Sun, 19 Nov 1978 05:00:00 GMT', 'Expires header was sent.'); $this->assertNotEqual(strpos($this->drupalGetHeader('Cache-Control'), 'no-cache'), FALSE, 'Cache-Control header contains \'no-cache\' to prevent caching.'); diff --git a/core/modules/system/lib/Drupal/system/Plugin/ImageToolkitInterface.php b/core/modules/system/lib/Drupal/system/Plugin/ImageToolkitInterface.php index 90bd15f..e7b9dad 100644 --- a/core/modules/system/lib/Drupal/system/Plugin/ImageToolkitInterface.php +++ b/core/modules/system/lib/Drupal/system/Plugin/ImageToolkitInterface.php @@ -11,6 +11,33 @@ use Drupal\Core\Image\ImageFile; /** + * @defgroup image Image toolkits + * @{ + * Functions for image file manipulations. + * + * Drupal's image toolkits provide an abstraction layer for common image file + * manipulations like scaling, cropping, and rotating. The abstraction frees + * module authors from the need to support multiple image libraries, and it + * allows site administrators to choose the library that's best for them. + * + * PHP includes the GD library by default so a GD toolkit is installed with + * Drupal. Other toolkits like ImageMagick are available from contrib modules. + * GD works well for small images, but using it with larger files may cause PHP + * to run out of memory. In contrast the ImageMagick library does not suffer + * from this problem, but it requires the ISP to have installed additional + * software. + * + * Image toolkits are discovered using the Plugin system using + * \Drupal\system\Plugin\ImageToolkitManager. The toolkit must then be enabled + * using the admin/config/media/image-toolkit form. + * + * Only one toolkit may be selected at a time. If a module author wishes to call + * a specific toolkit they can check that it is installed by calling + * \Drupal\system\Plugin\ImageToolkitManager::getAvailableToolkits(), and then + * calling its functions directly. + */ + +/** * Defines an interface for image toolkits. * * An image toolkit provides common image file manipulations like scaling, @@ -142,7 +169,7 @@ function save(ImageFile $image, $destination); * - "extension": Commonly used file extension for the image. * - "mime_type": MIME type ('image/jpeg', 'image/gif', 'image/png'). * - * @see image_get_info() + * @see \Drupal\Core\Image\ImageFile::getInfo() */ function getInfo(ImageFile $image); 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 a8bdd84..8eae39f 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTest.php @@ -11,7 +11,7 @@ use Drupal\system\Plugin\ImageToolkitManager; /** - * Test that the functions in image.inc correctly pass data to the toolkit. + * Tests that the methods in ImageFile correctly pass data to the toolkit. */ class ToolkitTest extends ToolkitTestBase { public static function getInfo() { 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 f2f8c39..b066601 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTestBase.php +++ b/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitTestBase.php @@ -53,8 +53,8 @@ function setUp() { // Setup a dummy image to work with, this replicate image_load() so we // can avoid calling it. $this->image = new ImageFile($this->file); + $this->image->getInfo(); $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/system.api.php b/core/modules/system/system.api.php index 1e1bae3..c85dbaf 100644 --- a/core/modules/system/system.api.php +++ b/core/modules/system/system.api.php @@ -2150,8 +2150,8 @@ function hook_file_download($uri) { return -1; } else { - $info = image_get_info($uri); - return array('Content-Type' => $info['mime_type']); + $image = new \Drupal\Core\Image\ImageFile($uri); + return array('Content-Type' => $image->get('mime_type')); } } }