Version Notes
==== 2.0.0 ====
Public release - Completely Rebuild code
Download this release
Release Info
Developer | Tiny |
Extension | Tiny_Compresss_Images |
Version | 2.0.0 |
Comparing to | |
See all releases |
Code changes from version 1.0.1 to 2.0.0
- app/code/community/Tiny/CompressImages/Block/Adminhtml/ApiNotification.php +27 -0
- app/code/community/Tiny/CompressImages/Block/Adminhtml/System/Config/Form.php +107 -0
- app/code/community/Tiny/CompressImages/Block/Adminhtml/System/Config/Form/Field/AccountType.php +17 -0
- app/code/community/Tiny/CompressImages/Block/Adminhtml/System/Config/Form/Field/Api.php +111 -0
- app/code/community/Tiny/CompressImages/Block/Adminhtml/System/Config/Form/Field/LogFile.php +30 -0
- app/code/community/Tiny/CompressImages/Block/Adminhtml/System/Config/Form/Field/LogStatus.php +34 -0
- app/code/community/Tiny/CompressImages/Block/Adminhtml/System/Config/Form/Field/Radios.php +81 -0
- app/code/community/Tiny/CompressImages/Block/Adminhtml/System/Config/Form/Field/Saved.php +20 -0
- app/code/community/Tiny/CompressImages/Block/Adminhtml/System/Config/Form/Field/Status.php +65 -0
- app/code/community/Tiny/CompressImages/Block/Adminhtml/System/Config/Form/Field/SupportTab.php +50 -0
- app/code/community/Tiny/CompressImages/Exception.php +2 -0
- app/code/community/Tiny/CompressImages/Helper/Config.php +184 -0
- app/code/community/Tiny/CompressImages/Helper/Data.php +205 -0
- app/code/community/Tiny/CompressImages/Helper/Tinify.php +750 -0
- app/code/community/Tiny/CompressImages/Model/Image.php +327 -0
- app/code/community/Tiny/CompressImages/Model/Observer.php +20 -68
- app/code/community/Tiny/CompressImages/Model/Product/Image.php +62 -9
- app/code/community/Tiny/CompressImages/Model/Resource/Image.php +13 -0
- app/code/community/Tiny/CompressImages/Model/Resource/Image/Collection.php +9 -0
- app/code/community/Tiny/CompressImages/Model/Resource/Setup.php +76 -0
- app/code/community/Tiny/CompressImages/Model/Resource/Totals.php +13 -0
- app/code/community/Tiny/CompressImages/Model/Resource/Totals/Collection.php +9 -0
- app/code/community/Tiny/CompressImages/Model/System/Config/Backend/ApiKey.php +33 -0
- app/code/community/Tiny/CompressImages/Model/System/Config/Backend/Comment/LoggingMode.php +26 -0
- app/code/community/Tiny/CompressImages/Model/System/Config/Source/Cms/ImageTypes.php +30 -0
- app/code/community/Tiny/CompressImages/Model/System/Config/Source/Log.php +34 -0
- app/code/community/Tiny/CompressImages/Model/System/Config/Source/OnOff.php +26 -0
- app/code/community/Tiny/CompressImages/Model/System/Config/Source/Product/ImageTypes.php +34 -0
- app/code/community/Tiny/CompressImages/Model/System/Config/Source/Testlive.php +33 -0
- app/code/community/Tiny/CompressImages/Model/Totals.php +89 -0
- app/code/community/Tiny/CompressImages/Test/Block/Adminhtml/System/Config/Form/Field/LogStatusTest.php +32 -0
- app/code/community/Tiny/CompressImages/Test/Framework/Tiny/Test/Config.php +72 -0
- app/code/community/Tiny/CompressImages/Test/Framework/Tiny/Test/Http/Response.php +58 -0
- app/code/community/Tiny/CompressImages/Test/Framework/Tiny/Test/TestCase.php +244 -0
- app/code/community/Tiny/CompressImages/Test/Helper/ConfigTest.php +96 -0
- app/code/community/Tiny/CompressImages/Test/Model/ImageTest.php +227 -0
- app/code/community/Tiny/CompressImages/Test/Model/Product/ImageTest.php +40 -0
- app/code/community/Tiny/CompressImages/Test/Model/System/Config/Backend/Comment/LoggingModeTest.php +34 -0
- app/code/community/Tiny/CompressImages/Test/bootstrap.php +10 -0
- app/code/community/Tiny/CompressImages/controllers/CompressImagesAdminhtml/ConfigController.php +65 -0
- app/code/community/Tiny/CompressImages/controllers/CompressImagesAdminhtml/StatusController.php +46 -0
- app/code/community/Tiny/CompressImages/etc/adminhtml.xml +22 -17
- app/code/community/Tiny/CompressImages/etc/config.xml +103 -28
- app/code/community/Tiny/CompressImages/etc/system.xml +191 -87
- app/code/community/Tiny/CompressImages/sql/tiny_compressimages_setup/install-1.0.0.php +250 -0
- app/design/adminhtml/default/default/layout/Tiny/CompressImages.xml +16 -0
- app/design/adminhtml/default/default/template/Tiny/CompressImages/Api/keyNotification.phtml +9 -0
- app/design/adminhtml/default/default/template/Tiny/CompressImages/system/config/form/field/log_file.phtml +21 -0
- app/design/adminhtml/default/default/template/Tiny/CompressImages/system/config/form/field/log_status.phtml +164 -0
- app/design/adminhtml/default/default/template/Tiny/CompressImages/system/config/form/field/support_tab.phtml +87 -0
- app/etc/modules/Tiny_CompressImages.xml +7 -7
- app/locale/en_US/Tiny_CompressImages.csv +99 -0
- lib/TinyCompress/.gitignore +1 -0
- lib/TinyCompress/.travis.yml +25 -0
- lib/TinyCompress/LICENSE +21 -0
- lib/TinyCompress/README.md +50 -16
- lib/TinyCompress/class-tiny-compress-curl.php +0 -77
- lib/TinyCompress/class-tiny-compress-fopen.php +0 -85
- lib/TinyCompress/class-tiny-compress.php +0 -97
- lib/TinyCompress/class-tiny-exception.php +0 -32
- lib/TinyCompress/class-tiny-php.php +0 -29
- lib/TinyCompress/composer.json +41 -0
- lib/TinyCompress/composer.lock +977 -0
- lib/TinyCompress/config/tinypng-api.ini +0 -2
- lib/TinyCompress/lib/Tinify.php +85 -0
- lib/TinyCompress/lib/Tinify/Client.php +105 -0
- lib/TinyCompress/lib/Tinify/Exception.php +34 -0
- lib/TinyCompress/lib/Tinify/Result.php +36 -0
- lib/TinyCompress/lib/Tinify/ResultMeta.php +23 -0
- lib/TinyCompress/lib/Tinify/Source.php +69 -0
- lib/TinyCompress/{cacert.pem → lib/data/cacert.pem} +307 -213
- lib/TinyCompress/phpunit.xml +12 -0
- lib/TinyCompress/test/TinifyClientTest.php +176 -0
- lib/TinyCompress/test/TinifyResultMetaTest.php +20 -0
- lib/TinyCompress/test/TinifyResultTest.php +35 -0
- lib/TinyCompress/test/TinifySourceTest.php +314 -0
- lib/TinyCompress/test/TinifyTest.php +100 -0
- lib/TinyCompress/test/curl_mock.php +160 -0
- lib/TinyCompress/test/examples/dummy.png +0 -0
- lib/TinyCompress/test/examples/voormedia.png +0 -0
- lib/TinyCompress/test/helper.php +14 -0
- lib/TinyCompress/test/integration.php +77 -0
- package.xml +75 -12
- skin/adminhtml/default/default/css/Tiny/CompressImages/config.css +157 -0
- skin/adminhtml/default/default/images/Tiny/CompressImages/george-magento@2x_opt.png +0 -0
- skin/adminhtml/default/default/images/Tiny/CompressImages/george-menu-icon@2x.png +0 -0
app/code/community/Tiny/CompressImages/Block/Adminhtml/ApiNotification.php
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Block_Adminhtml_ApiNotification extends Mage_Adminhtml_Block_Abstract
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* Check if the api key is set.
|
6 |
+
*
|
7 |
+
* @return bool
|
8 |
+
*/
|
9 |
+
public function isApiKeySet()
|
10 |
+
{
|
11 |
+
$configHelper = Mage::helper('tiny_compressimages/config');
|
12 |
+
|
13 |
+
if ($configHelper->getApiKey()) {
|
14 |
+
return true;
|
15 |
+
}
|
16 |
+
|
17 |
+
return false;
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @return string
|
22 |
+
*/
|
23 |
+
public function getBackendUrl()
|
24 |
+
{
|
25 |
+
return Mage::helper('adminhtml')->getUrl('adminhtml/system_config/edit/section/tiny_compressimages/');
|
26 |
+
}
|
27 |
+
}
|
app/code/community/Tiny/CompressImages/Block/Adminhtml/System/Config/Form.php
ADDED
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Block_Adminhtml_System_Config_Form extends Mage_Adminhtml_Block_System_Config_Form
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* @var array
|
6 |
+
*/
|
7 |
+
protected $_elementTypes = array();
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Add the new form elements
|
11 |
+
*
|
12 |
+
* @return array
|
13 |
+
*/
|
14 |
+
protected function _getAdditionalElementTypes()
|
15 |
+
{
|
16 |
+
$this->_elementTypes = parent::_getAdditionalElementTypes();
|
17 |
+
|
18 |
+
$this
|
19 |
+
->_addRadioButtons()
|
20 |
+
->_addStatusIndicator()
|
21 |
+
->_addSavedIndicator()
|
22 |
+
->_addApiIndicator()
|
23 |
+
->_addAccountType()
|
24 |
+
->_addLogButtonType()
|
25 |
+
;
|
26 |
+
|
27 |
+
return $this->_elementTypes;
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Add the Off/Live/Test radio button list.
|
32 |
+
*
|
33 |
+
* @return $this
|
34 |
+
*/
|
35 |
+
protected function _addRadioButtons()
|
36 |
+
{
|
37 |
+
$this->_elementTypes['compressimages_radios'] = Mage::getConfig()
|
38 |
+
->getBlockClassName('tiny_compressimages/adminhtml_system_config_form_field_radios');
|
39 |
+
|
40 |
+
return $this;
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Add a field that shows the status indicator.
|
45 |
+
*
|
46 |
+
* @return $this
|
47 |
+
*/
|
48 |
+
protected function _addStatusIndicator()
|
49 |
+
{
|
50 |
+
$this->_elementTypes['compressimages_status'] = Mage::getConfig()
|
51 |
+
->getBlockClassName('tiny_compressimages/adminhtml_system_config_form_field_status');
|
52 |
+
|
53 |
+
return $this;
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Add a field that shows how much has been saved.
|
58 |
+
*
|
59 |
+
* @return $this
|
60 |
+
*/
|
61 |
+
protected function _addSavedIndicator()
|
62 |
+
{
|
63 |
+
$this->_elementTypes['compressimages_saved'] = Mage::getConfig()
|
64 |
+
->getBlockClassName('tiny_compressimages/adminhtml_system_config_form_field_saved');
|
65 |
+
|
66 |
+
return $this;
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Add a field that shows the api status indicator.
|
71 |
+
*
|
72 |
+
* @return $this
|
73 |
+
*/
|
74 |
+
protected function _addApiIndicator()
|
75 |
+
{
|
76 |
+
$this->_elementTypes['compressimages_api'] = Mage::getConfig()
|
77 |
+
->getBlockClassName('tiny_compressimages/adminhtml_system_config_form_field_api');
|
78 |
+
|
79 |
+
return $this;
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Add a field that shows the api status indicator.
|
84 |
+
*
|
85 |
+
* @return $this
|
86 |
+
*/
|
87 |
+
protected function _addAccountType()
|
88 |
+
{
|
89 |
+
$this->_elementTypes['compressimages_account_type'] = Mage::getConfig()
|
90 |
+
->getBlockClassName('tiny_compressimages/adminhtml_system_config_form_field_accountType');
|
91 |
+
|
92 |
+
return $this;
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Add a field that shows the api status indicator.
|
97 |
+
*
|
98 |
+
* @return $this
|
99 |
+
*/
|
100 |
+
protected function _addLogButtonType()
|
101 |
+
{
|
102 |
+
$this->_elementTypes['compressimages_log_button'] = Mage::getConfig()
|
103 |
+
->getBlockClassName('tiny_compressimages/adminhtml_system_config_form_field_logFile');
|
104 |
+
|
105 |
+
return $this;
|
106 |
+
}
|
107 |
+
}
|
app/code/community/Tiny/CompressImages/Block/Adminhtml/System/Config/Form/Field/AccountType.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Block_Adminhtml_System_Config_Form_Field_AccountType extends Varien_Data_Form_Element_Abstract
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* Generate the status for the CompressImages extension.
|
6 |
+
*
|
7 |
+
* @return string
|
8 |
+
*/
|
9 |
+
public function getElementHtml()
|
10 |
+
{
|
11 |
+
$button = '<a href="https://tinypng.com/developers/subscription" target="_blank" class="manual-links">';
|
12 |
+
$button .= Mage::helper('tiny_compressimages')->__('Credits');
|
13 |
+
$button .= '</a>';
|
14 |
+
|
15 |
+
return Mage::helper('tiny_compressimages')->__('Free (A maximum of 500 images per month)<br>' . $button);
|
16 |
+
}
|
17 |
+
}
|
app/code/community/Tiny/CompressImages/Block/Adminhtml/System/Config/Form/Field/Api.php
ADDED
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Block_Adminhtml_System_Config_Form_Field_Api extends Varien_Data_Form_Element_Abstract
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* @var Tiny_Compressimages_Helper_Config
|
6 |
+
*/
|
7 |
+
protected $_configHelper = null;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @var Tiny_Compressimages_Helper_Tinify
|
11 |
+
*/
|
12 |
+
protected $_tinifyHelper = null;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @var string
|
16 |
+
*/
|
17 |
+
protected $output = '';
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Get the config helper.
|
21 |
+
*
|
22 |
+
* @return Tiny_CompressImages_Helper_Config
|
23 |
+
*/
|
24 |
+
public function getConfigHelper()
|
25 |
+
{
|
26 |
+
if ($this->_configHelper === null) {
|
27 |
+
$this->_configHelper = Mage::helper('tiny_compressimages/config');
|
28 |
+
}
|
29 |
+
|
30 |
+
return $this->_configHelper;
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Get the Tinify helper.
|
35 |
+
*
|
36 |
+
* @return Tiny_CompressImages_Helper_Tinify
|
37 |
+
*/
|
38 |
+
public function getTinifyHelper()
|
39 |
+
{
|
40 |
+
if ($this->_tinifyHelper === null) {
|
41 |
+
$this->_tinifyHelper = Mage::helper('tiny_compressimages/tinify');
|
42 |
+
}
|
43 |
+
|
44 |
+
return $this->_tinifyHelper;
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Generate the status for the CompressImages extension.
|
49 |
+
*
|
50 |
+
* @return string
|
51 |
+
*/
|
52 |
+
public function getElementHtml()
|
53 |
+
{
|
54 |
+
$this
|
55 |
+
->_getStatusHtml()
|
56 |
+
->_getJavascript()
|
57 |
+
;
|
58 |
+
|
59 |
+
return $this->output;
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Generate the status message.
|
64 |
+
*
|
65 |
+
* @return $this
|
66 |
+
*/
|
67 |
+
protected function _getStatusHtml()
|
68 |
+
{
|
69 |
+
$result = $this->getTinifyHelper()->getApiStatus(true);
|
70 |
+
|
71 |
+
$this->output .= $result['message'];
|
72 |
+
|
73 |
+
return $this;
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Generate the javascript to make the Ajax call to check the API.
|
78 |
+
*
|
79 |
+
* @return $this
|
80 |
+
*/
|
81 |
+
protected function _getJavascript()
|
82 |
+
{
|
83 |
+
$js = '';
|
84 |
+
|
85 |
+
if ($this->getConfigHelper()->isEnabled()) {
|
86 |
+
$js
|
87 |
+
.= '<script type="text/javascript">
|
88 |
+
var url = "' . Mage::helper("adminhtml")->getUrl(
|
89 |
+
'adminhtml/CompressImagesAdminhtml_status/getApiStatus'
|
90 |
+
) . '";
|
91 |
+
|
92 |
+
document.observe("dom:loaded", function() {
|
93 |
+
new Ajax.Request(url,
|
94 |
+
{
|
95 |
+
method: "post",
|
96 |
+
onSuccess: function (data) {
|
97 |
+
var result = data.responseText.evalJSON(true);
|
98 |
+
if (result.status == "success") {
|
99 |
+
$("compressimages_api_status").innerHTML = result.message;
|
100 |
+
}
|
101 |
+
}
|
102 |
+
})
|
103 |
+
});
|
104 |
+
</script>';
|
105 |
+
}
|
106 |
+
|
107 |
+
$this->output .= $js;
|
108 |
+
|
109 |
+
return $this;
|
110 |
+
}
|
111 |
+
}
|
app/code/community/Tiny/CompressImages/Block/Adminhtml/System/Config/Form/Field/LogFile.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Block_Adminhtml_System_Config_Form_Field_LogFile extends Varien_Data_Form_Element_Abstract
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* Template file used
|
6 |
+
*
|
7 |
+
* @var string
|
8 |
+
*/
|
9 |
+
protected $_template = 'Tiny/CompressImages/system/config/form/field/log_file.phtml';
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Get the URL where we can download the log file.
|
13 |
+
*
|
14 |
+
* @return string
|
15 |
+
*/
|
16 |
+
public function getDownloadUrl()
|
17 |
+
{
|
18 |
+
return Mage::helper('adminhtml')->getUrl('adminhtml/CompressImagesAdminhtml_config/downloadLogs');
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Helper to check if the log file exists.
|
23 |
+
*
|
24 |
+
* @return bool
|
25 |
+
*/
|
26 |
+
public function logFileExists()
|
27 |
+
{
|
28 |
+
return Mage::helper('tiny_compressimages')->getLogFileExists();
|
29 |
+
}
|
30 |
+
}
|
app/code/community/Tiny/CompressImages/Block/Adminhtml/System/Config/Form/Field/LogStatus.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Block_Adminhtml_System_Config_Form_Field_LogStatus extends Mage_Adminhtml_Block_Abstract implements Varien_Data_Form_Element_Renderer_Interface
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* Template file used
|
6 |
+
*
|
7 |
+
* @var string
|
8 |
+
*/
|
9 |
+
protected $_template = 'Tiny/CompressImages/system/config/form/field/log_status.phtml';
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Render template
|
13 |
+
*
|
14 |
+
* @param Varien_Data_Form_Element_Abstract $element
|
15 |
+
*
|
16 |
+
* @return string
|
17 |
+
*/
|
18 |
+
public function render(Varien_Data_Form_Element_Abstract $element)
|
19 |
+
{
|
20 |
+
$this->setElement($element);
|
21 |
+
|
22 |
+
return $this->toHtml();
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @return string
|
27 |
+
*/
|
28 |
+
public function getCleanImagesUrl()
|
29 |
+
{
|
30 |
+
$url = Mage::helper("adminhtml")->getUrl('adminhtml/CompressImagesAdminhtml_config/clearCache');
|
31 |
+
|
32 |
+
return $url;
|
33 |
+
}
|
34 |
+
}
|
app/code/community/Tiny/CompressImages/Block/Adminhtml/System/Config/Form/Field/Radios.php
ADDED
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Block_Adminhtml_System_Config_Form_Field_Radios extends Varien_Data_Form_Element_Radios
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* Get the html for each individual radio button.
|
6 |
+
*
|
7 |
+
* @param array|Varien_Object $option
|
8 |
+
* @param string $selected
|
9 |
+
*
|
10 |
+
* @return string
|
11 |
+
*/
|
12 |
+
protected function _optionToHtml($option, $selected)
|
13 |
+
{
|
14 |
+
$html = '<div class="wrapper-radio">';
|
15 |
+
$html .= '<input type="radio"'.$this->serialize(array('name', 'class', 'style', 'disabled'));
|
16 |
+
if (is_array($option)) {
|
17 |
+
$html.= 'value="'
|
18 |
+
. $this->_escape($option['value'])
|
19 |
+
. '" id="'
|
20 |
+
. $this->getHtmlId()
|
21 |
+
. $option['value']
|
22 |
+
. '"';
|
23 |
+
|
24 |
+
if ($option['value'] == $selected) {
|
25 |
+
$html .= ' checked="checked"';
|
26 |
+
}
|
27 |
+
|
28 |
+
$html .= ' />';
|
29 |
+
|
30 |
+
$html .= '<label class="inline" for="'
|
31 |
+
. $this->getHtmlId()
|
32 |
+
. $option['value']
|
33 |
+
. '">'
|
34 |
+
. $option['label']
|
35 |
+
. '</label>';
|
36 |
+
} else if ($option instanceof Varien_Object) {
|
37 |
+
$html .= 'id="'
|
38 |
+
. $this->getHtmlId()
|
39 |
+
. $option->getValue()
|
40 |
+
. '"'
|
41 |
+
. $option->serialize(
|
42 |
+
array(
|
43 |
+
'label',
|
44 |
+
'title',
|
45 |
+
'value',
|
46 |
+
'class',
|
47 |
+
'style',
|
48 |
+
)
|
49 |
+
);
|
50 |
+
|
51 |
+
if (in_array($option->getValue(), $selected)) {
|
52 |
+
$html .= ' checked="checked"';
|
53 |
+
}
|
54 |
+
|
55 |
+
$html .= ' />';
|
56 |
+
|
57 |
+
$html .= '<label class="inline" for="'
|
58 |
+
. $this->getHtmlId()
|
59 |
+
. $option->getValue()
|
60 |
+
. '">'
|
61 |
+
. $option->getLabel()
|
62 |
+
. '</label>';
|
63 |
+
}
|
64 |
+
|
65 |
+
$html.= '</div>';
|
66 |
+
|
67 |
+
return $html;
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Wrap the output in a container div.
|
72 |
+
*
|
73 |
+
* @return string
|
74 |
+
*/
|
75 |
+
public function getElementHtml()
|
76 |
+
{
|
77 |
+
$html = parent::getElementHtml();
|
78 |
+
|
79 |
+
return '<div class="radio-container">' . $html . '</div>';
|
80 |
+
}
|
81 |
+
}
|
app/code/community/Tiny/CompressImages/Block/Adminhtml/System/Config/Form/Field/Saved.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Block_Adminhtml_System_Config_Form_Field_Saved extends Varien_Data_Form_Element_Abstract
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* Generate the status for the CompressImages extension.
|
6 |
+
*
|
7 |
+
* @return string
|
8 |
+
*/
|
9 |
+
public function getElementHtml()
|
10 |
+
{
|
11 |
+
$data = Mage::getModel('tiny_compressimages/totals')->getTotalCompressionInformation();
|
12 |
+
|
13 |
+
return Mage::helper('tiny_compressimages')->__(
|
14 |
+
'Saved %s%% over a total of %s compressions',
|
15 |
+
$data['percentageSaved'],
|
16 |
+
$data['totalCompressions']
|
17 |
+
);
|
18 |
+
|
19 |
+
}
|
20 |
+
}
|
app/code/community/Tiny/CompressImages/Block/Adminhtml/System/Config/Form/Field/Status.php
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Block_Adminhtml_System_Config_Form_Field_Status extends Varien_Data_Form_Element_Abstract
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* @var Tiny_CompressImages_Helper_Data
|
6 |
+
*/
|
7 |
+
protected $_helper = null;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* The constructor
|
11 |
+
*/
|
12 |
+
public function __construct($attributes = array())
|
13 |
+
{
|
14 |
+
parent::__construct($attributes);
|
15 |
+
|
16 |
+
$this->_helper = Mage::helper('tiny_compressimages');
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Generate the status for the CompressImages extension.
|
21 |
+
*
|
22 |
+
* @return string
|
23 |
+
*/
|
24 |
+
public function getElementHtml()
|
25 |
+
{
|
26 |
+
/** @var Tiny_CompressImages_Helper_Config $configHelper */
|
27 |
+
$configHelper = Mage::helper('tiny_compressimages/config');
|
28 |
+
|
29 |
+
if (!$configHelper->isConfigured()) {
|
30 |
+
if (!$configHelper->getApiKey()) {
|
31 |
+
return '<span class="compressimages-api-deactivated">'
|
32 |
+
. $this->_helper->__('Please enter your api key to check the compression count.')
|
33 |
+
. '</span>';
|
34 |
+
}
|
35 |
+
|
36 |
+
if (!$configHelper->isEnabled()) {
|
37 |
+
return '<span class="compressimages-api-deactivated">'
|
38 |
+
. $this->_helper->__('Please enable the extension to check the compression count.')
|
39 |
+
. '</span>';
|
40 |
+
}
|
41 |
+
}
|
42 |
+
|
43 |
+
// TODO: Find a method to determine whether to use our or Tinify's compression count
|
44 |
+
$compressionCount = Mage::helper('tiny_compressimages/tinify')->compressionCount();
|
45 |
+
|
46 |
+
if ($configHelper->getApiKey() == '') {
|
47 |
+
return $this->_helper->__('Add your TinyPNG API key to check the status');
|
48 |
+
}
|
49 |
+
|
50 |
+
if ($compressionCount == 0 || $compressionCount == 500) {
|
51 |
+
$button = '<a href="https://tinypng.com/developers/subscription" target="_blank" id="tinypng_check_status" class="tiny-compressimages-button-orange scalable">';
|
52 |
+
$button .= '<span><span><span>Upgrade</span></span></span></a>';
|
53 |
+
|
54 |
+
$onhold = $this->_helper->__('Compression on hold. 500 free images compressed this month.');
|
55 |
+
$upgrade = $this->_helper->__('Upgrade your account to compress more images');
|
56 |
+
|
57 |
+
return '<span class="compressimages-api-deactivated">' . $onhold . '</span>' . $upgrade . '<br>' . $button;
|
58 |
+
}
|
59 |
+
|
60 |
+
return $this->_helper->__(
|
61 |
+
'There are %s compressions done this month.',
|
62 |
+
$compressionCount
|
63 |
+
);
|
64 |
+
}
|
65 |
+
}
|
app/code/community/Tiny/CompressImages/Block/Adminhtml/System/Config/Form/Field/SupportTab.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Block_Adminhtml_System_Config_Form_Field_SupportTab
|
3 |
+
extends Mage_Adminhtml_Block_Abstract
|
4 |
+
implements Varien_Data_Form_Element_Renderer_Interface
|
5 |
+
{
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Template file used
|
9 |
+
*
|
10 |
+
* @var string
|
11 |
+
*/
|
12 |
+
protected $_template = 'Tiny/CompressImages/system/config/form/field/support_tab.phtml';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Render fieldset html
|
16 |
+
*
|
17 |
+
* @param Varien_Data_Form_Element_Abstract $element
|
18 |
+
* @return string
|
19 |
+
*/
|
20 |
+
public function render(Varien_Data_Form_Element_Abstract $element)
|
21 |
+
{
|
22 |
+
$this->setElement($element);
|
23 |
+
|
24 |
+
return $this->toHtml();
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Get the current version of the PostNL extension's code base.
|
29 |
+
*
|
30 |
+
* @return string
|
31 |
+
*/
|
32 |
+
public function getModuleVersion()
|
33 |
+
{
|
34 |
+
$version = (string) Mage::getConfig()->getModuleConfig('Tiny_CompressImages')->version;
|
35 |
+
|
36 |
+
return $version;
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Get the current stability of the PostNL extension's code base.
|
41 |
+
*
|
42 |
+
* @return string
|
43 |
+
*/
|
44 |
+
public function getModuleStability()
|
45 |
+
{
|
46 |
+
$stability = (string) Mage::getConfig()->getModuleConfig('Tiny_CompressImages')->stability;
|
47 |
+
|
48 |
+
return $stability;
|
49 |
+
}
|
50 |
+
}
|
app/code/community/Tiny/CompressImages/Exception.php
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Exception extends Exception {}
|
app/code/community/Tiny/CompressImages/Helper/Config.php
ADDED
@@ -0,0 +1,184 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Helper_Config extends Mage_Core_Helper_Abstract
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* Configuration XPATH
|
6 |
+
*/
|
7 |
+
const XPATH_ENABLED = 'tiny_compressimages/advanced/enabled';
|
8 |
+
const XPATH_API_KEY = 'tiny_compressimages/settings/api_key';
|
9 |
+
const XPATH_IMAGE_TYPE_BASE = 'tiny_compressimages/image_types/base_images';
|
10 |
+
const XPATH_IMAGE_TYPE_SMALL = 'tiny_compressimages/image_types/small_images';
|
11 |
+
const XPATH_IMAGE_TYPE_THUMBNAIL = 'tiny_compressimages/image_types/thumbnails';
|
12 |
+
const XPATH_IMAGE_TYPE_SWATCHES = 'tiny_compressimages/image_types/swatches';
|
13 |
+
const XPATH_LOGGING_MODE = 'tiny_compressimages/advanced/logging_mode';
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Return the enabled modus (off, test or live)
|
17 |
+
*
|
18 |
+
* @param null $store
|
19 |
+
*
|
20 |
+
* @return int
|
21 |
+
*/
|
22 |
+
protected function _getEnabled($store = null)
|
23 |
+
{
|
24 |
+
return Mage::getStoreConfig(self::XPATH_ENABLED, $store);
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Is the extension enabled
|
29 |
+
*
|
30 |
+
* @param null|int $store
|
31 |
+
*
|
32 |
+
* @return bool
|
33 |
+
*/
|
34 |
+
public function isEnabled($store = null)
|
35 |
+
{
|
36 |
+
$enabledValue = $this->_getEnabled($store);
|
37 |
+
|
38 |
+
if ($enabledValue != 0) {
|
39 |
+
return true;
|
40 |
+
} else {
|
41 |
+
return false;
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Is the extension currently in test mode
|
47 |
+
*
|
48 |
+
* @param null|int $store
|
49 |
+
*
|
50 |
+
* @return bool
|
51 |
+
*/
|
52 |
+
public function isTestMode($store = null)
|
53 |
+
{
|
54 |
+
$enabledValue = $this->_getEnabled($store);
|
55 |
+
|
56 |
+
if ($enabledValue == 1) {
|
57 |
+
return true;
|
58 |
+
} else {
|
59 |
+
return false;
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* @param null $store
|
65 |
+
*
|
66 |
+
* @return bool
|
67 |
+
*/
|
68 |
+
public function isConfigured($store = null)
|
69 |
+
{
|
70 |
+
if (!$this->isEnabled($store)) {
|
71 |
+
return false;
|
72 |
+
}
|
73 |
+
|
74 |
+
if (!$this->getApiKey($store)) {
|
75 |
+
return false;
|
76 |
+
}
|
77 |
+
|
78 |
+
return true;
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Return the API Key
|
83 |
+
*
|
84 |
+
* @param null|int $store
|
85 |
+
*
|
86 |
+
* @return string
|
87 |
+
*/
|
88 |
+
public function getApiKey($store = null)
|
89 |
+
{
|
90 |
+
return Mage::getStoreConfig(self::XPATH_API_KEY, $store);
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Lets you know if base images should be compressed.
|
95 |
+
*
|
96 |
+
* @param null $store
|
97 |
+
*
|
98 |
+
* @return mixed
|
99 |
+
*/
|
100 |
+
public function isBaseImageTypeEnabledForCompression($store = null)
|
101 |
+
{
|
102 |
+
return Mage::getStoreConfig(self::XPATH_IMAGE_TYPE_BASE, $store);
|
103 |
+
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Lets you know if small images should be compressed.
|
107 |
+
*
|
108 |
+
* @param null $store
|
109 |
+
*
|
110 |
+
* @return mixed
|
111 |
+
*/
|
112 |
+
public function isSmallImageTypeEnabledForCompression($store = null)
|
113 |
+
{
|
114 |
+
return Mage::getStoreConfig(self::XPATH_IMAGE_TYPE_SMALL, $store);
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Lets you know if thumbnail-sized images should be compressed.
|
119 |
+
*
|
120 |
+
* @param null $store
|
121 |
+
*
|
122 |
+
* @return mixed
|
123 |
+
*/
|
124 |
+
public function isThumbnailTypeEnabledForCompression($store = null)
|
125 |
+
{
|
126 |
+
return Mage::getStoreConfig(self::XPATH_IMAGE_TYPE_THUMBNAIL, $store);
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Lets you know if swachtes (small images used to select product attributes) images should be compressed.
|
131 |
+
*
|
132 |
+
* @param null $store
|
133 |
+
*
|
134 |
+
* @return mixed
|
135 |
+
*/
|
136 |
+
public function isSwatchTypeEnabledForCompression($store = null)
|
137 |
+
{
|
138 |
+
return Mage::getStoreConfig(self::XPATH_IMAGE_TYPE_SWATCHES, $store);
|
139 |
+
}
|
140 |
+
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Returns an array of image types that can be compressed by CompressImages
|
144 |
+
*
|
145 |
+
* @param null $store
|
146 |
+
*
|
147 |
+
* @return mixed
|
148 |
+
*/
|
149 |
+
public function getProductImageTypesToCompress($store = null)
|
150 |
+
{
|
151 |
+
$imageTypes = array();
|
152 |
+
|
153 |
+
if ($this->isBaseImageTypeEnabledForCompression($store)) {
|
154 |
+
$imageTypes[] = 'image';
|
155 |
+
}
|
156 |
+
|
157 |
+
if ($this->isSmallImageTypeEnabledForCompression($store)) {
|
158 |
+
$imageTypes[] = 'small_image';
|
159 |
+
}
|
160 |
+
|
161 |
+
if ($this->isThumbnailTypeEnabledForCompression($store)) {
|
162 |
+
$imageTypes[] = 'thumbnail';
|
163 |
+
$imageTypes[] = 'media_image';
|
164 |
+
}
|
165 |
+
|
166 |
+
if ($this->isSwatchTypeEnabledForCompression($store)) {
|
167 |
+
$imageTypes[] = 'swatches';
|
168 |
+
}
|
169 |
+
|
170 |
+
return $imageTypes;
|
171 |
+
}
|
172 |
+
|
173 |
+
/**
|
174 |
+
* Returns the logging mode.
|
175 |
+
*
|
176 |
+
* @param null $store
|
177 |
+
*
|
178 |
+
* @return mixed
|
179 |
+
*/
|
180 |
+
public function getLoggingMode($store = null)
|
181 |
+
{
|
182 |
+
return Mage::getStoreConfig(self::XPATH_LOGGING_MODE, $store);
|
183 |
+
}
|
184 |
+
}
|
app/code/community/Tiny/CompressImages/Helper/Data.php
ADDED
@@ -0,0 +1,205 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Helper_Data extends Mage_Core_Helper_Abstract
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* The name of the logfile.
|
6 |
+
*
|
7 |
+
* @var string
|
8 |
+
*/
|
9 |
+
protected $logFile = 'image-optimization.log';
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @var Tiny_CompressImages_Helper_Config
|
13 |
+
*/
|
14 |
+
protected $_configHelper = null;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Class constructor
|
18 |
+
*/
|
19 |
+
public function __construct()
|
20 |
+
{
|
21 |
+
$this->_configHelper = Mage::helper('tiny_compressimages/config');
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @param $msg
|
26 |
+
* @param $type
|
27 |
+
*
|
28 |
+
* @return $this;
|
29 |
+
*/
|
30 |
+
public function log($msg, $type = null, $store = null)
|
31 |
+
{
|
32 |
+
$logginModes = $this->_loggingArray($store);
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Always log exceptions. $msg should be an instanceof Exception!
|
36 |
+
*/
|
37 |
+
if ($msg instanceof Exception) {
|
38 |
+
$type = 'exception';
|
39 |
+
$msg = $msg->__toString();
|
40 |
+
}
|
41 |
+
|
42 |
+
if (!in_array($type, $logginModes)) {
|
43 |
+
return $this;
|
44 |
+
}
|
45 |
+
|
46 |
+
Mage::log($msg, null, $this->logFile, true);
|
47 |
+
|
48 |
+
return $this;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @param $store
|
53 |
+
*
|
54 |
+
* @return array
|
55 |
+
*/
|
56 |
+
protected function _loggingArray($store)
|
57 |
+
{
|
58 |
+
switch ($this->_configHelper->getLoggingMode($store))
|
59 |
+
{
|
60 |
+
case 'only_exceptions':
|
61 |
+
$logginArray = array('exception');
|
62 |
+
break;
|
63 |
+
case 'fail_and_exceptions':
|
64 |
+
$logginArray = array('error', 'exception');
|
65 |
+
break;
|
66 |
+
case 'all':
|
67 |
+
$logginArray = array('info', 'error', 'exception');
|
68 |
+
break;
|
69 |
+
case 'off':
|
70 |
+
default:
|
71 |
+
$logginArray = array('');
|
72 |
+
}
|
73 |
+
|
74 |
+
return $logginArray;
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Returns whether the log file exists or not
|
79 |
+
*
|
80 |
+
* @return bool
|
81 |
+
*/
|
82 |
+
public function getLogFileExists()
|
83 |
+
{
|
84 |
+
$filePath = $this->getLogFilePath();
|
85 |
+
|
86 |
+
if (!@file_exists($filePath)) {
|
87 |
+
return false;
|
88 |
+
}
|
89 |
+
|
90 |
+
return true;
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Returns the file path of the log file
|
95 |
+
*
|
96 |
+
* @return string
|
97 |
+
*/
|
98 |
+
public function getLogFilePath()
|
99 |
+
{
|
100 |
+
$logDir = Mage::getBaseDir('log');
|
101 |
+
|
102 |
+
$filePath = $logDir . DS . $this->logFile;
|
103 |
+
|
104 |
+
return $filePath;
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Get the name of the logfile.
|
109 |
+
*
|
110 |
+
* @return string
|
111 |
+
*/
|
112 |
+
public function getLogFilename()
|
113 |
+
{
|
114 |
+
return $this->logFile;
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Copied from https://gist.github.com/jblyberg/1572386
|
119 |
+
*
|
120 |
+
* @param $datefrom
|
121 |
+
* @param int $dateto
|
122 |
+
*
|
123 |
+
* @return string
|
124 |
+
*/
|
125 |
+
public function timeAgo($datefrom, $dateto = -1) {
|
126 |
+
$datefrom = strtotime($datefrom);
|
127 |
+
if ($datefrom <= 0) {
|
128 |
+
return $this->__('A long time ago');
|
129 |
+
}
|
130 |
+
if ($dateto == -1) {
|
131 |
+
$dateto = time();
|
132 |
+
}
|
133 |
+
$difference = $dateto - $datefrom;
|
134 |
+
if ($difference < 60) {
|
135 |
+
$interval = "s";
|
136 |
+
} elseif ($difference >= 60 && $difference < 60 * 60) {
|
137 |
+
$interval = "n";
|
138 |
+
} elseif ($difference >= 60 * 60 && $difference < 60 * 60 * 24) {
|
139 |
+
$interval = "h";
|
140 |
+
} elseif ($difference >= 60 * 60 * 24 && $difference < 60 * 60 * 24 * 7) {
|
141 |
+
$interval = "d";
|
142 |
+
} elseif ($difference >= 60 * 60 * 24 * 7 && $difference < 60 * 60 * 24 * 30) {
|
143 |
+
$interval = "ww";
|
144 |
+
} elseif ($difference >= 60 * 60 * 24 * 30 && $difference < 60 * 60 * 24 * 365) {
|
145 |
+
$interval = "m";
|
146 |
+
} elseif ($difference >= 60 * 60 * 24 * 365) {
|
147 |
+
$interval = "y";
|
148 |
+
}
|
149 |
+
switch ($interval) {
|
150 |
+
case "m":
|
151 |
+
$months_difference = floor($difference / 60 / 60 / 24 / 29);
|
152 |
+
while (mktime(date("H", $datefrom), date("i", $datefrom), date("s", $datefrom), date("n", $datefrom) + ($months_difference), date("j", $dateto), date("Y", $datefrom)) < $dateto) {
|
153 |
+
$months_difference++;
|
154 |
+
}
|
155 |
+
$datediff = $months_difference;
|
156 |
+
if ($datediff == 12) {
|
157 |
+
$datediff--;
|
158 |
+
}
|
159 |
+
$res = ($datediff == 1) ? $this->__('%s month ago', $datediff) : $this->__('%s months ago', $datediff);
|
160 |
+
break;
|
161 |
+
case "y":
|
162 |
+
$datediff = floor($difference / 60 / 60 / 24 / 365);
|
163 |
+
$res = ($datediff == 1) ? $this->__('%s year ago', $datediff) : $this->__('%s years ago', $datediff);
|
164 |
+
break;
|
165 |
+
case "d":
|
166 |
+
$datediff = floor($difference / 60 / 60 / 24);
|
167 |
+
$res = ($datediff == 1) ? $this->__('%s day ago', $datediff) : $this->__('%s days ago', $datediff);
|
168 |
+
break;
|
169 |
+
case "ww":
|
170 |
+
$datediff = floor($difference / 60 / 60 / 24 / 7);
|
171 |
+
$res = ($datediff == 1) ? $this->__('%s week ago', $datediff) : $this->__('%s weeks ago', $datediff);
|
172 |
+
break;
|
173 |
+
case "h":
|
174 |
+
$datediff = floor($difference / 60 / 60);
|
175 |
+
$res = ($datediff == 1) ? $this->__('%s hour ago', $datediff) : $this->__('%s hours ago', $datediff);
|
176 |
+
break;
|
177 |
+
case "n":
|
178 |
+
$datediff = floor($difference / 60);
|
179 |
+
$res = ($datediff == 1) ? $this->__('%s minute ago', $datediff) : $this->__('%s minutes ago', $datediff);
|
180 |
+
break;
|
181 |
+
case "s":
|
182 |
+
$datediff = $difference;
|
183 |
+
$res = ($datediff == 1) ? $this->__('%s second ago', $datediff) : $this->__('%s seconds ago', $datediff);
|
184 |
+
break;
|
185 |
+
}
|
186 |
+
|
187 |
+
return $res;
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Retrieve a human readable file size.
|
192 |
+
* Copied from http://jeffreysambells.com/2012/10/25/human-readable-filesize-php
|
193 |
+
*
|
194 |
+
* @param $bytes
|
195 |
+
*
|
196 |
+
* @return string
|
197 |
+
*/
|
198 |
+
public function fileSize($bytes)
|
199 |
+
{
|
200 |
+
$size = array('B','kB','MB','GB','TB','PB','EB','ZB','YB');
|
201 |
+
$factor = floor((strlen($bytes) - 1) / 3);
|
202 |
+
|
203 |
+
return sprintf('%.0f ', $bytes / pow(1024, $factor)) . @$size[$factor];
|
204 |
+
}
|
205 |
+
}
|
app/code/community/Tiny/CompressImages/Helper/Tinify.php
ADDED
@@ -0,0 +1,750 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Helper_Tinify extends Mage_Core_Helper_Abstract
|
3 |
+
{
|
4 |
+
const TINY_COMPRESSIMAGES_MEDIA_DIRECTORY = '/media/catalog/product/optimized';
|
5 |
+
|
6 |
+
const CACHE_KEY = 'tiny_compressimages_api_status';
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @var bool $allowCompression
|
10 |
+
*/
|
11 |
+
protected $allowCompression;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var bool $isProductTypeAllowed
|
15 |
+
*/
|
16 |
+
protected $isProductTypeAllowed = true;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @var string $destinationSubdir
|
20 |
+
*/
|
21 |
+
protected $destinationSubdir = '';
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @var SplFileInfo $newFile
|
25 |
+
*/
|
26 |
+
protected $newFile = '';
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @var string $imageWidth
|
30 |
+
*/
|
31 |
+
protected $imageWidth = '';
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @var string $imageHeight
|
35 |
+
*/
|
36 |
+
protected $imageHeight = '';
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @var string $hashBefore
|
40 |
+
*/
|
41 |
+
protected $hashBefore = '';
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @var string $hashAfter
|
45 |
+
*/
|
46 |
+
protected $hashAfter = '';
|
47 |
+
|
48 |
+
/**
|
49 |
+
* @var int $bytesBefore
|
50 |
+
*/
|
51 |
+
protected $bytesBefore = 0;
|
52 |
+
|
53 |
+
/**
|
54 |
+
* @var int $bytesAfter
|
55 |
+
*/
|
56 |
+
protected $bytesAfter = 0;
|
57 |
+
|
58 |
+
/**
|
59 |
+
* @var null|int $parentId
|
60 |
+
*/
|
61 |
+
protected $parentId = null;
|
62 |
+
|
63 |
+
/**
|
64 |
+
* @var bool $isCompressedBefore
|
65 |
+
*/
|
66 |
+
protected $isCompressedBefore = false;
|
67 |
+
|
68 |
+
/**
|
69 |
+
* @var int $isUsedAsSource
|
70 |
+
*/
|
71 |
+
protected $isUsedAsSource = 1;
|
72 |
+
|
73 |
+
/**
|
74 |
+
* @var Tiny_CompressImages_Helper_Data
|
75 |
+
*/
|
76 |
+
protected $helper;
|
77 |
+
|
78 |
+
/**
|
79 |
+
* @var int $storeId
|
80 |
+
*/
|
81 |
+
protected $storeId = 0;
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @var Tiny_CompressImages_Helper_Config
|
85 |
+
*/
|
86 |
+
protected $configHelper;
|
87 |
+
|
88 |
+
/**
|
89 |
+
* @var null|Tiny_CompressImages_Model_Image
|
90 |
+
*/
|
91 |
+
protected $_model = null;
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Constructor
|
95 |
+
*/
|
96 |
+
public function __construct() {
|
97 |
+
$this->_registerAutoloader();
|
98 |
+
$this->_setIdentifier();
|
99 |
+
|
100 |
+
$this->helper = Mage::helper('tiny_compressimages');
|
101 |
+
$this->configHelper = Mage::helper('tiny_compressimages/config');
|
102 |
+
|
103 |
+
$apiKey = $this->configHelper->getApiKey($this->storeId);
|
104 |
+
$this->allowCompression = $this->validate($apiKey);
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Register our custom autoloader, this is needed because Magento can't handle PHP's namespaces.
|
109 |
+
*
|
110 |
+
* @return $this
|
111 |
+
*/
|
112 |
+
protected function _registerAutoloader()
|
113 |
+
{
|
114 |
+
require_once(Mage::getBaseDir('lib') . '/TinyCompress/lib/Tinify.php');
|
115 |
+
|
116 |
+
spl_autoload_register( array($this, 'load'), true, true );
|
117 |
+
|
118 |
+
return $this;
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Set the app identifier
|
123 |
+
*
|
124 |
+
* @return $this
|
125 |
+
*/
|
126 |
+
protected function _setIdentifier()
|
127 |
+
{
|
128 |
+
$version = Mage::getVersion();
|
129 |
+
$edition = Mage::getEdition();
|
130 |
+
|
131 |
+
Tinify\setAppIdentifier('Magento ' . $edition . ' ' . $version);
|
132 |
+
|
133 |
+
return $this;
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* This function autoloads Tinify classes
|
138 |
+
*
|
139 |
+
* @param string $class
|
140 |
+
*/
|
141 |
+
protected static function load($class)
|
142 |
+
{
|
143 |
+
/**
|
144 |
+
* Project-specific namespace prefix
|
145 |
+
*/
|
146 |
+
$prefix = 'Tinify';
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Base directory for the namespace prefix
|
150 |
+
*/
|
151 |
+
$base_dir = Mage::getBaseDir('lib') . '/TinyCompress/lib/';
|
152 |
+
|
153 |
+
if (strpos($class, $prefix) !== 0) {
|
154 |
+
/**
|
155 |
+
* No, move to the next registered autoloader
|
156 |
+
*/
|
157 |
+
return;
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Get the relative class name
|
162 |
+
*/
|
163 |
+
$class_directory = str_replace('\\', '/', $class);
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Tinify has all its exceptions in one file, so take that in account
|
167 |
+
*/
|
168 |
+
if (substr($class_directory, -9) == 'Exception') {
|
169 |
+
$class_array = explode('/', $class_directory);
|
170 |
+
$class_array[count($class_array) - 1] = 'Exception';
|
171 |
+
|
172 |
+
$class_directory = implode('/', $class_array);
|
173 |
+
}
|
174 |
+
|
175 |
+
/**
|
176 |
+
* Replace the namespace prefix with the base directory, replace namespace
|
177 |
+
* separators with directory separators in the relative class name, append
|
178 |
+
* with .php
|
179 |
+
*/
|
180 |
+
$file = $base_dir . $class_directory . '.php';
|
181 |
+
|
182 |
+
/**
|
183 |
+
* if the file exists, require it
|
184 |
+
*/
|
185 |
+
if (file_exists($file)) {
|
186 |
+
require $file;
|
187 |
+
}
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Validate the Tinify Api Key.
|
192 |
+
*
|
193 |
+
* @param $apiKey
|
194 |
+
*
|
195 |
+
* @return bool
|
196 |
+
*/
|
197 |
+
public function validate($apiKey) {
|
198 |
+
if (empty($apiKey)) {
|
199 |
+
return false;
|
200 |
+
}
|
201 |
+
|
202 |
+
\Tinify\setKey($apiKey);
|
203 |
+
|
204 |
+
try {
|
205 |
+
\Tinify\validate();
|
206 |
+
} catch (\Tinify\Exception $e) {
|
207 |
+
$this->helper->log($e->getMessage(), null, $this->storeId);
|
208 |
+
return false;
|
209 |
+
}
|
210 |
+
|
211 |
+
return true;
|
212 |
+
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* Compress the image.
|
216 |
+
*
|
217 |
+
* @return bool
|
218 |
+
* @throws Tiny_CompressImages_Exception
|
219 |
+
*/
|
220 |
+
public function compress()
|
221 |
+
{
|
222 |
+
if (!$this->configHelper->isEnabled($this->storeId)) {
|
223 |
+
$this->helper->log('The TinyPNG module is disabled, not compressing ' . $this->newFile->getPathname(), 'info', $this->storeId);
|
224 |
+
|
225 |
+
return false;
|
226 |
+
}
|
227 |
+
|
228 |
+
if (!$this->_isCompressionAllowed()) {
|
229 |
+
$this->helper->log('Compression is not allowed at this moment.', 'info', $this->storeId);
|
230 |
+
|
231 |
+
return false;
|
232 |
+
}
|
233 |
+
|
234 |
+
$this->_prepareCompression();
|
235 |
+
|
236 |
+
if ($this->_isInOptimizedMediaDirectory()) {
|
237 |
+
$this->helper->log(
|
238 |
+
$this->newFile->getPathname(). ' is propably compressed before and can be found in the compression folder'
|
239 |
+
);
|
240 |
+
$this
|
241 |
+
->_SetCompressionAsPreviously()
|
242 |
+
->_saveCompression();
|
243 |
+
return true;
|
244 |
+
}
|
245 |
+
|
246 |
+
/**
|
247 |
+
* Check if this file is compressed before. If that is the case, copy it to this location.
|
248 |
+
*/
|
249 |
+
if ($this->_isAlreadyCompressed()) {
|
250 |
+
return true;
|
251 |
+
}
|
252 |
+
|
253 |
+
try {
|
254 |
+
$message = '';
|
255 |
+
$input = \Tinify\fromFile($this->newFile->getPathname());
|
256 |
+
|
257 |
+
if ($this->configHelper->isTestMode($this->storeId)) {
|
258 |
+
$message .= 'TESTMODE - ';
|
259 |
+
|
260 |
+
if (function_exists('mb_strlen')) {
|
261 |
+
$this->bytesAfter = mb_strlen($input->toBuffer(), '8bit');
|
262 |
+
} else {
|
263 |
+
$this->bytesAfter = strlen($input->toBuffer());
|
264 |
+
}
|
265 |
+
|
266 |
+
if (!is_writable($this->newFile->getPathname())) {
|
267 |
+
throw new Tiny_CompressImages_Exception('The file ' . $this->newFile->getPathname() . ' is not writable!');
|
268 |
+
}
|
269 |
+
} else {
|
270 |
+
$input->toFile($this->newFile->getPathname());
|
271 |
+
$this->bytesAfter = $this->_getFileSize($this->newFile);
|
272 |
+
}
|
273 |
+
|
274 |
+
$this->_model->createPath();
|
275 |
+
|
276 |
+
$compressionFile = $this->_model->getFilepathOptimized();
|
277 |
+
$this->helper->log('Write to compression Folder : '. $compressionFile, 'info', $this->storeId);
|
278 |
+
file_put_contents($compressionFile, $input->toBuffer());
|
279 |
+
|
280 |
+
$message .=
|
281 |
+
'Compressed: ' . $this->newFile->getFilename() . ' - ' .
|
282 |
+
'Variant: '. $this->destinationSubdir . ' - ' .
|
283 |
+
'Size (WxH): ' . $this->imageWidth . 'x' . $this->imageHeight . ' - ' .
|
284 |
+
'Bytes saved: ' . ($this->bytesBefore - $this->bytesAfter) . ' - ' .
|
285 |
+
'Compressed Before'. $this->isCompressedBefore . ' - '.
|
286 |
+
'Path: ' . $compressionFile;
|
287 |
+
|
288 |
+
$this->helper->log($message, 'info', $this->storeId);
|
289 |
+
} catch (\Tinify\Exception $e) {
|
290 |
+
$this->helper->log($e, null, $this->storeId);
|
291 |
+
return false;
|
292 |
+
}
|
293 |
+
|
294 |
+
$this->_saveCompression();
|
295 |
+
|
296 |
+
return true;
|
297 |
+
}
|
298 |
+
|
299 |
+
/**
|
300 |
+
* Calculates the hash and checks if the file was processed before. If so, it will copy the base file if it still
|
301 |
+
* exists. Otherwise it will delete the record from the database.
|
302 |
+
*
|
303 |
+
* @return bool
|
304 |
+
*/
|
305 |
+
protected function _isAlreadyCompressed()
|
306 |
+
{
|
307 |
+
$hash = $this->_getFileHash($this->newFile);
|
308 |
+
|
309 |
+
/** @var Tiny_CompressImages_Model_Image|null $model */
|
310 |
+
$model = Mage::getModel('tiny_compressimages/image')->getByHash($hash);
|
311 |
+
|
312 |
+
if ($model !== null) {
|
313 |
+
return $this->_copyExistingFile($model);
|
314 |
+
} else {
|
315 |
+
$this->helper->log('No existing file found with hash ' . $hash, 'info', $this->storeId);
|
316 |
+
|
317 |
+
return false;
|
318 |
+
}
|
319 |
+
}
|
320 |
+
|
321 |
+
/**
|
322 |
+
* Check if the Optimized media direcotory already contains the images.
|
323 |
+
*
|
324 |
+
* @return bool
|
325 |
+
*/
|
326 |
+
protected function _isInOptimizedMediaDirectory()
|
327 |
+
{
|
328 |
+
$path = $this->_model->getPathOptimized();
|
329 |
+
$file = new SplFileInfo($path);
|
330 |
+
|
331 |
+
if ($file->isFile()) {
|
332 |
+
$this->isCompressedBefore = true;
|
333 |
+
return true;
|
334 |
+
}
|
335 |
+
|
336 |
+
return false;
|
337 |
+
}
|
338 |
+
|
339 |
+
/**
|
340 |
+
* Check if the file exists. If so, copy it to the new location to prevent duplicate compressions. If does not
|
341 |
+
* exists anymore, delete the model.
|
342 |
+
*
|
343 |
+
* @param Tiny_CompressImages_Model_Image $model
|
344 |
+
*
|
345 |
+
* @return bool
|
346 |
+
*/
|
347 |
+
protected function _copyExistingFile($model)
|
348 |
+
{
|
349 |
+
$sourceFile = new SplFileInfo(Mage::getBaseDir() . $model->getPathOptimized());
|
350 |
+
|
351 |
+
if (!$sourceFile->isFile()) {
|
352 |
+
$message = 'Failed: Copying the source file ' . $sourceFile->getPathname() . '. The file does not exists ' .
|
353 |
+
'anymore. Deleting the model (ID: ' . $model->getId() . ').';
|
354 |
+
$this->helper->log($message, 'info', $this->storeId);
|
355 |
+
|
356 |
+
$model->delete();
|
357 |
+
|
358 |
+
return false;
|
359 |
+
} else {
|
360 |
+
$model->addUsedAsSource()->save();
|
361 |
+
|
362 |
+
$this->helper->log('Copying the source file from ' . $sourceFile->getPathname() .
|
363 |
+
' to ' . $this->newFile->getPathname(), 'info', $this->storeId);
|
364 |
+
|
365 |
+
if ($this->configHelper->isTestMode($this->storeId)) {
|
366 |
+
$this->helper->log('Testmode is enabled, no image is copied');
|
367 |
+
|
368 |
+
return true;
|
369 |
+
}
|
370 |
+
|
371 |
+
$this->hashBefore = $this->_getFileHash($this->newFile);
|
372 |
+
$this->hashAfter = $model->getHashAfter();
|
373 |
+
$this->bytesAfter = $this->_getFileSize($this->newFile);
|
374 |
+
$this->bytesBefore = $model->getBytesBefore();
|
375 |
+
$this->isUsedAsSource = $model->getUsedAsSource();
|
376 |
+
$this->parentId = $model->getId();
|
377 |
+
$this->isCompressedBefore = false;
|
378 |
+
|
379 |
+
$this->_saveCompression();
|
380 |
+
|
381 |
+
// Reset parent id and used at source.
|
382 |
+
$this->parentId = null;
|
383 |
+
$this->isUsedAsSource = 1;
|
384 |
+
|
385 |
+
return copy($sourceFile->getPathname(), $this->newFile->getPathname());
|
386 |
+
}
|
387 |
+
}
|
388 |
+
|
389 |
+
/**
|
390 |
+
* @param Mage_Catalog_Model_Product_Image $image
|
391 |
+
* @param $storeId
|
392 |
+
*
|
393 |
+
* @return $this
|
394 |
+
*/
|
395 |
+
public function setProductImage($image, $storeId = null)
|
396 |
+
{
|
397 |
+
$this->newFile = new SplFileInfo($image->getNewFile());
|
398 |
+
$this->hashBefore = $this->_getFileHash($this->newFile);
|
399 |
+
$this->bytesBefore = $this->_getFileSize($this->newFile);
|
400 |
+
|
401 |
+
if ($storeId !== null) {
|
402 |
+
$this->storeId = $storeId;
|
403 |
+
}
|
404 |
+
|
405 |
+
if (!$this->configHelper->isEnabled($this->storeId)) {
|
406 |
+
return $this;
|
407 |
+
}
|
408 |
+
|
409 |
+
if (!$this->_isProductImageAllowed($image->getDestinationSubdir())) {
|
410 |
+
$this->isProductTypeAllowed = false;
|
411 |
+
$this->helper->log(
|
412 |
+
'Product ' . $image->getDestinationSubdir() . ' image type is not selected for optimization',
|
413 |
+
'error',
|
414 |
+
$this->storeId
|
415 |
+
);
|
416 |
+
|
417 |
+
return $this;
|
418 |
+
}
|
419 |
+
|
420 |
+
$this->destinationSubdir = $image->getDestinationSubdir();
|
421 |
+
$this->imageWidth = $image->getWidth();
|
422 |
+
$this->imageHeight = $image->getHeight();
|
423 |
+
|
424 |
+
if (!$this->newFile->isFile()) {
|
425 |
+
$this->helper->log('Could not load the core image data', 'info', $this->storeId);
|
426 |
+
|
427 |
+
return $this;
|
428 |
+
}
|
429 |
+
|
430 |
+
return $this;
|
431 |
+
}
|
432 |
+
|
433 |
+
/**
|
434 |
+
* Prepare the compression. This way the optimized path can be calculated.
|
435 |
+
*
|
436 |
+
* @return $this
|
437 |
+
*/
|
438 |
+
protected function _prepareCompression()
|
439 |
+
{
|
440 |
+
$path = str_replace(Mage::getBaseDir(), '', $this->newFile->getPathname());
|
441 |
+
|
442 |
+
/** @var Tiny_CompressImages_Model_Image */
|
443 |
+
$this->_model = Mage::getModel('tiny_compressimages/image');
|
444 |
+
$this->_model->setPath($path);
|
445 |
+
$this->_model->setImageType($this->destinationSubdir);
|
446 |
+
$this->_model->setHashBefore($this->hashBefore);
|
447 |
+
$this->_model->setBytesBefore($this->bytesBefore);
|
448 |
+
|
449 |
+
return $this;
|
450 |
+
}
|
451 |
+
|
452 |
+
/**
|
453 |
+
* Save the file meta info to the database. This way we can prevent duplicate compressions.
|
454 |
+
*
|
455 |
+
* @return $this
|
456 |
+
*/
|
457 |
+
protected function _saveCompression()
|
458 |
+
{
|
459 |
+
$this->hashAfter = $this->_getFileHash($this->newFile);
|
460 |
+
|
461 |
+
$this->_model->setHashAfter($this->hashAfter);
|
462 |
+
$this->_model->setBytesAfter($this->bytesAfter);
|
463 |
+
$this->_model->setProcessedAt(Varien_Date::now());
|
464 |
+
$this->_model->setUsedAsSource($this->isUsedAsSource);
|
465 |
+
|
466 |
+
if ($this->configHelper->isTestMode($this->storeId)) {
|
467 |
+
$this->_model->setIsTest(1);
|
468 |
+
}
|
469 |
+
|
470 |
+
$this->_model->setParentId($this->parentId);
|
471 |
+
$this->_model->setCompressedBefore($this->isCompressedBefore);
|
472 |
+
|
473 |
+
$this->_model->save();
|
474 |
+
|
475 |
+
$this->setTotalSavings();
|
476 |
+
|
477 |
+
return $this;
|
478 |
+
}
|
479 |
+
|
480 |
+
/**
|
481 |
+
* @return $this
|
482 |
+
*/
|
483 |
+
protected function _SetCompressionAsPreviously()
|
484 |
+
{
|
485 |
+
$compressedFile = new SplFileInfo($this->_getOptimizedMediaPath($this->newFile->getPathname()));
|
486 |
+
|
487 |
+
$this->isCompressedBefore = true;
|
488 |
+
|
489 |
+
$this->bytesAfter = $this->_getFileSize($compressedFile);
|
490 |
+
$this->hashAfter = $this->_getFileHash($compressedFile);
|
491 |
+
|
492 |
+
return $this;
|
493 |
+
}
|
494 |
+
|
495 |
+
/**
|
496 |
+
* Save the file meta for the total month savings.
|
497 |
+
*
|
498 |
+
* @return $this
|
499 |
+
*/
|
500 |
+
public function setTotalSavings()
|
501 |
+
{
|
502 |
+
$model = Mage::getModel('tiny_compressimages/totals');
|
503 |
+
$collection = $model->getCollection()->setOrder('entity_id', 'DESC');
|
504 |
+
|
505 |
+
/** @var Tiny_CompressImages_Model_Totals $latest */
|
506 |
+
$latest = $collection->getFirstItem();
|
507 |
+
|
508 |
+
$bytesBefore = $this->bytesBefore;
|
509 |
+
$bytesAfter = $this->bytesAfter;
|
510 |
+
$totalCompression = 1;
|
511 |
+
|
512 |
+
if ($this->isBetweenDates($latest->getDateFrom(),$latest->getDateTo())) {
|
513 |
+
$bytesBefore = $bytesBefore + $latest->getTotalBytesBefore();
|
514 |
+
$bytesAfter = $bytesAfter + $latest->getTotalBytesAfter();
|
515 |
+
$totalCompression = $totalCompression + $latest->getTotalCompressions();
|
516 |
+
$dateFrom = $latest->getDateFrom();
|
517 |
+
$dateTo = $latest->getDateTo();
|
518 |
+
|
519 |
+
// Load the latest record for updates.
|
520 |
+
$model->load($latest->getEntityId());
|
521 |
+
|
522 |
+
} else {
|
523 |
+
$dateFrom = Mage::getModel('core/date')->date('Y-m-01');
|
524 |
+
$dateTo = Mage::getModel('core/date')->date('Y-m-t');
|
525 |
+
}
|
526 |
+
|
527 |
+
$model->setTotalBytesBefore($bytesBefore);
|
528 |
+
$model->setTotalBytesAfter($bytesAfter);
|
529 |
+
$model->setTotalCompressions($totalCompression);
|
530 |
+
$model->setDateFrom($dateFrom);
|
531 |
+
$model->setDateTo($dateTo);
|
532 |
+
$model->setUpdatedAt(Varien_Date::now());
|
533 |
+
|
534 |
+
$model->save();
|
535 |
+
|
536 |
+
return $this;
|
537 |
+
}
|
538 |
+
|
539 |
+
/**
|
540 |
+
* @param $from
|
541 |
+
* @param $to
|
542 |
+
*
|
543 |
+
* @return bool
|
544 |
+
*/
|
545 |
+
public function isBetweenDates($from, $to)
|
546 |
+
{
|
547 |
+
$between = false;
|
548 |
+
|
549 |
+
if ((Varien_Date::now() > $from)
|
550 |
+
&& (Varien_Date::now() < $to)
|
551 |
+
) {
|
552 |
+
$between = true;
|
553 |
+
}
|
554 |
+
|
555 |
+
return $between;
|
556 |
+
}
|
557 |
+
|
558 |
+
/**
|
559 |
+
* Check if we are allowed to compress images.
|
560 |
+
*
|
561 |
+
* @return bool
|
562 |
+
*/
|
563 |
+
protected function _isCompressionAllowed()
|
564 |
+
{
|
565 |
+
if (!$this->allowCompression) {
|
566 |
+
return false;
|
567 |
+
}
|
568 |
+
|
569 |
+
if (!$this->isProductTypeAllowed) {
|
570 |
+
return false;
|
571 |
+
}
|
572 |
+
|
573 |
+
return true;
|
574 |
+
}
|
575 |
+
|
576 |
+
/**
|
577 |
+
* @param $imageDestination
|
578 |
+
*
|
579 |
+
* @return bool
|
580 |
+
*/
|
581 |
+
protected function _isProductImageAllowed($imageDestination)
|
582 |
+
{
|
583 |
+
if (!$this->allowCompression) {
|
584 |
+
return false;
|
585 |
+
}
|
586 |
+
|
587 |
+
$typesAllowed = $this->configHelper->getProductImageTypesToCompress($this->storeId);
|
588 |
+
|
589 |
+
if (in_array($imageDestination, $typesAllowed)) {
|
590 |
+
return true;
|
591 |
+
}
|
592 |
+
|
593 |
+
return false;
|
594 |
+
}
|
595 |
+
|
596 |
+
/**
|
597 |
+
* Check how many images have been compressed this month
|
598 |
+
*
|
599 |
+
* @param null $store
|
600 |
+
*
|
601 |
+
* @return int|null
|
602 |
+
*/
|
603 |
+
public function compressionCount($store = null) {
|
604 |
+
if(!$this->configHelper->isConfigured($store)) {
|
605 |
+
return 0;
|
606 |
+
}
|
607 |
+
|
608 |
+
$apiKey = $this->configHelper->getApiKey($store);
|
609 |
+
$validated = $this->validate($apiKey);
|
610 |
+
|
611 |
+
if (!$validated) {
|
612 |
+
return 0;
|
613 |
+
}
|
614 |
+
|
615 |
+
return \Tinify\compressionCount();
|
616 |
+
}
|
617 |
+
|
618 |
+
/**
|
619 |
+
* Get all the compressions
|
620 |
+
*
|
621 |
+
* @return Tiny_CompressImages_Model_Resource_Image_Collection
|
622 |
+
*/
|
623 |
+
public function getCompressionStatus()
|
624 |
+
{
|
625 |
+
$collection = Mage::getModel('tiny_compressimages/image')->getCollection();
|
626 |
+
$select = $collection->getSelect();
|
627 |
+
$select->limit(50);
|
628 |
+
|
629 |
+
$fromDate = Mage::getModel('core/date')->date('Y-m-01');
|
630 |
+
$toDate = Mage::getModel('core/date')->date('Y-m-t');
|
631 |
+
|
632 |
+
$select->where(
|
633 |
+
'processed_at',
|
634 |
+
array(
|
635 |
+
'from' => $fromDate,
|
636 |
+
'to' => $toDate,
|
637 |
+
'date' => true
|
638 |
+
)
|
639 |
+
);
|
640 |
+
|
641 |
+
$collection->setOrder('processed_at', Varien_Data_Collection_Db::SORT_ORDER_DESC);
|
642 |
+
|
643 |
+
return $collection;
|
644 |
+
}
|
645 |
+
|
646 |
+
/**
|
647 |
+
* Check the API status.
|
648 |
+
*
|
649 |
+
* @return array
|
650 |
+
*/
|
651 |
+
public function getApiStatus($useCache = false)
|
652 |
+
{
|
653 |
+
$apiStatusCache = Mage::app()->loadCache(static::CACHE_KEY);
|
654 |
+
if ($useCache && $apiStatusCache !== false) {
|
655 |
+
return json_decode($apiStatusCache, true);
|
656 |
+
}
|
657 |
+
|
658 |
+
/** @var Tiny_CompressImages_Helper_Config $configHelper */
|
659 |
+
$configHelper = Mage::helper('tiny_compressimages/config');
|
660 |
+
$apiKey = $configHelper->getApiKey();
|
661 |
+
$isValidated = Mage::helper('tiny_compressimages/tinify')->validate($apiKey);
|
662 |
+
|
663 |
+
$cacheData = array();
|
664 |
+
if (!$apiKey || $isValidated) {
|
665 |
+
$message = '<span class="compressimages_status_success">'
|
666 |
+
. '<span class="indicator"><img src="' . Mage::getDesign()->getSkinUrl('images/fam_bullet_success.gif') . '"></span>'
|
667 |
+
. Mage::helper('tiny_compressimages')->__('API connection successful')
|
668 |
+
. '</span>';
|
669 |
+
|
670 |
+
$cacheData['status'] = 'operational';
|
671 |
+
} else {
|
672 |
+
$message = '<span class="compressimages_status_failure">'
|
673 |
+
. '<span class="indicator"><img src="' . Mage::getDesign()->getSkinUrl('images/error_msg_icon.gif') . '"></span>'
|
674 |
+
. Mage::helper('tiny_compressimages')->__('Non-operational')
|
675 |
+
. '</span>';
|
676 |
+
|
677 |
+
$cacheData['status'] = 'nonoperational';
|
678 |
+
}
|
679 |
+
|
680 |
+
$result = array();
|
681 |
+
$result['status'] = 'success';
|
682 |
+
$result['message'] = $message;
|
683 |
+
|
684 |
+
/**
|
685 |
+
* Only cache the results if the api is up.
|
686 |
+
*/
|
687 |
+
if ($cacheData['status'] == 'operational') {
|
688 |
+
Mage::app()->saveCache(json_encode($result), static::CACHE_KEY);
|
689 |
+
}
|
690 |
+
|
691 |
+
return $result;
|
692 |
+
}
|
693 |
+
|
694 |
+
/**
|
695 |
+
* @param $file
|
696 |
+
*
|
697 |
+
* @return string
|
698 |
+
*/
|
699 |
+
protected function _getOptimizedMediaPath($file)
|
700 |
+
{
|
701 |
+
$baseDir = Mage::getBaseDir('media');
|
702 |
+
$tinyPath = substr(Tiny_CompressImages_Helper_Tinify::TINY_COMPRESSIMAGES_MEDIA_DIRECTORY.DS, 1);
|
703 |
+
|
704 |
+
$path = str_replace(
|
705 |
+
$baseDir . DS,
|
706 |
+
$tinyPath,
|
707 |
+
$file
|
708 |
+
);
|
709 |
+
|
710 |
+
return Mage::getBaseDir(). '/' .str_replace(DS, '/', $path);
|
711 |
+
}
|
712 |
+
|
713 |
+
/**
|
714 |
+
* Generic function so we can change the hash function easily.
|
715 |
+
*
|
716 |
+
* @param SplFileInfo $file
|
717 |
+
*
|
718 |
+
* @return string
|
719 |
+
*/
|
720 |
+
protected function _getFileHash(SplFileInfo $file)
|
721 |
+
{
|
722 |
+
if (!$file->isFile()) {
|
723 |
+
return false;
|
724 |
+
}
|
725 |
+
|
726 |
+
return md5_file($file->getPathname());
|
727 |
+
}
|
728 |
+
|
729 |
+
/**
|
730 |
+
* Get the filesize for the specified file.
|
731 |
+
*
|
732 |
+
* @param SplFileInfo $file
|
733 |
+
*
|
734 |
+
* @return bool|int
|
735 |
+
*/
|
736 |
+
protected function _getFileSize(SplFileInfo $file)
|
737 |
+
{
|
738 |
+
if (!$file->isFile())
|
739 |
+
{
|
740 |
+
return false;
|
741 |
+
}
|
742 |
+
|
743 |
+
/**
|
744 |
+
* Flush PHP's internal cache so we always have use a fresh copy of the file.
|
745 |
+
*/
|
746 |
+
clearstatcache();
|
747 |
+
|
748 |
+
return $file->getSize();
|
749 |
+
}
|
750 |
+
}
|
app/code/community/Tiny/CompressImages/Model/Image.php
ADDED
@@ -0,0 +1,327 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @method string|null getPath();
|
4 |
+
* @method $this setPathOptimized(String $path);
|
5 |
+
* @method string|null getPathOptimized();
|
6 |
+
* @method $this setImageType(String $type);
|
7 |
+
* @method $this setHashBefore(String $hash);
|
8 |
+
* @method string|null getHashBefore();
|
9 |
+
* @method $this setHashAfter(String $hash);
|
10 |
+
* @method string|null getHashAfter();
|
11 |
+
* @method $this setBytesBefore(int $bytes);
|
12 |
+
* @method int|null getBytesBefore();
|
13 |
+
* @method $this setBytesAfter(int $bytes);
|
14 |
+
* @method int|null getBytesAfter();
|
15 |
+
* @method $this setUsedAsSource(int $times);
|
16 |
+
* @method int|null getUsedAsSource();
|
17 |
+
* @method $this setProcessedAt(String $date);
|
18 |
+
* @method string|null getProcessedAt();
|
19 |
+
* @method $this setIsTest(int $testMode);
|
20 |
+
* @method string|null getIsTest();
|
21 |
+
* @method $this setCompressedBefore(int $compressedBefore);
|
22 |
+
* @method int|null getCompressedBefore();
|
23 |
+
* @method $this setParentId(int $parentId);
|
24 |
+
* @method int|null getParentId();
|
25 |
+
*/
|
26 |
+
class Tiny_CompressImages_Model_Image extends Mage_Core_Model_Abstract
|
27 |
+
{
|
28 |
+
/**
|
29 |
+
* @var Tiny_CompressImages_Helper_Data
|
30 |
+
*/
|
31 |
+
protected $_helper = null;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* The constructer. Loads the helper.
|
35 |
+
*/
|
36 |
+
public function __construct()
|
37 |
+
{
|
38 |
+
parent::__construct();
|
39 |
+
|
40 |
+
$this->_helper = Mage::helper('tiny_compressimages');
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Class constructor.
|
45 |
+
*/
|
46 |
+
public function _construct()
|
47 |
+
{
|
48 |
+
$this->_init('tiny_compressimages/image');
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Set the path and also calculate the optimized path.
|
53 |
+
*
|
54 |
+
* @param $path
|
55 |
+
*
|
56 |
+
* @return $this
|
57 |
+
*/
|
58 |
+
public function setPath($path)
|
59 |
+
{
|
60 |
+
$this->setData('path', $path);
|
61 |
+
|
62 |
+
$filename = basename($path);
|
63 |
+
$newPath = str_replace($filename, '', $path);
|
64 |
+
$hash = md5($newPath);
|
65 |
+
|
66 |
+
$optimizedPath = Tiny_CompressImages_Helper_Tinify::TINY_COMPRESSIMAGES_MEDIA_DIRECTORY;
|
67 |
+
$optimizedPath .= '/' . $hash[0] . '/' . $hash[1] . '/' . $hash . '/' . $filename;
|
68 |
+
|
69 |
+
$this->setPathOptimized($optimizedPath);
|
70 |
+
|
71 |
+
return $this;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Creates the path where the image will be saved.
|
76 |
+
*
|
77 |
+
* @return $this
|
78 |
+
*/
|
79 |
+
public function createPath()
|
80 |
+
{
|
81 |
+
$path = dirname($this->getPathOptimized());
|
82 |
+
$fullpath = Mage::getBaseDir('media') . str_replace('/media', '', $path);
|
83 |
+
|
84 |
+
if (!is_dir($fullpath)) {
|
85 |
+
mkdir($fullpath, 0777, true);
|
86 |
+
}
|
87 |
+
|
88 |
+
return $this;
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* The full path where the image will be saved.
|
93 |
+
*
|
94 |
+
* @return string
|
95 |
+
*/
|
96 |
+
public function getFilepathOptimized()
|
97 |
+
{
|
98 |
+
$path = $this->getPathOptimized();
|
99 |
+
return Mage::getBaseDir('media') . str_replace('/media', '', $path);
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Retrieve the url to the image.
|
104 |
+
*
|
105 |
+
* @return string
|
106 |
+
*/
|
107 |
+
public function getUrl()
|
108 |
+
{
|
109 |
+
return Mage::getBaseUrl('media') . str_replace('/media/', '', $this->getPathOptimized());
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Get the statistics for the CompressImages module.
|
114 |
+
*
|
115 |
+
* $options:
|
116 |
+
* - current_month: defaults to true
|
117 |
+
*
|
118 |
+
* @param array $options
|
119 |
+
*
|
120 |
+
* @return Varien_Object
|
121 |
+
*/
|
122 |
+
public function getStatistics($options = array())
|
123 |
+
{
|
124 |
+
$collection = $this->getCollection();
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Filter by the current month.
|
128 |
+
*/
|
129 |
+
if (
|
130 |
+
!isset($options['current_month']) ||
|
131 |
+
(
|
132 |
+
isset($options['current_month']) &&
|
133 |
+
$options['current_month']
|
134 |
+
)
|
135 |
+
) {
|
136 |
+
$dateFrom = Mage::getModel('core/date')->date('Y-m-01');
|
137 |
+
$dateTo = Mage::getModel('core/date')->date('Y-m-t');
|
138 |
+
|
139 |
+
$collection->addFieldToFilter(
|
140 |
+
'processed_at',
|
141 |
+
array(
|
142 |
+
'from' => $dateFrom,
|
143 |
+
'to' => $dateTo,
|
144 |
+
'date' => true
|
145 |
+
)
|
146 |
+
);
|
147 |
+
}
|
148 |
+
|
149 |
+
$collection
|
150 |
+
->getSelect()
|
151 |
+
->reset(Zend_Db_Select::COLUMNS)
|
152 |
+
->columns('count(image_id) as images_count')
|
153 |
+
->columns('sum(bytes_before) as bytes_before')
|
154 |
+
->columns('sum(bytes_after) as bytes_after')
|
155 |
+
->columns('max(((bytes_before - bytes_after) / bytes_before) * 100) as greatest_saving')
|
156 |
+
;
|
157 |
+
|
158 |
+
$data = $collection->getFirstItem();
|
159 |
+
|
160 |
+
if ($data->images_count > 0) {
|
161 |
+
$data->setData('percentage_saved', (($data->bytes_before - $data->bytes_after) / $data->bytes_before) * 100);
|
162 |
+
} else {
|
163 |
+
$data->setData('percentage_saved', 0);
|
164 |
+
}
|
165 |
+
|
166 |
+
return $data;
|
167 |
+
}
|
168 |
+
|
169 |
+
/**
|
170 |
+
* Retrieve a model by the hash.
|
171 |
+
*
|
172 |
+
* @param $hash
|
173 |
+
*
|
174 |
+
* @return Tiny_CompressImages_Model_Image|null
|
175 |
+
*/
|
176 |
+
public function getByHash($hash)
|
177 |
+
{
|
178 |
+
/** @var Tiny_CompressImages_Model_Resource_Image_Collection $model */
|
179 |
+
$model = $this->getCollection();
|
180 |
+
$model->addFieldToFilter(
|
181 |
+
array(
|
182 |
+
'hash_before',
|
183 |
+
'hash_after',
|
184 |
+
),
|
185 |
+
array(
|
186 |
+
array('eq' => $hash),
|
187 |
+
array('eq' => $hash),
|
188 |
+
)
|
189 |
+
);
|
190 |
+
|
191 |
+
$item = $model->getFirstItem();
|
192 |
+
if ($item->getId() !== null) {
|
193 |
+
return $item;
|
194 |
+
} else {
|
195 |
+
return null;
|
196 |
+
}
|
197 |
+
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Simple function to add 1 to the used_as_source column.
|
201 |
+
*
|
202 |
+
* @return $this
|
203 |
+
*/
|
204 |
+
public function addUsedAsSource()
|
205 |
+
{
|
206 |
+
$this->setUsedAsSource($this->getUsedAsSource() + 1);
|
207 |
+
|
208 |
+
return $this;
|
209 |
+
}
|
210 |
+
|
211 |
+
/**
|
212 |
+
* Get the url for this image.
|
213 |
+
*
|
214 |
+
* @return string
|
215 |
+
*/
|
216 |
+
public function getImageUrl()
|
217 |
+
{
|
218 |
+
// If it is a duplicate image, then there will be a link to his parent.
|
219 |
+
if ($this->getParentId()) {
|
220 |
+
/** @var Tiny_CompressImages_Model_Image $parent */
|
221 |
+
$parent = Mage::getModel('tiny_compressimages/image')->load($this->getParentId());
|
222 |
+
|
223 |
+
return $parent->getUrl();
|
224 |
+
}
|
225 |
+
|
226 |
+
return $this->getUrl();
|
227 |
+
}
|
228 |
+
|
229 |
+
/**
|
230 |
+
* Calculate the bytes saved.
|
231 |
+
*
|
232 |
+
* @return null|string
|
233 |
+
*/
|
234 |
+
public function getBytesSaved()
|
235 |
+
{
|
236 |
+
return $this->getBytesBefore() - $this->getBytesAfter();
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Show the correct image type.
|
241 |
+
*
|
242 |
+
* @return string
|
243 |
+
*/
|
244 |
+
public function getImageType()
|
245 |
+
{
|
246 |
+
$data = $this->getData('image_type');
|
247 |
+
|
248 |
+
switch($data) {
|
249 |
+
case 'image':
|
250 |
+
$data = 'Base image';
|
251 |
+
break;
|
252 |
+
|
253 |
+
case 'small_image':
|
254 |
+
$data = 'Small image';
|
255 |
+
break;
|
256 |
+
|
257 |
+
case 'thumbnail':
|
258 |
+
$data = 'Thumbnail';
|
259 |
+
break;
|
260 |
+
|
261 |
+
case 'media_image':
|
262 |
+
$data = 'Swatches';
|
263 |
+
break;
|
264 |
+
}
|
265 |
+
|
266 |
+
return $data;
|
267 |
+
}
|
268 |
+
|
269 |
+
/**
|
270 |
+
* Calculate the percentage saved.
|
271 |
+
*
|
272 |
+
* @return null|string
|
273 |
+
*/
|
274 |
+
public function getPercentageSaved()
|
275 |
+
{
|
276 |
+
$bytesSaved = $this->getBytesSaved();
|
277 |
+
|
278 |
+
if ($bytesSaved == 0) {
|
279 |
+
return '0 %';
|
280 |
+
} else {
|
281 |
+
return round(($bytesSaved / $this->getBytesBefore()) * 100) . ' %';
|
282 |
+
}
|
283 |
+
}
|
284 |
+
|
285 |
+
/**
|
286 |
+
* Shows the time ago in human readable format when this image was processed.
|
287 |
+
*
|
288 |
+
* @return string
|
289 |
+
*/
|
290 |
+
public function getTimeAgo()
|
291 |
+
{
|
292 |
+
return $this->_helper->timeAgo($this->getProcessedAt());
|
293 |
+
}
|
294 |
+
|
295 |
+
/**
|
296 |
+
* Delete all models
|
297 |
+
*
|
298 |
+
* @return $this
|
299 |
+
*/
|
300 |
+
public function deleteAll()
|
301 |
+
{
|
302 |
+
$collection = $this->getCollection();
|
303 |
+
|
304 |
+
Mage::getSingleton('core/resource_iterator')->walk($collection->getSelect(), array( function ($args) {
|
305 |
+
Mage::getModel('tiny_compressimages/image')->load($args['row']['image_id'])->delete();
|
306 |
+
}));
|
307 |
+
|
308 |
+
return $this;
|
309 |
+
}
|
310 |
+
|
311 |
+
/**
|
312 |
+
* Delete all models
|
313 |
+
*
|
314 |
+
* @return $this
|
315 |
+
*/
|
316 |
+
public function deleteTest()
|
317 |
+
{
|
318 |
+
$collection = $this->getCollection();
|
319 |
+
$collection->addFieldToFilter('is_test', '1');
|
320 |
+
|
321 |
+
Mage::getSingleton('core/resource_iterator')->walk($collection->getSelect(), array( function ($args) {
|
322 |
+
Mage::getModel('tiny_compressimages/image')->load($args['row']['image_id'])->delete();
|
323 |
+
}));
|
324 |
+
|
325 |
+
return $this;
|
326 |
+
}
|
327 |
+
}
|
app/code/community/Tiny/CompressImages/Model/Observer.php
CHANGED
@@ -1,75 +1,27 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
-
/*
|
4 |
-
* Tiny Compress Images - Magento Extension.
|
5 |
-
* Copyright (C) 2015 Voormedia B.V.
|
6 |
-
*
|
7 |
-
* This program is free software; you can redistribute it and/or modify it
|
8 |
-
* under the terms of the GNU General Public License as published by the Free
|
9 |
-
* Software Foundation; either version 2 of the License, or (at your option)
|
10 |
-
* any later version.
|
11 |
-
*
|
12 |
-
* This program is distributed in the hope that it will be useful, but WITHOUT
|
13 |
-
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
14 |
-
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
15 |
-
* more details.
|
16 |
-
*
|
17 |
-
* You should have received a copy of the GNU General Public License along
|
18 |
-
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
19 |
-
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
20 |
-
*/
|
21 |
-
|
22 |
-
require('TinyCompress' . DIRECTORY_SEPARATOR . 'class-tiny-exception.php');
|
23 |
-
require('TinyCompress' . DIRECTORY_SEPARATOR . 'class-tiny-php.php');
|
24 |
-
require('TinyCompress' . DIRECTORY_SEPARATOR . 'class-tiny-compress.php');
|
25 |
-
require('TinyCompress' . DIRECTORY_SEPARATOR . 'class-tiny-compress-curl.php');
|
26 |
-
require('TinyCompress' . DIRECTORY_SEPARATOR . 'class-tiny-compress-fopen.php');
|
27 |
-
|
28 |
class Tiny_CompressImages_Model_Observer
|
29 |
{
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
{
|
32 |
-
$
|
33 |
-
|
34 |
-
switch ($destinationSubdir) {
|
35 |
-
case "image" :
|
36 |
-
$allowCompression = Mage::getStoreConfig('compress_images/image_sizes/compress_image');
|
37 |
-
break;
|
38 |
-
case "small_image" :
|
39 |
-
$allowCompression = Mage::getStoreConfig('compress_images/image_sizes/compress_small_image');
|
40 |
-
break;
|
41 |
-
case "thumbnail" :
|
42 |
-
$allowCompression = Mage::getStoreConfig('compress_images/image_sizes/compress_thumbnail');
|
43 |
-
break;
|
44 |
-
default :
|
45 |
-
$allowCompression = Mage::getStoreConfig('compress_images/image_sizes/compress_other_images');
|
46 |
-
break;
|
47 |
}
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
$height = $imageObject->getHeight();
|
54 |
-
$compressor = Tiny_Compress::get_compressor($apiKey);
|
55 |
-
try {
|
56 |
-
$details = $compressor->compress_file($newFile);
|
57 |
-
$logDescription =
|
58 |
-
"Variant " . $destinationSubdir .
|
59 |
-
" allowed " . $allowCompression .
|
60 |
-
" width " . $width .
|
61 |
-
" height " . $height .
|
62 |
-
" API " . $apiKey .
|
63 |
-
" JSON response " . json_encode($details);
|
64 |
-
} catch (Tiny_Exception $e) {
|
65 |
-
$logDescription = $e->get_error() . ': ' . $e->getMessage();
|
66 |
-
}
|
67 |
-
} else {
|
68 |
-
$logDescription = "No API key found for compression.";
|
69 |
-
}
|
70 |
-
} else {
|
71 |
-
$logDescription = "Variant {$destinationSubdir} not selected for compression.";
|
72 |
-
}
|
73 |
-
Mage::log($logDescription, null, 'image-compression.log');
|
74 |
}
|
75 |
}
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
class Tiny_CompressImages_Model_Observer
|
3 |
{
|
4 |
+
/**
|
5 |
+
* @var null|Tiny_CompressImages_Helper_Tinify
|
6 |
+
*/
|
7 |
+
protected $_tinifyHelper = null;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Compress product images
|
11 |
+
*
|
12 |
+
* @param $observer
|
13 |
+
*
|
14 |
+
* @return $this
|
15 |
+
*/
|
16 |
+
public function catalogProductImageSaveAfter($observer)
|
17 |
{
|
18 |
+
if ($this->_tinifyHelper === null) {
|
19 |
+
$this->_tinifyHelper = Mage::helper('tiny_compressimages/tinify');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
}
|
21 |
+
|
22 |
+
$storeId = Mage::app()->getStore()->getStoreId();
|
23 |
+
$this->_tinifyHelper->setProductImage($observer->getObject(), $storeId)->compress();
|
24 |
+
|
25 |
+
return $this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
}
|
27 |
}
|
app/code/community/Tiny/CompressImages/Model/Product/Image.php
CHANGED
@@ -1,24 +1,77 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
class Tiny_CompressImages_Model_Product_Image extends Mage_Catalog_Model_Product_Image
|
4 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
|
6 |
-
|
7 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
|
9 |
/**
|
10 |
-
* @return Mage_Catalog_Model_Product_Image
|
11 |
*/
|
12 |
public function saveFile()
|
13 |
{
|
14 |
-
|
15 |
-
$this->getImageProcessor()->save($filename);
|
16 |
-
Mage::helper('core/file_storage_database')->saveFile($filename);
|
17 |
|
18 |
-
/* Added for TinyPNG image compression */
|
19 |
Mage::dispatchEvent('catalog_product_image_save_after', array($this->_eventObject => $this));
|
20 |
|
21 |
return $this;
|
22 |
}
|
23 |
-
|
24 |
}
|
1 |
<?php
|
|
|
2 |
class Tiny_CompressImages_Model_Product_Image extends Mage_Catalog_Model_Product_Image
|
3 |
{
|
4 |
+
/**
|
5 |
+
* Set the minimun required quality for CompressImages which is 95
|
6 |
+
*
|
7 |
+
* @var int
|
8 |
+
*/
|
9 |
+
protected $_quality = 85;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @var Tiny_CompressImages_Helper_Config|null
|
13 |
+
*/
|
14 |
+
protected $_configHelper = null;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var Tiny_CompressImages_Helper_Tinify|null
|
18 |
+
*/
|
19 |
+
protected $_dataHelper = null;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @return Tiny_CompressImages_Helper_Config
|
23 |
+
*/
|
24 |
+
public function getConfigHelper()
|
25 |
+
{
|
26 |
+
if ($this->_configHelper === null) {
|
27 |
+
$this->_configHelper = Mage::helper('tiny_compressimages/config');
|
28 |
+
}
|
29 |
+
|
30 |
+
return $this->_configHelper;
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @return Tiny_CompressImages_Helper_Data
|
35 |
+
*/
|
36 |
+
public function getDataHelper()
|
37 |
+
{
|
38 |
+
if ($this->_dataHelper === null) {
|
39 |
+
$this->_dataHelper = Mage::helper('tiny_compressimages');
|
40 |
+
}
|
41 |
+
|
42 |
+
return $this->_dataHelper;
|
43 |
+
}
|
44 |
|
45 |
+
/**
|
46 |
+
* @return string
|
47 |
+
*/
|
48 |
+
public function getUrl()
|
49 |
+
{
|
50 |
+
/** @var Tiny_CompressImages_Helper_Config $helper */
|
51 |
+
$helper = $this->getConfigHelper();
|
52 |
+
if ($helper->isTestMode(Mage::app()->getStore()->getStoreId())) {
|
53 |
+
return parent::getUrl();
|
54 |
+
}
|
55 |
+
|
56 |
+
/** @var Tiny_Compressimages_Model_Image $model */
|
57 |
+
$path = substr($this->_newFile, strlen(Mage::getBaseDir('media')) - 6);
|
58 |
+
$model = Mage::getModel('tiny_compressimages/image')->load($path, 'path');
|
59 |
+
if (!$model->getId() || !file_exists($model->getFilepathOptimized())) {
|
60 |
+
return parent::getUrl();
|
61 |
+
}
|
62 |
+
|
63 |
+
return $model->getUrl();
|
64 |
+
}
|
65 |
|
66 |
/**
|
67 |
+
* @return Mage_Catalog_Model_Product_Image $this
|
68 |
*/
|
69 |
public function saveFile()
|
70 |
{
|
71 |
+
parent::saveFile();
|
|
|
|
|
72 |
|
|
|
73 |
Mage::dispatchEvent('catalog_product_image_save_after', array($this->_eventObject => $this));
|
74 |
|
75 |
return $this;
|
76 |
}
|
|
|
77 |
}
|
app/code/community/Tiny/CompressImages/Model/Resource/Image.php
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Model_Resource_Image extends Mage_Core_Model_Resource_Db_Abstract
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* Define main table and id field name.
|
6 |
+
*
|
7 |
+
* @return void
|
8 |
+
*/
|
9 |
+
protected function _construct()
|
10 |
+
{
|
11 |
+
$this->_init('tiny_compressimages/image', 'image_id');
|
12 |
+
}
|
13 |
+
}
|
app/code/community/Tiny/CompressImages/Model/Resource/Image/Collection.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Model_Resource_Image_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
|
3 |
+
{
|
4 |
+
public function _construct()
|
5 |
+
{
|
6 |
+
parent::_construct();
|
7 |
+
$this->_init('tiny_compressimages/image');
|
8 |
+
}
|
9 |
+
}
|
app/code/community/Tiny/CompressImages/Model/Resource/Setup.php
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Model_Resource_Setup extends Mage_Core_Model_Resource_Setup
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* Copy a config setting from an old xpath to a new xpath directly in the database, rather than using Magento config
|
6 |
+
* entities.
|
7 |
+
*
|
8 |
+
* @param string $fromXpath
|
9 |
+
* @param string $toXpath
|
10 |
+
*
|
11 |
+
* @return $this
|
12 |
+
*/
|
13 |
+
public function moveConfigSettingInDb($fromXpath, $toXpath)
|
14 |
+
{
|
15 |
+
$conn = $this->getConnection();
|
16 |
+
|
17 |
+
try {
|
18 |
+
$select = $conn->select()
|
19 |
+
->from($this->getTable('core/config_data'))
|
20 |
+
->where('path = ?', $fromXpath);
|
21 |
+
|
22 |
+
$result = $conn->fetchAll($select);
|
23 |
+
foreach ($result as $row) {
|
24 |
+
try {
|
25 |
+
/**
|
26 |
+
* Copy the old setting to the new setting.
|
27 |
+
*
|
28 |
+
* @todo Check if the row already exists.
|
29 |
+
*/
|
30 |
+
$conn->insert(
|
31 |
+
$this->getTable('core/config_data'),
|
32 |
+
array(
|
33 |
+
'scope' => $row['scope'],
|
34 |
+
'scope_id' => $row['scope_id'],
|
35 |
+
'value' => $row['value'],
|
36 |
+
'path' => $toXpath
|
37 |
+
)
|
38 |
+
);
|
39 |
+
} catch (Exception $e) {
|
40 |
+
Mage::helper('tiny_compressimages')->log($e);
|
41 |
+
}
|
42 |
+
}
|
43 |
+
} catch (Exception $e) {
|
44 |
+
Mage::helper('tiny_compressimages')->log($e);
|
45 |
+
}
|
46 |
+
|
47 |
+
return $this;
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Check if the specified xpath exists.
|
52 |
+
*
|
53 |
+
* @param $xpath
|
54 |
+
*
|
55 |
+
* @return bool
|
56 |
+
*/
|
57 |
+
public function configExists($xpath)
|
58 |
+
{
|
59 |
+
$conn = $this->getConnection();
|
60 |
+
|
61 |
+
try {
|
62 |
+
$select = $conn->select()
|
63 |
+
->from($this->getTable('core/config_data'))
|
64 |
+
->where('path = ?', $xpath);
|
65 |
+
|
66 |
+
$result = $conn->fetchAll($select);
|
67 |
+
foreach ($result as $row) {
|
68 |
+
return true;
|
69 |
+
}
|
70 |
+
} catch (Exception $e) {
|
71 |
+
Mage::helper('tiny_compressimages')->log($e);
|
72 |
+
}
|
73 |
+
|
74 |
+
return false;
|
75 |
+
}
|
76 |
+
}
|
app/code/community/Tiny/CompressImages/Model/Resource/Totals.php
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Model_Resource_Totals extends Mage_Core_Model_Resource_Db_Abstract
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* Define main table and id field name.
|
6 |
+
*
|
7 |
+
* @return void
|
8 |
+
*/
|
9 |
+
protected function _construct()
|
10 |
+
{
|
11 |
+
$this->_init('tiny_compressimages/totals', 'entity_id');
|
12 |
+
}
|
13 |
+
}
|
app/code/community/Tiny/CompressImages/Model/Resource/Totals/Collection.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Model_Resource_Totals_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
|
3 |
+
{
|
4 |
+
public function _construct()
|
5 |
+
{
|
6 |
+
parent::_construct();
|
7 |
+
$this->_init('tiny_compressimages/totals');
|
8 |
+
}
|
9 |
+
}
|
app/code/community/Tiny/CompressImages/Model/System/Config/Backend/ApiKey.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Model_System_Config_Backend_ApiKey extends Mage_Core_Model_Config_Data
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* Validate the value before saving.
|
6 |
+
*
|
7 |
+
* @return Mage_Core_Model_Abstract
|
8 |
+
* @throws Mage_Exception
|
9 |
+
*/
|
10 |
+
protected function _beforeSave()
|
11 |
+
{
|
12 |
+
$apiKeyValue = $this->getValue();
|
13 |
+
$oldApiKeyValue = $this->getOldValue();
|
14 |
+
$helper = Mage::helper('tiny_compressimages/tinify');
|
15 |
+
|
16 |
+
if (strlen($apiKeyValue) > 0) {
|
17 |
+
$validateResult = $helper->validate($apiKeyValue);
|
18 |
+
|
19 |
+
if (!$validateResult) {
|
20 |
+
throw new Mage_Exception($helper->__('The Api Key is invalid'));
|
21 |
+
}
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Remove the cached items.
|
26 |
+
*/
|
27 |
+
if ($apiKeyValue != $oldApiKeyValue) {
|
28 |
+
Mage::app()->removeCache(Tiny_CompressImages_Helper_Tinify::CACHE_KEY);
|
29 |
+
}
|
30 |
+
|
31 |
+
return parent::_beforeSave();
|
32 |
+
}
|
33 |
+
}
|
app/code/community/Tiny/CompressImages/Model/System/Config/Backend/Comment/LoggingMode.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Model_System_Config_Backend_Comment_LoggingMode
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* Make the /var/log/image-optimization.log file clickable.
|
6 |
+
*
|
7 |
+
* @return string
|
8 |
+
*/
|
9 |
+
public function getCommentText()
|
10 |
+
{
|
11 |
+
$text = Mage::helper('tiny_compressimages')->__('Any error messages will be saved to %s');
|
12 |
+
$downloadUrl = Mage::helper("adminhtml")->getUrl('adminhtml/CompressImagesAdminhtml_config/downloadLogs');
|
13 |
+
$logPath = Mage::helper('tiny_compressimages')->getLogFilePath();
|
14 |
+
$basePath = Mage::getBaseDir();
|
15 |
+
|
16 |
+
$nicePath = str_replace($basePath, '', $logPath);
|
17 |
+
|
18 |
+
if (Mage::helper('tiny_compressimages')->getLogFileExists()) {
|
19 |
+
$text = sprintf($text, '<a href="' . $downloadUrl . '">' . $nicePath . '</a>');
|
20 |
+
} else {
|
21 |
+
$text = sprintf($text, $nicePath);
|
22 |
+
}
|
23 |
+
|
24 |
+
return $text;
|
25 |
+
}
|
26 |
+
}
|
app/code/community/Tiny/CompressImages/Model/System/Config/Source/Cms/ImageTypes.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Model_System_Config_Source_Cms_ImageTypes
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* Source cms model for collecting the image types.
|
6 |
+
*
|
7 |
+
* @return array
|
8 |
+
*/
|
9 |
+
public function toOptionArray()
|
10 |
+
{
|
11 |
+
$helper = Mage::helper('tiny_compressimages');
|
12 |
+
|
13 |
+
$array = array(
|
14 |
+
array(
|
15 |
+
'value' => 'category_images',
|
16 |
+
'label' => $helper->__('Category images')
|
17 |
+
),
|
18 |
+
array(
|
19 |
+
'value' => 'block_images',
|
20 |
+
'label' => $helper->__('Block images')
|
21 |
+
),
|
22 |
+
array(
|
23 |
+
'value' => 'cms_images',
|
24 |
+
'label' => $helper->__('CMS page images')
|
25 |
+
),
|
26 |
+
);
|
27 |
+
|
28 |
+
return $array;
|
29 |
+
}
|
30 |
+
}
|
app/code/community/Tiny/CompressImages/Model/System/Config/Source/Log.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Model_System_Config_Source_Log
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* Get the select list for logging mode.
|
6 |
+
*
|
7 |
+
* @return array
|
8 |
+
*/
|
9 |
+
public function toOptionArray()
|
10 |
+
{
|
11 |
+
$helper = Mage::helper('tiny_compressimages');
|
12 |
+
|
13 |
+
$array = array(
|
14 |
+
array(
|
15 |
+
'value' => 'off',
|
16 |
+
'label' => $helper->__('Logging disabled')
|
17 |
+
),
|
18 |
+
array(
|
19 |
+
'value' => 'only_exceptions',
|
20 |
+
'label' => $helper->__('Exceptions only')
|
21 |
+
),
|
22 |
+
array(
|
23 |
+
'value' => 'fail_and_exceptions',
|
24 |
+
'label' => $helper->__('Errors and Exceptions')
|
25 |
+
),
|
26 |
+
array(
|
27 |
+
'value' => 'all',
|
28 |
+
'label' => $helper->__('All logging information')
|
29 |
+
),
|
30 |
+
);
|
31 |
+
|
32 |
+
return $array;
|
33 |
+
}
|
34 |
+
}
|
app/code/community/Tiny/CompressImages/Model/System/Config/Source/OnOff.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Model_System_Config_Source_OnOff
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* Source model for on / off selection
|
6 |
+
*
|
7 |
+
* @return array
|
8 |
+
*/
|
9 |
+
public function toOptionArray()
|
10 |
+
{
|
11 |
+
$helper = Mage::helper('tiny_compressimages');
|
12 |
+
|
13 |
+
$array = array(
|
14 |
+
array(
|
15 |
+
'value' => 0,
|
16 |
+
'label' => $helper->__('Off')
|
17 |
+
),
|
18 |
+
array(
|
19 |
+
'value' => 1,
|
20 |
+
'label' => $helper->__('On')
|
21 |
+
),
|
22 |
+
);
|
23 |
+
|
24 |
+
return $array;
|
25 |
+
}
|
26 |
+
}
|
app/code/community/Tiny/CompressImages/Model/System/Config/Source/Product/ImageTypes.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Model_System_Config_Source_Product_ImageTypes
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* Source product model for collecting the image types.
|
6 |
+
*
|
7 |
+
* @return array
|
8 |
+
*/
|
9 |
+
public function toOptionArray()
|
10 |
+
{
|
11 |
+
$helper = Mage::helper('tiny_compressimages');
|
12 |
+
|
13 |
+
$array = array(
|
14 |
+
array(
|
15 |
+
'value' => 'thumbnail',
|
16 |
+
'label' => $helper->__('Thumbnail')
|
17 |
+
),
|
18 |
+
array(
|
19 |
+
'value' => 'small_image',
|
20 |
+
'label' => $helper->__('Small Image')
|
21 |
+
),
|
22 |
+
array(
|
23 |
+
'value' => 'image',
|
24 |
+
'label' => $helper->__('Base Image')
|
25 |
+
),
|
26 |
+
array(
|
27 |
+
'value' => 'media_image',
|
28 |
+
'label' => $helper->__('Media Image')
|
29 |
+
),
|
30 |
+
);
|
31 |
+
|
32 |
+
return $array;
|
33 |
+
}
|
34 |
+
}
|
app/code/community/Tiny/CompressImages/Model/System/Config/Source/Testlive.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Model_System_Config_Source_Testlive
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* Source model for test / live setting.
|
6 |
+
*
|
7 |
+
* @return array
|
8 |
+
*/
|
9 |
+
public function toOptionArray()
|
10 |
+
{
|
11 |
+
$helper = Mage::helper('tiny_compressimages');
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Used 0, 1 and 2 as values so that Mage::getStoreConfigFlag() would still function for checking if the
|
15 |
+
* extension is active. You still need to check if the value is 2 to see if it's in live or test mode.
|
16 |
+
*/
|
17 |
+
$array = array(
|
18 |
+
array(
|
19 |
+
'value' => '2',
|
20 |
+
'label' => $helper->__('Live')
|
21 |
+
),
|
22 |
+
array(
|
23 |
+
'value' => '1',
|
24 |
+
'label' => $helper->__('Test')
|
25 |
+
),
|
26 |
+
array(
|
27 |
+
'value' => '0',
|
28 |
+
'label' => $helper->__('Disabled')
|
29 |
+
),
|
30 |
+
);
|
31 |
+
return $array;
|
32 |
+
}
|
33 |
+
}
|
app/code/community/Tiny/CompressImages/Model/Totals.php
ADDED
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @method string|null getEntityId();
|
4 |
+
* @method $this setDateFrom(String $date);
|
5 |
+
* @method string|null getDateFrom();
|
6 |
+
* @method $this setDateTo(String $date);
|
7 |
+
* @method string|null getDateTo();
|
8 |
+
* @method $this setTotalBytesBefore(int $bytes);
|
9 |
+
* @method int|null getTotalBytesBefore();
|
10 |
+
* @method $this setTotalBytesAfter(int $bytes);
|
11 |
+
* @method int|null getTotalBytesAfter();
|
12 |
+
* @method $this setTotalCompressions(int $compressions);
|
13 |
+
* @method string|null getTotalCompressions();
|
14 |
+
* @method $this setUpdatedAt(String $date);
|
15 |
+
* @method string|null getUpdatedAt();
|
16 |
+
*/
|
17 |
+
class Tiny_CompressImages_Model_Totals extends Mage_Core_Model_Abstract
|
18 |
+
{
|
19 |
+
/**
|
20 |
+
* Constructor load his parent.
|
21 |
+
*/
|
22 |
+
public function __construct()
|
23 |
+
{
|
24 |
+
parent::__construct();
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Class constructor.
|
29 |
+
*/
|
30 |
+
public function _construct()
|
31 |
+
{
|
32 |
+
$this->_init('tiny_compressimages/totals');
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Gets the compression information over the total data.
|
37 |
+
*
|
38 |
+
* @return array
|
39 |
+
*/
|
40 |
+
public function getTotalCompressionInformation()
|
41 |
+
{
|
42 |
+
$collection = $this->getCollection();
|
43 |
+
|
44 |
+
$totalCompressions = 0;
|
45 |
+
$totalBytesBefore = 0;
|
46 |
+
$totalBytesAfter = 0;
|
47 |
+
|
48 |
+
/** @var Tiny_CompressImages_Model_Totals $record */
|
49 |
+
foreach ($collection as $record) {
|
50 |
+
$totalCompressions = $record->getTotalCompressions() + $totalCompressions;
|
51 |
+
$totalBytesBefore = $record->getTotalBytesBefore() + $totalBytesBefore;
|
52 |
+
$totalBytesAfter = $record->getTotalBytesAfter() + $totalBytesAfter;
|
53 |
+
}
|
54 |
+
|
55 |
+
$bytesSaved = $totalBytesBefore - $totalBytesAfter;
|
56 |
+
$percantageSaved = 0;
|
57 |
+
|
58 |
+
if ($bytesSaved !== 0) {
|
59 |
+
$percantageSaved = round(($bytesSaved / $totalBytesBefore) * 100);
|
60 |
+
}
|
61 |
+
|
62 |
+
return array(
|
63 |
+
'percentageSaved' => $percantageSaved,
|
64 |
+
'totalCompressions' => $totalCompressions,
|
65 |
+
'bytesBefore' => $this->formatBytes($totalBytesBefore),
|
66 |
+
'bytesAfter' => $this->formatBytes($totalBytesAfter),
|
67 |
+
);
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* @param $bytes
|
72 |
+
* @param int $precision
|
73 |
+
*
|
74 |
+
* @return string
|
75 |
+
*/
|
76 |
+
function formatBytes($bytes, $precision = 2) {
|
77 |
+
if ($bytes <= 0) {
|
78 |
+
return '0 KB';
|
79 |
+
}
|
80 |
+
|
81 |
+
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
82 |
+
|
83 |
+
$i = floor(log($bytes, 1024));
|
84 |
+
$sum = round($bytes / pow(1024, $i), $precision);
|
85 |
+
|
86 |
+
return $sum . ' ' . $units[$i];
|
87 |
+
|
88 |
+
}
|
89 |
+
}
|
app/code/community/Tiny/CompressImages/Test/Block/Adminhtml/System/Config/Form/Field/LogStatusTest.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Test_Block_Adminhtml_System_Config_Form_Field_LogStatusTest
|
3 |
+
extends Tiny_CompressImages_Test_Framework_Tiny_Test_TestCase
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* @var Tiny_CompressImages_Block_Adminhtml_System_Config_Form_Field_LogStatus
|
7 |
+
*/
|
8 |
+
protected $_instance = null;
|
9 |
+
|
10 |
+
protected function setUp()
|
11 |
+
{
|
12 |
+
$this->_instance = new Tiny_CompressImages_Block_Adminhtml_System_Config_Form_Field_LogStatus;
|
13 |
+
$this->_instance->setArea('adminhtml');
|
14 |
+
|
15 |
+
Mage::getModel('tiny_compressimages/image')->deleteAll();
|
16 |
+
}
|
17 |
+
|
18 |
+
public function testImagesLimit()
|
19 |
+
{
|
20 |
+
$html = $this->_instance->toHtml();
|
21 |
+
$this->assertNotContains('id="show_all"', $html);
|
22 |
+
|
23 |
+
for ($i = 0; $i < 11; $i++) {
|
24 |
+
$model = Mage::getModel('tiny_compressimages/image');
|
25 |
+
$model->setProcessedAt(Varien_Date::now());
|
26 |
+
$model->save();
|
27 |
+
}
|
28 |
+
|
29 |
+
$html = $this->_instance->toHtml();
|
30 |
+
$this->assertContains('id="show_all"', $html);
|
31 |
+
}
|
32 |
+
}
|
app/code/community/Tiny/CompressImages/Test/Framework/Tiny/Test/Config.php
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Test_Framework_Tiny_Test_Config extends Mage_Core_Model_Config
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* @var array
|
6 |
+
*/
|
7 |
+
protected $_mockModels = array();
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @var array
|
11 |
+
*/
|
12 |
+
protected $_mockResourceModels = array();
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @param string $modelClass
|
16 |
+
* @param object $mock
|
17 |
+
*
|
18 |
+
* @return $this
|
19 |
+
*/
|
20 |
+
public function setModelMock($modelClass, $mock)
|
21 |
+
{
|
22 |
+
$this->_mockModels[$modelClass] = $mock;
|
23 |
+
return $this;
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @param string $modelClass
|
28 |
+
* @param object $mock
|
29 |
+
*
|
30 |
+
* @return $this
|
31 |
+
*/
|
32 |
+
public function setResourceModelMock($modelClass, $mock)
|
33 |
+
{
|
34 |
+
$this->_mockResourceModels[$modelClass] = $mock;
|
35 |
+
return $this;
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @param string $modelClass
|
40 |
+
* @param array $constructArguments
|
41 |
+
*
|
42 |
+
* @return false|Mage_Core_Model_Abstract
|
43 |
+
*/
|
44 |
+
public function getModelInstance($modelClass = '', $constructArguments = array())
|
45 |
+
{
|
46 |
+
$modelClass = (string) $modelClass;
|
47 |
+
|
48 |
+
if (array_key_exists($modelClass, $this->_mockModels)) {
|
49 |
+
return $this->_mockModels[$modelClass];
|
50 |
+
}
|
51 |
+
|
52 |
+
return parent::getModelInstance($modelClass, $constructArguments);
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Get resource model object by alias
|
57 |
+
*
|
58 |
+
* @param string $modelClass
|
59 |
+
* @param array $constructArguments
|
60 |
+
* @return object
|
61 |
+
*/
|
62 |
+
public function getResourceModelInstance($modelClass='', $constructArguments = array())
|
63 |
+
{
|
64 |
+
$modelClass = (string) $modelClass;
|
65 |
+
|
66 |
+
if (array_key_exists($modelClass, $this->_mockResourceModels)) {
|
67 |
+
return $this->_mockResourceModels[$modelClass];
|
68 |
+
}
|
69 |
+
|
70 |
+
return parent::getResourceModelInstance($modelClass, $constructArguments);
|
71 |
+
}
|
72 |
+
}
|
app/code/community/Tiny/CompressImages/Test/Framework/Tiny/Test/Http/Response.php
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Test_Framework_Tiny_Test_Http_Response extends Mage_Core_Controller_Response_Http
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* @var bool
|
6 |
+
*/
|
7 |
+
protected $_headersSent = false;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @param boolean $headersSent
|
11 |
+
*
|
12 |
+
* @return Tiny_CompressImages_Test_Framework_Tiny_Test_Http_Response
|
13 |
+
*/
|
14 |
+
public function setHeadersSent($headersSent)
|
15 |
+
{
|
16 |
+
$this->_headersSent = $headersSent;
|
17 |
+
|
18 |
+
return $this;
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @return boolean
|
23 |
+
*/
|
24 |
+
public function getHeadersSent()
|
25 |
+
{
|
26 |
+
return $this->_headersSent;
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @param bool $throw
|
31 |
+
*
|
32 |
+
* @return bool
|
33 |
+
*/
|
34 |
+
public function canSendHeaders($throw = false)
|
35 |
+
{
|
36 |
+
$canSendHeaders = !$this->getHeadersSent();
|
37 |
+
return $canSendHeaders;
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @return Mage_Core_Controller_Response_Http
|
42 |
+
*/
|
43 |
+
public function sendHeaders()
|
44 |
+
{
|
45 |
+
$this->setHeadersSent(true);
|
46 |
+
|
47 |
+
return $this;
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @return $this
|
52 |
+
*/
|
53 |
+
public function sendResponse()
|
54 |
+
{
|
55 |
+
return $this;
|
56 |
+
}
|
57 |
+
|
58 |
+
}
|
app/code/community/Tiny/CompressImages/Test/Framework/Tiny/Test/TestCase.php
ADDED
@@ -0,0 +1,244 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Test_Framework_Tiny_Test_TestCase extends PHPUnit_Framework_TestCase
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* @var null
|
6 |
+
*/
|
7 |
+
protected $_instance = null;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Resets and restarts Magento.
|
11 |
+
*/
|
12 |
+
public static function resetMagento()
|
13 |
+
{
|
14 |
+
Mage::reset();
|
15 |
+
|
16 |
+
Mage::setIsDeveloperMode(false);
|
17 |
+
Mage::app(
|
18 |
+
'admin',
|
19 |
+
'store',
|
20 |
+
array(
|
21 |
+
'config_model' => 'Tiny_CompressImages_Test_Framework_Tiny_Test_Config'
|
22 |
+
)
|
23 |
+
)->setResponse(new Tiny_CompressImages_Test_Framework_Tiny_Test_Http_Response());
|
24 |
+
|
25 |
+
$handler = set_error_handler(function() {});
|
26 |
+
|
27 |
+
set_error_handler(function($errno, $errstr, $errfile, $errline) use ($handler) {
|
28 |
+
if (E_WARNING === $errno
|
29 |
+
&& 0 === strpos($errstr, 'include(')
|
30 |
+
&& substr($errfile, -19) == 'Varien/Autoload.php'
|
31 |
+
) {
|
32 |
+
return null;
|
33 |
+
}
|
34 |
+
return call_user_func(
|
35 |
+
$handler, $errno, $errstr, $errfile, $errline
|
36 |
+
);
|
37 |
+
});
|
38 |
+
}
|
39 |
+
|
40 |
+
public function prepareFrontendDispatch()
|
41 |
+
{
|
42 |
+
$store = Mage::app()->getDefaultStoreView();
|
43 |
+
$store->setConfig('web/url/redirect_to_base', false);
|
44 |
+
$store->setConfig('web/url/use_store', false);
|
45 |
+
$store->setConfig('advanced/modules_disable_output/Enterprise_Banner', true);
|
46 |
+
|
47 |
+
Mage::app()->setCurrentStore($store->getCode());
|
48 |
+
|
49 |
+
$this->registerMockSessions();
|
50 |
+
}
|
51 |
+
|
52 |
+
public function registerMockSessions($modules = null)
|
53 |
+
{
|
54 |
+
if (!is_array($modules)) {
|
55 |
+
$modules = array('core', 'customer', 'checkout', 'catalog', 'reports');
|
56 |
+
}
|
57 |
+
|
58 |
+
foreach ($modules as $module) {
|
59 |
+
$class = "$module/session";
|
60 |
+
$sessionMock = $this->getMockBuilder(
|
61 |
+
Mage::getConfig()->getModelClassName($class)
|
62 |
+
)->disableOriginalConstructor()
|
63 |
+
->getMock();
|
64 |
+
$sessionMock->expects($this->any())
|
65 |
+
->method('start')
|
66 |
+
->will($this->returnSelf());
|
67 |
+
$sessionMock->expects($this->any())
|
68 |
+
->method('init')
|
69 |
+
->will($this->returnSelf());
|
70 |
+
$sessionMock->expects($this->any())
|
71 |
+
->method('getMessages')
|
72 |
+
->will($this->returnValue(
|
73 |
+
Mage::getModel('core/message_collection')
|
74 |
+
));
|
75 |
+
$sessionMock->expects($this->any())
|
76 |
+
->method('getSessionIdQueryParam')
|
77 |
+
->will($this->returnValue(
|
78 |
+
Mage_Core_Model_Session_Abstract::SESSION_ID_QUERY_PARAM
|
79 |
+
));
|
80 |
+
$sessionMock->expects($this->any())
|
81 |
+
->method('getCookieShouldBeReceived')
|
82 |
+
->will($this->returnValue(false));
|
83 |
+
$this->setSingletonMock($class, $sessionMock);
|
84 |
+
$this->setModelMock($class, $sessionMock);
|
85 |
+
}
|
86 |
+
|
87 |
+
$cookieMock = $this->getMock('Mage_Core_Model_Cookie');
|
88 |
+
$cookieMock->expects($this->any())
|
89 |
+
->method('get')
|
90 |
+
->will($this->returnValue(serialize('dummy')));
|
91 |
+
Mage::unregister('_singleton/core/cookie');
|
92 |
+
Mage::register('_singleton/core/cookie', $cookieMock);
|
93 |
+
|
94 |
+
// mock visitor log observer
|
95 |
+
$logVisitorMock = $this->getMock('Mage_Log_Model_Visitor');
|
96 |
+
$this->setModelMock('log/visitor', $logVisitorMock);
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Fix enterprise catalog permissions issue
|
100 |
+
*/
|
101 |
+
$factoryName = 'enterprise_catalogpermissions/permission_index';
|
102 |
+
$className = Mage::getConfig()->getModelClassName($factoryName);
|
103 |
+
if (class_exists($className)) {
|
104 |
+
$mockPermissions = $this->getMock($className);
|
105 |
+
$mockPermissions->expects($this->any())
|
106 |
+
->method('getIndexForCategory')
|
107 |
+
->withAnyParameters()
|
108 |
+
->will($this->returnValue(array()));
|
109 |
+
|
110 |
+
$this->setSingletonMock($factoryName, $mockPermissions);
|
111 |
+
}
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* @param string $modelClass
|
116 |
+
* @param object $mock
|
117 |
+
*
|
118 |
+
* @return $this
|
119 |
+
*/
|
120 |
+
public function setModelMock($modelClass, $mock)
|
121 |
+
{
|
122 |
+
$this->getConfig()->setModelMock($modelClass, $mock);
|
123 |
+
|
124 |
+
return $this;
|
125 |
+
}
|
126 |
+
/**
|
127 |
+
* @param string $modelClass
|
128 |
+
* @param object $mock
|
129 |
+
*
|
130 |
+
* @return $this
|
131 |
+
*/
|
132 |
+
public function setResourceModelMock($modelClass, $mock)
|
133 |
+
{
|
134 |
+
$this->getConfig()->setResourceModelMock($modelClass, $mock);
|
135 |
+
|
136 |
+
return $this;
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* @param string $modelClass
|
141 |
+
* @param object $mock
|
142 |
+
*
|
143 |
+
* @return $this
|
144 |
+
*/
|
145 |
+
public function setSingletonMock($modelClass, $mock)
|
146 |
+
{
|
147 |
+
$registryKey = '_singleton/' . $modelClass;
|
148 |
+
|
149 |
+
Mage::unregister($registryKey);
|
150 |
+
Mage::register($registryKey, $mock);
|
151 |
+
|
152 |
+
return $this;
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* @param $modelClass
|
157 |
+
*
|
158 |
+
* @return mixed
|
159 |
+
*/
|
160 |
+
public function getSingletonMock($modelClass)
|
161 |
+
{
|
162 |
+
$registryKey = '_singleton/' . $modelClass;
|
163 |
+
|
164 |
+
return Mage::registry($registryKey);
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* @param string $resourceModelClass
|
169 |
+
* @param object $mock
|
170 |
+
*
|
171 |
+
* @return $this
|
172 |
+
*/
|
173 |
+
public function setResourceSingletonMock($resourceModelClass, $mock)
|
174 |
+
{
|
175 |
+
$registryKey = '_resource_singleton/' . $resourceModelClass;
|
176 |
+
|
177 |
+
Mage::unregister($registryKey);
|
178 |
+
Mage::register($registryKey, $mock);
|
179 |
+
|
180 |
+
return $this;
|
181 |
+
}
|
182 |
+
|
183 |
+
/**
|
184 |
+
* @param string $helperClass
|
185 |
+
* @param object $mock
|
186 |
+
*
|
187 |
+
* @return $this
|
188 |
+
*/
|
189 |
+
public function setHelperMock($helperClass, $mock)
|
190 |
+
{
|
191 |
+
$registryKey = '_helper/' . $helperClass;
|
192 |
+
|
193 |
+
Mage::unregister($registryKey);
|
194 |
+
Mage::register($registryKey, $mock);
|
195 |
+
|
196 |
+
return $this;
|
197 |
+
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* @return Tiny_CompressImages_Test_Framework_Tiny_Test_Config
|
201 |
+
*/
|
202 |
+
public function getConfig()
|
203 |
+
{
|
204 |
+
return Mage::getConfig();
|
205 |
+
}
|
206 |
+
|
207 |
+
/**
|
208 |
+
* Create the models with the provided data.
|
209 |
+
*
|
210 |
+
* @param $modelName
|
211 |
+
* @param $data
|
212 |
+
*/
|
213 |
+
public function createModels($modelName, $data)
|
214 |
+
{
|
215 |
+
foreach ($data as $row) {
|
216 |
+
$model = Mage::getModel($modelName);
|
217 |
+
$model->setData($row);
|
218 |
+
$model->save();
|
219 |
+
}
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* Sets a protected property to the provided value.
|
224 |
+
*
|
225 |
+
* @param $property
|
226 |
+
* @param $value
|
227 |
+
* @param null $instance
|
228 |
+
*
|
229 |
+
* @return $this
|
230 |
+
*/
|
231 |
+
public function setProperty($property, $value, $instance = null)
|
232 |
+
{
|
233 |
+
if ($instance === null) {
|
234 |
+
$instance = $this->_instance;
|
235 |
+
}
|
236 |
+
|
237 |
+
$reflection = new ReflectionObject($instance);
|
238 |
+
$property = $reflection->getProperty($property);
|
239 |
+
$property->setAccessible(true);
|
240 |
+
$property->setValue($instance, $value);
|
241 |
+
|
242 |
+
return $this;
|
243 |
+
}
|
244 |
+
}
|
app/code/community/Tiny/CompressImages/Test/Helper/ConfigTest.php
ADDED
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Test_Helper_DataTest extends Tiny_CompressImages_Test_Framework_Tiny_Test_TestCase
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* @var Tiny_CompressImages_Helper_Config
|
6 |
+
*/
|
7 |
+
protected $_instance = null;
|
8 |
+
|
9 |
+
public function setUp()
|
10 |
+
{
|
11 |
+
$this->_instance = Mage::helper('tiny_compressimages/config');
|
12 |
+
}
|
13 |
+
|
14 |
+
public function getProductImageTypesToCompressDataProvider()
|
15 |
+
{
|
16 |
+
return array(
|
17 |
+
array(
|
18 |
+
array(
|
19 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_BASE => 1,
|
20 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_SMALL => 1,
|
21 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_THUMBNAIL => 1,
|
22 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_SWATCHES => 1,
|
23 |
+
),
|
24 |
+
array(
|
25 |
+
'image',
|
26 |
+
'small_image',
|
27 |
+
'thumbnail',
|
28 |
+
'media_image',
|
29 |
+
'swatches',
|
30 |
+
),
|
31 |
+
),
|
32 |
+
array(
|
33 |
+
array(
|
34 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_BASE => 0,
|
35 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_SMALL => 1,
|
36 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_THUMBNAIL => 1,
|
37 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_SWATCHES => 1,
|
38 |
+
),
|
39 |
+
array(
|
40 |
+
'small_image',
|
41 |
+
'thumbnail',
|
42 |
+
'media_image',
|
43 |
+
'swatches',
|
44 |
+
),
|
45 |
+
),
|
46 |
+
array(
|
47 |
+
array(
|
48 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_BASE => 0,
|
49 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_SMALL => 0,
|
50 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_THUMBNAIL => 1,
|
51 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_SWATCHES => 1,
|
52 |
+
),
|
53 |
+
array(
|
54 |
+
'thumbnail',
|
55 |
+
'media_image',
|
56 |
+
'swatches',
|
57 |
+
),
|
58 |
+
),
|
59 |
+
array(
|
60 |
+
array(
|
61 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_BASE => 0,
|
62 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_SMALL => 0,
|
63 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_THUMBNAIL => 0,
|
64 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_SWATCHES => 1,
|
65 |
+
),
|
66 |
+
array(
|
67 |
+
'swatches',
|
68 |
+
),
|
69 |
+
),
|
70 |
+
array(
|
71 |
+
array(
|
72 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_BASE => 0,
|
73 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_SMALL => 0,
|
74 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_THUMBNAIL => 0,
|
75 |
+
Tiny_CompressImages_Helper_Config::XPATH_IMAGE_TYPE_SWATCHES => 0,
|
76 |
+
),
|
77 |
+
array(
|
78 |
+
),
|
79 |
+
),
|
80 |
+
);
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @dataProvider getProductImageTypesToCompressDataProvider
|
85 |
+
*/
|
86 |
+
public function testGetProductImageTypesToCompress($config, $shouldHave)
|
87 |
+
{
|
88 |
+
foreach ($config as $path => $value) {
|
89 |
+
Mage::app()->getStore()->setConfig($path, $value);
|
90 |
+
}
|
91 |
+
|
92 |
+
$result = $this->_instance->getProductImageTypesToCompress();
|
93 |
+
|
94 |
+
$this->assertEquals($shouldHave, $result);
|
95 |
+
}
|
96 |
+
}
|
app/code/community/Tiny/CompressImages/Test/Model/ImageTest.php
ADDED
@@ -0,0 +1,227 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class ImageTest extends Tiny_CompressImages_Test_Framework_Tiny_Test_TestCase
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* @var Tiny_CompressImages_Model_Image
|
6 |
+
*/
|
7 |
+
protected $_instance = null;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Delete all models before testing.
|
11 |
+
*/
|
12 |
+
public function setup()
|
13 |
+
{
|
14 |
+
Mage::getModel('tiny_compressimages/image')->deleteAll();
|
15 |
+
|
16 |
+
$this->_instance = Mage::getModel('tiny_compressimages/image');
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Test data.
|
21 |
+
*
|
22 |
+
* @return array
|
23 |
+
*/
|
24 |
+
public function testGetStatisticsDataProvider()
|
25 |
+
{
|
26 |
+
$now = Zend_Date::now();
|
27 |
+
|
28 |
+
return array(
|
29 |
+
array(
|
30 |
+
array(
|
31 |
+
array(
|
32 |
+
'path' => '/media/catalog/product/cache/1/image/c96a280f94e22e3ee3823dd0a1a87606/a/c/acj003_2.jpg',
|
33 |
+
'hash_before' => md5(uniqid()),
|
34 |
+
'hash_after' => md5(uniqid()),
|
35 |
+
'bytes_before' => 100,
|
36 |
+
'bytes_after' => 50,
|
37 |
+
'used_as_source' => 3,
|
38 |
+
'processed_at' => $now->subMonth(1),
|
39 |
+
),
|
40 |
+
array(
|
41 |
+
'path' => '/media/catalog/product/cache/1/image/c96a280f94e22e3ee3823dd0a1a87606/a/c/acj003_2.jpg',
|
42 |
+
'hash_before' => md5(uniqid()),
|
43 |
+
'hash_after' => md5(uniqid()),
|
44 |
+
'bytes_before' => 100,
|
45 |
+
'bytes_after' => 75,
|
46 |
+
'used_as_source' => 3,
|
47 |
+
'processed_at' => Varien_Date::now(),
|
48 |
+
),
|
49 |
+
),
|
50 |
+
array(
|
51 |
+
'percentage' => '25 %',
|
52 |
+
'percentage_all_year' => '38 %',
|
53 |
+
'greatest_saving' => '25',
|
54 |
+
'greatest_saving_all_year' => '50',
|
55 |
+
'bytes_saved' => 25,
|
56 |
+
'bytes_saved_all_year' => 75,
|
57 |
+
'images_count' => 1,
|
58 |
+
'images_count_all_year' => 2,
|
59 |
+
)
|
60 |
+
),
|
61 |
+
array(
|
62 |
+
array(
|
63 |
+
array(
|
64 |
+
'path' => '/media/catalog/product/cache/1/image/c96a280f94e22e3ee3823dd0a1a87606/d/e/dec001_1.jpg',
|
65 |
+
'hash_before' => md5(uniqid()),
|
66 |
+
'hash_after' => md5(uniqid()),
|
67 |
+
'bytes_before' => 500,
|
68 |
+
'bytes_after' => 400,
|
69 |
+
'used_as_source' => 1,
|
70 |
+
'processed_at' => Varien_Date::now(),
|
71 |
+
),
|
72 |
+
),
|
73 |
+
array(
|
74 |
+
'percentage' => '20 %',
|
75 |
+
'percentage_all_year' => '20 %',
|
76 |
+
'greatest_saving' => '20',
|
77 |
+
'greatest_saving_all_year' => '20',
|
78 |
+
'bytes_saved' => 100,
|
79 |
+
'bytes_saved_all_year' => 100,
|
80 |
+
'images_count' => 1,
|
81 |
+
'images_count_all_year' => 1,
|
82 |
+
)
|
83 |
+
),
|
84 |
+
array(
|
85 |
+
array(
|
86 |
+
array(
|
87 |
+
'path' => '/media/catalog/product/cache/1/image/c96a280f94e22e3ee3823dd0a1a87606/t/r/troe008.jpg',
|
88 |
+
'hash_before' => md5(uniqid()),
|
89 |
+
'hash_after' => md5(uniqid()),
|
90 |
+
'bytes_before' => 200,
|
91 |
+
'bytes_after' => 150,
|
92 |
+
'used_as_source' => 1,
|
93 |
+
'processed_at' => Varien_Date::now(),
|
94 |
+
),
|
95 |
+
),
|
96 |
+
array(
|
97 |
+
'percentage' => '25 %',
|
98 |
+
'percentage_all_year' => '25 %',
|
99 |
+
'greatest_saving' => '25',
|
100 |
+
'greatest_saving_all_year' => '25',
|
101 |
+
'bytes_saved' => 50,
|
102 |
+
'bytes_saved_all_year' => 50,
|
103 |
+
'images_count' => 1,
|
104 |
+
'images_count_all_year' => 1,
|
105 |
+
)
|
106 |
+
),
|
107 |
+
);
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Test the results provided by the getStatistics method.
|
112 |
+
*
|
113 |
+
* @dataProvider testGetStatisticsDataProvider
|
114 |
+
*/
|
115 |
+
public function testGetStatistics($models, $results)
|
116 |
+
{
|
117 |
+
$this->createModels('tiny_compressimages/image', $models);
|
118 |
+
|
119 |
+
$stats = $this->_instance->getStatistics();
|
120 |
+
$this->assertEquals($results['percentage'], $stats->getPercentageSaved());
|
121 |
+
$this->assertEquals($results['bytes_saved'], $stats->getBytesSaved());
|
122 |
+
$this->assertEquals($results['images_count'], $stats->getImagesCount());
|
123 |
+
$this->assertEquals($results['greatest_saving'], $stats->getGreatestSaving());
|
124 |
+
|
125 |
+
$stats = $this->_instance->getStatistics(['current_month' => false]);
|
126 |
+
$this->assertEquals($results['percentage_all_year'], $stats->getPercentageSaved());
|
127 |
+
$this->assertEquals($results['bytes_saved_all_year'], $stats->getBytesSaved());
|
128 |
+
$this->assertEquals($results['images_count_all_year'], $stats->getImagesCount());
|
129 |
+
$this->assertEquals($results['greatest_saving_all_year'], $stats->getGreatestSaving());
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Test the fetching of a model by a hash.
|
134 |
+
*/
|
135 |
+
public function testGetByHash()
|
136 |
+
{
|
137 |
+
$this->createModels('tiny_compressimages/image', array(
|
138 |
+
array(
|
139 |
+
'path' => '1.jpg',
|
140 |
+
'hash_before' => '54eab696c5c868b669076216ede66a9f',
|
141 |
+
'hash_after' => '636734773941b236c82c9285b11d7f6c',
|
142 |
+
'processed_at' => Varien_Date::now(),
|
143 |
+
),
|
144 |
+
array(
|
145 |
+
'path' => '2.jpg',
|
146 |
+
'hash_before' => 'e79f197d28bebd30ba1bc571c2cc075a',
|
147 |
+
'hash_after' => 'df72ed8dbbdca9c440ff6d3182fb0070',
|
148 |
+
'processed_at' => Varien_Date::now(),
|
149 |
+
),
|
150 |
+
array(
|
151 |
+
'path' => '3.jpg',
|
152 |
+
'hash_before' => '59c50fe6455c85fe00b169bde7cb1962',
|
153 |
+
'hash_after' => '8e160a4f7fa67e9126269bedcc81c640',
|
154 |
+
'processed_at' => Varien_Date::now(),
|
155 |
+
),
|
156 |
+
));
|
157 |
+
|
158 |
+
$model = $this->_instance->getByHash('54eab696c5c868b669076216ede66a9f');
|
159 |
+
$this->assertEquals('1.jpg', $model->getPath());
|
160 |
+
|
161 |
+
$model = $this->_instance->getByHash('df72ed8dbbdca9c440ff6d3182fb0070');
|
162 |
+
$this->assertEquals('2.jpg', $model->getPath());
|
163 |
+
|
164 |
+
$model = $this->_instance->getByHash('foobar');
|
165 |
+
$this->assertNull($model);
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* Test if the addUsedAsSource works properly.
|
170 |
+
*/
|
171 |
+
public function testAddUsedAsSource()
|
172 |
+
{
|
173 |
+
for ($i = 1; $i <= 3; $i++) {
|
174 |
+
$this->_instance->addUsedAsSource();
|
175 |
+
$this->assertEquals($i, $this->_instance->getUsedAsSource());
|
176 |
+
}
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Test the getBytesSaved method.
|
181 |
+
*/
|
182 |
+
public function testGetBytesSaved()
|
183 |
+
{
|
184 |
+
$this->_instance->setBytesBefore(500);
|
185 |
+
$this->_instance->setBytesAfter(300);
|
186 |
+
|
187 |
+
$this->assertEquals(200, $this->_instance->getBytesSaved());
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Test the getPercentageSaved method.
|
192 |
+
*/
|
193 |
+
public function testGetPercentageSaved()
|
194 |
+
{
|
195 |
+
$this->_instance->setBytesBefore(500);
|
196 |
+
$this->_instance->setBytesAfter(400);
|
197 |
+
|
198 |
+
$this->assertEquals('20 %', $this->_instance->getPercentageSaved());
|
199 |
+
|
200 |
+
$this->_instance->setBytesBefore(500);
|
201 |
+
$this->_instance->setBytesAfter(500);
|
202 |
+
|
203 |
+
$this->assertEquals('0 %', $this->_instance->getPercentageSaved());
|
204 |
+
}
|
205 |
+
|
206 |
+
/**
|
207 |
+
* Test the deleteTest method.
|
208 |
+
*/
|
209 |
+
public function testDeleteAll()
|
210 |
+
{
|
211 |
+
$models = array();
|
212 |
+
for ($i = 0; $i < 10; $i++) {
|
213 |
+
$models[] = array(
|
214 |
+
'hash_before' => md5(uniqid()),
|
215 |
+
'hash_after' => md5(uniqid()),
|
216 |
+
);
|
217 |
+
}
|
218 |
+
|
219 |
+
$this->createModels('tiny_compressimages/image', $models);
|
220 |
+
|
221 |
+
$this->assertEquals(10, $this->_instance->getCollection()->getSize());
|
222 |
+
|
223 |
+
$this->_instance->deleteAll();
|
224 |
+
|
225 |
+
$this->assertEquals(0, $this->_instance->getCollection()->getSize());
|
226 |
+
}
|
227 |
+
}
|
app/code/community/Tiny/CompressImages/Test/Model/Product/ImageTest.php
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Model_Product_ImageTest extends Tiny_CompressImages_Test_Framework_Tiny_Test_TestCase
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* @var null|Tiny_CompressImages_Helper_Config
|
6 |
+
*/
|
7 |
+
protected $_helper = null;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @var Mage_Catalog_Model_Product_Image
|
11 |
+
*/
|
12 |
+
protected $_instance = null;
|
13 |
+
|
14 |
+
public function setUp()
|
15 |
+
{
|
16 |
+
$this->_instance = Mage::getModel('catalog/product_image');
|
17 |
+
$this->_helper = $this->getMock('Tiny_CompressImages_Helper_Config');
|
18 |
+
|
19 |
+
$this->setProperty('_configHelper', $this->_helper);
|
20 |
+
}
|
21 |
+
|
22 |
+
public function testGetUrl()
|
23 |
+
{
|
24 |
+
$this->_helper
|
25 |
+
->expects($this->once())
|
26 |
+
->method('isTestMode')
|
27 |
+
->willReturn('false');
|
28 |
+
|
29 |
+
$this->setProperty('_newFile', 'test.jpg');
|
30 |
+
|
31 |
+
$url = Mage::getBaseUrl('web');
|
32 |
+
$result = $this->_instance->getUrl();
|
33 |
+
|
34 |
+
$this->assertEquals('http://magento.local/media/test.jpg', str_replace($url, 'http://magento.local/', $result));
|
35 |
+
|
36 |
+
Mage::app()->getStore()->setConfig('web/seo/', 1);
|
37 |
+
|
38 |
+
$this->assertEquals('http://magento.local/media/test.jpg', str_replace($url, 'http://magento.local/', $result));
|
39 |
+
}
|
40 |
+
}
|
app/code/community/Tiny/CompressImages/Test/Model/System/Config/Backend/Comment/LoggingModeTest.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_Test_Model_System_Config_Backend_Comment_LoggingModeTest
|
3 |
+
extends Tiny_CompressImages_Test_Framework_Tiny_Test_TestCase
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* @var null|Tiny_CompressImages_Model_System_Config_Backend_Comment_LoggingMode
|
7 |
+
*/
|
8 |
+
protected $_instance = null;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var null|string
|
12 |
+
*/
|
13 |
+
protected $_logPath = null;
|
14 |
+
|
15 |
+
public function setUp()
|
16 |
+
{
|
17 |
+
$this->_logPath = Mage::helper('tiny_compressimages')->getLogFilePath();
|
18 |
+
$this->_instance = new Tiny_CompressImages_Model_System_Config_Backend_Comment_LoggingMode;
|
19 |
+
|
20 |
+
if (file_exists($this->_logPath)) {
|
21 |
+
unlink($this->_logPath);
|
22 |
+
}
|
23 |
+
}
|
24 |
+
|
25 |
+
public function testCommentReturnsLink()
|
26 |
+
{
|
27 |
+
$text = $this->_instance->getCommentText();
|
28 |
+
$this->assertNotContains('<a href', $text);
|
29 |
+
|
30 |
+
touch($this->_logPath);
|
31 |
+
$text = $this->_instance->getCommentText();
|
32 |
+
$this->assertContains('<a href', $text);
|
33 |
+
}
|
34 |
+
}
|
app/code/community/Tiny/CompressImages/Test/bootstrap.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if (strpos(__DIR__, '.modman') !== false) {
|
3 |
+
require_once(dirname(__DIR__) . '/../../../../../../../app/Mage.php');
|
4 |
+
} else {
|
5 |
+
require_once(__DIR__ . '/../../../../../../Mage.php');
|
6 |
+
}
|
7 |
+
|
8 |
+
ini_set('display_errors', true);
|
9 |
+
error_reporting(-1);
|
10 |
+
Tiny_CompressImages_Test_Framework_Tiny_Test_TestCase::resetMagento();
|
app/code/community/Tiny/CompressImages/controllers/CompressImagesAdminhtml/ConfigController.php
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_CompressImagesAdminhtml_ConfigController extends Mage_Adminhtml_Controller_Action
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* @return bool
|
6 |
+
*/
|
7 |
+
protected function _isAllowed()
|
8 |
+
{
|
9 |
+
/** @var Mage_Admin_Model_Session $session */
|
10 |
+
$session = Mage::getSingleton('admin/session');
|
11 |
+
|
12 |
+
return $session->isAllowed('admin/compressimages');
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Download CompressImages log file
|
17 |
+
*
|
18 |
+
* @return $this
|
19 |
+
*/
|
20 |
+
public function downloadLogsAction()
|
21 |
+
{
|
22 |
+
/** @var Tiny_CompressImages_Helper_Data $helper */
|
23 |
+
$helper = Mage::helper('tiny_compressimages');
|
24 |
+
$filePath = $helper->getLogFilePath();
|
25 |
+
|
26 |
+
if (!$helper->getLogFileExists()) {
|
27 |
+
return $this;
|
28 |
+
}
|
29 |
+
|
30 |
+
$content = array(
|
31 |
+
'type' => 'filename',
|
32 |
+
'value' => $filePath,
|
33 |
+
'rm' => false,
|
34 |
+
);
|
35 |
+
|
36 |
+
$this->postDispatch();
|
37 |
+
$this->_prepareDownloadResponse($helper->getLogFilename(), $content);
|
38 |
+
|
39 |
+
return $this;
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @return bool
|
44 |
+
*/
|
45 |
+
public function clearCacheAction()
|
46 |
+
{
|
47 |
+
try {
|
48 |
+
Mage::getModel('catalog/product_image')->clearCache();
|
49 |
+
Mage::dispatchEvent('clean_catalog_images_cache_after');
|
50 |
+
$this->_getSession()->addSuccess(
|
51 |
+
Mage::helper('adminhtml')->__('The image cache was cleaned.')
|
52 |
+
);
|
53 |
+
}
|
54 |
+
catch (Mage_Core_Exception $e) {
|
55 |
+
$this->_getSession()->addError($e->getMessage());
|
56 |
+
}
|
57 |
+
catch (Exception $e) {
|
58 |
+
$this->_getSession()->addException(
|
59 |
+
$e,
|
60 |
+
Mage::helper('adminhtml')->__('An error occurred while clearing the image cache.')
|
61 |
+
);
|
62 |
+
}
|
63 |
+
$this->_redirect('adminhtml/system_config/edit/section/tiny_compressimages');
|
64 |
+
}
|
65 |
+
}
|
app/code/community/Tiny/CompressImages/controllers/CompressImagesAdminhtml/StatusController.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class Tiny_CompressImages_CompressImagesAdminhtml_StatusController extends Mage_Adminhtml_Controller_Action
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* @var Tiny_Compressimages_Helper_Tinify
|
6 |
+
*/
|
7 |
+
protected $_helper = null;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @return bool
|
11 |
+
*/
|
12 |
+
protected function _isAllowed()
|
13 |
+
{
|
14 |
+
/** @var Mage_Admin_Model_Session $session */
|
15 |
+
$session = Mage::getSingleton('admin/session');
|
16 |
+
|
17 |
+
return $session->isAllowed('admin/compressimages');
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Get the Tinify helper.
|
22 |
+
*
|
23 |
+
* @return Tiny_CompressImages_Helper_Tinify
|
24 |
+
*/
|
25 |
+
public function getHelper()
|
26 |
+
{
|
27 |
+
if ($this->_helper === null) {
|
28 |
+
$this->_helper = Mage::helper('tiny_compressimages/tinify');
|
29 |
+
}
|
30 |
+
|
31 |
+
return $this->_helper;
|
32 |
+
}
|
33 |
+
|
34 |
+
public function getApiStatusAction()
|
35 |
+
{
|
36 |
+
if (!$this->_validateFormKey()) {
|
37 |
+
return;
|
38 |
+
}
|
39 |
+
|
40 |
+
$result = $this->getHelper()->getApiStatus();
|
41 |
+
|
42 |
+
/** @var Mage_Core_Helper_Data $coreHelper */
|
43 |
+
$coreHelper = Mage::helper('core');
|
44 |
+
$this->getResponse()->setBody($coreHelper->jsonEncode($result));
|
45 |
+
}
|
46 |
+
}
|
app/code/community/Tiny/CompressImages/etc/adminhtml.xml
CHANGED
@@ -1,21 +1,26 @@
|
|
|
|
1 |
<config>
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
<
|
8 |
-
<config>
|
9 |
<children>
|
10 |
-
|
11 |
-
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
</children>
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
</children>
|
18 |
-
</admin>
|
19 |
-
</resources>
|
20 |
-
</acl>
|
21 |
</config>
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
<config>
|
3 |
+
<acl>
|
4 |
+
<resources>
|
5 |
+
<all>
|
6 |
+
<title>Allow everything</title>
|
7 |
+
</all>
|
8 |
+
<admin>
|
|
|
9 |
<children>
|
10 |
+
<system>
|
11 |
+
<children>
|
12 |
+
<config>
|
13 |
+
<children>
|
14 |
+
<tiny_compressimages translate="title">
|
15 |
+
<title>Tiny CompressImages</title>
|
16 |
+
<sort_order>500</sort_order>
|
17 |
+
</tiny_compressimages>
|
18 |
+
</children>
|
19 |
+
</config>
|
20 |
+
</children>
|
21 |
+
</system>
|
22 |
</children>
|
23 |
+
</admin>
|
24 |
+
</resources>
|
25 |
+
</acl>
|
|
|
|
|
|
|
|
|
26 |
</config>
|
app/code/community/Tiny/CompressImages/etc/config.xml
CHANGED
@@ -1,30 +1,105 @@
|
|
|
|
1 |
<config>
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
<
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
<
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
</config>
|
1 |
+
<?xml version="1.0"?>
|
2 |
<config>
|
3 |
+
<modules>
|
4 |
+
<Tiny_CompressImages>
|
5 |
+
<version>2.0.0</version>
|
6 |
+
<stability>stable</stability>
|
7 |
+
</Tiny_CompressImages>
|
8 |
+
</modules>
|
9 |
+
<global>
|
10 |
+
<blocks>
|
11 |
+
<tiny_compressimages>
|
12 |
+
<class>Tiny_CompressImages_Block</class>
|
13 |
+
</tiny_compressimages>
|
14 |
+
</blocks>
|
15 |
+
<helpers>
|
16 |
+
<tiny_compressimages>
|
17 |
+
<class>Tiny_CompressImages_Helper</class>
|
18 |
+
</tiny_compressimages>
|
19 |
+
</helpers>
|
20 |
+
<models>
|
21 |
+
<tiny_compressimages>
|
22 |
+
<class>Tiny_CompressImages_Model</class>
|
23 |
+
<resourceModel>tiny_compressimages_resource</resourceModel>
|
24 |
+
</tiny_compressimages>
|
25 |
+
<tiny_compressimages_resource>
|
26 |
+
<class>Tiny_CompressImages_Model_Resource</class>
|
27 |
+
<entities>
|
28 |
+
<image>
|
29 |
+
<table>tiny_compressimages_image</table>
|
30 |
+
</image>
|
31 |
+
<totals>
|
32 |
+
<table>tiny_compressimages_totals</table>
|
33 |
+
</totals>
|
34 |
+
</entities>
|
35 |
+
</tiny_compressimages_resource>
|
36 |
+
<catalog>
|
37 |
+
<rewrite>
|
38 |
+
<product_image>Tiny_CompressImages_Model_Product_Image</product_image>
|
39 |
+
</rewrite>
|
40 |
+
</catalog>
|
41 |
+
</models>
|
42 |
+
<resources>
|
43 |
+
<tiny_compressimages_setup>
|
44 |
+
<setup>
|
45 |
+
<class>Tiny_CompressImages_Model_Resource_Setup</class>
|
46 |
+
<module>Tiny_CompressImages</module>
|
47 |
+
</setup>
|
48 |
+
</tiny_compressimages_setup>
|
49 |
+
</resources>
|
50 |
+
<events>
|
51 |
+
<catalog_product_image_save_after>
|
52 |
+
<observers>
|
53 |
+
<tiny_compressimages_compress_product_image>
|
54 |
+
<type>singleton</type>
|
55 |
+
<class>Tiny_CompressImages_Model_Observer</class>
|
56 |
+
<method>catalogProductImageSaveAfter</method>
|
57 |
+
</tiny_compressimages_compress_product_image>
|
58 |
+
</observers>
|
59 |
+
</catalog_product_image_save_after>
|
60 |
+
</events>
|
61 |
+
</global>
|
62 |
+
<admin>
|
63 |
+
<routers>
|
64 |
+
<adminhtml>
|
65 |
+
<args>
|
66 |
+
<modules>
|
67 |
+
<tiny_compressimages after="Mage_Adminhtml">Tiny_CompressImages</tiny_compressimages>
|
68 |
+
</modules>
|
69 |
+
</args>
|
70 |
+
</adminhtml>
|
71 |
+
</routers>
|
72 |
+
</admin>
|
73 |
+
<adminhtml>
|
74 |
+
<layout>
|
75 |
+
<updates>
|
76 |
+
<tiny_compressimages>
|
77 |
+
<file>Tiny/CompressImages.xml</file>
|
78 |
+
</tiny_compressimages>
|
79 |
+
</updates>
|
80 |
+
</layout>
|
81 |
+
<translate>
|
82 |
+
<modules>
|
83 |
+
<Tiny_CompressImages>
|
84 |
+
<files>
|
85 |
+
<default>Tiny_CompressImages.csv</default>
|
86 |
+
</files>
|
87 |
+
</Tiny_CompressImages>
|
88 |
+
</modules>
|
89 |
+
</translate>
|
90 |
+
</adminhtml>
|
91 |
+
<default>
|
92 |
+
<tiny_compressimages>
|
93 |
+
<image_types>
|
94 |
+
<base_images>1</base_images>
|
95 |
+
<small_images>1</small_images>
|
96 |
+
<thumbnails>1</thumbnails>
|
97 |
+
<swatches>1</swatches>
|
98 |
+
</image_types>
|
99 |
+
<advanced>
|
100 |
+
<logging_mode>all</logging_mode>
|
101 |
+
<enabled>2</enabled>
|
102 |
+
</advanced>
|
103 |
+
</tiny_compressimages>
|
104 |
+
</default>
|
105 |
</config>
|
app/code/community/Tiny/CompressImages/etc/system.xml
CHANGED
@@ -1,89 +1,193 @@
|
|
|
|
1 |
<config>
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
</config>
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
<config>
|
3 |
+
<sections>
|
4 |
+
<tiny_compressimages translate="label" module="tiny_compressimages">
|
5 |
+
<label>Image Optimization</label>
|
6 |
+
<tab>general</tab>
|
7 |
+
<frontend_model>tiny_compressimages/adminhtml_system_config_form</frontend_model>
|
8 |
+
<class>tiny-compressimages-section</class>
|
9 |
+
<frontend_type>text</frontend_type>
|
10 |
+
<sort_order>1200</sort_order>
|
11 |
+
<show_in_default>1</show_in_default>
|
12 |
+
<show_in_website>1</show_in_website>
|
13 |
+
<show_in_store>1</show_in_store>
|
14 |
+
<groups>
|
15 |
+
<support translate="label" module="tiny_compressimages">
|
16 |
+
<label>Version & Support</label>
|
17 |
+
<sort_order>10</sort_order> <!-- This should always be the first tab -->
|
18 |
+
<show_in_default>1</show_in_default>
|
19 |
+
<show_in_website>1</show_in_website>
|
20 |
+
<show_in_store>1</show_in_store>
|
21 |
+
<fields>
|
22 |
+
<support>
|
23 |
+
<sort_order>0</sort_order>
|
24 |
+
<frontend_model>tiny_compressimages/adminhtml_system_config_form_field_supportTab</frontend_model>
|
25 |
+
<show_in_default>1</show_in_default>
|
26 |
+
<show_in_website>1</show_in_website>
|
27 |
+
<show_in_store>1</show_in_store>
|
28 |
+
</support>
|
29 |
+
</fields>
|
30 |
+
</support>
|
31 |
+
<settings translate="label">
|
32 |
+
<label>Connection Settings</label>
|
33 |
+
<sort_order>20</sort_order>
|
34 |
+
<show_in_default>1</show_in_default>
|
35 |
+
<show_in_website>1</show_in_website>
|
36 |
+
<show_in_store>1</show_in_store>
|
37 |
+
<class>active</class>
|
38 |
+
<fields>
|
39 |
+
<api_key tranaslate="label comment">
|
40 |
+
<label>API Key</label>
|
41 |
+
<frontend_type>text</frontend_type>
|
42 |
+
<backend_model>tiny_compressimages/system_config_backend_apiKey</backend_model>
|
43 |
+
<comment><![CDATA[Visit <a href="https://tinypng.com/developers/subscription" target="_BLANK">TinyPNG Developer section</a> to get an API key.]]></comment>
|
44 |
+
<sort_order>10</sort_order>
|
45 |
+
<show_in_default>1</show_in_default>
|
46 |
+
<show_in_website>1</show_in_website>
|
47 |
+
<show_in_store>1</show_in_store>
|
48 |
+
</api_key>
|
49 |
+
<api>
|
50 |
+
<label>TinyPNG API Status</label>
|
51 |
+
<sort_order>20</sort_order>
|
52 |
+
<frontend_type>compressimages_api</frontend_type>
|
53 |
+
<show_in_default>1</show_in_default>
|
54 |
+
<show_in_website>1</show_in_website>
|
55 |
+
<show_in_store>1</show_in_store>
|
56 |
+
</api>
|
57 |
+
<usage translate="label comment">
|
58 |
+
<label> </label>
|
59 |
+
<sort_order>30</sort_order>
|
60 |
+
<frontend_type>compressimages_status</frontend_type>
|
61 |
+
<show_in_default>1</show_in_default>
|
62 |
+
<show_in_website>0</show_in_website>
|
63 |
+
<show_in_store>0</show_in_store>
|
64 |
+
</usage>
|
65 |
+
</fields>
|
66 |
+
</settings>
|
67 |
+
<image_types translate="label">
|
68 |
+
<label>Image Types to Optimize</label>
|
69 |
+
<comment>Choose which generated image types should be optimized with TinyPNG or TinyJPG. Each selected image size counts as one compression in your compression total.</comment>
|
70 |
+
<sort_order>25</sort_order>
|
71 |
+
<show_in_default>1</show_in_default>
|
72 |
+
<show_in_website>1</show_in_website>
|
73 |
+
<show_in_store>1</show_in_store>
|
74 |
+
<class>active</class>
|
75 |
+
<fields>
|
76 |
+
<base_images translate="label comment tooltip">
|
77 |
+
<label>Base Images</label>
|
78 |
+
<frontend_type>select</frontend_type>
|
79 |
+
<comment>Large images on product pages.</comment>
|
80 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
81 |
+
<sort_order>10</sort_order>
|
82 |
+
<show_in_default>1</show_in_default>
|
83 |
+
<show_in_website>1</show_in_website>
|
84 |
+
<show_in_store>1</show_in_store>
|
85 |
+
</base_images>
|
86 |
+
<small_images translate="label comment tooltip">
|
87 |
+
<label>Small Images</label>
|
88 |
+
<comment>Smaller images on category pages, in list of recently viewed product, new product lists, upsells, wish lists, etc.</comment>
|
89 |
+
<frontend_type>select</frontend_type>
|
90 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
91 |
+
<sort_order>20</sort_order>
|
92 |
+
<show_in_default>1</show_in_default>
|
93 |
+
<show_in_website>1</show_in_website>
|
94 |
+
<show_in_store>1</show_in_store>
|
95 |
+
</small_images>
|
96 |
+
<thumbnails translate="label comment tooltip">
|
97 |
+
<label>Thumbnails</label>
|
98 |
+
<comment>Thumbnail-sized images in product image galleries, sidebars, widgets, RSS feeds, etc.</comment>
|
99 |
+
<frontend_type>select</frontend_type>
|
100 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
101 |
+
<sort_order>30</sort_order>
|
102 |
+
<show_in_default>1</show_in_default>
|
103 |
+
<show_in_website>1</show_in_website>
|
104 |
+
<show_in_store>1</show_in_store>
|
105 |
+
</thumbnails>
|
106 |
+
<swatches>
|
107 |
+
<label>Swatches</label>
|
108 |
+
<comment>Small images used to select product attributes.</comment>
|
109 |
+
<frontend_type>select</frontend_type>
|
110 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
111 |
+
<sort_order>40</sort_order>
|
112 |
+
<show_in_default>1</show_in_default>
|
113 |
+
<show_in_website>1</show_in_website>
|
114 |
+
<show_in_store>1</show_in_store>
|
115 |
+
</swatches>
|
116 |
+
</fields>
|
117 |
+
</image_types>
|
118 |
+
<status translate="label">
|
119 |
+
<label>Latest Optimizations</label>
|
120 |
+
<sort_order>30</sort_order>
|
121 |
+
<show_in_default>1</show_in_default>
|
122 |
+
<show_in_website>1</show_in_website>
|
123 |
+
<show_in_store>1</show_in_store>
|
124 |
+
<class>active</class>
|
125 |
+
<fields>
|
126 |
+
<log_status>
|
127 |
+
<sort_order>40</sort_order>
|
128 |
+
<frontend_model>tiny_compressimages/adminhtml_system_config_form_field_logStatus</frontend_model>
|
129 |
+
<show_in_default>1</show_in_default>
|
130 |
+
<show_in_website>1</show_in_website>
|
131 |
+
<show_in_store>1</show_in_store>
|
132 |
+
</log_status>
|
133 |
+
</fields>
|
134 |
+
</status>
|
135 |
+
<advanced translate="label">
|
136 |
+
<label>Advanced</label>
|
137 |
+
<sort_order>40</sort_order>
|
138 |
+
<show_in_default>1</show_in_default>
|
139 |
+
<show_in_website>1</show_in_website>
|
140 |
+
<show_in_store>1</show_in_store>
|
141 |
+
<fields>
|
142 |
+
<enabled translate="label comment tooltip">
|
143 |
+
<label>Mode</label>
|
144 |
+
<frontend_type>select</frontend_type>
|
145 |
+
<sort_order>10</sort_order>
|
146 |
+
<source_model>tiny_compressimages/system_config_source_testlive</source_model>
|
147 |
+
<comment><![CDATA[
|
148 |
+
Live: Extension works normally (default)
|
149 |
+
<br>
|
150 |
+
<br>
|
151 |
+
Test: New product images will be optimized and saved so you can
|
152 |
+
test if everything works as expected. However, the optimized
|
153 |
+
images will not be shown in your store. After testing and switching
|
154 |
+
to live mode, your store will show the optimized images.
|
155 |
+
<br>
|
156 |
+
<br>
|
157 |
+
Disabled: The extension is switched off and no new product
|
158 |
+
images will be optimized.
|
159 |
+
<br>
|
160 |
+
<br>
|
161 |
+
]]>
|
162 |
+
</comment>
|
163 |
+
<tooltip>If test mode is activated, the extension will do real compressions. The result won't be saved.</tooltip>
|
164 |
+
<show_in_default>1</show_in_default>
|
165 |
+
<show_in_website>1</show_in_website>
|
166 |
+
<show_in_store>1</show_in_store>
|
167 |
+
</enabled>
|
168 |
+
<logging_mode translate="label comment">
|
169 |
+
<label>Messages that should be logged</label>
|
170 |
+
<sort_order>20</sort_order>
|
171 |
+
<source_model>tiny_compressimages/system_config_source_log</source_model>
|
172 |
+
<frontend_type>select</frontend_type>
|
173 |
+
<comment>
|
174 |
+
<model>tiny_compressimages/system_config_backend_comment_loggingMode</model>
|
175 |
+
</comment>
|
176 |
+
<show_in_default>1</show_in_default>
|
177 |
+
<show_in_website>1</show_in_website>
|
178 |
+
<show_in_store>1</show_in_store>
|
179 |
+
</logging_mode>
|
180 |
+
<log_file translate="label comment">
|
181 |
+
<label>Download the logfile</label>
|
182 |
+
<sort_order>30</sort_order>
|
183 |
+
<frontend_type>compressimages_log_button</frontend_type>
|
184 |
+
<show_in_default>1</show_in_default>
|
185 |
+
<show_in_website>1</show_in_website>
|
186 |
+
<show_in_store>1</show_in_store>
|
187 |
+
</log_file>
|
188 |
+
</fields>
|
189 |
+
</advanced>
|
190 |
+
</groups>
|
191 |
+
</tiny_compressimages>
|
192 |
+
</sections>
|
193 |
</config>
|
app/code/community/Tiny/CompressImages/sql/tiny_compressimages_setup/install-1.0.0.php
ADDED
@@ -0,0 +1,250 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var Tiny_CompressImages_Model_Resource_Setup $installer
|
4 |
+
*/
|
5 |
+
$installer = $this;
|
6 |
+
|
7 |
+
$installer->startSetup();
|
8 |
+
|
9 |
+
/** @var Varien_Db_Adapter_Interface $connection */
|
10 |
+
$connection = $installer->getConnection();
|
11 |
+
|
12 |
+
$tableName = $installer->getTable('tiny_compressimages/image');
|
13 |
+
if (!$connection->isTableExists($tableName)) {
|
14 |
+
$table = $connection
|
15 |
+
->newTable($tableName)
|
16 |
+
->addColumn(
|
17 |
+
'image_id',
|
18 |
+
Varien_Db_Ddl_Table::TYPE_INTEGER,
|
19 |
+
null,
|
20 |
+
array(
|
21 |
+
'identity' => true,
|
22 |
+
'unsigned' => true,
|
23 |
+
'nullable' => false,
|
24 |
+
'primary' => true,
|
25 |
+
),
|
26 |
+
'ID'
|
27 |
+
)
|
28 |
+
->addColumn(
|
29 |
+
'path',
|
30 |
+
Varien_Db_Ddl_Table::TYPE_VARCHAR,
|
31 |
+
255,
|
32 |
+
array(
|
33 |
+
'nullable' => false,
|
34 |
+
),
|
35 |
+
'The path of this image'
|
36 |
+
)
|
37 |
+
->addColumn(
|
38 |
+
'path_optimized',
|
39 |
+
Varien_Db_Ddl_Table::TYPE_VARCHAR,
|
40 |
+
255,
|
41 |
+
array(
|
42 |
+
'nullable' => false,
|
43 |
+
),
|
44 |
+
'The optimized path of this image'
|
45 |
+
)
|
46 |
+
->addColumn(
|
47 |
+
'image_type',
|
48 |
+
Varien_Db_Ddl_Table::TYPE_VARCHAR,
|
49 |
+
255,
|
50 |
+
array(
|
51 |
+
'nullable' => false,
|
52 |
+
),
|
53 |
+
'The type of this image'
|
54 |
+
)
|
55 |
+
->addColumn(
|
56 |
+
'hash_before',
|
57 |
+
Varien_Db_Ddl_Table::TYPE_VARCHAR,
|
58 |
+
255,
|
59 |
+
array(
|
60 |
+
'nullable' => false,
|
61 |
+
),
|
62 |
+
'The hash of the image before processing'
|
63 |
+
)
|
64 |
+
->addColumn(
|
65 |
+
'hash_after',
|
66 |
+
Varien_Db_Ddl_Table::TYPE_VARCHAR,
|
67 |
+
255,
|
68 |
+
array(
|
69 |
+
'nullable' => false,
|
70 |
+
),
|
71 |
+
'The hash of the image after processing'
|
72 |
+
)
|
73 |
+
->addColumn(
|
74 |
+
'bytes_before',
|
75 |
+
Varien_Db_Ddl_Table::TYPE_INTEGER,
|
76 |
+
null,
|
77 |
+
array(
|
78 |
+
'nullable' => false,
|
79 |
+
),
|
80 |
+
'The number of bytes before processing'
|
81 |
+
)
|
82 |
+
->addColumn(
|
83 |
+
'bytes_after',
|
84 |
+
Varien_Db_Ddl_Table::TYPE_INTEGER,
|
85 |
+
null,
|
86 |
+
array(
|
87 |
+
'nullable' => false,
|
88 |
+
),
|
89 |
+
'The number of bytes after processing'
|
90 |
+
)
|
91 |
+
->addColumn(
|
92 |
+
'used_as_source',
|
93 |
+
Varien_Db_Ddl_Table::TYPE_INTEGER,
|
94 |
+
null,
|
95 |
+
array(
|
96 |
+
'nullable' => false,
|
97 |
+
),
|
98 |
+
'How many times is this file used as source'
|
99 |
+
)
|
100 |
+
->addColumn(
|
101 |
+
'is_test',
|
102 |
+
Varien_Db_Ddl_Table::TYPE_INTEGER,
|
103 |
+
null,
|
104 |
+
array(
|
105 |
+
'nullable' => false,
|
106 |
+
),
|
107 |
+
'Is this image processed in test mode?'
|
108 |
+
)
|
109 |
+
->addColumn(
|
110 |
+
'parent_id',
|
111 |
+
Varien_Db_Ddl_Table::TYPE_INTEGER,
|
112 |
+
null,
|
113 |
+
array(),
|
114 |
+
'Has parent image and therefore its copied'
|
115 |
+
)
|
116 |
+
->addColumn(
|
117 |
+
'compressed_before',
|
118 |
+
Varien_Db_Ddl_Table::TYPE_INTEGER,
|
119 |
+
null,
|
120 |
+
array(),
|
121 |
+
'Is copressed before and therefore not compressed again'
|
122 |
+
)
|
123 |
+
->addColumn(
|
124 |
+
'processed_at',
|
125 |
+
Varien_Db_Ddl_Table::TYPE_DATETIME,
|
126 |
+
null,
|
127 |
+
array(
|
128 |
+
'nullable' => false,
|
129 |
+
),
|
130 |
+
'Processed At'
|
131 |
+
);
|
132 |
+
|
133 |
+
$connection->createTable($table);
|
134 |
+
}
|
135 |
+
|
136 |
+
$tableName = $installer->getTable('tiny_compressimages/totals');
|
137 |
+
if (!$connection->isTableExists($tableName)) {
|
138 |
+
$table = $connection
|
139 |
+
->newTable($tableName)
|
140 |
+
->addColumn(
|
141 |
+
'entity_id',
|
142 |
+
Varien_Db_Ddl_Table::TYPE_INTEGER,
|
143 |
+
null,
|
144 |
+
array(
|
145 |
+
'identity' => true,
|
146 |
+
'unsigned' => true,
|
147 |
+
'nullable' => false,
|
148 |
+
'primary' => true,
|
149 |
+
),
|
150 |
+
'ID'
|
151 |
+
)
|
152 |
+
->addColumn(
|
153 |
+
'total_bytes_before',
|
154 |
+
Varien_Db_Ddl_Table::TYPE_INTEGER,
|
155 |
+
null,
|
156 |
+
array(
|
157 |
+
'nullable' => false,
|
158 |
+
),
|
159 |
+
'The number of bytes before processing'
|
160 |
+
)
|
161 |
+
->addColumn(
|
162 |
+
'total_bytes_after',
|
163 |
+
Varien_Db_Ddl_Table::TYPE_INTEGER,
|
164 |
+
null,
|
165 |
+
array(
|
166 |
+
'nullable' => false,
|
167 |
+
),
|
168 |
+
'The number of bytes after processing'
|
169 |
+
)
|
170 |
+
->addColumn(
|
171 |
+
'total_compressions',
|
172 |
+
Varien_Db_Ddl_Table::TYPE_INTEGER,
|
173 |
+
null,
|
174 |
+
array(
|
175 |
+
'nullable' => false,
|
176 |
+
),
|
177 |
+
'The number of compressions'
|
178 |
+
)
|
179 |
+
->addColumn(
|
180 |
+
'date_from',
|
181 |
+
Varien_Db_Ddl_Table::TYPE_DATETIME,
|
182 |
+
null,
|
183 |
+
array(
|
184 |
+
'nullable' => false,
|
185 |
+
),
|
186 |
+
'First day of the month'
|
187 |
+
)
|
188 |
+
->addColumn(
|
189 |
+
'date_to',
|
190 |
+
Varien_Db_Ddl_Table::TYPE_DATETIME,
|
191 |
+
null,
|
192 |
+
array(
|
193 |
+
'nullable' => false,
|
194 |
+
),
|
195 |
+
'Last day of the month'
|
196 |
+
)
|
197 |
+
->addColumn(
|
198 |
+
'updated_at',
|
199 |
+
Varien_Db_Ddl_Table::TYPE_DATETIME,
|
200 |
+
null,
|
201 |
+
array(
|
202 |
+
'nullable' => false,
|
203 |
+
),
|
204 |
+
'Processed At'
|
205 |
+
);
|
206 |
+
|
207 |
+
$connection->createTable($table);
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Move the api_key setting to it's new location
|
212 |
+
*/
|
213 |
+
$installer->moveConfigSettingInDb('compress_images/settings/api_key', 'tiny_compressimages/settings/api_key');
|
214 |
+
|
215 |
+
/**
|
216 |
+
* In the old module the different image types are 4 different options, in the new module this is only 1 option
|
217 |
+
*/
|
218 |
+
$images = array(
|
219 |
+
'compress_image' => 'image',
|
220 |
+
'compress_small_image' => 'small_image',
|
221 |
+
'compress_thumbnail' => 'thumbnail',
|
222 |
+
'compress_other_images' => 'media',
|
223 |
+
);
|
224 |
+
|
225 |
+
$allowedTypes = array();
|
226 |
+
foreach ($images as $from => $to) {
|
227 |
+
$value = Mage::getConfig('compress_images/image_sizes/' . $from);
|
228 |
+
|
229 |
+
if ($value) {
|
230 |
+
$allowedTypes[] = $to;
|
231 |
+
}
|
232 |
+
}
|
233 |
+
|
234 |
+
if (count($allowedTypes)) {
|
235 |
+
try {
|
236 |
+
$connection->insert(
|
237 |
+
$installer->getTable('core/config_data'),
|
238 |
+
array(
|
239 |
+
'scope' => 'default',
|
240 |
+
'scope_id' => '0',
|
241 |
+
'value' => implode(',', $allowedTypes),
|
242 |
+
'path' => 'tiny_compressimages/settings/product_compression',
|
243 |
+
)
|
244 |
+
);
|
245 |
+
} catch (Exception $e) {
|
246 |
+
Mage::helper('tiny_compressimages')->log($e);
|
247 |
+
}
|
248 |
+
}
|
249 |
+
|
250 |
+
$installer->endSetup();
|
app/design/adminhtml/default/default/layout/Tiny/CompressImages.xml
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<layout>
|
3 |
+
<default>
|
4 |
+
<reference name="notifications">
|
5 |
+
<block type="tiny_compressimages/adminhtml_apiNotification" name="tiny_compressimages_api_key_notification" template="Tiny/CompressImages/Api/keyNotification.phtml"/>
|
6 |
+
</reference>
|
7 |
+
</default>
|
8 |
+
<adminhtml_system_config_edit>
|
9 |
+
<reference name="head">
|
10 |
+
<action method="addItem">
|
11 |
+
<type>skin_css</type>
|
12 |
+
<name>css/Tiny/CompressImages/config.css</name>
|
13 |
+
</action>
|
14 |
+
</reference>
|
15 |
+
</adminhtml_system_config_edit>
|
16 |
+
</layout>
|
app/design/adminhtml/default/default/template/Tiny/CompressImages/Api/keyNotification.phtml
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php $helper = Mage::helper('tiny_compressimages'); ?>
|
2 |
+
<?php if (!$this->isApiKeySet()) : ?>
|
3 |
+
<div class="notification-global">
|
4 |
+
<?php echo $helper->__('Add your TinyPNG API key to start compressing images.'); ?>
|
5 |
+
<a href="<?php echo $this->getBackendUrl(); ?>">
|
6 |
+
<?php echo $helper->__('Go to Image Optimization Settings and add your key.'); ?>
|
7 |
+
</a>
|
8 |
+
</div>
|
9 |
+
<?php endif; ?>
|
app/design/adminhtml/default/default/template/Tiny/CompressImages/system/config/form/field/log_file.phtml
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/** @var Tiny_CompressImages_Block_Adminhtml_System_Config_Form_Field_LogFile $this */
|
3 |
+
?>
|
4 |
+
<tr id="row_tiny_compressimages_advanced_log_file">
|
5 |
+
<td class="label">
|
6 |
+
<label for="tiny_compressimages_advanced_log_file"> Log file</label>
|
7 |
+
</td>
|
8 |
+
<td class="value">
|
9 |
+
<?php if ($this->logFileExists()): ?>
|
10 |
+
<button onclick="setLocation('<?php echo $this->getDownloadUrl(); ?>')" type="button" class="scalable">
|
11 |
+
<span><span><span><?php echo $this->__('Download log file'); ?></span></span></span>
|
12 |
+
</button>
|
13 |
+
<?php else: ?>
|
14 |
+
<button type="button" class="scalable disabled">
|
15 |
+
<span><span><span><?php echo $this->__('Download log file'); ?></span></span></span>
|
16 |
+
</button>
|
17 |
+
<?php endif; ?>
|
18 |
+
</td>
|
19 |
+
</tr>
|
20 |
+
|
21 |
+
|
app/design/adminhtml/default/default/template/Tiny/CompressImages/system/config/form/field/log_status.phtml
ADDED
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var Tiny_CompressImages_Block_Adminhtml_System_Config_Form_Field_LogStatus $this
|
4 |
+
*/
|
5 |
+
|
6 |
+
/** @var Tiny_CompressImages_Helper_Tinify $_tinify */
|
7 |
+
$_tinify = Mage::helper('tiny_compressimages/tinify');
|
8 |
+
|
9 |
+
/** @var Tiny_CompressImages_Helper_Data $_helper */
|
10 |
+
$_helper = Mage::helper('tiny_compressimages');
|
11 |
+
$_data = Mage::getModel('tiny_compressimages/totals')->getTotalCompressionInformation();
|
12 |
+
|
13 |
+
/** @var Tiny_CompressImages_Model_Image $image */
|
14 |
+
$_images = $_tinify->getCompressionStatus();
|
15 |
+
|
16 |
+
$_imagesLimit = 10;
|
17 |
+
?>
|
18 |
+
|
19 |
+
<tr>
|
20 |
+
<td colspan="4">
|
21 |
+
<table cellspacing="5" class="form-list">
|
22 |
+
<tr>
|
23 |
+
<td>
|
24 |
+
<h5><?php echo $this->__('Images are optimized each time Magento generates new product images in the image cache folder')?></h5>
|
25 |
+
<?php if ($_data['totalCompressions'] < 1) :?>
|
26 |
+
<p><?php
|
27 |
+
echo $this->__(
|
28 |
+
'If you have never used the extension before you should flush the product images cache. Magento will
|
29 |
+
generate new product images that will be automatically optimized. You will only need to flush the cache
|
30 |
+
once, any new products will be automatically optimized in future.'
|
31 |
+
);
|
32 |
+
?></p>
|
33 |
+
|
34 |
+
<button onclick="setLocation('<?php echo $this->getCleanImagesUrl()?>')" type="button" class="scalable">
|
35 |
+
<span><span><span><?php echo Mage::helper('adminhtml')->__('Flush Catalog Images Cache') ?></span></span></span>
|
36 |
+
</button>
|
37 |
+
<?php endif; ?>
|
38 |
+
</td>
|
39 |
+
</tr>
|
40 |
+
</table>
|
41 |
+
</td>
|
42 |
+
</tr>
|
43 |
+
|
44 |
+
|
45 |
+
<?php if ($_data['totalCompressions'] > 0) :?>
|
46 |
+
<tr>
|
47 |
+
<td class="log-details-td">
|
48 |
+
<?php echo Mage::helper('tiny_compressimages')->__(
|
49 |
+
'Total of %s optimized product images. Original size : %s. New size : %s. Average savings %s%%.',
|
50 |
+
$_data['totalCompressions'],
|
51 |
+
$_data['bytesBefore'],
|
52 |
+
$_data['bytesAfter'],
|
53 |
+
$_data['percentageSaved']
|
54 |
+
); ?>
|
55 |
+
</td>
|
56 |
+
</tr>
|
57 |
+
<?php endif; ?>
|
58 |
+
|
59 |
+
<?php $i = 0; ?>
|
60 |
+
<?php if ($_images->count()): ?>
|
61 |
+
<tr>
|
62 |
+
<td colspan="4">
|
63 |
+
<table id="tiny_compressimages_compression" cellspacing="5">
|
64 |
+
<?php /** Tiny_CompressImages_Model_Image $image */?>
|
65 |
+
<?php foreach ($_images as $image): ?>
|
66 |
+
<?php $i++; ?>
|
67 |
+
<?php if ($i > $_imagesLimit): ?>
|
68 |
+
<tr class="tiny_compressimages_log log_hidden">
|
69 |
+
<?php else : ?>
|
70 |
+
<tr class="tiny_compressimages_log">
|
71 |
+
<?php endif;?>
|
72 |
+
<td class="image_path">
|
73 |
+
<a href="<?php echo $image->getImageUrl(); ?>" target="_BLANK">
|
74 |
+
<img src="<?php echo $image->getImageUrl(); ?>">
|
75 |
+
</a>
|
76 |
+
</td>
|
77 |
+
<td class="info_box"><?php echo $image->getImageType(); ?></td>
|
78 |
+
<td class="info_box tiny_compressimages_width">
|
79 |
+
<?php echo $image->getPercentageSaved(); ?> saved (<?php echo $_helper->fileSize($image->getBytesBefore()). ' / '. $_helper->fileSize($image->getBytesAfter()); ?>)
|
80 |
+
</td>
|
81 |
+
<td class="info_box tiny_compressimages_width">
|
82 |
+
<?php if ($image->getCompressedBefore()) : ?>
|
83 |
+
<?php echo $this->__('Optimized previously'); ?>
|
84 |
+
<?php elseif ($image->getParentId()) :?>
|
85 |
+
<?php echo $this->__('Duplicate image'); ?>
|
86 |
+
<?php else: ?>
|
87 |
+
<?php echo $this->__('Optimized'); ?>
|
88 |
+
<?php endif; ?>
|
89 |
+
</td>
|
90 |
+
<td class="info_box tiny_compressimages_width"><?php echo $image->getTimeAgo(); ?></td>
|
91 |
+
</tr>
|
92 |
+
<?php endforeach; ?>
|
93 |
+
|
94 |
+
<?php if ($_images->getSize() > $_images->count()): ?>
|
95 |
+
<tr class="tiny_compressimages_log log_hidden">
|
96 |
+
<td colspan="5"><?php echo $_helper->__('...and %d more images', $_images->getSize() - $_images->count()); ?></td>
|
97 |
+
</tr>
|
98 |
+
<?php endif; ?>
|
99 |
+
|
100 |
+
<?php if ($i > $_imagesLimit): ?>
|
101 |
+
<tr>
|
102 |
+
<td colspan="5"><a id="show_all" href="#"><?php echo $this->__('Show more'); ?></a></td>
|
103 |
+
</tr>
|
104 |
+
<tr>
|
105 |
+
<td colspan="5"><a id="show_less" href="#"><?php echo $this->__('Show less'); ?></a></td>
|
106 |
+
</tr>
|
107 |
+
<?php endif; ?>
|
108 |
+
</table>
|
109 |
+
</td>
|
110 |
+
</tr>
|
111 |
+
<?php else: ?>
|
112 |
+
<tr>
|
113 |
+
<td class="tiny_compressimages-no-images">
|
114 |
+
<?php echo $_helper->__('There are no saved compressions available yet.'); ?><br>
|
115 |
+
</td>
|
116 |
+
</tr>
|
117 |
+
<?php endif; ?>
|
118 |
+
|
119 |
+
<tr>
|
120 |
+
<td class="log-details-td">
|
121 |
+
<?php $url = "<a href=".$this->getCleanImagesUrl()."/>".$this->__('flush the Magento image cache')."</a>"; ?>
|
122 |
+
<?php echo $_helper->__('If an image does not appear you may need to %s and visit the product page
|
123 |
+
again so images will be regenerated and optimized.', $url
|
124 |
+
); ?>
|
125 |
+
</td>
|
126 |
+
</tr>
|
127 |
+
|
128 |
+
|
129 |
+
<script type="application/javascript">
|
130 |
+
document.observe('dom:loaded', function() {
|
131 |
+
|
132 |
+
var show_less = $('show_less');
|
133 |
+
var show_all = $('show_all');
|
134 |
+
|
135 |
+
$$('.log_hidden').each(function(element) {
|
136 |
+
element.hide();
|
137 |
+
});
|
138 |
+
|
139 |
+
if (show_all !== null) {
|
140 |
+
show_all.observe('click', function (e) {
|
141 |
+
Event.stop(e);
|
142 |
+
|
143 |
+
$$('.log_hidden').each(function (element) {
|
144 |
+
element.show();
|
145 |
+
});
|
146 |
+
show_all.hide();
|
147 |
+
show_less.show();
|
148 |
+
});
|
149 |
+
}
|
150 |
+
|
151 |
+
if (show_less !== null) {
|
152 |
+
show_less.hide();
|
153 |
+
show_less.observe('click', function (e) {
|
154 |
+
Event.stop(e);
|
155 |
+
|
156 |
+
$$('.log_hidden').each(function (element) {
|
157 |
+
element.hide();
|
158 |
+
});
|
159 |
+
show_less.hide();
|
160 |
+
show_all.show();
|
161 |
+
});
|
162 |
+
}
|
163 |
+
});
|
164 |
+
</script>
|
app/design/adminhtml/default/default/template/Tiny/CompressImages/system/config/form/field/support_tab.phtml
ADDED
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/** @var Tiny_CompressImages_Block_Adminhtml_System_Config_Form_Field_SupportTab $this */
|
3 |
+
?>
|
4 |
+
|
5 |
+
<?php $_tigHomepage = 'https://tig.nl/image-optimization-magento-extension-community-edition'; ?>
|
6 |
+
<?php $_kbUrl = 'http://servicedesk.tig.nl/hc/nl/categories/202720888-TinyPNG'; ?>
|
7 |
+
<?php $_kbTicketUrl = 'mailto:servicedesk@tig.nl'; ?>
|
8 |
+
<?php $_changelogUrl = 'https://tig.nl'; ?>
|
9 |
+
<?php $_installationManualUrl = 'http://servicedesk.tig.nl/hc/nl/articles/219422177-TinyPNG-handleiding'; ?>
|
10 |
+
<?php $_userGuideUrl = 'https://tig.nl'; ?>
|
11 |
+
<?php $_version = $this->getModuleVersion(); ?>
|
12 |
+
<?php $_stability = $this->getModuleStability(); ?>
|
13 |
+
|
14 |
+
<tr id="tiny_compressimages_support">
|
15 |
+
<td>
|
16 |
+
<h2 class="content-heading">
|
17 |
+
<?php echo $this->__('Image Optimization %s', $_version);?>
|
18 |
+
<?php if (!empty($_stability) && $_stability != 'stable'): ?>
|
19 |
+
- <?php echo $_stability; ?>
|
20 |
+
<?php endif; ?>
|
21 |
+
</h2>
|
22 |
+
<table id="supportWrap" cellpadding="0" cellspacing="0">
|
23 |
+
<tr>
|
24 |
+
<td colspan="2">
|
25 |
+
|
26 |
+
<div class="">
|
27 |
+
<div class="col-set">
|
28 |
+
<div class="col-1">
|
29 |
+
<p>
|
30 |
+
<?php echo $this->__('Make your store faster by optimizing your JPEG and PNG product images. This extension automatically optimizes the images by integrating with the popular image compression services TinyJPG and TinyPNG.'); ?>
|
31 |
+
</p>
|
32 |
+
|
33 |
+
<!-- Magento CE -->
|
34 |
+
<?php if (Mage::getEdition() === 'Community'): ?>
|
35 |
+
<p>
|
36 |
+
<?php echo $this->__('In case you need help or assistance with the extension or your account please contact'); ?> <a href="mailto:support@tinypng.com">support@tinypng.com</a>.
|
37 |
+
</p>
|
38 |
+
<?php else: ?>
|
39 |
+
<!-- Magento EE -->
|
40 |
+
<p>
|
41 |
+
<?php echo $this->__('For general questions and help with your account please contact') ?> <a href="mailto:support@tinypng.com">support@tinypng.com</a>.
|
42 |
+
</p>
|
43 |
+
<?php endif; ?>
|
44 |
+
|
45 |
+
<p>
|
46 |
+
<?php echo $this->__('This extension is developed by <a href="%s" target="_BLANK">TIG</a>. Please <a href="%s" target="_BLANK">contact them</a> for technical support.', $_tigHomepage, $_kbTicketUrl); ?>
|
47 |
+
</p>
|
48 |
+
|
49 |
+
</div>
|
50 |
+
<div class="col-2">
|
51 |
+
<img class="tiny-logo-bear" alt="CompressImages" src="<?php echo $this->getSkinUrl('images/Tiny/CompressImages/george-magento@2x_opt.png'); ?>" />
|
52 |
+
</div>
|
53 |
+
</div>
|
54 |
+
</div>
|
55 |
+
</td>
|
56 |
+
</tr>
|
57 |
+
</table>
|
58 |
+
</td>
|
59 |
+
</tr>
|
60 |
+
|
61 |
+
<script>
|
62 |
+
//<![CDATA[
|
63 |
+
document.observe('dom:loaded', function() {
|
64 |
+
var elem;
|
65 |
+
|
66 |
+
// Set tabs open.
|
67 |
+
[
|
68 |
+
'tiny_compressimages_support-head',
|
69 |
+
'tiny_compressimages_image_types-head',
|
70 |
+
'tiny_compressimages_status-head',
|
71 |
+
'tiny_compressimages_settings-head'
|
72 |
+
].each( function (name) {
|
73 |
+
elem = $(name);
|
74 |
+
|
75 |
+
if (!elem.hasClassName('open')) {
|
76 |
+
elem.click();
|
77 |
+
}
|
78 |
+
});
|
79 |
+
|
80 |
+
// Remove default onclick value
|
81 |
+
$('tiny_compressimages_support-head').setAttribute('onclick', '');
|
82 |
+
|
83 |
+
// Get and remove the first head on the page (ours)
|
84 |
+
$$('.entry-edit-head')[0].remove();
|
85 |
+
});
|
86 |
+
//]]>
|
87 |
+
</script>
|
app/etc/modules/Tiny_CompressImages.xml
CHANGED
@@ -1,9 +1,9 @@
|
|
1 |
-
<?xml version="1.0"
|
2 |
<config>
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
</config>
|
1 |
+
<?xml version="1.0"?>
|
2 |
<config>
|
3 |
+
<modules>
|
4 |
+
<Tiny_CompressImages>
|
5 |
+
<active>true</active>
|
6 |
+
<codePool>community</codePool>
|
7 |
+
</Tiny_CompressImages>
|
8 |
+
</modules>
|
9 |
</config>
|
app/locale/en_US/Tiny_CompressImages.csv
ADDED
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"Tiny_CompressImages::TinyPNG","TinyPNG"
|
2 |
+
"Tiny_CompressImages::Version & Support","Version & Support"
|
3 |
+
"Tiny_CompressImages::Enable TinyPNG","Enable TinyPNG"
|
4 |
+
"Tiny_CompressImages::Logging disabled","Logging disabled"
|
5 |
+
"Tiny_CompressImages::Exceptions only","Exceptions only"
|
6 |
+
"Tiny_CompressImages::Errors and Exceptions","Errors and Exceptions"
|
7 |
+
"Tiny_CompressImages::All logging information","All logging information"
|
8 |
+
"Tiny_CompressImages::A long time ago","A long time ago"
|
9 |
+
"Tiny_CompressImages::%s month ago","%s month ago"
|
10 |
+
"Tiny_CompressImages::%s months ago","%s months ago"
|
11 |
+
"Tiny_CompressImages::%s year ago","%s year ago"
|
12 |
+
"Tiny_CompressImages::%s years ago","%s years ago"
|
13 |
+
"Tiny_CompressImages::%s day ago","%s days ago"
|
14 |
+
"Tiny_CompressImages::%s week ago","%s weeks ago"
|
15 |
+
"Tiny_CompressImages::%s hour ago","%s hours ago"
|
16 |
+
"Tiny_CompressImages::%s minute ago","%s minutes ago"
|
17 |
+
"Tiny_CompressImages::%s second ago","%s seconds ago"
|
18 |
+
"Tiny_CompressImages::...and %d more images","...and %d more images"
|
19 |
+
"Tiny_CompressImages::There are no saved compressions available yet.","There are no saved compressions available yet."
|
20 |
+
"Tiny_CompressImages::Warning: Flushing the image cache will cause the TinyPNG module to recompress all images. When having a big catalog this can lead to high costs.\n\nAre you sure you want to continue?","Warning: Flushing the image cache will cause the TinyPNG module to recompress all images. When having a big catalog this can lead to high costs.\n\nAre you sure you want to continue?"
|
21 |
+
"Tiny_CompressImages::TIG Tinypng %s","TIG Tinypng %s"
|
22 |
+
"Tiny_CompressImages::Information about the TinyPNG extension","Information about the TinyPNG extension"
|
23 |
+
"Tiny_CompressImages::Magento & 3rd party version compatibility","Magento & 3rd party version compatibility"
|
24 |
+
"Tiny_CompressImages::Magento Community Edition version","Magento Community Edition version"
|
25 |
+
"Tiny_CompressImages::Magento Enterprise Edition version","Magento Enterprise Edition version"
|
26 |
+
"Tiny_CompressImages::Support","Support"
|
27 |
+
"Tiny_CompressImages::The extension is developed by TIG.","The extension is developed by TIG."
|
28 |
+
"Tiny_CompressImages::Website:","Website:"
|
29 |
+
"Tiny_CompressImages::Support website:","Support website:"
|
30 |
+
"Tiny_CompressImages::Extension support and configuration questions","Extension support and configuration questions"
|
31 |
+
"Tiny_CompressImages::For questions about installing and configuring the extension please consult the relevant documentation:","For questions about installing and configuring the extension please consult the relevant documentation:"
|
32 |
+
"Tiny_CompressImages::Frequently asked questions","Frequently asked questions"
|
33 |
+
"Tiny_CompressImages::FAQ","FAQ"
|
34 |
+
"Tiny_CompressImages::Installation Manual","Installation Manual"
|
35 |
+
"Tiny_CompressImages::Do you have any additional questions?","Do you have any additional questions?"
|
36 |
+
"Tiny_CompressImages::Please contact the TIG servicedesk for additional questions.","Please contact the TIG servicedesk for additional questions."
|
37 |
+
"Tiny_CompressImages::Ask your question","Ask your question"
|
38 |
+
"Tiny_CompressImages::TIG.nl","TIG.nl"
|
39 |
+
"Tiny_CompressImages::TIG Knowledgebase","TIG Knowledgebase"
|
40 |
+
"Tiny_CompressImages::Operational","Operational"
|
41 |
+
"Tiny_CompressImages::Non-operational","Non-operational"
|
42 |
+
"Tiny_CompressImages::Click the button to check the API status.","Click the button to check the API status."
|
43 |
+
"Tiny_CompressImages::Check status","Check status"
|
44 |
+
"Tiny_CompressImages::TinyPNG API Status","TinyPNG API Status"
|
45 |
+
"Tiny_CompressImages::We saved %s%% this month! The greatest image compression was %s%%.","We saved %s%% this month! The greatest image compression was %s%%."
|
46 |
+
"Tiny_CompressImages::There are %s compressions done this month.","There are %s compressions done this month."
|
47 |
+
"Tiny_CompressImages::TinyPNG Settings","TinyPNG Settings"
|
48 |
+
"Tiny_CompressImages::On","On"
|
49 |
+
"Tiny_CompressImages::Off","Off"
|
50 |
+
"Tiny_CompressImages::Test","Test"
|
51 |
+
"Tiny_CompressImages::Live","Live"
|
52 |
+
"Tiny_CompressImages::If this is set to Off, TinyPNG will no longer compress images","If this is set to Off, TinyPNG will no longer compress images"
|
53 |
+
"Tiny_CompressImages::If test mode is activated, the extension will do real compressions. The result won't be saved.","If test mode is activated, the extension will do real compressions. The result won't be saved."
|
54 |
+
"Tiny_CompressImages::API Key","API Key"
|
55 |
+
"Tiny_CompressImages::You can fetch the API Key from the <a href=""https://tinypng.com/developers/subscription"" target=""_BLANK"">TinyPNG website</a>.","You can fetch the API Key from the <a href=""https://tinypng.com/developers/subscription"" target=""_BLANK"">TinyPNG website</a>."
|
56 |
+
"Tiny_CompressImages::Product images to be compressed","Product images to be compressed"
|
57 |
+
"Tiny_CompressImages::Messages that should be logged","Messages that should be logged"
|
58 |
+
"Tiny_CompressImages::TinyPNG Status","TinyPNG Status"
|
59 |
+
"Tiny_CompressImages::Status","Status"
|
60 |
+
"Tiny_CompressImages::Saved","Saved"
|
61 |
+
"Tiny_CompressImages::The Api Key is invalid","The Api Key is invalid"
|
62 |
+
"Tiny_CompressImages::Category images","Category images"
|
63 |
+
"Tiny_CompressImages::Block images","Block images"
|
64 |
+
"Tiny_CompressImages::CMS page images","CMS page images"
|
65 |
+
"Tiny_CompressImages::Thumbnail","Thumbnail"
|
66 |
+
"Tiny_CompressImages::Small Image","Small Image"
|
67 |
+
"Tiny_CompressImages::Base Image","Base Image"
|
68 |
+
"Tiny_CompressImages::Media Image","Media Image"
|
69 |
+
"Tiny_CompressImages::File","File"
|
70 |
+
"Tiny_CompressImages::File size","File size"
|
71 |
+
"Tiny_CompressImages::Bytes Saved","Bytes Saved"
|
72 |
+
"Tiny_CompressImages::Percentage saved","Percentage saved"
|
73 |
+
"Tiny_CompressImages::Time","Time"
|
74 |
+
"Tiny_CompressImages::Show more","Show more"
|
75 |
+
"Tiny_CompressImages::Show less","Show less"
|
76 |
+
"Tiny_CompressImages::Saved %s%% over a total of %s compressions", "Saved %s%% over a total of %s compressions"
|
77 |
+
"Tiny_CompressImages::When set to all, the log file can become huge. Recommended setting for production servers is Errors and Exceptions.","When set to all, the log file can become huge. Recommended setting for production servers is Errors and Exceptions."
|
78 |
+
"Tiny_CompressImages::Account type","Account type"
|
79 |
+
"Tiny_CompressImages::TinyPNG Log","TinyPNG Log"
|
80 |
+
"Tiny_CompressImages::Note: When flushing the image cache, the TinyPNG extension will re-optimize all product images that are shown on the store view(s).","Note: When flushing the image cache, the TinyPNG extension will re-optimize all product images that are shown on the store view(s)."
|
81 |
+
"Tiny_CompressImages::File","File"
|
82 |
+
"Tiny_CompressImages::Original","Original"
|
83 |
+
"Tiny_CompressImages::Now","Now"
|
84 |
+
"Tiny_CompressImages::Saved","Saved"
|
85 |
+
"Tiny_CompressImages::Time","Time"
|
86 |
+
"Tiny_CompressImages::Download log file","Download log file"
|
87 |
+
"Tiny_CompressImages::Download TinyPNG log file","Download TinyPNG log file"
|
88 |
+
"Tiny_CompressImages::Information about the TinyPNG extension","Information about the TinyPNG extension"
|
89 |
+
"Tiny_CompressImages::What does TinyPNG do?","What does TinyPNG do?"
|
90 |
+
"Tiny_CompressImages::TinyPNG uses smart lossy compression techniques to reduce the file size of your PNG files. By selectively decreasing the number of colors in the image, fewer bytes are required to store the data. The effect is nearly invisible but it makes a very large difference in file size!","TinyPNG uses smart lossy compression techniques to reduce the file size of your PNG files. By selectively decreasing the number of colors in the image, fewer bytes are required to store the data. The effect is nearly invisible but it makes a very large difference in file size!"
|
91 |
+
"Tiny_CompressImages::Why should I use TinyPNG?","Why should I use TinyPNG?"
|
92 |
+
"Tiny_CompressImages::PNG is useful because it's the only widely supported format that can store partially transparent images. The format uses compression, but the files can still be large. Use TinyPNG to shrink images for your apps and sites. It will use less bandwidth and load faster.","PNG is useful because it's the only widely supported format that can store partially transparent images. The format uses compression, but the files can still be large. Use TinyPNG to shrink images for your apps and sites. It will use less bandwidth and load faster."
|
93 |
+
"Tiny_CompressImages::How does the extension work?","How does the extension work?"
|
94 |
+
"Tiny_CompressImages::When a users visits the store view, the TinyPNG will automatically compress the images on the fly. This only applies for images that are not already cached. So in order to optimize all images, <a target=\"_blank\" href=\"%s\">flush your entire images cache</a> so your whole images database will be optimized. When test mode is enabled, the images will also be compressed on the fly, however, compressed images will not be saved to disk. The result can be found in the status log, which can be downloaded in the <a href=\"#tiny_compressimages_logging-head\">Log section</a> tab of this extension.","When a users visits the store view, the TinyPNG will automatically compress the images on the fly. This only applies for images that are not already cached. So in order to optimize all images, <a target=\"_blank\" href=\"%s\">flush your entire images cache</a> so your whole images database will be optimized. When test mode is enabled, the images will also be compressed on the fly, however, compressed images will not be saved to disk. The result can be found in the status log, which can be downloaded in the <a href=\"#tiny_compressimages_logging-head\">Log section</a> tab of this extension."
|
95 |
+
"Tiny_CompressImages::General settings and accountdata","General settings and accountdata"
|
96 |
+
"Tiny_CompressImages::Please contact TinyPNG for assistance in setting up your account data:","Please contact TinyPNG for assistance in setting up your account data:"
|
97 |
+
"Tiny_CompressImages::Optimized,Optimized"
|
98 |
+
"Tiny_CompressImages::Please enable the extension to check the compression count.,Please enable the extension to check the compression count."
|
99 |
+
"Tiny_CompressImages::Please enter your api key to check the compression count.,Please enter your api key to check the compression count."
|
lib/TinyCompress/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
vendor
|
lib/TinyCompress/.travis.yml
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
language: php
|
2 |
+
php:
|
3 |
+
- 5.3
|
4 |
+
- 5.4
|
5 |
+
- 5.5
|
6 |
+
- 5.6
|
7 |
+
- 7.0
|
8 |
+
- hhvm
|
9 |
+
- nightly
|
10 |
+
env:
|
11 |
+
global:
|
12 |
+
secure: BFdcLqU/07l3/NGaSZA5+VSB5FSVSwTL9wAyrJSD1N7jN2HzFTE4xxxmcVrAqq6t+jhZqajXcSf8/DTUKyLcmWXGw3JkseHx3ofHw5p2E4Mp+dUvNMh+3KgAABCPm5zEBUgnhNGwFqL+WA/cgXIJY1/sv87u/mg63ojvf3orKJ3KMxFFsVbGo553XYVsiSUXfzvV3foqPdcV9D0SZ0v7IiLcsuwtDRtfJ/udgSZ2C2LFiOek1dLwbjM3inMBPkfLcpuvC2l8Z1CyW5ptxYRrHHJqCMbdRmmwGH04hxRju54EJKX5PGTyDhfG9Kyiu8/hQCtDL4jNQlVNAKbvHrRTnLogoMKhHMRaAIDMNI+lcQB9OHHuureYAqL7gJvRmE2sfN/OAbzizYJ2z+yXvjaKJsd2htrHff8hgvl0M3guhP+mA5C9ubibzGiCD66kdeqS5tJi3EH7wk9GO75lFm3tlZEWZ4FJCwgyFQRZGMGSRJC5cWvW4QlGLHeVnWwnf9CM9/B2oD21LraccgCZhpIbib5/XJ2vTQO0V2ke3kXT1D9E3P8E2eClxnge1aShUSy+d5kMTNeLxkfalgGEviWqA236XLzS8+MjWzNWy3+roBb63Vh0OPp4GyTO810U16Y5lwCMegVrxusnz9bCo1HbK1w2k8D7Ueb/O7LEFYaZSD4=
|
13 |
+
matrix:
|
14 |
+
allow_failures:
|
15 |
+
- php: nightly
|
16 |
+
include:
|
17 |
+
- php: 5.6
|
18 |
+
env: INTEGRATION_TESTS=true
|
19 |
+
script: "if [ \"$TRAVIS_PULL_REQUEST\" == \"false\" ]; then vendor/bin/phpunit --no-configuration test/integration.php; fi"
|
20 |
+
before_script: composer install
|
21 |
+
script: vendor/bin/phpunit
|
22 |
+
notifications:
|
23 |
+
email: false
|
24 |
+
slack:
|
25 |
+
secure: W1cEp+ctAD+in3hA/gansbUYrFZsR3EMd7s/XiK2mfAxRRXPCPgCvv0PWpYelJ5F2AnHXkmBP3USKFDhKN+JLmOOxrZpjzh4ve9QSNs4IPgcrU4meQYSgJ3uovS7h4fqAmqhQKL+FpAnrXAmXWGXVPCPtneySsMTyU6kNdmVfulxXRMJ+kLHtFQlT+U7cPYG0f8FkKR2u5CbRsdjUvoZHwbK7jmWpUcCi2O0A1vvMMEMEOG+iuayWW/RbfSfKIgM/SZG0pGYpoAB7I8XfYns7IyLhkJAw18jIWnowF4DuBusNRdr3zIfwC7bSlLKMFYJYpEsiLFCaeGZgp1NbYJ77DvqpwNp9xmoPz9rFGNe7Re+i13pjNWhEnwc5N3St7x8DYNhUC3L0upQ2FWZSomMM7ghlc6GIVtlXYrRJ5AnxIjSWyLRcTRU5Pf/PPRckOTiuLnVgUZNMVIlAHlRV7c/pUVDjbPvjcOajdXnpcd3+5cuKyzCYpXugIfJ9Hzsozq0yCHDKjo8ssAU+5H3mEfB7M25Rtd2awObb3zqOyUPm+J3M/dzql95cF+zj2SWQsBF/ViwkHo+9SoAr/FYqCZveiS0w9vzoKzbGXVDYCfFD+GlEMJ2b8zw4d2sqmIbw24jGq1ZPgczrpD5fcbI2TaheKBkgWvsBJFFO5KbGWqzHIM=
|
lib/TinyCompress/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
The MIT License
|
2 |
+
|
3 |
+
Copyright (c) 2013-2016 Voormedia
|
4 |
+
|
5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6 |
+
of this software and associated documentation files (the "Software"), to deal
|
7 |
+
in the Software without restriction, including without limitation the rights
|
8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9 |
+
copies of the Software, and to permit persons to whom the Software is
|
10 |
+
furnished to do so, subject to the following conditions:
|
11 |
+
|
12 |
+
The above copyright notice and this permission notice shall be included in
|
13 |
+
all copies or substantial portions of the Software.
|
14 |
+
|
15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21 |
+
THE SOFTWARE.
|
lib/TinyCompress/README.md
CHANGED
@@ -1,24 +1,58 @@
|
|
1 |
-
|
2 |
|
3 |
-
|
4 |
-
in the cache folder.
|
5 |
|
6 |
-
|
7 |
|
8 |
-
|
9 |
-
- You will save bandwidth and hosting costs
|
10 |
-
- Compression happens on-the-fly in the background
|
11 |
-
- The extension is compatible with serving images through a CDN
|
12 |
-
- No cron jobs or scheduled tasks needed
|
13 |
|
14 |
-
|
15 |
|
16 |
-
|
17 |
-
Magento version 1.9.1.0 with the new Dispatch Event and changed the default JPEG
|
18 |
-
quality to 95%.
|
19 |
|
20 |
-
|
21 |
|
22 |
-
|
23 |
-
|
|
|
|
|
|
|
|
|
|
|
24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[<img src="https://travis-ci.org/tinify/tinify-php.svg?branch=master" alt="Build Status">](https://travis-ci.org/tinify/tinify-php)
|
2 |
|
3 |
+
# Tinify API client for PHP
|
|
|
4 |
|
5 |
+
PHP client for the Tinify API, used for [TinyPNG](https://tinypng.com) and [TinyJPG](https://tinyjpg.com). Tinify compresses your images intelligently. Read more at [http://tinify.com](http://tinify.com).
|
6 |
|
7 |
+
## Documentation
|
|
|
|
|
|
|
|
|
8 |
|
9 |
+
[Go to the documentation for the PHP client](https://tinypng.com/developers/reference/php).
|
10 |
|
11 |
+
## Installation
|
|
|
|
|
12 |
|
13 |
+
Install the API client with Composer. Add this to your `composer.json`:
|
14 |
|
15 |
+
```json
|
16 |
+
{
|
17 |
+
"require": {
|
18 |
+
"tinify/tinify": "*"
|
19 |
+
}
|
20 |
+
}
|
21 |
+
```
|
22 |
|
23 |
+
Then install with:
|
24 |
+
|
25 |
+
```
|
26 |
+
composer install
|
27 |
+
```
|
28 |
+
|
29 |
+
Use autoloading to make the client available in PHP:
|
30 |
+
|
31 |
+
```php
|
32 |
+
require_once("vendor/autoload.php");
|
33 |
+
```
|
34 |
+
|
35 |
+
## Usage
|
36 |
+
|
37 |
+
```php
|
38 |
+
Tinify\setKey("YOUR_API_KEY");
|
39 |
+
Tinify\fromFile("unoptimized.png")->toFile("optimized.png");
|
40 |
+
```
|
41 |
+
|
42 |
+
## Running tests
|
43 |
+
|
44 |
+
```
|
45 |
+
composer install
|
46 |
+
vendor/bin/phpunit
|
47 |
+
```
|
48 |
+
|
49 |
+
### Integration tests
|
50 |
+
|
51 |
+
```
|
52 |
+
composer install
|
53 |
+
TINIFY_KEY=$YOUR_API_KEY vendor/bin/phpunit --no-configuration test/integration.php
|
54 |
+
```
|
55 |
+
|
56 |
+
## License
|
57 |
+
|
58 |
+
This software is licensed under the MIT License. [View the license](LICENSE).
|
lib/TinyCompress/class-tiny-compress-curl.php
DELETED
@@ -1,77 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
* Tiny Compress Images - WordPress plugin.
|
4 |
-
* Copyright (C) 2015 Voormedia B.V.
|
5 |
-
*
|
6 |
-
* This program is free software; you can redistribute it and/or modify it
|
7 |
-
* under the terms of the GNU General Public License as published by the Free
|
8 |
-
* Software Foundation; either version 2 of the License, or (at your option)
|
9 |
-
* any later version.
|
10 |
-
*
|
11 |
-
* This program is distributed in the hope that it will be useful, but WITHOUT
|
12 |
-
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
13 |
-
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
14 |
-
* more details.
|
15 |
-
*
|
16 |
-
* You should have received a copy of the GNU General Public License along
|
17 |
-
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
18 |
-
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
19 |
-
*/
|
20 |
-
|
21 |
-
class Tiny_Compress_Curl extends Tiny_Compress {
|
22 |
-
protected function shrink_options($input) {
|
23 |
-
return array(
|
24 |
-
CURLOPT_URL => $this->config['api']['url'],
|
25 |
-
CURLOPT_USERPWD => 'api:' . $this->api_key,
|
26 |
-
CURLOPT_POSTFIELDS => $input,
|
27 |
-
CURLOPT_BINARYTRANSFER => true,
|
28 |
-
CURLOPT_RETURNTRANSFER => true,
|
29 |
-
CURLOPT_HEADER => true,
|
30 |
-
CURLOPT_CAINFO => self::get_ca_file(),
|
31 |
-
CURLOPT_SSL_VERIFYPEER => true,
|
32 |
-
CURLOPT_USERAGENT => Tiny_Compress::identification() . ' cURL'
|
33 |
-
);
|
34 |
-
}
|
35 |
-
|
36 |
-
protected function shrink($input) {
|
37 |
-
$request = curl_init();
|
38 |
-
curl_setopt_array($request, $this->shrink_options($input));
|
39 |
-
|
40 |
-
$output_url = null;
|
41 |
-
$response = curl_exec($request);
|
42 |
-
if ($response === false) {
|
43 |
-
return array(array(
|
44 |
-
'error' => 'CurlError',
|
45 |
-
'message' => curl_error($request)
|
46 |
-
), null
|
47 |
-
);
|
48 |
-
}
|
49 |
-
|
50 |
-
$header_size = curl_getinfo($request, CURLINFO_HEADER_SIZE);
|
51 |
-
if (curl_getinfo($request, CURLINFO_HTTP_CODE) === 201) {
|
52 |
-
$output_url = self::parse_location_header(substr($response, 0, $header_size));
|
53 |
-
}
|
54 |
-
curl_close($request);
|
55 |
-
|
56 |
-
return array(self::decode(substr($response, $header_size)), $output_url);
|
57 |
-
}
|
58 |
-
|
59 |
-
protected function output_options($url) {
|
60 |
-
return array(
|
61 |
-
CURLOPT_URL => $url,
|
62 |
-
CURLOPT_RETURNTRANSFER => true,
|
63 |
-
CURLOPT_CAINFO => self::get_ca_file(),
|
64 |
-
CURLOPT_SSL_VERIFYPEER => true
|
65 |
-
);
|
66 |
-
}
|
67 |
-
|
68 |
-
protected function output($url) {
|
69 |
-
$request = curl_init();
|
70 |
-
curl_setopt_array($request, $this->output_options($url));
|
71 |
-
|
72 |
-
$response = curl_exec($request);
|
73 |
-
curl_close($request);
|
74 |
-
|
75 |
-
return $response;
|
76 |
-
}
|
77 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/TinyCompress/class-tiny-compress-fopen.php
DELETED
@@ -1,85 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
* Tiny Compress Images - WordPress plugin.
|
4 |
-
* Copyright (C) 2015 Voormedia B.V.
|
5 |
-
*
|
6 |
-
* This program is free software; you can redistribute it and/or modify it
|
7 |
-
* under the terms of the GNU General Public License as published by the Free
|
8 |
-
* Software Foundation; either version 2 of the License, or (at your option)
|
9 |
-
* any later version.
|
10 |
-
*
|
11 |
-
* This program is distributed in the hope that it will be useful, but WITHOUT
|
12 |
-
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
13 |
-
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
14 |
-
* more details.
|
15 |
-
*
|
16 |
-
* You should have received a copy of the GNU General Public License along
|
17 |
-
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
18 |
-
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
19 |
-
*/
|
20 |
-
|
21 |
-
class Tiny_Compress_Fopen extends Tiny_Compress {
|
22 |
-
protected function shrink_options($input) {
|
23 |
-
return array(
|
24 |
-
'http' => array(
|
25 |
-
'method' => 'POST',
|
26 |
-
'header' => array(
|
27 |
-
'Content-type: image/png',
|
28 |
-
'Authorization: Basic ' . base64_encode('api:' . $this->api_key),
|
29 |
-
'User-Agent: ' . Tiny_Compress::identification() . ' fopen',
|
30 |
-
),
|
31 |
-
'content' => $input
|
32 |
-
),
|
33 |
-
'ssl' => array(
|
34 |
-
'cafile' => self::get_ca_file(),
|
35 |
-
'verify_peer' => true
|
36 |
-
)
|
37 |
-
);
|
38 |
-
}
|
39 |
-
|
40 |
-
protected function shrink($input) {
|
41 |
-
$context = stream_context_create($this->shrink_options($input));
|
42 |
-
$request = @fopen($this->config['api']['url'], 'r', false, $context);
|
43 |
-
|
44 |
-
if (!$request) {
|
45 |
-
return array(array(
|
46 |
-
'error' => 'FopenError',
|
47 |
-
'message' => 'Could not compress, enable cURL for detailed error'
|
48 |
-
), null
|
49 |
-
);
|
50 |
-
}
|
51 |
-
|
52 |
-
$response = stream_get_contents($request);
|
53 |
-
$meta_data = stream_get_meta_data($request);
|
54 |
-
$output_url = self::parse_location_header($meta_data['wrapper_data']);
|
55 |
-
fclose($request);
|
56 |
-
|
57 |
-
return array(self::decode($response), $output_url);
|
58 |
-
}
|
59 |
-
|
60 |
-
protected function output_options() {
|
61 |
-
return array(
|
62 |
-
'http' => array(
|
63 |
-
'method' => 'GET',
|
64 |
-
),
|
65 |
-
'ssl' => array(
|
66 |
-
'cafile' => self::get_ca_file(),
|
67 |
-
'verify_peer' => true
|
68 |
-
)
|
69 |
-
);
|
70 |
-
}
|
71 |
-
|
72 |
-
protected function output($url) {
|
73 |
-
$context = stream_context_create($this->output_options());
|
74 |
-
$request = @fopen($url, 'rb', false, $context);
|
75 |
-
|
76 |
-
if ($request) {
|
77 |
-
$response = stream_get_contents($request);
|
78 |
-
fclose($request);
|
79 |
-
} else {
|
80 |
-
$response = '';
|
81 |
-
}
|
82 |
-
|
83 |
-
return $response;
|
84 |
-
}
|
85 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/TinyCompress/class-tiny-compress.php
DELETED
@@ -1,97 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
* Tiny Compress Images - WordPress plugin.
|
4 |
-
* Copyright (C) 2015 Voormedia B.V.
|
5 |
-
*
|
6 |
-
* This program is free software; you can redistribute it and/or modify it
|
7 |
-
* under the terms of the GNU General Public License as published by the Free
|
8 |
-
* Software Foundation; either version 2 of the License, or (at your option)
|
9 |
-
* any later version.
|
10 |
-
*
|
11 |
-
* This program is distributed in the hope that it will be useful, but WITHOUT
|
12 |
-
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
13 |
-
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
14 |
-
* more details.
|
15 |
-
*
|
16 |
-
* You should have received a copy of the GNU General Public License along
|
17 |
-
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
18 |
-
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
19 |
-
*/
|
20 |
-
|
21 |
-
abstract class Tiny_Compress {
|
22 |
-
protected $api_key;
|
23 |
-
protected $config;
|
24 |
-
|
25 |
-
public static function identification() {
|
26 |
-
return "Tiny Compress Magento v1.0";
|
27 |
-
}
|
28 |
-
|
29 |
-
public static function get_ca_file() {
|
30 |
-
return dirname(__FILE__) . '/cacert.pem';
|
31 |
-
}
|
32 |
-
|
33 |
-
public static function get_config() {
|
34 |
-
return parse_ini_file(dirname(__FILE__) . '/config/tinypng-api.ini', true);
|
35 |
-
}
|
36 |
-
|
37 |
-
public static function get_compressor($api_key) {
|
38 |
-
if (Tiny_PHP::is_curl_available()) {
|
39 |
-
return new Tiny_Compress_Curl($api_key, self::get_config());
|
40 |
-
} elseif (Tiny_PHP::is_fopen_available()) {
|
41 |
-
return new Tiny_Compress_Fopen($api_key, self::get_config());
|
42 |
-
}
|
43 |
-
throw new Tiny_Exception('No HTTP client is available (cURL or fopen)', 'NoHttpClient');
|
44 |
-
}
|
45 |
-
|
46 |
-
protected function __construct($api_key, $config) {
|
47 |
-
$this->api_key = $api_key;
|
48 |
-
$this->config = $config;
|
49 |
-
}
|
50 |
-
|
51 |
-
abstract protected function shrink($input);
|
52 |
-
abstract protected function output($url);
|
53 |
-
|
54 |
-
public function compress($input) {
|
55 |
-
list($details, $outputUrl) = $this->shrink($input);
|
56 |
-
if (isset($details['error']) && $details['error']) {
|
57 |
-
throw new Tiny_Exception($details['message'], $details['error']);
|
58 |
-
} else if ($outputUrl === null) {
|
59 |
-
throw new Tiny_Exception('Could not find output url', 'OutputNotFound');
|
60 |
-
}
|
61 |
-
$output = $this->output($outputUrl);
|
62 |
-
if (strlen($output) == 0) {
|
63 |
-
throw new Tiny_Exception('Could not download output', 'OutputError');
|
64 |
-
}
|
65 |
-
return array($output, $details);
|
66 |
-
}
|
67 |
-
|
68 |
-
public function compress_file($file) {
|
69 |
-
if (!file_exists($file)) {
|
70 |
-
throw new Tiny_Exception('File does not exists', 'FileError');
|
71 |
-
}
|
72 |
-
list($output, $details) = $this->compress(file_get_contents($file));
|
73 |
-
file_put_contents($file, $output);
|
74 |
-
return $details;
|
75 |
-
}
|
76 |
-
|
77 |
-
protected static function parse_location_header($headers) {
|
78 |
-
if (!is_array($headers)) {
|
79 |
-
$headers = explode("\r\n", $headers);
|
80 |
-
}
|
81 |
-
foreach ($headers as $header) {
|
82 |
-
if (strtolower(substr($header, 0, 10)) === "location: ") {
|
83 |
-
return substr($header, 10);
|
84 |
-
}
|
85 |
-
}
|
86 |
-
return null;
|
87 |
-
}
|
88 |
-
|
89 |
-
protected static function decode($text) {
|
90 |
-
$result = json_decode($text, true);
|
91 |
-
if ($result === null) {
|
92 |
-
throw new Tiny_Exception('Could not decode JSON', 'JsonError');
|
93 |
-
}
|
94 |
-
return $result;
|
95 |
-
}
|
96 |
-
}
|
97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/TinyCompress/class-tiny-exception.php
DELETED
@@ -1,32 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
* Tiny Compress Images - WordPress plugin.
|
4 |
-
* Copyright (C) 2015 Voormedia B.V.
|
5 |
-
*
|
6 |
-
* This program is free software; you can redistribute it and/or modify it
|
7 |
-
* under the terms of the GNU General Public License as published by the Free
|
8 |
-
* Software Foundation; either version 2 of the License, or (at your option)
|
9 |
-
* any later version.
|
10 |
-
*
|
11 |
-
* This program is distributed in the hope that it will be useful, but WITHOUT
|
12 |
-
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
13 |
-
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
14 |
-
* more details.
|
15 |
-
*
|
16 |
-
* You should have received a copy of the GNU General Public License along
|
17 |
-
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
18 |
-
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
19 |
-
*/
|
20 |
-
|
21 |
-
class Tiny_Exception extends Exception {
|
22 |
-
private $error;
|
23 |
-
|
24 |
-
public function __construct($message, $error=null) {
|
25 |
-
parent::__construct($message);
|
26 |
-
$this->error = $error;
|
27 |
-
}
|
28 |
-
|
29 |
-
public function get_error() {
|
30 |
-
return $this->error;
|
31 |
-
}
|
32 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/TinyCompress/class-tiny-php.php
DELETED
@@ -1,29 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
* Tiny Compress Images - WordPress plugin.
|
4 |
-
* Copyright (C) 2015 Voormedia B.V.
|
5 |
-
*
|
6 |
-
* This program is free software; you can redistribute it and/or modify it
|
7 |
-
* under the terms of the GNU General Public License as published by the Free
|
8 |
-
* Software Foundation; either version 2 of the License, or (at your option)
|
9 |
-
* any later version.
|
10 |
-
*
|
11 |
-
* This program is distributed in the hope that it will be useful, but WITHOUT
|
12 |
-
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
13 |
-
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
14 |
-
* more details.
|
15 |
-
*
|
16 |
-
* You should have received a copy of the GNU General Public License along
|
17 |
-
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
18 |
-
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
19 |
-
*/
|
20 |
-
|
21 |
-
class Tiny_PHP {
|
22 |
-
public static function is_curl_available() {
|
23 |
-
return extension_loaded('curl');
|
24 |
-
}
|
25 |
-
|
26 |
-
public static function is_fopen_available() {
|
27 |
-
return ini_get('allow_url_fopen');
|
28 |
-
}
|
29 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib/TinyCompress/composer.json
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "tinify/tinify",
|
3 |
+
"description": "PHP client for the Tinify API. Tinify compresses your images intelligently. Read more at https://tinify.com.",
|
4 |
+
"keywords": [
|
5 |
+
"tinify",
|
6 |
+
"tinypng",
|
7 |
+
"tinyjpg",
|
8 |
+
"compress",
|
9 |
+
"images",
|
10 |
+
"api"
|
11 |
+
],
|
12 |
+
|
13 |
+
"homepage": "https://tinify.com/developers",
|
14 |
+
"license": "MIT",
|
15 |
+
|
16 |
+
"support": {
|
17 |
+
"email": "support@tinify.com"
|
18 |
+
},
|
19 |
+
|
20 |
+
"authors": [{
|
21 |
+
"name": "Rolf Timmermans",
|
22 |
+
"email": "rolftimmermans@voormedia.com"
|
23 |
+
}],
|
24 |
+
|
25 |
+
"require": {
|
26 |
+
"php": ">=5.3.0",
|
27 |
+
"ext-curl": "*",
|
28 |
+
"ext-json": "*",
|
29 |
+
"lib-curl": ">=7.20.0"
|
30 |
+
},
|
31 |
+
|
32 |
+
"require-dev": {
|
33 |
+
"symfony/yaml": "~2.0",
|
34 |
+
"phpunit/phpunit": "~4.0"
|
35 |
+
},
|
36 |
+
|
37 |
+
"autoload": {
|
38 |
+
"files": ["lib/Tinify.php", "lib/Tinify/Exception.php"],
|
39 |
+
"psr-4": {"Tinify\\": "lib/Tinify/"}
|
40 |
+
}
|
41 |
+
}
|
lib/TinyCompress/composer.lock
ADDED
@@ -0,0 +1,977 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"_readme": [
|
3 |
+
"This file locks the dependencies of your project to a known state",
|
4 |
+
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
5 |
+
"This file is @generated automatically"
|
6 |
+
],
|
7 |
+
"hash": "24129bff61e8cfa8b2a82efee5c7069a",
|
8 |
+
"content-hash": "6251dc24eeaff94cb037569e414a6195",
|
9 |
+
"packages": [],
|
10 |
+
"packages-dev": [
|
11 |
+
{
|
12 |
+
"name": "doctrine/instantiator",
|
13 |
+
"version": "1.0.5",
|
14 |
+
"source": {
|
15 |
+
"type": "git",
|
16 |
+
"url": "https://github.com/doctrine/instantiator.git",
|
17 |
+
"reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
|
18 |
+
},
|
19 |
+
"dist": {
|
20 |
+
"type": "zip",
|
21 |
+
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
|
22 |
+
"reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
|
23 |
+
"shasum": ""
|
24 |
+
},
|
25 |
+
"require": {
|
26 |
+
"php": ">=5.3,<8.0-DEV"
|
27 |
+
},
|
28 |
+
"require-dev": {
|
29 |
+
"athletic/athletic": "~0.1.8",
|
30 |
+
"ext-pdo": "*",
|
31 |
+
"ext-phar": "*",
|
32 |
+
"phpunit/phpunit": "~4.0",
|
33 |
+
"squizlabs/php_codesniffer": "~2.0"
|
34 |
+
},
|
35 |
+
"type": "library",
|
36 |
+
"extra": {
|
37 |
+
"branch-alias": {
|
38 |
+
"dev-master": "1.0.x-dev"
|
39 |
+
}
|
40 |
+
},
|
41 |
+
"autoload": {
|
42 |
+
"psr-4": {
|
43 |
+
"Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
|
44 |
+
}
|
45 |
+
},
|
46 |
+
"notification-url": "https://packagist.org/downloads/",
|
47 |
+
"license": [
|
48 |
+
"MIT"
|
49 |
+
],
|
50 |
+
"authors": [
|
51 |
+
{
|
52 |
+
"name": "Marco Pivetta",
|
53 |
+
"email": "ocramius@gmail.com",
|
54 |
+
"homepage": "http://ocramius.github.com/"
|
55 |
+
}
|
56 |
+
],
|
57 |
+
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
|
58 |
+
"homepage": "https://github.com/doctrine/instantiator",
|
59 |
+
"keywords": [
|
60 |
+
"constructor",
|
61 |
+
"instantiate"
|
62 |
+
],
|
63 |
+
"time": "2015-06-14 21:17:01"
|
64 |
+
},
|
65 |
+
{
|
66 |
+
"name": "phpdocumentor/reflection-docblock",
|
67 |
+
"version": "2.0.4",
|
68 |
+
"source": {
|
69 |
+
"type": "git",
|
70 |
+
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
|
71 |
+
"reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
|
72 |
+
},
|
73 |
+
"dist": {
|
74 |
+
"type": "zip",
|
75 |
+
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
|
76 |
+
"reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
|
77 |
+
"shasum": ""
|
78 |
+
},
|
79 |
+
"require": {
|
80 |
+
"php": ">=5.3.3"
|
81 |
+
},
|
82 |
+
"require-dev": {
|
83 |
+
"phpunit/phpunit": "~4.0"
|
84 |
+
},
|
85 |
+
"suggest": {
|
86 |
+
"dflydev/markdown": "~1.0",
|
87 |
+
"erusev/parsedown": "~1.0"
|
88 |
+
},
|
89 |
+
"type": "library",
|
90 |
+
"extra": {
|
91 |
+
"branch-alias": {
|
92 |
+
"dev-master": "2.0.x-dev"
|
93 |
+
}
|
94 |
+
},
|
95 |
+
"autoload": {
|
96 |
+
"psr-0": {
|
97 |
+
"phpDocumentor": [
|
98 |
+
"src/"
|
99 |
+
]
|
100 |
+
}
|
101 |
+
},
|
102 |
+
"notification-url": "https://packagist.org/downloads/",
|
103 |
+
"license": [
|
104 |
+
"MIT"
|
105 |
+
],
|
106 |
+
"authors": [
|
107 |
+
{
|
108 |
+
"name": "Mike van Riel",
|
109 |
+
"email": "mike.vanriel@naenius.com"
|
110 |
+
}
|
111 |
+
],
|
112 |
+
"time": "2015-02-03 12:10:50"
|
113 |
+
},
|
114 |
+
{
|
115 |
+
"name": "phpspec/prophecy",
|
116 |
+
"version": "v1.6.0",
|
117 |
+
"source": {
|
118 |
+
"type": "git",
|
119 |
+
"url": "https://github.com/phpspec/prophecy.git",
|
120 |
+
"reference": "3c91bdf81797d725b14cb62906f9a4ce44235972"
|
121 |
+
},
|
122 |
+
"dist": {
|
123 |
+
"type": "zip",
|
124 |
+
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/3c91bdf81797d725b14cb62906f9a4ce44235972",
|
125 |
+
"reference": "3c91bdf81797d725b14cb62906f9a4ce44235972",
|
126 |
+
"shasum": ""
|
127 |
+
},
|
128 |
+
"require": {
|
129 |
+
"doctrine/instantiator": "^1.0.2",
|
130 |
+
"php": "^5.3|^7.0",
|
131 |
+
"phpdocumentor/reflection-docblock": "~2.0",
|
132 |
+
"sebastian/comparator": "~1.1",
|
133 |
+
"sebastian/recursion-context": "~1.0"
|
134 |
+
},
|
135 |
+
"require-dev": {
|
136 |
+
"phpspec/phpspec": "~2.0"
|
137 |
+
},
|
138 |
+
"type": "library",
|
139 |
+
"extra": {
|
140 |
+
"branch-alias": {
|
141 |
+
"dev-master": "1.5.x-dev"
|
142 |
+
}
|
143 |
+
},
|
144 |
+
"autoload": {
|
145 |
+
"psr-0": {
|
146 |
+
"Prophecy\\": "src/"
|
147 |
+
}
|
148 |
+
},
|
149 |
+
"notification-url": "https://packagist.org/downloads/",
|
150 |
+
"license": [
|
151 |
+
"MIT"
|
152 |
+
],
|
153 |
+
"authors": [
|
154 |
+
{
|
155 |
+
"name": "Konstantin Kudryashov",
|
156 |
+
"email": "ever.zet@gmail.com",
|
157 |
+
"homepage": "http://everzet.com"
|
158 |
+
},
|
159 |
+
{
|
160 |
+
"name": "Marcello Duarte",
|
161 |
+
"email": "marcello.duarte@gmail.com"
|
162 |
+
}
|
163 |
+
],
|
164 |
+
"description": "Highly opinionated mocking framework for PHP 5.3+",
|
165 |
+
"homepage": "https://github.com/phpspec/prophecy",
|
166 |
+
"keywords": [
|
167 |
+
"Double",
|
168 |
+
"Dummy",
|
169 |
+
"fake",
|
170 |
+
"mock",
|
171 |
+
"spy",
|
172 |
+
"stub"
|
173 |
+
],
|
174 |
+
"time": "2016-02-15 07:46:21"
|
175 |
+
},
|
176 |
+
{
|
177 |
+
"name": "phpunit/php-code-coverage",
|
178 |
+
"version": "2.2.4",
|
179 |
+
"source": {
|
180 |
+
"type": "git",
|
181 |
+
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
182 |
+
"reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
|
183 |
+
},
|
184 |
+
"dist": {
|
185 |
+
"type": "zip",
|
186 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
|
187 |
+
"reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
|
188 |
+
"shasum": ""
|
189 |
+
},
|
190 |
+
"require": {
|
191 |
+
"php": ">=5.3.3",
|
192 |
+
"phpunit/php-file-iterator": "~1.3",
|
193 |
+
"phpunit/php-text-template": "~1.2",
|
194 |
+
"phpunit/php-token-stream": "~1.3",
|
195 |
+
"sebastian/environment": "^1.3.2",
|
196 |
+
"sebastian/version": "~1.0"
|
197 |
+
},
|
198 |
+
"require-dev": {
|
199 |
+
"ext-xdebug": ">=2.1.4",
|
200 |
+
"phpunit/phpunit": "~4"
|
201 |
+
},
|
202 |
+
"suggest": {
|
203 |
+
"ext-dom": "*",
|
204 |
+
"ext-xdebug": ">=2.2.1",
|
205 |
+
"ext-xmlwriter": "*"
|
206 |
+
},
|
207 |
+
"type": "library",
|
208 |
+
"extra": {
|
209 |
+
"branch-alias": {
|
210 |
+
"dev-master": "2.2.x-dev"
|
211 |
+
}
|
212 |
+
},
|
213 |
+
"autoload": {
|
214 |
+
"classmap": [
|
215 |
+
"src/"
|
216 |
+
]
|
217 |
+
},
|
218 |
+
"notification-url": "https://packagist.org/downloads/",
|
219 |
+
"license": [
|
220 |
+
"BSD-3-Clause"
|
221 |
+
],
|
222 |
+
"authors": [
|
223 |
+
{
|
224 |
+
"name": "Sebastian Bergmann",
|
225 |
+
"email": "sb@sebastian-bergmann.de",
|
226 |
+
"role": "lead"
|
227 |
+
}
|
228 |
+
],
|
229 |
+
"description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
|
230 |
+
"homepage": "https://github.com/sebastianbergmann/php-code-coverage",
|
231 |
+
"keywords": [
|
232 |
+
"coverage",
|
233 |
+
"testing",
|
234 |
+
"xunit"
|
235 |
+
],
|
236 |
+
"time": "2015-10-06 15:47:00"
|
237 |
+
},
|
238 |
+
{
|
239 |
+
"name": "phpunit/php-file-iterator",
|
240 |
+
"version": "1.4.1",
|
241 |
+
"source": {
|
242 |
+
"type": "git",
|
243 |
+
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
|
244 |
+
"reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0"
|
245 |
+
},
|
246 |
+
"dist": {
|
247 |
+
"type": "zip",
|
248 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
|
249 |
+
"reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
|
250 |
+
"shasum": ""
|
251 |
+
},
|
252 |
+
"require": {
|
253 |
+
"php": ">=5.3.3"
|
254 |
+
},
|
255 |
+
"type": "library",
|
256 |
+
"extra": {
|
257 |
+
"branch-alias": {
|
258 |
+
"dev-master": "1.4.x-dev"
|
259 |
+
}
|
260 |
+
},
|
261 |
+
"autoload": {
|
262 |
+
"classmap": [
|
263 |
+
"src/"
|
264 |
+
]
|
265 |
+
},
|
266 |
+
"notification-url": "https://packagist.org/downloads/",
|
267 |
+
"license": [
|
268 |
+
"BSD-3-Clause"
|
269 |
+
],
|
270 |
+
"authors": [
|
271 |
+
{
|
272 |
+
"name": "Sebastian Bergmann",
|
273 |
+
"email": "sb@sebastian-bergmann.de",
|
274 |
+
"role": "lead"
|
275 |
+
}
|
276 |
+
],
|
277 |
+
"description": "FilterIterator implementation that filters files based on a list of suffixes.",
|
278 |
+
"homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
|
279 |
+
"keywords": [
|
280 |
+
"filesystem",
|
281 |
+
"iterator"
|
282 |
+
],
|
283 |
+
"time": "2015-06-21 13:08:43"
|
284 |
+
},
|
285 |
+
{
|
286 |
+
"name": "phpunit/php-text-template",
|
287 |
+
"version": "1.2.1",
|
288 |
+
"source": {
|
289 |
+
"type": "git",
|
290 |
+
"url": "https://github.com/sebastianbergmann/php-text-template.git",
|
291 |
+
"reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
|
292 |
+
},
|
293 |
+
"dist": {
|
294 |
+
"type": "zip",
|
295 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
|
296 |
+
"reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
|
297 |
+
"shasum": ""
|
298 |
+
},
|
299 |
+
"require": {
|
300 |
+
"php": ">=5.3.3"
|
301 |
+
},
|
302 |
+
"type": "library",
|
303 |
+
"autoload": {
|
304 |
+
"classmap": [
|
305 |
+
"src/"
|
306 |
+
]
|
307 |
+
},
|
308 |
+
"notification-url": "https://packagist.org/downloads/",
|
309 |
+
"license": [
|
310 |
+
"BSD-3-Clause"
|
311 |
+
],
|
312 |
+
"authors": [
|
313 |
+
{
|
314 |
+
"name": "Sebastian Bergmann",
|
315 |
+
"email": "sebastian@phpunit.de",
|
316 |
+
"role": "lead"
|
317 |
+
}
|
318 |
+
],
|
319 |
+
"description": "Simple template engine.",
|
320 |
+
"homepage": "https://github.com/sebastianbergmann/php-text-template/",
|
321 |
+
"keywords": [
|
322 |
+
"template"
|
323 |
+
],
|
324 |
+
"time": "2015-06-21 13:50:34"
|
325 |
+
},
|
326 |
+
{
|
327 |
+
"name": "phpunit/php-timer",
|
328 |
+
"version": "1.0.7",
|
329 |
+
"source": {
|
330 |
+
"type": "git",
|
331 |
+
"url": "https://github.com/sebastianbergmann/php-timer.git",
|
332 |
+
"reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b"
|
333 |
+
},
|
334 |
+
"dist": {
|
335 |
+
"type": "zip",
|
336 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
|
337 |
+
"reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
|
338 |
+
"shasum": ""
|
339 |
+
},
|
340 |
+
"require": {
|
341 |
+
"php": ">=5.3.3"
|
342 |
+
},
|
343 |
+
"type": "library",
|
344 |
+
"autoload": {
|
345 |
+
"classmap": [
|
346 |
+
"src/"
|
347 |
+
]
|
348 |
+
},
|
349 |
+
"notification-url": "https://packagist.org/downloads/",
|
350 |
+
"license": [
|
351 |
+
"BSD-3-Clause"
|
352 |
+
],
|
353 |
+
"authors": [
|
354 |
+
{
|
355 |
+
"name": "Sebastian Bergmann",
|
356 |
+
"email": "sb@sebastian-bergmann.de",
|
357 |
+
"role": "lead"
|
358 |
+
}
|
359 |
+
],
|
360 |
+
"description": "Utility class for timing",
|
361 |
+
"homepage": "https://github.com/sebastianbergmann/php-timer/",
|
362 |
+
"keywords": [
|
363 |
+
"timer"
|
364 |
+
],
|
365 |
+
"time": "2015-06-21 08:01:12"
|
366 |
+
},
|
367 |
+
{
|
368 |
+
"name": "phpunit/php-token-stream",
|
369 |
+
"version": "1.4.8",
|
370 |
+
"source": {
|
371 |
+
"type": "git",
|
372 |
+
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
|
373 |
+
"reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da"
|
374 |
+
},
|
375 |
+
"dist": {
|
376 |
+
"type": "zip",
|
377 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
|
378 |
+
"reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
|
379 |
+
"shasum": ""
|
380 |
+
},
|
381 |
+
"require": {
|
382 |
+
"ext-tokenizer": "*",
|
383 |
+
"php": ">=5.3.3"
|
384 |
+
},
|
385 |
+
"require-dev": {
|
386 |
+
"phpunit/phpunit": "~4.2"
|
387 |
+
},
|
388 |
+
"type": "library",
|
389 |
+
"extra": {
|
390 |
+
"branch-alias": {
|
391 |
+
"dev-master": "1.4-dev"
|
392 |
+
}
|
393 |
+
},
|
394 |
+
"autoload": {
|
395 |
+
"classmap": [
|
396 |
+
"src/"
|
397 |
+
]
|
398 |
+
},
|
399 |
+
"notification-url": "https://packagist.org/downloads/",
|
400 |
+
"license": [
|
401 |
+
"BSD-3-Clause"
|
402 |
+
],
|
403 |
+
"authors": [
|
404 |
+
{
|
405 |
+
"name": "Sebastian Bergmann",
|
406 |
+
"email": "sebastian@phpunit.de"
|
407 |
+
}
|
408 |
+
],
|
409 |
+
"description": "Wrapper around PHP's tokenizer extension.",
|
410 |
+
"homepage": "https://github.com/sebastianbergmann/php-token-stream/",
|
411 |
+
"keywords": [
|
412 |
+
"tokenizer"
|
413 |
+
],
|
414 |
+
"time": "2015-09-15 10:49:45"
|
415 |
+
},
|
416 |
+
{
|
417 |
+
"name": "phpunit/phpunit",
|
418 |
+
"version": "4.8.24",
|
419 |
+
"source": {
|
420 |
+
"type": "git",
|
421 |
+
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
422 |
+
"reference": "a1066c562c52900a142a0e2bbf0582994671385e"
|
423 |
+
},
|
424 |
+
"dist": {
|
425 |
+
"type": "zip",
|
426 |
+
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a1066c562c52900a142a0e2bbf0582994671385e",
|
427 |
+
"reference": "a1066c562c52900a142a0e2bbf0582994671385e",
|
428 |
+
"shasum": ""
|
429 |
+
},
|
430 |
+
"require": {
|
431 |
+
"ext-dom": "*",
|
432 |
+
"ext-json": "*",
|
433 |
+
"ext-pcre": "*",
|
434 |
+
"ext-reflection": "*",
|
435 |
+
"ext-spl": "*",
|
436 |
+
"php": ">=5.3.3",
|
437 |
+
"phpspec/prophecy": "^1.3.1",
|
438 |
+
"phpunit/php-code-coverage": "~2.1",
|
439 |
+
"phpunit/php-file-iterator": "~1.4",
|
440 |
+
"phpunit/php-text-template": "~1.2",
|
441 |
+
"phpunit/php-timer": ">=1.0.6",
|
442 |
+
"phpunit/phpunit-mock-objects": "~2.3",
|
443 |
+
"sebastian/comparator": "~1.1",
|
444 |
+
"sebastian/diff": "~1.2",
|
445 |
+
"sebastian/environment": "~1.3",
|
446 |
+
"sebastian/exporter": "~1.2",
|
447 |
+
"sebastian/global-state": "~1.0",
|
448 |
+
"sebastian/version": "~1.0",
|
449 |
+
"symfony/yaml": "~2.1|~3.0"
|
450 |
+
},
|
451 |
+
"suggest": {
|
452 |
+
"phpunit/php-invoker": "~1.1"
|
453 |
+
},
|
454 |
+
"bin": [
|
455 |
+
"phpunit"
|
456 |
+
],
|
457 |
+
"type": "library",
|
458 |
+
"extra": {
|
459 |
+
"branch-alias": {
|
460 |
+
"dev-master": "4.8.x-dev"
|
461 |
+
}
|
462 |
+
},
|
463 |
+
"autoload": {
|
464 |
+
"classmap": [
|
465 |
+
"src/"
|
466 |
+
]
|
467 |
+
},
|
468 |
+
"notification-url": "https://packagist.org/downloads/",
|
469 |
+
"license": [
|
470 |
+
"BSD-3-Clause"
|
471 |
+
],
|
472 |
+
"authors": [
|
473 |
+
{
|
474 |
+
"name": "Sebastian Bergmann",
|
475 |
+
"email": "sebastian@phpunit.de",
|
476 |
+
"role": "lead"
|
477 |
+
}
|
478 |
+
],
|
479 |
+
"description": "The PHP Unit Testing framework.",
|
480 |
+
"homepage": "https://phpunit.de/",
|
481 |
+
"keywords": [
|
482 |
+
"phpunit",
|
483 |
+
"testing",
|
484 |
+
"xunit"
|
485 |
+
],
|
486 |
+
"time": "2016-03-14 06:16:08"
|
487 |
+
},
|
488 |
+
{
|
489 |
+
"name": "phpunit/phpunit-mock-objects",
|
490 |
+
"version": "2.3.8",
|
491 |
+
"source": {
|
492 |
+
"type": "git",
|
493 |
+
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
|
494 |
+
"reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
|
495 |
+
},
|
496 |
+
"dist": {
|
497 |
+
"type": "zip",
|
498 |
+
"url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
|
499 |
+
"reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
|
500 |
+
"shasum": ""
|
501 |
+
},
|
502 |
+
"require": {
|
503 |
+
"doctrine/instantiator": "^1.0.2",
|
504 |
+
"php": ">=5.3.3",
|
505 |
+
"phpunit/php-text-template": "~1.2",
|
506 |
+
"sebastian/exporter": "~1.2"
|
507 |
+
},
|
508 |
+
"require-dev": {
|
509 |
+
"phpunit/phpunit": "~4.4"
|
510 |
+
},
|
511 |
+
"suggest": {
|
512 |
+
"ext-soap": "*"
|
513 |
+
},
|
514 |
+
"type": "library",
|
515 |
+
"extra": {
|
516 |
+
"branch-alias": {
|
517 |
+
"dev-master": "2.3.x-dev"
|
518 |
+
}
|
519 |
+
},
|
520 |
+
"autoload": {
|
521 |
+
"classmap": [
|
522 |
+
"src/"
|
523 |
+
]
|
524 |
+
},
|
525 |
+
"notification-url": "https://packagist.org/downloads/",
|
526 |
+
"license": [
|
527 |
+
"BSD-3-Clause"
|
528 |
+
],
|
529 |
+
"authors": [
|
530 |
+
{
|
531 |
+
"name": "Sebastian Bergmann",
|
532 |
+
"email": "sb@sebastian-bergmann.de",
|
533 |
+
"role": "lead"
|
534 |
+
}
|
535 |
+
],
|
536 |
+
"description": "Mock Object library for PHPUnit",
|
537 |
+
"homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
|
538 |
+
"keywords": [
|
539 |
+
"mock",
|
540 |
+
"xunit"
|
541 |
+
],
|
542 |
+
"time": "2015-10-02 06:51:40"
|
543 |
+
},
|
544 |
+
{
|
545 |
+
"name": "sebastian/comparator",
|
546 |
+
"version": "1.2.0",
|
547 |
+
"source": {
|
548 |
+
"type": "git",
|
549 |
+
"url": "https://github.com/sebastianbergmann/comparator.git",
|
550 |
+
"reference": "937efb279bd37a375bcadf584dec0726f84dbf22"
|
551 |
+
},
|
552 |
+
"dist": {
|
553 |
+
"type": "zip",
|
554 |
+
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22",
|
555 |
+
"reference": "937efb279bd37a375bcadf584dec0726f84dbf22",
|
556 |
+
"shasum": ""
|
557 |
+
},
|
558 |
+
"require": {
|
559 |
+
"php": ">=5.3.3",
|
560 |
+
"sebastian/diff": "~1.2",
|
561 |
+
"sebastian/exporter": "~1.2"
|
562 |
+
},
|
563 |
+
"require-dev": {
|
564 |
+
"phpunit/phpunit": "~4.4"
|
565 |
+
},
|
566 |
+
"type": "library",
|
567 |
+
"extra": {
|
568 |
+
"branch-alias": {
|
569 |
+
"dev-master": "1.2.x-dev"
|
570 |
+
}
|
571 |
+
},
|
572 |
+
"autoload": {
|
573 |
+
"classmap": [
|
574 |
+
"src/"
|
575 |
+
]
|
576 |
+
},
|
577 |
+
"notification-url": "https://packagist.org/downloads/",
|
578 |
+
"license": [
|
579 |
+
"BSD-3-Clause"
|
580 |
+
],
|
581 |
+
"authors": [
|
582 |
+
{
|
583 |
+
"name": "Jeff Welch",
|
584 |
+
"email": "whatthejeff@gmail.com"
|
585 |
+
},
|
586 |
+
{
|
587 |
+
"name": "Volker Dusch",
|
588 |
+
"email": "github@wallbash.com"
|
589 |
+
},
|
590 |
+
{
|
591 |
+
"name": "Bernhard Schussek",
|
592 |
+
"email": "bschussek@2bepublished.at"
|
593 |
+
},
|
594 |
+
{
|
595 |
+
"name": "Sebastian Bergmann",
|
596 |
+
"email": "sebastian@phpunit.de"
|
597 |
+
}
|
598 |
+
],
|
599 |
+
"description": "Provides the functionality to compare PHP values for equality",
|
600 |
+
"homepage": "http://www.github.com/sebastianbergmann/comparator",
|
601 |
+
"keywords": [
|
602 |
+
"comparator",
|
603 |
+
"compare",
|
604 |
+
"equality"
|
605 |
+
],
|
606 |
+
"time": "2015-07-26 15:48:44"
|
607 |
+
},
|
608 |
+
{
|
609 |
+
"name": "sebastian/diff",
|
610 |
+
"version": "1.4.1",
|
611 |
+
"source": {
|
612 |
+
"type": "git",
|
613 |
+
"url": "https://github.com/sebastianbergmann/diff.git",
|
614 |
+
"reference": "13edfd8706462032c2f52b4b862974dd46b71c9e"
|
615 |
+
},
|
616 |
+
"dist": {
|
617 |
+
"type": "zip",
|
618 |
+
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e",
|
619 |
+
"reference": "13edfd8706462032c2f52b4b862974dd46b71c9e",
|
620 |
+
"shasum": ""
|
621 |
+
},
|
622 |
+
"require": {
|
623 |
+
"php": ">=5.3.3"
|
624 |
+
},
|
625 |
+
"require-dev": {
|
626 |
+
"phpunit/phpunit": "~4.8"
|
627 |
+
},
|
628 |
+
"type": "library",
|
629 |
+
"extra": {
|
630 |
+
"branch-alias": {
|
631 |
+
"dev-master": "1.4-dev"
|
632 |
+
}
|
633 |
+
},
|
634 |
+
"autoload": {
|
635 |
+
"classmap": [
|
636 |
+
"src/"
|
637 |
+
]
|
638 |
+
},
|
639 |
+
"notification-url": "https://packagist.org/downloads/",
|
640 |
+
"license": [
|
641 |
+
"BSD-3-Clause"
|
642 |
+
],
|
643 |
+
"authors": [
|
644 |
+
{
|
645 |
+
"name": "Kore Nordmann",
|
646 |
+
"email": "mail@kore-nordmann.de"
|
647 |
+
},
|
648 |
+
{
|
649 |
+
"name": "Sebastian Bergmann",
|
650 |
+
"email": "sebastian@phpunit.de"
|
651 |
+
}
|
652 |
+
],
|
653 |
+
"description": "Diff implementation",
|
654 |
+
"homepage": "https://github.com/sebastianbergmann/diff",
|
655 |
+
"keywords": [
|
656 |
+
"diff"
|
657 |
+
],
|
658 |
+
"time": "2015-12-08 07:14:41"
|
659 |
+
},
|
660 |
+
{
|
661 |
+
"name": "sebastian/environment",
|
662 |
+
"version": "1.3.5",
|
663 |
+
"source": {
|
664 |
+
"type": "git",
|
665 |
+
"url": "https://github.com/sebastianbergmann/environment.git",
|
666 |
+
"reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf"
|
667 |
+
},
|
668 |
+
"dist": {
|
669 |
+
"type": "zip",
|
670 |
+
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf",
|
671 |
+
"reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf",
|
672 |
+
"shasum": ""
|
673 |
+
},
|
674 |
+
"require": {
|
675 |
+
"php": ">=5.3.3"
|
676 |
+
},
|
677 |
+
"require-dev": {
|
678 |
+
"phpunit/phpunit": "~4.4"
|
679 |
+
},
|
680 |
+
"type": "library",
|
681 |
+
"extra": {
|
682 |
+
"branch-alias": {
|
683 |
+
"dev-master": "1.3.x-dev"
|
684 |
+
}
|
685 |
+
},
|
686 |
+
"autoload": {
|
687 |
+
"classmap": [
|
688 |
+
"src/"
|
689 |
+
]
|
690 |
+
},
|
691 |
+
"notification-url": "https://packagist.org/downloads/",
|
692 |
+
"license": [
|
693 |
+
"BSD-3-Clause"
|
694 |
+
],
|
695 |
+
"authors": [
|
696 |
+
{
|
697 |
+
"name": "Sebastian Bergmann",
|
698 |
+
"email": "sebastian@phpunit.de"
|
699 |
+
}
|
700 |
+
],
|
701 |
+
"description": "Provides functionality to handle HHVM/PHP environments",
|
702 |
+
"homepage": "http://www.github.com/sebastianbergmann/environment",
|
703 |
+
"keywords": [
|
704 |
+
"Xdebug",
|
705 |
+
"environment",
|
706 |
+
"hhvm"
|
707 |
+
],
|
708 |
+
"time": "2016-02-26 18:40:46"
|
709 |
+
},
|
710 |
+
{
|
711 |
+
"name": "sebastian/exporter",
|
712 |
+
"version": "1.2.1",
|
713 |
+
"source": {
|
714 |
+
"type": "git",
|
715 |
+
"url": "https://github.com/sebastianbergmann/exporter.git",
|
716 |
+
"reference": "7ae5513327cb536431847bcc0c10edba2701064e"
|
717 |
+
},
|
718 |
+
"dist": {
|
719 |
+
"type": "zip",
|
720 |
+
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e",
|
721 |
+
"reference": "7ae5513327cb536431847bcc0c10edba2701064e",
|
722 |
+
"shasum": ""
|
723 |
+
},
|
724 |
+
"require": {
|
725 |
+
"php": ">=5.3.3",
|
726 |
+
"sebastian/recursion-context": "~1.0"
|
727 |
+
},
|
728 |
+
"require-dev": {
|
729 |
+
"phpunit/phpunit": "~4.4"
|
730 |
+
},
|
731 |
+
"type": "library",
|
732 |
+
"extra": {
|
733 |
+
"branch-alias": {
|
734 |
+
"dev-master": "1.2.x-dev"
|
735 |
+
}
|
736 |
+
},
|
737 |
+
"autoload": {
|
738 |
+
"classmap": [
|
739 |
+
"src/"
|
740 |
+
]
|
741 |
+
},
|
742 |
+
"notification-url": "https://packagist.org/downloads/",
|
743 |
+
"license": [
|
744 |
+
"BSD-3-Clause"
|
745 |
+
],
|
746 |
+
"authors": [
|
747 |
+
{
|
748 |
+
"name": "Jeff Welch",
|
749 |
+
"email": "whatthejeff@gmail.com"
|
750 |
+
},
|
751 |
+
{
|
752 |
+
"name": "Volker Dusch",
|
753 |
+
"email": "github@wallbash.com"
|
754 |
+
},
|
755 |
+
{
|
756 |
+
"name": "Bernhard Schussek",
|
757 |
+
"email": "bschussek@2bepublished.at"
|
758 |
+
},
|
759 |
+
{
|
760 |
+
"name": "Sebastian Bergmann",
|
761 |
+
"email": "sebastian@phpunit.de"
|
762 |
+
},
|
763 |
+
{
|
764 |
+
"name": "Adam Harvey",
|
765 |
+
"email": "aharvey@php.net"
|
766 |
+
}
|
767 |
+
],
|
768 |
+
"description": "Provides the functionality to export PHP variables for visualization",
|
769 |
+
"homepage": "http://www.github.com/sebastianbergmann/exporter",
|
770 |
+
"keywords": [
|
771 |
+
"export",
|
772 |
+
"exporter"
|
773 |
+
],
|
774 |
+
"time": "2015-06-21 07:55:53"
|
775 |
+
},
|
776 |
+
{
|
777 |
+
"name": "sebastian/global-state",
|
778 |
+
"version": "1.1.1",
|
779 |
+
"source": {
|
780 |
+
"type": "git",
|
781 |
+
"url": "https://github.com/sebastianbergmann/global-state.git",
|
782 |
+
"reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
|
783 |
+
},
|
784 |
+
"dist": {
|
785 |
+
"type": "zip",
|
786 |
+
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
|
787 |
+
"reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
|
788 |
+
"shasum": ""
|
789 |
+
},
|
790 |
+
"require": {
|
791 |
+
"php": ">=5.3.3"
|
792 |
+
},
|
793 |
+
"require-dev": {
|
794 |
+
"phpunit/phpunit": "~4.2"
|
795 |
+
},
|
796 |
+
"suggest": {
|
797 |
+
"ext-uopz": "*"
|
798 |
+
},
|
799 |
+
"type": "library",
|
800 |
+
"extra": {
|
801 |
+
"branch-alias": {
|
802 |
+
"dev-master": "1.0-dev"
|
803 |
+
}
|
804 |
+
},
|
805 |
+
"autoload": {
|
806 |
+
"classmap": [
|
807 |
+
"src/"
|
808 |
+
]
|
809 |
+
},
|
810 |
+
"notification-url": "https://packagist.org/downloads/",
|
811 |
+
"license": [
|
812 |
+
"BSD-3-Clause"
|
813 |
+
],
|
814 |
+
"authors": [
|
815 |
+
{
|
816 |
+
"name": "Sebastian Bergmann",
|
817 |
+
"email": "sebastian@phpunit.de"
|
818 |
+
}
|
819 |
+
],
|
820 |
+
"description": "Snapshotting of global state",
|
821 |
+
"homepage": "http://www.github.com/sebastianbergmann/global-state",
|
822 |
+
"keywords": [
|
823 |
+
"global state"
|
824 |
+
],
|
825 |
+
"time": "2015-10-12 03:26:01"
|
826 |
+
},
|
827 |
+
{
|
828 |
+
"name": "sebastian/recursion-context",
|
829 |
+
"version": "1.0.2",
|
830 |
+
"source": {
|
831 |
+
"type": "git",
|
832 |
+
"url": "https://github.com/sebastianbergmann/recursion-context.git",
|
833 |
+
"reference": "913401df809e99e4f47b27cdd781f4a258d58791"
|
834 |
+
},
|
835 |
+
"dist": {
|
836 |
+
"type": "zip",
|
837 |
+
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791",
|
838 |
+
"reference": "913401df809e99e4f47b27cdd781f4a258d58791",
|
839 |
+
"shasum": ""
|
840 |
+
},
|
841 |
+
"require": {
|
842 |
+
"php": ">=5.3.3"
|
843 |
+
},
|
844 |
+
"require-dev": {
|
845 |
+
"phpunit/phpunit": "~4.4"
|
846 |
+
},
|
847 |
+
"type": "library",
|
848 |
+
"extra": {
|
849 |
+
"branch-alias": {
|
850 |
+
"dev-master": "1.0.x-dev"
|
851 |
+
}
|
852 |
+
},
|
853 |
+
"autoload": {
|
854 |
+
"classmap": [
|
855 |
+
"src/"
|
856 |
+
]
|
857 |
+
},
|
858 |
+
"notification-url": "https://packagist.org/downloads/",
|
859 |
+
"license": [
|
860 |
+
"BSD-3-Clause"
|
861 |
+
],
|
862 |
+
"authors": [
|
863 |
+
{
|
864 |
+
"name": "Jeff Welch",
|
865 |
+
"email": "whatthejeff@gmail.com"
|
866 |
+
},
|
867 |
+
{
|
868 |
+
"name": "Sebastian Bergmann",
|
869 |
+
"email": "sebastian@phpunit.de"
|
870 |
+
},
|
871 |
+
{
|
872 |
+
"name": "Adam Harvey",
|
873 |
+
"email": "aharvey@php.net"
|
874 |
+
}
|
875 |
+
],
|
876 |
+
"description": "Provides functionality to recursively process PHP variables",
|
877 |
+
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
|
878 |
+
"time": "2015-11-11 19:50:13"
|
879 |
+
},
|
880 |
+
{
|
881 |
+
"name": "sebastian/version",
|
882 |
+
"version": "1.0.6",
|
883 |
+
"source": {
|
884 |
+
"type": "git",
|
885 |
+
"url": "https://github.com/sebastianbergmann/version.git",
|
886 |
+
"reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
|
887 |
+
},
|
888 |
+
"dist": {
|
889 |
+
"type": "zip",
|
890 |
+
"url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
|
891 |
+
"reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
|
892 |
+
"shasum": ""
|
893 |
+
},
|
894 |
+
"type": "library",
|
895 |
+
"autoload": {
|
896 |
+
"classmap": [
|
897 |
+
"src/"
|
898 |
+
]
|
899 |
+
},
|
900 |
+
"notification-url": "https://packagist.org/downloads/",
|
901 |
+
"license": [
|
902 |
+
"BSD-3-Clause"
|
903 |
+
],
|
904 |
+
"authors": [
|
905 |
+
{
|
906 |
+
"name": "Sebastian Bergmann",
|
907 |
+
"email": "sebastian@phpunit.de",
|
908 |
+
"role": "lead"
|
909 |
+
}
|
910 |
+
],
|
911 |
+
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
|
912 |
+
"homepage": "https://github.com/sebastianbergmann/version",
|
913 |
+
"time": "2015-06-21 13:59:46"
|
914 |
+
},
|
915 |
+
{
|
916 |
+
"name": "symfony/yaml",
|
917 |
+
"version": "v2.8.4",
|
918 |
+
"source": {
|
919 |
+
"type": "git",
|
920 |
+
"url": "https://github.com/symfony/yaml.git",
|
921 |
+
"reference": "584e52cb8f788a887553ba82db6caacb1d6260bb"
|
922 |
+
},
|
923 |
+
"dist": {
|
924 |
+
"type": "zip",
|
925 |
+
"url": "https://api.github.com/repos/symfony/yaml/zipball/584e52cb8f788a887553ba82db6caacb1d6260bb",
|
926 |
+
"reference": "584e52cb8f788a887553ba82db6caacb1d6260bb",
|
927 |
+
"shasum": ""
|
928 |
+
},
|
929 |
+
"require": {
|
930 |
+
"php": ">=5.3.9"
|
931 |
+
},
|
932 |
+
"type": "library",
|
933 |
+
"extra": {
|
934 |
+
"branch-alias": {
|
935 |
+
"dev-master": "2.8-dev"
|
936 |
+
}
|
937 |
+
},
|
938 |
+
"autoload": {
|
939 |
+
"psr-4": {
|
940 |
+
"Symfony\\Component\\Yaml\\": ""
|
941 |
+
},
|
942 |
+
"exclude-from-classmap": [
|
943 |
+
"/Tests/"
|
944 |
+
]
|
945 |
+
},
|
946 |
+
"notification-url": "https://packagist.org/downloads/",
|
947 |
+
"license": [
|
948 |
+
"MIT"
|
949 |
+
],
|
950 |
+
"authors": [
|
951 |
+
{
|
952 |
+
"name": "Fabien Potencier",
|
953 |
+
"email": "fabien@symfony.com"
|
954 |
+
},
|
955 |
+
{
|
956 |
+
"name": "Symfony Community",
|
957 |
+
"homepage": "https://symfony.com/contributors"
|
958 |
+
}
|
959 |
+
],
|
960 |
+
"description": "Symfony Yaml Component",
|
961 |
+
"homepage": "https://symfony.com",
|
962 |
+
"time": "2016-03-04 07:54:35"
|
963 |
+
}
|
964 |
+
],
|
965 |
+
"aliases": [],
|
966 |
+
"minimum-stability": "stable",
|
967 |
+
"stability-flags": [],
|
968 |
+
"prefer-stable": false,
|
969 |
+
"prefer-lowest": false,
|
970 |
+
"platform": {
|
971 |
+
"php": ">=5.3.0",
|
972 |
+
"ext-curl": "*",
|
973 |
+
"ext-json": "*",
|
974 |
+
"lib-curl": ">=7.20.0"
|
975 |
+
},
|
976 |
+
"platform-dev": []
|
977 |
+
}
|
lib/TinyCompress/config/tinypng-api.ini
DELETED
@@ -1,2 +0,0 @@
|
|
1 |
-
[api]
|
2 |
-
url = "https://api.tinypng.com/shrink"
|
|
|
|
lib/TinyCompress/lib/Tinify.php
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Tinify;
|
4 |
+
|
5 |
+
const VERSION = "1.3.0";
|
6 |
+
|
7 |
+
class Tinify {
|
8 |
+
private static $key = NULL;
|
9 |
+
private static $appIdentifier = NULL;
|
10 |
+
private static $compressionCount = NULL;
|
11 |
+
private static $client = NULL;
|
12 |
+
|
13 |
+
public static function setKey($key) {
|
14 |
+
self::$key = $key;
|
15 |
+
self::$client = NULL;
|
16 |
+
}
|
17 |
+
|
18 |
+
public static function setAppIdentifier($appIdentifier) {
|
19 |
+
self::$appIdentifier = $appIdentifier;
|
20 |
+
self::$client = NULL;
|
21 |
+
}
|
22 |
+
|
23 |
+
public static function getCompressionCount() {
|
24 |
+
return self::$compressionCount;
|
25 |
+
}
|
26 |
+
|
27 |
+
public static function setCompressionCount($compressionCount) {
|
28 |
+
self::$compressionCount = $compressionCount;
|
29 |
+
}
|
30 |
+
|
31 |
+
public static function getClient() {
|
32 |
+
if (!self::$key) {
|
33 |
+
throw new AccountException("Provide an API key with Tinify\setKey(...)");
|
34 |
+
}
|
35 |
+
|
36 |
+
if (!self::$client) {
|
37 |
+
self::$client = new Client(self::$key, self::$appIdentifier);
|
38 |
+
}
|
39 |
+
|
40 |
+
return self::$client;
|
41 |
+
}
|
42 |
+
|
43 |
+
public static function setClient($client) {
|
44 |
+
self::$client = $client;
|
45 |
+
}
|
46 |
+
}
|
47 |
+
|
48 |
+
function setKey($key) {
|
49 |
+
return Tinify::setKey($key);
|
50 |
+
}
|
51 |
+
|
52 |
+
function setAppIdentifier($appIdentifier) {
|
53 |
+
return Tinify::setAppIdentifier($appIdentifier);
|
54 |
+
}
|
55 |
+
|
56 |
+
function getCompressionCount() {
|
57 |
+
return Tinify::getCompressionCount();
|
58 |
+
}
|
59 |
+
|
60 |
+
function compressionCount() {
|
61 |
+
return Tinify::getCompressionCount();
|
62 |
+
}
|
63 |
+
|
64 |
+
function fromFile($path) {
|
65 |
+
return Source::fromFile($path);
|
66 |
+
}
|
67 |
+
|
68 |
+
function fromBuffer($string) {
|
69 |
+
return Source::fromBuffer($string);
|
70 |
+
}
|
71 |
+
|
72 |
+
function fromUrl($string) {
|
73 |
+
return Source::fromUrl($string);
|
74 |
+
}
|
75 |
+
|
76 |
+
function validate() {
|
77 |
+
try {
|
78 |
+
Tinify::getClient()->request("post", "/shrink");
|
79 |
+
} catch (AccountException $err) {
|
80 |
+
if ($err->status == 429) return true;
|
81 |
+
throw $err;
|
82 |
+
} catch (ClientException $err) {
|
83 |
+
return true;
|
84 |
+
}
|
85 |
+
}
|
lib/TinyCompress/lib/Tinify/Client.php
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Tinify;
|
4 |
+
|
5 |
+
class Client {
|
6 |
+
const API_ENDPOINT = "https://api.tinify.com";
|
7 |
+
|
8 |
+
private $options;
|
9 |
+
|
10 |
+
public static function userAgent() {
|
11 |
+
$curl = curl_version();
|
12 |
+
return "Tinify/" . VERSION . " PHP/" . PHP_VERSION . " curl/" . $curl["version"];
|
13 |
+
}
|
14 |
+
|
15 |
+
private static function caBundle() {
|
16 |
+
return __DIR__ . "/../data/cacert.pem";
|
17 |
+
}
|
18 |
+
|
19 |
+
function __construct($key, $app_identifier = NULL) {
|
20 |
+
$this->options = array(
|
21 |
+
CURLOPT_BINARYTRANSFER => true,
|
22 |
+
CURLOPT_RETURNTRANSFER => true,
|
23 |
+
CURLOPT_HEADER => true,
|
24 |
+
CURLOPT_USERPWD => "api:" . $key,
|
25 |
+
CURLOPT_CAINFO => self::caBundle(),
|
26 |
+
CURLOPT_SSL_VERIFYPEER => true,
|
27 |
+
CURLOPT_USERAGENT => join(" ", array_filter(array(self::userAgent(), $app_identifier))),
|
28 |
+
);
|
29 |
+
}
|
30 |
+
|
31 |
+
function request($method, $url, $body = NULL, $header = array()) {
|
32 |
+
if (is_array($body)) {
|
33 |
+
if (!empty($body)) {
|
34 |
+
$body = json_encode($body);
|
35 |
+
array_push($header, "Content-Type: application/json");
|
36 |
+
} else {
|
37 |
+
$body = NULL;
|
38 |
+
}
|
39 |
+
}
|
40 |
+
|
41 |
+
$request = curl_init();
|
42 |
+
curl_setopt_array($request, $this->options);
|
43 |
+
|
44 |
+
$url = strtolower(substr($url, 0, 6)) == "https:" ? $url : Client::API_ENDPOINT . $url;
|
45 |
+
curl_setopt($request, CURLOPT_URL, $url);
|
46 |
+
curl_setopt($request, CURLOPT_HTTPHEADER, $header);
|
47 |
+
curl_setopt($request, CURLOPT_CUSTOMREQUEST, strtoupper($method));
|
48 |
+
|
49 |
+
if ($body) {
|
50 |
+
curl_setopt($request, CURLOPT_POSTFIELDS, $body);
|
51 |
+
}
|
52 |
+
|
53 |
+
$response = curl_exec($request);
|
54 |
+
|
55 |
+
if (is_string($response)) {
|
56 |
+
$status = curl_getinfo($request, CURLINFO_HTTP_CODE);
|
57 |
+
$headerSize = curl_getinfo($request, CURLINFO_HEADER_SIZE);
|
58 |
+
curl_close($request);
|
59 |
+
|
60 |
+
$headers = self::parseHeaders(substr($response, 0, $headerSize));
|
61 |
+
$body = substr($response, $headerSize);
|
62 |
+
|
63 |
+
if (isset($headers["compression-count"])) {
|
64 |
+
Tinify::setCompressionCount(intval($headers["compression-count"]));
|
65 |
+
}
|
66 |
+
|
67 |
+
if ($status >= 200 && $status <= 299) {
|
68 |
+
return array("body" => $body, "headers" => $headers);
|
69 |
+
}
|
70 |
+
|
71 |
+
$details = json_decode($body);
|
72 |
+
if (!$details) {
|
73 |
+
$message = sprintf("Error while parsing response: %s (#%d)",
|
74 |
+
PHP_VERSION_ID >= 50500 ? json_last_error_msg() : "Error",
|
75 |
+
json_last_error());
|
76 |
+
$details = (object) array(
|
77 |
+
"message" => $message,
|
78 |
+
"error" => "ParseError"
|
79 |
+
);
|
80 |
+
}
|
81 |
+
|
82 |
+
throw Exception::create($details->message, $details->error, $status);
|
83 |
+
} else {
|
84 |
+
$message = sprintf("%s (#%d)", curl_error($request), curl_errno($request));
|
85 |
+
curl_close($request);
|
86 |
+
throw new ConnectionException("Error while connecting: " . $message);
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
protected static function parseHeaders($headers) {
|
91 |
+
if (!is_array($headers)) {
|
92 |
+
$headers = explode("\r\n", $headers);
|
93 |
+
}
|
94 |
+
|
95 |
+
$res = array();
|
96 |
+
foreach ($headers as $header) {
|
97 |
+
if (empty($header)) continue;
|
98 |
+
$split = explode(":", $header, 2);
|
99 |
+
if (count($split) === 2) {
|
100 |
+
$res[strtolower($split[0])] = trim($split[1]);
|
101 |
+
}
|
102 |
+
}
|
103 |
+
return $res;
|
104 |
+
}
|
105 |
+
}
|
lib/TinyCompress/lib/Tinify/Exception.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Tinify;
|
4 |
+
|
5 |
+
class Exception extends \Exception {
|
6 |
+
public static function create($message, $type, $status) {
|
7 |
+
if ($status == 401 || $status == 429) {
|
8 |
+
$klass = "Tinify\AccountException";
|
9 |
+
} else if($status >= 400 && $status <= 499) {
|
10 |
+
$klass = "Tinify\ClientException";
|
11 |
+
} else if($status >= 500 && $status <= 599) {
|
12 |
+
$klass = "Tinify\ServerException";
|
13 |
+
} else {
|
14 |
+
$klass = "Tinify\Exception";
|
15 |
+
}
|
16 |
+
|
17 |
+
if (empty($message)) $message = "No message was provided";
|
18 |
+
return new $klass($message, $type, $status);
|
19 |
+
}
|
20 |
+
|
21 |
+
function __construct($message, $type = NULL, $status = NULL) {
|
22 |
+
if ($status) {
|
23 |
+
$this->status = $status;
|
24 |
+
parent::__construct($message . " (HTTP " . $status . "/" . $type . ")");
|
25 |
+
} else {
|
26 |
+
parent::__construct($message);
|
27 |
+
}
|
28 |
+
}
|
29 |
+
}
|
30 |
+
|
31 |
+
class AccountException extends Exception {}
|
32 |
+
class ClientException extends Exception {}
|
33 |
+
class ServerException extends Exception {}
|
34 |
+
class ConnectionException extends Exception {}
|
lib/TinyCompress/lib/Tinify/Result.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Tinify;
|
4 |
+
|
5 |
+
class Result extends ResultMeta {
|
6 |
+
protected $data;
|
7 |
+
|
8 |
+
public function __construct($meta, $data) {
|
9 |
+
$this->meta = $meta;
|
10 |
+
$this->data = $data;
|
11 |
+
}
|
12 |
+
|
13 |
+
public function data() {
|
14 |
+
return $this->data;
|
15 |
+
}
|
16 |
+
|
17 |
+
public function toBuffer() {
|
18 |
+
return $this->data;
|
19 |
+
}
|
20 |
+
|
21 |
+
public function toFile($path) {
|
22 |
+
return file_put_contents($path, $this->toBuffer());
|
23 |
+
}
|
24 |
+
|
25 |
+
public function size() {
|
26 |
+
return intval($this->meta["content-length"]);
|
27 |
+
}
|
28 |
+
|
29 |
+
public function mediaType() {
|
30 |
+
return $this->meta["content-type"];
|
31 |
+
}
|
32 |
+
|
33 |
+
public function contentType() {
|
34 |
+
return $this->mediaType();
|
35 |
+
}
|
36 |
+
}
|
lib/TinyCompress/lib/Tinify/ResultMeta.php
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Tinify;
|
4 |
+
|
5 |
+
class ResultMeta {
|
6 |
+
protected $meta;
|
7 |
+
|
8 |
+
public function __construct($meta) {
|
9 |
+
$this->meta = $meta;
|
10 |
+
}
|
11 |
+
|
12 |
+
public function width() {
|
13 |
+
return intval($this->meta["image-width"]);
|
14 |
+
}
|
15 |
+
|
16 |
+
public function height() {
|
17 |
+
return intval($this->meta["image-height"]);
|
18 |
+
}
|
19 |
+
|
20 |
+
public function location() {
|
21 |
+
return isset($this->meta["location"]) ? $this->meta["location"] : null;
|
22 |
+
}
|
23 |
+
}
|
lib/TinyCompress/lib/Tinify/Source.php
ADDED
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Tinify;
|
4 |
+
|
5 |
+
class Source {
|
6 |
+
private $url, $commands;
|
7 |
+
|
8 |
+
public static function fromFile($path) {
|
9 |
+
return self::fromBuffer(file_get_contents($path));
|
10 |
+
}
|
11 |
+
|
12 |
+
public static function fromBuffer($string) {
|
13 |
+
$response = Tinify::getClient()->request("post", "/shrink", $string);
|
14 |
+
return new self($response["headers"]["location"]);
|
15 |
+
}
|
16 |
+
|
17 |
+
public static function fromUrl($url) {
|
18 |
+
$body = array("source" => array("url" => $url));
|
19 |
+
$response = Tinify::getClient()->request("post", "/shrink", $body);
|
20 |
+
return new self($response["headers"]["location"]);
|
21 |
+
}
|
22 |
+
|
23 |
+
public function __construct($url, $commands = array()) {
|
24 |
+
$this->url = $url;
|
25 |
+
$this->commands = $commands;
|
26 |
+
}
|
27 |
+
|
28 |
+
public function preserve() {
|
29 |
+
$options = $this->flatten(func_get_args());
|
30 |
+
$commands = array_merge($this->commands, array("preserve" => $options));
|
31 |
+
return new self($this->url, $commands);
|
32 |
+
}
|
33 |
+
|
34 |
+
public function resize($options) {
|
35 |
+
$commands = array_merge($this->commands, array("resize" => $options));
|
36 |
+
return new self($this->url, $commands);
|
37 |
+
}
|
38 |
+
|
39 |
+
public function store($options) {
|
40 |
+
$response = Tinify::getClient()->request("post", $this->url,
|
41 |
+
array_merge($this->commands, array("store" => $options)));
|
42 |
+
return new Result($response["headers"], $response["body"]);
|
43 |
+
}
|
44 |
+
|
45 |
+
public function result() {
|
46 |
+
$response = Tinify::getClient()->request("get", $this->url, $this->commands);
|
47 |
+
return new Result($response["headers"], $response["body"]);
|
48 |
+
}
|
49 |
+
|
50 |
+
public function toFile($path) {
|
51 |
+
return $this->result()->toFile($path);
|
52 |
+
}
|
53 |
+
|
54 |
+
public function toBuffer() {
|
55 |
+
return $this->result()->toBuffer();
|
56 |
+
}
|
57 |
+
|
58 |
+
private static function flatten($options) {
|
59 |
+
$flattened = array();
|
60 |
+
foreach ($options as $option) {
|
61 |
+
if (is_array($option)) {
|
62 |
+
$flattened = array_merge($flattened, $option);
|
63 |
+
} else {
|
64 |
+
array_push($flattened, $option);
|
65 |
+
}
|
66 |
+
}
|
67 |
+
return $flattened;
|
68 |
+
}
|
69 |
+
}
|
lib/TinyCompress/{cacert.pem → lib/data/cacert.pem}
RENAMED
@@ -1,7 +1,7 @@
|
|
1 |
##
|
2 |
## Bundle of CA Root Certificates
|
3 |
##
|
4 |
-
## Certificate data from Mozilla
|
5 |
##
|
6 |
## This is a bundle of X.509 certificates of public Certificate Authorities
|
7 |
## (CA). These were automatically extracted from Mozilla's root certificates
|
@@ -13,66 +13,11 @@
|
|
13 |
## an Apache+mod_ssl webserver for SSL client authentication.
|
14 |
## Just configure this file as the SSLCACertificateFile.
|
15 |
##
|
16 |
-
## Conversion done with mk-ca-bundle.pl
|
17 |
-
## SHA1:
|
18 |
##
|
19 |
|
20 |
|
21 |
-
GTE CyberTrust Global Root
|
22 |
-
==========================
|
23 |
-
-----BEGIN CERTIFICATE-----
|
24 |
-
MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUg
|
25 |
-
Q29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEG
|
26 |
-
A1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJvb3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEz
|
27 |
-
MjM1OTAwWjB1MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQL
|
28 |
-
Ex5HVEUgQ3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0
|
29 |
-
IEdsb2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrHiM3dFw4u
|
30 |
-
sJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTSr41tiGeA5u2ylc9yMcql
|
31 |
-
HHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X404Wqk2kmhXBIgD8SFcd5tB8FLztimQID
|
32 |
-
AQABMA0GCSqGSIb3DQEBBAUAA4GBAG3rGwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMW
|
33 |
-
M4ETCJ57NE7fQMh017l93PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OF
|
34 |
-
NMQkpw0PlZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/
|
35 |
-
-----END CERTIFICATE-----
|
36 |
-
|
37 |
-
Thawte Server CA
|
38 |
-
================
|
39 |
-
-----BEGIN CERTIFICATE-----
|
40 |
-
MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT
|
41 |
-
DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs
|
42 |
-
dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UE
|
43 |
-
AxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5j
|
44 |
-
b20wHhcNOTYwODAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNV
|
45 |
-
BAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29u
|
46 |
-
c3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcG
|
47 |
-
A1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0
|
48 |
-
ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl
|
49 |
-
/Kj0R1HahbUgdJSGHg91yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg7
|
50 |
-
1CcEJRCXL+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGjEzAR
|
51 |
-
MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG7oWDTSEwjsrZqG9J
|
52 |
-
GubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6eQNuozDJ0uW8NxuOzRAvZim+aKZuZ
|
53 |
-
GCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZqdq5snUb9kLy78fyGPmJvKP/iiMucEc=
|
54 |
-
-----END CERTIFICATE-----
|
55 |
-
|
56 |
-
Thawte Premium Server CA
|
57 |
-
========================
|
58 |
-
-----BEGIN CERTIFICATE-----
|
59 |
-
MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkExFTATBgNVBAgT
|
60 |
-
DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs
|
61 |
-
dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UE
|
62 |
-
AxMYVGhhd3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZl
|
63 |
-
ckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYT
|
64 |
-
AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU
|
65 |
-
VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2
|
66 |
-
aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3DQEJARYZ
|
67 |
-
cHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2
|
68 |
-
aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIh
|
69 |
-
Udib0GfQug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMRuHM/
|
70 |
-
qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQAm
|
71 |
-
SCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUIhfzJATj/Tb7yFkJD57taRvvBxhEf
|
72 |
-
8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JMpAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7t
|
73 |
-
UCemDaYj+bvLpgcUQg==
|
74 |
-
-----END CERTIFICATE-----
|
75 |
-
|
76 |
Equifax Secure CA
|
77 |
=================
|
78 |
-----BEGIN CERTIFICATE-----
|
@@ -93,25 +38,6 @@ BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95
|
|
93 |
70+sB3c4
|
94 |
-----END CERTIFICATE-----
|
95 |
|
96 |
-
Verisign Class 3 Public Primary Certification Authority - G2
|
97 |
-
============================================================
|
98 |
-
-----BEGIN CERTIFICATE-----
|
99 |
-
MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT
|
100 |
-
MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
|
101 |
-
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
|
102 |
-
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
|
103 |
-
dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT
|
104 |
-
MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
|
105 |
-
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
|
106 |
-
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
|
107 |
-
dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCO
|
108 |
-
FoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71
|
109 |
-
lSk8UOg013gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQAB
|
110 |
-
MA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01UbSuvDV1Ai2TT
|
111 |
-
1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7iF6YM40AIOw7n60RzKprxaZLvcRTD
|
112 |
-
Oaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpYoJ2daZH9
|
113 |
-
-----END CERTIFICATE-----
|
114 |
-
|
115 |
GlobalSign Root CA
|
116 |
==================
|
117 |
-----BEGIN CERTIFICATE-----
|
@@ -248,40 +174,6 @@ Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H
|
|
248 |
RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
|
249 |
-----END CERTIFICATE-----
|
250 |
|
251 |
-
Equifax Secure Global eBusiness CA
|
252 |
-
==================================
|
253 |
-
-----BEGIN CERTIFICATE-----
|
254 |
-
MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
|
255 |
-
RXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNp
|
256 |
-
bmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIwMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMx
|
257 |
-
HDAaBgNVBAoTE0VxdWlmYXggU2VjdXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEds
|
258 |
-
b2JhbCBlQnVzaW5lc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRV
|
259 |
-
PEnCUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc58O/gGzN
|
260 |
-
qfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/o5brhTMhHD4ePmBudpxn
|
261 |
-
hcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAHMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j
|
262 |
-
BBgwFoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hs
|
263 |
-
MA0GCSqGSIb3DQEBBAUAA4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okEN
|
264 |
-
I7SS+RkAZ70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv8qIY
|
265 |
-
NMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV
|
266 |
-
-----END CERTIFICATE-----
|
267 |
-
|
268 |
-
Equifax Secure eBusiness CA 1
|
269 |
-
=============================
|
270 |
-
-----BEGIN CERTIFICATE-----
|
271 |
-
MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
|
272 |
-
RXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENB
|
273 |
-
LTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQwMDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UE
|
274 |
-
ChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNz
|
275 |
-
IENBLTEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ
|
276 |
-
1MRoRvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBuWqDZQu4a
|
277 |
-
IZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKwEnv+j6YDAgMBAAGjZjBk
|
278 |
-
MBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEp4MlIR21kW
|
279 |
-
Nl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRKeDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQF
|
280 |
-
AAOBgQB1W6ibAxHm6VZMzfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5
|
281 |
-
lSE/9dR+WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN/Bf+
|
282 |
-
KpYrtWKmpj29f5JZzVoqgrI3eQ==
|
283 |
-
-----END CERTIFICATE-----
|
284 |
-
|
285 |
AddTrust Low-Value Services Root
|
286 |
================================
|
287 |
-----BEGIN CERTIFICATE-----
|
@@ -527,59 +419,6 @@ gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm
|
|
527 |
X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
|
528 |
-----END CERTIFICATE-----
|
529 |
|
530 |
-
America Online Root Certification Authority 1
|
531 |
-
=============================================
|
532 |
-
-----BEGIN CERTIFICATE-----
|
533 |
-
MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
|
534 |
-
QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp
|
535 |
-
Y2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkG
|
536 |
-
A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg
|
537 |
-
T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQAD
|
538 |
-
ggEPADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lkhsmj76CG
|
539 |
-
v2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym1BW32J/X3HGrfpq/m44z
|
540 |
-
DyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsWOqMFf6Dch9Wc/HKpoH145LcxVR5lu9Rh
|
541 |
-
sCFg7RAycsWSJR74kEoYeEfffjA3PlAb2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP
|
542 |
-
8c9GsEsPPt2IYriMqQkoO3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0T
|
543 |
-
AQH/BAUwAwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAUAK3Z
|
544 |
-
o/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQB8itEf
|
545 |
-
GDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkFZu90821fnZmv9ov761KyBZiibyrF
|
546 |
-
VL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAbLjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft
|
547 |
-
3OJvx8Fi8eNy1gTIdGcL+oiroQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43g
|
548 |
-
Kd8hdIaC2y+CMMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds
|
549 |
-
sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7
|
550 |
-
-----END CERTIFICATE-----
|
551 |
-
|
552 |
-
America Online Root Certification Authority 2
|
553 |
-
=============================================
|
554 |
-
-----BEGIN CERTIFICATE-----
|
555 |
-
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
-
QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp
|
557 |
-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
-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
-
T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQAD
|
560 |
-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
-
fHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFciKtZHgVdEglZTvYYUAQv8
|
562 |
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-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
-
+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzcccobGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXg
|
574 |
-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
-
zH1kUQ7rVyZ2OuMeIjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgO
|
576 |
-
ZtMADjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2FAjgQ5ANh
|
577 |
-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
-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
-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
|
580 |
-
cX/9XhmgD0uRuMRUvAawRY8mkaKO/qk=
|
581 |
-
-----END CERTIFICATE-----
|
582 |
-
|
583 |
Visa eCommerce Root
|
584 |
===================
|
585 |
-----BEGIN CERTIFICATE-----
|
@@ -1777,33 +1616,6 @@ JOzHdiEoZa5X6AeIdUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfk
|
|
1777 |
vQ==
|
1778 |
-----END CERTIFICATE-----
|
1779 |
|
1780 |
-
TC TrustCenter Class 3 CA II
|
1781 |
-
============================
|
1782 |
-
-----BEGIN CERTIFICATE-----
|
1783 |
-
MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC
|
1784 |
-
REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy
|
1785 |
-
IENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYw
|
1786 |
-
MTEyMTQ0MTU3WhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1
|
1787 |
-
c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UE
|
1788 |
-
AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
1789 |
-
AQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJWHt4bNwcwIi9v8Qbxq63W
|
1790 |
-
yKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+QVl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo
|
1791 |
-
6SI7dYnWRBpl8huXJh0obazovVkdKyT21oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZ
|
1792 |
-
uV3bOx4a+9P/FRQI2AlqukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk
|
1793 |
-
2ZyqBwi1Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1UdEwEB
|
1794 |
-
/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NXXAek0CSnwPIA1DCB
|
1795 |
-
7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90
|
1796 |
-
Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU
|
1797 |
-
cnVzdENlbnRlciUyMENsYXNzJTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i
|
1798 |
-
SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
|
1799 |
-
TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlNirTzwppVMXzE
|
1800 |
-
O2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8TtXqluJucsG7Kv5sbviRmEb8
|
1801 |
-
yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9
|
1802 |
-
IJqDnxrcOfHFcqMRA/07QlIp2+gB95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal
|
1803 |
-
092Y+tTmBvTwtiBjS+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc
|
1804 |
-
5A==
|
1805 |
-
-----END CERTIFICATE-----
|
1806 |
-
|
1807 |
TC TrustCenter Universal CA I
|
1808 |
=============================
|
1809 |
-----BEGIN CERTIFICATE-----
|
@@ -2421,28 +2233,6 @@ yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi
|
|
2421 |
LXpUq3DDfSJlgnCW
|
2422 |
-----END CERTIFICATE-----
|
2423 |
|
2424 |
-
E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi
|
2425 |
-
===================================================
|
2426 |
-
-----BEGIN CERTIFICATE-----
|
2427 |
-
MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG
|
2428 |
-
EwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxpZ2kgQS5TLjE8MDoGA1UEAxMz
|
2429 |
-
ZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3
|
2430 |
-
MDEwNDExMzI0OFoXDTE3MDEwNDExMzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0
|
2431 |
-
cm9uaWsgQmlsZ2kgR3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9u
|
2432 |
-
aWsgU2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
2433 |
-
AQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdUMZTe1RK6UxYC6lhj71vY
|
2434 |
-
8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlTL/jDj/6z/P2douNffb7tC+Bg62nsM+3Y
|
2435 |
-
jfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAI
|
2436 |
-
JjjcJRFHLfO6IxClv7wC90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk
|
2437 |
-
9Ok0oSy1c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/BAQD
|
2438 |
-
AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoEVtstxNulMA0GCSqG
|
2439 |
-
SIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLPqk/CaOv/gKlR6D1id4k9CnU58W5d
|
2440 |
-
F4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwq
|
2441 |
-
D2fK/A+JYZ1lpTzlvBNbCNvj/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4
|
2442 |
-
Vwpm+Vganf2XKWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq
|
2443 |
-
fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX
|
2444 |
-
-----END CERTIFICATE-----
|
2445 |
-
|
2446 |
GlobalSign Root CA - R3
|
2447 |
=======================
|
2448 |
-----BEGIN CERTIFICATE-----
|
@@ -3892,3 +3682,307 @@ ONFLAzkopR6RctR9q5czxNM+4Gm2KHmgCY0c0f9BckgG/Jou5yD5m6Leie2uPAmvylezkolwQOQv
|
|
3892 |
T8Jwg0DXJCxr5wkf09XHwQj02w47HAcLQxGEIYbpgNR12KvxAmLBsX5VYc8T1yaw15zLKYs4SgsO
|
3893 |
kI26oQ==
|
3894 |
-----END CERTIFICATE-----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
##
|
2 |
## Bundle of CA Root Certificates
|
3 |
##
|
4 |
+
## Certificate data from Mozilla as of: Wed Apr 22 03:12:04 2015
|
5 |
##
|
6 |
## This is a bundle of X.509 certificates of public Certificate Authorities
|
7 |
## (CA). These were automatically extracted from Mozilla's root certificates
|
13 |
## an Apache+mod_ssl webserver for SSL client authentication.
|
14 |
## Just configure this file as the SSLCACertificateFile.
|
15 |
##
|
16 |
+
## Conversion done with mk-ca-bundle.pl version 1.25.
|
17 |
+
## SHA1: ed3c0bbfb7912bcc00cd2033b0cb85c98d10559c
|
18 |
##
|
19 |
|
20 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
Equifax Secure CA
|
22 |
=================
|
23 |
-----BEGIN CERTIFICATE-----
|
38 |
70+sB3c4
|
39 |
-----END CERTIFICATE-----
|
40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
GlobalSign Root CA
|
42 |
==================
|
43 |
-----BEGIN CERTIFICATE-----
|
174 |
RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
|
175 |
-----END CERTIFICATE-----
|
176 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
177 |
AddTrust Low-Value Services Root
|
178 |
================================
|
179 |
-----BEGIN CERTIFICATE-----
|
419 |
X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
|
420 |
-----END CERTIFICATE-----
|
421 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
422 |
Visa eCommerce Root
|
423 |
===================
|
424 |
-----BEGIN CERTIFICATE-----
|
1616 |
vQ==
|
1617 |
-----END CERTIFICATE-----
|
1618 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1619 |
TC TrustCenter Universal CA I
|
1620 |
=============================
|
1621 |
-----BEGIN CERTIFICATE-----
|
2233 |
LXpUq3DDfSJlgnCW
|
2234 |
-----END CERTIFICATE-----
|
2235 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2236 |
GlobalSign Root CA - R3
|
2237 |
=======================
|
2238 |
-----BEGIN CERTIFICATE-----
|
3682 |
T8Jwg0DXJCxr5wkf09XHwQj02w47HAcLQxGEIYbpgNR12KvxAmLBsX5VYc8T1yaw15zLKYs4SgsO
|
3683 |
kI26oQ==
|
3684 |
-----END CERTIFICATE-----
|
3685 |
+
|
3686 |
+
COMODO RSA Certification Authority
|
3687 |
+
==================================
|
3688 |
+
-----BEGIN CERTIFICATE-----
|
3689 |
+
MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE
|
3690 |
+
BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG
|
3691 |
+
A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlv
|
3692 |
+
biBBdXRob3JpdHkwHhcNMTAwMTE5MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMC
|
3693 |
+
R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE
|
3694 |
+
ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBB
|
3695 |
+
dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0Rn
|
3696 |
+
dJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZ
|
3697 |
+
FGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+
|
3698 |
+
5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pG
|
3699 |
+
x8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z+pUX
|
3700 |
+
2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQL
|
3701 |
+
OvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3
|
3702 |
+
sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+C
|
3703 |
+
GCe01a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5
|
3704 |
+
WdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E
|
3705 |
+
FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w
|
3706 |
+
DQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvlwFTPoCWOAvn9sKIN9SCYPBMt
|
3707 |
+
rFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+
|
3708 |
+
nq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg
|
3709 |
+
tZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW
|
3710 |
+
sRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp
|
3711 |
+
pC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmckejkk9u+UJueBPSZI9FoJA
|
3712 |
+
zMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yLS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHq
|
3713 |
+
ZJx64SIDqZxubw5lT2yHh17zbqD5daWbQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk52
|
3714 |
+
7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I
|
3715 |
+
LaZRfyHBNVOFBkpdn627G190
|
3716 |
+
-----END CERTIFICATE-----
|
3717 |
+
|
3718 |
+
USERTrust RSA Certification Authority
|
3719 |
+
=====================================
|
3720 |
+
-----BEGIN CERTIFICATE-----
|
3721 |
+
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
|
3747 |
+
Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9
|
3748 |
+
-----END CERTIFICATE-----
|
3749 |
+
|
3750 |
+
USERTrust ECC Certification Authority
|
3751 |
+
=====================================
|
3752 |
+
-----BEGIN CERTIFICATE-----
|
3753 |
+
MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC
|
3754 |
+
VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
|
3755 |
+
aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv
|
3756 |
+
biBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC
|
3757 |
+
VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
|
3758 |
+
aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv
|
3759 |
+
biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2
|
3760 |
+
0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez
|
3761 |
+
nPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV
|
3762 |
+
HQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB
|
3763 |
+
HU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu
|
3764 |
+
9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
|
3765 |
+
-----END CERTIFICATE-----
|
3766 |
+
|
3767 |
+
GlobalSign ECC Root CA - R4
|
3768 |
+
===========================
|
3769 |
+
-----BEGIN CERTIFICATE-----
|
3770 |
+
MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEkMCIGA1UECxMb
|
3771 |
+
R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
|
3772 |
+
EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb
|
3773 |
+
R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
|
3774 |
+
EwpHbG9iYWxTaWduMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprl
|
3775 |
+
OQcJFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAwDgYDVR0P
|
3776 |
+
AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61FuOJAf/sKbvu+M8k8o4TV
|
3777 |
+
MAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGXkPoUVy0D7O48027KqGx2vKLeuwIgJ6iF
|
3778 |
+
JzWbVsaj8kfSt24bAgAXqmemFZHe+pTsewv4n4Q=
|
3779 |
+
-----END CERTIFICATE-----
|
3780 |
+
|
3781 |
+
GlobalSign ECC Root CA - R5
|
3782 |
+
===========================
|
3783 |
+
-----BEGIN CERTIFICATE-----
|
3784 |
+
MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb
|
3785 |
+
R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
|
3786 |
+
EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb
|
3787 |
+
R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
|
3788 |
+
EwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6
|
3789 |
+
SFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS
|
3790 |
+
h5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd
|
3791 |
+
BgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx
|
3792 |
+
uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7
|
3793 |
+
yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3
|
3794 |
+
-----END CERTIFICATE-----
|
3795 |
+
|
3796 |
+
Staat der Nederlanden Root CA - G3
|
3797 |
+
==================================
|
3798 |
+
-----BEGIN CERTIFICATE-----
|
3799 |
+
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
|
3824 |
+
-----END CERTIFICATE-----
|
3825 |
+
|
3826 |
+
Staat der Nederlanden EV Root CA
|
3827 |
+
================================
|
3828 |
+
-----BEGIN CERTIFICATE-----
|
3829 |
+
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
|
3853 |
+
eUN51q1veieQA6TqJIc/2b3Z6fJfUEkc7uzXLg==
|
3854 |
+
-----END CERTIFICATE-----
|
3855 |
+
|
3856 |
+
IdenTrust Commercial Root CA 1
|
3857 |
+
==============================
|
3858 |
+
-----BEGIN CERTIFICATE-----
|
3859 |
+
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
|
3883 |
+
cGzM7vRX+Bi6hG6H
|
3884 |
+
-----END CERTIFICATE-----
|
3885 |
+
|
3886 |
+
IdenTrust Public Sector Root CA 1
|
3887 |
+
=================================
|
3888 |
+
-----BEGIN CERTIFICATE-----
|
3889 |
+
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
|
3913 |
+
3Wl9af0AVqW3rLatt8o+Ae+c
|
3914 |
+
-----END CERTIFICATE-----
|
3915 |
+
|
3916 |
+
Entrust Root Certification Authority - G2
|
3917 |
+
=========================================
|
3918 |
+
-----BEGIN CERTIFICATE-----
|
3919 |
+
MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV
|
3920 |
+
BAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy
|
3921 |
+
bXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug
|
3922 |
+
b25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw
|
3923 |
+
HhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT
|
3924 |
+
DUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx
|
3925 |
+
OTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s
|
3926 |
+
eTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi
|
3927 |
+
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP
|
3928 |
+
/vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz
|
3929 |
+
HHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU
|
3930 |
+
s/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y
|
3931 |
+
TGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx
|
3932 |
+
AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6
|
3933 |
+
0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z
|
3934 |
+
iXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
|
3935 |
+
Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi
|
3936 |
+
nWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+
|
3937 |
+
vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO
|
3938 |
+
e4pIb4tF9g==
|
3939 |
+
-----END CERTIFICATE-----
|
3940 |
+
|
3941 |
+
Entrust Root Certification Authority - EC1
|
3942 |
+
==========================================
|
3943 |
+
-----BEGIN CERTIFICATE-----
|
3944 |
+
MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx
|
3945 |
+
FjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn
|
3946 |
+
YWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl
|
3947 |
+
ZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
|
3948 |
+
IC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw
|
3949 |
+
FAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs
|
3950 |
+
LXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg
|
3951 |
+
dXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt
|
3952 |
+
IEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy
|
3953 |
+
AsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef
|
3954 |
+
9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
|
3955 |
+
FLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h
|
3956 |
+
vxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8
|
3957 |
+
kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
|
3958 |
+
-----END CERTIFICATE-----
|
3959 |
+
|
3960 |
+
CFCA EV ROOT
|
3961 |
+
============
|
3962 |
+
-----BEGIN CERTIFICATE-----
|
3963 |
+
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
|
3988 |
+
-----END CERTIFICATE-----
|
lib/TinyCompress/phpunit.xml
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<phpunit bootstrap="test/helper.php" colors="true">
|
2 |
+
<testsuites>
|
3 |
+
<testsuite name="Tinify PHP Test Suite">
|
4 |
+
<directory suffix="Test.php">test</directory>
|
5 |
+
</testsuite>
|
6 |
+
</testsuites>
|
7 |
+
<filter>
|
8 |
+
<whitelist>
|
9 |
+
<directory>lib</directory>
|
10 |
+
</whitelist>
|
11 |
+
</filter>
|
12 |
+
</phpunit>
|
lib/TinyCompress/test/TinifyClientTest.php
ADDED
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use Tinify\CurlMock;
|
4 |
+
|
5 |
+
class TinifyClientTest extends TestCase {
|
6 |
+
public function testRequestWhenValidShouldIssueRequest() {
|
7 |
+
CurlMock::register("https://api.tinify.com/", array("status" => 200));
|
8 |
+
$client = new Tinify\Client("key");
|
9 |
+
$client->request("get", "/");
|
10 |
+
|
11 |
+
$this->assertSame("https://api.tinify.com/", CurlMock::last(CURLOPT_URL));
|
12 |
+
$this->assertSame("api:key", CurlMock::last(CURLOPT_USERPWD));
|
13 |
+
}
|
14 |
+
|
15 |
+
public function testRequestWhenValidShouldIssueRequestWithoutBodyWhenOptionsAreEmpty() {
|
16 |
+
CurlMock::register("https://api.tinify.com/", array("status" => 200));
|
17 |
+
$client = new Tinify\Client("key");
|
18 |
+
$client->request("get", "/", array());
|
19 |
+
|
20 |
+
$this->assertFalse(CurlMock::last_has(CURLOPT_POSTFIELDS));
|
21 |
+
}
|
22 |
+
|
23 |
+
public function testRequestWhenValidShouldIssueRequestWithoutContentTypeWhenOptionsAreEmpty() {
|
24 |
+
CurlMock::register("https://api.tinify.com/", array("status" => 200));
|
25 |
+
$client = new Tinify\Client("key");
|
26 |
+
$client->request("get", "/", array());
|
27 |
+
|
28 |
+
$this->assertSame(array(), CurlMock::last(CURLOPT_HTTPHEADER));
|
29 |
+
}
|
30 |
+
|
31 |
+
public function testRequestWhenValidShouldIssueRequestWithJSONBody() {
|
32 |
+
CurlMock::register("https://api.tinify.com/", array("status" => 200));
|
33 |
+
$client = new Tinify\Client("key");
|
34 |
+
$client->request("get", "/", array("hello" => "world"));
|
35 |
+
|
36 |
+
$this->assertSame(array("Content-Type: application/json"), CurlMock::last(CURLOPT_HTTPHEADER));
|
37 |
+
$this->assertSame('{"hello":"world"}', CurlMock::last(CURLOPT_POSTFIELDS));
|
38 |
+
}
|
39 |
+
|
40 |
+
public function testRequestWhenValidShouldIssueRequestWithUserAgent() {
|
41 |
+
CurlMock::register("https://api.tinify.com/", array("status" => 200));
|
42 |
+
$client = new Tinify\Client("key");
|
43 |
+
$client->request("get", "/");
|
44 |
+
|
45 |
+
$curl = curl_version();
|
46 |
+
$this->assertSame(Tinify\Client::userAgent(), CurlMock::last(CURLOPT_USERAGENT));
|
47 |
+
}
|
48 |
+
|
49 |
+
public function testRequestWhenValidShouldUpdateCompressionCount() {
|
50 |
+
CurlMock::register("https://api.tinify.com/", array(
|
51 |
+
"status" => 200, "headers" => array("Compression-Count" => "12")
|
52 |
+
));
|
53 |
+
$client = new Tinify\Client("key");
|
54 |
+
$client->request("get", "/");
|
55 |
+
|
56 |
+
$this->assertSame(12, Tinify\getCompressionCount());
|
57 |
+
}
|
58 |
+
|
59 |
+
public function testRequestWhenValidWithAppIdShouldIssueRequestWithUserAgent() {
|
60 |
+
CurlMock::register("https://api.tinify.com/", array("status" => 200));
|
61 |
+
$client = new Tinify\Client("key", "TestApp/0.1");
|
62 |
+
$client->request("get", "/");
|
63 |
+
|
64 |
+
$curl = curl_version();
|
65 |
+
$this->assertSame(Tinify\Client::userAgent() . " TestApp/0.1", CurlMock::last(CURLOPT_USERAGENT));
|
66 |
+
}
|
67 |
+
|
68 |
+
public function testRequestWithUnexpectedErrorShouldThrowConnectionException() {
|
69 |
+
CurlMock::register("https://api.tinify.com/", array(
|
70 |
+
"error" => "Failed!", "errno" => 2
|
71 |
+
));
|
72 |
+
$this->setExpectedException("Tinify\ConnectionException");
|
73 |
+
$client = new Tinify\Client("key");
|
74 |
+
$client->request("get", "/");
|
75 |
+
}
|
76 |
+
|
77 |
+
public function testRequestWithUnexpectedErrorShouldThrowExceptionWithMessage() {
|
78 |
+
CurlMock::register("https://api.tinify.com/", array(
|
79 |
+
"error" => "Failed!", "errno" => 2
|
80 |
+
));
|
81 |
+
$this->setExpectedExceptionRegExp("Tinify\ConnectionException",
|
82 |
+
"/Error while connecting: Failed! \(#2\)/");
|
83 |
+
$client = new Tinify\Client("key");
|
84 |
+
$client->request("get", "/");
|
85 |
+
}
|
86 |
+
|
87 |
+
public function testRequestWithCurlErrorShouldThrowConnectionError() {
|
88 |
+
CurlMock::register("https://api.tinify.com/", array(
|
89 |
+
"errno" => 0, "error" => "", "return" => null
|
90 |
+
));
|
91 |
+
$this->setExpectedException("Tinify\ConnectionException");
|
92 |
+
$client = new Tinify\Client("key");
|
93 |
+
$client->request("get", "/");
|
94 |
+
}
|
95 |
+
|
96 |
+
public function testRequestWithServerErrorShouldThrowServerException() {
|
97 |
+
CurlMock::register("https://api.tinify.com/", array(
|
98 |
+
"status" => 584, "body" => '{"error":"InternalServerError","message":"Oops!"}'
|
99 |
+
));
|
100 |
+
$this->setExpectedException("Tinify\ServerException");
|
101 |
+
$client = new Tinify\Client("key");
|
102 |
+
$client->request("get", "/");
|
103 |
+
}
|
104 |
+
|
105 |
+
public function testRequestWithServerErrorShouldThrowExceptionWithMessage() {
|
106 |
+
CurlMock::register("https://api.tinify.com/", array(
|
107 |
+
"status" => 584, "body" => '{"error":"InternalServerError","message":"Oops!"}'
|
108 |
+
));
|
109 |
+
$this->setExpectedExceptionRegExp("Tinify\ServerException",
|
110 |
+
"/Oops! \(HTTP 584\/InternalServerError\)/");
|
111 |
+
$client = new Tinify\Client("key");
|
112 |
+
$client->request("get", "/");
|
113 |
+
}
|
114 |
+
|
115 |
+
public function testRequestWithBadServerResponseShouldThrowServerException() {
|
116 |
+
CurlMock::register("https://api.tinify.com/", array(
|
117 |
+
"status" => 543, "body" => '<!-- this is not json -->'
|
118 |
+
));
|
119 |
+
$this->setExpectedException("Tinify\ServerException");
|
120 |
+
$client = new Tinify\Client("key");
|
121 |
+
$client->request("get", "/");
|
122 |
+
}
|
123 |
+
|
124 |
+
public function testRequestWithBadServerResponseShouldThrowExceptionWithMessage() {
|
125 |
+
CurlMock::register("https://api.tinify.com/", array(
|
126 |
+
"status" => 543, "body" => '<!-- this is not json -->'
|
127 |
+
));
|
128 |
+
if (PHP_VERSION_ID >= 50500) {
|
129 |
+
$this->setExpectedExceptionRegExp("Tinify\ServerException",
|
130 |
+
"/Error while parsing response: Syntax error \(#4\) \(HTTP 543\/ParseError\)/");
|
131 |
+
} else {
|
132 |
+
$this->setExpectedExceptionRegExp("Tinify\ServerException",
|
133 |
+
"/Error while parsing response: Error \(#4\) \(HTTP 543\/ParseError\)/");
|
134 |
+
}
|
135 |
+
$client = new Tinify\Client("key");
|
136 |
+
$client->request("get", "/");
|
137 |
+
}
|
138 |
+
|
139 |
+
public function testRequestWithClientErrorShouldThrowClientException() {
|
140 |
+
CurlMock::register("https://api.tinify.com/", array(
|
141 |
+
"status" => 492, "body" => '{"error":"BadRequest","message":"Oops!"}')
|
142 |
+
);
|
143 |
+
$this->setExpectedException("Tinify\ClientException");
|
144 |
+
$client = new Tinify\Client("key");
|
145 |
+
$client->request("get", "/");
|
146 |
+
}
|
147 |
+
|
148 |
+
public function testRequestWithClientErrorShouldThrowExceptionWithMessage() {
|
149 |
+
CurlMock::register("https://api.tinify.com/", array(
|
150 |
+
"status" => 492, "body" => '{"error":"BadRequest","message":"Oops!"}'
|
151 |
+
));
|
152 |
+
$this->setExpectedExceptionRegExp("Tinify\ClientException",
|
153 |
+
"/Oops! \(HTTP 492\/BadRequest\)/");
|
154 |
+
$client = new Tinify\Client("key");
|
155 |
+
$client->request("get", "/");
|
156 |
+
}
|
157 |
+
|
158 |
+
public function testRequestWithBadCredentialsShouldThrowAccountException() {
|
159 |
+
CurlMock::register("https://api.tinify.com/", array(
|
160 |
+
"status" => 401, "body" => '{"error":"Unauthorized","message":"Oops!"}'
|
161 |
+
));
|
162 |
+
$this->setExpectedException("Tinify\AccountException");
|
163 |
+
$client = new Tinify\Client("key");
|
164 |
+
$client->request("get", "/");
|
165 |
+
}
|
166 |
+
|
167 |
+
public function testRequestWithBadCredentialsShouldThrowExceptionWithMessage() {
|
168 |
+
CurlMock::register("https://api.tinify.com/", array(
|
169 |
+
"status" => 401, "body" => '{"error":"Unauthorized","message":"Oops!"}'
|
170 |
+
));
|
171 |
+
$this->setExpectedExceptionRegExp("Tinify\AccountException",
|
172 |
+
"/Oops! \(HTTP 401\/Unauthorized\)/");
|
173 |
+
$client = new Tinify\Client("key");
|
174 |
+
$client->request("get", "/");
|
175 |
+
}
|
176 |
+
}
|
lib/TinyCompress/test/TinifyResultMetaTest.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use Tinify\CurlMock;
|
4 |
+
|
5 |
+
class TinifyResultMetaTest extends TestCase {
|
6 |
+
public function testWithMetadataWidthShouldReturnImageWidth() {
|
7 |
+
$result = new Tinify\ResultMeta(array("image-width" => "100"));
|
8 |
+
$this->assertSame(100, $result->width());
|
9 |
+
}
|
10 |
+
|
11 |
+
public function testWithMetadataHeightShouldReturnImageHeight() {
|
12 |
+
$result = new Tinify\ResultMeta(array("image-height" => "60"));
|
13 |
+
$this->assertSame(60, $result->height());
|
14 |
+
}
|
15 |
+
|
16 |
+
public function testWithMetadataLocationShouldReturnImageLocation() {
|
17 |
+
$result = new Tinify\ResultMeta(array("location" => "https://example.com/image.png"));
|
18 |
+
$this->assertSame("https://example.com/image.png", $result->location());
|
19 |
+
}
|
20 |
+
}
|
lib/TinyCompress/test/TinifyResultTest.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use Tinify\CurlMock;
|
4 |
+
|
5 |
+
class TinifyResultTest extends TestCase {
|
6 |
+
public function testWithMetaAndDataWidthShouldReturnImageWidth() {
|
7 |
+
$result = new Tinify\Result(array("image-width" => "100"), "image data");
|
8 |
+
$this->assertSame(100, $result->width());
|
9 |
+
}
|
10 |
+
|
11 |
+
public function testWithMetaAndDataHeightShouldReturnImageHeight() {
|
12 |
+
$result = new Tinify\Result(array("image-height" => "60"), "image data");
|
13 |
+
$this->assertSame(60, $result->height());
|
14 |
+
}
|
15 |
+
|
16 |
+
public function testWithMetaAndDataLocationShouldReturnNull() {
|
17 |
+
$result = new Tinify\ResultMeta(array(), "image data");
|
18 |
+
$this->assertSame(null, $result->location());
|
19 |
+
}
|
20 |
+
|
21 |
+
public function testWithMetaAndDataSizeShouldReturnContentLength() {
|
22 |
+
$result = new Tinify\Result(array("content-length" => "450"), "image data");
|
23 |
+
$this->assertSame(450, $result->size());
|
24 |
+
}
|
25 |
+
|
26 |
+
public function testWithMetaAndDataContentTypeShouldReturnMimeType() {
|
27 |
+
$result = new Tinify\Result(array("content-type" => "image/png"), "image data");
|
28 |
+
$this->assertSame("image/png", $result->contentType());
|
29 |
+
}
|
30 |
+
|
31 |
+
public function testWithMetaAndDataToBufferShouldReturnImageData() {
|
32 |
+
$result = new Tinify\Result(array(), "image data");
|
33 |
+
$this->assertSame("image data", $result->toBuffer());
|
34 |
+
}
|
35 |
+
}
|
lib/TinyCompress/test/TinifySourceTest.php
ADDED
@@ -0,0 +1,314 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use Tinify\CurlMock;
|
4 |
+
|
5 |
+
class TinifySourceTest extends TestCase {
|
6 |
+
private $dummyFile;
|
7 |
+
|
8 |
+
public function setUp() {
|
9 |
+
parent::setUp();
|
10 |
+
$this->dummyFile = __DIR__ . "/examples/dummy.png";
|
11 |
+
}
|
12 |
+
|
13 |
+
public function testWithInvalidApiKeyFromFileShouldThrowAccountException() {
|
14 |
+
Tinify\setKey("invalid");
|
15 |
+
|
16 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
17 |
+
"status" => 401, "body" => '{"error":"Unauthorized","message":"Credentials are invalid"}'
|
18 |
+
));
|
19 |
+
|
20 |
+
$this->setExpectedException("Tinify\AccountException");
|
21 |
+
Tinify\Source::fromFile($this->dummyFile);
|
22 |
+
}
|
23 |
+
|
24 |
+
public function testWithInvalidApiKeyFromBufferShouldThrowAccountException() {
|
25 |
+
Tinify\setKey("invalid");
|
26 |
+
|
27 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
28 |
+
"status" => 401, "body" => '{"error":"Unauthorized","message":"Credentials are invalid"}'
|
29 |
+
));
|
30 |
+
|
31 |
+
$this->setExpectedException("Tinify\AccountException");
|
32 |
+
Tinify\Source::fromBuffer("png file");
|
33 |
+
}
|
34 |
+
|
35 |
+
public function testWithInvalidApiKeyFromUrlShouldThrowAccountException() {
|
36 |
+
Tinify\setKey("invalid");
|
37 |
+
|
38 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
39 |
+
"status" => 401, "body" => '{"error":"Unauthorized","message":"Credentials are invalid"}'
|
40 |
+
));
|
41 |
+
|
42 |
+
$this->setExpectedException("Tinify\AccountException");
|
43 |
+
Tinify\Source::fromUrl("http://example.com/test.jpg");
|
44 |
+
}
|
45 |
+
|
46 |
+
public function testWithValidApiKeyFromFileShouldReturnSource() {
|
47 |
+
Tinify\setKey("valid");
|
48 |
+
|
49 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
50 |
+
"status" => 201, "headers" => array("Location" => "https://api.tinify.com/some/location")
|
51 |
+
));
|
52 |
+
|
53 |
+
$this->assertInstanceOf("Tinify\Source", Tinify\Source::fromFile($this->dummyFile));
|
54 |
+
}
|
55 |
+
|
56 |
+
public function testWithValidApiKeyFromFileShouldReturnSourceWithData() {
|
57 |
+
Tinify\setKey("valid");
|
58 |
+
|
59 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
60 |
+
"status" => 201, "headers" => array("Location" => "https://api.tinify.com/some/location")
|
61 |
+
));
|
62 |
+
|
63 |
+
CurlMock::register("https://api.tinify.com/some/location", array(
|
64 |
+
"status" => 200, "body" => "compressed file"
|
65 |
+
));
|
66 |
+
|
67 |
+
$this->assertSame("compressed file", Tinify\Source::fromFile($this->dummyFile)->toBuffer());
|
68 |
+
}
|
69 |
+
|
70 |
+
public function testWithValidApiKeyFromBufferShouldReturnSource() {
|
71 |
+
Tinify\setKey("valid");
|
72 |
+
|
73 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
74 |
+
"status" => 201, "headers" => array("Location" => "https://api.tinify.com/some/location")
|
75 |
+
));
|
76 |
+
|
77 |
+
$this->assertInstanceOf("Tinify\Source", Tinify\Source::fromBuffer("png file"));
|
78 |
+
}
|
79 |
+
|
80 |
+
public function testWithValidApiKeyFromBufferShouldReturnSourceWithData() {
|
81 |
+
Tinify\setKey("valid");
|
82 |
+
|
83 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
84 |
+
"status" => 201, "headers" => array("Location" => "https://api.tinify.com/some/location")
|
85 |
+
));
|
86 |
+
|
87 |
+
CurlMock::register("https://api.tinify.com/some/location", array(
|
88 |
+
"status" => 200, "body" => "compressed file"
|
89 |
+
));
|
90 |
+
|
91 |
+
$this->assertSame("compressed file", Tinify\Source::fromBuffer("png file")->toBuffer());
|
92 |
+
}
|
93 |
+
|
94 |
+
public function testWithValidApiKeyFromUrlShouldReturnSource() {
|
95 |
+
Tinify\setKey("valid");
|
96 |
+
|
97 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
98 |
+
"status" => 201, "headers" => array("Location" => "https://api.tinify.com/some/location")
|
99 |
+
));
|
100 |
+
|
101 |
+
$this->assertInstanceOf("Tinify\Source", Tinify\Source::fromUrl("http://example.com/testWithValidApiKey.jpg"));
|
102 |
+
}
|
103 |
+
|
104 |
+
public function testWithValidApiKeyFromUrlShouldReturnSourceWithData() {
|
105 |
+
Tinify\setKey("valid");
|
106 |
+
|
107 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
108 |
+
"status" => 201, "headers" => array("Location" => "https://api.tinify.com/some/location")
|
109 |
+
));
|
110 |
+
|
111 |
+
CurlMock::register("https://api.tinify.com/some/location", array(
|
112 |
+
"status" => 200, "body" => "compressed file"
|
113 |
+
));
|
114 |
+
|
115 |
+
$this->assertSame("compressed file", Tinify\Source::fromUrl("http://example.com/testWithValidApiKey.jpg")->toBuffer());
|
116 |
+
}
|
117 |
+
|
118 |
+
public function testWithValidApiKeyFromUrlShouldThrowExceptionIfRequestIsNotOK() {
|
119 |
+
Tinify\setKey("valid");
|
120 |
+
|
121 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
122 |
+
"status" => 400, "body" => '{"error":"Source not found","message":"Cannot parse URL"}'
|
123 |
+
));
|
124 |
+
|
125 |
+
$this->setExpectedException("Tinify\ClientException");
|
126 |
+
Tinify\Source::fromUrl("file://wrong");
|
127 |
+
}
|
128 |
+
|
129 |
+
public function testWithValidApiKeyResultShouldReturnResult() {
|
130 |
+
Tinify\setKey("valid");
|
131 |
+
|
132 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
133 |
+
"status" => 201,
|
134 |
+
"headers" => array("Location" => "https://api.tinify.com/some/location"),
|
135 |
+
));
|
136 |
+
|
137 |
+
$this->assertInstanceOf("Tinify\Result", Tinify\Source::fromBuffer("png file")->result());
|
138 |
+
}
|
139 |
+
|
140 |
+
public function testWithValidApiKeyPreserveShouldReturnSource() {
|
141 |
+
Tinify\setKey("valid");
|
142 |
+
|
143 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
144 |
+
"status" => 201, "headers" => array("Location" => "https://api.tinify.com/some/location")
|
145 |
+
));
|
146 |
+
|
147 |
+
CurlMock::register("https://api.tinify.com/some/location", array(
|
148 |
+
"status" => 200, "body" => "copyrighted file"
|
149 |
+
));
|
150 |
+
|
151 |
+
$this->assertInstanceOf("Tinify\Source", Tinify\Source::fromBuffer("png file")->preserve("copyright", "location"));
|
152 |
+
$this->assertSame("png file", CurlMock::last(CURLOPT_POSTFIELDS));
|
153 |
+
}
|
154 |
+
|
155 |
+
public function testWithValidApiKeyPreserveShouldReturnSourceWithData() {
|
156 |
+
Tinify\setKey("valid");
|
157 |
+
|
158 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
159 |
+
"status" => 201, "headers" => array("Location" => "https://api.tinify.com/some/location")
|
160 |
+
));
|
161 |
+
|
162 |
+
CurlMock::register("https://api.tinify.com/some/location", array(
|
163 |
+
"status" => 200, "body" => "copyrighted file"
|
164 |
+
));
|
165 |
+
|
166 |
+
$this->assertSame("copyrighted file", Tinify\Source::fromBuffer("png file")->preserve("copyright", "location")->toBuffer());
|
167 |
+
$this->assertSame("{\"preserve\":[\"copyright\",\"location\"]}", CurlMock::last(CURLOPT_POSTFIELDS));
|
168 |
+
}
|
169 |
+
|
170 |
+
public function testWithValidApiKeyPreserveShouldReturnSourceWithDataForArray() {
|
171 |
+
Tinify\setKey("valid");
|
172 |
+
|
173 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
174 |
+
"status" => 201, "headers" => array("Location" => "https://api.tinify.com/some/location")
|
175 |
+
));
|
176 |
+
|
177 |
+
CurlMock::register("https://api.tinify.com/some/location", array(
|
178 |
+
"status" => 200, "body" => "copyrighted file"
|
179 |
+
));
|
180 |
+
|
181 |
+
$this->assertSame("copyrighted file", Tinify\Source::fromBuffer("png file")->preserve(array("copyright", "location"))->toBuffer());
|
182 |
+
$this->assertSame("{\"preserve\":[\"copyright\",\"location\"]}", CurlMock::last(CURLOPT_POSTFIELDS));
|
183 |
+
}
|
184 |
+
|
185 |
+
public function testWithValidApiKeyPreserveShouldIncludeOtherOptionsIfSet() {
|
186 |
+
Tinify\setKey("valid");
|
187 |
+
|
188 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
189 |
+
"status" => 201, "headers" => array("Location" => "https://api.tinify.com/some/location")
|
190 |
+
));
|
191 |
+
|
192 |
+
CurlMock::register("https://api.tinify.com/some/location", array(
|
193 |
+
"status" => 200, "body" => "copyrighted resized file"
|
194 |
+
));
|
195 |
+
|
196 |
+
$source = Tinify\Source::fromBuffer("png file")->resize(array("width" => 400))->preserve(array("copyright", "location"));
|
197 |
+
|
198 |
+
$this->assertSame("copyrighted resized file", $source->toBuffer());
|
199 |
+
$this->assertSame("{\"resize\":{\"width\":400},\"preserve\":[\"copyright\",\"location\"]}", CurlMock::last(CURLOPT_POSTFIELDS));
|
200 |
+
}
|
201 |
+
|
202 |
+
public function testWithValidApiKeyResizeShouldReturnSource() {
|
203 |
+
Tinify\setKey("valid");
|
204 |
+
|
205 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
206 |
+
"status" => 201, "headers" => array("Location" => "https://api.tinify.com/some/location")
|
207 |
+
));
|
208 |
+
|
209 |
+
CurlMock::register("https://api.tinify.com/some/location", array(
|
210 |
+
"status" => 200, "body" => "small file"
|
211 |
+
));
|
212 |
+
|
213 |
+
$this->assertInstanceOf("Tinify\Source", Tinify\Source::fromBuffer("png file")->resize(array("width" => 400)));
|
214 |
+
$this->assertSame("png file", CurlMock::last(CURLOPT_POSTFIELDS));
|
215 |
+
}
|
216 |
+
|
217 |
+
public function testWithValidApiKeyResizeShouldReturnSourceWithData() {
|
218 |
+
Tinify\setKey("valid");
|
219 |
+
|
220 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
221 |
+
"status" => 201, "headers" => array("Location" => "https://api.tinify.com/some/location")
|
222 |
+
));
|
223 |
+
|
224 |
+
CurlMock::register("https://api.tinify.com/some/location", array(
|
225 |
+
"status" => 200, "body" => "small file"
|
226 |
+
));
|
227 |
+
|
228 |
+
$this->assertSame("small file", Tinify\Source::fromBuffer("png file")->resize(array("width" => 400))->toBuffer());
|
229 |
+
$this->assertSame("{\"resize\":{\"width\":400}}", CurlMock::last(CURLOPT_POSTFIELDS));
|
230 |
+
}
|
231 |
+
|
232 |
+
public function testWithValidApiKeyStoreShouldReturnResultMeta() {
|
233 |
+
Tinify\setKey("valid");
|
234 |
+
|
235 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
236 |
+
"status" => 201,
|
237 |
+
"headers" => array("Location" => "https://api.tinify.com/some/location"),
|
238 |
+
));
|
239 |
+
|
240 |
+
CurlMock::register("https://api.tinify.com/some/location", array(
|
241 |
+
"body" => '{"store":{"service":"s3","aws_secret_access_key":"abcde"}}'
|
242 |
+
), array("status" => 200));
|
243 |
+
|
244 |
+
$options = array("service" => "s3", "aws_secret_access_key" => "abcde");
|
245 |
+
$this->assertInstanceOf("Tinify\Result", Tinify\Source::fromBuffer("png file")->store($options));
|
246 |
+
$this->assertSame("{\"store\":{\"service\":\"s3\",\"aws_secret_access_key\":\"abcde\"}}", CurlMock::last(CURLOPT_POSTFIELDS));
|
247 |
+
}
|
248 |
+
|
249 |
+
public function testWithValidApiKeyStoreShouldReturnResultMetaWithLocation() {
|
250 |
+
Tinify\setKey("valid");
|
251 |
+
|
252 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
253 |
+
"status" => 201,
|
254 |
+
"headers" => array("Location" => "https://api.tinify.com/some/location"),
|
255 |
+
));
|
256 |
+
|
257 |
+
CurlMock::register("https://api.tinify.com/some/location", array(
|
258 |
+
"body" => '{"store":{"service":"s3"}}'
|
259 |
+
), array(
|
260 |
+
"status" => 201,
|
261 |
+
"headers" => array("Location" => "https://bucket.s3.amazonaws.com/example"),
|
262 |
+
));
|
263 |
+
|
264 |
+
$location = Tinify\Source::fromBuffer("png file")->store(array("service" => "s3"))->location();
|
265 |
+
$this->assertSame("https://bucket.s3.amazonaws.com/example", $location);
|
266 |
+
$this->assertSame("{\"store\":{\"service\":\"s3\"}}", CurlMock::last(CURLOPT_POSTFIELDS));
|
267 |
+
}
|
268 |
+
|
269 |
+
public function testWithValidApiKeyStoreShouldIncludeOtherOptionsIfSet() {
|
270 |
+
Tinify\setKey("valid");
|
271 |
+
|
272 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
273 |
+
"status" => 201,
|
274 |
+
"headers" => array("Location" => "https://api.tinify.com/some/location"),
|
275 |
+
));
|
276 |
+
|
277 |
+
CurlMock::register("https://api.tinify.com/some/location", array(
|
278 |
+
"body" => '{"resize":{"width":300},"store":{"service":"s3","aws_secret_access_key":"abcde"}}'
|
279 |
+
), array("status" => 200));
|
280 |
+
|
281 |
+
$options = array("service" => "s3", "aws_secret_access_key" => "abcde");
|
282 |
+
$this->assertInstanceOf("Tinify\Result", Tinify\Source::fromBuffer("png file")->resize(array("width" => 300))->store($options));
|
283 |
+
$this->assertSame("{\"resize\":{\"width\":300},\"store\":{\"service\":\"s3\",\"aws_secret_access_key\":\"abcde\"}}", CurlMock::last(CURLOPT_POSTFIELDS));
|
284 |
+
}
|
285 |
+
|
286 |
+
public function testWithValidApiKeyToBufferShouldReturnImageData() {
|
287 |
+
Tinify\setKey("valid");
|
288 |
+
|
289 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
290 |
+
"status" => 201, "headers" => array("Location" => "https://api.tinify.com/some/location")
|
291 |
+
));
|
292 |
+
CurlMock::register("https://api.tinify.com/some/location", array(
|
293 |
+
"status" => 200, "body" => "compressed file"
|
294 |
+
));
|
295 |
+
|
296 |
+
$this->assertSame("compressed file", Tinify\Source::fromBuffer("png file")->toBuffer());
|
297 |
+
}
|
298 |
+
|
299 |
+
public function testWithValidApiKeyToFileShouldStoreImageData() {
|
300 |
+
Tinify\setKey("valid");
|
301 |
+
|
302 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
303 |
+
"status" => 201, "headers" => array("Location" => "https://api.tinify.com/some/location")
|
304 |
+
));
|
305 |
+
|
306 |
+
CurlMock::register("https://api.tinify.com/some/location", array(
|
307 |
+
"status" => 200, "body" => "compressed file"
|
308 |
+
));
|
309 |
+
|
310 |
+
$path = tempnam(sys_get_temp_dir(), "tinify-php");
|
311 |
+
Tinify\Source::fromBuffer("png file")->toFile($path);
|
312 |
+
$this->assertSame("compressed file", file_get_contents($path));
|
313 |
+
}
|
314 |
+
}
|
lib/TinyCompress/test/TinifyTest.php
ADDED
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use Tinify\CurlMock;
|
4 |
+
|
5 |
+
class ClientTest extends TestCase {
|
6 |
+
private $dummyFile;
|
7 |
+
|
8 |
+
public function setUp() {
|
9 |
+
parent::setUp();
|
10 |
+
$this->dummyFile = __DIR__ . "/examples/dummy.png";
|
11 |
+
}
|
12 |
+
|
13 |
+
public function testKeyShouldResetClientWithNewKey() {
|
14 |
+
CurlMock::register("https://api.tinify.com/", array("status" => 200));
|
15 |
+
Tinify\setKey("abcde");
|
16 |
+
Tinify\Tinify::getClient();
|
17 |
+
Tinify\setKey("fghij");
|
18 |
+
$client = Tinify\Tinify::getClient();
|
19 |
+
$client->request("get", "/");
|
20 |
+
|
21 |
+
$this->assertSame("api:fghij", CurlMock::last(CURLOPT_USERPWD));
|
22 |
+
}
|
23 |
+
|
24 |
+
public function testAppIdentifierShouldResetClientWithNewAppIdentifier() {
|
25 |
+
CurlMock::register("https://api.tinify.com/", array("status" => 200));
|
26 |
+
Tinify\setKey("abcde");
|
27 |
+
Tinify\setAppIdentifier("MyApp/1.0");
|
28 |
+
Tinify\Tinify::getClient();
|
29 |
+
Tinify\setAppIdentifier("MyApp/2.0");
|
30 |
+
$client = Tinify\Tinify::getClient();
|
31 |
+
$client->request("get", "/");
|
32 |
+
|
33 |
+
$this->assertSame(Tinify\Client::userAgent() . " MyApp/2.0", CurlMock::last(CURLOPT_USERAGENT));
|
34 |
+
}
|
35 |
+
|
36 |
+
public function testClientWithKeyShouldReturnClient() {
|
37 |
+
Tinify\setKey("abcde");
|
38 |
+
$this->assertInstanceOf("Tinify\Client", Tinify\Tinify::getClient());
|
39 |
+
}
|
40 |
+
|
41 |
+
public function testClientWithoutKeyShouldThrowException() {
|
42 |
+
$this->setExpectedException("Tinify\AccountException");
|
43 |
+
$this->assertInstanceOf("Tinify\Client", Tinify\Tinify::getClient());
|
44 |
+
}
|
45 |
+
|
46 |
+
public function testSetClientShouldReplaceClient() {
|
47 |
+
Tinify\setKey("abcde");
|
48 |
+
Tinify\Tinify::setClient("foo");
|
49 |
+
$this->assertSame("foo", Tinify\Tinify::getClient());
|
50 |
+
}
|
51 |
+
|
52 |
+
public function testValidateWithValidKeyShouldReturnTrue() {
|
53 |
+
Tinify\setKey("valid");
|
54 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
55 |
+
"status" => 400, "body" => '{"error":"Input missing","message":"No input"}'
|
56 |
+
));
|
57 |
+
$this->assertTrue(Tinify\validate());
|
58 |
+
}
|
59 |
+
|
60 |
+
public function testValidateWithLimitedKeyShouldReturnTrue() {
|
61 |
+
Tinify\setKey("invalid");
|
62 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
63 |
+
"status" => 429, "body" => '{"error":"Too many requests","message":"Your monthly limit has been exceeded"}'
|
64 |
+
));
|
65 |
+
$this->assertTrue(Tinify\validate());
|
66 |
+
}
|
67 |
+
|
68 |
+
public function testValidateWithErrorShouldThrowException() {
|
69 |
+
Tinify\setKey("invalid");
|
70 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
71 |
+
"status" => 401, "body" => '{"error":"Unauthorized","message":"Credentials are invalid"}'
|
72 |
+
));
|
73 |
+
$this->setExpectedException("Tinify\AccountException");
|
74 |
+
Tinify\validate();
|
75 |
+
}
|
76 |
+
|
77 |
+
public function testFromFileShouldReturnSource() {
|
78 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
79 |
+
"status" => 201, "headers" => array("Location" => "https://api.tinify.com/some/location")
|
80 |
+
));
|
81 |
+
Tinify\setKey("valid");
|
82 |
+
$this->assertInstanceOf("Tinify\Source", Tinify\fromFile($this->dummyFile));
|
83 |
+
}
|
84 |
+
|
85 |
+
public function testFromBufferShouldReturnSource() {
|
86 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
87 |
+
"status" => 201, "headers" => array("Location" => "https://api.tinify.com/some/location")
|
88 |
+
));
|
89 |
+
Tinify\setKey("valid");
|
90 |
+
$this->assertInstanceOf("Tinify\Source", Tinify\fromBuffer("png file"));
|
91 |
+
}
|
92 |
+
|
93 |
+
public function testFromUrlShouldReturnSource() {
|
94 |
+
CurlMock::register("https://api.tinify.com/shrink", array(
|
95 |
+
"status" => 201, "headers" => array("Location" => "https://api.tinify.com/some/location")
|
96 |
+
));
|
97 |
+
Tinify\setKey("valid");
|
98 |
+
$this->assertInstanceOf("Tinify\Source", Tinify\fromUrl("http://example.com/test.jpg"));
|
99 |
+
}
|
100 |
+
}
|
lib/TinyCompress/test/curl_mock.php
ADDED
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Tinify;
|
4 |
+
|
5 |
+
class CurlMockException extends Exception {
|
6 |
+
}
|
7 |
+
|
8 |
+
class CurlMock {
|
9 |
+
private static $urls = array();
|
10 |
+
private static $requests = array();
|
11 |
+
|
12 |
+
public $options = array();
|
13 |
+
public $response;
|
14 |
+
public $closed = false;
|
15 |
+
|
16 |
+
public static function register($url, $request, $response = NULL) {
|
17 |
+
if (!$response) {
|
18 |
+
$response = $request;
|
19 |
+
$request = NULL;
|
20 |
+
}
|
21 |
+
self::$urls[$url] = array($request, $response);
|
22 |
+
}
|
23 |
+
|
24 |
+
public static function reset() {
|
25 |
+
self::$requests = array();
|
26 |
+
}
|
27 |
+
|
28 |
+
public static function last_has($key) {
|
29 |
+
$lastReq = self::$requests[count(self::$requests) - 1];
|
30 |
+
return array_key_exists($key, $lastReq->options);
|
31 |
+
}
|
32 |
+
|
33 |
+
public static function last($key = null) {
|
34 |
+
$lastReq = self::$requests[count(self::$requests) - 1];
|
35 |
+
if ($key) {
|
36 |
+
return $lastReq->options[$key];
|
37 |
+
} else {
|
38 |
+
return $lastReq;
|
39 |
+
}
|
40 |
+
}
|
41 |
+
|
42 |
+
public function close() {
|
43 |
+
$this->closed = true;
|
44 |
+
}
|
45 |
+
|
46 |
+
public function exec() {
|
47 |
+
if ($this->closed) {
|
48 |
+
throw new CurlMockException("Curl already closed");
|
49 |
+
}
|
50 |
+
array_push(self::$requests, $this);
|
51 |
+
|
52 |
+
list($this->request, $this->response) = self::$urls[$this->options[CURLOPT_URL]];
|
53 |
+
if ($this->request) {
|
54 |
+
if ($this->request["body"]) {
|
55 |
+
if ($this->options[CURLOPT_POSTFIELDS] != $this->request["body"]) {
|
56 |
+
throw new Exception("Body '" . $this->options[CURLOPT_POSTFIELDS] .
|
57 |
+
"' does not match expected '" . $this->request["body"] . "'");
|
58 |
+
}
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
if (isset($this->response["headers"])) {
|
63 |
+
$headers = "";
|
64 |
+
foreach ($this->response["headers"] as $header => $value) {
|
65 |
+
$headers .= $header . ": " . $value . "\r\n";
|
66 |
+
}
|
67 |
+
$this->response["headers"] = $headers . "\r\n";
|
68 |
+
} else {
|
69 |
+
$this->response["headers"] = "\r\n";
|
70 |
+
}
|
71 |
+
|
72 |
+
if (!isset($this->response["body"])) {
|
73 |
+
$this->response["body"] = "";
|
74 |
+
}
|
75 |
+
|
76 |
+
if (array_key_exists("return", $this->response)) {
|
77 |
+
return $this->response["return"];
|
78 |
+
} else if (isset($this->response["status"])) {
|
79 |
+
return $this->response["headers"] . $this->response["body"];
|
80 |
+
} else {
|
81 |
+
return false;
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
public function setopt_array($array) {
|
86 |
+
if ($this->closed) {
|
87 |
+
throw new CurlMockException("Curl already closed");
|
88 |
+
}
|
89 |
+
foreach ($array as $key => $value) {
|
90 |
+
$this->options[$key] = $value;
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
public function setopt($key, $value) {
|
95 |
+
if ($this->closed) {
|
96 |
+
throw new CurlMockException("Curl already closed");
|
97 |
+
}
|
98 |
+
$this->options[$key] = $value;
|
99 |
+
}
|
100 |
+
|
101 |
+
public function getinfo($key) {
|
102 |
+
if ($this->closed) {
|
103 |
+
throw new CurlMockException("Curl already closed");
|
104 |
+
}
|
105 |
+
switch ($key) {
|
106 |
+
case CURLINFO_HTTP_CODE:
|
107 |
+
return isset($this->response["status"]) ? $this->response["status"] : 0;
|
108 |
+
case CURLINFO_HEADER_SIZE:
|
109 |
+
return strlen($this->response["headers"]);
|
110 |
+
default:
|
111 |
+
throw new Exception("Bad key $key");
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
public function error() {
|
116 |
+
if ($this->closed) {
|
117 |
+
throw new CurlMockException("Curl already closed");
|
118 |
+
}
|
119 |
+
return $this->response["error"];
|
120 |
+
}
|
121 |
+
|
122 |
+
public function errno() {
|
123 |
+
if ($this->closed) {
|
124 |
+
throw new CurlMockException("Curl already closed");
|
125 |
+
}
|
126 |
+
return $this->response["errno"];
|
127 |
+
}
|
128 |
+
}
|
129 |
+
|
130 |
+
function curl_init() {
|
131 |
+
return new CurlMock();
|
132 |
+
}
|
133 |
+
|
134 |
+
function curl_exec($mock) {
|
135 |
+
return $mock->exec();
|
136 |
+
}
|
137 |
+
|
138 |
+
function curl_close($mock) {
|
139 |
+
$mock->close();
|
140 |
+
}
|
141 |
+
|
142 |
+
function curl_setopt_array($mock, $array) {
|
143 |
+
return $mock->setopt_array($array);
|
144 |
+
}
|
145 |
+
|
146 |
+
function curl_setopt($mock, $key, $value) {
|
147 |
+
return $mock->setopt($key, $value);
|
148 |
+
}
|
149 |
+
|
150 |
+
function curl_getinfo($mock, $key) {
|
151 |
+
return $mock->getinfo($key);
|
152 |
+
}
|
153 |
+
|
154 |
+
function curl_error($mock) {
|
155 |
+
return $mock->error();
|
156 |
+
}
|
157 |
+
|
158 |
+
function curl_errno($mock) {
|
159 |
+
return $mock->errno();
|
160 |
+
}
|
lib/TinyCompress/test/examples/dummy.png
ADDED
File without changes
|
lib/TinyCompress/test/examples/voormedia.png
ADDED
Binary file
|
lib/TinyCompress/test/helper.php
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once("curl_mock.php");
|
4 |
+
require_once("vendor/autoload.php");
|
5 |
+
|
6 |
+
class TestCase extends \PHPUnit_Framework_TestCase {
|
7 |
+
function setUp() {
|
8 |
+
Tinify\setKey(NULL);
|
9 |
+
}
|
10 |
+
|
11 |
+
function tearDown() {
|
12 |
+
Tinify\CurlMock::reset();
|
13 |
+
}
|
14 |
+
}
|
lib/TinyCompress/test/integration.php
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if (!getenv("TINIFY_KEY")) {
|
4 |
+
exit("Set the TINIFY_KEY environment variable.\n");
|
5 |
+
}
|
6 |
+
|
7 |
+
class ClientIntegrationTest extends PHPUnit_Framework_TestCase {
|
8 |
+
static private $optimized;
|
9 |
+
|
10 |
+
static public function setUpBeforeClass() {
|
11 |
+
\Tinify\setKey(getenv("TINIFY_KEY"));
|
12 |
+
|
13 |
+
$unoptimizedPath = __DIR__ . "/examples/voormedia.png";
|
14 |
+
self::$optimized = \Tinify\fromFile($unoptimizedPath);
|
15 |
+
}
|
16 |
+
|
17 |
+
public function testShouldCompressFromFile() {
|
18 |
+
$path = tempnam(sys_get_temp_dir(), "tinify-php");
|
19 |
+
self::$optimized->toFile($path);
|
20 |
+
|
21 |
+
$size = filesize($path);
|
22 |
+
$contents = fread(fopen($path, "rb"), $size);
|
23 |
+
|
24 |
+
$this->assertGreaterThan(1000, $size);
|
25 |
+
$this->assertLessThan(1500, $size);
|
26 |
+
|
27 |
+
/* width == 137 */
|
28 |
+
$this->assertContains("\0\0\0\x89", $contents);
|
29 |
+
$this->assertNotContains("Copyright Voormedia", $contents);
|
30 |
+
}
|
31 |
+
|
32 |
+
public function testShouldCompressFromUrl() {
|
33 |
+
$path = tempnam(sys_get_temp_dir(), "tinify-php");
|
34 |
+
$source = \Tinify\fromUrl("https://raw.githubusercontent.com/tinify/tinify-php/master/test/examples/voormedia.png");
|
35 |
+
$source->toFile($path);
|
36 |
+
|
37 |
+
$size = filesize($path);
|
38 |
+
$contents = fread(fopen($path, "rb"), $size);
|
39 |
+
|
40 |
+
$this->assertGreaterThan(1000, $size);
|
41 |
+
$this->assertLessThan(1500, $size);
|
42 |
+
|
43 |
+
/* width == 137 */
|
44 |
+
$this->assertContains("\0\0\0\x89", $contents);
|
45 |
+
$this->assertNotContains("Copyright Voormedia", $contents);
|
46 |
+
}
|
47 |
+
|
48 |
+
public function testShouldResize() {
|
49 |
+
$path = tempnam(sys_get_temp_dir(), "tinify-php");
|
50 |
+
self::$optimized->resize(array("method" => "fit", "width" => 50, "height" => 20))->toFile($path);
|
51 |
+
|
52 |
+
$size = filesize($path);
|
53 |
+
$contents = fread(fopen($path, "rb"), $size);
|
54 |
+
|
55 |
+
$this->assertGreaterThan(500, $size);
|
56 |
+
$this->assertLessThan(1000, $size);
|
57 |
+
|
58 |
+
/* width == 50 */
|
59 |
+
$this->assertContains("\0\0\0\x32", $contents);
|
60 |
+
$this->assertNotContains("Copyright Voormedia", $contents);
|
61 |
+
}
|
62 |
+
|
63 |
+
public function testShouldPreserveMetadata() {
|
64 |
+
$path = tempnam(sys_get_temp_dir(), "tinify-php");
|
65 |
+
self::$optimized->preserve("copyright", "creation")->toFile($path);
|
66 |
+
|
67 |
+
$size = filesize($path);
|
68 |
+
$contents = fread(fopen($path, "rb"), $size);
|
69 |
+
|
70 |
+
$this->assertGreaterThan(1000, $size);
|
71 |
+
$this->assertLessThan(2000, $size);
|
72 |
+
|
73 |
+
/* width == 137 */
|
74 |
+
$this->assertContains("\0\0\0\x89", $contents);
|
75 |
+
$this->assertContains("Copyright Voormedia", $contents);
|
76 |
+
}
|
77 |
+
}
|
package.xml
CHANGED
@@ -1,20 +1,83 @@
|
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>Tiny_Compresss_Images</name>
|
4 |
-
<version>
|
5 |
<stability>stable</stability>
|
6 |
-
<license
|
7 |
<channel>community</channel>
|
8 |
<extends/>
|
9 |
-
<summary>
|
10 |
-
<description
|
11 |
-

|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
<compatible/>
|
19 |
-
<dependencies><required><php><min>5.
|
20 |
</package>
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>Tiny_Compresss_Images</name>
|
4 |
+
<version>2.0.0</version>
|
5 |
<stability>stable</stability>
|
6 |
+
<license>MIT License</license>
|
7 |
<channel>community</channel>
|
8 |
<extends/>
|
9 |
+
<summary>Compress JPEG & PNG images</summary>
|
10 |
+
<description># Compress JPEG & PNG images for Magento 1
|
11 |
+

|
12 |
+
Make your Magento 1 store faster by compressing your JPEG and PNG images.
|
13 |
+

|
14 |
+
This plugin automatically optimizes your images by integrating with the
|
15 |
+
popular image compression services TinyJPG and TinyPNG.
|
16 |
+

|
17 |
+
Learn more about TinyJPG and TinyPNG at https://tinypng.com/.
|
18 |
+

|
19 |
+
Do you use Magento 2? Install our Magento 2 plugin instead:
|
20 |
+
https://packagist.org/packages/tinify/magento2
|
21 |
+

|
22 |
+
## How doest it work?
|
23 |
+

|
24 |
+
When you view a product in your webshop, Magento creates different image sizes
|
25 |
+
in its cache folders. This extension will compress these images for you
|
26 |
+
automatically. Any image sizes that are exact duplicates of each other will
|
27 |
+
only be compressed once.
|
28 |
+

|
29 |
+
Your product images are uploaded to the TinyJPG or TinyPNG service and
|
30 |
+
analyzed to apply the best possible compression. Based on the content of the
|
31 |
+
image an optimal strategy is chosen. The result is sent back to your Magento
|
32 |
+
webshop and saved in your public media folder.
|
33 |
+

|
34 |
+
On average JPEG images are compressed by 40-60% and PNG images by 50-80%
|
35 |
+
without visible loss in quality. Your webshop will load faster for your
|
36 |
+
visitors, and you’ll save storage space and bandwidth!
|
37 |
+

|
38 |
+
## Getting started
|
39 |
+

|
40 |
+
Obtain your free API key from https://tinypng.com/developers. The first 500
|
41 |
+
compressions per month are completely free, no strings attached! As each
|
42 |
+
product will be shown in different sizes, between 50 and 100 products can be
|
43 |
+
uploaded to your Magento webshop and compressed for free. You can also change
|
44 |
+
which of types of image sizes should be compressed.
|
45 |
+

|
46 |
+
If you’re a heavy user, you can compress additional images for a small
|
47 |
+
additional fee per image by upgrading your account. You can keep track of the
|
48 |
+
amount of compressions in the Magento 1 configuration section.
|
49 |
+

|
50 |
+
## Installation
|
51 |
+

|
52 |
+
Copy the extension key from Magento Connect. Login on your webshop backend
|
53 |
+
and open *System -> Magento Connect -> Magento Connect Manager*.
|
54 |
+
Paste the extension key to install the extension.
|
55 |
+

|
56 |
+
After installation, go to *System -> Configuration -> Image Optimization*, and 
|
57 |
+
enter your TinyPNG API Key. Flush the images cache to start compressing.
|
58 |
+

|
59 |
+
## Contact us
|
60 |
+

|
61 |
+
Got questions or feedback? Let us know! Contact us at support@tinypng.com.
|
62 |
+

|
63 |
+
## Information for plugin contributors
|
64 |
+

|
65 |
+
* PHP 5.4 or newer.
|
66 |
+
* MySQL 5.4 or newer (integration tests).
|
67 |
+
* Magento 1.8.0.0 or newer.
|
68 |
+
* phpunit 4.8 or newer.
|
69 |
+

|
70 |
+
### Running the unit tests
|
71 |
+

|
72 |
+
From the .modman/Tiny_CompressImages directory:
|
73 |
+

|
74 |
+
phpunit</description>
|
75 |
+
<notes>==== 2.0.0 ====
|
76 |
+
Public release - Completely Rebuild code</notes>
|
77 |
+
<authors><author><name>Tiny</name><user>TinyPNG</user><email>support@tinypng.com</email></author></authors>
|
78 |
+
<date>2016-07-20</date>
|
79 |
+
<time>11:02:06</time>
|
80 |
+
<contents><target name="magecommunity"><dir name="Tiny"><dir name="CompressImages"><dir name="Block"><dir name="Adminhtml"><file name="ApiNotification.php" hash="6426312d49088e23b6ee1f627929adbb"/><dir name="System"><dir name="Config"><dir name="Form"><dir name="Field"><file name="AccountType.php" hash="380f33d6963230c46fab8e57866dc1f8"/><file name="Api.php" hash="8ceb591180cf579793f05924a043dc9c"/><file name="LogFile.php" hash="4e25c761671651b6553d562d3741dcd1"/><file name="LogStatus.php" hash="8146245e4a4a31d9e2286c933026cca4"/><file name="Radios.php" hash="4c7ece1b54c42297f6045b045fcb84e0"/><file name="Saved.php" hash="f0542c956a2a8679e1391c24dc3485ab"/><file name="Status.php" hash="3a6e9353a54936a98d7fbc63fc0ef3ed"/><file name="SupportTab.php" hash="d507bd32b83a8b14aaf52461d9b63f66"/></dir></dir><file name="Form.php" hash="6dcad3be2f0234a6afdb5a74fb4fe5fe"/></dir></dir></dir></dir><file name="Exception.php" hash="232327ae8c91c77b8ce4f2ea7e945b5d"/><dir name="Helper"><file name="Config.php" hash="b4f5af580d639c4c97eaa3dfb77a5f32"/><file name="Data.php" hash="c13a81a9520be131e7536a30541d0762"/><file name="Tinify.php" hash="1e7ff414f2624343728c6d970673cff7"/></dir><dir name="Model"><file name="Image.php" hash="0cb0d880bf82fa05777bd3742332726f"/><file name="Observer.php" hash="c8a474b20d0430cfd63d4feee5534261"/><dir name="Product"><file name="Image.php" hash="a2e4186d060aa9069fade4d4ebcc518e"/></dir><dir name="Resource"><dir name="Image"><file name="Collection.php" hash="d9d16df3b1b6440e3076251aa81f8780"/></dir><file name="Image.php" hash="2eb4265ecbf7458f804c62b61e80e734"/><file name="Setup.php" hash="e283458ac9c153678a3a6c719cdbfb91"/><dir name="Totals"><file name="Collection.php" hash="fdcdc1ca85ac337fab31252864eb941d"/></dir><file name="Totals.php" hash="70e729f767002c31faae7ded152eb911"/></dir><dir name="System"><dir name="Config"><dir name="Backend"><file name="ApiKey.php" hash="22499692a62df9ee8860e2df09e4bbd2"/><dir name="Comment"><file name="LoggingMode.php" hash="8d62d2a43629522bdd6acceb54016d74"/></dir></dir><dir name="Source"><dir name="Cms"><file name="ImageTypes.php" hash="f4ff83b2a25d152df5e425815a1b9ac7"/></dir><file name="Log.php" hash="fdfad3559c14ebab9f5990f489a78ce8"/><file name="OnOff.php" hash="460040d33b3a2522532b60673f749e57"/><dir name="Product"><file name="ImageTypes.php" hash="841b9ccd4f6bbe449074cfd5aadb0d70"/></dir><file name="Testlive.php" hash="d1cb53fdb8278202c04351c6e525aad3"/></dir></dir></dir><file name="Totals.php" hash="eee19b6e18ea8fa326ccd5957443281a"/></dir><dir name="Test"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Form"><dir name="Field"><file name="LogStatusTest.php" hash="4c89257172518a55e930d7f2f0683ae8"/></dir></dir></dir></dir></dir></dir><dir name="Framework"><dir name="Tiny"><dir name="Test"><file name="Config.php" hash="9220264aabacd8ca1f63b62a7527cad6"/><dir name="Http"><file name="Response.php" hash="a7c31bcd031b8ae7e895b1a48602fc62"/></dir><file name="TestCase.php" hash="32556035e6eb7d9d9a13187a3f33f911"/></dir></dir></dir><dir name="Helper"><file name="ConfigTest.php" hash="c361ed44073e7f03bbdf285a929e175c"/></dir><dir name="Model"><file name="ImageTest.php" hash="5567d1208225d1aa98814ce26c4a3c66"/><dir name="Product"><file name="ImageTest.php" hash="4552bc02eb244fd04f02b06f56e5474a"/></dir><dir name="System"><dir name="Config"><dir name="Backend"><dir name="Comment"><file name="LoggingModeTest.php" hash="99c46dc66ba10db9a5cf2ab1aa88904f"/></dir></dir></dir></dir></dir><file name="bootstrap.php" hash="29ef0d78bdb07399a148609f70ebe6de"/></dir><dir name="controllers"><dir name="CompressImagesAdminhtml"><file name="ConfigController.php" hash="4ded82dc68dae8e14eeaa60d66698c3d"/><file name="StatusController.php" hash="7e9eb303e31a28b75a6bf0af940b9866"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="61c1da0f235d4fb616fd0e2e5a6a78a7"/><file name="config.xml" hash="eecdde03b3be7c4ede1dfb12c1b125f4"/><file name="system.xml" hash="a34f6d2381366f5001a03a314e157c3c"/></dir><dir name="sql"><dir name="tiny_compressimages_setup"><file name="install-1.0.0.php" hash="333d08c5949c91ac6ae098e15c64054d"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Tiny_CompressImages.xml" hash="598a989aeda17423c8b9f9ab11c341bb"/></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><dir name="Tiny"><file name="CompressImages.xml" hash="63d02f84f40722cd69ddaa234900e811"/></dir></dir><dir name="template"><dir name="Tiny"><dir name="CompressImages"><dir name="Api"><file name="keyNotification.phtml" hash="f202d40d56e5657493de5edb67906504"/></dir><dir name="system"><dir name="config"><dir name="form"><dir name="field"><file name="log_file.phtml" hash="f6ad229ffe35bc1cdbc3a2ee58e05b88"/><file name="log_status.phtml" hash="c3539e506c59059b3ea9137585c78dd0"/><file name="support_tab.phtml" hash="82d7ee5b4a782dc9dcfabb0fa5b843ae"/></dir></dir></dir></dir></dir></dir></dir></dir></dir></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="css"><dir name="Tiny"><dir name="CompressImages"><file name="config.css" hash="61b1a856e391d6a3fffbd1703f11509e"/></dir></dir></dir><dir name="images"><dir name="Tiny"><dir name="CompressImages"><file name="george-magento@2x_opt.png" hash="13554407009301f1f62b212d67f5ae5e"/><file name="george-menu-icon@2x.png" hash="b1417eacc5320ad2741b8fd76ee60d56"/></dir></dir></dir></dir></dir></dir></target><target name="magelocale"><dir name="en_US"><file name="Tiny_CompressImages.csv" hash="a734673d17763c1334561e7e43d5f65f"/></dir></target><target name="magelib"><dir name="TinyCompress"><file name="LICENSE" hash="83cea2ac6da126d2dc6bcb26e740bac4"/><file name="README.md" hash="bd0c9f693fb84769a64c0b8721ecb394"/><file name="composer.json" hash="24129bff61e8cfa8b2a82efee5c7069a"/><file name="composer.lock" hash="faf46a8bba90ecc3a886f94f3cf922f4"/><dir name="lib"><dir name="Tinify"><file name="Client.php" hash="2c6d298a95c17762bf4e18a4b6343faa"/><file name="Exception.php" hash="ef195fc4ac81e45a7a52053d094da53f"/><file name="Result.php" hash="d6e0474e180cb17d0dc383ab974c0062"/><file name="ResultMeta.php" hash="4ec72ae5736f7fc91d7cb2b4bb55d3b9"/><file name="Source.php" hash="4c105bacaef6d6e69aa85da603c0378e"/></dir><file name="Tinify.php" hash="c3938730013e0a8237c3232b3ff8dc80"/><dir name="data"><file name="cacert.pem" hash="380df856e8f789c1af97d0da9a243769"/></dir></dir><file name="phpunit.xml" hash="73458f69fc3467a5d6ed3b1e5cd160cf"/><dir name="test"><file name="TinifyClientTest.php" hash="65160c2eed8aff5da38a0690575bfdfd"/><file name="TinifyResultMetaTest.php" hash="6c7e18d7ad946c7ac61a638cc92df8df"/><file name="TinifyResultTest.php" hash="0b574d4fd3b16d2cf7afb09a9f3e6e3a"/><file name="TinifySourceTest.php" hash="0db178b560fb4e59ec8ea31541ca3a98"/><file name="TinifyTest.php" hash="c018f154445101ec12fc0a5d493de09d"/><file name="curl_mock.php" hash="6b28a44ab36b3b53fcccbbad060fae05"/><dir name="examples"><file name="dummy.png" hash="d41d8cd98f00b204e9800998ecf8427e"/><file name="voormedia.png" hash="2824dd3c804309be2d275dbc2f16c788"/></dir><file name="helper.php" hash="7a7d4ddf6f771260cc74c8e18145a1bd"/><file name="integration.php" hash="43dbc9d7dc2f6b9be72c6a0d5036e9ce"/></dir><file name=".gitignore" hash="e8a346051f935e6cb104e1dc40998a91"/><file name=".travis.yml" hash="dbe91093178a614d31b4ac430659b81a"/></dir></target></contents>
|
81 |
<compatible/>
|
82 |
+
<dependencies><required><php><min>5.4.0</min><max>7.0.0</max></php></required></dependencies>
|
83 |
</package>
|
skin/adminhtml/default/default/css/Tiny/CompressImages/config.css
ADDED
@@ -0,0 +1,157 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* Default Magento Override */
|
2 |
+
|
3 |
+
.content-header h3 {
|
4 |
+
color:#253033;
|
5 |
+
}
|
6 |
+
|
7 |
+
/* Modus radios */
|
8 |
+
.wrapper-radio { margin-bottom: 3px; }
|
9 |
+
.wrapper-radio input { margin-right: 5px; }
|
10 |
+
#row_tiny_compressimages_status_usage .label { vertical-align: middle; }
|
11 |
+
.radio-container { display: inline-block; }
|
12 |
+
.radio-container + .field-tooltip { float:right; }
|
13 |
+
|
14 |
+
/* ======== Logo / Identity ======== */
|
15 |
+
|
16 |
+
/* logo in title bar */
|
17 |
+
#tiny_compressimages_support .content-heading { background: url('../../../images/Tiny/CompressImages/george-menu-icon@2x.png') no-repeat 0 0px !important;
|
18 |
+
background-size: auto 40px !important;
|
19 |
+
line-height: 40px;
|
20 |
+
padding-left: 50px;
|
21 |
+
padding-bottom: 5px;
|
22 |
+
}
|
23 |
+
|
24 |
+
/* logo in left column */
|
25 |
+
.tiny-compressimages-section { position: relative; line-height: 24px; }
|
26 |
+
.tiny-compressimages-section span { padding-left: 50px !important; }
|
27 |
+
.tiny-compressimages-section:after { content: '';
|
28 |
+
display: block;
|
29 |
+
position: absolute;
|
30 |
+
top: 3px;
|
31 |
+
left: 18px;
|
32 |
+
height: 40px;
|
33 |
+
width: 54px;
|
34 |
+
background: url('../../../images/Tiny/CompressImages/george-menu-icon@2x.png') no-repeat 0 0px !important;
|
35 |
+
background-size: auto 25px !important;
|
36 |
+
}
|
37 |
+
/* ======== Support Tab General ====== */
|
38 |
+
|
39 |
+
#tiny_compressimages_support { position :relative;}
|
40 |
+
#tiny_compressimages_support p,
|
41 |
+
#tiny_compressimages_support ul,
|
42 |
+
#tiny_compressimages_support ol { padding: 6px 0 10px 0; }
|
43 |
+
|
44 |
+
#tiny_compressimages_support ol { list-style: decimal inside; }
|
45 |
+
#tiny_compressimages_support ol ol { list-style: lower-alpha inside; padding: 0 0 10px 12px; }
|
46 |
+
#tiny_compressimages_support ul ul { list-style:none; padding: 0 0 10px 12px; }
|
47 |
+
#tiny_compressimages_support h2.content-heading { border-bottom: 4px solid #dfdfdf; }
|
48 |
+
#tiny_compressimages_support h2.content-heading .content-heading-logo { height: 24px; }
|
49 |
+
|
50 |
+
#tiny_compressimages_support h4,
|
51 |
+
#tiny_compressimages_support p { margin: 0; }
|
52 |
+
|
53 |
+
/* ======== Support Tab ====== */
|
54 |
+
|
55 |
+
.tiny-logo-bear {
|
56 |
+
position: absolute;
|
57 |
+
bottom: 0px;
|
58 |
+
right: 0;
|
59 |
+
width: auto;
|
60 |
+
max-width: 20%;
|
61 |
+
height: auto;
|
62 |
+
max-height: 180px; }
|
63 |
+
|
64 |
+
#tiny_compressimages_support a:hover { text-decoration:none; }
|
65 |
+
#tiny_compressimages_support img { max-width: 100%; }
|
66 |
+
|
67 |
+
#tiny_compressimages_support .col-set { float:left; width: 100%; }
|
68 |
+
#tiny_compressimages_support .col-set .col-1 { float:left; width: 75%; box-sizing:border-box; padding-right: 10px; }
|
69 |
+
#tiny_compressimages_support .col-set .col-2 { float:left; width: 25%; box-sizing:border-box; padding-left: 10px;}
|
70 |
+
|
71 |
+
#tiny_compressimages_support .tig_branding { float:left; width: 100%; }
|
72 |
+
#tiny_compressimages_support .tig_branding .image { float:left; width: 50px; margin-top: 3px; }
|
73 |
+
#tiny_compressimages_support .tig_branding .signature{ float:left; width: calc(100% - 50px); }
|
74 |
+
|
75 |
+
/* ======== Connection Settings ======== */
|
76 |
+
|
77 |
+
#compressimages_api_status { color: #009f3e;float: left; padding-bottom: 5px; clear: both; }
|
78 |
+
.compressimages-api-deactivated { color: #cc0000; }
|
79 |
+
|
80 |
+
.compressimages_status_success .indicator,
|
81 |
+
.compressimages_status_failure .indicator {
|
82 |
+
vertical-align: top;
|
83 |
+
display: inline-block;
|
84 |
+
margin-right: 3px;
|
85 |
+
}
|
86 |
+
|
87 |
+
.compressimages_status_failure { color: #cc0000; }
|
88 |
+
|
89 |
+
#row_tiny_compressimages_settings_api_key a:hover { text-decoration:none; }
|
90 |
+
#compressimages_check_status { margin-left: 0 !important; float:left; clear:both; }
|
91 |
+
|
92 |
+
/* ======== Image types to optimize ======== */
|
93 |
+
|
94 |
+
|
95 |
+
|
96 |
+
|
97 |
+
/* ======== Latest Optimizations ======== */
|
98 |
+
|
99 |
+
#tiny_compressimages_status tr td .scalable{ margin: 10px 0; }
|
100 |
+
|
101 |
+
#tiny_compressimages_compression { padding: 9px 0; }
|
102 |
+
#tiny_compressimages_compression td { padding-top:2px; padding-bottom:2px; margin:0; vertical-align:middle; overflow:hidden; }
|
103 |
+
#tiny_compressimages_compression tr.tiny_compressimages_log { border-bottom: 1px solid #ececec; width: 100%; }
|
104 |
+
|
105 |
+
#tiny_compressimages_compression .image_path { padding-left: 10px; }
|
106 |
+
|
107 |
+
#tiny_compressimages_compression .image_path img { display: inline-block; max-width: 30px; max-height: 30px; vertical-align: middle; border: 1px solid #d6d6d6; }
|
108 |
+
|
109 |
+
#tiny_compressimages_compression .info_box { padding: 0 0 0 20px; }
|
110 |
+
|
111 |
+
#tiny_compressimages_compression .centered td,
|
112 |
+
#tiny_compressimages_compression .show_less td,
|
113 |
+
#tiny_compressimages_compression .show_more td { text-align:center; }
|
114 |
+
|
115 |
+
.tiny_compressimages_width { box-sizing: border-box; min-width: 180px;}
|
116 |
+
.tiny_compressimages-no-images {padding: 0 0 10px 4px; font-weight: bold;}
|
117 |
+
.log-details-td {padding-left: 4px;}
|
118 |
+
|
119 |
+
.title-file { width: 45px; }
|
120 |
+
.title-original { width: 65px; }
|
121 |
+
.title-now { width: 50px; }
|
122 |
+
|
123 |
+
/* ======== Advanced options ======== */
|
124 |
+
|
125 |
+
|
126 |
+
|
127 |
+
|
128 |
+
|
129 |
+
|
130 |
+
|
131 |
+
|
132 |
+
|
133 |
+
|
134 |
+
|
135 |
+
|
136 |
+
|
137 |
+
|
138 |
+
|
139 |
+
|
140 |
+
|
141 |
+
|
142 |
+
|
143 |
+
|
144 |
+
|
145 |
+
|
146 |
+
|
147 |
+
|
148 |
+
|
149 |
+
|
150 |
+
|
151 |
+
|
152 |
+
|
153 |
+
|
154 |
+
|
155 |
+
|
156 |
+
|
157 |
+
|
skin/adminhtml/default/default/images/Tiny/CompressImages/george-magento@2x_opt.png
ADDED
Binary file
|
skin/adminhtml/default/default/images/Tiny/CompressImages/george-menu-icon@2x.png
ADDED
Binary file
|