From 1ebf066be383f1168a9cff84a99b20ad0861b46d Mon Sep 17 00:00:00 2001 From: Lauren Song Date: Mon, 28 Oct 2019 10:02:46 -0400 Subject: [PATCH] Fix admin backend log out issue with LiteMage --- Block/Backend/Cache/Management.php | 137 +++++------ Block/Inject/CustomVary.php | 17 +- Controller/Block/CustomVary.php | 6 +- Controller/Block/Esi.php | 13 +- Controller/Shell/Purge.php | 121 +++++++--- Helper/Data.php | 106 ++++++++- Logger/Handler.php | 14 +- Logger/Logger.php | 6 +- Model/App/FrontController/LitemagePlugin.php | 41 ++-- Model/App/Response/HttpPurgePlugin.php | 18 +- Model/CacheControl.php | 222 +++++------------- Model/CachePurge.php | 111 +++++++++ Model/Config.php | 23 +- Model/Controller/Result/LitemagePlugin.php | 16 +- .../Config/Source/ApplicationPlugin.php | 3 +- Model/System/Config/Source/CustomVary.php | 3 +- Model/System/Config/Source/EnableDebug.php | 2 +- Observer/FlushAllCache.php | 36 +-- Observer/FlushCacheByCli.php | 151 ++++++------ Observer/FlushCacheByEvents.php | 24 +- Observer/FlushCacheByTags.php | 48 ++-- Observer/LayoutGenerateBlocksAfter.php | 34 +-- Observer/LayoutRenderElement.php | 25 +- composer.json | 4 +- etc/adminhtml/di.xml | 2 +- etc/module.xml | 2 +- 26 files changed, 704 insertions(+), 481 deletions(-) create mode 100644 Model/CachePurge.php diff --git a/Block/Backend/Cache/Management.php b/Block/Backend/Cache/Management.php index 950c0ce..b769fa8 100644 --- a/Block/Backend/Cache/Management.php +++ b/Block/Backend/Cache/Management.php @@ -1,4 +1,5 @@ config = $config; - $this->httpClientFactory = $httpClientFactory; + $this->config = $config; + $this->httpClientFactory = $httpClientFactory; } /** @@ -42,75 +47,72 @@ public function __construct( */ public function getPurgeUrl($type) { - if ($type == 'Refresh') { - return $this->getUrl('*/*/cache/index'); - } - else { - $types = ['All', 'Tag', 'Url']; + if ($type == 'Refresh') { + return $this->getUrl('*/*/cache/index'); + } else { + $types = ['All', 'Tag', 'Url']; - if (in_array($type, $types)) { - return $this->getUrl('*/litemageCache/purge' . $type); - } - else { - return $this->getUrl('*/litemageCache/purgeAll'); - } - } + if (in_array($type, $types)) { + return $this->getUrl('*/litemageCache/purge' . $type); + } else { + return $this->getUrl('*/litemageCache/purgeAll'); + } + } } - public function getCacheStatistics() - { - $statUri = '/__LSCACHE/STATS'; + public function getCacheStatistics() + { + $statUri = '/__LSCACHE/STATS'; $base = $this->getUrl(); - if ((stripos($base, 'http') !== false) && ($pos = strpos($base, '://'))) { - $pos2 = strpos($base, '/', $pos+ 4); - if ($pos2 === false) { - $statBase = $base; - } - else { - $statBase = substr($base, 0, $pos2); - if (substr($base, $pos2+1, 1) == '~') { - if ($pos3 = strpos($base, '/', $pos2+1)) { - $statBase = substr($base, 0, $pos3); - } - } - } - } - $statUri = $statBase . $statUri; + if ((stripos($base, 'http') !== false) && ($pos = strpos($base, '://'))) { + $pos2 = strpos($base, '/', $pos + 4); + if ($pos2 === false) { + $statBase = $base; + } else { + $statBase = substr($base, 0, $pos2); + if (substr($base, $pos2 + 1, 1) == '~') { + if ($pos3 = strpos($base, '/', $pos2 + 1)) { + $statBase = substr($base, 0, $pos3); + } + } + } + } + $statUri = $statBase . $statUri; - try { - $client = $this->httpClientFactory->create(); + try { + $client = $this->httpClientFactory->create(); $client->setOption(CURLOPT_SSL_VERIFYHOST, 0); $client->setOption(CURLOPT_SSL_VERIFYPEER, 0); $client->setOption(CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); // need to force http1.1 - $client->get($statUri) ; - $data = trim($client->getBody()); - if ($data == '' || $data{0} !== '{') { - return null; - } - - $data1 = json_decode($data, true); - $data2 = array_values($data1); - if (count($data2)) { - $stats = $data2[0]; - switch ($stats['LITEMAGE_PLAN']) { - case 11: $stats['plan'] = 'LiteMage Standard'; - $stats['plan_desc'] = 'up to 25000 publicly cached objects'; - break; - case 3: $stats['plan'] = 'LiteMage Unlimited'; - $stats['plan_desc'] = 'unlimited publicly cached objects'; - break; - case 9: - default: - $stats['plan'] = 'LiteMage Starter'; - $stats['plan_desc'] = 'up to 1500 publicly cached objects'; - } - return $stats; - } - } catch ( Exception $e ) { - } - return null; - } + $client->get($statUri); + $data = trim($client->getBody()); + if ($data == '' || $data{0} !== '{') { + return null; + } + $data1 = json_decode($data, true); + $data2 = array_values($data1); + if (count($data2)) { + $stats = $data2[0]; + switch ($stats['LITEMAGE_PLAN']) { + case 11: $stats['plan'] = 'LiteMage Standard'; + $stats['plan_desc'] = 'up to 25000 publicly cached objects'; + break; + case 3: $stats['plan'] = 'LiteMage Unlimited'; + $stats['plan_desc'] = 'unlimited publicly cached objects'; + break; + case 9: + default: + $stats['plan'] = 'LiteMage Starter'; + $stats['plan_desc'] = 'up to 1500 publicly cached objects'; + } + return $stats; + } + } catch (Exception $e) { + + } + return null; + } /** * Check if block can be displayed @@ -122,5 +124,4 @@ public function canShowButton() return $this->config->moduleEnabled(); } - } diff --git a/Block/Inject/CustomVary.php b/Block/Inject/CustomVary.php index be16f9e..e88683e 100644 --- a/Block/Inject/CustomVary.php +++ b/Block/Inject/CustomVary.php @@ -12,28 +12,27 @@ class CustomVary extends \Magento\Framework\View\Element\Template { /** - * @var \Litespeed\Litemage\Model\CacheControl + * @var \Litespeed\Litemage\Helper\Data */ - protected $litemageCache; + protected $helper; /** - * @param \Magento\Backend\Block\Template\Context $context - * @param \Litespeed\Litemage\Model\Config $config, + * @param \Magento\Framework\View\Element\Template\Context $context, + * @param \Litespeed\Litemage\Helper\Data $helper, * @param array $data */ public function __construct( - \Magento\Backend\Block\Template\Context $context, - \Litespeed\Litemage\Model\CacheControl $litemageCache, + \Magento\Framework\View\Element\Template\Context $context, + \Litespeed\Litemage\Helper\Data $helper, array $data = []) { parent::__construct($context, $data); - $this->litemageCache = $litemageCache; + $this->helper = $helper; } - public function needAjax() { - return $this->litemageCache->needCustVaryAjax(); + return $this->helper->needCustVaryAjax(); } public function getCheckUrl() diff --git a/Controller/Block/CustomVary.php b/Controller/Block/CustomVary.php index 4fda6dc..bcd96a4 100644 --- a/Controller/Block/CustomVary.php +++ b/Controller/Block/CustomVary.php @@ -1,4 +1,5 @@ jsonFactory = $jsonFactory; $this->litemageCache = $litemageCache; diff --git a/Controller/Block/Esi.php b/Controller/Block/Esi.php index 7871b21..cb28597 100644 --- a/Controller/Block/Esi.php +++ b/Controller/Block/Esi.php @@ -1,4 +1,5 @@ translateInline = $translateInline; $this->litemageCache = $litemageCache; @@ -49,7 +51,8 @@ public function execute() $response = $this->getResponse(); $ttl = 86400; $html = $layout->renderElement($block); - if ( $tags = $this->litemageCache->getElementCacheTags($layout, $block) ) { + if ($tags = $this->litemageCache->getElementCacheTags($layout, + $block)) { $this->litemageCache->setCacheTags($tags); } @@ -83,7 +86,7 @@ protected function _prepareLayout(&$block) if ($layout->hasElement($block)) { return $layout; } - else - return null; + return null; } + } diff --git a/Controller/Shell/Purge.php b/Controller/Shell/Purge.php index 5b891b1..11f5ada 100644 --- a/Controller/Shell/Purge.php +++ b/Controller/Shell/Purge.php @@ -1,4 +1,5 @@ httpHeader = $httpHeader; - $this->litemageCache = $litemageCache; + $this->httpHeader = $httpHeader; + $this->litemagePurge = $litemagePurge; + $this->helper = $helper; } /** @@ -39,36 +60,60 @@ public function __construct( */ public function execute() { - if (!$this->litemageCache->moduleEnabled()) { - return $this->_errorExit('Abort: LiteMage is not enabled'); - } - if ( $this->httpHeader->getHttpUserAgent() !== 'litemage_walker') { - return $this->_errorExit('Access denied'); - } - - $tags = []; - $req = $this->getRequest(); - if ($req->getParam('all')) { - $tags[] = '*'; - } - elseif ($t = $req->getParam('tags')) { - $tags = explode(',', $t); - } - - if (empty($tags)) { - $this->_errorExit('Invalid url'); - } - else { - $this->litemageCache->addPurgeTags($tags, 'ShellPurgeController'); - $this->getResponse()->setBody('purged tags ' . implode(',', $tags)); - } + if ($err = $this->_validateReq()) { + return $this->_errorExit($err); + } + + $this->litemagePurge->addPurgeTags($this->_tags, 'ShellPurgeController'); + $this->getResponse()->setBody(sprintf("LiteMage purged tags %s \n", + implode(',', $this->_tags))); } - protected function _errorExit($errorMesg) + private function _validateReq() { - $resp = $this->getResponse() ; - $resp->setHttpResponseCode(500) ; - $resp->setBody($errorMesg) ; - $this->litemageCache->debugLog('litemage/shell/purge ErrorExit: ' . $errorMesg) ; + if (!$this->helper->moduleEnabled()) { + return 'Abort: LiteMage is not enabled'; + } + if ($this->httpHeader->getHttpUserAgent() !== 'litemage_walker') { + return 'Access denied'; + } + + $req = $this->getRequest(); + $secret = $req->getParam('secret'); + + if (strlen($secret) != 32) { + return 'Invalid request'; + } + $file = dirname(dirname(dirname(__FILE__))) . '/Observer/FlushCacheByCli.php'; + $stat = stat($file); + $stat[] = date('l jS F Y h'); + $secret1 = md5(print_r($stat, 1)); + + if ($secret != $secret1) { + return 'Invalid token'; + } + + $this->_tags = []; + + if ($req->getParam('all')) { + $this->_tags[] = '*'; + } elseif ($t = $req->getParam('tags')) { + $this->_tags = explode(',', $t); + } + + if (empty($this->_tags)) { + return 'Invalid url'; + } + + return null; } + + private function _errorExit($errorMesg) + { + $resp = $this->getResponse(); + $resp->setHttpResponseCode(500); + $resp->setBody($errorMesg); + $this->helper->debugLog('litemage/shell/purge ErrorExit: ' . $errorMesg); + } + } diff --git a/Helper/Data.php b/Helper/Data.php index ca4e6c7..407ef97 100644 --- a/Helper/Data.php +++ b/Helper/Data.php @@ -1,4 +1,5 @@ config = $config; $this->_logger = $logger; + if ($config->moduleEnabled()) { + $this->_debug = $this->config->debugEnabled(); + $this->_debugTrace = $this->config->debugTraceEnabled(); + } } public function getUrl($route, array $params = []) { $fullurl = $this->_getUrl($route, $params); - if ((stripos($fullurl, 'http') !== false) && ($pos = strpos($fullurl, '://'))) { + if ((stripos($fullurl, 'http') !== false) && ($pos = strpos($fullurl, + '://'))) { // remove domain part $pos2 = strpos($fullurl, '/', $pos + 4); $fullurl = ($pos2 === false) ? '/' : substr($fullurl, $pos2); @@ -32,9 +51,90 @@ public function getUrl($route, array $params = []) return $fullurl; } - public function debugLog($message) + private function log($message) { $this->_logger->notice($message); // allow to show in production mode } + public function debugLog($message) + { + if ($this->_debug) { + $this->log($message); + } + } + + public function debugTrace($message) + { + if ($this->_debug && $this->_debugTrace) { + ob_start(); + debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 200); + $trace = ob_get_contents(); + ob_end_clean(); + $this->log("***** $message *****\n$trace"); + } + } + + public function debugEnabled() + { + return $this->_debug; + } + + public function moduleEnabled() + { + return $this->config->moduleEnabled(); + } + + public function isCacheable() + { + return ($this->_isCacheable === 1); + } + + public function needCustVaryAjax() + { + return (($this->_isCacheable === 1) && ($this->config->getCustomVaryMode() == 1)); + } + + /** + * setCacheableFlag - should only be called by CacheControl + * + * @param type $reason + */ + public function setCacheableFlag($flag, $reason, $trace = false) + { + $this->_isCacheable = $flag; + if ($this->_debug) { + $msg = sprintf('setCacheableFlag=%d %s', $flag, $reason); + if ($trace) { + $this->debugTrace($msg); + } else { + $this->debugLog($msg); + } + } + } + + /** + * translateTags + * @param string or array of strings $tagString + * @return string or array + */ + // input can be array or string + public function translateTags($tagString) + { + $search = ['block', 'footer_links', 'left-menu', + 'cms_b', + 'cat_p', + 'cat_c_p', // sequence matters, need to be in front of shorter ones + 'cat_c']; + $replace = ['B', 'f', 'l', + 'MB', + 'P', + 'C', 'C']; + + $lstags = str_replace($search, $replace, $tagString); + + /* $this->debugLog("in translate tags from = " . print_r($tagString, 1) + . ' to = ' . print_r($lstags,1)); */ + return $lstags; + } + } diff --git a/Logger/Handler.php b/Logger/Handler.php index 4f6295f..727e2d3 100644 --- a/Logger/Handler.php +++ b/Logger/Handler.php @@ -1,4 +1,5 @@ getLogTag(); @@ -44,14 +45,13 @@ private function getLogTag() if (isset($_SERVER['REMOTE_ADDR'])) { // from server http request - $tag .= '['; - /*if ($this->_httpHeader->getHttpUserAgent() == $cronUserAgent) { - $this->_debugTag .= $cronUserAgent . ':'; - }*/ - $tag .= $_SERVER['REMOTE_ADDR']; + /* if ($this->_httpHeader->getHttpUserAgent() == $cronUserAgent) { + $this->_debugTag .= $cronUserAgent . ':'; + } */ $msec = microtime(); $msec1 = substr($msec, 2, strpos($msec, ' ') - 2); - $tag .= ':' . $_SERVER['REMOTE_PORT'] . ':' . $msec1 . ']'; + $tag .= sprintf('[%s:%s:%s]', $_SERVER['REMOTE_ADDR'], + $_SERVER['REMOTE_PORT'], $msec1); } return $tag; } diff --git a/Logger/Logger.php b/Logger/Logger.php index 4807da7..aa2116c 100644 --- a/Logger/Logger.php +++ b/Logger/Logger.php @@ -1,4 +1,5 @@ name = $name; $this->handlers = $handlers; $this->processors = $processors; } + } diff --git a/Model/App/FrontController/LitemagePlugin.php b/Model/App/FrontController/LitemagePlugin.php index be4335c..7b55ddd 100644 --- a/Model/App/FrontController/LitemagePlugin.php +++ b/Model/App/FrontController/LitemagePlugin.php @@ -1,4 +1,5 @@ litemageCache = $litemageCache; + \Litespeed\Litemage\Helper\Data $helper, + \Magento\Framework\App\PageCache\Version $version + ) + { + $this->helper = $helper; $this->version = $version; } @@ -46,14 +47,20 @@ public function __construct( * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function aroundDispatch( - \Magento\Framework\App\FrontControllerInterface $subject, - \Closure $proceed, - \Magento\Framework\App\RequestInterface $request - ) { - $this->litemageCache->debugLog('aroundDispatch0 ' . $request->getMethod() . ' '. $request->getUriString()); + \Magento\Framework\App\FrontControllerInterface $subject, + \Closure $proceed, \Magento\Framework\App\RequestInterface $request + ) + { $response = $proceed($request); - $this->litemageCache->debugLog('aroundDispatch1 FrontController ' . $request->getModuleName() . ':' . $request->getActionName() . ' cacheable=' . (int)$this->litemageCache->isCacheable()); - if ($this->litemageCache->moduleEnabled() && $response instanceof \Magento\Framework\App\Response\Http) { + if ($this->helper->debugEnabled()) { + $this->helper->debugLog(sprintf('after aroundDispatch %s %s [%s:%s] cacheable=%s', + $request->getMethod(), + $request->getUriString(), + $request->getModuleName(), + $request->getActionName(), + $this->helper->isCacheable() ? '1' : '0')); + } + if ($this->helper->moduleEnabled() && $response instanceof \Magento\Framework\App\Response\Http) { $this->version->process(); } return $response; diff --git a/Model/App/Response/HttpPurgePlugin.php b/Model/App/Response/HttpPurgePlugin.php index 47de629..e4f87bb 100644 --- a/Model/App/Response/HttpPurgePlugin.php +++ b/Model/App/Response/HttpPurgePlugin.php @@ -1,4 +1,5 @@ litemageCache = $litemageCache; + \Litespeed\Litemage\Model\CachePurge $litemagePurge + ) + { + $this->litemagePurge = $litemagePurge; } /** @@ -38,8 +40,8 @@ public function __construct( */ public function beforeSendResponse(\Magento\Framework\App\Response\Http $subject) { - if ($this->litemageCache->needPurge()) { - $this->litemageCache->setPurgeHeaders($subject); + if ($this->litemagePurge->needPurge()) { + $this->litemagePurge->setPurgeHeaders($subject); } } diff --git a/Model/CacheControl.php b/Model/CacheControl.php index bd9c05c..b3b4ee1 100644 --- a/Model/CacheControl.php +++ b/Model/CacheControl.php @@ -1,4 +1,5 @@ httpContext = $httpContext; @@ -106,8 +98,6 @@ public function __construct(\Magento\Framework\App\Http\Context $httpContext, $this->helper = $helper; $this->_moduleEnabled = $config->moduleEnabled(); if ($this->_moduleEnabled) { - $this->_debug = $this->config->debugEnabled(); - $this->_debugTrace = $this->config->debugTraceEnabled(); $this->_bypassedContext = $this->config->getBypassedContext(); } @@ -121,7 +111,8 @@ public function __construct(\Magento\Framework\App\Http\Context $httpContext, } if ($reason) { - $fullreason = sprintf("%s CacheControl constructor: %s", $request->getRequestUri(), $reason); + $fullreason = sprintf("%s CacheControl constructor: %s", + $request->getRequestUri(), $reason); $this->setNotCacheable($fullreason, $reason); } } @@ -131,74 +122,23 @@ public function moduleEnabled() return $this->_moduleEnabled; } - public function debugLog($message) - { - if ($this->_debug) { - $this->helper->debugLog($message); - } - } - - public function debugTrace($message) - { - if ($this->_debug && $this->_debugTrace) { - ob_start(); - debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 200); - $trace = ob_get_contents(); - ob_end_clean(); - $this->helper->debugLog("***** $message *****\n$trace"); - } - } - - public function debugEnabled() - { - return $this->_debug; - } - - public function needPurge() - { - return ($this->_moduleEnabled && !empty($this->_purgeTags)); - } - - /** - * Add purgeable tags - * @param array $tags - * @param string $source - * - */ - public function addPurgeTags($tags, $source) - { - if (empty($tags)) { - return; - } - $newtags = array_diff($tags, $this->_purgeTags); - if (!empty($newtags)) { - $this->_purgeTags = array_merge($this->_purgeTags, $newtags); - if ($this->_debug) { - $this->debugLog('add purge tags from ' - . $source . ' : ' . implode(',', $tags) - . ' Result=' . implode(',',$this->_purgeTags) ); - $this->debugTrace($source); - } - } - } - public function setCacheable($ttl, $msg) { // cannot set from non cacheable to cacheable if ($this->_isCacheable == -1) { $this->_isCacheable = 1; - $this->debugLog('setCacheable from ' . $msg); + $this->helper->setCacheableFlag(1, $msg); } if ($ttl > 0) { $this->_ttl = $ttl; } } - public function setNotCacheable($reason, $shortReason='') + public function setNotCacheable($reason, $shortReason = '') { if ($this->_isCacheable != 0) { $this->_isCacheable = 0; - $this->debugLog('setNotCacheable ' . $reason); + $this->helper->setCacheableFlag(0, $reason); $this->_nocacheReason = $shortReason ?: $reason; } } @@ -208,13 +148,6 @@ public function setEsiRequest($isEsiReq = true) $this->_isEsiRequest = $isEsiReq; } - public function needCustVaryAjax() - { - if (($this->_isCacheable === 1) && ($this->config->getCustomVaryMode() == 1)) { - return true; - } - return false; - } public function isCacheable() { @@ -237,8 +170,8 @@ public function getEsiUrl($handles, $blockName) $url = $this->helper->getUrl( 'litemage/block/esi', [ - 'b' => $blockName, - 'h' => $this->encodeEsiHandles($handles) + 'b' => $blockName, + 'h' => $this->encodeEsiHandles($handles) ] ); @@ -293,6 +226,13 @@ public function setCacheControlHeaders($response) $changed = $this->checkCacheVary(); $responsecode = $response->getHttpResponseCode(); + if ($responsecode == 404) { + if (strpos($this->request->getRequestUri(), 'checkout') !== false) { + $this->_isCacheable = 0; + $this->helper->setCacheableFlag(0, 'CHECKOUT ALERT 404', true); + } + } + if (( $responsecode == 200 || $responsecode == 404) && ($this->_isCacheable == 1) ) { // cacheable @@ -305,23 +245,28 @@ public function setCacheControlHeaders($response) $cacheControlHeader .= ','; $cacheControlHeader .= 'esi=on'; } - if ($cacheControlHeader) { - $response->setHeader(self::LSHEADER_CACHE_CONTROL, $cacheControlHeader); - $this->debugLog('SetCacheControlHeaders: ' . $cacheControlHeader . ' Tags:' . $lstags); + if ($cacheControlHeader) { + $response->setHeader(self::LSHEADER_CACHE_CONTROL, + $cacheControlHeader); + $this->helper->debugLog(sprintf('SetCacheControlHeaders: %s Tags: %s', + $cacheControlHeader, $lstags)); } if ($cch = $response->getHeader('Cache-Control')) { if (preg_match('/public.*s-maxage=(\d+)/', $cch->getFieldValue(), - $matches)) { + $matches)) { $maxAge = $matches[1]; $response->setNoCacheHeaders(); } } - if ($this->_debug == 2) { + if ($this->helper->debugEnabled() == 2) { // show debug headers $response->setHeader(self::LSHEADER_DEBUG_CC, $cacheControlHeader); $response->setHeader(self::LSHEADER_DEBUG_Tag, $lstags); - $response->setHeader(self::LSHEADER_DEBUG_INFO, substr(htmlspecialchars(str_replace("\n", ' ', $this->_nocacheReason)), 0, 256)); + $response->setHeader(self::LSHEADER_DEBUG_INFO, + substr(htmlspecialchars(str_replace("\n", ' ', + $this->_nocacheReason)), + 0, 256)); $response->setHeader(self::LSHEADER_DEBUG_VARY, $this->rawVaryString); } } @@ -330,7 +275,7 @@ protected function _setCacheTagHeader($response) { $lstags = ''; if (!empty($this->_cacheTags)) { - $lstags = $this->translateTags($this->_cacheTags); + $lstags = $this->helper->translateTags($this->_cacheTags); if (is_array($lstags)) { $lstags = implode(',', array_unique($lstags)); } @@ -346,14 +291,15 @@ public function checkCacheVary() $rawdata = $varyString = ''; $varymode = $this->config->getCustomVaryMode(); if ($varymode == 2) { - $this->httpContext->setValue('litemage_custvary_enforce', $varymode, 0); + $this->httpContext->setValue('litemage_custvary_enforce', $varymode, + 0); } if ($varymode) { // 1 or 2 $curcustvary = $this->request->get(self::LITEMAGE_CUSTVARY_COOKIE); if ($curcustvary != $varymode) { $cookMetadata = $this->cookieMetadataFactory->createPublicCookieMetadata()->setPath('/')->setHttpOnly(false)->setSecure(false); $this->cookieManager->setPublicCookie(self::LITEMAGE_CUSTVARY_COOKIE, - $varymode, $cookMetadata); + $varymode, $cookMetadata); } } @@ -374,10 +320,11 @@ public function checkCacheVary() if (!empty($data) && !empty($this->_bypassedContext)) { // already not cacheable, like POST request, do filter - $data = array_filter($data, function($k) { + $data = array_filter($data, + function($k) { return (!in_array($k, $this->_bypassedContext)); }, ARRAY_FILTER_USE_KEY); - } + } if (!empty($data)) { ksort($data); @@ -392,49 +339,31 @@ public function checkCacheVary() if ($varyString) { $sensitiveCookMetadata = $this->cookieMetadataFactory->createSensitiveCookieMetadata()->setPath('/'); $this->cookieManager->setSensitiveCookie(self::ENV_VARYCOOKIE_DEFAULT, - $varyString, $sensitiveCookMetadata); + $varyString, + $sensitiveCookMetadata); } else { $cookieMetadata = $this->cookieMetadataFactory->createSensitiveCookieMetadata()->setPath('/'); $this->cookieManager->deleteCookie(self::ENV_VARYCOOKIE_DEFAULT, - $cookieMetadata); + $cookieMetadata); } $changed = true; - $rawdata .= ' changed'; + $rawdata .= ' changed'; $this->setNotCacheable("EnvVary $rawdata"); } - if ($this->_debug && $rawdata) { - $this->debugLog("EnvVary: $rawdata"); + if ($rawdata) { + $this->helper->debugLog("EnvVary: $rawdata"); } $this->rawVaryString = $rawdata; return $changed; } - public function setPurgeHeaders($response) - { - if (empty($this->_purgeTags)) - return; - - if (in_array('*', $this->_purgeTags)) { - $purgeTags = '*'; - } else { - $purgeTags = 'tag=' . implode(',tag=', array_unique($this->translateTags($this->_purgeTags))); - } - $response->setHeader(self::LSHEADER_PURGE, $purgeTags); - if ($this->_debug) { - $this->debugLog('Set purge header ' . $purgeTags); - if ($this->_debug == 2) { - $response->setHeader(self::LSHEADER_DEBUG_Purge, $purgeTags); - } - } - } - public function addCacheTags($tags) { if (is_array($tags)) { $this->_cacheTags = array_unique(array_merge($this->_cacheTags, - $tags)); - } else if ($tags && !in_array($tags, $this->_cacheTags)) { + $tags)); + } elseif ($tags && !in_array($tags, $this->_cacheTags)) { $this->_cacheTags[] = $tags; } } @@ -444,28 +373,7 @@ public function setCacheTags($tags) $this->_cacheTags = $tags; } - /** - * translateTags - * @param string or array of strings $tagString - * @return string or array - */ - // input can be array or string - public function translateTags($tagString) - { - $search = ['_block', - 'catalog_product_', - 'catalog_product', - 'catalog_category_product_', // sequence matters, need to be in front of shorter ones - 'catalog_category_' ]; - $replace = ['.B', 'P.', 'P', 'C.', 'C.']; - - $lstags = str_replace($search, $replace, $tagString); - - //$this->debugLog("in translate tags from = $tagString , to = $lstags"); - return $lstags; - } - - // used by ESI blocks + // used by ESI blocks public function getElementCacheTags($layout, $elementName) { if (!$layout->hasElement($elementName)) @@ -500,12 +408,12 @@ public function getElementCacheTags($layout, $elementName) } } } - if (!empty($tags)) { - $lstag = implode(',', array_unique($this->translateTags($tags))); - } - else { + if (!empty($tags)) { + $lstag = implode(',', + array_unique($this->helper->translateTags($tags))); + } else { $lstag = $elementName; - } + } return $lstag; } diff --git a/Model/CachePurge.php b/Model/CachePurge.php new file mode 100644 index 0000000..5b0063f --- /dev/null +++ b/Model/CachePurge.php @@ -0,0 +1,111 @@ +config = $config; + $this->helper = $helper; + $this->_debug = $this->helper->debugEnabled(); + } + + public function needPurge() + { + return ($this->config->moduleEnabled() && !empty($this->_purgeTags)); + } + + /** + * Add Purge tags + * @param array $tags + * @param string $source + * + */ + public function addPurgeTags($tags, $source) + { + if ($this->_isPurgeAll || empty($tags)) { + return; + } + $changed = false; + if (in_array('*', $tags)) { + $this->_isPurgeAll = true; + $this->_purgeTags = ['*']; + $changed = true; + } else { + $newtags = array_diff($tags, $this->_purgeTags); + if (!empty($newtags)) { + $this->_purgeTags = array_merge($this->_purgeTags, $newtags); + $changed = true; + } + } + + if ($changed && $this->_debug) { + $this->helper->debugLog(sprintf('add purge tags from %s : %s Result=%s', + $source, implode(',', $tags), + implode(',', $this->_purgeTags))); + $this->helper->debugTrace($source); + } + } + + public function setPurgeHeaders($response) + { + if (empty($this->_purgeTags)) + return; + + if ($this->_isPurgeAll) { + $purgeTags = '*'; + } else { + $purgeTags = 'tag=' . implode(',tag=', + array_unique($this->helper->translateTags($this->_purgeTags))); + } + $response->setHeader(self::LSHEADER_PURGE, $purgeTags); + if ($this->_debug) { + $this->helper->debugLog('Set purge header ' . $purgeTags); + if ($this->_debug == 2) { + $response->setHeader(self::LSHEADER_DEBUG_Purge, $purgeTags); + } + } + } + +} diff --git a/Model/Config.php b/Model/Config.php index 6ac011b..c9136c0 100644 --- a/Model/Config.php +++ b/Model/Config.php @@ -19,17 +19,16 @@ class Config */ const LITEMAGE = 'LITEMAGE'; + private const CFGXML_DEFAULTLM = 'litemage' ; - const CFGXML_DEFAULTLM = 'litemage' ; + private const STOREXML_PUBLICTTL = 'system/full_page_cache/ttl'; - const STOREXML_PUBLICTTL = 'system/full_page_cache/ttl'; - - const CFG_DEBUGON = 'debug' ; - const CFG_CONTEXTBYPASS = 'contextbypass'; - const CFG_CUSTOMVARY = 'custom_vary'; + private const CFG_DEBUGON = 'debug' ; + private const CFG_CONTEXTBYPASS = 'contextbypass'; + private const CFG_CUSTOMVARY = 'custom_vary'; //const CFG_ADMINIPS = 'admin_ips'; - const CFG_PUBLICTTL = 'public_ttl'; - const LITEMAGE_GENERAL_CACHE_TAG = 'LITESPEED_LITEMAGE' ; + private const CFG_PUBLICTTL = 'public_ttl'; + private const LITEMAGE_GENERAL_CACHE_TAG = 'LITESPEED_LITEMAGE' ; // config items protected $_conf = []; @@ -203,7 +202,7 @@ protected function _initConf( $type = '' ) switch ( $type ) { default: - $debugon = $lm['dev'][self::CFG_DEBUGON] ?: 0; + $debugon = isset($lm['dev'][self::CFG_DEBUGON]) ? $lm['dev'][self::CFG_DEBUGON] : 0; if ($debugon && isset($lm['dev']['debug_ips'])) { // check ips $debugips = trim($lm['dev']['debug_ips']); @@ -221,17 +220,17 @@ protected function _initConf( $type = '' ) $this->_conf[self::CFG_DEBUGON] = $debugon ; $this->_isDebug = $debugon; if ($debugon) { - $this->_debug_trace = $lm['dev']['debug_trace'] ?: 0; + $this->_debug_trace = isset($lm['dev']['debug_trace']) ? $lm['dev']['debug_trace'] : 0; } $this->_conf[self::CFG_PUBLICTTL] = $this->scopeConfig->getValue(self::STOREXML_PUBLICTTL); - $bypass = $lm['general'][self::CFG_CONTEXTBYPASS] ?: ''; + $bypass = isset($lm['general'][self::CFG_CONTEXTBYPASS]) ? $lm['general'][self::CFG_CONTEXTBYPASS] : ''; if ($bypass) { $this->_conf[self::CFG_CONTEXTBYPASS] = array_unique(preg_split($pattern, $bypass, null, PREG_SPLIT_NO_EMPTY)); } else { $this->_conf[self::CFG_CONTEXTBYPASS] = []; } - $this->_conf[self::CFG_CUSTOMVARY] = $lm['general'][self::CFG_CUSTOMVARY] ?: 0; + $this->_conf[self::CFG_CUSTOMVARY] = isset($lm['general'][self::CFG_CUSTOMVARY]) ? $lm['general'][self::CFG_CUSTOMVARY] : 0; $this->_esiTag = array('include' => 'esi:include', 'inline' => 'esi:inline', 'remove' => 'esi:remove'); } } diff --git a/Model/Controller/Result/LitemagePlugin.php b/Model/Controller/Result/LitemagePlugin.php index 5db9e1d..d8e2651 100644 --- a/Model/Controller/Result/LitemagePlugin.php +++ b/Model/Controller/Result/LitemagePlugin.php @@ -15,9 +15,9 @@ class LitemagePlugin { /** - * @var \Litespeed\Litemage\Model\CacheControl + * @var \Litespeed\Litemage\Model\Config */ - protected $litemageCache; + protected $config; /** * @var \Magento\Framework\App\PageCache\Version @@ -30,18 +30,18 @@ class LitemagePlugin protected $registry; /** - * Constructor - * - * @param \Litespeed\Litemage\Model\CacheControl $litemageCache + * + * @param \Litespeed\Litemage\Model\Config $config * @param \Magento\Framework\App\PageCache\Version $version + * @param \Magento\Framework\Registry $registry */ public function __construct( - \Litespeed\Litemage\Model\CacheControl $litemageCache, + \Litespeed\Litemage\Model\Config $config, \Magento\Framework\App\PageCache\Version $version, \Magento\Framework\Registry $registry ) { - $this->litemageCache = $litemageCache; + $this->config = $config; $this->version = $version; $this->registry = $registry; } @@ -61,7 +61,7 @@ public function aroundRenderResult( { $result = $proceed($response); $usePlugin = $this->registry->registry('use_page_cache_plugin'); - if ($usePlugin && $this->litemageCache->moduleEnabled()) { + if ($usePlugin && $this->config->moduleEnabled()) { $this->version->process(); } return $result; diff --git a/Model/System/Config/Source/ApplicationPlugin.php b/Model/System/Config/Source/ApplicationPlugin.php index 163ca39..cb49998 100644 --- a/Model/System/Config/Source/ApplicationPlugin.php +++ b/Model/System/Config/Source/ApplicationPlugin.php @@ -51,8 +51,9 @@ protected function _hasLicense() elseif (isset($_SERVER['HTTP_X_LITEMAGE']) && $_SERVER['HTTP_X_LITEMAGE']) { return true; // for webadc } - else + else { return false; + } } } diff --git a/Model/System/Config/Source/CustomVary.php b/Model/System/Config/Source/CustomVary.php index 6329585..f43be02 100644 --- a/Model/System/Config/Source/CustomVary.php +++ b/Model/System/Config/Source/CustomVary.php @@ -1,4 +1,5 @@ config = $config; - $this->eventManager = $eventManager; + $this->eventManager = $eventManager; } /** @@ -38,20 +39,19 @@ public function __construct(\Litespeed\Litemage\Model\Config $config, */ public function execute(\Magento\Framework\Event\Observer $observer) { - if (!$this->config->moduleEnabled()) - return; - - $reason = 'FlushAllCache from '. $observer->getEvent()->getName(); - $param = ['tags' => ['*'], 'reason' => $reason]; - - if (PHP_SAPI == 'cli') { - // from command line - $this->eventManager->dispatch('litemage_cli_purge', $param); - } - else { - $this->eventManager->dispatch('litemage_purge', $param); + if (!$this->config->moduleEnabled()) { + return; } - } + $reason = 'FlushAllCache from ' . $observer->getEvent()->getName(); + $param = ['tags' => ['*'], 'reason' => $reason]; + + if (PHP_SAPI == 'cli') { + // from command line + $this->eventManager->dispatch('litemage_cli_purge', $param); + } else { + $this->eventManager->dispatch('litemage_purge', $param); + } + } } diff --git a/Observer/FlushCacheByCli.php b/Observer/FlushCacheByCli.php index 82546ec..9211f56 100644 --- a/Observer/FlushCacheByCli.php +++ b/Observer/FlushCacheByCli.php @@ -1,4 +1,5 @@ config = $config; - $this->coreRegistry = $coreRegistry; - $this->url = $url; - $this->logger = $logger; + $this->coreRegistry = $coreRegistry; + $this->url = $url; + $this->helper = $helper; } /** @@ -51,66 +64,69 @@ public function __construct(\Litespeed\Litemage\Model\Config $config, */ public function execute(\Magento\Framework\Event\Observer $observer) { - if (!$this->config->moduleEnabled()) - return; + if (!$this->config->moduleEnabled()) + return; - $event = $observer->getEvent(); - $tags = $event->getTags(); + $event = $observer->getEvent(); + $tags = $event->getTags(); $this->_reason = $event->getReason(); - if (in_array('*', $tags)) { - if ($this->coreRegistry->registry('shellPurgeAll') === null) { - $this->coreRegistry->register('shellPurgeAll', 1); - $this->_shellPurge(['all' => 1]); - } - } - else { - $tags = array_unique($tags); - $used = []; - foreach ($tags as $tag) { - if ($this->coreRegistry->registry("shellPurge_{$tag}") === null) { - $this->coreRegistry->register("shellPurge_{$tag}", 1); - $used[] = $tag; - } - } - if (!empty($used)) { - $this->_shellPurge(['tags' => implode(',', $used)]); - } - } + if (in_array('*', $tags)) { + if ($this->coreRegistry->registry('shellPurgeAll') === null) { + $this->coreRegistry->register('shellPurgeAll', 1); + $this->_shellPurge(['all' => 1]); + } + } else { + $tags = array_unique($tags); + $used = []; + foreach ($tags as $tag) { + if ($this->coreRegistry->registry("shellPurge_{$tag}") === null) { + $this->coreRegistry->register("shellPurge_{$tag}", 1); + $used[] = $tag; + } + } + if (!empty($used)) { + $this->_shellPurge(['tags' => implode(',', $used)]); + } + } } - protected function _shellPurge($params) - { - $server_ip = false; //in future, allow this configurable. - $uparams = ['_type' => \Magento\Framework\UrlInterface::URL_TYPE_LINK, + private function _shellPurge($params) + { + $msg = sprintf("FlushCacheByCli %s tags=%s", $this->_reason, + print_r($params, 1)); + + $server_ip = false; //in future, allow this configurable. + $uparams = ['_type' => \Magento\Framework\UrlInterface::URL_TYPE_LINK, '_secure' => true]; $base = $this->url->getBaseUrl($uparams); $headers = []; - if ($server_ip) { - $pattern = "/:\/\/([^\/^:]+)(\/|:)?/"; - if (preg_match($pattern, $base, $m)) { - $domain = $m[1]; - $pos = strpos($base, $domain); - $base = substr($base, 0, $pos) . $server_ip . substr($base, $pos + strlen($domain)); + if ($server_ip) { + $pattern = "/:\/\/([^\/^:]+)(\/|:)?/"; + if (preg_match($pattern, $base, $m)) { + $domain = $m[1]; + $pos = strpos($base, $domain); + $base = substr($base, 0, $pos) . $server_ip + . substr($base, $pos + strlen($domain)); $headers[] = "Host: $domain"; - } - } - - $uri = $base . 'litemage/shell/purge'; + } + } + $stat = stat(__FILE__); + $stat[] = date('l jS F Y h'); + $params['secret'] = md5(print_r($stat, 1)); + $uri = $base . 'litemage/shell/purge?' . http_build_query($params); $result = true; - $msg = "FlushCacheByCli {$this->_reason}\n URI = $uri tags=" . print_r($params, 1); - try { + try { $curl = curl_init(); - - $options = [CURLOPT_CUSTOMREQUEST => 'POST', - CURLOPT_URL => $uri, - CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_HEADER => false, - CURLOPT_TIMEOUT => 180, - CURLOPT_USERAGENT => 'litemage_walker', - CURLOPT_POSTFIELDS => $params, + // cannot use POST due to csrf validation + $options = [CURLOPT_CUSTOMREQUEST => 'GET', + CURLOPT_URL => $uri, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_HEADER => false, + CURLOPT_TIMEOUT => 180, + CURLOPT_USERAGENT => 'litemage_walker', ]; if (strpos($uri, 'https://') !== false) { $options[CURLOPT_SSL_VERIFYHOST] = 0; @@ -127,15 +143,14 @@ protected function _shellPurge($params) $response = curl_exec($curl); curl_close($curl); - $msg .= $response; + $msg .= 'res=' . $response; } catch (\Exception $e) { $msg .= 'Exception ' . $e->getMessage(); $result = false; } - if ($this->config->debugEnabled()) { - $this->logger->notice($msg); - } + $this->helper->debugLog($msg); + return $result; } diff --git a/Observer/FlushCacheByEvents.php b/Observer/FlushCacheByEvents.php index 0bf660a..53ef44c 100644 --- a/Observer/FlushCacheByEvents.php +++ b/Observer/FlushCacheByEvents.php @@ -12,16 +12,26 @@ class FlushCacheByEvents implements \Magento\Framework\Event\ObserverInterface { /** - * @var \Litespeed\Litemage\Model\CacheControl + * @var \Litespeed\Litemage\Model\CachePurge */ - protected $litemageCache; + protected $litemagePurge; /** - * @param \Litespeed\Litemage\Model\CacheControl $litemageCache + * + * @var \Litespeed\Litemage\Model\Config + */ + protected $config; + + /** + * + * @param \Litespeed\Litemage\Model\CachePurge $litemagePurge + * @param \Litespeed\Litemage\Model\Config $config */ - public function __construct(\Litespeed\Litemage\Model\CacheControl $litemageCache) + public function __construct(\Litespeed\Litemage\Model\CachePurge $litemagePurge, + \Litespeed\Litemage\Model\Config $config) { - $this->litemageCache = $litemageCache; + $this->litemagePurge = $litemagePurge; + $this->config = $config; } /** @@ -32,7 +42,7 @@ public function __construct(\Litespeed\Litemage\Model\CacheControl $litemageCach */ public function execute(\Magento\Framework\Event\Observer $observer) { - if (!$this->litemageCache->moduleEnabled()) + if (!$this->config->moduleEnabled()) return; $event = $observer->getEvent(); @@ -51,7 +61,7 @@ public function execute(\Magento\Framework\Event\Observer $observer) break; } if (!empty($tags)) { - $this->litemageCache->addPurgeTags($tags , $msg); + $this->litemagePurge->addPurgeTags($tags , $msg); } } diff --git a/Observer/FlushCacheByTags.php b/Observer/FlushCacheByTags.php index 3f95041..745d753 100644 --- a/Observer/FlushCacheByTags.php +++ b/Observer/FlushCacheByTags.php @@ -1,4 +1,5 @@ config = $config; - $this->eventManager = $eventManager; + $this->eventManager = $eventManager; } /** @@ -37,27 +39,27 @@ public function __construct(\Litespeed\Litemage\Model\Config $config, */ public function execute(\Magento\Framework\Event\Observer $observer) { - $rawtags = []; - $object = $observer->getEvent()->getObject(); - if ($object instanceof \Magento\Framework\DataObject\IdentityInterface) { - $rawtags = $object->getIdentities(); - } - - if (empty($rawtags) || !$this->config->moduleEnabled()) { - return; - } - - $reason = 'FlushCacheByTags from ' . $observer->getEvent()->getName(). ' ' . implode(',', $rawtags); - $param = ['tags' => $rawtags, 'reason' => $reason]; - - if (PHP_SAPI == 'cli') { - // from command line - $this->eventManager->dispatch('litemage_cli_purge', $param); - } - else { - $this->eventManager->dispatch('litemage_purge', $param); + $rawtags = []; + $object = $observer->getEvent()->getObject(); + if ($object instanceof \Magento\Framework\DataObject\IdentityInterface) { + $rawtags = $object->getIdentities(); } - } + if (empty($rawtags) || !$this->config->moduleEnabled()) { + return; + } + + $reason = sprintf('FlushCacheByTags from %s %s', + $observer->getEvent()->getName(), + implode(',', $rawtags)); + $param = ['tags' => $rawtags, 'reason' => $reason]; + + if (PHP_SAPI == 'cli') { + // from command line + $this->eventManager->dispatch('litemage_cli_purge', $param); + } else { + $this->eventManager->dispatch('litemage_purge', $param); + } + } } diff --git a/Observer/LayoutGenerateBlocksAfter.php b/Observer/LayoutGenerateBlocksAfter.php index fa90c85..84ecf1b 100644 --- a/Observer/LayoutGenerateBlocksAfter.php +++ b/Observer/LayoutGenerateBlocksAfter.php @@ -1,4 +1,5 @@ litemageCache->maybeCacheable()) { - $layout = $observer->getEvent()->getLayout(); - $msg = 'Observer LayoutGenerateBlocksAfter'; - if ($layout->isCacheable()) { - // only now, as maybe multiple layout - $this->litemageCache->setCacheable(null, $msg); - } else { - $blocks = $layout->getUpdate()->asSimplexml()->xpath('//' . \Magento\Framework\View\Layout\Element::TYPE_BLOCK . '[@cacheable="false"]'); - $str = print_r($blocks, 1); - $shortmsg = 'Layout has uncacheable blocks '; - if (preg_match_all('/\[name\] => ([^\s]+)/', $str, $m)) { - $shortmsg .= implode(', ', $m[1]); - } - $msg .= ' Blocks not cacheable ' . $str; - $this->litemageCache->setNotCacheable($msg, $shortmsg); + if (!$this->litemageCache->maybeCacheable()) { + return; + } + $layout = $observer->getEvent()->getLayout(); + $msg = 'Observer LayoutGenerateBlocksAfter'; + if ($layout->isCacheable()) { + // only now, as maybe multiple layout + $this->litemageCache->setCacheable(null, $msg); + } else { + // not cacheable by layout, find out which blocks caused that for trouble shooting + $nocache = '//' . \Magento\Framework\View\Layout\Element::TYPE_BLOCK . '[@cacheable="false"]'; + $blocks = $layout->getUpdate()->asSimplexml()->xpath($nocache); + $str = print_r($blocks, 1); + $shortmsg = 'Layout has uncacheable blocks '; + if (preg_match_all('/\[name\] => ([^\s]+)/', $str, $m)) { + $shortmsg .= implode(', ', $m[1]); } + $msg .= ' Blocks not cacheable ' . $str; + $this->litemageCache->setNotCacheable($msg, $shortmsg); } } diff --git a/Observer/LayoutRenderElement.php b/Observer/LayoutRenderElement.php index 1a017c2..825ca84 100644 --- a/Observer/LayoutRenderElement.php +++ b/Observer/LayoutRenderElement.php @@ -1,4 +1,5 @@ litemageCache = $litemageCache; + $this->helper = $helper; //$this->_injectBlocks = ['footer']; } @@ -37,8 +45,9 @@ public function __construct( * @param \Magento\Framework\View\Layout $layout * @return string */ - protected function _replaceEsi( - $blockName, \Magento\Framework\View\Layout $layout, $transport) + protected function _replaceEsi($blockName, + \Magento\Framework\View\Layout $layout, + $transport) { $handles = $layout->getUpdate()->getHandles(); $url = $this->litemageCache->getEsiUrl($handles, $blockName); @@ -55,8 +64,8 @@ protected function _replaceEsi( $this->litemageCache->setEsiOn(true); $output = $uri; // discard original output - if ($this->litemageCache->debugEnabled()) { - $this->litemageCache->debugLog('replace esi ; ' . $uri); + if ($this->helper->debugEnabled()) { + $this->helper->debugLog('replace esi ; ' . $uri); $output = '' . $uri . ''; } $transport->setData('output', $output); diff --git a/composer.json b/composer.json index a51fcef..f888f0b 100644 --- a/composer.json +++ b/composer.json @@ -2,13 +2,13 @@ "name": "litespeed/module-litemage", "description": "LiteMage Full Page Cache for LiteSpeed Web Server", "require": { - "php": ">=7.0.0", + "php": ">=7.1.0", "ext-curl": "*", "magento/module-page-cache": "*", "magento/framework": "*" }, "type": "magento2-module", - "version": "2.1.3", + "version": "2.1.4", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/etc/adminhtml/di.xml b/etc/adminhtml/di.xml index 43dba0d..8bb0353 100644 --- a/etc/adminhtml/di.xml +++ b/etc/adminhtml/di.xml @@ -11,6 +11,6 @@ - + \ No newline at end of file diff --git a/etc/module.xml b/etc/module.xml index 7046d34..c2f75aa 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -7,7 +7,7 @@ */ --> - +