Version Notes
No notes
Download this release
Release Info
| Developer | Yireo |
| Extension | Yireo_WebP |
| Version | 1.0.3 |
| Comparing to | |
| See all releases | |
Code changes from version 1.0.0 to 1.0.3
- app/code/community/Yireo/Webp/Block/Adminhtml/System/Config/Field/Gd.php +87 -0
- app/code/community/Yireo/Webp/Helper/Data.php +272 -57
- app/code/community/Yireo/Webp/Helper/File.php +99 -0
- app/code/community/Yireo/Webp/Lib/Io/File.php +25 -0
- app/code/community/Yireo/Webp/Model/Observer.php +192 -81
- app/code/community/Yireo/Webp/etc/config.xml +3 -1
- app/code/community/Yireo/Webp/etc/system.xml +27 -4
- package.xml +1 -1
app/code/community/Yireo/Webp/Block/Adminhtml/System/Config/Field/Gd.php
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Yireo Webp for Magento
|
| 4 |
+
*
|
| 5 |
+
* @package Yireo_Webp
|
| 6 |
+
* @author Yireo <info@yireo.com>
|
| 7 |
+
* @copyright 2015 Yireo <https://www.yireo.com/>
|
| 8 |
+
* @license Open Source License (OSL v3)
|
| 9 |
+
*/
|
| 10 |
+
|
| 11 |
+
/**
|
| 12 |
+
* Webp helper
|
| 13 |
+
*/
|
| 14 |
+
class Yireo_Webp_Block_Adminhtml_System_Config_Field_Gd extends Mage_Adminhtml_Block_System_Config_Form_Field
|
| 15 |
+
{
|
| 16 |
+
/**
|
| 17 |
+
* Override method to output our custom HTML with JavaScript
|
| 18 |
+
*
|
| 19 |
+
* @param Varien_Data_Form_Element_Abstract $element
|
| 20 |
+
* @return String
|
| 21 |
+
*/
|
| 22 |
+
protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
|
| 23 |
+
{
|
| 24 |
+
$html = parent::_getElementHtml($element);
|
| 25 |
+
|
| 26 |
+
$html .= $this->getCheckLine('GD support for WebP', $this->doesGdInfoIncludeWebp());
|
| 27 |
+
$html .= $this->getCheckLine('Function <code>imagewebp()</code> available', $this->doesImagewebpFunctionExist());
|
| 28 |
+
|
| 29 |
+
return $html;
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
/**
|
| 33 |
+
* @param $label
|
| 34 |
+
* @param $value
|
| 35 |
+
*
|
| 36 |
+
* @return string
|
| 37 |
+
*/
|
| 38 |
+
protected function getCheckLine($label, $value)
|
| 39 |
+
{
|
| 40 |
+
return '<p class="note">' . $label . ' = ' . $this->getCheckLabel($value) . '</p>';
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
/**
|
| 44 |
+
* @param $value
|
| 45 |
+
*
|
| 46 |
+
* @return string
|
| 47 |
+
*/
|
| 48 |
+
protected function getCheckLabel($value)
|
| 49 |
+
{
|
| 50 |
+
if ($value == true) {
|
| 51 |
+
return $this->__('Yes');
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
return $this->__('No');
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
/**
|
| 58 |
+
* @return bool
|
| 59 |
+
*/
|
| 60 |
+
protected function doesImagewebpFunctionExist()
|
| 61 |
+
{
|
| 62 |
+
if (function_exists('imagewebp')) {
|
| 63 |
+
return true;
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
return false;
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
/**
|
| 70 |
+
* @return bool
|
| 71 |
+
*/
|
| 72 |
+
protected function doesGdInfoIncludeWebp()
|
| 73 |
+
{
|
| 74 |
+
if (function_exists('gd_info') == false) {
|
| 75 |
+
return false;
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
$gdInfo = gd_info();
|
| 79 |
+
foreach ($gdInfo as $gdLabel => $gdValue) {
|
| 80 |
+
if (stristr($gdLabel, 'webp')) {
|
| 81 |
+
return (bool) $gdValue;
|
| 82 |
+
}
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
return false;
|
| 86 |
+
}
|
| 87 |
+
}
|
app/code/community/Yireo/Webp/Helper/Data.php
CHANGED
|
@@ -1,10 +1,10 @@
|
|
| 1 |
<?php
|
| 2 |
/**
|
| 3 |
-
* Yireo Webp for Magento
|
| 4 |
*
|
| 5 |
* @package Yireo_Webp
|
| 6 |
-
* @author Yireo
|
| 7 |
-
* @copyright
|
| 8 |
* @license Open Source License (OSL v3)
|
| 9 |
*/
|
| 10 |
|
|
@@ -13,140 +13,355 @@
|
|
| 13 |
*/
|
| 14 |
class Yireo_Webp_Helper_Data extends Mage_Core_Helper_Abstract
|
| 15 |
{
|
| 16 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
* Method to check whether this extension is enabled
|
|
|
|
|
|
|
| 18 |
*/
|
| 19 |
public function enabled()
|
| 20 |
{
|
| 21 |
-
$
|
| 22 |
-
if($config_enabled == false) {
|
| 23 |
return false;
|
| 24 |
}
|
| 25 |
|
| 26 |
-
if(
|
| 27 |
return true;
|
| 28 |
}
|
| 29 |
|
| 30 |
-
|
| 31 |
-
if(
|
| 32 |
return true;
|
| 33 |
}
|
| 34 |
|
| 35 |
// Check for GD support
|
| 36 |
-
if (
|
| 37 |
return true;
|
| 38 |
}
|
| 39 |
|
| 40 |
// Check for potential cwebp execution
|
| 41 |
-
|
| 42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
return true;
|
| 44 |
}
|
| 45 |
|
| 46 |
return false;
|
| 47 |
}
|
| 48 |
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
* Method to check whether WebP should actually be introduced
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
*/
|
| 52 |
public function allowWebp($image)
|
| 53 |
{
|
| 54 |
$enabled = $this->enabled();
|
| 55 |
-
if($enabled == false) {
|
| 56 |
return false;
|
| 57 |
}
|
| 58 |
|
| 59 |
-
if(empty($image)) {
|
| 60 |
return false;
|
| 61 |
}
|
| 62 |
|
| 63 |
-
|
|
|
|
| 64 |
return false;
|
| 65 |
}
|
| 66 |
|
| 67 |
-
if(
|
| 68 |
return false;
|
| 69 |
}
|
| 70 |
|
| 71 |
return false;
|
| 72 |
}
|
| 73 |
|
| 74 |
-
|
| 75 |
* Method to convert an image to WebP
|
|
|
|
|
|
|
|
|
|
|
|
|
| 76 |
*/
|
| 77 |
public function convertToWebp($imagePath)
|
| 78 |
{
|
| 79 |
-
if(empty($imagePath)
|
| 80 |
-
return;
|
| 81 |
}
|
| 82 |
|
| 83 |
-
if(
|
| 84 |
-
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
}
|
| 86 |
|
| 87 |
// Detect alpha-transparency in PNG-images and skip it
|
| 88 |
-
if(
|
| 89 |
-
|
| 90 |
-
$colorType = ord(@file_get_contents($image, NULL, NULL, 25, 1));
|
| 91 |
-
if($colorType == 6 || $colorType == 4) {
|
| 92 |
-
return;
|
| 93 |
-
} elseif(stripos($imageContents, 'PLTE') !== false && stripos($imageContents, 'tRNS') !== false) {
|
| 94 |
-
return;
|
| 95 |
-
}
|
| 96 |
}
|
| 97 |
|
| 98 |
// Construct the new WebP image-name
|
| 99 |
-
$webpPath =
|
| 100 |
|
| 101 |
// Check for the current WebP image
|
| 102 |
-
if(
|
| 103 |
return $webpPath;
|
| 104 |
}
|
| 105 |
|
| 106 |
// GD function
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
$image = imagecreatefrompng($imagePath);
|
| 110 |
-
} elseif(preg_match('/\.gif$/', $imagePath) && function_exists('imagecreatefromgif')) {
|
| 111 |
-
$image = imagecreatefromgif($imagePath);
|
| 112 |
-
} elseif(preg_match('/\.(jpg|jpeg)$/', $imagePath) && function_exists('imagecreatefromjpeg')) {
|
| 113 |
-
$image = imagecreatefromjpeg($imagePath);
|
| 114 |
-
} else {
|
| 115 |
-
return;
|
| 116 |
-
}
|
| 117 |
-
|
| 118 |
-
imagewebp($image, $webpPath);
|
| 119 |
return $webpPath;
|
| 120 |
}
|
| 121 |
|
| 122 |
// Only do the following if the WebP image does not yet exist, or if the original PNG/JPEG seems to be updated
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
}
|
| 129 |
|
| 130 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
}
|
| 132 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
public function getSystemPaths()
|
| 134 |
{
|
| 135 |
$systemPaths = array(
|
| 136 |
'skin' => array(
|
| 137 |
'url' => Mage::getBaseUrl('skin'),
|
| 138 |
-
'path' => Mage::getBaseDir('skin'),
|
| 139 |
-
),
|
| 140 |
'media' => array(
|
| 141 |
'url' => Mage::getBaseUrl('media'),
|
| 142 |
-
'path' => Mage::getBaseDir('media'),
|
| 143 |
-
),
|
| 144 |
'base' => array(
|
| 145 |
'url' => Mage::getBaseUrl(),
|
| 146 |
-
'path' => Mage::getBaseDir('base')
|
| 147 |
-
),
|
| 148 |
-
);
|
| 149 |
|
| 150 |
return $systemPaths;
|
| 151 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 152 |
}
|
| 1 |
<?php
|
| 2 |
/**
|
| 3 |
+
* Yireo Webp for Magento
|
| 4 |
*
|
| 5 |
* @package Yireo_Webp
|
| 6 |
+
* @author Yireo <info@yireo.com>
|
| 7 |
+
* @copyright 2015 Yireo <https://www.yireo.com/>
|
| 8 |
* @license Open Source License (OSL v3)
|
| 9 |
*/
|
| 10 |
|
| 13 |
*/
|
| 14 |
class Yireo_Webp_Helper_Data extends Mage_Core_Helper_Abstract
|
| 15 |
{
|
| 16 |
+
/**
|
| 17 |
+
* @var Yireo_Webp_Helper_File
|
| 18 |
+
*/
|
| 19 |
+
protected $fileHelper;
|
| 20 |
+
|
| 21 |
+
/**
|
| 22 |
+
* Constructor
|
| 23 |
+
*/
|
| 24 |
+
public function __construct()
|
| 25 |
+
{
|
| 26 |
+
$this->fileHelper = Mage::helper('webp/file');
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
/**
|
| 30 |
* Method to check whether this extension is enabled
|
| 31 |
+
*
|
| 32 |
+
* @return bool
|
| 33 |
*/
|
| 34 |
public function enabled()
|
| 35 |
{
|
| 36 |
+
if ($this->isModuleEnabled() == false) {
|
|
|
|
| 37 |
return false;
|
| 38 |
}
|
| 39 |
|
| 40 |
+
if ($this->hasWebpCookieEnabled()) {
|
| 41 |
return true;
|
| 42 |
}
|
| 43 |
|
| 44 |
+
/** @var Mage_Core_Helper_Http $httpHelper */
|
| 45 |
+
if ($this->isChromeBrowser()) {
|
| 46 |
return true;
|
| 47 |
}
|
| 48 |
|
| 49 |
// Check for GD support
|
| 50 |
+
if ($this->hasGdSupport()) {
|
| 51 |
return true;
|
| 52 |
}
|
| 53 |
|
| 54 |
// Check for potential cwebp execution
|
| 55 |
+
if ($this->hasBinarySupport()) {
|
| 56 |
+
return true;
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
return false;
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
/**
|
| 63 |
+
* @return bool
|
| 64 |
+
*/
|
| 65 |
+
protected function hasWebpCookieEnabled()
|
| 66 |
+
{
|
| 67 |
+
$webpCookie = (int)Mage::app()
|
| 68 |
+
->getRequest()
|
| 69 |
+
->getCookie('webp', 0);
|
| 70 |
+
|
| 71 |
+
if ($webpCookie == 1) {
|
| 72 |
+
return true;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
return false;
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
/**
|
| 79 |
+
* @return bool
|
| 80 |
+
*/
|
| 81 |
+
protected function hasBinarySupport()
|
| 82 |
+
{
|
| 83 |
+
if (Mage::getStoreConfig('web/webp/cwebp_enabled') == 0) {
|
| 84 |
+
return false;
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
$cwebp = $this->getCwebpBinary();
|
| 88 |
+
if (empty($cwebp)) {
|
| 89 |
+
return false;
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
if (function_exists('exec') == false) {
|
| 93 |
+
return false;
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
return true;
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
/**
|
| 100 |
+
* @return bool
|
| 101 |
+
*/
|
| 102 |
+
protected function hasGdSupport()
|
| 103 |
+
{
|
| 104 |
+
if (Mage::getStoreConfig('web/webp/gd_enabled') == 0) {
|
| 105 |
+
return false;
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
if (!function_exists('imagewebp')) {
|
| 109 |
+
return false;
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
return true;
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
/**
|
| 116 |
+
* @return bool
|
| 117 |
+
*/
|
| 118 |
+
protected function isChromeBrowser()
|
| 119 |
+
{
|
| 120 |
+
/** @var Mage_Core_Helper_Http $httpHelper */
|
| 121 |
+
$httpHelper = Mage::helper('core/http');
|
| 122 |
+
$browser = $httpHelper->getHttpUserAgent();
|
| 123 |
+
if (preg_match('/Chrome\/(9|10|11|12|13|14|15|16)/', $browser)) {
|
| 124 |
return true;
|
| 125 |
}
|
| 126 |
|
| 127 |
return false;
|
| 128 |
}
|
| 129 |
|
| 130 |
+
/**
|
| 131 |
+
* @return bool
|
| 132 |
+
*/
|
| 133 |
+
public function isModuleEnabled()
|
| 134 |
+
{
|
| 135 |
+
if ((bool)Mage::getStoreConfig('advanced/modules_disable_output/Yireo_WebP')) {
|
| 136 |
+
return false;
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
$config_enabled = (bool)Mage::getStoreConfig('web/webp/enabled');
|
| 140 |
+
if ($config_enabled == false) {
|
| 141 |
+
return false;
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
return true;
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
/**
|
| 148 |
* Method to check whether WebP should actually be introduced
|
| 149 |
+
*
|
| 150 |
+
* @param string $image
|
| 151 |
+
*
|
| 152 |
+
* @return bool
|
| 153 |
*/
|
| 154 |
public function allowWebp($image)
|
| 155 |
{
|
| 156 |
$enabled = $this->enabled();
|
| 157 |
+
if ($enabled == false) {
|
| 158 |
return false;
|
| 159 |
}
|
| 160 |
|
| 161 |
+
if (empty($image)) {
|
| 162 |
return false;
|
| 163 |
}
|
| 164 |
|
| 165 |
+
// The image already exists
|
| 166 |
+
if (preg_match('/\.webp$/i', $image)) {
|
| 167 |
return false;
|
| 168 |
}
|
| 169 |
|
| 170 |
+
if (!$this->fileHelper->isWritableDir($image)) {
|
| 171 |
return false;
|
| 172 |
}
|
| 173 |
|
| 174 |
return false;
|
| 175 |
}
|
| 176 |
|
| 177 |
+
/**
|
| 178 |
* Method to convert an image to WebP
|
| 179 |
+
*
|
| 180 |
+
* @param string $imagePath
|
| 181 |
+
*
|
| 182 |
+
* @return string
|
| 183 |
*/
|
| 184 |
public function convertToWebp($imagePath)
|
| 185 |
{
|
| 186 |
+
if (empty($imagePath)) {
|
| 187 |
+
return false;
|
| 188 |
}
|
| 189 |
|
| 190 |
+
if (!$this->fileHelper->exists($imagePath)) {
|
| 191 |
+
return false;
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
if ($this->enabled() == false) {
|
| 195 |
+
return false;
|
| 196 |
}
|
| 197 |
|
| 198 |
// Detect alpha-transparency in PNG-images and skip it
|
| 199 |
+
if ($this->hasAlphaTransparency($imagePath)) {
|
| 200 |
+
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 201 |
}
|
| 202 |
|
| 203 |
// Construct the new WebP image-name
|
| 204 |
+
$webpPath = $this->getWebpNameFromImage($imagePath);
|
| 205 |
|
| 206 |
// Check for the current WebP image
|
| 207 |
+
if ($this->fileHelper->exists($webpPath) && $this->fileHelper->isNewerThan($webpPath, $imagePath)) {
|
| 208 |
return $webpPath;
|
| 209 |
}
|
| 210 |
|
| 211 |
// GD function
|
| 212 |
+
$webpPath = $this->convertToWebpViaGd($imagePath, $webpPath);
|
| 213 |
+
if ($this->fileHelper->exists($webpPath)) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 214 |
return $webpPath;
|
| 215 |
}
|
| 216 |
|
| 217 |
// Only do the following if the WebP image does not yet exist, or if the original PNG/JPEG seems to be updated
|
| 218 |
+
return $this->convertToWebpViaBinary($imagePath, $webpPath);
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
/**
|
| 222 |
+
* Method to convert an image to WebP using the GD method
|
| 223 |
+
*
|
| 224 |
+
* @param $imagePath
|
| 225 |
+
* @param $webpPath
|
| 226 |
+
*
|
| 227 |
+
* @return bool
|
| 228 |
+
*/
|
| 229 |
+
public function convertToWebpViaGd($imagePath, $webpPath)
|
| 230 |
+
{
|
| 231 |
+
if ($this->hasGdSupport() == false) {
|
| 232 |
+
return false;
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
if (preg_match('/\.png$/', $imagePath) && function_exists('imagecreatefrompng')) {
|
| 236 |
+
$image = imagecreatefrompng($imagePath);
|
| 237 |
+
} elseif (preg_match('/\.gif$/', $imagePath) && function_exists('imagecreatefromgif')) {
|
| 238 |
+
$image = imagecreatefromgif($imagePath);
|
| 239 |
+
} elseif (preg_match('/\.(jpg|jpeg)$/', $imagePath) && function_exists('imagecreatefromjpeg')) {
|
| 240 |
+
$image = imagecreatefromjpeg($imagePath);
|
| 241 |
+
} else {
|
| 242 |
+
return false;
|
| 243 |
+
}
|
| 244 |
+
|
| 245 |
+
imagewebp($image, $webpPath);
|
| 246 |
+
|
| 247 |
+
return $webpPath;
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
+
/**
|
| 251 |
+
* Method to convert an image to WebP using the binary method
|
| 252 |
+
*
|
| 253 |
+
* @param $imagePath
|
| 254 |
+
* @param $webpPath
|
| 255 |
+
*
|
| 256 |
+
* @return bool
|
| 257 |
+
*/
|
| 258 |
+
public function convertToWebpViaBinary($imagePath, $webpPath)
|
| 259 |
+
{
|
| 260 |
+
if ($this->hasBinarySupport() == false) {
|
| 261 |
+
return false;
|
| 262 |
}
|
| 263 |
|
| 264 |
+
$cwebp = $this->getCwebpBinary();
|
| 265 |
+
$cmd = $cwebp . ' -quiet ' . $imagePath . ' -o ' . $webpPath;
|
| 266 |
+
exec($cmd, $output, $return);
|
| 267 |
+
|
| 268 |
+
return $webpPath;
|
| 269 |
}
|
| 270 |
|
| 271 |
+
/**
|
| 272 |
+
* Detect whether an image has PNG alpha transparency
|
| 273 |
+
*
|
| 274 |
+
* @param $image
|
| 275 |
+
*
|
| 276 |
+
* @return bool
|
| 277 |
+
*/
|
| 278 |
+
public function hasAlphaTransparency($image)
|
| 279 |
+
{
|
| 280 |
+
if (empty($image)) {
|
| 281 |
+
return false;
|
| 282 |
+
}
|
| 283 |
+
|
| 284 |
+
if ($this->fileHelper->exists($image) == false) {
|
| 285 |
+
return false;
|
| 286 |
+
}
|
| 287 |
+
|
| 288 |
+
if (preg_match('/\.png$/', $image)) {
|
| 289 |
+
return false;
|
| 290 |
+
}
|
| 291 |
+
|
| 292 |
+
$fileIo = new Yireo_Webp_Lib_Io_File();
|
| 293 |
+
$fileIo->setCwd(dirname($image));
|
| 294 |
+
$fileIo->setIwd(dirname($image));
|
| 295 |
+
|
| 296 |
+
$imageContents = $fileIo->read($image);
|
| 297 |
+
$colorType = ord(substr($imageContents, 25, 1));
|
| 298 |
+
|
| 299 |
+
if ($colorType == 6 || $colorType == 4) {
|
| 300 |
+
return true;
|
| 301 |
+
} elseif (stripos($imageContents, 'PLTE') !== false && stripos($imageContents, 'tRNS') !== false) {
|
| 302 |
+
return true;
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
+
return false;
|
| 306 |
+
}
|
| 307 |
+
|
| 308 |
+
/**
|
| 309 |
+
* Get the WebP path equivalent of an image path
|
| 310 |
+
*
|
| 311 |
+
* @param $image
|
| 312 |
+
*
|
| 313 |
+
* @return mixed
|
| 314 |
+
*/
|
| 315 |
+
public function getWebpNameFromImage($image)
|
| 316 |
+
{
|
| 317 |
+
return preg_replace('/\.(png|jpg|jpeg)$/i', '.webp', $image);
|
| 318 |
+
}
|
| 319 |
+
|
| 320 |
+
/**
|
| 321 |
+
* Return all the system paths
|
| 322 |
+
*
|
| 323 |
+
* @return array
|
| 324 |
+
*/
|
| 325 |
public function getSystemPaths()
|
| 326 |
{
|
| 327 |
$systemPaths = array(
|
| 328 |
'skin' => array(
|
| 329 |
'url' => Mage::getBaseUrl('skin'),
|
| 330 |
+
'path' => Mage::getBaseDir('skin').DS),
|
|
|
|
| 331 |
'media' => array(
|
| 332 |
'url' => Mage::getBaseUrl('media'),
|
| 333 |
+
'path' => Mage::getBaseDir('media').DS),
|
|
|
|
| 334 |
'base' => array(
|
| 335 |
'url' => Mage::getBaseUrl(),
|
| 336 |
+
'path' => Mage::getBaseDir('base').DS));
|
|
|
|
|
|
|
| 337 |
|
| 338 |
return $systemPaths;
|
| 339 |
}
|
| 340 |
+
|
| 341 |
+
/**
|
| 342 |
+
* Get the path to the "cwebp" binary
|
| 343 |
+
*
|
| 344 |
+
* @return string
|
| 345 |
+
*/
|
| 346 |
+
public function getCwebpBinary()
|
| 347 |
+
{
|
| 348 |
+
$cwebp = $this->getCwebpPath();
|
| 349 |
+
if (empty($cwebp)) {
|
| 350 |
+
return null;
|
| 351 |
+
}
|
| 352 |
+
|
| 353 |
+
if (preg_match('/\/$/', $cwebp)) {
|
| 354 |
+
return $cwebp . 'cwebp';
|
| 355 |
+
}
|
| 356 |
+
|
| 357 |
+
return $cwebp;
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
/**
|
| 361 |
+
* @return mixed
|
| 362 |
+
*/
|
| 363 |
+
protected function getCwebpPath()
|
| 364 |
+
{
|
| 365 |
+
return Mage::getStoreConfig('web/webp/cwebp_path');
|
| 366 |
+
}
|
| 367 |
}
|
app/code/community/Yireo/Webp/Helper/File.php
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Yireo Webp for Magento
|
| 4 |
+
*
|
| 5 |
+
* @package Yireo_Webp
|
| 6 |
+
* @author Yireo <info@yireo.com>
|
| 7 |
+
* @copyright 2015 Yireo <https://www.yireo.com/>
|
| 8 |
+
* @license Open Source License (OSL v3)
|
| 9 |
+
*/
|
| 10 |
+
|
| 11 |
+
/**
|
| 12 |
+
* Webp file helper
|
| 13 |
+
*/
|
| 14 |
+
class Yireo_Webp_Helper_File extends Mage_Core_Helper_Abstract
|
| 15 |
+
{
|
| 16 |
+
/**
|
| 17 |
+
* Method to check to see if a file exists or not
|
| 18 |
+
*
|
| 19 |
+
* @param string $file
|
| 20 |
+
* @return bool
|
| 21 |
+
*/
|
| 22 |
+
public function exists($file)
|
| 23 |
+
{
|
| 24 |
+
if (file_exists($file)) {
|
| 25 |
+
return true;
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
$validator = new Zend_Validate_File_Exists();
|
| 29 |
+
|
| 30 |
+
if ($validator->isValid($file) == true) {
|
| 31 |
+
return true;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
return false;
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
/**
|
| 38 |
+
* Method to check to see if a file is writable or not
|
| 39 |
+
*
|
| 40 |
+
* @param $file
|
| 41 |
+
*
|
| 42 |
+
* @return bool
|
| 43 |
+
*/
|
| 44 |
+
public function isWritable($file)
|
| 45 |
+
{
|
| 46 |
+
$fileIo = new Varien_Io_File;
|
| 47 |
+
|
| 48 |
+
return $fileIo->isWriteable($file);
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
/**
|
| 52 |
+
* Method to check to see if a file is writable or not
|
| 53 |
+
*
|
| 54 |
+
* @param $file
|
| 55 |
+
*
|
| 56 |
+
* @return bool
|
| 57 |
+
*/
|
| 58 |
+
public function isWritableDir($file)
|
| 59 |
+
{
|
| 60 |
+
$fileIo = new Varien_Io_File;
|
| 61 |
+
$fileHandler = new Varien_File_Object($file);
|
| 62 |
+
|
| 63 |
+
return $fileIo->isWriteable($fileHandler->getDirName());
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
/**
|
| 67 |
+
* Method to return the modification time of a file
|
| 68 |
+
*
|
| 69 |
+
* @param $file
|
| 70 |
+
*
|
| 71 |
+
* @return int
|
| 72 |
+
*/
|
| 73 |
+
public function getModificationTime($file)
|
| 74 |
+
{
|
| 75 |
+
$fileHandler = new Varien_File_Object($file);
|
| 76 |
+
|
| 77 |
+
return $fileHandler->getCTime();
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
/**
|
| 81 |
+
* Method to check if a $file1 is newer than a $file2
|
| 82 |
+
*
|
| 83 |
+
* @param $file1
|
| 84 |
+
* @param $file2
|
| 85 |
+
*
|
| 86 |
+
* @return bool
|
| 87 |
+
*/
|
| 88 |
+
public function isNewerThan($file1, $file2)
|
| 89 |
+
{
|
| 90 |
+
$file1ModificationTime = $this->getModificationTime($file1);
|
| 91 |
+
$file2ModificationTime = $this->getModificationTime($file2);
|
| 92 |
+
|
| 93 |
+
if($file1ModificationTime > $file2ModificationTime) {
|
| 94 |
+
return true;
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
return false;
|
| 98 |
+
}
|
| 99 |
+
}
|
app/code/community/Yireo/Webp/Lib/Io/File.php
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
/**
|
| 3 |
+
* Yireo Webp for Magento
|
| 4 |
+
*
|
| 5 |
+
* @package Yireo_Webp
|
| 6 |
+
* @author Yireo <info@yireo.com>
|
| 7 |
+
* @copyright 2015 Yireo <https://www.yireo.com/>
|
| 8 |
+
* @license Open Source License (OSL v3)
|
| 9 |
+
*/
|
| 10 |
+
|
| 11 |
+
/**
|
| 12 |
+
* Webp helper
|
| 13 |
+
*/
|
| 14 |
+
class Yireo_Webp_Lib_Io_File extends Varien_Io_File
|
| 15 |
+
{
|
| 16 |
+
public function setIwd($iwd)
|
| 17 |
+
{
|
| 18 |
+
$this->_iwd = $iwd;
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
public function setCwd($cwd)
|
| 22 |
+
{
|
| 23 |
+
$this->_cwd = $cwd;
|
| 24 |
+
}
|
| 25 |
+
}
|
app/code/community/Yireo/Webp/Model/Observer.php
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
<?php
|
| 2 |
/**
|
| 3 |
-
* Webp plugin for Magento
|
| 4 |
*
|
| 5 |
* @package Yireo_Webp
|
| 6 |
* @author Yireo (http://www.yireo.com/)
|
|
@@ -8,108 +8,219 @@
|
|
| 8 |
* @license Open Source License (OSL v3)
|
| 9 |
*/
|
| 10 |
|
|
|
|
|
|
|
|
|
|
| 11 |
class Yireo_Webp_Model_Observer
|
| 12 |
{
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
* Listen to the event core_block_abstract_to_html_after
|
| 15 |
-
*
|
| 16 |
-
* @access public
|
| 17 |
* @parameter Varien_Event_Observer $observer
|
|
|
|
| 18 |
* @return $this
|
| 19 |
*/
|
| 20 |
public function coreBlockAbstractToHtmlAfter($observer)
|
| 21 |
{
|
| 22 |
-
if(
|
| 23 |
return $this;
|
| 24 |
}
|
| 25 |
|
| 26 |
$transport = $observer->getEvent()->getTransport();
|
| 27 |
$block = $observer->getEvent()->getBlock();
|
| 28 |
-
$systemPaths = Mage::helper('webp')->getSystemPaths();
|
| 29 |
|
| 30 |
-
$
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
$layout = Mage::app()->getLayout();
|
| 34 |
-
$html = $transport->getHtml();
|
| 35 |
-
|
| 36 |
-
$newHtml = array();
|
| 37 |
-
if(preg_match_all('/\ src=\"([^\"]+)\.(png|jpg|jpeg)/i', $html, $matches)) {
|
| 38 |
-
|
| 39 |
-
$imageList = array();
|
| 40 |
-
foreach($matches[0] as $index => $match) {
|
| 41 |
-
|
| 42 |
-
// Convert the URL to a valid path
|
| 43 |
-
$imagePath = null;
|
| 44 |
-
$imageUrl = $matches[1][$index].'.'.$matches[2][$index];
|
| 45 |
-
if(preg_match('/^http/', $imageUrl)) {
|
| 46 |
-
foreach($systemPaths as $systemPath) {
|
| 47 |
-
if(strstr($imageUrl, $systemPath['url'])) {
|
| 48 |
-
$imagePath = str_replace($systemPath['url'], $systemPath['path'].DS, $imageUrl);
|
| 49 |
-
break;
|
| 50 |
-
}
|
| 51 |
-
}
|
| 52 |
-
}
|
| 53 |
-
|
| 54 |
-
// If this failed, don't continue
|
| 55 |
-
if(!file_exists($imagePath)) {
|
| 56 |
-
continue;
|
| 57 |
-
}
|
| 58 |
-
|
| 59 |
-
// Construct the new WebP image-name
|
| 60 |
-
$webpPath = Mage::helper('webp')->convertToWebp($imagePath);
|
| 61 |
-
|
| 62 |
-
// If this failed, don't continue
|
| 63 |
-
if(empty($webpPath) || file_exists($webpPath) == false) {
|
| 64 |
-
continue;
|
| 65 |
-
}
|
| 66 |
-
|
| 67 |
-
// Convert the path back to a valid URL
|
| 68 |
-
$webpUrl = null;
|
| 69 |
-
foreach($systemPaths as $systemPath) {
|
| 70 |
-
if(strstr($webpPath, $systemPath['path'])) {
|
| 71 |
-
$webpUrl = str_replace($systemPath['path'], $systemPath['url'].DS, $webpPath);
|
| 72 |
-
break;
|
| 73 |
-
}
|
| 74 |
-
}
|
| 75 |
-
|
| 76 |
-
// Replace the img tag in the HTML
|
| 77 |
-
$htmlTag = $matches[0][$index];
|
| 78 |
-
$newHtmlTag = str_replace('src="'.$imageUrl, 'data-img="'.md5($imageUrl), $htmlTag);
|
| 79 |
-
$html = str_replace($htmlTag, $newHtmlTag, $html);
|
| 80 |
-
|
| 81 |
-
// Add the images to the return-array
|
| 82 |
-
$imageList[md5($imageUrl)] = array('orig' => $imageUrl, 'webp' => $webpUrl);
|
| 83 |
-
}
|
| 84 |
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
|
|
|
|
|
|
|
|
|
| 97 |
}
|
| 98 |
|
| 99 |
-
|
| 100 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
}
|
|
|
|
|
|
|
| 102 |
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
}
|
|
|
|
|
|
|
| 109 |
|
| 110 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
}
|
| 112 |
|
| 113 |
-
return $
|
| 114 |
}
|
| 115 |
}
|
| 1 |
<?php
|
| 2 |
/**
|
| 3 |
+
* Webp plugin for Magento
|
| 4 |
*
|
| 5 |
* @package Yireo_Webp
|
| 6 |
* @author Yireo (http://www.yireo.com/)
|
| 8 |
* @license Open Source License (OSL v3)
|
| 9 |
*/
|
| 10 |
|
| 11 |
+
/**
|
| 12 |
+
* Class Yireo_Webp_Model_Observer
|
| 13 |
+
*/
|
| 14 |
class Yireo_Webp_Model_Observer
|
| 15 |
{
|
| 16 |
+
/**
|
| 17 |
+
* @var Yireo_Webp_Helper_Data
|
| 18 |
+
*/
|
| 19 |
+
protected $helper;
|
| 20 |
+
|
| 21 |
+
/**
|
| 22 |
+
* @var Yireo_Webp_Helper_File
|
| 23 |
+
*/
|
| 24 |
+
protected $fileHelper;
|
| 25 |
+
|
| 26 |
+
/**
|
| 27 |
+
* Constructor
|
| 28 |
+
*/
|
| 29 |
+
public function __construct()
|
| 30 |
+
{
|
| 31 |
+
$this->helper = Mage::helper('webp');
|
| 32 |
+
$this->fileHelper = Mage::helper('webp/file');
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
/**
|
| 36 |
+
* @param Mage_Core_Block_Abstract $block
|
| 37 |
+
*
|
| 38 |
+
* @return bool
|
| 39 |
+
*/
|
| 40 |
+
protected function isAllowedBlock($block)
|
| 41 |
+
{
|
| 42 |
+
$allowedBlocks = array('root');
|
| 43 |
+
|
| 44 |
+
if (in_array($block->getNameInLayout(), $allowedBlocks)) {
|
| 45 |
+
return true;
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
return false;
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
/**
|
| 52 |
* Listen to the event core_block_abstract_to_html_after
|
| 53 |
+
*
|
|
|
|
| 54 |
* @parameter Varien_Event_Observer $observer
|
| 55 |
+
*
|
| 56 |
* @return $this
|
| 57 |
*/
|
| 58 |
public function coreBlockAbstractToHtmlAfter($observer)
|
| 59 |
{
|
| 60 |
+
if ($this->helper->enabled() == false) {
|
| 61 |
return $this;
|
| 62 |
}
|
| 63 |
|
| 64 |
$transport = $observer->getEvent()->getTransport();
|
| 65 |
$block = $observer->getEvent()->getBlock();
|
|
|
|
| 66 |
|
| 67 |
+
if ($this->isAllowedBlock($block) == false) {
|
| 68 |
+
return $this;
|
| 69 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
|
| 71 |
+
$html = $transport->getHtml();
|
| 72 |
+
|
| 73 |
+
if (preg_match_all('/\ src=\"([^\"]+)\.(png|jpg|jpeg)/i', $html, $matches) == false) {
|
| 74 |
+
return $this;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
$imageList = array();
|
| 78 |
+
foreach ($matches[0] as $index => $match) {
|
| 79 |
+
|
| 80 |
+
// Convert the URL to a valid path
|
| 81 |
+
$imageUrl = $matches[1][$index] . '.' . $matches[2][$index];
|
| 82 |
+
$webpUrl = $this->convertImageUrlToWebp($imageUrl);
|
| 83 |
+
|
| 84 |
+
if (empty($webpUrl)) {
|
| 85 |
+
return false;
|
| 86 |
}
|
| 87 |
|
| 88 |
+
// Replace the img tag in the HTML
|
| 89 |
+
$htmlTag = $matches[0][$index];
|
| 90 |
+
$newHtmlTag = str_replace('src="' . $imageUrl, 'data-img="' . md5($imageUrl), $htmlTag);
|
| 91 |
+
$html = str_replace($htmlTag, $newHtmlTag, $html);
|
| 92 |
+
|
| 93 |
+
// Add the images to the return-array
|
| 94 |
+
$imageList[md5($imageUrl)] = array('orig' => $imageUrl, 'webp' => $webpUrl);
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
// Add a JavaScript-list to the HTML-document
|
| 98 |
+
if (empty($imageList)) {
|
| 99 |
+
return $this;
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
$newHtml = $this->getScriptHtmlLines($imageList);
|
| 103 |
+
|
| 104 |
+
if ($block->getNameInLayout() == 'root') {
|
| 105 |
+
$newHtml[] = '<script type="text/javascript" src="' . Mage::getBaseUrl('js') . 'webp/jquery.detect.js"></script>';
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
$html = $this->addScriptToBody($html, $newHtml);
|
| 109 |
+
$transport->setHtml($html);
|
| 110 |
+
|
| 111 |
+
return $this;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
/**
|
| 115 |
+
* @param $imageUrl
|
| 116 |
+
*
|
| 117 |
+
* @return bool|mixed
|
| 118 |
+
*/
|
| 119 |
+
protected function convertImageUrlToWebp($imageUrl)
|
| 120 |
+
{
|
| 121 |
+
$imagePath = $this->getImagePathFromUrl($imageUrl);
|
| 122 |
+
|
| 123 |
+
if (empty($imagePath)) {
|
| 124 |
+
return false;
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
if ($this->fileHelper->exists($imagePath) == false) {
|
| 128 |
+
return false;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
// Construct the new WebP image-name
|
| 132 |
+
$webpPath = $this->helper->convertToWebp($imagePath);
|
| 133 |
+
|
| 134 |
+
if (empty($webpPath)) {
|
| 135 |
+
return false;
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
if ($this->fileHelper->exists($webpPath) == false) {
|
| 139 |
+
return false;
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
// Convert the path back to a valid URL
|
| 143 |
+
$webpUrl = $this->getImageUrlFromPath($webpPath);
|
| 144 |
+
|
| 145 |
+
if (empty($webpUrl)) {
|
| 146 |
+
return false;
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
return $webpUrl;
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
/**
|
| 153 |
+
* @param $imageList
|
| 154 |
+
*
|
| 155 |
+
* @return array
|
| 156 |
+
*/
|
| 157 |
+
protected function getScriptHtmlLines($imageList)
|
| 158 |
+
{
|
| 159 |
+
$newHtml = array();
|
| 160 |
+
|
| 161 |
+
$newHtml[] = '<script>';
|
| 162 |
+
$newHtml[] = 'var SKIN_URL = \'' . Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_SKIN) . '\';';
|
| 163 |
+
$webpCookie = (int)Mage::app()->getRequest()->getCookie('webp', 0);
|
| 164 |
+
|
| 165 |
+
$newHtml[] = 'var WEBP_COOKIE = ' . $webpCookie . ';';
|
| 166 |
+
$newHtml[] = 'if(webpReplacements == null) { var webpReplacements = new Object(); }';
|
| 167 |
+
foreach ($imageList as $name => $value) {
|
| 168 |
+
$newHtml[] = 'webpReplacements[\'' . $name . '\'] = ' . json_encode($value);
|
| 169 |
+
}
|
| 170 |
+
$newHtml[] = '</script>';
|
| 171 |
+
|
| 172 |
+
return $newHtml;
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
/**
|
| 176 |
+
* @param string $imagePath
|
| 177 |
+
*
|
| 178 |
+
* @return mixed
|
| 179 |
+
*/
|
| 180 |
+
protected function getImageUrlFromPath($imagePath)
|
| 181 |
+
{
|
| 182 |
+
$systemPaths = $this->helper->getSystemPaths();
|
| 183 |
+
|
| 184 |
+
foreach ($systemPaths as $systemPath) {
|
| 185 |
+
if (strstr($imagePath, $systemPath['path'])) {
|
| 186 |
+
return str_replace($systemPath['path'], $systemPath['url'], $imagePath);
|
| 187 |
}
|
| 188 |
+
}
|
| 189 |
+
}
|
| 190 |
|
| 191 |
+
/**
|
| 192 |
+
* @param string $imageUrl
|
| 193 |
+
*
|
| 194 |
+
* @return mixed
|
| 195 |
+
*/
|
| 196 |
+
protected function getImagePathFromUrl($imageUrl)
|
| 197 |
+
{
|
| 198 |
+
$systemPaths = $this->helper->getSystemPaths();
|
| 199 |
+
|
| 200 |
+
if (preg_match('/^http/', $imageUrl)) {
|
| 201 |
+
foreach ($systemPaths as $systemPath) {
|
| 202 |
+
if (strstr($imageUrl, $systemPath['url'])) {
|
| 203 |
+
return str_replace($systemPath['url'], $systemPath['path'], $imageUrl);
|
| 204 |
+
}
|
| 205 |
}
|
| 206 |
+
}
|
| 207 |
+
}
|
| 208 |
|
| 209 |
+
/**
|
| 210 |
+
* @param $html
|
| 211 |
+
* @param $scriptLines
|
| 212 |
+
*
|
| 213 |
+
* @return mixed|string
|
| 214 |
+
*/
|
| 215 |
+
protected function addScriptToBody($html, $scriptLines)
|
| 216 |
+
{
|
| 217 |
+
$script = implode("\n", $scriptLines) . "\n";
|
| 218 |
+
if (strstr($html, '</body>')) {
|
| 219 |
+
$html = str_replace('</body>', $script . '</body>', $html);
|
| 220 |
+
} else {
|
| 221 |
+
$html = $html . $script;
|
| 222 |
}
|
| 223 |
|
| 224 |
+
return $html;
|
| 225 |
}
|
| 226 |
}
|
app/code/community/Yireo/Webp/etc/config.xml
CHANGED
|
@@ -13,7 +13,7 @@
|
|
| 13 |
|
| 14 |
<modules>
|
| 15 |
<Yireo_Webp>
|
| 16 |
-
<version>1.0.
|
| 17 |
</Yireo_Webp>
|
| 18 |
</modules>
|
| 19 |
|
|
@@ -65,7 +65,9 @@
|
|
| 65 |
<enabled>1</enabled>
|
| 66 |
<load_css>0</load_css>
|
| 67 |
<load_jquery>1</load_jquery>
|
|
|
|
| 68 |
<cwebp_path></cwebp_path>
|
|
|
|
| 69 |
</webp>
|
| 70 |
</web>
|
| 71 |
</default>
|
| 13 |
|
| 14 |
<modules>
|
| 15 |
<Yireo_Webp>
|
| 16 |
+
<version>1.0.3</version>
|
| 17 |
</Yireo_Webp>
|
| 18 |
</modules>
|
| 19 |
|
| 65 |
<enabled>1</enabled>
|
| 66 |
<load_css>0</load_css>
|
| 67 |
<load_jquery>1</load_jquery>
|
| 68 |
+
<cwebp_enabled>1</cwebp_enabled>
|
| 69 |
<cwebp_path></cwebp_path>
|
| 70 |
+
<gd_enabled>1</gd_enabled>
|
| 71 |
</webp>
|
| 72 |
</web>
|
| 73 |
</default>
|
app/code/community/Yireo/Webp/etc/system.xml
CHANGED
|
@@ -30,29 +30,52 @@
|
|
| 30 |
<show_in_website>1</show_in_website>
|
| 31 |
<show_in_store>1</show_in_store>
|
| 32 |
</enabled>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
<cwebp_path translate="label">
|
| 34 |
<label>Path to cwebp</label>
|
| 35 |
-
<comment><![CDATA[
|
| 36 |
<frontend_type>text</frontend_type>
|
| 37 |
-
<sort_order>
|
| 38 |
<show_in_default>1</show_in_default>
|
| 39 |
<show_in_website>1</show_in_website>
|
| 40 |
<show_in_store>1</show_in_store>
|
| 41 |
</cwebp_path>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
<load_jquery translate="label">
|
| 43 |
<label>Load jQuery</label>
|
|
|
|
| 44 |
<frontend_type>select</frontend_type>
|
| 45 |
<source_model>adminhtml/system_config_source_yesno</source_model>
|
| 46 |
-
<sort_order>
|
| 47 |
<show_in_default>1</show_in_default>
|
| 48 |
<show_in_website>1</show_in_website>
|
| 49 |
<show_in_store>1</show_in_store>
|
| 50 |
</load_jquery>
|
| 51 |
<load_css translate="label">
|
| 52 |
<label>Load WebP CSS</label>
|
|
|
|
| 53 |
<frontend_type>select</frontend_type>
|
| 54 |
<source_model>adminhtml/system_config_source_yesno</source_model>
|
| 55 |
-
<sort_order>
|
| 56 |
<show_in_default>1</show_in_default>
|
| 57 |
<show_in_website>1</show_in_website>
|
| 58 |
<show_in_store>1</show_in_store>
|
| 30 |
<show_in_website>1</show_in_website>
|
| 31 |
<show_in_store>1</show_in_store>
|
| 32 |
</enabled>
|
| 33 |
+
<cwebp_enabled translate="label">
|
| 34 |
+
<label>cwebp Method Enabled</label>
|
| 35 |
+
<comment>Whether you want to use the cwebp binary or not. Make sure to configure your hosting environment properly for this.</comment>
|
| 36 |
+
<frontend_type>select</frontend_type>
|
| 37 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
| 38 |
+
<sort_order>11</sort_order>
|
| 39 |
+
<show_in_default>1</show_in_default>
|
| 40 |
+
<show_in_website>1</show_in_website>
|
| 41 |
+
<show_in_store>1</show_in_store>
|
| 42 |
+
</cwebp_enabled>
|
| 43 |
<cwebp_path translate="label">
|
| 44 |
<label>Path to cwebp</label>
|
| 45 |
+
<comment><![CDATA[Example: "/usr/local/bin/cwebp"]]></comment>
|
| 46 |
<frontend_type>text</frontend_type>
|
| 47 |
+
<sort_order>12</sort_order>
|
| 48 |
<show_in_default>1</show_in_default>
|
| 49 |
<show_in_website>1</show_in_website>
|
| 50 |
<show_in_store>1</show_in_store>
|
| 51 |
</cwebp_path>
|
| 52 |
+
<gd_enabled translate="label">
|
| 53 |
+
<label>GD Method Enabled</label>
|
| 54 |
+
<comment>Whether you want to use the PHP GD or not</comment>
|
| 55 |
+
<frontend_type>select</frontend_type>
|
| 56 |
+
<frontend_model>webp/adminhtml_system_config_field_gd</frontend_model>
|
| 57 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
| 58 |
+
<sort_order>21</sort_order>
|
| 59 |
+
<show_in_default>1</show_in_default>
|
| 60 |
+
<show_in_website>1</show_in_website>
|
| 61 |
+
<show_in_store>1</show_in_store>
|
| 62 |
+
</gd_enabled>
|
| 63 |
<load_jquery translate="label">
|
| 64 |
<label>Load jQuery</label>
|
| 65 |
+
<comment>At this moment jQuery is required for detecting WebP support. Disable this if you are already loading jQuery in another way.</comment>
|
| 66 |
<frontend_type>select</frontend_type>
|
| 67 |
<source_model>adminhtml/system_config_source_yesno</source_model>
|
| 68 |
+
<sort_order>31</sort_order>
|
| 69 |
<show_in_default>1</show_in_default>
|
| 70 |
<show_in_website>1</show_in_website>
|
| 71 |
<show_in_store>1</show_in_store>
|
| 72 |
</load_jquery>
|
| 73 |
<load_css translate="label">
|
| 74 |
<label>Load WebP CSS</label>
|
| 75 |
+
<comment>Load a customizable CSS defining WebP-sources for the HTML elements in your theme. This needs to be customized by hand.</comment>
|
| 76 |
<frontend_type>select</frontend_type>
|
| 77 |
<source_model>adminhtml/system_config_source_yesno</source_model>
|
| 78 |
+
<sort_order>32</sort_order>
|
| 79 |
<show_in_default>1</show_in_default>
|
| 80 |
<show_in_website>1</show_in_website>
|
| 81 |
<show_in_store>1</show_in_store>
|
package.xml
CHANGED
|
@@ -1,2 +1,2 @@
|
|
| 1 |
<?xml version="1.0"?>
|
| 2 |
-
<package><name>Yireo_WebP</name><version>1.0.
|
| 1 |
<?xml version="1.0"?>
|
| 2 |
+
<package><name>Yireo_WebP</name><version>1.0.3</version><stability>stable</stability><license>Open Source License</license><channel>community</channel><extends></extends><summary>No summary</summary><description>No description</description><notes>No notes</notes><authors><author><name>Yireo</name><user>yireo</user><email>info@yireo.com</email></author></authors><date>2016-02-29</date><time>3:42:46</time><compatible></compatible><dependencies><required><php><min>5.4.0</min><max>6.0.0</max></php></required></dependencies><contents><target name="mage"><dir name="skin"><dir name="frontend"><dir name="default"><dir name="default"><dir name="images"><dir name="webp"><file name="test.webp" hash="0e2687e3a6c95084e6ce912aa45d3803"/></dir></dir><dir name="css"><file name="webp.css" hash="0edbf3ac7d124afb09332c5c67f68c98"/></dir></dir></dir></dir></dir><dir name="js"><dir name="webp"><file name="jquery.detect.js" hash="aeb31fc9a097c84db6fb9009c832ccfe"/><file name="jquery.js" hash="4e2a6874f8b028fa23591492284a1643"/></dir></dir><dir name="app"><dir name="etc"><dir name="modules"><file name="Yireo_Webp.xml" hash="ce4be2ddd8bcb72b3e28c138cabe4539"/></dir></dir><dir name="design"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="webp.xml" hash="cc1e3268c9e14c9258afa260c440e25c"/></dir></dir></dir></dir></dir><dir name="code"><dir name="community"><dir name="Yireo"><dir name="Webp"><dir name="etc"><file name="config.xml" hash="574b7f015e32b381cb7ee43cd42ac504"/><file name="system.xml" hash="9c758689114a6aa64a63f9900686daef"/></dir><dir name="Model"><file name="Observer.php" hash="043a29320c3ff099dc3373851187f34c"/></dir><dir name="Lib"><dir name="Io"><file name="File.php" hash="d0d7e1ab1c7631854222a1600f63ac72"/></dir></dir><dir name="Helper"><file name="Data.php" hash="178785cce9bf6e6575051552269de5ea"/><file name="File.php" hash="f383de5eabc3ffc29504260a5dc06d2c"/></dir><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Field"><file name="Gd.php" hash="bf9bed9b14c1a169db79dcd7555fec09"/></dir></dir></dir></dir></dir></dir></dir></dir></dir></dir></target></contents></package>
|
