From 7cf9e4db4542a78a643b3da8e1197bcd2a719e9a Mon Sep 17 00:00:00 2001 From: pini-girit Date: Wed, 13 Mar 2019 13:42:59 +0200 Subject: [PATCH 01/11] CLOUDINARY-102: Working on Cloudinary-Product-Gallery implementation (configuration area is ready, started layout changes) --- .../System/Config/Form/Field/ColorPicker.php | 43 ++++ Block/Catalog/CloudinaryProductGallery.php | 183 ++++++++++++++++++ Helper/ProductGalleryHelper.php | 67 +++++++ .../ProductGalleryCustomFreeParams.php | 83 ++++++++ .../Dropdown/ProductGallery/AspectRatio.php | 62 ++++++ .../ProductGallery/CarouselLocation.php | 30 +++ .../Dropdown/ProductGallery/CarouselStyle.php | 26 +++ .../ProductGallery/IndicatorsShape.php | 26 +++ .../Dropdown/ProductGallery/Navigation.php | 26 +++ .../ThumbnailsMediaSymbolShape.php | 30 +++ .../ThumbnailsNavigationShape.php | 34 ++++ .../ThumbnailsSelectedBorderPosition.php | 42 ++++ .../ThumbnailsSelectedStyle.php | 26 +++ .../Dropdown/ProductGallery/Transition.php | 26 +++ .../Dropdown/ProductGallery/ZoomTrigger.php | 22 +++ .../Dropdown/ProductGallery/ZoomType.php | 26 +++ .../ProductGallery/ZoomViewerPosition.php | 30 +++ Model/Configuration.php | 73 +++++-- etc/adminhtml/system.xml | 183 +++++++++++++++++- etc/config.xml | 26 +++ .../layout/adminhtml_system_config_edit.xml | 6 + .../frontend/layout/_catalog_product_view.xml | 57 ++++++ view/frontend/templates/product/gallery.phtml | 6 + 23 files changed, 1119 insertions(+), 14 deletions(-) create mode 100644 Block/Adminhtml/System/Config/Form/Field/ColorPicker.php create mode 100644 Block/Catalog/CloudinaryProductGallery.php create mode 100644 Helper/ProductGalleryHelper.php create mode 100644 Model/Config/Backend/ProductGalleryCustomFreeParams.php create mode 100644 Model/Config/Source/Dropdown/ProductGallery/AspectRatio.php create mode 100644 Model/Config/Source/Dropdown/ProductGallery/CarouselLocation.php create mode 100644 Model/Config/Source/Dropdown/ProductGallery/CarouselStyle.php create mode 100644 Model/Config/Source/Dropdown/ProductGallery/IndicatorsShape.php create mode 100644 Model/Config/Source/Dropdown/ProductGallery/Navigation.php create mode 100644 Model/Config/Source/Dropdown/ProductGallery/ThumbnailsMediaSymbolShape.php create mode 100644 Model/Config/Source/Dropdown/ProductGallery/ThumbnailsNavigationShape.php create mode 100644 Model/Config/Source/Dropdown/ProductGallery/ThumbnailsSelectedBorderPosition.php create mode 100644 Model/Config/Source/Dropdown/ProductGallery/ThumbnailsSelectedStyle.php create mode 100644 Model/Config/Source/Dropdown/ProductGallery/Transition.php create mode 100644 Model/Config/Source/Dropdown/ProductGallery/ZoomTrigger.php create mode 100644 Model/Config/Source/Dropdown/ProductGallery/ZoomType.php create mode 100644 Model/Config/Source/Dropdown/ProductGallery/ZoomViewerPosition.php create mode 100644 view/adminhtml/layout/adminhtml_system_config_edit.xml create mode 100644 view/frontend/layout/_catalog_product_view.xml create mode 100644 view/frontend/templates/product/gallery.phtml diff --git a/Block/Adminhtml/System/Config/Form/Field/ColorPicker.php b/Block/Adminhtml/System/Config/Form/Field/ColorPicker.php new file mode 100644 index 0000000..0928b2c --- /dev/null +++ b/Block/Adminhtml/System/Config/Form/Field/ColorPicker.php @@ -0,0 +1,43 @@ +getElementHtml(); + $value = $element->getData('value'); + + $html .= ''; + + return $html; + } +} diff --git a/Block/Catalog/CloudinaryProductGallery.php b/Block/Catalog/CloudinaryProductGallery.php new file mode 100644 index 0000000..d780e09 --- /dev/null +++ b/Block/Catalog/CloudinaryProductGallery.php @@ -0,0 +1,183 @@ +productGalleryHelper = $productGalleryHelper; + } + + /** + * @return $this + */ + protected function _prepareLayout() + { + $this->pageConfig->getTitle()->set($this->getProduct()->getMetaTitle()); + return parent::_prepareLayout(); + } + + /** + * @return Product + */ + public function getProduct() + { + return $this->_coreRegistry->registry('product'); + } + + /** + * @return Collection + */ + public function getGalleryCollection() + { + return $this->getProduct()->getMediaGalleryImages(); + } + + /** + * @return Image|null + */ + public function getCurrentImage() + { + $imageId = $this->getRequest()->getParam('image'); + $image = null; + if ($imageId) { + $image = $this->getGalleryCollection()->getItemById($imageId); + } + + if (!$image) { + $image = $this->getGalleryCollection()->getFirstItem(); + } + return $image; + } + + /** + * @return string + */ + public function getImageUrl() + { + return $this->getCurrentImage()->getUrl(); + } + + /** + * @return mixed + */ + public function getImageFile() + { + return $this->getCurrentImage()->getFile(); + } + + /** + * Retrieve image width + * + * @return bool|int + */ + public function getImageWidth() + { + $file = $this->getCurrentImage()->getPath(); + + if ($this->_filesystem->getDirectoryRead(DirectoryList::MEDIA)->isFile($file)) { + $size = getimagesize($file); + if (isset($size[0])) { + if ($size[0] > 600) { + return 600; + } else { + return $size[0]; + } + } + } + + return false; + } + + /** + * @return Image|false + */ + public function getPreviousImage() + { + $current = $this->getCurrentImage(); + if (!$current) { + return false; + } + $previous = false; + foreach ($this->getGalleryCollection() as $image) { + if ($image->getValueId() == $current->getValueId()) { + return $previous; + } + $previous = $image; + } + return $previous; + } + + /** + * @return Image|false + */ + public function getNextImage() + { + $current = $this->getCurrentImage(); + if (!$current) { + return false; + } + + $next = false; + $currentFind = false; + foreach ($this->getGalleryCollection() as $image) { + if ($currentFind) { + return $image; + } + if ($image->getValueId() == $current->getValueId()) { + $currentFind = true; + } + } + return $next; + } + + /** + * @return false|string + */ + public function getPreviousImageUrl() + { + $image = $this->getPreviousImage(); + if ($image) { + return $this->getUrl('*/*/*', ['_current' => true, 'image' => $image->getValueId()]); + } + return false; + } + + /** + * @return false|string + */ + public function getNextImageUrl() + { + $image = $this->getNextImage(); + if ($image) { + return $this->getUrl('*/*/*', ['_current' => true, 'image' => $image->getValueId()]); + } + return false; + } +} diff --git a/Helper/ProductGalleryHelper.php b/Helper/ProductGalleryHelper.php new file mode 100644 index 0000000..cb05dda --- /dev/null +++ b/Helper/ProductGalleryHelper.php @@ -0,0 +1,67 @@ +configuration = $configuration; + } + + /** + * @method getCloudinaryPGOptions + * @param bool $refresh Refresh options + * @return array + */ + public function getCloudinaryPGOptions($refresh = true) + { + if ((is_null($this->cloudinaryMLoptions) || $refresh) && $this->configuration->isEnabled() && $this->configuration->isEnabledProductGallery()) { + $this->cloudinaryPGoptions = $this->configuration->getProductGalleryAll(); + foreach ($this->cloudinaryPGoptions as $key => $value) { + $path = explode("_", $key); + if (in_array($path[0], ['themeProps','zoomProps','thumbnailProps','indicatorProps'])) { + if (!isset($this->cloudinaryPGoptions[$path[0]])) { + $this->cloudinaryPGoptions[$path[0]] = []; + } + array_shift($path); + $path = implode("_", $path); + $this->cloudinaryPGoptions[$path[0]][$path] = $value; + unset($this->cloudinaryPGoptions[$key]); + } + } + if (isset($this->cloudinaryPGoptions['enabled'])) { + unset($this->cloudinaryPGoptions['enabled']); + } + if (isset($this->cloudinaryPGoptions['custom_free_params'])) { + $customFreeParams = (array) @json_decode($this->cloudinaryPGoptions['custom_free_params'], true); + $this->cloudinaryPGoptions = array_merge_recursive($this->cloudinaryPGoptions, $customFreeParams); + unset($this->cloudinaryPGoptions['custom_free_params']); + } + } + + return $this->cloudinaryMLoptions; + } +} diff --git a/Model/Config/Backend/ProductGalleryCustomFreeParams.php b/Model/Config/Backend/ProductGalleryCustomFreeParams.php new file mode 100644 index 0000000..04ea774 --- /dev/null +++ b/Model/Config/Backend/ProductGalleryCustomFreeParams.php @@ -0,0 +1,83 @@ + 'No error', + JSON_ERROR_DEPTH => 'Maximum stack depth exceeded', + JSON_ERROR_STATE_MISMATCH => 'State mismatch (invalid or malformed JSON)', + JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded', + JSON_ERROR_SYNTAX => 'Syntax error', + JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded' + ]; + + /** + * @var ManagerInterface + */ + private $messageManager; + + /** + * Application config + * + * @var ScopeConfigInterface + */ + protected $appConfig; + + public function __construct( + Context $context, + Registry $registry, + ScopeConfigInterface $config, + TypeListInterface $cacheTypeList, + AbstractResource $resource = null, + AbstractDb $resourceCollection = null, + ManagerInterface $messageManager, + ReinitableConfigInterface $appConfig, + array $data = [] + ) { + $this->messageManager = $messageManager; + $this->appConfig = $appConfig; + + parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data); + } + + public function beforeSave() + { + $rawValue = $this->getValue(); + + parent::beforeSave(); + + $this->cacheTypeList->cleanType(\Magento\Framework\App\Cache\Type\Config::TYPE_IDENTIFIER); + $this->appConfig->reinit(); + + if ($rawValue) { + $data = @json_decode($rawValue); + if ($data === null || $data === false) { + $this->setValue('{}'); + try { + if (json_last_error() !== JSON_ERROR_NONE) { + $this->messageManager->addError(self::BAD_JSON_ERROR_MESSAGE . ' (' . self::JSON_ERRORS[json_last_error()] . ')'); + } + } catch (\Exception $e) { + $this->messageManager->addError(self::BAD_JSON_ERROR_MESSAGE); + } + } else { + $this->setValue(json_encode((array)$data)); + } + } else { + $this->setValue('{}'); + } + } +} diff --git a/Model/Config/Source/Dropdown/ProductGallery/AspectRatio.php b/Model/Config/Source/Dropdown/ProductGallery/AspectRatio.php new file mode 100644 index 0000000..3f8dbbd --- /dev/null +++ b/Model/Config/Source/Dropdown/ProductGallery/AspectRatio.php @@ -0,0 +1,62 @@ + 'square', + 'label' => 'Square', + ], + [ + 'value' => '1:1', + 'label' => '1:1', + ], + [ + 'value' => '3:4', + 'label' => '3:4', + ], + [ + 'value' => '4:3', + 'label' => '4:3', + ], + [ + 'value' => '4:6', + 'label' => '4:6', + ], + [ + 'value' => '6:4', + 'label' => '6:4', + ], + [ + 'value' => '5:7', + 'label' => '5:7', + ], + [ + 'value' => '7:5', + 'label' => '7:5', + ], + [ + 'value' => '5:8', + 'label' => '5:8', + ], + [ + 'value' => '8:5', + 'label' => '8:5', + ], + [ + 'value' => '9:16', + 'label' => '9:16', + ], + [ + 'value' => '16:9', + 'label' => '16:9', + ], + ]; + } +} diff --git a/Model/Config/Source/Dropdown/ProductGallery/CarouselLocation.php b/Model/Config/Source/Dropdown/ProductGallery/CarouselLocation.php new file mode 100644 index 0000000..5f8fde6 --- /dev/null +++ b/Model/Config/Source/Dropdown/ProductGallery/CarouselLocation.php @@ -0,0 +1,30 @@ + 'top', + 'label' => 'Top', + ], + [ + 'value' => 'right', + 'label' => 'Right', + ], + [ + 'value' => 'left', + 'label' => 'Left', + ], + [ + 'value' => 'bottom', + 'label' => 'Bottom', + ], + ]; + } +} diff --git a/Model/Config/Source/Dropdown/ProductGallery/CarouselStyle.php b/Model/Config/Source/Dropdown/ProductGallery/CarouselStyle.php new file mode 100644 index 0000000..b5da76c --- /dev/null +++ b/Model/Config/Source/Dropdown/ProductGallery/CarouselStyle.php @@ -0,0 +1,26 @@ + 'none', + 'label' => 'None', + ], + [ + 'value' => 'thumbnails', + 'label' => 'Thumbnails', + ], + [ + 'value' => 'indicators', + 'label' => 'Indicators', + ], + ]; + } +} diff --git a/Model/Config/Source/Dropdown/ProductGallery/IndicatorsShape.php b/Model/Config/Source/Dropdown/ProductGallery/IndicatorsShape.php new file mode 100644 index 0000000..0f5e17e --- /dev/null +++ b/Model/Config/Source/Dropdown/ProductGallery/IndicatorsShape.php @@ -0,0 +1,26 @@ + 'round', + 'label' => 'Round', + ], + [ + 'value' => 'square', + 'label' => 'Square', + ], + [ + 'value' => 'radius', + 'label' => 'Radius', + ], + ]; + } +} diff --git a/Model/Config/Source/Dropdown/ProductGallery/Navigation.php b/Model/Config/Source/Dropdown/ProductGallery/Navigation.php new file mode 100644 index 0000000..c893ef0 --- /dev/null +++ b/Model/Config/Source/Dropdown/ProductGallery/Navigation.php @@ -0,0 +1,26 @@ + 'none', + 'label' => 'None', + ], + [ + 'value' => 'always', + 'label' => 'Always', + ], + [ + 'value' => 'mouseover', + 'label' => 'Mouseover', + ], + ]; + } +} diff --git a/Model/Config/Source/Dropdown/ProductGallery/ThumbnailsMediaSymbolShape.php b/Model/Config/Source/Dropdown/ProductGallery/ThumbnailsMediaSymbolShape.php new file mode 100644 index 0000000..707b88c --- /dev/null +++ b/Model/Config/Source/Dropdown/ProductGallery/ThumbnailsMediaSymbolShape.php @@ -0,0 +1,30 @@ + 'none', + 'label' => 'None', + ], + [ + 'value' => 'round', + 'label' => 'Round', + ], + [ + 'value' => 'square', + 'label' => 'Square', + ], + [ + 'value' => 'radius', + 'label' => 'Radius', + ], + ]; + } +} diff --git a/Model/Config/Source/Dropdown/ProductGallery/ThumbnailsNavigationShape.php b/Model/Config/Source/Dropdown/ProductGallery/ThumbnailsNavigationShape.php new file mode 100644 index 0000000..7195579 --- /dev/null +++ b/Model/Config/Source/Dropdown/ProductGallery/ThumbnailsNavigationShape.php @@ -0,0 +1,34 @@ + 'none', + 'label' => 'None', + ], + [ + 'value' => 'round', + 'label' => 'Round', + ], + [ + 'value' => 'square', + 'label' => 'Square', + ], + [ + 'value' => 'radius', + 'label' => 'Radius', + ], + [ + 'value' => 'rectangle', + 'label' => 'Rectangle', + ], + ]; + } +} diff --git a/Model/Config/Source/Dropdown/ProductGallery/ThumbnailsSelectedBorderPosition.php b/Model/Config/Source/Dropdown/ProductGallery/ThumbnailsSelectedBorderPosition.php new file mode 100644 index 0000000..cec7374 --- /dev/null +++ b/Model/Config/Source/Dropdown/ProductGallery/ThumbnailsSelectedBorderPosition.php @@ -0,0 +1,42 @@ + 'top', + 'label' => 'Top', + ], + [ + 'value' => 'bottom', + 'label' => 'Bottom', + ], + [ + 'value' => 'left', + 'label' => 'Left', + ], + [ + 'value' => 'right', + 'label' => 'Right', + ], + [ + 'value' => 'top-bottom', + 'label' => 'Top-Bottom', + ], + [ + 'value' => 'left-right', + 'label' => 'Left-Right', + ], + [ + 'value' => 'all', + 'label' => 'All', + ], + ]; + } +} diff --git a/Model/Config/Source/Dropdown/ProductGallery/ThumbnailsSelectedStyle.php b/Model/Config/Source/Dropdown/ProductGallery/ThumbnailsSelectedStyle.php new file mode 100644 index 0000000..10f7014 --- /dev/null +++ b/Model/Config/Source/Dropdown/ProductGallery/ThumbnailsSelectedStyle.php @@ -0,0 +1,26 @@ + 'border', + 'label' => 'Border', + ], + [ + 'value' => 'gradient', + 'label' => 'Gradient', + ], + [ + 'value' => 'all', + 'label' => 'All', + ], + ]; + } +} diff --git a/Model/Config/Source/Dropdown/ProductGallery/Transition.php b/Model/Config/Source/Dropdown/ProductGallery/Transition.php new file mode 100644 index 0000000..7305764 --- /dev/null +++ b/Model/Config/Source/Dropdown/ProductGallery/Transition.php @@ -0,0 +1,26 @@ + 'none', + 'label' => 'None', + ], + [ + 'value' => 'fade', + 'label' => 'Fade', + ], + [ + 'value' => 'slide', + 'label' => 'Slide', + ], + ]; + } +} diff --git a/Model/Config/Source/Dropdown/ProductGallery/ZoomTrigger.php b/Model/Config/Source/Dropdown/ProductGallery/ZoomTrigger.php new file mode 100644 index 0000000..ae902c6 --- /dev/null +++ b/Model/Config/Source/Dropdown/ProductGallery/ZoomTrigger.php @@ -0,0 +1,22 @@ + 'click', + 'label' => 'Click', + ], + [ + 'value' => 'hover', + 'label' => 'Hover', + ], + ]; + } +} diff --git a/Model/Config/Source/Dropdown/ProductGallery/ZoomType.php b/Model/Config/Source/Dropdown/ProductGallery/ZoomType.php new file mode 100644 index 0000000..ff5c441 --- /dev/null +++ b/Model/Config/Source/Dropdown/ProductGallery/ZoomType.php @@ -0,0 +1,26 @@ + 'inline', + 'label' => 'Inline', + ], + [ + 'value' => 'flyout', + 'label' => 'Flyout', + ], + [ + 'value' => 'lightbox', + 'label' => 'Lightbox', + ], + ]; + } +} diff --git a/Model/Config/Source/Dropdown/ProductGallery/ZoomViewerPosition.php b/Model/Config/Source/Dropdown/ProductGallery/ZoomViewerPosition.php new file mode 100644 index 0000000..f9eea46 --- /dev/null +++ b/Model/Config/Source/Dropdown/ProductGallery/ZoomViewerPosition.php @@ -0,0 +1,30 @@ + 'top', + 'label' => 'Top', + ], + [ + 'value' => 'right', + 'label' => 'Right', + ], + [ + 'value' => 'left', + 'label' => 'Left', + ], + [ + 'value' => 'bottom', + 'label' => 'Bottom', + ], + ]; + } +} diff --git a/Model/Configuration.php b/Model/Configuration.php index 1893274..16485b7 100644 --- a/Model/Configuration.php +++ b/Model/Configuration.php @@ -23,26 +23,57 @@ class Configuration implements ConfigurationInterface { + //= Basics 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'; + const CONFIG_PATH_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'; + const CONFIG_PATH_DEFAULT_GRAVITY = 'cloudinary/transformations/cloudinary_gravity'; + const CONFIG_PATH_DEFAULT_QUALITY = 'cloudinary/transformations/cloudinary_image_quality'; + const CONFIG_PATH_DEFAULT_DPR = 'cloudinary/transformations/cloudinary_image_dpr'; + const CONFIG_PATH_DEFAULT_FETCH_FORMAT = 'cloudinary/transformations/cloudinary_fetch_format'; + const CONFIG_PATH_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'; + + //= Product Gallery + const CONFIG_PATH_PG_ALL = 'cloudinary/product_gallery'; + const CONFIG_PATH_PG_ENABLED = 'cloudinary/product_gallery/enabled'; + const CONFIG_PATH_PG_THEMEPROPS_PRIMARY = 'cloudinary/product_gallery/themeProps_primary'; + const CONFIG_PATH_PG_THEMEPROPS_ONPRIMARY = 'cloudinary/product_gallery/themeProps_onPrimary'; + const CONFIG_PATH_PG_THEMEPROPS_ACTIVE = 'cloudinary/product_gallery/themeProps_active'; + const CONFIG_PATH_PG_THEMEPROPS_ONACTIVE = 'cloudinary/product_gallery/themeProps_onActive'; + const CONFIG_PATH_PG_TRANSITION = 'cloudinary/product_gallery/transition'; + const CONFIG_PATH_PG_ASPECT_RATIO = 'cloudinary/product_gallery/aspectRatio'; + const CONFIG_PATH_PG_ZOOMPROPS_NAVIGATION = 'cloudinary/product_gallery/navigation'; + const CONFIG_PATH_PG_ZOOM = 'cloudinary/product_gallery/zoom'; + const CONFIG_PATH_PG_ZOOMPROPS_TYPE = 'cloudinary/product_gallery/zoomProps_type'; + const CONFIG_PATH_PG_ZOOMPROPS_POSITION = 'cloudinary/product_gallery/zoomPropsViewerPosition'; + const CONFIG_PATH_PG_ZOOMPROPS_TRIGGER = 'cloudinary/product_gallery/zoomProps_trigger'; + const CONFIG_PATH_PG_CAROUSEL_LOCATION = 'cloudinary/product_gallery/carouselLocation'; + const CONFIG_PATH_PG_CAROUSEL_OFFSET = 'cloudinary/product_gallery/carouselOffset'; + const CONFIG_PATH_PG_CAROUSEL_STYLE = 'cloudinary/product_gallery/carouselStyle'; + const CONFIG_PATH_PG_THUMBNAILPROPS_WIDTH = 'cloudinary/product_gallery/thumbnailProps_width'; + const CONFIG_PATH_PG_THUMBNAILPROPS_HEIGHT = 'cloudinary/product_gallery/thumbnailProps_height'; + const CONFIG_PATH_PG_THUMBNAILPROPS_NAVIGATION_SHAPE = 'cloudinary/product_gallery/thumbnailProps_navigationShape'; + const CONFIG_PATH_PG_THUMBNAILPROPS_SELECTED_STYLE = 'cloudinary/product_gallery/thumbnailProps_selectedStyle'; + const CONFIG_PATH_PG_THUMBNAILPROPS_SELECTED_BORDER_POSITION = 'cloudinary/product_gallery/thumbnailProps_selectedBorderPosition'; + const CONFIG_PATH_PG_THUMBNAILPROPS_SELECTED_BORDER_WIDTH = 'cloudinary/product_gallery/thumbnailProps_selectedBorderWidth'; + const CONFIG_PATH_PG_THUMBNAILPROPS_MEDIA_ICON_SHAPE = 'cloudinary/product_gallery/thumbnailProps_mediaSymbolShape'; + const CONFIG_PATH_PG_INDICATORPROPS_SHAPE = 'cloudinary/product_gallery/indicatorProps_shape'; + const CONFIG_PATH_PG_CUSTOM_FREE_PARAMS = 'cloudinary/product_gallery/custom_free_params'; + //= 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 CONFIG_PATH_USE_SIGNED_URLS = 'cloudinary/advanced/use_signed_urls'; + const USER_PLATFORM_TEMPLATE = 'CloudinaryMagento/%s (Magento %s)'; const USE_FILENAME = true; const UNIQUE_FILENAME = false; const OVERWRITE = false; @@ -152,7 +183,7 @@ public function getDefaultTransformation() */ private function getDefaultGlobalFreeform() { - return (string) $this->configReader->getValue(self::CONFIG_GLOBAL_FREEFORM); + return (string) $this->configReader->getValue(self::CONFIG_PATH_GLOBAL_FREEFORM); } /** @@ -160,7 +191,7 @@ private function getDefaultGlobalFreeform() */ public function getCdnSubdomainStatus() { - return $this->configReader->isSetFlag(self::CONFIG_CDN_SUBDOMAIN); + return $this->configReader->isSetFlag(self::CONFIG_PATH_CDN_SUBDOMAIN); } /** @@ -219,7 +250,7 @@ public function getMigratedPath($file) */ public function getDefaultGravity() { - return (string) $this->configReader->getValue(self::CONFIG_DEFAULT_GRAVITY); + return (string) $this->configReader->getValue(self::CONFIG_PATH_DEFAULT_GRAVITY); } /** @@ -227,7 +258,7 @@ public function getDefaultGravity() */ public function getFetchFormat() { - return $this->configReader->isSetFlag(self::CONFIG_DEFAULT_FETCH_FORMAT) ? FetchFormat::FETCH_FORMAT_AUTO : ''; + return $this->configReader->isSetFlag(self::CONFIG_PATH_DEFAULT_FETCH_FORMAT) ? FetchFormat::FETCH_FORMAT_AUTO : ''; } /** @@ -235,7 +266,7 @@ public function getFetchFormat() */ public function getImageQuality() { - return (string) $this->configReader->getValue(self::CONFIG_DEFAULT_QUALITY); + return (string) $this->configReader->getValue(self::CONFIG_PATH_DEFAULT_QUALITY); } /** @@ -243,7 +274,7 @@ public function getImageQuality() */ public function getImageDpr() { - return $this->configReader->getValue(self::CONFIG_DEFAULT_DPR); + return $this->configReader->getValue(self::CONFIG_PATH_DEFAULT_DPR); } /** @@ -274,6 +305,22 @@ public function getEnvironmentVariable() return $this->environmentVariable; } + /** + * @return bool + */ + public function isEnabledProductGallery() + { + return (bool) $this->configReader->getValue(self::CONFIG_PATH_PG_ENABLED); + } + + /** + * @return array + */ + public function getProductGalleryAll() + { + return (array) $this->configReader->getValue(self::CONFIG_PATH_PG_ALL); + } + /** * @return bool */ diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 42b42ef..6e4cd44 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -11,6 +11,7 @@ Cloudinary_Cloudinary::config_cloudinary + 1 Magento\Config\Model\Config\Source\Yesno @@ -18,6 +19,7 @@ + 1 Format should be: cloudinary://API_Key:API_Secret@Cloud_Name]]> @@ -30,6 +32,7 @@ + 1 Enable multiple sub-domains of image delivery URLs for faster page load speed. @@ -43,6 +46,7 @@ + 0 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. @@ -69,8 +73,185 @@ Cloudinary\Cloudinary\Block\Adminhtml\Form\Field\Free - + + + 0 + + + Enable Cloudinary's product gallery (override Magento's default) + Magento\Config\Model\Config\Source\Yesno + cloudinary/product_gallery/enabled + + + + 1 + + + cloudinary/product_gallery/themeProps_primary + Cloudinary\Cloudinary\Block\Adminhtml\System\Config\Form\Field\ColorPicker + validate-length minimum-length-4 maximum-length-7 + + + + cloudinary/product_gallery/themeProps_onPrimary + Cloudinary\Cloudinary\Block\Adminhtml\System\Config\Form\Field\ColorPicker + validate-length minimum-length-4 maximum-length-7 + + + + cloudinary/product_gallery/themeProps_active + Cloudinary\Cloudinary\Block\Adminhtml\System\Config\Form\Field\ColorPicker + validate-length minimum-length-4 maximum-length-7 + + + + cloudinary/product_gallery/themeProps_onActive + Cloudinary\Cloudinary\Block\Adminhtml\System\Config\Form\Field\ColorPicker + validate-length minimum-length-4 maximum-length-7 + + + + + 1 + + + cloudinary/product_gallery/transition + Cloudinary\Cloudinary\Model\Config\Source\Dropdown\ProductGallery\Transition + + + + cloudinary/product_gallery/aspectRatio + Cloudinary\Cloudinary\Model\Config\Source\Dropdown\ProductGallery\AspectRatio + + + + cloudinary/product_gallery/navigation + Cloudinary\Cloudinary\Model\Config\Source\Dropdown\ProductGallery\Navigation + + + + cloudinary/product_gallery/zoom + Magento\Config\Model\Config\Source\Yesno + + + + cloudinary/product_gallery/zoomProps_type + Cloudinary\Cloudinary\Model\Config\Source\Dropdown\ProductGallery\ZoomType + + 1 + + + + + cloudinary/product_gallery/zoomProps_viewerPosition + Cloudinary\Cloudinary\Model\Config\Source\Dropdown\ProductGallery\ZoomViewerPosition + + 1 + flyout + + + + + cloudinary/product_gallery/zoomProps_trigger + Cloudinary\Cloudinary\Model\Config\Source\Dropdown\ProductGallery\ZoomTrigger + + 1 + + + + + + 1 + + + cloudinary/product_gallery/carouselLocation + Cloudinary\Cloudinary\Model\Config\Source\Dropdown\ProductGallery\CarouselLocation + + + + cloudinary/product_gallery/carouselOffset + validate-number + + + + cloudinary/product_gallery/carouselStyle + Cloudinary\Cloudinary\Model\Config\Source\Dropdown\ProductGallery\CarouselStyle + + + + cloudinary/product_gallery/thumbnailProps_width + validate-number + + thumbnails + + + + + cloudinary/product_gallery/thumbnailProps_height + validate-number + + thumbnails + + + + + cloudinary/product_gallery/thumbnailProps_navigationShape + Cloudinary\Cloudinary\Model\Config\Source\Dropdown\ProductGallery\ThumbnailsNavigationShape + + thumbnails + + + + + cloudinary/product_gallery/thumbnailProps_selectedStyle + Cloudinary\Cloudinary\Model\Config\Source\Dropdown\ProductGallery\ThumbnailsSelectedStyle + + thumbnails + + + + + cloudinary/product_gallery/thumbnailProps_selectedBorderPosition + Cloudinary\Cloudinary\Model\Config\Source\Dropdown\ProductGallery\ThumbnailsSelectedBorderPosition + + thumbnails + + + + + cloudinary/product_gallery/thumbnailProps_selectedBorderWidth + validate-number + + thumbnails + + + + + cloudinary/product_gallery/thumbnailProps_mediaSymbolShape + Cloudinary\Cloudinary\Model\Config\Source\Dropdown\ProductGallery\ThumbnailsMediaSymbolShape + + thumbnails + + + + + cloudinary/product_gallery/indicatorProps_shape + Cloudinary\Cloudinary\Model\Config\Source\Dropdown\ProductGallery\IndicatorsShape + + indicators + + + + + + Custom Json code that will add to (or override) the above params + cloudinary/product_gallery/custom_free_params + Cloudinary\Cloudinary\Model\Config\Backend\ProductGalleryCustomFreeParams + + + + 0 Remove version number (e.g., ".../v1/...") from URLs diff --git a/etc/config.xml b/etc/config.xml index 251673a..2d4ac67 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -15,6 +15,32 @@ 0 0 + + 0 + #ffffff + #000000 + #0078ff + #ffffff + slide + square + mouseover + 1 + inline + right + click + left + 5 + thumbnails + 64 + 64 + rectangle + all + left + 2 + round + round + {} + diff --git a/view/adminhtml/layout/adminhtml_system_config_edit.xml b/view/adminhtml/layout/adminhtml_system_config_edit.xml new file mode 100644 index 0000000..685e5f6 --- /dev/null +++ b/view/adminhtml/layout/adminhtml_system_config_edit.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/view/frontend/layout/_catalog_product_view.xml b/view/frontend/layout/_catalog_product_view.xml new file mode 100644 index 0000000..93c4331 --- /dev/null +++ b/view/frontend/layout/_catalog_product_view.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + gallery-prev-area + + + + + + gallery-next-area + Skip to the end of the images gallery + + + + + + + + gallery-prev-area + Skip to the beginning of the images gallery + + + + + + gallery-next-area + + + + + + diff --git a/view/frontend/templates/product/gallery.phtml b/view/frontend/templates/product/gallery.phtml new file mode 100644 index 0000000..6a7e030 --- /dev/null +++ b/view/frontend/templates/product/gallery.phtml @@ -0,0 +1,6 @@ + +

Pini is here!

From ea2ec05c2fe47f6c7533346b78bf2127bf14b9b7 Mon Sep 17 00:00:00 2001 From: pini-girit Date: Thu, 14 Mar 2019 09:52:03 +0200 Subject: [PATCH 02/11] CLOUDINARY-102: Working on Cloudinary-Product-Gallery implementation --- Block/Catalog/CloudinaryProductGallery.php | 152 ++---------------- Helper/ProductGalleryHelper.php | 24 ++- Plugin/Catalog/Block/Product/View/Gallery.php | 50 ++++++ etc/di.xml | 48 +++--- .../frontend/layout/_catalog_product_view.xml | 57 ------- view/frontend/layout/catalog_product_view.xml | 9 ++ view/frontend/templates/product/gallery.phtml | 5 +- 7 files changed, 115 insertions(+), 230 deletions(-) create mode 100644 Plugin/Catalog/Block/Product/View/Gallery.php delete mode 100644 view/frontend/layout/_catalog_product_view.xml create mode 100644 view/frontend/layout/catalog_product_view.xml diff --git a/Block/Catalog/CloudinaryProductGallery.php b/Block/Catalog/CloudinaryProductGallery.php index d780e09..0c7b29f 100644 --- a/Block/Catalog/CloudinaryProductGallery.php +++ b/Block/Catalog/CloudinaryProductGallery.php @@ -3,9 +3,6 @@ namespace Cloudinary\Cloudinary\Block\Catalog; use Cloudinary\Cloudinary\Helper\ProductGalleryHelper; -use Magento\Catalog\Model\Product; -use Magento\Framework\App\Filesystem\DirectoryList; -use Magento\Framework\Data\Collection; /** * @api @@ -35,149 +32,26 @@ public function __construct( } /** - * @return $this - */ - protected function _prepareLayout() - { - $this->pageConfig->getTitle()->set($this->getProduct()->getMetaTitle()); - return parent::_prepareLayout(); - } - - /** - * @return Product - */ - public function getProduct() - { - return $this->_coreRegistry->registry('product'); - } - - /** - * @return Collection - */ - public function getGalleryCollection() - { - return $this->getProduct()->getMediaGalleryImages(); - } - - /** - * @return Image|null - */ - public function getCurrentImage() - { - $imageId = $this->getRequest()->getParam('image'); - $image = null; - if ($imageId) { - $image = $this->getGalleryCollection()->getItemById($imageId); - } - - if (!$image) { - $image = $this->getGalleryCollection()->getFirstItem(); - } - return $image; - } - - /** - * @return string - */ - public function getImageUrl() - { - return $this->getCurrentImage()->getUrl(); - } - - /** - * @return mixed - */ - public function getImageFile() - { - return $this->getCurrentImage()->getFile(); - } - - /** - * Retrieve image width + * Render block HTML * - * @return bool|int - */ - public function getImageWidth() - { - $file = $this->getCurrentImage()->getPath(); - - if ($this->_filesystem->getDirectoryRead(DirectoryList::MEDIA)->isFile($file)) { - $size = getimagesize($file); - if (isset($size[0])) { - if ($size[0] > 600) { - return 600; - } else { - return $size[0]; - } - } - } - - return false; - } - - /** - * @return Image|false - */ - public function getPreviousImage() - { - $current = $this->getCurrentImage(); - if (!$current) { - return false; - } - $previous = false; - foreach ($this->getGalleryCollection() as $image) { - if ($image->getValueId() == $current->getValueId()) { - return $previous; - } - $previous = $image; - } - return $previous; - } - - /** - * @return Image|false - */ - public function getNextImage() - { - $current = $this->getCurrentImage(); - if (!$current) { - return false; - } - - $next = false; - $currentFind = false; - foreach ($this->getGalleryCollection() as $image) { - if ($currentFind) { - return $image; - } - if ($image->getValueId() == $current->getValueId()) { - $currentFind = true; - } - } - return $next; - } - - /** - * @return false|string + * @return string */ - public function getPreviousImageUrl() + protected function _toHtml() { - $image = $this->getPreviousImage(); - if ($image) { - return $this->getUrl('*/*/*', ['_current' => true, 'image' => $image->getValueId()]); - } - return false; + /*if ($this->productGalleryHelper->canDisplayProductGallery()) { + $this->setTemplate('Cloudinary_Cloudinary::product/gallery.phtml'); + }*/ + return parent::_toHtml(); } /** - * @return false|string + * @method getCloudinaryPGOptions + * @param bool $refresh Refresh options + * @param bool $ignoreDisabled Get te options even if the module or the product gallery are disabled + * @return array */ - public function getNextImageUrl() + public function getCloudinaryPGOptions($refresh = false, $ignoreDisabled = false) { - $image = $this->getNextImage(); - if ($image) { - return $this->getUrl('*/*/*', ['_current' => true, 'image' => $image->getValueId()]); - } - return false; + return $this->productGalleryHelper->getCloudinaryPGOptions($refresh, $ignoreDisabled); } } diff --git a/Helper/ProductGalleryHelper.php b/Helper/ProductGalleryHelper.php index cb05dda..6f092f3 100644 --- a/Helper/ProductGalleryHelper.php +++ b/Helper/ProductGalleryHelper.php @@ -34,21 +34,23 @@ public function __construct( /** * @method getCloudinaryPGOptions * @param bool $refresh Refresh options + * @param bool $ignoreDisabled Get te options even if the module or the product gallery are disabled * @return array */ - public function getCloudinaryPGOptions($refresh = true) + public function getCloudinaryPGOptions($refresh = false, $ignoreDisabled = false) { - if ((is_null($this->cloudinaryMLoptions) || $refresh) && $this->configuration->isEnabled() && $this->configuration->isEnabledProductGallery()) { + if ((is_null($this->cloudinaryPGoptions) || $refresh) && ($ignoreDisabled || ($this->configuration->isEnabled() && $this->configuration->isEnabledProductGallery()))) { $this->cloudinaryPGoptions = $this->configuration->getProductGalleryAll(); foreach ($this->cloudinaryPGoptions as $key => $value) { $path = explode("_", $key); - if (in_array($path[0], ['themeProps','zoomProps','thumbnailProps','indicatorProps'])) { - if (!isset($this->cloudinaryPGoptions[$path[0]])) { - $this->cloudinaryPGoptions[$path[0]] = []; + $_path = $path[0]; + if (in_array($_path, ['themeProps','zoomProps','thumbnailProps','indicatorProps'])) { + if (!isset($this->cloudinaryPGoptions[$_path])) { + $this->cloudinaryPGoptions[$_path] = []; } array_shift($path); $path = implode("_", $path); - $this->cloudinaryPGoptions[$path[0]][$path] = $value; + $this->cloudinaryPGoptions[$_path][$path] = $value; unset($this->cloudinaryPGoptions[$key]); } } @@ -62,6 +64,14 @@ public function getCloudinaryPGOptions($refresh = true) } } - return $this->cloudinaryMLoptions; + return $this->cloudinaryPGoptions; + } + + /** + * @return bool + */ + public function canDisplayProductGallery() + { + return ($this->configuration->isEnabled() && $this->configuration->isEnabledProductGallery()) ? true : false; } } diff --git a/Plugin/Catalog/Block/Product/View/Gallery.php b/Plugin/Catalog/Block/Product/View/Gallery.php new file mode 100644 index 0000000..823627a --- /dev/null +++ b/Plugin/Catalog/Block/Product/View/Gallery.php @@ -0,0 +1,50 @@ +productGalleryHelper = $productGalleryHelper; + } + + /** + * Override product gallery with the one from Cloudinary + * + * @param \Magento\Catalog\Block\Product\View\Gallery $productGalleryBlock + * @return string + */ + public function beforeToHtml(\Magento\Catalog\Block\Product\View\Gallery $productGalleryBlock) + { + if (!$this->processed && $this->productGalleryHelper->canDisplayProductGallery()) { + $this->processed = true; + $productGalleryBlock->setTemplate('Cloudinary_Cloudinary::product/gallery.phtml'); + $productGalleryBlock->setCloudinaryPGOptions($this->getCloudinaryPGOptions()); + } + } + + /** + * @method getCloudinaryPGOptions + * @param bool $refresh Refresh options + * @param bool $ignoreDisabled Get te options even if the module or the product gallery are disabled + * @return array + */ + protected function getCloudinaryPGOptions($refresh = false, $ignoreDisabled = false) + { + return $this->productGalleryHelper->getCloudinaryPGOptions($refresh, $ignoreDisabled); + } +} diff --git a/etc/di.xml b/etc/di.xml index e9d4b46..a21fbc0 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -12,64 +12,60 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + \ No newline at end of file diff --git a/view/frontend/layout/_catalog_product_view.xml b/view/frontend/layout/_catalog_product_view.xml deleted file mode 100644 index 93c4331..0000000 --- a/view/frontend/layout/_catalog_product_view.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - - gallery-prev-area - - - - - - gallery-next-area - Skip to the end of the images gallery - - - - - - - - gallery-prev-area - Skip to the beginning of the images gallery - - - - - - gallery-next-area - - - - - - diff --git a/view/frontend/layout/catalog_product_view.xml b/view/frontend/layout/catalog_product_view.xml new file mode 100644 index 0000000..40b62a2 --- /dev/null +++ b/view/frontend/layout/catalog_product_view.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/view/frontend/templates/product/gallery.phtml b/view/frontend/templates/product/gallery.phtml index 6a7e030..3564cb4 100644 --- a/view/frontend/templates/product/gallery.phtml +++ b/view/frontend/templates/product/gallery.phtml @@ -3,4 +3,7 @@ * @var \Cloudinary\Cloudinary\Block\Catalog\CloudinaryProductGallery $block */ ?> -

Pini is here!

+

Cloudinary Product Gallery will be loaded here:

+
+    getCloudinaryPGOptions()); ?>
+
From 74b7e9693d870c150f87a8d167e9f64761d5a7dc Mon Sep 17 00:00:00 2001 From: pini-girit Date: Thu, 14 Mar 2019 12:32:22 +0200 Subject: [PATCH 03/11] CLOUDINARY-102: Working on Cloudinary-Product-Gallery implementation --- Helper/ProductGalleryHelper.php | 33 +++++++++++++ Plugin/Catalog/Block/Product/View/Gallery.php | 49 ++++++++++++++++++- view/frontend/requirejs-config.js | 6 ++- view/frontend/templates/product/gallery.phtml | 9 ++-- 4 files changed, 91 insertions(+), 6 deletions(-) diff --git a/Helper/ProductGalleryHelper.php b/Helper/ProductGalleryHelper.php index 6f092f3..43cdae6 100644 --- a/Helper/ProductGalleryHelper.php +++ b/Helper/ProductGalleryHelper.php @@ -3,6 +3,7 @@ namespace Cloudinary\Cloudinary\Helper; use Cloudinary\Cloudinary\Core\ConfigurationInterface; +use Cloudinary\Cloudinary\Model\Configuration; use Magento\Framework\App\Helper\Context; class ProductGalleryHelper extends \Magento\Framework\App\Helper\AbstractHelper @@ -19,6 +20,31 @@ class ProductGalleryHelper extends \Magento\Framework\App\Helper\AbstractHelper */ protected $cloudinaryPGoptions; + const CASTING = [ + 'themeProps_primary' => 'string', + 'themeProps_onPrimary' => 'string', + 'themeProps_active' => 'string', + 'themeProps_onActive' => 'string', + 'transition' => 'string', + 'aspectRatio' => 'string', + 'navigation' => 'string', + 'zoom' => 'bool', + 'zoomProps_type' => 'string', + 'zoomPropsViewerPosition' => 'string', + 'zoomProps_trigger' => 'string', + 'carouselLocation' => 'string', + 'carouselOffset' => 'float', + 'carouselStyle' => 'string', + 'thumbnailProps_width' => 'float', + 'thumbnailProps_height' => 'float', + 'thumbnailProps_navigationShape' => 'string', + 'thumbnailProps_selectedStyle' => 'string', + 'thumbnailProps_selectedBorderPosition' => 'string', + 'thumbnailProps_selectedBorderWidth' => 'float', + 'thumbnailProps_mediaSymbolShape' => 'string', + 'indicatorProps_shape' => 'string', + ]; + /** * @param Context $context * @param ConfigurationInterface $configuration @@ -42,6 +68,12 @@ public function getCloudinaryPGOptions($refresh = false, $ignoreDisabled = false if ((is_null($this->cloudinaryPGoptions) || $refresh) && ($ignoreDisabled || ($this->configuration->isEnabled() && $this->configuration->isEnabledProductGallery()))) { $this->cloudinaryPGoptions = $this->configuration->getProductGalleryAll(); foreach ($this->cloudinaryPGoptions as $key => $value) { + //Change casting + if (isset(self::CASTING[$key])) { + \settype($value, self::CASTING[$key]); + $this->cloudinaryPGoptions[$key] = $value; + } + //Build options hierarchy $path = explode("_", $key); $_path = $path[0]; if (in_array($_path, ['themeProps','zoomProps','thumbnailProps','indicatorProps'])) { @@ -62,6 +94,7 @@ public function getCloudinaryPGOptions($refresh = false, $ignoreDisabled = false $this->cloudinaryPGoptions = array_merge_recursive($this->cloudinaryPGoptions, $customFreeParams); unset($this->cloudinaryPGoptions['custom_free_params']); } + $this->cloudinaryPGoptions['cloudName'] = (string)$this->configuration->getCloud(); } return $this->cloudinaryPGoptions; diff --git a/Plugin/Catalog/Block/Product/View/Gallery.php b/Plugin/Catalog/Block/Product/View/Gallery.php index 823627a..5d0ee33 100644 --- a/Plugin/Catalog/Block/Product/View/Gallery.php +++ b/Plugin/Catalog/Block/Product/View/Gallery.php @@ -3,6 +3,7 @@ namespace Cloudinary\Cloudinary\Plugin\Catalog\Block\Product\View; use Cloudinary\Cloudinary\Helper\ProductGalleryHelper; +use Magento\Framework\Json\EncoderInterface; class Gallery { @@ -11,15 +12,30 @@ class Gallery */ protected $productGalleryHelper; + /** + * @var EncoderInterface + */ + protected $jsonEncoder; + protected $processed; + protected $htmlId; + + /** + * Cloudinary PG Options + * @var array|null + */ + protected $cloudinaryPGoptions; /** * @param ProductGalleryHelper $productGalleryHelper + * @param EncoderInterface $jsonEncoder */ public function __construct( - ProductGalleryHelper $productGalleryHelper + ProductGalleryHelper $productGalleryHelper, + EncoderInterface $jsonEncoder ) { $this->productGalleryHelper = $productGalleryHelper; + $this->jsonEncoder = $jsonEncoder; } /** @@ -34,7 +50,21 @@ public function beforeToHtml(\Magento\Catalog\Block\Product\View\Gallery $produc $this->processed = true; $productGalleryBlock->setTemplate('Cloudinary_Cloudinary::product/gallery.phtml'); $productGalleryBlock->setCloudinaryPGOptions($this->getCloudinaryPGOptions()); + $productGalleryBlock->setCldPGid($this->getCldPGid()); + } + } + + public function getHtmlId() + { + if (!$this->htmlId) { + $this->htmlId = md5(uniqid('', true)); } + return $this->htmlId; + } + + public function getCldPGid() + { + return 'cldPGid_' . $this->getHtmlId(); } /** @@ -45,6 +75,21 @@ public function beforeToHtml(\Magento\Catalog\Block\Product\View\Gallery $produc */ protected function getCloudinaryPGOptions($refresh = false, $ignoreDisabled = false) { - return $this->productGalleryHelper->getCloudinaryPGOptions($refresh, $ignoreDisabled); + if (is_null($this->cloudinaryPGoptions) || $refresh) { + $this->cloudinaryPGoptions = $this->productGalleryHelper->getCloudinaryPGOptions($refresh, $ignoreDisabled); + $this->cloudinaryPGoptions['container'] = '#' . $this->getCldPGid(); + $this->cloudinaryPGoptions['mediaAssets'] = [ + (object)["publicId" => "sample", "mediaType" => "image"], + (object)["publicId" => "sample", "mediaType" => "image"], + (object)["publicId" => "sample", "mediaType" => "image"], + ]; + } + return $this->jsonEncoder->encode( + [ + 'htmlId' => $this->getHtmlId(), + 'cldPGid' => $this->getCldPGid(), + 'cloudinaryPGoptions' => $this->cloudinaryPGoptions, + ] + ); } } diff --git a/view/frontend/requirejs-config.js b/view/frontend/requirejs-config.js index a888a5d..8e3fd10 100644 --- a/view/frontend/requirejs-config.js +++ b/view/frontend/requirejs-config.js @@ -2,7 +2,11 @@ var config = { map: { '*': { loadPlayer: 'Cloudinary_Cloudinary/js/load-player', - 'Magento_ProductVideo/js/fotorama-add-video-events': 'Cloudinary_Cloudinary/js/fotorama-add-video-events' + 'Magento_ProductVideo/js/fotorama-add-video-events': 'Cloudinary_Cloudinary/js/fotorama-add-video-events', + cloudinaryProductGallery: 'Cloudinary_Cloudinary/js/cloudinary-product-gallery' } }, + paths: { + cloudinaryProductGalleryAll: "//product-gallery.cloudinary.com/all" + } }; \ No newline at end of file diff --git a/view/frontend/templates/product/gallery.phtml b/view/frontend/templates/product/gallery.phtml index 3564cb4..cbde146 100644 --- a/view/frontend/templates/product/gallery.phtml +++ b/view/frontend/templates/product/gallery.phtml @@ -1,9 +1,12 @@ -

Cloudinary Product Gallery will be loaded here:

+
-    getCloudinaryPGOptions()); ?>
+    getCloudinaryPGOptions())); ?>
 
From 1fa02967a7e9285631681cfcf762776be66e4aab Mon Sep 17 00:00:00 2001 From: pini-girit Date: Thu, 14 Mar 2019 14:48:56 +0200 Subject: [PATCH 04/11] CLOUDINARY-102: Working on Cloudinary-Product-Gallery implementation --- etc/adminhtml/system.xml | 30 +++++++++------- .../web/js/cloudinary-product-gallery.js | 35 +++++++++++++++++++ 2 files changed, 52 insertions(+), 13 deletions(-) create mode 100644 view/frontend/web/js/cloudinary-product-gallery.js diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 6e4cd44..c8f3a82 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -3,8 +3,10 @@ - - + +
cloudinary @@ -22,7 +24,9 @@ 1 - Format should be: cloudinary://API_Key:API_Secret@Cloud_Name]]> + + Format should be: cloudinary://API_Key:API_Secret@Cloud_Name]]> + Cloudinary\Cloudinary\Model\Config\Backend\Credentials @@ -147,7 +151,7 @@ Cloudinary\Cloudinary\Model\Config\Source\Dropdown\ProductGallery\ZoomViewerPosition 1 - flyout + flyout @@ -182,7 +186,7 @@ cloudinary/product_gallery/thumbnailProps_width validate-number - thumbnails + thumbnails @@ -190,7 +194,7 @@ cloudinary/product_gallery/thumbnailProps_height validate-number - thumbnails + thumbnails @@ -198,7 +202,7 @@ cloudinary/product_gallery/thumbnailProps_navigationShape Cloudinary\Cloudinary\Model\Config\Source\Dropdown\ProductGallery\ThumbnailsNavigationShape - thumbnails + thumbnails @@ -206,7 +210,7 @@ cloudinary/product_gallery/thumbnailProps_selectedStyle Cloudinary\Cloudinary\Model\Config\Source\Dropdown\ProductGallery\ThumbnailsSelectedStyle - thumbnails + thumbnails @@ -214,7 +218,7 @@ cloudinary/product_gallery/thumbnailProps_selectedBorderPosition Cloudinary\Cloudinary\Model\Config\Source\Dropdown\ProductGallery\ThumbnailsSelectedBorderPosition - thumbnails + thumbnails @@ -222,7 +226,7 @@ cloudinary/product_gallery/thumbnailProps_selectedBorderWidth validate-number - thumbnails + thumbnails @@ -230,7 +234,7 @@ cloudinary/product_gallery/thumbnailProps_mediaSymbolShape Cloudinary\Cloudinary\Model\Config\Source\Dropdown\ProductGallery\ThumbnailsMediaSymbolShape - thumbnails + thumbnails @@ -238,7 +242,7 @@ cloudinary/product_gallery/indicatorProps_shape Cloudinary\Cloudinary\Model\Config\Source\Dropdown\ProductGallery\IndicatorsShape - indicators + indicators @@ -270,4 +274,4 @@
-
+ \ No newline at end of file diff --git a/view/frontend/web/js/cloudinary-product-gallery.js b/view/frontend/web/js/cloudinary-product-gallery.js new file mode 100644 index 0000000..10319dd --- /dev/null +++ b/view/frontend/web/js/cloudinary-product-gallery.js @@ -0,0 +1,35 @@ +define([ + 'jquery', + 'cloudinaryProductGalleryAll' +], function($) { + 'use strict'; + + $.widget('mage.cloudinaryProductGallery', { + + options: { + cloudinaryPGoptions: {}, // Options for Cloudinary-PG galleryWidget() + cldPGid: 0, + }, + + /** + * @private + */ + _create: function() { + this._super(); + + console.log(this.options.cloudinaryPGoptions); + var widget = this; + window.cloudinary_pg = window.cloudinary_pg || []; + this.options.cldPGid = this.options.cldPGid || 0; + if (typeof window.cloudinary_pg[this.options.cldPGid] === "undefined") { + this.cloudinary_pg = window.cloudinary_pg[this.options.cldPGid] = cloudinary.galleryWidget(this.options.cloudinaryPGoptions); + this.cloudinary_pg.render(); + } else { + this.cloudinary_pg = window.cloudinary_pg[this.options.cldPGid]; + } + }, + + }); + + return $.mage.cloudinaryProductGallery; +}); \ No newline at end of file From da7117ea072bb736eb2c71e208add3b71cadfe49 Mon Sep 17 00:00:00 2001 From: pini-girit Date: Sun, 17 Mar 2019 16:24:25 +0200 Subject: [PATCH 05/11] CLOUDINARY-102: Working on Cloudinary-Product-Gallery implementation (almost done) --- Plugin/Catalog/Block/Product/View/Gallery.php | 37 ++++++++++++++++--- view/frontend/templates/product/gallery.phtml | 3 +- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/Plugin/Catalog/Block/Product/View/Gallery.php b/Plugin/Catalog/Block/Product/View/Gallery.php index 5d0ee33..3b7bac3 100644 --- a/Plugin/Catalog/Block/Product/View/Gallery.php +++ b/Plugin/Catalog/Block/Product/View/Gallery.php @@ -17,6 +17,11 @@ class Gallery */ protected $jsonEncoder; + /** + * @var \Magento\Catalog\Block\Product\View\Gallery + */ + protected $productGalleryBlock; + protected $processed; protected $htmlId; @@ -48,6 +53,7 @@ public function beforeToHtml(\Magento\Catalog\Block\Product\View\Gallery $produc { if (!$this->processed && $this->productGalleryHelper->canDisplayProductGallery()) { $this->processed = true; + $this->productGalleryBlock = $productGalleryBlock; $productGalleryBlock->setTemplate('Cloudinary_Cloudinary::product/gallery.phtml'); $productGalleryBlock->setCloudinaryPGOptions($this->getCloudinaryPGOptions()); $productGalleryBlock->setCldPGid($this->getCldPGid()); @@ -78,11 +84,32 @@ protected function getCloudinaryPGOptions($refresh = false, $ignoreDisabled = fa if (is_null($this->cloudinaryPGoptions) || $refresh) { $this->cloudinaryPGoptions = $this->productGalleryHelper->getCloudinaryPGOptions($refresh, $ignoreDisabled); $this->cloudinaryPGoptions['container'] = '#' . $this->getCldPGid(); - $this->cloudinaryPGoptions['mediaAssets'] = [ - (object)["publicId" => "sample", "mediaType" => "image"], - (object)["publicId" => "sample", "mediaType" => "image"], - (object)["publicId" => "sample", "mediaType" => "image"], - ]; + $galleryAssets = (array) @json_decode($this->productGalleryBlock->getGalleryImagesJson(), true); + if (count($galleryAssets)>1) { + usort($galleryAssets, function ($a, $b) { + return $b['isMain'] - $a['isMain']; + }); + usort($galleryAssets, function ($a, $b) { + return $a['position'] - $b['position']; + }); + } + $this->cloudinaryPGoptions['mediaAssets'] = []; + foreach ($galleryAssets as $key => $value) { + switch ($value['type']) { + case 'image': + $this->cloudinaryPGoptions['mediaAssets'][] = (object)[ + "publicId" => $value['full'], + "mediaType" => $value['type'], + ]; + break; + case 'video': + $this->cloudinaryPGoptions['mediaAssets'][] = (object)[ + "publicId" => $value['videoUrl'], + "mediaType" => $value['type'], + ]; + break; + } + } } return $this->jsonEncoder->encode( [ diff --git a/view/frontend/templates/product/gallery.phtml b/view/frontend/templates/product/gallery.phtml index cbde146..7a58a31 100644 --- a/view/frontend/templates/product/gallery.phtml +++ b/view/frontend/templates/product/gallery.phtml @@ -7,6 +7,7 @@ class="cloudinary-product-gallery" data-mage-init='{"cloudinaryProductGallery": getCloudinaryPGOptions() ?>}' style="max-width:100%;margin:auto"> +

Cloudinary Product Gallery Options:

-    getCloudinaryPGOptions())); ?>
+    getCloudinaryPGOptions())->cloudinaryPGoptions); ?>
 
From 7154d96e3c88c1f13d542514d3715040346212a1 Mon Sep 17 00:00:00 2001 From: pini-girit Date: Sun, 17 Mar 2019 16:44:12 +0200 Subject: [PATCH 06/11] CLOUDINARY-102: Working on Cloudinary-Product-Gallery implementation (almost done) --- Plugin/Catalog/Block/Product/View/Gallery.php | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Plugin/Catalog/Block/Product/View/Gallery.php b/Plugin/Catalog/Block/Product/View/Gallery.php index 3b7bac3..179501c 100644 --- a/Plugin/Catalog/Block/Product/View/Gallery.php +++ b/Plugin/Catalog/Block/Product/View/Gallery.php @@ -81,6 +81,9 @@ public function getCldPGid() */ protected function getCloudinaryPGOptions($refresh = false, $ignoreDisabled = false) { + $url = 'https://res.cloudinary.com/dqlogi9lv/video/upload/v1551969992/video5test_copy_4.mp4'; + echo pathinfo($url, PATHINFO_FILENAME); + die; if (is_null($this->cloudinaryPGoptions) || $refresh) { $this->cloudinaryPGoptions = $this->productGalleryHelper->getCloudinaryPGOptions($refresh, $ignoreDisabled); $this->cloudinaryPGoptions['container'] = '#' . $this->getCldPGid(); @@ -95,20 +98,21 @@ protected function getCloudinaryPGOptions($refresh = false, $ignoreDisabled = fa } $this->cloudinaryPGoptions['mediaAssets'] = []; foreach ($galleryAssets as $key => $value) { + $publicId = null; switch ($value['type']) { case 'image': - $this->cloudinaryPGoptions['mediaAssets'][] = (object)[ - "publicId" => $value['full'], - "mediaType" => $value['type'], - ]; + $publicId = $value['full'] ?: $value['img']; break; case 'video': - $this->cloudinaryPGoptions['mediaAssets'][] = (object)[ - "publicId" => $value['videoUrl'], - "mediaType" => $value['type'], - ]; + $publicId = @pathinfo($value['videoUrl'], PATHINFO_FILENAME) ?: null; break; } + if ($publicId) { + $this->cloudinaryPGoptions['mediaAssets'][] = (object)[ + "publicId" => $publicId, + "mediaType" => $value['type'], + ]; + } } } return $this->jsonEncoder->encode( From 7373bccf7076fc96cbeaab0b7c0251c5b3a2cd86 Mon Sep 17 00:00:00 2001 From: pini-girit Date: Sun, 17 Mar 2019 16:52:17 +0200 Subject: [PATCH 07/11] CLOUDINARY-102: Working on Cloudinary-Product-Gallery implementation (almost done) --- Plugin/Catalog/Block/Product/View/Gallery.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Plugin/Catalog/Block/Product/View/Gallery.php b/Plugin/Catalog/Block/Product/View/Gallery.php index 179501c..e04fbfe 100644 --- a/Plugin/Catalog/Block/Product/View/Gallery.php +++ b/Plugin/Catalog/Block/Product/View/Gallery.php @@ -104,7 +104,9 @@ protected function getCloudinaryPGOptions($refresh = false, $ignoreDisabled = fa $publicId = $value['full'] ?: $value['img']; break; case 'video': - $publicId = @pathinfo($value['videoUrl'], PATHINFO_FILENAME) ?: null; + if (strpos($value['videoUrl'], '.cloudinary.com/') !== false) { + $publicId = @pathinfo($value['videoUrl'], PATHINFO_FILENAME) ?: null; + } break; } if ($publicId) { From 3d397d19f53fca744128cab455bb8d26342fbeae Mon Sep 17 00:00:00 2001 From: pini-girit Date: Sun, 17 Mar 2019 16:57:48 +0200 Subject: [PATCH 08/11] CLOUDINARY-102: Working on Cloudinary-Product-Gallery implementation (almost done) --- Plugin/Catalog/Block/Product/View/Gallery.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/Plugin/Catalog/Block/Product/View/Gallery.php b/Plugin/Catalog/Block/Product/View/Gallery.php index e04fbfe..ad2858b 100644 --- a/Plugin/Catalog/Block/Product/View/Gallery.php +++ b/Plugin/Catalog/Block/Product/View/Gallery.php @@ -81,9 +81,6 @@ public function getCldPGid() */ protected function getCloudinaryPGOptions($refresh = false, $ignoreDisabled = false) { - $url = 'https://res.cloudinary.com/dqlogi9lv/video/upload/v1551969992/video5test_copy_4.mp4'; - echo pathinfo($url, PATHINFO_FILENAME); - die; if (is_null($this->cloudinaryPGoptions) || $refresh) { $this->cloudinaryPGoptions = $this->productGalleryHelper->getCloudinaryPGOptions($refresh, $ignoreDisabled); $this->cloudinaryPGoptions['container'] = '#' . $this->getCldPGid(); From 31318df9acafac88a5f9d128eb6bb2c6700b2e45 Mon Sep 17 00:00:00 2001 From: pini-girit Date: Sun, 17 Mar 2019 17:02:14 +0200 Subject: [PATCH 09/11] CLOUDINARY-102: Working on Cloudinary-Product-Gallery implementation (almost done) --- view/frontend/templates/product/gallery.phtml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/view/frontend/templates/product/gallery.phtml b/view/frontend/templates/product/gallery.phtml index 7a58a31..9378f87 100644 --- a/view/frontend/templates/product/gallery.phtml +++ b/view/frontend/templates/product/gallery.phtml @@ -7,7 +7,3 @@ class="cloudinary-product-gallery" data-mage-init='{"cloudinaryProductGallery": getCloudinaryPGOptions() ?>}' style="max-width:100%;margin:auto"> -

Cloudinary Product Gallery Options:

-
-    getCloudinaryPGOptions())->cloudinaryPGoptions); ?>
-
From 17384f4699e942078ab4d4286df72599899bf1c9 Mon Sep 17 00:00:00 2001 From: pini-girit Date: Sun, 17 Mar 2019 17:26:32 +0200 Subject: [PATCH 10/11] CLOUDINARY-105,CLOUDINARY-107: Minor content fixes --- view/adminhtml/web/template/product/free_transform.html | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/view/adminhtml/web/template/product/free_transform.html b/view/adminhtml/web/template/product/free_transform.html index 3d87e4b..10ee595 100644 --- a/view/adminhtml/web/template/product/free_transform.html +++ b/view/adminhtml/web/template/product/free_transform.html @@ -12,7 +12,7 @@ File - Free transform + Cloudinary Transformation Action @@ -32,9 +32,7 @@

For information about the full range of transforms available see the - - Cloudinary documentation - . + Cloudinary documentation.

You may need to clear or rebuild the Magento block and full page caches to see the changes in the front end. From ae26cfd2cbe8270184ae2e254140ccf4d582243c Mon Sep 17 00:00:00 2001 From: pini-girit Date: Wed, 3 Jul 2019 13:01:59 +0300 Subject: [PATCH 11/11] CLOUDINARY-134: Fixed Magento 2.3.1 issue on wysiwyg from GH issue #29 --- Model/Configuration.php | 2 +- composer.json | 2 +- etc/module.xml | 2 +- marketplace.composer.json | 2 +- view/adminhtml/layout/cms_wysiwyg_images_index.xml | 6 +++++- view/adminhtml/web/js/cloudinary-media-library-modal.js | 1 + 6 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Model/Configuration.php b/Model/Configuration.php index 3dd612e..b03e30e 100644 --- a/Model/Configuration.php +++ b/Model/Configuration.php @@ -199,7 +199,7 @@ public function getCdnSubdomainStatus() */ public function getUserPlatform() { - return sprintf(self::USER_PLATFORM_TEMPLATE, '1.9.0', '2.0.0'); + return sprintf(self::USER_PLATFORM_TEMPLATE, '1.9.1', '2.0.0'); } /** diff --git a/composer.json b/composer.json index be32cbe..3ee3111 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "cloudinary/cloudinary-magento2", "description": "Cloudinary Magento 2 Integration.", "type": "magento2-module", - "version": "1.9.0", + "version": "1.9.1", "license": "MIT", "require": { "cloudinary/cloudinary_php": "*" diff --git a/etc/module.xml b/etc/module.xml index 1389dd1..4460b20 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -1,6 +1,6 @@ - + diff --git a/marketplace.composer.json b/marketplace.composer.json index 8d180a6..7245e00 100644 --- a/marketplace.composer.json +++ b/marketplace.composer.json @@ -1,7 +1,7 @@ { "name": "cloudinary/cloudinary", "type": "magento2-module", - "version": "1.9.0", + "version": "1.9.1", "description": "Cloudinary Magento 2 Integration.", "license": "MIT", "require": { diff --git a/view/adminhtml/layout/cms_wysiwyg_images_index.xml b/view/adminhtml/layout/cms_wysiwyg_images_index.xml index 53a5bbc..323ba36 100644 --- a/view/adminhtml/layout/cms_wysiwyg_images_index.xml +++ b/view/adminhtml/layout/cms_wysiwyg_images_index.xml @@ -3,7 +3,11 @@ - + + + Magento\Backend\Block\DataProviders\ImageUploadConfig + + diff --git a/view/adminhtml/web/js/cloudinary-media-library-modal.js b/view/adminhtml/web/js/cloudinary-media-library-modal.js index e67e91d..5315975 100644 --- a/view/adminhtml/web/js/cloudinary-media-library-modal.js +++ b/view/adminhtml/web/js/cloudinary-media-library-modal.js @@ -53,6 +53,7 @@ define([ 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); } }