From a328aed4512f7f722af3cf273e4eda7b8bfbc80b Mon Sep 17 00:00:00 2001
From: Claudiu Cristea <clau.cristea@gmail.com>
Date: Fri, 16 Aug 2013 00:16:14 +0200
Subject: [PATCH] Issue #2066219 by claudiu.cristea: Add getAvailableExtensions
 method to ImageToolkitInterface.

---
 .../system/Plugin/ImageToolkit/GDToolkit.php       | 27 +++++++++++++++++---
 .../Drupal/system/Plugin/ImageToolkitInterface.php | 25 +++++++++++++------
 .../Drupal/system/Tests/Image/ToolkitGdTest.php    | 29 +++++++++++++++++++++-
 .../image_test/Plugin/ImageToolkit/TestToolkit.php | 27 +++++++++++++++++---
 4 files changed, 91 insertions(+), 17 deletions(-)

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 3219edb..322b0bb 100644
--- a/core/modules/system/lib/Drupal/system/Plugin/ImageToolkit/GDToolkit.php
+++ b/core/modules/system/lib/Drupal/system/Plugin/ImageToolkit/GDToolkit.php
@@ -7,10 +7,11 @@
 
 namespace Drupal\system\Plugin\ImageToolkit;
 
-use Drupal\Component\Plugin\PluginBase;
-use Drupal\system\Annotation\ImageToolkit;
 use Drupal\Core\Annotation\Translation;
 use Drupal\Core\Image\ImageInterface;
+use Drupal\Component\Plugin\PluginBase;
+use Drupal\Component\Utility\Unicode;
+use Drupal\system\Annotation\ImageToolkit;
 use Drupal\system\Plugin\ImageToolkitInterface;
 
 /**
@@ -221,8 +222,18 @@ public function getInfo(ImageInterface $image) {
     $data = getimagesize($image->getSource());
 
     if (isset($data) && is_array($data)) {
-      $extensions = array('1' => 'gif', '2' => 'jpg', '3' => 'png');
-      $extension = isset($extensions[$data[2]]) ?  $extensions[$data[2]] : '';
+      // image_type_to_extension(IMAGETYPE_JPEG) always returns 'jpeg' even if
+      // the extension is 'jpg'. Extract the extension from the filename.
+      if ($data[2] == IMAGETYPE_JPEG) {
+        $extension = pathinfo($image->getSource(), PATHINFO_EXTENSION);
+        // It may be a temporary file, without extension. Fallback to 'jpg'.
+        $extension = Unicode::strtolower($extension);
+        $extension = in_array($extension, array('jpg', 'jpeg')) ? $extension : 'jpg';
+      }
+      else {
+        $extension = image_type_to_extension($data[2], FALSE);
+        $extension = in_array($extension, static::getAvailableExtensions()) ? $extension : '';
+      }
       $details = array(
         'width'     => $data[0],
         'height'    => $data[1],
@@ -290,4 +301,12 @@ public static function isAvailable() {
     }
     return FALSE;
   }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getAvailableExtensions() {
+    return array('png', 'gif', 'jpg', 'jpeg');
+  }
+
 }
diff --git a/core/modules/system/lib/Drupal/system/Plugin/ImageToolkitInterface.php b/core/modules/system/lib/Drupal/system/Plugin/ImageToolkitInterface.php
index 774f050..a1ddbd0 100644
--- a/core/modules/system/lib/Drupal/system/Plugin/ImageToolkitInterface.php
+++ b/core/modules/system/lib/Drupal/system/Plugin/ImageToolkitInterface.php
@@ -50,14 +50,14 @@
    *
    * @see system_image_toolkit_settings()
    */
-  function settingsForm();
+  public function settingsForm();
 
   /**
    * Handles submissions for toolkit's settings form.
    *
    * @see system_image_toolkit_settings_submit()
    */
-  function settingsFormSubmit($form, &$form_state);
+  public function settingsFormSubmit($form, &$form_state);
 
   /**
    * Scales an image to the specified size.
@@ -73,7 +73,7 @@ function settingsFormSubmit($form, &$form_state);
    * @return bool
    *   TRUE or FALSE, based on success.
    */
-  function resize(ImageInterface $image, $width, $height);
+  public function resize(ImageInterface $image, $width, $height);
 
   /**
    * Rotates an image the given number of degrees.
@@ -93,7 +93,7 @@ function resize(ImageInterface $image, $width, $height);
    * @return bool
    *   TRUE or FALSE, based on success.
    */
-  function rotate(ImageInterface $image, $degrees, $background = NULL);
+  public function rotate(ImageInterface $image, $degrees, $background = NULL);
 
   /**
    * Crops an image.
@@ -115,7 +115,7 @@ function rotate(ImageInterface $image, $degrees, $background = NULL);
    *
    * @see image_crop()
    */
-  function crop(ImageInterface $image, $x, $y, $width, $height);
+  public function crop(ImageInterface $image, $x, $y, $width, $height);
 
   /**
    * Converts an image resource to grayscale.
@@ -140,7 +140,7 @@ function desaturate(ImageInterface $image);
    * @return bool
    *   TRUE or FALSE, based on success.
    */
-  function load(ImageInterface $image);
+  public function load(ImageInterface $image);
 
   /**
    * Writes an image resource to a destination file.
@@ -153,7 +153,7 @@ function load(ImageInterface $image);
    * @return bool
    *   TRUE or FALSE, based on success.
    */
-  function save(ImageInterface $image, $destination);
+  public function save(ImageInterface $image, $destination);
 
   /**
    * Gets details about an image.
@@ -179,5 +179,14 @@ function getInfo(ImageInterface $image);
    * @return bool
    *   True if the GD toolkit is available on this machine.
    */
-  static function isAvailable();
+  public static function isAvailable();
+
+  /**
+   * Returns a list of image extensions handled by the image toolkit.
+   *
+   * @return array
+   *   An array of available image extensions.
+   */
+  public static function getAvailableExtensions();
+
 }
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 1797b78..648b2f6 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitGdTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Image/ToolkitGdTest.php
@@ -264,7 +264,7 @@ function testManipulations() {
         $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->getExtension() != 'jpg') {
+        if (!in_array($image->getExtension(), array('jpg', 'jpeg'))) {
           // Now check each of the corners to ensure color correctness.
           foreach ($values['corners'] as $key => $corner) {
             // Get the location of the corner.
@@ -293,6 +293,33 @@ function testManipulations() {
         }
       }
     }
+  }
+
+  /**
+   * Test allowed extensions.
+   */
+  public function testExtensions() {
+    $toolkit = $this->container->get('image.toolkit.manager')->createInstance('gd');
+    $image_factory = $this->container->get('image.factory')->setToolkit($toolkit);
 
+    // Define a list of files to be tested.
+    $files = array();
+    foreach (array('png', 'gif', 'jpg') as $extension) {
+      $files[$extension] = drupal_get_path('module', 'simpletest') . '/files/image-test.' . $extension;
+    }
+
+    // Add also a .jpeg extension file and a JPEG file without any extension.
+    foreach (array('jpeg', '') as $extension) {
+      $destination = 'public://image-test' . (empty($extension) ? '' : '.') . $extension;
+      file_unmanaged_copy($files['jpg'], $destination);
+      $files[$extension] = $destination;
+    }
+
+    foreach ($files as $extension => $file) {
+      $image = $image_factory->get($file);
+      $expected = $extension ?: 'jpg';
+      $this->assertEqual($image->getExtension(), $expected);
+    }
   }
+
 }
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 eede36a..f5b336e 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
@@ -7,10 +7,11 @@
 
 namespace Drupal\image_test\Plugin\ImageToolkit;
 
-use Drupal\Component\Plugin\PluginBase;
-use Drupal\system\Annotation\ImageToolkit;
 use Drupal\Core\Annotation\Translation;
 use Drupal\Core\Image\ImageInterface;
+use Drupal\Component\Plugin\PluginBase;
+use Drupal\Component\Utility\Unicode;
+use Drupal\system\Annotation\ImageToolkit;
 use Drupal\system\Plugin\ImageToolkitInterface;
 
 /**
@@ -46,8 +47,18 @@ public function getInfo(ImageInterface $image) {
     $data = getimagesize($image->getSource());
 
     if (isset($data) && is_array($data)) {
-      $extensions = array('1' => 'gif', '2' => 'jpg', '3' => 'png');
-      $extension = isset($extensions[$data[2]]) ?  $extensions[$data[2]] : '';
+      // image_type_to_extension(IMAGETYPE_JPEG) always returns 'jpeg' even if
+      // the extension is 'jpg'. Extract the extension from the filename.
+      if ($data[2] == IMAGETYPE_JPEG) {
+        $extension = pathinfo($image->getSource(), PATHINFO_EXTENSION);
+        // It may be a temporary file, without extension. Fallback to 'jpg'.
+        $extension = Unicode::strtolower($extension);
+        $extension = in_array($extension, array('jpg', 'jpeg')) ? $extension : 'jpg';
+      }
+      else {
+        $extension = image_type_to_extension($data[2], FALSE);
+        $extension = in_array($extension, self::getAvailableExtensions()) ? $extension : '';
+      }
       $details = array(
         'width'     => $data[0],
         'height'    => $data[1],
@@ -133,4 +144,12 @@ protected function logCall($op, $args) {
   public static function isAvailable() {
     return TRUE;
   }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getAvailableExtensions() {
+    return array('png', 'gif', 'jpg', 'jpeg');
+  }
+
 }
-- 
1.8.3.1

