diff --git a/app/code/community/Cloudinary/Cloudinary/Helper/Image.php b/app/code/community/Cloudinary/Cloudinary/Helper/Image.php index 307f832..ffe375d 100644 --- a/app/code/community/Cloudinary/Cloudinary/Helper/Image.php +++ b/app/code/community/Cloudinary/Cloudinary/Helper/Image.php @@ -81,7 +81,9 @@ public function init(Mage_Catalog_Model_Product $product, $attributeName, $image */ public function resize($width, $height = null) { - $this->_dimensions = Dimensions::fromWidthAndHeight($width, $height); + if ($this->_configuration->isEnabled()) { + $this->_dimensions = Dimensions::fromWidthAndHeight($width, $height); + } return parent::resize($width, $height); } @@ -104,16 +106,22 @@ public function getImageUrlForCategory(Mage_Catalog_Model_Category $category) */ public function __toString() { + if (!$this->_configuration->isEnabled()) { + return parent::__toString(); + } $image = $this->_imageFactory->build( $this->_getRequestedImageFile(), - function() { return parent::__toString();} + function () { + return parent::__toString(); + } ); return $this->_urlGenerator->generateFor( $image, $this->_transformation->addFreeformTransformationForImage( $this->createTransformation(), - $this->_getRequestedImageFile() + $this->_getRequestedImageFile(), + $this->getProduct() ) ); } diff --git a/app/code/community/Cloudinary/Cloudinary/Model/AdminProductObserver.php b/app/code/community/Cloudinary/Cloudinary/Model/AdminProductObserver.php index 65eaa63..ed1fb19 100644 --- a/app/code/community/Cloudinary/Cloudinary/Model/AdminProductObserver.php +++ b/app/code/community/Cloudinary/Cloudinary/Model/AdminProductObserver.php @@ -37,7 +37,7 @@ private function filterUpdatedImages(array $imageData, array $imageUpdated) { return array_filter( $imageData, - function($id) use ($imageUpdated) { + function ($id) use ($imageUpdated) { return $imageUpdated[$id]; }, ARRAY_FILTER_USE_KEY @@ -71,12 +71,32 @@ private function storeFreeTransformFields(array $imageData, Mage_Catalog_Model_P { $mediaImages = $this->getMediaGalleryImages($product); + // TODO: Should be removed on future releases foreach ($imageData as $id => $freeTransform) { Mage::getModel('cloudinary_cloudinary/transformation') ->setImageName($this->getImageNameForId($id, $mediaImages)) ->setFreeTransformation($freeTransform) ->save(); + + $cloudinaryData = json_decode((string)$product->getCloudinaryData(), true) ?: array(); + $cloudinaryData['transformation'] = (isset($cloudinaryData['transformation']))? (array) $cloudinaryData['transformation'] : array(); + $cloudinaryData['transformation'][md5($this->getImageNameForId($id, $mediaImages))] = (string) $freeTransform; + $product->setCloudinaryData(json_encode($cloudinaryData)); + } + + + /*foreach ($mediaImages as &$image) { + if (isset($imageData[$image["value_id"]])) { + $image['cloudinary_transformation'] = $imageData[$image["value_id"]]; + } } + + $productPost = Mage::app()->getRequest()->getPost("product"); + $productPost['media_gallery']['images'] = json_encode($mediaImages); + Mage::app()->getRequest()->setPost("product", $productPost); + $mediaGallery = $product->getMediaGallery(); + $mediaGallery['images'] = $productPost['media_gallery']['images']; + $product->setData('media_gallery', $mediaGallery);*/ } /** diff --git a/app/code/community/Cloudinary/Cloudinary/Model/Catalog/Product/Image.php b/app/code/community/Cloudinary/Cloudinary/Model/Catalog/Product/Image.php index 7072ffd..4a74278 100644 --- a/app/code/community/Cloudinary/Cloudinary/Model/Catalog/Product/Image.php +++ b/app/code/community/Cloudinary/Cloudinary/Model/Catalog/Product/Image.php @@ -24,7 +24,10 @@ public function __construct() public function getUrl() { return (string) $this->_imageFactory->build( - $this->_newFile, function() { return parent::getUrl();} + $this->_newFile, + function () { + return parent::getUrl(); + } ); } diff --git a/app/code/community/Cloudinary/Cloudinary/Model/Catalog/Product/Media.php b/app/code/community/Cloudinary/Cloudinary/Model/Catalog/Product/Media.php index a4cdb7c..f84bb7a 100644 --- a/app/code/community/Cloudinary/Cloudinary/Model/Catalog/Product/Media.php +++ b/app/code/community/Cloudinary/Cloudinary/Model/Catalog/Product/Media.php @@ -2,12 +2,11 @@ class Cloudinary_Cloudinary_Model_Catalog_Product_Media extends Mage_Core_Model_Abstract { - private $_newImages; public function newImagesForProduct(Mage_Catalog_Model_Product $product) { - $this->_setNewImages($product->getData('media_gallery')); + $this->_setNewImages((array)$product->getData('media_gallery')); return $this->_getNewImages($product); } @@ -52,4 +51,4 @@ private function _isImageRemoved($toFilter) { return is_array($toFilter) && array_key_exists('removed', $toFilter) && $toFilter['removed'] === 1; } -} \ No newline at end of file +} diff --git a/app/code/community/Cloudinary/Cloudinary/Model/Catalog/Product/Media/Config.php b/app/code/community/Cloudinary/Cloudinary/Model/Catalog/Product/Media/Config.php index 49e58c2..78e3ae5 100644 --- a/app/code/community/Cloudinary/Cloudinary/Model/Catalog/Product/Media/Config.php +++ b/app/code/community/Cloudinary/Cloudinary/Model/Catalog/Product/Media/Config.php @@ -16,19 +16,26 @@ class Cloudinary_Cloudinary_Model_Catalog_Product_Media_Config extends Mage_Cata */ private $_urlGenerator; + /** + * @var Configuration + */ + private $_configuration; + public function __construct() { - $configuration = Mage::getModel('cloudinary_cloudinary/configuration'); + $this->_configuration = Mage::getModel('cloudinary_cloudinary/configuration'); - $this->_imageFactory = new ImageFactory( - $configuration, - Mage::getModel('cloudinary_cloudinary/synchronizationChecker') - ); + if ($this->_configuration->isEnabled()) { + $this->_imageFactory = new ImageFactory( + $this->_configuration, + Mage::getModel('cloudinary_cloudinary/synchronizationChecker') + ); - $this->_urlGenerator = new UrlGenerator( - $configuration, - CloudinaryImageProvider::fromConfiguration($configuration) - ); + $this->_urlGenerator = new UrlGenerator( + $this->_configuration, + CloudinaryImageProvider::fromConfiguration($this->_configuration) + ); + } } /** @@ -37,7 +44,13 @@ public function __construct() */ public function getMediaUrl($file) { - $image = $this->_imageFactory->build($file, function() use($file) { return parent::getMediaUrl($file); }); + if (!$this->_configuration->isEnabled()) { + return parent::getMediaUrl($file); + } + + $image = $this->_imageFactory->build($file, function () use ($file) { + return parent::getMediaUrl($file); + }); return $this->_urlGenerator->generateFor( $image, diff --git a/app/code/community/Cloudinary/Cloudinary/Model/Catalog/Template/Filter.php b/app/code/community/Cloudinary/Cloudinary/Model/Catalog/Template/Filter.php new file mode 100644 index 0000000..f827add --- /dev/null +++ b/app/code/community/Cloudinary/Cloudinary/Model/Catalog/Template/Filter.php @@ -0,0 +1,79 @@ + + * @todo Needs to be reimplemented to get rid of the copypasted methods + */ +class Cloudinary_Cloudinary_Model_Catalog_Template_Filter extends Mage_Catalog_Model_Template_Filter +{ + /** + * @var ImageFactory + */ + private $imageFactory; + + /** + * @var UrlGenerator + */ + private $urlGenerator; + + /** + * @var Configuration + */ + private $configuration; + + public function __construct() + { + $this->configuration = Mage::getModel('cloudinary_cloudinary/configuration'); + if ($this->configuration->isEnabled()) { + $this->imageFactory = new ImageFactory( + $this->configuration, + Mage::getModel('cloudinary_cloudinary/synchronizationChecker') + ); + + $this->urlGenerator = new UrlGenerator( + $this->configuration, + CloudinaryImageProvider::fromConfiguration($this->configuration) + ); + } + } + + /** + * Retrieve media file URL directive + * + * @param array $construction + * @return string + * @see Mage_Core_Model_Email_Template_Filter::mediaDirective() method has been copypasted + */ + public function mediaDirective($construction) + { + if (!$this->configuration->isEnabled()) { + return parent::mediaDirective($construction); + } + + $imagePath = $this->getImagePath($construction[2]); + + $image = $this->imageFactory->build( + $imagePath, + function () use ($construction) { + return parent::mediaDirective($construction); + } + ); + + return $this->urlGenerator->generateFor($image); + } + + private function getImagePath($directiveParams) + { + $params = $this->_getIncludeParameters($directiveParams); + return $params['url']; + } +} diff --git a/app/code/community/Cloudinary/Cloudinary/Model/System/Config/Free.php b/app/code/community/Cloudinary/Cloudinary/Model/System/Config/Free.php index 937e9d0..0d6499e 100644 --- a/app/code/community/Cloudinary/Cloudinary/Model/System/Config/Free.php +++ b/app/code/community/Cloudinary/Cloudinary/Model/System/Config/Free.php @@ -8,7 +8,7 @@ class Cloudinary_Cloudinary_Model_System_Config_Free extends Mage_Core_Model_Config_Data { - const ERROR_FORMAT = 'Incorrect custom transform - %s'; + const ERROR_FORMAT = 'Incorrect Cloudinary Transformation - %s'; const ERROR_DEFAULT = 'please update'; /** @@ -43,25 +43,41 @@ protected function _beforeSave() ->getDefaultTransformation() ->withFreeform(Freeform::fromString($this->getValue())); - $this->validateImageUrl($this->sampleImageUrl($transform)); + $this->validateImageUrl($this->sampleImageUrl($transform), false); return $this; } /** * @param string $url + * @param bool $strict Throw exception on errors + * @return bool */ - public function validateImageUrl($url) + public function validateImageUrl($url, $strict = true) { try { $response = $this->httpRequest($url); } catch (Exception $e) { - throw new Mage_Core_Exception(sprintf(self::ERROR_FORMAT, self::ERROR_DEFAULT)); + $this->setValue(null); + if ($strict) { + throw new Mage_Core_Exception(sprintf(self::ERROR_FORMAT, self::ERROR_DEFAULT)); + } else { + Mage::getSingleton('adminhtml/session')->addError(sprintf(self::ERROR_FORMAT, self::ERROR_DEFAULT)); + } + return false; } - if ($response->isError()) { - throw new Mage_Core_Exception($this->formatError($response)); + if (is_object($response) && ($response->error || !in_array($response->code, [200,301,302]))) { + $this->setValue(null); + if ($strict) { + throw new Mage_Core_Exception($this->formatError($response)); + } else { + Mage::getSingleton('adminhtml/session')->addError($this->formatError($response)); + } + return false; } + + return true; } /** @@ -79,11 +95,11 @@ public function defaultTransform($freeTransform) * @param Zend_Http_Response $response * @return string */ - public function formatError(Zend_Http_Response $response) + public function formatError($response) { return sprintf( self::ERROR_FORMAT, - $response->getStatus() == 400 ? $response->getHeader('x-cld-error') : self::ERROR_DEFAULT + (is_object($response) && isset($response->headers['x-cld-error']) && $response->headers['x-cld-error']) ? $response->headers['x-cld-error'] : self::ERROR_DEFAULT ); } @@ -93,9 +109,16 @@ public function formatError(Zend_Http_Response $response) */ public function httpRequest($url) { - $client = new Varien_Http_Client($url); - $client->setMethod(Varien_Http_Client::GET); - return $client->request(); + $curl = new Varien_Http_Adapter_Curl(); + $curl->write(Zend_Http_Client::GET, $url); + $response = $curl->read(); + $response = (object)[ + "code" => Zend_Http_Response::extractCode($response), + "body" => Zend_Http_Response::extractBody($response), + "headers" => (array) Zend_Http_Response::extractHeaders($response), + "error" => $curl->getError() + ]; + return $response; } /** diff --git a/app/code/community/Cloudinary/Cloudinary/Model/Transformation.php b/app/code/community/Cloudinary/Cloudinary/Model/Transformation.php index afac07d..a577334 100644 --- a/app/code/community/Cloudinary/Cloudinary/Model/Transformation.php +++ b/app/code/community/Cloudinary/Cloudinary/Model/Transformation.php @@ -28,33 +28,65 @@ protected function _construct() * @param string $imageFile * @return Transformation */ - public function transformationForImage($imageFile) + public function transformationForImage($imageFile, Mage_Catalog_Model_Product $product = null) { return $this->addFreeformTransformationForImage( $this->configuration->getDefaultTransformation(), - $imageFile + $imageFile, + $product ); } /** * @param Transformation $transformation * @param string $imageFile + * @param Mage_Catalog_Model_Product|null $product * @return Transformation */ - public function addFreeformTransformationForImage(Transformation $transformation, $imageFile) + public function addFreeformTransformationForImage(Transformation $transformation, $imageFile, Mage_Catalog_Model_Product $product = null) { - $transformationString = $this->cache->loadCache( - $this->getTransformCacheKeyFromImageFile($imageFile), - function () use ($imageFile) { - $this->warmTransformationCache(); + $transformationString = false; + if ($product) { + $cloudinaryData = json_decode((string)$product->getCloudinaryData(), true) ?: array(); + if (isset($cloudinaryData['transformation']) && isset($cloudinaryData['transformation'][md5($imageFile)])) { + $transformationString = $cloudinaryData['transformation'][md5($imageFile)]; + } else { + $updateProduct = true; + $transformationString = $this->cache->loadCache( + $this->getTransformCacheKeyFromImageFile($imageFile), + function () use ($imageFile) { + $this->warmTransformationCache(); - $this->load($imageFile); - if (($this->getImageName() === $imageFile) && $this->hasFreeTransformation()) { - return $this->getFreeTransformation(); - } - return ''; + $this->load($imageFile); + if (($this->getImageName() === $imageFile) && $this->hasFreeTransformation()) { + return $this->getFreeTransformation(); + } + return ''; + } + ); } - ); + } else { + /*$transformationString = $this->cache->loadCache( + $this->getTransformCacheKeyFromImageFile($imageFile), + function () use ($imageFile) { + $this->warmTransformationCache(); + + $this->load($imageFile); + if (($this->getImageName() === $imageFile) && $this->hasFreeTransformation()) { + return $this->getFreeTransformation(); + } + return ''; + } + );*/ + } + + if (isset($updateProduct)) { + //$initialEnvironmentInfo = Mage::getSingleton('core/app_emulation')->startEnvironmentEmulation(Mage_Core_Model_App::ADMIN_STORE_ID); + $cloudinaryData['transformation'][md5($imageFile)] = $transformationString; + $product->setCloudinaryData(json_encode($cloudinaryData)); + $product->getResource()->saveAttribute($product, 'cloudinary_data'); + //Mage::getSingleton('core/app_emulation')->stopEnvironmentEmulation($initialEnvironmentInfo); + } if ($transformationString != false) { $transformation->withFreeform(Freeform::fromString($transformationString)); diff --git a/app/code/community/Cloudinary/Cloudinary/etc/config.xml b/app/code/community/Cloudinary/Cloudinary/etc/config.xml index cad3e20..fccb9d6 100644 --- a/app/code/community/Cloudinary/Cloudinary/etc/config.xml +++ b/app/code/community/Cloudinary/Cloudinary/etc/config.xml @@ -2,7 +2,7 @@ - 2.9.5 + 2.9.7 @@ -20,6 +20,7 @@ Cloudinary_Cloudinary_Model_Catalog_Product_Image Cloudinary_Cloudinary_Model_Catalog_Product_Media_Config + Cloudinary_Cloudinary_Model_Catalog_Template_Filter @@ -119,6 +120,7 @@ Cloudinary_Cloudinary + Mage_Eav_Model_Entity_Setup diff --git a/app/code/community/Cloudinary/Cloudinary/sql/cloudinary_setup/upgrade-2.9.6-2.9.7.php b/app/code/community/Cloudinary/Cloudinary/sql/cloudinary_setup/upgrade-2.9.6-2.9.7.php new file mode 100644 index 0000000..4c0c99c --- /dev/null +++ b/app/code/community/Cloudinary/Cloudinary/sql/cloudinary_setup/upgrade-2.9.6-2.9.7.php @@ -0,0 +1,24 @@ +startSetup(); + +$installer->addAttribute('catalog_product', 'cloudinary_data', array( + 'group' => 'General', + 'label' => 'Cloudinary Data', + 'input' => 'text', + 'type' => 'text', + 'required' => 0, + 'visible_on_front' => 0, + 'filterable' => 0, + 'searchable' => 0, + 'comparable' => 0, + 'user_defined' => 0, + 'is_configurable' => 0, + 'used_in_product_listing' => '1', + 'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL, + 'note' => '', +)); + +$installer->endSetup(); diff --git a/var/connect/Cloudinary_Cloudinary.xml b/var/connect/Cloudinary_Cloudinary.xml index afc0245..3b17ac3 100644 --- a/var/connect/Cloudinary_Cloudinary.xml +++ b/var/connect/Cloudinary_Cloudinary.xml @@ -1,5 +1,5 @@ <_> - 4PxTwwcoXimxtiy4 + 3uENH8mYhOhm4EWZ Cloudinary_Cloudinary community @@ -9,7 +9,7 @@ Cloudinary supercharges your images! Upload images to the cloud, deliver optimized via a fast CDN, perform smart resizing and apply effects. MIT License (MITL) - 2.9.6 + 2.9.7 stable - Match MEQP1 coding standards @@ -41,7 +41,7 @@ - + @@ -108,8 +108,4 @@ - 1 - 200 - - diff --git a/var/package/package.xml b/var/package/package.xml index acc0631..7060a78 100644 --- a/var/package/package.xml +++ b/var/package/package.xml @@ -1,7 +1,7 @@ Cloudinary_Cloudinary - 2.9.6 + 2.9.7 stable MIT License (MITL) community @@ -11,9 +11,9 @@ - Match MEQP1 coding standards Cloudinarycloudinaryaccounts+magento@cloudinary.com - 2019-01-08 - - + 2019-03-17 + + 5.4.07.2.2