diff --git a/Block/Adminhtml/Product/Edit/NewVideo.php b/Block/Adminhtml/Product/Edit/NewVideo.php index d762b3a..9dafd36 100644 --- a/Block/Adminhtml/Product/Edit/NewVideo.php +++ b/Block/Adminhtml/Product/Edit/NewVideo.php @@ -66,7 +66,7 @@ public function getWidgetOptions() 'htmlId' => $this->getHtmlId(), 'youTubeApiKey' => $this->mediaHelper->getYouTubeApiKey(), 'videoSelector' => $this->videoSelector, - 'cloudinaryPlaceholder' => $this->getViewFileUrl('Cloudinary_Cloudinary::images/cloudinary_logo_for_white_bg.jpg') + 'cloudinaryPlaceholder' => $this->getViewFileUrl('Cloudinary_Cloudinary::images/cloudinary_vertical_logo_for_white_bg.svg') ] ); } diff --git a/Core/CloudinaryImageProvider.php b/Core/CloudinaryImageProvider.php index cbfe356..f54bc3e 100644 --- a/Core/CloudinaryImageProvider.php +++ b/Core/CloudinaryImageProvider.php @@ -3,12 +3,9 @@ namespace Cloudinary\Cloudinary\Core; use Cloudinary; -use Cloudinary\Uploader; use Cloudinary\Cloudinary\Core\Exception\ApiError; use Cloudinary\Cloudinary\Core\Image\Transformation; -use Cloudinary\Cloudinary\Core\Security; -use Cloudinary\Cloudinary\Core\Image\Transformation\Format; -use Cloudinary\Cloudinary\Core\Image\Transformation\FetchFormat; +use Cloudinary\Uploader; class CloudinaryImageProvider implements ImageProvider { @@ -57,7 +54,8 @@ public function __construct( * @param ConfigurationInterface $configuration * @return CloudinaryImageProvider */ - public static function fromConfiguration(ConfigurationInterface $configuration){ + public static function fromConfiguration(ConfigurationInterface $configuration) + { return new CloudinaryImageProvider( $configuration, new ConfigurationBuilder($configuration), @@ -94,10 +92,18 @@ public function upload(Image $image) */ public function retrieveTransformed(Image $image, Transformation $transformation) { - return Image::fromPath( - \cloudinary_url($image->getId(), ['transformation' => $transformation->build(), 'secure' => true]), - $image->getRelativePath() - ); + $imagePath = \cloudinary_url($image->getId(), ['transformation' => $transformation->build(), 'secure' => true]); + + if ($this->configuration->getUseRootPath()) { + $imagePath = str_replace(".com/{$this->configuration->getCloud()}/image/upload/", ".com/{$this->configuration->getCloud()}/", $imagePath); + } + + if ($this->configuration->getRemoveVersionNumber()) { + $regex = '/\/v[0-9]+\/' . preg_quote(ltrim($image->getId(), '/'), '/') . '$/'; + $imagePath = preg_replace($regex, '/' . ltrim($image->getId(), '/'), $imagePath); + } + + return Image::fromPath($imagePath, $image->getRelativePath()); } /** diff --git a/Model/AutoUploadMapping/AutoUploadConfiguration.php b/Model/AutoUploadMapping/AutoUploadConfiguration.php index 697c8a5..55d3cdb 100644 --- a/Model/AutoUploadMapping/AutoUploadConfiguration.php +++ b/Model/AutoUploadMapping/AutoUploadConfiguration.php @@ -2,9 +2,9 @@ namespace Cloudinary\Cloudinary\Model\AutoUploadMapping; +use Cloudinary\Cloudinary\Core\AutoUploadMapping\AutoUploadConfigurationInterface; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\Config\Storage\WriterInterface; -use Cloudinary\Cloudinary\Core\AutoUploadMapping\AutoUploadConfigurationInterface; class AutoUploadConfiguration implements AutoUploadConfigurationInterface { diff --git a/Model/Configuration.php b/Model/Configuration.php index fad16c2..3a9447a 100644 --- a/Model/Configuration.php +++ b/Model/Configuration.php @@ -19,6 +19,7 @@ use Magento\Framework\App\Config\Storage\WriterInterface; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Encryption\EncryptorInterface; +use Magento\Store\Model\StoreManagerInterface; class Configuration implements ConfigurationInterface { @@ -26,11 +27,20 @@ class Configuration implements ConfigurationInterface const USER_PLATFORM_TEMPLATE = 'CloudinaryMagento/%s (Magento %s)'; const CONFIG_PATH_ENVIRONMENT_VARIABLE = 'cloudinary/setup/cloudinary_environment_variable'; const CONFIG_CDN_SUBDOMAIN = 'cloudinary/configuration/cloudinary_cdn_subdomain'; + //= Transformations const CONFIG_DEFAULT_GRAVITY = 'cloudinary/transformations/cloudinary_gravity'; const CONFIG_DEFAULT_QUALITY = 'cloudinary/transformations/cloudinary_image_quality'; const CONFIG_DEFAULT_DPR = 'cloudinary/transformations/cloudinary_image_dpr'; const CONFIG_DEFAULT_FETCH_FORMAT = 'cloudinary/transformations/cloudinary_fetch_format'; const CONFIG_GLOBAL_FREEFORM = 'cloudinary/transformations/cloudinary_free_transform_global'; + //= Advanced + const CONFIG_PATH_REMOVE_VERSION_NUMBER = 'cloudinary/advanced/remove_version_number'; + const CONFIG_PATH_USE_ROOT_PATH = 'cloudinary/advanced/use_root_path'; + //= Others + const CONFIG_PATH_SECURE_BASE_URL = "web/secure/base_url"; + const CONFIG_PATH_UNSECURE_BASE_URL = "web/unsecure/base_url"; + const CONFIG_PATH_USE_SECURE_IN_FRONTEND = "web/secure/use_in_frontend"; + const USE_FILENAME = true; const UNIQUE_FILENAME = false; const OVERWRITE = false; @@ -62,24 +72,32 @@ class Configuration implements ConfigurationInterface */ private $autoUploadConfiguration; + /** + * @var StoreManagerInterface + */ + private $storeManager; + /** * @param ScopeConfigInterface $configReader * @param WriterInterface $configWriter * @param EncryptorInterface $decryptor * @param AutoUploadConfigurationInterface $autoUploadConfiguration + * @param StoreManagerInterface $storeManager */ public function __construct( ScopeConfigInterface $configReader, WriterInterface $configWriter, EncryptorInterface $decryptor, AutoUploadConfigurationInterface $autoUploadConfiguration, - \Psr\Log\LoggerInterface $logger + \Psr\Log\LoggerInterface $logger, + StoreManagerInterface $storeManager ) { $this->configReader = $configReader; $this->configWriter = $configWriter; $this->decryptor = $decryptor; $this->autoUploadConfiguration = $autoUploadConfiguration; $this->logger = $logger; + $this->storeManager = $storeManager; } /** @@ -132,7 +150,7 @@ public function getCdnSubdomainStatus() */ public function getUserPlatform() { - return sprintf(self::USER_PLATFORM_TEMPLATE, '1.6.0', '2.0.0'); + return sprintf(self::USER_PLATFORM_TEMPLATE, '1.6.3', '2.0.0'); } /** @@ -236,4 +254,29 @@ private function getEnvironmentVariable() } return $this->environmentVariable; } + + /** + * @return bool + */ + public function getRemoveVersionNumber() + { + return (bool) $this->configReader->getValue(self::CONFIG_PATH_REMOVE_VERSION_NUMBER); + } + + /** + * @return bool + */ + public function getUseRootPath() + { + return (bool) $this->configReader->getValue(self::CONFIG_PATH_REMOVE_VERSION_NUMBER); + } + + /** + * @method getMediaBaseUrl + * @return string + */ + public function getMediaBaseUrl() + { + return $this->storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA); + } } diff --git a/Model/Observer/Configuration.php b/Model/Observer/Configuration.php index b0a7274..b060417 100644 --- a/Model/Observer/Configuration.php +++ b/Model/Observer/Configuration.php @@ -2,13 +2,11 @@ namespace Cloudinary\Cloudinary\Model\Observer; -use Cloudinary\Cloudinary\Core\CloudinaryImageManager; -use Magento\Framework\App\ObjectManager; +use Cloudinary\Cloudinary\Core\AutoUploadMapping\RequestProcessor; +use Magento\Framework\App\Cache\TypeListInterface; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; -use Cloudinary\Cloudinary\Core\AutoUploadMapping\RequestProcessor; use Magento\Framework\Message\ManagerInterface; -use Magento\Framework\UrlInterface; class Configuration implements ObserverInterface { @@ -17,23 +15,41 @@ class Configuration implements ObserverInterface /** * @var RequestProcessor */ - private $requestProcessor; + protected $requestProcessor; /** * @var ManagerInterface */ - private $messageManager; + protected $messageManager; + + /** + * @var \Cloudinary\Cloudinary\Model\Configuration + */ + protected $configuration; + + /** + * @var TypeListInterface + */ + protected $cacheTypeList; + + protected $changedPaths = []; /** * @param RequestProcessor $requestProcessor * @param ManagerInterface $messageManager + * @param \Cloudinary\Cloudinary\Model\Configuration $configuration + * @param TypeListInterface $cacheTypeList */ public function __construct( RequestProcessor $requestProcessor, - ManagerInterface $messageManager + ManagerInterface $messageManager, + \Cloudinary\Cloudinary\Model\Configuration $configuration, + TypeListInterface $cacheTypeList ) { $this->requestProcessor = $requestProcessor; $this->messageManager = $messageManager; + $this->configuration = $configuration; + $this->cacheTypeList = $cacheTypeList; } /** @@ -41,24 +57,25 @@ public function __construct( */ public function execute(Observer $observer) { - if (!$this->requestProcessor->handle('media', $this->getMediaBaseUrl())) { + //Clear config cache if needed + $this->changedPaths = (array) $observer->getEvent()->getChangedPaths(); + if (in_array($this->changedPaths, [ + \Cloudinary\Cloudinary\Model\Configuration::CONFIG_PATH_ENABLED, + \Cloudinary\Cloudinary\Model\Configuration::CONFIG_PATH_ENVIRONMENT_VARIABLE, + \Cloudinary\Cloudinary\Model\AutoUploadMapping\AutoUploadConfiguration::REQUEST_PATH + ])) { + $this->cleanConfigCache(); + } + + if (!$this->requestProcessor->handle('media', $this->configuration->getMediaBaseUrl())) { $this->messageManager->addErrorMessage(self::AUTO_UPLOAD_SETUP_FAIL_MESSAGE); } } - /** - * @return string - */ - function getMediaBaseUrl() { - /** @var \Magento\Framework\ObjectManagerInterface $om */ - $om = ObjectManager::getInstance(); - - /** @var \Magento\Store\Model\StoreManagerInterface $storeManager */ - $storeManager = $om->get('Magento\Store\Model\StoreManagerInterface'); - - /** @var \Magento\Store\Api\Data\StoreInterface|\Magento\Store\Model\Store $currentStore */ - $currentStore = $storeManager->getStore(); - - return $currentStore->getBaseUrl(UrlInterface::URL_TYPE_MEDIA); + protected function cleanConfigCache() + { + $this->_cacheTypeList->cleanType(\Magento\Framework\App\Cache\Type\Config::TYPE_IDENTIFIER); + $this->_cacheTypeList->cleanType(\Magento\PageCache\Model\Cache\Type::TYPE_IDENTIFIER); + return $this; } } diff --git a/Model/Template/Filter.php b/Model/Template/Filter.php index 316c187..c916eac 100644 --- a/Model/Template/Filter.php +++ b/Model/Template/Filter.php @@ -2,9 +2,9 @@ namespace Cloudinary\Cloudinary\Model\Template; -use Magento\Widget\Model\Template\Filter as WidgetFilter; use Cloudinary\Cloudinary\Core\Image\ImageFactory; use Cloudinary\Cloudinary\Core\UrlGenerator; +use Magento\Widget\Model\Template\Filter as WidgetFilter; class Filter extends WidgetFilter { @@ -92,7 +92,7 @@ public function mediaDirective($construction) $image = $this->imageFactory->build( $params['url'], - function() use ($storeManager, $params) { + function () use ($storeManager, $params) { return sprintf( '%s%s', $storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA), diff --git a/README.md b/README.md index 0c001a4..34bcf74 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,22 @@ Magento 2 module for integration with Cloudinary. --- +## ✓ Installation (using git & composer) +Run the following command under your Magento 2 root dir: + +``` +git clone https://github.com/cloudinary/cloudinary_magento2 app/code/Cloudinary/Cloudinary +composer require cloudinary/cloudinary_php:1.8.0 +php bin/magento setup:upgrade +php bin/magento setup:di:compile +php bin/magento setup:static-content:deploy +php bin/magento cache:flush +``` + +--- + https://www.cloudinary.com/ Copyright © 2018 Cloudinary. All rights reserved. -![Cloudinary Logo](https://cloudinary-res.cloudinary.com/image/upload/v1538583988/cloudinary_logo_for_white_bg.svg) +![Cloudinary Logo](https://cloudinary-res.cloudinary.com/image/upload/c_scale,w_300/v1/logo/for_white_bg/cloudinary_logo_for_white_bg.svg) diff --git a/Setup/UpgradeData.php b/Setup/UpgradeData.php new file mode 100644 index 0000000..e499e6a --- /dev/null +++ b/Setup/UpgradeData.php @@ -0,0 +1,52 @@ +_resourceConnection = $resourceConnection; + } + + /** + * {@inheritdoc} + */ + public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context) + { + $setup->startSetup(); + + if (version_compare($context->getVersion(), '0.6.3') < 0) { + echo "- Reseting configurations for 'website' & 'store' scopes (only supports 'default' at the moment).\n"; + $this->_resourceConnection->getConnection()->delete( + $this->_resourceConnection->getTableName('core_config_data'), + "path LIKE 'cloudinary/%' AND scope != 'default'" + ); + } + + $setup->endSetup(); + } +} diff --git a/composer.json b/composer.json index 482453f..947b51b 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "cloudinary/magento2-module-cloudinary", "description": "Cloudinary Magento 2 Integration.", "type": "magento2-module", - "version": "1.6.0", + "version": "1.6.3", "minimum-stability": "dev", "license": "MIT", "repositories": { diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 5175e4a..58e36b6 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -2,66 +2,82 @@ -
- - service + + + +
+ + cloudinary Cloudinary_Cloudinary::config_cloudinary - + - + Magento\Config\Model\Config\Source\Yesno - + - + Set the credentials of your Cloudinary account. Copy the "Environment variable" string from the dashboard of Cloudinary's Management Console. Cloudinary\Cloudinary\Model\Config\Backend\Credentials - + - + Enable multiple sub-domains of image delivery URLs for faster page load speed. Magento\Config\Model\Config\Source\Yesno - + When enabled, Cloudinary will fetch images it does not have from your site automatically without requiring the manual migration process. Magento\Config\Model\Config\Source\Yesno - + - + Automatically deliver images converted to modern image formats based on viewing device and browser. For example, deliver WebP on Chrome and JPEG-XR on Internet Explorer for better performance and user experience. Magento\Config\Model\Config\Source\Yesno - + Adjust quality of generated images to balance between visual quality and file size minimization. The quality is relevant for JPEG and WebP compression levels for example. Cloudinary\Cloudinary\Model\Config\Source\Dropdown\Quality - + Define the part of the image to focus on when cropping images in order to better match your graphic design. Cloudinary\Cloudinary\Model\Config\Source\Dropdown\Gravity - + Use DPR value higher than 1.0 to generate and deliver hi-res images for better visual result on HiDPI devices, such as Retina Display devices (e.g., 2.0). Cloudinary\Cloudinary\Model\Config\Source\Dropdown\Dpr - + Cloudinary\Cloudinary\Model\Config\Backend\Free Cloudinary\Cloudinary\Block\Adminhtml\Form\Field\Free + + + + + Remove version number (e.g., ".../v1/...") from URLs + Magento\Config\Model\Config\Source\Yesno + + + + Remove "/image/upload/" from URLs + Magento\Config\Model\Config\Source\Yesno + +
diff --git a/etc/config.xml b/etc/config.xml index 7c0f7bd..251673a 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -11,6 +11,10 @@ 1 + + 0 + 0 + diff --git a/etc/module.xml b/etc/module.xml index b350786..6814263 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -1,6 +1,6 @@ - + diff --git a/view/adminhtml/web/css/source/_module.less b/view/adminhtml/web/css/source/_module.less new file mode 100644 index 0000000..5983d59 --- /dev/null +++ b/view/adminhtml/web/css/source/_module.less @@ -0,0 +1,11 @@ +.cloudinary-icon { + background-image: url('Cloudinary_Cloudinary::images/cloudinary_icon_for_white_bg.svg'); + background-size: contain; + background-repeat: no-repeat; + background-position: center center; + display: inline-block; + width: 22px; + height: 18px; + margin-right: 5px; + vertical-align: text-bottom; +} diff --git a/view/base/web/images/cloudinary_icon_for_white_bg.svg b/view/base/web/images/cloudinary_icon_for_white_bg.svg new file mode 100644 index 0000000..0dae7c9 --- /dev/null +++ b/view/base/web/images/cloudinary_icon_for_white_bg.svg @@ -0,0 +1,69 @@ + + + + + + + + + + diff --git a/view/base/web/images/cloudinary_logo_for_white_bg.jpg b/view/base/web/images/cloudinary_logo_for_white_bg.jpg deleted file mode 100644 index b448103..0000000 Binary files a/view/base/web/images/cloudinary_logo_for_white_bg.jpg and /dev/null differ diff --git a/view/base/web/images/cloudinary_logo_for_white_bg.svg b/view/base/web/images/cloudinary_logo_for_white_bg.svg new file mode 100644 index 0000000..f5e2b10 --- /dev/null +++ b/view/base/web/images/cloudinary_logo_for_white_bg.svg @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/view/base/web/images/cloudinary_vertical_logo_for_white_bg.svg b/view/base/web/images/cloudinary_vertical_logo_for_white_bg.svg new file mode 100644 index 0000000..2e4d2e0 --- /dev/null +++ b/view/base/web/images/cloudinary_vertical_logo_for_white_bg.svg @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + +