LiteSpeed_LiteMage - Version 1.2.0

Version Notes

Fixed a bug that caused errors when receiving soap api requests.
Added auto-collect feature to collect URLs not included in the sitemap including deep urls with different filter selections.
Added Delta crawler, URLs related to purged tags will now be recrawled.
Added settings allowing customization of product page and related category purging on product quantity or stock status changes.
LiteMage will now auto detect and set cache varies for product pages based on whether the review form is displayed and whether your site allows guests to write reviews.
Improved compatibility with third party themes including MT themes.

Download this release

Release Info

Developer LiteSpeed Technologies
Extension LiteSpeed_LiteMage
Version 1.2.0
Comparing to
See all releases


Code changes from version 1.1.2 to 1.2.0

app/code/community/Litespeed/Litemage/Block/Adminhtml/Cache/Management.php CHANGED
@@ -54,7 +54,17 @@ class Litespeed_Litemage_Block_Adminhtml_Cache_Management extends Mage_Adminhtml
54
  $base = Mage::getBaseUrl();
55
  if ((stripos($base, 'http') !== false) && ($pos = strpos($base, '://'))) {
56
  $pos2 = strpos($base, '/', $pos+ 4);
57
- $statBase = ($pos2 === false) ? $base : substr($base, 0, $pos2);
 
 
 
 
 
 
 
 
 
 
58
  }
59
  $statUri = $statBase . $statUri;
60
 
54
  $base = Mage::getBaseUrl();
55
  if ((stripos($base, 'http') !== false) && ($pos = strpos($base, '://'))) {
56
  $pos2 = strpos($base, '/', $pos+ 4);
57
+ if ($pos === false) {
58
+ $statBase = $base;
59
+ }
60
+ else {
61
+ $statBase = substr($base, 0, $pos2);
62
+ if (substr($base, $pos2+1, 1) == '~') {
63
+ if ($pos3 = strpos($base, '/', $pos2+1)) {
64
+ $statBase = substr($base, 0, $pos3);
65
+ }
66
+ }
67
+ }
68
  }
69
  $statUri = $statBase . $statUri;
70
 
app/code/community/Litespeed/Litemage/Block/Core/Dummy.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * LiteMage
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program. If not, see https://opensource.org/licenses/GPL-3.0 .
20
+ *
21
+ * @package LiteSpeed_LiteMage
22
+ * @copyright Copyright (c) 2016 LiteSpeed Technologies, Inc. (https://www.litespeedtech.com)
23
+ * @license https://opensource.org/licenses/GPL-3.0
24
+ */
25
+
26
+ class Litespeed_Litemage_Block_Core_Dummy extends Mage_Core_Block_Abstract
27
+ {
28
+ protected $_name;
29
+
30
+ public function __construct($name)
31
+ {
32
+ // most time is root, head
33
+ $this->_name = $name;
34
+ }
35
+
36
+ // dummy block not exist in ESILayout, they are not ESI block, safe to ignore
37
+ public function __call($method, $args)
38
+ {
39
+ Mage::helper('litemage/data')->debugMesg('Dummy block ' . $this->_name . " called $method - ignore");
40
+
41
+ }
42
+
43
+ public static function __callStatic($method, $args)
44
+ {
45
+ Mage::helper('litemage/data')->debugMesg('Dummy block ' . $this->_name . " called static $method - ignore");
46
+ }
47
+
48
+ }
app/code/community/Litespeed/Litemage/Block/Inject/Nickname.php CHANGED
@@ -33,6 +33,9 @@
33
  * Update template code to:
34
  * <input type="text" name="nickname" id="nickname_field" class="input-text required-entry" value="<?php echo $this->getChildHtml('nickname') ?>" required/>
35
  * For regular esi injected block, we'll output html comment tags around it, however for this case, we can only output pure value.
 
 
 
36
 
37
  */
38
 
33
  * Update template code to:
34
  * <input type="text" name="nickname" id="nickname_field" class="input-text required-entry" value="<?php echo $this->getChildHtml('nickname') ?>" required/>
35
  * For regular esi injected block, we'll output html comment tags around it, however for this case, we can only output pure value.
36
+ *
37
+ * This is just one example. As of 1.2.0, the nickname output inside Review Form on a cacheable page (like in product view page) is handled automatically.
38
+ * You no longer need to manually adjust layout file.
39
 
40
  */
41
 
app/code/community/Litespeed/Litemage/Helper/Data.php CHANGED
@@ -32,27 +32,20 @@ class Litespeed_Litemage_Helper_Data extends Mage_Core_Helper_Abstract
32
  const STOREXML_HOMETTL = 'litemage/general/home_ttl' ;
33
  const STOREXML_TRACKLASTVIEWED = 'litemage/general/track_viewed' ;
34
  const STOREXML_DIFFCUSTGRP = 'litemage/general/diff_customergroup' ;
35
- const STOREXML_WARMUP_EANBLED = 'litemage/warmup/enable_warmup' ;
36
- const STOREXML_WARMUP_MULTICURR = 'litemage/warmup/multi_currency' ;
37
- const STOREXML_WARMUP_INTERVAL = 'litemage/warmup/interval' ;
38
- const STOREXML_WARMUP_PRIORITY = 'litemage/warmup/priority' ;
39
- const STOREXML_WARMUP_CUSTLIST = 'litemage/warmup/custlist' ;
40
- const STOREXML_WARMUP_CUSTLIST_PRIORITY = 'litemage/warmup/custlist_priority' ;
41
- const STOREXML_WARMUP_CUSTLIST_INTERVAL = 'litemage/warmup/custlist_interval' ;
42
  const CFG_ENABLED = 'enabled' ;
43
  const CFG_DEBUGON = 'debug' ;
44
  const CFG_WARMUP = 'warmup' ;
45
- const CFG_WARMUP_ALLOW = 'allow_warmup' ;
46
- const CFG_WARMUP_EANBLED = 'enable_warmup' ;
47
  const CFG_WARMUP_LOAD_LIMIT = 'load_limit' ;
48
  const CFG_WARMUP_MAXTIME = 'max_time' ;
49
  const CFG_WARMUP_THREAD_LIMIT = 'thread_limit' ;
50
- const CFG_WARMUP_MULTICURR = 'multi_currency' ;
51
  const CFG_TRACKLASTVIEWED = 'track_viewed' ;
52
  const CFG_DIFFCUSTGRP = 'diff_customergroup' ;
53
  const CFG_PUBLICTTL = 'public_ttl' ;
54
  const CFG_PRIVATETTL = 'private_ttl' ;
55
- const CFG_HOMETTL = 'home_ttl';
56
  const CFG_ESIBLOCK = 'esiblock' ;
57
  const CFG_NOCACHE = 'nocache' ;
58
  const CFG_CACHE_ROUTE = 'cache_routes' ;
@@ -62,7 +55,10 @@ class Litespeed_Litemage_Helper_Data extends Mage_Core_Helper_Abstract
62
  const CFG_NOCACHE_URL = 'nocache_urls' ;
63
  const CFG_ALLOWEDIPS = 'allow_ips' ;
64
  const CFG_ADMINIPS = 'admin_ips' ;
 
 
65
  const LITEMAGE_GENERAL_CACHE_TAG = 'LITESPEED_LITEMAGE' ;
 
66
 
67
  // config items
68
  protected $_conf = array() ;
@@ -90,8 +86,9 @@ class Litespeed_Litemage_Helper_Data extends Mage_Core_Helper_Abstract
90
  $tag = '' ;
91
  $httphelper = Mage::helper('core/http') ;
92
  $remoteAddr = $httphelper->getRemoteAddr() ;
93
- if ( $httphelper->getHttpUserAgent() == 'litemage_walker' ) {
94
- $tag = 'litemage_walker:' ;
 
95
  }
96
  else if ( $ips = $this->getConf(self::CFG_ALLOWEDIPS) ) {
97
  if ( ! in_array($remoteAddr, $ips) ) {
@@ -157,7 +154,7 @@ class Litespeed_Litemage_Helper_Data extends Mage_Core_Helper_Abstract
157
  'pc' => array(
158
  0 => array( 'Mage_Core_Block_Messages', 'Mage_Core_Block_Template' ),
159
  1 => array( 'M', 'T' ) )
160
- ) ;
161
  }
162
  return $this->_translateParams ;
163
  }
@@ -256,8 +253,8 @@ class Litespeed_Litemage_Helper_Data extends Mage_Core_Helper_Abstract
256
  public function getWarmUpConf()
257
  {
258
  if ( ! isset($this->_conf[self::CFG_WARMUP]) ) {
259
-
260
  $storeInfo = array() ;
 
261
  if ( $this->getConf(self::CFG_ENABLED) ) {
262
  $this->getConf('', self::CFG_WARMUP) ;
263
  $storeIds = array_keys(Mage::app()->getStores()) ;
@@ -277,16 +274,97 @@ class Litespeed_Litemage_Helper_Data extends Mage_Core_Helper_Abstract
277
  return $this->_conf[self::CFG_WARMUP] ;
278
  }
279
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
  protected function _getStoreWarmUpInfo( $storeId, $vary_dev )
281
  {
282
- $storeInfo = array();
283
- $enabled = Mage::getStoreConfig(self::STOREXML_WARMUP_EANBLED, $storeId);
284
- if ($enabled == 0)
285
- return $storeInfo;
286
 
287
  $store = Mage::app()->getStore($storeId) ;
288
- if ( !$store->getIsActive() )
289
- return $storeInfo;
 
 
 
 
 
290
 
291
  $site = $store->getWebsite() ;
292
  $is_default_store = ($site->getDefaultStore()->getId() == $storeId) ; // cannot use $app->getDefaultStoreView()->getId();
@@ -300,7 +378,7 @@ class Litespeed_Litemage_Helper_Data extends Mage_Core_Helper_Abstract
300
  $availCurrCodes = $store->getAvailableCurrencyCodes() ;
301
  $default_currency = $store->getDefaultCurrencyCode() ;
302
  $vary_curr = '' ;
303
- $curr = trim(Mage::getStoreConfig(self::STOREXML_WARMUP_MULTICURR, $storeId)) ;
304
  if ( $curr ) {
305
  // get currency vary
306
  $currs = preg_split("/[\s,]+/", strtoupper($curr), null, PREG_SPLIT_NO_EMPTY) ;
@@ -336,22 +414,20 @@ class Litespeed_Litemage_Helper_Data extends Mage_Core_Helper_Abstract
336
 
337
  $env = '' ;
338
 
339
- $storeName = $store->getName();
340
  if ( ! $is_default_store ) {
341
  $env .= '/store/' . $store->getCode() . '/storeId/' . $storeId ;
342
  }
343
  $env .= $vary_curr . $vary_cgrp . $vary_dev ;
344
  $baseurl = $store->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK) ;
345
  $ttl = Mage::getStoreConfig(self::STOREXML_PUBLICTTL, $storeId) ;
 
 
 
 
 
346
 
347
- if ($enabled == 1) {
348
- $priority = Mage::getStoreConfig(self::STOREXML_WARMUP_PRIORITY, $storeId) + $orderAdjust ;
349
-
350
- $interval = Mage::getStoreConfig(self::STOREXML_WARMUP_INTERVAL, $storeId) ;
351
- if ( $interval == '' || $interval < 600 ) { // for upgrade users, not refreshed conf
352
- $interval = $ttl ;
353
- }
354
-
355
  $listId = 'store' . $storeId ;
356
  $storeInfo[$listId] = array(
357
  'id' => $listId,
@@ -367,34 +443,77 @@ class Litespeed_Litemage_Helper_Data extends Mage_Core_Helper_Abstract
367
  'baseurl' => $baseurl ) ;
368
  }
369
 
370
- // check custom list
371
- $custlist = Mage::getStoreConfig(self::STOREXML_WARMUP_CUSTLIST, $storeId) ;
372
- $lines = explode("\n", $custlist) ;
373
- foreach ( $lines as $index => $line ) {
374
- $f = preg_split("/[\s]+/", $line, null, PREG_SPLIT_NO_EMPTY) ;
375
- if (count($f) != 3) {
376
- continue;
377
- }
378
- $custFile = $f[0] ;
379
- if ( ! is_readable($custFile) || ! isset($f[1]) || ! isset($f[2]) || $f[1] < 600 || $f[2] <= 0 ) {
380
- continue ;
381
  }
382
- $custInterval = $f[1] ;
383
- $custPriority = $f[2] ;
384
- $listId = 'cust' . $storeId . '-' . $index ;
385
  $storeInfo[$listId] = array(
386
  'id' => $listId,
387
  'storeid' => $storeId,
388
  'store_name' => $storeName,
389
  'default_curr' => $default_currency,
 
 
390
  'env' => $env,
391
- 'interval' => $custInterval,
392
  'ttl' => $ttl,
393
- 'priority' => $custPriority,
394
- 'baseurl' => $baseurl,
395
- 'file' => $custFile ) ;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
396
  }
397
- return $storeInfo;
 
398
  }
399
 
400
  public function isEsiBlock( $block, $startDynamic )
@@ -403,6 +522,7 @@ class Litespeed_Litemage_Helper_Data extends Mage_Core_Helper_Abstract
403
  $tag = null ;
404
  $valueonly = 0 ;
405
  $blockType = null ;
 
406
 
407
  $ref = $this->_conf[self::CFG_ESIBLOCK]['block'] ;
408
  if ( isset($ref['bn'][$blockName]) ) {
@@ -443,7 +563,7 @@ class Litespeed_Litemage_Helper_Data extends Mage_Core_Helper_Abstract
443
  'valueonly' => $valueonly,
444
  'bn' => $blockName,
445
  'bt' => $blockType
446
- ) ;
447
  if ( $startDynamic ) {
448
  $bconf['pc'] = get_class($block) ;
449
  $bconf['is_dynamic'] = 1 ;
@@ -504,9 +624,11 @@ class Litespeed_Litemage_Helper_Data extends Mage_Core_Helper_Abstract
504
  $this->_conf[self::CFG_ESIBLOCK]['tag'] = $this->_getConfigByPath(self::CFGXML_ESIBLOCK) ;
505
 
506
  $custblocks = array() ;
507
- $custblocks['welcome'] = preg_split($pattern, $this->_conf['defaultlm']['donotcache']['welcome'], null, PREG_SPLIT_NO_EMPTY) ;
508
- $custblocks['toplinks'] = preg_split($pattern, $this->_conf['defaultlm']['donotcache']['toplinks'], null, PREG_SPLIT_NO_EMPTY) ;
509
- $custblocks['messages'] = preg_split($pattern, $this->_conf['defaultlm']['donotcache']['messages'], null, PREG_SPLIT_NO_EMPTY) ;
 
 
510
 
511
  $allblocks = array( 'bn' => array(), 'bt' => array() ) ;
512
  foreach ( $this->_conf[self::CFG_ESIBLOCK]['tag'] as $tag => $d ) {
@@ -533,6 +655,9 @@ class Litespeed_Litemage_Helper_Data extends Mage_Core_Helper_Abstract
533
  }
534
  if ( isset($d['purge_tags']) ) {
535
  $pts = preg_split($pattern, $d['purge_tags'], null, PREG_SPLIT_NO_EMPTY) ;
 
 
 
536
  if ( ! isset($d['purge_events']) ) {
537
  $this->_conf[self::CFG_ESIBLOCK]['tag'][$tag]['purge_events'] = array() ;
538
  }
@@ -550,22 +675,28 @@ class Litespeed_Litemage_Helper_Data extends Mage_Core_Helper_Abstract
550
  $this->_conf[self::CFG_NOCACHE] = array() ;
551
  $default = $this->_conf['defaultlm']['default'] ;
552
  $cust = $this->_conf['defaultlm']['donotcache'] ;
 
 
 
553
 
554
  $this->_conf[self::CFG_NOCACHE][self::CFG_CACHE_ROUTE] = array_merge(preg_split($pattern, $default['cache_routes'], null, PREG_SPLIT_NO_EMPTY), preg_split($pattern, $cust['cache_routes'], null, PREG_SPLIT_NO_EMPTY)) ;
555
  $this->_conf[self::CFG_NOCACHE][self::CFG_NOCACHE_ROUTE] = array_merge(preg_split($pattern, $default['nocache_subroutes'], null, PREG_SPLIT_NO_EMPTY), preg_split($pattern, $default['nocache_subroutes'], null, PREG_SPLIT_NO_EMPTY)) ;
556
- $this->_conf[self::CFG_NOCACHE][self::CFG_FULLCACHE_ROUTE] = preg_split($pattern, $default['fullcache_routes'], null, PREG_SPLIT_NO_EMPTY) ;
557
  $this->_conf[self::CFG_NOCACHE][self::CFG_NOCACHE_VAR] = preg_split($pattern, $cust['vars'], null, PREG_SPLIT_NO_EMPTY) ;
558
  $this->_conf[self::CFG_NOCACHE][self::CFG_NOCACHE_URL] = preg_split($pattern, $cust['urls'], null, PREG_SPLIT_NO_EMPTY) ;
559
  break ;
560
 
561
  case self::CFG_WARMUP:
562
  $warmup = $this->_conf['defaultlm']['warmup'] ;
 
 
 
 
563
  $this->_conf[self::CFG_WARMUP] = array(
564
- self::CFG_WARMUP_EANBLED => $warmup[self::CFG_WARMUP_EANBLED],
565
  self::CFG_WARMUP_LOAD_LIMIT => $warmup[self::CFG_WARMUP_LOAD_LIMIT],
566
  self::CFG_WARMUP_THREAD_LIMIT => $warmup[self::CFG_WARMUP_THREAD_LIMIT],
567
  self::CFG_WARMUP_MAXTIME => $warmup[self::CFG_WARMUP_MAXTIME],
568
- self::CFG_WARMUP_MULTICURR => $warmup[self::CFG_WARMUP_MULTICURR] ) ;
569
  break ;
570
 
571
  default:
@@ -575,6 +706,11 @@ class Litespeed_Litemage_Helper_Data extends Mage_Core_Helper_Abstract
575
  $test = $this->_conf['defaultlm']['test'] ;
576
  $this->_conf[self::CFG_DEBUGON] = $test[self::CFG_DEBUGON] ;
577
  $this->_isDebug = $test[self::CFG_DEBUGON] ; // required by cron, needs to be set even when module disabled.
 
 
 
 
 
578
 
579
  if ( ! $general[self::CFG_ENABLED] )
580
  break ;
@@ -586,8 +722,6 @@ class Litespeed_Litemage_Helper_Data extends Mage_Core_Helper_Abstract
586
  $this->_conf[self::CFG_PRIVATETTL] = Mage::getStoreConfig(self::STOREXML_PRIVATETTL, $storeId) ;
587
  $this->_conf[self::CFG_HOMETTL] = Mage::getStoreConfig(self::STOREXML_HOMETTL, $storeId) ;
588
 
589
- $adminIps = trim($general[self::CFG_ADMINIPS]) ;
590
- $this->_conf[self::CFG_ADMINIPS] = $adminIps ? preg_split($pattern, $adminIps, null, PREG_SPLIT_NO_EMPTY) : '' ;
591
  if ( $general['alt_esi_syntax'] ) {
592
  $this->_esiTag = array( 'include' => 'esi_include', 'inline' => 'esi_inline', 'remove' => 'esi_remove' ) ;
593
  }
@@ -596,6 +730,7 @@ class Litespeed_Litemage_Helper_Data extends Mage_Core_Helper_Abstract
596
  }
597
  $allowedIps = trim($test[self::CFG_ALLOWEDIPS]) ;
598
  $this->_conf[self::CFG_ALLOWEDIPS] = $allowedIps ? preg_split($pattern, $allowedIps, null, PREG_SPLIT_NO_EMPTY) : '' ;
 
599
  }
600
  }
601
 
@@ -607,6 +742,20 @@ class Litespeed_Litemage_Helper_Data extends Mage_Core_Helper_Abstract
607
  return $node->asCanonicalArray() ;
608
  }
609
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
610
  public function debugMesg( $mesg )
611
  {
612
  if ( $this->_isDebug ) {
32
  const STOREXML_HOMETTL = 'litemage/general/home_ttl' ;
33
  const STOREXML_TRACKLASTVIEWED = 'litemage/general/track_viewed' ;
34
  const STOREXML_DIFFCUSTGRP = 'litemage/general/diff_customergroup' ;
35
+ const STOREXML_WARMUP_ENABLED = 'litemage/warmup/enable_warmup' ;
 
 
 
 
 
 
36
  const CFG_ENABLED = 'enabled' ;
37
  const CFG_DEBUGON = 'debug' ;
38
  const CFG_WARMUP = 'warmup' ;
39
+ const CFG_WARMUP_SERVER_IP = 'server_ip' ;
 
40
  const CFG_WARMUP_LOAD_LIMIT = 'load_limit' ;
41
  const CFG_WARMUP_MAXTIME = 'max_time' ;
42
  const CFG_WARMUP_THREAD_LIMIT = 'thread_limit' ;
43
+ const CFG_AUTOCOLLECT = 'collect' ;
44
  const CFG_TRACKLASTVIEWED = 'track_viewed' ;
45
  const CFG_DIFFCUSTGRP = 'diff_customergroup' ;
46
  const CFG_PUBLICTTL = 'public_ttl' ;
47
  const CFG_PRIVATETTL = 'private_ttl' ;
48
+ const CFG_HOMETTL = 'home_ttl' ;
49
  const CFG_ESIBLOCK = 'esiblock' ;
50
  const CFG_NOCACHE = 'nocache' ;
51
  const CFG_CACHE_ROUTE = 'cache_routes' ;
55
  const CFG_NOCACHE_URL = 'nocache_urls' ;
56
  const CFG_ALLOWEDIPS = 'allow_ips' ;
57
  const CFG_ADMINIPS = 'admin_ips' ;
58
+ const CFG_FLUSH_PRODCAT = 'flush_prodcat' ;
59
+ const CFG_NEED_ADD_DELTA = 'add_delta' ;
60
  const LITEMAGE_GENERAL_CACHE_TAG = 'LITESPEED_LITEMAGE' ;
61
+ const LITEMAGE_DELTA_CACHE_ID = 'LITEMAGE_DELTA' ;
62
 
63
  // config items
64
  protected $_conf = array() ;
86
  $tag = '' ;
87
  $httphelper = Mage::helper('core/http') ;
88
  $remoteAddr = $httphelper->getRemoteAddr() ;
89
+ $ua = $httphelper->getHttpUserAgent() ;
90
+ if ( $ua == 'litemage_walker' || $ua == 'litemage_runner' ) {
91
+ $tag = $ua . ':' ;
92
  }
93
  else if ( $ips = $this->getConf(self::CFG_ALLOWEDIPS) ) {
94
  if ( ! in_array($remoteAddr, $ips) ) {
154
  'pc' => array(
155
  0 => array( 'Mage_Core_Block_Messages', 'Mage_Core_Block_Template' ),
156
  1 => array( 'M', 'T' ) )
157
+ ) ;
158
  }
159
  return $this->_translateParams ;
160
  }
253
  public function getWarmUpConf()
254
  {
255
  if ( ! isset($this->_conf[self::CFG_WARMUP]) ) {
 
256
  $storeInfo = array() ;
257
+
258
  if ( $this->getConf(self::CFG_ENABLED) ) {
259
  $this->getConf('', self::CFG_WARMUP) ;
260
  $storeIds = array_keys(Mage::app()->getStores()) ;
274
  return $this->_conf[self::CFG_WARMUP] ;
275
  }
276
 
277
+ public function needAddDeltaTags()
278
+ {
279
+ if ( ! isset($this->_conf[self::CFG_NEED_ADD_DELTA]) ) {
280
+ $found = false ;
281
+ // as long as we find one store has delta crawl enabled
282
+ if ( $this->getConf(self::CFG_ENABLED) ) {
283
+ $storeIds = array_keys(Mage::app()->getStores()) ;
284
+
285
+ foreach ( $storeIds as $storeId ) {
286
+ $enabled_sel = Mage::getStoreConfig(self::STOREXML_WARMUP_ENABLED, $storeId) ;
287
+ if ( strpos($enabled_sel, '8') !== false ) {
288
+ if ( Mage::app()->getStore($storeId)->getIsActive() )
289
+ $found = true ;
290
+ break ;
291
+ }
292
+ }
293
+ }
294
+ $this->_conf[self::CFG_NEED_ADD_DELTA] = $found ;
295
+ }
296
+
297
+ return $this->_conf[self::CFG_NEED_ADD_DELTA] ;
298
+ }
299
+
300
+ public function getCrawlerListDir()
301
+ {
302
+ $path = Mage::getBaseDir('var') . DS . 'litemage' ;
303
+
304
+ if ( ! is_dir($path) ) {
305
+ mkdir($path) ;
306
+ chmod($path, 0777) ;
307
+ }
308
+ return $path ;
309
+ }
310
+
311
+ public function getAutoCollectConf( $storeId )
312
+ {
313
+ if ( ! isset($this->_conf[self::CFG_AUTOCOLLECT][$storeId]) ) {
314
+
315
+ if ( ! isset($this->_conf[self::CFG_AUTOCOLLECT]) ) {
316
+ $this->_conf[self::CFG_AUTOCOLLECT] = array() ;
317
+ }
318
+ $info = array( 'collect' => 0, 'crawlDelta' => 0, 'crawlAuto' => 0, 'frame' => 0, 'remove' => 0, 'deep' => 0, 'deltaDeep' => 0, 'countRobot' => 0 ) ;
319
+
320
+ if ( $this->getConf(self::CFG_ENABLED) ) {
321
+ $enabled_sel = Mage::getStoreConfig(self::STOREXML_WARMUP_ENABLED, $storeId) ;
322
+ if ( $enabled_sel ) {
323
+
324
+ if ( strpos($enabled_sel, '8') !== false ) {
325
+ $info['crawlDelta'] = 1 ;
326
+ $info['deltaDeep'] = Mage::getStoreConfig('litemage/warmup/delta_depth', $storeId) ;
327
+ }
328
+ if ( strpos($enabled_sel, '4') !== false ) {
329
+ $info['crawlAuto'] = 1 ;
330
+ if ( Mage::getStoreConfig('litemage/warmup/enable_autocollect', $storeId) ) {
331
+ $info['collect'] = Mage::getStoreConfig('litemage/warmup/auto_collect_add', $storeId) ;
332
+ $info['countRobot'] = Mage::getStoreConfig('litemage/warmup/auto_collect_robot', $storeId) ;
333
+ $info['remove'] = Mage::getStoreConfig('litemage/warmup/auto_collect_remove', $storeId) ;
334
+ if ( $info['remove'] < 1 )
335
+ $info['remove'] = 1 ; // minimum is 1
336
+ elseif ( $info['remove'] > $info['collect'] )
337
+ $info['remove'] = $info['collect'] ;
338
+ $info['frame'] = Mage::getStoreConfig('litemage/warmup/auto_collect_hours', $storeId)
339
+ * 3600 ;
340
+ $info['deep'] = Mage::getStoreConfig('litemage/warmup/auto_collect_depth', $storeId) ;
341
+ if ( $info['deltaDeep'] > $info['deep'] )
342
+ $info['deltaDeep'] = $info['deep'] ;
343
+ }
344
+ }
345
+ }
346
+ }
347
+ $this->_conf[self::CFG_AUTOCOLLECT][$storeId] = $info ;
348
+ }
349
+
350
+ return $this->_conf[self::CFG_AUTOCOLLECT][$storeId] ;
351
+ }
352
+
353
  protected function _getStoreWarmUpInfo( $storeId, $vary_dev )
354
  {
355
+ $storeInfo = array() ;
356
+ $enabled_sel = Mage::getStoreConfig(self::STOREXML_WARMUP_ENABLED, $storeId) ;
357
+ if ( ! $enabled_sel )
358
+ return $storeInfo ;
359
 
360
  $store = Mage::app()->getStore($storeId) ;
361
+ if ( ! $store->getIsActive() )
362
+ return $storeInfo ;
363
+
364
+ $enabledStore = (strpos($enabled_sel, '1') !== false) ;
365
+ $enabledCust = (strpos($enabled_sel, '2') !== false) ;
366
+ $enabledAuto = (strpos($enabled_sel, '4') !== false) ;
367
+ $enabledDelta = (strpos($enabled_sel, '8') !== false) ;
368
 
369
  $site = $store->getWebsite() ;
370
  $is_default_store = ($site->getDefaultStore()->getId() == $storeId) ; // cannot use $app->getDefaultStoreView()->getId();
378
  $availCurrCodes = $store->getAvailableCurrencyCodes() ;
379
  $default_currency = $store->getDefaultCurrencyCode() ;
380
  $vary_curr = '' ;
381
+ $curr = trim(Mage::getStoreConfig('litemage/warmup/multi_currency', $storeId)) ;
382
  if ( $curr ) {
383
  // get currency vary
384
  $currs = preg_split("/[\s,]+/", strtoupper($curr), null, PREG_SPLIT_NO_EMPTY) ;
414
 
415
  $env = '' ;
416
 
417
+ $storeName = $store->getName() ;
418
  if ( ! $is_default_store ) {
419
  $env .= '/store/' . $store->getCode() . '/storeId/' . $storeId ;
420
  }
421
  $env .= $vary_curr . $vary_cgrp . $vary_dev ;
422
  $baseurl = $store->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK) ;
423
  $ttl = Mage::getStoreConfig(self::STOREXML_PUBLICTTL, $storeId) ;
424
+ $priority = Mage::getStoreConfig('litemage/warmup/priority', $storeId) + $orderAdjust ;
425
+ $interval = Mage::getStoreConfig('litemage/warmup/interval', $storeId) ;
426
+ if ( $interval == '' || $interval < 600 ) { // for upgrade users, not refreshed conf
427
+ $interval = $ttl ;
428
+ }
429
 
430
+ if ( $enabledStore ) {
 
 
 
 
 
 
 
431
  $listId = 'store' . $storeId ;
432
  $storeInfo[$listId] = array(
433
  'id' => $listId,
443
  'baseurl' => $baseurl ) ;
444
  }
445
 
446
+ if ( $enabledAuto ) {
447
+ // check auto list
448
+ $autopriority = Mage::getStoreConfig('litemage/warmup/autolist_priority', $storeId) ;
449
+ $autopriority += $orderAdjust ;
450
+ $autointerval = Mage::getStoreConfig('litemage/warmup/autolist_interval', $storeId) ;
451
+ if ( $autointerval == '' || $interval < $autointerval / 2 ) { // for upgrade users, not refreshed conf
452
+ $autointerval = $ttl ;
 
 
 
 
453
  }
454
+ $listId = 'auto' . $storeId ;
 
 
455
  $storeInfo[$listId] = array(
456
  'id' => $listId,
457
  'storeid' => $storeId,
458
  'store_name' => $storeName,
459
  'default_curr' => $default_currency,
460
+ 'default_store' => $is_default_store,
461
+ 'default_site' => $is_default_site,
462
  'env' => $env,
463
+ 'interval' => $autointerval,
464
  'ttl' => $ttl,
465
+ 'priority' => $autopriority,
466
+ 'baseurl' => $baseurl ) ;
467
+ }
468
+
469
+ if ( $enabledDelta ) {
470
+ // delta list
471
+ $autoconf = $this->getAutoCollectConf($storeId) ;
472
+ $listId = 'delta' . $storeId ;
473
+ $storeInfo[$listId] = array(
474
+ 'storeid' => $storeId,
475
+ 'store_name' => $storeName,
476
+ 'default_curr' => $default_currency,
477
+ 'default_store' => $is_default_store,
478
+ 'default_site' => $is_default_site,
479
+ 'env' => $env,
480
+ 'priority' => $priority,
481
+ 'depth' => $autoconf['deltaDeep'],
482
+ 'baseurl' => $baseurl ) ;
483
+ }
484
+
485
+ if ( $enabledCust ) {
486
+ // check custom list
487
+ $custlist = Mage::getStoreConfig('litemage/warmup/custlist', $storeId) ;
488
+ $lines = explode("\n", $custlist) ;
489
+ foreach ( $lines as $index => $line ) {
490
+ $f = preg_split("/[\s]+/", $line, null, PREG_SPLIT_NO_EMPTY) ;
491
+ if ( count($f) != 3 ) {
492
+ continue ;
493
+ }
494
+ $custFile = $f[0] ;
495
+ if ( ! is_readable($custFile) || ! isset($f[1]) || ! isset($f[2]) || $f[1] < 600
496
+ || $f[2] <= 0 ) {
497
+ continue ;
498
+ }
499
+ $custInterval = $f[1] ;
500
+ $custPriority = $f[2] ;
501
+ $listId = 'cust' . $storeId . '-' . $index ;
502
+ $storeInfo[$listId] = array(
503
+ 'id' => $listId,
504
+ 'storeid' => $storeId,
505
+ 'store_name' => $storeName,
506
+ 'default_curr' => $default_currency,
507
+ 'env' => $env,
508
+ 'interval' => $custInterval,
509
+ 'ttl' => $ttl,
510
+ 'priority' => $custPriority + $orderAdjust,
511
+ 'baseurl' => $baseurl,
512
+ 'file' => $custFile ) ;
513
+ }
514
  }
515
+
516
+ return $storeInfo ;
517
  }
518
 
519
  public function isEsiBlock( $block, $startDynamic )
522
  $tag = null ;
523
  $valueonly = 0 ;
524
  $blockType = null ;
525
+ $classname = get_class($block) ;
526
 
527
  $ref = $this->_conf[self::CFG_ESIBLOCK]['block'] ;
528
  if ( isset($ref['bn'][$blockName]) ) {
563
  'valueonly' => $valueonly,
564
  'bn' => $blockName,
565
  'bt' => $blockType
566
+ ) ;
567
  if ( $startDynamic ) {
568
  $bconf['pc'] = get_class($block) ;
569
  $bconf['is_dynamic'] = 1 ;
624
  $this->_conf[self::CFG_ESIBLOCK]['tag'] = $this->_getConfigByPath(self::CFGXML_ESIBLOCK) ;
625
 
626
  $custblocks = array() ;
627
+ $cust = $this->_conf['defaultlm']['donotcache'] ;
628
+ $custblocks['welcome'] = empty($cust['welcome']) ? array() : preg_split($pattern, $cust['welcome'], null, PREG_SPLIT_NO_EMPTY) ;
629
+ $custblocks['toplinks'] = empty($cust['toplinks']) ? array() : preg_split($pattern, $cust['toplinks'], null, PREG_SPLIT_NO_EMPTY) ;
630
+ $custblocks['messages'] = empty($cust['messages']) ? array() : preg_split($pattern, $cust['messages'], null, PREG_SPLIT_NO_EMPTY) ;
631
+ $toplinkstag = empty($cust['toplinkstag']) ? array() : preg_split($pattern, $cust['toplinkstag'], null, PREG_SPLIT_NO_EMPTY) ;
632
 
633
  $allblocks = array( 'bn' => array(), 'bt' => array() ) ;
634
  foreach ( $this->_conf[self::CFG_ESIBLOCK]['tag'] as $tag => $d ) {
655
  }
656
  if ( isset($d['purge_tags']) ) {
657
  $pts = preg_split($pattern, $d['purge_tags'], null, PREG_SPLIT_NO_EMPTY) ;
658
+ if ( $tag == 'toplinks' && ! empty($toplinkstag) ) {
659
+ $pts = array_merge($pts, $toplinkstag) ;
660
+ }
661
  if ( ! isset($d['purge_events']) ) {
662
  $this->_conf[self::CFG_ESIBLOCK]['tag'][$tag]['purge_events'] = array() ;
663
  }
675
  $this->_conf[self::CFG_NOCACHE] = array() ;
676
  $default = $this->_conf['defaultlm']['default'] ;
677
  $cust = $this->_conf['defaultlm']['donotcache'] ;
678
+ if ( ! isset($cust['fullcache_routes']) ) {
679
+ $cust['fullcache_routes'] = '' ;
680
+ }
681
 
682
  $this->_conf[self::CFG_NOCACHE][self::CFG_CACHE_ROUTE] = array_merge(preg_split($pattern, $default['cache_routes'], null, PREG_SPLIT_NO_EMPTY), preg_split($pattern, $cust['cache_routes'], null, PREG_SPLIT_NO_EMPTY)) ;
683
  $this->_conf[self::CFG_NOCACHE][self::CFG_NOCACHE_ROUTE] = array_merge(preg_split($pattern, $default['nocache_subroutes'], null, PREG_SPLIT_NO_EMPTY), preg_split($pattern, $default['nocache_subroutes'], null, PREG_SPLIT_NO_EMPTY)) ;
684
+ $this->_conf[self::CFG_NOCACHE][self::CFG_FULLCACHE_ROUTE] = preg_split($pattern, $cust['fullcache_routes'], null, PREG_SPLIT_NO_EMPTY) ;
685
  $this->_conf[self::CFG_NOCACHE][self::CFG_NOCACHE_VAR] = preg_split($pattern, $cust['vars'], null, PREG_SPLIT_NO_EMPTY) ;
686
  $this->_conf[self::CFG_NOCACHE][self::CFG_NOCACHE_URL] = preg_split($pattern, $cust['urls'], null, PREG_SPLIT_NO_EMPTY) ;
687
  break ;
688
 
689
  case self::CFG_WARMUP:
690
  $warmup = $this->_conf['defaultlm']['warmup'] ;
691
+ $server_ip = $warmup[self::CFG_WARMUP_SERVER_IP] ;
692
+ if ( $server_ip && ! Mage::helper('core/http')->validateIpAddr($server_ip) ) {
693
+ $server_ip = '' ;
694
+ }
695
  $this->_conf[self::CFG_WARMUP] = array(
 
696
  self::CFG_WARMUP_LOAD_LIMIT => $warmup[self::CFG_WARMUP_LOAD_LIMIT],
697
  self::CFG_WARMUP_THREAD_LIMIT => $warmup[self::CFG_WARMUP_THREAD_LIMIT],
698
  self::CFG_WARMUP_MAXTIME => $warmup[self::CFG_WARMUP_MAXTIME],
699
+ self::CFG_WARMUP_SERVER_IP => $server_ip ) ;
700
  break ;
701
 
702
  default:
706
  $test = $this->_conf['defaultlm']['test'] ;
707
  $this->_conf[self::CFG_DEBUGON] = $test[self::CFG_DEBUGON] ;
708
  $this->_isDebug = $test[self::CFG_DEBUGON] ; // required by cron, needs to be set even when module disabled.
709
+ $adminIps = trim($general[self::CFG_ADMINIPS]) ;
710
+ $this->_conf[self::CFG_ADMINIPS] = $adminIps ? preg_split($pattern, $adminIps, null, PREG_SPLIT_NO_EMPTY) : '' ;
711
+ if ( ($this->_isDebug == 2) && (empty($this->_conf[self::CFG_ADMINIPS]) || ! in_array(Mage::helper('core/http')->getRemoteAddr(), $this->_conf[self::CFG_ADMINIPS])) ) {
712
+ $this->_isDebug = 0 ;
713
+ }
714
 
715
  if ( ! $general[self::CFG_ENABLED] )
716
  break ;
722
  $this->_conf[self::CFG_PRIVATETTL] = Mage::getStoreConfig(self::STOREXML_PRIVATETTL, $storeId) ;
723
  $this->_conf[self::CFG_HOMETTL] = Mage::getStoreConfig(self::STOREXML_HOMETTL, $storeId) ;
724
 
 
 
725
  if ( $general['alt_esi_syntax'] ) {
726
  $this->_esiTag = array( 'include' => 'esi_include', 'inline' => 'esi_inline', 'remove' => 'esi_remove' ) ;
727
  }
730
  }
731
  $allowedIps = trim($test[self::CFG_ALLOWEDIPS]) ;
732
  $this->_conf[self::CFG_ALLOWEDIPS] = $allowedIps ? preg_split($pattern, $allowedIps, null, PREG_SPLIT_NO_EMPTY) : '' ;
733
+ $this->_conf[self::CFG_FLUSH_PRODCAT] = isset($general[self::CFG_FLUSH_PRODCAT]) ? $general[self::CFG_FLUSH_PRODCAT] : 0 ; // for upgrade, maynot save in config
734
  }
735
  }
736
 
742
  return $node->asCanonicalArray() ;
743
  }
744
 
745
+ public function useInternalCache()
746
+ {
747
+ if ( ! isset($this->_conf['useInternalCache']) ) {
748
+ $this->_conf['useInternalCache'] = Mage::app()->useCache('layout') ;
749
+ }
750
+ return $this->_conf['useInternalCache'] ;
751
+ }
752
+
753
+ public function saveInternalCache( $data, $id, $tags = array() )
754
+ {
755
+ $tags[] = self::LITEMAGE_GENERAL_CACHE_TAG ;
756
+ Mage::app()->saveCache($data, $id, $tags, null) ;
757
+ }
758
+
759
  public function debugMesg( $mesg )
760
  {
761
  if ( $this->_isDebug ) {
app/code/community/Litespeed/Litemage/Helper/Esi.php CHANGED
@@ -48,9 +48,11 @@ class Litespeed_Litemage_Helper_Esi
48
  const FORMKEY_REPLACE = 'litemagefmkeylmg' ; //do not use special characters, maybe changed by urlencode
49
  const FORMKEY_NAME = '_form_key' ;
50
 
 
 
51
  // config items
52
  protected $_viewedTracker ;
53
- protected $_cacheVars = array( 'tag' => array(), 'flag' => 0, 'ttl' => -1, 'env' => array(), 'cookie' => array(), 'baseUrl' => '', 'baseUrlESI' => '' ) ;
54
  protected $_esiLayoutCache ;
55
  protected $_esiPurgeEvents = array() ;
56
  protected $_defaultEnvVaryCookie = '_lscache_vary'; // system default
@@ -128,7 +130,6 @@ class Litespeed_Litemage_Helper_Esi
128
  return $url;
129
  }
130
 
131
-
132
  public function canInjectEsi()
133
  {
134
  $flag = $this->_cacheVars['flag'] ;
@@ -158,13 +159,22 @@ class Litespeed_Litemage_Helper_Esi
158
  {
159
  if ( ($this->_cacheVars['flag'] & self::CHBM_FORMKEY_REPLACED) != 0 ) {
160
  $session = Mage::getSingleton('core/session') ;
161
- if ( ($realFormKey = $session->getData(self::FORMKEY_REAL)) != NULL ) {
162
  $session->unsetData(self::FORMKEY_REAL) ;
163
  $session->setData(self::FORMKEY_NAME, $realFormKey) ;
164
  }
165
  }
166
  }
167
 
 
 
 
 
 
 
 
 
 
168
  public function addPrivatePurgeEvent( $eventName )
169
  {
170
  // always set purge header, due to ajax call, before_reponse_send will not be triggered, also it may die out in the middle, so must set raw header using php directly
@@ -183,7 +193,7 @@ class Litespeed_Litemage_Helper_Esi
183
  protected function _getEsiPurgeTags()
184
  {
185
  if ( count($this->_esiPurgeEvents) == 0 )
186
- return NULL ;
187
 
188
  $events = $this->_config->getEsiConf('event');
189
  $tags = array() ;
@@ -201,7 +211,7 @@ class Litespeed_Litemage_Helper_Esi
201
  $this->_config->debugMesg('Purge events ' . implode(', ', $this->_esiPurgeEvents) . ' tags: ' . implode(', ', $tags));
202
  }
203
 
204
- return (count($tags) ? $tags : NULL) ;
205
  }
206
 
207
  protected function _getPurgeHeaderValue($tags, $isPrivate)
@@ -212,21 +222,26 @@ class Litespeed_Litemage_Helper_Esi
212
  $t .= ( $tag == '*' ) ? '*' : 'tag=' . $tag . ',' ;
213
  }
214
  $purgeHeader .= trim($t, ',');
 
 
 
 
 
215
  return $purgeHeader;
216
  }
217
 
218
- public function setPurgeHeader( $tags, $by, $response = NULL, $isPrivate = false )
219
  {
220
  $purgeHeader = $this->_getPurgeHeaderValue($tags, $isPrivate);
221
 
222
- if ( $response == NULL ) {
223
  $response = Mage::app()->getResponse() ;
224
  }
 
225
 
226
- if ($this->_isDebug) {
227
  $this->_config->debugMesg("SetPurgeHeader: " . $purgeHeader . ' (triggered by ' . $by . ')') ;
228
  }
229
- $response->setHeader(self::LSHEADER_PURGE, $purgeHeader, true) ;
230
  }
231
 
232
  public function setPurgeURLHeader( $url, $by )
@@ -251,7 +266,7 @@ class Litespeed_Litemage_Helper_Esi
251
 
252
  public function trackProduct( $productId )
253
  {
254
- if ( $this->_viewedTracker == NULL )
255
  $this->_viewedTracker = array( 'product' => $productId ) ;
256
  else
257
  $this->_viewedTracker['product'] = $productId ;
@@ -274,7 +289,6 @@ class Litespeed_Litemage_Helper_Esi
274
  return $html;
275
  }
276
 
277
-
278
  protected function _initEsiLayoutCache( $block )
279
  {
280
  /*
@@ -366,7 +380,7 @@ class Litespeed_Litemage_Helper_Esi
366
  $blockIndex = array();
367
  $blockName = $block->getNameInLayout();
368
 
369
- if ($layout->getBlock($blockName) != $block) {
370
  $alias = $block->getBlockAlias();
371
  if ($alias != '' && $alias != $blockName) {
372
  $blockName .= ',' . $alias;
@@ -397,7 +411,7 @@ class Litespeed_Litemage_Helper_Esi
397
 
398
  protected function _getChildrenNames( $block, $layout )
399
  {
400
- if ($block == NULL) {
401
  return array();
402
  }
403
 
@@ -419,9 +433,9 @@ class Litespeed_Litemage_Helper_Esi
419
 
420
  protected function _refreshEsiBlockCache()
421
  {
422
- if ($this->_esiLayoutCache['adjusted'] && Mage::app()->useCache('layout')) {
423
- $tags = array(Litespeed_Litemage_Helper_Data::LITEMAGE_GENERAL_CACHE_TAG, Mage_Core_Model_Layout_Update::LAYOUT_GENERAL_CACHE_TAG);
424
- Mage::app()->saveCache(serialize($this->_esiLayoutCache['blocks']), $this->_esiLayoutCache['cacheId'], $tags) ;
425
  $this->_esiLayoutCache['adjusted'] = false;
426
  }
427
  }
@@ -431,17 +445,20 @@ class Litespeed_Litemage_Helper_Esi
431
  $this->_refreshEsiBlockCache();
432
 
433
  $extraHeaders = array();
434
- $envChanged = $this->setEnvCookie();
435
 
436
  $cacheControlHeader = '' ;
437
  $flag = $this->_cacheVars['flag'] ;
438
  $cacheable = true;
 
 
439
 
440
  if ( (($flag & self::CHBM_CACHEABLE) == 0)
441
- || $envChanged
442
  || Mage::registry('LITEMAGE_SHOWHOLES')
443
  || Mage::registry('LITEMAGE_PURGE')
444
- || !in_array($response->getHttpResponseCode(), array( 200, 301, 404 ))) {
 
445
  $cacheable = false;
446
  }
447
 
@@ -472,7 +489,7 @@ class Litespeed_Litemage_Helper_Esi
472
  if ((($flag & self::CHBM_ESI_REQ) == 0) // for non-esi request
473
  && ((($flag & self::CHBM_ESI_ON) != 0) // esi on
474
  || (($flag & self::CHBM_FORMKEY_REPLACED) != 0) // formkey replaced
475
- || ($this->_viewedTracker != NULL))) { // has view tracker
476
  $this->_updateResponseBody($response) ;
477
  }
478
 
@@ -486,7 +503,7 @@ class Litespeed_Litemage_Helper_Esi
486
  $extraHeaders[self::LSHEADER_CACHE_CONTROL] = $cacheControlHeader;
487
  }
488
 
489
- // due to ajax, move purge header when event happens, so already purged
490
  if (Mage::registry('LITEMAGE_PURGE')) {
491
  $extraHeaders[self::LSHEADER_PURGE] = $this->_getPurgeCacheTags();
492
  }
@@ -523,7 +540,17 @@ class Litespeed_Litemage_Helper_Esi
523
  $updated = true ;
524
  }
525
 
526
- if ( $this->_viewedTracker != NULL ) {
 
 
 
 
 
 
 
 
 
 
527
  $logOptions = $this->_viewedTracker;
528
  $logOptions['s'] = $sharedParams['s'];
529
  // no need to use comment, will be removed by minify extensions
@@ -558,7 +585,7 @@ class Litespeed_Litemage_Helper_Esi
558
  }
559
  else {
560
  $response->setBody($combined . $tracker . $responseBody) ;
561
- if ($this->_isDebug) {
562
  $this->_config->debugMesg('_updateResponseBody failed to insert combined after <body>');
563
  }
564
  }
@@ -572,33 +599,334 @@ class Litespeed_Litemage_Helper_Esi
572
  if ($notEsiReq) {
573
  if ( count($tags) == 0 ) {
574
  // set tag for product id, cid, and pageid
575
- if ( ($curProduct = Mage::registry('current_product')) != NULL ) {
576
  $tags[] = self::TAG_PREFIX_PRODUCT . $curProduct->getId() ;
577
  }
578
- elseif ( ($curCategory = Mage::registry('current_category')) != NULL ) {
579
  $tags[] = self::TAG_PREFIX_CATEGORY . $curCategory->getId() ;
580
  }
581
  }
582
 
583
- $currStore = Mage::app()->getStore() ;
584
- if ($currStore->getCurrentCurrencyCode() != $currStore->getBaseCurrencyCode()) {
585
  $tags[] = 'CURR'; // will be purged by currency rate update event
586
  }
 
 
 
 
 
587
  }
588
 
589
  $tag = count($tags) ? implode(',', $tags) : '' ;
590
  return $tag ;
591
  }
592
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
593
  protected function _getPurgeCacheTags()
594
  {
595
  $tags = $this->_cacheVars['tag'] ;
596
  if (empty($tags)) {
597
  // set tag for product id, cid, and pageid
598
- if ( ($curProduct = Mage::registry('current_product')) != NULL ) {
599
  $tags[] = self::TAG_PREFIX_PRODUCT . $curProduct->getId() ;
600
  }
601
- elseif ( ($curCategory = Mage::registry('current_category')) != NULL ) {
602
  $tags[] = self::TAG_PREFIX_CATEGORY . $curCategory->getId() ;
603
  }
604
  else {
@@ -610,6 +938,9 @@ class Litespeed_Litemage_Helper_Esi
610
  $tags[] = $uri;
611
  }
612
  }
 
 
 
613
  $tag = count($tags) ? implode(',', $tags) : '' ;
614
  return $tag ;
615
  }
@@ -621,7 +952,7 @@ class Litespeed_Litemage_Helper_Esi
621
  foreach ($this->_cacheVars['env'] as $name => $data) {
622
  $newVal = '';
623
  $oldVal = '';
624
- if ($data != NULL) {
625
  ksort($data); // data is array, key sorted
626
  foreach ($data as $k => $v) {
627
  $newVal .= $k . '~' . $v . '~';
@@ -639,7 +970,6 @@ class Litespeed_Litemage_Helper_Esi
639
  }
640
  }
641
  return $changed;
642
-
643
  }
644
 
645
  protected function _getCacheVaryOn()
@@ -657,44 +987,63 @@ class Litespeed_Litemage_Helper_Esi
657
  case 1: return $vary_on[0];
658
  default: return implode(',', $vary_on);
659
  }
660
-
661
  }
662
 
663
  public function setDefaultEnvCookie()
664
  {
665
  // when calling set, always reset, as value may change during processing
 
 
 
 
 
 
666
  $default = array() ;
667
- $app = Mage::app() ;
668
- $currStore = $app->getStore() ;
669
- $currStoreId = $currStore->getId() ;
670
- $currStoreCurrency = $currStore->getCurrentCurrencyCode() ;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
671
  $currStoreDefaultCurrency = $currStore->getDefaultCurrencyCode() ;
672
 
673
  if ($currStoreCurrency != $currStoreDefaultCurrency) {
674
- $default['curr'] = $currStoreCurrency ;
675
- }
676
 
677
- if ( $currStore->getWebsite()->getDefaultStore()->getId() != $currStoreId ) {
678
- $default['st'] = intval($currStoreId) ;
679
- }
680
- if ($diffGrp = $this->_config->getConf(Litespeed_Litemage_Helper_Data::CFG_DIFFCUSTGRP)) {
681
- // diff cache copy peer customer group
682
- $currCustomerGroup = Mage::getSingleton('customer/session')->getCustomerGroupId() ;
683
- if ( Mage_Customer_Model_Group::NOT_LOGGED_IN_ID != $currCustomerGroup ) {
684
- if ($diffGrp == 1) // diff copy per group
685
- $default['cgrp'] = $currCustomerGroup ;
686
- else // diff copy for logged in user
687
- $default['cgrp'] = 'in' ;
688
- }
689
- }
690
- if ($this->_config->isRestrainedIP()) {
691
- $default['dev'] = 1; //developer mode for restrained IP
692
- }
693
 
694
- $this->_cacheVars['env'][$this->_defaultEnvVaryCookie] = count($default) > 0 ? $default : NULL ;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
695
  }
696
 
697
-
698
  public function getDefaultEnvCookie()
699
  {
700
  if ( ! isset($this->_cacheVars['env'][$this->_defaultEnvVaryCookie]) ) {
@@ -738,13 +1087,19 @@ class Litespeed_Litemage_Helper_Esi
738
  public function getCookieEnvVars( $cookieName )
739
  {
740
  if ( ! isset($this->_cacheVars['cookie'][$cookieName]) ) {
741
- $this->_cacheVars['cookie'][$cookieName] = NULL ;
742
  $cookieVal = Mage::getSingleton('core/cookie')->get($cookieName) ;
743
- if ( $cookieVal != NULL ) {
744
  $cv = explode('~', trim($cookieVal, '~')); // restore cookie value
745
- for ($i = 0 ; $i < count($cv) ; $i += 2) {
746
- $this->_cacheVars['cookie'][$cookieName][$cv[$i]] = $cv[$i+1];
747
- }
 
 
 
 
 
 
748
 
749
  $this->_cacheVars['cookie'][$cookieName]['_ORG_'] = $cookieVal ;
750
  }
@@ -754,7 +1109,7 @@ class Litespeed_Litemage_Helper_Esi
754
 
755
  public function addEnvVars($cookieName, $key='', $val='' )
756
  {
757
- if ( ! isset($this->_cacheVars['env'][$cookieName]) || ($this->_cacheVars['env'][$cookieName] == NULL) ) {
758
  $this->_cacheVars['env'][$cookieName] = array() ;
759
  }
760
  if ($key != '') {
@@ -762,4 +1117,15 @@ class Litespeed_Litemage_Helper_Esi
762
  }
763
  }
764
 
 
 
 
 
 
 
 
 
 
 
 
765
  }
48
  const FORMKEY_REPLACE = 'litemagefmkeylmg' ; //do not use special characters, maybe changed by urlencode
49
  const FORMKEY_NAME = '_form_key' ;
50
 
51
+ const NICKNAME_REPLACE = 'litemagenicknamelmg' ; //do not use special characters, maybe changed by urlencode
52
+
53
  // config items
54
  protected $_viewedTracker ;
55
+ protected $_cacheVars = array( 'tag' => array(), 'flag' => 0, 'ttl' => -1, 'env' => array(), 'internal' => array(), 'cookie' => array(), 'baseUrl' => '', 'baseUrlESI' => '' ) ;
56
  protected $_esiLayoutCache ;
57
  protected $_esiPurgeEvents = array() ;
58
  protected $_defaultEnvVaryCookie = '_lscache_vary'; // system default
130
  return $url;
131
  }
132
 
 
133
  public function canInjectEsi()
134
  {
135
  $flag = $this->_cacheVars['flag'] ;
159
  {
160
  if ( ($this->_cacheVars['flag'] & self::CHBM_FORMKEY_REPLACED) != 0 ) {
161
  $session = Mage::getSingleton('core/session') ;
162
+ if ( ($realFormKey = $session->getData(self::FORMKEY_REAL)) != null ) {
163
  $session->unsetData(self::FORMKEY_REAL) ;
164
  $session->setData(self::FORMKEY_NAME, $realFormKey) ;
165
  }
166
  }
167
  }
168
 
169
+ // $block instanceof Mage_Review_Block_Form
170
+ public function initNickName($block)
171
+ {
172
+ $data = new Varien_Object();
173
+ $data->setNickname(self::NICKNAME_REPLACE);
174
+ $block->assign('data', $data);
175
+ $this->_cacheVars['internal']['nickname'] = 1; // replaced
176
+ }
177
+
178
  public function addPrivatePurgeEvent( $eventName )
179
  {
180
  // always set purge header, due to ajax call, before_reponse_send will not be triggered, also it may die out in the middle, so must set raw header using php directly
193
  protected function _getEsiPurgeTags()
194
  {
195
  if ( count($this->_esiPurgeEvents) == 0 )
196
+ return null ;
197
 
198
  $events = $this->_config->getEsiConf('event');
199
  $tags = array() ;
211
  $this->_config->debugMesg('Purge events ' . implode(', ', $this->_esiPurgeEvents) . ' tags: ' . implode(', ', $tags));
212
  }
213
 
214
+ return (count($tags) ? $tags : null) ;
215
  }
216
 
217
  protected function _getPurgeHeaderValue($tags, $isPrivate)
222
  $t .= ( $tag == '*' ) ? '*' : 'tag=' . $tag . ',' ;
223
  }
224
  $purgeHeader .= trim($t, ',');
225
+
226
+ if (!$isPrivate ) {
227
+ $this->_addDeltaByTags($tags);
228
+ }
229
+
230
  return $purgeHeader;
231
  }
232
 
233
+ public function setPurgeHeader( $tags, $by, $response = null, $isPrivate = false )
234
  {
235
  $purgeHeader = $this->_getPurgeHeaderValue($tags, $isPrivate);
236
 
237
+ if ( $response == null ) {
238
  $response = Mage::app()->getResponse() ;
239
  }
240
+ $response->setHeader(self::LSHEADER_PURGE, $purgeHeader, true) ;
241
 
242
+ if ($this->_isDebug) {
243
  $this->_config->debugMesg("SetPurgeHeader: " . $purgeHeader . ' (triggered by ' . $by . ')') ;
244
  }
 
245
  }
246
 
247
  public function setPurgeURLHeader( $url, $by )
266
 
267
  public function trackProduct( $productId )
268
  {
269
+ if ( $this->_viewedTracker == null )
270
  $this->_viewedTracker = array( 'product' => $productId ) ;
271
  else
272
  $this->_viewedTracker['product'] = $productId ;
289
  return $html;
290
  }
291
 
 
292
  protected function _initEsiLayoutCache( $block )
293
  {
294
  /*
380
  $blockIndex = array();
381
  $blockName = $block->getNameInLayout();
382
 
383
+ if ($layout->getBlock($blockName) !== $block) {
384
  $alias = $block->getBlockAlias();
385
  if ($alias != '' && $alias != $blockName) {
386
  $blockName .= ',' . $alias;
411
 
412
  protected function _getChildrenNames( $block, $layout )
413
  {
414
+ if ($block == null) {
415
  return array();
416
  }
417
 
433
 
434
  protected function _refreshEsiBlockCache()
435
  {
436
+ if ($this->_esiLayoutCache['adjusted'] && $this->_config->useInternalCache()) {
437
+ $tags = array(Mage_Core_Model_Layout_Update::LAYOUT_GENERAL_CACHE_TAG);
438
+ $this->_config->saveInternalCache(serialize($this->_esiLayoutCache['blocks']), $this->_esiLayoutCache['cacheId'], $tags) ;
439
  $this->_esiLayoutCache['adjusted'] = false;
440
  }
441
  }
445
  $this->_refreshEsiBlockCache();
446
 
447
  $extraHeaders = array();
448
+ $envChanged = $this->setEnvCookie(); // envChanged, need to set even when not cacheable (like currency change), need to above other things.
449
 
450
  $cacheControlHeader = '' ;
451
  $flag = $this->_cacheVars['flag'] ;
452
  $cacheable = true;
453
+ $responseCode = $response->getHttpResponseCode();
454
+ $this->_cacheVars['internal']['response_code'] = $responseCode;
455
 
456
  if ( (($flag & self::CHBM_CACHEABLE) == 0)
457
+ || $envChanged
458
  || Mage::registry('LITEMAGE_SHOWHOLES')
459
  || Mage::registry('LITEMAGE_PURGE')
460
+ || !in_array($responseCode, array( 200, 301, 404 ))
461
+ ) {
462
  $cacheable = false;
463
  }
464
 
489
  if ((($flag & self::CHBM_ESI_REQ) == 0) // for non-esi request
490
  && ((($flag & self::CHBM_ESI_ON) != 0) // esi on
491
  || (($flag & self::CHBM_FORMKEY_REPLACED) != 0) // formkey replaced
492
+ || ($this->_viewedTracker != null))) { // has view tracker
493
  $this->_updateResponseBody($response) ;
494
  }
495
 
503
  $extraHeaders[self::LSHEADER_CACHE_CONTROL] = $cacheControlHeader;
504
  }
505
 
506
+ // due to ajax, move purge header when event happens, so already purged, here's for LITEMAGE_CTRL=PURGE
507
  if (Mage::registry('LITEMAGE_PURGE')) {
508
  $extraHeaders[self::LSHEADER_PURGE] = $this->_getPurgeCacheTags();
509
  }
540
  $updated = true ;
541
  }
542
 
543
+ if ( isset($this->_cacheVars['internal']['nickname']) && strpos($responseBody, self::NICKNAME_REPLACE)) {
544
+ // use single quote for pagespeed module
545
+ $replace = '<' . $esiIncludeTag . " src='" . $this->getEsiBaseUrl() . "litemage/esi/getNickName' combine='sub' cache-control='no-vary,private' cache-tag='E.welcome'/>" ;
546
+ $responseBody = str_replace(self::NICKNAME_REPLACE, $replace, $responseBody) ;
547
+ if ($this->_isDebug) {
548
+ $this->_config->debugMesg('Nickname replaced as ' . $replace);
549
+ }
550
+ $updated = true ;
551
+ }
552
+
553
+ if ( $this->_viewedTracker != null ) {
554
  $logOptions = $this->_viewedTracker;
555
  $logOptions['s'] = $sharedParams['s'];
556
  // no need to use comment, will be removed by minify extensions
585
  }
586
  else {
587
  $response->setBody($combined . $tracker . $responseBody) ;
588
+ if ($this->_isDebug && !Mage::app()->getRequest()->isAjax()) {
589
  $this->_config->debugMesg('_updateResponseBody failed to insert combined after <body>');
590
  }
591
  }
599
  if ($notEsiReq) {
600
  if ( count($tags) == 0 ) {
601
  // set tag for product id, cid, and pageid
602
+ if ( ($curProduct = Mage::registry('current_product')) != null ) {
603
  $tags[] = self::TAG_PREFIX_PRODUCT . $curProduct->getId() ;
604
  }
605
+ elseif ( ($curCategory = Mage::registry('current_category')) != null ) {
606
  $tags[] = self::TAG_PREFIX_CATEGORY . $curCategory->getId() ;
607
  }
608
  }
609
 
610
+ $curStore = Mage::app()->getStore() ;
611
+ if ($curStore->getCurrentCurrencyCode() != $curStore->getBaseCurrencyCode()) {
612
  $tags[] = 'CURR'; // will be purged by currency rate update event
613
  }
614
+
615
+ $debugMesg = $this->_autoCollectUrls($curStore->getId(), $tags);
616
+ if ($this->_isDebug && $debugMesg) {
617
+ $this->_config->debugMesg('_autoCollectUrls: ' . $debugMesg);
618
+ }
619
  }
620
 
621
  $tag = count($tags) ? implode(',', $tags) : '' ;
622
  return $tag ;
623
  }
624
 
625
+ public function setInternal($data)
626
+ {
627
+ foreach ($data as $key => $value) {
628
+ $this->_cacheVars['internal'][$key] = $value;
629
+ }
630
+ // avail key route_info, cron(1), response_code, url, nickname
631
+ }
632
+
633
+ protected function _autoCollectUrls($storeId, $tags)
634
+ {
635
+ $dbgMsg = '';
636
+ if (!$this->_config->useInternalCache())
637
+ return $dbgMsg;
638
+
639
+ $conf = $this->_config->getAutoCollectConf($storeId);
640
+ // array('collect' => 0, 'crawlDelta' => 0, 'crawlAuto' => 0, 'frame' => 0, 'remove' => 0, 'deep' => 0, 'deltaDeep' => 0, 'countRobot'=>1) ;
641
+
642
+ if ($conf['collect'] == 0 && $conf['crawlDelta'] == 0)
643
+ return $dbgMsg;
644
+
645
+ $url = $this->_cacheVars['internal']['url'];
646
+ $level = 0;
647
+ if (!empty($_SERVER['QUERY_STRING'])) {
648
+ $level = substr_count($_SERVER['QUERY_STRING'], '&') + 1;
649
+ }
650
+
651
+ $dbgMsg = $url;
652
+ $cronLabel = '';
653
+
654
+ if (isset($this->_cacheVars['internal']['cron'])) {
655
+ $cronLabel = $this->_cacheVars['internal']['cron'];//substr($this->_cacheVars['internal']['cron'], 0, 1); // s|c|a|d
656
+ }
657
+
658
+ if ( $this->_cacheVars['internal']['response_code'] != 200 ) {
659
+ if ($cronLabel)
660
+ $dbgMsg .= $this->_removeBadUrl($cronLabel, $url, $storeId, $level, $conf['crawlAuto']);
661
+ return $dbgMsg;
662
+ }
663
+
664
+ if ( $level > max($conf['deep'], $conf['deltaDeep'])) {
665
+ $dbgMsg .= ' depth ' . $level . ' over limit ';
666
+ return $dbgMsg;
667
+ }
668
+
669
+ $isRobot = $this->isRobot();
670
+ // only collect those are referred (allow internal & external) if has query string to avoid manually typed
671
+ if ($level && !$cronLabel && !$isRobot && !isset($_SERVER['HTTP_REFERER'])) {
672
+ $dbgMsg .= ' is not robot, has query string, no referer, ignored';
673
+ return $dbgMsg;
674
+ }
675
+
676
+ $tag = '';
677
+ foreach($tags as $t) {
678
+ if ((strpos($t, self::TAG_PREFIX_PRODUCT) !== false)
679
+ || (strpos($t, self::TAG_PREFIX_CATEGORY) !== false)
680
+ || (strpos($t, self::TAG_PREFIX_CMS) !== false)) {
681
+ $tag = $t;
682
+ break;
683
+ }
684
+ }
685
+
686
+ if (!$tag) {
687
+ $tag = $this->_cacheVars['internal']['route_info'];
688
+ }
689
+
690
+ $attr = 0; // BitMask 1: user, 2: robot, 4: cron_store, 8: cron_cust, 16: cron_auto, 32: is_ajax,
691
+ if ($isRobot) {
692
+ $attr |= 2;
693
+ }
694
+ elseif ($cronLabel ) {
695
+ switch ($cronLabel{0}) {
696
+ case 's': $attr |= 4; break;
697
+ case 'c': $attr |= 8; break;
698
+ case 'a': $attr |= 16; break;
699
+ }
700
+ }
701
+ else {
702
+ $attr |= 1;
703
+ }
704
+ if ($this->_cacheVars['internal']['is_ajax']) {
705
+ $attr |= 32;
706
+ }
707
+
708
+ // 2. load tags cache
709
+ $cacheId = 'LITEMAGE_AUTOURL_' . $tag;
710
+ $updated = false;
711
+ $now = time() - date('Z') ;
712
+
713
+ $tagUrls = null;
714
+ if ( $result = Mage::app()->loadCache($cacheId) ) {
715
+ $tagUrls = unserialize($result) ;
716
+ }
717
+
718
+ if (!$tagUrls) { // no cache or cache bad
719
+ $tagUrls = array();
720
+ $updated = true;
721
+ }
722
+
723
+ if (!isset($tagUrls[$storeId])) {
724
+ $tagUrls[$storeId] = array('utctime' => array($now, $now)); // utctime 0:inittime; 1:updatetime
725
+ $updated = true;
726
+ }
727
+ else {
728
+ // maintain level
729
+ foreach (array_keys($tagUrls[$storeId]) as $k ) {
730
+ if (is_int($k) && $k > $conf['deep'] && $k > $conf['deltaDeep']) {
731
+ $dbgMsg .= ' found old saved level=' . $k . ' higher than defined, clean up ';
732
+ unset($tagUrls[$storeId][$k]);
733
+ $updated = true;
734
+ }
735
+ }
736
+ }
737
+ $tagInitTime = $tagUrls[$storeId]['utctime'][0];
738
+
739
+ if (!isset($tagUrls[$storeId][$level])) {
740
+ $tagUrls[$storeId][$level] = array();
741
+ $updated = true;
742
+ }
743
+
744
+ if (!isset($tagUrls[$storeId][$level][$url])) {
745
+ $tagUrls[$storeId][$level][$url] = array(0, $attr); // 0:visitor count, 1: attr
746
+ $updated = true;
747
+ }
748
+
749
+ $tagUrl = &$tagUrls[$storeId][$level][$url];
750
+ $dbgMsg .= ' attr=' . $attr . ' level=' . $level;
751
+
752
+ if ($conf['collect']) {
753
+ if ((($attr & 1) == 1) || ($conf['countRobot'] && (($attr & 2) == 2))) {
754
+ $tagUrl[0] ++;
755
+ $updated = true;
756
+ }
757
+ if (($attr & $tagUrl[1]) != $attr ) {
758
+ $tagUrl[1] |= $attr;
759
+ $updated = true;
760
+ }
761
+
762
+ if (($now - $tagInitTime) > $conf['frame']) {
763
+ // window is over
764
+ $dbgMsg .= $this->_adjustAutoWarmupList($storeId, $tag, $tagInitTime);
765
+ }
766
+ elseif (($tagUrl[0] >= $conf['collect']) && (($tagUrl[1] & 28) == 0)) {
767
+ // not over the time limit, not seeing from cron, possible candidate to add, whether already in autolist will be determinted by cron
768
+ $isAjax = (($tagUrl[1] & 32) > 0);
769
+ $dbgMsg .= $this->_adjustAutoWarmupList($storeId, $tag, $tagInitTime, $url, ($isAjax? 2:1));
770
+ }
771
+
772
+ // put add/removal in cron, here only update attr
773
+ }
774
+
775
+ if ($updated) {
776
+ $tagUrls[$storeId]['utctime'][1] = $now;
777
+ $this->_config->saveInternalCache(serialize($tagUrls), $cacheId) ;
778
+ $dbgMsg .= ' tag cache updated ';
779
+ }
780
+
781
+ return $dbgMsg;
782
+ }
783
+
784
+ protected function _removeBadUrl($cronLabel, $url, $storeId, $level, $crawlAuto)
785
+ {
786
+ $dbgMesg = ' in _removeBadUrl ';
787
+ $type = $cronLabel{0};
788
+ if ($type != 'a' && $type != 'd') {
789
+ $dbgMesg .= ' not from auto or delta, ignore. ';
790
+ return $dbgMesg;
791
+ }
792
+ $pos = strpos($cronLabel, ':');
793
+ if (!$pos) {
794
+ $dbgMesg .= ' no cron tag: found, ignore. ';
795
+ return $dbgMesg;
796
+ }
797
+ // tag needs to retrieve from cronlabel, not from current req
798
+ $tag = substr($cronLabel, $pos + 1);
799
+ if (!$tag) {
800
+ $dbgMesg .= ' no cron tag found, ignore. ';
801
+ return $dbgMesg;
802
+ }
803
+
804
+ $cacheId = 'LITEMAGE_AUTOURL_' . $tag;
805
+ $attr = 0;
806
+ if ( $result = Mage::app()->loadCache($cacheId) ) {
807
+ $tagUrls = unserialize($result) ;
808
+ if (isset($tagUrls[$storeId][$level][$url])) {
809
+ $attr = $tagUrls[$storeId][$level][$url][1];
810
+ unset($tagUrls[$storeId][$level][$url]);
811
+ $this->_config->saveInternalCache(serialize($tagUrls), $cacheId) ;
812
+ $dbgMesg .= ' removed from tag cache ' . $tag ;
813
+ }
814
+ }
815
+ if ($crawlAuto && ($type == 'a' || ($type == 'd' && ($attr & 16)))) { // in autolist, remove
816
+ $dbgMesg .= $this->_adjustAutoWarmupList($storeId, $tag, $url, -1);
817
+ }
818
+ return $dbgMesg;
819
+ }
820
+
821
+ // action: -1 (remove) 1 (add regular) 2 (add ajax)
822
+ protected function _adjustAutoWarmupList($storeId, $tag, $tagInitTime, $url='', $action='')
823
+ {
824
+ $cacheId = 'LITEMAGE_AUTOURL_ADJ_S' . $storeId;
825
+ $pending = null;
826
+ $now = time() - date('Z');
827
+ $dbgMesg = ' _adjustAutoWarmupList for ' . $tag;
828
+ if ( $result = Mage::app()->loadCache($cacheId) ) {
829
+ $pending = unserialize($result) ;
830
+ }
831
+ if (!$pending) {
832
+ // [utctime] = [inittime, updatetime]
833
+ // [tag][0] = 0|1 -- full check
834
+ // [1][url] = 1/-1 -- url check AddReg(1) AddAjax(2) Remove(-1)
835
+ $pending = array('utctime' => array($now, $now));
836
+ $dbgMesg .= ' no existing list, start new. ';
837
+ }
838
+
839
+ if (!isset($pending[$tag])) {
840
+ $pending[$tag] = array(0 => 0, 't' => $tagInitTime);
841
+ }
842
+ elseif ($pending[$tag][0]) {
843
+ // already full check
844
+ $dbgMesg .= ' already in pending full check, ignore. ';
845
+ return $dbgMesg;
846
+ }
847
+
848
+ if ($url == '') {
849
+ $pending[$tag][0] = 1;
850
+ $dbgMesg .= ' window is over, doing full check. ';
851
+
852
+ if (isset($pending[$tag][1])) {
853
+ unset($pending[$tag][1]);
854
+ $dbgMesg .= ' reset previous single url check. ';
855
+ }
856
+ }
857
+ else {
858
+ if (!isset($pending[$tag][1])) {
859
+ $pending[$tag][1] = array($url => $action);
860
+ }
861
+ elseif (isset($pending[$tag][1][$url]) && $pending[$tag][1][$url] == $action) {
862
+ $dbgMesg .= ' already in pending url check, ignore. ';
863
+ return $dbgMesg;
864
+ }
865
+ else {
866
+ $pending[$tag][1][$url] = $action;
867
+ }
868
+ $dbgMesg .= ' add single url check ' . $action;
869
+ }
870
+ $pending['utctime'][1] = $now; // updated time
871
+ $this->_config->saveInternalCache(serialize($pending), $cacheId) ;
872
+ return $dbgMesg;
873
+ }
874
+
875
+ protected function _addDeltaByTags($tags)
876
+ {
877
+ if (!$this->_config->useInternalCache() || !$this->_config->needAddDeltaTags())
878
+ return;
879
+
880
+ $cacheId = Litespeed_Litemage_Helper_Data::LITEMAGE_DELTA_CACHE_ID ;
881
+
882
+ $updated = 1; // 0: no update; 1: reinit; 2: append
883
+
884
+ if (in_array('*', $tags)) {
885
+ $tags = array();
886
+ }
887
+ elseif ($result = Mage::app()->loadCache($cacheId)) {
888
+ $data = unserialize($result) ;
889
+ if (is_array($data) && isset($data['time']) && isset($data['tags'])) {
890
+ $updated = 0;
891
+ $extra = array();
892
+ foreach ($tags as $tag) {
893
+ if (!in_array($tag, $data['tags'])) {
894
+ $data['tags'][] = $tag;
895
+ $extra[] = $tag;
896
+ $updated = 2;
897
+ }
898
+ }
899
+ }
900
+ }
901
+
902
+ if ($updated) {
903
+ if ($updated == 1) {
904
+ $data = array('time' => microtime(), 'tags' => $tags);
905
+ }
906
+ $this->_config->saveInternalCache(serialize($data), $cacheId) ;
907
+ }
908
+
909
+ if ($this->_isDebug) {
910
+ if ($updated == 0)
911
+ $msg = 'Delta tags not added, already in pending list';
912
+ elseif ($updated == 1)
913
+ $msg = 'Reinit Delta queue [time=' . $data['time'] . '] tags=' . implode(',', $tags);
914
+ else
915
+ $msg = 'Delta queue [time=' . $data['time'] . '] appended tag ' . implode(',', $extra);
916
+
917
+ $this->_config->debugMesg($msg) ;
918
+ }
919
+ }
920
+
921
  protected function _getPurgeCacheTags()
922
  {
923
  $tags = $this->_cacheVars['tag'] ;
924
  if (empty($tags)) {
925
  // set tag for product id, cid, and pageid
926
+ if ( ($curProduct = Mage::registry('current_product')) != null ) {
927
  $tags[] = self::TAG_PREFIX_PRODUCT . $curProduct->getId() ;
928
  }
929
+ elseif ( ($curCategory = Mage::registry('current_category')) != null ) {
930
  $tags[] = self::TAG_PREFIX_CATEGORY . $curCategory->getId() ;
931
  }
932
  else {
938
  $tags[] = $uri;
939
  }
940
  }
941
+
942
+ $this->_addDeltaByTags($tags);
943
+
944
  $tag = count($tags) ? implode(',', $tags) : '' ;
945
  return $tag ;
946
  }
952
  foreach ($this->_cacheVars['env'] as $name => $data) {
953
  $newVal = '';
954
  $oldVal = '';
955
+ if ($data != null) {
956
  ksort($data); // data is array, key sorted
957
  foreach ($data as $k => $v) {
958
  $newVal .= $k . '~' . $v . '~';
970
  }
971
  }
972
  return $changed;
 
973
  }
974
 
975
  protected function _getCacheVaryOn()
987
  case 1: return $vary_on[0];
988
  default: return implode(',', $vary_on);
989
  }
 
990
  }
991
 
992
  public function setDefaultEnvCookie()
993
  {
994
  // when calling set, always reset, as value may change during processing
995
+ $default = $this->_getDefaultEnvCookieValue();
996
+ $this->_cacheVars['env'][$this->_defaultEnvVaryCookie] = count($default) > 0 ? $default : null ;
997
+ }
998
+
999
+ protected function _getDefaultEnvCookieValue()
1000
+ {
1001
  $default = array() ;
1002
+ $currStore = Mage::app()->getStore();
1003
+
1004
+ // check null to avoid error from soap api call
1005
+ if (!$currStore) {
1006
+ return $default;
1007
+ }
1008
+
1009
+ $website = $currStore->getWebsite();
1010
+ if (!$website) {
1011
+ return $default;
1012
+ }
1013
+
1014
+ $defaultStore = $website->getDefaultStore();
1015
+ if (!$defaultStore) {
1016
+ return $default;
1017
+ }
1018
+
1019
+ $currStoreId = $currStore->getId() ;
1020
+ $currStoreCurrency = $currStore->getCurrentCurrencyCode() ;
1021
  $currStoreDefaultCurrency = $currStore->getDefaultCurrencyCode() ;
1022
 
1023
  if ($currStoreCurrency != $currStoreDefaultCurrency) {
1024
+ $default['curr'] = $currStoreCurrency ;
1025
+ }
1026
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1027
 
1028
+ if ( $defaultStore->getId() != $currStoreId ) {
1029
+ $default['st'] = intval($currStoreId) ;
1030
+ }
1031
+ if ($diffGrp = $this->_config->getConf(Litespeed_Litemage_Helper_Data::CFG_DIFFCUSTGRP)) {
1032
+ // diff cache copy peer customer group
1033
+ $currCustomerGroup = Mage::getSingleton('customer/session')->getCustomerGroupId() ;
1034
+ if ( Mage_Customer_Model_Group::NOT_LOGGED_IN_ID != $currCustomerGroup ) {
1035
+ if ($diffGrp == 1) // diff copy per group
1036
+ $default['cgrp'] = $currCustomerGroup ;
1037
+ else // diff copy for logged in user
1038
+ $default['cgrp'] = 'in' ;
1039
+ }
1040
+ }
1041
+ if ($this->_config->isRestrainedIP()) {
1042
+ $default['dev'] = 1; //developer mode for restrained IP
1043
+ }
1044
+ return $default;
1045
  }
1046
 
 
1047
  public function getDefaultEnvCookie()
1048
  {
1049
  if ( ! isset($this->_cacheVars['env'][$this->_defaultEnvVaryCookie]) ) {
1087
  public function getCookieEnvVars( $cookieName )
1088
  {
1089
  if ( ! isset($this->_cacheVars['cookie'][$cookieName]) ) {
1090
+ $this->_cacheVars['cookie'][$cookieName] = null ;
1091
  $cookieVal = Mage::getSingleton('core/cookie')->get($cookieName) ;
1092
+ if ( $cookieVal != null ) {
1093
  $cv = explode('~', trim($cookieVal, '~')); // restore cookie value
1094
+ $num = count($cv);
1095
+ if (($num % 2) == 0) {
1096
+ for ($i = 0 ; $i < $num ; $i += 2) {
1097
+ $this->_cacheVars['cookie'][$cookieName][$cv[$i]] = $cv[$i+1];
1098
+ }
1099
+ }
1100
+ else if ($this->_isDebug) {
1101
+ $this->_config->debugMesg('Env Cookie value parse error ' . $cookieName . ' = ' . $cookieVal) ;
1102
+ }
1103
 
1104
  $this->_cacheVars['cookie'][$cookieName]['_ORG_'] = $cookieVal ;
1105
  }
1109
 
1110
  public function addEnvVars($cookieName, $key='', $val='' )
1111
  {
1112
+ if ( ! isset($this->_cacheVars['env'][$cookieName]) || ($this->_cacheVars['env'][$cookieName] == null) ) {
1113
  $this->_cacheVars['env'][$cookieName] = array() ;
1114
  }
1115
  if ($key != '') {
1117
  }
1118
  }
1119
 
1120
+ public function isRobot($userAgent = '')
1121
+ {
1122
+ // for auto collect, ignore robot visits, so don't have to be very accurate, cover common case is fine
1123
+ if ($userAgent == '') {
1124
+ $userAgent = Mage::helper('core/http')->getHttpUserAgent();
1125
+ }
1126
+ $ua = strtolower($userAgent);
1127
+ $isRobot = preg_match('/bot|slurp|spider|crawl|archiver/', $ua);
1128
+ return $isRobot;
1129
+ }
1130
+
1131
  }
app/code/community/Litespeed/Litemage/Helper/Viewvary.php CHANGED
@@ -26,10 +26,11 @@
26
  class Litespeed_Litemage_Helper_Viewvary
27
  {
28
 
29
- protected $_vary = array( 'toolbar' => '_adjustToolbar', 'env' => '_setEnv' ) ;
30
 
31
  public function persistViewVary( $tags )
32
  {
 
33
  foreach ( $tags as $tag ) {
34
  $func = $this->_vary[$tag] ;
35
  $this->$func(true) ;
@@ -52,6 +53,26 @@ class Litespeed_Litemage_Helper_Viewvary
52
  }
53
  }
54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  protected function _adjustToolbar( $isSave )
56
  {
57
  // for Mage_Catalog_Block_Product_List
26
  class Litespeed_Litemage_Helper_Viewvary
27
  {
28
 
29
+ protected $_vary = array( 'toolbar' => '_adjustToolbar', 'env' => '_setEnv', 'review' => '_checkReviewVary' ) ;
30
 
31
  public function persistViewVary( $tags )
32
  {
33
+ $tags = array_unique($tags);
34
  foreach ( $tags as $tag ) {
35
  $func = $this->_vary[$tag] ;
36
  $this->$func(true) ;
53
  }
54
  }
55
 
56
+ protected function _checkReviewVary($isSave)
57
+ {
58
+ if ($isSave) {
59
+ // only set if there's existing cookie
60
+ if (!Mage::helper('review')->getIsGuestAllowToWrite()) {
61
+ // only logged in allow to write review
62
+ if (0 == Mage::helper('litemage/data')->getConf(Litespeed_Litemage_Helper_Data::CFG_DIFFCUSTGRP)) {
63
+ // no seperate copy per user group, so need to distinguish here
64
+ $cookieName = '_lscache_vary_review' ;
65
+ if (Mage::getSingleton('customer/session')->isLoggedIn()) {
66
+ Mage::helper('litemage/esi')->addEnvVars($cookieName, 'write', '1') ;
67
+ }
68
+ else {
69
+ Mage::helper('litemage/esi')->addEnvVars($cookieName) ;
70
+ }
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
  protected function _adjustToolbar( $isSave )
77
  {
78
  // for Mage_Catalog_Block_Product_List
app/code/community/Litespeed/Litemage/Model/Config/Source/EnableDebugLog.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * LiteMage
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This program is free software: you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation, either version 3 of the License, or
10
+ * (at your option) any later version.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License
18
+ * along with this program. If not, see https://opensource.org/licenses/GPL-3.0 .
19
+ *
20
+ * @package LiteSpeed_LiteMage
21
+ * @copyright Copyright (c) 2016 LiteSpeed Technologies, Inc. (https://www.litespeedtech.com)
22
+ * @license https://opensource.org/licenses/GPL-3.0
23
+ */
24
+
25
+
26
+ class Litespeed_Litemage_Model_Config_Source_EnableDebugLog {
27
+ public function toOptionArray() {
28
+ $helper = Mage::helper('litemage/data');
29
+ return array(
30
+ array( 'value' => 0, 'label' => $helper->__( 'No' ) ),
31
+ array( 'value' => 1, 'label' => $helper->__( 'Yes' ) ),
32
+ array( 'value' => 2, 'label' => $helper->__( 'Only for defined Admin IPs' ) ),
33
+ );
34
+ }
35
+ }
app/code/community/Litespeed/Litemage/Model/Config/Source/EnableWarmUp.php CHANGED
@@ -23,13 +23,16 @@
23
  */
24
 
25
 
26
- class Litespeed_Litemage_Model_Config_Source_EnableWarmUp {
27
- public function toOptionArray() {
 
 
28
  $helper = Mage::helper('litemage/data');
29
  return array(
30
- array( 'value' => 1, 'label' => $helper->__( 'Yes' ) ),
31
- array( 'value' => 2, 'label' => $helper->__( 'Only for custom defined URL list' ) ),
32
- array( 'value' => 0, 'label' => $helper->__( 'No' ) ),
 
33
  );
34
  }
35
  }
23
  */
24
 
25
 
26
+ class Litespeed_Litemage_Model_Config_Source_EnableWarmUp
27
+ {
28
+ public function toOptionArray($isMultiselect)
29
+ {
30
  $helper = Mage::helper('litemage/data');
31
  return array(
32
+ array( 'value' => 1, 'label' => $helper->__( 'Store site map' ) ),
33
+ array( 'value' => 2, 'label' => $helper->__( 'Custom defined URL list' ) ),
34
+ array( 'value' => 4, 'label' => $helper->__( 'Auto collected (deep crawling) URL list' ) ),
35
+ array( 'value' => 8, 'label' => $helper->__( 'Delta list after tag purge' ) ),
36
  );
37
  }
38
  }
app/code/community/Litespeed/Litemage/Model/Config/Source/FlushCategory.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * LiteMage
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This program is free software: you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation, either version 3 of the License, or
10
+ * (at your option) any later version.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License
18
+ * along with this program. If not, see https://opensource.org/licenses/GPL-3.0 .
19
+ *
20
+ * @package LiteSpeed_LiteMage
21
+ * @copyright Copyright (c) 2016 LiteSpeed Technologies, Inc. (https://www.litespeedtech.com)
22
+ * @license https://opensource.org/licenses/GPL-3.0
23
+ */
24
+
25
+
26
+ class Litespeed_Litemage_Model_Config_Source_FlushCategory
27
+ {
28
+ // Flush Product and Categories When Product Qty Change
29
+ // 0: default - Flush product when qty change, flush categories when stock status change
30
+ // 1: Only flush product and categories when stock status change
31
+ // 2: Flush product when stock status change, do not flush categories
32
+ // 3: Always flush product and categories when qty/stock status change
33
+
34
+ public function toOptionArray() {
35
+ $helper = Mage::helper('litemage/data');
36
+ return array(
37
+ array( 'value' => 0, 'label' => $helper->__( 'Flush product when quantity or stock status change, flush categories only when stock status changes' ) ),
38
+ array( 'value' => 1, 'label' => $helper->__( 'Flush product and categories only when stock status changes' ) ),
39
+ array( 'value' => 2, 'label' => $helper->__( 'Flush product when stock status changes, do not flush categories when stock status or quantity change' ) ),
40
+ array( 'value' => 3, 'label' => $helper->__( 'Always flush product and categories when quantity or stock status change' ) )
41
+ );
42
+ }
43
+ }
app/code/community/Litespeed/Litemage/Model/EsiData.php CHANGED
@@ -27,6 +27,7 @@ class Litespeed_Litemage_Model_EsiData
27
  {
28
 
29
  const ACTION_GET_FORMKEY = 'getFormKey';
 
30
  const ACTION_LOG = 'log';
31
  const ACTION_GET_BLOCK = 'getBlock';
32
  const ACTION_GET_COMBINED = 'getCombined';
@@ -58,6 +59,9 @@ class Litespeed_Litemage_Model_EsiData
58
  case self::ACTION_GET_FORMKEY:
59
  $this->_initFormKey($configHelper);
60
  break;
 
 
 
61
  case self::ACTION_LOG:
62
  $this->_initLogProduct($params);
63
  break;
@@ -123,14 +127,13 @@ class Litespeed_Litemage_Model_EsiData
123
  return $this->_batchId;
124
  }
125
 
126
- public function saveLayoutCache($layoutUnique, $xmlString)
127
  {
128
  $this->_layoutCacheId = 'LAYOUT_ESI_' . md5($layoutUnique . '_' . $this->_layoutIdentifier);
129
  $this->_layoutXml = $xmlString;
130
- if ( Mage::app()->useCache('layout') ) {
131
- $tags = array( Litespeed_Litemage_Helper_Data::LITEMAGE_GENERAL_CACHE_TAG,
132
- Mage_Core_Model_Layout_Update::LAYOUT_GENERAL_CACHE_TAG ) ;
133
- Mage::app()->saveCache($xmlString, $this->_layoutCacheId, $tags) ;
134
  }
135
  }
136
 
@@ -153,7 +156,7 @@ class Litespeed_Litemage_Model_EsiData
153
  {
154
  $this->_rawOutput = trim($rawOutput);
155
  $this->_responseCode = $responseCode;
156
- if ( $this->_cacheAttr['ttl'] > 0 && ! in_array($responseCode, array( 200, 301, 404 )) ) {
157
  $this->_cacheAttr['ttl'] = 0 ;
158
  }
159
  }
@@ -251,6 +254,13 @@ class Litespeed_Litemage_Model_EsiData
251
  $this->_batchId = self::BATCH_DIRECT;
252
  }
253
 
 
 
 
 
 
 
 
254
  protected function _initLogProduct( $params)
255
  {
256
  // ttl is 0, no cache
@@ -335,6 +345,5 @@ class Litespeed_Litemage_Model_EsiData
335
  return $dparams ;
336
  }
337
 
338
-
339
  }
340
 
27
  {
28
 
29
  const ACTION_GET_FORMKEY = 'getFormKey';
30
+ const ACTION_GET_NICKNAME = 'getNickName';
31
  const ACTION_LOG = 'log';
32
  const ACTION_GET_BLOCK = 'getBlock';
33
  const ACTION_GET_COMBINED = 'getCombined';
59
  case self::ACTION_GET_FORMKEY:
60
  $this->_initFormKey($configHelper);
61
  break;
62
+ case self::ACTION_GET_NICKNAME:
63
+ $this->_initNickName($configHelper);
64
+ break;
65
  case self::ACTION_LOG:
66
  $this->_initLogProduct($params);
67
  break;
127
  return $this->_batchId;
128
  }
129
 
130
+ public function saveLayoutCache($layoutUnique, $xmlString, $helper)
131
  {
132
  $this->_layoutCacheId = 'LAYOUT_ESI_' . md5($layoutUnique . '_' . $this->_layoutIdentifier);
133
  $this->_layoutXml = $xmlString;
134
+ if ( $helper->useInternalCache() ) {
135
+ $tags = array(Mage_Core_Model_Layout_Update::LAYOUT_GENERAL_CACHE_TAG ) ;
136
+ $helper->saveInternalCache($xmlString, $this->_layoutCacheId, $tags) ;
 
137
  }
138
  }
139
 
156
  {
157
  $this->_rawOutput = trim($rawOutput);
158
  $this->_responseCode = $responseCode;
159
+ if ( $this->_cacheAttr['ttl'] > 0 && ($responseCode != 200)) { // for esi req, 301 and 404 also treat as error, nocache
160
  $this->_cacheAttr['ttl'] = 0 ;
161
  }
162
  }
254
  $this->_batchId = self::BATCH_DIRECT;
255
  }
256
 
257
+ protected function _initNickName($configHelper)
258
+ {
259
+ $this->_cacheAttr['ttl'] = $configHelper->getConf(Litespeed_Litemage_Helper_Data::CFG_PRIVATETTL) ;
260
+ $this->_cacheAttr['tag'] = 'E.welcome';
261
+ $this->_batchId = self::BATCH_DIRECT;
262
+ }
263
+
264
  protected function _initLogProduct( $params)
265
  {
266
  // ttl is 0, no cache
345
  return $dparams ;
346
  }
347
 
 
348
  }
349
 
app/code/community/Litespeed/Litemage/Model/EsiLayout.php CHANGED
@@ -22,6 +22,9 @@
22
  * @copyright Copyright (c) 2015-2016 LiteSpeed Technologies, Inc. (https://www.litespeedtech.com)
23
  * @license https://opensource.org/licenses/GPL-3.0
24
  */
 
 
 
25
  class Litespeed_Litemage_Model_EsiLayout extends Mage_Core_Model_Layout
26
  {
27
 
@@ -41,15 +44,17 @@ class Litespeed_Litemage_Model_EsiLayout extends Mage_Core_Model_Layout
41
 
42
  public function getBlock( $name )
43
  {
44
- if ( ! isset($this->_blocks[$name]) ) {
45
- $dummyblocks = array( 'root', 'head' ) ;
46
- if ( in_array($name, $dummyblocks) ) {
47
- $dummy = new Varien_Object() ;
48
- return $dummy ;
49
- }
50
- return null ;
 
 
 
51
  }
52
- return $this->_blocks[$name] ;
53
  }
54
 
55
  public function loadEsiLayout( $esiData )
22
  * @copyright Copyright (c) 2015-2016 LiteSpeed Technologies, Inc. (https://www.litespeedtech.com)
23
  * @license https://opensource.org/licenses/GPL-3.0
24
  */
25
+
26
+ // should only be used by EsiController
27
+
28
  class Litespeed_Litemage_Model_EsiLayout extends Mage_Core_Model_Layout
29
  {
30
 
44
 
45
  public function getBlock( $name )
46
  {
47
+ if (isset($this->_blocks[$name] )) {
48
+ return $this->_blocks[$name] ;
49
+ }
50
+ elseif (strpos($name, 'price') !== false) {
51
+ // catalog_product_price_template
52
+ return null;
53
+ }
54
+ else {
55
+ // root head
56
+ return new Litespeed_Litemage_Block_Core_Dummy($name);
57
  }
 
58
  }
59
 
60
  public function loadEsiLayout( $esiData )
app/code/community/Litespeed/Litemage/Model/Layout/EsiUpdate.php CHANGED
@@ -26,18 +26,12 @@
26
  class Litespeed_Litemage_Model_Layout_EsiUpdate extends Mage_Core_Model_Layout_Update
27
  {
28
  protected $_cachePrefix;
29
- protected $_cacheTags;
30
  protected $_layoutMaster;
31
  protected $_isDebug;
32
 
33
  public function setCachePrefix($unique)
34
  {
35
-
36
  $this->_cachePrefix = 'LAYOUT_ESI_' . $unique . '_';
37
-
38
- $this->_cacheTags = array(Mage_Core_Model_Layout_Update::LAYOUT_GENERAL_CACHE_TAG,
39
- Litespeed_Litemage_Helper_Data::LITEMAGE_GENERAL_CACHE_TAG);
40
-
41
  $this->_isDebug = Mage::helper('litemage/data')->isDebug() ;
42
  }
43
 
26
  class Litespeed_Litemage_Model_Layout_EsiUpdate extends Mage_Core_Model_Layout_Update
27
  {
28
  protected $_cachePrefix;
 
29
  protected $_layoutMaster;
30
  protected $_isDebug;
31
 
32
  public function setCachePrefix($unique)
33
  {
 
34
  $this->_cachePrefix = 'LAYOUT_ESI_' . $unique . '_';
 
 
 
 
35
  $this->_isDebug = Mage::helper('litemage/data')->isDebug() ;
36
  }
37
 
app/code/community/Litespeed/Litemage/Model/Layout/Update.php CHANGED
@@ -49,14 +49,6 @@ class Litespeed_Litemage_Model_Layout_Update extends Mage_Core_Model_Layout_Upda
49
  parent::__construct() ;
50
  }
51
 
52
- public function resetUpdates()
53
- {
54
- if ( $this->_modified ) {
55
- $this->_resetInternals() ;
56
- }
57
- return parent::resetUpdates() ;
58
- }
59
-
60
  public function resetHandles()
61
  {
62
  if ( $this->_modified ) {
49
  parent::__construct() ;
50
  }
51
 
 
 
 
 
 
 
 
 
52
  public function resetHandles()
53
  {
54
  if ( $this->_modified ) {
app/code/community/Litespeed/Litemage/Model/Observer/Cron.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * LiteMage
4
  *
@@ -21,63 +22,60 @@
21
  * @copyright Copyright (c) 2015-2016 LiteSpeed Technologies, Inc. (https://www.litespeedtech.com)
22
  * @license https://opensource.org/licenses/GPL-3.0
23
  */
24
-
25
  class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
26
  {
27
 
28
- const WARMUP_MAP_FILE = 'litemage_warmup_urlmap' ;
29
- const WARMUP_META_CACHE_ID = 'litemage_warmup_meta' ;
30
- const USER_AGENT = 'litemage_walker' ;
 
31
  const FAST_USER_AGENT = 'litemage_runner' ;
32
- const ENV_COOKIE_NAME = '_lscache_vary' ;
33
-
34
- protected $_meta ; // time, curfileline
35
- protected $_conf;
36
- protected $_isDebug ;
37
- protected $_debugTag;
38
- protected $_maxRunTime;
39
- protected $_curThreads = -1;
 
 
40
  protected $_curThreadTime ;
41
- protected $_curList ;
42
- protected $_listDir;
43
- protected $_priority;
44
-
45
-
46
- protected function _construct()
47
- {
48
- $helper = Mage::helper('litemage/data') ;
49
- $this->_isDebug = $helper->isDebug() ;
50
- if ($this->_isDebug) {
51
- $this->_debugTag = 'LiteMage [cron:';
52
- if (isset($_SERVER['USER']))
53
- $this->_debugTag .= $_SERVER['USER'];
54
- elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
55
- $this->_debugTag .= $_SERVER['HTTP_X_FORWARDED_FOR'];
56
- $this->_debugTag .= ':'. $_SERVER['REQUEST_TIME'] . '] ' ;
57
- }
58
- $this->_listDir = Mage::getBaseDir('var') . DS . 'litemage';
59
 
60
- if (!is_dir($this->_listDir)) {
61
- mkdir($this->_listDir);
62
- chmod($this->_listDir, 0777);
 
 
 
 
 
 
 
 
63
  }
 
64
 
65
- $this->_conf = $helper->getWarmUpConf();
66
- }
67
 
68
- public function resetCrawlerList($listId)
69
  {
70
  $adminSession = Mage::getSingleton('adminhtml/session') ;
71
- $meta = Mage::app()->loadCache(self::WARMUP_META_CACHE_ID);
72
- $updated = false;
73
 
74
- if ($listId) {
75
- $id = strtolower($listId);
76
  if ( $meta ) {
77
  $meta = unserialize($meta) ;
78
- if (isset($meta[$id])) {
79
- unset($meta[$id]);
80
- $updated = true;
81
  $adminSession->addSuccess($listId . ' ' . Mage::helper('litemage/data')->__('List has been reset and will be regenerated in next run.')) ;
82
  }
83
  else {
@@ -86,9 +84,9 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
86
  }
87
  }
88
  else {
89
- if ($meta) {
90
- Mage::app()->removeCache(self::WARMUP_META_CACHE_ID);
91
- $updated = true;
92
  $adminSession->addSuccess(Mage::helper('litemage/data')->__('All lists have been reset and will be regenerated in next run.')) ;
93
  }
94
  else {
@@ -96,113 +94,146 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
96
  }
97
  }
98
 
99
- if ($updated) {
100
- $this->_saveMeta($meta);
101
  }
102
  }
103
 
104
- public function getCrawlerList($listId)
105
  {
106
- $output = '<h3>Generated URL List ' . $listId . '</h3>';
107
  if ( ($urls = $this->_getCrawlListFileData($listId)) != null ) {
108
- $output .= '<pre>' . $urls . '</pre>';
109
  }
110
  else {
111
- $output .= '<p>Cannot find generated URL list. It will be regenerated in next run.</p>';
112
  }
113
- return $output;
114
  }
115
 
116
- public function getCrawlerStatus()
117
- {
118
- $this->_initMeta();
119
- $meta = $this->_meta;
120
- $timefmt = 'Y-m-d H:i:s';
121
- $status = array('lastupdate' => '', 'endreason' => '',
122
- 'stores' => array());
 
 
 
 
 
123
 
124
- if (isset($meta['lastupdate'])) {
125
- $status['lastupdate'] = date($timefmt, $meta['lastupdate']);
126
- unset($meta['lastupdate']);
127
  }
 
 
 
 
 
 
 
 
 
128
 
129
- if (isset($meta['endreason'])) {
130
- $status['endreason'] = $meta['endreason'];
131
- unset($meta['endreason']);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  }
 
 
 
 
 
 
133
 
134
- $lists = array();
135
- $priority = array();
136
- foreach ($meta as $listId => $store_stat) {
137
- $disp = array();
138
- $disp['priority'] = intval($store_stat['priority'] + 0.5);
139
- $disp['id'] = strtoupper($listId);
140
- $disp['store_name'] = $store_stat['store_name'];
141
- $disp['default_curr'] = $store_stat['default_curr'];
142
- $disp['baseurl'] = $store_stat['baseurl'];
143
- $disp['file'] = (isset($store_stat['file']) ? $store_stat['file'] : '');
144
- $disp['ttl'] = $store_stat['ttl'];
145
- $disp['interval'] = $store_stat['interval'];
146
- $disp['gentime'] = ($store_stat['gentime'] > 0) ? date($timefmt, $store_stat['gentime']) : 'N/A';
147
- $disp['tmpmsg'] = isset($store_stat['tmpmsg']) ? $store_stat['tmpmsg'] : '';
148
- $disp['lastquerytime'] = ($store_stat['lastquerytime'] > 0) ? date($timefmt, $store_stat['lastquerytime']) : 'N/A';
149
- $disp['endtime'] = ($store_stat['endtime'] > 0) ? date($timefmt, $store_stat['endtime']) : 'N/A';
150
- $disp['listsize'] = ($store_stat['listsize'] > 0) ? $store_stat['listsize'] : 'N/A';
151
- $disp['curpos'] = $store_stat['curpos'];
152
- $disp['env'] = $store_stat['env'];
153
- $disp['curvary'] = preg_replace("/_lscache_vary=.+;/", '', $store_stat['curvary']);
154
- $disp['queried'] = $store_stat['queried'];
155
- $priority[$listId] = $store_stat['priority'];
156
- $lists[$listId] = $disp;
157
- }
158
- asort($priority, SORT_NUMERIC);
159
- foreach ($priority as $id => $pri) {
160
- $status['stores'][] = $lists[$id];
161
- }
162
- return $status;
163
- }
164
-
165
- /**
166
- * called by cron job
167
- */
168
-
169
- public function warmCache()
170
- {
171
- if ($errmsg = $this->_init()) {
172
- $this->_meta['endreason'] = 'Skipped this round - ' . $errmsg;
173
- $this->_saveMeta();
174
- $this->_debugLog('Cron warmCache skip this round - ' . $errmsg);
175
  return;
176
  }
177
 
178
- $options = array(
179
- CURLOPT_SSL_VERIFYPEER => 0,
180
- CURLOPT_TIMEOUT => 180
181
- );
182
 
183
- $client = new Varien_Http_Adapter_Curl();
184
- $curCookie = '';
185
- $endReason = '';
 
186
 
187
- while ($urls = $this->_getNextUrls($curCookie)) {
188
- $curlOptions = $options;
189
- if ($curCookie) {
190
- $curlOptions[CURLOPT_COOKIE] = $curCookie;
191
- }
192
- $id = $this->_curList['id'];
193
- if (isset($this->_meta[$id]['ua'])) {
194
- $curlOptions[CURLOPT_USERAGENT] = $this->_meta[$id]['ua'];
195
  }
196
- else {
197
- $curlOptions[CURLOPT_USERAGENT] = self::FAST_USER_AGENT;
 
 
 
 
198
  }
199
 
200
- if ($this->_isDebug) {
201
- $this->_debugLog('crawling ' . $id . ' urls (cur_pos:' . $this->_meta[$id]['curpos'] . ') with cookie ' . $curCookie . ' ' . print_r($urls, true));
 
 
 
 
 
202
  }
203
 
204
  try {
205
- $client->multiRequest($urls, $curlOptions) ;
 
 
 
 
 
 
206
  } catch ( Exception $e ) {
207
  $endReason = 'Error when crawling url ' . implode(' ', $urls) . ' : ' . $e->getMessage() ;
208
  break ;
@@ -210,190 +241,282 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
210
 
211
  $this->_finishCurPosition() ;
212
 
213
- if ($this->_meta['lastupdate'] > $this->_maxRunTime) {
214
- $endReason = Mage::helper('litemage/data')->__('Stopped due to exceeding defined Maximum Run Time.');
215
- break;
216
  }
217
 
218
- if ($this->_meta['lastupdate'] - 60 > $this->_curThreadTime) {
219
- $this->_adjustCurThreads();
220
- if ($this->_curThreads == 0) {
221
- $endReason = Mage::helper('litemage/data')->__('Stopped due to current system load exceeding defined load limit.');
222
- break;
223
  }
224
  }
225
- sleep(1);
226
  }
227
- $this->_meta['endreason'] = $endReason;
228
 
229
- $this->_saveMeta() ;
230
  if ( $this->_isDebug ) {
231
  $this->_debugLog($endReason . ' cron meta end = ' . print_r($this->_meta, true)) ;
232
  }
233
  }
234
 
235
- protected function _getCrawlListFileData($listId)
236
  {
237
- $filename = $this->_listDir . DS . self::WARMUP_MAP_FILE . '_' . strtolower($listId);
238
- if (!file_exists($filename))
239
- return null;
240
  else
241
- return file_get_contents($filename);
242
  }
243
 
244
- protected function _saveCrawlListFileData($listId, $urls)
245
  {
246
- $this->_meta[$listId]['listsize'] = count($urls);
247
- $this->_meta[$listId]['gentime'] = time();
248
- $this->_meta[$listId]['endtime'] = 0;
249
- $this->_meta[$listId]['lastquerytime'] = 0;
250
- $this->_meta[$listId]['curpos'] = 0;
251
- $this->_meta[$listId]['curvary'] = '';
252
- $this->_meta[$listId]['queried'] = 0;
253
-
254
- $this->_meta['lastupdate'] = $this->_meta[$listId]['gentime'];
 
 
 
255
  $header = $this->_meta[$listId]['gentime'] . "\t"
256
  . $this->_meta[$listId]['listsize'] . "\t"
257
- . $this->_meta[$listId]['env'] . "\n";
258
 
259
  if ( $this->_isDebug ) {
260
- $this->_debugLog('Generate url map for ' . $listId . ' url count =' . $this->_meta[$listId]['listsize']);
261
  }
262
 
263
- $buf = $header . implode("\n", $urls);
264
 
265
- $filename = $this->_listDir . DS . self::WARMUP_MAP_FILE . '_' . strtolower($listId);
266
- if (!file_put_contents($filename, $buf)) {
267
- $this->_debugLog('Failed to save url map file ' . $filename);
268
  }
269
  else {
270
- chmod($filename, 0644);
271
  }
272
  }
273
 
274
  protected function _prepareCurList()
275
  {
276
- $id = array_shift($this->_priority);
277
- if ($id == null) {
278
- return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
279
  }
280
 
281
- $m = $this->_meta[$id];
282
  // parse env & get all possible varies
283
- $vary = array();
284
- $fixed = $this->_parseEnvCookies($m['env'], $vary);
285
- if (!in_array($m['curvary'], $vary) || $m['curpos'] > $m['listsize']) {
 
286
  // reset current pointer
287
- $this->_meta[$id]['curvary'] = $vary[0];
288
- $this->_meta[$id]['curpos'] = 0;
289
  if ( $this->_isDebug ) {
290
- $this->_debugLog('Reset current position pointer to 0. curvary is ' . $m['curvary']);
291
  }
292
  }
293
 
294
- while ($this->_meta[$id]['curvary'] != $vary[0]) {
295
- array_shift($vary);
296
  }
297
 
298
- $this->_curList = array('id' => $id, 'fixed' => $fixed, 'vary' => $vary, 'working' => 0);
299
- if ($m['gentime'] > 0 && $m['endtime'] == 0
300
- && ($urls = $this->_getCrawlListFileData($id)) != null ) {
 
 
301
  $allurls = explode("\n", $urls) ;
302
  // verify data
303
- $header = explode("\t", array_shift($allurls));
304
- if (($m['gentime'] == $header[0])
305
- && ($m['listsize'] == $header[1])
306
- && ($m['env'] == $header[2])
307
- && count($allurls) == $m['listsize']) {
308
- $this->_curList['urls'] = $allurls;
309
  }
310
  else if ( $this->_isDebug ) {
311
  $this->_debugLog('load saved url list, header does not match, will regenerate') ;
312
  }
313
  }
314
 
315
- if (!isset($this->_curList['urls'])) {
316
  // regenerate
317
- $this->_curList['urls'] = $this->_generateUrlList($id);
318
  }
319
 
320
- if ($this->_meta[$id]['listsize'] > 0) {
321
- return true;
322
  }
323
  else {
324
  // get next list
325
- return $this->_prepareCurList();
326
  }
327
  }
328
 
329
- protected function _parseEnvCookies( $env, &$vary )
330
- {
331
- $fixed = 'litemage_cron=' . self::USER_AGENT .';';
332
- if ( $env ) {
333
- $lsvary = array();
334
- $multiCurr = array('-') ; // default currency
335
- $multiCgrp = array('-') ; // default user group
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
336
 
337
- $env = trim($env, '/');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
  $envs = explode('/', $env) ;
339
- $envVars = array() ;
340
- $cnt = count($envs) ;
341
- for ( $i = 0 ; ($i + 1) < $cnt ; $i+=2 ) {
342
- $envVars[$envs[$i]] = $envs[$i + 1] ;
343
- }
344
- if ( isset($envVars['vary_dev']) ) {
345
- $lsvary['dev'] = 1 ;
346
- }
347
-
348
- if ( isset($envVars['store']) ) {
349
- $fixed .= Mage_Core_Model_Store::COOKIE_NAME . '=' . $envVars['store'] . ';';
350
- $lsvary['st'] = $envVars['storeId'] ;
351
- }
352
-
353
- if ( isset($envVars['vary_cgrp']) ) {
354
- $multiCgrp = explode(',', $envVars['vary_cgrp']) ;
355
- }
356
-
357
- if ( isset($envVars['vary_curr']) ) {
358
- $multiCurr = explode(',', $envVars['vary_curr']) ;
359
- }
360
-
361
- foreach ( $multiCurr as $currency ) {
362
- $cookie_vary = '';
363
- $lsvary1 = $lsvary;
364
-
365
- if ( $currency != '-' ) {
366
- $lsvary1['curr'] = $currency ;
367
- $cookie_vary .= Mage_Core_Model_Store::COOKIE_CURRENCY . '=' . $currency . ';' ;
368
- }
369
-
370
- foreach ( $multiCgrp as $cgrp ) {
371
- if ( $cgrp != '-' ) {
372
- // need to set user id
373
- $lsvary1['cgrp'] = $cgrp ;
374
- }
375
-
376
- if (!empty($lsvary1)) {
377
- ksort($lsvary1) ;
378
- $lsvary1_val = '';
379
- foreach ($lsvary1 as $k => $v) {
380
- $lsvary1_val .= $k . '%7E' . urlencode($v) . '%7E'; // %7E is "~"
381
- }
382
- $cookie_vary .= self::ENV_COOKIE_NAME . '=' . $lsvary1_val . ';';
383
  }
384
- $vary[] = $cookie_vary; // can be empty string for default no vary
385
- }
386
- }
387
 
388
- }
 
 
 
 
 
 
 
 
 
 
 
389
  else {
390
- $vary[] = ''; // no vary
391
  }
392
 
393
- return $fixed;
394
- }
395
 
396
- protected function _getNextUrls( &$curCookie )
397
  {
398
  $this->_curList['working'] = 0 ;
399
  $id = $this->_curList['id'] ;
@@ -406,9 +529,47 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
406
  }
407
  }
408
 
 
409
  $curpos = $this->_meta[$id]['curpos'] ;
410
  $curCookie = $this->_curList['fixed'] . $this->_meta[$id]['curvary'] ;
411
- $urls = array_slice($this->_curList['urls'], $this->_meta[$id]['curpos'], $this->_curThreads) ;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
412
 
413
  if ( empty($urls) ) {
414
  return null ;
@@ -416,7 +577,13 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
416
  else {
417
  $baseurl = $this->_meta[$id]['baseurl'] ;
418
  foreach ( $urls as $key => $val ) {
419
- $urls[$key] = $baseurl . $val ;
 
 
 
 
 
 
420
  }
421
  $this->_curList['working'] = count($urls) ;
422
  return $urls ;
@@ -424,30 +591,30 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
424
  }
425
 
426
  protected function _finishCurPosition()
427
- {
428
- $now = time();
429
- $id = $this->_curList['id'];
430
- if (($this->_meta[$id]['curpos'] + $this->_curList['working']) < $this->_meta[$id]['listsize']) {
431
- $this->_meta[$id]['curpos'] += $this->_curList['working'];
432
  }
433
  else {
434
- if (count($this->_curList['vary']) > 1) {
435
- array_shift($this->_curList['vary']);
436
- $this->_meta[$id]['curvary'] = $this->_curList['vary'][0];
437
- $this->_meta[$id]['curpos'] = 0;
438
  }
439
  else {
440
- $this->_meta[$id]['endtime'] = $now;
441
- $this->_meta[$id]['curpos'] = $this->_meta[$id]['listsize'];
442
  }
443
  }
444
- $this->_meta[$id]['queried'] += $this->_curList['working'];
445
- $this->_meta[$id]['lastquerytime'] = $now;
446
- $this->_meta['lastupdate'] = $now;
447
- $this->_curList['working'] = 0;
448
- }
449
 
450
- protected function _newStoreMeta($storeInfo, $tmpmsg)
451
  {
452
  $meta = array(
453
  'id' => $storeInfo['id'], // store1, custom1, delta
@@ -458,6 +625,7 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
458
  'ttl' => $storeInfo['ttl'],
459
  'interval' => $storeInfo['interval'],
460
  'priority' => $storeInfo['priority'],
 
461
  'gentime' => 0,
462
  'listsize' => 0,
463
  'env' => $storeInfo['env'],
@@ -466,119 +634,284 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
466
  'curvary' => '',
467
  'queried' => 0,
468
  'lastquerytime' => 0,
469
- 'endtime' => 0);
470
- if (isset($storeInfo['file'])) {
471
- $meta['file'] = $storeInfo['file'];
472
  }
473
- if ($tmpmsg) {
474
- $meta['tmpmsg'] = $tmpmsg;
475
  }
476
 
477
- return $meta;
478
  }
479
 
480
- protected function _saveMeta($meta=null)
481
- {
482
- if ($meta == null) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
483
  $meta = $this->_meta ;
484
  }
485
- $tags = array( Litespeed_Litemage_Helper_Data::LITEMAGE_GENERAL_CACHE_TAG, self::WARMUP_META_CACHE_ID ) ;
486
- Mage::app()->saveCache(serialize($meta), self::WARMUP_META_CACHE_ID, $tags) ;
487
- }
 
 
 
488
 
489
  protected function _initMeta()
490
  {
491
- $this->_meta = array();
492
 
493
- $saved = array();
494
- if ( $meta = Mage::app()->loadCache(self::WARMUP_META_CACHE_ID) ) {
495
- $saved = unserialize($meta) ;
496
- if (isset($saved['lastupdate'])) {
497
- $this->_meta['lastupdate'] = $saved['lastupdate'];
498
  }
499
- if (isset($saved['endreason'])) {
500
- $this->_meta['endreason'] = $saved['endreason'];
501
  }
502
- }
503
 
504
- if (empty($this->_conf['store'])) {
505
- return array();
506
  }
507
 
508
- $unfinished = array();
509
- $expired = array();
510
- $curtime = time();
 
511
 
512
- foreach( $this->_conf['store'] as $listId => $info) {
513
- $tmpmsg = '';
514
- if (isset($saved[$listId])) {
 
 
 
 
515
  // validate saved
516
- $m = $saved[$listId];
517
- if (isset($m['storeid']) && ($m['storeid'] == $info['storeid'])
518
- && isset($m['env']) && ($m['env'] == $info['env'])
519
- && isset($m['interval']) && ($m['interval'] == $info['interval'])
520
- && isset($m['priority']) && ($m['priority'] == $info['priority'])
521
- && isset($m['baseurl']) && ($m['baseurl'] == $info['baseurl'])) {
522
-
523
- if ($m['gentime'] == 0) {
524
- $tmpmsg = 'New list will be generated';
525
- $unfinished[$listId] = $m['priority'];
526
  }
527
- elseif ($m['endtime'] == 0) {
528
  // not finished
529
- $unfinished[$listId] = $m['priority'];
530
- $tmpmsg = 'Has not finished, will continue.';
 
 
 
 
 
531
  }
532
- elseif (($m['endtime'] + $m['interval'] < $curtime)) {
533
  // expired
534
- $expired[$listId] = $m['priority'];
535
- $m['ua'] = self::USER_AGENT;
536
- $tmpmsg = 'Run interval passed, will restart.';
537
  }
538
  else {
539
- $tmpmsg = 'Still fresh within interval.';
 
 
 
 
540
  }
541
- $m['tmpmsg'] = $tmpmsg;
542
- $this->_meta[$listId] = $m;
543
  }
544
- else {
545
- $tmpmsg = 'Saved configuration does not match current configuration. List will be regenerated.';
546
- $m['gentime'] = 0;
547
- if ($m['endtime'] == 0)
548
- $unfinished[$listId] = $m['priority'];
 
549
  else {
550
- $expired[$listId] = $m['priority'];
551
- $m['ua'] = self::USER_AGENT;
552
  }
553
  }
554
  }
555
  else {
556
- $tmpmsg = 'New list will be generated';
557
- $m['gentime'] = 0;
558
- $unfinished[$listId] = $info['priority'];
559
  }
560
- if (!isset($this->_meta[$listId])) {
561
- $this->_meta[$listId] = $this->_newStoreMeta($info, $tmpmsg);
562
  }
563
  }
564
 
565
- asort($unfinished, SORT_NUMERIC);
566
- asort($expired, SORT_NUMERIC);
567
- $priority = array_merge(array_keys($unfinished), array_keys($expired));
568
 
569
- return $priority;
570
  }
571
 
572
- protected function _init()
573
- {
574
- if (empty($this->_conf['store'])) {
575
- return 'configuration not enabled.';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
576
  }
577
 
578
- $this->_priority = $this->_initMeta();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
579
  if ( empty($this->_priority) ) {
580
- return 'no url list available for warm up';
581
- }
582
 
583
  $maxTime = (int) ini_get('max_execution_time') ;
584
  if ( $maxTime == 0 )
@@ -586,122 +919,124 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
586
  else
587
  $maxTime -= 5 ;
588
 
589
- $configed = $this->_conf[Litespeed_Litemage_Helper_Data::CFG_WARMUP_MAXTIME];
590
  if ( $maxTime > $configed )
591
  $maxTime = $configed ;
592
- $this->_maxRunTime = $maxTime + time();
593
 
594
- $this->_adjustCurThreads();
595
 
596
- if ($this->_curThreads == 0) {
597
  return 'load over limit' ;
598
  }
599
 
600
- if ($this->_prepareCurList())
601
- return ''; // no err msg
602
  else {
603
- return 'No url list available';
604
  }
605
- }
606
 
607
  protected function _adjustCurThreads()
608
  {
609
- $max = $this->_conf[Litespeed_Litemage_Helper_Data::CFG_WARMUP_THREAD_LIMIT];
610
  $limit = $this->_conf[Litespeed_Litemage_Helper_Data::CFG_WARMUP_LOAD_LIMIT] ;
611
 
612
  $load = sys_getloadavg() ;
613
- $curload = $load[0];
614
 
615
- if ($this->_curThreads == -1) {
616
  // init
617
- if ($curload > $limit) {
618
- $curthreads = 0;
619
  }
620
- elseif ($curload >= ($limit - 1)) {
621
- $curthreads = 1;
622
  }
623
  else {
624
- $curthreads = intval($limit - $curload);
625
- if ($curthreads > $max) {
626
- $curthreads = $max;
627
  }
628
  }
629
  }
630
  else {
631
  // adjust
632
- $curthreads = $this->_curThreads;
633
- if ($curload >= $limit + 1 ) {
634
- sleep(5); // sleep 5 secs
635
- if ($curthreads >= 1)
636
- $curthreads --;
637
  }
638
- elseif ($curload >= $limit) {
639
- if ($curthreads > 1) // if already 1, keep
640
- $curthreads --;
641
  }
642
  elseif ( ($curload + 1) < $limit ) {
643
- if ($curthreads < $max)
644
- $curthreads ++;
645
  }
646
  }
647
 
648
 
649
- if ($this->_isDebug) {
650
  $this->_debugLog('set current threads = ' . $curthreads . ' previous=' . $this->_curThreads
651
- . ' max_allowed=' . $max . ' load_limit=' . $limit . ' current_load=' . $curload);
652
  }
653
 
654
- $this->_curThreads = $curthreads;
655
- $this->_curThreadTime = time();
656
-
657
  }
658
 
659
- protected function _generateUrlList($listId)
660
  {
661
- if ($listId{0} == 's') {
662
- // store
663
- return $this->_generateStoreUrlList($listId);
664
- }
665
- else {
666
- return $this->_generateCustUrlList($listId);
 
 
 
667
  }
668
  }
669
 
670
- protected function _generateStoreUrlList($listId)
671
- {
672
- $app = Mage::app() ;
673
- $storeId = $this->_meta[$listId]['storeid'];
674
- $store = $app->getStore($storeId);
675
  $app->setCurrentStore($store) ;
676
 
677
- $baseUrl = $this->_meta[$listId]['baseurl'];
678
- $basen = strlen($baseUrl);
679
 
680
- $urls = array(''); // first line is empty for base url
681
 
682
- $visibility = array(
683
- Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
684
- Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG,
685
- ) ;
686
- $catModel = Mage::getModel('catalog/category') ;
687
 
688
  $activeCat = $catModel->getCollection($storeId)->addIsActiveFilter() ;
689
 
690
- $produrls = array();
691
 
692
  // url with cat in path
693
  foreach ( $activeCat as $cat ) {
694
  $caturl = $cat->getUrl() ;
695
- if (strncasecmp($baseUrl, $caturl, $basen) == 0) {
696
- $urls[] = substr($caturl, $basen);
697
  }
698
  foreach ( $cat->getProductCollection($storeId)
699
  ->addUrlRewrite($cat->getId())
700
  ->addAttributeToFilter('visibility', $visibility)
701
  as $prod ) {
702
  $produrl = $prod->getProductUrl() ;
703
- if (strncasecmp($baseUrl, $produrl, $basen) == 0) {
704
- $produrls[] = substr($produrl, $basen);
705
  }
706
  }
707
  }
@@ -712,74 +1047,227 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
712
  ->addAttributeToFilter('visibility', $visibility)
713
  as $prod ) {
714
  $produrl = $prod->getProductUrl() ;
715
- if (strncasecmp($baseUrl, $produrl, $basen) == 0) {
716
- $produrls[] = substr($produrl, $basen);
717
  }
718
  }
719
  }
720
 
721
  $sitemap = 'sitemap/cms_page' ;
722
  $sitemap = (Mage::getConfig()->getNode('modules/MageWorx_XSitemap') !== false) ?
723
- 'xsitemap/cms_page' : 'sitemap/cms_page' ;
724
 
725
- $sitemodel = Mage::getResourceModel($sitemap);
726
- if ($sitemodel != null) {
727
  foreach ( $sitemodel->getCollection($storeId) as $item ) {
728
- $sitemapurl = $item->getUrl();
729
- $urls[] = $sitemapurl;
730
  }
731
  }
732
 
733
- $produrls = array_unique($produrls);
734
- $urls = array_merge($urls, $produrls);
735
 
736
- $this->_saveCrawlListFileData($listId, $urls);
737
 
738
- return $urls;
739
- }
740
 
741
- protected function _generateCustUrlList($listId)
742
- {
743
- $baseUrl = $this->_meta[$listId]['baseurl'];
744
- $basen = strlen($baseUrl);
745
- $custlist = $this->_meta[$listId]['file'];
746
- $lines = file($custlist, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
747
- $urls = array();
748
- if ($lines === false) {
749
  if ( $this->_isDebug ) {
750
- $this->_debugLog('Fail to read custom URL list file ' . $custlist);
751
  }
752
  }
753
- else if (!empty($lines)) {
754
- $urls[] = ''; // always add home page
755
- foreach ($lines as $line) {
756
- $line = ltrim(trim($line), '/');
757
- if ($line != '') {
758
- if (strpos($line, 'http') !== false) {
759
- if (strncasecmp($baseUrl, $line, $basen) == 0) {
760
- $urls[] = substr($line, $basen);
761
  }
762
  }
763
  else {
764
- $urls[] = $line;
765
  }
766
  }
767
  }
768
- $urls = array_unique($urls);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
769
  }
 
 
 
 
 
 
 
 
 
 
 
 
770
 
771
- $this->_saveCrawlListFileData($listId, $urls);
 
772
 
773
- return $urls;
774
- }
 
 
 
 
 
 
 
 
 
775
 
776
- protected function _debugLog( $message, $level = 0 )
777
- {
778
- if ( $this->_isDebug ) {
779
- $message = str_replace("\n", ("\n" . $this->_debugTag . ' '), $message);
780
- Mage::log($this->_debugTag . ' '. $message ) ;
781
- }
782
 
783
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
784
 
785
  }
1
  <?php
2
+
3
  /**
4
  * LiteMage
5
  *
22
  * @copyright Copyright (c) 2015-2016 LiteSpeed Technologies, Inc. (https://www.litespeedtech.com)
23
  * @license https://opensource.org/licenses/GPL-3.0
24
  */
 
25
  class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
26
  {
27
 
28
+ const WARMUP_MAP_FILE = 'litemage_warmup_urlmap' ;
29
+ const WARMUP_META_CACHE_ID = 'litemage_warmup_meta' ;
30
+ const DELTA_META_CACHE_ID = 'litemage_delta_meta' ;
31
+ const USER_AGENT = 'litemage_walker' ;
32
  const FAST_USER_AGENT = 'litemage_runner' ;
33
+ const ENV_COOKIE_NAME = '_lscache_vary' ;
34
+
35
+ protected $_meta ; // time, curfileline
36
+ protected $_conf ;
37
+ protected $_helper ;
38
+ protected $_isDebug ;
39
+ protected $_isDelta;
40
+ protected $_debugTag ;
41
+ protected $_maxRunTime ;
42
+ protected $_curThreads = -1 ;
43
  protected $_curThreadTime ;
44
+ protected $_curList ;
45
+ protected $_curDelta ;
46
+ protected $_listDir ;
47
+ protected $_priority ;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
+ protected function _construct()
50
+ {
51
+ $this->_helper = Mage::helper('litemage/data') ;
52
+ $this->_isDebug = $this->_helper->isDebug() ;
53
+ if ( $this->_isDebug ) {
54
+ $this->_debugTag = 'LiteMage [cron:' ;
55
+ if ( isset($_SERVER['USER']) )
56
+ $this->_debugTag .= $_SERVER['USER'] ;
57
+ elseif ( isset($_SERVER['HTTP_X_FORWARDED_FOR']) )
58
+ $this->_debugTag .= $_SERVER['HTTP_X_FORWARDED_FOR'] ;
59
+ $this->_debugTag .= ':' . $_SERVER['REQUEST_TIME'] . '] ' ;
60
  }
61
+ $this->_listDir = $this->_helper->getCrawlerListDir() ;
62
 
63
+ $this->_conf = $this->_helper->getWarmUpConf() ;
64
+ }
65
 
66
+ public function resetCrawlerList( $listId )
67
  {
68
  $adminSession = Mage::getSingleton('adminhtml/session') ;
69
+ $meta = Mage::app()->loadCache(self::WARMUP_META_CACHE_ID) ;
70
+ $updated = false ;
71
 
72
+ if ( $listId ) {
73
+ $id = strtolower($listId) ;
74
  if ( $meta ) {
75
  $meta = unserialize($meta) ;
76
+ if ( isset($meta[$id]) ) {
77
+ unset($meta[$id]) ;
78
+ $updated = true ;
79
  $adminSession->addSuccess($listId . ' ' . Mage::helper('litemage/data')->__('List has been reset and will be regenerated in next run.')) ;
80
  }
81
  else {
84
  }
85
  }
86
  else {
87
+ if ( $meta ) {
88
+ Mage::app()->removeCache(self::WARMUP_META_CACHE_ID) ;
89
+ $updated = true ;
90
  $adminSession->addSuccess(Mage::helper('litemage/data')->__('All lists have been reset and will be regenerated in next run.')) ;
91
  }
92
  else {
94
  }
95
  }
96
 
97
+ if ( $updated ) {
98
+ $this->_saveMeta($meta) ;
99
  }
100
  }
101
 
102
+ public function getCrawlerList( $listId )
103
  {
104
+ $output = '<h3>Generated URL List ' . $listId . '</h3>' ;
105
  if ( ($urls = $this->_getCrawlListFileData($listId)) != null ) {
106
+ $output .= '<pre>' . $urls . '</pre>' ;
107
  }
108
  else {
109
+ $output .= '<p>Cannot find generated URL list. It will be regenerated in next run.</p>' ;
110
  }
111
+ return $output ;
112
  }
113
 
114
+ public function getCrawlerStatus()
115
+ {
116
+ $this->_initMeta() ;
117
+ $meta = $this->_meta ;
118
+ $timefmt = 'n.d H:i:s' ;
119
+ $status = array( 'lastupdate' => '', 'endreason' => '',
120
+ 'stores' => array() ) ;
121
+
122
+ if ( isset($meta['lastupdate']) ) {
123
+ $status['lastupdate'] = date($timefmt, $meta['lastupdate']) ;
124
+ unset($meta['lastupdate']) ;
125
+ }
126
 
127
+ if ( isset($meta['endreason']) ) {
128
+ $status['endreason'] = $meta['endreason'] ;
129
+ unset($meta['endreason']) ;
130
  }
131
+ unset($meta['deltalist']) ;
132
+
133
+ $lists = array() ;
134
+ $priority = array() ;
135
+ foreach ( $meta as $listId => $store_stat ) {
136
+ $disp = array() ;
137
+ $disp['priority'] = intval($store_stat['priority'] + 0.5) ;
138
+ $disp['id'] = strtoupper($listId) ;
139
+ if ( $listId == 'delta' ) {
140
 
141
+ }
142
+ else {
143
+ $disp['store_name'] = $store_stat['store_name'] ;
144
+ $disp['default_curr'] = $store_stat['default_curr'] ;
145
+ $disp['baseurl'] = $store_stat['baseurl'] ;
146
+ $disp['file'] = (isset($store_stat['file']) ? $store_stat['file'] : '') ;
147
+ $disp['ttl'] = $store_stat['ttl'] ;
148
+ $disp['interval'] = $store_stat['interval'] ;
149
+ $disp['gentime'] = ($store_stat['gentime'] > 0) ? date($timefmt, $store_stat['gentime']) : ' ' ;
150
+ $disp['tmpmsg'] = isset($store_stat['tmpmsg']) ? $store_stat['tmpmsg'] : '' ;
151
+ $disp['endtime'] = ($store_stat['endtime'] > 0) ? date($timefmt, $store_stat['endtime']) : ' ' ;
152
+ $disp['lastendtime'] = ($store_stat['lastendtime'] > 0) ? date($timefmt, $store_stat['lastendtime']) : ' ' ;
153
+ $disp['listsize'] = ($store_stat['listsize'] > 0) ? $store_stat['listsize'] : 'N/A' ;
154
+ $disp['curpos'] = $store_stat['curpos'] ;
155
+ $disp['env'] = $store_stat['env'] ;
156
+ $disp['curvary'] = preg_replace("/_lscache_vary=.+;/", '', $store_stat['curvary']) ;
157
+ }
158
+ $disp['lastquerytime'] = ($store_stat['lastquerytime'] > 0) ? date($timefmt, $store_stat['lastquerytime']) : ' ' ;
159
+ $disp['queried'] = $store_stat['queried'] ;
160
+ $priority[$listId] = $store_stat['priority'] ;
161
+ $lists[$listId] = $disp ;
162
  }
163
+ asort($priority, SORT_NUMERIC) ;
164
+ foreach ( $priority as $id => $pri ) {
165
+ $status['stores'][] = $lists[$id] ;
166
+ }
167
+ return $status ;
168
+ }
169
 
170
+ /**
171
+ * called by cron job
172
+ */
173
+ public function warmCache()
174
+ {
175
+ $this->_crawl(false);
176
+ }
177
+
178
+ public function crawlDelta()
179
+ {
180
+ $this->_crawl(true);
181
+ }
182
+
183
+ protected function _crawl($isDelta)
184
+ {
185
+ $this->_isDelta = $isDelta ;
186
+ if ( $errmsg = $this->_init() ) {
187
+ $this->_meta['endreason'] = 'Skipped this round - ' . $errmsg ;
188
+ $this->_saveMeta() ;
189
+ $this->_debugLog('Cron ' . ($isDelta ? 'warmDelta' : 'warmCache' ) . ' skip this round - ' . $errmsg) ;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
  return;
191
  }
192
 
193
+ $options = array(
194
+ CURLOPT_SSL_VERIFYPEER => 0,
195
+ CURLOPT_TIMEOUT => 180
196
+ ) ;
197
 
198
+ $server_ip = $this->_conf[Litespeed_Litemage_Helper_Data::CFG_WARMUP_SERVER_IP] ;
199
+ if ($server_ip) {
200
+ $options[CURLOPT_INTERFACE] = $server_ip;
201
+ }
202
 
203
+ $client = new Varien_Http_Adapter_Curl() ;
204
+ $curCookie = '' ;
205
+ $endReason = '' ;
206
+
207
+ while ( $urls = $this->_getNextUrls($curCookie) ) {
208
+ $curlOptions = $options ;
209
+ if ( $curCookie ) {
210
+ $curlOptions[CURLOPT_COOKIE] = $curCookie ;
211
  }
212
+ $id = $this->_curList['id'] ;
213
+ $ua = isset($this->_meta[$id]['ua']) ? $this->_meta[$id]['ua'] : self::FAST_USER_AGENT ;
214
+ $curlOptions[CURLOPT_USERAGENT] = $ua ;
215
+
216
+ if ( $this->_isDebug ) {
217
+ $this->_debugLog($ua . ' crawling ' . $server_ip . ' ' . $id . ' urls (cur_pos:' . $this->_meta[$id]['curpos'] . ') with cookie ' . $curCookie . ' ' . print_r($urls, true)) ;
218
  }
219
 
220
+ $regular = array();
221
+ $ajax = array();
222
+ foreach ($urls as $url) {
223
+ if ($url{0} == ':')
224
+ $ajax[] = substr($url, 1);
225
+ else
226
+ $regular[] = $url;
227
  }
228
 
229
  try {
230
+ if (count($regular)) {
231
+ $client->multiRequest($regular, $curlOptions) ;
232
+ }
233
+ if (count($ajax)) {
234
+ $curlOptions[CURLOPT_HTTPHEADER] = array('X-Requested-With: XMLHttpRequest');
235
+ $client->multiRequest($ajax, $curlOptions) ;
236
+ }
237
  } catch ( Exception $e ) {
238
  $endReason = 'Error when crawling url ' . implode(' ', $urls) . ' : ' . $e->getMessage() ;
239
  break ;
241
 
242
  $this->_finishCurPosition() ;
243
 
244
+ if ( $this->_meta['lastupdate'] > $this->_maxRunTime ) {
245
+ $endReason = Mage::helper('litemage/data')->__('Stopped due to exceeding defined Maximum Run Time.') ;
246
+ break ;
247
  }
248
 
249
+ if ( $this->_meta['lastupdate'] - 60 > $this->_curThreadTime ) {
250
+ $this->_adjustCurThreads() ;
251
+ if ( $this->_curThreads == 0 ) {
252
+ $endReason = Mage::helper('litemage/data')->__('Stopped due to current system load exceeding defined load limit.') ;
253
+ break ;
254
  }
255
  }
256
+ sleep(1) ;
257
  }
258
+ $this->_meta['endreason'] = $endReason ;
259
 
260
+ $this->_saveMeta() ;
261
  if ( $this->_isDebug ) {
262
  $this->_debugLog($endReason . ' cron meta end = ' . print_r($this->_meta, true)) ;
263
  }
264
  }
265
 
266
+ protected function _getCrawlListFileData( $listId )
267
  {
268
+ $filename = $this->_listDir . DS . self::WARMUP_MAP_FILE . '_' . strtolower($listId) ;
269
+ if ( ! file_exists($filename) )
270
+ return null ;
271
  else
272
+ return trim(file_get_contents($filename)) ;
273
  }
274
 
275
+ protected function _saveCrawlListFileData( $listId, $urls )
276
  {
277
+ $size = count($urls);
278
+ $now = time();
279
+ $this->_meta[$listId]['listsize'] = $size ;
280
+ $this->_meta[$listId]['gentime'] = $now ;
281
+ $this->_meta[$listId]['lastendtime'] = $this->_meta[$listId]['endtime'] ;
282
+ $this->_meta[$listId]['endtime'] = ($size == 0) ? $now : 0 ;
283
+ $this->_meta[$listId]['lastquerytime'] = 0 ;
284
+ $this->_meta[$listId]['curpos'] = 0 ;
285
+ $this->_meta[$listId]['curvary'] = '' ;
286
+ $this->_meta[$listId]['queried'] = 0 ;
287
+
288
+ $this->_meta['lastupdate'] = $this->_meta[$listId]['gentime'] ;
289
  $header = $this->_meta[$listId]['gentime'] . "\t"
290
  . $this->_meta[$listId]['listsize'] . "\t"
291
+ . $this->_meta[$listId]['env'] . "\n" ;
292
 
293
  if ( $this->_isDebug ) {
294
+ $this->_debugLog('Generate url map for ' . $listId . ' url count=' . $this->_meta[$listId]['listsize']) ;
295
  }
296
 
297
+ $buf = $header . implode("\n", $urls) ;
298
 
299
+ $filename = $this->_listDir . DS . self::WARMUP_MAP_FILE . '_' . strtolower($listId) ;
300
+ if ( ! file_put_contents($filename, $buf) ) {
301
+ $this->_debugLog('Failed to save url map file ' . $filename) ;
302
  }
303
  else {
304
+ chmod($filename, 0644) ;
305
  }
306
  }
307
 
308
  protected function _prepareCurList()
309
  {
310
+ if ( empty($this->_priority) )
311
+ return false ;
312
+
313
+ if ( $this->_priority[0] == 'delta' ) {
314
+ if ( $this->_prepareDeltaList() ) {
315
+ return true ;
316
+ }
317
+ array_shift($this->_priority) ;
318
+ }
319
+ elseif ( $this->_priority[0]{0} == 'M') {
320
+ $this->_maintainAutoList(substr(array_shift($this->_priority), 1));
321
+ return $this->_prepareCurList() ;
322
+ }
323
+
324
+ $id = array_shift($this->_priority) ;
325
+ if ( $id == null ) {
326
+ return false ;
327
  }
328
 
329
+ $m = &$this->_meta[$id] ;
330
  // parse env & get all possible varies
331
+ $vary = array() ;
332
+ $fixed = 'litemage_cron=' . $id . ';' ;
333
+ $fixed .= $this->_parseEnvCookies($m['env'], $vary) ;
334
+ if ( ! in_array($m['curvary'], $vary) || $m['curpos'] > $m['listsize'] ) {
335
  // reset current pointer
336
+ $m['curvary'] = $vary[0] ;
337
+ $m['curpos'] = 0 ;
338
  if ( $this->_isDebug ) {
339
+ $this->_debugLog('Reset current position pointer to 0. curvary is ' . $m['curvary']) ;
340
  }
341
  }
342
 
343
+ while ( ! empty($vary) && ($m['curvary'] != $vary[0]) ) {
344
+ array_shift($vary) ;
345
  }
346
 
347
+ $this->_curList = array(
348
+ 'id' => $id, 'fixed' => $fixed, 'vary' => $vary, 'working' => 0 ) ;
349
+
350
+ if ( $m['gentime'] > 0 && $m['endtime'] == 0 && ($urls = $this->_getCrawlListFileData($id))
351
+ != null ) {
352
  $allurls = explode("\n", $urls) ;
353
  // verify data
354
+ $header = explode("\t", array_shift($allurls)) ;
355
+ if ( ($m['gentime'] == $header[0]) && ($m['listsize'] == $header[1]) && ($m['env']
356
+ == $header[2]) && count($allurls) == $m['listsize'] ) {
357
+ $this->_curList['urls'] = $allurls ;
 
 
358
  }
359
  else if ( $this->_isDebug ) {
360
  $this->_debugLog('load saved url list, header does not match, will regenerate') ;
361
  }
362
  }
363
 
364
+ if ( ! isset($this->_curList['urls']) ) {
365
  // regenerate
366
+ $this->_curList['urls'] = $this->_generateUrlList($id) ;
367
  }
368
 
369
+ if ( $m['listsize'] > 0 ) {
370
+ return true ;
371
  }
372
  else {
373
  // get next list
374
+ return $this->_prepareCurList() ;
375
  }
376
  }
377
 
378
+ protected function _prepareDeltaList()
379
+ {
380
+ $m = &$this->_meta['delta'] ;
381
+ if ( isset($this->_curDelta['storeurls']) && ($m['endtime'] > 0) ) {
382
+ array_shift($this->_curDelta['ids']) ;
383
+ if ( empty($this->_curDelta['ids']) ) {
384
+ // switch to next tag
385
+ unset($this->_curDelta['storeurls']) ;
386
+ $m['curtag'] = '' ;
387
+ }
388
+ else {
389
+ $m['curlist'] = $this->_curDelta['ids'][0] ;
390
+ $m['curpos'] = 0 ;
391
+ $m['curvary'] = '' ;
392
+ $m['endtime'] = 0 ;
393
+ }
394
+ }
395
+ if ( ! isset($this->_curDelta['storeurls']) && ! $this->_loadNextDeltaTag() ) {
396
+ return false ;
397
+ }
398
+
399
+ if ( ! $m['curlist'] ) {
400
+ $m['curlist'] = $this->_curDelta['ids'][0] ;
401
+ }
402
+
403
+ while ( $m['curlist'] != $this->_curDelta['ids'][0] ) {
404
+ array_shift($this->_curDelta['ids']) ;
405
+ }
406
 
407
+ $urls = array();
408
+ $depth = $this->_meta['deltaDepth'][$m['curlist']];
409
+ foreach ($this->_curDelta['storeurls'][$m['curlist']] as $level => $ud) {
410
+ if (is_int($level) && $level <= $depth) {
411
+ $urls = array_merge($urls, array_keys($ud));
412
+ }
413
+ }
414
+
415
+ $m['listsize'] = count($urls) ;
416
+
417
+ $id = 'delta' . $m['curlist'] ;
418
+ if ( isset($this->_conf['store'][$id]['fixed']) ) {
419
+ $fixed = $this->_conf['store'][$id]['fixed'] ;
420
+ $vary = $this->_conf['store'][$id]['vary'] ;
421
+ }
422
+ else {
423
+ $vary = array() ;
424
+ $fixed = 'litemage_cron=' . $id . ':' . $m['curtag'] . ';' ;
425
+ $fixed .= $this->_parseEnvCookies($this->_conf['store'][$id]['env'], $vary) ;
426
+ $this->_conf['store'][$id]['fixed'] = $fixed ;
427
+ $this->_conf['store'][$id]['vary'] = $vary ;
428
+ }
429
+ $m['baseurl'] = $this->_conf['store'][$id]['baseurl'] ;
430
+
431
+ if ( ! in_array($m['curvary'], $vary) || $m['curpos'] > $m['listsize'] ) {
432
+ // reset current pointer
433
+ $m['curvary'] = $vary[0] ;
434
+ $m['curpos'] = 0 ;
435
+ if ( $this->_isDebug ) {
436
+ $this->_debugLog('Reset current position pointer to 0. curvary is ' . $m['curvary']) ;
437
+ }
438
+ }
439
+
440
+ while ( $m['curvary'] != $vary[0] ) {
441
+ array_shift($vary) ;
442
+ }
443
+
444
+ $this->_curList = array(
445
+ 'id' => 'delta', 'fixed' => $fixed, 'vary' => $vary, 'working' => 0, 'urls' => $urls ) ;
446
+
447
+ if ( $this->_isDebug ) {
448
+ $this->_debugLog('current delta list for tag ' . $m['curtag'] . ' ' . print_r($this->_curList, true)) ;
449
+ }
450
+ return true ;
451
+ }
452
+
453
+ protected function _parseEnvCookies( $env, &$vary )
454
+ {
455
+ $fixed = '' ;
456
+ if ( $env ) {
457
+ $lsvary = array() ;
458
+ $multiCurr = array( '-' ) ; // default currency
459
+ $multiCgrp = array( '-' ) ; // default user group
460
+
461
+ $env = trim($env, '/') ;
462
  $envs = explode('/', $env) ;
463
+ $envVars = array() ;
464
+ $cnt = count($envs) ;
465
+ for ( $i = 0 ; ($i + 1) < $cnt ; $i+=2 ) {
466
+ $envVars[$envs[$i]] = $envs[$i + 1] ;
467
+ }
468
+ if ( isset($envVars['vary_dev']) ) {
469
+ $lsvary['dev'] = 1 ;
470
+ }
471
+
472
+ if ( isset($envVars['store']) ) {
473
+ $fixed .= Mage_Core_Model_Store::COOKIE_NAME . '=' . $envVars['store'] . ';' ;
474
+ $lsvary['st'] = $envVars['storeId'] ;
475
+ }
476
+
477
+ if ( isset($envVars['vary_cgrp']) ) {
478
+ $multiCgrp = explode(',', $envVars['vary_cgrp']) ;
479
+ }
480
+
481
+ if ( isset($envVars['vary_curr']) ) {
482
+ $multiCurr = explode(',', $envVars['vary_curr']) ;
483
+ }
484
+
485
+ foreach ( $multiCurr as $currency ) {
486
+ $cookie_vary = '' ;
487
+ $lsvary1 = $lsvary ;
488
+
489
+ if ( $currency != '-' ) {
490
+ $lsvary1['curr'] = $currency ;
491
+ $cookie_vary .= Mage_Core_Model_Store::COOKIE_CURRENCY . '=' . $currency . ';' ;
492
+ }
493
+
494
+ foreach ( $multiCgrp as $cgrp ) {
495
+ if ( $cgrp != '-' ) {
496
+ // need to set user id
497
+ $lsvary1['cgrp'] = $cgrp ;
 
 
 
 
 
 
 
 
 
498
  }
 
 
 
499
 
500
+ if ( ! empty($lsvary1) ) {
501
+ ksort($lsvary1) ;
502
+ $lsvary1_val = '' ;
503
+ foreach ( $lsvary1 as $k => $v ) {
504
+ $lsvary1_val .= $k . '%7E' . urlencode($v) . '%7E' ; // %7E is "~"
505
+ }
506
+ $cookie_vary .= self::ENV_COOKIE_NAME . '=' . $lsvary1_val . ';' ;
507
+ }
508
+ $vary[] = $cookie_vary ; // can be empty string for default no vary
509
+ }
510
+ }
511
+ }
512
  else {
513
+ $vary[] = '' ; // no vary
514
  }
515
 
516
+ return $fixed ;
517
+ }
518
 
519
+ protected function _getNextUrls( &$curCookie )
520
  {
521
  $this->_curList['working'] = 0 ;
522
  $id = $this->_curList['id'] ;
529
  }
530
  }
531
 
532
+ $isAutoList = ($id{0} == 'a');
533
  $curpos = $this->_meta[$id]['curpos'] ;
534
  $curCookie = $this->_curList['fixed'] . $this->_meta[$id]['curvary'] ;
535
+
536
+ if ($isAutoList) {
537
+ // {tag}:url
538
+ $curtag = '';
539
+ $urls = array();
540
+ for ($i = 0; $i < $this->_curThreads ; $i ++) {
541
+ if (!isset($this->_curList['urls'][$curpos]))
542
+ break;
543
+
544
+ $line = $this->_curList['urls'][$curpos];
545
+ $curpos ++;
546
+
547
+ if ($pos = strpos($line, '}')) {
548
+ $url = substr($line, $pos+1);
549
+ $tag = substr($line, 1, $pos-1);
550
+ }
551
+ else {
552
+ // bad line, ignore
553
+ continue;
554
+ }
555
+
556
+ if ($curtag == '') {
557
+ $curtag = $tag;
558
+ }
559
+ elseif ($curtag != $tag) {
560
+ break;
561
+ }
562
+ $urls[] = $url;
563
+ }
564
+ if ($curtag) {
565
+ //'litemage_cron=' . $id . ':' . $m['curtag'] . ';' ;
566
+ $replace = '$1' . ':' . $curtag . ';';
567
+ $curCookie = preg_replace('/(litemage_cron=[^;]+);/', $replace, $curCookie);
568
+ }
569
+ }
570
+ else {
571
+ $urls = array_slice($this->_curList['urls'], $curpos, $this->_curThreads) ;
572
+ }
573
 
574
  if ( empty($urls) ) {
575
  return null ;
577
  else {
578
  $baseurl = $this->_meta[$id]['baseurl'] ;
579
  foreach ( $urls as $key => $val ) {
580
+ if ($val != '' && $val{0} == ':') {
581
+ $val = substr($val, 1);
582
+ $urls[$key] = ':' . $baseurl . $val ; // ajax
583
+ }
584
+ else {
585
+ $urls[$key] = $baseurl . $val ;
586
+ }
587
  }
588
  $this->_curList['working'] = count($urls) ;
589
  return $urls ;
591
  }
592
 
593
  protected function _finishCurPosition()
594
+ {
595
+ $now = time() ;
596
+ $id = $this->_curList['id'] ;
597
+ if ( ($this->_meta[$id]['curpos'] + $this->_curList['working']) < $this->_meta[$id]['listsize'] ) {
598
+ $this->_meta[$id]['curpos'] += $this->_curList['working'] ;
599
  }
600
  else {
601
+ if ( count($this->_curList['vary']) > 1 ) {
602
+ array_shift($this->_curList['vary']) ;
603
+ $this->_meta[$id]['curvary'] = $this->_curList['vary'][0] ;
604
+ $this->_meta[$id]['curpos'] = 0 ;
605
  }
606
  else {
607
+ $this->_meta[$id]['endtime'] = $now ;
608
+ $this->_meta[$id]['curpos'] = $this->_meta[$id]['listsize'] ;
609
  }
610
  }
611
+ $this->_meta[$id]['queried'] += $this->_curList['working'] ;
612
+ $this->_meta[$id]['lastquerytime'] = $now ;
613
+ $this->_meta['lastupdate'] = $now ;
614
+ $this->_curList['working'] = 0 ;
615
+ }
616
 
617
+ protected function _newStoreMeta( $storeInfo, $tmpmsg )
618
  {
619
  $meta = array(
620
  'id' => $storeInfo['id'], // store1, custom1, delta
625
  'ttl' => $storeInfo['ttl'],
626
  'interval' => $storeInfo['interval'],
627
  'priority' => $storeInfo['priority'],
628
+ 'lastendtime' => 0,
629
  'gentime' => 0,
630
  'listsize' => 0,
631
  'env' => $storeInfo['env'],
634
  'curvary' => '',
635
  'queried' => 0,
636
  'lastquerytime' => 0,
637
+ 'endtime' => 0 ) ;
638
+ if ( isset($storeInfo['file']) ) {
639
+ $meta['file'] = $storeInfo['file'] ;
640
  }
641
+ if ( $tmpmsg ) {
642
+ $meta['tmpmsg'] = $tmpmsg ;
643
  }
644
 
645
+ return $meta ;
646
  }
647
 
648
+ protected function _resetDeltaMeta( $time, $curtag, $pending )
649
+ {
650
+ if ( ! isset($this->_meta['delta']) ) {
651
+ $this->_meta['delta'] = array( 'time' => -1 ) ;
652
+ }
653
+ $m = &$this->_meta['delta'] ;
654
+ $now = time() ;
655
+ if ( $this->_meta['delta']['time'] != $time ) {
656
+ // new delta list
657
+ $this->_meta['delta'] = array(
658
+ 'time' => $time,
659
+ 'priority' => 0,
660
+ 'gentime' => $now,
661
+ 'listsize' => 0,
662
+ 'ua' => self::FAST_USER_AGENT,
663
+ 'curtag' => $curtag,
664
+ 'pending' => 0,
665
+ 'curlist' => '',
666
+ 'curpos' => 0,
667
+ 'curvary' => '',
668
+ 'queried' => 0,
669
+ 'lastquerytime' => 0,
670
+ 'endtime' => 0
671
+ ) ;
672
+ }
673
+ elseif ( $this->_meta['delta']['curtag'] != $curtag ) {
674
+ $m['curtag'] = $curtag ;
675
+ $m['gentime'] = $now ;
676
+ $m['pending'] = $pending ;
677
+ $m['curlist'] = '' ;
678
+ $m['curpos'] = 0 ;
679
+ $m['curvary'] = '' ;
680
+ $m['lastquerytime'] = 0 ;
681
+ $m['endtime'] = 0 ;
682
+ }
683
+ else {
684
+ $m['pending'] = $pending ;
685
+ if ( ! in_array($m['curlist'], $this->_meta['deltalist']) ) {
686
+ $m = &$this->_meta['delta'] ;
687
+ $m['curlist'] = '' ;
688
+ $m['gentime'] = $now ;
689
+ $m['curpos'] = 0 ;
690
+ $m['curvary'] = '' ;
691
+ $m['lastquerytime'] = 0 ;
692
+ $m['endtime'] = 0 ;
693
+ }
694
+ }
695
+ }
696
+
697
+ protected function _saveMeta( $meta = null )
698
+ {
699
+ if ( $meta == null ) {
700
  $meta = $this->_meta ;
701
  }
702
+ if ( $this->_helper->useInternalCache() ) {
703
+ $cacheId = $this->_isDelta ? self::DELTA_META_CACHE_ID : self::WARMUP_META_CACHE_ID;
704
+ $tags = array( $cacheId ) ;
705
+ $this->_helper->saveInternalCache(serialize($meta), $cacheId, $tags) ;
706
+ }
707
+ }
708
 
709
  protected function _initMeta()
710
  {
711
+ $this->_meta = array() ;
712
 
713
+ $saved = array() ;
714
+ if ( $meta = Mage::app()->loadCache(self::WARMUP_META_CACHE_ID) ) {
715
+ $saved = unserialize($meta) ;
716
+ if ( isset($saved['lastupdate']) ) {
717
+ $this->_meta['lastupdate'] = $saved['lastupdate'] ;
718
  }
719
+ if ( isset($saved['endreason']) ) {
720
+ $this->_meta['endreason'] = $saved['endreason'] ;
721
  }
722
+ }
723
 
724
+ if ( empty($this->_conf['store']) ) {
725
+ return array() ;
726
  }
727
 
728
+ $unfinished = array() ;
729
+ $expired = array() ;
730
+ $curtime = time() ;
731
+ $auto = array();
732
 
733
+ foreach ( $this->_conf['store'] as $listId => $info ) {
734
+ if ( $listId{0} == 'd' ) {
735
+ // delta list
736
+ continue ;
737
+ }
738
+ $tmpmsg = '' ;
739
+ if ( isset($saved[$listId]) ) {
740
  // validate saved
741
+ $m = $saved[$listId] ;
742
+ if ( isset($m['storeid']) && ($m['storeid'] == $info['storeid']) && isset($m['env'])
743
+ && ($m['env'] == $info['env']) && isset($m['interval']) && ($m['interval']
744
+ == $info['interval']) && isset($m['priority']) && ($m['priority'] == $info['priority'])
745
+ && isset($m['baseurl']) && ($m['baseurl'] == $info['baseurl']) ) {
746
+
747
+ if ( $m['gentime'] == 0 ) {
748
+ $tmpmsg = 'New list will be generated.' ;
749
+ $unfinished[$listId] = $m['priority'] ;
 
750
  }
751
+ elseif ( $m['endtime'] == 0 ) {
752
  // not finished
753
+ if ($m['lastendtime']== 0) {
754
+ $unfinished[$listId] = $m['priority'] ;
755
+ }
756
+ else {
757
+ $expired[$listId] = $m['priority'] ;
758
+ }
759
+ $tmpmsg = 'Has not finished, will continue.' ;
760
  }
761
+ elseif ( ($m['endtime'] + $m['interval'] < $curtime ) ) {
762
  // expired
763
+ $expired[$listId] = $m['priority'] ;
764
+ $m['ua'] = self::USER_AGENT ;
765
+ $tmpmsg = 'Run interval passed, will restart.' ;
766
  }
767
  else {
768
+ $tmpmsg = 'Still fresh within interval.' ;
769
+ if ($listId{0} == 'a') {
770
+ // maintain auto
771
+ $auto[] = 'M' . $listId;
772
+ }
773
  }
774
+ $m['tmpmsg'] = $tmpmsg ;
775
+ $this->_meta[$listId] = $m ;
776
  }
777
+ else {
778
+ $tmpmsg = 'Saved configuration does not match current configuration. List will be regenerated.' ;
779
+ $m['gentime'] = 0 ;
780
+ if ( $m['lastendtime'] == 0 ) {
781
+ $unfinished[$listId] = $m['priority'] ;
782
+ }
783
  else {
784
+ $expired[$listId] = $m['priority'] ;
785
+ $m['ua'] = self::USER_AGENT ;
786
  }
787
  }
788
  }
789
  else {
790
+ $tmpmsg = 'New list will be generated' ;
791
+ $m['gentime'] = 0 ;
792
+ $unfinished[$listId] = $info['priority'] ;
793
  }
794
+ if ( ! isset($this->_meta[$listId]) ) {
795
+ $this->_meta[$listId] = $this->_newStoreMeta($info, $tmpmsg) ;
796
  }
797
  }
798
 
799
+ asort($unfinished, SORT_NUMERIC) ;
800
+ asort($expired, SORT_NUMERIC) ;
801
+ $priority = array_merge(array_keys($unfinished), array_keys($expired), $auto) ;
802
 
803
+ return $priority ;
804
  }
805
 
806
+ protected function _initDeltaMeta()
807
+ {
808
+ $this->_meta = array() ;
809
+ $priority = array();
810
+
811
+ $saved = array() ;
812
+ if ( $meta = Mage::app()->loadCache(self::DELTA_META_CACHE_ID) ) {
813
+ $saved = unserialize($meta) ;
814
+ if ( isset($saved['lastupdate']) ) {
815
+ $this->_meta['lastupdate'] = $saved['lastupdate'] ;
816
+ }
817
+ if ( isset($saved['endreason']) ) {
818
+ $this->_meta['endreason'] = $saved['endreason'] ;
819
+ }
820
+ }
821
+
822
+ if ( empty($this->_conf['store']) ) {
823
+ return $priority ;
824
+ }
825
+
826
+ $delta = array() ;
827
+ $depth = array();
828
+
829
+ foreach ( $this->_conf['store'] as $listId => $info ) {
830
+ if ( $listId{0} == 'd' ) {
831
+ // delta list
832
+ $storeId = $info['storeid'];
833
+ $delta[$storeId] = $info['priority'] ;
834
+ $depth[$storeId] = $info['depth'];
835
+ }
836
  }
837
 
838
+ if ( ! empty($delta) ) {
839
+ asort($delta, SORT_NUMERIC) ;
840
+ $this->_meta['deltalist'] = array_keys($delta) ;
841
+ $this->_meta['deltaDepth'] = $depth;
842
+ if ( isset($saved['delta']) ) {
843
+ $this->_meta['delta'] = $saved['delta'] ;
844
+ }
845
+ else {
846
+ $this->_resetDeltaMeta(0, '', 0) ;
847
+ }
848
+ $priority[] = 'delta';
849
+ }
850
+
851
+ return $priority ;
852
+ }
853
+
854
+ protected function _loadNextDeltaTag()
855
+ {
856
+ $deltaCacheId = Litespeed_Litemage_Helper_Data::LITEMAGE_DELTA_CACHE_ID ;
857
+ $result = Mage::app()->loadCache($deltaCacheId) ;
858
+ if ( ! $result )
859
+ return false ; // cache reset
860
+
861
+ $delta = unserialize($result) ;
862
+ $this->_curDelta = array() ;
863
+
864
+ $curtag = '' ;
865
+ $curIds = array() ;
866
+ $updated = false ;
867
+
868
+ while ( ! empty($delta['tags']) ) {
869
+ $tag = array_shift($delta['tags']) ;
870
+ $updated = true ;
871
+ $cacheId = 'LITEMAGE_AUTOURL_' . $tag ;
872
+ if ( $data = Mage::app()->loadCache($cacheId) ) {
873
+ $tagdata = unserialize($data) ;
874
+ foreach ( $this->_meta['deltalist'] as $storeId ) {
875
+ if ( ! empty($tagdata[$storeId][0]) ) {
876
+ $curIds[] = $storeId ;
877
+ }
878
+ }
879
+ if ( count($curIds) ) {
880
+ $curtag = $tag ;
881
+ $this->_curDelta['storeurls'] = $tagdata ;
882
+ $this->_curDelta['ids'] = $curIds ;
883
+ $this->_curDelta['tag'] = $tag ;
884
+ break ;
885
+ }
886
+ }
887
+
888
+ if ( $this->_isDebug ) {
889
+ $this->_debugLog('No urls saved for current delta tag ' . $tag . ' - bypass') ;
890
+ }
891
+ }
892
+
893
+ if ( $updated ) {
894
+ $this->_helper->saveInternalCache(serialize($delta), $deltaCacheId) ;
895
+ }
896
+
897
+ $this->_resetDeltaMeta($delta['time'], $curtag, count($delta['tags'])) ;
898
+ return ($curtag != '') ;
899
+ }
900
+
901
+ protected function _init()
902
+ {
903
+ if ( empty($this->_conf['store']) ) {
904
+ return 'configuration not enabled.' ;
905
+ }
906
+
907
+ if ( ! $this->_helper->useInternalCache() ) {
908
+ return 'cache storage is disabled' ;
909
+ }
910
+
911
+ $this->_priority = $this->_isDelta ? $this->_initDeltaMeta() : $this->_initMeta() ;
912
  if ( empty($this->_priority) ) {
913
+ return 'no url list available for warm up' ;
914
+ }
915
 
916
  $maxTime = (int) ini_get('max_execution_time') ;
917
  if ( $maxTime == 0 )
919
  else
920
  $maxTime -= 5 ;
921
 
922
+ $configed = $this->_conf[Litespeed_Litemage_Helper_Data::CFG_WARMUP_MAXTIME] ;
923
  if ( $maxTime > $configed )
924
  $maxTime = $configed ;
925
+ $this->_maxRunTime = $maxTime + time() ;
926
 
927
+ $this->_adjustCurThreads() ;
928
 
929
+ if ( $this->_curThreads == 0 ) {
930
  return 'load over limit' ;
931
  }
932
 
933
+ if ( $this->_prepareCurList() )
934
+ return '' ; // no err msg
935
  else {
936
+ return 'No url list available' ;
937
  }
938
+ }
939
 
940
  protected function _adjustCurThreads()
941
  {
942
+ $max = $this->_conf[Litespeed_Litemage_Helper_Data::CFG_WARMUP_THREAD_LIMIT] ;
943
  $limit = $this->_conf[Litespeed_Litemage_Helper_Data::CFG_WARMUP_LOAD_LIMIT] ;
944
 
945
  $load = sys_getloadavg() ;
946
+ $curload = 1; //$load[0] ;
947
 
948
+ if ( $this->_curThreads == -1 ) {
949
  // init
950
+ if ( $curload > $limit ) {
951
+ $curthreads = 0 ;
952
  }
953
+ elseif ( $curload >= ($limit - 1) ) {
954
+ $curthreads = 1 ;
955
  }
956
  else {
957
+ $curthreads = intval($limit - $curload) ;
958
+ if ( $curthreads > $max ) {
959
+ $curthreads = $max ;
960
  }
961
  }
962
  }
963
  else {
964
  // adjust
965
+ $curthreads = $this->_curThreads ;
966
+ if ( $curload >= $limit + 1 ) {
967
+ sleep(5) ; // sleep 5 secs
968
+ if ( $curthreads >= 1 )
969
+ $curthreads -- ;
970
  }
971
+ elseif ( $curload >= $limit ) {
972
+ if ( $curthreads > 1 ) // if already 1, keep
973
+ $curthreads -- ;
974
  }
975
  elseif ( ($curload + 1) < $limit ) {
976
+ if ( $curthreads < $max )
977
+ $curthreads ++ ;
978
  }
979
  }
980
 
981
 
982
+ if ( $this->_isDebug ) {
983
  $this->_debugLog('set current threads = ' . $curthreads . ' previous=' . $this->_curThreads
984
+ . ' max_allowed=' . $max . ' load_limit=' . $limit . ' current_load=' . $curload) ;
985
  }
986
 
987
+ $this->_curThreads = $curthreads ;
988
+ $this->_curThreadTime = time() ;
 
989
  }
990
 
991
+ protected function _generateUrlList( $listId )
992
  {
993
+ switch ( $listId{0} ) {
994
+ case 's':
995
+ return $this->_generateStoreUrlList($listId) ;
996
+ case 'c':
997
+ return $this->_generateCustUrlList($listId) ;
998
+ case 'a':
999
+ return $this->_generateAutoUrlList($listId) ;
1000
+ default:
1001
+ return array() ;
1002
  }
1003
  }
1004
 
1005
+ protected function _generateStoreUrlList( $listId )
1006
+ {
1007
+ $app = Mage::app() ;
1008
+ $storeId = $this->_meta[$listId]['storeid'] ;
1009
+ $store = $app->getStore($storeId) ;
1010
  $app->setCurrentStore($store) ;
1011
 
1012
+ $baseUrl = $this->_meta[$listId]['baseurl'] ;
1013
+ $basen = strlen($baseUrl) ;
1014
 
1015
+ $urls = array( '' ) ; // first line is empty for base url
1016
 
1017
+ $visibility = array(
1018
+ Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
1019
+ Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG,
1020
+ ) ;
1021
+ $catModel = Mage::getModel('catalog/category') ;
1022
 
1023
  $activeCat = $catModel->getCollection($storeId)->addIsActiveFilter() ;
1024
 
1025
+ $produrls = array() ;
1026
 
1027
  // url with cat in path
1028
  foreach ( $activeCat as $cat ) {
1029
  $caturl = $cat->getUrl() ;
1030
+ if ( strncasecmp($baseUrl, $caturl, $basen) == 0 ) {
1031
+ $urls[] = substr($caturl, $basen) ;
1032
  }
1033
  foreach ( $cat->getProductCollection($storeId)
1034
  ->addUrlRewrite($cat->getId())
1035
  ->addAttributeToFilter('visibility', $visibility)
1036
  as $prod ) {
1037
  $produrl = $prod->getProductUrl() ;
1038
+ if ( strncasecmp($baseUrl, $produrl, $basen) == 0 ) {
1039
+ $produrls[] = substr($produrl, $basen) ;
1040
  }
1041
  }
1042
  }
1047
  ->addAttributeToFilter('visibility', $visibility)
1048
  as $prod ) {
1049
  $produrl = $prod->getProductUrl() ;
1050
+ if ( strncasecmp($baseUrl, $produrl, $basen) == 0 ) {
1051
+ $produrls[] = substr($produrl, $basen) ;
1052
  }
1053
  }
1054
  }
1055
 
1056
  $sitemap = 'sitemap/cms_page' ;
1057
  $sitemap = (Mage::getConfig()->getNode('modules/MageWorx_XSitemap') !== false) ?
1058
+ 'xsitemap/cms_page' : 'sitemap/cms_page' ;
1059
 
1060
+ $sitemodel = Mage::getResourceModel($sitemap) ;
1061
+ if ( $sitemodel != null ) {
1062
  foreach ( $sitemodel->getCollection($storeId) as $item ) {
1063
+ $sitemapurl = $item->getUrl() ;
1064
+ $urls[] = $sitemapurl ;
1065
  }
1066
  }
1067
 
1068
+ $produrls = array_unique($produrls) ;
1069
+ $urls = array_merge($urls, $produrls) ;
1070
 
1071
+ $this->_saveCrawlListFileData($listId, $urls) ;
1072
 
1073
+ return $urls ;
1074
+ }
1075
 
1076
+ protected function _generateCustUrlList( $listId )
1077
+ {
1078
+ $baseUrl = $this->_meta[$listId]['baseurl'] ;
1079
+ $basen = strlen($baseUrl) ;
1080
+ $custlist = $this->_meta[$listId]['file'] ;
1081
+ $lines = file($custlist, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ;
1082
+ $urls = array() ;
1083
+ if ( $lines === false ) {
1084
  if ( $this->_isDebug ) {
1085
+ $this->_debugLog('Fail to read custom URL list file ' . $custlist) ;
1086
  }
1087
  }
1088
+ else if ( ! empty($lines) ) {
1089
+ $urls[] = '' ; // always add home page
1090
+ foreach ( $lines as $line ) {
1091
+ $line = ltrim(trim($line), '/') ;
1092
+ if ( $line != '' ) {
1093
+ if ( strpos($line, 'http') !== false ) {
1094
+ if ( strncasecmp($baseUrl, $line, $basen) == 0 ) {
1095
+ $urls[] = substr($line, $basen) ;
1096
  }
1097
  }
1098
  else {
1099
+ $urls[] = $line ;
1100
  }
1101
  }
1102
  }
1103
+ $urls = array_unique($urls) ;
1104
+ }
1105
+
1106
+ $this->_saveCrawlListFileData($listId, $urls) ;
1107
+
1108
+ return $urls ;
1109
+ }
1110
+
1111
+ protected function _generateAutoUrlList( $listId )
1112
+ {
1113
+ $storeId = $this->_meta[$listId]['storeid'] ;
1114
+ $tagurls = $this->_maintainAutoList($listId);
1115
+ if (!$tagurls) {
1116
+ $file = $this->_listDir . DS . '_AUTO_STORE_' . $storeId ;
1117
+ if ( ! file_exists($file) ) {
1118
+ return array() ;
1119
+ }
1120
+ $tagurls = unserialize(file_get_contents($file)) ;
1121
+ if ( ! is_array($tagurls) ) {
1122
+ return array() ; // bad file
1123
+ }
1124
  }
1125
+ $urls = array();
1126
+ foreach ($tagurls as $tag => $turls) {
1127
+ foreach ($turls as $url => $v) {
1128
+ $tagurl = '{' . $tag . '}';
1129
+ if ($v == 2) // for ajax
1130
+ $tagurl .= ':';
1131
+ $tagurl .= $url;
1132
+ $urls[] = $tagurl;
1133
+ }
1134
+ }
1135
+
1136
+ $this->_saveCrawlListFileData($listId, $urls) ;
1137
 
1138
+ return $urls ;
1139
+ }
1140
 
1141
+ protected function _maintainAutoList($listId)
1142
+ {
1143
+ $storeId = $this->_meta[$listId]['storeid'] ;
1144
+ $pendingCacheId = 'LITEMAGE_AUTOURL_ADJ_S' . $storeId;
1145
+ $pending = null;
1146
+ if ( $result = Mage::app()->loadCache($pendingCacheId) ) {
1147
+ $pending = unserialize($result) ;
1148
+ }
1149
+ if (!$pending || !is_array($pending) || count($pending) <=1) {
1150
+ return null; // no pending tags
1151
+ }
1152
 
1153
+ $autoconf = $this->_helper->getAutoCollectConf($storeId);
1154
+ // array('collect' => 0, 'crawlDelta' => 0, 'crawlAuto' => 0, 'frame' => 0, 'remove' => 0, 'deep' => 0, 'deltaDeep' => 0) ;
 
 
 
 
1155
 
1156
+ $list = null;
1157
+
1158
+ $file = $this->_listDir . DS . '_AUTO_STORE_' . $storeId ;
1159
+ if ( file_exists($file) ) {
1160
+ $list = unserialize(file_get_contents($file)) ;
1161
+ }
1162
+ if ( ! is_array($list) ) {
1163
+ $list = array();
1164
+ }
1165
+ unset($pending['utctime']);
1166
+
1167
+ if (!$autoconf['collect']) {
1168
+ // only do single removal adjust
1169
+ foreach($pending as $tag => $pd) {
1170
+ if (isset($pd[1])) {
1171
+ foreach ($pd[1] as $url => $act) {
1172
+ if ($act == -1 && isset($list[$tag][$url])) {
1173
+ unset($list[$tag][$url]);
1174
+ }
1175
+ }
1176
+ }
1177
+ }
1178
+ }
1179
+ else {
1180
+ $now = time() - date('Z') ;
1181
+ foreach($pending as $tag => $pd) {
1182
+ $tagCacheId = 'LITEMAGE_AUTOURL_' . $tag;
1183
+ $tagUrls = null;
1184
+ if ( $result = Mage::app()->loadCache($tagCacheId) ) {
1185
+ $tagUrls = unserialize($result) ;
1186
+ }
1187
+ if (!$tagUrls || !isset($tagUrls[$storeId])) {
1188
+ // cache file changed, ignore
1189
+ continue;
1190
+ }
1191
+ $tagInitTime = $pd['t'];
1192
+ $cacheInitTime = $tagUrls[$storeId]['utctime'][0];
1193
+
1194
+ if (($pd[0] == 1) || (($now - $cacheInitTime) > $autoconf['frame'])) {
1195
+ // is full check
1196
+ $stu = $tagUrls[$storeId];
1197
+ $orig = &$tagUrls[$storeId];
1198
+ $newAutoUrls = array();
1199
+ foreach ( $stu as $level => $data ) {
1200
+ if ( $level === 'utctime' ) {
1201
+ $orig['utctime'] = array( $now, $now ) ; // reset window
1202
+ }
1203
+ else {
1204
+ if ( $level > $autoconf['deep'] ) {
1205
+ // only check removal
1206
+ unset($orig[$level]) ;
1207
+ continue ;
1208
+ }
1209
+
1210
+ foreach ( $data as $url => $ud ) {
1211
+ $visitorCount = $ud[0];
1212
+ $attr = $ud[1] ;
1213
+ // check if still qualify
1214
+ if ( (($attr & 8) == 0) // not cron cust
1215
+ && (($attr & 4) == 0) // not cron store
1216
+ && (($visitorCount >= $autoconf['collect']) // over add limit
1217
+ || (isset($list[$tag][$url]) && ($visitorCount >= $autoconf['remove']))) // over remove limit
1218
+ ) {
1219
+ $newAutoUrls[$url] = ($attr & 32) ? 2 : 1 ; // isajax = 2
1220
+ }
1221
+ // reset
1222
+ $orig[$level][$url] = array( 0, 0 ) ;
1223
+ }
1224
+ }
1225
+ }
1226
+
1227
+ $this->_helper->saveInternalCache(serialize($tagUrls), $tagCacheId) ;
1228
+
1229
+ if (!empty($newAutoUrls)) {
1230
+ $list[$tag] = $newAutoUrls; // refresh autolist
1231
+ }
1232
+ elseif (isset($list[$tag])) { // remove from autolist
1233
+ unset($list[$tag]);
1234
+ }
1235
+ }
1236
+ elseif (isset($pd[1])) { // only do url check, act: -1(remove), 1(add regular), 2(add ajax)
1237
+ foreach ($pd[1] as $url => $act) {
1238
+ if (isset($list[$tag][$url])) {
1239
+ // in list already, check if removal
1240
+ if ($act == -1) {
1241
+ unset($list[$tag][$url]);
1242
+ }
1243
+ }
1244
+ else if ($act == 1 || $act == 2) {
1245
+ $list[$tag][$url] = $act;
1246
+ }
1247
+ }
1248
+ if (empty($list[$tag])) {
1249
+ unset($list[$tag]);
1250
+ }
1251
+
1252
+ }
1253
+ }
1254
+ }
1255
+ if ( ! file_put_contents($file, serialize($list)) ) {
1256
+ $this->_debugLog('Failed to save AUTO list ' . $file) ;
1257
+ }
1258
+ else {
1259
+ chmod($file, 0644) ;
1260
+ Mage::app()->removeCache($pendingCacheId);
1261
+ }
1262
+ return $list;
1263
+ }
1264
+
1265
+ protected function _debugLog( $message, $level = 0 )
1266
+ {
1267
+ if ( $this->_isDebug ) {
1268
+ $message = str_replace("\n", ("\n" . $this->_debugTag . ' '), $message) ;
1269
+ Mage::log($this->_debugTag . ' ' . $message) ;
1270
+ }
1271
+ }
1272
 
1273
  }
app/code/community/Litespeed/Litemage/Model/Observer/Esi.php CHANGED
@@ -46,6 +46,7 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
46
  protected $_routeCache;
47
  protected $_injectedBlocks = array();
48
  protected $_startDynamic = false;
 
49
 
50
  protected function _construct()
51
  {
@@ -66,11 +67,24 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
66
  public function purgeUserPrivateCache( $eventObj )
67
  {
68
  if ( $this->_moduleEnabledForUser ) {
69
- $this->_helper->setPurgeHeader(array('*'), $eventObj->getEvent()->getName(), NULL, true) ;
70
  $this->_viewVary[] = 'env';
 
 
71
  }
72
  }
73
 
 
 
 
 
 
 
 
 
 
 
 
74
  //customer_login
75
  //other are captured when pre-dispatch by action name
76
  public function changeEnvCookie( $eventObj )
@@ -91,6 +105,12 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
91
  $req = Mage::app()->getRequest() ;
92
  $controller = $eventObj->getControllerAction();
93
  $curActionName = $controller->getFullActionName() ;
 
 
 
 
 
 
94
  $reason = '';
95
 
96
  if ($this->_helper->notCacheable()) {
@@ -101,7 +121,7 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
101
  return;
102
  }
103
 
104
- if (($lmdebug = $req->getParam('LITEMAGE_DEBUG')) !== NULL) {
105
  // either isDebug or IP match
106
  if ($this->_isDebug || $this->_config->isRestrainedIP() || $this->_config->isAdminIP()) {
107
  if ($lmdebug == 'SHOWHOLES') {
@@ -122,7 +142,7 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
122
  }
123
 
124
  if ($reason == '') {
125
- $reason = $this->_cannotCache($req, $curActionName);
126
  }
127
 
128
  if ($reason != '') {
@@ -147,7 +167,7 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
147
  $this->_setWholeRouteCache($curActionName, $controller);
148
  }
149
 
150
- if (($lmctrl = $req->getParam('LITEMAGE_CTRL')) !== NULL) {
151
  // either isDebug or IP match
152
  if ($this->_config->isAdminIP()) {
153
  if ($lmctrl == 'PURGE') {
@@ -172,11 +192,21 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
172
  }
173
  $this->_helper->setCacheControlFlag(Litespeed_Litemage_Helper_Esi::CHBM_CACHEABLE, $ttl) ;
174
 
175
- if (Mage::getSingleton('core/cookie')->get('litemage_cron') == Litespeed_Litemage_Model_Observer_Cron::USER_AGENT) {
 
 
 
 
 
 
 
 
176
  $currency = Mage::getSingleton('core/cookie')->get('currency');
177
  if ($currency != '')
178
  Mage::app()->getStore()->setCurrentCurrencyCode($currency);
179
  }
 
 
180
  }
181
 
182
  if ( $this->_isDebug ) {
@@ -186,10 +216,8 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
186
  }
187
 
188
  // return reason string. if can be cached, return false;
189
- protected function _cannotCache( $req, $curActionName )
190
  {
191
- $requrl = $req->getRequestString() ;
192
-
193
  if ( $req->isPost() ) {
194
  return 'POST';
195
  }
@@ -257,6 +285,10 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
257
  $this->_injectedBlocks[] = $block;
258
  }
259
  }
 
 
 
 
260
  }
261
 
262
  //controller_action_layout_generate_blocks_after
@@ -337,6 +369,8 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
337
  return;
338
  }
339
 
 
 
340
  if ( count($this->_viewVary) ) {
341
  // this needs to run before helper's beforeResponseSend
342
  Mage::Helper('litemage/viewvary')->persistViewVary($this->_viewVary) ;
@@ -344,8 +378,7 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
344
 
345
  $extraHeaders = $this->_helper->beforeResponseSend($resp) ;
346
 
347
- if (isset($this->_routeCache['cacheId']) && Mage::app()->useCache('layout')) {
348
- $tags = array(Litespeed_Litemage_Helper_Data::LITEMAGE_GENERAL_CACHE_TAG);
349
  $content = array();
350
  $content['body'] = $resp->getBody();
351
  $cheaders = array();
@@ -362,7 +395,7 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
362
  $content['respcode'] = $curRespCode;
363
  }
364
 
365
- Mage::app()->saveCache(serialize($content), $this->_routeCache['cacheId'], $tags);
366
  }
367
 
368
  if ($this->_isDebug) {
46
  protected $_routeCache;
47
  protected $_injectedBlocks = array();
48
  protected $_startDynamic = false;
49
+ protected $_internal = array();
50
 
51
  protected function _construct()
52
  {
67
  public function purgeUserPrivateCache( $eventObj )
68
  {
69
  if ( $this->_moduleEnabledForUser ) {
70
+ // do not purge all private, session is new anyway
71
  $this->_viewVary[] = 'env';
72
+ $this->_viewVary[] = 'review';
73
+ $this->_internal['purgeUserPrivateCache'] = 1;
74
  }
75
  }
76
 
77
+ protected function _catchMissedChecks()
78
+ {
79
+ if ($this->_internal['route_info'] == 'customer_account_loginPost') {
80
+ if (!isset($this->_internal['purgeUserPrivateCache']) && Mage::getSingleton('customer/session')->isLoggedIn()) {
81
+ $this->_viewVary[] = 'env';
82
+ $this->_viewVary[] = 'review';
83
+ $this->_internal['purgeUserPrivateCache'] = 1;
84
+ }
85
+ }
86
+ }
87
+
88
  //customer_login
89
  //other are captured when pre-dispatch by action name
90
  public function changeEnvCookie( $eventObj )
105
  $req = Mage::app()->getRequest() ;
106
  $controller = $eventObj->getControllerAction();
107
  $curActionName = $controller->getFullActionName() ;
108
+ $reqUrl = $req->getRequestString() ;
109
+
110
+ $this->_helper->setInternal(array('route_info' => $curActionName,
111
+ 'is_ajax' => $req->isXmlHttpRequest())); // here do not use isAjax()
112
+ $this->_internal['route_info'] = $curActionName;
113
+
114
  $reason = '';
115
 
116
  if ($this->_helper->notCacheable()) {
121
  return;
122
  }
123
 
124
+ if (($lmdebug = $req->getParam('LITEMAGE_DEBUG')) !== null) {
125
  // either isDebug or IP match
126
  if ($this->_isDebug || $this->_config->isRestrainedIP() || $this->_config->isAdminIP()) {
127
  if ($lmdebug == 'SHOWHOLES') {
142
  }
143
 
144
  if ($reason == '') {
145
+ $reason = $this->_cannotCache($req, $curActionName, $reqUrl);
146
  }
147
 
148
  if ($reason != '') {
167
  $this->_setWholeRouteCache($curActionName, $controller);
168
  }
169
 
170
+ if (($lmctrl = $req->getParam('LITEMAGE_CTRL')) !== null) {
171
  // either isDebug or IP match
172
  if ($this->_config->isAdminIP()) {
173
  if ($lmctrl == 'PURGE') {
192
  }
193
  $this->_helper->setCacheControlFlag(Litespeed_Litemage_Helper_Esi::CHBM_CACHEABLE, $ttl) ;
194
 
195
+ $fullUrl = ltrim($reqUrl, '/');
196
+ if (!empty($_SERVER['QUERY_STRING'])) {
197
+ $fullUrl .= '?' . $_SERVER['QUERY_STRING'];
198
+ }
199
+
200
+ $internalData = array( 'url' => $fullUrl);
201
+
202
+ if ( $cron = Mage::getSingleton('core/cookie')->get('litemage_cron') ) {
203
+ $internalData['cron'] = $cron;
204
  $currency = Mage::getSingleton('core/cookie')->get('currency');
205
  if ($currency != '')
206
  Mage::app()->getStore()->setCurrentCurrencyCode($currency);
207
  }
208
+ $this->_helper->setInternal($internalData);
209
+
210
  }
211
 
212
  if ( $this->_isDebug ) {
216
  }
217
 
218
  // return reason string. if can be cached, return false;
219
+ protected function _cannotCache( $req, $curActionName, $requrl )
220
  {
 
 
221
  if ( $req->isPost() ) {
222
  return 'POST';
223
  }
285
  $this->_injectedBlocks[] = $block;
286
  }
287
  }
288
+ elseif ($block instanceof Mage_Review_Block_Form) {
289
+ $this->_helper->initNickName($block);
290
+ $this->_viewVary[] = 'review';
291
+ }
292
  }
293
 
294
  //controller_action_layout_generate_blocks_after
369
  return;
370
  }
371
 
372
+ $this->_catchMissedChecks();
373
+
374
  if ( count($this->_viewVary) ) {
375
  // this needs to run before helper's beforeResponseSend
376
  Mage::Helper('litemage/viewvary')->persistViewVary($this->_viewVary) ;
378
 
379
  $extraHeaders = $this->_helper->beforeResponseSend($resp) ;
380
 
381
+ if (isset($this->_routeCache['cacheId']) && $this->_config->useInternalCache()) {
 
382
  $content = array();
383
  $content['body'] = $resp->getBody();
384
  $cheaders = array();
395
  $content['respcode'] = $curRespCode;
396
  }
397
 
398
+ $this->_config->saveInternalCache(serialize($content), $this->_routeCache['cacheId']);
399
  }
400
 
401
  if ($this->_isDebug) {
app/code/community/Litespeed/Litemage/Model/Observer/Purge.php CHANGED
@@ -26,8 +26,6 @@
26
  class Litespeed_Litemage_Model_Observer_Purge extends Varien_Event_Observer
27
  {
28
 
29
- const WARMUP_DELTA_CACHE_ID = 'litemage_warmup_delta' ;
30
-
31
  protected $_curProductId ;
32
 
33
  /**
@@ -81,7 +79,7 @@ class Litespeed_Litemage_Model_Observer_Purge extends Varien_Event_Observer
81
  $cacheTags[] = $type . '.' . $tag;
82
  }
83
  if (count($cacheTags)) {
84
- $this->_purgeTagByAdmin($cacheTags, 'by ID ' . $ids . ' (from cache management)');
85
  }
86
  }
87
  }
@@ -175,57 +173,82 @@ class Litespeed_Litemage_Model_Observer_Purge extends Varien_Event_Observer
175
  } catch ( Exception $e ) {
176
  Mage::helper('litemage/data')->debugMesg('Error on adminPurgeCatalogCategory: ' . $e->getMessage()) ;
177
  }
 
178
  }
179
 
180
  //admin catalog_product_save_commit_after
181
  public function adminPurgeCatalogProduct( $eventObj )
182
- {
183
- try {
184
- if ( Mage::helper('litemage/data')->moduleEnabled() ) {
185
- $product = $eventObj->getEvent()->getProduct() ;
186
- if ( $product != null ) {
187
- $this->_purgeByProduct($product, 'adminPurgeCatalogProduct') ;
188
- }
189
- }
190
- } catch ( Exception $e ) {
191
- Mage::helper('litemage/data')->debugMesg('Error on adminPurgeCatalogProduct: ' . $e->getMessage()) ;
192
- }
193
- }
194
-
195
- // global cataloginventory_stock_item_save_after
196
- public function purgeCatalogProductByStock_orig( $eventObj )
197
- {
198
- try {
199
- if ( Mage::helper('litemage/data')->moduleEnabled() ) {
200
- $item = $eventObj->getEvent()->getItem() ;
201
- if ( $item->getStockStatusChangedAutomatically() || ($item->getOriginalInventoryQty() <= 0 && $item->getQty() > 0 && $item->getQtyCorrection() > 0) ) {
202
- $product = Mage::getModel('catalog/product')->load($item->getProductId());
203
- $this->_purgeByProduct($product, 'purgeCatalogProductByStock') ;
204
- Mage::helper('litemage/data')->debugMesg("in cataloginventory_stock_item_save_after with qy change");
205
- }
206
- else {
207
- Mage::helper('litemage/data')->debugMesg("in cataloginventory_stock_item_save_after -- no change");
208
  }
209
- }
210
- } catch ( Exception $e ) {
211
- Mage::helper('litemage/data')->debugMesg('Error on purgeCatalogProductByStock: ' . $e->getMessage()) ;
212
- }
213
- }
214
 
 
215
  public function purgeCatalogProductByStock( $eventObj )
216
  {
217
  try {
218
- if ( Mage::helper('litemage/data')->moduleEnabled() ) {
 
219
  $item = $eventObj->getEvent()->getItem() ;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
 
221
- if ( $item->getStockStatusChangedAutomatically() ) {
 
222
  $product = Mage::getModel('catalog/product')->load($item->getProductId());
223
- $this->_purgeByProduct($product, 'purgeCatalogProductByStock - getStockStatusChangedAutomatically') ;
 
 
224
  }
225
- else if ($item->getOriginalInventoryQty() <= 0 && $item->getQty() > 0 && $item->getQtyCorrection() > 0 ) {
226
- $product = Mage::getModel('catalog/product')->load($item->getProductId());
227
- $this->_purgeByProduct($product, 'purgeCatalogProductByStock - qty ') ;
228
- }
229
  }
230
  } catch ( Exception $e ) {
231
  Mage::helper('litemage/data')->debugMesg('Error on purgeCatalogProductByStock: ' . $e->getMessage()) ;
@@ -251,11 +274,11 @@ class Litespeed_Litemage_Model_Observer_Purge extends Varien_Event_Observer
251
  }
252
  }
253
 
254
- protected function _purgeByProduct( $product, $reason )
255
  {
256
  $productId = $product->getId() ;
257
  if ( $this->_curProductId == $productId )
258
- return ; // already purged
259
  $this->_curProductId = $productId ;
260
 
261
  $cids = $product->getCategoryIds() ;
@@ -278,37 +301,27 @@ class Litespeed_Litemage_Model_Observer_Purge extends Varien_Event_Observer
278
  }
279
  }
280
 
281
- $cids = array_unique($cids) ;
282
- $pcids = array() ;
283
-
284
- foreach ( $cids as $cid ) {
285
- $tags[] = Litespeed_Litemage_Helper_Esi::TAG_PREFIX_CATEGORY . $cid ;
286
- $cat = Mage::getModel('catalog/category')->load($cid) ;
287
- $pcids = array_merge($pcids, $cat->getParentIds()) ;
288
- }
289
-
290
- $pcids = array_diff(array_unique($pcids), $cids) ;
291
- foreach ( $pcids as $cid ) {
292
- $cat = Mage::getModel('catalog/category')->load($cid) ;
293
- $dispmode = $cat->getDisplayMode() ;
294
- if ( $dispmode == Mage_Catalog_Model_Category::DM_PRODUCT || $dispmode == Mage_Catalog_Model_Category::DM_MIXED )
295
- $tags[] = Litespeed_Litemage_Helper_Esi::TAG_PREFIX_CATEGORY . $cid ;
296
- }
297
-
298
- $this->_purgeTagByAdmin($tags, $product->getName(), $reason) ;
 
 
299
  }
300
 
301
- /* protected function _addDelta($urls)
302
- {
303
- $app = Mage::app();
304
- if ($delta = $app->loadCache( self::WARMUP_DELTA_CACHE_ID )) {
305
- $delta .= "\n" . implode("\n", $urls);
306
- }
307
- else {
308
- $delta = time() . "\n" . implode("\n", $urls);
309
- }
310
- $tags = array(Litespeed_Litemage_Helper_Data::LITEMAGE_GENERAL_CACHE_TAG);
311
- $app->saveCache($delta, self::WARMUP_DELTA_CACHE_ID, $tags);
312
-
313
- } */
314
  }
26
  class Litespeed_Litemage_Model_Observer_Purge extends Varien_Event_Observer
27
  {
28
 
 
 
29
  protected $_curProductId ;
30
 
31
  /**
79
  $cacheTags[] = $type . '.' . $tag;
80
  }
81
  if (count($cacheTags)) {
82
+ $this->_purgeTagByAdmin($cacheTags, 'by tag ' . implode(',', $cacheTags) . ' (from cache management)');
83
  }
84
  }
85
  }
173
  } catch ( Exception $e ) {
174
  Mage::helper('litemage/data')->debugMesg('Error on adminPurgeCatalogCategory: ' . $e->getMessage()) ;
175
  }
176
+
177
  }
178
 
179
  //admin catalog_product_save_commit_after
180
  public function adminPurgeCatalogProduct( $eventObj )
181
+ {
182
+ try {
183
+ if ( Mage::helper('litemage/data')->moduleEnabled() ) {
184
+ $product = $eventObj->getEvent()->getProduct() ;
185
+ if ( ($product != null) &&
186
+ ( $tags = $this->_getPurgeProductTags($product, true)) ) {
187
+ $this->_purgeTagByAdmin($tags, $product->getName(), 'adminPurgeCatalogProduct - catalog_product_save_commit_after') ;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  }
189
+ }
190
+ } catch ( Exception $e ) {
191
+ Mage::helper('litemage/data')->debugMesg('Error on adminPurgeCatalogProduct: ' . $e->getMessage()) ;
192
+ }
193
+ }
194
 
195
+ // global cataloginventory_stock_item_save_after
196
  public function purgeCatalogProductByStock( $eventObj )
197
  {
198
  try {
199
+ $helper = Mage::helper('litemage/data');
200
+ if ( $helper->moduleEnabled() ) {
201
  $item = $eventObj->getEvent()->getItem() ;
202
+ $option = $helper->getConf(Litespeed_Litemage_Helper_Data::CFG_FLUSH_PRODCAT) ;
203
+
204
+ $changedauto = $item->getStockStatusChangedAutomatically() ;
205
+ $origqty = $item->getOriginalInventoryQty();
206
+ $qty = $item->getQty();
207
+ $qtycorrection = $item->getQtyCorrection();
208
+
209
+ $qtyChanged = $qtycorrection > 0;
210
+ $stockStatusChanged = $changedauto || ($origqty <= 0 && $qty > 0 && $qtycorrection > 0);
211
+
212
+ $purgeProd = false;
213
+ $purgeCategory = false;
214
+
215
+ switch ($option) {
216
+ case 1: // Only flush product and categories when stock status change
217
+ if ($stockStatusChanged) {
218
+ $purgeProd = true;
219
+ $purgeCategory = true;
220
+ }
221
+ break;
222
+ case 2: // Flush product when stock status change, do not flush categories
223
+ if ($stockStatusChanged) {
224
+ $purgeProd = true;
225
+ }
226
+ break;
227
+ case 3: // Always flush product and categories when qty/stock status change
228
+ if ($qtyChanged || $stockStatusChanged) {
229
+ $purgeProd = true;
230
+ $purgeCategory = true;
231
+ }
232
+ break;
233
+ case 0: // Flush product when qty/stock status change, flush categories only when stock status change
234
+ default:
235
+ if ($qtyChanged || $stockStatusChanged) {
236
+ $purgeProd = true;
237
+ }
238
+ if ($stockStatusChanged) {
239
+ $purgeCategory = true;
240
+ }
241
+
242
+ }
243
 
244
+ $reason = "in cataloginventory_stock_item_save_after option = $option purgeprod = $purgeProd purgeCategory = $purgeCategory statusChangedAuto = $changedauto , origQty = $origqty , qty = $qty, qtyCorrection = $qtycorrection";
245
+ if ($purgeProd) {
246
  $product = Mage::getModel('catalog/product')->load($item->getProductId());
247
+ if ($tags = $this->_getPurgeProductTags($product, $purgeCategory)) {
248
+ Mage::helper('litemage/esi')->setPurgeHeader($tags, $reason) ;
249
+ }
250
  }
251
+ Mage::helper('litemage/data')->debugMesg($reason);
 
 
 
252
  }
253
  } catch ( Exception $e ) {
254
  Mage::helper('litemage/data')->debugMesg('Error on purgeCatalogProductByStock: ' . $e->getMessage()) ;
274
  }
275
  }
276
 
277
+ protected function _getPurgeProductTags( $product, $purgeCategory )
278
  {
279
  $productId = $product->getId() ;
280
  if ( $this->_curProductId == $productId )
281
+ return null; // already purged
282
  $this->_curProductId = $productId ;
283
 
284
  $cids = $product->getCategoryIds() ;
301
  }
302
  }
303
 
304
+ if ($purgeCategory) {
305
+ $cids = array_unique($cids) ;
306
+ $pcids = array() ;
307
+
308
+ foreach ( $cids as $cid ) {
309
+ $tags[] = Litespeed_Litemage_Helper_Esi::TAG_PREFIX_CATEGORY . $cid ;
310
+ $cat = Mage::getModel('catalog/category')->load($cid) ;
311
+ $pcids = array_merge($pcids, $cat->getParentIds()) ;
312
+ }
313
+
314
+ $pcids = array_diff(array_unique($pcids), $cids) ;
315
+ foreach ( $pcids as $cid ) {
316
+ $cat = Mage::getModel('catalog/category')->load($cid) ;
317
+ $dispmode = $cat->getDisplayMode() ;
318
+ if ( $dispmode == Mage_Catalog_Model_Category::DM_PRODUCT || $dispmode == Mage_Catalog_Model_Category::DM_MIXED )
319
+ $tags[] = Litespeed_Litemage_Helper_Esi::TAG_PREFIX_CATEGORY . $cid ;
320
+ }
321
+ }
322
+
323
+ return $tags;
324
  }
325
 
326
+
 
 
 
 
 
 
 
 
 
 
 
 
327
  }
app/code/community/Litespeed/Litemage/controllers/EsiController.php CHANGED
@@ -90,6 +90,8 @@ class Litespeed_Litemage_EsiController extends Mage_Core_Controller_Front_Action
90
  break ;
91
  case 'getFormKey': $this->getFormKeyAction() ;
92
  break ;
 
 
93
  case 'getBlock': $this->getBlockAction() ;
94
  break ;
95
  case 'getMessage': $this->getMessageAction() ;
@@ -112,6 +114,11 @@ class Litespeed_Litemage_EsiController extends Mage_Core_Controller_Front_Action
112
  $this->_getSingle() ;
113
  }
114
 
 
 
 
 
 
115
  public function logAction()
116
  {
117
  $this->_getSingle() ;
@@ -196,42 +203,6 @@ class Litespeed_Litemage_EsiController extends Mage_Core_Controller_Front_Action
196
  return $out ;
197
  }
198
 
199
- protected function _renderEsiBlock1( $esiData, $saveLayout )
200
- {
201
- $blockIndex = $esiData->getLayoutAttribute('bi') ;
202
- $isFullLayout = $saveLayout ;
203
- $block = $this->_layout->getEsiBlock($blockIndex, $isFullLayout) ;
204
- if ( ! $block ) {
205
- if ( $this->_isDebug ) {
206
- $this->_config->debugMesg('cannot get esi block ' . $blockIndex) ;
207
- }
208
- return '' ;
209
- }
210
- try {
211
- $out = $block->toHtml() ;
212
- if ( $this->_env['translate_inline'] ) {
213
- Mage::getSingleton('core/translate_inline')->processResponseBody($out) ;
214
- }
215
- } catch ( Exception $e ) {
216
- if ( $this->_isDebug ) {
217
- $this->_config->debugMesg('_renderEsiBlock, exception for block ' . $blockIndex . ' : ' . $e->getMessage()) ;
218
- }
219
- }
220
-
221
- if ( $saveLayout && Mage::app()->useCache('layout') ) {
222
- $cacheId = $esiData->getLayoutCacheId() ;
223
- if ( $cacheId ) {
224
- $layoutXml = $block->getData('lm_xml') ;
225
- if ( $layoutXml ) {
226
- $tags = array( Litespeed_Litemage_Helper_Data::LITEMAGE_GENERAL_CACHE_TAG,
227
- Mage_Core_Model_Layout_Update::LAYOUT_GENERAL_CACHE_TAG ) ;
228
- Mage::app()->saveCache($layoutXml, $cacheId, $tags) ;
229
- }
230
- }
231
- }
232
- return $out ;
233
- }
234
-
235
  // return esiUrl
236
  protected function _setOriginalReq()
237
  {
@@ -338,38 +309,41 @@ class Litespeed_Litemage_EsiController extends Mage_Core_Controller_Front_Action
338
 
339
  foreach ( $this->_processed as $url => $esiData ) {
340
  if ( is_string($esiData) ) {
341
- $body .= $esiData ;
 
342
  }
343
  else {
344
  $inlineHtml = $esiData->getInlineHtml($esiInlineTag, $shared) ;
345
  $refreshed = $this->_refreshCacheEntry($url, $esiData, $inlineHtml) ;
346
- if ( $this->_isDebug ) {
347
- if ( $refreshed == -1 )
348
- $status = ':no_cache' ;
349
- elseif ( $refreshed == 0 )
350
- $status = '' ;
351
- elseif ( $refreshed == 1 )
352
- $status = ':upd_entry' ;
353
- elseif ( $refreshed == 2 )
354
- $status = ':upd_detail' ;
355
- elseif ( $refreshed == 3 )
356
- $status = ':match_shared' ;
357
 
 
358
  $status .= ' ' . $esiData->getBatchId() . ' ' ;
359
  $cacheId = $esiData->getLayoutCacheId() ;
360
  if ( $cacheId ) {
361
  $status .= substr($cacheId, 11, 10) . ' ' ;
362
  }
363
- $this->_config->debugMesg('out' . $status . substr($inlineHtml, 0, strpos($inlineHtml, "\n"))) ;
364
  }
365
- $body .= $inlineHtml ;
366
  }
 
367
  }
368
  $this->getResponse()->setBody($body) ;
369
 
370
- if ( $this->_env['cache_updated'] && Mage::app()->useCache('layout') ) {
371
- $tags = array( Litespeed_Litemage_Helper_Data::LITEMAGE_GENERAL_CACHE_TAG ) ;
372
- Mage::app()->saveCache(serialize($this->_esiCache), $this->_env['cache_id'], $tags) ;
 
373
  }
374
  }
375
 
@@ -385,11 +359,11 @@ class Litespeed_Litemage_EsiController extends Mage_Core_Controller_Front_Action
385
  $this->_processLayout($urllist);
386
  }
387
  else {
388
- $hanldes = $this->_env['defaultHandles'] ;
389
  if ( $batchId != Litespeed_Litemage_Model_EsiData::BATCH_HANLE ) {
390
- $hanldes = array_merge(explode(',', $batchId), $hanldes) ;
391
  }
392
- $this->_layout->loadHanleXml($hanldes) ;
393
  $this->_saveEsiXml($urllist);
394
  $this->_processLayout($urllist);
395
  }
@@ -402,7 +376,7 @@ class Litespeed_Litemage_EsiController extends Mage_Core_Controller_Front_Action
402
  $bi = $esiData->getLayoutAttribute('bi') ;
403
  if ( $block = $this->_layout->getBiBlock($bi) ) {
404
  if ($layoutXml = $block->getXmlString($bi) ) {
405
- $esiData->saveLayoutCache($this->_env['layout_unique'], $layoutXml);
406
  }
407
  }
408
  else {
@@ -411,7 +385,6 @@ class Litespeed_Litemage_EsiController extends Mage_Core_Controller_Front_Action
411
  }
412
  }
413
  }
414
-
415
  }
416
 
417
  protected function _processLayout($urllist)
@@ -423,7 +396,6 @@ class Litespeed_Litemage_EsiController extends Mage_Core_Controller_Front_Action
423
  $esiData->setRawOutput($output, $response->getHttpResponseCode()) ;
424
  $this->_processed[$url] = $esiData ;
425
  }
426
-
427
  }
428
 
429
  protected function _processDirect( $urllist )
@@ -433,6 +405,9 @@ class Litespeed_Litemage_EsiController extends Mage_Core_Controller_Front_Action
433
  case Litespeed_Litemage_Model_EsiData::ACTION_GET_FORMKEY:
434
  $this->_procDirectFormKey($esiData) ;
435
  break ;
 
 
 
436
  case Litespeed_Litemage_Model_EsiData::ACTION_LOG:
437
  $this->_procDirectLog($esiData) ;
438
  break ;
@@ -460,6 +435,17 @@ class Litespeed_Litemage_EsiController extends Mage_Core_Controller_Front_Action
460
  $esiData->setRawOutput($real_formkey) ;
461
  }
462
 
 
 
 
 
 
 
 
 
 
 
 
463
  protected function _procDirectLog( $esiData )
464
  {
465
  $data = $esiData->getData() ;
@@ -555,7 +541,7 @@ class Litespeed_Litemage_EsiController extends Mage_Core_Controller_Front_Action
555
  }
556
  }
557
 
558
- $this->_layout->getUpdate()->setCachePrefix($unique) ;
559
  }
560
 
561
  protected function _getShared( $url )
@@ -574,9 +560,11 @@ class Litespeed_Litemage_EsiController extends Mage_Core_Controller_Front_Action
574
  return -1 ;
575
  }
576
 
 
 
577
  if ( $this->_env['shared'] ) {
578
  if ( empty($this->_esiCache[$url]) ) {
579
- $this->_esiCache[$url] = $inlineHtml ;
580
  $this->_env['cache_updated'] = true ;
581
  return 2 ;
582
  }
@@ -585,11 +573,7 @@ class Litespeed_Litemage_EsiController extends Mage_Core_Controller_Front_Action
585
 
586
  if ( ! isset($this->_esiCache[$url]) ) {
587
  // insert if entry not exist
588
- if ( $esiData->getAction() == Litespeed_Litemage_Model_EsiData::ACTION_GET_FORMKEY )
589
- $this->_esiCache[$url] = self::ESICACHE_ENTRYONLY ;
590
- else
591
- $this->_esiCache[$url] = '' ;
592
-
593
  $this->_env['cache_updated'] = true ;
594
  return 1 ;
595
  }
90
  break ;
91
  case 'getFormKey': $this->getFormKeyAction() ;
92
  break ;
93
+ case 'getNickName': $this->getNickNameAction() ;
94
+ break ;
95
  case 'getBlock': $this->getBlockAction() ;
96
  break ;
97
  case 'getMessage': $this->getMessageAction() ;
114
  $this->_getSingle() ;
115
  }
116
 
117
+ public function getNickNameAction()
118
+ {
119
+ $this->_getSingle() ;
120
+ }
121
+
122
  public function logAction()
123
  {
124
  $this->_getSingle() ;
203
  return $out ;
204
  }
205
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  // return esiUrl
207
  protected function _setOriginalReq()
208
  {
309
 
310
  foreach ( $this->_processed as $url => $esiData ) {
311
  if ( is_string($esiData) ) {
312
+ $inlineHtml = $esiData;
313
+ $refreshed = 4; // direct string
314
  }
315
  else {
316
  $inlineHtml = $esiData->getInlineHtml($esiInlineTag, $shared) ;
317
  $refreshed = $this->_refreshCacheEntry($url, $esiData, $inlineHtml) ;
318
+ }
319
+ if ( $this->_isDebug ) {
320
+ switch ($refreshed) {
321
+ case -1: $status = ':no_cache' ; break;
322
+ case 1: $status = ':upd_entry' ; break;
323
+ case 2: $status = ':upd_detail' ; break;
324
+ case 3: $status = ':match_shared' ; break;
325
+ case 4: $status = ':use_shared ' ; break;
326
+ case 0:
327
+ default: $status = '';
328
+ }
329
 
330
+ if ($refreshed != 4) {
331
  $status .= ' ' . $esiData->getBatchId() . ' ' ;
332
  $cacheId = $esiData->getLayoutCacheId() ;
333
  if ( $cacheId ) {
334
  $status .= substr($cacheId, 11, 10) . ' ' ;
335
  }
 
336
  }
337
+ $this->_config->debugMesg('out' . $status . substr($inlineHtml, 0, strpos($inlineHtml, "\n"))) ;
338
  }
339
+ $body .= $inlineHtml ;
340
  }
341
  $this->getResponse()->setBody($body) ;
342
 
343
+
344
+
345
+ if ( $this->_env['cache_updated'] && $this->_config->useInternalCache() ) {
346
+ $this->_config->saveInternalCache(serialize($this->_esiCache), $this->_env['cache_id']) ;
347
  }
348
  }
349
 
359
  $this->_processLayout($urllist);
360
  }
361
  else {
362
+ $handles = $this->_env['defaultHandles'] ;
363
  if ( $batchId != Litespeed_Litemage_Model_EsiData::BATCH_HANLE ) {
364
+ $handles = array_merge(explode(',', $batchId), $handles) ;
365
  }
366
+ $this->_layout->loadHanleXml($handles) ;
367
  $this->_saveEsiXml($urllist);
368
  $this->_processLayout($urllist);
369
  }
376
  $bi = $esiData->getLayoutAttribute('bi') ;
377
  if ( $block = $this->_layout->getBiBlock($bi) ) {
378
  if ($layoutXml = $block->getXmlString($bi) ) {
379
+ $esiData->saveLayoutCache($this->_env['layout_unique'], $layoutXml, $this->_config);
380
  }
381
  }
382
  else {
385
  }
386
  }
387
  }
 
388
  }
389
 
390
  protected function _processLayout($urllist)
396
  $esiData->setRawOutput($output, $response->getHttpResponseCode()) ;
397
  $this->_processed[$url] = $esiData ;
398
  }
 
399
  }
400
 
401
  protected function _processDirect( $urllist )
405
  case Litespeed_Litemage_Model_EsiData::ACTION_GET_FORMKEY:
406
  $this->_procDirectFormKey($esiData) ;
407
  break ;
408
+ case Litespeed_Litemage_Model_EsiData::ACTION_GET_NICKNAME:
409
+ $this->_procDirectNickName($esiData) ;
410
+ break ;
411
  case Litespeed_Litemage_Model_EsiData::ACTION_LOG:
412
  $this->_procDirectLog($esiData) ;
413
  break ;
435
  $esiData->setRawOutput($real_formkey) ;
436
  }
437
 
438
+ protected function _procDirectNickName( $esiData )
439
+ {
440
+ $nickname = '';
441
+ $session = Mage::getSingleton('customer/session');
442
+ if ($session->isLoggedIn()) {
443
+ $nickname = Mage::helper('core')->escapeHtml($session->getCustomer()->getFirstname());
444
+ }
445
+
446
+ $esiData->setRawOutput($nickname) ;
447
+ }
448
+
449
  protected function _procDirectLog( $esiData )
450
  {
451
  $data = $esiData->getData() ;
541
  }
542
  }
543
 
544
+ $this->getLayout()->getUpdate()->setCachePrefix($unique) ;
545
  }
546
 
547
  protected function _getShared( $url )
560
  return -1 ;
561
  }
562
 
563
+ $isEntryOnly = ($esiData->getAction() == Litespeed_Litemage_Model_EsiData::ACTION_GET_FORMKEY );
564
+
565
  if ( $this->_env['shared'] ) {
566
  if ( empty($this->_esiCache[$url]) ) {
567
+ $this->_esiCache[$url] = $isEntryOnly ? self::ESICACHE_ENTRYONLY : $inlineHtml ;
568
  $this->_env['cache_updated'] = true ;
569
  return 2 ;
570
  }
573
 
574
  if ( ! isset($this->_esiCache[$url]) ) {
575
  // insert if entry not exist
576
+ $this->_esiCache[$url] = $isEntryOnly ? self::ESICACHE_ENTRYONLY : '' ;
 
 
 
 
577
  $this->_env['cache_updated'] = true ;
578
  return 1 ;
579
  }
app/code/community/Litespeed/Litemage/etc/config.xml CHANGED
@@ -26,7 +26,7 @@
26
  <config>
27
  <modules>
28
  <Litespeed_Litemage>
29
- <version>1.1.2</version>
30
  </Litespeed_Litemage>
31
  </modules>
32
  <global>
@@ -379,7 +379,8 @@
379
  <purge_tags>cart, wishlist</purge_tags>
380
  <!-- This is a composite grouping. The purge events for the blocks in this grouping are
381
  a combination of existing purge event sets from other groupings. By using purge_tags
382
- to reference these other groupings, you do not need to redefine these purge events. -->
 
383
  </toplinks>
384
  <compare>
385
  <access>private</access>
@@ -453,37 +454,46 @@
453
  <home_ttl>28800</home_ttl>
454
  <track_viewed>0</track_viewed>
455
  <diff_customergroup>0</diff_customergroup>
456
- <diff_cookie/>
457
  <alt_esi_syntax>0</alt_esi_syntax>
458
  </general>
459
  <warmup>
460
  <enable_warmup>0</enable_warmup>
 
461
  <load_limit>5</load_limit>
462
  <thread_limit>6</thread_limit>
463
  <max_time>360</max_time>
464
  <interval>21600</interval>
465
  <priority>100</priority>
466
  <multi_currency/>
 
 
 
 
 
 
 
 
 
467
  <custlist/>
468
- <custlist_priority>50</custlist_priority>
469
- <custlist_interval>7200</custlist_interval>
470
  </warmup>
471
  <default>
472
  <!-- Full or partial match on controller full action name for cacheable routes. Space, return, and comma separated -->
473
  <cache_routes><![CDATA[catalog cms contacts_index_index]]></cache_routes>
474
  <!-- Full or partial match on controller full action name for non-cacheable routes within cacheable routes. Space, return, and comma separated -->
475
  <nocache_subroutes><![CDATA[catalog_product_compare catalogsearch]]></nocache_subroutes>
476
- <!-- Entire response cached based on routes, same content for all urls, such as "cms_index_noRoute" for 404 pages. Space, return, and comma separated. -->
477
- <fullcache_routes><![CDATA[cms_index_noRoute]]></fullcache_routes>
478
  </default>
479
  <donotcache>
480
  <!-- configured through Admin Panel, do not update here. Customized settings will be picked up from database -->
481
  <cache_routes/>
482
  <nocache_subroutes/>
 
 
483
  <vars>no_cache</vars>
484
  <urls/>
485
  <welcome/>
486
  <toplinks/>
 
487
  <messages/>
488
  </donotcache>
489
  <test>
@@ -496,12 +506,20 @@
496
  <jobs>
497
  <litemage_warmup_cache>
498
  <schedule>
499
- <cron_expr>0,10,20,30,40,50 * * * *</cron_expr>
500
  </schedule>
501
  <run>
502
  <model>litemage/observer_cron::warmCache</model>
503
  </run>
504
  </litemage_warmup_cache>
 
 
 
 
 
 
 
 
505
  </jobs>
506
  </crontab>
507
  </config>
26
  <config>
27
  <modules>
28
  <Litespeed_Litemage>
29
+ <version>1.2.0</version>
30
  </Litespeed_Litemage>
31
  </modules>
32
  <global>
379
  <purge_tags>cart, wishlist</purge_tags>
380
  <!-- This is a composite grouping. The purge events for the blocks in this grouping are
381
  a combination of existing purge event sets from other groupings. By using purge_tags
382
+ to reference these other groupings, you do not need to redefine these purge events.
383
+ Different block name and additional purge tags can be defined in configuration screen. -->
384
  </toplinks>
385
  <compare>
386
  <access>private</access>
454
  <home_ttl>28800</home_ttl>
455
  <track_viewed>0</track_viewed>
456
  <diff_customergroup>0</diff_customergroup>
457
+ <flush_prodcat>0</flush_prodcat>
458
  <alt_esi_syntax>0</alt_esi_syntax>
459
  </general>
460
  <warmup>
461
  <enable_warmup>0</enable_warmup>
462
+ <server_ip/>
463
  <load_limit>5</load_limit>
464
  <thread_limit>6</thread_limit>
465
  <max_time>360</max_time>
466
  <interval>21600</interval>
467
  <priority>100</priority>
468
  <multi_currency/>
469
+ <autolist_interval>28800</autolist_interval>
470
+ <autolist_priority>300</autolist_priority>
471
+ <enable_autocollect>0</enable_autocollect>
472
+ <auto_collect_add>6</auto_collect_add>
473
+ <auto_collect_robot>1</auto_collect_robot>
474
+ <auto_collect_depth>2</auto_collect_depth>
475
+ <auto_collect_remove>0</auto_collect_remove>
476
+ <auto_collect_hours>48</auto_collect_hours>
477
+ <delta_depth>1</delta_depth>
478
  <custlist/>
 
 
479
  </warmup>
480
  <default>
481
  <!-- Full or partial match on controller full action name for cacheable routes. Space, return, and comma separated -->
482
  <cache_routes><![CDATA[catalog cms contacts_index_index]]></cache_routes>
483
  <!-- Full or partial match on controller full action name for non-cacheable routes within cacheable routes. Space, return, and comma separated -->
484
  <nocache_subroutes><![CDATA[catalog_product_compare catalogsearch]]></nocache_subroutes>
 
 
485
  </default>
486
  <donotcache>
487
  <!-- configured through Admin Panel, do not update here. Customized settings will be picked up from database -->
488
  <cache_routes/>
489
  <nocache_subroutes/>
490
+ <!-- Entire response cached based on routes, same content for all urls, such as "cms_index_noRoute" for 404 pages. Space, return, and comma separated. -->
491
+ <fullcache_routes><![CDATA[cms_index_noRoute]]></fullcache_routes>
492
  <vars>no_cache</vars>
493
  <urls/>
494
  <welcome/>
495
  <toplinks/>
496
+ <toplinkstag/>
497
  <messages/>
498
  </donotcache>
499
  <test>
506
  <jobs>
507
  <litemage_warmup_cache>
508
  <schedule>
509
+ <cron_expr>2,12,22,32,42,52 * * * *</cron_expr>
510
  </schedule>
511
  <run>
512
  <model>litemage/observer_cron::warmCache</model>
513
  </run>
514
  </litemage_warmup_cache>
515
+ <litemage_crawl_delta>
516
+ <schedule>
517
+ <cron_expr>*/5 * * * *</cron_expr>
518
+ </schedule>
519
+ <run>
520
+ <model>litemage/observer_cron::crawlDelta</model>
521
+ </run>
522
+ </litemage_crawl_delta>
523
  </jobs>
524
  </crontab>
525
  </config>
app/code/community/Litespeed/Litemage/etc/system.xml CHANGED
@@ -27,7 +27,7 @@
27
  <config>
28
  <tabs>
29
  <Litespeed_Litemage translate="label">
30
- <label>LiteMage Cache 1.1.2</label>
31
  <sort_order>5000</sort_order>
32
  </Litespeed_Litemage>
33
  </tabs>
@@ -128,15 +128,16 @@
128
  <show_in_website>1</show_in_website>
129
  <show_in_store>1</show_in_store>
130
  </diff_customergroup>
131
- <diff_cookie translate="label,comment">
132
- <label>Separate Cache Copy for Customized Cookie Values</label>
133
- <comment>This settings has been retired since 1.0.11 as using rewrite rules is more efficient. Add the below rewrite rule in .htaccess: <![CDATA[<br>]]>RewriteRule .* - [E=cache-vary:cookie_name]</comment>
134
- <frontend_type>label</frontend_type>
 
135
  <sort_order>70</sort_order>
136
  <show_in_default>1</show_in_default>
137
  <show_in_website>0</show_in_website>
138
  <show_in_store>0</show_in_store>
139
- </diff_cookie>
140
  <alt_esi_syntax translate="label,comment">
141
  <label>Use Alternative ESI Syntax</label>
142
  <comment>If the standard ESI include tags are being filtered by some extension(s) and causing ESI parser errors, you can enable Alternative ESI Syntax, which is known only by LiteMage and LiteSpeed Web Server. </comment>
@@ -204,6 +205,15 @@
204
  <show_in_website>0</show_in_website>
205
  <show_in_store>0</show_in_store>
206
  </nocache_subroutes>
 
 
 
 
 
 
 
 
 
207
  <vars translate="label,comment">
208
  <label>Do-Not-Cache GET Parameters</label>
209
  <comment>Comma-separated list of GET variables that prevents caching URLs within Cacheable Routes.</comment>
@@ -240,11 +250,20 @@
240
  <show_in_website>0</show_in_website>
241
  <show_in_store>0</show_in_store>
242
  </toplinks>
 
 
 
 
 
 
 
 
 
243
  <messages translate="label,comment">
244
  <label>Customized Block Names for "messages" Tag</label>
245
  <comment>Comma-separated list of customized block names associated with the "messages" tag. Only define here if the block is not derived from Mage_Core_Block_Messages.</comment>
246
  <frontend_type>text</frontend_type>
247
- <sort_order>70</sort_order>
248
  <show_in_default>1</show_in_default>
249
  <show_in_website>0</show_in_website>
250
  <show_in_store>0</show_in_store>
@@ -261,13 +280,23 @@
261
  <enable_warmup translate="label,comment">
262
  <label>Enable Cache Warm Up</label>
263
  <comment>Allow LiteMage to automatically warm up the cache. Magento cron job must be enabled.</comment>
264
- <frontend_type>select</frontend_type>
265
  <source_model>litemage/config_source_enableWarmUp</source_model>
266
  <sort_order>10</sort_order>
267
  <show_in_default>1</show_in_default>
268
  <show_in_website>1</show_in_website>
269
  <show_in_store>1</show_in_store>
 
270
  </enable_warmup>
 
 
 
 
 
 
 
 
 
271
  <load_limit translate="label,comment">
272
  <label>Only Run When Load Is Less Than</label>
273
  <comment>Warm up will only run when current server load is less than this limit.</comment>
@@ -300,7 +329,7 @@
300
  </max_time>
301
  <interval translate="label,comment">
302
  <label>Warm Up Interval (seconds)</label>
303
- <comment>Specify how often the full list is crawled. Crawler requests will always be served directly by the backend. If you set this interval to be less than the public TTL, your cache will always be kept warm.</comment>
304
  <frontend_type>text</frontend_type>
305
  <validate>validate-digits validate-digits-range digits-range-600-</validate>
306
  <sort_order>50</sort_order>
@@ -346,11 +375,116 @@ Each file listed should contain a list of custom-defined URLs (one per line). Th
346
  <validate>validate-customList</validate>
347
  <source_model>litemage/config_source_customerGroup</source_model>
348
  <backend_model>litemage/config_backend_warmUp</backend_model>
349
- <sort_order>85</sort_order>
350
  <show_in_default>0</show_in_default>
351
  <show_in_website>0</show_in_website>
352
  <show_in_store>1</show_in_store>
353
  </custlist>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
354
  </fields>
355
  </warmup>
356
 
@@ -371,11 +505,11 @@ Each file listed should contain a list of custom-defined URLs (one per line). Th
371
  <show_in_store>0</show_in_store>
372
  </allow_ips>
373
  <debug translate="label,comment">
374
- <label>Enable Debug</label>
375
  <comment>Prints additional information to /var/log/system.log for debugging purposes. (Ensure developer log is enabled.)
376
  <![CDATA[<span class="notice">Turn off for production use.</span>]]></comment>
377
  <frontend_type>select</frontend_type>
378
- <source_model>adminhtml/system_config_source_yesno</source_model>
379
  <sort_order>20</sort_order>
380
  <show_in_default>1</show_in_default>
381
  <show_in_website>0</show_in_website>
27
  <config>
28
  <tabs>
29
  <Litespeed_Litemage translate="label">
30
+ <label>LiteMage Cache 1.2.0</label>
31
  <sort_order>5000</sort_order>
32
  </Litespeed_Litemage>
33
  </tabs>
128
  <show_in_website>1</show_in_website>
129
  <show_in_store>1</show_in_store>
130
  </diff_customergroup>
131
+ <flush_prodcat translate="label,comment">
132
+ <label>Flush Product and Categories When Product Qty Changes</label>
133
+ <comment>Selection depends on whether product page shows quantity and whether category pages hide or label out of stock products.</comment>
134
+ <frontend_type>select</frontend_type>
135
+ <source_model>litemage/config_source_flushCategory</source_model>
136
  <sort_order>70</sort_order>
137
  <show_in_default>1</show_in_default>
138
  <show_in_website>0</show_in_website>
139
  <show_in_store>0</show_in_store>
140
+ </flush_prodcat>
141
  <alt_esi_syntax translate="label,comment">
142
  <label>Use Alternative ESI Syntax</label>
143
  <comment>If the standard ESI include tags are being filtered by some extension(s) and causing ESI parser errors, you can enable Alternative ESI Syntax, which is known only by LiteMage and LiteSpeed Web Server. </comment>
205
  <show_in_website>0</show_in_website>
206
  <show_in_store>0</show_in_store>
207
  </nocache_subroutes>
208
+ <fullcache_routes translate="label,comment">
209
+ <label>Full Route Action Cache</label>
210
+ <comment>Cache entire responses based on routes actions instead of URLs. The same content is cached for all URLs with this route action. For example, if all of your 404 pages are the same, you may add "cms_index_noRoute". This setting uses case sensitive exact matching and is space, comma, return separated.</comment>
211
+ <frontend_type>textarea</frontend_type>
212
+ <sort_order>25</sort_order>
213
+ <show_in_default>1</show_in_default>
214
+ <show_in_website>0</show_in_website>
215
+ <show_in_store>0</show_in_store>
216
+ </fullcache_routes>
217
  <vars translate="label,comment">
218
  <label>Do-Not-Cache GET Parameters</label>
219
  <comment>Comma-separated list of GET variables that prevents caching URLs within Cacheable Routes.</comment>
250
  <show_in_website>0</show_in_website>
251
  <show_in_store>0</show_in_store>
252
  </toplinks>
253
+ <toplinkstag translate="label,comment">
254
+ <label>Additional Purge Tags for "toplinks" Blocks</label>
255
+ <comment>The "toplinks" tag is associated with the "cart" and "wishlist" tags. This setting associates additional purge tags with the "toplinks" tag. For example, if you have minicompare on toplinks blocks you can add "compare" here. Tags are predefined in the config.xml file under litemage/esiblock. This setting uses a comma-separated list.</comment>
256
+ <frontend_type>text</frontend_type>
257
+ <sort_order>70</sort_order>
258
+ <show_in_default>1</show_in_default>
259
+ <show_in_website>0</show_in_website>
260
+ <show_in_store>0</show_in_store>
261
+ </toplinkstag>
262
  <messages translate="label,comment">
263
  <label>Customized Block Names for "messages" Tag</label>
264
  <comment>Comma-separated list of customized block names associated with the "messages" tag. Only define here if the block is not derived from Mage_Core_Block_Messages.</comment>
265
  <frontend_type>text</frontend_type>
266
+ <sort_order>80</sort_order>
267
  <show_in_default>1</show_in_default>
268
  <show_in_website>0</show_in_website>
269
  <show_in_store>0</show_in_store>
280
  <enable_warmup translate="label,comment">
281
  <label>Enable Cache Warm Up</label>
282
  <comment>Allow LiteMage to automatically warm up the cache. Magento cron job must be enabled.</comment>
283
+ <frontend_type>multiselect</frontend_type>
284
  <source_model>litemage/config_source_enableWarmUp</source_model>
285
  <sort_order>10</sort_order>
286
  <show_in_default>1</show_in_default>
287
  <show_in_website>1</show_in_website>
288
  <show_in_store>1</show_in_store>
289
+ <can_be_empty>1</can_be_empty>
290
  </enable_warmup>
291
+ <server_ip translate="label,comment">
292
+ <label>LiteMage Server IP</label>
293
+ <comment>Tell the crawler where the LiteMage cache server is located so it can directly hit the server instead of having to go through DNS lookup. Use this if LiteMage is behind a CDN or proxy server or on LiteSpeed Load Balancer in front of the crawler node.</comment>
294
+ <frontend_type>text</frontend_type>
295
+ <sort_order>15</sort_order>
296
+ <show_in_default>1</show_in_default>
297
+ <show_in_website>0</show_in_website>
298
+ <show_in_store>0</show_in_store>
299
+ </server_ip>
300
  <load_limit translate="label,comment">
301
  <label>Only Run When Load Is Less Than</label>
302
  <comment>Warm up will only run when current server load is less than this limit.</comment>
329
  </max_time>
330
  <interval translate="label,comment">
331
  <label>Warm Up Interval (seconds)</label>
332
+ <comment>Specify how often the full site map list is crawled. Crawler requests will always be served directly by the backend. If you set this interval to be less than the public TTL, your cache will always be kept warm.</comment>
333
  <frontend_type>text</frontend_type>
334
  <validate>validate-digits validate-digits-range digits-range-600-</validate>
335
  <sort_order>50</sort_order>
375
  <validate>validate-customList</validate>
376
  <source_model>litemage/config_source_customerGroup</source_model>
377
  <backend_model>litemage/config_backend_warmUp</backend_model>
378
+ <sort_order>90</sort_order>
379
  <show_in_default>0</show_in_default>
380
  <show_in_website>0</show_in_website>
381
  <show_in_store>1</show_in_store>
382
  </custlist>
383
+ <autolist_interval translate="label,comment">
384
+ <label>Auto Collect List Interval (seconds)</label>
385
+ <comment>Specify how often the auto collect list is crawled. The minimum value this can be set to is half the value of the public TTL. Values that are lower than that will be ignored.</comment>
386
+ <frontend_type>text</frontend_type>
387
+ <validate>validate-digits validate-digits-range digits-range-600-</validate>
388
+ <sort_order>100</sort_order>
389
+ <show_in_default>1</show_in_default>
390
+ <show_in_website>1</show_in_website>
391
+ <show_in_store>1</show_in_store>
392
+ </autolist_interval>
393
+ <autolist_priority translate="label,comment">
394
+ <label>Auto Collect List Priority</label>
395
+ <comment>The priority used when crawling the Auto Collect list. This value should be larger than 0, the lower the number, the higher the priority.</comment>
396
+ <frontend_type>text</frontend_type>
397
+ <validate>validate-digits validate-greater-than-zero</validate>
398
+ <sort_order>110</sort_order>
399
+ <show_in_default>1</show_in_default>
400
+ <show_in_website>1</show_in_website>
401
+ <show_in_store>1</show_in_store>
402
+ </autolist_priority>
403
+ <enable_autocollect translate="label,comment">
404
+ <label>Enable Auto Collect</label>
405
+ <comment>Enable automatically collecting additional URLs that are not currently being crawled. Once the list is fully collected, you can disable this collecting process and just crawl the collected URLs. This will also be disabled if Auto collected (deep crawling) URL list is not selected in the Enable Cache Warm Up setting.</comment>
406
+ <frontend_type>select</frontend_type>
407
+ <source_model>adminhtml/system_config_source_yesno</source_model>
408
+ <sort_order>115</sort_order>
409
+ <show_in_default>1</show_in_default>
410
+ <show_in_website>1</show_in_website>
411
+ <show_in_store>1</show_in_store>
412
+ </enable_autocollect>
413
+ <auto_collect_add translate="label,comment">
414
+ <label>Add to Auto Collect List</label>
415
+ <comment>Add additional URLs that are not currently being crawled if visited more than this number of times within the amount of time defined in the Auto Collect Time Frame setting. Only requests that hit backend can be counted.</comment>
416
+ <frontend_type>text</frontend_type>
417
+ <validate>validate-digits validate-greater-than-zero</validate>
418
+ <depends>
419
+ <enable_autocollect>1</enable_autocollect>
420
+ </depends>
421
+ <sort_order>120</sort_order>
422
+ <show_in_default>1</show_in_default>
423
+ <show_in_website>1</show_in_website>
424
+ <show_in_store>1</show_in_store>
425
+ </auto_collect_add>
426
+ <auto_collect_robot translate="label,comment">
427
+ <label>Include Robots in Auto Collect Visitor Count</label>
428
+ <comment>The value of this setting will tell LiteMage to include or exclude robots such as GoogleBots when determining which pages to add or remove from the Auto Collect List.</comment>
429
+ <frontend_type>select</frontend_type>
430
+ <source_model>adminhtml/system_config_source_yesno</source_model>
431
+ <depends>
432
+ <enable_autocollect>1</enable_autocollect>
433
+ </depends>
434
+ <sort_order>125</sort_order>
435
+ <show_in_default>1</show_in_default>
436
+ <show_in_website>1</show_in_website>
437
+ <show_in_store>1</show_in_store>
438
+ </auto_collect_robot>
439
+ <auto_collect_depth translate="label,comment">
440
+ <label>Auto Collect Depth</label>
441
+ <comment>The maximum number of GET parameters a URL can contain and still be auto collected. Valid range is 0 to 10.</comment>
442
+ <frontend_type>text</frontend_type>
443
+ <validate>validate-digits validate-digits-range digits-range-0-10</validate>
444
+ <depends>
445
+ <enable_autocollect>1</enable_autocollect>
446
+ </depends>
447
+ <sort_order>130</sort_order>
448
+ <show_in_default>1</show_in_default>
449
+ <show_in_website>1</show_in_website>
450
+ <show_in_store>1</show_in_store>
451
+ </auto_collect_depth>
452
+ <auto_collect_remove translate="label,comment">
453
+ <label>Remove from Auto Collect List</label>
454
+ <comment>Remove from Auto Collect List if a URL is visited less than this number of times (excluding LiteMage Crawlers) within the amount of time defined in the Auto Collect Time Frame. This will actively keep the Auto Collect List from growing too large. This should be set to a lower value than the Add to Auto Collect List Setting. If this is set to 0, only 404 pages will be removed from the Auto Collect List.</comment>
455
+ <frontend_type>text</frontend_type>
456
+ <validate>validate-digits validate-digits-range digits-range-0-</validate>
457
+ <depends>
458
+ <enable_autocollect>1</enable_autocollect>
459
+ </depends>
460
+ <sort_order>140</sort_order>
461
+ <show_in_default>1</show_in_default>
462
+ <show_in_website>1</show_in_website>
463
+ <show_in_store>1</show_in_store>
464
+ </auto_collect_remove>
465
+ <auto_collect_hours translate="label,comment">
466
+ <label>Auto Collect Time Frame (hours)</label>
467
+ <comment>Auto collect counter will be reset after this time frame.</comment>
468
+ <frontend_type>text</frontend_type>
469
+ <validate>validate-digits validate-greater-than-zero</validate>
470
+ <depends>
471
+ <enable_autocollect>1</enable_autocollect>
472
+ </depends>
473
+ <sort_order>150</sort_order>
474
+ <show_in_default>1</show_in_default>
475
+ <show_in_website>1</show_in_website>
476
+ <show_in_store>1</show_in_store>
477
+ </auto_collect_hours>
478
+ <delta_depth translate="label,comment">
479
+ <label>Delta Crawl Depth</label>
480
+ <comment>After a tag is purged, if delta crawl is enabled, a delta URL list will be created. Set a limit on the number of GET parameters that a URL can have and still be included in the delta list. This value must be less than auto collect depth. Valid range is 0 to 3.</comment>
481
+ <frontend_type>text</frontend_type>
482
+ <validate>validate-digits validate-digits-range digits-range-0-3</validate>
483
+ <sort_order>160</sort_order>
484
+ <show_in_default>1</show_in_default>
485
+ <show_in_website>1</show_in_website>
486
+ <show_in_store>1</show_in_store>
487
+ </delta_depth>
488
  </fields>
489
  </warmup>
490
 
505
  <show_in_store>0</show_in_store>
506
  </allow_ips>
507
  <debug translate="label,comment">
508
+ <label>Enable Debug Log</label>
509
  <comment>Prints additional information to /var/log/system.log for debugging purposes. (Ensure developer log is enabled.)
510
  <![CDATA[<span class="notice">Turn off for production use.</span>]]></comment>
511
  <frontend_type>select</frontend_type>
512
+ <source_model>litemage/config_source_enableDebugLog</source_model>
513
  <sort_order>20</sort_order>
514
  <show_in_default>1</show_in_default>
515
  <show_in_website>0</show_in_website>
app/design/adminhtml/default/default/template/litemage/cache_management.phtml CHANGED
@@ -137,7 +137,7 @@ if ($status = $this->getCrawlerStatus()) : ?>
137
  <div class="content-header">
138
  <table class="form-list" cellspacing="0">
139
  <tr>
140
- <td><h3><?php echo $lmhelper->__('LiteMage Crawler Warm-up Status') ?><button type="submit" class="scalable"><span><?php echo $lmhelper->__('Refresh') ?></span></button></h3></td>
141
  </tr>
142
  <tr><td class="scope-label"><?php echo $lmhelper->__('You can click Reset All / Reset links below to restart a crawler queue.') ?></td></tr>
143
  </table>
@@ -153,7 +153,7 @@ if ($status = $this->getCrawlerStatus()) : ?>
153
  <th class="no-link a-right"><?php echo $lmhelper->__('Prioirty') . '<br>' . $lmhelper->__('Run Interval (secs)')
154
  . '<br>' . $lmhelper->__('Public TTL (secs)'); ?>
155
  </th>
156
- <th class="no-link a-center"><?php echo $lmhelper->__('Generated') . '<br>' . $lmhelper->__('Finished') . '<br>' . $lmhelper->__('Last Query Time'); ?></th>
157
  <th class="no-link"><?php echo $lmhelper->__('Environment') . '<br>' . $lmhelper->__('Current Vary'); ?></th>
158
  <th class="no-link a-right"><?php echo $lmhelper->__('Current Position') . ' | ' . $lmhelper->__('List Size') . '<br>' . $lmhelper->__('Total Queried')
159
  . '<br>' . $lmhelper->__('Current Status'); ?></th>
@@ -167,7 +167,7 @@ if ($status = $this->getCrawlerStatus()) : ?>
167
  . '"> </a><br/> <a href="' . $status['url_reset'] . '?list=' . $s['id'] . '" title="Click to reset this crawler queue">' . $lmhelper->__('Reset') . '</a></td>'
168
  . '<td>' . $s['store_name']. ' ('. $s['default_curr'] . ')<br>'. $s['baseurl'] . '<br>' . $s['file'] . '</td>'
169
  . '<td class="a-right">' . $s['priority'] . '<br>' . $s['interval'] . '<br>' . $s['ttl'] . '</td>'
170
- . '<td class="a-center">' . $s['gentime'] . '<br>' . $s['endtime'] . '<br>' . $s['lastquerytime'] . '</td>'
171
  . '<td>' . $s['env'] . '<br>' . $s['curvary'] . '</td>'
172
  . '<td class="a-right">Current Position: ' . $s['curpos'] . ' | List Size: ' . $s['listsize'] . ' <br>Total Queried: '. $s['queried'] . '<br>' . $s['tmpmsg'] . '</td>'
173
  . "</tr>\n";
137
  <div class="content-header">
138
  <table class="form-list" cellspacing="0">
139
  <tr>
140
+ <td><h3><?php echo $lmhelper->__('LiteMage Crawler Warm-up Status') ?> <button type="submit" class="scalable"><span><?php echo $lmhelper->__('Refresh') ?></span></button></h3></td>
141
  </tr>
142
  <tr><td class="scope-label"><?php echo $lmhelper->__('You can click Reset All / Reset links below to restart a crawler queue.') ?></td></tr>
143
  </table>
153
  <th class="no-link a-right"><?php echo $lmhelper->__('Prioirty') . '<br>' . $lmhelper->__('Run Interval (secs)')
154
  . '<br>' . $lmhelper->__('Public TTL (secs)'); ?>
155
  </th>
156
+ <th class="no-link a-center"><?php echo $lmhelper->__('Last Round Finish Time') . '<br>' . $lmhelper->__('Generate Time | Finish Time') . '<br>' . $lmhelper->__('Last Query Time'); ?></th>
157
  <th class="no-link"><?php echo $lmhelper->__('Environment') . '<br>' . $lmhelper->__('Current Vary'); ?></th>
158
  <th class="no-link a-right"><?php echo $lmhelper->__('Current Position') . ' | ' . $lmhelper->__('List Size') . '<br>' . $lmhelper->__('Total Queried')
159
  . '<br>' . $lmhelper->__('Current Status'); ?></th>
167
  . '"> </a><br/> <a href="' . $status['url_reset'] . '?list=' . $s['id'] . '" title="Click to reset this crawler queue">' . $lmhelper->__('Reset') . '</a></td>'
168
  . '<td>' . $s['store_name']. ' ('. $s['default_curr'] . ')<br>'. $s['baseurl'] . '<br>' . $s['file'] . '</td>'
169
  . '<td class="a-right">' . $s['priority'] . '<br>' . $s['interval'] . '<br>' . $s['ttl'] . '</td>'
170
+ . '<td class="a-center">' . $s['lastendtime'] . '<br>' . $s['gentime'] . ' | ' . $s['endtime'] . '<br>' . $s['lastquerytime'] . '</td>'
171
  . '<td>' . $s['env'] . '<br>' . $s['curvary'] . '</td>'
172
  . '<td class="a-right">Current Position: ' . $s['curpos'] . ' | List Size: ' . $s['listsize'] . ' <br>Total Queried: '. $s['queried'] . '<br>' . $s['tmpmsg'] . '</td>'
173
  . "</tr>\n";
package.xml CHANGED
@@ -1,19 +1,24 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>LiteSpeed_LiteMage</name>
4
- <version>1.1.2</version>
5
  <stability>stable</stability>
6
- <license uri="https://opensource.org/licenses/GPL-3.0">GPLv3</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>LiteMage Cache speeds up Magento by automatically integrating Magento with LiteSpeed's superior ESI implementation.</summary>
10
  <description>LiteMage Cache is a powerful Magento page caching utility built into LiteSpeed Web Server. It combines superior ESI implementation with easy set up. LiteMage Cache contains a number of optimizations, including combined subrequests, that give it faster, more efficient performance than other page caching utilities. In addition, because it is part of the web server, LiteMage Cache does away with the communication problems and overhead other page caching solutions suffer from. The LiteMage Magento extension then automatically integrates Magento installations with LiteSpeed's top-of-the-line ESI implementation, combining the greatest Magento performance enhancement possible with a painless set up.</description>
11
- <notes>Added cached objects counter and statistics to the Cache Management page.&#xD;
12
- Fixed a bug that could result in a blank page after LiteMage installation.</notes>
 
 
 
 
 
13
  <authors><author><name>LiteSpeed Technologies</name><user>LiteSpeedTech</user><email>lsong@litespeedtech.com</email></author></authors>
14
- <date>2016-06-17</date>
15
- <time>18:40:32</time>
16
- <contents><target name="magecommunity"><dir name="Litespeed"><dir name="Litemage"><dir name="Block"><dir name="Adminhtml"><dir name="Cache"><file name="Management.php" hash="c84719997fb95a4f0cff711f20de08bd"/></dir></dir><dir name="Core"><file name="Esi.php" hash="32da90253e38aedf67a8c4619bfc983b"/><file name="Messages.php" hash="da581eb4adaa1ac4e2d4b86ff30f08d4"/><file name="Xml.php" hash="6c7d088368f06151be14609dde9afade"/></dir><dir name="Inject"><file name="Jsvar.php" hash="cc0590fe211c81d6d29de570503fe8fd"/><file name="Nickname.php" hash="3edf87b7d3f3da4093110bd4c98e0738"/></dir></dir><dir name="Helper"><file name="Data.php" hash="0b4db22d27711c3c5b79da2b35b9841d"/><file name="Esi.php" hash="c8223dd743cfadacb811bbc4e46aa487"/><file name="Viewvary.php" hash="00b51b413114123c8e5d7bfd44e1cfdc"/></dir><dir name="Model"><dir name="Config"><dir name="Backend"><file name="WarmUp.php" hash="663ecf7689115059eb94898f37adeb6f"/></dir><dir name="Source"><file name="CustomerGroup.php" hash="2aa52d9a1614a545035267958be0656f"/><file name="EnableWarmUp.php" hash="d32dd158463297672dfb58628007a88c"/></dir></dir><file name="EsiData.php" hash="5a7fa9094a5286e317a15d7dc133676b"/><file name="EsiLayout.php" hash="8e382410414f467c69e818380872113e"/><dir name="Layout"><file name="EsiUpdate.php" hash="d11658321942742ba38cad1a7558f1f6"/><file name="Master.php" hash="1fae1314f099070df8637f53e0d2d1f2"/><file name="Update.php" hash="bc4b131d642853f009b6278b06843885"/></dir><dir name="Observer"><file name="Cron.php" hash="f62a6d3778b9f7678dc58cac5b580cdb"/><file name="Esi.php" hash="916293a6e45da6d2f2663a9f3908e4e8"/><file name="Purge.php" hash="4945c3659507ec3d00390a6273287899"/></dir><file name="Session.php" hash="558a80fb45a532af59727ae5657cd380"/><file name="Translate.php" hash="35326b8d2214f516d7dba82519902529"/></dir><dir name="controllers"><file name="AdminController.php" hash="d4d81dfdcb28354a7aabd9d9f6f10c86"/><dir name="Adminhtml"><file name="LitemageCacheController.php" hash="18b8cd29b5cf0fe20bd8d18d515fd79d"/></dir><file name="EsiController.php" hash="8bce324af8bfbcd085fe4b8f020e4db8"/></dir><dir name="etc"><file name="config.xml" hash="b105a16dd71e90295ed4c37a817fdaed"/><file name="system.xml" hash="3a4e5fa00857741522977101b1ad696b"/></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="litemage.xml" hash="70c8a6fc5f5eaf99b8c0648a33bb3b7d"/></dir><dir name="template"><dir name="litemage"><file name="cache_management.phtml" hash="17f174bf28b463d13938e4ac42678260"/></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="litemage.xml" hash="4c840b12cc6246f68b1b028f0ef1056d"/></dir><dir name="template"><dir name="litemage"><dir name="inject"><file name="jsvar.phtml" hash="5bbd9992e7ba5925d09f21cf03237676"/></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Litespeed_Litemage.xml" hash="ba0c8904bc89219c6829e37cc14d9bdd"/></dir></target></contents>
17
  <compatible/>
18
  <dependencies><required><php><min>5.3.0</min><max>7.1.0</max></php></required></dependencies>
19
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>LiteSpeed_LiteMage</name>
4
+ <version>1.2.0</version>
5
  <stability>stable</stability>
6
+ <license uri="https://opensource.org/licenses/GPL-3.0 ">GPL v3</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>LiteMage Cache speeds up Magento by automatically integrating Magento with LiteSpeed's superior ESI implementation.</summary>
10
  <description>LiteMage Cache is a powerful Magento page caching utility built into LiteSpeed Web Server. It combines superior ESI implementation with easy set up. LiteMage Cache contains a number of optimizations, including combined subrequests, that give it faster, more efficient performance than other page caching utilities. In addition, because it is part of the web server, LiteMage Cache does away with the communication problems and overhead other page caching solutions suffer from. The LiteMage Magento extension then automatically integrates Magento installations with LiteSpeed's top-of-the-line ESI implementation, combining the greatest Magento performance enhancement possible with a painless set up.</description>
11
+ <notes>Fixed a bug that caused errors when receiving soap api requests.&#xD;
12
+ Added auto-collect feature to collect URLs not included in the sitemap including deep urls with different filter selections.&#xD;
13
+ Added Delta crawler, URLs related to purged tags will now be recrawled.&#xD;
14
+ Added settings allowing customization of product page and related category purging on product quantity or stock status changes.&#xD;
15
+ LiteMage will now auto detect and set cache varies for product pages based on whether the review form is displayed and whether your site allows guests to write reviews.&#xD;
16
+ Improved compatibility with third party themes including MT themes.&#xD;
17
+ </notes>
18
  <authors><author><name>LiteSpeed Technologies</name><user>LiteSpeedTech</user><email>lsong@litespeedtech.com</email></author></authors>
19
+ <date>2016-08-05</date>
20
+ <time>19:01:23</time>
21
+ <contents><target name="magecommunity"><dir name="Litespeed"><dir name="Litemage"><dir name="Block"><dir name="Adminhtml"><dir name="Cache"><file name="Management.php" hash="126c636bebf6a1933f45781d6e95863d"/></dir></dir><dir name="Core"><file name="Dummy.php" hash="ae50751905056dd3eb34c3222d17a310"/><file name="Esi.php" hash="32da90253e38aedf67a8c4619bfc983b"/><file name="Messages.php" hash="da581eb4adaa1ac4e2d4b86ff30f08d4"/><file name="Xml.php" hash="6c7d088368f06151be14609dde9afade"/></dir><dir name="Inject"><file name="Jsvar.php" hash="cc0590fe211c81d6d29de570503fe8fd"/><file name="Nickname.php" hash="deba1efffd6449b6492bb13aaca4658b"/></dir></dir><dir name="Helper"><file name="Data.php" hash="9184238289204d961e826308e32ac8d8"/><file name="Esi.php" hash="aaffc0c2b0f43a0748ade48efaf1a22b"/><file name="Viewvary.php" hash="04f39f2d726a3c92f83ff53abdf4cffe"/></dir><dir name="Model"><dir name="Config"><dir name="Backend"><file name="WarmUp.php" hash="663ecf7689115059eb94898f37adeb6f"/></dir><dir name="Source"><file name="CustomerGroup.php" hash="2aa52d9a1614a545035267958be0656f"/><file name="EnableDebugLog.php" hash="27d4b6030f564dfae8c89a84264b1175"/><file name="EnableWarmUp.php" hash="f44aafa2f6ba65a0e4926b7635ff264d"/><file name="FlushCategory.php" hash="b8017a1859b320f05af272f4d4e442e2"/></dir></dir><file name="EsiData.php" hash="2617769575cfb9eadf6c41cd47cc596a"/><file name="EsiLayout.php" hash="26bef4ee2a873ecb26ba7f292cfe0fd6"/><dir name="Layout"><file name="EsiUpdate.php" hash="3c98a2961b08f0acb3d334ab932eb397"/><file name="Master.php" hash="1fae1314f099070df8637f53e0d2d1f2"/><file name="Update.php" hash="6e191bf888804a7f9181d3d402912b7e"/></dir><dir name="Observer"><file name="Cron.php" hash="e6705d90a5b5e14cd2136ce06bb76caf"/><file name="Esi.php" hash="a1f69c44b7cbab2a82bd7f6323f46bd7"/><file name="Purge.php" hash="adc0e613f232c6df400e21fbdd21f0f8"/></dir><file name="Session.php" hash="558a80fb45a532af59727ae5657cd380"/><file name="Translate.php" hash="35326b8d2214f516d7dba82519902529"/></dir><dir name="controllers"><file name="AdminController.php" hash="d4d81dfdcb28354a7aabd9d9f6f10c86"/><dir name="Adminhtml"><file name="LitemageCacheController.php" hash="18b8cd29b5cf0fe20bd8d18d515fd79d"/></dir><file name="EsiController.php" hash="a4bbb66f836d6476447b85cd1dec9184"/></dir><dir name="etc"><file name="config.xml" hash="02fefc19e35785b5b80d39e9d4190d07"/><file name="system.xml" hash="e79509ff5a7d0e21c5ebac4108efdde3"/></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="litemage.xml" hash="70c8a6fc5f5eaf99b8c0648a33bb3b7d"/></dir><dir name="template"><dir name="litemage"><file name="cache_management.phtml" hash="e534a8cf2c6db8df170edd58c4f679fa"/></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="litemage.xml" hash="4c840b12cc6246f68b1b028f0ef1056d"/></dir><dir name="template"><dir name="litemage"><dir name="inject"><file name="jsvar.phtml" hash="5bbd9992e7ba5925d09f21cf03237676"/></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Litespeed_Litemage.xml" hash="ba0c8904bc89219c6829e37cc14d9bdd"/></dir></target></contents>
22
  <compatible/>
23
  <dependencies><required><php><min>5.3.0</min><max>7.1.0</max></php></required></dependencies>
24
  </package>