Version Notes
v1.2.0
Release Highlights:
* Foldered migration
Download this release
Release Info
Developer | Cloudinary |
Extension | Cloudinary_Cloudinary |
Version | 1.2.0 |
Comparing to | |
See all releases |
Code changes from version 1.1.0 to 1.2.0
- app/code/community/Cloudinary/Cloudinary/Block/Adminhtml/Manage.php +40 -8
- app/code/community/Cloudinary/Cloudinary/Helper/Configuration.php +42 -3
- app/code/community/Cloudinary/Cloudinary/Helper/Image.php +11 -3
- app/code/community/Cloudinary/Cloudinary/Helper/Util/ArrayUtils.php +22 -0
- app/code/community/Cloudinary/Cloudinary/Model/Catalog/Product/Image.php +10 -8
- app/code/community/Cloudinary/Cloudinary/Model/Catalog/Product/Media.php +6 -2
- app/code/community/Cloudinary/Cloudinary/Model/Catalog/Product/Media/Config.php +3 -2
- app/code/community/Cloudinary/Cloudinary/Model/Cms/Synchronisation.php +8 -4
- app/code/community/Cloudinary/Cloudinary/Model/{MediaCollectionCounter.php → CollectionCounter.php} +5 -7
- app/code/community/Cloudinary/Cloudinary/Model/Cron.php +4 -0
- app/code/community/Cloudinary/Cloudinary/Model/Image.php +10 -3
- app/code/community/Cloudinary/Cloudinary/Model/Logger.php +29 -0
- app/code/community/Cloudinary/Cloudinary/Model/MagentoFolderTranslator.php +81 -0
- app/code/community/Cloudinary/Cloudinary/Model/MigrationError.php +26 -0
- app/code/community/Cloudinary/Cloudinary/Model/PreConditionsValidator.php +7 -2
- app/code/community/Cloudinary/Cloudinary/Model/Resource/Cms/Synchronisation/Collection.php +40 -7
- app/code/community/Cloudinary/Cloudinary/Model/Resource/Media/Collection.php +9 -1
- app/code/community/Cloudinary/Cloudinary/Model/Resource/MigrationError.php +10 -0
- app/code/community/Cloudinary/Cloudinary/Model/Resource/MigrationError/Collection.php +10 -0
- app/code/community/Cloudinary/Cloudinary/Model/Resource/Synchronisation/Collection.php +25 -7
- app/code/community/Cloudinary/Cloudinary/Model/Synchronisation.php +16 -5
- app/code/community/Cloudinary/Cloudinary/Model/SynchronisedMediaUnifier.php +1 -1
- app/code/community/Cloudinary/Cloudinary/controllers/Adminhtml/CloudinaryController.php +12 -1
- app/code/community/Cloudinary/Cloudinary/data/cloudinary_setup/data-upgrade-1.1.2-1.1.3.php +3 -0
- app/code/community/Cloudinary/Cloudinary/etc/config.xml +5 -2
- app/code/community/Cloudinary/Cloudinary/etc/system.xml +11 -1
- app/code/community/Cloudinary/Cloudinary/sql/cloudinary_setup/upgrade-1.1.3-1.1.4.php +18 -0
- app/code/community/Cloudinary/Cloudinary/sql/cloudinary_setup/upgrade-1.1.4-1.1.5.php +20 -0
- app/design/adminhtml/default/default/template/cloudinary/manage.phtml +46 -2
- lib/Cloudinary/Api.php +0 -1
- lib/Cloudinary/Cloudinary.php +24 -22
- lib/Cloudinary/Uploader.php +22 -12
- lib/CloudinaryExtension/CloudinaryImageProvider.php +21 -2
- lib/CloudinaryExtension/Exception/MigrationError.php +50 -0
- lib/CloudinaryExtension/FolderTranslator.php +16 -0
- lib/CloudinaryExtension/Image.php +26 -8
- lib/CloudinaryExtension/Image/Synchronizable.php +2 -2
- lib/CloudinaryExtension/Migration/BatchUploader.php +41 -7
- lib/CloudinaryExtension/Migration/Logger.php +2 -0
- package.xml +8 -7
app/code/community/Cloudinary/Cloudinary/Block/Adminhtml/Manage.php
CHANGED
@@ -3,7 +3,6 @@
|
|
3 |
class Cloudinary_Cloudinary_Block_Adminhtml_Manage extends Mage_Adminhtml_Block_Widget_Grid_Container
|
4 |
{
|
5 |
private $_migrationTask;
|
6 |
-
|
7 |
private $_cloudinaryConfig;
|
8 |
|
9 |
public function __construct()
|
@@ -23,9 +22,20 @@ class Cloudinary_Cloudinary_Block_Adminhtml_Manage extends Mage_Adminhtml_Block_
|
|
23 |
parent::__construct();
|
24 |
}
|
25 |
|
|
|
|
|
|
|
|
|
|
|
26 |
public function getPercentComplete()
|
27 |
{
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
}
|
30 |
|
31 |
public function getSynchronizedImageCount()
|
@@ -35,11 +45,16 @@ class Cloudinary_Cloudinary_Block_Adminhtml_Manage extends Mage_Adminhtml_Block_
|
|
35 |
|
36 |
public function getTotalImageCount()
|
37 |
{
|
38 |
-
|
39 |
-
|
40 |
-
|
|
|
|
|
|
|
|
|
41 |
|
42 |
-
|
|
|
43 |
}
|
44 |
|
45 |
public function isExtensionEnabled()
|
@@ -49,7 +64,11 @@ class Cloudinary_Cloudinary_Block_Adminhtml_Manage extends Mage_Adminhtml_Block_
|
|
49 |
|
50 |
public function allImagesSynced()
|
51 |
{
|
52 |
-
|
|
|
|
|
|
|
|
|
53 |
}
|
54 |
|
55 |
public function getEnableButton()
|
@@ -78,6 +97,12 @@ class Cloudinary_Cloudinary_Block_Adminhtml_Manage extends Mage_Adminhtml_Block_
|
|
78 |
return $this->_makeButton($startLabel, $startAction, $this->allImagesSynced());
|
79 |
}
|
80 |
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
private function _makeButton($label, $action, $disabled = false)
|
82 |
{
|
83 |
$button = $this->getLayout()->createBlock('adminhtml/widget_button')
|
@@ -90,4 +115,11 @@ class Cloudinary_Cloudinary_Block_Adminhtml_Manage extends Mage_Adminhtml_Block_
|
|
90 |
|
91 |
return $button->toHtml();
|
92 |
}
|
93 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
class Cloudinary_Cloudinary_Block_Adminhtml_Manage extends Mage_Adminhtml_Block_Widget_Grid_Container
|
4 |
{
|
5 |
private $_migrationTask;
|
|
|
6 |
private $_cloudinaryConfig;
|
7 |
|
8 |
public function __construct()
|
22 |
parent::__construct();
|
23 |
}
|
24 |
|
25 |
+
public function isFolderedMigration()
|
26 |
+
{
|
27 |
+
return $this->_cloudinaryConfig->isFolderedMigration();
|
28 |
+
}
|
29 |
+
|
30 |
public function getPercentComplete()
|
31 |
{
|
32 |
+
try {
|
33 |
+
if ($this->getTotalImageCount() != 0) {
|
34 |
+
return $this->getSynchronizedImageCount() * 100 / $this->getTotalImageCount();
|
35 |
+
}
|
36 |
+
} catch (Exception $e) {
|
37 |
+
return 'Unknown';
|
38 |
+
}
|
39 |
}
|
40 |
|
41 |
public function getSynchronizedImageCount()
|
45 |
|
46 |
public function getTotalImageCount()
|
47 |
{
|
48 |
+
try {
|
49 |
+
$collectionCounter = Mage::getModel('cloudinary_cloudinary/collectionCounter')
|
50 |
+
->addCollection(Mage::getResourceModel('cloudinary_cloudinary/cms_synchronisation_collection'));
|
51 |
+
$result = $collectionCounter->count();
|
52 |
+
} catch (Exception $e) {
|
53 |
+
return 'Unknown';
|
54 |
+
}
|
55 |
|
56 |
+
$result += Mage::getResourceModel('cloudinary_cloudinary/media_collection')->uniqueImageCount();
|
57 |
+
return $result;
|
58 |
}
|
59 |
|
60 |
public function isExtensionEnabled()
|
64 |
|
65 |
public function allImagesSynced()
|
66 |
{
|
67 |
+
try {
|
68 |
+
return $this->getSynchronizedImageCount() === $this->getTotalImageCount();
|
69 |
+
} catch (Exception $e) {
|
70 |
+
return false;
|
71 |
+
}
|
72 |
}
|
73 |
|
74 |
public function getEnableButton()
|
97 |
return $this->_makeButton($startLabel, $startAction, $this->allImagesSynced());
|
98 |
}
|
99 |
|
100 |
+
public function getClearErrorsButton()
|
101 |
+
{
|
102 |
+
$areThereErrors = $this->getErrors();
|
103 |
+
return $this->_makeButton($areThereErrors ? 'Clear errors' : 'No errors to clear', 'clearErrors', !$areThereErrors);
|
104 |
+
}
|
105 |
+
|
106 |
private function _makeButton($label, $action, $disabled = false)
|
107 |
{
|
108 |
$button = $this->getLayout()->createBlock('adminhtml/widget_button')
|
115 |
|
116 |
return $button->toHtml();
|
117 |
}
|
118 |
+
|
119 |
+
public function getErrors()
|
120 |
+
{
|
121 |
+
$coll = Mage::getModel('cloudinary_cloudinary/migrationError')->getCollection();
|
122 |
+
$coll->addOrder('timestamp');
|
123 |
+
return $coll->getItems();
|
124 |
+
}
|
125 |
+
}
|
app/code/community/Cloudinary/Cloudinary/Helper/Configuration.php
CHANGED
@@ -24,12 +24,21 @@ class Cloudinary_Cloudinary_Helper_Configuration extends Mage_Core_Helper_Abstra
|
|
24 |
|
25 |
const CONFIG_CDN_SUBDOMAIN = 'cloudinary/configuration/cloudinary_cdn_subdomain';
|
26 |
|
|
|
|
|
27 |
const STATUS_ENABLED = 1;
|
28 |
|
29 |
const STATUS_DISABLED = 0;
|
30 |
|
31 |
const USER_PLATFORM_TEMPLATE = 'CloudinaryMagento/%s (Magento %s)';
|
32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
public function buildCredentials()
|
34 |
{
|
35 |
$environmentVariable = CloudinaryEnvironmentVariable::fromString($this->getEnvironmentVariable());
|
@@ -66,6 +75,29 @@ class Cloudinary_Cloudinary_Helper_Configuration extends Mage_Core_Helper_Abstra
|
|
66 |
return (boolean)Mage::getStoreConfig(self::CONFIG_CDN_SUBDOMAIN);
|
67 |
}
|
68 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
public function isEnabled()
|
70 |
{
|
71 |
return (boolean)Mage::getStoreConfig(self::CONFIG_PATH_ENABLED);
|
@@ -98,7 +130,7 @@ class Cloudinary_Cloudinary_Helper_Configuration extends Mage_Core_Helper_Abstra
|
|
98 |
|
99 |
$config->setUserPlatform($this->getUserPlatform());
|
100 |
|
101 |
-
if($this->getCdnSubdomainFlag()) {
|
102 |
$config->enableCdnSubdomain();
|
103 |
}
|
104 |
|
@@ -106,8 +138,7 @@ class Cloudinary_Cloudinary_Helper_Configuration extends Mage_Core_Helper_Abstra
|
|
106 |
->withGravity(Gravity::fromString($this->getDefaultGravity()))
|
107 |
->withFetchFormat(FetchFormat::fromString($this->getFetchFormat()))
|
108 |
->withQuality(Quality::fromString($this->getImageQuality()))
|
109 |
-
->withDpr(Dpr::fromString($this->getImageDpr()))
|
110 |
-
;
|
111 |
|
112 |
return $config;
|
113 |
}
|
@@ -118,4 +149,12 @@ class Cloudinary_Cloudinary_Helper_Configuration extends Mage_Core_Helper_Abstra
|
|
118 |
$config->saveConfig($configPath, $value)->reinit();
|
119 |
}
|
120 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
}
|
24 |
|
25 |
const CONFIG_CDN_SUBDOMAIN = 'cloudinary/configuration/cloudinary_cdn_subdomain';
|
26 |
|
27 |
+
const CONFIG_FOLDERED_MIGRATION = 'cloudinary/configuration/cloudinary_foldered_migration';
|
28 |
+
|
29 |
const STATUS_ENABLED = 1;
|
30 |
|
31 |
const STATUS_DISABLED = 0;
|
32 |
|
33 |
const USER_PLATFORM_TEMPLATE = 'CloudinaryMagento/%s (Magento %s)';
|
34 |
|
35 |
+
private $folderTranslator;
|
36 |
+
|
37 |
+
public function __construct()
|
38 |
+
{
|
39 |
+
$this->folderTranslator = Mage::getModel('cloudinary_cloudinary/magentoFolderTranslator');
|
40 |
+
}
|
41 |
+
|
42 |
public function buildCredentials()
|
43 |
{
|
44 |
$environmentVariable = CloudinaryEnvironmentVariable::fromString($this->getEnvironmentVariable());
|
75 |
return (boolean)Mage::getStoreConfig(self::CONFIG_CDN_SUBDOMAIN);
|
76 |
}
|
77 |
|
78 |
+
public function isFolderedMigration()
|
79 |
+
{
|
80 |
+
return Mage::getStoreConfigFlag(self::CONFIG_FOLDERED_MIGRATION);
|
81 |
+
}
|
82 |
+
|
83 |
+
public function getMigratedPath($file)
|
84 |
+
{
|
85 |
+
if ($this->isFolderedMigration()) {
|
86 |
+
$result = $this->folderTranslator->translate($file);
|
87 |
+
} else {
|
88 |
+
$result = basename($file);
|
89 |
+
}
|
90 |
+
return $result;
|
91 |
+
}
|
92 |
+
|
93 |
+
public function reverseMigratedPathIfNeeded($migratedPath)
|
94 |
+
{
|
95 |
+
if ($this->isFolderedMigration()) {
|
96 |
+
return $this->folderTranslator->reverse($migratedPath);
|
97 |
+
}
|
98 |
+
return $migratedPath;
|
99 |
+
}
|
100 |
+
|
101 |
public function isEnabled()
|
102 |
{
|
103 |
return (boolean)Mage::getStoreConfig(self::CONFIG_PATH_ENABLED);
|
130 |
|
131 |
$config->setUserPlatform($this->getUserPlatform());
|
132 |
|
133 |
+
if ($this->getCdnSubdomainFlag()) {
|
134 |
$config->enableCdnSubdomain();
|
135 |
}
|
136 |
|
138 |
->withGravity(Gravity::fromString($this->getDefaultGravity()))
|
139 |
->withFetchFormat(FetchFormat::fromString($this->getFetchFormat()))
|
140 |
->withQuality(Quality::fromString($this->getImageQuality()))
|
141 |
+
->withDpr(Dpr::fromString($this->getImageDpr()));
|
|
|
142 |
|
143 |
return $config;
|
144 |
}
|
149 |
$config->saveConfig($configPath, $value)->reinit();
|
150 |
}
|
151 |
|
152 |
+
/**
|
153 |
+
* @return Cloudinary_Cloudinary_Helper_Configuration
|
154 |
+
*/
|
155 |
+
public static function getInstance()
|
156 |
+
{
|
157 |
+
return Mage::helper('cloudinary_cloudinary/configuration');
|
158 |
+
}
|
159 |
+
|
160 |
}
|
app/code/community/Cloudinary/Cloudinary/Helper/Image.php
CHANGED
@@ -48,17 +48,25 @@ class Cloudinary_Cloudinary_Helper_Image extends Mage_Catalog_Helper_Image
|
|
48 |
|
49 |
public function __toString()
|
50 |
{
|
|
|
51 |
$imageFile = $this->_getRequestedImageFile();
|
52 |
|
53 |
if ($this->_imageShouldComeFromCloudinary($imageFile)) {
|
54 |
-
$image =
|
55 |
|
56 |
$transformation = $this->_configuration->getDefaultTransformation()
|
57 |
->withDimensions($this->_dimensions);
|
58 |
|
59 |
-
|
|
|
|
|
60 |
}
|
|
|
|
|
61 |
|
62 |
-
|
|
|
|
|
63 |
}
|
|
|
64 |
}
|
48 |
|
49 |
public function __toString()
|
50 |
{
|
51 |
+
$result = null;
|
52 |
$imageFile = $this->_getRequestedImageFile();
|
53 |
|
54 |
if ($this->_imageShouldComeFromCloudinary($imageFile)) {
|
55 |
+
$image = Cloudinary_Cloudinary_Helper_Image::newApiImage($imageFile);
|
56 |
|
57 |
$transformation = $this->_configuration->getDefaultTransformation()
|
58 |
->withDimensions($this->_dimensions);
|
59 |
|
60 |
+
$result = (string)$this->_imageProvider->transformImage($image, $transformation);
|
61 |
+
} else {
|
62 |
+
$result = parent::__toString();
|
63 |
}
|
64 |
+
return $result;
|
65 |
+
}
|
66 |
|
67 |
+
public static function newApiImage($path){
|
68 |
+
$migratedPath = Cloudinary_Cloudinary_Helper_Configuration::getInstance()->getMigratedPath($path);
|
69 |
+
return Image::fromPath($path, $migratedPath);
|
70 |
}
|
71 |
+
|
72 |
}
|
app/code/community/Cloudinary/Cloudinary/Helper/Util/ArrayUtils.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Cloudinary_Cloudinary_Helper_Util_ArrayUtils
|
4 |
+
{
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Results with a subset of an associative array, preserving only the values that have a key that is present in $keys
|
8 |
+
*
|
9 |
+
* @param $array the original array we want to select from
|
10 |
+
* @param $keys the keys to preserve in the input array
|
11 |
+
* @return array
|
12 |
+
*/
|
13 |
+
public static function arraySelect($array, $keys)
|
14 |
+
{
|
15 |
+
$result = [];
|
16 |
+
foreach ($keys as $key) {
|
17 |
+
$result[$key] = $array[$key];
|
18 |
+
}
|
19 |
+
return $result;
|
20 |
+
}
|
21 |
+
}
|
22 |
+
|
app/code/community/Cloudinary/Cloudinary/Model/Catalog/Product/Image.php
CHANGED
@@ -9,13 +9,15 @@ class Cloudinary_Cloudinary_Model_Catalog_Product_Image extends Mage_Catalog_Mod
|
|
9 |
|
10 |
public function getUrl()
|
11 |
{
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
|
|
|
|
17 |
}
|
18 |
-
|
19 |
-
return
|
20 |
}
|
21 |
-
}
|
9 |
|
10 |
public function getUrl()
|
11 |
{
|
12 |
+
$config = $this->_getConfigHelper();
|
13 |
+
$file = $this->_newFile;
|
14 |
+
if ($this->_imageShouldComeFromCloudinary($file)) {
|
15 |
+
$imageProvider = CloudinaryImageProvider::fromConfiguration($config->buildConfiguration());
|
16 |
+
$result = (string)$imageProvider->transformImage(Cloudinary_Cloudinary_Helper_Image::newApiImage($file));
|
17 |
+
} else {
|
18 |
+
$result = parent::getUrl();
|
19 |
}
|
20 |
+
Cloudinary_Cloudinary_Model_Logger::getInstance()->debugLog($result);
|
21 |
+
return $result;
|
22 |
}
|
23 |
+
}
|
app/code/community/Cloudinary/Cloudinary/Model/Catalog/Product/Media.php
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
class Cloudinary_Cloudinary_Model_Catalog_Product_Media extends Mage_Core_Model_Abstract
|
4 |
{
|
5 |
|
@@ -41,7 +41,11 @@ class Cloudinary_Cloudinary_Model_Catalog_Product_Media extends Mage_Core_Model_
|
|
41 |
|
42 |
private function _getRemovedImages(array $mediaGallery)
|
43 |
{
|
44 |
-
|
|
|
|
|
|
|
|
|
45 |
}
|
46 |
|
47 |
private function _isImageRemoved($toFilter)
|
1 |
<?php
|
2 |
+
|
3 |
class Cloudinary_Cloudinary_Model_Catalog_Product_Media extends Mage_Core_Model_Abstract
|
4 |
{
|
5 |
|
41 |
|
42 |
private function _getRemovedImages(array $mediaGallery)
|
43 |
{
|
44 |
+
if (!is_array($mediaGallery['images'])) {
|
45 |
+
$mediaGallery['images'] = json_decode($mediaGallery['images'], true);
|
46 |
+
}
|
47 |
+
|
48 |
+
return array_filter($mediaGallery['images'], array($this, '_isImageRemoved'));
|
49 |
}
|
50 |
|
51 |
private function _isImageRemoved($toFilter)
|
app/code/community/Cloudinary/Cloudinary/Model/Catalog/Product/Media/Config.php
CHANGED
@@ -28,8 +28,9 @@ class Cloudinary_Cloudinary_Model_Catalog_Product_Media_Config extends Mage_Cata
|
|
28 |
|
29 |
private function _getUrlForImage($file)
|
30 |
{
|
31 |
-
$
|
|
|
32 |
|
33 |
-
return (string)$imageProvider->transformImage(
|
34 |
}
|
35 |
}
|
28 |
|
29 |
private function _getUrlForImage($file)
|
30 |
{
|
31 |
+
$config = Cloudinary_Cloudinary_Helper_Configuration::getInstance();
|
32 |
+
$imageProvider = CloudinaryImageProvider::fromConfiguration($config->buildConfiguration());
|
33 |
|
34 |
+
return (string)$imageProvider->transformImage(Cloudinary_Cloudinary_Helper_Image::newApiImage($file));
|
35 |
}
|
36 |
}
|
app/code/community/Cloudinary/Cloudinary/Model/Cms/Synchronisation.php
CHANGED
@@ -18,17 +18,21 @@ class Cloudinary_Cloudinary_Model_Cms_Synchronisation extends Mage_Core_Model_Ab
|
|
18 |
public function setValue($fileName)
|
19 |
{
|
20 |
$this->setData('basename', basename($fileName));
|
21 |
-
|
22 |
return $this;
|
23 |
}
|
24 |
|
|
|
|
|
|
|
|
|
|
|
25 |
public function tagAsSynchronized()
|
26 |
{
|
27 |
-
$this->setData('image_name', $this->getData('basename'));
|
28 |
$this->setData('media_gallery_id', null);
|
29 |
$this->setData('cloudinary_synchronisation_id', null);
|
30 |
-
|
|
|
31 |
$this->save();
|
32 |
}
|
33 |
|
34 |
-
}
|
18 |
public function setValue($fileName)
|
19 |
{
|
20 |
$this->setData('basename', basename($fileName));
|
|
|
21 |
return $this;
|
22 |
}
|
23 |
|
24 |
+
public function getRelativePath(){
|
25 |
+
$helperConfig = Mage::helper('cloudinary_cloudinary/configuration');
|
26 |
+
return $helperConfig->getMigratedPath($this->getFilename());
|
27 |
+
}
|
28 |
+
|
29 |
public function tagAsSynchronized()
|
30 |
{
|
|
|
31 |
$this->setData('media_gallery_id', null);
|
32 |
$this->setData('cloudinary_synchronisation_id', null);
|
33 |
+
$this->setData('image_name', $this->getRelativePath());
|
34 |
+
Cloudinary_Cloudinary_Model_Logger::getInstance()->debugLog( json_encode($this->toArray(), JSON_PRETTY_PRINT));
|
35 |
$this->save();
|
36 |
}
|
37 |
|
38 |
+
}
|
app/code/community/Cloudinary/Cloudinary/Model/{MediaCollectionCounter.php → CollectionCounter.php}
RENAMED
@@ -1,9 +1,8 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class
|
4 |
{
|
5 |
-
|
6 |
-
private $_collections = array();
|
7 |
|
8 |
public function addCollection(Varien_Data_Collection $collection)
|
9 |
{
|
@@ -14,11 +13,10 @@ class Cloudinary_Cloudinary_Model_MediaCollectionCounter implements Countable
|
|
14 |
|
15 |
public function count()
|
16 |
{
|
17 |
-
$
|
18 |
foreach ($this->_collections as $collection) {
|
19 |
-
$
|
20 |
}
|
21 |
-
return $
|
22 |
}
|
23 |
-
|
24 |
}
|
1 |
<?php
|
2 |
|
3 |
+
class Cloudinary_Cloudinary_Model_CollectionCounter implements Countable
|
4 |
{
|
5 |
+
private $_collections = [];
|
|
|
6 |
|
7 |
public function addCollection(Varien_Data_Collection $collection)
|
8 |
{
|
13 |
|
14 |
public function count()
|
15 |
{
|
16 |
+
$count = 0;
|
17 |
foreach ($this->_collections as $collection) {
|
18 |
+
$count += $collection->getSize();
|
19 |
}
|
20 |
+
return $count;
|
21 |
}
|
|
|
22 |
}
|
app/code/community/Cloudinary/Cloudinary/Model/Cron.php
CHANGED
@@ -38,6 +38,10 @@ class Cloudinary_Cloudinary_Model_Cron extends Mage_Core_Model_Abstract
|
|
38 |
|
39 |
$migrationQueue->process();
|
40 |
|
|
|
|
|
|
|
|
|
41 |
return $this;
|
42 |
}
|
43 |
}
|
38 |
|
39 |
$migrationQueue->process();
|
40 |
|
41 |
+
foreach ($batchUploader->getMigrationErrors() as $error) {
|
42 |
+
Cloudinary_Cloudinary_Model_MigrationError::saveFromException($error);
|
43 |
+
}
|
44 |
+
|
45 |
return $this;
|
46 |
}
|
47 |
}
|
app/code/community/Cloudinary/Cloudinary/Model/Image.php
CHANGED
@@ -8,10 +8,16 @@ class Cloudinary_Cloudinary_Model_Image extends Mage_Core_Model_Abstract
|
|
8 |
{
|
9 |
use Cloudinary_Cloudinary_Model_PreConditionsValidator;
|
10 |
|
|
|
|
|
11 |
public function upload(array $imageDetails)
|
12 |
{
|
|
|
|
|
|
|
|
|
13 |
$imageManager = $this->_getImageProvider();
|
14 |
-
$imageManager->upload(Image::fromPath($this->_imageFullPathFromImageDetails($imageDetails)));
|
15 |
|
16 |
Mage::getModel('cloudinary_cloudinary/synchronisation')
|
17 |
->setValueId($imageDetails['value_id'])
|
@@ -39,13 +45,14 @@ class Cloudinary_Cloudinary_Model_Image extends Mage_Core_Model_Abstract
|
|
39 |
|
40 |
public function deleteImage($imageName)
|
41 |
{
|
42 |
-
$this->_getImageProvider()->deleteImage(
|
43 |
}
|
44 |
|
45 |
public function getUrl($imagePath)
|
46 |
{
|
47 |
$imageProvider = $this->_getImageProvider();
|
48 |
-
|
|
|
49 |
}
|
50 |
|
51 |
private function _getImageProvider()
|
8 |
{
|
9 |
use Cloudinary_Cloudinary_Model_PreConditionsValidator;
|
10 |
|
11 |
+
private $_folder;
|
12 |
+
|
13 |
public function upload(array $imageDetails)
|
14 |
{
|
15 |
+
if ($this->_getConfigHelper()->isFolderedMigration()) {
|
16 |
+
$this->_folder = $this->_getConfigHelper()->getMigratedPath($imageDetails['file']);
|
17 |
+
}
|
18 |
+
|
19 |
$imageManager = $this->_getImageProvider();
|
20 |
+
$imageManager->upload(Image::fromPath($this->_imageFullPathFromImageDetails($imageDetails), $this->_folder));
|
21 |
|
22 |
Mage::getModel('cloudinary_cloudinary/synchronisation')
|
23 |
->setValueId($imageDetails['value_id'])
|
45 |
|
46 |
public function deleteImage($imageName)
|
47 |
{
|
48 |
+
$this->_getImageProvider()->deleteImage(Cloudinary_Cloudinary_Helper_Image::newApiImage($imageName));
|
49 |
}
|
50 |
|
51 |
public function getUrl($imagePath)
|
52 |
{
|
53 |
$imageProvider = $this->_getImageProvider();
|
54 |
+
|
55 |
+
return (string)$imageProvider->transformImage(Cloudinary_Cloudinary_Helper_Image::newApiImage($imagePath));
|
56 |
}
|
57 |
|
58 |
private function _getImageProvider()
|
app/code/community/Cloudinary/Cloudinary/Model/Logger.php
CHANGED
@@ -2,6 +2,8 @@
|
|
2 |
|
3 |
class Cloudinary_Cloudinary_Model_Logger extends Mage_Core_Model_Abstract implements \CloudinaryExtension\Migration\Logger
|
4 |
{
|
|
|
|
|
5 |
public function warning($message, array $context = array())
|
6 |
{
|
7 |
Mage::log($message, Zend_Log::WARN);
|
@@ -16,4 +18,31 @@ class Cloudinary_Cloudinary_Model_Logger extends Mage_Core_Model_Abstract implem
|
|
16 |
{
|
17 |
Mage::log($message, Zend_Log::ERR);
|
18 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
}
|
2 |
|
3 |
class Cloudinary_Cloudinary_Model_Logger extends Mage_Core_Model_Abstract implements \CloudinaryExtension\Migration\Logger
|
4 |
{
|
5 |
+
const SIGNATURE_TEMPLATE = "%s::%s ";
|
6 |
+
|
7 |
public function warning($message, array $context = array())
|
8 |
{
|
9 |
Mage::log($message, Zend_Log::WARN);
|
18 |
{
|
19 |
Mage::log($message, Zend_Log::ERR);
|
20 |
}
|
21 |
+
|
22 |
+
public function debugLog($message)
|
23 |
+
{
|
24 |
+
if (Mage::getIsDeveloperMode()){
|
25 |
+
Mage::log($this->getSignature() . $message . "\n", 1, debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['class']);
|
26 |
+
}
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Add extra information to a log entry: class and funcion name from which the log is called
|
31 |
+
* @param $message
|
32 |
+
* @return string
|
33 |
+
*/
|
34 |
+
public static function getSignature()
|
35 |
+
{
|
36 |
+
$parentTrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3)[2];
|
37 |
+
$logSignature = sprintf(self::SIGNATURE_TEMPLATE, $parentTrace['class'], $parentTrace['function']);
|
38 |
+
return $logSignature;
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @return Cloudinary_Cloudinary_Model_Logger
|
43 |
+
*/
|
44 |
+
public static function getInstance()
|
45 |
+
{
|
46 |
+
return Mage::getModel('cloudinary_cloudinary/logger');
|
47 |
+
}
|
48 |
}
|
app/code/community/Cloudinary/Cloudinary/Model/MagentoFolderTranslator.php
ADDED
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Cloudinary_Cloudinary_Model_MagentoFolderTranslator implements \CloudinaryExtension\FolderTranslator
|
4 |
+
{
|
5 |
+
private $absolutePathRegex;
|
6 |
+
private $wysiwygPathRegex;
|
7 |
+
private $productPathRegex;
|
8 |
+
private $mediaDir;
|
9 |
+
|
10 |
+
public function __construct()
|
11 |
+
{
|
12 |
+
$baseDir = Mage::getBaseDir();
|
13 |
+
$mediaDir = $this->mediaDir = $this->removeMagentoBaseDir(Mage::getBaseDir('media'));
|
14 |
+
$this->absolutePathRegex = "#^$baseDir/.*#"; //anything starting with the magento base dir
|
15 |
+
$this->mediaPathRegex = "#^$mediaDir/.*#"; //anything starting with the media folder
|
16 |
+
$this->wysiwygPathRegex = "#^/wysiwyg/.*#"; // anything starting with the /wysiwyg folder
|
17 |
+
$this->productPathRegex = "#(^/cache/.*|^/(\\w/){2})#"; // any path that has '/cache/' prefix, or '/l/l/' structure, where l is a single letter
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* The method tries to find out the absolute path of the input, and remove the magento base directory from it (this method is typically called via a product image path, a wysiwyg path, or an absolute path)
|
22 |
+
*
|
23 |
+
* @param $path
|
24 |
+
* @return mixed the input, truncated from the magento base directory
|
25 |
+
*/
|
26 |
+
public function translate($path)
|
27 |
+
{
|
28 |
+
$baseName = basename($path);
|
29 |
+
$result = $this->unifiedDirName($path);
|
30 |
+
$debug = $result;
|
31 |
+
|
32 |
+
$baseDir = Mage::getBaseDir();
|
33 |
+
|
34 |
+
if (preg_match($this->absolutePathRegex, $result)) {
|
35 |
+
// the input is absolute, we truncate the magento base dir to get the relative path
|
36 |
+
$result = preg_replace("#^$baseDir#", '', $result);
|
37 |
+
|
38 |
+
} else if (preg_match($this->productPathRegex, $result)) {
|
39 |
+
/* the input appears to be a product image, we insert the path to product images relative to magento base dir
|
40 |
+
* (by default /media/catalog/product/ ) */
|
41 |
+
$catalogMediapath = Mage::getSingleton('catalog/product_media_config')->getBaseMediaPath();
|
42 |
+
$result = $this->removeMagentoBaseDir($catalogMediapath) . $result;
|
43 |
+
|
44 |
+
} else if (preg_match($this->mediaPathRegex, $result)) {
|
45 |
+
// the input appears to be relative to the magento base dir
|
46 |
+
// NOP, the result should be the input
|
47 |
+
|
48 |
+
} else {
|
49 |
+
// we just assume the input is relative to the media library, in which case the relative path is "/media/$path" (in defualt case)
|
50 |
+
$result = $this->mediaDir . $result;
|
51 |
+
}
|
52 |
+
$result .= $baseName;
|
53 |
+
Cloudinary_Cloudinary_Model_Logger::getInstance()->debugLog("$path => $debug => $result");
|
54 |
+
return $result;
|
55 |
+
}
|
56 |
+
|
57 |
+
public function reverse($path)
|
58 |
+
{
|
59 |
+
return str_replace(DS . DS, DS, Mage::getBaseDir() . DS . $path);
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Appends DS the the start of the path, and removes duplicate DS-es
|
64 |
+
*
|
65 |
+
* @param $path
|
66 |
+
* @return mixed
|
67 |
+
*/
|
68 |
+
private static function unifiedDirName($path)
|
69 |
+
{
|
70 |
+
return str_replace(DS . DS, DS, DS . dirname($path) . DS);
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* @param $path an absolute path pointing somewhere inside magento folder structure
|
75 |
+
* @return mixed the path relative to the magento base directory
|
76 |
+
*/
|
77 |
+
private static function removeMagentoBaseDir($path)
|
78 |
+
{
|
79 |
+
return str_replace(Mage::getBaseDir(), '', $path);
|
80 |
+
}
|
81 |
+
}
|
app/code/community/Cloudinary/Cloudinary/Model/MigrationError.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
class Cloudinary_Cloudinary_Model_MigrationError extends Mage_Core_Model_Abstract
|
5 |
+
{
|
6 |
+
public function __construct()
|
7 |
+
{
|
8 |
+
$this->_init('cloudinary_cloudinary/migrationError');
|
9 |
+
}
|
10 |
+
|
11 |
+
public static function saveFromException(\CloudinaryExtension\Exception\MigrationError $e)
|
12 |
+
{
|
13 |
+
$image = $e->getImage();
|
14 |
+
$filePath = (string)$image;
|
15 |
+
|
16 |
+
$entry = Mage::getModel('cloudinary_cloudinary/migrationError');
|
17 |
+
$entry->setFilePath($filePath);
|
18 |
+
|
19 |
+
$entry->setRelativePath($image->getRelativePath());
|
20 |
+
$entry->setMessage($e->getMessage());
|
21 |
+
$entry->setCode($e->getCode());
|
22 |
+
$entry->setTimestamp(time());
|
23 |
+
|
24 |
+
$entry->save();
|
25 |
+
}
|
26 |
+
}
|
app/code/community/Cloudinary/Cloudinary/Model/PreConditionsValidator.php
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
<?php
|
|
|
2 |
trait Cloudinary_Cloudinary_Model_PreConditionsValidator
|
3 |
{
|
4 |
private function _isEnabled()
|
@@ -11,6 +12,9 @@ trait Cloudinary_Cloudinary_Model_PreConditionsValidator
|
|
11 |
return Mage::getModel('cloudinary_cloudinary/synchronisation')->isImageInCloudinary($imageName);
|
12 |
}
|
13 |
|
|
|
|
|
|
|
14 |
private function _getConfigHelper()
|
15 |
{
|
16 |
return Mage::helper('cloudinary_cloudinary/configuration');
|
@@ -18,7 +22,8 @@ trait Cloudinary_Cloudinary_Model_PreConditionsValidator
|
|
18 |
|
19 |
private function _imageShouldComeFromCloudinary($file)
|
20 |
{
|
21 |
-
|
|
|
|
|
22 |
}
|
23 |
}
|
24 |
-
|
1 |
<?php
|
2 |
+
|
3 |
trait Cloudinary_Cloudinary_Model_PreConditionsValidator
|
4 |
{
|
5 |
private function _isEnabled()
|
12 |
return Mage::getModel('cloudinary_cloudinary/synchronisation')->isImageInCloudinary($imageName);
|
13 |
}
|
14 |
|
15 |
+
/**
|
16 |
+
* @return Cloudinary_Cloudinary_Helper_Configuration
|
17 |
+
*/
|
18 |
private function _getConfigHelper()
|
19 |
{
|
20 |
return Mage::helper('cloudinary_cloudinary/configuration');
|
22 |
|
23 |
private function _imageShouldComeFromCloudinary($file)
|
24 |
{
|
25 |
+
$relativePath = $this->_getConfigHelper()->getMigratedPath($file);
|
26 |
+
$result = $this->_isEnabled() && $this->_isImageInCloudinary($relativePath);
|
27 |
+
return $result;
|
28 |
}
|
29 |
}
|
|
app/code/community/Cloudinary/Cloudinary/Model/Resource/Cms/Synchronisation/Collection.php
CHANGED
@@ -6,37 +6,70 @@ class Cloudinary_Cloudinary_Model_Resource_Cms_Synchronisation_Collection
|
|
6 |
extends Mage_Cms_Model_Wysiwyg_Images_Storage_Collection
|
7 |
implements SynchronizedMediaRepository
|
8 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
public function __construct()
|
11 |
{
|
12 |
$this->addTargetDir(Mage::helper('cms/wysiwyg_images')->getStorageRoot());
|
13 |
$this->setItemObjectClass('cloudinary_cloudinary/cms_synchronisation');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
}
|
15 |
|
16 |
public function findUnsynchronisedImages()
|
17 |
{
|
18 |
-
$
|
|
|
|
|
|
|
|
|
|
|
19 |
|
|
|
20 |
return $this->getItems();
|
21 |
}
|
22 |
|
23 |
private function _getSynchronisedImageNames()
|
24 |
{
|
25 |
-
|
26 |
-
|
27 |
-
|
|
|
|
|
28 |
},
|
29 |
$this->_getSynchronisedImageData()
|
30 |
);
|
|
|
|
|
31 |
}
|
32 |
|
33 |
private function _getSynchronisedImageData()
|
34 |
{
|
35 |
-
|
36 |
->addFieldToSelect('image_name')
|
37 |
->addFieldToFilter('media_gallery_id', array('null' => true))
|
38 |
-
->distinct(true)
|
39 |
->getData();
|
|
|
40 |
}
|
41 |
|
42 |
-
}
|
6 |
extends Mage_Cms_Model_Wysiwyg_Images_Storage_Collection
|
7 |
implements SynchronizedMediaRepository
|
8 |
{
|
9 |
+
/**
|
10 |
+
* @var string[]
|
11 |
+
* @link http://cloudinary.com/documentation/image_transformations#format_conversion
|
12 |
+
* @link http://cloudinary.com/documentation/upload_images
|
13 |
+
*/
|
14 |
+
private $allowedImgExtensions = ['JPG', 'PNG', 'GIF', 'BMP', 'TIFF', 'EPS', 'PSD', 'SVG', 'WebP'];
|
15 |
|
16 |
public function __construct()
|
17 |
{
|
18 |
$this->addTargetDir(Mage::helper('cms/wysiwyg_images')->getStorageRoot());
|
19 |
$this->setItemObjectClass('cloudinary_cloudinary/cms_synchronisation');
|
20 |
+
$this->setFilesFilter(
|
21 |
+
sprintf('#^[a-z0-9\.\-\_]+\.(?:%s)$#i', implode('|', $this->allowedImgExtensions))
|
22 |
+
);
|
23 |
+
}
|
24 |
+
|
25 |
+
public function addTargetDir($value)
|
26 |
+
{
|
27 |
+
try {
|
28 |
+
parent::addTargetDir($value);
|
29 |
+
} catch (Exception $e) {
|
30 |
+
Mage::logException($e);
|
31 |
+
if (!Mage::registry('error_' . $value)) {
|
32 |
+
Mage::getSingleton('core/session')->addError("Couldn't find path " . $value);
|
33 |
+
Mage::register('error_' . $value, true);
|
34 |
+
}
|
35 |
+
throw $e;
|
36 |
+
}
|
37 |
}
|
38 |
|
39 |
public function findUnsynchronisedImages()
|
40 |
{
|
41 |
+
$helperConfig = Mage::helper('cloudinary_cloudinary/configuration');
|
42 |
+
if ($helperConfig->isFolderedMigration()){
|
43 |
+
$this->addFieldToFilter('filename', array('nin' => $this->_getSynchronisedImageNames()));
|
44 |
+
} else {
|
45 |
+
$this->addFieldToFilter('basename', array('nin' => $this->_getSynchronisedImageNames()));
|
46 |
+
}
|
47 |
|
48 |
+
Cloudinary_Cloudinary_Model_Logger::getInstance()->debugLog(json_encode($this->toArray(), JSON_PRETTY_PRINT));
|
49 |
return $this->getItems();
|
50 |
}
|
51 |
|
52 |
private function _getSynchronisedImageNames()
|
53 |
{
|
54 |
+
$helperConfig = Cloudinary_Cloudinary_Helper_Configuration::getInstance();
|
55 |
+
$result = array_map(
|
56 |
+
function ($itemData) use ($helperConfig) {
|
57 |
+
$imageName = $itemData['image_name'];
|
58 |
+
return $helperConfig->reverseMigratedPathIfNeeded($imageName);
|
59 |
},
|
60 |
$this->_getSynchronisedImageData()
|
61 |
);
|
62 |
+
Cloudinary_Cloudinary_Model_Logger::getInstance()->debugLog(print_r($result, true));
|
63 |
+
return $result;
|
64 |
}
|
65 |
|
66 |
private function _getSynchronisedImageData()
|
67 |
{
|
68 |
+
$result = Mage::getResourceModel('cloudinary_cloudinary/synchronisation_collection')
|
69 |
->addFieldToSelect('image_name')
|
70 |
->addFieldToFilter('media_gallery_id', array('null' => true))
|
|
|
71 |
->getData();
|
72 |
+
return $result;
|
73 |
}
|
74 |
|
75 |
+
}
|
app/code/community/Cloudinary/Cloudinary/Model/Resource/Media/Collection.php
CHANGED
@@ -7,4 +7,12 @@ class Cloudinary_Cloudinary_Model_Resource_Media_Collection extends Mage_Core_Mo
|
|
7 |
{
|
8 |
$this->_init('catalog/product_attribute_backend_media');
|
9 |
}
|
10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
{
|
8 |
$this->_init('catalog/product_attribute_backend_media');
|
9 |
}
|
10 |
+
|
11 |
+
public function uniqueImageCount()
|
12 |
+
{
|
13 |
+
$table = $this->getMainTable();
|
14 |
+
$query = "select count(distinct value) from $table";
|
15 |
+
|
16 |
+
return $this->getConnection()->query($query)->fetchColumn();
|
17 |
+
}
|
18 |
+
}
|
app/code/community/Cloudinary/Cloudinary/Model/Resource/MigrationError.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Cloudinary_Cloudinary_Model_Resource_MigrationError extends Mage_Core_Model_Resource_Db_Abstract
|
4 |
+
{
|
5 |
+
protected function _construct()
|
6 |
+
{
|
7 |
+
$this->_init('cloudinary_cloudinary/migrationError', 'file_path');
|
8 |
+
$this->_isPkAutoIncrement = false;
|
9 |
+
}
|
10 |
+
}
|
app/code/community/Cloudinary/Cloudinary/Model/Resource/MigrationError/Collection.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Cloudinary_Cloudinary_Model_Resource_MigrationError_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
|
4 |
+
{
|
5 |
+
|
6 |
+
protected function _construct()
|
7 |
+
{
|
8 |
+
$this->_init('cloudinary_cloudinary/migrationError');
|
9 |
+
}
|
10 |
+
}
|
app/code/community/Cloudinary/Cloudinary/Model/Resource/Synchronisation/Collection.php
CHANGED
@@ -31,16 +31,34 @@ class Cloudinary_Cloudinary_Model_Resource_Synchronisation_Collection
|
|
31 |
return $resource->getMainTable();
|
32 |
}
|
33 |
|
34 |
-
public function findUnsynchronisedImages($limit=
|
35 |
{
|
36 |
$tableName = Mage::getSingleton('core/resource')->getTableName('cloudinary_cloudinary/catalog_media_gallery');
|
|
|
37 |
|
38 |
-
$this->getSelect()
|
39 |
-
->joinRight($tableName, 'value_id=media_gallery_id', '*')
|
40 |
-
->where('cloudinary_synchronisation_id is null')
|
41 |
-
->limit($limit)
|
42 |
-
;
|
43 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
return $this->getItems();
|
45 |
}
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
return $resource->getMainTable();
|
32 |
}
|
33 |
|
34 |
+
public function findUnsynchronisedImages($limit = 100)
|
35 |
{
|
36 |
$tableName = Mage::getSingleton('core/resource')->getTableName('cloudinary_cloudinary/catalog_media_gallery');
|
37 |
+
$syncedImagesQuery = $this->getQueryForSyncedImageNames();
|
38 |
|
39 |
+
$select = $this->getSelect();
|
|
|
|
|
|
|
|
|
40 |
|
41 |
+
$select
|
42 |
+
->joinRight($tableName, 'value_id=media_gallery_id', '*')
|
43 |
+
->group('value')
|
44 |
+
->order('value')
|
45 |
+
->where("cloudinary_synchronisation_id is null and value not in ($syncedImagesQuery)")
|
46 |
+
->limit($limit);
|
47 |
+
|
48 |
+
Cloudinary_Cloudinary_Model_Logger::getInstance()->debugLog(print_r($this->toArray(), true));
|
49 |
return $this->getItems();
|
50 |
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* basically returns with all product image's media_gallery stored name which has been synced
|
54 |
+
*
|
55 |
+
* @return Varien_Db_Select
|
56 |
+
*/
|
57 |
+
private function getQueryForSyncedImageNames()
|
58 |
+
{
|
59 |
+
$select = clone $this->getSelect();
|
60 |
+
$select->reset(Zend_Db_Select::COLUMNS);
|
61 |
+
$select->where('media_gallery_value is not null');
|
62 |
+
return $select->columns('media_gallery_value');
|
63 |
+
}
|
64 |
+
}
|
app/code/community/Cloudinary/Cloudinary/Model/Synchronisation.php
CHANGED
@@ -12,17 +12,21 @@ class Cloudinary_Cloudinary_Model_Synchronisation extends Mage_Core_Model_Abstra
|
|
12 |
|
13 |
public function tagAsSynchronized()
|
14 |
{
|
15 |
-
$this->setData('image_name',
|
16 |
$this->setData('media_gallery_id', $this['value_id']);
|
|
|
17 |
$this->unsetData('value_id');
|
18 |
-
|
19 |
$this->save();
|
20 |
}
|
21 |
|
22 |
public function isImageInCloudinary($imageName)
|
23 |
{
|
24 |
-
$this->
|
25 |
-
|
|
|
|
|
|
|
26 |
}
|
27 |
|
28 |
public function getFilename()
|
@@ -33,8 +37,15 @@ class Cloudinary_Cloudinary_Model_Synchronisation extends Mage_Core_Model_Abstra
|
|
33 |
return $this->_baseMediaPath() . $this->getValue();
|
34 |
}
|
35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
private function _baseMediaPath()
|
37 |
{
|
38 |
return Mage::getModel('catalog/product_media_config')->getBaseMediaPath();
|
39 |
}
|
40 |
-
}
|
12 |
|
13 |
public function tagAsSynchronized()
|
14 |
{
|
15 |
+
$this->setData('image_name', $this->getRelativePath());
|
16 |
$this->setData('media_gallery_id', $this['value_id']);
|
17 |
+
$this->setData('media_gallery_value', $this['value']);
|
18 |
$this->unsetData('value_id');
|
19 |
+
Cloudinary_Cloudinary_Model_Logger::getInstance()->debugLog( json_encode($this->toArray(), JSON_PRETTY_PRINT));
|
20 |
$this->save();
|
21 |
}
|
22 |
|
23 |
public function isImageInCloudinary($imageName)
|
24 |
{
|
25 |
+
$coll = $this->getCollection();
|
26 |
+
$table = $coll->getMainTable();
|
27 |
+
// case sensitive check
|
28 |
+
$query = "select count(*) from $table where binary image_name = '$imageName' limit 1";
|
29 |
+
return $coll->getConnection()->query($query)->fetchColumn() > 0;
|
30 |
}
|
31 |
|
32 |
public function getFilename()
|
37 |
return $this->_baseMediaPath() . $this->getValue();
|
38 |
}
|
39 |
|
40 |
+
|
41 |
+
public function getRelativePath()
|
42 |
+
{
|
43 |
+
$helperConfig = Mage::helper('cloudinary_cloudinary/configuration');
|
44 |
+
return $helperConfig->getMigratedPath($this->getFilename());
|
45 |
+
}
|
46 |
+
|
47 |
private function _baseMediaPath()
|
48 |
{
|
49 |
return Mage::getModel('catalog/product_media_config')->getBaseMediaPath();
|
50 |
}
|
51 |
+
}
|
app/code/community/Cloudinary/Cloudinary/Model/SynchronisedMediaUnifier.php
CHANGED
@@ -24,4 +24,4 @@ class Cloudinary_Cloudinary_Model_SynchronisedMediaUnifier implements Synchroniz
|
|
24 |
return array_slice($this->_unsychronisedImages, 0, $limit);
|
25 |
}
|
26 |
|
27 |
-
}
|
24 |
return array_slice($this->_unsychronisedImages, 0, $limit);
|
25 |
}
|
26 |
|
27 |
+
}
|
app/code/community/Cloudinary/Cloudinary/controllers/Adminhtml/CloudinaryController.php
CHANGED
@@ -53,6 +53,17 @@ class Cloudinary_Cloudinary_Adminhtml_CloudinaryController extends Mage_Adminhtm
|
|
53 |
$this->_redirectToManageCloudinary();
|
54 |
}
|
55 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
private function _redirectToManageCloudinary()
|
57 |
{
|
58 |
return $this->_redirect('*/cloudinary');
|
@@ -63,4 +74,4 @@ class Cloudinary_Cloudinary_Adminhtml_CloudinaryController extends Mage_Adminhtm
|
|
63 |
return $this->getLayout()->createBlock('core/text')->setText('<meta http-equiv="refresh" content="5">');
|
64 |
}
|
65 |
|
66 |
-
}
|
53 |
$this->_redirectToManageCloudinary();
|
54 |
}
|
55 |
|
56 |
+
public function clearErrorsAction()
|
57 |
+
{
|
58 |
+
$items = Mage::getModel('cloudinary_cloudinary/migrationError')->getCollection()->getItems();
|
59 |
+
|
60 |
+
foreach ($items as $error){
|
61 |
+
$error->delete();
|
62 |
+
}
|
63 |
+
|
64 |
+
$this->_redirectToManageCloudinary();
|
65 |
+
}
|
66 |
+
|
67 |
private function _redirectToManageCloudinary()
|
68 |
{
|
69 |
return $this->_redirect('*/cloudinary');
|
74 |
return $this->getLayout()->createBlock('core/text')->setText('<meta http-equiv="refresh" content="5">');
|
75 |
}
|
76 |
|
77 |
+
}
|
app/code/community/Cloudinary/Cloudinary/data/cloudinary_setup/data-upgrade-1.1.2-1.1.3.php
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$config = new Mage_Core_Model_Config();
|
3 |
+
$config->saveConfig('cloudinary/cloud/cloudinary_foldered_migration', '0', 'default', 0);
|
app/code/community/Cloudinary/Cloudinary/etc/config.xml
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
<config>
|
3 |
<modules>
|
4 |
<Cloudinary_Cloudinary>
|
5 |
-
<version>1.1.
|
6 |
</Cloudinary_Cloudinary>
|
7 |
</modules>
|
8 |
<global>
|
@@ -44,6 +44,9 @@
|
|
44 |
<catalog_media_gallery>
|
45 |
<table>catalog_product_entity_media_gallery</table>
|
46 |
</catalog_media_gallery>
|
|
|
|
|
|
|
47 |
</entities>
|
48 |
</cloudinary_resource>
|
49 |
</models>
|
@@ -152,7 +155,7 @@
|
|
152 |
<jobs>
|
153 |
<cloudinary_migrate>
|
154 |
<schedule>
|
155 |
-
<cron_expr
|
156 |
</schedule>
|
157 |
<run>
|
158 |
<model>cloudinary_cloudinary/cron::migrateImages</model>
|
2 |
<config>
|
3 |
<modules>
|
4 |
<Cloudinary_Cloudinary>
|
5 |
+
<version>1.1.5</version>
|
6 |
</Cloudinary_Cloudinary>
|
7 |
</modules>
|
8 |
<global>
|
44 |
<catalog_media_gallery>
|
45 |
<table>catalog_product_entity_media_gallery</table>
|
46 |
</catalog_media_gallery>
|
47 |
+
<migrationError>
|
48 |
+
<table>cloudinary_migration_error</table>
|
49 |
+
</migrationError>
|
50 |
</entities>
|
51 |
</cloudinary_resource>
|
52 |
</models>
|
155 |
<jobs>
|
156 |
<cloudinary_migrate>
|
157 |
<schedule>
|
158 |
+
<cron_expr>*/3 * * * *</cron_expr>
|
159 |
</schedule>
|
160 |
<run>
|
161 |
<model>cloudinary_cloudinary/cron::migrateImages</model>
|
app/code/community/Cloudinary/Cloudinary/etc/system.xml
CHANGED
@@ -54,6 +54,16 @@
|
|
54 |
<show_in_store>1</show_in_store>
|
55 |
<source_model>adminhtml/system_config_source_yesno</source_model>
|
56 |
</cloudinary_cdn_subdomain>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
</fields>
|
58 |
</configuration>
|
59 |
<transformations translate="label">
|
@@ -108,4 +118,4 @@
|
|
108 |
</groups>
|
109 |
</cloudinary>
|
110 |
</sections>
|
111 |
-
</config>
|
54 |
<show_in_store>1</show_in_store>
|
55 |
<source_model>adminhtml/system_config_source_yesno</source_model>
|
56 |
</cloudinary_cdn_subdomain>
|
57 |
+
<cloudinary_foldered_migration>
|
58 |
+
<label>Migrate images to folders relative to the magento root folder</label>
|
59 |
+
<comment>When enabled, cloudinary migration will clone the folder structure of the images relative to the magento root folder</comment>
|
60 |
+
<frontend_type>select</frontend_type>
|
61 |
+
<sort_order>5</sort_order>
|
62 |
+
<show_in_default>1</show_in_default>
|
63 |
+
<show_in_website>1</show_in_website>
|
64 |
+
<show_in_store>1</show_in_store>
|
65 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
66 |
+
</cloudinary_foldered_migration>
|
67 |
</fields>
|
68 |
</configuration>
|
69 |
<transformations translate="label">
|
118 |
</groups>
|
119 |
</cloudinary>
|
120 |
</sections>
|
121 |
+
</config>
|
app/code/community/Cloudinary/Cloudinary/sql/cloudinary_setup/upgrade-1.1.3-1.1.4.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/* @var $installer Mage_Core_Model_Resource_Setup */
|
4 |
+
$installer = $this;
|
5 |
+
$installer->startSetup();
|
6 |
+
|
7 |
+
$conn = $installer->getConnection();
|
8 |
+
$synchronizationTable = $installer->getTable('cloudinary_cloudinary/synchronisation');
|
9 |
+
|
10 |
+
$options = [
|
11 |
+
'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
|
12 |
+
'length' => 255,
|
13 |
+
'comment' => 'The name with which the image can be found in the product related media gallery table'
|
14 |
+
];
|
15 |
+
|
16 |
+
$result = $conn->addColumn($synchronizationTable, 'media_gallery_value', $options);
|
17 |
+
|
18 |
+
$installer->endSetup();
|
app/code/community/Cloudinary/Cloudinary/sql/cloudinary_setup/upgrade-1.1.4-1.1.5.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/* @var $installer Mage_Core_Model_Resource_Setup */
|
4 |
+
$installer = $this;
|
5 |
+
$installer->startSetup();
|
6 |
+
|
7 |
+
$table = $installer->getConnection()
|
8 |
+
->newTable($installer->getTable('cloudinary_cloudinary/migrationError'))
|
9 |
+
->addColumn('file_path', Varien_Db_Ddl_Table::TYPE_BINARY, 255, array(
|
10 |
+
'primary' => true,
|
11 |
+
'nullable' => false
|
12 |
+
), 'File path')
|
13 |
+
->addColumn('message', Varien_Db_Ddl_Table::TYPE_VARCHAR, 255)
|
14 |
+
->addColumn('code', Varien_Db_Ddl_Table::TYPE_INTEGER, null)
|
15 |
+
->addColumn('relative_path', Varien_Db_Ddl_Table::TYPE_BINARY, 255)
|
16 |
+
->addColumn('timestamp', Varien_Db_Ddl_Table::TYPE_DATETIME, null);
|
17 |
+
|
18 |
+
$installer->getConnection()->createTable($table);
|
19 |
+
|
20 |
+
$installer->endSetup();
|
app/design/adminhtml/default/default/template/cloudinary/manage.phtml
CHANGED
@@ -14,12 +14,56 @@
|
|
14 |
</div>
|
15 |
|
16 |
<p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
<?php if ($this->allImagesSynced()): ?>
|
18 |
<div id="messages"><ul class="messages"><li class="notice-msg"><ul><li><span>All images have been successfully migrated to Cloudinary</span></li></ul></li></ul></div>
|
19 |
<?php else: ?>
|
20 |
<p>Image migration progress: <?php echo floor($this->getPercentComplete()) ?>%</p>
|
21 |
<p><?php echo $this->getSynchronizedImageCount() ?> of <?php echo $this->getTotalImageCount() ?> images migrated to Cloudinary.</p>
|
22 |
<?php endif; ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
</p>
|
24 |
|
25 |
<p>
|
@@ -31,11 +75,11 @@
|
|
31 |
|
32 |
|
33 |
<p>
|
34 |
-
<strong>Looking for more information?</strong>
|
35 |
<a href="http://support.cloudinary.com/hc/en-us/sections/200956331-Magento" target="_blank">Visit our Knowledge Base</a>.
|
36 |
</p>
|
37 |
|
38 |
<p>
|
39 |
-
<strong>Need assistance or got feedback?</strong>
|
40 |
<a href="http://support.cloudinary.com/hc/en-us/requests/new" target="_blank">Contact our support</a>.
|
41 |
</p>
|
14 |
</div>
|
15 |
|
16 |
<p>
|
17 |
+
<p>
|
18 |
+
<p>
|
19 |
+
|
20 |
+
Foldered migration: <strong><?php echo $this->isFolderedMigration() ? "Enabled" : "Disabled" ?> </strong><br>
|
21 |
+
|
22 |
+
Foldered migration now available! (don't start migration if you want foldered migration before doing the below tasks) <br> <br>
|
23 |
+
To set up foldered migration you need to: <br> <br>
|
24 |
+
|
25 |
+
- <a target="_blank" href="https://cloudinary.com/console/settings/upload">https://cloudinary.com/console/settings/upload</a>
|
26 |
+
and set 'Auto-create folders' - Enabled <br>
|
27 |
+
|
28 |
+
- <a target="_blank" href="https://cloudinary.com/console/settings/upload">https://cloudinary.com/console/settings/upload</a>
|
29 |
+
and set 'Use file name in Media Library' - Yes <br>
|
30 |
+
|
31 |
+
- <a href="<?php echo $this->getUrl('adminhtml/system_config/edit/section/cloudinary'); ?>"><?php echo $this->__('Go to the Cloudinary configuration section'); ?></a>
|
32 |
+
and set 'Migrate images to folders relative to the magento root folder' - Yes <br>
|
33 |
+
<br>
|
34 |
+
|
35 |
+
If you already use simple migration, you will have deprecated information which you can fold: <br>
|
36 |
+
- `cloudinary_synchronisation` table entries (you can wipe the table clean before starting foldered migration) <br>
|
37 |
+
- all previously migrated images to cloudinary are not touched and will remain in the unfoldered structure
|
38 |
+
(they all are in the cloudinary root folder and can be erased safely, since all images migrated with folders
|
39 |
+
will take place in the /media/... folder) <br> <br> <br>
|
40 |
+
</p>
|
41 |
+
|
42 |
+
</p>
|
43 |
<?php if ($this->allImagesSynced()): ?>
|
44 |
<div id="messages"><ul class="messages"><li class="notice-msg"><ul><li><span>All images have been successfully migrated to Cloudinary</span></li></ul></li></ul></div>
|
45 |
<?php else: ?>
|
46 |
<p>Image migration progress: <?php echo floor($this->getPercentComplete()) ?>%</p>
|
47 |
<p><?php echo $this->getSynchronizedImageCount() ?> of <?php echo $this->getTotalImageCount() ?> images migrated to Cloudinary.</p>
|
48 |
<?php endif; ?>
|
49 |
+
|
50 |
+
<div class="migration_errors">
|
51 |
+
|
52 |
+
<?php
|
53 |
+
|
54 |
+
$errors = $this->getErrors();
|
55 |
+
$count = sizeof($errors);
|
56 |
+
echo "<div><strong>ERRORS ($count):</strong> (re-occuring errors refresh their timestamp)</div>";
|
57 |
+
echo $this->getClearErrorsButton();
|
58 |
+
|
59 |
+
foreach ($errors as $error){
|
60 |
+
$message = $error->getMessage();
|
61 |
+
$filePath = $error->getFilePath();
|
62 |
+
$timestamp = $error->getTimestamp();
|
63 |
+
echo "<div class=\"migration_error\">$filePath: $message ($timestamp)</div>";
|
64 |
+
}
|
65 |
+
?>
|
66 |
+
</div>
|
67 |
</p>
|
68 |
|
69 |
<p>
|
75 |
|
76 |
|
77 |
<p>
|
78 |
+
<strong>Looking for more information?</strong>
|
79 |
<a href="http://support.cloudinary.com/hc/en-us/sections/200956331-Magento" target="_blank">Visit our Knowledge Base</a>.
|
80 |
</p>
|
81 |
|
82 |
<p>
|
83 |
+
<strong>Need assistance or got feedback?</strong>
|
84 |
<a href="http://support.cloudinary.com/hc/en-us/requests/new" target="_blank">Contact our support</a>.
|
85 |
</p>
|
lib/Cloudinary/Api.php
CHANGED
@@ -246,7 +246,6 @@ class Api {
|
|
246 |
|
247 |
# Based on http://snipplr.com/view/17242/
|
248 |
protected function execute($ch) {
|
249 |
-
\Mage::log(\Cloudinary::userAgent());
|
250 |
$string = curl_exec($ch);
|
251 |
$headers = array();
|
252 |
$content = '';
|
246 |
|
247 |
# Based on http://snipplr.com/view/17242/
|
248 |
protected function execute($ch) {
|
|
|
249 |
$string = curl_exec($ch);
|
250 |
$headers = array();
|
251 |
$content = '';
|
lib/Cloudinary/Cloudinary.php
CHANGED
@@ -10,9 +10,9 @@ class Cloudinary {
|
|
10 |
const RANGE_VALUE_RE = '/^(?P<value>(\d+\.)?\d+)(?P<modifier>[%pP])?$/';
|
11 |
const RANGE_RE = '/^(\d+\.)?\d+[%pP]?\.\.(\d+\.)?\d+[%pP]?$/';
|
12 |
|
13 |
-
const VERSION = "1.1.
|
14 |
/** @internal Do not change this value */
|
15 |
-
const USER_AGENT = "CloudinaryPHP/1.1.
|
16 |
|
17 |
/**
|
18 |
* Additional information to be passed with the USER_AGENT, e.g. "CloudinaryMagento/1.0.1". This value is set in platform-specific
|
@@ -236,26 +236,28 @@ class Cloudinary {
|
|
236 |
"w" => $width);
|
237 |
|
238 |
$simple_params = array(
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
|
|
|
|
259 |
|
260 |
foreach ($simple_params as $param=>$option) {
|
261 |
$params[$param] = Cloudinary::option_consume($options, $option);
|
10 |
const RANGE_VALUE_RE = '/^(?P<value>(\d+\.)?\d+)(?P<modifier>[%pP])?$/';
|
11 |
const RANGE_RE = '/^(\d+\.)?\d+[%pP]?\.\.(\d+\.)?\d+[%pP]?$/';
|
12 |
|
13 |
+
const VERSION = "1.1.4";
|
14 |
/** @internal Do not change this value */
|
15 |
+
const USER_AGENT = "CloudinaryPHP/1.1.4";
|
16 |
|
17 |
/**
|
18 |
* Additional information to be passed with the USER_AGENT, e.g. "CloudinaryMagento/1.0.1". This value is set in platform-specific
|
236 |
"w" => $width);
|
237 |
|
238 |
$simple_params = array(
|
239 |
+
"ac" => "audio_codec",
|
240 |
+
"af" => "audio_frequency",
|
241 |
+
"ar" => "aspect_ratio",
|
242 |
+
"br" => "bit_rate",
|
243 |
+
"cs" => "color_space",
|
244 |
+
"d" => "default_image",
|
245 |
+
"dl" => "delay",
|
246 |
+
"dn" => "density",
|
247 |
+
"f" => "fetch_format",
|
248 |
+
"g" => "gravity",
|
249 |
+
"l" => "overlay",
|
250 |
+
"o" => "opacity",
|
251 |
+
"p" => "prefix",
|
252 |
+
"pg" => "page",
|
253 |
+
"q" => "quality",
|
254 |
+
"r" => "radius",
|
255 |
+
"u" => "underlay",
|
256 |
+
"vs" => "video_sampling",
|
257 |
+
"x" => "x",
|
258 |
+
"y" => "y",
|
259 |
+
"z" => "zoom"
|
260 |
+
);
|
261 |
|
262 |
foreach ($simple_params as $param=>$option) {
|
263 |
$params[$param] = Cloudinary::option_consume($options, $option);
|
lib/Cloudinary/Uploader.php
CHANGED
@@ -138,17 +138,19 @@ namespace Cloudinary {
|
|
138 |
public static function explicit($public_id, $options = array())
|
139 |
{
|
140 |
$params = array(
|
141 |
-
"timestamp" => time(),
|
142 |
-
"public_id" => $public_id,
|
143 |
-
"type" => \Cloudinary::option_get($options, "type"),
|
144 |
"callback" => \Cloudinary::option_get($options, "callback"),
|
|
|
|
|
145 |
"eager" => Uploader::build_eager(\Cloudinary::option_get($options, "eager")),
|
146 |
"eager_async" => \Cloudinary::option_get($options, "eager_async"),
|
147 |
"eager_notification_url" => \Cloudinary::option_get($options, "eager_notification_url"),
|
|
|
148 |
"headers" => Uploader::build_custom_headers(\Cloudinary::option_get($options, "headers")),
|
|
|
|
|
149 |
"tags" => \Cloudinary::encode_array(\Cloudinary::option_get($options, "tags")),
|
150 |
-
"
|
151 |
-
"
|
152 |
);
|
153 |
return Uploader::call_api("explicit", $params, $options);
|
154 |
}
|
@@ -245,12 +247,20 @@ namespace Cloudinary {
|
|
245 |
|
246 |
$api_url = \Cloudinary::cloudinary_api_url($action, $options);
|
247 |
|
248 |
-
# Serialize params
|
249 |
-
$api_url .= "?" . preg_replace("/%5B\d+%5D/", "%5B%5D", http_build_query($params));
|
250 |
-
|
251 |
$ch = curl_init($api_url);
|
252 |
|
253 |
$post_params = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
254 |
if ($file) {
|
255 |
if (!preg_match('/^@|^ftp:|^https?:|^s3:|^data:[^;]*;base64,([a-zA-Z0-9\/+\n=]+)$/', $file)) {
|
256 |
if (function_exists("curl_file_create")) {
|
@@ -266,10 +276,10 @@ namespace Cloudinary {
|
|
266 |
|
267 |
curl_setopt($ch, CURLOPT_POST, true);
|
268 |
$timeout = \Cloudinary::option_get($options, "timeout", \Cloudinary::config_get("timeout", 60));
|
269 |
-
curl_setopt($ch,
|
270 |
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_params);
|
271 |
curl_setopt($ch, CURLOPT_CAINFO,realpath(dirname(__FILE__)).DIRECTORY_SEPARATOR."cacert.pem");
|
272 |
-
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
273 |
curl_setopt($ch, CURLOPT_USERAGENT, \Cloudinary::userAgent());
|
274 |
curl_setopt($ch, CURLOPT_PROXY, \Cloudinary::option_get($options, "api_proxy", \Cloudinary::config_get("api_proxy")));
|
275 |
|
@@ -277,7 +287,7 @@ namespace Cloudinary {
|
|
277 |
if ($range != NULL){
|
278 |
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Range: '.$range));
|
279 |
}
|
280 |
-
|
281 |
$response = curl_exec($ch);
|
282 |
$curl_error = NULL;
|
283 |
if(curl_errno($ch))
|
@@ -312,7 +322,7 @@ namespace Cloudinary {
|
|
312 |
$eager = array();
|
313 |
foreach (\Cloudinary::build_array($transformations) as $trans) {
|
314 |
$transformation = $trans;
|
315 |
-
$format = \Cloudinary::option_consume($
|
316 |
$single_eager = implode("/", array_filter(array(\Cloudinary::generate_transformation_string($transformation), $format)));
|
317 |
array_push($eager, $single_eager);
|
318 |
}
|
138 |
public static function explicit($public_id, $options = array())
|
139 |
{
|
140 |
$params = array(
|
|
|
|
|
|
|
141 |
"callback" => \Cloudinary::option_get($options, "callback"),
|
142 |
+
"context" => \Cloudinary::encode_assoc_array(\Cloudinary::option_get($options, "context")),
|
143 |
+
"custom_coordinates" => \Cloudinary::encode_double_array(\Cloudinary::option_get($options, "custom_coordinates")),
|
144 |
"eager" => Uploader::build_eager(\Cloudinary::option_get($options, "eager")),
|
145 |
"eager_async" => \Cloudinary::option_get($options, "eager_async"),
|
146 |
"eager_notification_url" => \Cloudinary::option_get($options, "eager_notification_url"),
|
147 |
+
"face_coordinates" => \Cloudinary::encode_double_array(\Cloudinary::option_get($options, "face_coordinates")),
|
148 |
"headers" => Uploader::build_custom_headers(\Cloudinary::option_get($options, "headers")),
|
149 |
+
"invalidate" => \Cloudinary::option_get($options, "invalidate"),
|
150 |
+
"public_id" => $public_id,
|
151 |
"tags" => \Cloudinary::encode_array(\Cloudinary::option_get($options, "tags")),
|
152 |
+
"timestamp" => time(),
|
153 |
+
"type" => \Cloudinary::option_get($options, "type")
|
154 |
);
|
155 |
return Uploader::call_api("explicit", $params, $options);
|
156 |
}
|
247 |
|
248 |
$api_url = \Cloudinary::cloudinary_api_url($action, $options);
|
249 |
|
|
|
|
|
|
|
250 |
$ch = curl_init($api_url);
|
251 |
|
252 |
$post_params = array();
|
253 |
+
foreach ($params as $key => $value) {
|
254 |
+
if (is_array($value)) {
|
255 |
+
$i = 0;
|
256 |
+
foreach ($value as $item) {
|
257 |
+
$post_params[$key . "[$i]"] = $item;
|
258 |
+
$i++;
|
259 |
+
}
|
260 |
+
} else {
|
261 |
+
$post_params[$key] = $value;
|
262 |
+
}
|
263 |
+
}
|
264 |
if ($file) {
|
265 |
if (!preg_match('/^@|^ftp:|^https?:|^s3:|^data:[^;]*;base64,([a-zA-Z0-9\/+\n=]+)$/', $file)) {
|
266 |
if (function_exists("curl_file_create")) {
|
276 |
|
277 |
curl_setopt($ch, CURLOPT_POST, true);
|
278 |
$timeout = \Cloudinary::option_get($options, "timeout", \Cloudinary::config_get("timeout", 60));
|
279 |
+
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
|
280 |
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_params);
|
281 |
curl_setopt($ch, CURLOPT_CAINFO,realpath(dirname(__FILE__)).DIRECTORY_SEPARATOR."cacert.pem");
|
282 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); # no effect since PHP 5.1.3
|
283 |
curl_setopt($ch, CURLOPT_USERAGENT, \Cloudinary::userAgent());
|
284 |
curl_setopt($ch, CURLOPT_PROXY, \Cloudinary::option_get($options, "api_proxy", \Cloudinary::config_get("api_proxy")));
|
285 |
|
287 |
if ($range != NULL){
|
288 |
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Range: '.$range));
|
289 |
}
|
290 |
+
|
291 |
$response = curl_exec($ch);
|
292 |
$curl_error = NULL;
|
293 |
if(curl_errno($ch))
|
322 |
$eager = array();
|
323 |
foreach (\Cloudinary::build_array($transformations) as $trans) {
|
324 |
$transformation = $trans;
|
325 |
+
$format = \Cloudinary::option_consume($transformation, "format");
|
326 |
$single_eager = implode("/", array_filter(array(\Cloudinary::generate_transformation_string($transformation), $format)));
|
327 |
array_push($eager, $single_eager);
|
328 |
}
|
lib/CloudinaryExtension/CloudinaryImageProvider.php
CHANGED
@@ -5,6 +5,8 @@ namespace CloudinaryExtension;
|
|
5 |
|
6 |
use Cloudinary;
|
7 |
use Cloudinary\Uploader;
|
|
|
|
|
8 |
use CloudinaryExtension\Image\Transformation;
|
9 |
use CloudinaryExtension\Security;
|
10 |
|
@@ -12,6 +14,12 @@ class CloudinaryImageProvider implements ImageProvider
|
|
12 |
{
|
13 |
private $configuration;
|
14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
private function __construct(Configuration $configuration)
|
16 |
{
|
17 |
$this->configuration = $configuration;
|
@@ -25,7 +33,18 @@ class CloudinaryImageProvider implements ImageProvider
|
|
25 |
|
26 |
public function upload(Image $image)
|
27 |
{
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
}
|
30 |
|
31 |
public function transformImage(Image $image, Transformation $transformation = null)
|
@@ -33,7 +52,7 @@ class CloudinaryImageProvider implements ImageProvider
|
|
33 |
if ($transformation === null) {
|
34 |
$transformation = $this->configuration->getDefaultTransformation();
|
35 |
}
|
36 |
-
return Image::fromPath(\cloudinary_url($image->getId(), $transformation->build()));
|
37 |
}
|
38 |
|
39 |
public function validateCredentials()
|
5 |
|
6 |
use Cloudinary;
|
7 |
use Cloudinary\Uploader;
|
8 |
+
use CloudinaryExtension\Exception\FileAlreadyExists;
|
9 |
+
use CloudinaryExtension\Exception\MigrationError;
|
10 |
use CloudinaryExtension\Image\Transformation;
|
11 |
use CloudinaryExtension\Security;
|
12 |
|
14 |
{
|
15 |
private $configuration;
|
16 |
|
17 |
+
private $uploadConfig = array(
|
18 |
+
"use_filename" => true,
|
19 |
+
"unique_filename" => false,
|
20 |
+
"overwrite" => false
|
21 |
+
);
|
22 |
+
|
23 |
private function __construct(Configuration $configuration)
|
24 |
{
|
25 |
$this->configuration = $configuration;
|
33 |
|
34 |
public function upload(Image $image)
|
35 |
{
|
36 |
+
try{
|
37 |
+
$imagePath = (string)$image;
|
38 |
+
$uploadOptionsAndFolder = $this->uploadConfig + ["folder" => $image->getRelativeFolder()];
|
39 |
+
$uploadResult = Uploader::upload($imagePath, $uploadOptionsAndFolder);
|
40 |
+
|
41 |
+
if ($uploadResult['existing'] == 1) {
|
42 |
+
MigrationError::throwWith($image, MigrationError::CODE_FILE_ALREADY_EXISTS);
|
43 |
+
}
|
44 |
+
return $uploadResult;
|
45 |
+
} catch (\Exception $e) {
|
46 |
+
MigrationError::throwWith($image, MigrationError::CODE_API_ERROR, $e->getMessage());
|
47 |
+
}
|
48 |
}
|
49 |
|
50 |
public function transformImage(Image $image, Transformation $transformation = null)
|
52 |
if ($transformation === null) {
|
53 |
$transformation = $this->configuration->getDefaultTransformation();
|
54 |
}
|
55 |
+
return Image::fromPath(\cloudinary_url($image->getId(), $transformation->build()), $image->getRelativePath());
|
56 |
}
|
57 |
|
58 |
public function validateCredentials()
|
lib/CloudinaryExtension/Exception/MigrationError.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace CloudinaryExtension\Exception;
|
4 |
+
|
5 |
+
use CloudinaryExtension\Image;
|
6 |
+
use Exception;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class MigrationError
|
10 |
+
* @package CloudinaryExtension\Exception
|
11 |
+
*/
|
12 |
+
class MigrationError extends Exception
|
13 |
+
{
|
14 |
+
const CODE_FILE_ALREADY_EXISTS = 0;
|
15 |
+
const CODE_API_ERROR = 1;
|
16 |
+
|
17 |
+
private static $messages = [
|
18 |
+
self::CODE_FILE_ALREADY_EXISTS => 'File already exists (cloudinary is case insensitive!!).',
|
19 |
+
self::CODE_API_ERROR => 'Internal API error'
|
20 |
+
];
|
21 |
+
|
22 |
+
private $image;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @return Image
|
26 |
+
*/
|
27 |
+
public function getImage()
|
28 |
+
{
|
29 |
+
return $this->image;
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @param Image $image
|
34 |
+
* @param $code
|
35 |
+
* @param $message overrides the default message attached to the code
|
36 |
+
* @return MigrationError
|
37 |
+
*/
|
38 |
+
private static function build(Image $image, $code, $message = '')
|
39 |
+
{
|
40 |
+
$result = new MigrationError($message ?: self::$messages[$code], $code);
|
41 |
+
$result->image = $image;
|
42 |
+
return $result;
|
43 |
+
}
|
44 |
+
|
45 |
+
public static function throwWith(Image $image, $code, $message = '')
|
46 |
+
{
|
47 |
+
throw self::build($image, $code, $message);
|
48 |
+
}
|
49 |
+
|
50 |
+
}
|
lib/CloudinaryExtension/FolderTranslator.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace CloudinaryExtension;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Interface FolderTranslator
|
7 |
+
*
|
8 |
+
* Supposed to contain the logic of which folder should a file be uploaded in cloudinary.
|
9 |
+
*
|
10 |
+
* @package CloudinaryExtension\Migration
|
11 |
+
*/
|
12 |
+
interface FolderTranslator
|
13 |
+
{
|
14 |
+
public function translate($path);
|
15 |
+
public function reverse($folder);
|
16 |
+
}
|
lib/CloudinaryExtension/Image.php
CHANGED
@@ -5,18 +5,21 @@ namespace CloudinaryExtension;
|
|
5 |
class Image
|
6 |
{
|
7 |
private $imagePath;
|
|
|
|
|
8 |
|
9 |
-
private $
|
10 |
-
|
11 |
-
private function __construct($imagePath)
|
12 |
{
|
|
|
|
|
13 |
$this->imagePath = $imagePath;
|
14 |
-
$this->
|
|
|
15 |
}
|
16 |
|
17 |
-
public static function fromPath($
|
18 |
{
|
19 |
-
return new Image($
|
20 |
}
|
21 |
|
22 |
public function __toString()
|
@@ -24,13 +27,28 @@ class Image
|
|
24 |
return $this->imagePath;
|
25 |
}
|
26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
public function getId()
|
28 |
{
|
29 |
-
|
|
|
|
|
|
|
|
|
30 |
}
|
31 |
|
32 |
public function getExtension()
|
33 |
{
|
34 |
-
return $this->
|
35 |
}
|
36 |
}
|
5 |
class Image
|
6 |
{
|
7 |
private $imagePath;
|
8 |
+
private $relativePath;
|
9 |
+
private $pathInfo;
|
10 |
|
11 |
+
private function __construct($imagePath, $relativePath = '')
|
|
|
|
|
12 |
{
|
13 |
+
$caller = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3)[2];
|
14 |
+
\Cloudinary_Cloudinary_Model_Logger::getInstance()->debugLog("$imagePath, $relativePath, {$caller['class']}::{$caller['function']}");
|
15 |
$this->imagePath = $imagePath;
|
16 |
+
$this->relativePath = $relativePath;
|
17 |
+
$this->pathInfo = pathinfo($this->imagePath);
|
18 |
}
|
19 |
|
20 |
+
public static function fromPath($imagePath, $relativePath = '')
|
21 |
{
|
22 |
+
return new Image($imagePath, $relativePath);
|
23 |
}
|
24 |
|
25 |
public function __toString()
|
27 |
return $this->imagePath;
|
28 |
}
|
29 |
|
30 |
+
public function getRelativePath()
|
31 |
+
{
|
32 |
+
return $this->relativePath;
|
33 |
+
}
|
34 |
+
|
35 |
+
public function getRelativeFolder()
|
36 |
+
{
|
37 |
+
$result = dirname($this->getRelativePath());
|
38 |
+
return $result == '.' ? '' : $result;
|
39 |
+
}
|
40 |
+
|
41 |
public function getId()
|
42 |
{
|
43 |
+
if ($this->relativePath) {
|
44 |
+
return $this->getRelativeFolder() . DS . $this->pathInfo['filename'];
|
45 |
+
} else {
|
46 |
+
return $this->pathInfo['filename'];
|
47 |
+
}
|
48 |
}
|
49 |
|
50 |
public function getExtension()
|
51 |
{
|
52 |
+
return $this->pathInfo['extension'];
|
53 |
}
|
54 |
}
|
lib/CloudinaryExtension/Image/Synchronizable.php
CHANGED
@@ -5,6 +5,6 @@ namespace CloudinaryExtension\Image;
|
|
5 |
interface Synchronizable
|
6 |
{
|
7 |
public function getFilename();
|
8 |
-
|
9 |
public function tagAsSynchronized();
|
10 |
-
}
|
5 |
interface Synchronizable
|
6 |
{
|
7 |
public function getFilename();
|
8 |
+
public function getRelativePath();
|
9 |
public function tagAsSynchronized();
|
10 |
+
}
|
lib/CloudinaryExtension/Migration/BatchUploader.php
CHANGED
@@ -2,13 +2,15 @@
|
|
2 |
|
3 |
namespace CloudinaryExtension\Migration;
|
4 |
|
|
|
5 |
use CloudinaryExtension\Image;
|
6 |
use CloudinaryExtension\Image\Synchronizable;
|
7 |
use CloudinaryExtension\ImageProvider;
|
|
|
8 |
|
9 |
class BatchUploader
|
10 |
{
|
11 |
-
const MESSAGE_STATUS = 'Cloudinary migration: %s images migrated';
|
12 |
|
13 |
const MESSAGE_UPLOADED = 'Cloudinary migration: uploaded %s';
|
14 |
|
@@ -23,6 +25,9 @@ class BatchUploader
|
|
23 |
private $migrationTask;
|
24 |
|
25 |
private $countMigrated = 0;
|
|
|
|
|
|
|
26 |
|
27 |
public function __construct(ImageProvider $imageProvider, Task $migrationTask, Logger $logger, $baseMediaPath)
|
28 |
{
|
@@ -35,7 +40,6 @@ class BatchUploader
|
|
35 |
public function uploadImages(array $images)
|
36 |
{
|
37 |
$this->countMigrated = 0;
|
38 |
-
|
39 |
foreach ($images as $image) {
|
40 |
|
41 |
if ($this->migrationTask->hasBeenStopped()) {
|
@@ -43,8 +47,7 @@ class BatchUploader
|
|
43 |
}
|
44 |
$this->uploadImage($image);
|
45 |
}
|
46 |
-
|
47 |
-
$this->logger->notice(sprintf(self::MESSAGE_STATUS, $this->countMigrated));
|
48 |
}
|
49 |
|
50 |
private function getAbsolutePath(Synchronizable $image)
|
@@ -54,14 +57,45 @@ class BatchUploader
|
|
54 |
|
55 |
private function uploadImage(Synchronizable $image)
|
56 |
{
|
|
|
|
|
|
|
|
|
57 |
try {
|
58 |
-
$this->imageProvider->upload(
|
59 |
$image->tagAsSynchronized();
|
60 |
$this->countMigrated++;
|
61 |
-
$this->
|
|
|
62 |
} catch (\Exception $e) {
|
63 |
-
$this->
|
|
|
|
|
64 |
}
|
65 |
}
|
66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
}
|
2 |
|
3 |
namespace CloudinaryExtension\Migration;
|
4 |
|
5 |
+
use CloudinaryExtension\Exception\MigrationError;
|
6 |
use CloudinaryExtension\Image;
|
7 |
use CloudinaryExtension\Image\Synchronizable;
|
8 |
use CloudinaryExtension\ImageProvider;
|
9 |
+
use \Cloudinary_Cloudinary_Helper_Util_ArrayUtils as ArrayUtils;
|
10 |
|
11 |
class BatchUploader
|
12 |
{
|
13 |
+
const MESSAGE_STATUS = 'Cloudinary migration: %s images migrated, %s failed';
|
14 |
|
15 |
const MESSAGE_UPLOADED = 'Cloudinary migration: uploaded %s';
|
16 |
|
25 |
private $migrationTask;
|
26 |
|
27 |
private $countMigrated = 0;
|
28 |
+
private $countFailed = 0;
|
29 |
+
|
30 |
+
private $errors = [];
|
31 |
|
32 |
public function __construct(ImageProvider $imageProvider, Task $migrationTask, Logger $logger, $baseMediaPath)
|
33 |
{
|
40 |
public function uploadImages(array $images)
|
41 |
{
|
42 |
$this->countMigrated = 0;
|
|
|
43 |
foreach ($images as $image) {
|
44 |
|
45 |
if ($this->migrationTask->hasBeenStopped()) {
|
47 |
}
|
48 |
$this->uploadImage($image);
|
49 |
}
|
50 |
+
$this->logger->notice(sprintf(self::MESSAGE_STATUS, $this->countMigrated, $this->countFailed));
|
|
|
51 |
}
|
52 |
|
53 |
private function getAbsolutePath(Synchronizable $image)
|
57 |
|
58 |
private function uploadImage(Synchronizable $image)
|
59 |
{
|
60 |
+
$absolutePath = $this->getAbsolutePath($image);
|
61 |
+
$relativePath = $image->getRelativePath();
|
62 |
+
$apiImage = Image::fromPath($absolutePath, $relativePath);
|
63 |
+
|
64 |
try {
|
65 |
+
$uploadResult = $this->imageProvider->upload($apiImage);
|
66 |
$image->tagAsSynchronized();
|
67 |
$this->countMigrated++;
|
68 |
+
$this->_debugLogResult($uploadResult);
|
69 |
+
$this->logger->notice(sprintf(self::MESSAGE_UPLOADED, $absolutePath . ' - ' . $relativePath));
|
70 |
} catch (\Exception $e) {
|
71 |
+
$this->errors[] = $e;
|
72 |
+
$this->countFailed++;
|
73 |
+
$this->logger->error(sprintf(self::MESSAGE_UPLOAD_ERROR, $e->getMessage(), $absolutePath . ' - ' . $relativePath));
|
74 |
}
|
75 |
}
|
76 |
|
77 |
+
/**
|
78 |
+
* @param $uploadResult
|
79 |
+
*/
|
80 |
+
private function _debugLogResult($uploadResult)
|
81 |
+
{
|
82 |
+
$extractedResult = ArrayUtils::arraySelect($uploadResult, ['url', 'public_id']);
|
83 |
+
$this->logger->debugLog(json_encode($extractedResult, JSON_PRETTY_PRINT) . "\n");
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* @return array
|
88 |
+
*/
|
89 |
+
public function getErrors()
|
90 |
+
{
|
91 |
+
return $this->errors;
|
92 |
+
}
|
93 |
+
|
94 |
+
public function getMigrationErrors()
|
95 |
+
{
|
96 |
+
return array_filter($this->errors, function ($val) {
|
97 |
+
return $val instanceof MigrationError;
|
98 |
+
});
|
99 |
+
}
|
100 |
+
|
101 |
}
|
lib/CloudinaryExtension/Migration/Logger.php
CHANGED
@@ -9,4 +9,6 @@ interface Logger
|
|
9 |
public function notice($message, array $context = array());
|
10 |
|
11 |
public function error($message, array $context = array());
|
|
|
|
|
12 |
}
|
9 |
public function notice($message, array $context = array());
|
10 |
|
11 |
public function error($message, array $context = array());
|
12 |
+
|
13 |
+
public function debugLog($message);
|
14 |
}
|
package.xml
CHANGED
@@ -1,21 +1,22 @@
|
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>Cloudinary_Cloudinary</name>
|
4 |
-
<version>1.
|
5 |
<stability>stable</stability>
|
6 |
<license>MIT License (MITL)</license>
|
7 |
<channel>community</channel>
|
8 |
<extends/>
|
9 |
<summary>Cloudinary - Image Management In The Cloud</summary>
|
10 |
<description>Cloudinary supercharges your images! Upload images to the cloud, deliver optimized via a fast CDN, perform smart resizing and apply effects.</description>
|
11 |
-
<notes>v1.
|
12 |

|
13 |
-
|
14 |
-
|
|
|
15 |
<authors><author><name>Cloudinary</name><user>cloudinary</user><email>accounts+magento@cloudinary.com</email></author></authors>
|
16 |
-
<date>
|
17 |
-
<time>
|
18 |
-
<contents><target name="magecommunity"><dir name="Cloudinary"><dir name="Cloudinary"><dir name="Block"><dir name="Adminhtml"><dir name="Manage"><file name="Grid.php" hash="b6a05f6ba08c5ba0d08846a7b0a06776"/></dir><file name="Manage.php" hash="
|
19 |
<compatible/>
|
20 |
<dependencies><required><php><min>5.4.0</min><max>7.0.0</max></php></required></dependencies>
|
21 |
</package>
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>Cloudinary_Cloudinary</name>
|
4 |
+
<version>1.2.0</version>
|
5 |
<stability>stable</stability>
|
6 |
<license>MIT License (MITL)</license>
|
7 |
<channel>community</channel>
|
8 |
<extends/>
|
9 |
<summary>Cloudinary - Image Management In The Cloud</summary>
|
10 |
<description>Cloudinary supercharges your images! Upload images to the cloud, deliver optimized via a fast CDN, perform smart resizing and apply effects.</description>
|
11 |
+
<notes>v1.2.0
|
12 |

|
13 |
+
Release Highlights:
|
14 |
+

|
15 |
+
* Foldered migration</notes>
|
16 |
<authors><author><name>Cloudinary</name><user>cloudinary</user><email>accounts+magento@cloudinary.com</email></author></authors>
|
17 |
+
<date>2016-02-29</date>
|
18 |
+
<time>16:32:17</time>
|
19 |
+
<contents><target name="magecommunity"><dir name="Cloudinary"><dir name="Cloudinary"><dir name="Block"><dir name="Adminhtml"><dir name="Manage"><file name="Grid.php" hash="b6a05f6ba08c5ba0d08846a7b0a06776"/></dir><file name="Manage.php" hash="c525e34955df149b70d3a7fdde427672"/><dir name="Page"><file name="Menu.php" hash="891d6a4c075ba03c9a20658076c86ad0"/></dir><dir name="System"><dir name="Config"><file name="Signup.php" hash="235c27f236e45900eb94dea0181027cc"/></dir></dir></dir></dir><dir name="Helper"><file name="Autoloader.php" hash="393b3e2fc25e63ca28157152d2542b18"/><dir name="Configuration"><file name="Validation.php" hash="6d17d39ba39f67888701fadf0fe3de62"/></dir><file name="Configuration.php" hash="045cf15e781fac57b999551e1e5c88ea"/><file name="Console.php" hash="e4ca7f9bf450b05383def130b2819ce0"/><file name="Data.php" hash="42c9d44f1bbe530e30cf5379846dea65"/><file name="Image.php" hash="2b0b6a42a3f38203952547739e36632d"/><dir name="Util"><file name="ArrayUtils.php" hash="dbf5b1f86213f6e1ea34b1523b2b9ffe"/></dir></dir><dir name="Model"><dir name="Catalog"><dir name="Product"><file name="Image.php" hash="4c04c8db36be21aaecfc681fac429f69"/><dir name="Media"><file name="Config.php" hash="ff27ccd9fc2becce9feae31ffd1d59e2"/></dir><file name="Media.php" hash="05726616a07d7d08933e9654e6107283"/></dir></dir><dir name="Cms"><dir name="Adminhtml"><dir name="Template"><file name="Filter.php" hash="4ef453061d790fff6b772286e90439f2"/></dir></dir><file name="Synchronisation.php" hash="3bf5d872b6451cf3ce6f83ec92104415"/><dir name="Template"><file name="Filter.php" hash="5ec9589ef22b1e9c88b20c3272d01f8c"/></dir><file name="Uploader.php" hash="bcaca2303cf806d41bac82a009ba9eb6"/><dir name="Wysiwyg"><dir name="Images"><file name="Storage.php" hash="b3eae9a3a4810d9de5ab6a91243d047d"/></dir></dir></dir><file name="CollectionCounter.php" hash="e69953aee5d966a3ec13d33533f017e0"/><file name="Cron.php" hash="13ea00a9e40622912bf46ed367f9a214"/><dir name="Exception"><file name="BadFilePathException.php" hash="68135da8dfe2f0589a531b4bd36e3330"/></dir><file name="Image.php" hash="0377e2c24c5e2f23357a55d744098fda"/><file name="Logger.php" hash="226893f4a59d1431330688f455975d61"/><file name="MagentoFolderTranslator.php" hash="ad11d373bc6e193b689d29f16f5f6480"/><file name="Migration.php" hash="e923053b36d2ab469362b3590935ecfe"/><file name="MigrationError.php" hash="1c91373b020d639ae3fb8acfa099eea0"/><file name="Observer.php" hash="22a8e380ac895894f218e7239560b2e2"/><file name="PreConditionsValidator.php" hash="b7cf4e4b4372a2ea5b87d849b2a3d748"/><dir name="Resource"><dir name="Cms"><dir name="Synchronisation"><file name="Collection.php" hash="117085bb56d3f0db8f3d52f136a8b84b"/></dir></dir><dir name="Media"><file name="Collection.php" hash="f54d914a6f79c7b3ab51f822bf64de39"/></dir><file name="Migration.php" hash="69a545d0627016afc03ea097641aa749"/><dir name="MigrationError"><file name="Collection.php" hash="3c5ef530b18b4cd7763a610b84cd3d41"/></dir><file name="MigrationError.php" hash="e6de24a80cb0daed6ead44c699dce535"/><dir name="Synchronisation"><file name="Collection.php" hash="8abfc042f7c84f424015e8bc34dab0dc"/></dir><file name="Synchronisation.php" hash="5b721d854d8f89bc3310e46081be7153"/></dir><file name="Synchronisation.php" hash="553d95d0c40d677539b6e9f035c52b91"/><file name="SynchronisedMediaUnifier.php" hash="dd47a04cc2eaa2a81b6dce27f22301f2"/><dir name="System"><dir name="Config"><dir name="Source"><dir name="Dropdown"><file name="Dpr.php" hash="2b9bfd5f836dbdb5d7224d298264f540"/><file name="Gravity.php" hash="c241498e2093640892170673cd7550cd"/><file name="Quality.php" hash="e0c5902f5c36c96fb8a8ba7cc741ce1f"/></dir></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="CloudinaryController.php" hash="4e23d18f841d78abf8443de71a951ed6"/></dir></dir><dir name="data"><dir name="cloudinary_setup"><file name="data-upgrade-0.1.0-0.1.1.php" hash="4c6ce6cd9ab0d94654afb4a398fb3d6c"/><file name="data-upgrade-1.1.2-1.1.3.php" hash="fe2026874346017303a8f41a9d0d6c0d"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="46e365e2f4b1d543aad248dfcfb99c50"/><file name="config.xml" hash="8449286938df94d41182641f54de1d06"/><file name="system.xml" hash="a4ae810df3e6587625d395985b79ee83"/></dir><dir name="sql"><dir name="cloudinary_setup"><file name="install-0.1.0.php" hash="55d93b3dab573c2a932edbb5a2fa4865"/><file name="upgrade-0.1.0-0.1.1.php" hash="6c8d430fbf7b9714586b67db3d455008"/><file name="upgrade-1.1.3-1.1.4.php" hash="d6314fc1843b2061d0d04ae60c4d8091"/><file name="upgrade-1.1.4-1.1.5.php" hash="5b035e4b600cbbc743e9ff6a7b505230"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Cloudinary_Cloudinary.xml" hash="9337962a4ccf8a43164d5d71dfd2d756"/></dir></target><target name="magelib"><dir name="CloudinaryExtension"><file name="Cloud.php" hash="59b0debf9ae297e4e824e39ba819b1d1"/><file name="CloudinaryImageProvider.php" hash="e75c77d6a169fec4c96c875de477fc75"/><file name="Configuration.php" hash="b4ece3c87e2aa2af83b8362311ad7850"/><file name="Credentials.php" hash="ccd2da6450df39f3218cfd64ac47103f"/><dir name="Exception"><file name="InvalidCredentials.php" hash="abecc635a25f6c9896c605ad16e1f7d7"/><file name="MigrationError.php" hash="1f37d28be668edb805e46fd207c72fd9"/></dir><file name="FolderTranslator.php" hash="19a335acf751d67bd7efe46829602490"/><dir name="Image"><file name="Synchronizable.php" hash="38a6b9db4cfc3fde3e94db5b35a92bf8"/><dir name="Transformation"><file name="Dimensions.php" hash="8b9a09da6980aa2ff42e8f00d79a1b83"/><file name="Dpr.php" hash="f78cd1bfabaf3088ca8d4af972bfd453"/><file name="FetchFormat.php" hash="b81c62dd756dee4ad085ee6f0a83356a"/><file name="Format.php" hash="ab8ea9b6a8c813a24f23b079ea6236da"/><file name="Gravity.php" hash="c1c2adf4dbbeaa6b06d67d2014300559"/><file name="Quality.php" hash="23a857f3910aecf6e45645194ff7f54e"/></dir><file name="Transformation.php" hash="fc443a6abad4a478e94df5661e4aef12"/></dir><file name="Image.php" hash="cf1b7cd018475520cda04a49780a17de"/><file name="ImageProvider.php" hash="f4eb49d5e1e4c1728a5dde29b6b5a3fa"/><dir name="Migration"><file name="BatchUploader.php" hash="5d25c21cf55040b79320221f815df8e8"/><file name="Logger.php" hash="648b47bb065de0c81b386ac300b4f9a3"/><file name="Queue.php" hash="add92864192b0950c29c91ffe5e5a3ee"/><file name="SynchronizedMediaRepository.php" hash="9e7e1dae66b40ce991b0e86ecdff4c24"/><file name="Task.php" hash="ac11d06c531d48b38cf88f6e8f2bdc19"/></dir><dir name="Security"><file name="ApiSignature.php" hash="049c7db2684ec2a6cf5bb4efcd064951"/><file name="CloudinaryEnvironmentVariable.php" hash="2b5c28381b52350586ea1589854ca498"/><file name="ConsoleUrl.php" hash="4e748cfe0f5a0aeab2307c623179c6f9"/><file name="EnvironmentVariable.php" hash="297fa60b819ffc028b9a32dae6eef63d"/><file name="Key.php" hash="ac3a50b59f2a7db1edcf30386759c7ec"/><file name="Secret.php" hash="b1010679976575d57752dbb07f1b94ed"/><file name="SignedConsoleUrl.php" hash="791e1f1080be23423c2ad87f431f6221"/></dir><file name="ValidateRemoteUrlRequest.php" hash="c2e2eb712e5293ad508a23610dfbbd6d"/></dir><dir name="Cloudinary"><file name="Api.php" hash="f046d7b1db05efb0997a458fb610a09f"/><file name="Cloudinary.php" hash="debd99bcb8076cf250f59a8925f8ba1b"/><file name="CloudinaryField.php" hash="411714580d21b58115ab07737367173a"/><file name="Helpers.php" hash="63035ebeaa237bd69dcad2d756a00b44"/><file name="PreloadedFile.php" hash="73cc9e276f96553814f05eae592d11ee"/><file name="Uploader.php" hash="2fbea92cd3e409ec62e61ecbf36e6f2c"/><file name="cacert.pem" hash="c4290b9deb70d0bef2f88b67fc68c8ec"/></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><dir name="cloudinary"><file name="cloudinary.xml" hash="8cf333ec4b49c684ea6a209061f5128b"/></dir></dir><dir name="template"><dir name="cloudinary"><file name="manage.phtml" hash="080ea639f961da33a5a3d2429da13edc"/><dir name="system"><dir name="config"><file name="signup.phtml" hash="2a0e06990eb542f22531ac2ebb5996f5"/></dir></dir></dir></dir></dir></dir></dir></target></contents>
|
20 |
<compatible/>
|
21 |
<dependencies><required><php><min>5.4.0</min><max>7.0.0</max></php></required></dependencies>
|
22 |
</package>
|