From 0e0bbebd33ab6ba47e2967c59c3263130cd34e43 Mon Sep 17 00:00:00 2001 From: Daniel Zohm Date: Fri, 27 Jul 2012 16:14:52 +0200 Subject: [PATCH 001/136] Added Cache-Control: no-cache for non cacheable sites --- code/Model/Observer.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/Model/Observer.php b/code/Model/Observer.php index edfd815..582aa2d 100644 --- a/code/Model/Observer.php +++ b/code/Model/Observer.php @@ -43,7 +43,8 @@ public function processPreDispatch(Varien_Event_Observer $observer) $name = $session->getCustomer()->getName(); } $response->setHeader('X-Magento-LoggedIn', $loggedIn ? '1' : '0', true); // Only for debugging and information - $cookie->set('aoestatic_customername', $name, '3600', '/'); + $response->setHeader('Cache-Control', 'no-cache'); + $cookie->set('aoestatic_customername', $name, '3600', '/'); } $response->setHeader('X-Magento-Action', $fullActionName, true); // Only for debugging and information From bd9b2953246a17e9813657b734f3413b0740d68d Mon Sep 17 00:00:00 2001 From: Fabrizio Branca Date: Fri, 27 Jul 2012 14:59:10 -0700 Subject: [PATCH 002/136] Changed configuration to read xml files aoe_static.xml --- code/Helper/Data.php | 20 +------ code/Model/Config.php | 51 ++++++++++++++++++ code/Model/Observer.php | 112 ++++++++++++++++++++++++++++------------ code/etc/aoe_static.xml | 88 +++++++++++++++++++++++++++++++ code/etc/config.xml | 16 ------ code/etc/system.xml | 36 ------------- 6 files changed, 220 insertions(+), 103 deletions(-) create mode 100644 code/Model/Config.php create mode 100644 code/etc/aoe_static.xml delete mode 100644 code/etc/system.xml diff --git a/code/Helper/Data.php b/code/Helper/Data.php index ee9eae8..91e07b8 100644 --- a/code/Helper/Data.php +++ b/code/Helper/Data.php @@ -7,23 +7,5 @@ * @package Aoe_Static * @author Toni Grigoriu */ -class Aoe_Static_Helper_Data extends Mage_Core_Helper_Abstract -{ - /** - * Check if a fullActionName is configured as cacheable - * - * @param string $fullActionName - * @return false|int false if not cacheable, otherwise lifetime in seconds - */ - public function isCacheableAction($fullActionName) - { - $cacheActionsString = Mage::getStoreConfig('system/aoe_static/cache_actions'); - foreach (explode(',', $cacheActionsString) as $singleActionConfiguration) { - list($actionName, $lifeTime) = explode(';', $singleActionConfiguration); - if (trim($actionName) == $fullActionName) { - return intval(trim($lifeTime)); - } - } - return false; - } +class Aoe_Static_Helper_Data extends Mage_Core_Helper_Abstract { } \ No newline at end of file diff --git a/code/Model/Config.php b/code/Model/Config.php new file mode 100644 index 0000000..8a6496a --- /dev/null +++ b/code/Model/Config.php @@ -0,0 +1,51 @@ +setCacheId('cache_config'); + $this->_cacheChecksum = null; + $this->_cache = Mage::app()->getCache(); + + $canUsaCache = Mage::app()->useCache('config'); + if ($canUsaCache) { + if ($this->loadCache()) { + return $this; + } + } + + $config = Mage::getConfig()->loadModulesConfiguration('aoe_static.xml'); + $this->setXml($config->getNode()); + + if ($canUsaCache) { + $this->saveCache(array(Mage_Core_Model_Config::CACHE_TAG)); + } + return $this; + } + + /** + * Get action configuration + * + * @param $fullActionName + * @return false|Mage_Core_Model_Config_Element + */ + public function getActionConfiguration($fullActionName) { + $configuration = $this->getNode('aoe_static/'.$fullActionName); + if (!$configuration || 1 == $configuration->disabled) { + return false; + } + $use = (string)$configuration->use; + if ($use) { + $configuration = $this->getActionConfiguration($use); + } + return $configuration; + } + +} diff --git a/code/Model/Observer.php b/code/Model/Observer.php index 582aa2d..c4a2731 100644 --- a/code/Model/Observer.php +++ b/code/Model/Observer.php @@ -7,65 +7,113 @@ * @author Fabrizio Branca * @author Toni Grigoriu */ -class Aoe_Static_Model_Observer -{ +class Aoe_Static_Model_Observer { + + /** + * @var Aoe_Static_Model_Config + */ + protected $_config; + + /** + * Constructor + */ + public function __construct() { + $this->_config = Mage::getSingleton('aoestatic/config'); + } + /** * Check when varnish caching should be enabled. * * @param Varien_Event_Observer $observer * @return Aoe_Static_Model_Observer */ - public function processPreDispatch(Varien_Event_Observer $observer) - { - - $helper = Mage::helper('aoestatic'); /* @var $helper Aoe_Static_Helper_Data */ + public function processPreDispatch(Varien_Event_Observer $observer) { $event = $observer->getEvent(); /* @var $event Varien_Event */ $controllerAction = $event->getControllerAction(); /* @var $controllerAction Mage_Core_Controller_Varien_Action */ $fullActionName = $controllerAction->getFullActionName(); - $lifetime = $helper->isCacheableAction($fullActionName); - $response = $controllerAction->getResponse(); /* @var $response Mage_Core_Controller_Response_Http */ - if ($lifetime) { - // allow caching - $response->setHeader('X-Magento-Lifetime', $lifetime, true); // Only for debugging and information - $response->setHeader('Cache-Control', 'max-age='. $lifetime, true); - $response->setHeader('aoestatic', 'cache', true); - } else { - // do not allow caching - $cookie = Mage::getModel('core/cookie'); /* @var $cookie Mage_Core_Model_Cookie */ - $name = ''; - $loggedIn = false; - $session = Mage::getSingleton('customer/session'); /* @var $session Mage_Customer_Model_Session */ - if ($session->isLoggedIn()) { - $loggedIn = true; - $name = $session->getCustomer()->getName(); - } - $response->setHeader('X-Magento-LoggedIn', $loggedIn ? '1' : '0', true); // Only for debugging and information - $response->setHeader('Cache-Control', 'no-cache'); - $cookie->set('aoestatic_customername', $name, '3600', '/'); + // gather information for replace array + $customerName = ''; + $loggedIn = '0'; + $session = Mage::getSingleton('customer/session'); /* @var $session Mage_Customer_Model_Session */ + if ($session->isLoggedIn()) { + $loggedIn = '0'; + $customerName = $session->getCustomer()->getName(); + } + + $replace = array( + '###FULLACTIONNAME###' => $fullActionName, + '###CUSTOMERNAME###' => $customerName, + '###ISLOGGEDIN###' => $loggedIn + ); + + // apply default configuration in any case + $defaultConf = $this->_config->getActionConfiguration('default'); + if ($defaultConf) { + $this->applyConf($defaultConf, $response, $replace); + } + + // check if there is a configured configuration for this full action name + $conf = $this->_config->getActionConfiguration($fullActionName); + if (!$conf) { + // load the "uncached" configuration if no other configuration was found + $conf = $this->_config->getActionConfiguration('uncached'); + } + + // apply the configuration + if ($conf) { + $this->applyConf($conf, $response, $replace); } - $response->setHeader('X-Magento-Action', $fullActionName, true); // Only for debugging and information return $this; } + /** + * Apply configuration (set headers and cookies) + * + * @param Mage_Core_Model_Config_Element $conf + * @param Mage_Core_Controller_Response_Http $response + * @param array $replace + */ + protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Controller_Response_Http $response, array $replace) { + foreach ($conf->headers->children() as $key => $value) { + $value = str_replace(array_keys($replace), array_values($replace), $value); + $response->setHeader($key, $value, true); + } + if ($conf->cookies) { + $cookie = Mage::getModel('core/cookie'); /* @var $cookie Mage_Core_Model_Cookie */ + foreach ($conf->cookies->children() as $name => $cookieConf) { + if (1 == $cookieConf->disabled) { + continue; + } + $value = (string)$cookieConf->value; + $value = str_replace(array_keys($replace), array_values($replace), $value); + $period = $cookieConf->period ? (string)$cookieConf->period : null; + $path = $cookieConf->path ? (string)$cookieConf->path : null; + $domain = $cookieConf->domain ? (string)$cookieConf->domain : null; + $secure = $cookieConf->secure ? (string)$cookieConf->secure : null; + $httponly = $cookieConf->httponly ? (string)$cookieConf->httponly : null; + + $cookie->set($name, $value, $period, $path, $domain, $secure, $httponly); + } + } + } + /** * Add layout handle 'aoestatic_cacheable' or 'aoestatic_notcacheable' * * @param Varien_Event_Observer $observer */ - public function beforeLoadLayout(Varien_Event_Observer $observer) - { - $helper = Mage::helper('aoestatic'); /* @var $helper Aoe_Static_Helper_Data */ + public function beforeLoadLayout(Varien_Event_Observer $observer) { $event = $observer->getEvent(); /* @var $event Varien_Event */ $controllerAction = $event->getAction(); /* @var $controllerAction Mage_Core_Controller_Varien_Action */ $fullActionName = $controllerAction->getFullActionName(); - $lifetime = $helper->isCacheableAction($fullActionName); + $conf = $this->_config->getActionConfiguration($fullActionName); - $handle = $lifetime ? 'aoestatic_cacheable' : 'aoestatic_notcacheable'; + $handle = $conf ? 'aoestatic_cacheable' : 'aoestatic_notcacheable'; $observer->getEvent()->getLayout()->getUpdate()->addHandle($handle); } diff --git a/code/etc/aoe_static.xml b/code/etc/aoe_static.xml new file mode 100644 index 0000000..50ace69 --- /dev/null +++ b/code/etc/aoe_static.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + ###FULLACTIONNAME### + + + + + + + ###LOGGEDIN### + no-cache + cache + + + + ###CUSTOMERNAME### + 3600 + + + + + + + + + 0 + + 86400 + max-age=86400 + cache + + + + + + cms_index_index + + + + cms_index_index + + + + cms_index_index + + + + \ No newline at end of file diff --git a/code/etc/config.xml b/code/etc/config.xml index bacc0e7..34d9893 100644 --- a/code/etc/config.xml +++ b/code/etc/config.xml @@ -71,20 +71,4 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/code/etc/system.xml b/code/etc/system.xml deleted file mode 100644 index d040087..0000000 --- a/code/etc/system.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - text - 200 - 1 - 1 - 1 - - - - "<route>_<controller>_<action>;<lifeTimeInSeconds>" The output generated from these actions will be cached by Varnish.]]> - textarea - 100 - 1 - 1 - 1 - - - - - - - \ No newline at end of file From 5b1a93c5a4200763b8bb7b92f2064c9fe80b7b7b Mon Sep 17 00:00:00 2001 From: Daniel Zohm Date: Mon, 30 Jul 2012 15:01:29 +0200 Subject: [PATCH 003/136] Fixed typo and removed aoestatic header with value cache in non cached items --- code/etc/aoe_static.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/etc/aoe_static.xml b/code/etc/aoe_static.xml index 50ace69..5964fc2 100644 --- a/code/etc/aoe_static.xml +++ b/code/etc/aoe_static.xml @@ -45,9 +45,8 @@ - ###LOGGEDIN### + ###ISLOGGEDIN### no-cache - cache From b051716be79aa42667e86b73de357780ffe0d230 Mon Sep 17 00:00:00 2001 From: Daniel Kopp Date: Wed, 15 Aug 2012 15:28:32 +0200 Subject: [PATCH 004/136] Fix to show Headers too if config cache is enabled --- code/Model/Config.php | 61 +++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/code/Model/Config.php b/code/Model/Config.php index 8a6496a..93649df 100644 --- a/code/Model/Config.php +++ b/code/Model/Config.php @@ -1,33 +1,54 @@ '; /** * Class constructor * load cache configuration * - * @param $data + * @param string $sourceData */ - public function __construct($data = null) { - parent::__construct($data); - $this->setCacheId('cache_config'); - $this->_cacheChecksum = null; - $this->_cache = Mage::app()->getCache(); - - $canUsaCache = Mage::app()->useCache('config'); - if ($canUsaCache) { - if ($this->loadCache()) { - return $this; + public function __construct($sourceData = null) + { + $tags = array(self::CACHE_TAG_NAME); + $useCache = Mage::app()->useCache(self::CACHE_TAG_NAME); + $this->setCacheId(self::CACHE_KEY_NAME); + $this->setCacheTags($tags); + if ($useCache && ($cache = Mage::app()->loadCache(self::CACHE_KEY_NAME))) { + parent::__construct($cache); + } else { + parent::__construct(self::CONFIGURATION_TEMPLATE); + Mage::getConfig()->loadModulesConfiguration(self::CONFIGURATION_FILENAME, $this); + if ($useCache) { + $xmlString = $this->getXmlString(); + Mage::app()->saveCache($xmlString, self::CACHE_KEY_NAME, $tags); } } - - $config = Mage::getConfig()->loadModulesConfiguration('aoe_static.xml'); - $this->setXml($config->getNode()); - - if ($canUsaCache) { - $this->saveCache(array(Mage_Core_Model_Config::CACHE_TAG)); - } - return $this; } /** From 1427d50fa4bc12b37c0018a4e1ef29893c868907 Mon Sep 17 00:00:00 2001 From: Tymoteusz Motylewski Date: Mon, 24 Sep 2012 13:52:08 +0200 Subject: [PATCH 005/136] Fix cache ID conflict with Full Page Cache, Rename constants for better readability --- code/Model/Config.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/code/Model/Config.php b/code/Model/Config.php index 93649df..55e5ad2 100644 --- a/code/Model/Config.php +++ b/code/Model/Config.php @@ -7,13 +7,13 @@ class Aoe_Static_Model_Config extends Mage_Core_Model_Config_Base { * * @var string */ - const CACHE_KEY_NAME = 'cache_config'; + const CACHE_ID = 'aoe_static_cache'; /** * Tag name for cache type, used in mass cache cleaning * * @var string */ - const CACHE_TAG_NAME = 'config'; + const CACHE_TAG = 'config'; /** * Filename that will be collected from different modules * @@ -35,18 +35,18 @@ class Aoe_Static_Model_Config extends Mage_Core_Model_Config_Base { */ public function __construct($sourceData = null) { - $tags = array(self::CACHE_TAG_NAME); - $useCache = Mage::app()->useCache(self::CACHE_TAG_NAME); - $this->setCacheId(self::CACHE_KEY_NAME); + $tags = array(self::CACHE_TAG); + $useCache = Mage::app()->useCache('config'); + $this->setCacheId(self::CACHE_ID); $this->setCacheTags($tags); - if ($useCache && ($cache = Mage::app()->loadCache(self::CACHE_KEY_NAME))) { + if ($useCache && ($cache = Mage::app()->loadCache(self::CACHE_ID))) { parent::__construct($cache); } else { parent::__construct(self::CONFIGURATION_TEMPLATE); Mage::getConfig()->loadModulesConfiguration(self::CONFIGURATION_FILENAME, $this); if ($useCache) { $xmlString = $this->getXmlString(); - Mage::app()->saveCache($xmlString, self::CACHE_KEY_NAME, $tags); + Mage::app()->saveCache($xmlString, self::CACHE_ID, $tags); } } } From 710befa7e4256bed9af937cd7e8e761138a32d65 Mon Sep 17 00:00:00 2001 From: Tymoteusz Motylewski Date: Mon, 24 Sep 2012 16:04:39 +0200 Subject: [PATCH 006/136] Raise version number --- code/etc/config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/etc/config.xml b/code/etc/config.xml index 34d9893..e49b932 100644 --- a/code/etc/config.xml +++ b/code/etc/config.xml @@ -5,7 +5,7 @@ true local - 0.0.1 + 0.0.2 From 1ee2d6f69ba152a38bad5a3d5ac8f764d8084c64 Mon Sep 17 00:00:00 2001 From: Fabrizio Branca Date: Mon, 22 Oct 2012 23:07:41 -0700 Subject: [PATCH 007/136] Added new marker --- code/Model/Observer.php | 3 ++- code/etc/aoe_static.xml | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/code/Model/Observer.php b/code/Model/Observer.php index c4a2731..cb788ee 100644 --- a/code/Model/Observer.php +++ b/code/Model/Observer.php @@ -46,7 +46,8 @@ public function processPreDispatch(Varien_Event_Observer $observer) { $replace = array( '###FULLACTIONNAME###' => $fullActionName, '###CUSTOMERNAME###' => $customerName, - '###ISLOGGEDIN###' => $loggedIn + '###ISLOGGEDIN###' => $loggedIn, + '###NUMBEROFITEMSINCART' => Mage::helper('checkout/cart')->getSummaryCount(), ); // apply default configuration in any case diff --git a/code/etc/aoe_static.xml b/code/etc/aoe_static.xml index 5964fc2..fbf9546 100644 --- a/code/etc/aoe_static.xml +++ b/code/etc/aoe_static.xml @@ -31,6 +31,7 @@ - ###FULLACTIONNAME### - ###CUSTOMERNAME### - ###ISLOGGEDIN### + - ###NUMBEROFITEMSINCART --> @@ -57,6 +58,14 @@ --> + + ###NUMBEROFITEMSINCART### + 3600 + + + From b548a6329dc65ebdb8729a54cacb7b1b3d5cc823 Mon Sep 17 00:00:00 2001 From: Fabrizio Branca Date: Wed, 24 Oct 2012 20:42:23 -0700 Subject: [PATCH 008/136] Removing CUSTOMERNAME and CARTSUMMARYCOUNT from before_body_end block --- frontend/template/aoestatic/beforebodyend.phtml | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend/template/aoestatic/beforebodyend.phtml b/frontend/template/aoestatic/beforebodyend.phtml index 807e44d..c938d61 100644 --- a/frontend/template/aoestatic/beforebodyend.phtml +++ b/frontend/template/aoestatic/beforebodyend.phtml @@ -4,7 +4,5 @@ var AJAXHOME_URL = 'getStore()->isCurrentlySecure() ? array('_secure' => 1) : array()) ?>'; var FULLACTIONNAME = 'getAction()->getFullActionName() ?>'; var CURRENTPRODUCTID = 'getId() ?>'; - var CUSTOMERNAME = 'getCustomerName() ?>'; - var CARTSUMMARYCOUNT = 'getCartSummaryCount(); ?>'; //]]> From 4ac4fd1b2d17ef2e284a9ef2e2d555658077f46d Mon Sep 17 00:00:00 2001 From: Fabrizio Branca Date: Wed, 24 Oct 2012 22:24:21 -0700 Subject: [PATCH 009/136] Fixed missing marker characters --- code/Model/Observer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/Model/Observer.php b/code/Model/Observer.php index cb788ee..810c7dc 100644 --- a/code/Model/Observer.php +++ b/code/Model/Observer.php @@ -47,7 +47,7 @@ public function processPreDispatch(Varien_Event_Observer $observer) { '###FULLACTIONNAME###' => $fullActionName, '###CUSTOMERNAME###' => $customerName, '###ISLOGGEDIN###' => $loggedIn, - '###NUMBEROFITEMSINCART' => Mage::helper('checkout/cart')->getSummaryCount(), + '###NUMBEROFITEMSINCART###' => Mage::helper('checkout/cart')->getSummaryCount(), ); // apply default configuration in any case From b69232724282b724f92eb23f7ddaab5ed67ad88a Mon Sep 17 00:00:00 2001 From: Fabrizio Branca Date: Wed, 24 Oct 2012 22:24:33 -0700 Subject: [PATCH 010/136] Added some comments --- frontend/template/aoestatic/beforebodyend.phtml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/template/aoestatic/beforebodyend.phtml b/frontend/template/aoestatic/beforebodyend.phtml index c938d61..0ba21ce 100644 --- a/frontend/template/aoestatic/beforebodyend.phtml +++ b/frontend/template/aoestatic/beforebodyend.phtml @@ -3,6 +3,8 @@ //getStore()->isCurrentlySecure() ? array('_secure' => 1) : array()) ?>'; var FULLACTIONNAME = 'getAction()->getFullActionName() ?>'; + + var CURRENTPRODUCTID = 'getId() ?>'; //]]> From 81df9cbd6d2a56531b4f4f96ad7406c48149b5df Mon Sep 17 00:00:00 2001 From: Tymoteusz Motylewski Date: Tue, 6 Nov 2012 10:48:07 +0100 Subject: [PATCH 011/136] Make cookies available for js when "use httpOnly" setting is set in configuration/web/session cookie management Add proper casting for bolean values in configuration --- code/Model/Observer.php | 4 ++-- code/etc/aoe_static.xml | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/code/Model/Observer.php b/code/Model/Observer.php index 810c7dc..e5c92c9 100644 --- a/code/Model/Observer.php +++ b/code/Model/Observer.php @@ -94,8 +94,8 @@ protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Con $period = $cookieConf->period ? (string)$cookieConf->period : null; $path = $cookieConf->path ? (string)$cookieConf->path : null; $domain = $cookieConf->domain ? (string)$cookieConf->domain : null; - $secure = $cookieConf->secure ? (string)$cookieConf->secure : null; - $httponly = $cookieConf->httponly ? (string)$cookieConf->httponly : null; + $secure = $cookieConf->secure ? filter_var($cookieConf->secure, FILTER_VALIDATE_BOOLEAN) : null; + $httponly = $cookieConf->httponly ? filter_var($cookieConf->httponly, FILTER_VALIDATE_BOOLEAN) : null; $cookie->set($name, $value, $period, $path, $domain, $secure, $httponly); } diff --git a/code/etc/aoe_static.xml b/code/etc/aoe_static.xml index fbf9546..512d707 100644 --- a/code/etc/aoe_static.xml +++ b/code/etc/aoe_static.xml @@ -55,16 +55,16 @@ 3600 + --> + 0 ###NUMBEROFITEMSINCART### 3600 + --> + 0 From 607178eb4db84140ffc4b5688153f9c251edca40 Mon Sep 17 00:00:00 2001 From: Tymoteusz Motylewski Date: Wed, 16 Jan 2013 13:31:22 +0100 Subject: [PATCH 012/136] Fix XSS issue with customer name Escape customer's name before setting cookie --- code/Model/Observer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/Model/Observer.php b/code/Model/Observer.php index e5c92c9..bd132ef 100644 --- a/code/Model/Observer.php +++ b/code/Model/Observer.php @@ -40,7 +40,7 @@ public function processPreDispatch(Varien_Event_Observer $observer) { $session = Mage::getSingleton('customer/session'); /* @var $session Mage_Customer_Model_Session */ if ($session->isLoggedIn()) { $loggedIn = '0'; - $customerName = $session->getCustomer()->getName(); + $customerName = Mage::helper('core')->escapeHtml($session->getCustomer()->getName()); } $replace = array( From d741551fa6610d5321940e283cbaf2ff7c97aa20 Mon Sep 17 00:00:00 2001 From: Dmytro Zavalkin Date: Wed, 3 Apr 2013 22:25:17 +0300 Subject: [PATCH 013/136] MAGE-239: Varnish doesn't purge the GuidaTv page - added custom url max age functionality --- adminhtml/layout/aoestatic/aoestatic.xml | 16 ++ code/Block/Adminhtml/CustomUrl.php | 37 +++ code/Block/Adminhtml/CustomUrl/Edit.php | 70 +++++ code/Block/Adminhtml/CustomUrl/Edit/Form.php | 93 +++++++ code/Block/Adminhtml/CustomUrl/Grid.php | 91 ++++++ code/Model/CustomUrl.php | 39 +++ code/Model/Observer.php | 262 ++++++++++-------- code/Model/Resource/CustomUrl.php | 108 ++++++++ code/Model/Resource/CustomUrl/Collection.php | 34 +++ .../Aoestatic/CustomUrlController.php | 216 +++++++++++++++ code/etc/adminhtml.xml | 47 ++++ code/etc/config.xml | 166 ++++++----- code/sql/aoestatic_setup/install-0.0.3.php | 41 +++ modman | 12 +- 14 files changed, 1050 insertions(+), 182 deletions(-) create mode 100644 adminhtml/layout/aoestatic/aoestatic.xml create mode 100755 code/Block/Adminhtml/CustomUrl.php create mode 100644 code/Block/Adminhtml/CustomUrl/Edit.php create mode 100644 code/Block/Adminhtml/CustomUrl/Edit/Form.php create mode 100755 code/Block/Adminhtml/CustomUrl/Grid.php create mode 100644 code/Model/CustomUrl.php create mode 100644 code/Model/Resource/CustomUrl.php create mode 100644 code/Model/Resource/CustomUrl/Collection.php create mode 100755 code/controllers/Adminhtml/Aoestatic/CustomUrlController.php create mode 100755 code/etc/adminhtml.xml create mode 100644 code/sql/aoestatic_setup/install-0.0.3.php diff --git a/adminhtml/layout/aoestatic/aoestatic.xml b/adminhtml/layout/aoestatic/aoestatic.xml new file mode 100644 index 0000000..30e5cf9 --- /dev/null +++ b/adminhtml/layout/aoestatic/aoestatic.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/code/Block/Adminhtml/CustomUrl.php b/code/Block/Adminhtml/CustomUrl.php new file mode 100755 index 0000000..023825e --- /dev/null +++ b/code/Block/Adminhtml/CustomUrl.php @@ -0,0 +1,37 @@ + + */ +class Aoe_Static_Block_Adminhtml_CustomUrl extends Mage_Adminhtml_Block_Widget_Grid_Container +{ + /** + * Block constructor + */ + public function __construct() + { + $this->_blockGroup = 'aoestatic'; + $this->_controller = 'adminhtml_customUrl'; + $this->_headerText = Mage::helper('aoestatic')->__('Urls max-age management'); + + parent::__construct(); + + if ($this->_isAllowedAction('save')) { + $this->_updateButton('add', 'label', Mage::helper('aoestatic')->__('Add new custom url')); + } else { + $this->_removeButton('add'); + } + } + + /** + * Check permission for passed action + * + * @param string $action + * @return bool + */ + protected function _isAllowedAction($action) + { + return Mage::getSingleton('admin/session')->isAllowed('system/aoestatic_customUrl/' . $action); + } +} diff --git a/code/Block/Adminhtml/CustomUrl/Edit.php b/code/Block/Adminhtml/CustomUrl/Edit.php new file mode 100644 index 0000000..87d736b --- /dev/null +++ b/code/Block/Adminhtml/CustomUrl/Edit.php @@ -0,0 +1,70 @@ + + */ +class Aoe_Static_Block_Adminhtml_CustomUrl_Edit extends Mage_Adminhtml_Block_Widget_Form_Container +{ + /** + * Initialize edit form container + */ + public function __construct() + { + $this->_objectId = 'id'; + $this->_blockGroup = 'aoestatic'; + $this->_controller = 'adminhtml_customUrl'; + + parent::__construct(); + + if ($this->_isAllowedAction('save')) { + $this->_updateButton('save', 'label', Mage::helper('aoestatic')->__('Save custom url')); + $this->_addButton('saveandcontinue', array( + 'label' => Mage::helper('aoestatic')->__('Save and Continue Edit'), + 'onclick' => 'saveAndContinueEdit()', + 'class' => 'save', + ), -100); + } else { + $this->_removeButton('save'); + } + + if ($this->_isAllowedAction('delete')) { + $this->_updateButton('delete', 'label', Mage::helper('aoestatic')->__('Delete custom url')); + } else { + $this->_removeButton('delete'); + } + + $this->_formScripts[] = " + function saveAndContinueEdit(){ + editForm.submit($('edit_form').action+'back/edit/'); + } + "; + } + + /** + * Retrieve text for header element depending on loaded page + * + * @return string + */ + public function getHeaderText() + { + if (Mage::registry('custom_url')->getId()) { + return Mage::helper('aoestatic')->__("Edit custom url (ID: %d)", + $this->escapeHtml(Mage::registry('custom_url')->getId()) + ); + } else { + return Mage::helper('aoestatic')->__('New custom url'); + } + } + + /** + * Check permission for passed action + * + * @param string $action + * @return bool + */ + protected function _isAllowedAction($action) + { + return Mage::getSingleton('admin/session')->isAllowed('system/aoestatic_customUrl/' . $action); + } +} diff --git a/code/Block/Adminhtml/CustomUrl/Edit/Form.php b/code/Block/Adminhtml/CustomUrl/Edit/Form.php new file mode 100644 index 0000000..b070eff --- /dev/null +++ b/code/Block/Adminhtml/CustomUrl/Edit/Form.php @@ -0,0 +1,93 @@ + + */ +class Aoe_Static_Block_Adminhtml_CustomUrl_Edit_Form extends Mage_Adminhtml_Block_Widget_Form +{ + /** + * Set form id and title + */ + public function __construct() + { + parent::__construct(); + $this->setId('custom_url_form'); + $this->setTitle(Mage::helper('aoestatic')->__('Custom urls')); + } + + /** + * Prepare form layout + * + * @return $this + */ + protected function _prepareForm() + { + /** @var $model Aoe_Static_Model_CustomUrl */ + $model = Mage::registry('custom_url'); + + $form = new Varien_Data_Form( + array( + 'id' => 'edit_form', + 'action' => $this->getData('action'), + 'method' => 'post' + ) + ); + + // set form data either from model values or from session + $formValues = array( + 'store_id' => $model->getStoreId(), + 'request_path' => $model->getRequestPath(), + 'max_age' => $model->getMaxAge(), + ); + + $fieldset = $form->addFieldset('base_fieldset', array( + 'legend' => Mage::helper('aoestatic')->__('Custom urls') + )); + + // get store switcher or a hidden field with its id + if (!Mage::app()->isSingleStoreMode()) { + $stores = Mage::getSingleton('adminhtml/system_store')->getStoreValuesForForm(); + $element = $fieldset->addField('store_id', 'select', array( + 'label' => Mage::helper('aoestatic')->__('Store'), + 'title' => Mage::helper('aoestatic')->__('Store'), + 'class' => 'required-entry', + 'name' => 'store_id', + 'required' => true, + 'values' => $stores, + 'value' => $formValues['store_id'], + )); + $renderer = $this->getLayout()->createBlock('adminhtml/store_switcher_form_renderer_fieldset_element'); + $element->setRenderer($renderer); + } else { + $fieldset->addField('store_id', 'hidden', array( + 'name' => 'store_id', + 'value' => Mage::app()->getStore(true)->getId() + )); + } + + $fieldset->addField('request_path', 'text', array( + 'label' => Mage::helper('aoestatic')->__('Request Path'), + 'title' => Mage::helper('aoestatic')->__('Request Path'), + 'class' => 'required-entry', + 'name' => 'request_path', + 'required' => true, + 'value' => $formValues['request_path'] + )); + + $fieldset->addField('max_age', 'text', array( + 'label' => Mage::helper('aoestatic')->__('Max Age'), + 'title' => Mage::helper('aoestatic')->__('Max Age'), + 'class' => 'required-entry validate-digits', + 'name' => 'max_age', + 'required' => true, + 'value' => $formValues['max_age'] + )); + + $form->setUseContainer(true); + $form->setAction(Mage::helper('adminhtml')->getUrl('*/*/save', array('id' => $model->getId()))); + $this->setForm($form); + + return parent::_prepareForm(); + } +} diff --git a/code/Block/Adminhtml/CustomUrl/Grid.php b/code/Block/Adminhtml/CustomUrl/Grid.php new file mode 100755 index 0000000..50050c5 --- /dev/null +++ b/code/Block/Adminhtml/CustomUrl/Grid.php @@ -0,0 +1,91 @@ + + */ +class Aoe_Static_Block_Adminhtml_CustomUrl_Grid extends Mage_Adminhtml_Block_Widget_Grid +{ + /** + * Init grid default properties + */ + public function __construct() + { + parent::__construct(); + $this->setId('custom_url_list_grid'); + $this->setDefaultSort('custom_url_id'); + $this->setUseAjax(true); + } + + /** + * Prepare collection for grid + * + * @return $this + */ + protected function _prepareCollection() + { + /** @var $collection Aoe_Static_Model_Resource_CustomUrl_Collection */ + $collection = Mage::getResourceModel('aoestatic/customUrl_collection'); + + $this->setCollection($collection); + return parent::_prepareCollection(); + } + + /** + * Return row URL for js event handlers + * + * @param Aoe_Static_Model_CustomUrl $row + * @return string + */ + public function getRowUrl($row) + { + return $this->getUrl('*/*/edit', array('id' => $row->getId())); + } + + /** + * Prepare Grid columns + * + * @return $this + */ + protected function _prepareColumns() + { + $this->addColumn('custom_url_id', array( + 'header' => $this->__('ID'), + 'width' => '50px', + 'index' => 'custom_url_id' + )); + + if (!Mage::app()->isSingleStoreMode()) { + $this->addColumn('store_id', array( + 'header' => $this->__('Store View'), + 'width' => '200px', + 'index' => 'store_id', + 'type' => 'store', + 'store_view' => true, + )); + } + + $this->addColumn('request_path', array( + 'header' => $this->__('Request Path'), + 'width' => '50px', + 'index' => 'request_path' + )); + $this->addColumn('max_age', array( + 'header' => $this->__('Max Age'), + 'width' => '50px', + 'index' => 'max_age' + )); + + return parent::_prepareColumns(); + } + + /** + * Grid url getter + * + * @return string current grid url + */ + public function getGridUrl() + { + return $this->getUrl('*/*/grid', array('_current' => true)); + } +} diff --git a/code/Model/CustomUrl.php b/code/Model/CustomUrl.php new file mode 100644 index 0000000..24aed30 --- /dev/null +++ b/code/Model/CustomUrl.php @@ -0,0 +1,39 @@ + + * + * @method Aoe_Static_Model_Resource_CustomUrl _getResource() + * @method Aoe_Static_Model_Resource_CustomUrl getResource() + * @method int getStoreId() + * @method Aoe_Static_Model_CustomUrl setStoreId(int $value) + * @method string getRequestPath() + * @method Aoe_Static_Model_CustomUrl setRequestPath(string $value) + * @method int getMaxAge() + * @method Aoe_Static_Model_CustomUrl setMaxAge(int $value) + */ +class Aoe_Static_Model_CustomUrl extends Mage_Core_Model_Abstract +{ + protected function _construct() + { + $this->_init('aoestatic/customUrl'); + } + + /** + * Load url max-age information for request + * If $path is array - we must load possible records and choose one matching earlier record in array + * + * @param array|string $path + * @return $this + */ + public function loadByRequestPath($path) + { + $this->setId(null); + $this->_getResource()->loadByRequestPath($this, $path); + $this->_afterLoad(); + $this->setOrigData(); + $this->_hasDataChanges = false; + return $this; + } +} diff --git a/code/Model/Observer.php b/code/Model/Observer.php index bd132ef..35e1cde 100644 --- a/code/Model/Observer.php +++ b/code/Model/Observer.php @@ -4,118 +4,158 @@ * * @category Aoe * @package Aoe_Static - * @author Fabrizio Branca + * @author Fabrizio Branca * @author Toni Grigoriu */ -class Aoe_Static_Model_Observer { - - /** - * @var Aoe_Static_Model_Config - */ - protected $_config; - - /** - * Constructor - */ - public function __construct() { - $this->_config = Mage::getSingleton('aoestatic/config'); - } - - /** - * Check when varnish caching should be enabled. - * - * @param Varien_Event_Observer $observer - * @return Aoe_Static_Model_Observer - */ - public function processPreDispatch(Varien_Event_Observer $observer) { - $event = $observer->getEvent(); /* @var $event Varien_Event */ - $controllerAction = $event->getControllerAction(); /* @var $controllerAction Mage_Core_Controller_Varien_Action */ - $fullActionName = $controllerAction->getFullActionName(); - - $response = $controllerAction->getResponse(); /* @var $response Mage_Core_Controller_Response_Http */ - - // gather information for replace array - $customerName = ''; - $loggedIn = '0'; - $session = Mage::getSingleton('customer/session'); /* @var $session Mage_Customer_Model_Session */ - if ($session->isLoggedIn()) { - $loggedIn = '0'; - $customerName = Mage::helper('core')->escapeHtml($session->getCustomer()->getName()); - } - - $replace = array( - '###FULLACTIONNAME###' => $fullActionName, - '###CUSTOMERNAME###' => $customerName, - '###ISLOGGEDIN###' => $loggedIn, +class Aoe_Static_Model_Observer +{ + /** + * @var Aoe_Static_Model_Config + */ + protected $_config; + + /** + * Constructor + */ + public function __construct() + { + $this->_config = Mage::getSingleton('aoestatic/config'); + } + + /** + * Check when varnish caching should be enabled. + * + * @param Varien_Event_Observer $observer + * @return Aoe_Static_Model_Observer + */ + public function processPreDispatch(Varien_Event_Observer $observer) + { + /* @var $event Varien_Event */ + $event = $observer->getEvent(); + /* @var $controllerAction Mage_Core_Controller_Varien_Action */ + $controllerAction = $event->getControllerAction(); + $fullActionName = $controllerAction->getFullActionName(); + + /* @var $response Mage_Core_Controller_Response_Http */ + $response = $controllerAction->getResponse(); + + // gather information for replace array + $customerName = ''; + $loggedIn = '0'; + $session = Mage::getSingleton('customer/session'); + /* @var $session Mage_Customer_Model_Session */ + if ($session->isLoggedIn()) { + $loggedIn = '0'; + $customerName = Mage::helper('core')->escapeHtml($session->getCustomer()->getName()); + } + + $replace = array( + '###FULLACTIONNAME###' => $fullActionName, + '###CUSTOMERNAME###' => $customerName, + '###ISLOGGEDIN###' => $loggedIn, '###NUMBEROFITEMSINCART###' => Mage::helper('checkout/cart')->getSummaryCount(), - ); - - // apply default configuration in any case - $defaultConf = $this->_config->getActionConfiguration('default'); - if ($defaultConf) { - $this->applyConf($defaultConf, $response, $replace); - } - - // check if there is a configured configuration for this full action name - $conf = $this->_config->getActionConfiguration($fullActionName); - if (!$conf) { - // load the "uncached" configuration if no other configuration was found - $conf = $this->_config->getActionConfiguration('uncached'); - } - - // apply the configuration - if ($conf) { - $this->applyConf($conf, $response, $replace); - } - - return $this; - } - - /** - * Apply configuration (set headers and cookies) - * - * @param Mage_Core_Model_Config_Element $conf - * @param Mage_Core_Controller_Response_Http $response - * @param array $replace - */ - protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Controller_Response_Http $response, array $replace) { - foreach ($conf->headers->children() as $key => $value) { - $value = str_replace(array_keys($replace), array_values($replace), $value); - $response->setHeader($key, $value, true); - } - if ($conf->cookies) { - $cookie = Mage::getModel('core/cookie'); /* @var $cookie Mage_Core_Model_Cookie */ - foreach ($conf->cookies->children() as $name => $cookieConf) { - if (1 == $cookieConf->disabled) { - continue; - } - $value = (string)$cookieConf->value; - $value = str_replace(array_keys($replace), array_values($replace), $value); - $period = $cookieConf->period ? (string)$cookieConf->period : null; - $path = $cookieConf->path ? (string)$cookieConf->path : null; - $domain = $cookieConf->domain ? (string)$cookieConf->domain : null; - $secure = $cookieConf->secure ? filter_var($cookieConf->secure, FILTER_VALIDATE_BOOLEAN) : null; - $httponly = $cookieConf->httponly ? filter_var($cookieConf->httponly, FILTER_VALIDATE_BOOLEAN) : null; - - $cookie->set($name, $value, $period, $path, $domain, $secure, $httponly); - } - } - } - - /** - * Add layout handle 'aoestatic_cacheable' or 'aoestatic_notcacheable' - * - * @param Varien_Event_Observer $observer - */ - public function beforeLoadLayout(Varien_Event_Observer $observer) { - $event = $observer->getEvent(); /* @var $event Varien_Event */ - $controllerAction = $event->getAction(); /* @var $controllerAction Mage_Core_Controller_Varien_Action */ - $fullActionName = $controllerAction->getFullActionName(); - - $conf = $this->_config->getActionConfiguration($fullActionName); - - $handle = $conf ? 'aoestatic_cacheable' : 'aoestatic_notcacheable'; - - $observer->getEvent()->getLayout()->getUpdate()->addHandle($handle); - } + ); + + // apply default configuration in any case + $defaultConf = $this->_config->getActionConfiguration('default'); + if ($defaultConf) { + $this->applyConf($defaultConf, $response, $replace); + } + + // check if there is a configured configuration for this full action name + $conf = $this->_config->getActionConfiguration($fullActionName); + if (!$conf) { + // load the "uncached" configuration if no other configuration was found + $conf = $this->_config->getActionConfiguration('uncached'); + } + + // apply the configuration + if ($conf) { + $this->applyConf($conf, $response, $replace); + } + + $this->_applyCustomMaxAgeFromDb($controllerAction->getRequest(), $response); + + return $this; + } + + /** + * Apply configuration (set headers and cookies) + * + * @param Mage_Core_Model_Config_Element $conf + * @param Mage_Core_Controller_Response_Http $response + * @param array $replace + */ + protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Controller_Response_Http $response, + array $replace + ) { + foreach ($conf->headers->children() as $key => $value) { + $value = str_replace(array_keys($replace), array_values($replace), $value); + $response->setHeader($key, $value, true); + } + if ($conf->cookies) { + $cookie = Mage::getModel('core/cookie'); + /* @var $cookie Mage_Core_Model_Cookie */ + foreach ($conf->cookies->children() as $name => $cookieConf) { + if (1 == $cookieConf->disabled) { + continue; + } + $value = (string) $cookieConf->value; + $value = str_replace(array_keys($replace), array_values($replace), $value); + $period = $cookieConf->period ? (string) $cookieConf->period : null; + $path = $cookieConf->path ? (string) $cookieConf->path : null; + $domain = $cookieConf->domain ? (string) $cookieConf->domain : null; + $secure = $cookieConf->secure ? filter_var($cookieConf->secure, FILTER_VALIDATE_BOOLEAN) : null; + $httponly = $cookieConf->httponly ? filter_var($cookieConf->httponly, FILTER_VALIDATE_BOOLEAN) : null; + + $cookie->set($name, $value, $period, $path, $domain, $secure, $httponly); + } + } + } + + /** + * Apply custom Cache-Control: max-age from db + * + * @param Mage_Core_Controller_Request_Http $request + * @param Mage_Core_Controller_Response_Http $response + */ + protected function _applyCustomMaxAgeFromDb(Mage_Core_Controller_Request_Http $request, + Mage_Core_Controller_Response_Http $response + ) { + // apply custom max-age from db + $urls = array($request->getRequestUri()); + $alias = $request->getAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS); + if ($alias) { + $urls[] = $alias; + } + /** @var $customUrlModel Aoe_Static_Model_CustomUrl */ + $customUrlModel = Mage::getModel('aoestatic/customUrl'); + $customUrlModel->loadByRequestPath($urls); + + if ($customUrlModel->getId() && $customUrlModel->getMaxAge()) { + $response->setHeader('Cache-Control', 'max-age=' . (int) $customUrlModel->getMaxAge(), true); + $response->setHeader('X-Magento-Lifetime', (int) $customUrlModel->getMaxAge(), true); + $response->setHeader('aoestatic', 'cache', true); + } + } + + /** + * Add layout handle 'aoestatic_cacheable' or 'aoestatic_notcacheable' + * + * @param Varien_Event_Observer $observer + */ + public function beforeLoadLayout(Varien_Event_Observer $observer) + { + $event = $observer->getEvent(); + /* @var $event Varien_Event */ + $controllerAction = $event->getAction(); + /* @var $controllerAction Mage_Core_Controller_Varien_Action */ + $fullActionName = $controllerAction->getFullActionName(); + + $conf = $this->_config->getActionConfiguration($fullActionName); + + $handle = $conf ? 'aoestatic_cacheable' : 'aoestatic_notcacheable'; + + $observer->getEvent()->getLayout()->getUpdate()->addHandle($handle); + } } diff --git a/code/Model/Resource/CustomUrl.php b/code/Model/Resource/CustomUrl.php new file mode 100644 index 0000000..d8f2d92 --- /dev/null +++ b/code/Model/Resource/CustomUrl.php @@ -0,0 +1,108 @@ + + */ +class Aoe_Static_Model_Resource_CustomUrl extends Mage_Core_Model_Resource_Db_Abstract +{ + protected function _construct() + { + $this->_init('aoestatic/custom_url', 'custom_url_id'); + } + + /** + * Initialize array fields + * + * @return $this + */ + protected function _initUniqueFields() + { + $this->_uniqueFields = array( + array( + 'field' => array('request_path','store_id'), + 'title' => Mage::helper('core')->__('Request Path for Specified Store'), + ) + ); + return $this; + } + + /** + * Retrieve select object for load object data + * + * @param string $field + * @param mixed $value + * @param Aoe_Static_Model_CustomUrl $object + * @return Zend_Db_Select + */ + protected function _getLoadSelect($field, $value, $object) + { + /** @var $select Varien_Db_Select */ + $select = parent::_getLoadSelect($field, $value, $object); + + if (!is_null($object->getStoreId())) { + $select->where('store_id IN(?)', array(Mage_Core_Model_App::ADMIN_STORE_ID, $object->getStoreId())); + $select->order('store_id ' . Varien_Db_Select::SQL_DESC); + $select->limit(1); + } + + return $select; + } + + /** + * Load max-age information for given custom url + * If $path is array - we must load all possible records and choose one matching earlier record in array + * + * @param Aoe_Static_Model_CustomUrl $object + * @param array|string $path + * @return $this + */ + public function loadByRequestPath(Aoe_Static_Model_CustomUrl $object, $path) + { + if (!is_array($path)) { + $path = array($path); + } + + $pathBind = array(); + foreach ($path as $key => $url) { + $pathBind['path' . $key] = $url; + } + // Form select + $adapter = $this->_getReadAdapter(); + $select = $adapter->select() + ->from($this->getMainTable()) + ->where('request_path IN (:' . implode(', :', array_flip($pathBind)) . ')') + ->where('store_id IN(?)', array(Mage_Core_Model_App::ADMIN_STORE_ID, (int)$object->getStoreId())); + + $items = $adapter->fetchAll($select, $pathBind); + + // Go through all found records and choose one with lowest penalty - earlier path in array, concrete store + $mapPenalty = array_flip(array_values($path)); // we got mapping array(path => index), lower index - better + $currentPenalty = null; + $foundItem = null; + foreach ($items as $item) { + if (!array_key_exists($item['request_path'], $mapPenalty)) { + continue; + } + $penalty = $mapPenalty[$item['request_path']] << 1 + ($item['store_id'] ? 0 : 1); + if (!$foundItem || $currentPenalty > $penalty) { + $foundItem = $item; + $currentPenalty = $penalty; + if (!$currentPenalty) { + break; // Found best matching item with zero penalty, no reason to continue + } + } + } + + // Set data and finish loading + if ($foundItem) { + $object->setData($foundItem); + } + + // Finish + $this->unserializeFields($object); + $this->_afterLoad($object); + + return $this; + } +} diff --git a/code/Model/Resource/CustomUrl/Collection.php b/code/Model/Resource/CustomUrl/Collection.php new file mode 100644 index 0000000..918eb57 --- /dev/null +++ b/code/Model/Resource/CustomUrl/Collection.php @@ -0,0 +1,34 @@ + + */ +class Aoe_Static_Model_Resource_CustomUrl_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract +{ + protected function _construct() + { + $this->_init('aoestatic/customUrl'); + } + + /** + * Filter collections by stores + * + * @param mixed $store + * @param bool $withAdmin + * @return $this + */ + public function addStoreFilter($store, $withAdmin = true) + { + if (!is_array($store)) { + $store = array(Mage::app()->getStore($store)->getId()); + } + if ($withAdmin) { + $store[] = 0; + } + + $this->addFieldToFilter('store_id', array('in' => $store)); + + return $this; + } +} diff --git a/code/controllers/Adminhtml/Aoestatic/CustomUrlController.php b/code/controllers/Adminhtml/Aoestatic/CustomUrlController.php new file mode 100755 index 0000000..91450a4 --- /dev/null +++ b/code/controllers/Adminhtml/Aoestatic/CustomUrlController.php @@ -0,0 +1,216 @@ + + */ +class Aoe_Static_Adminhtml_Aoestatic_CustomUrlController extends Mage_Adminhtml_Controller_Action +{ + /** + * Init actions + * + * @return $this + */ + protected function _initAction() + { + // load layout, set active menu and breadcrumbs + $this->loadLayout() + ->_setActiveMenu('system/aoestatic_customUrl') + ->_addBreadcrumb( + Mage::helper('aoestatic')->__('System'), + Mage::helper('aoestatic')->__('System') + ) + ->_addBreadcrumb( + Mage::helper('aoestatic')->__('Urls max-age management'), + Mage::helper('aoestatic')->__('Urls max-age management') + ); + return $this; + } + + /** + * Index action + */ + public function indexAction() + { + $this->_title($this->__('System')) + ->_title($this->__('Urls max-age management')); + + $this->_initAction(); + $this->renderLayout(); + } + + /** + * Create new custom url + */ + public function newAction() + { + // the same form is used to create and edit + $this->_forward('edit'); + } + + /** + * Edit custom url + */ + public function editAction() + { + $this->_title($this->__('System')) + ->_title($this->__('Urls max-age management')); + + /** @var $model Aoe_Static_Model_CustomUrl */ + $model = Mage::getModel('aoestatic/customUrl'); + + $customUrlId = $this->getRequest()->getParam('id'); + if ($customUrlId) { + $model->load($customUrlId); + + if (!$model->getId()) { + $this->_getSession()->addError( + Mage::helper('aoestatic')->__('Custom url does not exist.') + ); + $this->_redirect('*/*/'); + return; + } + // prepare title + $breadCrumb = Mage::helper('aoestatic')->__('Edit custom url (ID: %d)', $model->getId()); + } else { + $breadCrumb = Mage::helper('aoestatic')->__('New Item'); + } + + // Init breadcrumbs + $this->_title($breadCrumb); + $this->_initAction()->_addBreadcrumb($breadCrumb, $breadCrumb); + + $data = Mage::getSingleton('adminhtml/session')->getFormData(true); + if (!empty($data)) { + $model->addData($data); + } + + Mage::register('custom_url', $model); + + $this->renderLayout(); + } + + /** + * Save action + */ + public function saveAction() + { + $redirectPath = '*/*'; + $redirectParams = array(); + + // check if data sent + $data = $this->getRequest()->getPost(); + if ($data) { + // init model and set data + /** @var $model Aoe_Static_Model_CustomUrl */ + $model = Mage::getModel('aoestatic/customUrl'); + + // if custom url exists, try to load it + $customUrlId = $this->getRequest()->getParam('id'); + if ($customUrlId) { + $model->load($customUrlId); + } + + $model->addData($data); + + try { + $hasError = false; + + // save the data + $model->save(); + + // display success message + $this->_getSession()->addSuccess( + Mage::helper('aoestatic')->__('Custom url has been saved.') + ); + + // check if 'Save and Continue' + if ($this->getRequest()->getParam('back')) { + $redirectPath = '*/*/edit'; + $redirectParams = array('id' => $model->getId()); + } + } catch (Mage_Core_Exception $e) { + $hasError = true; + $this->_getSession()->addError($e->getMessage()); + } catch (Exception $e) { + $hasError = true; + $this->_getSession()->addException($e, + Mage::helper('aoestatic')->__('An error occurred while saving custom url.') + ); + } + + if ($hasError) { + $this->_getSession()->setFormData($data); + $redirectPath = '*/*/edit'; + $redirectParams = array('id' => $this->getRequest()->getParam('id')); + } + } + + $this->_redirect($redirectPath, $redirectParams); + } + + /** + * Delete action + */ + public function deleteAction() + { + // check if we know what should be deleted + $customUrlId = $this->getRequest()->getParam('id'); + if ($customUrlId) { + try { + // init model and delete + /** @var $model Aoe_Static_Model_CustomUrl */ + $model = Mage::getModel('aoestatic/customUrl'); + $model->load($customUrlId); + if (!$model->getId()) { + Mage::throwException(Mage::helper('aoestatic')->__('Unable to find a custom url.')); + } + $model->delete(); + + // display success message + $this->_getSession()->addSuccess( + Mage::helper('aoestatic')->__('Custom url has been deleted.') + ); + } catch (Mage_Core_Exception $e) { + $this->_getSession()->addError($e->getMessage()); + } catch (Exception $e) { + $this->_getSession()->addException($e, + Mage::helper('aoestatic')->__('An error occurred while deleting custom url.') + ); + } + } + + // go to grid + $this->_redirect('*/*/'); + } + + /** + * Check the permission to run it + * + * @return boolean + */ + protected function _isAllowed() + { + switch ($this->getRequest()->getActionName()) { + case 'new': + case 'save': + return Mage::getSingleton('admin/session')->isAllowed('system/aoestatic_customUrl/save'); + break; + case 'delete': + return Mage::getSingleton('admin/session')->isAllowed('system/aoestatic_customUrl/delete'); + break; + default: + return Mage::getSingleton('admin/session')->isAllowed('system/aoestatic_customUrl'); + break; + } + } + + /** + * Grid ajax action + */ + public function gridAction() + { + $this->loadLayout(); + $this->renderLayout(); + } +} diff --git a/code/etc/adminhtml.xml b/code/etc/adminhtml.xml new file mode 100755 index 0000000..d6c3d10 --- /dev/null +++ b/code/etc/adminhtml.xml @@ -0,0 +1,47 @@ + + + + + + + Urls max-age management + adminhtml/aoestatic_customUrl + 10 + + + + + + + + + + + + Manage Urls max-age + 0 + + + Save Url + 0 + + + Delete Url + 10 + + + + + + + Urls max-age management + + + + + + + + + + diff --git a/code/etc/config.xml b/code/etc/config.xml index e49b932..4862ea0 100644 --- a/code/etc/config.xml +++ b/code/etc/config.xml @@ -1,74 +1,108 @@ + + + true + local + 0.0.3 + + - - - true - local - 0.0.2 - - + + + + Aoe_Static_Block + + + + + Aoe_Static_Model + aoestatic_resource + + + Aoe_Static_Model_Resource + + + aoestatic_custom_url
+
+
+
+
+ + + Aoe_Static_Helper + + + + + + Aoe_Static + Mage_Core_Model_Resource_Setup + + + +
- - - - Aoe_Static_Block - - - - - Aoe_Static_Model - - - - - Aoe_Static_Helper - - - + + + + + aoestatic/aoestatic.xml + + + + + + standard + + Aoe_Static + phone + + + - - - - - aoestatic/aoestatic.xml - - - - - - standard - - Aoe_Static - phone - - - + + + + + + aoestatic/observer + processPreDispatch + + + - + + + + + aoestatic/observer + beforeLoadLayout + + + + + - - - - - aoestatic/observer - processPreDispatch - - - + + + + + + Aoe_Static_Adminhtml + + + + + - - - - - aoestatic/observer - beforeLoadLayout - - - - - - - - -
\ No newline at end of file + + + + + aoestatic/aoestatic.xml + + + + + diff --git a/code/sql/aoestatic_setup/install-0.0.3.php b/code/sql/aoestatic_setup/install-0.0.3.php new file mode 100644 index 0000000..f21887c --- /dev/null +++ b/code/sql/aoestatic_setup/install-0.0.3.php @@ -0,0 +1,41 @@ +startSetup(); + +/** + * Create table 'aoestatic/custom_url' + */ +$table = $installer->getConnection() + ->newTable($installer->getTable('aoestatic/custom_url')) + ->addColumn('custom_url_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array( + 'identity' => true, + 'unsigned' => true, + 'nullable' => false, + 'primary' => true, + ), 'Url Id' + ) + ->addColumn('store_id', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array( + 'unsigned' => true, + 'nullable' => false, + 'default' => '0', + ), 'Store Id' + ) + ->addColumn('request_path', Varien_Db_Ddl_Table::TYPE_TEXT, 255, array( + ), 'Request Path' + ) + ->addColumn('max_age', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array( + 'unsigned' => true, + 'nullable' => false, + 'default' => '0', + ), 'Url max-age' + ) + ->addIndex($installer->getIdxName('aoestatic/custom_url', array('request_path', 'store_id'), + Varien_Db_Adapter_Interface::INDEX_TYPE_UNIQUE), + array('request_path', 'store_id'), array('type' => Varien_Db_Adapter_Interface::INDEX_TYPE_UNIQUE) + ) + ->setComment('Urls with custom Cache-Control: max-age'); +$installer->getConnection()->createTable($table); + +$installer->endSetup(); diff --git a/modman b/modman index 9d9a585..48f2fa5 100644 --- a/modman +++ b/modman @@ -1,5 +1,7 @@ -code/ app/code/local/Aoe/Static/ -js/aoestatic/ js/aoestatic/ -frontend/layout/aoestatic/ app/design/frontend/base/default/layout/aoestatic/ -frontend/template/aoestatic/ app/design/frontend/base/default/template/aoestatic/ -Aoe_Static.xml app/etc/modules/Aoe_Static.xml \ No newline at end of file +code/ app/code/local/Aoe/Static/ +js/aoestatic/ js/aoestatic/ +frontend/layout/aoestatic/ app/design/frontend/base/default/layout/aoestatic/ +frontend/template/aoestatic/ app/design/frontend/base/default/template/aoestatic/ +adminhtml/layout/aoestatic/ app/design/adminhtml/default/default/layout/aoestatic/ +adminhtml/template/aoestatic/ app/design/adminhtml/default/default/template/aoestatic/ +Aoe_Static.xml app/etc/modules/Aoe_Static.xml From 802d6133970d90f1ca7c0b38181a2648e9feb3b0 Mon Sep 17 00:00:00 2001 From: Dmytro Zavalkin Date: Thu, 4 Apr 2013 14:03:09 +0300 Subject: [PATCH 014/136] MAGE-239: Varnish doesn't purge the GuidaTv page - removed empty folder adminhtml/template/aoestatic/ --- modman | 1 - 1 file changed, 1 deletion(-) diff --git a/modman b/modman index 48f2fa5..7c3d869 100644 --- a/modman +++ b/modman @@ -3,5 +3,4 @@ js/aoestatic/ js/aoestatic/ frontend/layout/aoestatic/ app/design/frontend/base/default/layout/aoestatic/ frontend/template/aoestatic/ app/design/frontend/base/default/template/aoestatic/ adminhtml/layout/aoestatic/ app/design/adminhtml/default/default/layout/aoestatic/ -adminhtml/template/aoestatic/ app/design/adminhtml/default/default/template/aoestatic/ Aoe_Static.xml app/etc/modules/Aoe_Static.xml From b070dd92e7a9805290a138b94f204538a90644f7 Mon Sep 17 00:00:00 2001 From: Dmytro Zavalkin Date: Tue, 9 Apr 2013 11:22:16 +0300 Subject: [PATCH 015/136] MAGE-239: Varnish doesn't purge the GuidaTv page - fixed bug with not set store id --- code/Model/Observer.php | 1 + 1 file changed, 1 insertion(+) diff --git a/code/Model/Observer.php b/code/Model/Observer.php index 35e1cde..5b24612 100644 --- a/code/Model/Observer.php +++ b/code/Model/Observer.php @@ -130,6 +130,7 @@ protected function _applyCustomMaxAgeFromDb(Mage_Core_Controller_Request_Http $r } /** @var $customUrlModel Aoe_Static_Model_CustomUrl */ $customUrlModel = Mage::getModel('aoestatic/customUrl'); + $customUrlModel->setStoreId(Mage::app()->getStore()->getId()); $customUrlModel->loadByRequestPath($urls); if ($customUrlModel->getId() && $customUrlModel->getMaxAge()) { From 5cb64b719b793f2e01bb6770beab476590949696 Mon Sep 17 00:00:00 2001 From: Daniel Zohm Date: Sat, 30 Mar 2013 17:57:41 +0100 Subject: [PATCH 016/136] used request string without params as identifier --- code/Model/Observer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/Model/Observer.php b/code/Model/Observer.php index 5b24612..941a917 100644 --- a/code/Model/Observer.php +++ b/code/Model/Observer.php @@ -123,7 +123,7 @@ protected function _applyCustomMaxAgeFromDb(Mage_Core_Controller_Request_Http $r Mage_Core_Controller_Response_Http $response ) { // apply custom max-age from db - $urls = array($request->getRequestUri()); + $urls = array($request->getRequestString()); $alias = $request->getAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS); if ($alias) { $urls[] = $alias; From 18da5cd40f217b457c7e885eb31165eab3035bf0 Mon Sep 17 00:00:00 2001 From: Tymoteusz Motylewski Date: Fri, 14 Jun 2013 13:47:42 +0100 Subject: [PATCH 017/136] Add possibility to register own markers for cookies and headers --- code/Model/Config.php | 32 ++++++++++++++- code/Model/Observer.php | 86 ++++++++++++++++++++++++++++++++++++----- code/etc/aoe_static.xml | 17 +++++--- code/etc/config.xml | 2 +- 4 files changed, 121 insertions(+), 16 deletions(-) diff --git a/code/Model/Config.php b/code/Model/Config.php index 55e5ad2..16dd3fd 100644 --- a/code/Model/Config.php +++ b/code/Model/Config.php @@ -8,18 +8,21 @@ class Aoe_Static_Model_Config extends Mage_Core_Model_Config_Base { * @var string */ const CACHE_ID = 'aoe_static_cache'; + /** * Tag name for cache type, used in mass cache cleaning * * @var string */ const CACHE_TAG = 'config'; + /** * Filename that will be collected from different modules * * @var string */ const CONFIGURATION_FILENAME = 'aoe_static.xml'; + /** * Initial configuration file template, then merged in one file * @@ -27,6 +30,8 @@ class Aoe_Static_Model_Config extends Mage_Core_Model_Config_Base { */ const CONFIGURATION_TEMPLATE = ''; + protected $markers = NULL; + /** * Class constructor * load cache configuration @@ -69,4 +74,29 @@ public function getActionConfiguration($fullActionName) { return $configuration; } -} + /** + * @return Varien_Simplexml_Element + */ + public function getMarkersCallbackConfiguration() { + if ($this->markers !== NULL) { + return $this->markers; + } + $this->markers = $this->getNode('aoe_static/default/markers'); + return $this->markers; + } + + /** + * Get callback string like some_module/fooclass::getValue for a given marker name + * @param $marker string + * @return string callback + */ + public function getMarkerCallback($marker) { + $callback = ''; + $configuration = $this->getMarkersCallbackConfiguration(); + $markerWithoutHash = str_replace('#', '',$marker); + if (isset($configuration->$markerWithoutHash->valueCallback)) { + $callback = (string)$configuration->$markerWithoutHash->valueCallback; + } + return $callback; + } +} \ No newline at end of file diff --git a/code/Model/Observer.php b/code/Model/Observer.php index 941a917..471d37f 100644 --- a/code/Model/Observer.php +++ b/code/Model/Observer.php @@ -14,6 +14,12 @@ class Aoe_Static_Model_Observer */ protected $_config; + /** + * Local cache for calculated values of markers + * @var null | array + */ + protected $markersValues = null; + /** * Constructor */ @@ -49,7 +55,7 @@ public function processPreDispatch(Varien_Event_Observer $observer) $customerName = Mage::helper('core')->escapeHtml($session->getCustomer()->getName()); } - $replace = array( + $this->markersValues = array( '###FULLACTIONNAME###' => $fullActionName, '###CUSTOMERNAME###' => $customerName, '###ISLOGGEDIN###' => $loggedIn, @@ -59,7 +65,7 @@ public function processPreDispatch(Varien_Event_Observer $observer) // apply default configuration in any case $defaultConf = $this->_config->getActionConfiguration('default'); if ($defaultConf) { - $this->applyConf($defaultConf, $response, $replace); + $this->applyConf($defaultConf, $response); } // check if there is a configured configuration for this full action name @@ -71,7 +77,7 @@ public function processPreDispatch(Varien_Event_Observer $observer) // apply the configuration if ($conf) { - $this->applyConf($conf, $response, $replace); + $this->applyConf($conf, $response); } $this->_applyCustomMaxAgeFromDb($controllerAction->getRequest(), $response); @@ -84,13 +90,10 @@ public function processPreDispatch(Varien_Event_Observer $observer) * * @param Mage_Core_Model_Config_Element $conf * @param Mage_Core_Controller_Response_Http $response - * @param array $replace */ - protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Controller_Response_Http $response, - array $replace - ) { + protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Controller_Response_Http $response) { foreach ($conf->headers->children() as $key => $value) { - $value = str_replace(array_keys($replace), array_values($replace), $value); + $value = $this->replaceMarkers($value); $response->setHeader($key, $value, true); } if ($conf->cookies) { @@ -101,7 +104,7 @@ protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Con continue; } $value = (string) $cookieConf->value; - $value = str_replace(array_keys($replace), array_values($replace), $value); + $value = $this->replaceMarkers($value); $period = $cookieConf->period ? (string) $cookieConf->period : null; $path = $cookieConf->path ? (string) $cookieConf->path : null; $domain = $cookieConf->domain ? (string) $cookieConf->domain : null; @@ -159,4 +162,69 @@ public function beforeLoadLayout(Varien_Event_Observer $observer) $observer->getEvent()->getLayout()->getUpdate()->addHandle($handle); } + + /** + * Replaces markers in the $value, saves calculated value to the local cache + * + * @param string $value + * @return string + */ + protected function replaceMarkers($value) { + $matches = array(); + preg_match_all('|###[^#]+###|', $value, $matches); + $markersWithoutValues = array_diff($matches[0], array_keys($this->markersValues)); + foreach($markersWithoutValues as $marker) { + $this->markersValues[$marker] = $this->getMarkerValue($marker); + } + $value = str_replace(array_keys($this->markersValues), array_values($this->markersValues), $value); + return $value; + } + + /** + * Returns value of a given marker + * + * @param string $marker + * @return string + */ + protected function getMarkerValue($marker) { + $markerValue = $marker; + if (isset($this->markersValues[$marker]) && $this->markersValues[$marker] !== NULL) { + $markerValue = $this->markersValues[$marker]; + } elseif ($this->_config->getMarkerCallback($marker)) { + $markerValue = $this->executeCallback($this->_config->getMarkerCallback($marker)); + } + return (string)$markerValue; + } + + /** + * Executes method defined in the marker callback configuration and returns the result + * + * @param string $callbackString + * @return mixed + */ + protected function executeCallback($callbackString) { + $result = ""; + try { + + if ($callbackString) { + if (!preg_match(Mage_Cron_Model_Observer::REGEX_RUN_MODEL, (string)$callbackString, $run)) { + Mage::throwException('Invalid model/method definition, expecting "model/class::method".'); + } + if (!($model = Mage::getModel($run[1])) || !method_exists($model, $run[2])) { + Mage::throwException('Invalid callback: %s::%s does not exist', $run[1], $run[2]); + } + $callback = array($model, $run[2]); + $arguments = array(); + } + if (empty($callback)) { + Mage::throwException(Mage::helper('cron')->__('No callbacks found for marker')); + } + + $result = call_user_func_array($callback, $arguments); + + } catch (Exception $e) { + Mage::logException($e); + } + return $result; + } } diff --git a/code/etc/aoe_static.xml b/code/etc/aoe_static.xml index 512d707..f7bdac0 100644 --- a/code/etc/aoe_static.xml +++ b/code/etc/aoe_static.xml @@ -37,11 +37,18 @@ --> - - - ###FULLACTIONNAME### - - + + + ###FULLACTIONNAME### + + + + + diff --git a/code/etc/config.xml b/code/etc/config.xml index 4862ea0..cd54ce8 100644 --- a/code/etc/config.xml +++ b/code/etc/config.xml @@ -4,7 +4,7 @@ true local - 0.0.3 + 0.0.4 From 0ceab3ca9c48ae0c64488418bc2897a25d498399 Mon Sep 17 00:00:00 2001 From: Tymoteusz Motylewski Date: Mon, 17 Jun 2013 12:02:32 +0100 Subject: [PATCH 018/136] [!!!] add cookies and headers in the postprocess event instead of preprocess --- code/Model/Observer.php | 4 ++-- code/etc/config.xml | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/code/Model/Observer.php b/code/Model/Observer.php index 471d37f..1b27c95 100644 --- a/code/Model/Observer.php +++ b/code/Model/Observer.php @@ -29,12 +29,12 @@ public function __construct() } /** - * Check when varnish caching should be enabled. + * Set custom headers and cookies * * @param Varien_Event_Observer $observer * @return Aoe_Static_Model_Observer */ - public function processPreDispatch(Varien_Event_Observer $observer) + public function processPostDispatch(Varien_Event_Observer $observer) { /* @var $event Varien_Event */ $event = $observer->getEvent(); diff --git a/code/etc/config.xml b/code/etc/config.xml index cd54ce8..042c5ff 100644 --- a/code/etc/config.xml +++ b/code/etc/config.xml @@ -4,7 +4,7 @@ true local - 0.0.4 + 0.0.5 @@ -63,14 +63,14 @@ - + aoestatic/observer - processPreDispatch + processPostDispatch - + From cdf72d2c352488a080cb4af20089ae41a05bd48f Mon Sep 17 00:00:00 2001 From: Dmytro Zavalkin Date: Tue, 18 Jun 2013 13:48:34 +0200 Subject: [PATCH 019/136] removed bogus acl node --- code/etc/adminhtml.xml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/code/etc/adminhtml.xml b/code/etc/adminhtml.xml index d6c3d10..e56a0f5 100755 --- a/code/etc/adminhtml.xml +++ b/code/etc/adminhtml.xml @@ -31,13 +31,6 @@ - - - - Urls max-age management - - - From 0897bfeae600a66e3a0fd024c2b4f4d6f5502299 Mon Sep 17 00:00:00 2001 From: Dmytro Zavalkin Date: Tue, 18 Jun 2013 14:00:24 +0200 Subject: [PATCH 020/136] fixed translation helper name --- code/Model/Resource/CustomUrl.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/Model/Resource/CustomUrl.php b/code/Model/Resource/CustomUrl.php index d8f2d92..11eff6b 100644 --- a/code/Model/Resource/CustomUrl.php +++ b/code/Model/Resource/CustomUrl.php @@ -21,7 +21,7 @@ protected function _initUniqueFields() $this->_uniqueFields = array( array( 'field' => array('request_path','store_id'), - 'title' => Mage::helper('core')->__('Request Path for Specified Store'), + 'title' => Mage::helper('aoestatic')->__('Request Path for Specified Store'), ) ); return $this; From a5c18847ee3d9fe8619a366fcfb46b07008cd20a Mon Sep 17 00:00:00 2001 From: Dmytro Zavalkin Date: Tue, 18 Jun 2013 17:33:28 +0200 Subject: [PATCH 021/136] added mass actions block and actions column --- code/Block/Adminhtml/CustomUrl/Grid.php | 50 ++++++++++++++++--- .../Aoestatic/CustomUrlController.php | 28 +++++++++++ 2 files changed, 72 insertions(+), 6 deletions(-) diff --git a/code/Block/Adminhtml/CustomUrl/Grid.php b/code/Block/Adminhtml/CustomUrl/Grid.php index 50050c5..7e76cda 100755 --- a/code/Block/Adminhtml/CustomUrl/Grid.php +++ b/code/Block/Adminhtml/CustomUrl/Grid.php @@ -50,14 +50,14 @@ public function getRowUrl($row) protected function _prepareColumns() { $this->addColumn('custom_url_id', array( - 'header' => $this->__('ID'), - 'width' => '50px', + 'header' => Mage::helper('aoestatic')->__('ID'), + 'width' => '10px', 'index' => 'custom_url_id' )); if (!Mage::app()->isSingleStoreMode()) { $this->addColumn('store_id', array( - 'header' => $this->__('Store View'), + 'header' => Mage::helper('aoestatic')->__('Store View'), 'width' => '200px', 'index' => 'store_id', 'type' => 'store', @@ -66,19 +66,57 @@ protected function _prepareColumns() } $this->addColumn('request_path', array( - 'header' => $this->__('Request Path'), - 'width' => '50px', + 'header' => Mage::helper('aoestatic')->__('Request Path'), + 'width' => '80%', 'index' => 'request_path' )); $this->addColumn('max_age', array( - 'header' => $this->__('Max Age'), + 'header' => Mage::helper('aoestatic')->__('Max Age'), 'width' => '50px', 'index' => 'max_age' )); + $this->addColumn('action', + array( + 'header' => Mage::helper('aoestatic')->__('Actions'), + 'width' => '50px', + 'type' => 'action', + 'getter' => 'getId', + 'actions' => array( + array( + 'caption' => Mage::helper('aoestatic')->__('Delete'), + 'url' => array( + 'base' => '*/*/delete', + ), + 'field' => 'id', + 'confirm' => Mage::helper('aoestatic')->__('Are you sure you want to delete custom url?') + ) + ), + 'filter' => false, + 'sortable' => false, + ) + ); + return parent::_prepareColumns(); } + /** + * Prepare grid massaction actions + * + * @return $this + */ + protected function _prepareMassaction() + { + $this->setMassactionIdField('custom_url_id'); + $this->getMassactionBlock()->setFormFieldName('custom_url_ids'); + $this->getMassactionBlock()->addItem('delete', array( + 'label' => Mage::helper('aoestatic')->__('Delete'), + 'url' => $this->getUrl('*/*/massDelete'), + 'confirm' => Mage::helper('aoestatic')->__('Are you sure you want delete selected custom url(s)?') + )); + + return $this; + } /** * Grid url getter * diff --git a/code/controllers/Adminhtml/Aoestatic/CustomUrlController.php b/code/controllers/Adminhtml/Aoestatic/CustomUrlController.php index 91450a4..a48e257 100755 --- a/code/controllers/Adminhtml/Aoestatic/CustomUrlController.php +++ b/code/controllers/Adminhtml/Aoestatic/CustomUrlController.php @@ -213,4 +213,32 @@ public function gridAction() $this->loadLayout(); $this->renderLayout(); } + + /** + * Mass delete action + */ + public function massDeleteAction() + { + $customUrlIds = $this->getRequest()->getParam('custom_url_ids'); + if (!is_array($customUrlIds)) { + $this->_getSession()->addError( + Mage::helper('aoestatic')->__('Please select custom url(s) to delete.') + ); + } else { + if (!empty($customUrlIds)) { + try { + foreach ($customUrlIds as $customUrlId) { + Mage::getModel('aoestatic/customUrl')->setId($customUrlId) + ->delete(); + } + $this->_getSession()->addSuccess( + Mage::helper('aoestatic')->__('Total of %d custom url(s) have been deleted.', count($customUrlIds)) + ); + } catch (Exception $e) { + $this->_getSession()->addError(Mage::helper('aoestatic')->__($e->getMessage())); + } + } + } + $this->_redirectReferer(); + } } From 6cc04a0b5f74541b58ebbf1f063e5c3410429d2b Mon Sep 17 00:00:00 2001 From: Dmytro Zavalkin Date: Tue, 18 Jun 2013 17:41:48 +0200 Subject: [PATCH 022/136] fixed exception handler in massDeleteAction() --- .../controllers/Adminhtml/Aoestatic/CustomUrlController.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/controllers/Adminhtml/Aoestatic/CustomUrlController.php b/code/controllers/Adminhtml/Aoestatic/CustomUrlController.php index a48e257..5b0f396 100755 --- a/code/controllers/Adminhtml/Aoestatic/CustomUrlController.php +++ b/code/controllers/Adminhtml/Aoestatic/CustomUrlController.php @@ -234,8 +234,12 @@ public function massDeleteAction() $this->_getSession()->addSuccess( Mage::helper('aoestatic')->__('Total of %d custom url(s) have been deleted.', count($customUrlIds)) ); + } catch (Mage_Core_Exception $e) { + $this->_getSession()->addError($e->getMessage()); } catch (Exception $e) { - $this->_getSession()->addError(Mage::helper('aoestatic')->__($e->getMessage())); + $this->_getSession()->addException($e, + Mage::helper('aoestatic')->__('An error occurred while deleting custom url(s).') + ); } } } From 3d9b41ad6ed80c37fb20dc64e7f4bc439da802e6 Mon Sep 17 00:00:00 2001 From: Dmytro Zavalkin Date: Wed, 19 Jun 2013 10:01:29 +0200 Subject: [PATCH 023/136] fixed mass delete implementation --- code/Model/CustomUrl.php | 11 +++++++++++ code/Model/Resource/CustomUrl.php | 15 +++++++++++++++ .../Adminhtml/Aoestatic/CustomUrlController.php | 7 +++---- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/code/Model/CustomUrl.php b/code/Model/CustomUrl.php index 24aed30..b07af42 100644 --- a/code/Model/CustomUrl.php +++ b/code/Model/CustomUrl.php @@ -36,4 +36,15 @@ public function loadByRequestPath($path) $this->_hasDataChanges = false; return $this; } + + /** + * Delete custom urls with given ids + * + * @param array $customUrlIds + * @return $this + */ + public function deleteCustomUrls(array $customUrlIds) + { + $this->getResource()->deleteCustomUrls($customUrlIds); + } } diff --git a/code/Model/Resource/CustomUrl.php b/code/Model/Resource/CustomUrl.php index 11eff6b..f32800d 100644 --- a/code/Model/Resource/CustomUrl.php +++ b/code/Model/Resource/CustomUrl.php @@ -105,4 +105,19 @@ public function loadByRequestPath(Aoe_Static_Model_CustomUrl $object, $path) return $this; } + + /** + * Delete custom urls with given ids + * + * @param array $customUrlIds + * @return $this + */ + public function deleteCustomUrls(array $customUrlIds) + { + $this->_getWriteAdapter()->delete($this->getMainTable(), + array('custom_url_id IN(?)' => $customUrlIds) + ); + + return $this; + } } diff --git a/code/controllers/Adminhtml/Aoestatic/CustomUrlController.php b/code/controllers/Adminhtml/Aoestatic/CustomUrlController.php index 5b0f396..30d9edc 100755 --- a/code/controllers/Adminhtml/Aoestatic/CustomUrlController.php +++ b/code/controllers/Adminhtml/Aoestatic/CustomUrlController.php @@ -227,10 +227,9 @@ public function massDeleteAction() } else { if (!empty($customUrlIds)) { try { - foreach ($customUrlIds as $customUrlId) { - Mage::getModel('aoestatic/customUrl')->setId($customUrlId) - ->delete(); - } + /** @var Aoe_Static_Model_CustomUrl $customUrlModel */ + $customUrlModel = Mage::getModel('aoestatic/customUrl'); + $customUrlModel->deleteCustomUrls($customUrlIds); $this->_getSession()->addSuccess( Mage::helper('aoestatic')->__('Total of %d custom url(s) have been deleted.', count($customUrlIds)) ); From 40631c742f26705b568d844037c9002fde432fbb Mon Sep 17 00:00:00 2001 From: Daniel Zohm Date: Fri, 26 Jul 2013 09:18:26 +0200 Subject: [PATCH 024/136] MAGE-471: added check, which skips caching headers if messages should be printed on current page --- code/Model/Observer.php | 104 ++++++++++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 35 deletions(-) diff --git a/code/Model/Observer.php b/code/Model/Observer.php index 1b27c95..062c277 100644 --- a/code/Model/Observer.php +++ b/code/Model/Observer.php @@ -20,6 +20,12 @@ class Aoe_Static_Model_Observer */ protected $markersValues = null; + /** + * Indicates, if there are messages to show on the current page + * @var bool + */ + protected $messagesToShow = false; + /** * Constructor */ @@ -36,6 +42,9 @@ public function __construct() */ public function processPostDispatch(Varien_Event_Observer $observer) { + // check if we have messages to display + $this->messagesToShow = $this->checkForMessages(); + /* @var $event Varien_Event */ $event = $observer->getEvent(); /* @var $controllerAction Mage_Core_Controller_Varien_Action */ @@ -91,27 +100,30 @@ public function processPostDispatch(Varien_Event_Observer $observer) * @param Mage_Core_Model_Config_Element $conf * @param Mage_Core_Controller_Response_Http $response */ - protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Controller_Response_Http $response) { - foreach ($conf->headers->children() as $key => $value) { - $value = $this->replaceMarkers($value); - $response->setHeader($key, $value, true); - } - if ($conf->cookies) { - $cookie = Mage::getModel('core/cookie'); - /* @var $cookie Mage_Core_Model_Cookie */ - foreach ($conf->cookies->children() as $name => $cookieConf) { - if (1 == $cookieConf->disabled) { - continue; + protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Controller_Response_Http $response) + { + if (!$this->messagesToShow) { + foreach ($conf->headers->children() as $key => $value) { + $value = $this->replaceMarkers($value); + $response->setHeader($key, $value, true); + } + if ($conf->cookies) { + $cookie = Mage::getModel('core/cookie'); + /* @var $cookie Mage_Core_Model_Cookie */ + foreach ($conf->cookies->children() as $name => $cookieConf) { + if (1 == $cookieConf->disabled) { + continue; + } + $value = (string) $cookieConf->value; + $value = $this->replaceMarkers($value); + $period = $cookieConf->period ? (string) $cookieConf->period : null; + $path = $cookieConf->path ? (string) $cookieConf->path : null; + $domain = $cookieConf->domain ? (string) $cookieConf->domain : null; + $secure = $cookieConf->secure ? filter_var($cookieConf->secure, FILTER_VALIDATE_BOOLEAN) : null; + $httponly = $cookieConf->httponly ? filter_var($cookieConf->httponly, FILTER_VALIDATE_BOOLEAN) : null; + + $cookie->set($name, $value, $period, $path, $domain, $secure, $httponly); } - $value = (string) $cookieConf->value; - $value = $this->replaceMarkers($value); - $period = $cookieConf->period ? (string) $cookieConf->period : null; - $path = $cookieConf->path ? (string) $cookieConf->path : null; - $domain = $cookieConf->domain ? (string) $cookieConf->domain : null; - $secure = $cookieConf->secure ? filter_var($cookieConf->secure, FILTER_VALIDATE_BOOLEAN) : null; - $httponly = $cookieConf->httponly ? filter_var($cookieConf->httponly, FILTER_VALIDATE_BOOLEAN) : null; - - $cookie->set($name, $value, $period, $path, $domain, $secure, $httponly); } } } @@ -125,21 +137,23 @@ protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Con protected function _applyCustomMaxAgeFromDb(Mage_Core_Controller_Request_Http $request, Mage_Core_Controller_Response_Http $response ) { - // apply custom max-age from db - $urls = array($request->getRequestString()); - $alias = $request->getAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS); - if ($alias) { - $urls[] = $alias; - } - /** @var $customUrlModel Aoe_Static_Model_CustomUrl */ - $customUrlModel = Mage::getModel('aoestatic/customUrl'); - $customUrlModel->setStoreId(Mage::app()->getStore()->getId()); - $customUrlModel->loadByRequestPath($urls); - - if ($customUrlModel->getId() && $customUrlModel->getMaxAge()) { - $response->setHeader('Cache-Control', 'max-age=' . (int) $customUrlModel->getMaxAge(), true); - $response->setHeader('X-Magento-Lifetime', (int) $customUrlModel->getMaxAge(), true); - $response->setHeader('aoestatic', 'cache', true); + if (!$this->messagesToShow) { + // apply custom max-age from db + $urls = array($request->getRequestString()); + $alias = $request->getAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS); + if ($alias) { + $urls[] = $alias; + } + /** @var $customUrlModel Aoe_Static_Model_CustomUrl */ + $customUrlModel = Mage::getModel('aoestatic/customUrl'); + $customUrlModel->setStoreId(Mage::app()->getStore()->getId()); + $customUrlModel->loadByRequestPath($urls); + + if ($customUrlModel->getId() && $customUrlModel->getMaxAge()) { + $response->setHeader('Cache-Control', 'max-age=' . (int) $customUrlModel->getMaxAge(), true); + $response->setHeader('X-Magento-Lifetime', (int) $customUrlModel->getMaxAge(), true); + $response->setHeader('aoestatic', 'cache', true); + } } } @@ -150,6 +164,9 @@ protected function _applyCustomMaxAgeFromDb(Mage_Core_Controller_Request_Http $r */ public function beforeLoadLayout(Varien_Event_Observer $observer) { + // check if we have messages to display + $this->messagesToShow = $this->checkForMessages(); + $event = $observer->getEvent(); /* @var $event Varien_Event */ $controllerAction = $event->getAction(); @@ -227,4 +244,21 @@ protected function executeCallback($callbackString) { } return $result; } + + /** + * Checks if there are messages to display + * + * @return bool + */ + protected function checkForMessages() + { + if ( + (false === $this->messagesToShow) && + (Mage::app()->getLayout()->getMessagesBlock()->getMessageCollection()->count() > 0) + ) { + $this->messagesToShow = true; + } + + return $this->messagesToShow; + } } From 85299f69bce974dac22a7b77cdd740d562337ce2 Mon Sep 17 00:00:00 2001 From: Dmytro Zavalkin Date: Fri, 26 Jul 2013 16:41:40 +0200 Subject: [PATCH 025/136] MAGE-471: added check, which skips caching headers if messages should be printed on current page - reverted commit committed by mistake to the master branch --- code/Model/Observer.php | 104 ++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 69 deletions(-) diff --git a/code/Model/Observer.php b/code/Model/Observer.php index 062c277..1b27c95 100644 --- a/code/Model/Observer.php +++ b/code/Model/Observer.php @@ -20,12 +20,6 @@ class Aoe_Static_Model_Observer */ protected $markersValues = null; - /** - * Indicates, if there are messages to show on the current page - * @var bool - */ - protected $messagesToShow = false; - /** * Constructor */ @@ -42,9 +36,6 @@ public function __construct() */ public function processPostDispatch(Varien_Event_Observer $observer) { - // check if we have messages to display - $this->messagesToShow = $this->checkForMessages(); - /* @var $event Varien_Event */ $event = $observer->getEvent(); /* @var $controllerAction Mage_Core_Controller_Varien_Action */ @@ -100,30 +91,27 @@ public function processPostDispatch(Varien_Event_Observer $observer) * @param Mage_Core_Model_Config_Element $conf * @param Mage_Core_Controller_Response_Http $response */ - protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Controller_Response_Http $response) - { - if (!$this->messagesToShow) { - foreach ($conf->headers->children() as $key => $value) { - $value = $this->replaceMarkers($value); - $response->setHeader($key, $value, true); - } - if ($conf->cookies) { - $cookie = Mage::getModel('core/cookie'); - /* @var $cookie Mage_Core_Model_Cookie */ - foreach ($conf->cookies->children() as $name => $cookieConf) { - if (1 == $cookieConf->disabled) { - continue; - } - $value = (string) $cookieConf->value; - $value = $this->replaceMarkers($value); - $period = $cookieConf->period ? (string) $cookieConf->period : null; - $path = $cookieConf->path ? (string) $cookieConf->path : null; - $domain = $cookieConf->domain ? (string) $cookieConf->domain : null; - $secure = $cookieConf->secure ? filter_var($cookieConf->secure, FILTER_VALIDATE_BOOLEAN) : null; - $httponly = $cookieConf->httponly ? filter_var($cookieConf->httponly, FILTER_VALIDATE_BOOLEAN) : null; - - $cookie->set($name, $value, $period, $path, $domain, $secure, $httponly); + protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Controller_Response_Http $response) { + foreach ($conf->headers->children() as $key => $value) { + $value = $this->replaceMarkers($value); + $response->setHeader($key, $value, true); + } + if ($conf->cookies) { + $cookie = Mage::getModel('core/cookie'); + /* @var $cookie Mage_Core_Model_Cookie */ + foreach ($conf->cookies->children() as $name => $cookieConf) { + if (1 == $cookieConf->disabled) { + continue; } + $value = (string) $cookieConf->value; + $value = $this->replaceMarkers($value); + $period = $cookieConf->period ? (string) $cookieConf->period : null; + $path = $cookieConf->path ? (string) $cookieConf->path : null; + $domain = $cookieConf->domain ? (string) $cookieConf->domain : null; + $secure = $cookieConf->secure ? filter_var($cookieConf->secure, FILTER_VALIDATE_BOOLEAN) : null; + $httponly = $cookieConf->httponly ? filter_var($cookieConf->httponly, FILTER_VALIDATE_BOOLEAN) : null; + + $cookie->set($name, $value, $period, $path, $domain, $secure, $httponly); } } } @@ -137,23 +125,21 @@ protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Con protected function _applyCustomMaxAgeFromDb(Mage_Core_Controller_Request_Http $request, Mage_Core_Controller_Response_Http $response ) { - if (!$this->messagesToShow) { - // apply custom max-age from db - $urls = array($request->getRequestString()); - $alias = $request->getAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS); - if ($alias) { - $urls[] = $alias; - } - /** @var $customUrlModel Aoe_Static_Model_CustomUrl */ - $customUrlModel = Mage::getModel('aoestatic/customUrl'); - $customUrlModel->setStoreId(Mage::app()->getStore()->getId()); - $customUrlModel->loadByRequestPath($urls); - - if ($customUrlModel->getId() && $customUrlModel->getMaxAge()) { - $response->setHeader('Cache-Control', 'max-age=' . (int) $customUrlModel->getMaxAge(), true); - $response->setHeader('X-Magento-Lifetime', (int) $customUrlModel->getMaxAge(), true); - $response->setHeader('aoestatic', 'cache', true); - } + // apply custom max-age from db + $urls = array($request->getRequestString()); + $alias = $request->getAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS); + if ($alias) { + $urls[] = $alias; + } + /** @var $customUrlModel Aoe_Static_Model_CustomUrl */ + $customUrlModel = Mage::getModel('aoestatic/customUrl'); + $customUrlModel->setStoreId(Mage::app()->getStore()->getId()); + $customUrlModel->loadByRequestPath($urls); + + if ($customUrlModel->getId() && $customUrlModel->getMaxAge()) { + $response->setHeader('Cache-Control', 'max-age=' . (int) $customUrlModel->getMaxAge(), true); + $response->setHeader('X-Magento-Lifetime', (int) $customUrlModel->getMaxAge(), true); + $response->setHeader('aoestatic', 'cache', true); } } @@ -164,9 +150,6 @@ protected function _applyCustomMaxAgeFromDb(Mage_Core_Controller_Request_Http $r */ public function beforeLoadLayout(Varien_Event_Observer $observer) { - // check if we have messages to display - $this->messagesToShow = $this->checkForMessages(); - $event = $observer->getEvent(); /* @var $event Varien_Event */ $controllerAction = $event->getAction(); @@ -244,21 +227,4 @@ protected function executeCallback($callbackString) { } return $result; } - - /** - * Checks if there are messages to display - * - * @return bool - */ - protected function checkForMessages() - { - if ( - (false === $this->messagesToShow) && - (Mage::app()->getLayout()->getMessagesBlock()->getMessageCollection()->count() > 0) - ) { - $this->messagesToShow = true; - } - - return $this->messagesToShow; - } } From dd2ea56d9d68ae2cc2077c7fc837dc41af4985b0 Mon Sep 17 00:00:00 2001 From: Daniel Zohm Date: Wed, 4 Sep 2013 17:13:03 +0200 Subject: [PATCH 026/136] MAGE-471: added slightly modified changes again --- code/Model/Observer.php | 70 +++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 17 deletions(-) diff --git a/code/Model/Observer.php b/code/Model/Observer.php index 1b27c95..4d07b5f 100644 --- a/code/Model/Observer.php +++ b/code/Model/Observer.php @@ -20,6 +20,12 @@ class Aoe_Static_Model_Observer */ protected $markersValues = null; + /** + * Indicates, if there are messages to show on the current page + * @var bool + */ + protected $messagesToShow = false; + /** * Constructor */ @@ -36,6 +42,9 @@ public function __construct() */ public function processPostDispatch(Varien_Event_Observer $observer) { + // check if we have messages to display + $this->messagesToShow = $this->checkForMessages(); + /* @var $event Varien_Event */ $event = $observer->getEvent(); /* @var $controllerAction Mage_Core_Controller_Varien_Action */ @@ -91,8 +100,13 @@ public function processPostDispatch(Varien_Event_Observer $observer) * @param Mage_Core_Model_Config_Element $conf * @param Mage_Core_Controller_Response_Http $response */ - protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Controller_Response_Http $response) { + protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Controller_Response_Http $response) + { foreach ($conf->headers->children() as $key => $value) { + // skip aoestatic header if we have messages to display + if ($this->messagesToShow && ($key == 'aoestatic')) { + continue; + } $value = $this->replaceMarkers($value); $response->setHeader($key, $value, true); } @@ -123,23 +137,25 @@ protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Con * @param Mage_Core_Controller_Response_Http $response */ protected function _applyCustomMaxAgeFromDb(Mage_Core_Controller_Request_Http $request, - Mage_Core_Controller_Response_Http $response + Mage_Core_Controller_Response_Http $response ) { - // apply custom max-age from db - $urls = array($request->getRequestString()); - $alias = $request->getAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS); - if ($alias) { - $urls[] = $alias; - } - /** @var $customUrlModel Aoe_Static_Model_CustomUrl */ - $customUrlModel = Mage::getModel('aoestatic/customUrl'); - $customUrlModel->setStoreId(Mage::app()->getStore()->getId()); - $customUrlModel->loadByRequestPath($urls); - - if ($customUrlModel->getId() && $customUrlModel->getMaxAge()) { - $response->setHeader('Cache-Control', 'max-age=' . (int) $customUrlModel->getMaxAge(), true); - $response->setHeader('X-Magento-Lifetime', (int) $customUrlModel->getMaxAge(), true); - $response->setHeader('aoestatic', 'cache', true); + if (!$this->messagesToShow) { + // apply custom max-age from db + $urls = array($request->getRequestString()); + $alias = $request->getAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS); + if ($alias) { + $urls[] = $alias; + } + /** @var $customUrlModel Aoe_Static_Model_CustomUrl */ + $customUrlModel = Mage::getModel('aoestatic/customUrl'); + $customUrlModel->setStoreId(Mage::app()->getStore()->getId()); + $customUrlModel->loadByRequestPath($urls); + + if ($customUrlModel->getId() && $customUrlModel->getMaxAge()) { + $response->setHeader('Cache-Control', 'max-age=' . (int) $customUrlModel->getMaxAge(), true); + $response->setHeader('X-Magento-Lifetime', (int) $customUrlModel->getMaxAge(), true); + $response->setHeader('aoestatic', 'cache', true); + } } } @@ -150,6 +166,9 @@ protected function _applyCustomMaxAgeFromDb(Mage_Core_Controller_Request_Http $r */ public function beforeLoadLayout(Varien_Event_Observer $observer) { + // check if we have messages to display + $this->messagesToShow = $this->checkForMessages(); + $event = $observer->getEvent(); /* @var $event Varien_Event */ $controllerAction = $event->getAction(); @@ -227,4 +246,21 @@ protected function executeCallback($callbackString) { } return $result; } + + /** + * Checks if there are messages to display + * + * @return bool + */ + protected function checkForMessages() + { + if ( + (false === $this->messagesToShow) && + (Mage::app()->getLayout()->getMessagesBlock()->getMessageCollection()->count() > 0) + ) { + $this->messagesToShow = true; + } + + return $this->messagesToShow; + } } From 12f7db09393506aa1c99d94fc3252ff4e0bd467f Mon Sep 17 00:00:00 2001 From: Bastian Ike Date: Thu, 7 Nov 2013 12:55:56 +0100 Subject: [PATCH 027/136] added registry-based custom max-age settings for special cases like special products --- code/Helper/Data.php | 38 ++++++++++++++++++++++++++++++++++++-- code/Model/Observer.php | 22 ++++++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/code/Helper/Data.php b/code/Helper/Data.php index 91e07b8..ad05934 100644 --- a/code/Helper/Data.php +++ b/code/Helper/Data.php @@ -7,5 +7,39 @@ * @package Aoe_Static * @author Toni Grigoriu */ -class Aoe_Static_Helper_Data extends Mage_Core_Helper_Abstract { -} \ No newline at end of file +class Aoe_Static_Helper_Data extends Mage_Core_Helper_Abstract +{ + /** + * Registry Key to store individual max-age times + */ + const REGISTRY_MAX_AGE = 'aoe_static_max_age'; + + /** + * computes the minimum max-age timestamp, based on the given timestamps and a possible earlier-set timestamp + * + * @param array|int $timestamps + * @return Aoe_Static_Helper_Data + */ + public function computeRegistryMaxAge($timestamps) + { + $maxAge = -1; + if (!is_array($timestamps)) { + $timestamps = array($timestamps); + } + + foreach ($timestamps as $timestamp) { + if (($timestamp > 0) && (($timestamp < $maxAge) || ($maxAge < 0))) { + $maxAge = $timestamp; + } + } + if ($timestamp = Mage::registry(self::REGISTRY_MAX_AGE)) { + if (($timestamp > 0) && (($timestamp < $maxAge) || ($timestamp < 0))) { + $maxAge = $timestamp; + } + Mage::unregister(self::REGISTRY_MAX_AGE); + } + Mage::register(self::REGISTRY_MAX_AGE, $maxAge); + + return $this; + } +} diff --git a/code/Model/Observer.php b/code/Model/Observer.php index 4d07b5f..1ac26f5 100644 --- a/code/Model/Observer.php +++ b/code/Model/Observer.php @@ -89,11 +89,33 @@ public function processPostDispatch(Varien_Event_Observer $observer) $this->applyConf($conf, $response); } + $this->_applyRegistryMaxAge($response); $this->_applyCustomMaxAgeFromDb($controllerAction->getRequest(), $response); return $this; } + /** + * Apply a custom registry-stored max-age header (e.g. for special products) + * returns true if a max-age header was set + * + * @param Mage_Core_Controller_Response_Http $response + * @return bool + */ + protected function _applyRegistryMaxAge(Mage_Core_Controller_Response_Http $response) + { + if (!$maxAge = Mage::registry(Aoe_Static_Helper_Data::REGISTRY_MAX_AGE)) { + return false; + } + if (!$this->messagesToShow && ($maxAge > 0)) { + $response->setHeader('Cache-Control', 'max-age=' . (int) $maxAge, true); + $response->setHeader('X-Magento-Lifetime', (int) $maxAge, true); + $response->setHeader('aoestatic', 'cache', true); + return true; + } + return false; + } + /** * Apply configuration (set headers and cookies) * From db3475c1f0e8b7e0fb362a8ff72f5c714a7a743e Mon Sep 17 00:00:00 2001 From: Bastian Ike Date: Wed, 13 Nov 2013 15:04:24 +0100 Subject: [PATCH 028/136] refactored codestyle, updated folder structure to match magentos structure --- .../Aoe/Static}/Block/Adminhtml/CustomUrl.php | 0 .../Block/Adminhtml/CustomUrl/Edit.php | 0 .../Block/Adminhtml/CustomUrl/Edit/Form.php | 0 .../Block/Adminhtml/CustomUrl/Grid.php | 0 .../Aoe/Static/Block/Beforebodyend.php | 57 ++++++++++++ .../Aoe/Static}/Block/Placeholder.php | 12 +-- .../community/Aoe/Static}/Helper/Data.php | 0 .../community/Aoe/Static}/Model/Config.php | 55 ++++++----- .../community/Aoe/Static}/Model/CustomUrl.php | 0 .../community/Aoe/Static}/Model/Observer.php | 13 ++- .../Aoe/Static}/Model/Resource/CustomUrl.php | 0 .../Model/Resource/CustomUrl/Collection.php | 0 .../Aoestatic/CustomUrlController.php | 0 .../Aoe/Static/controllers/CallController.php | 43 +++++++++ .../community/Aoe/Static}/etc/adminhtml.xml | 0 .../community/Aoe/Static}/etc/aoe_static.xml | 0 .../code/community/Aoe/Static}/etc/config.xml | 0 .../sql/aoestatic_setup/install-0.0.3.php | 0 .../default}/layout/aoestatic/aoestatic.xml | 0 .../default/layout/aoestatic/aoestatic.xml | 24 +++++ .../template/aoestatic/beforebodyend.phtml | 10 ++ .../template/aoestatic/placeholder.phtml | 0 .../etc/modules/Aoe_Static.xml | 0 code/Block/Beforebodyend.php | 58 ------------ code/controllers/CallController.php | 47 ---------- frontend/layout/aoestatic/aoestatic.xml | 26 ------ .../template/aoestatic/beforebodyend.phtml | 10 -- js/aoestatic/common.js | 92 ++++++++++--------- modman | 12 +-- 29 files changed, 229 insertions(+), 230 deletions(-) rename {code => app/code/community/Aoe/Static}/Block/Adminhtml/CustomUrl.php (100%) mode change 100755 => 100644 rename {code => app/code/community/Aoe/Static}/Block/Adminhtml/CustomUrl/Edit.php (100%) rename {code => app/code/community/Aoe/Static}/Block/Adminhtml/CustomUrl/Edit/Form.php (100%) rename {code => app/code/community/Aoe/Static}/Block/Adminhtml/CustomUrl/Grid.php (100%) mode change 100755 => 100644 create mode 100644 app/code/community/Aoe/Static/Block/Beforebodyend.php rename {code => app/code/community/Aoe/Static}/Block/Placeholder.php (57%) rename {code => app/code/community/Aoe/Static}/Helper/Data.php (100%) rename {code => app/code/community/Aoe/Static}/Model/Config.php (72%) rename {code => app/code/community/Aoe/Static}/Model/CustomUrl.php (100%) rename {code => app/code/community/Aoe/Static}/Model/Observer.php (98%) rename {code => app/code/community/Aoe/Static}/Model/Resource/CustomUrl.php (100%) rename {code => app/code/community/Aoe/Static}/Model/Resource/CustomUrl/Collection.php (100%) rename {code => app/code/community/Aoe/Static}/controllers/Adminhtml/Aoestatic/CustomUrlController.php (100%) mode change 100755 => 100644 create mode 100644 app/code/community/Aoe/Static/controllers/CallController.php rename {code => app/code/community/Aoe/Static}/etc/adminhtml.xml (100%) mode change 100755 => 100644 rename {code => app/code/community/Aoe/Static}/etc/aoe_static.xml (100%) rename {code => app/code/community/Aoe/Static}/etc/config.xml (100%) rename {code => app/code/community/Aoe/Static}/sql/aoestatic_setup/install-0.0.3.php (100%) rename {adminhtml => app/design/adminhtml/default/default}/layout/aoestatic/aoestatic.xml (100%) create mode 100644 app/design/frontend/base/default/layout/aoestatic/aoestatic.xml create mode 100644 app/design/frontend/base/default/template/aoestatic/beforebodyend.phtml rename {frontend => app/design/frontend/base/default}/template/aoestatic/placeholder.phtml (100%) rename Aoe_Static.xml => app/etc/modules/Aoe_Static.xml (100%) delete mode 100644 code/Block/Beforebodyend.php delete mode 100644 code/controllers/CallController.php delete mode 100644 frontend/layout/aoestatic/aoestatic.xml delete mode 100644 frontend/template/aoestatic/beforebodyend.phtml diff --git a/code/Block/Adminhtml/CustomUrl.php b/app/code/community/Aoe/Static/Block/Adminhtml/CustomUrl.php old mode 100755 new mode 100644 similarity index 100% rename from code/Block/Adminhtml/CustomUrl.php rename to app/code/community/Aoe/Static/Block/Adminhtml/CustomUrl.php diff --git a/code/Block/Adminhtml/CustomUrl/Edit.php b/app/code/community/Aoe/Static/Block/Adminhtml/CustomUrl/Edit.php similarity index 100% rename from code/Block/Adminhtml/CustomUrl/Edit.php rename to app/code/community/Aoe/Static/Block/Adminhtml/CustomUrl/Edit.php diff --git a/code/Block/Adminhtml/CustomUrl/Edit/Form.php b/app/code/community/Aoe/Static/Block/Adminhtml/CustomUrl/Edit/Form.php similarity index 100% rename from code/Block/Adminhtml/CustomUrl/Edit/Form.php rename to app/code/community/Aoe/Static/Block/Adminhtml/CustomUrl/Edit/Form.php diff --git a/code/Block/Adminhtml/CustomUrl/Grid.php b/app/code/community/Aoe/Static/Block/Adminhtml/CustomUrl/Grid.php old mode 100755 new mode 100644 similarity index 100% rename from code/Block/Adminhtml/CustomUrl/Grid.php rename to app/code/community/Aoe/Static/Block/Adminhtml/CustomUrl/Grid.php diff --git a/app/code/community/Aoe/Static/Block/Beforebodyend.php b/app/code/community/Aoe/Static/Block/Beforebodyend.php new file mode 100644 index 0000000..ffb7e27 --- /dev/null +++ b/app/code/community/Aoe/Static/Block/Beforebodyend.php @@ -0,0 +1,57 @@ +session)) { + $this->session = Mage::getSingleton('customer/session'); + } + return $this->session; + } + + /** + * Check if there is a logged in customer + * + * @return bool + */ + public function isLoggedIn() { + return $this->getSession()->isLoggedIn(); + } + + /** + * Get customer name + * + * @return bool|string + */ + public function getCustomerName() { + if ($this->isLoggedIn()) { + return $this->getSession()->getCustomer()->getName(); + } else { + return false; + } + } + + /** + * Get cart summary count + * + * @return int + */ + public function getCartSummaryCount() { + // return Mage::helper('checkout/cart')->getSummaryCount(); + } +} diff --git a/code/Block/Placeholder.php b/app/code/community/Aoe/Static/Block/Placeholder.php similarity index 57% rename from code/Block/Placeholder.php rename to app/code/community/Aoe/Static/Block/Placeholder.php index b0c408e..8d6671a 100644 --- a/code/Block/Placeholder.php +++ b/app/code/community/Aoe/Static/Block/Placeholder.php @@ -8,10 +8,8 @@ */ class Aoe_Static_Block_Placeholder extends Mage_Core_Block_Template { - - /** - * @var string default template of this block - */ - protected $_template = 'aoestatic/placeholder.phtml'; - -} \ No newline at end of file + /** + * @var string default template of this block + */ + protected $_template = 'aoestatic/placeholder.phtml'; +} diff --git a/code/Helper/Data.php b/app/code/community/Aoe/Static/Helper/Data.php similarity index 100% rename from code/Helper/Data.php rename to app/code/community/Aoe/Static/Helper/Data.php diff --git a/code/Model/Config.php b/app/code/community/Aoe/Static/Model/Config.php similarity index 72% rename from code/Model/Config.php rename to app/code/community/Aoe/Static/Model/Config.php index 16dd3fd..d3ad01e 100644 --- a/code/Model/Config.php +++ b/app/code/community/Aoe/Static/Model/Config.php @@ -1,7 +1,7 @@ '; + /** + * @var null|array + */ protected $markers = NULL; /** @@ -56,32 +59,33 @@ public function __construct($sourceData = null) } } - /** - * Get action configuration - * - * @param $fullActionName - * @return false|Mage_Core_Model_Config_Element - */ - public function getActionConfiguration($fullActionName) { - $configuration = $this->getNode('aoe_static/'.$fullActionName); - if (!$configuration || 1 == $configuration->disabled) { - return false; - } - $use = (string)$configuration->use; - if ($use) { - $configuration = $this->getActionConfiguration($use); - } - return $configuration; - } + /** + * Get action configuration + * + * @param $fullActionName + * @return false|Mage_Core_Model_Config_Element + */ + public function getActionConfiguration($fullActionName) + { + $configuration = $this->getNode('aoe_static/'.$fullActionName); + if (!$configuration || (1 == $configuration->disabled)) { + return false; + } + $use = (string)$configuration->use; + if ($use) { + $configuration = $this->getActionConfiguration($use); + } + return $configuration; + } /** * @return Varien_Simplexml_Element */ - public function getMarkersCallbackConfiguration() { - if ($this->markers !== NULL) { - return $this->markers; + public function getMarkersCallbackConfiguration() + { + if (is_null($this->markers)) { + $this->markers = $this->getNode('aoe_static/default/markers'); } - $this->markers = $this->getNode('aoe_static/default/markers'); return $this->markers; } @@ -90,7 +94,8 @@ public function getMarkersCallbackConfiguration() { * @param $marker string * @return string callback */ - public function getMarkerCallback($marker) { + public function getMarkerCallback($marker) + { $callback = ''; $configuration = $this->getMarkersCallbackConfiguration(); $markerWithoutHash = str_replace('#', '',$marker); @@ -99,4 +104,4 @@ public function getMarkerCallback($marker) { } return $callback; } -} \ No newline at end of file +} diff --git a/code/Model/CustomUrl.php b/app/code/community/Aoe/Static/Model/CustomUrl.php similarity index 100% rename from code/Model/CustomUrl.php rename to app/code/community/Aoe/Static/Model/CustomUrl.php diff --git a/code/Model/Observer.php b/app/code/community/Aoe/Static/Model/Observer.php similarity index 98% rename from code/Model/Observer.php rename to app/code/community/Aoe/Static/Model/Observer.php index 1ac26f5..a8ec0a2 100644 --- a/code/Model/Observer.php +++ b/app/code/community/Aoe/Static/Model/Observer.php @@ -210,7 +210,8 @@ public function beforeLoadLayout(Varien_Event_Observer $observer) * @param string $value * @return string */ - protected function replaceMarkers($value) { + protected function replaceMarkers($value) + { $matches = array(); preg_match_all('|###[^#]+###|', $value, $matches); $markersWithoutValues = array_diff($matches[0], array_keys($this->markersValues)); @@ -227,7 +228,8 @@ protected function replaceMarkers($value) { * @param string $marker * @return string */ - protected function getMarkerValue($marker) { + protected function getMarkerValue($marker) + { $markerValue = $marker; if (isset($this->markersValues[$marker]) && $this->markersValues[$marker] !== NULL) { $markerValue = $this->markersValues[$marker]; @@ -243,10 +245,10 @@ protected function getMarkerValue($marker) { * @param string $callbackString * @return mixed */ - protected function executeCallback($callbackString) { + protected function executeCallback($callbackString) + { $result = ""; try { - if ($callbackString) { if (!preg_match(Mage_Cron_Model_Observer::REGEX_RUN_MODEL, (string)$callbackString, $run)) { Mage::throwException('Invalid model/method definition, expecting "model/class::method".'); @@ -260,9 +262,7 @@ protected function executeCallback($callbackString) { if (empty($callback)) { Mage::throwException(Mage::helper('cron')->__('No callbacks found for marker')); } - $result = call_user_func_array($callback, $arguments); - } catch (Exception $e) { Mage::logException($e); } @@ -282,7 +282,6 @@ protected function checkForMessages() ) { $this->messagesToShow = true; } - return $this->messagesToShow; } } diff --git a/code/Model/Resource/CustomUrl.php b/app/code/community/Aoe/Static/Model/Resource/CustomUrl.php similarity index 100% rename from code/Model/Resource/CustomUrl.php rename to app/code/community/Aoe/Static/Model/Resource/CustomUrl.php diff --git a/code/Model/Resource/CustomUrl/Collection.php b/app/code/community/Aoe/Static/Model/Resource/CustomUrl/Collection.php similarity index 100% rename from code/Model/Resource/CustomUrl/Collection.php rename to app/code/community/Aoe/Static/Model/Resource/CustomUrl/Collection.php diff --git a/code/controllers/Adminhtml/Aoestatic/CustomUrlController.php b/app/code/community/Aoe/Static/controllers/Adminhtml/Aoestatic/CustomUrlController.php old mode 100755 new mode 100644 similarity index 100% rename from code/controllers/Adminhtml/Aoestatic/CustomUrlController.php rename to app/code/community/Aoe/Static/controllers/Adminhtml/Aoestatic/CustomUrlController.php diff --git a/app/code/community/Aoe/Static/controllers/CallController.php b/app/code/community/Aoe/Static/controllers/CallController.php new file mode 100644 index 0000000..255fed8 --- /dev/null +++ b/app/code/community/Aoe/Static/controllers/CallController.php @@ -0,0 +1,43 @@ + + */ +class Aoe_Static_CallController extends Mage_Core_Controller_Front_Action +{ + /** + * Index action. This action is called by an ajax request + * + * @return void + * @author Fabrizio Branca + */ + public function indexAction() + { + // if (!$this->getRequest()->isXmlHttpRequest()) { Mage::throwException('This is not an XmlHttpRequest'); } + $response = array(); + $response['sid'] = Mage::getModel('core/session')->getEncryptedSessionId(); + + if ($currentProductId = $this->getRequest()->getParam('currentProductId')) { + Mage::getSingleton('catalog/session')->setLastViewedProductId($currentProductId); + } + + $this->loadLayout(); + $layout = $this->getLayout(); + + $requestedBlockNames = $this->getRequest()->getParam('getBlocks'); + if (is_array($requestedBlockNames)) { + foreach ($requestedBlockNames as $id => $requestedBlockName) { + $tmpBlock = $layout->getBlock($requestedBlockName); + if ($tmpBlock) { + $response['blocks'][$id] = $tmpBlock->toHtml(); + } else { + $response['blocks'][$id] = 'BLOCK NOT FOUND'; + } + } + } + $this->getResponse()->setBody(Zend_Json::encode($response)); + } +} diff --git a/code/etc/adminhtml.xml b/app/code/community/Aoe/Static/etc/adminhtml.xml old mode 100755 new mode 100644 similarity index 100% rename from code/etc/adminhtml.xml rename to app/code/community/Aoe/Static/etc/adminhtml.xml diff --git a/code/etc/aoe_static.xml b/app/code/community/Aoe/Static/etc/aoe_static.xml similarity index 100% rename from code/etc/aoe_static.xml rename to app/code/community/Aoe/Static/etc/aoe_static.xml diff --git a/code/etc/config.xml b/app/code/community/Aoe/Static/etc/config.xml similarity index 100% rename from code/etc/config.xml rename to app/code/community/Aoe/Static/etc/config.xml diff --git a/code/sql/aoestatic_setup/install-0.0.3.php b/app/code/community/Aoe/Static/sql/aoestatic_setup/install-0.0.3.php similarity index 100% rename from code/sql/aoestatic_setup/install-0.0.3.php rename to app/code/community/Aoe/Static/sql/aoestatic_setup/install-0.0.3.php diff --git a/adminhtml/layout/aoestatic/aoestatic.xml b/app/design/adminhtml/default/default/layout/aoestatic/aoestatic.xml similarity index 100% rename from adminhtml/layout/aoestatic/aoestatic.xml rename to app/design/adminhtml/default/default/layout/aoestatic/aoestatic.xml diff --git a/app/design/frontend/base/default/layout/aoestatic/aoestatic.xml b/app/design/frontend/base/default/layout/aoestatic/aoestatic.xml new file mode 100644 index 0000000..9aa88f8 --- /dev/null +++ b/app/design/frontend/base/default/layout/aoestatic/aoestatic.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + diff --git a/app/design/frontend/base/default/template/aoestatic/beforebodyend.phtml b/app/design/frontend/base/default/template/aoestatic/beforebodyend.phtml new file mode 100644 index 0000000..1ccdf26 --- /dev/null +++ b/app/design/frontend/base/default/template/aoestatic/beforebodyend.phtml @@ -0,0 +1,10 @@ + + diff --git a/frontend/template/aoestatic/placeholder.phtml b/app/design/frontend/base/default/template/aoestatic/placeholder.phtml similarity index 100% rename from frontend/template/aoestatic/placeholder.phtml rename to app/design/frontend/base/default/template/aoestatic/placeholder.phtml diff --git a/Aoe_Static.xml b/app/etc/modules/Aoe_Static.xml similarity index 100% rename from Aoe_Static.xml rename to app/etc/modules/Aoe_Static.xml diff --git a/code/Block/Beforebodyend.php b/code/Block/Beforebodyend.php deleted file mode 100644 index 90de650..0000000 --- a/code/Block/Beforebodyend.php +++ /dev/null @@ -1,58 +0,0 @@ -session)) { - $this->session = Mage::getSingleton('customer/session'); - } - return $this->session; - } - - /** - * Check if there is a logged in customer - * - * @return bool - */ - public function isLoggedIn() { - return $this->getSession()->isLoggedIn(); - } - - /** - * Get customer name - * - * @return bool|string - */ - public function getCustomerName() { - if ($this->isLoggedIn()) { - return $this->getSession()->getCustomer()->getName(); - } else { - return false; - } - } - - /** - * Get cart summary count - * - * @return int - */ - public function getCartSummaryCount() { - // return Mage::helper('checkout/cart')->getSummaryCount(); - } - -} \ No newline at end of file diff --git a/code/controllers/CallController.php b/code/controllers/CallController.php deleted file mode 100644 index c790a0c..0000000 --- a/code/controllers/CallController.php +++ /dev/null @@ -1,47 +0,0 @@ - - */ -class Aoe_Static_CallController extends Mage_Core_Controller_Front_Action { - - - - /** - * Index action. This action is called by an ajax request - * - * @return void - * @author Fabrizio Branca - */ - public function indexAction() { - - // if (!$this->getRequest()->isXmlHttpRequest()) { Mage::throwException('This is not an XmlHttpRequest'); } - - $response = array(); - $response['sid'] = Mage::getModel('core/session')->getEncryptedSessionId(); - - if ($currentProductId = $this->getRequest()->getParam('currentProductId')) { - Mage::getSingleton('catalog/session')->setLastViewedProductId($currentProductId); - } - - $this->loadLayout(); - $layout = $this->getLayout(); - - $requestedBlockNames = $this->getRequest()->getParam('getBlocks'); - if (is_array($requestedBlockNames)) { - foreach ($requestedBlockNames as $id => $requestedBlockName) { - $tmpBlock = $layout->getBlock($requestedBlockName); - if ($tmpBlock) { - $response['blocks'][$id] = $tmpBlock->toHtml(); - } else { - $response['blocks'][$id] = 'BLOCK NOT FOUND'; - } - } - } - $this->getResponse()->setBody(Zend_Json::encode($response)); - } - -} diff --git a/frontend/layout/aoestatic/aoestatic.xml b/frontend/layout/aoestatic/aoestatic.xml deleted file mode 100644 index 90a048d..0000000 --- a/frontend/layout/aoestatic/aoestatic.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/frontend/template/aoestatic/beforebodyend.phtml b/frontend/template/aoestatic/beforebodyend.phtml deleted file mode 100644 index 0ba21ce..0000000 --- a/frontend/template/aoestatic/beforebodyend.phtml +++ /dev/null @@ -1,10 +0,0 @@ - - diff --git a/js/aoestatic/common.js b/js/aoestatic/common.js index 0bd401c..7828729 100755 --- a/js/aoestatic/common.js +++ b/js/aoestatic/common.js @@ -5,51 +5,55 @@ * @author Fabrizio Branca */ $.noConflict(); -jQuery(document).ready(function($) { - var data = { - getBlocks: {} - }; +var Aoe_Static = { + populatePage: function(ajaxhome_url, fullactionname, currentproductid) { + jQuery(document).ready(function($) { + var data = { + getBlocks: {} + }; - // add placeholders - var counter = 0; - $('.placeholder').each(function() { - var id = $(this).attr('id'); - if (!id) { - // create dynamic id - id = 'ph_' + counter; - $(this).attr('id', id); - } - var rel = $(this).attr('rel'); - if (rel) { - data.getBlocks[id] = rel; - counter++; - } else { - throw 'Found placeholder without rel attribute'; - } - }); + // add placeholders + var counter = 0; + $('.placeholder').each(function() { + var id = $(this).attr('id'); + if (!id) { + // create dynamic id + id = 'ph_' + counter; + $(this).attr('id', id); + } + var rel = $(this).attr('rel'); + if (rel) { + data.getBlocks[id] = rel; + counter++; + } else { + throw 'Found placeholder without rel attribute'; + } + }); - // add current product - if (typeof CURRENTPRODUCTID !== 'undefined' && CURRENTPRODUCTID) { - data.currentProductId = CURRENTPRODUCTID; - } + // add current product + if (typeof currentproductid !== 'undefined' && currentproductid) { + data.currentProductId = currentproductid; + } - // E.T. phone home - if (typeof data.currentProductId !== 'undefined' || counter > 0) { - $.get( - AJAXHOME_URL, - data, - function (response) { - for(var id in response.blocks) { - $('#' + id).html(response.blocks[id]); - } - // inject session if (TODO: check if this is really needed) - // $.cookie('frontend', response.sid, { path: '/' }); - - // TODO: trigger event - }, - 'json' - ); - } - -}); \ No newline at end of file + // E.T. phone home + if (typeof data.currentProductId !== 'undefined' || counter > 0) { + $.get( + ajaxhome_url, + data, + function (response) { + for(var id in response.blocks) { + $('#' + id).html(response.blocks[id]); + } + // inject session if (TODO: check if this is really needed) + // $.cookie('frontend', response.sid, { path: '/' }); + + // TODO: trigger event + }, + 'json' + ); + } + + }); + } +} diff --git a/modman b/modman index 7c3d869..132b111 100644 --- a/modman +++ b/modman @@ -1,6 +1,6 @@ -code/ app/code/local/Aoe/Static/ -js/aoestatic/ js/aoestatic/ -frontend/layout/aoestatic/ app/design/frontend/base/default/layout/aoestatic/ -frontend/template/aoestatic/ app/design/frontend/base/default/template/aoestatic/ -adminhtml/layout/aoestatic/ app/design/adminhtml/default/default/layout/aoestatic/ -Aoe_Static.xml app/etc/modules/Aoe_Static.xml +./app/code/community/Aoe/Static ./app/code/community/Aoe/Static +./app/design/adminhtml/default/default/layout/aoestatic/ ./app/design/adminhtml/default/default/layout/aoestatic/ +./app/design/frontend/base/default/layout/aoestatic/ ./app/design/frontend/base/default/layout/aoestatic/ +./app/design/frontend/base/default/template/aoestatic/ ./app/design/frontend/base/default/template/aoestatic/ +./app/etc/modules/Aoe_Static.xml ./app/etc/modules/Aoe_Static.xml +./js/aoestatic/ ./js/aoestatic/ From 6b9d164984d206f0f226c8c2f25c0579c01e2b10 Mon Sep 17 00:00:00 2001 From: Bastian Ike Date: Wed, 20 Nov 2013 12:15:24 +0100 Subject: [PATCH 029/136] initial merging from Aoe_PurgeStatic (based on Magneto_Varnish and Aoe_AsyncVarnishCache) into Aoe_Static --- .../Block/Adminhtml/BlacklistUrlPattern.php | 40 +++ .../Aoe/Static/Block/Adminhtml/Purge.php | 3 + app/code/community/Aoe/Static/Helper/Data.php | 107 +++++-- .../Aoe/Static/Model/AsyncCacheObserver.php | 38 +++ .../Aoe/Static/Model/BlacklistUrlPattern.php | 73 +++++ .../Aoe/Static/Model/Cache/Control.php | 111 +++++++ .../Aoe/Static/Model/Cache/Marker.php | 98 ++++++ .../community/Aoe/Static/Model/Observer.php | 301 ++++++++++-------- .../Model/Resource/BlacklistUrlPattern.php | 45 +++ .../community/Aoe/Static/etc/adminhtml.xml | 21 ++ app/code/community/Aoe/Static/etc/config.xml | 72 ++++- .../aoestatic_setup/upgrade-0.0.5-0.0.6.php | 30 ++ .../default/layout/aoestatic/aoestatic.xml | 19 ++ 13 files changed, 809 insertions(+), 149 deletions(-) create mode 100644 app/code/community/Aoe/Static/Block/Adminhtml/BlacklistUrlPattern.php create mode 100644 app/code/community/Aoe/Static/Block/Adminhtml/Purge.php create mode 100644 app/code/community/Aoe/Static/Model/AsyncCacheObserver.php create mode 100644 app/code/community/Aoe/Static/Model/BlacklistUrlPattern.php create mode 100644 app/code/community/Aoe/Static/Model/Cache/Control.php create mode 100644 app/code/community/Aoe/Static/Model/Cache/Marker.php create mode 100644 app/code/community/Aoe/Static/Model/Resource/BlacklistUrlPattern.php create mode 100644 app/code/community/Aoe/Static/sql/aoestatic_setup/upgrade-0.0.5-0.0.6.php diff --git a/app/code/community/Aoe/Static/Block/Adminhtml/BlacklistUrlPattern.php b/app/code/community/Aoe/Static/Block/Adminhtml/BlacklistUrlPattern.php new file mode 100644 index 0000000..796db31 --- /dev/null +++ b/app/code/community/Aoe/Static/Block/Adminhtml/BlacklistUrlPattern.php @@ -0,0 +1,40 @@ + + */ +class Aoe_Static_Block_Adminhtml_BlacklistUrlPattern extends Mage_Adminhtml_Block_Widget_Grid_Container +{ + /** + * Block constructor + */ + public function __construct() + { + $this->_blockGroup = 'aoestatic'; + $this->_controller = 'adminhtml_blacklistUrlPattern'; + $this->_headerText = Mage::helper('aoestatic')->__('AOE Static Cache Url Blacklist'); + + parent::__construct(); + + if ($this->_isAllowedAction('save')) { + $this->_updateButton('add', 'label', + Mage::helper('aoestatic')->__('Add new blacklist url pattern') + ); + } else { + $this->_removeButton('add'); + } + } + + /** + * Check permission for passed action + * + * @param string $action + * @return bool + */ + protected function _isAllowedAction($action) + { + return Mage::getSingleton('admin/session') + ->isAllowed('system/aoestatic_blacklistUrlPattern/' . $action); + } +} diff --git a/app/code/community/Aoe/Static/Block/Adminhtml/Purge.php b/app/code/community/Aoe/Static/Block/Adminhtml/Purge.php new file mode 100644 index 0000000..06ce966 --- /dev/null +++ b/app/code/community/Aoe/Static/Block/Adminhtml/Purge.php @@ -0,0 +1,3 @@ +_config)) { + $this->_config = Mage::getModel('aoestatic/config'); + } + return $this->_config; + } /** - * computes the minimum max-age timestamp, based on the given timestamps and a possible earlier-set timestamp + * instantiates and caches active adapters * - * @param array|int $timestamps - * @return Aoe_Static_Helper_Data + * @return array */ - public function computeRegistryMaxAge($timestamps) + protected function _getAdapterInstances() { - $maxAge = -1; - if (!is_array($timestamps)) { - $timestamps = array($timestamps); + foreach ($this->getConfig()->getAdapters() as $key => $adapter) { + if (!isset($this->_adapterInstances[$key])) { + $adapterInstance = Mage::getSingleton($adapter['model']); + $adapterInstance->setConfig($adapter['config']); + $this->_adapterInstances[$key] = $adapterInstance; + } } - foreach ($timestamps as $timestamp) { - if (($timestamp > 0) && (($timestamp < $maxAge) || ($maxAge < 0))) { - $maxAge = $timestamp; - } + return $this->_adapterInstances; + } + + /** + * calls purgeAll on all adapter instances + * + * @return array + */ + public function purgeAll() + { + $result = array(); + foreach ($this->_getAdapterInstances() as $adapter) { + /** @var Aoe_Static_Model_Adapter_Interface $adapter */ + $result = array_merge($result, $adapter->purgeAll()); } - if ($timestamp = Mage::registry(self::REGISTRY_MAX_AGE)) { - if (($timestamp > 0) && (($timestamp < $maxAge) || ($timestamp < 0))) { - $maxAge = $timestamp; - } - Mage::unregister(self::REGISTRY_MAX_AGE); + return $result; + } + + /** + * Get array of blacklist url patterns + * + * @return array + */ + public function getBlacklist() + { + if (is_null($this->_blacklist)) { + /** @var Aoe_Static_Model_Resource_BlacklistUrlPattern_Collection $collection */ + $collection = Mage::getResourceModel('aoestatic/blacklistUrlPattern_collection'); + $this->_blacklist = $collection->getColumnValues('pattern'); } - Mage::register(self::REGISTRY_MAX_AGE, $maxAge); + return $this->_blacklist; + } - return $this; + /** + * calls purge on every adapter with given URLs + * + * @todo names/consts + * @param array $urls + * @param bool $async + * @return array + */ + public function purge(array $urls, $async = true) + { + $urls = array_filter($urls, function ($e) { return strlen($e) ? true : false; }); + $result = array(); + foreach ($this->_getAdapterInstances() as $adapter) { + /** @var Aoe_Static_Model_Adapter_Interface $adapter */ + + // queue if async cache is enabled in config and not forced to purge directly + if ($this->getConfig()->useAsyncCache() && $async) { + foreach ($urls as $url) { + /** @var $asyncCache Aoe_AsyncCache_Model_Asynccache */ + $asyncCache = Mage::getModel('aoeasynccache/asynccache'); + $asyncCache->setTstamp(time()) + ->setMode(Aoe_VarnishAsyncCache_Helper_Data::MODE_PURGEVARNISHURL) + ->setTags($url) + ->setStatus(Aoe_AsyncCache_Model_Asynccache::STATUS_PENDING) + ->save(); + } + } else { + $result = array_merge($result, $adapter->purge($urls)); + } + } + return $result; } } diff --git a/app/code/community/Aoe/Static/Model/AsyncCacheObserver.php b/app/code/community/Aoe/Static/Model/AsyncCacheObserver.php new file mode 100644 index 0000000..0457f18 --- /dev/null +++ b/app/code/community/Aoe/Static/Model/AsyncCacheObserver.php @@ -0,0 +1,38 @@ +getData('jobCollection'); + if (!$jobCollection) { + return; + } + foreach ($jobCollection as $job) { + /** @var $job Aoe_AsyncCache_Model_Job */ + /** @todo name */ + if (!$job->getIsProcessed() && ($job->getMode() == Aoe_VarnishAsyncCache_Helper_Data::MODE_PURGEVARNISHURL)) { + $startTime = time(); + $errors = Mage::helper('aoestatic')->purge($job->getTags(), false); + $job->setDuration(time() - $startTime); + $job->setIsProcessed(true); + + if (!empty($errors)) { + foreach ($errors as $error) { + Mage::log($error); + } + } + + Mage::log(sprintf('[ASYNCCACHE] MODE: %s, DURATION: %s sec, TAGS: %s', + $job->getMode(), + $job->getDuration(), + implode(', ', $job->getTags()) + )); + } + } + } +} diff --git a/app/code/community/Aoe/Static/Model/BlacklistUrlPattern.php b/app/code/community/Aoe/Static/Model/BlacklistUrlPattern.php new file mode 100644 index 0000000..499011c --- /dev/null +++ b/app/code/community/Aoe/Static/Model/BlacklistUrlPattern.php @@ -0,0 +1,73 @@ + + * + * @method Aoe_Static_Model_Resource_BlacklistUrlPattern _getResource() + * @method Aoe_Static_Model_Resource_BlacklistUrlPattern getResource() + * @method string getPattern() + * @method Aoe_Static_Model_BlacklistUrlPattern setPattern(string $value) + */ +class Aoe_Static_Model_BlacklistUrlPattern extends Mage_Core_Model_Abstract +{ + protected function _construct() + { + $this->_init('aoestatic/blacklistUrlPattern'); + } + + /** + * Validate model data + * + * @return array|bool + */ + public function validate() + { + $errors = array(); + + $pattern = $this->getData('pattern'); + if (@preg_match($pattern, '') === false) { + $errors[] = Mage::helper('aoestatic')->__('Pattern is not valid PHP PCRE Pattern'); + } + + if (count($errors) == 0) { + return true; + } else { + return $errors; + } + } + + /** + * Processing object before save data + * + * @return Mage_Core_Model_Abstract + * @throws Mage_Core_Exception + */ + protected function _beforeSave() + { + $validationResult = $this->validate(); + + if ($validationResult === true) { + return parent::_beforeSave(); + } else { + if (is_array($validationResult) && count($validationResult) > 0) { + $message = array_shift($validationResult); + } else { + $message = Mage::helper('aoestatic')->__('An error occurred while saving url pattern'); + } + + throw new Mage_Core_Exception($message); + } + } + + /** + * Delete url patterns with given ids + * + * @param array $patternIds + * @return $this + */ + public function deleteBlacklistUrlPatterns(array $patternIds) + { + $this->getResource()->deleteBlacklistUrlPatterns($patternIds); + } +} diff --git a/app/code/community/Aoe/Static/Model/Cache/Control.php b/app/code/community/Aoe/Static/Model/Cache/Control.php new file mode 100644 index 0000000..3d850de --- /dev/null +++ b/app/code/community/Aoe/Static/Model/Cache/Control.php @@ -0,0 +1,111 @@ +_enabled = true; + return $this; + } + + public function disable() + { + $this->_enabled = false; + return $this; + } + + public function addMaxAge($maxAge) + { + if (!is_array($maxAge)) { + $maxAge = array($maxAge); + } + + foreach ($maxAge as $timestamp) { + if (!$this->_maxAge || ($timestamp < $this->_maxAge)) { + $this->_maxAge = $timestamp; + } + } + } + + public function addCustomUrlMaxAge($request) + { + // apply custom max-age from db + $urls = array($request->getRequestString()); + $alias = $request->getAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS); + if ($alias) { + $urls[] = $alias; + } + /** @var $customUrlModel Aoe_Static_Model_CustomUrl */ + $customUrlModel = Mage::getModel('aoestatic/customUrl'); + $customUrlModel->setStoreId(Mage::app()->getStore()->getId()); + $customUrlModel->loadByRequestPath($urls); + + if ($customUrlModel->getId() && $customUrlModel->getMaxAge()) { + $this->addMaxAge($customUrlModel->getMaxAge()); + } + } + + public function addTag($tags) + { + if (!is_array($tags)) { + $tags = array($tags); + } + + foreach ($tags as $tag) { + if (!isset($this->_tags[$tag])) { + $this->_tags[$tag] = 0; + } + $this->_tags[$tag]++; + } + } + + public function applyCacheHeaders() + { + if ($this->_enabled) { + $response = Mage::app()->getResponse(); + $response->setHeader('X-Invalidated-By', '|' . implode('|', $this->_tags) . '|'); + $response->setHeader('Cache-Control', 'max-age=' . (int) $this->_maxAge, true); + $response->setHeader('X-Magento-Lifetime', (int) $this->_maxAge, true); + $response->setHeader('aoestatic', 'cache', true); + } + } + + /** + * get current category layer + * + * @return Mage_Catalog_Model_Layer + */ + protected function _getLayer() + { + $layer = Mage::registry('current_layer'); + if ($layer) { + return $layer; + } + return Mage::getSingleton('catalog/layer'); + } + + public function collectTags() + { + if (Mage::registry('product')) { + $this->addTag('product-' . Mage::registry('product')->getId()); + } + if (($layer = $this->_getLayer()) && ($layer->getProductCollection())) { + /** @var Mage_Catalog_Model_Layer $layer */ + $ids = $layer->getProductCollection()->getAllIds(); + $tags = array(); + foreach ($ids as $id) { + $tags[] = 'product-' . $id; + } + $this->addTag($tags); + } + if (Mage::registry('current_category')) { + /** @var Mage_Catalog_Model_Category $currentCategory */ + $currentCategory = Mage::registry('current_category'); + $this->addTag('category-' . $currentCategory->getId()); + } + } +} diff --git a/app/code/community/Aoe/Static/Model/Cache/Marker.php b/app/code/community/Aoe/Static/Model/Cache/Marker.php new file mode 100644 index 0000000..a11f83c --- /dev/null +++ b/app/code/community/Aoe/Static/Model/Cache/Marker.php @@ -0,0 +1,98 @@ +_config = Mage::getSingleton('aoestatic/config'); + } + + public function addMarkerValues($markers) + { + if (!is_array($markers)) { + $markers = array($markers); + } + + $this->_markersValues = array_merge($this->_markersValues, $markers); + } + + /** + * Replaces markers in the $value, saves calculated value to the local cache + * + * @param string $value + * @return string + */ + public function replaceMarkers($value) + { + $matches = array(); + preg_match_all('|###[^#]+###|', $value, $matches); + $markersWithoutValues = array_diff($matches[0], array_keys($this->markersValues)); + foreach($markersWithoutValues as $marker) { + $this->markersValues[$marker] = $this->getMarkerValue($marker); + } + $value = str_replace(array_keys($this->markersValues), array_values($this->markersValues), $value); + return $value; + } + + /** + * Returns value of a given marker + * + * @param string $marker + * @return string + */ + public function getMarkerValue($marker) + { + $markerValue = $marker; + if (isset($this->markersValues[$marker]) && $this->markersValues[$marker] !== NULL) { + $markerValue = $this->markersValues[$marker]; + } elseif ($this->_config->getMarkerCallback($marker)) { + $markerValue = $this->executeCallback($this->_config->getMarkerCallback($marker)); + } + return (string)$markerValue; + } + + /** + * Executes method defined in the marker callback configuration and returns the result + * + * @param string $callbackString + * @return mixed + */ + public function executeCallback($callbackString) + { + $result = ""; + try { + if ($callbackString) { + if (!preg_match(Mage_Cron_Model_Observer::REGEX_RUN_MODEL, (string)$callbackString, $run)) { + Mage::throwException('Invalid model/method definition, expecting "model/class::method".'); + } + if (!($model = Mage::getModel($run[1])) || !method_exists($model, $run[2])) { + Mage::throwException('Invalid callback: %s::%s does not exist', $run[1], $run[2]); + } + $callback = array($model, $run[2]); + $arguments = array(); + } + if (empty($callback)) { + Mage::throwException(Mage::helper('cron')->__('No callbacks found for marker')); + } + $result = call_user_func_array($callback, $arguments); + } catch (Exception $e) { + Mage::logException($e); + } + return $result; + } + +} diff --git a/app/code/community/Aoe/Static/Model/Observer.php b/app/code/community/Aoe/Static/Model/Observer.php index a8ec0a2..ece122d 100644 --- a/app/code/community/Aoe/Static/Model/Observer.php +++ b/app/code/community/Aoe/Static/Model/Observer.php @@ -10,21 +10,19 @@ class Aoe_Static_Model_Observer { /** - * @var Aoe_Static_Model_Config + * Indicates, if there are messages to show on the current page + * @var bool */ - protected $_config; + protected $messagesToShow = false; /** - * Local cache for calculated values of markers - * @var null | array + * Temporary storage for already processed entries + * + * @var array */ - protected $markersValues = null; + public $_tags_already_processed = array(); - /** - * Indicates, if there are messages to show on the current page - * @var bool - */ - protected $messagesToShow = false; + const REGISTRY_SKIPPABLE_NAME = 'aoestatic_skippableProductsForPurging'; /** * Constructor @@ -64,12 +62,14 @@ public function processPostDispatch(Varien_Event_Observer $observer) $customerName = Mage::helper('core')->escapeHtml($session->getCustomer()->getName()); } - $this->markersValues = array( + /** @var Aoe_Static_Model_Cache_Marker $cacheMarker */ + $cacheMarker = Mage::getSingleton('aoestatic/cache_marker'); + $cacheMarker->addMarkerValues(array( '###FULLACTIONNAME###' => $fullActionName, '###CUSTOMERNAME###' => $customerName, '###ISLOGGEDIN###' => $loggedIn, '###NUMBEROFITEMSINCART###' => Mage::helper('checkout/cart')->getSummaryCount(), - ); + )); // apply default configuration in any case $defaultConf = $this->_config->getActionConfiguration('default'); @@ -89,33 +89,17 @@ public function processPostDispatch(Varien_Event_Observer $observer) $this->applyConf($conf, $response); } - $this->_applyRegistryMaxAge($response); - $this->_applyCustomMaxAgeFromDb($controllerAction->getRequest(), $response); + if (!$this->messagesToShow) { + /** @var Aoe_Static_Model_Cache_Control $cacheControl */ + $cacheControl = Mage::getSingleton('aoestatic/cache_control'); + $cacheControl->addCustomUrlMaxAge($controllerAction->getRequest()); + $cacheControl->collectTags(); + $cacheControl->applyCacheHeaders(); + } return $this; } - /** - * Apply a custom registry-stored max-age header (e.g. for special products) - * returns true if a max-age header was set - * - * @param Mage_Core_Controller_Response_Http $response - * @return bool - */ - protected function _applyRegistryMaxAge(Mage_Core_Controller_Response_Http $response) - { - if (!$maxAge = Mage::registry(Aoe_Static_Helper_Data::REGISTRY_MAX_AGE)) { - return false; - } - if (!$this->messagesToShow && ($maxAge > 0)) { - $response->setHeader('Cache-Control', 'max-age=' . (int) $maxAge, true); - $response->setHeader('X-Magento-Lifetime', (int) $maxAge, true); - $response->setHeader('aoestatic', 'cache', true); - return true; - } - return false; - } - /** * Apply configuration (set headers and cookies) * @@ -124,12 +108,14 @@ protected function _applyRegistryMaxAge(Mage_Core_Controller_Response_Http $resp */ protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Controller_Response_Http $response) { + /** @var Aoe_Static_Model_Cache_Marker $cacheMarker */ + $cacheMarker = Mage::getSingleton('aoestatic/cache_marker'); foreach ($conf->headers->children() as $key => $value) { // skip aoestatic header if we have messages to display if ($this->messagesToShow && ($key == 'aoestatic')) { continue; } - $value = $this->replaceMarkers($value); + $value = $cacheMarker->replaceMarkers($value); $response->setHeader($key, $value, true); } if ($conf->cookies) { @@ -140,7 +126,7 @@ protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Con continue; } $value = (string) $cookieConf->value; - $value = $this->replaceMarkers($value); + $value = $cacheMarker->replaceMarkers($value); $period = $cookieConf->period ? (string) $cookieConf->period : null; $path = $cookieConf->path ? (string) $cookieConf->path : null; $domain = $cookieConf->domain ? (string) $cookieConf->domain : null; @@ -152,35 +138,6 @@ protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Con } } - /** - * Apply custom Cache-Control: max-age from db - * - * @param Mage_Core_Controller_Request_Http $request - * @param Mage_Core_Controller_Response_Http $response - */ - protected function _applyCustomMaxAgeFromDb(Mage_Core_Controller_Request_Http $request, - Mage_Core_Controller_Response_Http $response - ) { - if (!$this->messagesToShow) { - // apply custom max-age from db - $urls = array($request->getRequestString()); - $alias = $request->getAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS); - if ($alias) { - $urls[] = $alias; - } - /** @var $customUrlModel Aoe_Static_Model_CustomUrl */ - $customUrlModel = Mage::getModel('aoestatic/customUrl'); - $customUrlModel->setStoreId(Mage::app()->getStore()->getId()); - $customUrlModel->loadByRequestPath($urls); - - if ($customUrlModel->getId() && $customUrlModel->getMaxAge()) { - $response->setHeader('Cache-Control', 'max-age=' . (int) $customUrlModel->getMaxAge(), true); - $response->setHeader('X-Magento-Lifetime', (int) $customUrlModel->getMaxAge(), true); - $response->setHeader('aoestatic', 'cache', true); - } - } - } - /** * Add layout handle 'aoestatic_cacheable' or 'aoestatic_notcacheable' * @@ -191,97 +148,191 @@ public function beforeLoadLayout(Varien_Event_Observer $observer) // check if we have messages to display $this->messagesToShow = $this->checkForMessages(); - $event = $observer->getEvent(); - /* @var $event Varien_Event */ - $controllerAction = $event->getAction(); /* @var $controllerAction Mage_Core_Controller_Varien_Action */ + $controllerAction = $observer->getAction(); $fullActionName = $controllerAction->getFullActionName(); - $conf = $this->_config->getActionConfiguration($fullActionName); + $handle = $this->_config->getActionConfiguration($fullActionName) ? 'aoestatic_cacheable' : 'aoestatic_notcacheable'; - $handle = $conf ? 'aoestatic_cacheable' : 'aoestatic_notcacheable'; + $observer->getLayout()->getUpdate()->addHandle($handle); + } - $observer->getEvent()->getLayout()->getUpdate()->addHandle($handle); + /** + * Checks if there are messages to display + * + * @return bool + */ + protected function checkForMessages() + { + if ( + (false === $this->messagesToShow) && + (Mage::app()->getLayout()->getMessagesBlock()->getMessageCollection()->count() > 0) + ) { + $this->messagesToShow = true; + } + return $this->messagesToShow; } /** - * Replaces markers in the $value, saves calculated value to the local cache + * collect tags * - * @param string $value - * @return string + * @param Varien_Event_Observer $observer */ - protected function replaceMarkers($value) + public function coreBlockAbstractToHtmlBefore(Varien_Event_Observer $observer) { - $matches = array(); - preg_match_all('|###[^#]+###|', $value, $matches); - $markersWithoutValues = array_diff($matches[0], array_keys($this->markersValues)); - foreach($markersWithoutValues as $marker) { - $this->markersValues[$marker] = $this->getMarkerValue($marker); + $block = $observer->getBlock(); + + if ($block instanceof Mage_Cms_Block_Block && $block->getBlock()) { + Mage::getSingleton('aoestatic/cache_control')->addTag('block-' . $block->getBlock()->getId()); + } else if ($block instanceof Mage_Cms_Block_Page) { + Mage::getSingleton('aoestatic/cache_control')->addTag('page-' . ($block->getPageId() ?: ($block->getPage() ? $block->getPage()->getId() : Mage::getSingleton('cms/page')->getId()))); + } else if (($block instanceof Mage_Catalog_Block_Product_Abstract) && $block->getProductCollection()) { + $tags = array(); + foreach ($block->getProductCollection()->getAllIds() as $id) { + $tags[] = 'product-' . $id; + } + Mage::getSingleton('aoestatic/cache_control')->addTag($tags); } - $value = str_replace(array_keys($this->markersValues), array_values($this->markersValues), $value); - return $value; } /** - * Returns value of a given marker + * manual cache purging of specified URLs * - * @param string $marker - * @return string + * @param Varien_Event_Observer $event */ - protected function getMarkerValue($marker) + public function controllerActionPredispatchAdminhtmlCacheIndex(Varien_Event_Observer $event) { - $markerValue = $marker; - if (isset($this->markersValues[$marker]) && $this->markersValues[$marker] !== NULL) { - $markerValue = $this->markersValues[$marker]; - } elseif ($this->_config->getMarkerCallback($marker)) { - $markerValue = $this->executeCallback($this->_config->getMarkerCallback($marker)); + /** @var Mage_Core_Controller_Request_Http $request */ + $request = $event->getControllerAction()->getRequest(); + + if ($purgeUrls = $request->getParam('aoe_purge_urls')) { + $purgeUrls = array_map('trim', explode("\n", trim($purgeUrls))); + + // purge directly without queueing + Mage::helper('aoestatic')->purge($purgeUrls, false); + + Mage::getSingleton('adminhtml/session')->addSuccess("The Aoe_Static cache storage has been flushed."); + + /** @var Mage_Core_Controller_Response_Http $response */ + $response = $event->getControllerAction()->getResponse(); + $response->setRedirect(Mage::getModel('adminhtml/url')->getUrl('*/cache/index', array())); + $response->sendResponse(); + exit; } - return (string)$markerValue; } /** - * Executes method defined in the marker callback configuration and returns the result + * @see Mage_Core_Model_Cache * - * @param string $callbackString - * @return mixed + * @param Mage_Core_Model_Observer $observer + * @return Aoe_Static_Model_Observer */ - protected function executeCallback($callbackString) + public function catalogCategorySaveCommitAfter($observer) { - $result = ""; - try { - if ($callbackString) { - if (!preg_match(Mage_Cron_Model_Observer::REGEX_RUN_MODEL, (string)$callbackString, $run)) { - Mage::throwException('Invalid model/method definition, expecting "model/class::method".'); - } - if (!($model = Mage::getModel($run[1])) || !method_exists($model, $run[2])) { - Mage::throwException('Invalid callback: %s::%s does not exist', $run[1], $run[2]); - } - $callback = array($model, $run[2]); - $arguments = array(); - } - if (empty($callback)) { - Mage::throwException(Mage::helper('cron')->__('No callbacks found for marker')); - } - $result = call_user_func_array($callback, $arguments); - } catch (Exception $e) { - Mage::logException($e); + /** @var $category Mage_Catalog_Model_Category */ + $category = $observer->getCategory(); + if ($category->getData('include_in_menu')) { + // notify user that varnish needs to be refreshed + Mage::app()->getCacheInstance()->invalidateType(array('aoestatic')); } - return $result; + return $this; } /** - * Checks if there are messages to display + * Listens to application_clean_cache event and gets notified when a product/category/cms model is saved * - * @return bool + * @todo tzags isntead of urls + * @param $observer Mage_Core_Model_Observer + * @return Aoe_Static_Model_Observer */ - protected function checkForMessages() + public function applicationCleanCache($observer) { - if ( - (false === $this->messagesToShow) && - (Mage::app()->getLayout()->getMessagesBlock()->getMessageCollection()->count() > 0) - ) { - $this->messagesToShow = true; + // if Varnish is not enabled on admin don't do anything + if (!Mage::app()->useCache('aoestatic')) { + return $this; } - return $this->messagesToShow; + + /** @var Aoe_Static_Helper_Data $helper */ + $helper = Mage::helper('aoestatic'); + /** @var Mage_Adminhtml_Model_Session $session */ + $session = Mage::getSingleton('adminhtml/session'); + $tags = $observer->getTags(); + + // check if we should process tags from product which has no relevant changes + $skippableProductIds = Mage::registry(self::REGISTRY_SKIPPABLE_NAME); + if (null !== $skippableProductIds) { + foreach ((array) $tags as $tag) { + if (preg_match('/^catalog_product_(\d+)?/', $tag, $match)) { + if (isset($match[1]) && in_array($match[1], $skippableProductIds)) { + return $this; + } + } + } + } + + $urls = array(); + if ($tags == array()) { + $errors = Mage::helper('aoestatic')->purgeAll(); + if (!empty($errors)) { + $session->addError($helper->__("Static Purge failed")); + } else { + $session->addSuccess($helper->__("The Static cache storage has been flushed.")); + } + + return $this; + } + + // compute the urls for affected entities + foreach ((array)$tags as $tag) { + if (in_array($tag, $this->_tags_already_processed)) { + continue; + } + + $this->_tags_already_processed[] = $tag; + + //catalog_product_100 or catalog_category_186 + $tag_fields = explode('_', $tag); + if (count($tag_fields) == 3) { + switch ($tag_fields[1]) { + case 'product': + // get urls for product + $product = Mage::getModel('catalog/product')->load($tag_fields[2]); + $urls = array_merge($urls, Mage::helper('aoestatic/url')->_getUrlsForProduct($product)); + break; + + case 'category': + $category = Mage::getModel('catalog/category')->load($tag_fields[2]); + $category_urls = Mage::helper('aoestatic/url')->_getUrlsForCategory($category); + $urls = array_merge($urls, $category_urls); + break; + + case 'page': + $urls = Mage::helper('aoestatic/url')->_getUrlsForCmsPage($tag_fields[2]); + break; + } + } + } + // transform urls to relative urls + $relativeUrls = array(); + foreach ($urls as $url) { + $relativeUrls[] = parse_url($url, PHP_URL_PATH); + } + if (!empty($relativeUrls)) { + $errors = Mage::helper('aoestatic')->purge($relativeUrls); + if (!empty($errors)) { + $session->addError($helper->__("Some Static purges failed:
") . implode("
", $errors)); + } else { + $count = count($relativeUrls); + if ($count > 5) { + $relativeUrls = array_slice($relativeUrls, 0, 5); + $relativeUrls[] = '...'; + $relativeUrls[] = $helper->__("(Total number of purged urls: %d)", $count); + } + $session->addSuccess( + $helper->__("Purges have been submitted successfully:
") . implode("
", $relativeUrls) + ); + } + } + return $this; } } diff --git a/app/code/community/Aoe/Static/Model/Resource/BlacklistUrlPattern.php b/app/code/community/Aoe/Static/Model/Resource/BlacklistUrlPattern.php new file mode 100644 index 0000000..10fc188 --- /dev/null +++ b/app/code/community/Aoe/Static/Model/Resource/BlacklistUrlPattern.php @@ -0,0 +1,45 @@ + + */ +class Aoe_Static_Model_Resource_BlacklistUrlPattern extends Mage_Core_Model_Resource_Db_Abstract +{ + protected function _construct() + { + $this->_init('aoestatic/blacklist_url_pattern', 'pattern_id'); + } + + /** + * Initialize unique field + * + * @return $this + */ + protected function _initUniqueFields() + { + $this->_uniqueFields = array( + array( + 'field' => array('pattern'), + 'title' => Mage::helper('aoestatic')->__('Blacklist Url Pattern'), + ) + ); + + return $this; + } + + /** + * Delete url patterns with given ids + * + * @param array $patternIds + * @return $this + */ + public function deleteBlacklistUrlPatterns(array $patternIds) + { + $this->_getWriteAdapter()->delete($this->getMainTable(), + array('pattern_id IN(?)' => $patternIds) + ); + + return $this; + } +} diff --git a/app/code/community/Aoe/Static/etc/adminhtml.xml b/app/code/community/Aoe/Static/etc/adminhtml.xml index e56a0f5..f9bf8a9 100644 --- a/app/code/community/Aoe/Static/etc/adminhtml.xml +++ b/app/code/community/Aoe/Static/etc/adminhtml.xml @@ -8,6 +8,12 @@ adminhtml/aoestatic_customUrl 10 + + + Aoe Static Cache Url Blacklist + adminhtml/aoestatic_blacklistUrlPattern + 11 + @@ -31,6 +37,21 @@ + + + Manage Aoe Static Cache Url Blacklist + 0 + + + Save Url Pattern + 0 + + + Delete Url Pattern + 10 + + + diff --git a/app/code/community/Aoe/Static/etc/config.xml b/app/code/community/Aoe/Static/etc/config.xml index 042c5ff..bd8e587 100644 --- a/app/code/community/Aoe/Static/etc/config.xml +++ b/app/code/community/Aoe/Static/etc/config.xml @@ -4,7 +4,7 @@ true local - 0.0.5 + 0.0.6 @@ -25,6 +25,10 @@ aoestatic_custom_url
+ + + aoestatic_blacklist_url_pattern
+
@@ -41,6 +45,45 @@ + + + + + AOE Static Cache + + + + + + + + + aoestatic/asyncCacheObserver + aoeasynccacheProcessqueuePostprocessjobcollection + + + + + + + singleton + aoestatic/observer + applicationCleanCache + + + + + + + + singleton + aoestatic/observer + catalogCategorySaveCommitAfter + + + + @@ -56,7 +99,7 @@ standard Aoe_Static - phone + aoestatic @@ -75,12 +118,22 @@ - + aoestatic/observer beforeLoadLayout - + + + + + + singleton + aoestatic/observer + coreBlockAbstractToHtmlBefore + + +
@@ -104,5 +157,16 @@ + + + + + singleton + aoestatic/observer + controllerActionPredispatchAdminhtmlCacheIndex + + + + diff --git a/app/code/community/Aoe/Static/sql/aoestatic_setup/upgrade-0.0.5-0.0.6.php b/app/code/community/Aoe/Static/sql/aoestatic_setup/upgrade-0.0.5-0.0.6.php new file mode 100644 index 0000000..296d1d9 --- /dev/null +++ b/app/code/community/Aoe/Static/sql/aoestatic_setup/upgrade-0.0.5-0.0.6.php @@ -0,0 +1,30 @@ +startSetup(); + +/** + * Create table 'aoestatic/blacklist_url_pattern' + */ +$table = $installer->getConnection() + ->newTable($installer->getTable('aoestatic/blacklist_url_pattern')) + ->addColumn('pattern_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array( + 'identity' => true, + 'unsigned' => true, + 'nullable' => false, + 'primary' => true, + ), 'Pattern Id' + ) + ->addColumn('pattern', Varien_Db_Ddl_Table::TYPE_TEXT, 255, array( + ), 'Pattern' + ) + ->addIndex($installer->getIdxName('aoestatic/blacklist_url_pattern', array('pattern'), + Varien_Db_Adapter_Interface::INDEX_TYPE_UNIQUE), + array('pattern'), array('type' => Varien_Db_Adapter_Interface::INDEX_TYPE_UNIQUE) + ) + ->setComment('Blacklist to filter urls added to async cache queue'); + +$installer->getConnection()->createTable($table); + +$installer->endSetup(); diff --git a/app/design/adminhtml/default/default/layout/aoestatic/aoestatic.xml b/app/design/adminhtml/default/default/layout/aoestatic/aoestatic.xml index 30e5cf9..1893651 100644 --- a/app/design/adminhtml/default/default/layout/aoestatic/aoestatic.xml +++ b/app/design/adminhtml/default/default/layout/aoestatic/aoestatic.xml @@ -13,4 +13,23 @@ + + + + + + + + + + + + + + + + + + + From 76419897999834968c21d0a89d3095a4e5bf5e0b Mon Sep 17 00:00:00 2001 From: Bastian Ike Date: Wed, 20 Nov 2013 12:15:53 +0100 Subject: [PATCH 030/136] added missing files --- .../Adminhtml/BlacklistUrlPattern/Edit.php | 73 +++++++++++ .../BlacklistUrlPattern/Edit/Form.php | 62 ++++++++++ .../Adminhtml/BlacklistUrlPattern/Grid.php | 115 ++++++++++++++++++ .../BlacklistUrlPattern/Collection.php | 14 +++ .../default/template/aoestatic/purge.phtml | 28 +++++ 5 files changed, 292 insertions(+) create mode 100644 app/code/community/Aoe/Static/Block/Adminhtml/BlacklistUrlPattern/Edit.php create mode 100644 app/code/community/Aoe/Static/Block/Adminhtml/BlacklistUrlPattern/Edit/Form.php create mode 100644 app/code/community/Aoe/Static/Block/Adminhtml/BlacklistUrlPattern/Grid.php create mode 100644 app/code/community/Aoe/Static/Model/Resource/BlacklistUrlPattern/Collection.php create mode 100644 app/design/adminhtml/default/default/template/aoestatic/purge.phtml diff --git a/app/code/community/Aoe/Static/Block/Adminhtml/BlacklistUrlPattern/Edit.php b/app/code/community/Aoe/Static/Block/Adminhtml/BlacklistUrlPattern/Edit.php new file mode 100644 index 0000000..bcafd7d --- /dev/null +++ b/app/code/community/Aoe/Static/Block/Adminhtml/BlacklistUrlPattern/Edit.php @@ -0,0 +1,73 @@ + + */ +class Aoe_Static_Block_Adminhtml_BlacklistUrlPattern_Edit extends Mage_Adminhtml_Block_Widget_Form_Container +{ + /** + * Initialize edit form container + */ + public function __construct() + { + $this->_objectId = 'id'; + $this->_blockGroup = 'aoestatic'; + $this->_controller = 'adminhtml_blacklistUrlPattern'; + + parent::__construct(); + + if ($this->_isAllowedAction('save')) { + $this->_updateButton('save', 'label', Mage::helper('aoestatic')->__('Save blacklist url pattern')); + $this->_addButton('saveandcontinue', array( + 'label' => Mage::helper('aoestatic')->__('Save and Continue Edit'), + 'onclick' => 'saveAndContinueEdit()', + 'class' => 'save', + ), -100); + } else { + $this->_removeButton('save'); + } + + if ($this->_isAllowedAction('delete')) { + $this->_updateButton('delete', 'label', + Mage::helper('aoestatic')->__('Delete blacklist url pattern') + ); + } else { + $this->_removeButton('delete'); + } + + $this->_formScripts[] = " + function saveAndContinueEdit(){ + editForm.submit($('edit_form').action+'back/edit/'); + } + "; + } + + /** + * Retrieve text for header element depending on loaded page + * + * @return string + */ + public function getHeaderText() + { + if (Mage::registry('blacklist_url_pattern')->getId()) { + return Mage::helper('aoestatic')->__("Edit blacklist url pattern (ID: %d)", + $this->escapeHtml(Mage::registry('blacklist_url_pattern')->getId()) + ); + } else { + return Mage::helper('aoestatic')->__('New blacklist url pattern'); + } + } + + /** + * Check permission for passed action + * + * @param string $action + * @return bool + */ + protected function _isAllowedAction($action) + { + return Mage::getSingleton('admin/session') + ->isAllowed('system/aoestatic_blacklistUrlPattern/' . $action); + } +} diff --git a/app/code/community/Aoe/Static/Block/Adminhtml/BlacklistUrlPattern/Edit/Form.php b/app/code/community/Aoe/Static/Block/Adminhtml/BlacklistUrlPattern/Edit/Form.php new file mode 100644 index 0000000..ebb0b3f --- /dev/null +++ b/app/code/community/Aoe/Static/Block/Adminhtml/BlacklistUrlPattern/Edit/Form.php @@ -0,0 +1,62 @@ + + */ +class Aoe_Static_Block_Adminhtml_BlacklistUrlPattern_Edit_Form extends Mage_Adminhtml_Block_Widget_Form +{ + /** + * Set form id and title + */ + public function __construct() + { + parent::__construct(); + $this->setId('blacklist_url_pattern_form'); + $this->setTitle(Mage::helper('aoestatic')->__('Blacklist url pattern')); + } + + /** + * Prepare form layout + * + * @return $this + */ + protected function _prepareForm() + { + /** @var $model Aoe_Static_Model_BlacklistUrlPattern */ + $model = Mage::registry('blacklist_url_pattern'); + + $form = new Varien_Data_Form( + array( + 'id' => 'edit_form', + 'action' => $this->getData('action'), + 'method' => 'post' + ) + ); + + // set form data either from model values or from session + $formValues = array( + 'pattern' => $model->getPattern(), + ); + + $fieldset = $form->addFieldset('base_fieldset', array( + 'legend' => Mage::helper('aoestatic')->__('Blacklist url pattern') + )); + + $fieldset->addField('pattern', 'text', array( + 'label' => Mage::helper('aoestatic')->__('Pattern'), + 'title' => Mage::helper('aoestatic')->__('Pattern'), + 'class' => 'required-entry', + 'name' => 'pattern', + 'required' => true, + 'value' => $formValues['pattern'], + 'note' => 'Should be valid PHP PCRE Pattern' + )); + + $form->setUseContainer(true); + $form->setAction(Mage::helper('adminhtml')->getUrl('*/*/save', array('id' => $model->getId()))); + $this->setForm($form); + + return parent::_prepareForm(); + } +} diff --git a/app/code/community/Aoe/Static/Block/Adminhtml/BlacklistUrlPattern/Grid.php b/app/code/community/Aoe/Static/Block/Adminhtml/BlacklistUrlPattern/Grid.php new file mode 100644 index 0000000..375c9ce --- /dev/null +++ b/app/code/community/Aoe/Static/Block/Adminhtml/BlacklistUrlPattern/Grid.php @@ -0,0 +1,115 @@ + + */ +class Aoe_Static_Block_Adminhtml_BlacklistUrlPattern_Grid extends Mage_Adminhtml_Block_Widget_Grid +{ + /** + * Init grid default properties + */ + public function __construct() + { + parent::__construct(); + $this->setId('blacklist_url_list_grid'); + $this->setDefaultSort('blacklist_url_id'); + $this->setUseAjax(true); + } + + /** + * Prepare collection for grid + * + * @return $this + */ + protected function _prepareCollection() + { + /** @var $collection Aoe_Static_Model_Resource_BlacklistUrlPattern_Collection */ + $collection = Mage::getResourceModel('aoestatic/blacklistUrlPattern_collection'); + + $this->setCollection($collection); + return parent::_prepareCollection(); + } + + /** + * Return row URL for js event handlers + * + * @param Aoe_Static_Model_BlacklistUrlPattern $row + * @return string + */ + public function getRowUrl($row) + { + return $this->getUrl('*/*/edit', array('id' => $row->getId())); + } + + /** + * Prepare Grid columns + * + * @return $this + */ + protected function _prepareColumns() + { + $this->addColumn('pattern_id', array( + 'header' => Mage::helper('aoestatic')->__('ID'), + 'width' => '20px', + 'index' => 'pattern_id' + )); + + $this->addColumn('pattern', array( + 'header' => Mage::helper('aoestatic')->__('Url Pattern'), + 'width' => '95%', + 'index' => 'pattern' + )); + + $this->addColumn('action', + array( + 'header' => Mage::helper('aoestatic')->__('Actions'), + 'width' => '50px', + 'type' => 'action', + 'getter' => 'getId', + 'actions' => array( + array( + 'caption' => Mage::helper('aoestatic')->__('Delete'), + 'url' => array( + 'base' => '*/*/delete', + ), + 'field' => 'id', + 'confirm' => Mage::helper('aoestatic')->__('Are you sure you want delete url pattern?') + ) + ), + 'filter' => false, + 'sortable' => false, + ) + ); + + return parent::_prepareColumns(); + } + + /** + * Prepare grid massaction actions + * + * @return $this + */ + protected function _prepareMassaction() + { + $this->setMassactionIdField('pattern_id'); + $this->getMassactionBlock()->setFormFieldName('pattern_ids'); + $this->getMassactionBlock()->addItem('delete', array( + 'label' => Mage::helper('aoestatic')->__('Delete'), + 'url' => $this->getUrl('*/*/massDelete'), + 'confirm' => Mage::helper('aoestatic')->__('Are you sure you want to delete the selected url pattern(s)?') + )); + + return $this; + } + + /** + * Grid url getter + * + * @return string current grid url + */ + public function getGridUrl() + { + return $this->getUrl('*/*/grid', array('_current' => true)); + } +} diff --git a/app/code/community/Aoe/Static/Model/Resource/BlacklistUrlPattern/Collection.php b/app/code/community/Aoe/Static/Model/Resource/BlacklistUrlPattern/Collection.php new file mode 100644 index 0000000..a4f6b38 --- /dev/null +++ b/app/code/community/Aoe/Static/Model/Resource/BlacklistUrlPattern/Collection.php @@ -0,0 +1,14 @@ + + */ +class Aoe_Static_Model_Resource_BlacklistUrlPattern_Collection + extends Mage_Core_Model_Resource_Db_Collection_Abstract +{ + protected function _construct() + { + $this->_init('aoestatic/blacklistUrlPattern'); + } +} diff --git a/app/design/adminhtml/default/default/template/aoestatic/purge.phtml b/app/design/adminhtml/default/default/template/aoestatic/purge.phtml new file mode 100644 index 0000000..70461a7 --- /dev/null +++ b/app/design/adminhtml/default/default/template/aoestatic/purge.phtml @@ -0,0 +1,28 @@ + +
+
+ + + + +

__('Purge Urls from AOE Static Cache') ?>

+
+
+ + + + + + + + + +
+ +
+ + +
+
From e9fdc2f09d1306226b83e39341d6bce78c96eae5 Mon Sep 17 00:00:00 2001 From: Bastian Ike Date: Wed, 20 Nov 2013 13:36:42 +0100 Subject: [PATCH 031/136] fixes and phpdoc --- app/code/community/Aoe/Static/Helper/Data.php | 8 ++-- .../Aoe/Static/Model/Cache/Control.php | 42 +++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/app/code/community/Aoe/Static/Helper/Data.php b/app/code/community/Aoe/Static/Helper/Data.php index 8c9500c..0abaa9b 100644 --- a/app/code/community/Aoe/Static/Helper/Data.php +++ b/app/code/community/Aoe/Static/Helper/Data.php @@ -82,10 +82,10 @@ public function getBlacklist() * * @todo names/consts * @param array $urls - * @param bool $async + * @param bool $queue * @return array */ - public function purge(array $urls, $async = true) + public function purge(array $urls, $queue = true) { $urls = array_filter($urls, function ($e) { return strlen($e) ? true : false; }); $result = array(); @@ -93,12 +93,12 @@ public function purge(array $urls, $async = true) /** @var Aoe_Static_Model_Adapter_Interface $adapter */ // queue if async cache is enabled in config and not forced to purge directly - if ($this->getConfig()->useAsyncCache() && $async) { + if ($this->getConfig()->useAsyncCache() && $queue) { foreach ($urls as $url) { /** @var $asyncCache Aoe_AsyncCache_Model_Asynccache */ $asyncCache = Mage::getModel('aoeasynccache/asynccache'); $asyncCache->setTstamp(time()) - ->setMode(Aoe_VarnishAsyncCache_Helper_Data::MODE_PURGEVARNISHURL) + ->setMode(Aoe_Static_Helper_Data::MODE_PURGEVARNISHURL) ->setTags($url) ->setStatus(Aoe_AsyncCache_Model_Asynccache::STATUS_PENDING) ->save(); diff --git a/app/code/community/Aoe/Static/Model/Cache/Control.php b/app/code/community/Aoe/Static/Model/Cache/Control.php index 3d850de..55898bd 100644 --- a/app/code/community/Aoe/Static/Model/Cache/Control.php +++ b/app/code/community/Aoe/Static/Model/Cache/Control.php @@ -2,22 +2,38 @@ class Aoe_Static_Model_Cache_Control { + /** @var array Tags for tag-based purging */ protected $_tags = array(); + + /** @var int minimum maxage */ protected $_maxAge = 0; + + /** @var bool switch to disable sending out of cache headers */ protected $_enabled = true; + /** + * @return $this + */ public function enable() { $this->_enabled = true; return $this; } + /** + * @return $this + */ public function disable() { $this->_enabled = false; return $this; } + /** + * computes minimum max-age + * + * @param int|array $maxAge + */ public function addMaxAge($maxAge) { if (!is_array($maxAge)) { @@ -31,6 +47,11 @@ public function addMaxAge($maxAge) } } + /** + * loads specific max-age from database + * + * @param $request Mage_Core_Controller_Request_Http + */ public function addCustomUrlMaxAge($request) { // apply custom max-age from db @@ -49,6 +70,12 @@ public function addCustomUrlMaxAge($request) } } + /** + * adds tag(s) to currect cache + * + * @param $tags array|string + * @return $this + */ public function addTag($tags) { if (!is_array($tags)) { @@ -61,8 +88,15 @@ public function addTag($tags) } $this->_tags[$tag]++; } + + return $this; } + /** + * applies cache-headers if enabled is true (default) + * + * @return $this + */ public function applyCacheHeaders() { if ($this->_enabled) { @@ -72,6 +106,8 @@ public function applyCacheHeaders() $response->setHeader('X-Magento-Lifetime', (int) $this->_maxAge, true); $response->setHeader('aoestatic', 'cache', true); } + + return $this; } /** @@ -88,6 +124,11 @@ protected function _getLayer() return Mage::getSingleton('catalog/layer'); } + /** + * collect various possible tags from current products and category/layer pages + * + * @return $this + */ public function collectTags() { if (Mage::registry('product')) { @@ -107,5 +148,6 @@ public function collectTags() $currentCategory = Mage::registry('current_category'); $this->addTag('category-' . $currentCategory->getId()); } + return $this; } } From 44a2741821de1cc6145b68eea119170ff4bd75a4 Mon Sep 17 00:00:00 2001 From: Bastian Ike Date: Wed, 20 Nov 2013 13:54:56 +0100 Subject: [PATCH 032/136] implemented tag-based purging --- app/code/community/Aoe/Static/Helper/Data.php | 12 ++ .../Static/Model/Cache/Adapter/Interface.php | 13 ++ .../Static/Model/Cache/Adapter/Varnish.php | 124 ++++++++++++++++++ .../community/Aoe/Static/Model/Observer.php | 35 +++-- 4 files changed, 164 insertions(+), 20 deletions(-) create mode 100644 app/code/community/Aoe/Static/Model/Cache/Adapter/Interface.php create mode 100644 app/code/community/Aoe/Static/Model/Cache/Adapter/Varnish.php diff --git a/app/code/community/Aoe/Static/Helper/Data.php b/app/code/community/Aoe/Static/Helper/Data.php index 0abaa9b..8198127 100644 --- a/app/code/community/Aoe/Static/Helper/Data.php +++ b/app/code/community/Aoe/Static/Helper/Data.php @@ -109,4 +109,16 @@ public function purge(array $urls, $queue = true) } return $result; } + + public function purgeTags($tags) + { + $result = array(); + foreach ($tags as $tag) { + foreach ($this->_getAdapterInstances() as $adapter) { + /** @var Aoe_Static_Model_Cache_Adapter_Interface $adapter */ + $result = array_merge($result, $adapter->purgeTags($tag)); + } + } + return $result; + } } diff --git a/app/code/community/Aoe/Static/Model/Cache/Adapter/Interface.php b/app/code/community/Aoe/Static/Model/Cache/Adapter/Interface.php new file mode 100644 index 0000000..1a92bfe --- /dev/null +++ b/app/code/community/Aoe/Static/Model/Cache/Adapter/Interface.php @@ -0,0 +1,13 @@ +purge(array('/.*')); + } + + /** + * Purge an array of urls on all varnish servers. + * + * @param array $urls + * @return array with all errors + */ + public function purge(array $urls) + { + $errors = array(); + + // Init curl handler + $curlHandlers = array(); // keep references for clean up + $mh = curl_multi_init(); + + foreach ($this->_varnishServers as $varnishServer) { + foreach ($urls as $url) { + $varnishUrl = "http://" . $varnishServer . $url; + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $varnishUrl); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PURGE'); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); + + curl_multi_add_handle($mh, $ch); + $curlHandlers[] = $ch; + } + } + + do { + curl_multi_exec($mh, $active); + } while ($active); + + // Error handling and clean up + foreach ($curlHandlers as $ch) { + $info = curl_getinfo($ch); + + if (curl_errno($ch)) { + $errors[] = "Cannot purge url {$info['url']} due to error" . curl_error($ch); + } else if ($info['http_code'] != 200 && $info['http_code'] != 404) { + $errors[] = "Cannot purge url {$info['url']}, http code: {$info['http_code']}. curl error: " . curl_error($ch); + } + + curl_multi_remove_handle($mh, $ch); + curl_close($ch); + } + curl_multi_close($mh); + + return $errors; + } + + public function purgeTags(array $tags) + { + $errors = array(); + // Init curl handler + $curlHandlers = array(); // keep references for clean up + $mh = curl_multi_init(); + + foreach ($this->_varnishServers as $varnishServer) { + foreach ($tags as $tag) { + $varnishUrl = "http://" . $varnishServer; + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $varnishUrl); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'BAN'); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); + curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-Invalidates: |' . $tag . '|')); + + curl_multi_add_handle($mh, $ch); + $curlHandlers[] = $ch; + } + } + + do { + curl_multi_exec($mh, $active); + } while ($active); + + // Error handling and clean up + foreach ($curlHandlers as $ch) { + $info = curl_getinfo($ch); + + if (curl_errno($ch)) { + $errors[] = "Cannot purge tag {$info['url']} due to error" . curl_error($ch); + } else if ($info['http_code'] != 200 && $info['http_code'] != 404) { + $errors[] = "Cannot purge tag {$info['url']}, http code: {$info['http_code']}. curl error: " . curl_error($ch); + } + + curl_multi_remove_handle($mh, $ch); + curl_close($ch); + } + curl_multi_close($mh); + } + + /** + * set's varnish server urls + * + * @param string|array $config + */ + public function setConfig($config) + { + $this->_varnishServers = array_map('trim', explode("\n", trim($config['urls']))); + } +} diff --git a/app/code/community/Aoe/Static/Model/Observer.php b/app/code/community/Aoe/Static/Model/Observer.php index ece122d..e37de62 100644 --- a/app/code/community/Aoe/Static/Model/Observer.php +++ b/app/code/community/Aoe/Static/Model/Observer.php @@ -241,7 +241,6 @@ public function catalogCategorySaveCommitAfter($observer) /** * Listens to application_clean_cache event and gets notified when a product/category/cms model is saved * - * @todo tzags isntead of urls * @param $observer Mage_Core_Model_Observer * @return Aoe_Static_Model_Observer */ @@ -270,7 +269,7 @@ public function applicationCleanCache($observer) } } - $urls = array(); + $tags = array(); if ($tags == array()) { $errors = Mage::helper('aoestatic')->purgeAll(); if (!empty($errors)) { @@ -296,40 +295,36 @@ public function applicationCleanCache($observer) switch ($tag_fields[1]) { case 'product': // get urls for product - $product = Mage::getModel('catalog/product')->load($tag_fields[2]); - $urls = array_merge($urls, Mage::helper('aoestatic/url')->_getUrlsForProduct($product)); + $tags[] = 'product-' . $tag_fields[2]; break; case 'category': - $category = Mage::getModel('catalog/category')->load($tag_fields[2]); - $category_urls = Mage::helper('aoestatic/url')->_getUrlsForCategory($category); - $urls = array_merge($urls, $category_urls); + $tags[] = 'category-' . $tag_fields[2]; break; case 'page': - $urls = Mage::helper('aoestatic/url')->_getUrlsForCmsPage($tag_fields[2]); + $tags[] = 'page-' . $tag_fields[2]; + break; + + case 'block': + $tags[] = 'block-' . $tag_fields[2]; break; } } } - // transform urls to relative urls - $relativeUrls = array(); - foreach ($urls as $url) { - $relativeUrls[] = parse_url($url, PHP_URL_PATH); - } - if (!empty($relativeUrls)) { - $errors = Mage::helper('aoestatic')->purge($relativeUrls); + if (!empty($tags)) { + $errors = Mage::helper('aoestatic')->purgeTags($tags); if (!empty($errors)) { $session->addError($helper->__("Some Static purges failed:
") . implode("
", $errors)); } else { - $count = count($relativeUrls); + $count = count($tags); if ($count > 5) { - $relativeUrls = array_slice($relativeUrls, 0, 5); - $relativeUrls[] = '...'; - $relativeUrls[] = $helper->__("(Total number of purged urls: %d)", $count); + $tags = array_slice($tags, 0, 5); + $tags[] = '...'; + $tags[] = $helper->__("(Total number of purged urls: %d)", $count); } $session->addSuccess( - $helper->__("Purges have been submitted successfully:
") . implode("
", $relativeUrls) + $helper->__("Purges have been submitted successfully:
") . implode("
", $tags) ); } } From ae2c799484037d62a502134d87a967b69a06c76e Mon Sep 17 00:00:00 2001 From: Bastian Ike Date: Wed, 20 Nov 2013 14:50:24 +0100 Subject: [PATCH 033/136] fixes --- .../Aoe/Static/Model/Cache/Control.php | 2 +- .../Aoe/Static/Model/Cache/Marker.php | 14 +- .../community/Aoe/Static/Model/Observer.php | 3 + .../BlacklistUrlPatternController.php | 252 ++++++++++++++++++ .../community/Aoe/Static/etc/aoe_static.xml | 7 +- app/code/community/Aoe/Static/etc/config.xml | 2 - app/etc/modules/Aoe_Static.xml | 14 +- modman | 1 + 8 files changed, 277 insertions(+), 18 deletions(-) create mode 100644 app/code/community/Aoe/Static/controllers/Adminhtml/Aoestatic/BlacklistUrlPatternController.php diff --git a/app/code/community/Aoe/Static/Model/Cache/Control.php b/app/code/community/Aoe/Static/Model/Cache/Control.php index 55898bd..cc53342 100644 --- a/app/code/community/Aoe/Static/Model/Cache/Control.php +++ b/app/code/community/Aoe/Static/Model/Cache/Control.php @@ -101,7 +101,7 @@ public function applyCacheHeaders() { if ($this->_enabled) { $response = Mage::app()->getResponse(); - $response->setHeader('X-Invalidated-By', '|' . implode('|', $this->_tags) . '|'); + $response->setHeader('X-Invalidated-By', '|' . implode('|', array_keys($this->_tags)) . '|'); $response->setHeader('Cache-Control', 'max-age=' . (int) $this->_maxAge, true); $response->setHeader('X-Magento-Lifetime', (int) $this->_maxAge, true); $response->setHeader('aoestatic', 'cache', true); diff --git a/app/code/community/Aoe/Static/Model/Cache/Marker.php b/app/code/community/Aoe/Static/Model/Cache/Marker.php index a11f83c..7802435 100644 --- a/app/code/community/Aoe/Static/Model/Cache/Marker.php +++ b/app/code/community/Aoe/Static/Model/Cache/Marker.php @@ -9,9 +9,9 @@ class Aoe_Static_Model_Cache_Marker /** * Local cache for calculated values of markers - * @var null | array + * @var array */ - protected $_markersValues = null; + protected $_markersValues = array(); /** * Constructor @@ -40,11 +40,11 @@ public function replaceMarkers($value) { $matches = array(); preg_match_all('|###[^#]+###|', $value, $matches); - $markersWithoutValues = array_diff($matches[0], array_keys($this->markersValues)); + $markersWithoutValues = array_diff($matches[0], array_keys($this->_markersValues)); foreach($markersWithoutValues as $marker) { - $this->markersValues[$marker] = $this->getMarkerValue($marker); + $this->_markersValues[$marker] = $this->getMarkerValue($marker); } - $value = str_replace(array_keys($this->markersValues), array_values($this->markersValues), $value); + $value = str_replace(array_keys($this->_markersValues), array_values($this->_markersValues), $value); return $value; } @@ -57,8 +57,8 @@ public function replaceMarkers($value) public function getMarkerValue($marker) { $markerValue = $marker; - if (isset($this->markersValues[$marker]) && $this->markersValues[$marker] !== NULL) { - $markerValue = $this->markersValues[$marker]; + if (isset($this->_markersValues[$marker]) && $this->_markersValues[$marker] !== NULL) { + $markerValue = $this->_markersValues[$marker]; } elseif ($this->_config->getMarkerCallback($marker)) { $markerValue = $this->executeCallback($this->_config->getMarkerCallback($marker)); } diff --git a/app/code/community/Aoe/Static/Model/Observer.php b/app/code/community/Aoe/Static/Model/Observer.php index e37de62..1b04bc1 100644 --- a/app/code/community/Aoe/Static/Model/Observer.php +++ b/app/code/community/Aoe/Static/Model/Observer.php @@ -136,6 +136,9 @@ protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Con $cookie->set($name, $value, $period, $path, $domain, $secure, $httponly); } } + if ($conf->cache) { + Mage::getSingleton('aoestatic/cache_control')->addMaxAge($conf->cache->maxage); + } } /** diff --git a/app/code/community/Aoe/Static/controllers/Adminhtml/Aoestatic/BlacklistUrlPatternController.php b/app/code/community/Aoe/Static/controllers/Adminhtml/Aoestatic/BlacklistUrlPatternController.php new file mode 100644 index 0000000..a08f86e --- /dev/null +++ b/app/code/community/Aoe/Static/controllers/Adminhtml/Aoestatic/BlacklistUrlPatternController.php @@ -0,0 +1,252 @@ + + */ +class Aoe_Static_Adminhtml_Aoestatic_BlacklistUrlPatternController + extends Mage_Adminhtml_Controller_Action +{ + /** + * Init actions + * + * @return $this + */ + protected function _initAction() + { + // load layout, set active menu and breadcrumbs + $this->loadLayout() + ->_setActiveMenu('system/aoestatic_blacklistUrlPattern') + ->_addBreadcrumb( + Mage::helper('aoestatic')->__('System'), + Mage::helper('aoestatic')->__('System') + ) + ->_addBreadcrumb( + Mage::helper('aoestatic')->__('AOE Static Cache Url Blacklist'), + Mage::helper('aoestatic')->__('AOE Static Cache Url Blacklist') + ); + return $this; + } + + /** + * Index action + */ + public function indexAction() + { + $this->_title(Mage::helper('aoestatic')->__('System')) + ->_title(Mage::helper('aoestatic')->__('AOE Static Cache Url Blacklist')); + + $this->_initAction(); + $this->renderLayout(); + } + + /** + * Create new blacklist url + */ + public function newAction() + { + // the same form is used to create and edit + $this->_forward('edit'); + } + + /** + * Edit blacklist url + */ + public function editAction() + { + $this->_title(Mage::helper('aoestatic')->__('System')) + ->_title(Mage::helper('aoestatic')->__('AOE Static Cache Url Blacklist')); + + /** @var $model Aoe_Static_Model_BlacklistUrlPattern */ + $model = Mage::getModel('aoestatic/blacklistUrlPattern'); + + $blacklistUrlPatternId = $this->getRequest()->getParam('id'); + if ($blacklistUrlPatternId) { + $model->load($blacklistUrlPatternId); + + if (!$model->getId()) { + $this->_getSession()->addError( + Mage::helper('aoestatic')->__('Blacklist url pattern does not exist.') + ); + $this->_redirect('*/*/'); + return; + } + // prepare title + $breadCrumb = Mage::helper('aoestatic')->__('Edit blacklist url pattern (ID: %d)', $model->getId()); + } else { + $breadCrumb = Mage::helper('aoestatic')->__('New url pattern'); + } + + // Init breadcrumbs + $this->_title($breadCrumb); + $this->_initAction()->_addBreadcrumb($breadCrumb, $breadCrumb); + + $data = Mage::getSingleton('adminhtml/session')->getFormData(true); + if (!empty($data)) { + $model->addData($data); + } + + Mage::register('blacklist_url_pattern', $model); + + $this->renderLayout(); + } + + /** + * Save action + */ + public function saveAction() + { + $redirectPath = '*/*'; + $redirectParams = array(); + + // check if data sent + $data = $this->getRequest()->getPost(); + if ($data) { + // init model and set data + /** @var $model Aoe_Static_Model_BlacklistUrlPattern */ + $model = Mage::getModel('aoestatic/blacklistUrlPattern'); + + // if blacklist url pattern exists, try to load it + $blacklistUrlPatternId = $this->getRequest()->getParam('id'); + if ($blacklistUrlPatternId) { + $model->load($blacklistUrlPatternId); + } + + $model->addData($data); + + try { + $hasError = false; + + // save the data + $model->save(); + + // display success message + $this->_getSession()->addSuccess( + Mage::helper('aoestatic')->__('Blacklist url pattern has been saved.') + ); + + // check if 'Save and Continue' + if ($this->getRequest()->getParam('back')) { + $redirectPath = '*/*/edit'; + $redirectParams = array('id' => $model->getId()); + } + } catch (Mage_Core_Exception $e) { + $hasError = true; + $this->_getSession()->addError($e->getMessage()); + } catch (Exception $e) { + $hasError = true; + $this->_getSession()->addException($e, + Mage::helper('aoestatic')->__('An error occurred while saving blacklist url pattern.') + ); + } + + if ($hasError) { + $this->_getSession()->setFormData($data); + $redirectPath = '*/*/edit'; + $redirectParams = array('id' => $this->getRequest()->getParam('id')); + } + } + + $this->_redirect($redirectPath, $redirectParams); + } + + /** + * Delete action + */ + public function deleteAction() + { + // check if we know what should be deleted + $blacklistUrlPatternId = $this->getRequest()->getParam('id'); + if ($blacklistUrlPatternId) { + try { + // init model and delete + /** @var $model Aoe_Static_Model_BlacklistUrlPattern */ + $model = Mage::getModel('aoestatic/blacklistUrlPattern'); + $model->load($blacklistUrlPatternId); + if (!$model->getId()) { + Mage::throwException( + Mage::helper('aoestatic')->__('Unable to find a blacklist url pattern.') + ); + } + $model->delete(); + + // display success message + $this->_getSession()->addSuccess( + Mage::helper('aoestatic')->__('Blacklist url pattern has been deleted.') + ); + } catch (Mage_Core_Exception $e) { + $this->_getSession()->addError($e->getMessage()); + } catch (Exception $e) { + $this->_getSession()->addException($e, + Mage::helper('aoestatic')->__('An error occurred while deleting blacklist url pattern.') + ); + } + } + + // go to grid + $this->_redirect('*/*/'); + } + + /** + * Check the permission to run it + * + * @return boolean + */ + protected function _isAllowed() + { + /** @var Mage_Admin_Model_Session $session */ + $session = Mage::getSingleton('admin/session'); + switch ($this->getRequest()->getActionName()) { + case 'new': + case 'save': + return $session->isAllowed('system/aoestatic_blacklistUrlPattern/save'); + break; + case 'delete': + return $session->isAllowed('system/aoestatic_blacklistUrlPattern/delete'); + break; + default: + return $session->isAllowed('system/aoestatic_blacklistUrlPattern'); + break; + } + } + + /** + * Grid ajax action + */ + public function gridAction() + { + $this->loadLayout(); + $this->renderLayout(); + } + + /** + * Mass delete action + */ + public function massDeleteAction() + { + $patternIds = $this->getRequest()->getParam('pattern_ids'); + if (!is_array($patternIds)) { + $this->_getSession()->addError( + Mage::helper('aoestatic')->__('Please select pattern(s) to delete.') + ); + } else { + if (!empty($patternIds)) { + try { + /** @var Aoe_Static_Model_BlacklistUrlPattern $blacklistUrlPatternModel */ + $blacklistUrlPatternModel = Mage::getModel('aoestatic/blacklistUrlPattern'); + $blacklistUrlPatternModel->deleteBlacklistUrlPatterns($patternIds); + $this->_getSession()->addSuccess( + Mage::helper('aoestatic')->__('Total of %d pattern(s) have been deleted.', count($patternIds)) + ); + } catch (Mage_Core_Exception $e) { + $this->_getSession()->addError($e->getMessage()); + } catch (Exception $e) { + $this->_getSession()->addException($e, + Mage::helper('aoestatic')->__('An error occurred while deleting blacklist url pattern(s).') + ); + } + } + } + $this->_redirectReferer(); + } +} diff --git a/app/code/community/Aoe/Static/etc/aoe_static.xml b/app/code/community/Aoe/Static/etc/aoe_static.xml index f7bdac0..a4c5302 100644 --- a/app/code/community/Aoe/Static/etc/aoe_static.xml +++ b/app/code/community/Aoe/Static/etc/aoe_static.xml @@ -79,11 +79,16 @@ 0 + + 86400 + + @@ -100,4 +105,4 @@ - \ No newline at end of file + diff --git a/app/code/community/Aoe/Static/etc/config.xml b/app/code/community/Aoe/Static/etc/config.xml index bd8e587..56c517c 100644 --- a/app/code/community/Aoe/Static/etc/config.xml +++ b/app/code/community/Aoe/Static/etc/config.xml @@ -2,8 +2,6 @@ - true - local 0.0.6 diff --git a/app/etc/modules/Aoe_Static.xml b/app/etc/modules/Aoe_Static.xml index cf69494..db1d1d6 100644 --- a/app/etc/modules/Aoe_Static.xml +++ b/app/etc/modules/Aoe_Static.xml @@ -1,9 +1,9 @@ - - - true - local - - - \ No newline at end of file + + + true + community + + + diff --git a/modman b/modman index 132b111..260d30b 100644 --- a/modman +++ b/modman @@ -1,5 +1,6 @@ ./app/code/community/Aoe/Static ./app/code/community/Aoe/Static ./app/design/adminhtml/default/default/layout/aoestatic/ ./app/design/adminhtml/default/default/layout/aoestatic/ +./app/design/adminhtml/default/default/template/aoestatic/ ./app/design/adminhtml/default/default/template/aoestatic/ ./app/design/frontend/base/default/layout/aoestatic/ ./app/design/frontend/base/default/layout/aoestatic/ ./app/design/frontend/base/default/template/aoestatic/ ./app/design/frontend/base/default/template/aoestatic/ ./app/etc/modules/Aoe_Static.xml ./app/etc/modules/Aoe_Static.xml From 093e5db0b26e577bfa9cf281e25b8c64368dc83f Mon Sep 17 00:00:00 2001 From: thebod Date: Wed, 20 Nov 2013 14:59:16 +0100 Subject: [PATCH 034/136] updated vcl from varnish 2 to 3 and added BAN --- default.vcl | 203 +++++++++++++++++++++++++++------------------------- 1 file changed, 106 insertions(+), 97 deletions(-) diff --git a/default.vcl b/default.vcl index d0d2038..eb6a788 100755 --- a/default.vcl +++ b/default.vcl @@ -1,103 +1,112 @@ backend default { - .host = "127.0.0.1"; - .port = "80"; - .first_byte_timeout = 300s; + .host = "127.0.0.1"; + .port = "80"; + .first_byte_timeout = 300s; } sub vcl_hash { - set req.hash += req.url; + hash_data(req.url); if (req.http.host) { - set req.hash += req.http.host; + hash_data(req.http.host); } else { - set req.hash += server.ip; + hash_data(server.ip); } - if (req.http.https) { - set req.hash += req.http.https; + if (req.http.https) { + hash_data(req.http.https); } return (hash); } acl cache_acl { - "127.0.0.1"; - # insert additional ip's here + "127.0.0.1"; + # insert additional ip's here } /* Like the default function, only that cookies don't prevent caching */ sub vcl_recv { -# if (req.http.Host != "varnish.demo.aoemedia.de") { -# return (pipe); -# } - - # see http://www.varnish-cache.org/trac/wiki/VCLExampleNormalizeAcceptEncoding - ### parse accept encoding rulesets to normalize - if (req.http.Accept-Encoding) { - if (req.url ~ "\.(jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf|mp4|flv)$") { - # don't try to compress already compressed files - remove req.http.Accept-Encoding; - } elsif (req.http.Accept-Encoding ~ "gzip") { - set req.http.Accept-Encoding = "gzip"; - } elsif (req.http.Accept-Encoding ~ "deflate") { - set req.http.Accept-Encoding = "deflate"; - } else { - # unkown algorithm - remove req.http.Accept-Encoding; - } - } - - if (req.http.x-forwarded-for) { - set req.http.X-Forwarded-For = - req.http.X-Forwarded-For ", " client.ip; - } else { - set req.http.X-Forwarded-For = client.ip; - } - if (req.request != "GET" && - req.request != "HEAD" && - req.request != "PUT" && - req.request != "POST" && - req.request != "TRACE" && - req.request != "OPTIONS" && - req.request != "DELETE") { - /* Non-RFC2616 or CONNECT which is weird. */ - return (pipe); - } - - # Some known-static file types - if (req.url ~ "^[^?]*\.(css|js|htc|xml|txt|swf|flv|pdf|gif|jpe?g|png|ico)$") { - # Pretent no cookie was passed - unset req.http.Cookie; - } - - # Force lookup if the request is a no-cache request from the client. - if (req.http.Cache-Control ~ "no-cache") { - if (client.ip ~ cache_acl) { - purge_url(req.url); - error 200 "Purged."; - } else { - error 405 "Not allowed."; - } - } - - # PURGE requests - if (req.request == "PURGE") { +# if (req.http.Host != "varnish.demo.aoemedia.de") { +# return (pipe); +# } + + # see http://www.varnish-cache.org/trac/wiki/VCLExampleNormalizeAcceptEncoding + ### parse accept encoding rulesets to normalize + if (req.http.Accept-Encoding) { + if (req.url ~ "\.(jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf|mp4|flv)$") { + # don't try to compress already compressed files + remove req.http.Accept-Encoding; + } elsif (req.http.Accept-Encoding ~ "gzip") { + set req.http.Accept-Encoding = "gzip"; + } elsif (req.http.Accept-Encoding ~ "deflate") { + set req.http.Accept-Encoding = "deflate"; + } else { + # unkown algorithm + remove req.http.Accept-Encoding; + } + } + + if (req.request == "BAN") { + if (client.ip ~ cache_acl) { + ban("obj.http.X-Invalidated-By ~ " + req.http.X-Invalidates); + error 200 "Tag banned."; + } else { + error 405 "Not allowed."; + } + } + + if (req.http.x-forwarded-for) { + set req.http.X-Forwarded-For = + req.http.X-Forwarded-For + ", " + client.ip; + } else { + set req.http.X-Forwarded-For = client.ip; + } + if (req.request != "GET" && + req.request != "HEAD" && + req.request != "PUT" && + req.request != "POST" && + req.request != "TRACE" && + req.request != "OPTIONS" && + req.request != "DELETE") { + /* Non-RFC2616 or CONNECT which is weird. */ + return (pipe); + } + + # Some known-static file types + if (req.url ~ "^[^?]*\.(css|js|htc|xml|txt|swf|flv|pdf|gif|jpe?g|png|ico)$") { + # Pretent no cookie was passed + unset req.http.Cookie; + } + + # Force lookup if the request is a no-cache request from the client. + if (req.http.Cache-Control ~ "no-cache") { if (client.ip ~ cache_acl) { - purge_url(req.url); - error 200 "Purged."; - } else { - error 405 "Not allowed."; - } - } - - if (req.request != "GET" && req.request != "HEAD") { - /* We only deal with GET and HEAD by default */ - return (pass); - } - if (req.http.Authorization) { - /* Not cacheable by default */ - return (pass); - } - return (lookup); + ban_url(req.url); + error 200 "Purged."; + } else { + error 405 "Not allowed."; + } + } + + # PURGE requests + if (req.request == "PURGE") { + if (client.ip ~ cache_acl) { + ban_url(req.url); + error 200 "Purged."; + } else { + error 405 "Not allowed."; + } + } + + if (req.request != "GET" && req.request != "HEAD") { + /* We only deal with GET and HEAD by default */ + return (pass); + } + if (req.http.Authorization) { + /* Not cacheable by default */ + return (pass); + } + return (lookup); } /* @@ -116,7 +125,7 @@ sub vcl_fetch { set beresp.http.Cache-Control = "public"; set beresp.grace = 2m; set beresp.http.X_AOESTATIC_FETCH = "Removed cookie in vcl_fetch"; - set beresp.cacheable = true; + set beresp.ttl = 1d; } else { set beresp.http.X_AOESTATIC_FETCH = "Nothing removed"; } @@ -126,17 +135,17 @@ sub vcl_fetch { if (beresp.status >= 400) { set beresp.ttl = 0s; set beresp.http.X_AOESTATIC_FETCH_PASSREASON = "Status greater than 400"; - return(pass); + return(deliver); } - if (!beresp.cacheable) { + if (beresp.ttl < 1d) { set beresp.http.X_AOESTATIC_FETCH_PASSREASON = "Not cacheable"; - return(pass); + return(deliver); } if (req.http.Authorization) { set beresp.http.X_AOESTATIC_FETCH_PASSREASON = "HTTP AUTH"; - return(pass); + return(deliver); } # Some known-static file types @@ -149,17 +158,17 @@ sub vcl_fetch { if (beresp.http.Set-Cookie) { set beresp.http.X_AOESTATIC_FETCH_PASSREASON = "Cookie"; - return(pass); + return(deliver); } if (!beresp.http.Cache-Control ~ "public") { set beresp.http.X_AOESTATIC_FETCH_PASSREASON = "Cache-Control is not public"; - return(pass); + return(deliver); } if (beresp.http.Pragma ~ "(no-cache|private)") { set beresp.http.X_AOESTATIC_FETCH_PASSREASON = "Pragma is no-cache or private"; - return(pass); + return(deliver); } } @@ -167,11 +176,11 @@ sub vcl_fetch { Adding debugging information */ sub vcl_deliver { - if (obj.hits > 0) { - set resp.http.X-Cache = "HIT ("obj.hits")"; - set resp.http.Server = "Varnish (HIT: "obj.hits")"; - } else { - set resp.http.X-Cache = "MISS"; - set resp.http.Server = "Varnish (MISS)"; - } -} \ No newline at end of file + if (obj.hits > 0) { + set resp.http.X-Cache = "HIT (" + obj.hits + ")"; + set resp.http.Server = "Varnish (HIT: " + obj.hits + ")"; + } else { + set resp.http.X-Cache = "MISS"; + set resp.http.Server = "Varnish (MISS)"; + } +} From b8f1cee789b39031b98c8481ea49b548e25f91e4 Mon Sep 17 00:00:00 2001 From: thebod Date: Thu, 21 Nov 2013 12:51:54 +0100 Subject: [PATCH 035/136] fixed cache purging --- app/code/community/Aoe/Static/Helper/Data.php | 22 ++++--- .../Static/Model/Cache/Adapter/Varnish.php | 8 ++- .../Aoe/Static/Model/Cache/Control.php | 5 +- .../community/Aoe/Static/Model/Config.php | 23 +++++++ .../community/Aoe/Static/Model/Observer.php | 61 ++++++++++++------- .../community/Aoe/Static/etc/aoe_static.xml | 14 +++++ .../default/template/aoestatic/purge.phtml | 38 +++++++----- 7 files changed, 122 insertions(+), 49 deletions(-) diff --git a/app/code/community/Aoe/Static/Helper/Data.php b/app/code/community/Aoe/Static/Helper/Data.php index 8198127..5b79f6a 100644 --- a/app/code/community/Aoe/Static/Helper/Data.php +++ b/app/code/community/Aoe/Static/Helper/Data.php @@ -56,7 +56,7 @@ public function purgeAll() { $result = array(); foreach ($this->_getAdapterInstances() as $adapter) { - /** @var Aoe_Static_Model_Adapter_Interface $adapter */ + /** @var Aoe_Static_Model_Cache_Adapter_Interface $adapter */ $result = array_merge($result, $adapter->purgeAll()); } return $result; @@ -90,7 +90,7 @@ public function purge(array $urls, $queue = true) $urls = array_filter($urls, function ($e) { return strlen($e) ? true : false; }); $result = array(); foreach ($this->_getAdapterInstances() as $adapter) { - /** @var Aoe_Static_Model_Adapter_Interface $adapter */ + /** @var Aoe_Static_Model_Cache_Adapter_Interface $adapter */ // queue if async cache is enabled in config and not forced to purge directly if ($this->getConfig()->useAsyncCache() && $queue) { @@ -110,14 +110,22 @@ public function purge(array $urls, $queue = true) return $result; } + /** + * purge given tag(s) + * + * @param string|array $tags + * @return array + */ public function purgeTags($tags) { + if (!is_array($tags)) { + $tags = array($tags); + } + $result = array(); - foreach ($tags as $tag) { - foreach ($this->_getAdapterInstances() as $adapter) { - /** @var Aoe_Static_Model_Cache_Adapter_Interface $adapter */ - $result = array_merge($result, $adapter->purgeTags($tag)); - } + foreach ($this->_getAdapterInstances() as $adapter) { + /** @var Aoe_Static_Model_Cache_Adapter_Interface $adapter */ + $result = array_merge($result, $adapter->purgeTags($tags)); } return $result; } diff --git a/app/code/community/Aoe/Static/Model/Cache/Adapter/Varnish.php b/app/code/community/Aoe/Static/Model/Cache/Adapter/Varnish.php index 16d0045..199d671 100644 --- a/app/code/community/Aoe/Static/Model/Cache/Adapter/Varnish.php +++ b/app/code/community/Aoe/Static/Model/Cache/Adapter/Varnish.php @@ -1,6 +1,6 @@ _varnishServers as $varnishServer) { foreach ($urls as $url) { - $varnishUrl = "http://" . $varnishServer . $url; + $varnishUrl = "http://" . $varnishServer . '/' . $url; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $varnishUrl); @@ -85,7 +85,7 @@ public function purgeTags(array $tags) curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); - curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-Invalidates: |' . $tag . '|')); + curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-Invalidates: ' . Aoe_Static_Model_Cache_Control::DELIMITER . $tag . Aoe_Static_Model_Cache_Control::DELIMITER)); curl_multi_add_handle($mh, $ch); $curlHandlers[] = $ch; @@ -110,6 +110,8 @@ public function purgeTags(array $tags) curl_close($ch); } curl_multi_close($mh); + + return $errors; } /** diff --git a/app/code/community/Aoe/Static/Model/Cache/Control.php b/app/code/community/Aoe/Static/Model/Cache/Control.php index cc53342..3ef5f46 100644 --- a/app/code/community/Aoe/Static/Model/Cache/Control.php +++ b/app/code/community/Aoe/Static/Model/Cache/Control.php @@ -11,6 +11,9 @@ class Aoe_Static_Model_Cache_Control /** @var bool switch to disable sending out of cache headers */ protected $_enabled = true; + /** @var string */ + const DELIMITER = '/'; + /** * @return $this */ @@ -101,7 +104,7 @@ public function applyCacheHeaders() { if ($this->_enabled) { $response = Mage::app()->getResponse(); - $response->setHeader('X-Invalidated-By', '|' . implode('|', array_keys($this->_tags)) . '|'); + $response->setHeader('X-Invalidated-By', self::DELIMITER . implode(self::DELIMITER, array_keys($this->_tags)) . self::DELIMITER); $response->setHeader('Cache-Control', 'max-age=' . (int) $this->_maxAge, true); $response->setHeader('X-Magento-Lifetime', (int) $this->_maxAge, true); $response->setHeader('aoestatic', 'cache', true); diff --git a/app/code/community/Aoe/Static/Model/Config.php b/app/code/community/Aoe/Static/Model/Config.php index d3ad01e..94a2095 100644 --- a/app/code/community/Aoe/Static/Model/Config.php +++ b/app/code/community/Aoe/Static/Model/Config.php @@ -104,4 +104,27 @@ public function getMarkerCallback($marker) } return $callback; } + + /** + * fetch configured adapters + * + * @return array + */ + public function getAdapters() + { + $adapters = $this->getNode('aoe_static_purging/adapters'); + if (!$adapters) { + return array(); + } + + return $adapters->asArray(); + } + + /** + * @return bool + */ + public function useAsyncCache() + { + return (boolean) $this->getNode('aoe_static_purging/use_aoe_asynccache'); + } } diff --git a/app/code/community/Aoe/Static/Model/Observer.php b/app/code/community/Aoe/Static/Model/Observer.php index 1b04bc1..7c3964e 100644 --- a/app/code/community/Aoe/Static/Model/Observer.php +++ b/app/code/community/Aoe/Static/Model/Observer.php @@ -110,15 +110,17 @@ protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Con { /** @var Aoe_Static_Model_Cache_Marker $cacheMarker */ $cacheMarker = Mage::getSingleton('aoestatic/cache_marker'); - foreach ($conf->headers->children() as $key => $value) { - // skip aoestatic header if we have messages to display - if ($this->messagesToShow && ($key == 'aoestatic')) { - continue; + if (property_exists($conf, 'headers')) { + foreach ($conf->headers->children() as $key => $value) { + // skip aoestatic header if we have messages to display + if ($this->messagesToShow && ($key == 'aoestatic')) { + continue; + } + $value = $cacheMarker->replaceMarkers($value); + $response->setHeader($key, $value, true); } - $value = $cacheMarker->replaceMarkers($value); - $response->setHeader($key, $value, true); } - if ($conf->cookies) { + if (property_exists($conf, 'cookies') && $conf->cookies) { $cookie = Mage::getModel('core/cookie'); /* @var $cookie Mage_Core_Model_Cookie */ foreach ($conf->cookies->children() as $name => $cookieConf) { @@ -136,7 +138,7 @@ protected function applyConf(Mage_Core_Model_Config_Element $conf, Mage_Core_Con $cookie->set($name, $value, $period, $path, $domain, $secure, $httponly); } } - if ($conf->cache) { + if (property_exists($conf, 'cache') && $conf->cache) { Mage::getSingleton('aoestatic/cache_control')->addMaxAge($conf->cache->maxage); } } @@ -211,10 +213,23 @@ public function controllerActionPredispatchAdminhtmlCacheIndex(Varien_Event_Obse if ($purgeUrls = $request->getParam('aoe_purge_urls')) { $purgeUrls = array_map('trim', explode("\n", trim($purgeUrls))); - // purge directly without queueing - Mage::helper('aoestatic')->purge($purgeUrls, false); + foreach (Mage::helper('aoestatic')->purge($purgeUrls, false) as $message) { + Mage::getSingleton('adminhtml/session')->addNotice($message); + } - Mage::getSingleton('adminhtml/session')->addSuccess("The Aoe_Static cache storage has been flushed."); + /** @var Mage_Core_Controller_Response_Http $response */ + $response = $event->getControllerAction()->getResponse(); + $response->setRedirect(Mage::getModel('adminhtml/url')->getUrl('*/cache/index', array())); + $response->sendResponse(); + exit; + } + + if ($purgeTags = $request->getParam('aoe_purge_tags')) { + $purgeTags = array_map('trim', explode("\n", trim($purgeTags))); + + foreach (Mage::helper('aoestatic')->purgeTags($purgeTags, false) as $message) { + Mage::getSingleton('adminhtml/session')->addNotice($message); + } /** @var Mage_Core_Controller_Response_Http $response */ $response = $event->getControllerAction()->getResponse(); @@ -272,7 +287,7 @@ public function applicationCleanCache($observer) } } - $tags = array(); + $purgetags = array(); if ($tags == array()) { $errors = Mage::helper('aoestatic')->purgeAll(); if (!empty($errors)) { @@ -298,36 +313,36 @@ public function applicationCleanCache($observer) switch ($tag_fields[1]) { case 'product': // get urls for product - $tags[] = 'product-' . $tag_fields[2]; + $purgetags[] = 'product-' . $tag_fields[2]; break; case 'category': - $tags[] = 'category-' . $tag_fields[2]; + $purgetags[] = 'category-' . $tag_fields[2]; break; case 'page': - $tags[] = 'page-' . $tag_fields[2]; + $purgetags[] = 'page-' . $tag_fields[2]; break; case 'block': - $tags[] = 'block-' . $tag_fields[2]; + $purgetags[] = 'block-' . $tag_fields[2]; break; } } } - if (!empty($tags)) { - $errors = Mage::helper('aoestatic')->purgeTags($tags); + if (!empty($purgetags)) { + $errors = Mage::helper('aoestatic')->purgeTags($purgetags); if (!empty($errors)) { $session->addError($helper->__("Some Static purges failed:
") . implode("
", $errors)); } else { - $count = count($tags); + $count = count($purgetags); if ($count > 5) { - $tags = array_slice($tags, 0, 5); - $tags[] = '...'; - $tags[] = $helper->__("(Total number of purged urls: %d)", $count); + $purgetags = array_slice($purgetags, 0, 5); + $purgetags[] = '...'; + $purgetags[] = $helper->__("(Total number of purged urls: %d)", $count); } $session->addSuccess( - $helper->__("Purges have been submitted successfully:
") . implode("
", $tags) + $helper->__("Tag purges have been submitted successfully:
") . implode("
", $purgetags) ); } } diff --git a/app/code/community/Aoe/Static/etc/aoe_static.xml b/app/code/community/Aoe/Static/etc/aoe_static.xml index a4c5302..3b511a7 100644 --- a/app/code/community/Aoe/Static/etc/aoe_static.xml +++ b/app/code/community/Aoe/Static/etc/aoe_static.xml @@ -105,4 +105,18 @@ + + + + + aoestatic/cache_adapter_varnish + + + 127.0.0.1:6081 + + + + + 0 + diff --git a/app/design/adminhtml/default/default/template/aoestatic/purge.phtml b/app/design/adminhtml/default/default/template/aoestatic/purge.phtml index 70461a7..6ff943b 100644 --- a/app/design/adminhtml/default/default/template/aoestatic/purge.phtml +++ b/app/design/adminhtml/default/default/template/aoestatic/purge.phtml @@ -6,23 +6,31 @@ +

__('Purge Urls from AOE Static Cache') ?>

__('Purge Tags from AOE Static Cache') ?>

-
- - - - - - - + + + +
- -
+ + + + + - - -
+ + +
-
- + +
+
+ + +
+ +
+
+x From 331032a4fe4da79c6abd3fc860e486d767dc61fe Mon Sep 17 00:00:00 2001 From: thebod Date: Thu, 21 Nov 2013 12:55:44 +0100 Subject: [PATCH 036/136] fixed X --- app/code/community/Aoe/Static/Model/Observer.php | 12 ++++++++++++ app/code/community/Aoe/Static/etc/config.xml | 9 +++++++++ .../default/default/template/aoestatic/purge.phtml | 1 - 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/app/code/community/Aoe/Static/Model/Observer.php b/app/code/community/Aoe/Static/Model/Observer.php index 7c3964e..6415cb8 100644 --- a/app/code/community/Aoe/Static/Model/Observer.php +++ b/app/code/community/Aoe/Static/Model/Observer.php @@ -348,4 +348,16 @@ public function applicationCleanCache($observer) } return $this; } + + public function controllerActionPredispatchAdminhtmlCacheMassRefresh(Varien_Event_Observer $observer) + { + /** @var Mage_Core_Controller_Request_Http $request */ + $request = $observer->getRequest(); + + if (strpos($request->getParam('types'), 'aoestatic') !== false) { + foreach (Mage::helper('aoestatic')->purgeAll() as $message) { + Mage::getSingleton('adminhtml/session')->addNotice($message); + } + } + } } diff --git a/app/code/community/Aoe/Static/etc/config.xml b/app/code/community/Aoe/Static/etc/config.xml index 56c517c..471e8f5 100644 --- a/app/code/community/Aoe/Static/etc/config.xml +++ b/app/code/community/Aoe/Static/etc/config.xml @@ -165,6 +165,15 @@ + + + + singleton + aoestatic/observer + controllerActionPredispatchAdminhtmlCacheMassRefresh + + + diff --git a/app/design/adminhtml/default/default/template/aoestatic/purge.phtml b/app/design/adminhtml/default/default/template/aoestatic/purge.phtml index 6ff943b..f526772 100644 --- a/app/design/adminhtml/default/default/template/aoestatic/purge.phtml +++ b/app/design/adminhtml/default/default/template/aoestatic/purge.phtml @@ -33,4 +33,3 @@ -x From b93e1f2a94df4647984e755ef4ff62a353c06f55 Mon Sep 17 00:00:00 2001 From: thebod Date: Thu, 21 Nov 2013 13:06:40 +0100 Subject: [PATCH 037/136] added cache-type invalidation and checks if cache is enabled --- app/code/community/Aoe/Static/Helper/Data.php | 15 +++++++++++++++ .../Aoe/Static/Model/Cache/Adapter/Varnish.php | 2 +- app/code/community/Aoe/Static/Model/Observer.php | 4 ++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/app/code/community/Aoe/Static/Helper/Data.php b/app/code/community/Aoe/Static/Helper/Data.php index 5b79f6a..f403917 100644 --- a/app/code/community/Aoe/Static/Helper/Data.php +++ b/app/code/community/Aoe/Static/Helper/Data.php @@ -54,6 +54,11 @@ protected function _getAdapterInstances() */ public function purgeAll() { + // if Varnish is not enabled on admin don't do anything + if (!Mage::app()->useCache('aoestatic')) { + return array(); + } + $result = array(); foreach ($this->_getAdapterInstances() as $adapter) { /** @var Aoe_Static_Model_Cache_Adapter_Interface $adapter */ @@ -87,6 +92,11 @@ public function getBlacklist() */ public function purge(array $urls, $queue = true) { + // if Varnish is not enabled on admin don't do anything + if (!Mage::app()->useCache('aoestatic')) { + return array(); + } + $urls = array_filter($urls, function ($e) { return strlen($e) ? true : false; }); $result = array(); foreach ($this->_getAdapterInstances() as $adapter) { @@ -118,6 +128,11 @@ public function purge(array $urls, $queue = true) */ public function purgeTags($tags) { + // if Varnish is not enabled on admin don't do anything + if (!Mage::app()->useCache('aoestatic')) { + return array(); + } + if (!is_array($tags)) { $tags = array($tags); } diff --git a/app/code/community/Aoe/Static/Model/Cache/Adapter/Varnish.php b/app/code/community/Aoe/Static/Model/Cache/Adapter/Varnish.php index 199d671..33c9811 100644 --- a/app/code/community/Aoe/Static/Model/Cache/Adapter/Varnish.php +++ b/app/code/community/Aoe/Static/Model/Cache/Adapter/Varnish.php @@ -13,7 +13,7 @@ class Aoe_Static_Model_Cache_Adapter_Varnish */ public function purgeAll() { - return $this->purge(array('/.*')); + return $this->purge(array('.*')); } /** diff --git a/app/code/community/Aoe/Static/Model/Observer.php b/app/code/community/Aoe/Static/Model/Observer.php index 6415cb8..df057a9 100644 --- a/app/code/community/Aoe/Static/Model/Observer.php +++ b/app/code/community/Aoe/Static/Model/Observer.php @@ -352,9 +352,9 @@ public function applicationCleanCache($observer) public function controllerActionPredispatchAdminhtmlCacheMassRefresh(Varien_Event_Observer $observer) { /** @var Mage_Core_Controller_Request_Http $request */ - $request = $observer->getRequest(); + $request = $observer->getControllerAction()->getRequest(); - if (strpos($request->getParam('types'), 'aoestatic') !== false) { + if (in_array('aoestatic', $request->getParam('types'))) { foreach (Mage::helper('aoestatic')->purgeAll() as $message) { Mage::getSingleton('adminhtml/session')->addNotice($message); } From 3badb2c4c11f0e9e7d3e8ef8cacc85acf27262f0 Mon Sep 17 00:00:00 2001 From: thebod Date: Thu, 21 Nov 2013 13:21:47 +0100 Subject: [PATCH 038/136] renamed phone to aoestatic route name --- .../base/default/template/aoestatic/beforebodyend.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/design/frontend/base/default/template/aoestatic/beforebodyend.phtml b/app/design/frontend/base/default/template/aoestatic/beforebodyend.phtml index 1ccdf26..9d55dc9 100644 --- a/app/design/frontend/base/default/template/aoestatic/beforebodyend.phtml +++ b/app/design/frontend/base/default/template/aoestatic/beforebodyend.phtml @@ -2,7 +2,7 @@