LiteSpeed_LiteMage - Version 1.1.0

Version Notes

Added a Home Page TTL setting.
Added support for multiple custom URL warm-up list per store with different intervals and priorities
Added support for setting a different default vary cookie name through .htaccess to avoid conflicts with other LiteSpeed Cache plugins.
Updated esi:include URLs to be compatible with LiteSpeed Load Balancer’s PageSpeed module.
Improved ESI block detection and hole punching accuracy.
URL Blacklist will now perform an exact match unless an “*” is added.
Fixed a bug where non-cacheable pages that redirected to a 404 page where mistakenly cached.

Download this release

Release Info

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


Code changes from version 1.0.18 to 1.1.0

app/code/community/Litespeed/Litemage/Block/Core/Esi.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * LiteMage
4
  *
@@ -21,54 +22,53 @@
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
-
26
  class Litespeed_Litemage_Block_Core_Esi extends Mage_Core_Block_Abstract
27
  {
28
- public function initByPeer( $peer, $esiHtml )
29
- {
30
- $this->setData('esiHtml', $esiHtml) ;
31
- $peer->setData('litemageInjected', 1);
32
 
33
- $this->_layout = $peer->_layout;
34
- $this->_nameInLayout = $peer->_nameInLayout ;
35
- $this->_alias = $peer->_alias;
36
- $parent = $peer->getParentBlock();
37
- if ($parent != null) {
38
- $parent->setChild($peer->_alias, $this) ;
39
- }
40
- $this->_layout->setBlock($this->_nameInLayout, $this) ;
 
 
 
 
 
 
 
 
 
 
 
41
 
42
- if (!$this->hasData('valueonly') && Mage::registry('LITEMAGE_SHOWHOLES')) {
43
- $tip = 'LiteMage ESI block ' . $this->_nameInLayout;
44
- $wrapperBegin = '<div style="position:relative;border:1px dotted red;background-color:rgba(198,245,174,0.3);margin:2px;padding:18px 2px 2px 2px;zoom:1;" title="' . $tip
45
- . '"><div style="position: absolute; left: 0px; top: 0px; padding: 2px 5px; color: white; font-style: normal; font-variant: normal; font-weight: normal; font-size: 11px; line-height: normal; font-family: Arial; z-index: 998; text-align: left !important; background: rgba(0,100,0,0.5);">' . $tip . '</div>';
46
- $this->setData('lmwrapperBegin', $wrapperBegin);
47
- $this->setData('lmwrapperEnd', '</div>');
48
- }
49
 
50
- }
 
51
 
52
- protected function _loadCache()
53
- {
54
- if ($this->hasData('esiHtml')) {
55
- $esiHtml = $this->getData('esiHtml');
56
- Mage::helper('litemage/data')->debugMesg('Injected ESI block ' . $this->_nameInLayout . ' ' . $esiHtml) ;
57
 
58
- if (!$this->hasData('valueonly') && Mage::registry('LITEMAGE_SHOWHOLES'))
59
- return $this->getData('lmwrapperBegin') . $esiHtml . $this->getData('lmwrapperEnd') ;
60
- else {
61
- return $esiHtml;
62
- }
63
- }
64
- else {
65
- return false;
66
- }
67
- }
68
 
69
- protected function _saveCache($data)
70
- {
71
- return false;
72
- }
73
 
74
- }
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_Block_Core_Esi extends Mage_Core_Block_Abstract
26
  {
 
 
 
 
27
 
28
+ protected $_peer ;
29
+
30
+ public function initByPeer( $peer )
31
+ {
32
+ $this->_peer = $peer ;
33
+ $this->setData('litemage_bconf', $peer->getData('litemage_bconf')) ;
34
+
35
+ $this->_layout = $peer->_layout ;
36
+ $this->_nameInLayout = $peer->_nameInLayout ;
37
+ $this->_alias = $peer->_alias ;
38
+ if ( $parent = $peer->getParentBlock() ) {
39
+ $parent->setChild($peer->_alias, $this) ;
40
+ }
41
+
42
+ if ( $this->_layout->getBlock($peer->_nameInLayout) === $peer ) {
43
+ // some bad plugins with duplicated names may lost this block, only replace if same object
44
+ $this->_layout->setBlock($this->_nameInLayout, $this) ;
45
+ }
46
+ }
47
 
48
+ protected function _loadCache()
49
+ {
50
+ $esiHtml = Mage::helper('litemage/esi')->getEsiIncludeHtml($this) ;
51
+ if ( ! $esiHtml ) {
52
+ return false ;
53
+ }
 
54
 
55
+ $bconf = $this->getData('litemage_bconf') ;
56
+ Mage::helper('litemage/data')->debugMesg('Injected ESI block ' . $this->_nameInLayout . ' ' . $esiHtml) ;
57
 
58
+ if ( ! $bconf['valueonly'] && Mage::registry('LITEMAGE_SHOWHOLES') ) {
59
+ $tip = 'LiteMage ESI block ' . $this->_nameInLayout ;
60
+ $wrapperBegin = '<div style="position:relative;border:1px dotted red;background-color:rgba(198,245,174,0.3);margin:2px;padding:18px 2px 2px 2px;zoom:1;" title="' . $tip
61
+ . '"><div style="position: absolute; left: 0px; top: 0px; padding: 2px 5px; color: white; font-style: normal; font-variant: normal; font-weight: normal; font-size: 11px; line-height: normal; font-family: Arial; z-index: 998; text-align: left !important; background: rgba(0,100,0,0.5);">' . $tip . '</div>' ;
62
+ $wrapperEnd = '</div>' ;
63
 
64
+ return $wrapperBegin . $esiHtml . $wrapperEnd ;
65
+ }
66
+ return $esiHtml ;
67
+ }
 
 
 
 
 
 
68
 
69
+ protected function _saveCache( $data )
70
+ {
71
+ return false ;
72
+ }
73
 
74
+ }
app/code/community/Litespeed/Litemage/Block/Core/Messages.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * LiteMage
4
  *
@@ -21,324 +22,329 @@
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
-
26
  class Litespeed_Litemage_Block_Core_Messages extends Mage_Core_Block_Messages
27
  {
28
 
29
- protected $_isEsiInject = false ;
30
- protected $_hasSaved = false ;
31
- protected $_outputCall ;
32
-
33
- /*Override Mage_Core_Block_Abstract:getMessagesBlock */
34
- public function getMessagesBlock()
35
- {
36
- return $this;
37
- }
38
-
39
- public function initByPeer( $peer, $esiHtml )
40
- {
41
- $this->_isEsiInject = true ;
42
- $this->setData('esiHtml', $esiHtml) ;
43
- $peer->setData('litemageInjected', 1);
44
- $this->_layout = $peer->_layout;
45
- if ( $peer instanceof Mage_Core_Block_Messages ) {
46
- $this->_messagesBlock = $peer ;
47
- }
48
- else {
49
- $this->_messagesBlock = $this->_layout->getMessagesBlock();
50
- }
51
- $this->_nameInLayout = $peer->_nameInLayout ;
52
- $this->_alias = $peer->_alias;
53
- $parent = $peer->getParentBlock();
54
- if ($parent != null) {
55
- $parent->setChild($peer->_alias, $this) ;
56
- }
57
- $this->_layout->setBlock($this->_nameInLayout, $this) ;
58
-
59
- if (Mage::registry('LITEMAGE_SHOWHOLES')) {
60
- $tip = 'LiteMage ESI message block ' . $this->_nameInLayout;
61
- $wrapperBegin = '<div style="position:relative;border:1px dotted red;background-color:rgba(255,255,0,0.3);margin:2px;padding:18px 2px 2px 2px;zoom:1;" title="' . $tip
62
- . '"><div style="position: absolute; left: 0px; top: 0px; padding: 2px 5px; color: green; font-style: normal; font-variant: normal; font-weight: normal; font-size: 11px; line-height: normal; font-family: Arial; z-index: 998; text-align: left !important;">' . $tip . '</div>';
63
-
64
- $this->setData('lmwrapperBegin', $wrapperBegin);
65
- $this->setData('lmwrapperEnd', '</div>');
66
- }
67
- }
68
-
69
- public function initByEsi( $storageNames, $outputCall, $peer )
70
- {
71
- $this->_layout = $peer->_layout;
72
- if ( $peer instanceof Mage_Core_Block_Messages ) {
73
- $this->_messagesBlock = $peer ;
74
- }
75
- else {
76
- $this->_messagesBlock = $this->_layout->getMessagesBlock();
77
- if ($tmpl = $peer->getTemplate()) {
78
- $this->setTemplate($tmpl);
79
- }
80
- }
81
-
82
- $this->_usedStorageTypes = $storageNames ;
83
- $this->_nameInLayout = $peer->getNameInLayout() ;
84
- $this->_outputCall = $outputCall ;
85
- $this->_alias = $peer->_alias;
86
- $parent = $peer->getParentBlock();
87
- if ($parent != null) {
88
- $parent->setChild($peer->_alias, $this) ;
89
- }
90
- $this->_layout->setBlock($this->_nameInLayout, $this) ;
91
- }
92
-
93
- public function renderView()
94
- {
95
- if ( ! $this->_hasSaved ) {
96
- $messages = $this->getMessages() ;
97
- if ( count($messages) > 0 ) {
98
- // maybe multiple places point to same mesg block if use getMessageBlock(), use the name of the this->_messagesBlock, not itself
99
- Mage::getSingleton('litemage/session')->saveMessages($this->_messagesBlock->_nameInLayout, $messages) ;
100
- $this->getMessageCollection()->clear();
101
- }
102
-
103
- $this->_hasSaved = true ;
104
- }
105
- if ($this->_isEsiInject) {
106
- $esiHtml = $this->getData('esiHtml');
107
- Mage::helper('litemage/data')->debugMesg('Injected ESI Message block ' . $this->_nameInLayout . ' ' . $esiHtml) ;
108
-
109
- if (Mage::registry('LITEMAGE_SHOWHOLES'))
110
- return $this->getData('lmwrapperBegin') . $esiHtml . $this->getData('lmwrapperEnd') ;
111
- else
112
- return $esiHtml;
113
- }
114
- else
115
- return parent::renderView() ;
116
- }
117
-
118
- public function getGroupedHtml()
119
- {
120
- if ( $this->_isEsiInject ) {
121
- $this->_adjustEsiUrl('getGroupedHtml') ;
122
- return $this->renderView() ;
123
- }
124
- else {
125
- $this->_loadMessages() ;
126
- return $this->_messagesBlock->getGroupedHtml() ;
127
- }
128
- }
129
-
130
- public function getHtml( $type = null )
131
- {
132
- if ( $this->_isEsiInject ) {
133
- $this->_adjustEsiUrl('getHtml', $type) ;
134
- return $this->renderView() ;
135
- }
136
- else {
137
- $this->_loadMessages($type) ;
138
- return $this->_messagesBlock->getHtml($type) ;
139
- }
140
- }
141
-
142
- public function _prepareLayout()
143
- {
144
- // do nothing, as data already carried over
145
- return $this ;
146
- }
147
-
148
- protected function _loadCache()
149
- {
150
- if ( $this->_isEsiInject && $this->hasData('esiHtml') ) {
151
- $html = $this->getData('esiHtml') ;
152
- if ( strpos($html, '/getMessage/') ) {
153
- Mage::helper('litemage/data')->debugMesg('Injected ESI Message block ' . $this->_nameInLayout . ' ' . $html) ;
154
-
155
- if (Mage::registry('LITEMAGE_SHOWHOLES'))
156
- return $this->getData('lmwrapperBegin') . $html . $this->getData('lmwrapperEnd') ;
157
- else
158
- return $html ;
159
- }
160
- }
161
- return false ;
162
- }
163
-
164
- protected function _toHtml()
165
- {
166
- if ( $this->_isEsiInject ) {
167
- $this->_adjustEsiUrl('_toHtml') ;
168
- return $this->renderView() ;
169
- }
170
- else {
171
-
172
- if ($this->getTemplate()) {
173
- $this->_loadMessages();
174
- $this->setScriptPath(Mage::getBaseDir('design'));
175
- $html = $this->fetchView($this->getTemplateFile());
176
- return $html;
177
- }
178
-
179
- // default is getGroupedHtml
180
- if ( strncmp($this->_outputCall, 'getHtml', 7) == 0 ) {
181
- $type = ($this->_outputCall == 'getHtml') ? null : substr($this->_outputCall, 7) ;
182
- return $this->getHtml($type) ;
183
- }
184
- else {
185
- return $this->getGroupedHtml() ;
186
- }
187
- }
188
- }
189
-
190
-
191
- protected function _adjustEsiUrl( $caller, $type = null )
192
- {
193
- $esiHtml = $this->getData('esiHtml') ;
194
-
195
- if ( strpos($esiHtml, '/getBlock/') ) {
196
- $types = join(',', $this->_getStorageTypes());
197
- $param = array( $types, $caller . $type ) ;
198
- $param1 = str_replace('/session', '--', $param) ;
199
- $param1 = str_replace('/', '-', $param1) ;
200
- $replaced = '/getMessage/st/' . $param1[0] . '/call/' . $param1[1] . '/' ;
201
-
202
- $esiHtml = str_replace('/getBlock/', $replaced, $esiHtml) ;
203
- $this->setData('esiHtml', $esiHtml) ;
204
- Mage::helper('litemage/esi')->setEsiBlockHtml($this->_nameInLayout, $esiHtml);
205
- }
206
- }
207
-
208
- protected function _loadMessages( $type = null )
209
- {
210
- $session = Mage::getSingleton('litemage/session') ;
211
- if ( ($savedMessages = $session->loadMessages($this->_messagesBlock->_nameInLayout)) != null ) {
212
- foreach ( $savedMessages as $savedMessage ) {
213
- $this->addMessage($savedMessage) ;
214
- }
215
- }
216
-
217
- $types = ($type == null) ? $this->_usedStorageTypes : (is_array($type) ? $type : array( $type )) ;
218
-
219
- foreach ( $types as $storageName ) {
220
- if ( ($storage = Mage::getSingleton($storageName)) != null ) {
221
- $this->addMessages($storage->getMessages(true)) ;
222
- $this->setEscapeMessageFlag($storage->getEscapeMessages(true)) ;
223
- }
224
- }
225
- }
226
-
227
- public function setEscapeMessageFlag( $flag )
228
- {
229
- $this->_messagesBlock->setEscapeMessageFlag($flag) ;
230
- return $this ;
231
- }
232
-
233
- /**
234
- * Set messages collection
235
- *
236
- * @param Mage_Core_Model_Message_Collection $messages
237
- * @return Mage_Core_Block_Messages
238
- */
239
- public function setMessages( Mage_Core_Model_Message_Collection $messages )
240
- {
241
- $this->_messagesBlock->setMessages($messages) ;
242
- return $this ;
243
- }
244
-
245
- /**
246
- * Add messages to display
247
- *
248
- * @param Mage_Core_Model_Message_Collection $messages
249
- * @return Mage_Core_Block_Messages
250
- */
251
- public function addMessages( Mage_Core_Model_Message_Collection $messages )
252
- {
253
- if ( $messages->count() > 0 ) {
254
- $this->_messagesBlock->addMessages($messages) ;
255
- }
256
- return $this ;
257
- }
258
-
259
- /**
260
- * Retrieve messages collection
261
- *
262
- * @return Mage_Core_Model_Message_Collection
263
- */
264
- public function getMessageCollection()
265
- {
266
- return $this->_messagesBlock->getMessageCollection() ;
267
- }
268
-
269
- /**
270
- * Adding new message to message collection
271
- *
272
- * @param Mage_Core_Model_Message_Abstract $message
273
- * @return Mage_Core_Block_Messages
274
- */
275
- public function addMessage( Mage_Core_Model_Message_Abstract $message )
276
- {
277
- $this->_messagesBlock->addMessage($message) ;
278
- return $this ;
279
- }
280
-
281
- /**
282
- * Retrieve messages array by message type
283
- *
284
- * @param string $type
285
- * @return array
286
- */
287
- public function getMessages( $type = null )
288
- {
289
- return $this->_messagesBlock->getMessages($type) ;
290
- }
291
-
292
- /**
293
- * Set messages first level html tag name for output messages as html
294
- *
295
- * @param string $tagName
296
- */
297
- public function setMessagesFirstLevelTagName( $tagName )
298
- {
299
- $this->_messagesBlock->setMessagesFirstLevelTagName($tagName) ;
300
- }
301
-
302
- /**
303
- * Set messages first level html tag name for output messages as html
304
- *
305
- * @param string $tagName
306
- */
307
- public function setMessagesSecondLevelTagName( $tagName )
308
- {
309
- $this->_messagesBlock->setMessagesSecondLevelTagName($tagName) ;
310
- }
311
-
312
- /**
313
- * Get cache key informative items
314
- *
315
- * @return array
316
- */
317
- public function getCacheKeyInfo()
318
- {
319
- return $this->_messagesBlock->getCacheKeyInfo() ;
320
- }
321
-
322
- /**
323
- * Add used storage type
324
- *
325
- * @param string $type
326
- */
327
- public function addStorageType( $type )
328
- {
329
- $this->_messagesBlock->addStorageType($type) ;
330
- if ( ! in_array($type, $this->_usedStorageTypes) )
331
- $this->_usedStorageTypes[] = $type ;
332
- }
333
-
334
- protected function _getStorageTypes()
335
- {
336
- // it's possible, messageblock already replaced with esi one, when using layout->getMessageBlock
337
- $types = array_merge($this->_usedStorageTypes, $this->_messagesBlock->_usedStorageTypes);
338
- if ( ($this->_messagesBlock instanceof Litespeed_Litemage_Block_Core_Messages) && ($this->_messagesBlock->_messagesBlock != null)) {
339
- $types = array_merge($types, $this->_messagesBlock->_messagesBlock->_usedStorageTypes);
340
- }
341
- return array_unique($types);
342
- }
 
 
 
 
 
 
 
343
 
344
  }
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_Block_Core_Messages extends Mage_Core_Block_Messages
26
  {
27
 
28
+ protected $_peer ;
29
+ protected $_messageBlock ;
30
+ protected $_outputCall ;
31
+ protected $_peerClass ;
32
+ protected $_peerTemplate ;
33
+ protected $_blockIndex ;
34
+ protected $_isEsiInject ;
35
+
36
+ /* Override Mage_Core_Block_Abstract:getMessagesBlock */
37
+
38
+ public function getMessagesBlock()
39
+ {
40
+ return $this ;
41
+ }
42
+
43
+ public function initByPeer( $peer )
44
+ {
45
+ $this->_peer = $peer ;
46
+ $this->setData('litemage_bconf', $peer->getData('litemage_bconf')) ;
47
+ $this->_peerClass = get_class($peer) ;
48
+ $this->_peerTemplate = $peer->getTemplate() ; // todo: check if null;
49
+ $this->_isEsiInject = true ;
50
+
51
+ $this->_layout = $peer->_layout ;
52
+ if ( $peer instanceof Mage_Core_Block_Messages ) {
53
+ $this->_messageBlock = $peer ;
54
+ }
55
+ else {
56
+ $this->_messageBlock = $this->_layout->getMessagesBlock() ;
57
+ }
58
+
59
+ $this->_nameInLayout = $peer->_nameInLayout ;
60
+ $this->_alias = $peer->_alias ;
61
+ if ( $parent = $peer->getParentBlock() ) {
62
+ $parent->setChild($peer->_alias, $this) ;
63
+ }
64
+ if ( $this->_layout->getBlock($peer->_nameInLayout) === $peer ) {
65
+ // some bad plugins with duplicated names may lost this block, only replace if same object
66
+ $this->_layout->setBlock($this->_nameInLayout, $this) ;
67
+ }
68
+ }
69
+
70
+ public function getEsiOutput( $esiData )
71
+ {
72
+ $data = $esiData->getData() ;
73
+ $this->_usedStorageTypes = explode(',', $data['st']) ;
74
+ $this->_outputCall = $data['call'] ;
75
+ $this->_peerClass = $data['pc'] ;
76
+ $this->_blockIndex = $esiData->getLayoutAttribute('bi') ;
77
+ $this->_isEsiInject = false ;
78
+
79
+ $peer = new $this->_peerClass() ;
80
+ if ( $peer instanceof Mage_Core_Block_Messages ) {
81
+ $this->_messageBlock = $peer ;
82
+ }
83
+ else {
84
+ $this->_messageBlock = new Mage_Core_Block_Messages() ;
85
+ }
86
+
87
+ $this->_loadMessages() ;
88
+ if ( ! empty($data['pt']) ) {
89
+ $this->_peerTemplate = $data['pt'] ;
90
+ $this->setTemplate($this->_peerTemplate) ;
91
+ $this->setScriptPath(Mage::getBaseDir('design')) ;
92
+ return $this->fetchView($this->getTemplateFile()) ;
93
+ }
94
+ else {
95
+ // default is getGroupedHtml
96
+ if ( strncmp($this->_outputCall, 'getHtml', 7) == 0 ) {
97
+ $type = ($this->_outputCall == 'getHtml') ? null : substr($this->_outputCall, 7) ;
98
+ return $this->_messageBlock->getHtml($type) ;
99
+ }
100
+ else {
101
+ return $this->_messageBlock->getGroupedHtml() ;
102
+ }
103
+ }
104
+ }
105
+
106
+ public function renderView()
107
+ {
108
+ if ( ! $this->_isEsiInject ) {
109
+ return $this->_messageBlock->renderView() ;
110
+ }
111
+
112
+ $messages = $this->getMessages() ;
113
+ if ( count($messages) > 0 ) {
114
+ // maybe multiple places point to same mesg block if use getMessageBlock(), use the name of the this->_messagesBlock, not itself
115
+ //Mage::getSingleton('litemage/session')->saveMessages($this->_messageBlock->_nameInLayout, $messages) ;
116
+ // todo: change to bi
117
+ Mage::getSingleton('litemage/session')->saveMessages($this->_nameInLayout, $messages) ;
118
+ $this->getMessageCollection()->clear() ;
119
+ }
120
+
121
+ $esiHtml = $this->getData('esiHtml') ;
122
+ Mage::helper('litemage/data')->debugMesg('Injected ESI Message block renderview ' . $this->_nameInLayout . ' ' . $esiHtml) ;
123
+
124
+ if ( Mage::registry('LITEMAGE_SHOWHOLES') ) {
125
+ $tip = 'LiteMage ESI message block ' . $this->_nameInLayout ;
126
+ $wrapperBegin = '<div style="position:relative;border:1px dotted red;background-color:rgba(255,255,0,0.3);margin:2px;padding:18px 2px 2px 2px;zoom:1;" title="' . $tip
127
+ . '"><div style="position: absolute; left: 0px; top: 0px; padding: 2px 5px; color: green; font-style: normal; font-variant: normal; font-weight: normal; font-size: 11px; line-height: normal; font-family: Arial; z-index: 998; text-align: left !important;">' . $tip . '</div>' ;
128
+ $wrapperEnd = '</div>' ;
129
+
130
+ return $wrapperBegin . $esiHtml . $wrapperEnd ;
131
+ }
132
+ else
133
+ return $esiHtml ;
134
+ }
135
+
136
+ public function getGroupedHtml()
137
+ {
138
+ if ( ! $this->_isEsiInject ) {
139
+ return $this->_messageBlock->getGroupedHtml() ;
140
+ }
141
+
142
+ $esiHtml = Mage::helper('litemage/esi')->getEsiIncludeHtml($this) ;
143
+ $this->_adjustEsiUrl($esiHtml, 'getGroupedHtml') ;
144
+ return $this->renderView() ;
145
+ }
146
+
147
+ public function getHtml( $type = null )
148
+ {
149
+ if ( ! $this->_isEsiInject ) {
150
+ return $this->_messageBlock->getHtml() ;
151
+ }
152
+ $esiHtml = Mage::helper('litemage/esi')->getEsiIncludeHtml($this) ;
153
+ $this->_adjustEsiUrl($esiHtml, 'getHtml', $type) ;
154
+ return $this->renderView() ;
155
+ }
156
+
157
+ public function _prepareLayout()
158
+ {
159
+ // do nothing, as data already carried over
160
+ return $this ;
161
+ }
162
+
163
+ protected function _loadCache()
164
+ {
165
+ $esiHtml = Mage::helper('litemage/esi')->getEsiIncludeHtml($this) ;
166
+ $this->_adjustEsiUrl($esiHtml, '_toHtml') ;
167
+ return $this->renderView() ;
168
+ }
169
+
170
+ protected function _toHtml()
171
+ {
172
+ if ( $this->getTemplate() ) {
173
+ $this->setScriptPath(Mage::getBaseDir('design')) ;
174
+ $html = $this->fetchView($this->getTemplateFile()) ;
175
+ return $html ;
176
+ }
177
+ $this->_loadMessages() ;
178
+
179
+ // default is getGroupedHtml
180
+ if ( strncmp($this->_outputCall, 'getHtml', 7) == 0 ) {
181
+ $type = ($this->_outputCall == 'getHtml') ? null : substr($this->_outputCall, 7) ;
182
+ return $this->getHtml($type) ;
183
+ }
184
+ else {
185
+ return $this->getGroupedHtml() ;
186
+ }
187
+ }
188
+
189
+ protected function _adjustEsiUrl( $esiHtml, $caller, $type = null )
190
+ {
191
+ if ( strpos($esiHtml, '/getBlock/') ) {
192
+ $params = array(
193
+ 'st' => join(',', $this->_getStorageTypes()),
194
+ 'call' => $caller . $type,
195
+ 'pc' => $this->_peerClass,
196
+ 'pt' => $this->_peerTemplate ) ;
197
+ $eparams = Mage::helper('litemage/data')->encodeEsiUrlParams($params) ;
198
+ $replaced = '/getMessage' ;
199
+ foreach ( $eparams as $key => $v ) {
200
+ if ( $v ) {
201
+ $replaced .= '/' . $key . '/' . $v ;
202
+ }
203
+ }
204
+ $replaced .= '/' ;
205
+
206
+ $esiHtml = str_replace('/getBlock/', $replaced, $esiHtml) ;
207
+ $this->setData('esiHtml', $esiHtml) ;
208
+ }
209
+ }
210
+
211
+ protected function _loadMessages( $type = null )
212
+ {
213
+ $session = Mage::getSingleton('litemage/session') ;
214
+ if ( ($savedMessages = $session->loadMessages($this->_blockIndex)) != null ) {
215
+ foreach ( $savedMessages as $savedMessage ) {
216
+ $this->addMessage($savedMessage) ;
217
+ }
218
+ }
219
+
220
+ $types = ($type == null) ? $this->_usedStorageTypes : (is_array($type) ? $type : array( $type )) ;
221
+
222
+ foreach ( $types as $storageName ) {
223
+ if ( ($storage = Mage::getSingleton($storageName)) != null ) {
224
+ $this->addMessages($storage->getMessages(true)) ;
225
+ if ( $flag = $storage->getEscapeMessages(true) ) {
226
+ $this->setEscapeMessageFlag($flag) ;
227
+ }
228
+ }
229
+ }
230
+ }
231
+
232
+ public function setEscapeMessageFlag( $flag )
233
+ {
234
+ $this->_messageBlock->setEscapeMessageFlag($flag) ;
235
+ return $this ;
236
+ }
237
+
238
+ /**
239
+ * Set messages collection
240
+ *
241
+ * @param Mage_Core_Model_Message_Collection $messages
242
+ * @return Mage_Core_Block_Messages
243
+ */
244
+ public function setMessages( Mage_Core_Model_Message_Collection $messages )
245
+ {
246
+ $this->_messageBlock->setMessages($messages) ;
247
+ return $this ;
248
+ }
249
+
250
+ /**
251
+ * Add messages to display
252
+ *
253
+ * @param Mage_Core_Model_Message_Collection $messages
254
+ * @return Mage_Core_Block_Messages
255
+ */
256
+ public function addMessages( Mage_Core_Model_Message_Collection $messages )
257
+ {
258
+ if ( $messages->count() > 0 ) {
259
+ $this->_messageBlock->addMessages($messages) ;
260
+ }
261
+ return $this ;
262
+ }
263
+
264
+ /**
265
+ * Retrieve messages collection
266
+ *
267
+ * @return Mage_Core_Model_Message_Collection
268
+ */
269
+ public function getMessageCollection()
270
+ {
271
+ return $this->_messageBlock->getMessageCollection() ;
272
+ }
273
+
274
+ /**
275
+ * Adding new message to message collection
276
+ *
277
+ * @param Mage_Core_Model_Message_Abstract $message
278
+ * @return Mage_Core_Block_Messages
279
+ */
280
+ public function addMessage( Mage_Core_Model_Message_Abstract $message )
281
+ {
282
+ $this->_messageBlock->addMessage($message) ;
283
+ return $this ;
284
+ }
285
+
286
+ /**
287
+ * Retrieve messages array by message type
288
+ *
289
+ * @param string $type
290
+ * @return array
291
+ */
292
+ public function getMessages( $type = null )
293
+ {
294
+ return $this->_messageBlock->getMessages($type) ;
295
+ }
296
+
297
+ /**
298
+ * Set messages first level html tag name for output messages as html
299
+ *
300
+ * @param string $tagName
301
+ */
302
+ public function setMessagesFirstLevelTagName( $tagName )
303
+ {
304
+ $this->_messageBlock->setMessagesFirstLevelTagName($tagName) ;
305
+ }
306
+
307
+ /**
308
+ * Set messages first level html tag name for output messages as html
309
+ *
310
+ * @param string $tagName
311
+ */
312
+ public function setMessagesSecondLevelTagName( $tagName )
313
+ {
314
+ $this->_messageBlock->setMessagesSecondLevelTagName($tagName) ;
315
+ }
316
+
317
+ /**
318
+ * Get cache key informative items
319
+ *
320
+ * @return array
321
+ */
322
+ public function getCacheKeyInfo()
323
+ {
324
+ return $this->_messageBlock->getCacheKeyInfo() ;
325
+ }
326
+
327
+ /**
328
+ * Add used storage type
329
+ *
330
+ * @param string $type
331
+ */
332
+ public function addStorageType( $type )
333
+ {
334
+ $this->_messageBlock->addStorageType($type) ;
335
+ if ( ! in_array($type, $this->_usedStorageTypes) )
336
+ $this->_usedStorageTypes[] = $type ;
337
+ }
338
+
339
+ protected function _getStorageTypes()
340
+ {
341
+ // it's possible, messageblock already replaced with esi one, when using layout->getMessageBlock
342
+ $types = array_merge($this->_usedStorageTypes, $this->_messageBlock->_usedStorageTypes) ;
343
+ if ( ($this->_messageBlock instanceof Litespeed_Litemage_Block_Core_Messages) && ($this->_messageBlock->_messagesBlock
344
+ != null) ) {
345
+ $types = array_merge($types, $this->_messageBlock->_messagesBlock->_usedStorageTypes) ;
346
+ }
347
+ return array_unique($types) ;
348
+ }
349
 
350
  }
app/code/community/Litespeed/Litemage/Block/Core/Xml.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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) 2015-2016 LiteSpeed Technologies, Inc. (https://www.litespeedtech.com)
22
+ * @license https://opensource.org/licenses/GPL-3.0
23
+ */
24
+
25
+
26
+ class Litespeed_Litemage_Block_Core_Xml extends Mage_Core_Block_Abstract
27
+ {
28
+ protected $_xmlNodes = array();
29
+
30
+ public function addXmlNode($node)
31
+ {
32
+ $id = spl_object_hash($node);
33
+ if (!isset($this->_xmlNodes[$id])) {
34
+ $this->_xmlNodes[$id] = $node;
35
+ }
36
+ }
37
+
38
+ public function getXmlString($bi)
39
+ {
40
+ $xml = $this->_getBlockXmlString($bi);
41
+ return $xml;
42
+ }
43
+
44
+ protected function _getBlockXmlString($bi)
45
+ {
46
+ $xml = '';
47
+ $name = $this->getNameInLayout();
48
+ foreach ($this->_xmlNodes as $node) {
49
+ $xml .= $this->_getNodeXmlString($node, $bi);
50
+ }
51
+ foreach ($this->_children as $childBlock) {
52
+ $xml .= $childBlock->_getBlockXmlString($bi);
53
+ }
54
+ return $xml;
55
+ }
56
+
57
+ protected function _getNodeXmlString($node, $bi)
58
+ {
59
+ if ($node->getAttribute("lm_$bi")) {
60
+ return; // used
61
+ }
62
+ $xml = $node->asNiceXml();
63
+ $this->_markNode($node, $bi);
64
+ return $xml;
65
+ }
66
+
67
+ protected function _markNode($node, $bi)
68
+ {
69
+ $node->addAttribute("lm_$bi", true);
70
+ foreach ($node as $child) {
71
+ $this->_markNode($child, $bi);
72
+ }
73
+ }
74
+
75
+
76
+ }
app/code/community/Litespeed/Litemage/Helper/Data.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * LiteMage
4
  *
@@ -21,15 +22,14 @@
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_Helper_Data extends Mage_Core_Helper_Abstract
26
  {
27
 
28
- const CFGXML_DEFAULTLM = 'default/litemage' ;
29
- const CFGXML_ESIBLOCK = 'frontend/litemage/esiblock' ;
30
-
31
  const STOREXML_PUBLICTTL = 'litemage/general/public_ttl' ;
32
  const STOREXML_PRIVATETTL = 'litemage/general/private_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' ;
@@ -39,478 +39,575 @@ class Litespeed_Litemage_Helper_Data extends Mage_Core_Helper_Abstract
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
-
43
- const CFG_ENABLED = 'enabled' ;
44
- const CFG_DEBUGON = 'debug' ;
45
- const CFG_WARMUP = 'warmup' ;
46
  const CFG_WARMUP_ALLOW = 'allow_warmup' ;
47
- const CFG_WARMUP_EANBLED = 'enable_warmup' ;
48
- const CFG_WARMUP_LOAD_LIMIT = 'load_limit' ;
49
- const CFG_WARMUP_MAXTIME = 'max_time' ;
50
  const CFG_WARMUP_THREAD_LIMIT = 'thread_limit' ;
51
- const CFG_WARMUP_MULTICURR = 'multi_currency';
52
- const CFG_TRACKLASTVIEWED = 'track_viewed' ;
53
- const CFG_DIFFCUSTGRP = 'diff_customergroup' ;
54
- const CFG_PUBLICTTL = 'public_ttl' ;
55
- const CFG_PRIVATETTL = 'private_ttl' ;
56
- const CFG_ESIBLOCK = 'esiblock' ;
57
- const CFG_NOCACHE = 'nocache' ;
58
- const CFG_CACHE_ROUTE = 'cache_routes' ;
59
- const CFG_NOCACHE_ROUTE = 'nocache_routes' ;
60
- const CFG_FULLCACHE_ROUTE = 'fullcache_routes' ;
61
- const CFG_NOCACHE_VAR = 'nocache_vars' ;
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() ;
69
- protected $_userModuleEnabled = -2 ; // -2: not set, true, false
70
- protected $_esiTag;
71
- protected $_isDebug ;
72
- protected $_debugTag = 'LiteMage' ;
73
-
74
- public function moduleEnabled()
75
- {
76
- if ( isset($_SERVER['X-LITEMAGE']) && $_SERVER['X-LITEMAGE'] ) {
77
- return $this->getConf(self::CFG_ENABLED) ;
78
- }
79
- else {
80
- return false ;
81
- }
82
- }
83
-
84
- public function moduleEnabledForUser()
85
- {
86
- if ( $this->_userModuleEnabled === -2 ) {
87
- $allowed = $this->moduleEnabled() ;
88
- if ( $allowed ) {
89
- $tag = '';
90
- $httphelper = Mage::helper('core/http') ;
91
- $remoteAddr = $httphelper->getRemoteAddr() ;
 
 
92
  if ( $httphelper->getHttpUserAgent() == 'litemage_walker' ) {
93
- $tag = 'litemage_walker:';
94
  }
95
  else if ( $ips = $this->getConf(self::CFG_ALLOWEDIPS) ) {
96
  if ( ! in_array($remoteAddr, $ips) ) {
97
  $allowed = false ;
98
  }
99
- }
100
-
101
- if ($this->_isDebug && $allowed) {
102
- $tag .= $remoteAddr ;
103
- $msec = microtime();
104
- $msec1 = substr($msec, 2, strpos($msec, ' ') -2);
105
- $this->_debugTag .= ' [' . $tag . ':'. $_SERVER['REMOTE_PORT'] . ':' . $msec1 . ']' ;
106
- }
107
- }
108
- $this->_userModuleEnabled = $allowed ;
109
- }
110
- return $this->_userModuleEnabled ;
111
- }
112
-
113
- public function isAdminIP()
114
- {
115
- if ($adminIps = $this->getConf(self::CFG_ADMINIPS) ) {
116
- $remoteAddr = Mage::helper('core/http')->getRemoteAddr() ;
117
- if (in_array($remoteAddr, $adminIps)) {
118
- return true;
119
- }
120
- }
121
- return false;
122
- }
123
-
124
- public function isRestrainedIP()
125
- {
126
- return ($this->getConf(self::CFG_ALLOWEDIPS) != '') ;
127
- }
128
-
129
- public function isDebug()
130
- {
131
- return $this->getConf(self::CFG_DEBUGON) ;
132
- }
133
-
134
- public function esiTag($type)
135
- {
136
- if (isset($this->_esiTag[$type])) {
137
- return $this->_esiTag[$type];
138
- }
139
-
140
- if ( $this->_isDebug ) {
141
- $this->debugMesg('Invalid type for esiTag ' . $type);
142
- }
143
- }
144
-
145
- public function trackLastViewed()
146
- {
147
- return Mage::getStoreConfig(self::STOREXML_TRACKLASTVIEWED);
148
- }
149
-
150
- public function getEsiConf( $type = '', $name = '' ) //type = tag, block, event
151
- {
152
- $conf = $this->getConf('', self::CFG_ESIBLOCK) ;
153
- if ( $type == 'event' && ! isset($conf['event']) ) {
154
- $events = array() ;
155
- foreach ( $conf['tag'] as $tag => $d ) {
156
- if ( isset($d['purge_events']) ) {
157
- $pes = array_keys($d['purge_events']) ;
158
- foreach ( $pes as $e ) {
159
- if ( ! isset($events[$e]) )
160
- $events[$e] = array() ;
161
- $events[$e][] = $d['cache-tag'];
162
- }
163
- }
164
- }
165
- $this->_conf[self::CFG_ESIBLOCK]['event'] = $events ;
166
- return $events ;
167
- }
168
- if ( $type == '' )
169
- return $conf ;
170
- elseif ( $name == '' )
171
- return $conf[$type] ;
172
- else
173
- return $conf[$type][$name] ;
174
- }
175
 
176
- public function getWarmUpConf()
 
 
 
 
 
 
 
 
 
 
 
 
177
  {
178
- if (!isset($this->_conf[self::CFG_WARMUP])) {
 
 
 
 
 
 
 
179
 
180
- $storeInfo = array();
181
- if ( $this->getConf(self::CFG_ENABLED) ) {
182
- $this->getConf('', self::CFG_WARMUP);
183
- $app = Mage::app();
184
- $storeIds = array_keys($app->getStores());
185
- $vary_dev = $this->isRestrainedIP() ? '/vary_dev/1' : '';
186
-
187
- foreach ($storeIds as $storeId) {
188
- $isEnabled = Mage::getStoreConfig(self::STOREXML_WARMUP_EANBLED, $storeId);
189
- if ($isEnabled) {
190
- $store = $app->getStore($storeId);
191
- if (!$store->getIsActive()) {
192
- continue;
193
- }
194
- $site = $store->getWebsite();
195
- $is_default_store = ($site->getDefaultStore()->getId() == $storeId); // cannot use $app->getDefaultStoreView()->getId();
196
- $is_default_site = $site->getIsDefault();
197
- $orderAdjust = 0.0;
198
- if ($is_default_site)
199
- $orderAdjust -= 0.25;
200
- if ($is_default_store)
201
- $orderAdjust -= 0.25;
202
-
203
- $vary_curr = '';
204
- $curr = trim(Mage::getStoreConfig(self::STOREXML_WARMUP_MULTICURR, $storeId));
205
- if ($curr) {
206
- // get currency vary
207
- $availCurrCodes = $store->getAvailableCurrencyCodes() ;
208
- $default_currency = $store->getDefaultCurrencyCode() ;
209
-
210
- $currs = preg_split("/[\s,]+/", strtoupper($curr), null, PREG_SPLIT_NO_EMPTY) ;
211
- if (in_array('ALL', $currs)) {
212
- $currs = $availCurrCodes;
213
- }
214
- else {
215
- $currs = array_unique($currs);
216
- }
217
 
218
- foreach ($currs as $cur) {
219
- if ( $cur != $default_currency && in_array($cur, $availCurrCodes) ) {
220
- $vary_curr .= ',' . $cur ;
221
- }
222
- }
223
- if ($vary_curr) {
224
- $vary_curr = '/vary_curr/-' . $vary_curr; // "-" means default
225
- }
226
- }
227
 
228
- $vary_cgrp = '' ;
229
- /*if ( $diffGrp = Mage::getStoreConfig(self::STOREXML_DIFFCUSTGRP, $storeId)) ) {
230
- // $crawlgrp = 'out' ;
231
- $crawlUsers = array(138, 137);
232
- if ($crawlUsers) {
233
- if ($diffGrp == 2) {
234
- // for in & out
235
- $crawlgrp .= ',in_138';
236
- }
237
- * '/vary_cgrp/' . $vary_customergroup ;
238
- }
239
- //}*/
240
-
241
- $env = '';
242
-
243
- $priority = Mage::getStoreConfig(self::STOREXML_WARMUP_PRIORITY, $storeId) + $orderAdjust;
244
- if (!$is_default_store) {
245
- $env .= '/store/' . $store->getCode() . '/storeId/' . $storeId ;
246
- }
247
- $env .= $vary_curr . $vary_cgrp . $vary_dev;
248
- $baseurl = $store->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK);
249
- $ttl = Mage::getStoreConfig(self::STOREXML_PUBLICTTL, $storeId);
250
- $interval = Mage::getStoreConfig(self::STOREXML_WARMUP_INTERVAL, $storeId);
251
- if ($interval == '' || $interval < 600) { // for upgrade users, not refreshed conf
252
- $interval = $ttl;
253
- }
254
 
255
- if ($isEnabled == 1) {
256
- $listId = 'store' . $storeId;
257
- $storeInfo[$listId] = array(
258
- 'id' => $listId,
259
- 'storeid' => $storeId,
260
- 'default_store' => $is_default_store,
261
- 'default_site' => $is_default_site,
262
- 'env' => $env,
263
- 'interval' => $interval,
264
- 'ttl' => $ttl,
265
- 'priority' => $priority,
266
- 'baseurl' => $baseurl );
267
- }
268
 
269
- // check custom list
270
- $custlist = Mage::getStoreConfig(self::STOREXML_WARMUP_CUSTLIST, $storeId);
271
- if (is_readable($custlist)) {
272
- $priority = Mage::getStoreConfig(self::STOREXML_WARMUP_CUSTLIST_PRIORITY, $storeId) + $orderAdjust;
273
- $custInterval = Mage::getStoreConfig(self::STOREXML_WARMUP_CUSTLIST_INTERVAL, $storeId);
274
- $listId = 'cust' . $storeId;
275
- $storeInfo[$listId] = array(
276
- 'id' => $listId,
277
- 'storeid' => $storeId,
278
- 'env' => $env,
279
- 'interval' => $custInterval,
280
- 'ttl' => $ttl,
281
- 'priority' => $priority,
282
- 'baseurl' => $baseurl,
283
- 'file' => $custlist );
284
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  }
286
  }
287
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
288
  else {
289
- $this->_conf[self::CFG_WARMUP] = array();
290
  }
 
 
291
 
292
- if (empty($storeInfo)) {
293
- if ( $this->_isDebug ) {
294
- $this->debugMesg('Cron warm up skipped due to configuration not enabled.') ;
295
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
  }
297
  else {
298
- $load = sys_getloadavg() ;
299
- $limit = $this->_conf[self::CFG_WARMUP][self::CFG_WARMUP_LOAD_LIMIT] ;
300
- if ( $load[0] > $limit ) {
301
- if ( $this->_isDebug ) {
302
- $this->debugMesg('Cron warm up skipped due to load. Limit is ' . $limit . ', current load is ' . $load[0]) ;
303
- }
304
  }
305
- else {
306
- $this->_conf[self::CFG_WARMUP]['store'] = $storeInfo;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  }
308
  }
309
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
310
 
311
- return $this->_conf[self::CFG_WARMUP];
 
 
312
 
 
 
 
313
  }
314
 
315
- public function isEsiBlock( $block )
316
- {
317
- $blockName = $block->getNameInLayout();
318
- $tag = null;
319
- $valueonly = 0;
320
- $blockType = null;
321
-
322
- $ref = $this->_conf[self::CFG_ESIBLOCK]['block'];
323
- if (isset($ref['bn'][$blockName])) {
324
- $tag = $ref['bn'][$blockName]['tag'];
325
- $valueonly = $ref['bn'][$blockName]['valueonly'];
326
- }
327
- else {
328
- foreach ($ref['bt'] as $bt => $bv) {
329
- if ($block instanceof $bt) {
330
- $tag = $bv['tag'];
331
- $valueonly = $bv['valueonly'];
332
- $blockType = $bt;
333
- break;
334
- }
335
- }
336
- }
337
- if ($tag == null) {
338
- return null;
339
- }
340
- else {
341
- $tagdata = $this->_conf[self::CFG_ESIBLOCK]['tag'][$tag];
342
- $bconf = array(
343
- 'tag' => $tag,
344
- 'cache-tag' => $tagdata['cache-tag'],
345
- 'access' => $tagdata['access'],
346
- 'valueonly' => $valueonly,
347
- 'bn' => $blockName,
348
- 'bt' => $blockType
349
- );
350
- return $bconf;
351
- }
352
- }
353
-
354
- public function getNoCacheConf( $name = '' )
355
- {
356
- return $this->getConf($name, self::CFG_NOCACHE) ;
357
- }
358
-
359
- public function getConf( $name, $type = '' )
360
- {
361
- if ( ($type == '' && ! isset($this->_conf[$name])) || ($type != '' && ! isset($this->_conf[$type])) ) {
362
- $this->_initConf($type) ;
363
- }
364
 
365
  // get store override, because store id may change after init
366
- if ($name == self::CFG_DIFFCUSTGRP) {
367
- $this->_conf[self::CFG_DIFFCUSTGRP] = Mage::getStoreConfig(self::STOREXML_DIFFCUSTGRP);
368
  }
369
- elseif ($name == self::CFG_PUBLICTTL) {
370
- $this->_conf[self::CFG_PUBLICTTL] = Mage::getStoreConfig(self::STOREXML_PUBLICTTL);
371
  }
372
- elseif ($name == self::CFG_PRIVATETTL) {
373
- $this->_conf[self::CFG_PRIVATETTL] = Mage::getStoreConfig(self::STOREXML_PRIVATETTL);
374
  }
375
- elseif ($name == self::CFG_TRACKLASTVIEWED) {
376
- $this->_conf[self::CFG_TRACKLASTVIEWED] = Mage::getStoreConfig(self::STOREXML_TRACKLASTVIEWED);
377
  }
 
 
 
 
 
 
 
 
 
 
 
378
 
379
- if ( $type == '' )
380
- return $this->_conf[$name] ;
381
- else if ( $name == '' )
382
- return $this->_conf[$type] ;
383
- else
384
- return $this->_conf[$type][$name] ;
385
- }
386
-
387
- protected function _initConf( $type = '' )
388
- {
389
- $storeId = Mage::app()->getStore()->getId();
390
- if ( ! isset($this->_conf['defaultlm']) ) {
391
- $this->_conf['defaultlm'] = $this->_getConfigByPath(self::CFGXML_DEFAULTLM) ;
392
- }
393
- $pattern = "/[\s,]+/" ;
394
-
395
- switch ( $type ) {
396
- case self::CFG_ESIBLOCK:
397
- $this->_conf[self::CFG_ESIBLOCK] = array() ;
398
- $this->_conf[self::CFG_ESIBLOCK]['tag'] = $this->_getConfigByPath(self::CFGXML_ESIBLOCK) ;
399
-
400
- $custblocks = array();
401
- $custblocks['welcome'] = preg_split($pattern, $this->_conf['defaultlm']['donotcache']['welcome'], null, PREG_SPLIT_NO_EMPTY) ;
402
- $custblocks['toplinks'] = preg_split($pattern, $this->_conf['defaultlm']['donotcache']['toplinks'], null, PREG_SPLIT_NO_EMPTY) ;
403
- $custblocks['messages'] = preg_split($pattern, $this->_conf['defaultlm']['donotcache']['messages'], null, PREG_SPLIT_NO_EMPTY) ;
404
-
405
- $allblocks = array('bn' => array(), 'bt' => array());
406
- foreach ( $this->_conf[self::CFG_ESIBLOCK]['tag'] as $tag => $d ) {
407
- $this->_conf[self::CFG_ESIBLOCK]['tag'][$tag]['cache-tag'] = Litespeed_Litemage_Helper_Esi::TAG_PREFIX_ESIBLOCK . $tag ;
408
- $blocks = preg_split($pattern, $d['blocks'], null, PREG_SPLIT_NO_EMPTY) ;
409
- if (!empty($custblocks[$tag])) {
410
- $blocks = array_merge($blocks, $custblocks[$tag]);
411
- }
412
-
413
- foreach ( $blocks as $b ) {
414
- $valueonly = 0;
415
- if (substr($b, -2) == '$v') {
416
- $valueonly = 1;
417
- $b = substr($b, 0, -2);
418
- }
419
- $bc = array('tag' => $tag, 'valueonly' => $valueonly);
420
- if (substr($b,0,2) == 'T:') {
421
- $b = substr($b,2);
422
- $allblocks['bt'][$b] = $bc;
423
- }
424
- else {
425
- $allblocks['bn'][$b] = $bc;
426
- }
427
- }
428
- if ( isset($d['purge_tags']) ) {
429
- $pts = preg_split($pattern, $d['purge_tags'], null, PREG_SPLIT_NO_EMPTY) ;
430
- if (!isset($d['purge_events']))
431
- $this->_conf[self::CFG_ESIBLOCK]['tag'][$tag]['purge_events'] = array();
432
- foreach ( $pts as $t ) {
433
- if (isset($this->_conf[self::CFG_ESIBLOCK]['tag'][$t]['purge_events'])) {
434
- $this->_conf[self::CFG_ESIBLOCK]['tag'][$tag]['purge_events'] =
435
- array_merge($this->_conf[self::CFG_ESIBLOCK]['tag'][$tag]['purge_events'],
436
- $this->_conf[self::CFG_ESIBLOCK]['tag'][$t]['purge_events']);
437
- }
438
- }
439
-
440
- }
441
-
442
- }
443
- $this->_conf[self::CFG_ESIBLOCK]['block'] = $allblocks ;
444
- break ;
445
-
446
- case self::CFG_NOCACHE:
447
- $this->_conf[self::CFG_NOCACHE] = array() ;
448
- $default = $this->_conf['defaultlm']['default'] ;
449
- $cust = $this->_conf['defaultlm']['donotcache'] ;
450
-
451
- $this->_conf[self::CFG_NOCACHE][self::CFG_CACHE_ROUTE] = array_merge(preg_split($pattern, $default['cache_routes'], null, PREG_SPLIT_NO_EMPTY),
452
- preg_split($pattern, $cust['cache_routes'], null, PREG_SPLIT_NO_EMPTY));
453
- $this->_conf[self::CFG_NOCACHE][self::CFG_NOCACHE_ROUTE] = array_merge(preg_split($pattern, $default['nocache_subroutes'], null, PREG_SPLIT_NO_EMPTY),
454
- preg_split($pattern, $default['nocache_subroutes'], null, PREG_SPLIT_NO_EMPTY));
455
- $this->_conf[self::CFG_NOCACHE][self::CFG_FULLCACHE_ROUTE] = preg_split($pattern, $default['fullcache_routes'], null, PREG_SPLIT_NO_EMPTY) ;
456
- $this->_conf[self::CFG_NOCACHE][self::CFG_NOCACHE_VAR] = preg_split($pattern, $cust['vars'], null, PREG_SPLIT_NO_EMPTY) ;
457
- $this->_conf[self::CFG_NOCACHE][self::CFG_NOCACHE_URL] = preg_split($pattern, $cust['urls'], null, PREG_SPLIT_NO_EMPTY) ;
458
- break ;
459
-
460
- case self::CFG_WARMUP:
461
- $warmup = $this->_conf['defaultlm']['warmup'] ;
462
- $this->_conf[self::CFG_WARMUP] = array(
463
- self::CFG_WARMUP_EANBLED => $warmup[self::CFG_WARMUP_EANBLED],
464
- self::CFG_WARMUP_LOAD_LIMIT => $warmup[self::CFG_WARMUP_LOAD_LIMIT],
465
  self::CFG_WARMUP_THREAD_LIMIT => $warmup[self::CFG_WARMUP_THREAD_LIMIT],
466
- self::CFG_WARMUP_MAXTIME => $warmup[self::CFG_WARMUP_MAXTIME],
467
- self::CFG_WARMUP_MULTICURR => $warmup[self::CFG_WARMUP_MULTICURR]);
468
- break ;
469
 
470
- default:
471
- $general = $this->_conf['defaultlm']['general'] ;
472
- $this->_conf[self::CFG_ENABLED] = $general[self::CFG_ENABLED] ;
473
 
474
- $test = $this->_conf['defaultlm']['test'] ;
475
- $this->_conf[self::CFG_DEBUGON] = $test[self::CFG_DEBUGON] ;
476
- $this->_isDebug = $test[self::CFG_DEBUGON] ; // required by cron, needs to be set even when module disabled.
477
 
478
- if ( ! $general[self::CFG_ENABLED] )
479
- break ;
480
 
481
  // get store override
482
- $this->_conf[self::CFG_TRACKLASTVIEWED] = Mage::getStoreConfig(self::STOREXML_TRACKLASTVIEWED, $storeId);
483
- $this->_conf[self::CFG_DIFFCUSTGRP] = Mage::getStoreConfig(self::STOREXML_DIFFCUSTGRP, $storeId);
484
- $this->_conf[self::CFG_PUBLICTTL] = Mage::getStoreConfig(self::STOREXML_PUBLICTTL, $storeId);
485
- $this->_conf[self::CFG_PRIVATETTL] = Mage::getStoreConfig(self::STOREXML_PRIVATETTL, $storeId);
486
-
487
- $adminIps = trim($general[self::CFG_ADMINIPS]);
488
- $this->_conf[self::CFG_ADMINIPS] = $adminIps ? preg_split($pattern, $adminIps, null, PREG_SPLIT_NO_EMPTY) : '' ;
489
- if ($general['alt_esi_syntax']) {
490
- $this->_esiTag = array('include' => 'esi_include', 'inline' => 'esi_inline', 'remove' => 'esi_remove');
491
- }
492
- else {
493
- $this->_esiTag = array('include' => 'esi:include', 'inline' => 'esi:inline', 'remove' => 'esi:remove');
494
- }
495
- $allowedIps = trim($test[self::CFG_ALLOWEDIPS]) ;
496
- $this->_conf[self::CFG_ALLOWEDIPS] = $allowedIps ? preg_split($pattern, $allowedIps, null, PREG_SPLIT_NO_EMPTY) : '' ;
497
- }
498
- }
499
-
500
- protected function _getConfigByPath( $xmlPath )
501
- {
 
502
  $node = Mage::getConfig()->getNode($xmlPath) ;
503
- if ( ! $node )
504
- Mage::throwException('Litemage missing config in xml path ' . $xmlPath) ;
505
- return $node->asCanonicalArray() ;
506
- }
507
-
508
- public function debugMesg( $mesg )
509
- {
510
- if ( $this->_isDebug ) {
511
- $mesg = str_replace("\n", ("\n" . $this->_debugTag . ' '), $mesg);
512
- Mage::log($this->_debugTag . ' '. $mesg ) ;
513
- }
514
- }
515
 
516
  }
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_Helper_Data extends Mage_Core_Helper_Abstract
26
  {
27
 
28
+ const CFGXML_DEFAULTLM = 'default/litemage' ;
29
+ const CFGXML_ESIBLOCK = 'frontend/litemage/esiblock' ;
 
30
  const STOREXML_PUBLICTTL = 'litemage/general/public_ttl' ;
31
  const STOREXML_PRIVATETTL = 'litemage/general/private_ttl' ;
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' ;
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' ;
59
+ const CFG_NOCACHE_ROUTE = 'nocache_routes' ;
60
+ const CFG_FULLCACHE_ROUTE = 'fullcache_routes' ;
61
+ const CFG_NOCACHE_VAR = 'nocache_vars' ;
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() ;
69
+ protected $_userModuleEnabled = -2 ; // -2: not set, true, false
70
+ protected $_esiTag ;
71
+ protected $_isDebug ;
72
+ protected $_translateParams = null ;
73
+ protected $_debugTag = 'LiteMage' ;
74
+
75
+ public function moduleEnabled()
76
+ {
77
+ if ( isset($_SERVER['X-LITEMAGE']) && $_SERVER['X-LITEMAGE'] ) {
78
+ return $this->getConf(self::CFG_ENABLED) ;
79
+ }
80
+ else {
81
+ return false ;
82
+ }
83
+ }
84
+
85
+ public function moduleEnabledForUser()
86
+ {
87
+ if ( $this->_userModuleEnabled === -2 ) {
88
+ $allowed = $this->moduleEnabled() ;
89
+ if ( $allowed ) {
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) ) {
98
  $allowed = false ;
99
  }
100
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
 
102
+ if ( $this->_isDebug && $allowed ) {
103
+ $tag .= $remoteAddr ;
104
+ $msec = microtime() ;
105
+ $msec1 = substr($msec, 2, strpos($msec, ' ') - 2) ;
106
+ $this->_debugTag .= ' [' . $tag . ':' . $_SERVER['REMOTE_PORT'] . ':' . $msec1 . ']' ;
107
+ }
108
+ }
109
+ $this->_userModuleEnabled = $allowed ;
110
+ }
111
+ return $this->_userModuleEnabled ;
112
+ }
113
+
114
+ public function isAdminIP()
115
  {
116
+ if ( $adminIps = $this->getConf(self::CFG_ADMINIPS) ) {
117
+ $remoteAddr = Mage::helper('core/http')->getRemoteAddr() ;
118
+ if ( in_array($remoteAddr, $adminIps) ) {
119
+ return true ;
120
+ }
121
+ }
122
+ return false ;
123
+ }
124
 
125
+ public function isRestrainedIP()
126
+ {
127
+ return ($this->getConf(self::CFG_ALLOWEDIPS) != '') ;
128
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
 
130
+ public function isDebug()
131
+ {
132
+ return $this->getConf(self::CFG_DEBUGON) ;
133
+ }
 
 
 
 
 
134
 
135
+ public function esiTag( $type )
136
+ {
137
+ if ( isset($this->_esiTag[$type]) ) {
138
+ return $this->_esiTag[$type] ;
139
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
 
141
+ if ( $this->_isDebug ) {
142
+ $this->debugMesg('Invalid type for esiTag ' . $type) ;
143
+ }
144
+ }
 
 
 
 
 
 
 
 
 
145
 
146
+ protected function _getTranslateParams()
147
+ {
148
+ if ( $this->_translateParams == null ) {
149
+ // sample handles default:catalog_category_layered_nochildren:catalog_category_view:catalog_category_layered
150
+ $this->_translateParams = array(
151
+ 'h' => array(
152
+ 0 => array( 'default', 'catalog', 'category', 'layered', 'nochildren' ),
153
+ 1 => array( 'D', 'L', 'G', 'Y', 'N' ) ),
154
+ 'st' => array(
155
+ 0 => array( 'core/session', 'catalog/session', 'checkout/session', 'customer/session', '/session' ),
156
+ 1 => array( 'O', 'L', 'K', 'U', 'S' ) ),
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
+ }
164
+
165
+ public function encodeEsiUrlParams( $params )
166
+ {
167
+ $translated = array() ;
168
+ $tr = $this->_getTranslateParams() ;
169
+
170
+ foreach ( $params as $key => $value ) {
171
+ $newValue = $value ;
172
+ switch ( $key ) {
173
+ case 'h':
174
+ $newValue = str_replace($tr[$key][0], $tr[$key][1], $value) ;
175
+ break ;
176
+ case 'st':
177
+ $newValue = str_replace($tr[$key][0], $tr[$key][1], $value) ;
178
+ $newValue = str_replace('/', '--', $newValue) ;
179
+ break ;
180
+ case 'pc':
181
+ if ( ($index = array_search($value, $tr[$key][0])) !== false ) {
182
+ $newValue = $tr[$key][1][$index] ;
183
+ }
184
+ break ;
185
+ case 'pt':
186
+ case 'call':
187
+ $newValue = str_replace('/', '--', $value) ;
188
+ break ;
189
+ }
190
+ $translated[$key] = $newValue ;
191
+ }
192
+ return $translated ;
193
+ }
194
+
195
+ public function decodeEsiUrlParams( $params )
196
+ {
197
+ $translated = array() ;
198
+ $tr = $this->_getTranslateParams() ;
199
+
200
+ foreach ( $params as $key => $value ) {
201
+ $origValue = $value ;
202
+ switch ( $key ) {
203
+ case 'h':
204
+ $origValue = str_replace($tr[$key][1], $tr[$key][0], $value) ;
205
+ break ;
206
+ case 'st':
207
+ $origValue = str_replace('--', '/', $value) ;
208
+ $origValue = str_replace($tr[$key][1], $tr[$key][0], $origValue) ;
209
+ break ;
210
+ case 'pc':
211
+ if ( ($index = array_search($value, $tr[$key][1])) !== false ) {
212
+ $origValue = $tr[$key][0][$index] ;
213
+ }
214
+ break ;
215
+ case 'pt':
216
+ case 'call':
217
+ $origValue = str_replace('--', '/', $value) ;
218
+ break ;
219
+ }
220
+ $translated[$key] = $origValue ;
221
+ }
222
+ return $translated ;
223
+ }
224
+
225
+ public function trackLastViewed()
226
+ {
227
+ return Mage::getStoreConfig(self::STOREXML_TRACKLASTVIEWED) ;
228
+ }
229
+
230
+ public function getEsiConf( $type = '', $name = '' ) //type = tag, block, event
231
+ {
232
+ $conf = $this->getConf('', self::CFG_ESIBLOCK) ;
233
+ if ( $type == 'event' && ! isset($conf['event']) ) {
234
+ $events = array() ;
235
+ foreach ( $conf['tag'] as $tag => $d ) {
236
+ if ( isset($d['purge_events']) ) {
237
+ $pes = array_keys($d['purge_events']) ;
238
+ foreach ( $pes as $e ) {
239
+ if ( ! isset($events[$e]) )
240
+ $events[$e] = array() ;
241
+ $events[$e][] = $d['cache-tag'] ;
242
  }
243
  }
244
  }
245
+ $this->_conf[self::CFG_ESIBLOCK]['event'] = $events ;
246
+ return $events ;
247
+ }
248
+ if ( $type == '' )
249
+ return $conf ;
250
+ elseif ( $name == '' )
251
+ return $conf[$type] ;
252
+ else
253
+ return $conf[$type][$name] ;
254
+ }
255
+
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()) ;
264
+ $vary_dev = $this->isRestrainedIP() ? '/vary_dev/1' : '' ;
265
+
266
+ foreach ( $storeIds as $storeId ) {
267
+ $warmuplist = $this->_getStoreWarmUpInfo($storeId, $vary_dev) ;
268
+ $storeInfo = array_merge($storeInfo, $warmuplist) ;
269
+ }
270
+ }
271
  else {
272
+ $this->_conf[self::CFG_WARMUP] = array() ;
273
  }
274
+ $this->_conf[self::CFG_WARMUP]['store'] = $storeInfo ;
275
+ }
276
 
277
+ return $this->_conf[self::CFG_WARMUP] ;
278
+ }
279
+
280
+ protected function _getStoreWarmUpInfo( $storeId, $vary_dev )
281
+ {
282
+ $storeInfo = array();
283
+ if (!Mage::getStoreConfig(self::STOREXML_WARMUP_EANBLED, $storeId))
284
+ return $storeInfo;
285
+
286
+ $store = Mage::app()->getStore($storeId) ;
287
+ if ( !$store->getIsActive() )
288
+ return $storeInfo;
289
+
290
+ $site = $store->getWebsite() ;
291
+ $is_default_store = ($site->getDefaultStore()->getId() == $storeId) ; // cannot use $app->getDefaultStoreView()->getId();
292
+ $is_default_site = $site->getIsDefault() ;
293
+ $orderAdjust = 0.0 ;
294
+ if ( $is_default_site )
295
+ $orderAdjust -= 0.25 ;
296
+ if ( $is_default_store )
297
+ $orderAdjust -= 0.25 ;
298
+
299
+ $availCurrCodes = $store->getAvailableCurrencyCodes() ;
300
+ $default_currency = $store->getDefaultCurrencyCode() ;
301
+ $vary_curr = '' ;
302
+ $curr = trim(Mage::getStoreConfig(self::STOREXML_WARMUP_MULTICURR, $storeId)) ;
303
+ if ( $curr ) {
304
+ // get currency vary
305
+ $currs = preg_split("/[\s,]+/", strtoupper($curr), null, PREG_SPLIT_NO_EMPTY) ;
306
+ if ( in_array('ALL', $currs) ) {
307
+ $currs = $availCurrCodes ;
308
  }
309
  else {
310
+ $currs = array_unique($currs) ;
311
+ }
312
+
313
+ foreach ( $currs as $cur ) {
314
+ if ( $cur != $default_currency && in_array($cur, $availCurrCodes) ) {
315
+ $vary_curr .= ',' . $cur ;
316
  }
317
+ }
318
+ if ( $vary_curr ) {
319
+ $vary_curr = '/vary_curr/-' . $vary_curr ; // "-" means default
320
+ }
321
+ }
322
+
323
+ $vary_cgrp = '' ;
324
+ /* if ( $diffGrp = Mage::getStoreConfig(self::STOREXML_DIFFCUSTGRP, $storeId)) ) {
325
+ // $crawlgrp = 'out' ;
326
+ $crawlUsers = array(138, 137);
327
+ if ($crawlUsers) {
328
+ if ($diffGrp == 2) {
329
+ // for in & out
330
+ $crawlgrp .= ',in_138';
331
+ }
332
+ * '/vary_cgrp/' . $vary_customergroup ;
333
+ }
334
+ //} */
335
+
336
+ $env = '' ;
337
+
338
+ $priority = Mage::getStoreConfig(self::STOREXML_WARMUP_PRIORITY, $storeId) + $orderAdjust ;
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
+ $interval = Mage::getStoreConfig(self::STOREXML_WARMUP_INTERVAL, $storeId) ;
347
+ if ( $interval == '' || $interval < 600 ) { // for upgrade users, not refreshed conf
348
+ $interval = $ttl ;
349
+ }
350
+
351
+ $listId = 'store' . $storeId ;
352
+ $storeInfo[$listId] = array(
353
+ 'id' => $listId,
354
+ 'storeid' => $storeId,
355
+ 'store_name' => $storeName,
356
+ 'default_curr' => $default_currency,
357
+ 'default_store' => $is_default_store,
358
+ 'default_site' => $is_default_site,
359
+ 'env' => $env,
360
+ 'interval' => $interval,
361
+ 'ttl' => $ttl,
362
+ 'priority' => $priority,
363
+ 'baseurl' => $baseurl) ;
364
+
365
+ // check custom list
366
+ $custlist = Mage::getStoreConfig(self::STOREXML_WARMUP_CUSTLIST, $storeId) ;
367
+ $lines = explode("\n", $custlist) ;
368
+ foreach ( $lines as $index => $line ) {
369
+ $f = preg_split("/[\s]+/", $line, null, PREG_SPLIT_NO_EMPTY) ;
370
+ if (count($f) != 3) {
371
+ continue;
372
+ }
373
+ $custFile = $f[0] ;
374
+ if ( ! is_readable($custFile) || ! isset($f[1]) || ! isset($f[2]) || $f[1] < 600 || $f[2] <= 0 ) {
375
+ continue ;
376
+ }
377
+ $custInterval = $f[1] ;
378
+ $custPriority = $f[2] ;
379
+ $listId = 'cust' . $storeId . '-' . $index ;
380
+ $storeInfo[$listId] = array(
381
+ 'id' => $listId,
382
+ 'storeid' => $storeId,
383
+ 'store_name' => $storeName,
384
+ 'default_curr' => $default_currency,
385
+ 'env' => $env,
386
+ 'interval' => $custInterval,
387
+ 'ttl' => $ttl,
388
+ 'priority' => $custPriority,
389
+ 'baseurl' => $baseurl,
390
+ 'file' => $custFile ) ;
391
+ }
392
+ return $storeInfo;
393
+ }
394
+
395
+ public function isEsiBlock( $block, $startDynamic )
396
+ {
397
+ $blockName = $block->getNameInLayout() ;
398
+ $tag = null ;
399
+ $valueonly = 0 ;
400
+ $blockType = null ;
401
+
402
+ $ref = $this->_conf[self::CFG_ESIBLOCK]['block'] ;
403
+ if ( isset($ref['bn'][$blockName]) ) {
404
+ $tag = $ref['bn'][$blockName]['tag'] ;
405
+ $valueonly = $ref['bn'][$blockName]['valueonly'] ;
406
+ }
407
+ else {
408
+ foreach ( $ref['bt'] as $bt => $bv ) {
409
+ if ( $block instanceof $bt ) {
410
+ $tag = $bv['tag'] ;
411
+ $valueonly = $bv['valueonly'] ;
412
+ $blockType = $bt ;
413
+ break ;
414
  }
415
  }
416
  }
417
+ if ( ($tag == null) && ($bd = $block->getData('litemage_dynamic')) ) {
418
+ if ( isset($bd['tag']) && isset($this->_conf[self::CFG_ESIBLOCK]['tag'][$bd['tag']]) ) {
419
+ $tag = $bd['tag'] ;
420
+ }
421
+ else {
422
+ $tag = 'welcome' ; // default
423
+ }
424
+ if ( isset($bd['valueonly']) ) {
425
+ $valueonly = 1 ;
426
+ }
427
+ }
428
+
429
+ if ( $tag == null ) {
430
+ return false ;
431
+ }
432
+
433
+ $tagdata = $this->_conf[self::CFG_ESIBLOCK]['tag'][$tag] ;
434
+ $bconf = array(
435
+ 'tag' => $tag,
436
+ 'cache-tag' => $tagdata['cache-tag'],
437
+ 'access' => $tagdata['access'],
438
+ 'valueonly' => $valueonly,
439
+ 'bn' => $blockName,
440
+ 'bt' => $blockType
441
+ ) ;
442
+ if ( $startDynamic ) {
443
+ $bconf['pc'] = get_class($block) ;
444
+ $bconf['is_dynamic'] = 1 ;
445
+ // template may not be set at the moment
446
+ }
447
 
448
+ $block->setData('litemage_bconf', $bconf) ;
449
+ return true ;
450
+ }
451
 
452
+ public function getNoCacheConf( $name = '' )
453
+ {
454
+ return $this->getConf($name, self::CFG_NOCACHE) ;
455
  }
456
 
457
+ public function getConf( $name, $type = '' )
458
+ {
459
+ if ( ($type == '' && ! isset($this->_conf[$name])) || ($type != '' && ! isset($this->_conf[$type])) ) {
460
+ $this->_initConf($type) ;
461
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
462
 
463
  // get store override, because store id may change after init
464
+ if ( $name == self::CFG_DIFFCUSTGRP ) {
465
+ $this->_conf[self::CFG_DIFFCUSTGRP] = Mage::getStoreConfig(self::STOREXML_DIFFCUSTGRP) ;
466
  }
467
+ elseif ( $name == self::CFG_PUBLICTTL ) {
468
+ $this->_conf[self::CFG_PUBLICTTL] = Mage::getStoreConfig(self::STOREXML_PUBLICTTL) ;
469
  }
470
+ elseif ( $name == self::CFG_PRIVATETTL ) {
471
+ $this->_conf[self::CFG_PRIVATETTL] = Mage::getStoreConfig(self::STOREXML_PRIVATETTL) ;
472
  }
473
+ elseif ( $name == self::CFG_HOMETTL ) {
474
+ $this->_conf[self::CFG_HOMETTL] = Mage::getStoreConfig(self::STOREXML_HOMETTL) ;
475
  }
476
+ elseif ( $name == self::CFG_TRACKLASTVIEWED ) {
477
+ $this->_conf[self::CFG_TRACKLASTVIEWED] = Mage::getStoreConfig(self::STOREXML_TRACKLASTVIEWED) ;
478
+ }
479
+
480
+ if ( $type == '' )
481
+ return $this->_conf[$name] ;
482
+ elseif ( $name == '' )
483
+ return $this->_conf[$type] ;
484
+ else
485
+ return $this->_conf[$type][$name] ;
486
+ }
487
 
488
+ protected function _initConf( $type = '' )
489
+ {
490
+ $storeId = Mage::app()->getStore()->getId() ;
491
+ if ( ! isset($this->_conf['defaultlm']) ) {
492
+ $this->_conf['defaultlm'] = $this->_getConfigByPath(self::CFGXML_DEFAULTLM) ;
493
+ }
494
+ $pattern = "/[\s,]+/" ;
495
+
496
+ switch ( $type ) {
497
+ case self::CFG_ESIBLOCK:
498
+ $this->_conf[self::CFG_ESIBLOCK] = array() ;
499
+ $this->_conf[self::CFG_ESIBLOCK]['tag'] = $this->_getConfigByPath(self::CFGXML_ESIBLOCK) ;
500
+
501
+ $custblocks = array() ;
502
+ $custblocks['welcome'] = preg_split($pattern, $this->_conf['defaultlm']['donotcache']['welcome'], null, PREG_SPLIT_NO_EMPTY) ;
503
+ $custblocks['toplinks'] = preg_split($pattern, $this->_conf['defaultlm']['donotcache']['toplinks'], null, PREG_SPLIT_NO_EMPTY) ;
504
+ $custblocks['messages'] = preg_split($pattern, $this->_conf['defaultlm']['donotcache']['messages'], null, PREG_SPLIT_NO_EMPTY) ;
505
+
506
+ $allblocks = array( 'bn' => array(), 'bt' => array() ) ;
507
+ foreach ( $this->_conf[self::CFG_ESIBLOCK]['tag'] as $tag => $d ) {
508
+ $this->_conf[self::CFG_ESIBLOCK]['tag'][$tag]['cache-tag'] = Litespeed_Litemage_Helper_Esi::TAG_PREFIX_ESIBLOCK . $tag ;
509
+ $blocks = preg_split($pattern, $d['blocks'], null, PREG_SPLIT_NO_EMPTY) ;
510
+ if ( ! empty($custblocks[$tag]) ) {
511
+ $blocks = array_merge($blocks, $custblocks[$tag]) ;
512
+ }
513
+
514
+ foreach ( $blocks as $b ) {
515
+ $valueonly = 0 ;
516
+ if ( substr($b, -2) == '$v' ) {
517
+ $valueonly = 1 ;
518
+ $b = substr($b, 0, -2) ;
519
+ }
520
+ $bc = array( 'tag' => $tag, 'valueonly' => $valueonly ) ;
521
+ if ( substr($b, 0, 2) == 'T:' ) {
522
+ $b = substr($b, 2) ;
523
+ $allblocks['bt'][$b] = $bc ;
524
+ }
525
+ else {
526
+ $allblocks['bn'][$b] = $bc ;
527
+ }
528
+ }
529
+ if ( isset($d['purge_tags']) ) {
530
+ $pts = preg_split($pattern, $d['purge_tags'], null, PREG_SPLIT_NO_EMPTY) ;
531
+ if ( ! isset($d['purge_events']) ) {
532
+ $this->_conf[self::CFG_ESIBLOCK]['tag'][$tag]['purge_events'] = array() ;
533
+ }
534
+ foreach ( $pts as $t ) {
535
+ if ( isset($this->_conf[self::CFG_ESIBLOCK]['tag'][$t]['purge_events']) ) {
536
+ $this->_conf[self::CFG_ESIBLOCK]['tag'][$tag]['purge_events'] = array_merge($this->_conf[self::CFG_ESIBLOCK]['tag'][$tag]['purge_events'], $this->_conf[self::CFG_ESIBLOCK]['tag'][$t]['purge_events']) ;
537
+ }
538
+ }
539
+ }
540
+ }
541
+ $this->_conf[self::CFG_ESIBLOCK]['block'] = $allblocks ;
542
+ break ;
543
+
544
+ case self::CFG_NOCACHE:
545
+ $this->_conf[self::CFG_NOCACHE] = array() ;
546
+ $default = $this->_conf['defaultlm']['default'] ;
547
+ $cust = $this->_conf['defaultlm']['donotcache'] ;
548
+
549
+ $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)) ;
550
+ $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)) ;
551
+ $this->_conf[self::CFG_NOCACHE][self::CFG_FULLCACHE_ROUTE] = preg_split($pattern, $default['fullcache_routes'], null, PREG_SPLIT_NO_EMPTY) ;
552
+ $this->_conf[self::CFG_NOCACHE][self::CFG_NOCACHE_VAR] = preg_split($pattern, $cust['vars'], null, PREG_SPLIT_NO_EMPTY) ;
553
+ $this->_conf[self::CFG_NOCACHE][self::CFG_NOCACHE_URL] = preg_split($pattern, $cust['urls'], null, PREG_SPLIT_NO_EMPTY) ;
554
+ break ;
555
+
556
+ case self::CFG_WARMUP:
557
+ $warmup = $this->_conf['defaultlm']['warmup'] ;
558
+ $this->_conf[self::CFG_WARMUP] = array(
559
+ self::CFG_WARMUP_EANBLED => $warmup[self::CFG_WARMUP_EANBLED],
560
+ self::CFG_WARMUP_LOAD_LIMIT => $warmup[self::CFG_WARMUP_LOAD_LIMIT],
 
 
 
 
 
 
 
 
 
 
 
 
 
561
  self::CFG_WARMUP_THREAD_LIMIT => $warmup[self::CFG_WARMUP_THREAD_LIMIT],
562
+ self::CFG_WARMUP_MAXTIME => $warmup[self::CFG_WARMUP_MAXTIME],
563
+ self::CFG_WARMUP_MULTICURR => $warmup[self::CFG_WARMUP_MULTICURR] ) ;
564
+ break ;
565
 
566
+ default:
567
+ $general = $this->_conf['defaultlm']['general'] ;
568
+ $this->_conf[self::CFG_ENABLED] = $general[self::CFG_ENABLED] ;
569
 
570
+ $test = $this->_conf['defaultlm']['test'] ;
571
+ $this->_conf[self::CFG_DEBUGON] = $test[self::CFG_DEBUGON] ;
572
+ $this->_isDebug = $test[self::CFG_DEBUGON] ; // required by cron, needs to be set even when module disabled.
573
 
574
+ if ( ! $general[self::CFG_ENABLED] )
575
+ break ;
576
 
577
  // get store override
578
+ $this->_conf[self::CFG_TRACKLASTVIEWED] = Mage::getStoreConfig(self::STOREXML_TRACKLASTVIEWED, $storeId) ;
579
+ $this->_conf[self::CFG_DIFFCUSTGRP] = Mage::getStoreConfig(self::STOREXML_DIFFCUSTGRP, $storeId) ;
580
+ $this->_conf[self::CFG_PUBLICTTL] = Mage::getStoreConfig(self::STOREXML_PUBLICTTL, $storeId) ;
581
+ $this->_conf[self::CFG_PRIVATETTL] = Mage::getStoreConfig(self::STOREXML_PRIVATETTL, $storeId) ;
582
+ $this->_conf[self::CFG_HOMETTL] = Mage::getStoreConfig(self::STOREXML_HOMETTL, $storeId) ;
583
+
584
+ $adminIps = trim($general[self::CFG_ADMINIPS]) ;
585
+ $this->_conf[self::CFG_ADMINIPS] = $adminIps ? preg_split($pattern, $adminIps, null, PREG_SPLIT_NO_EMPTY) : '' ;
586
+ if ( $general['alt_esi_syntax'] ) {
587
+ $this->_esiTag = array( 'include' => 'esi_include', 'inline' => 'esi_inline', 'remove' => 'esi_remove' ) ;
588
+ }
589
+ else {
590
+ $this->_esiTag = array( 'include' => 'esi:include', 'inline' => 'esi:inline', 'remove' => 'esi:remove' ) ;
591
+ }
592
+ $allowedIps = trim($test[self::CFG_ALLOWEDIPS]) ;
593
+ $this->_conf[self::CFG_ALLOWEDIPS] = $allowedIps ? preg_split($pattern, $allowedIps, null, PREG_SPLIT_NO_EMPTY) : '' ;
594
+ }
595
+ }
596
+
597
+ protected function _getConfigByPath( $xmlPath )
598
+ {
599
  $node = Mage::getConfig()->getNode($xmlPath) ;
600
+ if ( ! $node )
601
+ Mage::throwException('Litemage missing config in xml path ' . $xmlPath) ;
602
+ return $node->asCanonicalArray() ;
603
+ }
604
+
605
+ public function debugMesg( $mesg )
606
+ {
607
+ if ( $this->_isDebug ) {
608
+ $mesg = str_replace("\n", ("\n" . $this->_debugTag . ' '), $mesg) ;
609
+ Mage::log($this->_debugTag . ' ' . $mesg) ;
610
+ }
611
+ }
612
 
613
  }
app/code/community/Litespeed/Litemage/Helper/Esi.php CHANGED
@@ -34,23 +34,26 @@ class Litespeed_Litemage_Helper_Esi
34
  const TAG_PREFIX_CATEGORY = 'C.' ;
35
  const TAG_PREFIX_PRODUCT = 'P.' ;
36
  const TAG_PREFIX_ESIBLOCK = 'E.' ;
37
- //BITMASK for Cache Header Flag
 
38
  const CHBM_CACHEABLE = 1 ;
39
  const CHBM_PRIVATE = 2 ;
40
  const CHBM_ONLY_CACHE_EMPTY = 4 ;
41
  const CHBM_ESI_ON = 16 ;
42
  const CHBM_ESI_REQ = 32 ;
43
  const CHBM_FORMKEY_REPLACED = 64 ;
 
 
44
  const FORMKEY_REAL = '_litemage_realformkey' ;
45
  const FORMKEY_REPLACE = 'litemagefmkeylmg' ; //do not use special characters, maybe changed by urlencode
46
  const FORMKEY_NAME = '_form_key' ;
47
- const ENV_COOKIE_NAME = '_lscache_vary' ;
48
 
49
  // config items
50
  protected $_viewedTracker ;
51
  protected $_cacheVars = array( 'tag' => array(), 'flag' => 0, 'ttl' => -1, 'env' => array(), 'cookie' => array(), 'baseUrl' => '', 'baseUrlESI' => '' ) ;
52
- protected $_esiBlocks = array();
53
  protected $_esiPurgeEvents = array() ;
 
54
  protected $_isDebug;
55
  protected $_config;
56
 
@@ -59,6 +62,9 @@ class Litespeed_Litemage_Helper_Esi
59
  {
60
  $this->_config = Mage::helper('litemage/data');
61
  $this->_isDebug = $this->_config->isDebug();
 
 
 
62
  }
63
 
64
  public function isDebug()
@@ -77,42 +83,21 @@ class Litespeed_Litemage_Helper_Esi
77
  $this->_config->getEsiConf('tag');
78
  }
79
 
80
- public function setEsiOn()
 
 
 
 
 
81
  {
82
  if ( ($this->_cacheVars['flag'] & self::CHBM_ESI_ON) == 0 ) {
83
  $this->_cacheVars['flag'] |= self::CHBM_ESI_ON ;
84
  }
85
  }
86
 
87
- public function setEsiBlockHtml($blockIndex, $html)
88
- {
89
- if (isset($this->_esiBlocks[$blockIndex])) {
90
- $this->_esiBlocks['adjusted'] = 1;
91
- }
92
- $this->_esiBlocks[$blockIndex] = $html ;
93
- }
94
-
95
- public function isEsiBlockAdjusted()
96
- {
97
- return isset($this->_esiBlocks['adjusted']);
98
- }
99
-
100
- public function getEsiBlockHtml()
101
- {
102
- return serialize($this->_esiBlocks);
103
- }
104
-
105
  public function getBaseUrl()
106
  {
107
  if ($this->_cacheVars['baseUrl'] == '') {
108
- /*$base2 = Mage::app()->getRequest()->getBaseUrl();
109
- if (($base2 == '') || (substr($base2, -1) != '/'))
110
- $base2 .= '/';
111
-
112
- if (strpos($base2, 'index.php/') === false)
113
- $base2 .= 'index.php/';
114
- */
115
-
116
  $base = Mage::getBaseUrl(); // cannot use request->getBaseUrl, as store ID maybe in url
117
  $this->_cacheVars['baseUrl'] = $base;
118
  $esibase = $base;
@@ -135,11 +120,12 @@ class Litespeed_Litemage_Helper_Esi
135
  return $this->_cacheVars['baseUrlESI'];
136
  }
137
 
138
- public function getSubReqUrl($route, $params)
139
  {
140
  $baseurl = $this->getEsiBaseUrl();
141
  $url = $baseurl . $route . '/';
142
- foreach ( $params as $key => $value ) {
 
143
  $url .= $key . '/' . $value . '/';
144
  }
145
  return $url;
@@ -171,37 +157,36 @@ class Litespeed_Litemage_Helper_Esi
171
  }
172
  }
173
 
174
- public function restoreFormKey()
175
  {
176
  if ( ($this->_cacheVars['flag'] & self::CHBM_FORMKEY_REPLACED) != 0 ) {
177
  $session = Mage::getSingleton('core/session') ;
178
- if ( ($realFormKey = $session->getData(self::FORMKEY_REAL)) != null ) {
179
  $session->unsetData(self::FORMKEY_REAL) ;
180
  $session->setData(self::FORMKEY_NAME, $realFormKey) ;
181
  }
182
  }
183
  }
184
 
185
- public function addPurgeEvent( $eventName )
186
  {
187
  // 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
188
- if (!isset($this->_esiPurgeEvents[$eventName])) {
189
-
190
- $this->_esiPurgeEvents[$eventName] = $eventName ;
191
-
192
- if ( $cachePurgeHeader = $this->_getEsiPurgeHeader() ) {
193
- $purgeHeader = $this->_getPurgeHeaderValue($cachePurgeHeader, true);
194
- header(self::LSHEADER_PURGE . ': ' . $purgeHeader, true);
195
- if ($this->_isDebug)
196
- $this->_config->debugMesg("SetPurgeHeader: " . $purgeHeader . ' (triggered by event ' . $eventName . ')') ;
197
- }
198
- }
199
  }
200
 
201
- protected function _getEsiPurgeHeader()
202
  {
203
  if ( count($this->_esiPurgeEvents) == 0 )
204
- return null ;
205
 
206
  $events = $this->_config->getEsiConf('event');
207
  $tags = array() ;
@@ -219,12 +204,12 @@ class Litespeed_Litemage_Helper_Esi
219
  $this->_config->debugMesg('Purge events ' . implode(', ', $this->_esiPurgeEvents) . ' tags: ' . implode(', ', $tags));
220
  }
221
 
222
- return (count($tags) ? $tags : null) ;
223
  }
224
 
225
- protected function _getPurgeHeaderValue($tags, $private)
226
  {
227
- $purgeHeader = $private ? 'private,' : '' ;
228
  $t = '';
229
  foreach ($tags as $tag) {
230
  $t .= ( $tag == '*' ) ? '*' : 'tag=' . $tag . ',' ;
@@ -233,16 +218,17 @@ class Litespeed_Litemage_Helper_Esi
233
  return $purgeHeader;
234
  }
235
 
236
- public function setPurgeHeader( $tags, $by, $response = null, $private = false )
237
  {
238
- $purgeHeader = $this->_getPurgeHeaderValue($tags, $private);
239
 
240
- if ( $response == null ) {
241
  $response = Mage::app()->getResponse() ;
242
  }
243
 
244
- if ($this->_isDebug)
245
  $this->_config->debugMesg("SetPurgeHeader: " . $purgeHeader . ' (triggered by ' . $by . ')') ;
 
246
  $response->setHeader(self::LSHEADER_PURGE, $purgeHeader, true) ;
247
  }
248
 
@@ -250,8 +236,9 @@ class Litespeed_Litemage_Helper_Esi
250
  {
251
  $response = Mage::app()->getResponse() ;
252
 
253
- if ($this->_isDebug)
254
  $this->_config->debugMesg("SetPurgeHeader: " . $url . ' (triggered by ' . $by . ')') ;
 
255
  $response->setHeader(self::LSHEADER_PURGE, $url, true) ;
256
  }
257
 
@@ -267,14 +254,185 @@ class Litespeed_Litemage_Helper_Esi
267
 
268
  public function trackProduct( $productId )
269
  {
270
- if ( $this->_viewedTracker == null )
271
  $this->_viewedTracker = array( 'product' => $productId ) ;
272
  else
273
  $this->_viewedTracker['product'] = $productId ;
274
  }
275
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
276
  public function beforeResponseSend( $response )
277
  {
 
 
278
  $extraHeaders = array();
279
  $envChanged = $this->setEnvCookie();
280
 
@@ -317,7 +475,7 @@ class Litespeed_Litemage_Helper_Esi
317
  if ((($flag & self::CHBM_ESI_REQ) == 0) // for non-esi request
318
  && ((($flag & self::CHBM_ESI_ON) != 0) // esi on
319
  || (($flag & self::CHBM_FORMKEY_REPLACED) != 0) // formkey replaced
320
- || ($this->_viewedTracker != null))) { // has view tracker
321
  $this->_updateResponseBody($response) ;
322
  }
323
 
@@ -336,7 +494,7 @@ class Litespeed_Litemage_Helper_Esi
336
  $extraHeaders[self::LSHEADER_PURGE] = $this->_getPurgeCacheTags();
337
  }
338
 
339
- $this->restoreFormKey() ;
340
 
341
  foreach($extraHeaders as $key => $val) {
342
  $response->setHeader($key, $val);
@@ -359,39 +517,53 @@ class Litespeed_Litemage_Helper_Esi
359
  $esiIncludeTag = $this->_config->esiTag('include');
360
 
361
  if ( (($this->_cacheVars['flag'] & self::CHBM_FORMKEY_REPLACED) != 0) && strpos($responseBody, self::FORMKEY_REPLACE) ) {
362
- $replace = '<' . $esiIncludeTag . ' src="' . $this->getEsiBaseUrl() . 'litemage/esi/getFormKey" as-var="1" combine="sub" cache-control="no-vary,private" cache-tag="E.formkey"/>' ;
 
363
  $responseBody = str_replace(self::FORMKEY_REPLACE, $replace, $responseBody) ;
364
  if ($this->_isDebug) {
365
- $this->_config->debugMesg('Form key replaced as ' . $replace);
366
  }
367
  $updated = true ;
368
  }
369
 
370
- if ( $this->_viewedTracker != null ) {
371
  $logOptions = $this->_viewedTracker;
372
  $logOptions['s'] = $sharedParams['s'];
373
- //$tracker = '<!--esi<esi:include src="' . $this->getSubReqUrl('litemage/esi/log', $logOptions)
374
- // . '" test="$(RESP_HEADER{X-LITESPEED-CACHE})!=\'\'" cache-control="no-cache" combine="sub"/>-->' ;
375
- // remove comments for html minify
376
  // if response coming from backend, no need to send separate log request
377
- $tracker = '<' . $esiIncludeTag . ' src="' . $this->getSubReqUrl('litemage/esi/log', $logOptions)
378
  . '" test="$(RESP_HEADER{X-LITESPEED-CACHE})!=\'\'" cache-control="no-cache" combine="sub"/>' ;
 
 
 
379
  $updated = true ;
380
  }
381
 
382
  if ( $updated )
383
- $this->setEsiOn() ;
384
 
385
  if ( ($this->_cacheVars['flag'] & self::CHBM_ESI_ON) != 0 ) {
386
  // no need to use comment, will be removed by minify extensions
387
- $combined = '<' . $esiIncludeTag . ' src="' . $this->getSubReqUrl('litemage/esi/getCombined', $sharedParams) . '" combine="main" cache-control="no-cache"/>' ;
 
 
 
388
  $updated = true;
389
  }
390
 
391
  if ( $updated ) {
392
- $response->setBody($combined . $tracker . $responseBody) ;
393
- if ($this->_isDebug) {
394
- $this->_config->debugMesg('_updateResponseBody combined is ' . $combined);
 
 
 
 
 
 
 
 
 
395
  }
396
  }
397
 
@@ -403,10 +575,10 @@ class Litespeed_Litemage_Helper_Esi
403
  if ($notEsiReq) {
404
  if ( count($tags) == 0 ) {
405
  // set tag for product id, cid, and pageid
406
- if ( ($curProduct = Mage::registry('current_product')) != null ) {
407
  $tags[] = self::TAG_PREFIX_PRODUCT . $curProduct->getId() ;
408
  }
409
- elseif ( ($curCategory = Mage::registry('current_category')) != null ) {
410
  $tags[] = self::TAG_PREFIX_CATEGORY . $curCategory->getId() ;
411
  }
412
  }
@@ -426,10 +598,10 @@ class Litespeed_Litemage_Helper_Esi
426
  $tags = $this->_cacheVars['tag'] ;
427
  if (empty($tags)) {
428
  // set tag for product id, cid, and pageid
429
- if ( ($curProduct = Mage::registry('current_product')) != null ) {
430
  $tags[] = self::TAG_PREFIX_PRODUCT . $curProduct->getId() ;
431
  }
432
- elseif ( ($curCategory = Mage::registry('current_category')) != null ) {
433
  $tags[] = self::TAG_PREFIX_CATEGORY . $curCategory->getId() ;
434
  }
435
  else {
@@ -452,7 +624,7 @@ class Litespeed_Litemage_Helper_Esi
452
  foreach ($this->_cacheVars['env'] as $name => $data) {
453
  $newVal = '';
454
  $oldVal = '';
455
- if ($data != null) {
456
  ksort($data); // data is array, key sorted
457
  foreach ($data as $k => $v) {
458
  $newVal .= $k . '~' . $v . '~';
@@ -478,7 +650,7 @@ class Litespeed_Litemage_Helper_Esi
478
  $vary_on = array();
479
 
480
  foreach ($this->_cacheVars['env'] as $name => $data) {
481
- if ($name != self::ENV_COOKIE_NAME) {
482
  $vary_on[] = 'cookie=' . $name;
483
  }
484
  }
@@ -522,16 +694,16 @@ class Litespeed_Litemage_Helper_Esi
522
  $default['dev'] = 1; //developer mode for restrained IP
523
  }
524
 
525
- $this->_cacheVars['env'][self::ENV_COOKIE_NAME] = count($default) > 0 ? $default : null ;
526
  }
527
 
528
 
529
  public function getDefaultEnvCookie()
530
  {
531
- if ( ! isset($this->_cacheVars['env'][self::ENV_COOKIE_NAME]) ) {
532
  $this->setDefaultEnvCookie();
533
  }
534
- return $this->_cacheVars['env'][self::ENV_COOKIE_NAME];
535
  }
536
 
537
  public function getEsiSharedParams()
@@ -569,9 +741,9 @@ class Litespeed_Litemage_Helper_Esi
569
  public function getCookieEnvVars( $cookieName )
570
  {
571
  if ( ! isset($this->_cacheVars['cookie'][$cookieName]) ) {
572
- $this->_cacheVars['cookie'][$cookieName] = null ;
573
  $cookieVal = Mage::getSingleton('core/cookie')->get($cookieName) ;
574
- if ( $cookieVal != null ) {
575
  $cv = explode('~', trim($cookieVal, '~')); // restore cookie value
576
  for ($i = 0 ; $i < count($cv) ; $i += 2) {
577
  $this->_cacheVars['cookie'][$cookieName][$cv[$i]] = $cv[$i+1];
@@ -585,7 +757,7 @@ class Litespeed_Litemage_Helper_Esi
585
 
586
  public function addEnvVars($cookieName, $key='', $val='' )
587
  {
588
- if ( ! isset($this->_cacheVars['env'][$cookieName]) || ($this->_cacheVars['env'][$cookieName] == null) ) {
589
  $this->_cacheVars['env'][$cookieName] = array() ;
590
  }
591
  if ($key != '') {
34
  const TAG_PREFIX_CATEGORY = 'C.' ;
35
  const TAG_PREFIX_PRODUCT = 'P.' ;
36
  const TAG_PREFIX_ESIBLOCK = 'E.' ;
37
+
38
+ //BITMASK for Cache Header Flag
39
  const CHBM_CACHEABLE = 1 ;
40
  const CHBM_PRIVATE = 2 ;
41
  const CHBM_ONLY_CACHE_EMPTY = 4 ;
42
  const CHBM_ESI_ON = 16 ;
43
  const CHBM_ESI_REQ = 32 ;
44
  const CHBM_FORMKEY_REPLACED = 64 ;
45
+ const CHBM_NOT_CACHEABLE = 128 ; // for redirect
46
+
47
  const FORMKEY_REAL = '_litemage_realformkey' ;
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
57
  protected $_isDebug;
58
  protected $_config;
59
 
62
  {
63
  $this->_config = Mage::helper('litemage/data');
64
  $this->_isDebug = $this->_config->isDebug();
65
+ if (isset($_SERVER['LSCACHE_VARY_COOKIE'])) {
66
+ $this->_defaultEnvVaryCookie = $_SERVER['LSCACHE_VARY_COOKIE'];
67
+ }
68
  }
69
 
70
  public function isDebug()
83
  $this->_config->getEsiConf('tag');
84
  }
85
 
86
+ public function notCacheable()
87
+ {
88
+ return ( ($this->_cacheVars['flag'] & self::CHBM_NOT_CACHEABLE) == self::CHBM_NOT_CACHEABLE );
89
+ }
90
+
91
+ protected function _setEsiOn()
92
  {
93
  if ( ($this->_cacheVars['flag'] & self::CHBM_ESI_ON) == 0 ) {
94
  $this->_cacheVars['flag'] |= self::CHBM_ESI_ON ;
95
  }
96
  }
97
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  public function getBaseUrl()
99
  {
100
  if ($this->_cacheVars['baseUrl'] == '') {
 
 
 
 
 
 
 
 
101
  $base = Mage::getBaseUrl(); // cannot use request->getBaseUrl, as store ID maybe in url
102
  $this->_cacheVars['baseUrl'] = $base;
103
  $esibase = $base;
120
  return $this->_cacheVars['baseUrlESI'];
121
  }
122
 
123
+ protected function _getSubReqUrl($route, $params)
124
  {
125
  $baseurl = $this->getEsiBaseUrl();
126
  $url = $baseurl . $route . '/';
127
+ $eparams = $this->_config->encodeEsiUrlParams($params);
128
+ foreach ( $eparams as $key => $value ) {
129
  $url .= $key . '/' . $value . '/';
130
  }
131
  return $url;
157
  }
158
  }
159
 
160
+ protected function _restoreFormKey()
161
  {
162
  if ( ($this->_cacheVars['flag'] & self::CHBM_FORMKEY_REPLACED) != 0 ) {
163
  $session = Mage::getSingleton('core/session') ;
164
+ if ( ($realFormKey = $session->getData(self::FORMKEY_REAL)) != NULL ) {
165
  $session->unsetData(self::FORMKEY_REAL) ;
166
  $session->setData(self::FORMKEY_NAME, $realFormKey) ;
167
  }
168
  }
169
  }
170
 
171
+ public function addPrivatePurgeEvent( $eventName )
172
  {
173
  // 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
174
+ if (isset($this->_esiPurgeEvents[$eventName]))
175
+ return;
176
+
177
+ $this->_esiPurgeEvents[$eventName] = $eventName ;
178
+ if ( $cachePurgeTags = $this->_getEsiPurgeTags() ) {
179
+ $purgeHeader = $this->_getPurgeHeaderValue($cachePurgeTags, true);
180
+ header(self::LSHEADER_PURGE . ': ' . $purgeHeader, true);
181
+ if ($this->_isDebug)
182
+ $this->_config->debugMesg("SetPurgeHeader: " . $purgeHeader . ' (triggered by event ' . $eventName . ')') ;
183
+ }
 
184
  }
185
 
186
+ protected function _getEsiPurgeTags()
187
  {
188
  if ( count($this->_esiPurgeEvents) == 0 )
189
+ return NULL ;
190
 
191
  $events = $this->_config->getEsiConf('event');
192
  $tags = array() ;
204
  $this->_config->debugMesg('Purge events ' . implode(', ', $this->_esiPurgeEvents) . ' tags: ' . implode(', ', $tags));
205
  }
206
 
207
+ return (count($tags) ? $tags : NULL) ;
208
  }
209
 
210
+ protected function _getPurgeHeaderValue($tags, $isPrivate)
211
  {
212
+ $purgeHeader = $isPrivate ? 'private,' : '' ;
213
  $t = '';
214
  foreach ($tags as $tag) {
215
  $t .= ( $tag == '*' ) ? '*' : 'tag=' . $tag . ',' ;
218
  return $purgeHeader;
219
  }
220
 
221
+ public function setPurgeHeader( $tags, $by, $response = NULL, $isPrivate = false )
222
  {
223
+ $purgeHeader = $this->_getPurgeHeaderValue($tags, $isPrivate);
224
 
225
+ if ( $response == NULL ) {
226
  $response = Mage::app()->getResponse() ;
227
  }
228
 
229
+ if ($this->_isDebug) {
230
  $this->_config->debugMesg("SetPurgeHeader: " . $purgeHeader . ' (triggered by ' . $by . ')') ;
231
+ }
232
  $response->setHeader(self::LSHEADER_PURGE, $purgeHeader, true) ;
233
  }
234
 
236
  {
237
  $response = Mage::app()->getResponse() ;
238
 
239
+ if ($this->_isDebug) {
240
  $this->_config->debugMesg("SetPurgeHeader: " . $url . ' (triggered by ' . $by . ')') ;
241
+ }
242
  $response->setHeader(self::LSHEADER_PURGE, $url, true) ;
243
  }
244
 
254
 
255
  public function trackProduct( $productId )
256
  {
257
+ if ( $this->_viewedTracker == NULL )
258
  $this->_viewedTracker = array( 'product' => $productId ) ;
259
  else
260
  $this->_viewedTracker['product'] = $productId ;
261
  }
262
 
263
+ public function getEsiIncludeHtml($block)
264
+ {
265
+ if (!isset($this->_esiLayoutCache)) {
266
+ // load from cache
267
+ $this->_initEsiLayoutCache($block);
268
+ }
269
+
270
+ $bi = $this->_getEsiBlockIndex($block);
271
+ if (isset($this->_esiLayoutCache['blocks'][$bi]['e'])) {
272
+ $html = $this->_esiLayoutCache['blocks'][$bi]['e'];
273
+ }
274
+ else {
275
+ $html = $this->_loadEsiIncludeHtml($block, $bi);
276
+ }
277
+ return $html;
278
+ }
279
+
280
+
281
+ protected function _initEsiLayoutCache( $block )
282
+ {
283
+ /*
284
+ * _esiLayoutCache => array(),
285
+ * 'cacheId'
286
+ * 'esiUpdate'
287
+ * 'adjusted'
288
+ * 'blocks[blockindex][e] : esiinclude html string'
289
+ * [h] : actual handle used
290
+ * [b] : block name
291
+ */
292
+
293
+ $update = $block->getLayout()->getUpdate();
294
+ if ( ! $update instanceof Litespeed_Litemage_Model_Layout_Update) {
295
+ Mage::throwException('LiteMage module requires Layout_Update class overwrite');
296
+ }
297
+
298
+ $tags = $update->getUsedHandles(); // used handles include customer_logged_in/out
299
+ $tags[] = 'LITEMAGE_INJECT_ESI' ;
300
+ $tags[] = join('-', $this->getEsiSharedParams()); // for env vary
301
+ $cacheId = 'LITEMAGE_BLOCK_' . md5(join('__', $tags)) ;
302
+ $this->_esiLayoutCache['cacheId'] = $cacheId ;
303
+ $this->_setEsiOn() ;
304
+
305
+ $preload = 0 ;
306
+ $this->_esiLayoutCache = array('adjusted' => false,
307
+ 'layoutUpdate' => $update,
308
+ 'cacheId' => $cacheId,
309
+ 'blocks' => array());
310
+
311
+ if ( $result = Mage::app()->loadCache($cacheId) ) {
312
+ $preload = 1 ;
313
+ $this->_esiLayoutCache['blocks'] = unserialize($result) ;
314
+ }
315
+
316
+ if ( $this->_isDebug ) {
317
+ // 0 not in cache, 1 from cache
318
+ $this->_config->debugMesg('INJECTING_' . $preload . ' ' . $_SERVER['REQUEST_URI']) ;
319
+ }
320
+ }
321
+
322
+ protected function _loadEsiIncludeHtml($block, $bi)
323
+ {
324
+ $bconf = $block->getData('litemage_bconf');
325
+ $blockName = $bconf['bn'];
326
+ $blockHandles = null;
327
+ $urlOptions = array('t' => $bconf['tag'], 'bi' => $bi);
328
+
329
+ if (isset($bconf['is_dynamic'])) {
330
+ $urlOptions['pc'] = $bconf['pc'];
331
+ if (!empty($block->getTemplate())) {
332
+ $urlOptions['pt'] = $block->getTemplate();
333
+ }
334
+ }
335
+ else {
336
+ $blockHandles = $this->_getBlockHandles($blockName, $block);
337
+ }
338
+
339
+ if (!empty($blockHandles)) {
340
+ $urlOptions['h'] = implode(',', $blockHandles);
341
+ }
342
+ $urlOptions = array_merge($urlOptions, $this->getEsiSharedParams());
343
+
344
+ $esiUrl = $this->_getSubReqUrl('litemage/esi/getBlock', $urlOptions) ;
345
+ // use single quote to work with pagespeed module
346
+ $esiHtml = '<' . $this->_config->esiTag('include') . " src='" . $esiUrl . "' combine='sub' cache-tag='" . $bconf['cache-tag'] . "' cache-control='no-vary," . $bconf['access'] . "'/>" ;
347
+ if ($this->_isDebug && !$bconf['valueonly']) {
348
+ $esiHtml = '<!--Litemage esi started ' . $blockName . '-->' . $esiHtml . '<!--Litemage esi ended ' . $blockName . '-->' ;
349
+ }
350
+
351
+ $this->_esiLayoutCache['blocks'][$bi] = array(
352
+ 'h' => $blockHandles, //actual handle used
353
+ 'e' => $esiHtml); // esiinclude html string
354
+ $this->_esiLayoutCache['adjusted'] = true;
355
+
356
+ return $esiHtml;
357
+ }
358
+
359
+ protected function _getEsiBlockIndex($block)
360
+ {
361
+ // check if it's in layout, maybe a lost child introduced by bad layout
362
+ $index = $this->_getEsiBlockIndexElement($block, $block->getLayout());
363
+ return implode(';', $index);
364
+ }
365
+
366
+ protected function _getEsiBlockIndexElement($block, $layout)
367
+ {
368
+ // check if it's in layout, maybe a lost child introduced by bad layout
369
+ $blockIndex = array();
370
+ $blockName = $block->getNameInLayout();
371
+
372
+ if ($layout->getBlock($blockName) != $block) {
373
+ $alias = $block->getBlockAlias();
374
+ if ($alias != '' && $alias != $blockName) {
375
+ $blockName .= ',' . $alias;
376
+ }
377
+
378
+ if ($parent = $block->getParentBlock()) {
379
+ $blockIndex = $this->_getEsiBlockIndexElement($parent, $layout);
380
+ }
381
+ }
382
+ $blockIndex[] = $blockName;
383
+ return $blockIndex;
384
+ }
385
+
386
+ protected function _getBlockHandles($blockName, $block)
387
+ {
388
+ $blockNames = $this->_getChildrenNames($block, $block->getLayout()) ;
389
+ if ( ($alias = $block->getBlockAlias()) && ($alias != $blockName) ) {
390
+ array_unshift($blockNames, $blockName, $alias) ;
391
+ }
392
+ else {
393
+ array_unshift($blockNames, $blockName) ;
394
+ }
395
+
396
+ $handles = $this->_esiLayoutCache['layoutUpdate']->getBlockHandles($blockNames);
397
+
398
+ return $handles;
399
+ }
400
+
401
+ protected function _getChildrenNames( $block, $layout )
402
+ {
403
+ if ($block == NULL) {
404
+ return array();
405
+ }
406
+
407
+ $children = $block->getSortedChildren() ;
408
+ foreach ( $children as $childName ) {
409
+ if ( $childBlock = $layout->getBlock($childName) ) {
410
+ $alias = $childBlock->getBlockAlias() ;
411
+ if ( $alias != $childName ) {
412
+ $children[] = $alias ;
413
+ }
414
+ $grandChildren = $this->_getChildrenNames($childBlock, $layout) ;
415
+ if ( count($grandChildren) > 0 ) {
416
+ $children = array_merge($children, $grandChildren) ;
417
+ }
418
+ }
419
+ }
420
+ return $children ;
421
+ }
422
+
423
+ protected function _refreshEsiBlockCache()
424
+ {
425
+ if ($this->_esiLayoutCache['adjusted'] && Mage::app()->useCache('layout')) {
426
+ $tags = array(Litespeed_Litemage_Helper_Data::LITEMAGE_GENERAL_CACHE_TAG, Mage_Core_Model_Layout_Update::LAYOUT_GENERAL_CACHE_TAG);
427
+ Mage::app()->saveCache(serialize($this->_esiLayoutCache['blocks']), $this->_esiLayoutCache['cacheId'], $tags) ;
428
+ $this->_esiLayoutCache['adjusted'] = false;
429
+ }
430
+ }
431
+
432
  public function beforeResponseSend( $response )
433
  {
434
+ $this->_refreshEsiBlockCache();
435
+
436
  $extraHeaders = array();
437
  $envChanged = $this->setEnvCookie();
438
 
475
  if ((($flag & self::CHBM_ESI_REQ) == 0) // for non-esi request
476
  && ((($flag & self::CHBM_ESI_ON) != 0) // esi on
477
  || (($flag & self::CHBM_FORMKEY_REPLACED) != 0) // formkey replaced
478
+ || ($this->_viewedTracker != NULL))) { // has view tracker
479
  $this->_updateResponseBody($response) ;
480
  }
481
 
494
  $extraHeaders[self::LSHEADER_PURGE] = $this->_getPurgeCacheTags();
495
  }
496
 
497
+ $this->_restoreFormKey() ;
498
 
499
  foreach($extraHeaders as $key => $val) {
500
  $response->setHeader($key, $val);
517
  $esiIncludeTag = $this->_config->esiTag('include');
518
 
519
  if ( (($this->_cacheVars['flag'] & self::CHBM_FORMKEY_REPLACED) != 0) && strpos($responseBody, self::FORMKEY_REPLACE) ) {
520
+ // use single quote for pagespeed module
521
+ $replace = '<' . $esiIncludeTag . " src='" . $this->getEsiBaseUrl() . "litemage/esi/getFormKey' as-var='1' combine='sub' cache-control='no-vary,private' cache-tag='E.formkey'/>" ;
522
  $responseBody = str_replace(self::FORMKEY_REPLACE, $replace, $responseBody) ;
523
  if ($this->_isDebug) {
524
+ $this->_config->debugMesg('FormKey replaced as ' . $replace);
525
  }
526
  $updated = true ;
527
  }
528
 
529
+ if ( $this->_viewedTracker != NULL ) {
530
  $logOptions = $this->_viewedTracker;
531
  $logOptions['s'] = $sharedParams['s'];
532
+ // no need to use comment, will be removed by minify extensions
 
 
533
  // if response coming from backend, no need to send separate log request
534
+ $tracker = '<' . $esiIncludeTag . ' src="' . $this->_getSubReqUrl('litemage/esi/log', $logOptions)
535
  . '" test="$(RESP_HEADER{X-LITESPEED-CACHE})!=\'\'" cache-control="no-cache" combine="sub"/>' ;
536
+ if ($this->_isDebug) {
537
+ $this->_config->debugMesg('Track recently viewed as ' . $tracker);
538
+ }
539
  $updated = true ;
540
  }
541
 
542
  if ( $updated )
543
+ $this->_setEsiOn() ;
544
 
545
  if ( ($this->_cacheVars['flag'] & self::CHBM_ESI_ON) != 0 ) {
546
  // no need to use comment, will be removed by minify extensions
547
+ $combined = '<' . $esiIncludeTag . ' src="' . $this->_getSubReqUrl('litemage/esi/getCombined', $sharedParams) . '" combine="main" cache-control="no-cache"/>' ;
548
+ if ($this->_isDebug) {
549
+ $this->_config->debugMesg('_updateResponseBody combined is ' . $combined);
550
+ }
551
  $updated = true;
552
  }
553
 
554
  if ( $updated ) {
555
+ // cannot insert at beginning of body, pagespeed module will complain
556
+ $pos = stripos($responseBody, '<body');
557
+ if ($pos) {
558
+ $pos = strpos($responseBody, '>', $pos);
559
+ $newbody = substr($responseBody, 0, $pos+1) . $combined . $tracker . substr($responseBody, $pos+1);
560
+ $response->setBody($newbody);
561
+ }
562
+ else {
563
+ $response->setBody($combined . $tracker . $responseBody) ;
564
+ if ($this->_isDebug) {
565
+ $this->_config->debugMesg('_updateResponseBody failed to insert combined after <body>');
566
+ }
567
  }
568
  }
569
 
575
  if ($notEsiReq) {
576
  if ( count($tags) == 0 ) {
577
  // set tag for product id, cid, and pageid
578
+ if ( ($curProduct = Mage::registry('current_product')) != NULL ) {
579
  $tags[] = self::TAG_PREFIX_PRODUCT . $curProduct->getId() ;
580
  }
581
+ elseif ( ($curCategory = Mage::registry('current_category')) != NULL ) {
582
  $tags[] = self::TAG_PREFIX_CATEGORY . $curCategory->getId() ;
583
  }
584
  }
598
  $tags = $this->_cacheVars['tag'] ;
599
  if (empty($tags)) {
600
  // set tag for product id, cid, and pageid
601
+ if ( ($curProduct = Mage::registry('current_product')) != NULL ) {
602
  $tags[] = self::TAG_PREFIX_PRODUCT . $curProduct->getId() ;
603
  }
604
+ elseif ( ($curCategory = Mage::registry('current_category')) != NULL ) {
605
  $tags[] = self::TAG_PREFIX_CATEGORY . $curCategory->getId() ;
606
  }
607
  else {
624
  foreach ($this->_cacheVars['env'] as $name => $data) {
625
  $newVal = '';
626
  $oldVal = '';
627
+ if ($data != NULL) {
628
  ksort($data); // data is array, key sorted
629
  foreach ($data as $k => $v) {
630
  $newVal .= $k . '~' . $v . '~';
650
  $vary_on = array();
651
 
652
  foreach ($this->_cacheVars['env'] as $name => $data) {
653
+ if ($name != $this->_defaultEnvVaryCookie) {
654
  $vary_on[] = 'cookie=' . $name;
655
  }
656
  }
694
  $default['dev'] = 1; //developer mode for restrained IP
695
  }
696
 
697
+ $this->_cacheVars['env'][$this->_defaultEnvVaryCookie] = count($default) > 0 ? $default : NULL ;
698
  }
699
 
700
 
701
  public function getDefaultEnvCookie()
702
  {
703
+ if ( ! isset($this->_cacheVars['env'][$this->_defaultEnvVaryCookie]) ) {
704
  $this->setDefaultEnvCookie();
705
  }
706
+ return $this->_cacheVars['env'][$this->_defaultEnvVaryCookie];
707
  }
708
 
709
  public function getEsiSharedParams()
741
  public function getCookieEnvVars( $cookieName )
742
  {
743
  if ( ! isset($this->_cacheVars['cookie'][$cookieName]) ) {
744
+ $this->_cacheVars['cookie'][$cookieName] = NULL ;
745
  $cookieVal = Mage::getSingleton('core/cookie')->get($cookieName) ;
746
+ if ( $cookieVal != NULL ) {
747
  $cv = explode('~', trim($cookieVal, '~')); // restore cookie value
748
  for ($i = 0 ; $i < count($cv) ; $i += 2) {
749
  $this->_cacheVars['cookie'][$cookieName][$cv[$i]] = $cv[$i+1];
757
 
758
  public function addEnvVars($cookieName, $key='', $val='' )
759
  {
760
+ if ( ! isset($this->_cacheVars['env'][$cookieName]) || ($this->_cacheVars['env'][$cookieName] == NULL) ) {
761
  $this->_cacheVars['env'][$cookieName] = array() ;
762
  }
763
  if ($key != '') {
app/code/community/Litespeed/Litemage/Model/Config/Backend/WarmUp.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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) 2015-2016 LiteSpeed Technologies, Inc. (https://www.litespeedtech.com)
23
+ * @license https://opensource.org/licenses/GPL-3.0
24
+ */
25
+
26
+
27
+ class Litespeed_Litemage_Model_Config_Backend_WarmUp extends Mage_Core_Model_Config_Data
28
+ {
29
+ protected function _beforeSave()
30
+ {
31
+ $value = $this->getValue();
32
+ $lines = explode("\n", $value);
33
+ $errs = array();
34
+ foreach ($lines as $line) {
35
+ $f = preg_split("/[\s]+/", $line, null, PREG_SPLIT_NO_EMPTY) ;
36
+ if (count($f) != 3) {
37
+ $errs[] = 'Requires 3 fields separated by space: absolute file path, interval and priority - ' . $line;
38
+ break;
39
+ }
40
+ if ( (intval($f[1]) != $f[1]) || ($f[1] < 600)) {
41
+ $errs[] = 'Second parameter is interval, requires an integer larger than 600 - ' . $line;
42
+ break;
43
+ }
44
+ if ( (intval($f[2]) != $f[2]) || ($f[2] <= 0)) {
45
+ $errs[] = 'Third parameter is priority, requires an integer larger than 0 - ' . $line;
46
+ break;
47
+ }
48
+ if ( $f[0][0] != '/' ) {
49
+ $errs[] = 'First parameter is custom URL file path, which requires absolute path - ' . $line;
50
+ break;
51
+ }
52
+ if ( ! is_readable($f[0]) ) {
53
+ $errs[] = 'First parameter is custom URL file path, cannot find it or file not readable due to permission - ' . $line;
54
+ break;
55
+ }
56
+ }
57
+
58
+ if (!empty($errs)) {
59
+ Mage::throwException('Error in Custom Defined URL List Files:<br> ' . implode("<br>", $errs));
60
+ }
61
+
62
+ return $this;
63
+ }
64
+ }
app/code/community/Litespeed/Litemage/Model/EsiData.php ADDED
@@ -0,0 +1,340 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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) 2015-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_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';
33
+ const ACTION_GET_MESSAGE = 'getMessage';
34
+
35
+ const BATCH_DIRECT = '_DIR_';
36
+ const BATCH_HANLE = '_HAN_';
37
+ const BATCH_LAYOUT_READY = '_LAY_';
38
+
39
+ //protected $_isDebug;
40
+
41
+ protected $_url;
42
+ protected $_rawOutput = null;
43
+ protected $_responseCode;
44
+
45
+ protected $_action;
46
+ protected $_cacheAttr = array('tag' => '', 'ttl' => 0, 'access' => 'private', 'cacheIfEmpty' => false);
47
+ protected $_layoutAttr = array('bi' => '', 'h' => '');
48
+ protected $_data;
49
+ protected $_batchId;
50
+ protected $_layoutIdentifier;
51
+ protected $_layoutXml;
52
+ protected $_layoutCacheId;
53
+
54
+ public function __construct($url, $configHelper)
55
+ {
56
+ $params = $this->_parseUrlParams($url, $configHelper);
57
+ switch ($this->_action) {
58
+ case self::ACTION_GET_FORMKEY:
59
+ $this->_initFormKey($configHelper);
60
+ break;
61
+ case self::ACTION_LOG:
62
+ $this->_initLogProduct($params);
63
+ break;
64
+ case self::ACTION_GET_COMBINED:
65
+ $this->_initCombined($params);
66
+ break;
67
+ case self::ACTION_GET_BLOCK:
68
+ $this->_initBlock($params, $configHelper);
69
+ break;
70
+ case self::ACTION_GET_MESSAGE:
71
+ $this->_initMessage($params, $configHelper);
72
+ break;
73
+ default:
74
+ $this->_exceptionOut('invalid action ' . $this->_action);
75
+ }
76
+ }
77
+
78
+ public function getAction()
79
+ {
80
+ return $this->_action;
81
+ }
82
+
83
+ public function getUrl()
84
+ {
85
+ return $this->_url;
86
+ }
87
+
88
+ public function getCacheAttribute($attr='')
89
+ {
90
+ if ($attr)
91
+ return $this->_cacheAttr[$attr];
92
+ else
93
+ return $this->_cacheAttr;
94
+ }
95
+
96
+ public function getLayoutAttribute($attr='')
97
+ {
98
+ if ($attr)
99
+ return $this->_layoutAttr[$attr];
100
+ else
101
+ return $this->_layoutAttr;
102
+ }
103
+
104
+ public function getBatchId()
105
+ {
106
+ return $this->_batchId;
107
+ }
108
+
109
+ public function getLayoutXml()
110
+ {
111
+ return $this->_layoutXml;
112
+ }
113
+
114
+ public function initLayoutCache($layoutUnique)
115
+ {
116
+ $this->_layoutCacheId = 'LAYOUT_ESI_' . md5($layoutUnique . '_' . $this->_layoutIdentifier);
117
+ if ( Mage::app()->useCache('layout') ) {
118
+ if ( $data = Mage::app()->loadCache($this->_layoutCacheId ) ) {
119
+ $this->_layoutXml = $data;
120
+ $this->_batchId = self::BATCH_LAYOUT_READY;
121
+ }
122
+ }
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
+
137
+ public function getLayoutCacheId()
138
+ {
139
+ return $this->_layoutCacheId;
140
+ }
141
+
142
+ public function hasRawOutput()
143
+ {
144
+ return ($this->_rawOutput !== null);
145
+ }
146
+
147
+ public function getRawOutput()
148
+ {
149
+ return $this->_rawOutput;
150
+ }
151
+
152
+ public function setRawOutput($rawOutput, $responseCode = 200)
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
+ }
160
+
161
+ public function getInlineHtml($esiInlineTag, $shared)
162
+ {
163
+ $buf = '<' . $esiInlineTag . ' name="' . $this->_url . '" cache-control="' ;
164
+
165
+ $ttl = $this->_cacheAttr['ttl'] ;
166
+
167
+ if ( $ttl == 0 ) {
168
+ $buf .= 'no-cache' ;
169
+ }
170
+ else {
171
+ $buf .= $this->_cacheAttr['access'] . ',max-age=' . $ttl . ',no-vary' ;
172
+ if ( $this->_cacheAttr['cacheIfEmpty'] )
173
+ $buf .= ',set-blank' ;
174
+ elseif ( $shared ) {
175
+ $buf .= ',shared' ;
176
+ }
177
+
178
+ $buf .= '" cache-tag="' . $this->_cacheAttr['tag'] ;
179
+ }
180
+
181
+ $buf .= '">' . $this->_rawOutput . "</$esiInlineTag>\n" ;
182
+
183
+ return $buf ;
184
+ }
185
+
186
+ protected function _exceptionOut($err)
187
+ {
188
+ Mage::throwException('LiteMage module invalid esi url ' . $this->_url . ' Err: ' . $err) ;;
189
+ }
190
+
191
+ protected function _initBlock($params, $configHelper)
192
+ {
193
+ $this->_initShared($params);
194
+
195
+ if (!isset($params['t']) || !isset($params['bi'])) {
196
+ $this->_exceptionOut('missing param t_bi');
197
+ }
198
+
199
+ $bconf = $configHelper->getEsiConf('tag', $params['t']) ;
200
+ if ( $bconf == null ) {
201
+ $this->_exceptionOut('missing config for tag ' . $params['t']) ;
202
+ }
203
+
204
+ $this->_cacheAttr['tag'] = $bconf['cache-tag'];
205
+ $this->_cacheAttr['access'] = $bconf['access'] ;
206
+ if (isset($bconf['ttl'])) {
207
+ $this->_cacheAttr['ttl'] = $bconf['ttl'];
208
+ }
209
+ elseif ($bconf['access'] == 'private') {
210
+ $this->_cacheAttr['ttl'] = $configHelper->getConf(Litespeed_Litemage_Helper_Data::CFG_PRIVATETTL) ;
211
+ }
212
+ else {
213
+ $this->_cacheAttr['ttl'] = $configHelper->getConf(Litespeed_Litemage_Helper_Data::CFG_PUBLICTTL) ;
214
+ }
215
+
216
+ $this->_layoutAttr['bi'] = $params['bi'];
217
+ $this->_batchId = self::BATCH_HANLE;
218
+ if (isset($params['h'])) {
219
+ $this->_batchId = $this->_layoutAttr['h'] = $params['h'];
220
+ }
221
+
222
+ if ( isset($params['pc']) ) {
223
+ $this->_batchId = self::BATCH_DIRECT;
224
+ $this->_data['pc'] = $params['pc'] ; // dynamic block or message
225
+ }
226
+ else {
227
+ $this->_layoutIdentifier = $params['_layout_Id_'];
228
+
229
+
230
+ }
231
+ if ( isset($params['pt']) ) {
232
+ $this->_data['pt'] = $params['pt'] ; // dynamic block template
233
+ }
234
+
235
+ }
236
+
237
+ protected function _initMessage($params, $configHelper)
238
+ {
239
+ $this->_initBlock($params, $configHelper);
240
+ if ( isset($params['st']) ) {
241
+ $this->_data['st'] = $params['st'] ;
242
+ $this->_data['call'] = $params['call'] ;
243
+ $this->_cacheAttr['cacheIfEmpty'] = true ;
244
+ }
245
+ }
246
+
247
+ protected function _initFormKey($configHelper)
248
+ {
249
+ $this->_cacheAttr['ttl'] = $configHelper->getConf(Litespeed_Litemage_Helper_Data::CFG_PRIVATETTL) ;
250
+ $this->_cacheAttr['tag'] = 'E.formkey';
251
+ $this->_batchId = self::BATCH_DIRECT;
252
+ }
253
+
254
+ protected function _initLogProduct( $params)
255
+ {
256
+ // ttl is 0, no cache
257
+ if ( isset($params['product']) && isset($params['s']) ) {
258
+ $this->_data = array('product' => $params['product'],
259
+ 's' => $params['s']);
260
+ $this->_batchId = self::BATCH_DIRECT;
261
+ }
262
+ // else exception out
263
+ }
264
+
265
+ protected function _initShared($params)
266
+ {
267
+ if ( ! isset($params['s']) || ! isset($params['dp']) || ! isset($params['dt']) ) {
268
+ $this->_exceptionOut('missing s_dp_dt') ;
269
+ }
270
+ $this->_data = array(
271
+ 's' => $params['s'],
272
+ 'dp' => $params['dp'],
273
+ 'dt' => $params['dt']
274
+ );
275
+ }
276
+
277
+ public function getData()
278
+ {
279
+ return $this->_data;
280
+ }
281
+
282
+ protected function _initCombined($params)
283
+ {
284
+ $this->_initShared($params);
285
+ if ( empty($_REQUEST['esi_include']) ) {
286
+ $this->_exceptionOut('missing esi_include');
287
+ }
288
+ }
289
+
290
+ protected function _procLogProduct( $params, $configHelper )
291
+ {
292
+ $this->_rawOutput = '';
293
+ // ttl is 0, no cache
294
+
295
+ if ( isset($params['product']) ) {
296
+ if ( isset($params['s']) && ! isset($this->_env['s']) ) {
297
+ $this->_env['s'] = $params['s'] ;
298
+ Mage::app()->setCurrentStore(Mage::app()->getStore($params['s'])) ;
299
+ }
300
+
301
+ $product = new Varien_Object() ;
302
+ $product->setId($params['product']) ;
303
+ try {
304
+ Mage::dispatchEvent('catalog_controller_product_view', array( 'product' => $product )) ;
305
+ } catch ( Exception $e ) {
306
+ if ( $this->_isDebug ) {
307
+ $this->_config->debugMesg('_logData, exception for product ' . $product->getId() . ' : ' . $e->getMessage()) ;
308
+ }
309
+ }
310
+ }
311
+ return $esiData ;
312
+ }
313
+
314
+
315
+ protected function _parseUrlParams( $esiUrl, $configHelper )
316
+ {
317
+ $esiUrl = urldecode($esiUrl) ;
318
+ $this->_url = $esiUrl;
319
+ $pos = strpos($esiUrl, 'litemage/esi/') ;
320
+ if ( $pos === false ) {
321
+ return null;
322
+ }
323
+
324
+ $url1 = substr($esiUrl, $pos + 13);
325
+ $buf = explode('/', $url1) ;
326
+ $this->_action = $buf[0];
327
+
328
+ $c = count($buf) ;
329
+ $param = array() ;
330
+ for ( $i = 1 ; ($i + 1) < $c ; $i+=2 ) {
331
+ $param[$buf[$i]] = $buf[$i + 1] ;
332
+ }
333
+ $dparams = $configHelper->decodeEsiUrlParams($param);
334
+ $dparams['_layout_Id_'] = $url1;
335
+ return $dparams ;
336
+ }
337
+
338
+
339
+ }
340
+
app/code/community/Litespeed/Litemage/Model/EsiLayout.php ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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) 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
+
28
+ protected $_collecting ;
29
+
30
+ /**
31
+ * Class constructor
32
+ *
33
+ * @param array $data
34
+ */
35
+ public function __construct( $data = array() )
36
+ {
37
+ $this->_elementClass = Mage::getConfig()->getModelClassName('core/layout_element') ;
38
+ $this->setXml(simplexml_load_string('<layout/>', $this->_elementClass)) ;
39
+ $this->_update = Mage::getModel('litemage/layout_esiUpdate') ;
40
+ }
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 )
56
+ {
57
+ $this->_output = array() ;
58
+ $this->_blocks = array() ;
59
+ $this->_collecting = false ;
60
+
61
+ $updates = '<?xml version="1.0"?><layout>' . $esiData->getLayoutXml() . '</layout>' ;
62
+ $this->setXml(simplexml_load_string($updates, $this->_elementClass)) ;
63
+ parent::generateBlocks() ;
64
+ }
65
+
66
+ public function loadHanleXml( $handles )
67
+ {
68
+ $this->_output = array() ;
69
+ $this->_blocks = array() ;
70
+ $this->_collecting = true ;
71
+
72
+ $this->_update->init($handles) ;
73
+ $this->generateXml() ;
74
+ $this->generateXmlBlocks() ;
75
+ }
76
+
77
+ public function generateXmlBlocks( $parent = null )
78
+ {
79
+ if ( empty($parent) ) {
80
+ $parent = $this->getNode() ;
81
+ }
82
+ foreach ( $parent as $node ) {
83
+ $attributes = $node->attributes() ;
84
+ if ( (bool) $attributes->ignore ) {
85
+ continue ;
86
+ }
87
+ switch ( $node->getName() ) {
88
+ case 'block':
89
+ $this->_generateXmlBlock($node, $parent) ;
90
+ $this->generateXmlBlocks($node) ;
91
+ break ;
92
+
93
+ case 'reference':
94
+ $this->generateXmlBlocks($node) ;
95
+ break ;
96
+
97
+ case 'action':
98
+ $this->_generateXmlAction($node, $parent) ;
99
+ break ;
100
+ }
101
+ }
102
+ }
103
+
104
+ protected function _generateXmlBlock( $node, $parent )
105
+ {
106
+ $name = (string) $node['name'] ;
107
+ if ( empty($name) || '.' === $name{0} ) { // ignore
108
+ return false ;
109
+ }
110
+ $block = new Litespeed_Litemage_Block_Core_Xml() ;
111
+ $block->setNameInLayout($name) ;
112
+ $block->setLayout($this) ;
113
+
114
+ $this->_blocks[$name] = $block ;
115
+
116
+ if ( ! empty($node['parent']) ) {
117
+ $parentBlock = $this->getBlock((string) $node['parent']) ;
118
+ }
119
+ else {
120
+ $parentName = $parent->getBlockName() ;
121
+ if ( ! empty($parentName) && isset($this->_blocks[$parentName]) ) {
122
+ $parentBlock = $this->_blocks[$parentName] ;
123
+ }
124
+ }
125
+ if ( ! empty($parentBlock) ) {
126
+ $alias = isset($node['as']) ? (string) $node['as'] : '' ;
127
+ $parentBlock->append($block, $alias) ;
128
+ if ( $parent != null && $parent->getName() == 'reference' ) {
129
+ $parentBlock->addXmlNode($parent) ;
130
+ }
131
+ }
132
+ $block->addXmlNode($node) ;
133
+
134
+ return $this ;
135
+ }
136
+
137
+ protected function _generateXmlAction( $node, $parent )
138
+ {
139
+ if ( ! empty($node['block']) ) {
140
+ $parentName = (string) $node['block'] ;
141
+ $collectNode = $node ;
142
+ }
143
+ else {
144
+ $parentName = $parent->getBlockName() ;
145
+ $collectNode = $parent ;
146
+ }
147
+
148
+ if ( ! empty($parentName) && isset($this->_blocks[$parentName]) ) {
149
+ $this->_blocks[$parentName]->addXmlNode($collectNode) ;
150
+ }
151
+
152
+ return $this ;
153
+ }
154
+
155
+ public function getBiBlock( $blockIndex )
156
+ {
157
+ if ( strpos($blockIndex, ';') === false ) {
158
+ return isset($this->_blocks[$blockIndex]) ?
159
+ $this->_blocks[$blockIndex] : null ;
160
+ }
161
+
162
+ $bi = explode(';', $blockIndex) ;
163
+
164
+ $pn = array_shift($bi) ;
165
+ if ( ! isset($this->_blocks[$pn]) ) {
166
+ return null ;
167
+ }
168
+
169
+ $parent = $this->_blocks[$pn] ;
170
+ foreach ( $bi as $bn ) {
171
+ if ( $pos = strpos($bn, ',') ) {
172
+ $bn = substr($bn, $pos + 1) ;
173
+ }
174
+ if ( $block = $parent->getChild($bn) ) {
175
+ $parent = $block ;
176
+ }
177
+ else {
178
+ return null ;
179
+ }
180
+ }
181
+ return $parent ;
182
+ }
183
+
184
+ public function getEsiBlock( $blockIndex )
185
+ {
186
+ if ( strpos($blockIndex, ';') ) {
187
+ $bi = explode(';', $blockIndex) ;
188
+ $bn = array_pop($bi) ;
189
+ if ( $pos = strpos($bn, ',') ) {
190
+ $bn = substr($bn, 0, $pos) ;
191
+ }
192
+ }
193
+ else {
194
+ $bn = $blockIndex ;
195
+ }
196
+
197
+ return isset($this->_blocks[$bn]) ? $this->_blocks[$bn] : null ;
198
+ }
199
+
200
+ }
app/code/community/Litespeed/Litemage/Model/Layout.php DELETED
@@ -1,121 +0,0 @@
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) 2015-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_Layout extends Mage_Core_Model_Layout
27
- {
28
- /**
29
- * Class constructor
30
- *
31
- * @param array $data
32
- */
33
-
34
- //protected $_isDebug;
35
-
36
- public function __construct()
37
- {
38
- $this->_elementClass = Mage::getConfig()->getModelClassName('core/layout_element');
39
- $this->setXml(simplexml_load_string('<layout/>', $this->_elementClass));
40
- $this->_update = Mage::getModel('litemage/layout_update');
41
- }
42
-
43
- public function getBlock($name)
44
- {
45
- if (!isset($this->_blocks[$name])) {
46
- $dummyblocks = array('root', 'head');
47
- if (in_array($name, $dummyblocks)) {
48
- $dummy = new Varien_Object();
49
- return $dummy;
50
- }
51
- return null;
52
- }
53
- return $this->_blocks[$name];
54
- }
55
-
56
- public function resetBlocks()
57
- {
58
- $this->_output = array();
59
- $this->_blocks = array();
60
- }
61
-
62
- /**
63
- * Create layout blocks hierarchy from layout xml configuration
64
- *
65
- * @param Mage_Core_Layout_Element|null $parent
66
- */
67
- public function generateBlocks($parent=null)
68
- {
69
- if (empty($parent)) {
70
- $root = $this->addBlock('page/html', 'esiroot');// dummy root
71
- $parent = $this->getNode();
72
- foreach ($parent as $node) {
73
- $node['parent'] = 'esiroot';
74
- }
75
- }
76
- parent::generateBlocks($parent);
77
- }
78
-
79
- public function getOutputBlock($name_alias)
80
- {
81
- $block = null;
82
- $mesg = '';
83
-
84
- if (isset($this->_blocks['esiroot']) && ($block = $this->_blocks['esiroot']->getChild($name_alias))) {
85
- // as alias
86
- if ( ($name = $block->getNameInLayout()) != $name_alias ) {
87
- if ($this->_blocks[$name] != $block) {
88
- $mesg = 'block name in layout is not unique, please check layout xml for block name ' . $name;
89
- }
90
- }
91
-
92
- }
93
- elseif (isset($this->_blocks[$name_alias])) {
94
- $block = $this->_blocks[$name_alias]; // dynamic block
95
- }
96
- else {
97
- $mesg = 'failed to find the block by alias or name';
98
- }
99
- if ($mesg != '') {
100
- Mage::helper('litemage/data')->debugMesg('getOutputBlock ' . $name_alias . ' ALERT: ' . $mesg);
101
- }
102
- return $block;
103
- }
104
-
105
- // override getOutput, as the output block maybe go by alias
106
- public function getOutput()
107
- {
108
- $out = '';
109
- if (!empty($this->_output)) {
110
- foreach ($this->_output as $callback) {
111
- if ($block = $this->getOutputBlock($callback[0])) {
112
- $out .= $block->$callback[1]();
113
- }
114
- }
115
- }
116
-
117
- return $out;
118
- }
119
-
120
- }
121
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Litespeed/Litemage/Model/Layout/EsiUpdate.php ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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) 2015-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_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
+
44
+ public function init($handles)
45
+ {
46
+ $this->_cacheId = null;
47
+ $this->resetHandles();
48
+ $this->resetUpdates();
49
+ $this->load($handles) ;
50
+ }
51
+
52
+ /**
53
+ * Get cache id
54
+ *
55
+ * @return string
56
+ */
57
+ public function getCacheId()
58
+ {
59
+ if (!$this->_cacheId) {
60
+ $tags = $this->getHandles();
61
+ $this->_cacheId = $this->_cachePrefix . md5(join('__', $tags));
62
+ if ($this->_isDebug) {
63
+ Mage::helper('litemage/data')->debugMesg('LU_Load H=' . join(',',$tags) . ' ID=' . substr($this->_cacheId, 7));
64
+ }
65
+
66
+ }
67
+ return $this->_cacheId;
68
+ }
69
+
70
+ /*
71
+ * @return -1: no layout cache allowed, 0: nocache, 1: has cache
72
+ */
73
+
74
+ public function loadEsiBlockCache($blockName, $handles)
75
+ {
76
+ if (!Mage::app()->useCache('layout')) {
77
+ return -1;
78
+ }
79
+ //reset internals
80
+ $this->setBlockNames(array($blockName));
81
+ $this->addHandle($handles);
82
+
83
+ if ($this->loadCache())
84
+ return 1;
85
+ else
86
+ return 0;
87
+ }
88
+
89
+ public function merge($handle)
90
+ {
91
+ if (!$this->_layoutMaster) {
92
+ $this->_layoutMaster = Mage::getSingleton('litemage/layout_master');
93
+ }
94
+ if (($update = $this->_layoutMaster->getHandleUpdates($handle)) !== false) {
95
+ return $this->addUpdate($update);
96
+ }
97
+ return parent::merge($handle);
98
+ }
99
+
100
+ public function loadCache()
101
+ {
102
+ if (!Mage::app()->useCache('layout')) {
103
+ return false;
104
+ }
105
+
106
+ if (!$result = Mage::app()->loadCache($this->getCacheId())) {
107
+ return false;
108
+ }
109
+
110
+ $this->addUpdate($result);
111
+
112
+ return true;
113
+ }
114
+
115
+ public function saveCache()
116
+ {
117
+ if (!Mage::app()->useCache('layout')) {
118
+ return false;
119
+ }
120
+
121
+ $tags = $this->getHandles();
122
+ $tags[] = Mage_Core_Model_Layout_Update::LAYOUT_GENERAL_CACHE_TAG;
123
+ $tags[] = Litespeed_Litemage_Helper_Data::LITEMAGE_GENERAL_CACHE_TAG;
124
+ $content = $this->asString();
125
+ return Mage::app()->saveCache($content, $this->getCacheId(), $tags, null);
126
+ }
127
+
128
+ }
app/code/community/Litespeed/Litemage/Model/Layout/Master.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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) 2015-2016 LiteSpeed Technologies, Inc. (https://www.litespeedtech.com)
23
+ * @license https://opensource.org/licenses/GPL-3.0
24
+ */
25
+ /*
26
+ * this class is used by rewrite class of Layout_Update
27
+ */
28
+
29
+ class Litespeed_Litemage_Model_Layout_Master
30
+ {
31
+
32
+ protected $_handleUpdates = array() ;
33
+ protected $_cachePrefix ;
34
+ protected $_cacheTags ;
35
+
36
+ public function __construct()
37
+ {
38
+ $design = Mage::getSingleton('core/design_package') ;
39
+ if ( $design->getArea() != 'frontend' ) {
40
+ throw Mage::exception('Litespeed_Litemage_Model_Layout_Master should only be used for frontend') ;
41
+ }
42
+
43
+ $storeId = Mage::app()->getStore()->getId() ;
44
+
45
+ $this->_cachePrefix = 'LAYOUT_MASTER_' . $storeId . '_' . $design->getPackageName() . '_'
46
+ . $design->getTheme('layout') . '_' ;
47
+
48
+ $this->_cacheTags = array( Mage_Core_Model_Layout_Update::LAYOUT_GENERAL_CACHE_TAG ) ;
49
+ }
50
+
51
+ public function getHandleUpdates( $handle )
52
+ {
53
+ if ( ! isset($this->_handleUpdates[$handle]) ) {
54
+ $result = false ;
55
+ if ( Mage::app()->useCache('layout') ) {
56
+ $cacheId = $this->_cachePrefix . $handle ;
57
+ $result = Mage::app()->loadCache($cacheId) ;
58
+ }
59
+ $this->_handleUpdates[$handle] = $result ;
60
+ }
61
+ return $this->_handleUpdates[$handle] ;
62
+ }
63
+
64
+ public function saveHandleUpdates( $handle, $updateString )
65
+ {
66
+ if ( isset($this->_handleUpdates[$handle]) && $this->_handleUpdates[$handle] === false ) {
67
+ $this->_handleUpdates[$handle] = $updateString ;// save even empty string
68
+
69
+ if ( Mage::app()->useCache('layout') ) {
70
+ $cacheId = $this->_cachePrefix . $handle ;
71
+ Mage::app()->saveCache($updateString, $cacheId, $this->_cacheTags, null) ;
72
+ }
73
+ }
74
+ }
75
+
76
+ }
app/code/community/Litespeed/Litemage/Model/Layout/Update.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * LiteMage
4
  *
@@ -21,195 +22,246 @@
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
 
26
  class Litespeed_Litemage_Model_Layout_Update extends Mage_Core_Model_Layout_Update
27
  {
28
- protected $_esiBlockName;
29
- protected $_storeId;
30
- protected $_filtered = false;
31
- protected $_blockNames = array();
32
- protected $_peerFullXml;
33
- protected $_isDebug;
34
-
35
- public function getPackageLayout()
36
- {
37
- if (empty($this->_packageLayout)) {
38
- $this->fetchFileLayoutUpdates();
39
- }
40
- return $this->_packageLayout;
41
- }
42
-
43
- public function setStoreId($storeId)
44
- {
45
- $this->_storeId = $storeId;
46
- $this->_isDebug = Mage::helper('litemage/data')->isDebug() ;
47
- }
48
-
49
- public function getEsiBlockName()
50
- {
51
- return $this->_esiBlockName;
52
- }
53
-
54
- public function setBlockNames($blockNames)
55
- {
56
- $this->_blockNames = $blockNames;
57
- $this->_esiBlockName = $blockNames[0];
58
- $this->_cacheId = null;
59
- $this->_filtered = false;
60
- $this->resetHandles();
61
- $this->resetUpdates();
62
- }
63
-
64
- public function getBlockNames()
65
- {
66
- return $this->_blockNames;
67
- }
68
-
69
- public function importLayoutUpdate($blockNames, $blockHandles, $layout )
70
- {
71
- $this->setBlockNames($blockNames);
72
- if ($this->_peerFullXml == null)
73
- $this->_peerFullXml = $layout->getUpdate()->asSimplexml() ;
74
-
75
- $this->_filterUpdates($this->_peerFullXml);
76
- $this->addHandle($blockHandles);
77
- $this->saveCache();
78
- return $this->_blockNames;
79
- }
80
-
81
- protected function _filterUpdates($layoutUpdateXml)
82
- {
83
- $this->resetUpdates();
84
- $blockUsed = array();
85
-
86
- foreach ($this->_blockNames as $blockName) {
87
- $xpath = '//*[@name="' . $blockName . '"]';
88
- $nameUsed = false;
89
- if ($els = $layoutUpdateXml->xpath($xpath)) {
90
- foreach ($els as $el) {
91
- if (!$el->getAttribute('litemage_used')) {
92
- $this->addUpdate($el->asNiceXml());
93
- $nameUsed = true;
94
- $this->_markNodeUsed($el);
95
- }
96
- }
97
- }
98
- if ($nameUsed)
99
- $blockUsed[] = $blockName;
100
- }
101
-
102
- // check if children blocks being removed
103
- $removeNodes = $layoutUpdateXml->xpath("//remove");
104
-
105
- if (is_array($removeNodes)) {
106
- $xml = $this->asSimplexml();
107
-
108
- foreach ($removeNodes as $removeNode) {
109
- $attributes = $removeNode->attributes();
110
- $blockName = (string)$attributes->name;
111
- if ($blockName) {
112
- $ignoreNodes = $xml->xpath("//block[@name='".$blockName."']");
113
- if (is_array($ignoreNodes) && count($ignoreNodes) > 0) {
114
- $this->addUpdate($removeNode->asNiceXml());
115
- }
116
- }
117
- }
118
- }
119
-
120
- $this->_blockNames = $blockUsed;
121
- $this->_filtered = true;
122
- }
123
-
124
- protected function _markNodeUsed($node)
125
- {
126
- $node->addAttribute('litemage_used', 'esi');
127
- $children = $node->children();
128
- foreach ($children as $child) {
129
- $this->_markNodeUsed($child);
130
- }
131
- }
132
-
133
- /**
134
- * Get cache id
135
- *
136
- * @return string
137
- */
138
- public function getCacheId()
139
- {
140
- if (!$this->_cacheId) {
141
- $tags = $this->getHandles();
142
- if (count($tags) > 1) {
143
- sort($tags);
144
- }
145
- $tags[] = 'LITEMAGE_ESI_' . $this->_esiBlockName;
146
-
147
- $this->_cacheId = 'LAYOUT_' . $this->_storeId . md5(join('__', $tags));
148
- }
149
- return $this->_cacheId;
150
- }
151
-
152
- /*
153
- * @return -1: no layout cache allowed, 0: nocache, 1: has cache
154
- */
155
-
156
- public function loadEsiBlockCache($blockName, $handles)
157
- {
158
- if (!Mage::app()->useCache('layout')) {
159
- return -1;
160
- }
161
- //reset internals
162
- $this->setBlockNames(array($blockName));
163
- $this->addHandle($handles);
164
-
165
- if ($this->loadCache())
166
- return 1;
167
- else
168
- return 0;
169
- }
170
-
171
- public function loadCache()
172
- {
173
- if (!Mage::app()->useCache('layout')) {
174
- return false;
175
- }
176
-
177
- if (!$result = Mage::app()->loadCache($this->getCacheId())) {
178
- return false;
179
- }
180
-
181
- $pos = strpos($result, "\n");
182
- $filteredBlocks = substr($result, 0, $pos);
183
- $this->_filtered = true;
184
- if ($this->_isDebug) {
185
- Mage::helper('litemage/data')->debugMesg('LU_Load B=' . $filteredBlocks . ' H=' . join(',',$this->getHandles()) . ' ID=' . substr($this->getCacheId(), 8, 10));
186
- }
187
- $this->_blockNames = explode(',', $filteredBlocks);
188
- $this->addUpdate(substr($result, $pos+1));
189
-
190
- return true;
191
- }
192
-
193
- public function saveCache()
194
- {
195
- if (!$this->_filtered) {
196
- $this->_filterUpdates($this->asSimplexml());
197
- }
198
-
199
- if (!Mage::app()->useCache('layout')) {
200
- return false;
201
- }
202
-
203
- $tags = $this->getHandles();
204
- $tags[] = Mage_Core_Model_Layout_Update::LAYOUT_GENERAL_CACHE_TAG;
205
- $tags[] = Litespeed_Litemage_Helper_Data::LITEMAGE_GENERAL_CACHE_TAG;
206
- $firstLine = join(',', $this->_blockNames);
207
- if ($this->_isDebug) {
208
- Mage::helper('litemage/data')->debugMesg('LU_Save B=' . $firstLine . ' H=' . join(',',$this->getHandles()) . ' ID=' . substr($this->getCacheId(), 8, 10));
209
- }
210
-
211
- $content = $firstLine . "\n" . $this->asString();
212
- return Mage::app()->saveCache($content, $this->getCacheId(), $tags, null);
213
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
 
215
  }
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
+ /*
26
+ * this class rewrite just try to remember what updates imported by which handle, only modify for frontend area
27
+ */
28
 
29
  class Litespeed_Litemage_Model_Layout_Update extends Mage_Core_Model_Layout_Update
30
  {
31
+
32
+ protected $_handleUpdates ;
33
+ protected $_layoutHandles ;
34
+ protected $_curHandles ;
35
+ protected $_recursiveUpdates ;
36
+ protected $_modified = false ;
37
+ protected $_sharedCacheId ;
38
+ protected $_layoutMaster ;
39
+ protected $_handleXml ;
40
+ protected $_isDebug ;
41
+
42
+ public function __construct()
43
+ {
44
+ if ( Mage::getSingleton('core/design_package')->getArea() == 'frontend' && Mage::helper('litemage/data')->moduleEnabled() ) {
45
+ $this->_modified = true ;
46
+ $this->_layoutMaster = Mage::getSingleton('litemage/layout_master') ;
47
+ $this->_isDebug = Mage::helper('litemage/data')->isDebug() ;
48
+ }
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 ) {
63
+ $this->_resetInternals() ;
64
+ }
65
+ return parent::resetHandles() ;
66
+ }
67
+
68
+ protected function _resetInternals()
69
+ {
70
+ $this->_cacheId = null ;
71
+ $this->_curHandles = array() ;
72
+ $this->_handleUpdates = array() ;
73
+ $this->_recursiveUpdates = array() ;
74
+ $this->_layoutHandles = array() ;
75
+ }
76
+
77
+ public function getUsedHandles()
78
+ {
79
+ return array_keys($this->_handleUpdates) ;
80
+ }
81
+
82
+ /**
83
+ * Merge layout update by handle
84
+ *
85
+ * @param string $handle
86
+ * @return Mage_Core_Model_Layout_Update
87
+ */
88
+ public function merge( $handle )
89
+ {
90
+ if ( ! $this->_modified ) {
91
+ return parent::merge($handle) ;
92
+ }
93
+
94
+ // can be recusively loaded handle
95
+ array_push($this->_curHandles, $handle) ;
96
+
97
+ if ( ($update = $this->_layoutMaster->getHandleUpdates($handle)) !== false ) {
98
+ $this->addUpdate($update) ;
99
+ }
100
+ else {
101
+ parent::merge($handle) ;
102
+ }
103
+
104
+ array_pop($this->_curHandles) ;
105
+ return $this ;
106
+ }
107
+
108
+ public function addUpdate( $update )
109
+ {
110
+ $update = trim($update) ;
111
+ if ( $update == '' )
112
+ return $this ;
113
+
114
+ if ( $this->_modified && ! empty($this->_curHandles) ) {
115
+ foreach ( $this->_curHandles as $h ) {
116
+ if ( in_array($h, $this->_layoutHandles) ) {
117
+ if ( ! isset($this->_handleUpdates[$h]) )
118
+ $this->_handleUpdates[$h] = '' ;
119
+ $this->_handleUpdates[$h] .= $update ;
120
+ }
121
+ else {
122
+ if ( ! isset($this->_recursiveUpdates[$h]) )
123
+ $this->_recursiveUpdates[$h] = '' ;
124
+ $this->_recursiveUpdates[$h] .= $update ;
125
+ }
126
+ }
127
+ }
128
+ return parent::addUpdate($update) ;
129
+ }
130
+
131
+ /**
132
+ * Get cache id
133
+ *
134
+ * @return string
135
+ */
136
+ public function getCacheId()
137
+ {
138
+ if ( ! $this->_cacheId ) {
139
+ if ( ! $this->_modified ) {
140
+ return parent::getCacheId() ;
141
+ }
142
+ $this->_resetInternals() ;
143
+ $this->_layoutHandles = $this->getHandles() ;
144
+ $tags = $this->_layoutHandles ;
145
+ $tags[] = 'LITEMAGE_MODIFY' ;
146
+ $this->_cacheId = 'LAYOUT_' . Mage::app()->getStore()->getId() . md5(join('__', $tags)) ;
147
+ }
148
+ return $this->_cacheId ;
149
+ }
150
+
151
+ public function loadCache()
152
+ {
153
+ if ( ! Mage::app()->useCache('layout') ) {
154
+ return false ;
155
+ }
156
+
157
+ if ( ! $this->_modified ) {
158
+ return parent::loadCache() ;
159
+ }
160
+
161
+ if ( ! $result = Mage::app()->loadCache($this->getCacheId()) ) {
162
+ return false ;
163
+ }
164
+
165
+ $this->_handleUpdates = unserialize($result) ;
166
+ if ( $this->_handleUpdates == false ) {
167
+ return false ;
168
+ }
169
+
170
+ if ( isset($this->_handleUpdates['LITEMAGE_SHARED']) ) {
171
+ $this->_sharedCacheId = $this->_handleUpdates['LITEMAGE_SHARED'] ;
172
+ if ( ! $result = Mage::app()->loadCache($this->_sharedCacheId) ) {
173
+ return false ;
174
+ }
175
+
176
+ $this->_handleUpdates = unserialize($result) ;
177
+ if ( $this->_handleUpdates == false ) {
178
+ return false ;
179
+ }
180
+ }
181
+ if ( $this->_isDebug ) {
182
+ Mage::helper('litemage/data')->debugMesg('Layout cache loaded '
183
+ . implode(':', array_keys($this->_handleUpdates))
184
+ . ' ' . substr($this->_cacheId, 8, 12)) ;
185
+ }
186
+ parent::addUpdate(implode('', $this->_handleUpdates)) ;
187
+
188
+ return true ;
189
+ }
190
+
191
+ public function saveCache()
192
+ {
193
+ if ( ! Mage::app()->useCache('layout') ) {
194
+ return false ;
195
+ }
196
+ if ( ! $this->_modified ) {
197
+ return parent::saveCache() ;
198
+ }
199
+
200
+ $this->_curHandles = array() ;
201
+ $tags = $this->getHandles() ; // all handles used, include recursive ones
202
+ $tags[] = self::LAYOUT_GENERAL_CACHE_TAG ;
203
+ $usedHandles = $this->getUsedHandles() ;
204
+
205
+ if ( count($this->_layoutHandles) > count($usedHandles) ) {
206
+ $shared = $usedHandles ;
207
+ $shared[] = 'LITEMAGE_SHARED' ;
208
+ $sharedTags = $usedHandles ;
209
+ $sharedTags[] = self::LAYOUT_GENERAL_CACHE_TAG ;
210
+ $this->_sharedCacheId = 'LAYOUT_' . Mage::app()->getStore()->getId() . md5(join('__', $shared)) ;
211
+ if ( ! $result = Mage::app()->loadCache($this->_sharedCacheId) ) {
212
+ $res = Mage::app()->saveCache(serialize($this->_handleUpdates), $this->_sharedCacheId, $sharedTags, null) ;
213
+ }
214
+ $ref = array( 'LITEMAGE_SHARED' => $this->_sharedCacheId ) ;
215
+ $res = Mage::app()->saveCache(serialize($ref), $this->getCacheId(), $tags, null) ;
216
+ }
217
+ else {
218
+ $res = Mage::app()->saveCache(serialize($this->_handleUpdates), $this->getCacheId(), $tags, null) ;
219
+ }
220
+ if ( $this->_isDebug ) {
221
+ Mage::helper('litemage/data')->debugMesg('Layout cache saved '
222
+ . implode(':', array_keys($this->_handleUpdates))
223
+ . ' ' . substr($this->_cacheId, 8, 12)) ;
224
+ }
225
+
226
+ foreach ( $this->_handleUpdates as $h => $update ) {
227
+ $this->_layoutMaster->saveHandleUpdates($h, $update) ;
228
+ }
229
+ foreach ( $this->_recursiveUpdates as $h => $update ) {
230
+ $this->_layoutMaster->saveHandleUpdates($h, $update) ;
231
+ }
232
+ return $res ;
233
+ }
234
+
235
+ public function getBlockHandles( $blockNameList )
236
+ {
237
+ if ( $this->_handleXml == null ) {
238
+ $this->_handleXml = array() ;
239
+ foreach ( $this->_handleUpdates as $h => $update ) {
240
+ if ( ($h != 'customer_logged_out') && ($h != 'customer_logged_in') ) {
241
+ $updates = '<' . '?xml version="1.0"?' . '><layout>' . $update . '</layout>' ;
242
+ $this->_handleXml[$h] = simplexml_load_string($updates, $this->getElementClass()) ;
243
+ }
244
+ }
245
+ }
246
+ $handles = array() ;
247
+ $parents = array() ;
248
+ $found = false ;
249
+ foreach ( $this->_handleXml as $h => $xml ) {
250
+ foreach ( $blockNameList as $name ) {
251
+ $xpath = '//*[@name="' . $name . '"]' ;
252
+ if ( $node = $xml->xpath($xpath) ) {
253
+ $handles[] = $h ;
254
+ $found = true ;
255
+ break ;
256
+ }
257
+ }
258
+ if ( ! $found ) {
259
+ $parents[] = $h ;
260
+ }
261
+ }
262
+ // need to get all parent handle
263
+ $blockHandles = count($handles) ? array_merge($parents, $handles) : array_slice($parents, 0, 1) ; // return default
264
+ return $blockHandles ;
265
+ }
266
 
267
  }
app/code/community/Litespeed/Litemage/Model/Observer/Cron.php CHANGED
@@ -31,7 +31,6 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
31
  const ENV_COOKIE_NAME = '_lscache_vary' ;
32
 
33
  protected $_meta ; // time, curfileline
34
- protected $_metaUpdated = false;
35
  protected $_conf;
36
  protected $_isDebug ;
37
  protected $_debugTag;
@@ -115,45 +114,50 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
115
 
116
  public function getCrawlerStatus()
117
  {
118
- $priority = $this->_initMeta();
119
- $saved = $this->_meta;
120
  $timefmt = 'Y-m-d H:i:s';
121
  $status = array('lastupdate' => '', 'endreason' => '',
122
  'stores' => array());
123
 
124
- if (isset($saved['lastupdate'])) {
125
- $status['lastupdate'] = date($timefmt, $saved['lastupdate']);
 
126
  }
127
 
128
- if (isset($saved['endreason'])) {
129
- $status['endreason'] = $saved['endreason'];
 
130
  }
131
 
132
- foreach ($priority as $listId => $pri ) {
133
- $store_stat = $saved[$listId];
 
134
  $disp = array();
135
- $disp['priority'] = intval($pri + 0.5);
136
  $disp['id'] = strtoupper($listId);
 
 
137
  $disp['baseurl'] = $store_stat['baseurl'];
138
  $disp['file'] = (isset($store_stat['file']) ? $store_stat['file'] : '');
139
  $disp['ttl'] = $store_stat['ttl'];
140
  $disp['interval'] = $store_stat['interval'];
141
- if ($store_stat['gentime'] > 0) {
142
- $disp['gentime'] = date($timefmt, $store_stat['gentime']);
143
- }
144
- else {
145
- $disp['gentime'] = isset($store_stat['tmpmsg']) ? $store_stat['tmpmsg'] : '';
146
- }
147
- $disp['lastquerytime'] = ($store_stat['lastquerytime'] > 0) ? date($timefmt, $store_stat['lastquerytime']) : '';
148
- $disp['endtime'] = ($store_stat['endtime'] > 0) ? date($timefmt, $store_stat['endtime']) : '';
149
- $disp['listsize'] = ($store_stat['listsize'] > 0) ? $store_stat['listsize'] : '';
150
  $disp['curpos'] = $store_stat['curpos'];
151
  $disp['env'] = $store_stat['env'];
152
  $disp['curvary'] = preg_replace("/_lscache_vary=.+;/", '', $store_stat['curvary']);
153
  $disp['queried'] = $store_stat['queried'];
154
- $status['stores'][] = $disp;
 
 
 
 
 
155
  }
156
-
157
  return $status;
158
  }
159
 
@@ -163,14 +167,10 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
163
 
164
  public function warmCache()
165
  {
166
- if ( $this->_isDebug ) {
167
- $this->_debugLog("cron warmCache envoked") ;
168
- }
169
-
170
- $curRunTime = time() ;
171
-
172
- if (!$this->_init()) {
173
- $this->_debugLog('skip this round');
174
  return;
175
  }
176
 
@@ -270,12 +270,9 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
270
  array_shift($vary);
271
  }
272
 
273
- $this->_curList = array(
274
- 'id' => $id,
275
- 'fixed' => $fixed,
276
- 'vary' => $vary,
277
- 'working' => 0);
278
- if ( ($urls = $this->_getCrawlListFileData($id)) != null ) {
279
  $allurls = explode("\n", $urls) ;
280
  // verify data
281
  $header = explode("\t", array_shift($allurls));
@@ -289,9 +286,6 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
289
  $this->_debugLog('load saved url list, header does not match, will regenerate') ;
290
  }
291
  }
292
- else if ($this->_isDebug) {
293
- $this->_debugLog('load saved url list failed, will regenerate');
294
- }
295
 
296
  if (!isset($this->_curList['urls'])) {
297
  // regenerate
@@ -426,7 +420,6 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
426
  $this->_meta[$id]['queried'] += $this->_curList['working'];
427
  $this->_meta[$id]['lastquerytime'] = $now;
428
  $this->_meta['lastupdate'] = $now;
429
- $this->_metaUpdated = true;
430
  $this->_curList['working'] = 0;
431
  }
432
 
@@ -435,6 +428,8 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
435
  $meta = array(
436
  'id' => $storeInfo['id'], // store1, custom1, delta
437
  'storeid' => $storeInfo['storeid'],
 
 
438
  'baseurl' => $storeInfo['baseurl'],
439
  'ttl' => $storeInfo['ttl'],
440
  'interval' => $storeInfo['interval'],
@@ -452,9 +447,6 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
452
  }
453
  if ($tmpmsg) {
454
  $meta['tmpmsg'] = $tmpmsg;
455
- if ( $this->_isDebug ) {
456
- $this->_debugLog($tmpmsg) ;
457
- }
458
  }
459
 
460
  return $meta;
@@ -471,8 +463,6 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
471
 
472
  protected function _initMeta()
473
  {
474
- $priority = array();
475
- $curtime = time();
476
  $this->_meta = array();
477
 
478
  $saved = array();
@@ -487,39 +477,66 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
487
  }
488
 
489
  if (empty($this->_conf['store'])) {
490
- return $priority;
491
  }
492
 
 
 
 
 
493
  foreach( $this->_conf['store'] as $listId => $info) {
494
  $tmpmsg = '';
495
  if (isset($saved[$listId])) {
496
  // validate saved
497
  $m = $saved[$listId];
498
  if (isset($m['storeid']) && ($m['storeid'] == $info['storeid'])
499
- && isset($m['env']) && ($m['env'] == $info['env'])
500
- && isset($m['interval']) && ($m['interval'] == $info['interval'])
501
- && isset($m['priority']) && ($m['priority'] == $info['priority'])
502
- && isset($m['baseurl']) && ($m['baseurl'] == $info['baseurl'])) {
503
-
504
- if (($m['endtime'] == 0) // not finished
505
- || ($m['endtime'] + $m['interval'] > $curtime)) { // not timedout
506
- $this->_meta[$listId] = $m;
 
 
 
 
 
 
 
 
 
 
507
  }
508
  else {
509
- $tmpmsg = strtoupper($listId) . ' - ' . Mage::helper('litemage/data')->__('Maximum Run Time exceeded. List will be regenerated.');
510
  }
 
 
511
  }
512
  else {
513
- $tmpmsg = strtoupper($listId) . ' - ' . Mage::helper('litemage/data')->__('Saved configuration does not match current configuration. List will be regenerated.');
 
 
 
 
 
514
  }
515
  }
 
 
 
 
 
516
  if (!isset($this->_meta[$listId])) {
517
  $this->_meta[$listId] = $this->_newStoreMeta($info, $tmpmsg);
518
  }
519
- $priority[$listId] = $this->_meta[$listId]['priority'];
520
  }
521
 
522
- asort($priority, SORT_NUMERIC);
 
 
523
 
524
  return $priority;
525
  }
@@ -527,54 +544,35 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
527
  protected function _init()
528
  {
529
  if (empty($this->_conf['store'])) {
530
- return false;
531
- }
532
- if ( $this->_isDebug ) {
533
- $this->_debugLog('cron config is = ' . print_r($this->_conf, true)) ;
534
  }
535
 
536
- $priority = $this->_initMeta();
537
- $this->_priority = array();
538
- foreach ($priority as $listId => $pri ) {
 
539
 
540
- if ($this->_meta[$listId]['gentime'] == 0) {
541
- $this->_generateUrlList($listId);
542
- }
543
- if ($this->_meta[$listId]['listsize'] > 0 && $this->_meta[$listId]['endtime'] == 0) {
544
- // need crawl
545
- $this->_priority[] = $listId;
546
- }
547
- }
548
 
549
- if ($this->_metaUpdated) {
550
- $this->_saveMeta();
551
- }
 
552
 
553
- if ( $this->_isDebug ) {
554
- $this->_debugLog('cron meta starting = ' . print_r($this->_meta, true)) ;
 
 
555
  }
556
 
557
- if ( empty($this->_priority) ) {
558
- if ( $this->_isDebug )
559
- $this->_debugLog("no url list available for warm up") ;
560
- return false;
561
- }
562
  else {
563
-
564
- $maxTime = (int) ini_get('max_execution_time') ;
565
- if ( $maxTime == 0 )
566
- $maxTime = 300 ; // hardlimit
567
- else
568
- $maxTime -= 5 ;
569
-
570
- $configed = $this->_conf[Litespeed_Litemage_Helper_Data::CFG_WARMUP_MAXTIME];
571
- if ( $maxTime > $configed )
572
- $maxTime = $configed ;
573
- $this->_maxRunTime = $maxTime + time();
574
-
575
- $this->_adjustCurThreads();
576
-
577
- return $this->_prepareCurList();
578
  }
579
  }
580
 
@@ -585,11 +583,13 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
585
 
586
  $load = sys_getloadavg() ;
587
  $curload = $load[0];
588
- $curthreads = $this->_curThreads;
589
 
590
  if ($this->_curThreads == -1) {
591
  // init
592
- if ($curload >= ($limit - 1)) {
 
 
 
593
  $curthreads = 1;
594
  }
595
  else {
@@ -601,9 +601,11 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
601
  }
602
  else {
603
  // adjust
 
604
  if ($curload >= $limit + 1 ) {
605
  sleep(5); // sleep 5 secs
606
- $curthreads --;
 
607
  }
608
  elseif ($curload >= $limit) {
609
  if ($curthreads > 1) // if already 1, keep
@@ -615,8 +617,6 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
615
  }
616
  }
617
 
618
- if ($curthreads <= 0)
619
- $curthreads = 0;
620
 
621
  if ($this->_isDebug) {
622
  $this->_debugLog('set current threads = ' . $curthreads . ' previous=' . $this->_curThreads
@@ -710,7 +710,6 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
710
  $this->_meta[$listId]['curpos'] = 0;
711
  //$this->_meta[$listId]['queried'] = 0;
712
  $this->_meta['lastupdate'] = $this->_meta[$listId]['gentime'];
713
- $this->_metaUpdated = true;
714
  $header = $this->_meta[$listId]['gentime'] . "\t"
715
  . $this->_meta[$listId]['listsize'] . "\t"
716
  . $this->_meta[$listId]['env'] . "\n";
@@ -759,7 +758,6 @@ class Litespeed_Litemage_Model_Observer_Cron extends Varien_Event_Observer
759
  $this->_meta[$listId]['listsize'] = count($urls);
760
  $this->_meta[$listId]['gentime'] = time();
761
  $this->_meta['lastupdate'] = $this->_meta[$listId]['gentime'];
762
- $this->_metaUpdated = true;
763
  $header = $this->_meta[$listId]['gentime'] . "\t"
764
  . $this->_meta[$listId]['listsize'] . "\t"
765
  . $this->_meta[$listId]['env'] . "\n";
31
  const ENV_COOKIE_NAME = '_lscache_vary' ;
32
 
33
  protected $_meta ; // time, curfileline
 
34
  protected $_conf;
35
  protected $_isDebug ;
36
  protected $_debugTag;
114
 
115
  public function getCrawlerStatus()
116
  {
117
+ $this->_initMeta();
118
+ $meta = $this->_meta;
119
  $timefmt = 'Y-m-d H:i:s';
120
  $status = array('lastupdate' => '', 'endreason' => '',
121
  'stores' => array());
122
 
123
+ if (isset($meta['lastupdate'])) {
124
+ $status['lastupdate'] = date($timefmt, $meta['lastupdate']);
125
+ unset($meta['lastupdate']);
126
  }
127
 
128
+ if (isset($meta['endreason'])) {
129
+ $status['endreason'] = $meta['endreason'];
130
+ unset($meta['endreason']);
131
  }
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
+ $disp['store_name'] = $store_stat['store_name'];
140
+ $disp['default_curr'] = $store_stat['default_curr'];
141
  $disp['baseurl'] = $store_stat['baseurl'];
142
  $disp['file'] = (isset($store_stat['file']) ? $store_stat['file'] : '');
143
  $disp['ttl'] = $store_stat['ttl'];
144
  $disp['interval'] = $store_stat['interval'];
145
+ $disp['gentime'] = ($store_stat['gentime'] > 0) ? date($timefmt, $store_stat['gentime']) : 'N/A';
146
+ $disp['tmpmsg'] = isset($store_stat['tmpmsg']) ? $store_stat['tmpmsg'] : '';
147
+ $disp['lastquerytime'] = ($store_stat['lastquerytime'] > 0) ? date($timefmt, $store_stat['lastquerytime']) : 'N/A';
148
+ $disp['endtime'] = ($store_stat['endtime'] > 0) ? date($timefmt, $store_stat['endtime']) : 'N/A';
149
+ $disp['listsize'] = ($store_stat['listsize'] > 0) ? $store_stat['listsize'] : 'N/A';
 
 
 
 
150
  $disp['curpos'] = $store_stat['curpos'];
151
  $disp['env'] = $store_stat['env'];
152
  $disp['curvary'] = preg_replace("/_lscache_vary=.+;/", '', $store_stat['curvary']);
153
  $disp['queried'] = $store_stat['queried'];
154
+ $priority[$listId] = $store_stat['priority'];
155
+ $lists[$listId] = $disp;
156
+ }
157
+ asort($priority, SORT_NUMERIC);
158
+ foreach ($priority as $id => $pri) {
159
+ $status['stores'][] = $lists[$id];
160
  }
 
161
  return $status;
162
  }
163
 
167
 
168
  public function warmCache()
169
  {
170
+ if ($errmsg = $this->_init()) {
171
+ $this->_meta['endreason'] = 'Skipped this round - ' . $errmsg;
172
+ $this->_saveMeta();
173
+ $this->_debugLog('Cron warmCache skip this round - ' . $errmsg);
 
 
 
 
174
  return;
175
  }
176
 
270
  array_shift($vary);
271
  }
272
 
273
+ $this->_curList = array('id' => $id, 'fixed' => $fixed, 'vary' => $vary, 'working' => 0);
274
+ if ($m['gentime'] > 0 && $m['endtime'] == 0
275
+ && ($urls = $this->_getCrawlListFileData($id)) != null ) {
 
 
 
276
  $allurls = explode("\n", $urls) ;
277
  // verify data
278
  $header = explode("\t", array_shift($allurls));
286
  $this->_debugLog('load saved url list, header does not match, will regenerate') ;
287
  }
288
  }
 
 
 
289
 
290
  if (!isset($this->_curList['urls'])) {
291
  // regenerate
420
  $this->_meta[$id]['queried'] += $this->_curList['working'];
421
  $this->_meta[$id]['lastquerytime'] = $now;
422
  $this->_meta['lastupdate'] = $now;
 
423
  $this->_curList['working'] = 0;
424
  }
425
 
428
  $meta = array(
429
  'id' => $storeInfo['id'], // store1, custom1, delta
430
  'storeid' => $storeInfo['storeid'],
431
+ 'store_name' => $storeInfo['store_name'],
432
+ 'default_curr' => $storeInfo['default_curr'],
433
  'baseurl' => $storeInfo['baseurl'],
434
  'ttl' => $storeInfo['ttl'],
435
  'interval' => $storeInfo['interval'],
447
  }
448
  if ($tmpmsg) {
449
  $meta['tmpmsg'] = $tmpmsg;
 
 
 
450
  }
451
 
452
  return $meta;
463
 
464
  protected function _initMeta()
465
  {
 
 
466
  $this->_meta = array();
467
 
468
  $saved = array();
477
  }
478
 
479
  if (empty($this->_conf['store'])) {
480
+ return array();
481
  }
482
 
483
+ $unfinished = array();
484
+ $expired = array();
485
+ $curtime = time();
486
+
487
  foreach( $this->_conf['store'] as $listId => $info) {
488
  $tmpmsg = '';
489
  if (isset($saved[$listId])) {
490
  // validate saved
491
  $m = $saved[$listId];
492
  if (isset($m['storeid']) && ($m['storeid'] == $info['storeid'])
493
+ && isset($m['env']) && ($m['env'] == $info['env'])
494
+ && isset($m['interval']) && ($m['interval'] == $info['interval'])
495
+ && isset($m['priority']) && ($m['priority'] == $info['priority'])
496
+ && isset($m['baseurl']) && ($m['baseurl'] == $info['baseurl'])) {
497
+
498
+ if ($m['gentime'] == 0) {
499
+ $tmpmsg = 'New list will be generated';
500
+ $unfinished[$listId] = $m['priority'];
501
+ }
502
+ elseif ($m['endtime'] == 0) {
503
+ // not finished
504
+ $unfinished[$listId] = $m['priority'];
505
+ $tmpmsg = 'Has not finished, will continue.';
506
+ }
507
+ elseif (($m['endtime'] + $m['interval'] < $curtime)) {
508
+ // expired
509
+ $expired[$listId] = $m['priority'];
510
+ $tmpmsg = 'Run interval passed, will restart.';
511
  }
512
  else {
513
+ $tmpmsg = 'Still fresh within interval.';
514
  }
515
+ $m['tmpmsg'] = $tmpmsg;
516
+ $this->_meta[$listId] = $m;
517
  }
518
  else {
519
+ $tmpmsg = 'Saved configuration does not match current configuration. List will be regenerated.';
520
+ $m['gentime'] = 0;
521
+ if ($m['endtime'] == 0)
522
+ $unfinished[$listId] = $m['priority'];
523
+ else
524
+ $expired[$listId] = $m['priority'];
525
  }
526
  }
527
+ else {
528
+ $tmpmsg = 'New list will be generated';
529
+ $m['gentime'] = 0;
530
+ $unfinished[$listId] = $info['priority'];
531
+ }
532
  if (!isset($this->_meta[$listId])) {
533
  $this->_meta[$listId] = $this->_newStoreMeta($info, $tmpmsg);
534
  }
 
535
  }
536
 
537
+ asort($unfinished, SORT_NUMERIC);
538
+ asort($expired, SORT_NUMERIC);
539
+ $priority = array_merge(array_keys($unfinished), array_keys($expired));
540
 
541
  return $priority;
542
  }
544
  protected function _init()
545
  {
546
  if (empty($this->_conf['store'])) {
547
+ return 'configuration not enabled.';
 
 
 
548
  }
549
 
550
+ $this->_priority = $this->_initMeta();
551
+ if ( empty($this->_priority) ) {
552
+ return 'no url list available for warm up';
553
+ }
554
 
555
+ $maxTime = (int) ini_get('max_execution_time') ;
556
+ if ( $maxTime == 0 )
557
+ $maxTime = 300 ; // hardlimit
558
+ else
559
+ $maxTime -= 5 ;
 
 
 
560
 
561
+ $configed = $this->_conf[Litespeed_Litemage_Helper_Data::CFG_WARMUP_MAXTIME];
562
+ if ( $maxTime > $configed )
563
+ $maxTime = $configed ;
564
+ $this->_maxRunTime = $maxTime + time();
565
 
566
+ $this->_adjustCurThreads();
567
+
568
+ if ($this->_curThreads == 0) {
569
+ return 'load over limit' ;
570
  }
571
 
572
+ if ($this->_prepareCurList())
573
+ return ''; // no err msg
 
 
 
574
  else {
575
+ return 'No url list available';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
576
  }
577
  }
578
 
583
 
584
  $load = sys_getloadavg() ;
585
  $curload = $load[0];
 
586
 
587
  if ($this->_curThreads == -1) {
588
  // init
589
+ if ($curload > $limit) {
590
+ $curthreads = 0;
591
+ }
592
+ elseif ($curload >= ($limit - 1)) {
593
  $curthreads = 1;
594
  }
595
  else {
601
  }
602
  else {
603
  // adjust
604
+ $curthreads = $this->_curThreads;
605
  if ($curload >= $limit + 1 ) {
606
  sleep(5); // sleep 5 secs
607
+ if ($curthreads >= 1)
608
+ $curthreads --;
609
  }
610
  elseif ($curload >= $limit) {
611
  if ($curthreads > 1) // if already 1, keep
617
  }
618
  }
619
 
 
 
620
 
621
  if ($this->_isDebug) {
622
  $this->_debugLog('set current threads = ' . $curthreads . ' previous=' . $this->_curThreads
710
  $this->_meta[$listId]['curpos'] = 0;
711
  //$this->_meta[$listId]['queried'] = 0;
712
  $this->_meta['lastupdate'] = $this->_meta[$listId]['gentime'];
 
713
  $header = $this->_meta[$listId]['gentime'] . "\t"
714
  . $this->_meta[$listId]['listsize'] . "\t"
715
  . $this->_meta[$listId]['env'] . "\n";
758
  $this->_meta[$listId]['listsize'] = count($urls);
759
  $this->_meta[$listId]['gentime'] = time();
760
  $this->_meta['lastupdate'] = $this->_meta[$listId]['gentime'];
 
761
  $header = $this->_meta[$listId]['gentime'] . "\t"
762
  . $this->_meta[$listId]['listsize'] . "\t"
763
  . $this->_meta[$listId]['env'] . "\n";
app/code/community/Litespeed/Litemage/Model/Observer/Esi.php CHANGED
@@ -34,7 +34,7 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
34
  * hard-coded HTML and also frequently skips the toHtml method
35
  *
36
  * @param Varien_Object $eventObj
37
- * @return null
38
  */
39
  protected $_esi ;
40
  protected $_isDebug ;
@@ -45,6 +45,7 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
45
  protected $_viewVary = array();
46
  protected $_routeCache;
47
  protected $_injectedBlocks = array();
 
48
 
49
  protected function _construct()
50
  {
@@ -57,15 +58,15 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
57
  public function purgeEsiCache( $eventObj )
58
  {
59
  if ( $this->_moduleEnabledForUser ) {
60
- $this->_helper->addPurgeEvent($eventObj->getEvent()->getName()) ;
61
  }
62
  }
63
 
64
- //customer_login, customer_logout
65
- public function purgePrivateCache( $eventObj )
66
  {
67
  if ( $this->_moduleEnabledForUser ) {
68
- $this->_helper->setPurgeHeader(array('*'), $eventObj->getEvent()->getName(), null, true) ;
69
  $this->_viewVary[] = 'env';
70
  }
71
  }
@@ -80,7 +81,7 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
80
  }
81
 
82
  //controller_action_predispatch
83
- public function checkControllerNoCache( $eventObj )
84
  {
85
  // no need to check admin, this is frontend event only
86
  if ( ! $this->_moduleEnabledForUser ) {
@@ -89,9 +90,18 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
89
  }
90
  $req = Mage::app()->getRequest() ;
91
  $controller = $eventObj->getControllerAction();
 
92
  $reason = '';
93
 
94
- if (($lmdebug = $req->getParam('LITEMAGE_DEBUG')) !== null) {
 
 
 
 
 
 
 
 
95
  // either isDebug or IP match
96
  if ($this->_isDebug || $this->_config->isRestrainedIP() || $this->_config->isAdminIP()) {
97
  if ($lmdebug == 'SHOWHOLES') {
@@ -111,7 +121,6 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
111
  }
112
  }
113
 
114
- $curActionName = $controller->getFullActionName() ;
115
  if ($reason == '') {
116
  $reason = $this->_cannotCache($req, $curActionName);
117
  }
@@ -119,6 +128,7 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
119
  if ($reason != '') {
120
  $this->_canInjectEsi = 0;
121
  $reason = ' NO_CACHE=' . $reason;
 
122
 
123
  // special checks
124
  $envChanged = array('customer_account_logoutSuccess', 'directory_currency_switch');
@@ -137,7 +147,7 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
137
  $this->_setWholeRouteCache($curActionName, $controller);
138
  }
139
 
140
- if (($lmctrl = $req->getParam('LITEMAGE_CTRL')) !== null) {
141
  // either isDebug or IP match
142
  if ($this->_config->isAdminIP()) {
143
  if ($lmctrl == 'PURGE') {
@@ -154,7 +164,13 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
154
  }
155
  }
156
 
157
- $this->_helper->setCacheControlFlag(Litespeed_Litemage_Helper_Esi::CHBM_CACHEABLE) ;
 
 
 
 
 
 
158
 
159
  if (Mage::getSingleton('core/cookie')->get('litemage_cron') == Litespeed_Litemage_Model_Observer_Cron::USER_AGENT) {
160
  $currency = Mage::getSingleton('core/cookie')->get('currency');
@@ -164,7 +180,7 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
164
  }
165
 
166
  if ( $this->_isDebug ) {
167
- $this->_config->debugMesg('****** PRECHECK route_action [' . $curActionName . '] url=' . $req->getRequestString() . $reason) ;
168
  }
169
 
170
  }
@@ -204,9 +220,15 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
204
  }
205
 
206
  foreach ( $nocache[Litespeed_Litemage_Helper_Data::CFG_NOCACHE_URL] as $url ) {
207
- if ( strpos($requrl, $url) !== false ) {
208
- return 'disabled url ' . $url;
209
- }
 
 
 
 
 
 
210
  }
211
 
212
  return ''; // can be cached
@@ -226,97 +248,15 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
226
  if ( ! $this->_canInjectEsi )
227
  return ;
228
 
229
- // this is to deal with duplicated block names, caused by bad extensions, those blocks are lost in layout->_blocks[name], since name not unique
230
  $block = $eventObj->getData('block') ;
231
-
232
- $bconf = $this->_config->isEsiBlock($block);
233
- if ($bconf != null) {
234
- $blockName = $bconf['bn'];
235
-
236
- if (!isset($this->_injectedBlocks[$blockName])) {
237
- $bconf['blocks'] = array();
238
- $this->_injectedBlocks[$blockName] = $bconf;
239
- }
240
- $this->_injectedBlocks[$blockName]['blocks'][] = $block;
241
- }
242
- // needs to be in its own section, not in else
243
- if ($block->hasData('litemage_dynamic')) {
244
- // dynamic injection right now
245
- $this->_injectDynamicBlock($block);
246
- }
247
- }
248
-
249
- protected function _injectDynamicBlock($block)
250
- {
251
- $bd = $block->getData('litemage_dynamic');
252
- if (!isset($bd['type']))
253
- return;
254
-
255
- if (!isset($bd['tag'])) { // todo: need to validate tag
256
- /*$conf = $this->_config->getEsiConf('tag', $tag) ;
257
- if ($conf == null) {
258
- if ( $this->_isDebug ) {
259
- $this->_config->debugMesg('Missing config for tag '. $tag) ;
260
- }
261
- return false ;
262
- } */
263
- $bd['tag'] = 'welcome';
264
- }
265
- $bd['cache-tag'] = 'E.' . $bd['tag'];
266
- if (!isset($bd['access']) || !in_array($bd['access'], array('private', 'public'))) {
267
- $bd['access'] = 'private';
268
- }
269
- if (!isset($bd['valueonly'])) {
270
- $bd['valueonly'] = false;
271
- }
272
-
273
- /*
274
- * $litemage_attr = array('litemage_dynamic' =>
275
- array('tag' => 'welcome', 'access' => 'private', 'type' => 'customer/form_login', 'template' => 'customer/form/mini.login.phtml'));
276
- */
277
-
278
- $blockName = $block->getNameInLayout();
279
- $layout = $block->getLayout();
280
-
281
- //re-init just in case
282
- $conf = $this->_config->getEsiConf() ;
283
- $preload = $this->_initInjectionCache($layout) ; // -1: donot use cache, 0 : no cahce, 1: cache loaded, 2: require update
284
-
285
-
286
- $esiHtml = '' ;
287
- if ( $preload && isset($this->_esi['layout']['blocks'][$blockName]) ) {
288
- $esiHtml = $this->_esi['layout']['blocks'][$blockName] ;
289
- unset($this->_esi['layout']['blocks'][$blockName]) ;
290
- }
291
- else {
292
- if ( $preload == 1 ) {
293
- $preload = 2 ; // found a new blockName not preloaded
294
- }
295
-
296
- $urlOptions = array('b' => $blockName, 't' => $bd['tag']);
297
- $urlOptions['p'] = str_replace('/', '--', $bd['type']);
298
- if (isset($bd['template'])) {
299
- $urlOptions['l'] = str_replace('/', '--', $bd['template']);
300
- }
301
- $urlOptions = array_merge($urlOptions, $this->_esi['urlParams']);
302
-
303
- $esiUrl = $this->_helper->getSubReqUrl('litemage/esi/getBlock', $urlOptions) ;
304
- $esiHtml = '<' . $this->_config->esiTag('include') . ' src="' . $esiUrl . '" combine="sub" cache-tag="' . $bd['cache-tag'] . '" cache-control="no-vary,' . $bd['access'] . '"/>' ;
305
- if (!$bd['valueonly'] && $this->_isDebug) {
306
- $esiHtml = '<!--Litemage esi started ' . $blockName . '-->' . $esiHtml . '<!--Litemage esi ended ' . $blockName . '-->' ;
307
- }
308
- }
309
-
310
- $this->_helper->setEsiBlockHtml($blockName, $esiHtml) ;
311
-
312
- $esiBlock = new Litespeed_Litemage_Block_Core_Esi() ;
313
- if ($bd['valueonly']) {
314
- $esiBlock->setData('valueonly', 1); // needs to set before initbypeer
315
  }
316
- $esiBlock->setData('dynamic', 1);
317
- $esiBlock->initByPeer($block, $esiHtml) ;
318
- $this->_esi['layout']['preload'] = $preload ;
319
-
320
  }
321
 
322
  //controller_action_layout_generate_blocks_after
@@ -331,113 +271,32 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
331
 
332
  $this->_helper->initFormKey() ;
333
 
334
- if (count($this->_injectedBlocks) == 0)
335
- return;
336
-
337
- $layout = $eventObj->getData('layout') ;
338
- $conf = $this->_config->getEsiConf() ;
339
- $preload = $this->_initInjectionCache($layout) ; // -1: donot use cache, 0 : no cahce, 1: cache loaded, 2: require update
340
- $esiLayoutUpdate = null ;
341
- $conflict = array();
342
-
343
- foreach ( $this->_injectedBlocks as $blockName => $bd ) {
344
-
345
- foreach ($bd['blocks'] as $block) {
346
-
347
- $esiHtml = '' ;
348
-
349
- $blockAlias = $block->getBlockAlias();
350
- $blockIndex = $blockName;
351
- if ($blockAlias != '' && $blockAlias != $blockName) {
352
- $blockIndex .= '!' . $blockAlias;
353
- }
354
-
355
- // check confliction
356
- if (!isset($conflict[$blockIndex])) {
357
- $conflict[$blockIndex] = array($block);
358
- }
359
- else {
360
- $conflict[$blockIndex][] = $block;
361
- if ( $this->_isDebug )
362
- $this->_config->debugMesg('ALERT not unique block name plus alias ' . $blockIndex);
363
- }
364
-
365
- if ( $preload && isset($this->_esi['layout']['blocks'][$blockIndex]) ) {
366
- $esiHtml = $this->_esi['layout']['blocks'][$blockIndex] ;
367
- unset($this->_esi['layout']['blocks'][$blockIndex]) ;
368
- }
369
- else {
370
- if ( $preload == 1 ) {
371
- $preload = 2 ; // found a new blockIndex not preloaded
372
- }
373
-
374
- // check if it is a child block of an injected block, bypassed one also need to save esihtml
375
- if ( $this->_checkIsInjectedChild($block) ) {
376
- $esiHtml = 'BYPASS';
377
- }
378
- else {
379
-
380
- if ( $esiLayoutUpdate == null ) {
381
- $esiLayoutUpdate = Mage::getSingleton('litemage/layout_update') ;
382
- $esiLayoutUpdate->setStoreId($this->_esi['urlParams']['s']) ;
383
- }
384
-
385
- $urlOptions = $this->_getEsiUrlBHOptions($blockName, $block, $layout, $esiLayoutUpdate) ;
386
- $urlOptions['t'] = $bd['tag'];
387
- if ($blockAlias != '' && $blockName != $blockAlias) {
388
- $urlOptions['a'] = $blockAlias;
389
- }
390
- $urlOptions = array_merge($urlOptions, $this->_esi['urlParams']);
391
-
392
- $esiUrl = $this->_helper->getSubReqUrl('litemage/esi/getBlock', $urlOptions) ;
393
-
394
- $esiHtml = '<' . $this->_config->esiTag('include') . ' src="' . $esiUrl . '" combine="sub" cache-tag="' . $bd['cache-tag'] . '" cache-control="no-vary,' . $bd['access'] . '"/>' ;
395
- if (!$bd['valueonly'] && $this->_isDebug) {
396
- //$esiHtml = '<esi:remove>ESI processing not enabled</esi:remove><!--esi' . $esiInclude . '-->' ; // remove comment, for html minify
397
- $esiHtml = '<!--Litemage esi started ' . $blockName . '-->' . $esiHtml . '<!--Litemage esi ended ' . $blockName . '-->' ;
398
- }
399
- }
400
- }
401
-
402
- $this->_helper->setEsiBlockHtml($blockIndex, $esiHtml) ;
403
-
404
- if ($esiHtml == 'BYPASS') {
405
- // can be a child block of an injected block
406
- continue;
407
- }
408
-
409
- if ( $bd['tag'] == 'messages' ) {
410
- $esiBlock = new Litespeed_Litemage_Block_Core_Messages() ;
411
- }
412
- else {
413
- $esiBlock = new Litespeed_Litemage_Block_Core_Esi() ;
414
- }
415
- if ($bd['valueonly']) {
416
- $esiBlock->setData('valueonly', 1); // needs to be before initbypeer
417
- }
418
- $esiBlock->initByPeer($block, $esiHtml) ;
419
 
420
- }
421
-
422
- }
423
-
424
- $this->_esi['layout']['preload'] = $preload ;
425
- }
426
-
427
- protected function _checkIsInjectedChild($block)
428
- {
429
- $layer = 20;
430
- $blk = $block;
431
- while (($blk = $blk->getParentBlock()) && $layer > 0 ) {
432
- if ($blk->getData('litemageInjected')) {
433
- return true;
434
- }
435
- $layer --;
436
- }
437
- return false;
438
  }
439
 
440
- protected function _setWholeRouteCache($actionName, $controller)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
441
  {
442
  $app = Mage::app();
443
  $design = Mage::getDesign() ;
@@ -454,118 +313,6 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
454
  }
455
  }
456
 
457
- protected function _initInjectionCache( $layout )
458
- {
459
- if (isset($this->_esi['layout']['cacheId'])) {
460
- // already initialized
461
- return isset($this->_esi['layout']['preload']) ? $this->_esi['layout']['preload'] : 0;
462
- }
463
-
464
- $this->_esi = array(
465
- 'layout' => array(),
466
- 'urlParams' => $this->_helper->getEsiSharedParams()) ;
467
- $rootHandles = $layout->getUpdate()->getHandles() ;
468
- //should we deal with wrong theme input? THEME_frontend_neoshop_Designer Sarees, Salwar Kameez, Lehengas, Wedding Sherwanis, Mens Kurta Pyjama, Online Shopping
469
- $tags = array() ;
470
- foreach ( $rootHandles as $handle ) {
471
- if ( (strpos($handle, 'CATEGORY_') === false) && ((strpos($handle, 'PRODUCT_') === false) || (strpos($handle, 'PRODUCT_TYPE_') !== false)) ) {
472
- $this->_esi['layout']['handles'][] = $handle ;
473
- if ( ($handle != 'customer_logged_out') && ($handle != 'customer_logged_in') )
474
- $tags[] = $handle ;
475
- }
476
- }
477
- sort($tags) ;
478
- $tags[] = 'LITEMAGE_INJECT_ESI' ;
479
- $tags[] = join('-', $this->_esi['urlParams']); // for env vary
480
- $cacheId = 'LITEMAGE_BLOCK_' . md5(join('__', $tags)) ;
481
- $this->_esi['layout']['cacheId'] = $cacheId ;
482
- $this->_helper->setEsiOn() ;
483
-
484
- $preload = 0 ;
485
-
486
- if ( $result = Mage::app()->loadCache($cacheId) ) {
487
- $preload = 1 ;
488
- $this->_esi['layout']['blocks'] = unserialize($result) ;
489
- }
490
-
491
- if ( $this->_isDebug )
492
- $this->_config->debugMesg('INJECTING_' . $preload . ' ' . $_SERVER['REQUEST_URI']) ;
493
-
494
- return $preload ;
495
- }
496
-
497
- protected function _getEsiUrlBHOptions( $blockName, $block, $layout, $esiLayoutUpdate )
498
- {
499
- // for blocks and handles
500
- $hParam = array() ;
501
- $handles = array() ;
502
- $packageLayout = $esiLayoutUpdate->getPackageLayout() ;
503
-
504
- $blockNames = $this->_getChildrenNames($block, $layout) ;
505
- if ( ($alias = $block->getBlockAlias()) && ($alias != $blockName) ) {
506
- array_unshift($blockNames, $blockName, $alias) ;
507
- }
508
- else {
509
- array_unshift($blockNames, $blockName) ;
510
- }
511
- foreach ( $this->_esi['layout']['handles'] as $h ) {
512
- if ( $h == 'customer_logged_out' || $h == 'customer_logged_in' ) {
513
- $handles[] = $h ;
514
- }
515
- else {
516
-
517
- foreach ( $blockNames as $name ) {
518
- $xpath = '//' . $h . '//*[@name="' . $name . '"]' ;
519
- if ( $node = $packageLayout->xpath($xpath) ) {
520
- $handles[] = $h ;
521
- $hParam[] = $h ;
522
- break ;
523
- }
524
- }
525
- }
526
- }
527
-
528
- $hasCache = $esiLayoutUpdate->loadEsiBlockCache($blockName, $handles) ;
529
- if ( $hasCache === 0 ) {
530
- //save layout cache right now, most economic way, blockNames will be filtered
531
- $blockNames = $esiLayoutUpdate->importLayoutUpdate($blockNames, $handles, $layout) ;
532
- }
533
- elseif ( $hasCache == 1 ) {
534
- // blockNames will be filtered
535
- $blockNames = $esiLayoutUpdate->getBlockNames() ;
536
- }
537
-
538
- $urlOptions = array(
539
- 'b' => implode(',', $blockNames) ) ;
540
-
541
- if ( count($hParam) > 0 )
542
- $urlOptions['h'] = implode(',', $hParam) ;
543
-
544
- return $urlOptions ;
545
- }
546
-
547
- protected function _getChildrenNames( $block, $layout )
548
- {
549
- if ($block == null) {
550
- return array();
551
- }
552
-
553
- $children = $block->getSortedChildren() ;
554
- foreach ( $children as $childName ) {
555
- if ( $childBlock = $layout->getBlock($childName) ) {
556
- $alias = $childBlock->getBlockAlias() ;
557
- if ( $alias != $childName ) {
558
- $children[] = $alias ;
559
- }
560
- $grandChildren = $this->_getChildrenNames($childBlock, $layout) ;
561
- if ( count($grandChildren) > 0 ) {
562
- $children = array_merge($children, $grandChildren) ;
563
- }
564
- }
565
- }
566
- return $children ;
567
- }
568
-
569
  //event: http_response_send_before
570
  public function beforeResponseSend( $eventObj )
571
  {
@@ -590,14 +337,6 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
590
  return;
591
  }
592
 
593
- if ( $this->_esi != null && ($this->_esi['layout']['preload'] != 1 || ! empty($this->_esi['layout']['blocks']) || $this->_helper->isEsiBlockAdjusted()) ) {
594
- $tags = array(Litespeed_Litemage_Helper_Data::LITEMAGE_GENERAL_CACHE_TAG, Mage_Core_Model_Layout_Update::LAYOUT_GENERAL_CACHE_TAG);
595
-
596
- if (Mage::app()->useCache('layout')) {
597
- Mage::app()->saveCache($this->_helper->getEsiBlockHtml(), $this->_esi['layout']['cacheId'], $tags) ;
598
- }
599
- }
600
-
601
  if ( count($this->_viewVary) ) {
602
  // this needs to run before helper's beforeResponseSend
603
  Mage::Helper('litemage/viewvary')->persistViewVary($this->_viewVary) ;
@@ -640,7 +379,7 @@ class Litespeed_Litemage_Model_Observer_Esi extends Varien_Event_Observer
640
  $this->_helper->addCacheEntryTag(Litespeed_Litemage_Helper_Esi::TAG_PREFIX_PRODUCT . $productId) ;
641
 
642
  if ( $this->_config->trackLastViewed() ) {
643
- $this->_helper->addPurgeEvent($eventObj->getEvent()->getName()) ;
644
  $this->_helper->trackProduct($productId) ;
645
  }
646
  }
34
  * hard-coded HTML and also frequently skips the toHtml method
35
  *
36
  * @param Varien_Object $eventObj
37
+ * @return NULL
38
  */
39
  protected $_esi ;
40
  protected $_isDebug ;
45
  protected $_viewVary = array();
46
  protected $_routeCache;
47
  protected $_injectedBlocks = array();
48
+ protected $_startDynamic = false;
49
 
50
  protected function _construct()
51
  {
58
  public function purgeEsiCache( $eventObj )
59
  {
60
  if ( $this->_moduleEnabledForUser ) {
61
+ $this->_helper->addPrivatePurgeEvent($eventObj->getEvent()->getName()) ;
62
  }
63
  }
64
 
65
+ //customer_login, customer_logout, purge all private cache for that user
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
  }
81
  }
82
 
83
  //controller_action_predispatch
84
+ public function predispatchCheckControllerNoCache( $eventObj )
85
  {
86
  // no need to check admin, this is frontend event only
87
  if ( ! $this->_moduleEnabledForUser ) {
90
  }
91
  $req = Mage::app()->getRequest() ;
92
  $controller = $eventObj->getControllerAction();
93
+ $curActionName = $controller->getFullActionName() ;
94
  $reason = '';
95
 
96
+ if ($this->_helper->notCacheable()) {
97
+ // from previous redirect
98
+ if ( $this->_isDebug ) {
99
+ $this->_config->debugMesg('no cache from previous redirect route_action ' . $controller->getFullActionName()) ;
100
+ }
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') {
121
  }
122
  }
123
 
 
124
  if ($reason == '') {
125
  $reason = $this->_cannotCache($req, $curActionName);
126
  }
128
  if ($reason != '') {
129
  $this->_canInjectEsi = 0;
130
  $reason = ' NO_CACHE=' . $reason;
131
+ $this->_helper->setCacheControlFlag(Litespeed_Litemage_Helper_Esi::CHBM_NOT_CACHEABLE) ;
132
 
133
  // special checks
134
  $envChanged = array('customer_account_logoutSuccess', 'directory_currency_switch');
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') {
164
  }
165
  }
166
 
167
+ $ttl = -1;
168
+ if ($curActionName == 'cms_index_index') {
169
+ $ttl = $this->_config->getConf(Litespeed_Litemage_Helper_Data::CFG_HOMETTL);
170
+ if ($ttl == '')
171
+ $ttl = -1;
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');
180
  }
181
 
182
  if ( $this->_isDebug ) {
183
+ $this->_config->debugMesg('****** PRECHECK route_action [' . $curActionName . '] ' . $req->getRequestString() . $reason) ;
184
  }
185
 
186
  }
220
  }
221
 
222
  foreach ( $nocache[Litespeed_Litemage_Helper_Data::CFG_NOCACHE_URL] as $url ) {
223
+ if (substr($url, -1) == '*') {
224
+ $url = trim($url, '*');
225
+ if ( strpos($requrl, $url) !== false ) {
226
+ return 'disabled url (partial match) ' . $url;
227
+ }
228
+ }
229
+ else if ($url == $requrl) {
230
+ return 'disabled url (exact match) ' . $url;
231
+ }
232
  }
233
 
234
  return ''; // can be cached
248
  if ( ! $this->_canInjectEsi )
249
  return ;
250
 
 
251
  $block = $eventObj->getData('block') ;
252
+ if ( $this->_config->isEsiBlock($block, $this->_startDynamic) ) {
253
+ if ($this->_startDynamic ) {
254
+ $this->_injectEsiBlock($block);
255
+ }
256
+ else {
257
+ $this->_injectedBlocks[] = $block;
258
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
259
  }
 
 
 
 
260
  }
261
 
262
  //controller_action_layout_generate_blocks_after
271
 
272
  $this->_helper->initFormKey() ;
273
 
274
+ foreach ( $this->_injectedBlocks as $block ) {
275
+ $this->_injectEsiBlock($block);
276
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
 
278
+ $this->_startDynamic = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
279
  }
280
 
281
+ protected function _injectEsiBlock($block)
282
+ {
283
+ $bconf = $block->getData('litemage_bconf');
284
+ if (!$bconf) {
285
+ // log something wrong
286
+ return;
287
+ }
288
+
289
+ if ( $bconf['tag'] == 'messages' ) {
290
+ $esiBlock = new Litespeed_Litemage_Block_Core_Messages() ;
291
+ }
292
+ else {
293
+ $esiBlock = new Litespeed_Litemage_Block_Core_Esi() ;
294
+ }
295
+ // just init, maynot be used
296
+ $esiBlock->initByPeer($block) ;
297
+ }
298
+
299
+ protected function _setWholeRouteCache($actionName, $controller)
300
  {
301
  $app = Mage::app();
302
  $design = Mage::getDesign() ;
313
  }
314
  }
315
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316
  //event: http_response_send_before
317
  public function beforeResponseSend( $eventObj )
318
  {
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) ;
379
  $this->_helper->addCacheEntryTag(Litespeed_Litemage_Helper_Esi::TAG_PREFIX_PRODUCT . $productId) ;
380
 
381
  if ( $this->_config->trackLastViewed() ) {
382
+ $this->_helper->addPrivatePurgeEvent($eventObj->getEvent()->getName()) ;
383
  $this->_helper->trackProduct($productId) ;
384
  }
385
  }
app/code/community/Litespeed/Litemage/controllers/EsiController.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * LiteMage
4
  *
@@ -21,743 +22,588 @@
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
-
26
  class Litespeed_Litemage_EsiController extends Mage_Core_Controller_Front_Action
27
  {
28
 
29
- const ESIDATA_CACHE_ID = 'litemage_esi_data' ;
30
- const ESIDATA_CACHE_NOTSET = '__NOTSET__' ;
31
-
32
- protected $_esiData ;
33
- protected $_curData ;
34
- protected $_env = array() ;
35
- protected $_helper ;
36
- protected $_config ;
37
- protected $_isDebug ;
38
- protected $_layout ;
39
-
40
- protected function _construct()
41
- {
42
- $this->setFlag('', Mage_Core_Controller_Varien_Action::FLAG_NO_PRE_DISPATCH, true);
43
- $this->setFlag('', Mage_Core_Controller_Varien_Action::FLAG_NO_POST_DISPATCH, true);
44
- }
45
-
46
- /**
47
- * Retrieve current layout object
48
- *
49
- * @return Mage_Core_Model_Layout
50
- */
51
- public function getLayout()
52
- {
53
- if ( $this->_layout == null ) {
54
- $this->_layout = Mage::getSingleton('litemage/layout') ;
55
- }
56
- return $this->_layout ;
57
- }
58
-
59
- /**
60
- * It seems this has to exist so we just make it redirect to the base URL
61
- * for lack of anything better to do.
62
- *
63
- * @return null
64
- */
65
- public function indexAction()
66
- {
67
- Mage::log('Err: litemage come to indexaction') ;
68
- $this->getResponse()->setRedirect(Mage::getBaseUrl()) ;
69
- }
70
-
71
- public function noRouteAction( $coreRoute = null )
72
- {
73
- //set esi off
74
- $origEsiUrl = $_SERVER['REQUEST_URI'] ;
75
- if ( $param = $this->_parseUrlParams($origEsiUrl) ) {
76
- switch ( $param['action'] ) {
77
- case 'getCombined': $this->getCombinedAction() ;
78
- break ;
79
- case 'getFormKey': $this->getFormKeyAction() ;
80
- break ;
81
- case 'getBlock': $this->getBlockAction() ;
82
- break ;
83
- case 'getMessage': $this->getMessageAction() ;
84
- break ;
85
- case 'log': $this->logAction() ;
86
- break ;
87
- default: $this->_errorExit() ;
88
- }
89
- }
90
- else {
91
- $this->_errorExit() ;
92
- }
93
- }
94
-
95
- protected function _errorExit()
96
- {
97
- $resp = $this->getResponse() ;
98
- $resp->setHttpResponseCode(500) ;
99
- $resp->setBody('<!-- ESI data is not valid -->') ;
100
- }
101
-
102
- /**
103
- * Spit out the form key for this session
104
- *
105
- * @return null
106
- */
107
- public function getFormKeyAction()
108
- {
109
- $action = 'getFormKey' ;
110
- if ( $this->_initUserParams($action) ) {
111
- $this->_setEsiFlag($this->_esiData[$action]) ;
112
- $data = $this->_esiData[$action]['raw_output'] ;
113
- $this->getResponse()->setBody($data) ;
114
- }
115
- else {
116
- $this->_errorExit() ;
117
- }
118
- }
119
-
120
- protected function _setEsiFlag( $esiData )
121
- {
122
- $flag = Litespeed_Litemage_Helper_Esi::CHBM_ESI_REQ ;
123
- $tag = '' ;
124
-
125
- if ( $esiData['ttl'] > 0 ) {
126
- $flag |= Litespeed_Litemage_Helper_Esi::CHBM_CACHEABLE ;
127
- if ( $esiData['access'] == 'private' )
128
- $flag |= Litespeed_Litemage_Helper_Esi::CHBM_PRIVATE ;
129
- if ( isset($esiData['cacheIfEmpty']) && $esiData['cacheIfEmpty'] )
130
- $flag |= Litespeed_Litemage_Helper_Esi::CHBM_ONLY_CACHE_EMPTY ;
131
- $tag = $esiData['tag'] ;
132
- }
133
- $this->_helper->setCacheControlFlag($flag, $esiData['ttl'], $tag) ;
134
- }
135
-
136
- public function getBlockAction()
137
- {
138
- if ( ! $this->_initUserParams('getBlock') ) {
139
- $this->_errorExit() ;
140
- return ;
141
- }
142
-
143
- $esiDatas = array_values($this->_esiData) ;
144
- $esiData = $esiDatas[0] ;
145
- if ( count($this->_esiData) > 1 ) {
146
- // not sure when this will happen
147
- $includeEsi = '<' . $this->_config->esiTag('include') . ' src="' . $esiData['url'] . '" combine="sub" cache-control="no-vary,private"/>' ;
148
- $this->_esiData['include'] = array( 'output' => $includeEsi ) ;
149
- $this->_getCombinedData() ;
150
- }
151
- else {
152
- $this->_setEsiFlag($esiData) ;
153
- if ( isset($esiData['output']) && ($esiData['output'] != self::ESIDATA_CACHE_NOTSET) ) {
154
- $this->getResponse()->setBody($esiData['output']) ;
155
- }
156
- else {
157
- $this->_blockData($esiData) ;
158
- if ( $this->_env['update_cache'] && Mage::app()->useCache('layout') ) {
159
- if ( $this->_env['update_cache'] & 2 ) {
160
- $this->_env['esiUrls'][$esiData['n']][$esiData['url']] = $this->getResponse()->getBody() ;
161
- }
162
- $tags = array( Litespeed_Litemage_Helper_Data::LITEMAGE_GENERAL_CACHE_TAG ) ;
163
- Mage::app()->saveCache(serialize($this->_env['esiUrls']), $this->_env['cache_id'], $tags) ;
164
- }
165
- }
166
- }
167
- }
168
-
169
- protected function _blockData( $esiData )
170
- {
171
- $this->_curData = $esiData ;
172
- if (isset($esiData['type'])) {
173
- // dynamic block
174
- $this->_layout->resetBlocks() ;
175
- if ($block = $this->_layout->createBlock($esiData['type'], $esiData['n'])) {
176
- if (isset($esiData['template'])) {
177
- $block->setTemplate($esiData['template']);
178
- }
179
- $this->renderLayout($esiData['n']) ;
180
- }
181
- }
182
- else {
183
- $this->loadLayoutUpdates() ;
184
- $this->generateLayoutXml() ;
185
- $this->generateLayoutBlocks() ;
186
- $name_alias = isset($esiData['alias']) ? $esiData['alias'] : $esiData['n'];
187
- $this->renderLayout($name_alias) ;
188
- }
189
- }
190
-
191
- public function renderLayout( $output = '' )
192
- {
193
- // override, output can be block name or alias
194
- if ( $output != '' && $this->_layout->getOutputBlock($output) != null ) {
195
- try {
196
- parent::renderLayout($output) ;
197
- } catch ( Exception $e ) {
198
- if ( $this->_isDebug ) {
199
- $this->_config->debugMesg('renderLayout, exception for block ' . $output . ' : ' . $e->getMessage()) ;
200
- }
201
- }
202
- }
203
- else {
204
- if ( $this->_isDebug ) {
205
- $this->_config->debugMesg('renderLayout, not output for ' . $output) ;
206
- }
207
- }
208
- return $this ;
209
- }
210
-
211
- public function getMessageAction()
212
- {
213
- if ( $this->_initUserParams('getMessage') ) {
214
- $esiData = array_values($this->_esiData) ;
215
- $this->_setEsiFlag($esiData[0]) ;
216
- $this->_messageData($esiData[0]) ;
217
- }
218
- else {
219
- $this->_errorExit() ;
220
- }
221
- }
222
-
223
- protected function _messageData( $esiData )
224
- {
225
- $this->_curData = $esiData ;
226
- $this->loadLayoutUpdates() ;
227
- $this->generateLayoutXml() ;
228
- $this->generateLayoutBlocks() ;
229
-
230
- $name_alias = isset($esiData['alias']) ? $esiData['alias'] : $esiData['n'];
231
-
232
- $block = $this->_layout->getOutputBlock($name_alias) ;
233
- $newMessages = new Litespeed_Litemage_Block_Core_Messages() ;
234
- $newMessages->initByEsi($esiData['st'], $esiData['call'], $block) ;
235
- $this->renderLayout($name_alias) ;
236
- }
237
-
238
- public function getCombinedAction()
239
- {
240
- if ( ! $this->_initUserParams('getCombined') ) {
241
- $this->_errorExit() ;
242
- return ;
243
- }
244
- //add raw header here, to handle ajax exception
245
- header(Litespeed_Litemage_Helper_Esi::LSHEADER_CACHE_CONTROL . ': esi=on', true) ;
246
- $this->_getCombinedData() ;
247
- }
248
-
249
- protected function _getCombinedData()
250
- {
251
- $this->_helper->setCacheControlFlag(Litespeed_Litemage_Helper_Esi::CHBM_ESI_ON | Litespeed_Litemage_Helper_Esi::CHBM_ESI_REQ) ;
252
- $response = $this->getResponse() ;
253
- $response->clearBody() ;
254
- $body = '' ;
255
-
256
- foreach ( $this->_esiData as $key => $esiData ) {
257
-
258
- if ( isset($esiData['output']) && ($esiData['output'] != self::ESIDATA_CACHE_NOTSET) ) {
259
- $body .= $esiData['output'] ;
260
- continue ;
261
- }
262
-
263
- if ( $esiData['action'] == 'log' ) {
264
- $this->_logData($esiData) ;
265
- $esiData['raw_output'] = '' ;
266
- }
267
-
268
- if ( isset($esiData['raw_output']) ) { //getFormKey & log
269
- $inlineBody = $this->_getInlineBody($esiData, $esiData['raw_output'], 200) ;
270
- }
271
- else {
272
- if ( $esiData['action'] == 'getMessage' ) {
273
- $this->_messageData($esiData) ;
274
- }
275
- else {
276
- // getBlock
277
- $this->_blockData($esiData) ;
278
- }
279
- // env['update_cache'] can be changed by logged_in handle
280
- $inlineBody = $this->_getInlineBody($esiData, $response->getBody(), $response->getHttpResponseCode(), ($this->_env['update_cache'] & 2)) ;
281
- $response->clearBody() ;
282
- }
283
-
284
-
285
- $body .= $inlineBody ;
286
- }
287
- $response->setBody($body) ;
288
- if ( $this->_env['update_cache'] && Mage::app()->useCache('layout')) {
289
- $tags = array( Litespeed_Litemage_Helper_Data::LITEMAGE_GENERAL_CACHE_TAG ) ;
290
- Mage::app()->saveCache(serialize($this->_env['esiUrls']), $this->_env['cache_id'], $tags) ;
291
- }
292
- }
293
-
294
- protected function _getInlineBody( $esiData, $output, $responseCode, $updateShared = -1 )
295
- {
296
- $output = trim($output) ;
297
- $esiInlineTag = $this->_config->esiTag('inline');
298
- $initShared = false ;
299
-
300
- if ( ($updateShared != -1) && ($esiData['access'] == 'private') && ($esiData['ttl'] > 0) ) {
301
- if ( $updateShared == 0 ) { // check if same as shared
302
- $out2 = '">' . $output . "</$esiInlineTag>" ;
303
- if ( strpos($this->_env['esiUrls'][$esiData['n']][$esiData['url']], $out2) ) {
304
- $buf = $this->_env['esiUrls'][$esiData['n']][$esiData['url']] ;
305
- if ( $this->_isDebug ) {
306
- $this->_config->debugMesg('Inline0m ' . substr($buf, 0, strpos($buf, "\n"))) ;
307
- }
308
- return $buf ;
309
- }
310
- }
311
- else if ( $updateShared == 2 ) {
312
- $initShared = true ;
313
- }
314
- }
315
-
316
-
317
- $buf = '<' . $esiInlineTag . ' name="' . $esiData['url'] . '" cache-control="' ;
318
-
319
- $ttl = $esiData['ttl'] ;
320
- if ( $ttl > 0 && ! in_array($responseCode, array( 200, 301, 404 )) ) {
321
- $ttl = 0 ;
322
- }
323
-
324
- if ( $ttl == 0 ) {
325
- $buf .= 'no-cache' ;
326
- }
327
- else {
328
- $buf .= $esiData['access'] . ',max-age=' . $esiData['ttl'] . ',no-vary' ;
329
- if ( $esiData['cacheIfEmpty'] )
330
- $buf .= ',set-blank' ;
331
- elseif ( $initShared ) {
332
- $buf .= ',shared' ;
333
- }
334
-
335
- $buf .= '" cache-tag="' . $esiData['tag'] ;
336
- }
337
-
338
- $buf .= '">' . $output . "</$esiInlineTag>\n" ;
339
- if ( $initShared ) {
340
- $this->_env['esiUrls'][$esiData['n']][$esiData['url']] = $buf ;
341
- }
342
-
343
- if ( $this->_isDebug ) {
344
- $this->_config->debugMesg('Inline' . $updateShared . ' ' . substr($buf, 0, strpos($buf, "\n"))) ;
345
- }
346
-
347
- return $buf ;
348
- }
349
-
350
- public function logAction()
351
- {
352
- $action = 'log' ;
353
- if ( $this->_initUserParams($action) ) {
354
- $this->_setEsiFlag($this->_esiData[$action]) ;
355
- $this->_logData($this->_esiData[$action]) ;
356
- }
357
- else
358
- $this->_errorExit() ;
359
- }
360
-
361
- protected function _logData( $esiData )
362
- {
363
- if ( isset($esiData['product']) ) {
364
- if ( isset($this->_env['s']) && ! isset($this->_env['dp']) ) {
365
- Mage::app()->setCurrentStore(Mage::app()->getStore($this->_env['s'])) ;
366
- }
367
-
368
- $product = new Varien_Object() ;
369
- $product->setId($esiData['product']) ;
370
- try {
371
- Mage::dispatchEvent('catalog_controller_product_view', array( 'product' => $product )) ;
372
- } catch ( Exception $e ) {
373
- if ( $this->_isDebug ) {
374
- $this->_config->debugMesg('_logData, exception for product ' . $product->getId() . ' : ' . $e->getMessage()) ;
375
- }
376
- }
377
- }
378
- }
379
-
380
- protected function _initUserParams( $action )
381
- {
382
- $this->_config = Mage::helper('litemage/data') ;
383
- $this->_isDebug = $this->_config->isDebug() ;
384
- if ( ! $this->_config->moduleEnabledForUser() ) {
385
- return false ;
386
- }
387
-
388
- $this->_helper = Mage::helper('litemage/esi') ;
389
-
390
-
391
- $origEsiUrl = $_SERVER['REQUEST_URI'] ;
392
- $req = $this->getRequest() ;
393
-
394
- //set original host url
395
- if ( $refererUrl = $req->getServer('ESI_REFERER') ) {
396
- $_SERVER['REQUEST_URI'] = $refererUrl ;
397
- $req->setRequestUri($refererUrl) ;
398
- $req->setPathInfo() ;
399
- }
400
- else {
401
- // illegal entrance, only allow from lsws
402
- if ( $this->_isDebug ) {
403
- $this->_config->debugMesg('Illegal Entrance') ;
404
- }
405
-
406
- return false ;
407
- }
408
-
409
- if ( $this->_isDebug )
410
- $this->_config->debugMesg('****** EsiController init url ' . $origEsiUrl) ;
411
-
412
-
413
- $this->setFlag('', Mage_Core_Controller_Varien_Action::FLAG_NO_START_SESSION, true); // only set here for postdispatch, do not set last viewed url
414
-
415
- $this->_env['update_cache'] = 0 ;
416
- $this->_esiData = array() ;
417
-
418
- if ( $action == 'getCombined' ) {
419
- if ( ! isset($_REQUEST['esi_include']) ) {
420
- if ( $this->_isDebug ) {
421
- $this->_config->debugMesg('Missing param esi_include') ;
422
- }
423
-
424
- return false ;
425
- }
426
-
427
- $esiIncludes = $_REQUEST['esi_include'] ;
428
- unset($_REQUEST['esi_include']) ;
429
-
430
- if ( $this->_isDebug ) {
431
- $this->_config->debugMesg('combined from ' . $refererUrl . ' includes = ' . print_r($esiIncludes, true)) ;
432
- }
433
-
434
- $this->_initEnv($req->getUserParams()) ;
435
- $res = $this->_parseEsiUrlList($esiIncludes, false) ;
436
- if ( ! $res )
437
- return false ;
438
- }
439
- else {
440
- if ( $param = $this->_parseUrlParams($origEsiUrl) ) {
441
- if ( $esiData = $this->_parseEsiData($param) ) {
442
- $this->_esiData[$esiData['id']] = $esiData ;
443
- }
444
- else {
445
- return false ;
446
- }
447
- }
448
- else {
449
- return false ;
450
- }
451
- }
452
- if ( isset($this->_env['fetch_all']) ) {
453
- $this->_fetchAll() ;
454
- }
455
- return true ;
456
- }
457
-
458
- protected function _fetchAll()
459
- {
460
- $extra = array() ;
461
-
462
- $session = Mage::getSingleton('core/session') ;
463
- $is_new_user = (($session->getData('_litemage_user') == null) && Mage::registry('LITEMAGE_NEWVISITOR') && (Mage::registry('current_customer') == null)) ;
464
- if ( $is_new_user ) {
465
- // new, return all blocks as non-logged in user first visit
466
- $session->setData('_litemage_user', 1) ;
467
- if ( method_exists($session, 'getFormKey') && ! isset($this->_esiData['getFormKey']) ) {
468
- $formkey_url = 'litemage/esi/getFormKey' ;
469
- $this->_esiData['getFormKey'] = $this->_getFormKeyEsiData($formkey_url) ;
470
- }
471
- foreach ( $this->_env['esiUrls'] as $blockname => $urls ) {
472
- foreach ( $urls as $url => $output ) {
473
- if ( $output == self::ESIDATA_CACHE_NOTSET ) {
474
- $this->_env['update_cache'] |= 2 ; // 2: full update, 1: update url only
475
- if ( ! isset($this->_esiData[$url]) ) {
476
- $extra[] = $url ;
477
- }
478
- }
479
- else {
480
- if ( isset($this->_esiData[$url]) ) {
481
- $this->_esiData[$url]['output'] = $output ;
482
- }
483
- else {
484
- $this->_esiData[$url] = array( 'output' => $output ) ;
485
- }
486
- }
487
- }
488
- }
489
- }
490
- else {
491
- // regenerate all blocks for that store
492
- foreach ( $this->_env['esiUrls'] as $blockname => $urls ) {
493
- foreach ( array_keys($urls) as $url ) {
494
- if ( ! isset($this->_esiData[$url]) ) {
495
- $extra[] = $url ;
496
- }
497
- }
498
- }
499
- }
500
-
501
- if ( count($extra) ) {
502
- $res = $this->_parseEsiUrlList($extra, true) ;
503
- }
504
-
505
- if ( $this->_isDebug ) {
506
- $this->_config->debugMesg(($is_new_user ? 'New user' : 'Existing user') . ' fetch extra = ' . count($extra)) ;
507
-
508
- //if ($this->_isDebug)
509
- //Mage::log('extra = ' . print_r($extra, true)) ;
510
- }
511
- }
512
-
513
- protected function _parseUrlParams( $esiUrl )
514
- {
515
- $esiUrl = urldecode($esiUrl) ;
516
- if ( ($pos = strpos($esiUrl, 'litemage/esi/')) !== false ) {
517
- $buf = explode('/', substr($esiUrl, $pos + 13)) ;
518
- $c = count($buf) ;
519
- $param = array() ;
520
- $param['action'] = $buf[0] ;
521
- $param['url'] = $esiUrl ;
522
- for ( $i = 1 ; ($i + 1) < $c ; $i+=2 ) {
523
- $param[$buf[$i]] = $buf[$i + 1] ;
524
- }
525
- return $param ;
526
- }
527
- else
528
- return null ;
529
- }
530
-
531
- protected function _parseEsiUrlList( $esiUrls, $ignoreErr = false )
532
- {
533
- $res = true ;
534
- foreach ( $esiUrls as $esiUrl ) {
535
-
536
- if ( $esiUrl == '*' ) {
537
- $this->_env['fetch_all'] = 1 ;
538
- continue ;
539
- }
540
- $param = $this->_parseUrlParams($esiUrl) ;
541
- if ( $param == null ) {
542
- $res = false ;
543
- if ( $ignoreErr )
544
- continue ;
545
- else
546
- break ;
547
- }
548
- if ( $esiData = $this->_parseEsiData($param) ) {
549
- $this->_esiData[$esiData['id']] = $esiData ;
550
- }
551
- else {
552
- $res = false ;
553
- if ( $ignoreErr ) {
554
- continue ;
555
- }
556
- else {
557
- break ;
558
- }
559
- }
560
- }
561
- return $res ;
562
- }
563
-
564
- protected function _getFormKeyEsiData( $url )
565
- {
566
- $session = Mage::getSingleton('core/session') ;
567
- $real_formkey = $session->getData(Litespeed_Litemage_Helper_Esi::FORMKEY_NAME) ;
568
- if ( ! $real_formkey ) {
569
- $real_formkey = $session->getFormKey() ;
570
- }
571
-
572
- $pri_ttl = isset($this->_env['pri_ttl']) ? $this->_env['pri_ttl'] : $this->_config->getConf(Litespeed_Litemage_Helper_Data::CFG_PRIVATETTL) ;
573
-
574
- return array( 'action' => 'getFormKey',
575
- 'cacheIfEmpty' => false,
576
- 'url' => $url,
577
- 'ttl' => $pri_ttl,
578
- 'tag' => 'E.formkey',
579
- 'access' => 'private',
580
- 'id' => 'getFormKey',
581
- 'raw_output' => $real_formkey ) ;
582
- }
583
-
584
- protected function _parseEsiData( $params )
585
- {
586
- $action = $params['action'] ;
587
- $url = $params['url'] ;
588
- if ( $action == 'getFormKey' ) {
589
- return $this->_getFormKeyEsiData($url) ;
590
- }
591
-
592
- $esiData = array( 'action' => $action, 'cacheIfEmpty' => false, 'url' => $url ) ;
593
-
594
- if ( $action == 'log' ) {
595
- if ( isset($params['product']) )
596
- $esiData['product'] = $params['product'] ;
597
- if ( isset($params['s']) && ! isset($this->_env['s']) )
598
- $this->_env['s'] = $params['s'] ;
599
- $esiData['ttl'] = 0 ; // no cache
600
- $esiData['id'] = $action ;
601
- }
602
- else {
603
-
604
- if ( ! isset($this->_env['dp']) ) {
605
- if ( ! $params['s'] || ! $params['dp'] || ! $params['dt'] ) {
606
- if ( $this->_isDebug ) {
607
- $this->_config->debugMesg('Missing param s_dp_dt') ;
608
- }
609
- return false ;
610
- }
611
-
612
- $this->_initEnv($params) ;
613
- }
614
-
615
- $tag = $params['t'] ;
616
- if ( $tag == null ) {
617
- if ( $this->_isDebug ) {
618
- $this->_config->debugMesg('Missing param t') ;
619
- }
620
- return false ;
621
- }
622
- else {
623
- $conf = $this->_config->getEsiConf('tag', $tag) ;
624
- if ($conf == null) {
625
- if ( $this->_isDebug ) {
626
- $this->_config->debugMesg('Missing config for tag '. $tag) ;
627
- }
628
- return false ;
629
- }
630
- }
631
-
632
- $esiData['b'] = explode(',', $params['b']) ;
633
- if (count($esiData['b']) == 0) {
634
- if ( $this->_isDebug ) {
635
- $this->_config->debugMesg('Missing param b') ;
636
- }
637
- return false ;
638
- }
639
- $blockName = $esiData['b'][0];
640
- $esiData['n'] = $blockName ;
641
- $esiData['h'] = isset($params['h']) ? explode(',', $params['h']) : array() ;
642
- $esiData['access'] = $conf['access'] ;
643
- $esiData['ttl'] = isset($conf['ttl']) ? $conf['ttl'] :
644
- (($conf['access'] == 'private') ? $this->_env['pri_ttl'] : $this->_env['pub_ttl'] ) ;
645
- $esiData['tag'] = $conf['cache-tag'] ;
646
- if (isset($params['a'])) {
647
- $esiData['alias'] = $params['a'];
648
- }
649
- if (isset($params['p'])) {
650
- $esiData['type'] = str_replace('--', '/', $params['p']); // dynamic block type
651
- if (isset($params['l']))
652
- $esiData['template'] = str_replace('--', '/', $params['l']);
653
- }
654
-
655
- if ( isset($params['st']) ) {
656
- $param1 = array( $params['st'], $params['call'] ) ; // session type and call func
657
- $param1 = str_replace('--', '/session', $param1) ;
658
- $param1 = str_replace('-', '/', $param1) ;
659
- $esiData['st'] = explode(',', $param1[0]) ;
660
- $esiData['call'] = $param1[1] ;
661
- $esiData['cacheIfEmpty'] = true ;
662
- }
663
- $esiData['id'] = $url ;
664
- if ( ($conf['access'] == 'private') && ($esiData['ttl'] > 0) ) {
665
- if ( ! isset($this->_env['esiUrls'][$blockName]) ) {
666
- $this->_env['esiUrls'][$blockName] = array( $url => self::ESIDATA_CACHE_NOTSET ) ;
667
- $this->_env['update_cache'] |= 1 ; // 2: full update, 1: update url only
668
- }
669
- elseif ( ! isset($this->_env['esiUrls'][$blockName][$url]) ) {
670
- $this->_env['esiUrls'][$blockName][$url] = self::ESIDATA_CACHE_NOTSET ;
671
- $this->_env['update_cache'] |= 1 ; // 2: full update, 1: update url only
672
- }
673
- }
674
- }
675
-
676
- return $esiData ;
677
- }
678
-
679
- protected function _initLayout()
680
- {
681
- $layout = $this->getLayout() ;
682
- $update = $layout->getUpdate() ;
683
-
684
- $update->setStoreId($this->_env['s']) ;
685
- // dispatch event for adding handles to layout update, this will auto add customer_logged_in or out
686
- Mage::dispatchEvent(
687
- 'controller_action_layout_load_before', array( 'action' => $this, 'layout' => $layout )
688
- ) ;
689
- $this->_env['defaultHandles'] = $update->getHandles() ;
690
- if ( (($this->_env['update_cache'] & 2) == 2) && in_array('customer_logged_in', $this->_env['defaultHandles']) ) {
691
- $this->_env['update_cache'] &= ~2 ; // 2: full update, 1: update url only
692
- //Mage::log('customer logged in, unset update_cahce 2 to 1 = ' . $this->_env['update_cache']);
693
- }
694
- }
695
-
696
- public function loadLayoutUpdates()
697
- {
698
- //$_profilerKey = self::PROFILER_KEY . '::' . $this->getFullActionName() . $this->_curData['n'] ;
699
-
700
- if ( ! isset($this->_env['defaultHandles']) ) {
701
- $this->_initLayout() ;
702
- }
703
-
704
- $this->_layout->resetBlocks() ;
705
- $update = $this->_layout->getUpdate() ;
706
- $update->setBlockNames($this->_curData['b']) ;
707
-
708
- $update->addHandle($this->_curData['h']) ;
709
- $update->addHandle($this->_env['defaultHandles']) ;
710
-
711
- // load layout updates by specified handles
712
- //Varien_Profiler::start("$_profilerKey::layout_load") ;
713
- $update->load() ;
714
- //Varien_Profiler::stop("$_profilerKey::layout_load") ;
715
-
716
- return $this ;
717
- }
718
-
719
- protected function _initEnv( $params )
720
- {
721
- if (isset($this->_env['cache_id']))
722
- return;
723
-
724
- $this->_env['s'] = $params['s'] ;
725
- $this->_env['dp'] = $params['dp'] ;
726
- $this->_env['dt'] = $params['dt'] ;
727
-
728
- $app = Mage::app() ;
729
- $app->setCurrentStore($app->getStore($this->_env['s'])) ;
730
- Mage::getSingleton('core/design_package')
731
- ->setPackageName($this->_env['dp'])
732
- ->setTheme($this->_env['dt']) ;
733
-
734
- $curLocale = $app->getLocale() ;
735
- $locale = Mage::getStoreConfig(Mage_Core_Model_Locale::XML_PATH_DEFAULT_LOCALE) ;
736
- if ( $curLocale->getLocaleCode() != $locale ) {
737
- $curLocale->setLocale($locale) ;
738
- $translator = $app->getTranslator() ;
739
- $translator->setLocale($locale) ;
740
- $translator->init('frontend') ;
741
- }
742
-
743
- $customer_session = Mage::getSingleton('customer/session') ;
744
- $customer_session->setNoReferer(true);
745
- if ( $customer_session->isLoggedIn() ) {
746
- Mage::register('current_customer', $customer_session->getCustomer()) ;
747
- }
748
-
749
- $tags = $this->_helper->getEsiSharedParams();
750
- $this->_env['cache_id'] = self::ESIDATA_CACHE_ID . '_' . md5(join('__', $tags)) ;
751
-
752
- $this->_env['esiUrls'] = array() ;
753
- if (Mage::app()->useCache('layout')) {
754
- if ( $data = Mage::app()->loadCache($this->_env['cache_id']) ) {
755
- $this->_env['esiUrls'] = unserialize($data) ;
756
- }
757
- }
758
-
759
- $this->_env['pri_ttl'] = $this->_config->getConf(Litespeed_Litemage_Helper_Data::CFG_PRIVATETTL) ;
760
- $this->_env['pub_ttl'] = $this->_config->getConf(Litespeed_Litemage_Helper_Data::CFG_PUBLICTTL) ;
761
- }
762
 
763
  }
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_EsiController extends Mage_Core_Controller_Front_Action
26
  {
27
 
28
+ const ESICACHE_ID = 'litemage_esi_data' ;
29
+ const ESICACHE_ENTRYONLY = '__' ;
30
+
31
+ protected $_processed = array() ;
32
+ protected $_scheduled = array() ;
33
+ protected $_esiCache ;
34
+ protected $_helper ;
35
+ protected $_config ;
36
+ protected $_isDebug ;
37
+ protected $_layout ;
38
+ protected $_env = array( 'shared' => false, 'fetch_all' => false ) ;
39
+
40
+ // defaultHandles, cache_id, cache_updated, layout_unique, translate_inline, inline_tag
41
+
42
+ protected function _construct()
43
+ {
44
+ $this->setFlag('', Mage_Core_Controller_Varien_Action::FLAG_NO_PRE_DISPATCH, true) ;
45
+ $this->setFlag('', Mage_Core_Controller_Varien_Action::FLAG_NO_POST_DISPATCH, true) ;
46
+ $this->setFlag('', Mage_Core_Controller_Varien_Action::FLAG_NO_START_SESSION, true) ; // postdispatch will not set last viewed url
47
+ $this->getFlag('', Mage_Core_Controller_Varien_Action::FLAG_NO_DISPATCH_BLOCK_EVENT, true) ;
48
+
49
+ $this->_config = Mage::helper('litemage/data') ;
50
+ if ( ! $this->_config->moduleEnabledForUser() ) {
51
+ Mage::throwException('LiteMage module not enabled for user') ;
52
+ }
53
+
54
+ $this->_isDebug = $this->_config->isDebug() ;
55
+ $this->_helper = Mage::helper('litemage/esi') ;
56
+ }
57
+
58
+ /**
59
+ * Retrieve current layout object
60
+ *
61
+ * @return Mage_Core_Model_Layout
62
+ */
63
+ public function getLayout()
64
+ {
65
+ if ( $this->_layout == null ) {
66
+ $this->_layout = Mage::getSingleton('litemage/esiLayout') ;
67
+ }
68
+ return $this->_layout ;
69
+ }
70
+
71
+ /**
72
+ * It seems this has to exist so we just make it redirect to the base URL
73
+ * for lack of anything better to do.
74
+ *
75
+ * @return null
76
+ */
77
+ public function indexAction()
78
+ {
79
+ Mage::log('Err: litemage come to indexaction') ;
80
+ $this->getResponse()->setRedirect(Mage::getBaseUrl()) ;
81
+ }
82
+
83
+ public function noRouteAction( $coreRoute = null )
84
+ {
85
+ //should not come here
86
+ $origEsiUrl = $_SERVER['REQUEST_URI'] ;
87
+ $esiData = new Litespeed_Litemage_Model_EsiData($origEsiUrl, $this->_config) ;
88
+ switch ( $esiData->getAction() ) {
89
+ case 'getCombined': $this->getCombinedAction() ;
90
+ break ;
91
+ case 'getFormKey': $this->getFormKeyAction() ;
92
+ break ;
93
+ case 'getBlock': $this->getBlockAction() ;
94
+ break ;
95
+ case 'getMessage': $this->getMessageAction() ;
96
+ break ;
97
+ case 'log': $this->logAction() ;
98
+ break ;
99
+ default: $this->_errorExit() ;
100
+ }
101
+ }
102
+
103
+ protected function _errorExit()
104
+ {
105
+ $resp = $this->getResponse() ;
106
+ $resp->setHttpResponseCode(500) ;
107
+ $resp->setBody('<!-- ESI data is not valid -->') ;
108
+ }
109
+
110
+ public function getFormKeyAction()
111
+ {
112
+ $this->_getSingle() ;
113
+ }
114
+
115
+ public function logAction()
116
+ {
117
+ $this->_getSingle() ;
118
+ }
119
+
120
+ public function getMessageAction()
121
+ {
122
+ $this->_getSingle() ;
123
+ }
124
+
125
+ public function getBlockAction()
126
+ {
127
+ $this->_getSingle() ;
128
+ }
129
+
130
+ protected function _getSingle()
131
+ {
132
+ $esiUrl = $this->_setOriginalReq() ;
133
+ $esiData = new Litespeed_Litemage_Model_EsiData($esiUrl, $this->_config) ;
134
+
135
+ if ( $this->_isDebug ) {
136
+ $this->_config->debugMesg('****** EsiController process ' . $esiData->getAction()) ;
137
+ }
138
+ $this->_initEnv($esiData) ;
139
+ $this->_scheduleProcess($esiData) ;
140
+ $this->_processScheduled() ;
141
+
142
+ $this->_sendProcessed($esiData) ;
143
+ }
144
+
145
+ public function getCombinedAction()
146
+ {
147
+ $esiUrl = $this->_setOriginalReq() ;
148
+ $esiData = new Litespeed_Litemage_Model_EsiData($esiUrl, $this->_config) ;
149
+ $this->_initEnv($esiData) ;
150
+
151
+ $esiIncludes = $_REQUEST['esi_include'] ;
152
+
153
+ if ( $this->_isDebug ) {
154
+ $this->_config->debugMesg('combined includes = ' . print_r($esiIncludes, true)) ;
155
+ }
156
+
157
+ if ( ($key = array_search('*', $esiIncludes)) !== false ) {
158
+ $this->_env['fetch_all'] = true ;
159
+ unset($esiIncludes[$key]) ;
160
+ // need to add getformkey
161
+ $esiIncludes = array_unique(array_merge($esiIncludes, array_keys($this->_esiCache))) ;
162
+ }
163
+
164
+ //add raw header here, to handle ajax exception
165
+ header(Litespeed_Litemage_Helper_Esi::LSHEADER_CACHE_CONTROL . ': esi=on', true) ;
166
+ $this->_helper->setCacheControlFlag(Litespeed_Litemage_Helper_Esi::CHBM_ESI_ON | Litespeed_Litemage_Helper_Esi::CHBM_ESI_REQ) ;
167
+
168
+ $this->_processIncoming($esiIncludes) ;
169
+
170
+ $this->_processScheduled() ;
171
+
172
+ $this->_sendProcessedInline() ;
173
+ }
174
+
175
+ protected function _renderEsiBlock( $esiData )
176
+ {
177
+ $blockIndex = $esiData->getLayoutAttribute('bi') ;
178
+ $block = $this->_layout->getEsiBlock($blockIndex) ;
179
+ if ( ! $block ) {
180
+ if ( $this->_isDebug ) {
181
+ $this->_config->debugMesg('cannot get esi block ' . $blockIndex) ;
182
+ }
183
+ return '' ;
184
+ }
185
+ try {
186
+ $out = $block->toHtml() ;
187
+ if ( $this->_env['translate_inline'] ) {
188
+ Mage::getSingleton('core/translate_inline')->processResponseBody($out) ;
189
+ }
190
+ } catch ( Exception $e ) {
191
+ if ( $this->_isDebug ) {
192
+ $this->_config->debugMesg('_renderEsiBlock, exception for block ' . $blockIndex . ' : ' . $e->getMessage()) ;
193
+ }
194
+ }
195
+
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
+ {
238
+ $origEsiUrl = $_SERVER['REQUEST_URI'] ;
239
+ $req = $this->getRequest() ;
240
+
241
+ //set original host url
242
+ if ( $refererUrl = $req->getServer('ESI_REFERER') ) {
243
+ $_SERVER['REQUEST_URI'] = $refererUrl ;
244
+ $req->setRequestUri($refererUrl) ;
245
+ $req->setPathInfo() ;
246
+ if ( $this->_isDebug ) {
247
+ $this->_config->debugMesg('****** EsiController process ' . $origEsiUrl . ' referral ' . $refererUrl) ;
248
+ }
249
+ }
250
+ else {
251
+ Mage::throwException('Illegal entrance for LiteMage module') ;
252
+ }
253
+ return $origEsiUrl ;
254
+ }
255
+
256
+ protected function _parseUrlParams( $esiUrl )
257
+ {
258
+ $esiUrl = urldecode($esiUrl) ;
259
+ $pos = strpos($esiUrl, 'litemage/esi/') ;
260
+ if ( $pos === false ) {
261
+ Mage::throwException('LiteMage module invalid esi data ' . $esiUrl) ;
262
+ }
263
+ $buf = explode('/', substr($esiUrl, $pos + 13)) ;
264
+ $c = count($buf) ;
265
+ $param = array() ;
266
+ $param['action'] = $buf[0] ;
267
+ $param['url'] = $esiUrl ;
268
+ for ( $i = 1 ; ($i + 1) < $c ; $i+=2 ) {
269
+ $param[$buf[$i]] = $buf[$i + 1] ;
270
+ }
271
+ return $param ;
272
+ }
273
+
274
+ protected function _processIncoming( $esiUrls )
275
+ {
276
+ if ( (Mage::getSingleton('core/session')->getData('_litemage_user') == null) && Mage::registry('LITEMAGE_NEWVISITOR') && (Mage::registry('current_customer') == null) ) {
277
+
278
+ $this->_env['shared'] = true ;
279
+
280
+ $list = array() ;
281
+ foreach ( $esiUrls as $url ) {
282
+ if ( $html = $this->_getShared($url) ) {
283
+ $this->_processed[$url] = $html ;
284
+ }
285
+ else {
286
+ $list[] = $url ;
287
+ }
288
+ }
289
+ }
290
+ else {
291
+ $list = $esiUrls ;
292
+ }
293
+ $this->_env['inline_tag'] = $this->_config->esiTag('inline') ;
294
+
295
+ foreach ( $list as $esiUrl ) {
296
+ $esiData = new Litespeed_Litemage_Model_EsiData($esiUrl, $this->_config) ;
297
+ $this->_scheduleProcess($esiData) ;
298
+ }
299
+ }
300
+
301
+ protected function _scheduleProcess( $esiData )
302
+ {
303
+ $batchId = $esiData->getBatchId() ;
304
+ if ( $batchId != Litespeed_Litemage_Model_EsiData::BATCH_DIRECT ) {
305
+ $batchId = $esiData->initLayoutCache($this->_env['layout_unique']) ;
306
+ }
307
+ if ( ! isset($this->_scheduled[$batchId]) ) {
308
+ $this->_scheduled[$batchId] = array() ;
309
+ }
310
+ $this->_scheduled[$batchId][$esiData->getUrl()] = $esiData ;
311
+ }
312
+
313
+ protected function _sendProcessed( $esiData )
314
+ {
315
+ $flag = Litespeed_Litemage_Helper_Esi::CHBM_ESI_REQ ;
316
+ $tag = '' ;
317
+
318
+ $attr = $esiData->getCacheAttribute() ;
319
+ if ( $attr['ttl'] > 0 ) {
320
+ $flag |= Litespeed_Litemage_Helper_Esi::CHBM_CACHEABLE ;
321
+ if ( $attr['access'] == 'private' )
322
+ $flag |= Litespeed_Litemage_Helper_Esi::CHBM_PRIVATE ;
323
+ if ( $attr['cacheIfEmpty'] )
324
+ $flag |= Litespeed_Litemage_Helper_Esi::CHBM_ONLY_CACHE_EMPTY ;
325
+ $tag = $attr['tag'] ;
326
+ }
327
+ $this->_helper->setCacheControlFlag($flag, $attr['ttl'], $tag) ;
328
+
329
+
330
+ $this->getResponse()->setBody($esiData->getRawOutput()) ;
331
+ }
332
+
333
+ protected function _sendProcessedInline()
334
+ {
335
+ $body = '' ;
336
+ $esiInlineTag = $this->_env['inline_tag'] ;
337
+ $shared = $this->_env['shared'] ;
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
+
376
+ protected function _processScheduled()
377
+ {
378
+ $this->_env['translate_inline'] = Mage::getSingleton('core/translate_inline')->isAllowed() ;
379
+
380
+ foreach ( $this->_scheduled as $batchId => $urllist ) {
381
+ if ( $batchId == Litespeed_Litemage_Model_EsiData::BATCH_DIRECT ) {
382
+ $this->_processDirect($urllist) ;
383
+ }
384
+ elseif ( $batchId == Litespeed_Litemage_Model_EsiData::BATCH_LAYOUT_READY ) {
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
+ }
396
+ }
397
+ }
398
+
399
+ protected function _saveEsiXml( $urllist )
400
+ {
401
+ foreach ( $urllist as $url => $esiData ) {
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 {
409
+ if ( $this->_isDebug ) {
410
+ $this->_config->debugMesg('cannot get esi block ' . $bi) ;
411
+ }
412
+ }
413
+ }
414
+
415
+ }
416
+
417
+ protected function _processLayout($urllist)
418
+ {
419
+ $response = $this->getResponse() ;
420
+ foreach ( $urllist as $url => $esiData ) {
421
+ $this->_layout->loadEsiLayout($esiData) ;
422
+ $output = $this->_renderEsiBlock($esiData, false) ;
423
+ $esiData->setRawOutput($output, $response->getHttpResponseCode()) ;
424
+ $this->_processed[$url] = $esiData ;
425
+ }
426
+
427
+ }
428
+
429
+ protected function _processDirect( $urllist )
430
+ {
431
+ foreach ( $urllist as $url => $esiData ) {
432
+ switch ( $esiData->getAction() ) {
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 ;
439
+ case Litespeed_Litemage_Model_EsiData::ACTION_GET_MESSAGE:
440
+ $this->_procDirectMessage($esiData) ;
441
+ break ;
442
+ case Litespeed_Litemage_Model_EsiData::ACTION_GET_BLOCK ;
443
+ $this->_procDirectBlock($esiData) ;
444
+ break ;
445
+ default:
446
+ // error out
447
+ }
448
+ $this->_processed[$url] = $esiData ;
449
+ }
450
+ }
451
+
452
+ protected function _procDirectFormKey( $esiData )
453
+ {
454
+ $session = Mage::getSingleton('core/session') ;
455
+ $real_formkey = $session->getData(Litespeed_Litemage_Helper_Esi::FORMKEY_NAME) ;
456
+ if ( ! $real_formkey ) {
457
+ $real_formkey = $session->getFormKey() ;
458
+ }
459
+
460
+ $esiData->setRawOutput($real_formkey) ;
461
+ }
462
+
463
+ protected function _procDirectLog( $esiData )
464
+ {
465
+ $data = $esiData->getData() ;
466
+ $product = new Varien_Object() ;
467
+ $product->setId($data['product']) ;
468
+
469
+ $responseCode = 200 ;
470
+ try {
471
+ Mage::dispatchEvent('catalog_controller_product_view', array( 'product' => $product )) ;
472
+ } catch ( Exception $e ) {
473
+ $responseCode = 500 ;
474
+ if ( $this->_isDebug ) {
475
+ $this->_config->debugMesg('_logData, exception for product ' . $product->getId() . ' : ' . $e->getMessage()) ;
476
+ }
477
+ }
478
+ $esiData->setRawOutput('', $responseCode) ;
479
+ }
480
+
481
+ protected function _procDirectMessage( $esiData )
482
+ {
483
+ $newMessages = new Litespeed_Litemage_Block_Core_Messages() ;
484
+ $out = $newMessages->getEsiOutput($esiData) ;
485
+ if ( $this->_env['translate_inline'] ) {
486
+ Mage::getSingleton('core/translate_inline')->processResponseBody($out) ;
487
+ }
488
+ $esiData->setRawOutput($out) ;
489
+ }
490
+
491
+ protected function _procDirectBlock( $esiData )
492
+ {
493
+ $data = $esiData->getData() ;
494
+ $block = new $data['pc']() ;
495
+ if ( isset($data['pt']) ) {
496
+ $block->setTemplate($data['pt']) ;
497
+ $out = $block->renderView() ;
498
+ }
499
+ else {
500
+ $out = $block->toHtml() ;
501
+ }
502
+ if ( $this->_env['translate_inline'] ) {
503
+ Mage::getSingleton('core/translate_inline')->processResponseBody($out) ;
504
+ }
505
+ $esiData->setRawOutput($out) ;
506
+ }
507
+
508
+ protected function _initEnv( $esiData )
509
+ {
510
+ $action = $esiData->getAction() ;
511
+ if ( $action == Litespeed_Litemage_Model_EsiData::ACTION_GET_FORMKEY ) {
512
+ return ;
513
+ }
514
+
515
+ $d = $esiData->getData() ;
516
+
517
+ $app = Mage::app() ;
518
+ $app->setCurrentStore($app->getStore($d['s'])) ;
519
+
520
+ if ( $action == Litespeed_Litemage_Model_EsiData::ACTION_LOG ) {
521
+ return ; // only need to set store
522
+ }
523
+
524
+ Mage::getSingleton('core/design_package')->setPackageName($d['dp'])->setTheme($d['dt']) ;
525
+
526
+ $curLocale = $app->getLocale() ;
527
+ $locale = Mage::getStoreConfig(Mage_Core_Model_Locale::XML_PATH_DEFAULT_LOCALE) ;
528
+ if ( $curLocale->getLocaleCode() != $locale ) {
529
+ $curLocale->setLocale($locale) ;
530
+ $translator = $app->getTranslator() ;
531
+ $translator->setLocale($locale) ;
532
+ $translator->init('frontend') ;
533
+ }
534
+
535
+ $customer_session = Mage::getSingleton('customer/session') ;
536
+ $customer_session->setNoReferer(true) ;
537
+ if ( $customer_session->isLoggedIn() ) {
538
+ Mage::register('current_customer', $customer_session->getCustomer()) ;
539
+ $this->_env['defaultHandles'] = array( 'customer_logged_in' ) ;
540
+ }
541
+ else {
542
+ $this->_env['defaultHandles'] = array( 'customer_logged_out' ) ;
543
+ }
544
+
545
+ $unique = join('__', $this->_helper->getEsiSharedParams()) ;
546
+
547
+ $this->_env['cache_id'] = self::ESICACHE_ID . '_' . md5($unique) ;
548
+ $this->_env['cache_updated'] = false ;
549
+ $this->_env['layout_unique'] = $unique . '__' . $this->_env['defaultHandles'][0] ;
550
+
551
+ $this->_esiCache = array() ;
552
+ if ( Mage::app()->useCache('layout') ) {
553
+ if ( $data = Mage::app()->loadCache($this->_env['cache_id']) ) {
554
+ $this->_esiCache = unserialize($data) ;
555
+ }
556
+ }
557
+
558
+ $this->_layout->getUpdate()->setCachePrefix($unique) ;
559
+ }
560
+
561
+ protected function _getShared( $url )
562
+ {
563
+ if ( ! empty($this->_esiCache[$url]) && ($this->_esiCache[$url] != self::ESICACHE_ENTRYONLY) ) {
564
+ return $this->_esiCache[$url] ;
565
+ }
566
+ return null ;
567
+ }
568
+
569
+ // return -1: no cache, 0: no update, 1: update entry, 2: update detail
570
+ protected function _refreshCacheEntry( $url, $esiData, &$inlineHtml )
571
+ {
572
+ $cacheAttr = $esiData->getCacheAttribute() ;
573
+ if ( ($cacheAttr['access'] != 'private') || ($cacheAttr['ttl'] == 0) ) {
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
+ }
583
+ return 0 ;
584
+ }
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
+ }
596
+
597
+ $html = $this->_esiCache[$url] ;
598
+ if ( $html != '' && $html != self::ESICACHE_ENTRYONLY ) {
599
+ // check if same as shared
600
+ $raw = '">' . $esiData->getRawOutput() . '</' . $this->_env['inline_tag'] . '>' ;
601
+ if ( strpos($html, $raw) ) {
602
+ $inlineHtml = $html ; // replace with shared attribute
603
+ return 3 ;
604
+ }
605
+ }
606
+ return 0 ;
607
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
608
 
609
  }
app/code/community/Litespeed/Litemage/etc/config.xml CHANGED
@@ -26,7 +26,7 @@
26
  <config>
27
  <modules>
28
  <Litespeed_Litemage>
29
- <version>1.0.18</version>
30
  </Litespeed_Litemage>
31
  </modules>
32
  <global>
@@ -47,6 +47,7 @@
47
  <core>
48
  <rewrite>
49
  <translate>Litespeed_Litemage_Model_Translate</translate>
 
50
  </rewrite>
51
  </core>
52
  </models>
@@ -204,7 +205,7 @@
204
  <observers>
205
  <litemage_esi>
206
  <class>litemage/observer_esi</class>
207
- <method>checkControllerNoCache</method>
208
  </litemage_esi>
209
  </observers>
210
  </controller_action_predispatch>
@@ -244,7 +245,7 @@
244
  <observers>
245
  <litemage_esi>
246
  <class>litemage/observer_esi</class>
247
- <method>purgePrivateCache</method>
248
  </litemage_esi>
249
  </observers>
250
  </customer_login>
@@ -252,7 +253,7 @@
252
  <observers>
253
  <litemage_esi>
254
  <class>litemage/observer_esi</class>
255
- <method>purgePrivateCache</method>
256
  </litemage_esi>
257
  </observers>
258
  </customer_logout>
@@ -449,6 +450,7 @@
449
  <admin_ips>127.0.0.1</admin_ips>
450
  <public_ttl>28800</public_ttl>
451
  <private_ttl>1800</private_ttl>
 
452
  <track_viewed>0</track_viewed>
453
  <diff_customergroup>0</diff_customergroup>
454
  <diff_cookie/>
26
  <config>
27
  <modules>
28
  <Litespeed_Litemage>
29
+ <version>1.1.0</version>
30
  </Litespeed_Litemage>
31
  </modules>
32
  <global>
47
  <core>
48
  <rewrite>
49
  <translate>Litespeed_Litemage_Model_Translate</translate>
50
+ <layout_update>Litespeed_Litemage_Model_Layout_Update</layout_update>
51
  </rewrite>
52
  </core>
53
  </models>
205
  <observers>
206
  <litemage_esi>
207
  <class>litemage/observer_esi</class>
208
+ <method>predispatchCheckControllerNoCache</method>
209
  </litemage_esi>
210
  </observers>
211
  </controller_action_predispatch>
245
  <observers>
246
  <litemage_esi>
247
  <class>litemage/observer_esi</class>
248
+ <method>purgeUserPrivateCache</method>
249
  </litemage_esi>
250
  </observers>
251
  </customer_login>
253
  <observers>
254
  <litemage_esi>
255
  <class>litemage/observer_esi</class>
256
+ <method>purgeUserPrivateCache</method>
257
  </litemage_esi>
258
  </observers>
259
  </customer_logout>
450
  <admin_ips>127.0.0.1</admin_ips>
451
  <public_ttl>28800</public_ttl>
452
  <private_ttl>1800</private_ttl>
453
+ <home_ttl>28800</home_ttl>
454
  <track_viewed>0</track_viewed>
455
  <diff_customergroup>0</diff_customergroup>
456
  <diff_cookie/>
app/code/community/Litespeed/Litemage/etc/config.xml.dev DELETED
@@ -1,506 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
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) 2015-2016 LiteSpeed Technologies, Inc. (https://www.litespeedtech.com)
23
- * @license https://opensource.org/licenses/GPL-3.0
24
- */
25
- -->
26
- <config>
27
- <modules>
28
- <Litespeed_Litemage>
29
- <version>1.0.17</version>
30
- </Litespeed_Litemage>
31
- </modules>
32
- <global>
33
- <blocks>
34
- <litemage>
35
- <class>Litespeed_Litemage_Block</class>
36
- </litemage>
37
- </blocks>
38
- <helpers>
39
- <litemage>
40
- <class>Litespeed_Litemage_Helper</class>
41
- </litemage>
42
- </helpers>
43
- <models>
44
- <litemage>
45
- <class>Litespeed_Litemage_Model</class>
46
- </litemage>
47
- <core>
48
- <rewrite>
49
- <translate>Litespeed_Litemage_Model_Translate</translate>
50
- </rewrite>
51
- </core>
52
- </models>
53
- <events>
54
- <!-- purge product cache after stock update -->
55
- <cataloginventory_stock_item_save_after>
56
- <observers>
57
- <litemage_purge>
58
- <class>litemage/observer_purge</class>
59
- <method>purgeCatalogProductByStock</method>
60
- </litemage_purge>
61
- </observers>
62
- </cataloginventory_stock_item_save_after>
63
- </events>
64
- </global>
65
- <admin>
66
- <routers>
67
- <adminhtml>
68
- <args>
69
- <modules>
70
- <litemage after="Mage_Adminhtml">Litespeed_Litemage_Adminhtml</litemage>
71
- </modules>
72
- </args>
73
- </adminhtml>
74
- </routers>
75
- </admin>
76
- <adminhtml>
77
- <layout>
78
- <updates>
79
- <litemage>
80
- <file>litemage.xml</file>
81
- </litemage>
82
- </updates>
83
- </layout>
84
- <acl>
85
- <resources>
86
- <admin>
87
- <children>
88
- <system>
89
- <children>
90
- <cache>
91
- <children>
92
- <litemage>
93
- <title>LiteMage Cache Management</title>
94
- </litemage>
95
- </children>
96
- </cache>
97
- <config>
98
- <children>
99
- <litemage>
100
- <title>LiteMage Cache Configuration</title>
101
- </litemage>
102
- </children>
103
- </config>
104
- </children>
105
- </system>
106
- </children>
107
- </admin>
108
- </resources>
109
- </acl>
110
- <events>
111
- <controller_action_postdispatch_adminhtml_cache_flushAll>
112
- <observers>
113
- <litemage_purge>
114
- <type>singleton</type>
115
- <class>litemage/observer_purge</class>
116
- <method>adminPurgeCache</method>
117
- </litemage_purge>
118
- </observers>
119
- </controller_action_postdispatch_adminhtml_cache_flushAll>
120
- <controller_action_postdispatch_adminhtml_cache_flushSystem>
121
- <observers>
122
- <litemage_purge>
123
- <type>singleton</type>
124
- <class>litemage/observer_purge</class>
125
- <method>adminPurgeCache</method>
126
- </litemage_purge>
127
- </observers>
128
- </controller_action_postdispatch_adminhtml_cache_flushSystem>
129
- <controller_action_postdispatch_adminhtml_system_currency_saveRates>
130
- <observers>
131
- <litemage_purge>
132
- <type>singleton</type>
133
- <class>litemage/observer_purge</class>
134
- <method>adminPurgeCurrency</method>
135
- </litemage_purge>
136
- </observers>
137
- </controller_action_postdispatch_adminhtml_system_currency_saveRates>
138
- <!-- purge category cache after save -->
139
- <catalog_category_save_commit_after>
140
- <observers>
141
- <litemage_purge>
142
- <class>litemage/observer_purge</class>
143
- <method>adminPurgeCatalogCategory</method>
144
- </litemage_purge>
145
- </observers>
146
- </catalog_category_save_commit_after>
147
- <!-- purge product cache after save -->
148
- <catalog_product_save_commit_after>
149
- <observers>
150
- <litemage_purge>
151
- <class>litemage/observer_purge</class>
152
- <method>adminPurgeCatalogProduct</method>
153
- </litemage_purge>
154
- </observers>
155
- </catalog_product_save_commit_after>
156
- <!-- purge cms page cache after save -->
157
- <cms_page_save_commit_after>
158
- <observers>
159
- <litemage_purge>
160
- <class>litemage/observer_purge</class>
161
- <method>adminPurgeCmsPage</method>
162
- </litemage_purge>
163
- </observers>
164
- </cms_page_save_commit_after>
165
- <!-- purge all caches when module disabled -->
166
- <admin_system_config_changed_section_litemage>
167
- <observers>
168
- <litemage_purge>
169
- <class>litemage/observer_purge</class>
170
- <method>adminConfigChangedSection</method>
171
- </litemage_purge>
172
- </observers>
173
- </admin_system_config_changed_section_litemage>
174
- <!-- displays warning if license not enabled -->
175
- <controller_action_predispatch_adminhtml_system_config_edit>
176
- <observers>
177
- <litemage_purge>
178
- <class>litemage/observer_purge</class>
179
- <method>adminConfigEditSection</method>
180
- </litemage_purge>
181
- </observers>
182
- </controller_action_predispatch_adminhtml_system_config_edit>
183
- </events>
184
- </adminhtml>
185
- <frontend>
186
- <routers>
187
- <litemage>
188
- <use>standard</use>
189
- <args>
190
- <module>Litespeed_Litemage</module>
191
- <frontName>litemage</frontName>
192
- </args>
193
- </litemage>
194
- </routers>
195
- <layout>
196
- <updates>
197
- <litemage>
198
- <file>litemage.xml</file>
199
- </litemage>
200
- </updates>
201
- </layout>
202
- <events>
203
- <controller_action_predispatch>
204
- <observers>
205
- <litemage_esi>
206
- <class>litemage/observer_esi</class>
207
- <method>checkControllerNoCache</method>
208
- </litemage_esi>
209
- </observers>
210
- </controller_action_predispatch>
211
- <visitor_init>
212
- <observers>
213
- <litemage_esi>
214
- <class>litemage/observer_esi</class>
215
- <method>initNewVisitor</method>
216
- </litemage_esi>
217
- </observers>
218
- </visitor_init>
219
- <core_layout_block_create_after>
220
- <observers>
221
- <litemage_esi>
222
- <class>litemage/observer_esi</class>
223
- <method>checkEsiBlock</method>
224
- </litemage_esi>
225
- </observers>
226
- </core_layout_block_create_after>
227
- <controller_action_layout_generate_blocks_after>
228
- <observers>
229
- <litemage_esi>
230
- <class>litemage/observer_esi</class>
231
- <method>prepareInjection</method>
232
- </litemage_esi>
233
- </observers>
234
- </controller_action_layout_generate_blocks_after>
235
- <http_response_send_before>
236
- <observers>
237
- <litemage_esi>
238
- <class>litemage/observer_esi</class>
239
- <method>beforeResponseSend</method>
240
- </litemage_esi>
241
- </observers>
242
- </http_response_send_before>
243
- <customer_login>
244
- <observers>
245
- <litemage_esi>
246
- <class>litemage/observer_esi</class>
247
- <method>purgePrivateCache</method>
248
- </litemage_esi>
249
- </observers>
250
- </customer_login>
251
- <customer_logout>
252
- <observers>
253
- <litemage_esi>
254
- <class>litemage/observer_esi</class>
255
- <method>purgePrivateCache</method>
256
- </litemage_esi>
257
- </observers>
258
- </customer_logout>
259
- <sales_quote_save_after>
260
- <observers>
261
- <litemage_esi>
262
- <class>litemage/observer_esi</class>
263
- <method>purgeEsiCache</method>
264
- </litemage_esi>
265
- </observers>
266
- </sales_quote_save_after>
267
- <wishlist_item_save_after>
268
- <observers>
269
- <litemage_esi>
270
- <class>litemage/observer_esi</class>
271
- <method>purgeEsiCache</method>
272
- </litemage_esi>
273
- </observers>
274
- </wishlist_item_save_after>
275
- <wishlist_item_delete_after>
276
- <observers>
277
- <litemage_esi>
278
- <class>litemage/observer_esi</class>
279
- <method>purgeEsiCache</method>
280
- </litemage_esi>
281
- </observers>
282
- </wishlist_item_delete_after>
283
- <catalog_product_compare_add_product>
284
- <observers>
285
- <litemage_esi>
286
- <class>litemage/observer_esi</class>
287
- <method>purgeEsiCache</method>
288
- </litemage_esi>
289
- </observers>
290
- </catalog_product_compare_add_product>
291
- <catalog_product_compare_remove_product>
292
- <observers>
293
- <litemage_esi>
294
- <class>litemage/observer_esi</class>
295
- <method>purgeEsiCache</method>
296
- </litemage_esi>
297
- </observers>
298
- </catalog_product_compare_remove_product>
299
- <catalog_product_compare_item_collection_clear>
300
- <observers>
301
- <litemage_esi>
302
- <class>litemage/observer_esi</class>
303
- <method>purgeEsiCache</method>
304
- </litemage_esi>
305
- </observers>
306
- </catalog_product_compare_item_collection_clear>
307
- <catalog_controller_product_view>
308
- <observers>
309
- <litemage_esi>
310
- <class>litemage/observer_esi</class>
311
- <method>onCatalogProductView</method>
312
- </litemage_esi>
313
- </observers>
314
- </catalog_controller_product_view>
315
- <cms_page_render>
316
- <observers>
317
- <litemage_esi>
318
- <class>litemage/observer_esi</class>
319
- <method>onCmsPageRender</method>
320
- </litemage_esi>
321
- </observers>
322
- </cms_page_render>
323
- <poll_vote_add>
324
- <observers>
325
- <litemage_esi>
326
- <class>litemage/observer_esi</class>
327
- <method>purgeEsiCache</method>
328
- </litemage_esi>
329
- </observers>
330
- </poll_vote_add>
331
- <core_session_abstract_add_message>
332
- <observers>
333
- <litemage_esi>
334
- <class>litemage/observer_esi</class>
335
- <method>purgeEsiCache</method>
336
- </litemage_esi>
337
- </observers>
338
- </core_session_abstract_add_message>
339
- <checkout_onepage_controller_success_action>
340
- <observers>
341
- <litemage_esi>
342
- <class>litemage/observer_esi</class>
343
- <method>purgeEsiCache</method>
344
- </litemage_esi>
345
- </observers>
346
- </checkout_onepage_controller_success_action>
347
- </events>
348
- <litemage>
349
- <esiblock>
350
- <!-- If you need to inject any other privately cached custom block groupings,
351
- you can add them here. <blocks> contains the block names defined in your
352
- layout files. All blocks that share the same purge events can be listed
353
- together in a single grouping. If their purge events are not being watched
354
- in the previous events section, you will also need to add a litemage esi
355
- observer for those events.
356
-
357
- This config file will be overwritten with upgrades to the LiteMage module.
358
- If you have made any modifications, please make sure to keep a copy -->
359
- <welcome>
360
- <!-- blocks only purged by login/logout events, no purge_events configuration is required as login/logout will auto purge all private blocks -->
361
- <access>private</access>
362
- <blocks>T:Mage_Page_Block_Html_Welcome,welcome,litemage.jsvar,nickname$v</blocks>
363
- <!-- Marking a block as valueonly, denoted by the suffix “$v”, will only output
364
- the blocks html value without the added html tags and comments when in debug mode.
365
- The block will also not be highlighted when using the LITEMAGE_DEBUG=SHOWHOLES parameter -->
366
- </welcome>
367
- <cart>
368
- <access>private</access>
369
- <!-- Blocks can be set using class type, denoted by the prefix "T:". This will include all blocks that inherit this type in the grouping -->
370
- <blocks>T:Mage_Checkout_Block_Cart_Abstract</blocks>
371
- <purge_events>
372
- <sales_quote_save_after/>
373
- </purge_events>
374
- </cart>
375
- <toplinks>
376
- <access>private</access>
377
- <blocks>top.links</blocks>
378
- <purge_tags>cart, wishlist</purge_tags>
379
- <!-- This is a composite grouping. The purge events for the blocks in this grouping are
380
- a combination of existing purge event sets from other groupings. By using purge_tags
381
- to reference these other groupings, you do not need to redefine these purge events. -->
382
- </toplinks>
383
- <compare>
384
- <access>private</access>
385
- <blocks>T:Mage_Catalog_Block_Product_Compare_Sidebar, T:Mage_Reports_Block_Product_Compared</blocks>
386
- <purge_events>
387
- <catalog_product_compare_add_product/>
388
- <catalog_product_compare_remove_product/>
389
- <catalog_product_compare_item_collection_clear/>
390
- </purge_events>
391
- </compare>
392
- <viewed>
393
- <access>private</access>
394
- <blocks>T:Mage_Reports_Block_Product_Viewed</blocks>
395
- <purge_events>
396
- <catalog_controller_product_view/>
397
- </purge_events>
398
- </viewed>
399
- <poll>
400
- <access>private</access>
401
- <blocks>T:Mage_Poll_Block_ActivePoll</blocks>
402
- <purge_events>
403
- <poll_vote_add/>
404
- </purge_events>
405
- </poll>
406
- <!-- messages is specially handled, cannot change the tag name here, has to be "messages" -->
407
- <messages>
408
- <access>private</access>
409
- <blocks>T:Mage_Core_Block_Messages</blocks>
410
- <purge_events>
411
- <core_session_abstract_add_message/>
412
- </purge_events>
413
- </messages>
414
- <!-- Blocks only visible when logged in -->
415
- <reorder>
416
- <access>private</access>
417
- <blocks>T:Mage_Sales_Block_Reorder_Sidebar</blocks>
418
- <purge_events>
419
- <sales_quote_save_after/>
420
- <checkout_onepage_controller_success_action/>
421
- </purge_events>
422
- </reorder>
423
- <wishlist>
424
- <access>private</access>
425
- <blocks>T:Mage_Wishlist_Block_Customer_Sidebar</blocks>
426
- <purge_events>
427
- <wishlist_item_save_after/>
428
- <wishlist_item_delete_after/>
429
- </purge_events>
430
- </wishlist>
431
- <!-- public blocks -->
432
- <!-- Some themes will use a variable in footer that is declared in the header,
433
- this causes the footer block to fail to generate. You can modify the
434
- template to generate the missing variable or simply choose to not punch
435
- a hole in footer (comment out the footer block).
436
-
437
- Making the footer a public block will speed up page generation and save some disk space -->
438
- <footer>
439
- <access>public</access>
440
- <blocks>footer</blocks>
441
- </footer>
442
- </esiblock>
443
- </litemage>
444
- </frontend>
445
- <default>
446
- <litemage>
447
- <general>
448
- <enabled>1</enabled>
449
- <admin_ips>127.0.0.1</admin_ips>
450
- <public_ttl>28800</public_ttl>
451
- <private_ttl>3600</private_ttl>
452
- <track_viewed>1</track_viewed>
453
- <diff_customergroup>0</diff_customergroup>
454
- <diff_cookie/>
455
- <alt_esi_syntax>0</alt_esi_syntax>
456
- </general>
457
- <warmup>
458
- <enable_warmup>1</enable_warmup>
459
- <load_limit>5</load_limit>
460
- <thread_limit>6</thread_limit>
461
- <max_time>360</max_time>
462
- <interval>21600</interval>
463
- <priority>100</priority>
464
- <multi_currency/>
465
- <custlist/>
466
- <custlist_priority>50</custlist_priority>
467
- <custlist_interval>7200</custlist_interval>
468
- </warmup>
469
- <default>
470
- <!-- Full or partial match on controller full action name for cacheable routes. Space, return, and comma separated -->
471
- <cache_routes><![CDATA[catalog cms contacts_index_index]]></cache_routes>
472
- <!-- Full or partial match on controller full action name for non-cacheable routes within cacheable routes. Space, return, and comma separated -->
473
- <nocache_subroutes><![CDATA[catalog_product_compare catalogsearch]]></nocache_subroutes>
474
- <!-- Entire response cached based on routes, same content for all urls, such as "cms_index_noRoute" for 404 pages. Space, return, and comma separated. -->
475
- <fullcache_routes><![CDATA[cms_index_noRoute]]></fullcache_routes>
476
- </default>
477
- <donotcache>
478
- <!-- configured through Admin Panel, do not update here. Customized settings will be picked up from database -->
479
- <cache_routes/>
480
- <nocache_subroutes/>
481
- <vars>no_cache</vars>
482
- <urls/>
483
- <welcome/>
484
- <toplinks/>
485
- <messages/>
486
- </donotcache>
487
- <test>
488
- <debug>0</debug>
489
- <allow_ips/>
490
- </test>
491
- </litemage>
492
- </default>
493
- <crontab>
494
- <jobs>
495
- <litemage_warmup_cache>
496
- <schedule>
497
- <!--cron_expr>0,10,20,30,40,50 * * * *</cron_expr-->
498
- <cron_expr>0,5,10,15,20,25,30,35,40,45,50,55 * * * *</cron_expr>
499
- </schedule>
500
- <run>
501
- <model>litemage/observer_cron::warmCache</model>
502
- </run>
503
- </litemage_warmup_cache>
504
- </jobs>
505
- </crontab>
506
- </config>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Litespeed/Litemage/etc/config.xml.package DELETED
@@ -1,505 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
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) 2015-2016 LiteSpeed Technologies, Inc. (https://www.litespeedtech.com)
23
- * @license https://opensource.org/licenses/GPL-3.0
24
- */
25
- -->
26
- <config>
27
- <modules>
28
- <Litespeed_Litemage>
29
- <version>1.0.17</version>
30
- </Litespeed_Litemage>
31
- </modules>
32
- <global>
33
- <blocks>
34
- <litemage>
35
- <class>Litespeed_Litemage_Block</class>
36
- </litemage>
37
- </blocks>
38
- <helpers>
39
- <litemage>
40
- <class>Litespeed_Litemage_Helper</class>
41
- </litemage>
42
- </helpers>
43
- <models>
44
- <litemage>
45
- <class>Litespeed_Litemage_Model</class>
46
- </litemage>
47
- <core>
48
- <rewrite>
49
- <translate>Litespeed_Litemage_Model_Translate</translate>
50
- </rewrite>
51
- </core>
52
- </models>
53
- <events>
54
- <!-- purge product cache after stock update -->
55
- <cataloginventory_stock_item_save_after>
56
- <observers>
57
- <litemage_purge>
58
- <class>litemage/observer_purge</class>
59
- <method>purgeCatalogProductByStock</method>
60
- </litemage_purge>
61
- </observers>
62
- </cataloginventory_stock_item_save_after>
63
- </events>
64
- </global>
65
- <admin>
66
- <routers>
67
- <adminhtml>
68
- <args>
69
- <modules>
70
- <litemage after="Mage_Adminhtml">Litespeed_Litemage_Adminhtml</litemage>
71
- </modules>
72
- </args>
73
- </adminhtml>
74
- </routers>
75
- </admin>
76
- <adminhtml>
77
- <layout>
78
- <updates>
79
- <litemage>
80
- <file>litemage.xml</file>
81
- </litemage>
82
- </updates>
83
- </layout>
84
- <acl>
85
- <resources>
86
- <admin>
87
- <children>
88
- <system>
89
- <children>
90
- <cache>
91
- <children>
92
- <litemage>
93
- <title>LiteMage Cache Management</title>
94
- </litemage>
95
- </children>
96
- </cache>
97
- <config>
98
- <children>
99
- <litemage>
100
- <title>LiteMage Cache Configuration</title>
101
- </litemage>
102
- </children>
103
- </config>
104
- </children>
105
- </system>
106
- </children>
107
- </admin>
108
- </resources>
109
- </acl>
110
- <events>
111
- <controller_action_postdispatch_adminhtml_cache_flushAll>
112
- <observers>
113
- <litemage_purge>
114
- <type>singleton</type>
115
- <class>litemage/observer_purge</class>
116
- <method>adminPurgeCache</method>
117
- </litemage_purge>
118
- </observers>
119
- </controller_action_postdispatch_adminhtml_cache_flushAll>
120
- <controller_action_postdispatch_adminhtml_cache_flushSystem>
121
- <observers>
122
- <litemage_purge>
123
- <type>singleton</type>
124
- <class>litemage/observer_purge</class>
125
- <method>adminPurgeCache</method>
126
- </litemage_purge>
127
- </observers>
128
- </controller_action_postdispatch_adminhtml_cache_flushSystem>
129
- <controller_action_postdispatch_adminhtml_system_currency_saveRates>
130
- <observers>
131
- <litemage_purge>
132
- <type>singleton</type>
133
- <class>litemage/observer_purge</class>
134
- <method>adminPurgeCurrency</method>
135
- </litemage_purge>
136
- </observers>
137
- </controller_action_postdispatch_adminhtml_system_currency_saveRates>
138
- <!-- purge category cache after save -->
139
- <catalog_category_save_commit_after>
140
- <observers>
141
- <litemage_purge>
142
- <class>litemage/observer_purge</class>
143
- <method>adminPurgeCatalogCategory</method>
144
- </litemage_purge>
145
- </observers>
146
- </catalog_category_save_commit_after>
147
- <!-- purge product cache after save -->
148
- <catalog_product_save_commit_after>
149
- <observers>
150
- <litemage_purge>
151
- <class>litemage/observer_purge</class>
152
- <method>adminPurgeCatalogProduct</method>
153
- </litemage_purge>
154
- </observers>
155
- </catalog_product_save_commit_after>
156
- <!-- purge cms page cache after save -->
157
- <cms_page_save_commit_after>
158
- <observers>
159
- <litemage_purge>
160
- <class>litemage/observer_purge</class>
161
- <method>adminPurgeCmsPage</method>
162
- </litemage_purge>
163
- </observers>
164
- </cms_page_save_commit_after>
165
- <!-- purge all caches when module disabled -->
166
- <admin_system_config_changed_section_litemage>
167
- <observers>
168
- <litemage_purge>
169
- <class>litemage/observer_purge</class>
170
- <method>adminConfigChangedSection</method>
171
- </litemage_purge>
172
- </observers>
173
- </admin_system_config_changed_section_litemage>
174
- <!-- displays warning if license not enabled -->
175
- <controller_action_predispatch_adminhtml_system_config_edit>
176
- <observers>
177
- <litemage_purge>
178
- <class>litemage/observer_purge</class>
179
- <method>adminConfigEditSection</method>
180
- </litemage_purge>
181
- </observers>
182
- </controller_action_predispatch_adminhtml_system_config_edit>
183
- </events>
184
- </adminhtml>
185
- <frontend>
186
- <routers>
187
- <litemage>
188
- <use>standard</use>
189
- <args>
190
- <module>Litespeed_Litemage</module>
191
- <frontName>litemage</frontName>
192
- </args>
193
- </litemage>
194
- </routers>
195
- <layout>
196
- <updates>
197
- <litemage>
198
- <file>litemage.xml</file>
199
- </litemage>
200
- </updates>
201
- </layout>
202
- <events>
203
- <controller_action_predispatch>
204
- <observers>
205
- <litemage_esi>
206
- <class>litemage/observer_esi</class>
207
- <method>checkControllerNoCache</method>
208
- </litemage_esi>
209
- </observers>
210
- </controller_action_predispatch>
211
- <visitor_init>
212
- <observers>
213
- <litemage_esi>
214
- <class>litemage/observer_esi</class>
215
- <method>initNewVisitor</method>
216
- </litemage_esi>
217
- </observers>
218
- </visitor_init>
219
- <core_layout_block_create_after>
220
- <observers>
221
- <litemage_esi>
222
- <class>litemage/observer_esi</class>
223
- <method>checkEsiBlock</method>
224
- </litemage_esi>
225
- </observers>
226
- </core_layout_block_create_after>
227
- <controller_action_layout_generate_blocks_after>
228
- <observers>
229
- <litemage_esi>
230
- <class>litemage/observer_esi</class>
231
- <method>prepareInjection</method>
232
- </litemage_esi>
233
- </observers>
234
- </controller_action_layout_generate_blocks_after>
235
- <http_response_send_before>
236
- <observers>
237
- <litemage_esi>
238
- <class>litemage/observer_esi</class>
239
- <method>beforeResponseSend</method>
240
- </litemage_esi>
241
- </observers>
242
- </http_response_send_before>
243
- <customer_login>
244
- <observers>
245
- <litemage_esi>
246
- <class>litemage/observer_esi</class>
247
- <method>purgePrivateCache</method>
248
- </litemage_esi>
249
- </observers>
250
- </customer_login>
251
- <customer_logout>
252
- <observers>
253
- <litemage_esi>
254
- <class>litemage/observer_esi</class>
255
- <method>purgePrivateCache</method>
256
- </litemage_esi>
257
- </observers>
258
- </customer_logout>
259
- <sales_quote_save_after>
260
- <observers>
261
- <litemage_esi>
262
- <class>litemage/observer_esi</class>
263
- <method>purgeEsiCache</method>
264
- </litemage_esi>
265
- </observers>
266
- </sales_quote_save_after>
267
- <wishlist_item_save_after>
268
- <observers>
269
- <litemage_esi>
270
- <class>litemage/observer_esi</class>
271
- <method>purgeEsiCache</method>
272
- </litemage_esi>
273
- </observers>
274
- </wishlist_item_save_after>
275
- <wishlist_item_delete_after>
276
- <observers>
277
- <litemage_esi>
278
- <class>litemage/observer_esi</class>
279
- <method>purgeEsiCache</method>
280
- </litemage_esi>
281
- </observers>
282
- </wishlist_item_delete_after>
283
- <catalog_product_compare_add_product>
284
- <observers>
285
- <litemage_esi>
286
- <class>litemage/observer_esi</class>
287
- <method>purgeEsiCache</method>
288
- </litemage_esi>
289
- </observers>
290
- </catalog_product_compare_add_product>
291
- <catalog_product_compare_remove_product>
292
- <observers>
293
- <litemage_esi>
294
- <class>litemage/observer_esi</class>
295
- <method>purgeEsiCache</method>
296
- </litemage_esi>
297
- </observers>
298
- </catalog_product_compare_remove_product>
299
- <catalog_product_compare_item_collection_clear>
300
- <observers>
301
- <litemage_esi>
302
- <class>litemage/observer_esi</class>
303
- <method>purgeEsiCache</method>
304
- </litemage_esi>
305
- </observers>
306
- </catalog_product_compare_item_collection_clear>
307
- <catalog_controller_product_view>
308
- <observers>
309
- <litemage_esi>
310
- <class>litemage/observer_esi</class>
311
- <method>onCatalogProductView</method>
312
- </litemage_esi>
313
- </observers>
314
- </catalog_controller_product_view>
315
- <cms_page_render>
316
- <observers>
317
- <litemage_esi>
318
- <class>litemage/observer_esi</class>
319
- <method>onCmsPageRender</method>
320
- </litemage_esi>
321
- </observers>
322
- </cms_page_render>
323
- <poll_vote_add>
324
- <observers>
325
- <litemage_esi>
326
- <class>litemage/observer_esi</class>
327
- <method>purgeEsiCache</method>
328
- </litemage_esi>
329
- </observers>
330
- </poll_vote_add>
331
- <core_session_abstract_add_message>
332
- <observers>
333
- <litemage_esi>
334
- <class>litemage/observer_esi</class>
335
- <method>purgeEsiCache</method>
336
- </litemage_esi>
337
- </observers>
338
- </core_session_abstract_add_message>
339
- <checkout_onepage_controller_success_action>
340
- <observers>
341
- <litemage_esi>
342
- <class>litemage/observer_esi</class>
343
- <method>purgeEsiCache</method>
344
- </litemage_esi>
345
- </observers>
346
- </checkout_onepage_controller_success_action>
347
- </events>
348
- <litemage>
349
- <esiblock>
350
- <!-- If you need to inject any other privately cached custom block groupings,
351
- you can add them here. <blocks> contains the block names defined in your
352
- layout files. All blocks that share the same purge events can be listed
353
- together in a single grouping. If their purge events are not being watched
354
- in the previous events section, you will also need to add a litemage esi
355
- observer for those events.
356
-
357
- This config file will be overwritten with upgrades to the LiteMage module.
358
- If you have made any modifications, please make sure to keep a copy -->
359
- <welcome>
360
- <!-- blocks only purged by login/logout events, no purge_events configuration is required as login/logout will auto purge all private blocks -->
361
- <access>private</access>
362
- <blocks>T:Mage_Page_Block_Html_Welcome,welcome,litemage.jsvar,nickname$v</blocks>
363
- <!-- Marking a block as valueonly, denoted by the suffix “$v”, will only output
364
- the blocks html value without the added html tags and comments when in debug mode.
365
- The block will also not be highlighted when using the LITEMAGE_DEBUG=SHOWHOLES parameter -->
366
- </welcome>
367
- <cart>
368
- <access>private</access>
369
- <!-- Blocks can be set using class type, denoted by the prefix "T:". This will include all blocks that inherit this type in the grouping -->
370
- <blocks>T:Mage_Checkout_Block_Cart_Abstract</blocks>
371
- <purge_events>
372
- <sales_quote_save_after/>
373
- </purge_events>
374
- </cart>
375
- <toplinks>
376
- <access>private</access>
377
- <blocks>top.links</blocks>
378
- <purge_tags>cart, wishlist</purge_tags>
379
- <!-- This is a composite grouping. The purge events for the blocks in this grouping are
380
- a combination of existing purge event sets from other groupings. By using purge_tags
381
- to reference these other groupings, you do not need to redefine these purge events. -->
382
- </toplinks>
383
- <compare>
384
- <access>private</access>
385
- <blocks>T:Mage_Catalog_Block_Product_Compare_Sidebar, T:Mage_Reports_Block_Product_Compared</blocks>
386
- <purge_events>
387
- <catalog_product_compare_add_product/>
388
- <catalog_product_compare_remove_product/>
389
- <catalog_product_compare_item_collection_clear/>
390
- </purge_events>
391
- </compare>
392
- <viewed>
393
- <access>private</access>
394
- <blocks>T:Mage_Reports_Block_Product_Viewed</blocks>
395
- <purge_events>
396
- <catalog_controller_product_view/>
397
- </purge_events>
398
- </viewed>
399
- <poll>
400
- <access>private</access>
401
- <blocks>T:Mage_Poll_Block_ActivePoll</blocks>
402
- <purge_events>
403
- <poll_vote_add/>
404
- </purge_events>
405
- </poll>
406
- <!-- messages is specially handled, cannot change the tag name here, has to be "messages" -->
407
- <messages>
408
- <access>private</access>
409
- <blocks>T:Mage_Core_Block_Messages</blocks>
410
- <purge_events>
411
- <core_session_abstract_add_message/>
412
- </purge_events>
413
- </messages>
414
- <!-- Blocks only visible when logged in -->
415
- <reorder>
416
- <access>private</access>
417
- <blocks>T:Mage_Sales_Block_Reorder_Sidebar</blocks>
418
- <purge_events>
419
- <sales_quote_save_after/>
420
- <checkout_onepage_controller_success_action/>
421
- </purge_events>
422
- </reorder>
423
- <wishlist>
424
- <access>private</access>
425
- <blocks>T:Mage_Wishlist_Block_Customer_Sidebar</blocks>
426
- <purge_events>
427
- <wishlist_item_save_after/>
428
- <wishlist_item_delete_after/>
429
- </purge_events>
430
- </wishlist>
431
- <!-- public blocks -->
432
- <!-- Some themes will use a variable in footer that is declared in the header,
433
- this causes the footer block to fail to generate. You can modify the
434
- template to generate the missing variable or simply choose to not punch
435
- a hole in footer (comment out the footer block).
436
-
437
- Making the footer a public block will speed up page generation and save some disk space -->
438
- <footer>
439
- <access>public</access>
440
- <blocks>footer</blocks>
441
- </footer>
442
- </esiblock>
443
- </litemage>
444
- </frontend>
445
- <default>
446
- <litemage>
447
- <general>
448
- <enabled>0</enabled>
449
- <admin_ips>127.0.0.1</admin_ips>
450
- <public_ttl>28800</public_ttl>
451
- <private_ttl>1800</private_ttl>
452
- <track_viewed>0</track_viewed>
453
- <diff_customergroup>0</diff_customergroup>
454
- <diff_cookie/>
455
- <alt_esi_syntax>0</alt_esi_syntax>
456
- </general>
457
- <warmup>
458
- <enable_warmup>0</enable_warmup>
459
- <load_limit>5</load_limit>
460
- <thread_limit>6</thread_limit>
461
- <max_time>360</max_time>
462
- <interval>21600</interval>
463
- <priority>100</priority>
464
- <multi_currency/>
465
- <custlist/>
466
- <custlist_priority>50</custlist_priority>
467
- <custlist_interval>7200</custlist_interval>
468
- </warmup>
469
- <default>
470
- <!-- Full or partial match on controller full action name for cacheable routes. Space, return, and comma separated -->
471
- <cache_routes><![CDATA[catalog cms contacts_index_index]]></cache_routes>
472
- <!-- Full or partial match on controller full action name for non-cacheable routes within cacheable routes. Space, return, and comma separated -->
473
- <nocache_subroutes><![CDATA[catalog_product_compare catalogsearch]]></nocache_subroutes>
474
- <!-- Entire response cached based on routes, same content for all urls, such as "cms_index_noRoute" for 404 pages. Space, return, and comma separated. -->
475
- <fullcache_routes><![CDATA[cms_index_noRoute]]></fullcache_routes>
476
- </default>
477
- <donotcache>
478
- <!-- configured through Admin Panel, do not update here. Customized settings will be picked up from database -->
479
- <cache_routes/>
480
- <nocache_subroutes/>
481
- <vars>no_cache</vars>
482
- <urls/>
483
- <welcome/>
484
- <toplinks/>
485
- <messages/>
486
- </donotcache>
487
- <test>
488
- <debug>0</debug>
489
- <allow_ips/>
490
- </test>
491
- </litemage>
492
- </default>
493
- <crontab>
494
- <jobs>
495
- <litemage_warmup_cache>
496
- <schedule>
497
- <cron_expr>0,10,20,30,40,50 * * * *</cron_expr>
498
- </schedule>
499
- <run>
500
- <model>litemage/observer_cron::warmCache</model>
501
- </run>
502
- </litemage_warmup_cache>
503
- </jobs>
504
- </crontab>
505
- </config>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Litespeed/Litemage/etc/system.xml CHANGED
@@ -22,13 +22,12 @@
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
  -->
27
 
28
  <config>
29
  <tabs>
30
  <Litespeed_Litemage translate="label">
31
- <label>LiteMage Cache 1.0.18</label>
32
  <sort_order>5000</sort_order>
33
  </Litespeed_Litemage>
34
  </tabs>
@@ -99,12 +98,22 @@
99
  <show_in_website>1</show_in_website>
100
  <show_in_store>1</show_in_store>
101
  </private_ttl>
 
 
 
 
 
 
 
 
 
 
102
  <track_viewed translate="label,comment">
103
  <label>Track Recently Viewed Products</label>
104
  <comment>Allows for recently viewed products functionality to work correctly even when page is served from cache. Disabling this will speed up page loading, but may make recently viewed products not appear and Magento "most viewed" reports not accurate.</comment>
105
  <frontend_type>select</frontend_type>
106
  <source_model>adminhtml/system_config_source_yesno</source_model>
107
- <sort_order>40</sort_order>
108
  <show_in_default>1</show_in_default>
109
  <show_in_website>1</show_in_website>
110
  <show_in_store>1</show_in_store>
@@ -114,7 +123,7 @@
114
  <comment>Enable this only if you have a different view or pricing schema for different customer groups.</comment>
115
  <frontend_type>select</frontend_type>
116
  <source_model>litemage/config_source_customerGroup</source_model>
117
- <sort_order>50</sort_order>
118
  <show_in_default>1</show_in_default>
119
  <show_in_website>1</show_in_website>
120
  <show_in_store>1</show_in_store>
@@ -123,7 +132,7 @@
123
  <label>Separate Cache Copy for Customized Cookie Values</label>
124
  <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>
125
  <frontend_type>label</frontend_type>
126
- <sort_order>60</sort_order>
127
  <show_in_default>1</show_in_default>
128
  <show_in_website>0</show_in_website>
129
  <show_in_store>0</show_in_store>
@@ -133,7 +142,7 @@
133
  <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>
134
  <frontend_type>select</frontend_type>
135
  <source_model>adminhtml/system_config_source_yesno</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>
@@ -207,7 +216,7 @@
207
  <urls translate="label,comment">
208
  <label>URL Blacklist</label>
209
  <frontend_type>textarea</frontend_type>
210
- <comment>List of relative URLs contained in Cacheable Routes that you would like to exclude from caching. Space, comma, return separated.</comment>
211
  <sort_order>40</sort_order>
212
  <show_in_default>1</show_in_default>
213
  <show_in_website>0</show_in_website>
@@ -319,8 +328,8 @@
319
  <show_in_store>1</show_in_store>
320
  </multi_currency>
321
  <custlist_note translate="label,comment">
322
- <label>Custom Defined Url List</label>
323
- <comment>You can supply your own Url list for each store view. Go to the “Current Configuration Scope” box and select a store to set this up.</comment>
324
  <frontend_type>label</frontend_type>
325
  <sort_order>80</sort_order>
326
  <show_in_default>1</show_in_default>
@@ -328,34 +337,20 @@
328
  <show_in_store>0</show_in_store>
329
  </custlist_note>
330
  <custlist translate="label,comment">
331
- <label>Custom Defined Url List</label>
332
- <comment>Absolute path of the file containing the list of custom-defined Urls. This should contain 1 Url per line. These Urls are relative to the store baseUrl (without http://domain/storepath). You can create a short list of the most important Urls, so they can be warmed up first and refreshed more frequently.</comment>
333
- <frontend_type>text</frontend_type>
 
 
 
 
 
 
334
  <sort_order>85</sort_order>
335
  <show_in_default>0</show_in_default>
336
  <show_in_website>0</show_in_website>
337
  <show_in_store>1</show_in_store>
338
  </custlist>
339
- <custlist_priority translate="label,comment">
340
- <label>Custom List Priority</label>
341
- <comment>You can specify a different priority for the custom-defined Url list. This value should be larger than 0, the lower the number, the higher the priority.</comment>
342
- <frontend_type>text</frontend_type>
343
- <validate>validate-digits validate-greater-than-zero</validate>
344
- <sort_order>90</sort_order>
345
- <show_in_default>1</show_in_default>
346
- <show_in_website>1</show_in_website>
347
- <show_in_store>1</show_in_store>
348
- </custlist_priority>
349
- <custlist_interval translate="label,comment">
350
- <label>Custom List Crawl Interval (seconds)</label>
351
- <comment>Specify how often you want to crawl the custom Url list.</comment>
352
- <frontend_type>text</frontend_type>
353
- <validate>validate-digits validate-digits-range-600-</validate>
354
- <sort_order>100</sort_order>
355
- <show_in_default>1</show_in_default>
356
- <show_in_website>1</show_in_website>
357
- <show_in_store>1</show_in_store>
358
- </custlist_interval>
359
  </fields>
360
  </warmup>
361
 
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
 
27
  <config>
28
  <tabs>
29
  <Litespeed_Litemage translate="label">
30
+ <label>LiteMage Cache 1.1.0</label>
31
  <sort_order>5000</sort_order>
32
  </Litespeed_Litemage>
33
  </tabs>
98
  <show_in_website>1</show_in_website>
99
  <show_in_store>1</show_in_store>
100
  </private_ttl>
101
+ <home_ttl translate="label,comment">
102
+ <label>Home Page TTL (seconds)</label>
103
+ <comment>Specify a different TTL for the home page. Default Public Cache TTL will be used by default.</comment>
104
+ <frontend_type>text</frontend_type>
105
+ <validate>validate-digits validate-digits-range digits-range-120-</validate>
106
+ <sort_order>40</sort_order>
107
+ <show_in_default>1</show_in_default>
108
+ <show_in_website>1</show_in_website>
109
+ <show_in_store>1</show_in_store>
110
+ </home_ttl>
111
  <track_viewed translate="label,comment">
112
  <label>Track Recently Viewed Products</label>
113
  <comment>Allows for recently viewed products functionality to work correctly even when page is served from cache. Disabling this will speed up page loading, but may make recently viewed products not appear and Magento "most viewed" reports not accurate.</comment>
114
  <frontend_type>select</frontend_type>
115
  <source_model>adminhtml/system_config_source_yesno</source_model>
116
+ <sort_order>50</sort_order>
117
  <show_in_default>1</show_in_default>
118
  <show_in_website>1</show_in_website>
119
  <show_in_store>1</show_in_store>
123
  <comment>Enable this only if you have a different view or pricing schema for different customer groups.</comment>
124
  <frontend_type>select</frontend_type>
125
  <source_model>litemage/config_source_customerGroup</source_model>
126
+ <sort_order>60</sort_order>
127
  <show_in_default>1</show_in_default>
128
  <show_in_website>1</show_in_website>
129
  <show_in_store>1</show_in_store>
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>
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>
143
  <frontend_type>select</frontend_type>
144
  <source_model>adminhtml/system_config_source_yesno</source_model>
145
+ <sort_order>80</sort_order>
146
  <show_in_default>1</show_in_default>
147
  <show_in_website>0</show_in_website>
148
  <show_in_store>0</show_in_store>
216
  <urls translate="label,comment">
217
  <label>URL Blacklist</label>
218
  <frontend_type>textarea</frontend_type>
219
+ <comment>List of relative URLs contained in Cacheable Routes to be excluded from caching. Partial matches can be performed by adding an "*" to the end of a URL. Space, comma, return separated.</comment>
220
  <sort_order>40</sort_order>
221
  <show_in_default>1</show_in_default>
222
  <show_in_website>0</show_in_website>
328
  <show_in_store>1</show_in_store>
329
  </multi_currency>
330
  <custlist_note translate="label,comment">
331
+ <label>Custom Defined URL List Files</label>
332
+ <comment>You can supply your own URL list for each store view. To do this go to the “Current Configuration Scope” box and select a store.</comment>
333
  <frontend_type>label</frontend_type>
334
  <sort_order>80</sort_order>
335
  <show_in_default>1</show_in_default>
337
  <show_in_store>0</show_in_store>
338
  </custlist_note>
339
  <custlist translate="label,comment">
340
+ <label>Custom Defined URL List Files</label>
341
+ <comment><![CDATA[Specify a list of files containing customized URL lists with varying intervals and priorities. Each line contains the absolute path to a single file followed by interval (seconds) and priority.
342
+ Interval must be set to a number greater than 600. Priority is a number larger than 0, where a lower number means a higher priority. <br/>
343
+ Each file listed should contain a list of custom-defined URLs (one per line). These URLs are relative to a store’s base URL (without http://domain/storepath/). This setting can be used to create a short list of important URLs to be warmed up first or refreshed more frequently.
344
+ ]]></comment>
345
+ <frontend_type>textarea</frontend_type>
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
 
app/design/adminhtml/default/default/template/litemage/cache_management.phtml CHANGED
@@ -106,30 +106,30 @@ if ($status = $this->getCrawlerStatus()) : ?>
106
 
107
  <div class="grid"><div class="hor-scroll"><table>
108
  <tr class="headings">
109
- <th class="no-link a-center"><?php echo $lmhelper->__('Prioirty');?></th>
110
- <th class="no-link a-center"><?php echo $lmhelper->__('List ID')
111
- . '<br><a href="' . $status['url_reset'] . '" title="Click to reset all crawler queues">' . $lmhelper->__('Reset All') . '</a>'; ?>
112
  </th>
113
- <th class="no-link"><?php echo $lmhelper->__('Base URL') . '<br>' . $lmhelper->__('Custom List Path'); ?></th>
114
- <th class="no-link a-right"><?php echo $lmhelper->__('Run Interval (secs)')
115
- . '<br>' . $lmhelper->__('Store Public TTL (secs)'); ?>
116
  </th>
117
- <th class="no-link a-center"><?php echo $lmhelper->__('Generated') . '<br>' . $lmhelper->__('Finished'); ?></th>
118
  <th class="no-link"><?php echo $lmhelper->__('Environment') . '<br>' . $lmhelper->__('Current Vary'); ?></th>
119
- <th class="no-link a-right"><?php echo $lmhelper->__('Current Position') . ' | ' . $lmhelper->__('List Size')
120
- . '<br>' . $lmhelper->__('Last Query Time | Total Queried'); ?></th>
121
  </tr>
122
- <?php foreach ($status['stores'] as $s) {
123
- $buf = '<tr>';
124
- $buf .= '<td class="a-center">' . $s['priority'] . '</td>'
125
- . '<td class="a-center">' . $s['id'] . '<br>'
126
- . '<a target="_blank" href="' . $status['url_details'] . '?list=' . $s['id'] . '">' . $lmhelper->__('Details')
127
- . '</a> | <a href="' . $status['url_reset'] . '?list=' . $s['id'] . '" title="Click to reset this crawler queue">' . $lmhelper->__('Reset') . '</a></td>'
128
- . '<td>' . $s['baseurl'] . '<br>' . $s['file'] . '</td>'
129
- . '<td class="a-right">' . $s['interval'] . '<br>' . $s['ttl'] . '</td>'
130
- . '<td class="a-center">' . $s['gentime'] . '<br>' . $s['endtime'] . '</td>'
 
131
  . '<td>' . $s['env'] . '<br>' . $s['curvary'] . '</td>'
132
- . '<td class="a-right">' . $s['curpos'] . ' | ' . $s['listsize'] . '<br>' . $s['lastquerytime'] . ' | '. $s['queried'] . '</td>'
133
  . "</tr>\n";
134
  echo $buf;
135
  }
106
 
107
  <div class="grid"><div class="hor-scroll"><table>
108
  <tr class="headings">
109
+ <th class="no-link a-center"><?php echo $lmhelper->__('Warm-up List')
110
+ . '<br><a href="' . $status['url_reset'] . '" class="form-button" title="Click to reset all crawler queues">' . $lmhelper->__('Reset All') . '</a>'; ?>
 
111
  </th>
112
+ <th class="no-link"><?php echo $lmhelper->__('Store Name') . ' (' . $lmhelper->__('default currency') . ')<br>' . $lmhelper->__('Base URL') . '<br>' . $lmhelper->__('Custom URL List File Path'); ?></th>
113
+ <th class="no-link a-right"><?php echo $lmhelper->__('Prioirty') . '<br>' . $lmhelper->__('Run Interval (secs)')
114
+ . '<br>' . $lmhelper->__('Public TTL (secs)'); ?>
115
  </th>
116
+ <th class="no-link a-center"><?php echo $lmhelper->__('Generated') . '<br>' . $lmhelper->__('Finished') . '<br>' . $lmhelper->__('Last Query Time'); ?></th>
117
  <th class="no-link"><?php echo $lmhelper->__('Environment') . '<br>' . $lmhelper->__('Current Vary'); ?></th>
118
+ <th class="no-link a-right"><?php echo $lmhelper->__('Current Position') . ' | ' . $lmhelper->__('List Size') . '<br>' . $lmhelper->__('Total Queried')
119
+ . '<br>' . $lmhelper->__('Current Status'); ?></th>
120
  </tr>
121
+ <?php
122
+ $i = 0;
123
+ foreach ($status['stores'] as $s) {
124
+ ++$i;
125
+ $buf = (($i % 2) == 0) ? '<tr class="even">' : '<tr>';
126
+ $buf .= '<td class="a-center">' . $s['id'] . ' <a title="Click to see details" target="_blank" class="field-tooltip" href="' . $status['url_details'] . '?list=' . $s['id']
127
+ . '"> </a><br/> <a href="' . $status['url_reset'] . '?list=' . $s['id'] . '" title="Click to reset this crawler queue">' . $lmhelper->__('Reset') . '</a></td>'
128
+ . '<td>' . $s['store_name']. ' ('. $s['default_curr'] . ')<br>'. $s['baseurl'] . '<br>' . $s['file'] . '</td>'
129
+ . '<td class="a-right">' . $s['priority'] . '<br>' . $s['interval'] . '<br>' . $s['ttl'] . '</td>'
130
+ . '<td class="a-center">' . $s['gentime'] . '<br>' . $s['endtime'] . '<br>' . $s['lastquerytime'] . '</td>'
131
  . '<td>' . $s['env'] . '<br>' . $s['curvary'] . '</td>'
132
+ . '<td class="a-right">Current Position: ' . $s['curpos'] . ' | List Size: ' . $s['listsize'] . ' <br>Total Queried: '. $s['queried'] . '<br>' . $s['tmpmsg'] . '</td>'
133
  . "</tr>\n";
134
  echo $buf;
135
  }
package.xml CHANGED
@@ -1,18 +1,25 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>LiteSpeed_LiteMage</name>
4
- <version>1.0.18</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>License changed from LiteSpeed proprietary to GPLv3.</notes>
 
 
 
 
 
 
 
12
  <authors><author><name>LiteSpeed Technologies</name><user>LiteSpeedTech</user><email>lsong@litespeedtech.com</email></author></authors>
13
- <date>2016-04-07</date>
14
- <time>21:10:55</time>
15
- <contents><target name="magecommunity"><dir name="Litespeed"><dir name="Litemage"><dir name="Block"><dir name="Adminhtml"><dir name="Cache"><file name="Management.php" hash="a16c9978a7177adf4aacc00a4a18476a"/></dir></dir><dir name="Core"><file name="Esi.php" hash="e491916a3654cb031113498934e36a81"/><file name="Messages.php" hash="89704ce091098dd0f2c6b5bf091ff32f"/></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="6640a1843d63da08f36b9bce57a0d5d3"/><file name="Esi.php" hash="7f28730e2be3437ff8e52146d2f1de60"/><file name="Viewvary.php" hash="00b51b413114123c8e5d7bfd44e1cfdc"/></dir><dir name="Model"><dir name="Config"><dir name="Source"><file name="CustomerGroup.php" hash="2aa52d9a1614a545035267958be0656f"/><file name="EnableWarmUp.php" hash="d32dd158463297672dfb58628007a88c"/></dir></dir><dir name="Layout"><file name="Update.php" hash="aed09d2eb10c38680839a7fef957c59c"/></dir><file name="Layout.php" hash="73aa0b370d35111dcc420abbff118782"/><dir name="Observer"><file name="Cron.php" hash="9e397b360d2e5b81efccbd3e4bd2792c"/><file name="Esi.php" hash="655342014432ea5ad124ef3fc6babeee"/><file name="Purge.php" hash="aa3672d74e943a63a6267c2e4025e05c"/></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="af5573b7eb74b48873a9c6a922d0a64d"/></dir><dir name="etc"><file name="config.xml" hash="f3f33da74787e94064688ab640ab563a"/><file name="config.xml.dev" hash="cd3f0860f7eeb206787d5c2d3297ebc4"/><file name="config.xml.package" hash="4220542c5e7689bf0b14f3adf05dcb23"/><file name="system.xml" hash="dc6bce0102d756500c8285a1db68a025"/></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="25be160ae1cb42391e4caa87049f272f"/></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>
16
  <compatible/>
17
  <dependencies><required><php><min>5.3.0</min><max>7.1.0</max></php></required></dependencies>
18
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>LiteSpeed_LiteMage</name>
4
+ <version>1.1.0</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 a Home Page TTL setting.&#xD;
12
+ Added support for multiple custom URL warm-up list per store with different intervals and priorities&#xD;
13
+ Added support for setting a different default vary cookie name through .htaccess to avoid conflicts with other LiteSpeed Cache plugins.&#xD;
14
+ Updated esi:include URLs to be compatible with LiteSpeed Load Balancer&#x2019;s PageSpeed module.&#xD;
15
+ Improved ESI block detection and hole punching accuracy.&#xD;
16
+ URL Blacklist will now perform an exact match unless an &#x201C;*&#x201D; is added.&#xD;
17
+ Fixed a bug where non-cacheable pages that redirected to a 404 page where mistakenly cached.&#xD;
18
+ </notes>
19
  <authors><author><name>LiteSpeed Technologies</name><user>LiteSpeedTech</user><email>lsong@litespeedtech.com</email></author></authors>
20
+ <date>2016-05-19</date>
21
+ <time>19:16:06</time>
22
+ <contents><target name="magecommunity"><dir name="Litespeed"><dir name="Litemage"><dir name="Block"><dir name="Adminhtml"><dir name="Cache"><file name="Management.php" hash="a16c9978a7177adf4aacc00a4a18476a"/></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="1e0673cf17d4d2e6792c9860d241b173"/><file name="Esi.php" hash="54036ce774753a7a4922d4d804b60562"/><file name="Viewvary.php" hash="00b51b413114123c8e5d7bfd44e1cfdc"/></dir><dir name="Model"><dir name="Config"><dir name="Backend"><file name="WarmUp.php" hash="ead7a41a31fc643d8f628e05a599eecb"/></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="339c53fc7ec3ee29b9be89116560d97a"/><file name="Esi.php" hash="916293a6e45da6d2f2663a9f3908e4e8"/><file name="Purge.php" hash="aa3672d74e943a63a6267c2e4025e05c"/></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="077e4129dcca238a48268db02b84ca41"/><file name="system.xml" hash="ab3318f299851672578fe36d0ed2d4b4"/></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="3ffb2b9e4351d0e99669c3025a565179"/></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>
23
  <compatible/>
24
  <dependencies><required><php><min>5.3.0</min><max>7.1.0</max></php></required></dependencies>
25
  </package>