diff --git a/Block/Adminhtml/Cms/Wysiwyg/Images/Content.php b/Block/Adminhtml/Cms/Wysiwyg/Images/Content.php index 9adcfb4..671e7a8 100644 --- a/Block/Adminhtml/Cms/Wysiwyg/Images/Content.php +++ b/Block/Adminhtml/Cms/Wysiwyg/Images/Content.php @@ -5,6 +5,7 @@ use Cloudinary\Cloudinary\Helper\MediaLibraryHelper; use Magento\Backend\Block\Widget\Context; use Magento\Framework\Json\EncoderInterface; +use Magento\Framework\App\ProductMetadataInterface; /** * Wysiwyg Images content block @@ -20,6 +21,9 @@ class Content extends \Magento\Cms\Block\Adminhtml\Wysiwyg\Images\Content */ protected $mediaLibraryHelper; + + protected $productMetadata; + /** * @param Context $context * @param EncoderInterface $jsonEncoder @@ -30,10 +34,12 @@ public function __construct( Context $context, EncoderInterface $jsonEncoder, MediaLibraryHelper $mediaLibraryHelper, + ProductMetadataInterface $productMetadata, array $data = [] ) { parent::__construct($context, $jsonEncoder, $data); $this->mediaLibraryHelper = $mediaLibraryHelper; + $this->productMetadata = $productMetadata; } /** @@ -50,12 +56,17 @@ public function getCloudinaryMediaLibraryWidgetOptions($multiple = false, $refre } try { + if (version_compare($this->productMetadata->getVersion(), '2.3.5', '<=')) { + $imageUploadUrl = $this->_urlBuilder->addSessionParam()->getUrl('cloudinary/cms_wysiwyg_images/upload', ['type' => $this->_getMediaType()]); + } else { + $imageUploadUrl = $this->_urlBuilder->getUrl('cloudinary/cms_wysiwyg_images/upload', ['type' => $this->_getMediaType()]); + } //Try to add session param on Magento versions prior to 2.3.5 - $imageUploadUrl = $this->_urlBuilder->addSessionParam()->getUrl('cloudinary/cms_wysiwyg_images/upload', ['type' => $this->_getMediaType()]); + } catch (\Exception $e) { //Catch deprecation error on Magento 2.3.5 and above - $imageUploadUrl = $this->_urlBuilder->getUrl('cloudinary/cms_wysiwyg_images/upload', ['type' => $this->_getMediaType()]); + throw new \Exception($e->getMessage()); } return $this->_jsonEncoder->encode( diff --git a/Block/Adminhtml/Product/Edit/NewVideo.php b/Block/Adminhtml/Product/Edit/NewVideo.php index 2d17865..15eb5bd 100644 --- a/Block/Adminhtml/Product/Edit/NewVideo.php +++ b/Block/Adminhtml/Product/Edit/NewVideo.php @@ -107,6 +107,10 @@ public function getWidgetOptions() */ protected function getNoteVideoUrl() { + if (!$this->configuration->isModuleEnabled()) { + return parent::getNoteVideoUrl(); + } + $result = __('Supported: Vimeo'); $messages = ""; if ($this->mediaHelper->getYouTubeApiKey() === null) { diff --git a/Block/Scripts.php b/Block/Scripts.php new file mode 100644 index 0000000..3ad2730 --- /dev/null +++ b/Block/Scripts.php @@ -0,0 +1,32 @@ +_helper = $mediaHelper; + } + + /** + * @return void + */ + public function getCname() + { + return $this->_helper->getCname(); + } + + +} diff --git a/Controller/Adminhtml/Cms/Wysiwyg/Images/Upload.php b/Controller/Adminhtml/Cms/Wysiwyg/Images/Upload.php index ea5f17e..bae2d86 100644 --- a/Controller/Adminhtml/Cms/Wysiwyg/Images/Upload.php +++ b/Controller/Adminhtml/Cms/Wysiwyg/Images/Upload.php @@ -18,6 +18,9 @@ use Magento\Framework\Validator\AllowedProtocols; use Magento\MediaStorage\Model\File\Validator\NotProtectedExtension; use Magento\MediaStorage\Model\ResourceModel\File\Storage\File; +use Magento\MediaGalleryUi\Model\UploadImage as MediaGalleryUploader; +use Magento\MediaGalleryApi\Api\Data\AssetInterfaceFactory; +use Magento\MediaGalleryApi\Api\SaveAssetsInterface; /** * Upload image. @@ -96,6 +99,13 @@ class Upload extends \Magento\Cms\Controller\Adminhtml\Wysiwyg\Images\Upload */ private $mediaLibraryMapFactory; + + private $mediaGalleryUploader; + + protected $mediaAsset; + + protected $mediaAssetSave; + /** * @method __construct * @param Context $context @@ -127,7 +137,11 @@ public function __construct( AllowedProtocols $protocolValidator, NotProtectedExtension $extensionValidator, ConfigurationInterface $configuration, - MediaLibraryMapFactory $mediaLibraryMapFactory + MediaLibraryMapFactory $mediaLibraryMapFactory, + MediaGalleryUploader $mediaGalleryUploader, + AssetInterfaceFactory $mediaAsset, + SaveAssetsInterface $mediaAssetSave + ) { parent::__construct($context, $coreRegistry, $resultJsonFactory, $directoryResolver); $this->directoryList = $directoryList; @@ -140,6 +154,9 @@ public function __construct( $this->protocolValidator = $protocolValidator; $this->configuration = $configuration; $this->mediaLibraryMapFactory = $mediaLibraryMapFactory; + $this->mediaGalleryUploader = $mediaGalleryUploader; + $this->mediaAsset = $mediaAsset; + $this->mediaAssetSave = $mediaAssetSave; } /** @@ -152,7 +169,12 @@ public function execute() { try { $this->_initAction(); - $path = $this->getStorage()->getSession()->getCurrentPath(); + $path = ($this->getStorage()->getSession()->getCurrentPath()) ?? null; + + if (!$path){ + $path = $this->directoryList->getRoot() .'/pub/'. DirectoryList::MEDIA .'/cloudinary'; + } + if (!$this->validatePath($path, DirectoryList::MEDIA)) { throw new \Magento\Framework\Exception\LocalizedException( __('Directory %1 is not under storage root path.', $path) @@ -174,6 +196,24 @@ public function execute() $this->getStorage()->resizeFile($localFilePath, true); $this->imageAdapter->validateUploadFile($localFilePath); $result = $this->appendResultSaveRemoteImage($localFilePath); + $asset = $this->getRequest()->getParam('asset'); + $reg = preg_match('/^(.*)\/media\//',$localFilePath,$substruct); + $newPath = str_replace($substruct[0],'',$localFilePath); + $ma = $this->mediaAsset->create( + [ + //'id' => 2020, + 'path' => $newPath, + 'description' => $localFileName, + 'contentType' => $asset['resource_type'], + 'title' => $localFileName, + 'source' => 'Cloudinary', + 'width' => $asset['width'], + 'height' => $asset['height'], + 'size' => $asset['bytes'] + ] + ); + $this->mediaAssetSave->execute([$ma]); + // $mgu = $this->mediaGalleryUploader->execute($path, $type); if ($this->configuration->isEnabledLocalMapping()) { $this->saveCloudinaryMapping(); } diff --git a/Controller/Adminhtml/PageBuilder/MediaGallery/Upload.php b/Controller/Adminhtml/PageBuilder/MediaGallery/Upload.php new file mode 100644 index 0000000..6d72df9 --- /dev/null +++ b/Controller/Adminhtml/PageBuilder/MediaGallery/Upload.php @@ -0,0 +1,58 @@ +logger = $logger; + } + + public function execute() + { + $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON); + try{ + $params = $this->getRequest()->getParams(); + + } catch (NoSuchEntityException $e) { + $responseCode = self::HTTP_OK; + $responseContent = []; + } catch (\Exception $e) { + $responseCode = self::HTTP_INTERNAL_ERROR; + $this->logger->critical($e); + $responseContent = [ + 'success' => false, + 'message' => __('An error occurred on attempt to retrieve asset information.'), + ]; + } + + $resultJson->setHttpResponseCode($responseCode); + $resultJson->setData($responseContent); + + return $resultJson; + } +} diff --git a/Core/ConfigurationBuilder.php b/Core/ConfigurationBuilder.php index db033af..655ade7 100644 --- a/Core/ConfigurationBuilder.php +++ b/Core/ConfigurationBuilder.php @@ -17,15 +17,26 @@ public function __construct(ConfigurationInterface $configuration) /** * @return Configuration instance - * CLOUDINARY_URL=cloudinary://667623344116464:cKLIAxkU1_iPW8OCjumZ4E2i51A@m2clduat */ public function build() { $reg = $this->configuration->getCoreRegistry(); + $credentials = $this->configuration->getCredentials(); + $cloud = [ + 'cloud_name' => $credentials['cloud_name'], + 'api_key' => $credentials['api_key'], + 'api_secret' => $credentials['api_secret'] + ]; - $config = array('cloud' => $this->configuration->getCredentials()); + $url = array_diff($credentials, $cloud); + + $config = array('cloud' => $cloud); + + if ($url && is_array($url)) { + $config['url'] = $url; + } if ($this->configuration->getCdnSubdomainStatus()) { $config['cloud']['cdn_subdomain'] = true; diff --git a/Helper/MediaLibraryHelper.php b/Helper/MediaLibraryHelper.php index fa2828c..4d0376c 100644 --- a/Helper/MediaLibraryHelper.php +++ b/Helper/MediaLibraryHelper.php @@ -100,4 +100,13 @@ public function getCloudinaryMLshowOptions($resourceType = null, $path = "") } return $options; } + + /** + * @return null + */ + public function getCname() + { + $cname = isset($this->configuration->getCredentials()['cname']) ? $this->configuration->getCredentials()['cname'] : null; + return $cname; + } } diff --git a/Helper/ProductGalleryHelper.php b/Helper/ProductGalleryHelper.php index 8e3103c..5e2da8f 100644 --- a/Helper/ProductGalleryHelper.php +++ b/Helper/ProductGalleryHelper.php @@ -94,6 +94,7 @@ public function getCloudinaryPGOptions($refresh = false, $ignoreDisabled = false unset($this->cloudinaryPGoptions['custom_free_params']); } $this->cloudinaryPGoptions['cloudName'] = $this->getCloudName(); + $this->cloudinaryPGoptions['cname'] = $this->getCname(); $this->cloudinaryPGoptions['queryParam'] = 'AB'; } @@ -109,6 +110,16 @@ public function getCloudName() return (string)$this->configuration->getCloud(); } + + public function getCname() + { + $config = $this->configuration->getCredentials(); + return ($config['cname']) ?? ''; + } + + + + /** * @return bool */ diff --git a/Model/Config/Backend/Credentials.php b/Model/Config/Backend/Credentials.php index 0c86bac..7a1ac68 100644 --- a/Model/Config/Backend/Credentials.php +++ b/Model/Config/Backend/Credentials.php @@ -156,14 +156,14 @@ private function getCredentialsFromEnvironmentVariable($environmentVariable) $environmentVariable = str_replace('CLOUDINARY_URL=', '', $environmentVariable); $uri = parse_url($environmentVariable); if (!isset($uri["scheme"]) || strtolower($uri["scheme"]) !== "cloudinary") { - throw new InvalidArgumentException("Invalid CLOUDINARY_URL scheme. Expecting to start with 'cloudinary://'"); + throw new \InvalidArgumentException("Invalid CLOUDINARY_URL scheme. Expecting to start with 'cloudinary://'"); } $q_params = []; if (isset($uri["query"])) { parse_str($uri["query"], $q_params); } $private_cdn = isset($uri["path"]) && $uri["path"] != "/"; - $config = array_merge( + $credentials = array_merge( $q_params, [ "cloud_name" => $uri["host"], @@ -172,19 +172,14 @@ private function getCredentialsFromEnvironmentVariable($environmentVariable) "private_cdn" => $private_cdn, ] ); - if ($private_cdn) { - $config["secure_distribution"] = substr($uri["path"], 1); - } - $credentials = [ - "cloud_name" => $config['cloud_name'], - "api_key" => $config['api_key'], - "api_secret" => $config['api_secret'] - ]; - if (isset($config['private_cdn'])) { - $credentials["private_cdn"] = $config['private_cdn']; + + if (isset($credentials['cname'])) { + $credentials['secure'] = true; + $credentials['secure_distribution'] = $credentials['cname']; } return $credentials; + } catch (\Exception $e) { throw new ValidatorException(__(self::CREDENTIALS_CHECK_FAILED)); } diff --git a/Model/Config/Backend/Free.php b/Model/Config/Backend/Free.php index 4298020..1c291af 100644 --- a/Model/Config/Backend/Free.php +++ b/Model/Config/Backend/Free.php @@ -11,18 +11,25 @@ use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Data\Collection\AbstractDb; use Magento\Framework\Exception\ValidatorException; -use Magento\Framework\HTTP\ZendClient; +use Magento\Framework\App\ProductMetadataInterface; use Magento\Framework\Model\Context; use Magento\Framework\Model\ResourceModel\AbstractResource; use Magento\Framework\Phrase; use Magento\Framework\Registry; -use Zend_Http_Response; +use Laminas\Http\Response as LaminasResponse; class Free extends \Magento\Framework\App\Config\Value { const ERROR_FORMAT = 'Incorrect custom transform - %1'; const ERROR_DEFAULT = 'please update'; + /** + * @var ProductMetadataInterface + */ + protected $productMetadata; + + protected $clientType; + /** * @var ConfigurationInterface */ @@ -34,21 +41,21 @@ class Free extends \Magento\Framework\App\Config\Value private $cloudinaryImageProvider; /** - * @var ZendClient + * @var LaminasClient|\Magento\Framework\HTTP\ZendClient */ - private $zendClient; + private $httpClient; /** - * @param Context $context - * @param Registry $registry - * @param ScopeConfigInterface $config - * @param TypeListInterface $cacheTypeList - * @param ConfigurationInterface $configuration, + * @param Context $context + * @param Registry $registry + * @param ScopeConfigInterface $config + * @param TypeListInterface $cacheTypeList + * @param ConfigurationInterface $configuration * @param CloudinaryImageProvider $cloudinaryImageProvider - * @param ZendClient $zendClient - * @param AbstractResource $resource - * @param AbstractDb $resourceCollection - * @param array $data + * @param ProductMetadataInterface $productMetadata + * @param AbstractResource|null $resource + * @param AbstractDb|null $resourceCollection + * @param array $data */ public function __construct( Context $context, @@ -57,18 +64,28 @@ public function __construct( TypeListInterface $cacheTypeList, ConfigurationInterface $configuration, CloudinaryImageProvider $cloudinaryImageProvider, - ZendClient $zendClient, + ProductMetadataInterface $productMetadata, AbstractResource $resource = null, AbstractDb $resourceCollection = null, array $data = [] ) { $this->configuration = $configuration; $this->cloudinaryImageProvider = $cloudinaryImageProvider; - $this->zendClient = $zendClient; + $this->productMetadata = $productMetadata; + // fix for magento versions 2.4.6 or newer + if (version_compare($productMetadata->getVersion(), '2.4.6', '>=')) { + $this->httpClient = new \Magento\Framework\HTTP\LaminasClient(); + $this->clientType = 'laminas'; + } else { + $this->httpClient = new \Magento\Framework\HTTP\ZendClient(); + $this->clientType = 'zend'; + } + parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data); } + public function beforeSave() { if ($this->hasAccountConfigured() && $this->getValue()) { @@ -96,30 +113,45 @@ public function validate($url) throw new ValidatorException(__(self::ERROR_FORMAT, self::ERROR_DEFAULT)); } - if ($response->isError()) { + $isError = ($this->clientType == 'laminas') ? (!$response->isSuccess()) : $response->isError(); + + if ($isError) { throw new ValidatorException($this->formatError($response)); } } + + protected function getHeader($response) { + return ($this->clientType == 'laminas') ? $response->getHeaders()->get('x-cld-error') : $response->getHeader('x-cld-error'); + } + /** - * @param Zend_Http_Response $response + * @param $response * @return Phrase */ - public function formatError(Zend_Http_Response $response) + public function formatError($response) { + $status = ($this->clientType == 'laminas') ? $response->getStatusCode() : $response->getStatus(); + $res = ($this->clientType == 'laminas') ? $this->getHeader($response)->getFieldValue() : $this->getHeader($response); return __( self::ERROR_FORMAT, - $response->getStatus() == 400 ? $response->getHeader('x-cld-error') : self::ERROR_DEFAULT + $status == 400 ? $res : self::ERROR_DEFAULT ); } /** - * @param string $url - * @return Zend_Http_Response + * @param $url + * @return mixed */ public function httpRequest($url) { - return $this->zendClient->setUri($url)->request(ZendClient::GET); + if ($this->clientType == 'laminas') { + $client = $this->httpClient->setUri($url)->setMethod(\Laminas\Http\Request::METHOD_GET); + return $client->send(); + } else { + return $this->httpClient->setUri($url)->request('GET'); + } + } /** diff --git a/Model/Configuration.php b/Model/Configuration.php index 997708c..9058c5c 100644 --- a/Model/Configuration.php +++ b/Model/Configuration.php @@ -164,20 +164,23 @@ class Configuration implements ConfigurationInterface */ private $coreRegistry; + /** + * @var ManagerInterface + */ private $messageManager; /** - * @method __construct - * @param ScopeConfigInterface $configReader - * @param WriterInterface $configWriter - * @param EncryptorInterface $decryptor - * @param AutoUploadConfigurationInterface $autoUploadConfiguration - * @param LoggerInterface $logger - * @param StoreManagerInterface $storeManager - * @param ModuleListInterface $moduleList - * @param ProductMetadataInterface $productMetadata - * @param CloudinaryLogger $cloudinaryLogger - * @param Registry $coreRegistry + * @param ScopeConfigInterface $configReader + * @param WriterInterface $configWriter + * @param EncryptorInterface $decryptor + * @param AutoUploadConfigurationInterface $autoUploadConfiguration + * @param LoggerInterface $logger + * @param StoreManagerInterface $storeManager + * @param ModuleListInterface $moduleList + * @param ProductMetadataInterface $productMetadata + * @param Logger $cloudinaryLogger + * @param Registry $coreRegistry + * @param ManagerInterface $messageManager */ public function __construct( ScopeConfigInterface $configReader, @@ -203,6 +206,7 @@ public function __construct( $this->cloudinaryLogger = $cloudinaryLogger; $this->coreRegistry = $coreRegistry; $this->messageManager = $messageManager; + } /** @@ -234,40 +238,38 @@ public function getCloud() */ public function getCredentials() { - $rawValue = $this->configReader->getValue(self::CONFIG_PATH_ENVIRONMENT_VARIABLE, \Magento\Store\Model\ScopeInterface::SCOPE_STORE); - $value = $this->decryptor->decrypt($rawValue); - $environmentVariable = str_replace('CLOUDINARY_URL=', '', $value); - $uri = parse_url($environmentVariable); - if (!isset($uri["scheme"]) || strtolower($uri["scheme"]) !== "cloudinary") { - throw new \InvalidArgumentException("Invalid CLOUDINARY_URL scheme. Expecting to start with 'cloudinary://'"); - } - $q_params = []; - if (isset($uri["query"])) { - parse_str($uri["query"], $q_params); - } - $private_cdn = isset($uri["path"]) && $uri["path"] != "/"; - $config = array_merge( - $q_params, - [ - "cloud_name" => $uri["host"], - "api_key" => $uri["user"], - "api_secret" => $uri["pass"], - "private_cdn" => $private_cdn, - ] - ); - if ($private_cdn) { - $config["secure_distribution"] = substr($uri["path"], 1); - } - $credentials = [ - "cloud_name" => $config['cloud_name'], - "api_key" => $config['api_key'], - "api_secret" => $config['api_secret'] - ]; - if (isset($config['private_cdn'])) { - $credentials["private_cdn"] = $config['private_cdn']; + if ($this->isModuleEnabled()) { + $rawValue = $this->configReader->getValue(self::CONFIG_PATH_ENVIRONMENT_VARIABLE, \Magento\Store\Model\ScopeInterface::SCOPE_STORE); + $value = $this->decryptor->decrypt($rawValue); + $environmentVariable = str_replace('CLOUDINARY_URL=', '', $value); + $uri = parse_url($environmentVariable); + if (!isset($uri["scheme"]) || strtolower($uri["scheme"]) !== "cloudinary") { + throw new \InvalidArgumentException("Invalid CLOUDINARY_URL scheme. Expecting to start with 'cloudinary://'"); + } + $q_params = []; + if (isset($uri["query"])) { + parse_str($uri["query"], $q_params); + } + $private_cdn = isset($uri["path"]) && $uri["path"] != "/"; + + $credentials = array_merge( + $q_params, + [ + "cloud_name" => $uri["host"], + "api_key" => $uri["user"], + "api_secret" => $uri["pass"], + "private_cdn" => $private_cdn, + ] + ); + + if (isset($credentials['cname'])) { + $credentials['secure'] = true; + $credentials['secure_distribution'] = $credentials['cname']; + } + + return $credentials; } - return $credentials; } /** @@ -341,6 +343,13 @@ public function getUploadConfig() return UploadConfig::fromBooleanValues(self::USE_FILENAME, self::UNIQUE_FILENAME, self::OVERWRITE); } + /** + * @return bool + */ + public function isModuleEnabled() + { + return (bool) $this->configReader->getValue(self::CONFIG_PATH_ENABLED); + } /** * @return boolean */ diff --git a/Model/Observer/UploadProductImage.php b/Model/Observer/UploadProductImage.php index d0e9faf..c09e8cb 100644 --- a/Model/Observer/UploadProductImage.php +++ b/Model/Observer/UploadProductImage.php @@ -39,7 +39,20 @@ public function execute(Observer $observer) $product = $observer->getEvent()->getProduct(); foreach ($this->productImageFinder->findNewImages($product) as $image) { - $this->cloudinaryImageManager->uploadAndSynchronise($image); + if (!$this->isCloudinaryImage($image)) { + $this->cloudinaryImageManager->uploadAndSynchronise($image); + } } } + /** + * Check if image sourced from Cloudinary media + * @param $image + * return bool + */ + protected function isCloudinaryImage($image) + { + $file = $image->getRelativePath(); + $cld_prefix = 'c/l/cld_'; + return strpos($file,$cld_prefix); + } } diff --git a/Ui/Component/Control/AddFromCloudinary.php b/Ui/Component/Control/AddFromCloudinary.php new file mode 100644 index 0000000..6e91330 --- /dev/null +++ b/Ui/Component/Control/AddFromCloudinary.php @@ -0,0 +1,67 @@ +images = $images; + $this->authorization = $authorization; + $this->cmsWysiwygImages = $cmsWysiwygImages; + } + /** + * @inheritdoc + */ + public function getButtonData(): array + { + $cloudinaryMLwidgetOprions = json_decode($this->images->getCloudinaryMediaLibraryWidgetOptions(),true); + + + $buttonData = [ + 'label' => __('Add From Cloudinary'), + 'class' => 'action-secondary add-from-cloudinary-button cloudinary-button-with-logo lg-margin-bottom', + 'on_click' => 'return false;', + 'data_attribute' => [ + 'mage-init' => ['cloudinaryMediaLibraryModal' => $cloudinaryMLwidgetOprions], + 'role' => 'add-from-cloudinary-button', + + ], + 'sort_order' => 200, + ]; + + if (!$this->authorization->isAllowed(self::ACL_UPLOAD_ASSETS)) { + $buttonData['disabled'] = 'disabled'; + } + + return $buttonData; + } +} diff --git a/etc/module.xml b/etc/module.xml index 273bb61..36fbd7c 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -4,6 +4,8 @@ + + diff --git a/view/adminhtml/layout/default.xml b/view/adminhtml/layout/default.xml index 92d372c..5ba003d 100644 --- a/view/adminhtml/layout/default.xml +++ b/view/adminhtml/layout/default.xml @@ -1,6 +1,9 @@ + + + diff --git a/view/adminhtml/requirejs-config.js b/view/adminhtml/requirejs-config.js index 79f4699..303017d 100644 --- a/view/adminhtml/requirejs-config.js +++ b/view/adminhtml/requirejs-config.js @@ -14,12 +14,16 @@ var config = { paths: { 'jquery.lazyload': "Cloudinary_Cloudinary/js/jquery.lazyload.min", cloudinaryMediaLibraryAll: "//media-library.cloudinary.com/global/all", - es6Promise: "//cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.auto.min" + es6Promise: "//cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.auto.min", + 'uiComponent': 'Magento_Ui/js/core/app', }, shim: { 'jquery.lazyload': { deps: ['jquery'] }, + 'uiComponent': { + deps: ['jquery'] + }, }, config: { mixins: { @@ -28,4 +32,4 @@ var config = { }, } } -}; \ No newline at end of file +}; diff --git a/view/adminhtml/templates/javascript.phtml b/view/adminhtml/templates/javascript.phtml new file mode 100644 index 0000000..1865906 --- /dev/null +++ b/view/adminhtml/templates/javascript.phtml @@ -0,0 +1,6 @@ +getCname(); +?> + + + diff --git a/view/adminhtml/ui_component/media_gallery_listing.xml b/view/adminhtml/ui_component/media_gallery_listing.xml new file mode 100644 index 0000000..2d7a911 --- /dev/null +++ b/view/adminhtml/ui_component/media_gallery_listing.xml @@ -0,0 +1,43 @@ + + ++ + + + media_gallery_listing.media_gallery_listing_data_source + + + + + + diff --git a/view/adminhtml/web/css/source/_module.less b/view/adminhtml/web/css/source/_module.less index b3e98a9..f9f81f1 100644 --- a/view/adminhtml/web/css/source/_module.less +++ b/view/adminhtml/web/css/source/_module.less @@ -199,4 +199,10 @@ } } } -} \ No newline at end of file +} +.page-actions button.cloudinary-button-with-logo{ + margin: 0 0 0 10px !important; + span{ + padding-left: 35px; + } +} diff --git a/view/adminhtml/web/js/cloudinary-media-library-modal.js b/view/adminhtml/web/js/cloudinary-media-library-modal.js index 45e6186..c04a5f1 100644 --- a/view/adminhtml/web/js/cloudinary-media-library-modal.js +++ b/view/adminhtml/web/js/cloudinary-media-library-modal.js @@ -1,15 +1,20 @@ define([ 'jquery', + 'mageUtils', + 'uiRegistry', 'productGallery', 'Magento_Ui/js/modal/alert', 'mage/backend/notification', 'mage/translate', + 'Magento_MediaGalleryUi/js/image-uploader', 'jquery/ui', 'Magento_Ui/js/modal/modal', 'mage/backend/validation', 'cloudinaryMediaLibraryAll', - 'es6Promise' -], function($, productGallery, uiAlert, notification, $t) { + 'es6Promise', + + +], function($, mageUtils, registry, productGallery, uiAlert, notification, $t, imageUploader) { 'use strict'; $.widget('mage.cloudinaryMediaLibraryModal', { @@ -62,14 +67,27 @@ define([ this._bind(); var widget = this; + var uiRegistry = registry; + + window.cloudinary_ml = window.cloudinary_ml || []; this.options.cldMLid = this.options.cldMLid || 0; + if (typeof window.cloudinary_ml[this.options.cldMLid] === "undefined") { this.cloudinary_ml = window.cloudinary_ml[this.options.cldMLid] = cloudinary.createMediaLibrary( this.options.cloudinaryMLoptions, { insertHandler: function(data) { $('body').first().css('overflow', 'initial'); - return widget.cloudinaryInsertHandler(data); + if (widget.isMediaBrowser()) { + return widget.cloudinaryInsertHandler(data); + } else { + // new media gallery + data['newGalleryMode'] = 1; + widget.cloudinaryInsertHandler(data); + if (uiRegistry.get('media_gallery_listing.media_gallery_listing_data_source')) { + $(window).trigger('reload.MediaGallery'); + } + } } } ); @@ -78,14 +96,33 @@ define([ } }, + getMageMediaBrowserData: function () { + return $('.media-gallery-modal').data('mageMediabrowser'); + }, + + isMediaBrowser: function () { + return typeof this.getMageMediaBrowserData() !== 'undefined'; + }, + selectImageInNewMediaGallery: function (record) { + this.uploadHandler(record); + }, /** * Fired on trigger "openMediaLibrary" */ openMediaLibrary: function() { this.cloudinary_ml.show(this.options.cloudinaryMLshowOptions); }, + showLoader: function () { + this.loader(true); + }, + /** + * Hides spinner loader + */ + hideLoader: function () { + this.loader(false); + }, /** * Escape Regex */ @@ -112,11 +149,11 @@ define([ asset.free_transformation = (asset.derived[0].hasOwnProperty('raw_transformation')) ? asset.derived[0].raw_transformation : asset.asset_derived_image_url - .replace(new RegExp('^.*cloudinary.com/(' + this.options.cloudinaryMLoptions.cloud_name + '/)?' + asset.resource_type + '/' + asset.type + '/'), '') - .replace(/\.[^/.]+$/, '') - .replace(new RegExp('\/' + widget.escapeRegex(encodeURI(decodeURI(asset.public_id))) + '$'), '') - .replace(new RegExp('\/v[0-9]{1,10}$'), '') - .replace(new RegExp('\/'), ','); + .replace(new RegExp('^.*cloudinary.com/(' + this.options.cloudinaryMLoptions.cloud_name + '/)?' + asset.resource_type + '/' + asset.type + '/'), '') + .replace(/\.[^/.]+$/, '') + .replace(new RegExp('\/' + widget.escapeRegex(encodeURI(decodeURI(asset.public_id))) + '$'), '') + .replace(new RegExp('\/v[0-9]{1,10}$'), '') + .replace(new RegExp('\/'), ','); if (widget.options.useDerived) { asset.asset_url = asset.asset_image_url = asset.derived[0].secure_url; } diff --git a/view/adminhtml/web/js/form/element/validator-rules-mixin.js b/view/adminhtml/web/js/form/element/validator-rules-mixin.js index b33b223..c4bc151 100644 --- a/view/adminhtml/web/js/form/element/validator-rules-mixin.js +++ b/view/adminhtml/web/js/form/element/validator-rules-mixin.js @@ -33,7 +33,7 @@ define([ return validateIsUrl(href) && ( href.match(/youtube\.com|youtu\.be/) || href.match(/vimeo\.com/) || - href.match(/cloudinary\.com/) || + href.match(/cloudinary/) || href.match(/\.(mp4|ogv|webm)(?!\w)/) ); }, @@ -52,7 +52,7 @@ define([ return validateIsUrl(href) && ( href.match(/youtube\.com|youtu\.be/) || href.match(/vimeo\.com/) || - href.match(/cloudinary\.com/) || + href.match(/cloudinary/) || href.match(/\.(mp4|ogv|webm)(?!\w)/) ); }, diff --git a/view/adminhtml/web/js/get-video-information.js b/view/adminhtml/web/js/get-video-information.js index db001c9..97922bd 100644 --- a/view/adminhtml/web/js/get-video-information.js +++ b/view/adminhtml/web/js/get-video-information.js @@ -789,7 +789,10 @@ define( type, ampersandPosition, vimeoRegex, - useYoutubeNocookie = false; + useYoutubeNocookie = false, + cname; + + cname = $('#cld_domain_cname').data('value'); if (typeof href !== 'string') { return href; @@ -825,12 +828,12 @@ define( if (href.href.match(vimeoRegex) != null) { id = href.href.match(vimeoRegex)[3]; } - } else if (href.host.match(/cloudinary\.com/)) { + } else if (href.host.match(/cloudinary/) || href.href.includes(cname)) { type = 'cloudinary'; id = href.href.replace(new RegExp('^.*\/video\/(upload\/)?((.*\/)?v[0-9]{1,10}\/)?'), '').replace(/\.[^.\/]+$/, ''); } - if ((!id || !type) && forceVideo) { + if ((!id || !type)) { id = href.href; type = 'custom'; } diff --git a/view/frontend/layout/default.xml b/view/frontend/layout/default.xml index 92d372c..5ba003d 100644 --- a/view/frontend/layout/default.xml +++ b/view/frontend/layout/default.xml @@ -1,6 +1,9 @@ + + + diff --git a/view/frontend/templates/javascript.phtml b/view/frontend/templates/javascript.phtml new file mode 100644 index 0000000..69eac9c --- /dev/null +++ b/view/frontend/templates/javascript.phtml @@ -0,0 +1,7 @@ +getCname(); +?> + + + + diff --git a/view/frontend/web/js/fotorama-add-video-events.js b/view/frontend/web/js/fotorama-add-video-events.js index 6d421d8..def45b2 100644 --- a/view/frontend/web/js/fotorama-add-video-events.js +++ b/view/frontend/web/js/fotorama-add-video-events.js @@ -60,7 +60,10 @@ define( type, ampersandPosition, vimeoRegex, - useYoutubeNocookie = false; + useYoutubeNocookie = false, + cname; + + cname = $('#cld_domain_cname').data('value'); /** * Get youtube ID @@ -89,6 +92,8 @@ define( href = parseHref(href); + + if (href.host.match(/youtube\.com/) && href.search) { id = href.search.split('v=')[1]; @@ -111,7 +116,7 @@ define( ].join('') ); id = href.href.match(vimeoRegex)[3]; - } else if (href.host.match(/cloudinary\.com/)) { + } else if (href.host.match(/cloudinary\.com/) || href.href.includes(cname)) { type = 'cloudinary'; id = _baseName(href.href); }