From 3e86102f05013c94018b365894a907cc215a1595 Mon Sep 17 00:00:00 2001
From: Stanislav Lopukhov <slopukhov@magento.com>
Date: Wed, 17 Jan 2018 10:53:36 +0200
Subject: [PATCH] MAGETWO-84480: Add cache for getimagesize() function for
 product images

---
 .../Magento/Catalog/Model/Product/Image.php   | 14 ++++-
 .../Test/Unit/Model/Product/ImageTest.php     | 61 ++++++++++++++++++-
 2 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/app/code/Magento/Catalog/Model/Product/Image.php b/app/code/Magento/Catalog/Model/Product/Image.php
index 77e4383859b..971f34e02f9 100644
--- a/app/code/Magento/Catalog/Model/Product/Image.php
+++ b/app/code/Magento/Catalog/Model/Product/Image.php
@@ -791,6 +791,7 @@ class Image extends \Magento\Framework\Model\AbstractModel
         $this->_mediaDirectory->delete($directory);
 
         $this->_coreFileStorageDatabase->deleteFolder($this->_mediaDirectory->getAbsolutePath($directory));
+        $this->clearImageInfoFromCache();
     }
 
     /**
@@ -898,7 +899,8 @@ class Image extends \Magento\Framework\Model\AbstractModel
         $imagePath = $this->cachePrefix  . $imagePath;
         $this->_cacheManager->save(
             $this->serializer->serialize($imageInfo),
-            $imagePath
+            $imagePath,
+            [$this->cachePrefix]
         );
     }
 
@@ -918,4 +920,14 @@ class Image extends \Magento\Framework\Model\AbstractModel
             return $this->serializer->unserialize($cacheData);
         }
     }
+
+    /**
+     * Clear image data from cache
+     *
+     * @return void
+     */
+    private function clearImageInfoFromCache()
+    {
+        $this->_cacheManager->clean([$this->cachePrefix]);
+    }
 }
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php
index f918692cb27..627aa184850 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php
@@ -5,12 +5,10 @@
  */
 namespace Magento\Catalog\Test\Unit\Model\Product;
 
-use Magento\Catalog\Model\View\Asset\Image\ContextFactory;
 use Magento\Catalog\Model\View\Asset\ImageFactory;
 use Magento\Catalog\Model\View\Asset\PlaceholderFactory;
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
 use Magento\Framework\App\Filesystem\DirectoryList;
-use Magento\Framework\View\Asset\ContextInterface;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -73,10 +71,24 @@ class ImageTest extends \PHPUnit\Framework\TestCase
      */
     private $viewAssetPlaceholderFactory;
 
+    /**
+     * @var \Magento\Framework\Serialize\SerializerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $serializer;
+
+    /**
+     * @var \Magento\Framework\App\CacheInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $cacheManager;
+
     protected function setUp()
     {
         $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
         $this->context = $this->createMock(\Magento\Framework\Model\Context::class);
+        $this->cacheManager = $this->getMockBuilder(\Magento\Framework\App\CacheInterface::class)
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $this->context->expects($this->any())->method('getCacheManager')->will($this->returnValue($this->cacheManager));
 
         $this->storeManager = $this->getMockBuilder(\Magento\Store\Model\StoreManager::class)
             ->disableOriginalConstructor()
@@ -112,17 +124,36 @@ class ImageTest extends \PHPUnit\Framework\TestCase
             ->disableOriginalConstructor()
             ->setMethods(['create'])
             ->getMock();
+        $this->serializer = $this->getMockBuilder(
+            \Magento\Framework\Serialize\SerializerInterface::class
+        )->getMockForAbstractClass();
+        $this->serializer->expects($this->any())
+            ->method('serialize')
+            ->willReturnCallback(
+                function ($value) {
+                    return json_encode($value);
+                }
+            );
+        $this->serializer->expects($this->any())
+            ->method('unserialize')
+            ->willReturnCallback(
+                function ($value) {
+                    return json_decode($value, true);
+                }
+            );
 
         $this->image = $objectManager->getObject(
             \Magento\Catalog\Model\Product\Image::class,
             [
+                'context' => $this->context,
                 'storeManager' => $this->storeManager,
                 'catalogProductMediaConfig' => $this->config,
                 'coreFileStorageDatabase' => $this->coreFileHelper,
                 'filesystem' => $this->filesystem,
                 'imageFactory' => $this->factory,
                 'viewAssetImageFactory' => $this->viewAssetImageFactory,
-                'viewAssetPlaceholderFactory' => $this->viewAssetPlaceholderFactory
+                'viewAssetPlaceholderFactory' => $this->viewAssetPlaceholderFactory,
+                'serializer' => $this->serializer
             ]
         );
 
@@ -354,12 +385,16 @@ class ImageTest extends \PHPUnit\Framework\TestCase
         $this->testSetGetBaseFile();
         $absolutePath = dirname(dirname(__DIR__)) . '/_files/catalog/product/watermark/somefile.png';
         $this->imageAsset->expects($this->any())->method('getPath')->willReturn($absolutePath);
+        $this->cacheManager->expects($this->once())->method('load')->willReturn(
+            json_encode(['size' => ['image data']])
+        );
         $this->assertTrue($this->image->isCached());
     }
 
     public function testClearCache()
     {
         $this->coreFileHelper->expects($this->once())->method('deleteFolder')->will($this->returnValue(true));
+        $this->cacheManager->expects($this->once())->method('clean');
         $this->image->clearCache();
     }
 
@@ -383,4 +418,24 @@ class ImageTest extends \PHPUnit\Framework\TestCase
     {
         $this->assertFalse($this->image->isBaseFilePlaceholder());
     }
+
+    public function testGetResizedImageInfoWithCache()
+    {
+        $absolutePath = dirname(dirname(__DIR__)) . '/_files/catalog/product/watermark/somefile.png';
+        $this->imageAsset->expects($this->any())->method('getPath')->willReturn($absolutePath);
+        $this->cacheManager->expects($this->once())->method('load')->willReturn(
+            json_encode(['size' => ['image data']])
+        );
+        $this->cacheManager->expects($this->never())->method('save');
+        $this->assertEquals(['image data'], $this->image->getResizedImageInfo());
+    }
+
+    public function testGetResizedImageInfoEmptyCache()
+    {
+        $absolutePath = dirname(dirname(__DIR__)) . '/_files/catalog/product/watermark/somefile.png';
+        $this->imageAsset->expects($this->any())->method('getPath')->willReturn($absolutePath);
+        $this->cacheManager->expects($this->once())->method('load')->willReturn(false);
+        $this->cacheManager->expects($this->once())->method('save');
+        $this->assertTrue(is_array($this->image->getResizedImageInfo()));
+    }
 }
-- 
GitLab