From 06faac10ef30c031ff5432cbbe35aa3cea055e95 Mon Sep 17 00:00:00 2001 From: Ariel Ashri Date: Thu, 29 Sep 2022 13:22:39 +0300 Subject: [PATCH 1/3] Magento marketplace standards - remove setup files --- Setup/InstallSchema.php | 44 -------- Setup/UpgradeData.php | 63 ----------- Setup/UpgradeSchema.php | 237 ---------------------------------------- 3 files changed, 344 deletions(-) delete mode 100644 Setup/InstallSchema.php delete mode 100644 Setup/UpgradeData.php delete mode 100644 Setup/UpgradeSchema.php diff --git a/Setup/InstallSchema.php b/Setup/InstallSchema.php deleted file mode 100644 index 03482ef..0000000 --- a/Setup/InstallSchema.php +++ /dev/null @@ -1,44 +0,0 @@ -startSetup(); - - /** - * Create table 'cloudinary_synchronisation' - */ - $table = $setup->getConnection()->newTable( - $setup->getTable('cloudinary_synchronisation') - )->addColumn( - 'cloudinary_synchronisation_id', - Table::TYPE_INTEGER, - null, - ['identity' => true, 'nullable' => false, 'primary' => true, 'unsigned' => true], - 'Cloudinary Synchronisation ID' - )->addColumn( - 'image_path', - Table::TYPE_TEXT, - 255, - ['nullable' => false], - 'Image Path' - ); - - $setup->getConnection()->createTable($table); - - $setup->endSetup(); - } -} diff --git a/Setup/UpgradeData.php b/Setup/UpgradeData.php deleted file mode 100644 index 063a518..0000000 --- a/Setup/UpgradeData.php +++ /dev/null @@ -1,63 +0,0 @@ -resourceConnection = $resourceConnection; - $this->output = $output; - } - - /** - * {@inheritdoc} - */ - public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context) - { - $setup->startSetup(); - - if (version_compare($context->getVersion(), '1.6.3') < 0) { - if ($context->getVersion()) { - $this->output->writeln("Reseting configurations for 'website' & 'store' scopes (only supports 'default' at the moment)"); - } - - $this->resourceConnection->getConnection()->delete( - $this->resourceConnection->getTableName('core_config_data'), - "path LIKE 'cloudinary/%' AND scope != 'default'" - ); - } - - $setup->endSetup(); - } -} diff --git a/Setup/UpgradeSchema.php b/Setup/UpgradeSchema.php deleted file mode 100644 index e335e04..0000000 --- a/Setup/UpgradeSchema.php +++ /dev/null @@ -1,237 +0,0 @@ -startSetup(); - - if (version_compare($context->getVersion(), '1.5.0', '<')) { - $this->createTransformationTable($setup); - } - - if (version_compare($context->getVersion(), '1.10.3', '<')) { - $this->createMediaLibraryMapTable($setup); - } - - if (version_compare($context->getVersion(), '1.12.0', '<')) { - $this->createProductGalleryApiQueueTable($setup); - } - - if (version_compare($context->getVersion(), '1.13.0', '<')) { - $this->createProductSpinsetMapTable($setup); - } - - if (version_compare($context->getVersion(), '1.14.9', '<')) { - $setup->getConnection()->addIndex( - $setup->getTable('cloudinary_synchronisation'), - $setup->getIdxName('cloudinary_synchronisation', ['image_path']), - ['image_path'] - ); - } - - $setup->endSetup(); - } - - /** - * @param SchemaSetupInterface $setup - */ - private function createTransformationTable(SchemaSetupInterface $setup) - { - $table = $setup->getConnection()->newTable( - $setup->getTable('cloudinary_transformation') - )->addColumn( - 'image_name', - Table::TYPE_TEXT, - 255, - ['nullable' => false, 'primary' => true], - 'Relative image path' - )->addColumn( - 'free_transformation', - Table::TYPE_TEXT, - 255, - [], - 'Free transformation' - ); - - $setup->getConnection()->createTable($table); - } - - /** - * @param SchemaSetupInterface $setup - */ - private function createMediaLibraryMapTable(SchemaSetupInterface $setup) - { - $table = $setup->getConnection()->newTable( - $setup->getTable('cloudinary_media_library_map') - )->addColumn( - 'id', - \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, - null, - ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true], - 'ID' - )->addColumn( - 'cld_uniqid', - Table::TYPE_TEXT, - 255, - ['nullable' => false], - 'Relative image path' - )->addColumn( - 'cld_public_id', - Table::TYPE_TEXT, - 255, - ['nullable' => false], - 'Cloudinary Public ID' - )->addColumn( - 'free_transformation', - Table::TYPE_TEXT, - 255, - [], - 'Free transformation' - )->addIndex( - $setup->getIdxName( - 'cloudinary_media_library_map', - ['cld_uniqid'], - \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE - ), - ['cld_uniqid'], - ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE] - ); - - $setup->getConnection()->createTable($table); - } - - /** - * - * @param SchemaSetupInterface $setup - */ - private function createProductGalleryApiQueueTable(SchemaSetupInterface $setup) - { - $table = $setup->getConnection()->newTable( - $setup->getTable('cloudinary_product_gallery_api_queue') - )->addColumn( - 'id', - \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, - null, - ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true], - 'ID' - )->addColumn( - 'sku', - Table::TYPE_TEXT, - 255, - ['nullable' => false], - 'Product SKU' - )->addColumn( - 'full_item_data', - \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, - 3000, - ['nullable' => true], - 'Prepared Schema' - ) - ->addColumn( - 'created_at', - \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP, - null, - ['nullable' => false, 'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT], - 'Created At' - ) - ->addColumn( - 'updated_at', - \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP, - null, - ['nullable' => false, 'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT_UPDATE], - 'Created At' - ) - ->addColumn( - 'success', - \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, - 1, - ['unsigned' => true, 'nullable' => false, 'default' => '0'], - 'Success' - ) - ->addColumn( - 'success_at', - \Magento\Framework\DB\Ddl\Table::TYPE_DATETIME, - null, - ['nullable' => true], - 'Success At' - ) - ->addColumn( - 'message', - \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, - 3000, - ['nullable' => true], - 'Message' - ) - ->addColumn( - 'has_errors', - \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, - 1, - ['unsigned' => true, 'nullable' => true, 'default' => '0'], - 'Has Errors' - ) - ->addColumn( - 'tryouts', - \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, - 11, - ['unsigned' => true, 'nullable' => true, 'default' => '0'], - 'Tryouts' - ); - $setup->getConnection()->createTable($table); - } - - /** - * @param SchemaSetupInterface $setup - */ - private function createProductSpinsetMapTable(SchemaSetupInterface $setup) - { - $table = $setup->getConnection()->newTable( - $setup->getTable('cloudinary_product_spinset_map') - )->addColumn( - 'id', - \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, - null, - ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true], - 'ID' - )->addColumn( - 'store_id', - \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, - null, - ['unsigned' => true, 'nullable' => false, 'default' => '0'], - 'Store ID' - )->addColumn( - 'image_name', - Table::TYPE_TEXT, - 255, - ['nullable' => false], - 'Relative image path' - )->addColumn( - 'cldspinset', - Table::TYPE_TEXT, - 255, - [], - 'Cloudinary Spinset Tag' - )->addIndex( - $setup->getIdxName( - 'cloudinary_product_spinset_map', - ['store_id', 'image_name'], - \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE - ), - ['store_id', 'image_name'], - ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE] - ); - - $setup->getConnection()->createTable($table); - } -} From 9aa64efe8e7a13033ab7767fe24c5ce1869eab2e Mon Sep 17 00:00:00 2001 From: Ariel Ashri Date: Sun, 16 Oct 2022 12:52:02 +0300 Subject: [PATCH 2/3] CLOUDINARY-412 - fix CMS block multiselect bug --- Model/Configuration.php | 9 ++++++++- composer.json | 2 +- etc/adminhtml/system.xml | 1 + etc/module.xml | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Model/Configuration.php b/Model/Configuration.php index ff9fe47..94956dd 100644 --- a/Model/Configuration.php +++ b/Model/Configuration.php @@ -471,9 +471,16 @@ public function isLazyloadAutoReplaceCmsBlocks() return (bool) $this->configReader->getValue(self::XML_PATH_LAZYLOAD_AUTO_REPLACE_CMS_BLOCKS); } + /** + * @return array|null + */ public function getLazyloadIgnoredCmsBlocksArray() { - return (array) explode(',', $this->configReader->getValue(self::XML_PATH_LAZYLOAD_IGNORED_CMS_BLOCKS)); + $value = ($this->configReader->getValue(self::XML_PATH_LAZYLOAD_IGNORED_CMS_BLOCKS)) + ? (array) explode(',', $this->configReader->getValue(self::XML_PATH_LAZYLOAD_IGNORED_CMS_BLOCKS)) + : null; + + return $value; } public function getLazyloadThreshold() diff --git a/composer.json b/composer.json index 7c9e784..a9780f6 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "cloudinary/cloudinary", "description": "Cloudinary Magento 2 Integration.", "type": "magento2-module", - "version": "1.19.0", + "version": "1.19.2", "license": "MIT", "require": { "cloudinary/cloudinary_php": ">=2.7 <2.8.1" diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 8aba1c0..148d290 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -317,6 +317,7 @@ List of CMS blocks to exclude from Lazyloading. Use this if there are conflicts on some of the blocks. cloudinary/lazyload/ignored_cms_blocks Cloudinary\Cloudinary\Model\Config\Source\Dropdown\CmsBlocks + 1 1 1 diff --git a/etc/module.xml b/etc/module.xml index ded8f92..9312b71 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -1,6 +1,6 @@ - + From 6ab597e5d970621b2f85a3ac4f712cfd987e7179 Mon Sep 17 00:00:00 2001 From: Ariel Ashri Date: Wed, 19 Oct 2022 14:15:59 +0300 Subject: [PATCH 3/3] CLOUDINARY-413 [Feature] Add delete method for product catalog API --- Api/ProductGalleryManagementInterface.php | 9 +++ Model/Api/ProductGalleryManagement.php | 86 +++++++++++++++++++++++ etc/webapi.xml | 9 +++ 3 files changed, 104 insertions(+) diff --git a/Api/ProductGalleryManagementInterface.php b/Api/ProductGalleryManagementInterface.php index 3fc70d2..23a3026 100644 --- a/Api/ProductGalleryManagementInterface.php +++ b/Api/ProductGalleryManagementInterface.php @@ -52,4 +52,13 @@ public function getProductMedia($sku); * @return string */ public function getProductsMedia($skus); + + + /** Remove Product images by publicIds + * @param string $sku + * @param mixed $urls + * @param bool | int | null $delete_all_gallery + * @return string + */ + public function removeProductMedia($sku, $urls, $delete_all_gallery = 0); } diff --git a/Model/Api/ProductGalleryManagement.php b/Model/Api/ProductGalleryManagement.php index 7bb673a..9b1c195 100644 --- a/Model/Api/ProductGalleryManagement.php +++ b/Model/Api/ProductGalleryManagement.php @@ -19,6 +19,7 @@ use Magento\Framework\App\ResourceConnection; use Magento\Framework\DataObject; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Filesystem; use Magento\Framework\HTTP\Adapter\Curl; use Magento\Framework\Image\AdapterFactory as ImageAdapterFactory; @@ -233,6 +234,88 @@ public function __construct( $this->resourceConnection = $resourceConnection; } + + /** + * Remove Gallery Item + * @param $product + * @param $url + * @param $removeAllGallery + * @return int|void + * @throws NoSuchEntityException . + */ + private function removeGalleryItem($product, $url, $removeAllGallery) + { + $unlinked = 0; + if ($product) { + $mediaGalleryEntries = $product->getMediaGalleryEntries(); + + if (is_array($mediaGalleryEntries)) { + foreach ($mediaGalleryEntries as $key => $entry) { + $image = $entry->getFile(); + $url = preg_replace('/\?.*/', '', $url); + $image = $this->storeManager->getStore()->getBaseUrl() . 'pub/media/catalog/product' . $image; + $basename = basename($image); + $ext = pathinfo($image, PATHINFO_EXTENSION); + // removing unique id from original filename + $pattern = '/^' . $this->configuration::CLD_UNIQID_PREFIX . '.*?_/'; + $basename = preg_replace($pattern, '', $basename); + $filename = basename($url); + $filename = preg_replace($pattern, '', $filename); + // $filename = $url . '.' . $ext; + + if ($basename == $filename || $removeAllGallery) { + unset($mediaGalleryEntries[$key]); + $this->mediaGalleryProcessor->removeImage($product, $image); + $unlinked++; + } + } + } + if ($unlinked) { + $product->setMediaGalleryEntries($mediaGalleryEntries); + try { + $product = $this->productRepository->save($product); + } catch (\Exception $e) { + $message = ['type' => 'error', 'message' => 'Falied Delete Image Error: ' . $e->getMessage() . ' line ' . $e->getLine()]; + } + } + return $unlinked; + } + } + + /** + * {@inheritdoc} + */ + public function removeProductMedia($sku, $urls, $delete_all_gallery = 0) + { + $result = [ + "passed" => 0, + "failed" => [ + "count" => 0, + "urls" => [] + ] + ]; + + $urls = (array) $urls; + + try { + $product = $this->productRepository->get($sku); + $this->checkEnvHeader(); + $this->checkEnabled(); + + foreach ($urls as $i => $url) { + $unlinked = $this->removeGalleryItem($product, $url, $delete_all_gallery); + } + + $result["passed"] = $unlinked; + } catch (\Exception $e) { + $result["failed"]["count"]++; + $result["error"] = $e->getMessage(); + $result["failed"]["public_id"][] = $url; + } + + return $this->jsonHelper->jsonEncode($result); + } + /** * {@inheritdoc} */ @@ -487,6 +570,7 @@ public function addGalleryItem($url, $sku, $publicId = null, $roles = null, $lab ); $mediaGalleryData = $product->getMediaGallery(); + // last gallery value from array $galItem = array_pop($mediaGalleryData["images"]); if ($this->parsedRemoteFileUrl["type"] === "video") { @@ -812,4 +896,6 @@ private function emulateAdminhtmlArea($force = true) $this->startEnvironmentEmulation(0, Area::AREA_ADMINHTML, $force); return $this; } + + } diff --git a/etc/webapi.xml b/etc/webapi.xml index afc1e3b..29c5b70 100644 --- a/etc/webapi.xml +++ b/etc/webapi.xml @@ -74,4 +74,13 @@ + + + + + + + + +