From f69523853427a092767fa7eb16ac4dc532a398cd Mon Sep 17 00:00:00 2001 From: pini-girit Date: Sun, 13 Jan 2019 17:16:20 +0200 Subject: [PATCH 01/64] Working on Media Library implementation - product edit page in progress --- etc/adminhtml/events.xml | 4 ++++ view/adminhtml/requirejs-config.js | 8 +++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/etc/adminhtml/events.xml b/etc/adminhtml/events.xml index e5721cf..a9c2ee9 100644 --- a/etc/adminhtml/events.xml +++ b/etc/adminhtml/events.xml @@ -1,6 +1,10 @@ + + + + diff --git a/view/adminhtml/requirejs-config.js b/view/adminhtml/requirejs-config.js index eaca295..329da34 100644 --- a/view/adminhtml/requirejs-config.js +++ b/view/adminhtml/requirejs-config.js @@ -3,7 +3,13 @@ var config = { '*': { cloudinaryFreeTransform: 'Cloudinary_Cloudinary/js/cloudinary-free', newVideoDialog: 'Cloudinary_Cloudinary/js/new-video-dialog', - 'Magento_ProductVideo/js/get-video-information': 'Cloudinary_Cloudinary/js/get-video-information' + 'Magento_ProductVideo/js/get-video-information': 'Cloudinary_Cloudinary/js/get-video-information', + selectImageFromCloudinaryDialog: 'Cloudinary_Cloudinary/js/new-image-from-cloudinary-dialog', + cloudinaryMediaLibraryModal: 'Cloudinary_Cloudinary/js/cloudinary-media-library-modal' } }, + paths: { + cloudinaryMediaLibraryAll: "//media-library.cloudinary.com/global/all", + es6Promise: "//cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.auto.min" + } }; \ No newline at end of file From c230109b0eef1827437cec9be92899cc16d811f4 Mon Sep 17 00:00:00 2001 From: pini-girit Date: Thu, 17 Jan 2019 10:24:40 +0200 Subject: [PATCH 02/64] Implementing Cloudinary Media Library (in progress) - currently available on product gallery edit only with images --- .../Product/Helper/Form/Gallery/Content.php | 138 +++++++ .../Adminhtml/Product/Gallery/Upload.php | 74 ++++ Model/Configuration.php | 9 + .../Observer/ProductGalleryChangeTemplate.php | 42 ++ etc/adminhtml/system.xml | 4 + view/adminhtml/requirejs-config.js | 1 - .../catalog/product/helper/gallery.phtml | 358 ++++++++++++++++++ view/adminhtml/ui_component/product_form.xml | 8 + view/adminhtml/web/css/source/_module.less | 16 + .../web/js/cloudinary-media-library-modal.js | 88 +++++ .../images/cloudinary_icon_for_dark_bg.svg | 69 ++++ .../images/cloudinary_logo_for_dark_bg.svg | 188 +++++++++ .../cloudinary_vertical_logo_for_dark_bg.svg | 203 ++++++++++ 13 files changed, 1197 insertions(+), 1 deletion(-) create mode 100644 Block/Adminhtml/Product/Helper/Form/Gallery/Content.php create mode 100644 Controller/Adminhtml/Product/Gallery/Upload.php create mode 100644 Model/Observer/ProductGalleryChangeTemplate.php create mode 100644 view/adminhtml/templates/catalog/product/helper/gallery.phtml create mode 100644 view/adminhtml/ui_component/product_form.xml create mode 100644 view/adminhtml/web/js/cloudinary-media-library-modal.js create mode 100644 view/base/web/images/cloudinary_icon_for_dark_bg.svg create mode 100644 view/base/web/images/cloudinary_logo_for_dark_bg.svg create mode 100644 view/base/web/images/cloudinary_vertical_logo_for_dark_bg.svg diff --git a/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php b/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php new file mode 100644 index 0000000..7eebd22 --- /dev/null +++ b/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php @@ -0,0 +1,138 @@ + + * + * @method \Magento\Framework\Data\Form\Element\AbstractElement getElement() + */ +namespace Cloudinary\Cloudinary\Block\Adminhtml\Product\Helper\Form\Gallery; + +use Cloudinary\Cloudinary\Core\ConfigurationBuilder; +use Cloudinary\Cloudinary\Core\ConfigurationInterface; +use Magento\Backend\Block\Template\Context; +use Magento\Catalog\Model\Product\Media\Config; +use Magento\Framework\Json\EncoderInterface; +use Magento\Framework\UrlInterface; + +/** + * Block for gallery content. + */ +class Content extends \Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Gallery\Content +{ + /** + * @var string + */ + protected $_template = 'Cloudinary_Cloudinary::catalog/product/helper/gallery.phtml'; + + /** + * @var UrlInterface + */ + protected $urlBuilder; + + /** + * @var ConfigurationInterface + */ + protected $configuration; + + /** + * @var ConfigurationBuilder + */ + protected $configurationBuilder; + + /** + * Cloudinary credentials + * @var array|null + */ + protected $credentials; + + /** + * Current timestamp + * @var int|null + */ + protected $timestamp; + + /** + * Sugnature + * @var string|null + */ + protected $signature; + + /** + * Cloudinary ML Options + * @var array|null + */ + protected $cloudinaryMLoptions; + + /** + * @param Context $context + * @param EncoderInterface $jsonEncoder + * @param Config $mediaConfig + * @param ConfigurationInterface $configuration + * @param ConfigurationBuilder $configurationBuilder + * @param array $data + */ + public function __construct( + Context $context, + EncoderInterface $jsonEncoder, + Config $mediaConfig, + ConfigurationInterface $configuration, + ConfigurationBuilder $configurationBuilder, + array $data = [] + ) { + parent::__construct($context, $jsonEncoder, $mediaConfig, $data); + $this->urlBuilder = $context->getUrlBuilder(); + $this->configuration = $configuration; + $this->configurationBuilder = $configurationBuilder; + } + + /** + * Get Cloudinary media library widget options + * + * @return string + */ + public function getCloudinaryMediaLibraryWidgetOptions($refresh = false) + { + if ((is_null($this->cloudinaryMLoptions) || $refresh) && $this->configuration->isEnabled()) { + $this->cloudinaryMLoptions = []; + $this->timestamp = time(); + $this->credentials = $this->configurationBuilder->build(); + if (!$this->credentials["cloud_name"] || !$this->credentials["api_key"] || !$this->credentials["api_secret"]) { + $this->credentials = null; + } else { + $this->cloudinaryMLoptions = [ + 'cloud_name' => $this->credentials["cloud_name"], + 'api_key' => $this->credentials["api_key"], + 'cms_type' => 'magento', + 'multiple' => true, + //'default_transformations' => [['quality' => 'auto'],['format' => 'auto']], + ]; + if (($this->credentials["username"] = $this->configuration->getAutomaticLoginUser())) { + $this->cloudinaryMLoptions["timestamp"] = $this->timestamp; + $this->cloudinaryMLoptions["username"] = $this->credentials["username"]; + $this->cloudinaryMLoptions["signature"] = $this->signature = hash('sha256', urldecode(http_build_query([ + 'cloud_name' => $this->credentials['cloud_name'], + 'timestamp' => $this->timestamp, + 'username' => $this->credentials['username'], + ])) . $this->credentials['api_secret']); + } + } + } + if (!$this->cloudinaryMLoptions) { + return null; + } + return $this->_jsonEncoder->encode( + [ + 'htmlId' => $this->getHtmlId(), + 'cloudinaryPlaceholder' => $this->getViewFileUrl('Cloudinary_Cloudinary::images/cloudinary_vertical_logo_for_white_bg.svg'), + 'uploaderUrl' => $this->_urlBuilder->addSessionParam()->getUrl('cloudinary/product_gallery/upload'), + 'cloudinaryMLoptions' => $this->cloudinaryMLoptions, + ] + ); + } +} diff --git a/Controller/Adminhtml/Product/Gallery/Upload.php b/Controller/Adminhtml/Product/Gallery/Upload.php new file mode 100644 index 0000000..2a8a3f3 --- /dev/null +++ b/Controller/Adminhtml/Product/Gallery/Upload.php @@ -0,0 +1,74 @@ +curl = $curl; + $this->configuration = $configuration; + } + + /** + * @return \Magento\Framework\Controller\Result\Raw + */ + public function execute() + { + try { + if ($this->configuration->isEnabled()) { + $asset = $this->getRequest()->getPostValue("asset"); + $this->curl->get($asset['url']); + $asset['image'] = $this->curl->getBody(); + $this->getRequest()->setPostValue("asset", $asset); + + $tmpfile = tmpfile(); + fwrite($tmpfile, $asset['image']); + + $_FILES['image'] = [ + "name" => basename($asset['url']), + "type" => "{$asset['resource_type']}/{$asset['format']}", + "tmp_name" => stream_get_meta_data($tmpfile)['uri'], + "error" => 0, + "size" => $asset['bytes'], + ]; + } + } catch (\Exception $e) { + $response = $this->resultRawFactory->create(); + $response->setHeader('Content-type', 'text/plain'); + $response->setContents(json_encode(['error' => $e->getMessage(), 'errorcode' => $e->getCode()])); + return $response; + } + + return parent::execute(); + } +} diff --git a/Model/Configuration.php b/Model/Configuration.php index 0198d96..0b0e3f3 100644 --- a/Model/Configuration.php +++ b/Model/Configuration.php @@ -26,6 +26,7 @@ class Configuration implements ConfigurationInterface const CONFIG_PATH_ENABLED = 'cloudinary/cloud/cloudinary_enabled'; const USER_PLATFORM_TEMPLATE = 'CloudinaryMagento/%s (Magento %s)'; const CONFIG_PATH_ENVIRONMENT_VARIABLE = 'cloudinary/setup/cloudinary_environment_variable'; + const CONFIG_PATH_AUTOMATIC_LOGIN_USER = 'cloudinary/setup/cloudinary_automatic_login_user'; const CONFIG_CDN_SUBDOMAIN = 'cloudinary/configuration/cloudinary_cdn_subdomain'; //= Transformations const CONFIG_DEFAULT_GRAVITY = 'cloudinary/transformations/cloudinary_gravity'; @@ -125,6 +126,14 @@ public function getCredentials() return $this->getEnvironmentVariable()->getCredentials(); } + /** + * @return string + */ + public function getAutomaticLoginUser() + { + return (string) $this->configReader->getValue(self::CONFIG_PATH_AUTOMATIC_LOGIN_USER); + } + /** * @return Transformation */ diff --git a/Model/Observer/ProductGalleryChangeTemplate.php b/Model/Observer/ProductGalleryChangeTemplate.php new file mode 100644 index 0000000..3477195 --- /dev/null +++ b/Model/Observer/ProductGalleryChangeTemplate.php @@ -0,0 +1,42 @@ +configuration = $configuration; + } + + /** + * @param mixed $observer + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @return void + */ + public function execute(\Magento\Framework\Event\Observer $observer) + { + if (!$this->configuration->isEnabled()) { + return $this; + } + $observer->getBlock()->setTemplate('Cloudinary_Cloudinary::catalog/product/helper/gallery.phtml'); + } +} diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index dd3091e..42b42ef 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -23,6 +23,10 @@ Format should be: cloudinary://API_Key:API_Secret@Cloud_Name]]> Cloudinary\Cloudinary\Model\Config\Backend\Credentials + + + To always automatically log in to the Media Library with a predefined user account, enter the relevant email address. Leave blank to prompt each account user to log in when the Media Library opens. + diff --git a/view/adminhtml/requirejs-config.js b/view/adminhtml/requirejs-config.js index 329da34..930fbd6 100644 --- a/view/adminhtml/requirejs-config.js +++ b/view/adminhtml/requirejs-config.js @@ -4,7 +4,6 @@ var config = { cloudinaryFreeTransform: 'Cloudinary_Cloudinary/js/cloudinary-free', newVideoDialog: 'Cloudinary_Cloudinary/js/new-video-dialog', 'Magento_ProductVideo/js/get-video-information': 'Cloudinary_Cloudinary/js/get-video-information', - selectImageFromCloudinaryDialog: 'Cloudinary_Cloudinary/js/new-image-from-cloudinary-dialog', cloudinaryMediaLibraryModal: 'Cloudinary_Cloudinary/js/cloudinary-media-library-modal' } }, diff --git a/view/adminhtml/templates/catalog/product/helper/gallery.phtml b/view/adminhtml/templates/catalog/product/helper/gallery.phtml new file mode 100644 index 0000000..bd82059 --- /dev/null +++ b/view/adminhtml/templates/catalog/product/helper/gallery.phtml @@ -0,0 +1,358 @@ +getElement()->getName() . '[images]'; +$formName = $block->getFormName(); +$cloudinaryMLwidgetOprions = $block->getCloudinaryMediaLibraryWidgetOptions(); +?> + +
+
+ + + + +
+
+ +getElement(); +$elementToggleCode = $element->getToggleCode() ? $element->getToggleCode() : 'toggleValueElements(this, this.parentNode.parentNode.parentNode)'; +?> + + + diff --git a/view/adminhtml/ui_component/product_form.xml b/view/adminhtml/ui_component/product_form.xml new file mode 100644 index 0000000..bcf102e --- /dev/null +++ b/view/adminhtml/ui_component/product_form.xml @@ -0,0 +1,8 @@ + +
+ + + + + +
diff --git a/view/adminhtml/web/css/source/_module.less b/view/adminhtml/web/css/source/_module.less index 5983d59..455f2c7 100644 --- a/view/adminhtml/web/css/source/_module.less +++ b/view/adminhtml/web/css/source/_module.less @@ -9,3 +9,19 @@ margin-right: 5px; vertical-align: text-bottom; } +.image.image-placeholder.add-from-cloudinary-button .product-image-wrapper:before { + background-image: url('Cloudinary_Cloudinary::images/cloudinary_icon_for_dark_bg.svg'); + background-repeat: no-repeat; + background-size: 80px; + background-position: center; + display: block; + content: ""; + width: 100%; + height: 102px; + position: absolute; + top: 0; + left: 0; + opacity: 0.5; + -webkit-filter: grayscale(100%); + filter: grayscale(100%); +} diff --git a/view/adminhtml/web/js/cloudinary-media-library-modal.js b/view/adminhtml/web/js/cloudinary-media-library-modal.js new file mode 100644 index 0000000..251f164 --- /dev/null +++ b/view/adminhtml/web/js/cloudinary-media-library-modal.js @@ -0,0 +1,88 @@ +define([ + 'jquery', + 'productGallery', + 'jquery/ui', + 'Magento_Ui/js/modal/modal', + 'mage/translate', + 'mage/backend/tree-suggest', + 'mage/backend/validation', + 'cloudinaryMediaLibraryAll', + 'es6Promise' +], function($, productGallery) { + 'use strict'; + + $.widget('mage.cloudinaryMediaLibraryModal', { + + /** + * Bind events + * @private + */ + _bind: function() { + $('.add-from-cloudinary-button[data-role="add-from-cloudinary-button"]').on('click', this.openMediaLibrary.bind(this)); + }, + + /** + * @private + */ + _create: function() { + this._super(); + this._bind(); + + var widget = this; + + if (typeof window.cloudinary_ml === "undefined") { + this.cloudinary_ml = window.cloudinary_ml = cloudinary.createMediaLibrary( + this.options.cloudinaryMLoptions, { + insertHandler: function(data) { + return widget.cloudinaryInsertHandler(data); + } + } + ); + } else { + this.cloudinary_ml = window.cloudinary_ml; + } + + }, + + /** + * Fired on trigger "openMediaLibrary" + */ + openMediaLibrary: function() { + this.cloudinary_ml.show(); + }, + + /** + * Fired on trigger "cloudinaryInsertHandler" + */ + cloudinaryInsertHandler: function(data) { + //console.log("Inserted assets:", JSON.stringify(data.assets, null, 2)); + data.assets.forEach(asset => { + if (asset.resource_type === 'image') { + $.ajax({ + url: this.options.uploaderUrl, + data: { + asset: asset, + form_key: window.FORM_KEY + }, + method: 'POST', + dataType: 'json', + async: false, + showLoader: true + }).done( + function(response) { + //console.log(response); + $("#media_gallery_content .image.image-placeholder > .uploader").last().trigger('addItem', response); + } + ).fail( + function(response) { + alert($.mage.__('An error occured during image insert!')); + //console.log(response); + } + ); + } + }); + } + }); + + return $.mage.cloudinaryMediaLibraryModal; +}); \ No newline at end of file diff --git a/view/base/web/images/cloudinary_icon_for_dark_bg.svg b/view/base/web/images/cloudinary_icon_for_dark_bg.svg new file mode 100644 index 0000000..0dae7c9 --- /dev/null +++ b/view/base/web/images/cloudinary_icon_for_dark_bg.svg @@ -0,0 +1,69 @@ + + + + + + + + + + diff --git a/view/base/web/images/cloudinary_logo_for_dark_bg.svg b/view/base/web/images/cloudinary_logo_for_dark_bg.svg new file mode 100644 index 0000000..58bc88b --- /dev/null +++ b/view/base/web/images/cloudinary_logo_for_dark_bg.svg @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/view/base/web/images/cloudinary_vertical_logo_for_dark_bg.svg b/view/base/web/images/cloudinary_vertical_logo_for_dark_bg.svg new file mode 100644 index 0000000..73618ee --- /dev/null +++ b/view/base/web/images/cloudinary_vertical_logo_for_dark_bg.svg @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + From 3a54b120f7f980b9ee0d9a06dc6d290e47afc744 Mon Sep 17 00:00:00 2001 From: pini-girit Date: Thu, 17 Jan 2019 14:14:41 +0200 Subject: [PATCH 03/64] Implementing Cloudinary Media Library (in progress) - working on category/cms --- .../Adminhtml/Cms/Wysiwyg/Images/Content.php | 57 +++++++++++++ .../Product/Helper/Form/Gallery/Content.php | 84 ++---------------- Helper/MediaLibraryHelper.php | 85 +++++++++++++++++++ .../layout/cms_wysiwyg_images_index.xml | 9 ++ .../adminhtml/templates/browser/content.phtml | 39 +++++++++ 5 files changed, 199 insertions(+), 75 deletions(-) create mode 100644 Block/Adminhtml/Cms/Wysiwyg/Images/Content.php create mode 100644 Helper/MediaLibraryHelper.php create mode 100644 view/adminhtml/layout/cms_wysiwyg_images_index.xml create mode 100644 view/adminhtml/templates/browser/content.phtml diff --git a/Block/Adminhtml/Cms/Wysiwyg/Images/Content.php b/Block/Adminhtml/Cms/Wysiwyg/Images/Content.php new file mode 100644 index 0000000..d3d7921 --- /dev/null +++ b/Block/Adminhtml/Cms/Wysiwyg/Images/Content.php @@ -0,0 +1,57 @@ +mediaLibraryHelper = $mediaLibraryHelper; + } + + /** + * Get Cloudinary media library widget options + * + * @return string + */ + public function getCloudinaryMediaLibraryWidgetOptions($refresh = false) + { + if (!($cloudinaryMLoptions = $this->mediaLibraryHelper->getCloudinaryMLOptions($refresh))) { + return null; + } + return $this->_jsonEncoder->encode( + [ + 'htmlId' => $this->getHtmlId(), + 'uploaderUrl' => $this->_urlBuilder->addSessionParam()->getUrl('cloudinary/product_gallery/upload'), + 'cloudinaryMLoptions' => $cloudinaryMLoptions, + ] + ); + } +} diff --git a/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php b/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php index 7eebd22..13ffa9a 100644 --- a/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php +++ b/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php @@ -13,12 +13,10 @@ */ namespace Cloudinary\Cloudinary\Block\Adminhtml\Product\Helper\Form\Gallery; -use Cloudinary\Cloudinary\Core\ConfigurationBuilder; -use Cloudinary\Cloudinary\Core\ConfigurationInterface; +use Cloudinary\Cloudinary\Helper\MediaLibraryHelper; use Magento\Backend\Block\Template\Context; use Magento\Catalog\Model\Product\Media\Config; use Magento\Framework\Json\EncoderInterface; -use Magento\Framework\UrlInterface; /** * Block for gallery content. @@ -31,64 +29,27 @@ class Content extends \Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Galle protected $_template = 'Cloudinary_Cloudinary::catalog/product/helper/gallery.phtml'; /** - * @var UrlInterface - */ - protected $urlBuilder; - - /** - * @var ConfigurationInterface - */ - protected $configuration; - - /** - * @var ConfigurationBuilder - */ - protected $configurationBuilder; - - /** - * Cloudinary credentials - * @var array|null - */ - protected $credentials; - - /** - * Current timestamp - * @var int|null - */ - protected $timestamp; - - /** - * Sugnature - * @var string|null - */ - protected $signature; - - /** - * Cloudinary ML Options + * MediaLibraryHelper * @var array|null */ - protected $cloudinaryMLoptions; + protected $mediaLibraryHelper; /** * @param Context $context * @param EncoderInterface $jsonEncoder * @param Config $mediaConfig - * @param ConfigurationInterface $configuration - * @param ConfigurationBuilder $configurationBuilder + * @param MediaLibraryHelper $mediaLibraryHelper * @param array $data */ public function __construct( Context $context, EncoderInterface $jsonEncoder, Config $mediaConfig, - ConfigurationInterface $configuration, - ConfigurationBuilder $configurationBuilder, + MediaLibraryHelper $mediaLibraryHelper, array $data = [] ) { parent::__construct($context, $jsonEncoder, $mediaConfig, $data); - $this->urlBuilder = $context->getUrlBuilder(); - $this->configuration = $configuration; - $this->configurationBuilder = $configurationBuilder; + $this->mediaLibraryHelper = $mediaLibraryHelper; } /** @@ -98,40 +59,13 @@ public function __construct( */ public function getCloudinaryMediaLibraryWidgetOptions($refresh = false) { - if ((is_null($this->cloudinaryMLoptions) || $refresh) && $this->configuration->isEnabled()) { - $this->cloudinaryMLoptions = []; - $this->timestamp = time(); - $this->credentials = $this->configurationBuilder->build(); - if (!$this->credentials["cloud_name"] || !$this->credentials["api_key"] || !$this->credentials["api_secret"]) { - $this->credentials = null; - } else { - $this->cloudinaryMLoptions = [ - 'cloud_name' => $this->credentials["cloud_name"], - 'api_key' => $this->credentials["api_key"], - 'cms_type' => 'magento', - 'multiple' => true, - //'default_transformations' => [['quality' => 'auto'],['format' => 'auto']], - ]; - if (($this->credentials["username"] = $this->configuration->getAutomaticLoginUser())) { - $this->cloudinaryMLoptions["timestamp"] = $this->timestamp; - $this->cloudinaryMLoptions["username"] = $this->credentials["username"]; - $this->cloudinaryMLoptions["signature"] = $this->signature = hash('sha256', urldecode(http_build_query([ - 'cloud_name' => $this->credentials['cloud_name'], - 'timestamp' => $this->timestamp, - 'username' => $this->credentials['username'], - ])) . $this->credentials['api_secret']); - } - } - } - if (!$this->cloudinaryMLoptions) { + if (!($cloudinaryMLoptions = $this->mediaLibraryHelper->getCloudinaryMLOptions($refresh))) { return null; } return $this->_jsonEncoder->encode( [ - 'htmlId' => $this->getHtmlId(), - 'cloudinaryPlaceholder' => $this->getViewFileUrl('Cloudinary_Cloudinary::images/cloudinary_vertical_logo_for_white_bg.svg'), - 'uploaderUrl' => $this->_urlBuilder->addSessionParam()->getUrl('cloudinary/product_gallery/upload'), - 'cloudinaryMLoptions' => $this->cloudinaryMLoptions, + //'uploaderUrl' => $this->_urlBuilder->addSessionParam()->getUrl('cloudinary/product_gallery/upload'), + 'cloudinaryMLoptions' => $cloudinaryMLoptions, ] ); } diff --git a/Helper/MediaLibraryHelper.php b/Helper/MediaLibraryHelper.php new file mode 100644 index 0000000..384324c --- /dev/null +++ b/Helper/MediaLibraryHelper.php @@ -0,0 +1,85 @@ +configuration = $configuration; + } + + public function getCloudinaryMLOptions($refresh = false) + { + if ((is_null($this->cloudinaryMLoptions) || $refresh) && $this->configuration->isEnabled()) { + $this->cloudinaryMLoptions = []; + $this->timestamp = time(); + $this->credentials = [ + "cloud_name" => (string)$this->configuration->getCloud(), + "api_key" => (string)$this->configuration->getCredentials()->getKey(), + "api_secret" => (string)$this->configuration->getCredentials()->getSecret() + ]; + if (!$this->credentials["cloud_name"] || !$this->credentials["api_key"] || !$this->credentials["api_secret"]) { + $this->credentials = null; + } else { + $this->cloudinaryMLoptions = [ + 'cloud_name' => $this->credentials["cloud_name"], + 'api_key' => $this->credentials["api_key"], + 'cms_type' => 'magento', + 'multiple' => true, + //'default_transformations' => [['quality' => 'auto'],['format' => 'auto']], + ]; + if (($this->credentials["username"] = $this->configuration->getAutomaticLoginUser())) { + $this->cloudinaryMLoptions["timestamp"] = $this->timestamp; + $this->cloudinaryMLoptions["username"] = $this->credentials["username"]; + $this->cloudinaryMLoptions["signature"] = $this->signature = hash('sha256', urldecode(http_build_query([ + 'cloud_name' => $this->credentials['cloud_name'], + 'timestamp' => $this->timestamp, + 'username' => $this->credentials['username'], + ])) . $this->credentials['api_secret']); + } + } + } + + return $this->cloudinaryMLoptions; + } +} diff --git a/view/adminhtml/layout/cms_wysiwyg_images_index.xml b/view/adminhtml/layout/cms_wysiwyg_images_index.xml new file mode 100644 index 0000000..53a5bbc --- /dev/null +++ b/view/adminhtml/layout/cms_wysiwyg_images_index.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/view/adminhtml/templates/browser/content.phtml b/view/adminhtml/templates/browser/content.phtml new file mode 100644 index 0000000..4c8339d --- /dev/null +++ b/view/adminhtml/templates/browser/content.phtml @@ -0,0 +1,39 @@ + +getCloudinaryMediaLibraryWidgetOptions(); +?> + + From 29c64f5bbdf0bc9415d22da4f1cd2af5f4b7892f Mon Sep 17 00:00:00 2001 From: pini-girit Date: Sun, 20 Jan 2019 14:33:15 +0200 Subject: [PATCH 04/64] CLOUDINARY-74 --- .../Adminhtml/Cms/Wysiwyg/Images/Content.php | 26 +++++++-- .../Product/Helper/Form/Gallery/Content.php | 7 ++- .../Adminhtml/Cms/Wysiwyg/Images/Upload.php | 56 +++++++++++++++++++ .../Adminhtml/Product/Gallery/Upload.php | 39 +++---------- Helper/MediaLibraryHelper.php | 48 +++++++++++++++- .../adminhtml/templates/browser/content.phtml | 14 +++-- .../catalog/product/helper/gallery.phtml | 21 +++---- view/adminhtml/web/css/source/_module.less | 39 +++++++++++++ .../web/js/cloudinary-media-library-modal.js | 26 +++++++-- 9 files changed, 212 insertions(+), 64 deletions(-) create mode 100644 Controller/Adminhtml/Cms/Wysiwyg/Images/Upload.php diff --git a/Block/Adminhtml/Cms/Wysiwyg/Images/Content.php b/Block/Adminhtml/Cms/Wysiwyg/Images/Content.php index d3d7921..32bc5fb 100644 --- a/Block/Adminhtml/Cms/Wysiwyg/Images/Content.php +++ b/Block/Adminhtml/Cms/Wysiwyg/Images/Content.php @@ -47,11 +47,25 @@ public function getCloudinaryMediaLibraryWidgetOptions($refresh = false) return null; } return $this->_jsonEncoder->encode( - [ - 'htmlId' => $this->getHtmlId(), - 'uploaderUrl' => $this->_urlBuilder->addSessionParam()->getUrl('cloudinary/product_gallery/upload'), - 'cloudinaryMLoptions' => $cloudinaryMLoptions, - ] - ); + [ + 'imageUploaderUrl' => $this->_urlBuilder->addSessionParam()->getUrl('cloudinary/cms_wysiwyg_images/upload', ['type' => $this->_getMediaType()]), + 'triggerSelector' => '.media-gallery-modal', + 'triggerEvent' => 'fileuploaddone', + 'cloudinaryMLoptions' => $cloudinaryMLoptions, + ] + ); + } + + /** + * Return current media type based on request or data + * + * @return string + */ + protected function _getMediaType() + { + if ($this->hasData('media_type')) { + return $this->_getData('media_type'); + } + return $this->getRequest()->getParam('type'); } } diff --git a/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php b/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php index 13ffa9a..1b5bd59 100644 --- a/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php +++ b/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php @@ -64,8 +64,11 @@ public function getCloudinaryMediaLibraryWidgetOptions($refresh = false) } return $this->_jsonEncoder->encode( [ - //'uploaderUrl' => $this->_urlBuilder->addSessionParam()->getUrl('cloudinary/product_gallery/upload'), - 'cloudinaryMLoptions' => $cloudinaryMLoptions, + 'htmlId' => $this->getHtmlId(), + 'imageUploaderUrl' => $this->_urlBuilder->addSessionParam()->getUrl('cloudinary/product_gallery/upload'), + 'triggerSelector' => '#media_gallery_content .image.image-placeholder > .uploader', + 'triggerEvent' => 'addItem', + 'cloudinaryMLoptions' => $cloudinaryMLoptions, ] ); } diff --git a/Controller/Adminhtml/Cms/Wysiwyg/Images/Upload.php b/Controller/Adminhtml/Cms/Wysiwyg/Images/Upload.php new file mode 100644 index 0000000..ba92a20 --- /dev/null +++ b/Controller/Adminhtml/Cms/Wysiwyg/Images/Upload.php @@ -0,0 +1,56 @@ +mediaLibraryHelper = $mediaLibraryHelper; + } + + /** + * Files upload processing. + * + * @return \Magento\Framework\Controller\ResultInterface + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function execute() + { + try { + $tmpfile = $this->mediaLibraryHelper->convertRequestAssetUrlToImage(); + } catch (\Exception $e) { + $resultJson = $this->resultJsonFactory->create(); + return $resultJson->setData(['error' => $e->getMessage(), 'errorcode' => $e->getCode()]); + } + + return parent::execute(); + } +} diff --git a/Controller/Adminhtml/Product/Gallery/Upload.php b/Controller/Adminhtml/Product/Gallery/Upload.php index 2a8a3f3..d352e44 100644 --- a/Controller/Adminhtml/Product/Gallery/Upload.php +++ b/Controller/Adminhtml/Product/Gallery/Upload.php @@ -1,21 +1,17 @@ curl = $curl; - $this->configuration = $configuration; + $this->mediaLibraryHelper = $mediaLibraryHelper; } /** @@ -45,23 +38,7 @@ public function __construct( public function execute() { try { - if ($this->configuration->isEnabled()) { - $asset = $this->getRequest()->getPostValue("asset"); - $this->curl->get($asset['url']); - $asset['image'] = $this->curl->getBody(); - $this->getRequest()->setPostValue("asset", $asset); - - $tmpfile = tmpfile(); - fwrite($tmpfile, $asset['image']); - - $_FILES['image'] = [ - "name" => basename($asset['url']), - "type" => "{$asset['resource_type']}/{$asset['format']}", - "tmp_name" => stream_get_meta_data($tmpfile)['uri'], - "error" => 0, - "size" => $asset['bytes'], - ]; - } + $tmpfile = $this->mediaLibraryHelper->convertRequestAssetUrlToImage(); } catch (\Exception $e) { $response = $this->resultRawFactory->create(); $response->setHeader('Content-type', 'text/plain'); diff --git a/Helper/MediaLibraryHelper.php b/Helper/MediaLibraryHelper.php index 384324c..0b8fd21 100644 --- a/Helper/MediaLibraryHelper.php +++ b/Helper/MediaLibraryHelper.php @@ -4,6 +4,8 @@ use Cloudinary\Cloudinary\Core\ConfigurationInterface; use Magento\Framework\App\Helper\Context; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\HTTP\Client\Curl; class MediaLibraryHelper extends \Magento\Framework\App\Helper\AbstractHelper { @@ -12,6 +14,16 @@ class MediaLibraryHelper extends \Magento\Framework\App\Helper\AbstractHelper */ protected $configuration; + /** + * @var RequestInterface + */ + protected $request; + + /** + * @var Curl + */ + protected $curl; + /** * Cloudinary credentials * @var array|null @@ -39,13 +51,24 @@ class MediaLibraryHelper extends \Magento\Framework\App\Helper\AbstractHelper /** * @param Context $context * @param ConfigurationInterface $configuration + * @param RequestInterface $request + * @param Curl $curl */ public function __construct( Context $context, - ConfigurationInterface $configuration + ConfigurationInterface $configuration, + RequestInterface $request, + Curl $curl ) { parent::__construct($context); $this->configuration = $configuration; + $this->request = $request; + $this->curl = $curl; + } + + protected function getRequest() + { + return $this->request; } public function getCloudinaryMLOptions($refresh = false) @@ -82,4 +105,27 @@ public function getCloudinaryMLOptions($refresh = false) return $this->cloudinaryMLoptions; } + + public function convertRequestAssetUrlToImage() + { + if ($this->configuration->isEnabled()) { + $asset = $this->getRequest()->getPostValue("asset"); + $this->curl->get($asset['url']); + $asset['image'] = $this->curl->getBody(); + $this->getRequest()->setPostValue("asset", $asset); + + $tmpfile = tmpfile(); + fwrite($tmpfile, $asset['image']); + + $_FILES['image'] = [ + "name" => basename($asset['url']), + "type" => "{$asset['resource_type']}/{$asset['format']}", + "tmp_name" => stream_get_meta_data($tmpfile)['uri'], + "error" => 0, + "size" => $asset['bytes'], + ]; + + return $tmpfile; + } + } } diff --git a/view/adminhtml/templates/browser/content.phtml b/view/adminhtml/templates/browser/content.phtml index 4c8339d..f1d12bc 100644 --- a/view/adminhtml/templates/browser/content.phtml +++ b/view/adminhtml/templates/browser/content.phtml @@ -26,12 +26,14 @@ $cloudinaryMLwidgetOprions = $block->getCloudinaryMediaLibraryWidgetOptions();
-
- [Cloudinary Button] -
-                    
-                
-

+
getChildHtml('wysiwyg_images.uploader') ?>
diff --git a/view/adminhtml/templates/catalog/product/helper/gallery.phtml b/view/adminhtml/templates/catalog/product/helper/gallery.phtml index bd82059..c9fb435 100644 --- a/view/adminhtml/templates/catalog/product/helper/gallery.phtml +++ b/view/adminhtml/templates/catalog/product/helper/gallery.phtml @@ -24,12 +24,12 @@ $cloudinaryMLwidgetOprions = $block->getCloudinaryMediaLibraryWidgetOptions();
@@ -43,10 +43,7 @@ $elementToggleCode = $element->getToggleCode() ? $element->getToggleCode() : 'to