diff --git a/Command/DownloadImages.php b/Command/DownloadImages.php index e973c16..2709401 100644 --- a/Command/DownloadImages.php +++ b/Command/DownloadImages.php @@ -3,7 +3,9 @@ namespace Cloudinary\Cloudinary\Command; use Cloudinary\Cloudinary\Model\BatchDownloader; +use Cloudinary\Cloudinary\Model\Configuration; use Cloudinary\Cloudinary\Model\Logger\OutputLogger; +use Magento\Framework\Registry; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -16,6 +18,8 @@ class DownloadImages extends Command * Keys and shortcuts for input arguments and options */ const OVERRIDE = 'override'; + const FORCE = 'force'; + const ENV = 'env'; /**#@- */ const OVERRIDE_CONFIRM_MESSAGE = "Are you sure you want to override local files (y/n)[n]?"; @@ -33,14 +37,26 @@ class DownloadImages extends Command private $outputLogger; /** - * @param BatchDownloader $batchDownloader + * @var Registry */ - public function __construct(BatchDownloader $batchDownloader, OutputLogger $outputLogger) - { + private $coreRegistry; + + /** + * @method __construct + * @param BatchDownloader $batchDownloader + * @param OutputLogger $outputLogger + * @param Registry $coreRegistry + */ + public function __construct( + BatchDownloader $batchDownloader, + OutputLogger $outputLogger, + Registry $coreRegistry + ) { parent::__construct('cloudinary:download:all'); $this->batchDownloader = $batchDownloader; $this->outputLogger = $outputLogger; + $this->coreRegistry = $coreRegistry; } /** @@ -59,6 +75,19 @@ protected function configure() InputOption::VALUE_NONE, 'Override local images if already exists' ), + new InputOption( + self::FORCE, + '-f', + InputOption::VALUE_NONE, + 'Force download even if Cloudinary is disabled' + ), + new InputOption( + self::ENV, + '-e', + InputOption::VALUE_OPTIONAL, + 'Cloudinary environment variable that will be used during the process', + null + ), ]); } @@ -74,6 +103,12 @@ protected function execute(InputInterface $input, OutputInterface $output) if ($input->getOption(self::OVERRIDE) && $this->confirmQuestion(self::OVERRIDE_CONFIRM_MESSAGE, $input, $output)) { $this->_override = true; } + if (($env = $input->getOption(self::ENV))) { + $this->coreRegistry->register(Configuration::CONFIG_PATH_ENVIRONMENT_VARIABLE, $env); + } + if ($input->getOption(self::FORCE)) { + $this->coreRegistry->register(Configuration::CONFIG_PATH_ENABLED, true); + } $this->outputLogger->setOutput($output); $this->batchDownloader->downloadUnsynchronisedImages($this->outputLogger, $this->_override); } catch (\Exception $e) { diff --git a/Command/UploadImages.php b/Command/UploadImages.php index 3bdfaff..25e63fe 100644 --- a/Command/UploadImages.php +++ b/Command/UploadImages.php @@ -3,13 +3,23 @@ namespace Cloudinary\Cloudinary\Command; use Cloudinary\Cloudinary\Model\BatchUploader; +use Cloudinary\Cloudinary\Model\Configuration; use Cloudinary\Cloudinary\Model\Logger\OutputLogger; +use Magento\Framework\Registry; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; class UploadImages extends Command { + /**#@+ + * Keys and shortcuts for input arguments and options + */ + const FORCE = 'force'; + const ENV = 'env'; + /**#@- */ + /** * @var BatchUploader */ @@ -21,14 +31,26 @@ class UploadImages extends Command private $outputLogger; /** - * @param BatchUploader $batchUploader + * @var Registry */ - public function __construct(BatchUploader $batchUploader, OutputLogger $outputLogger) - { + private $coreRegistry; + + /** + * @method __construct + * @param BatchUploader $batchUploader + * @param OutputLogger $outputLogger + * @param Registry $coreRegistry + */ + public function __construct( + BatchUploader $batchUploader, + OutputLogger $outputLogger, + Registry $coreRegistry + ) { parent::__construct('cloudinary:upload:all'); $this->batchUploader = $batchUploader; $this->outputLogger = $outputLogger; + $this->coreRegistry = $coreRegistry; } /** @@ -40,6 +62,21 @@ protected function configure() { $this->setName('cloudinary:upload:all'); $this->setDescription('Upload unsynchronised images'); + $this->setDefinition([ + new InputOption( + self::FORCE, + '-f', + InputOption::VALUE_NONE, + 'Force upload even if Cloudinary is disabled' + ), + new InputOption( + self::ENV, + '-e', + InputOption::VALUE_OPTIONAL, + 'Cloudinary environment variable that will be used during the process', + null + ), + ]); } /** @@ -51,6 +88,12 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { try { + if (($env = $input->getOption(self::ENV))) { + $this->coreRegistry->register(Configuration::CONFIG_PATH_ENVIRONMENT_VARIABLE, $env); + } + if ($input->getOption(self::FORCE)) { + $this->coreRegistry->register(Configuration::CONFIG_PATH_ENABLED, true); + } $this->outputLogger->setOutput($output); $this->batchUploader->uploadUnsynchronisedImages($this->outputLogger); } catch (\Exception $e) { diff --git a/Model/BatchDownloader.php b/Model/BatchDownloader.php index dfd260e..fe81cd2 100644 --- a/Model/BatchDownloader.php +++ b/Model/BatchDownloader.php @@ -9,10 +9,10 @@ use Cloudinary\Cloudinary\Core\Image; use Cloudinary\Cloudinary\Core\Image\SynchronizationCheck; use Cloudinary\Cloudinary\Core\SynchroniseAssetsRepositoryInterface; +use Cloudinary\Cloudinary\Model\Framework\File\Uploader; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\DataObject; use Magento\Framework\Exception\LocalizedException; -use Cloudinary\Cloudinary\Model\Framework\File\Uploader; use Magento\Framework\Filesystem; use Magento\Framework\HTTP\Adapter\Curl; use Magento\Framework\Validator\AllowedProtocols; @@ -26,7 +26,7 @@ class BatchDownloader const API_REQUESTS_SLEEP_BEFORE_NEXT_CALL = 3; //Seconds const API_REQUEST_STOP_ON_REMAINING_RATE_LIMIT = 10; const WAIT_FOR_RATE_LIMIT_RESET_MESSAGE = "Cloudinary API - calls rate limit reached, sleeping until %s ..."; - const ERROR_MIGRATION_ALREADY_RUNNING = 'Cannot start download - a migration is in progress or was interrupted. If you are sure a migration is not running elsewhere run the cloudinary:download:stop command before attempting another download.'; + const ERROR_MIGRATION_ALREADY_RUNNING = 'Cannot start download - a migration is in progress or was interrupted. If you are sure a migration is not running elsewhere run the cloudinary:migration:stop command before attempting another download.'; const MESSAGE_DOWNLOAD_INTERRUPTED = 'Download manually stopped.'; const DONE_MESSAGE = "Done :)"; @@ -164,9 +164,14 @@ private function _authorise() */ public function downloadUnsynchronisedImages(OutputInterface $output = null, $override = false) { - if ($this->_configuration->isEnabled()) { - $this->_authorise(); + if (!$this->_configuration->isEnabled(false)) { + throw new \Exception("Cloudinary seems to be disabled. Please enable it first or pass -f in order to force it on the CLI"); } + if (!$this->_configuration->hasEnvironmentVariable()) { + throw new \Exception("Cloudinary environment variable seems to be missing. Please configure it first or pass it to the command as `-e` in order to use on the CLI"); + } + + $this->_authorise(); //= Config $this->_output = $output; diff --git a/Model/BatchUploader.php b/Model/BatchUploader.php index 5774888..9f16235 100644 --- a/Model/BatchUploader.php +++ b/Model/BatchUploader.php @@ -72,6 +72,13 @@ public function __construct( */ public function uploadUnsynchronisedImages(OutputInterface $output = null) { + if (!$this->configuration->isEnabled(false)) { + throw new \Exception("Cloudinary seems to be disabled. Please enable it first or pass -f in order to force it on the CLI"); + } + if (!$this->configuration->hasEnvironmentVariable()) { + throw new \Exception("Cloudinary environment variable seems to be missing. Please configure it first or pass it to the command as `-e` in order to use on the CLI"); + } + if (!$this->validateAutoUploadMapping($output) || !$this->validateMigrationLock($output)) { return false; } diff --git a/Model/Configuration.php b/Model/Configuration.php index bf20c1b..5eb6f5b 100644 --- a/Model/Configuration.php +++ b/Model/Configuration.php @@ -22,6 +22,7 @@ use Magento\Framework\App\ProductMetadataInterface; use Magento\Framework\Encryption\EncryptorInterface; use Magento\Framework\Module\ModuleListInterface; +use Magento\Framework\Registry; use Magento\Framework\UrlInterface; use Magento\Store\Model\StoreManagerInterface; use Psr\Log\LoggerInterface; @@ -153,6 +154,11 @@ class Configuration implements ConfigurationInterface */ private $cloudinaryLogger; + /** + * @var Registry + */ + private $coreRegistry; + /** * @method __construct * @param ScopeConfigInterface $configReader @@ -164,6 +170,7 @@ class Configuration implements ConfigurationInterface * @param ModuleListInterface $moduleList * @param ProductMetadataInterface $productMetadata * @param CloudinaryLogger $cloudinaryLogger + * @param registry $coreRegistry */ public function __construct( ScopeConfigInterface $configReader, @@ -174,7 +181,8 @@ public function __construct( StoreManagerInterface $storeManager, ModuleListInterface $moduleList, ProductMetadataInterface $productMetadata, - CloudinaryLogger $cloudinaryLogger + CloudinaryLogger $cloudinaryLogger, + registry $coreRegistry ) { $this->configReader = $configReader; $this->configWriter = $configWriter; @@ -185,6 +193,7 @@ public function __construct( $this->moduleList = $moduleList; $this->productMetadata = $productMetadata; $this->cloudinaryLogger = $cloudinaryLogger; + $this->coreRegistry = $coreRegistry; } /** @@ -269,7 +278,7 @@ public function getUploadConfig() */ public function isEnabled($checkEnvVar = true) { - return ($this->hasEnvironmentVariable() || !$checkEnvVar) && $this->configReader->isSetFlag(self::CONFIG_PATH_ENABLED); + return ($this->hasEnvironmentVariable() || !$checkEnvVar) && ($this->coreRegistry->registry(self::CONFIG_PATH_ENABLED) || $this->configReader->isSetFlag(self::CONFIG_PATH_ENABLED)); } public function enable() @@ -336,7 +345,7 @@ public function getImageDpr() */ public function hasEnvironmentVariable() { - return (bool)$this->configReader->getValue(self::CONFIG_PATH_ENVIRONMENT_VARIABLE); + return $this->coreRegistry->registry(self::CONFIG_PATH_ENVIRONMENT_VARIABLE) ?: (bool)$this->configReader->getValue(self::CONFIG_PATH_ENVIRONMENT_VARIABLE); } /** @@ -347,6 +356,7 @@ public function getEnvironmentVariable() if (is_null($this->environmentVariable)) { try { $this->environmentVariable = CloudinaryEnvironmentVariable::fromString( + $this->coreRegistry->registry(self::CONFIG_PATH_ENVIRONMENT_VARIABLE) ?: $this->decryptor->decrypt( $this->configReader->getValue(self::CONFIG_PATH_ENVIRONMENT_VARIABLE) ) diff --git a/Model/ImageRepository.php b/Model/ImageRepository.php index 0a8a97a..56e9586 100644 --- a/Model/ImageRepository.php +++ b/Model/ImageRepository.php @@ -17,6 +17,11 @@ class ImageRepository { private $allowedImgExtensions = ['JPG', 'PNG', 'GIF', 'BMP', 'TIFF', 'EPS', 'PSD', 'SVG', 'WebP']; + /** + * @var Filesystem + */ + private $filesystem; + /** * @var ReadInterface */ @@ -32,7 +37,7 @@ class ImageRepository */ public function __construct(Filesystem $filesystem, SynchronizationCheck $synchronizationChecker) { - $this->mediaDirectory = $filesystem->getDirectoryRead(DirectoryList::MEDIA); + $this->filesystem = $filesystem; $this->synchronizationChecker = $synchronizationChecker; } @@ -41,11 +46,19 @@ public function __construct(Filesystem $filesystem, SynchronizationCheck $synchr */ public function findUnsynchronisedImages() { + $this->mediaDirectory = $this->filesystem->getDirectoryRead(DirectoryList::MEDIA); + if ($this->mediaDirectory->getAbsolutePath() !== ($mediaRealPath = realpath($this->mediaDirectory->getAbsolutePath()))) { + $this->mediaDirectory = $this->filesystem->getDirectoryReadByPath($mediaRealPath); + } + $images = []; foreach ($this->getRecursiveIterator($this->mediaDirectory->getAbsolutePath()) as $item) { $absolutePath = $item->getRealPath(); - $relativePath = $this->mediaDirectory->getRelativePath($item->getRealPath()); + if (strpos(basename($absolutePath), '.') === 0) { + continue; + } + $relativePath = $this->mediaDirectory->getRelativePath($absolutePath); if ($this->isValidImageFile($item) && !$this->synchronizationChecker->isSynchronized($relativePath)) { $images[] = Image::fromPath($absolutePath, $relativePath); } diff --git a/Model/Observer/Configuration.php b/Model/Observer/Configuration.php index 39b05ed..a876bc4 100644 --- a/Model/Observer/Configuration.php +++ b/Model/Observer/Configuration.php @@ -98,7 +98,11 @@ public function execute(Observer $observer) protected function cleanConfigCache() { - $this->cacheTypeList->cleanType(\Magento\Framework\App\Cache\Type\Config::TYPE_IDENTIFIER); + try { + $this->cacheTypeList->cleanType(\Magento\Framework\App\Cache\Type\Config::TYPE_IDENTIFIER); + } catch (\Exception $e) { + $this->messageManager->addNoticeMessage(__('For some reason, Cloudinary couldn\'t clear your config cache, please clear the cache manually. (Exception message: %1)', $e->getMessage())); + } return $this; } } diff --git a/composer.json b/composer.json index f830054..7ed13ac 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.14.6", + "version": "1.14.7", "license": "MIT", "require": { "cloudinary/cloudinary_php": "^1.20.0" diff --git a/etc/module.xml b/etc/module.xml index 65a86f7..54b47e0 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -1,6 +1,6 @@ - + diff --git a/marketplace.composer.json b/marketplace.composer.json index 183cbe4..122e62d 100644 --- a/marketplace.composer.json +++ b/marketplace.composer.json @@ -2,10 +2,10 @@ "name": "cloudinary/cloudinary", "description": "Cloudinary Magento 2 Integration.", "type": "magento2-module", - "version": "1.14.6", + "version": "1.14.7", "license": "MIT", "require": { - "cloudinary/cloudinary_php": "*" + "cloudinary/cloudinary_php": "^1.20.0" }, "autoload": { "files": [