Nexcessnet_Turpentine - Version 0.6.8

Version Notes

Supports Magento v1.6 and later

Download this release

Release Info

Developer Chris Wells
Extension Nexcessnet_Turpentine
Version 0.6.8
Comparing to
See all releases


Code changes from version 0.6.7 to 0.6.8

Files changed (55) hide show
  1. app/code/community/Nexcessnet/Turpentine/Block/Adminhtml/Cache/Grid.php +4 -4
  2. app/code/community/Nexcessnet/Turpentine/Block/Catalog/Product/List/Toolbar.php +0 -0
  3. app/code/community/Nexcessnet/Turpentine/Block/Core/Messages.php +65 -65
  4. app/code/community/Nexcessnet/Turpentine/Block/Management.php +5 -5
  5. app/code/community/Nexcessnet/Turpentine/Block/Notices.php +0 -0
  6. app/code/community/Nexcessnet/Turpentine/Block/Poll/ActivePoll.php +2 -2
  7. app/code/community/Nexcessnet/Turpentine/Block/Product/Compared.php +1 -1
  8. app/code/community/Nexcessnet/Turpentine/Block/Product/Viewed.php +1 -1
  9. app/code/community/Nexcessnet/Turpentine/Helper/Ban.php +12 -12
  10. app/code/community/Nexcessnet/Turpentine/Helper/Cron.php +62 -62
  11. app/code/community/Nexcessnet/Turpentine/Helper/Data.php +98 -90
  12. app/code/community/Nexcessnet/Turpentine/Helper/Debug.php +98 -99
  13. app/code/community/Nexcessnet/Turpentine/Helper/Esi.php +69 -70
  14. app/code/community/Nexcessnet/Turpentine/Helper/Varnish.php +33 -33
  15. app/code/community/Nexcessnet/Turpentine/Model/Config/Select/LoadBalancing.php +0 -0
  16. app/code/community/Nexcessnet/Turpentine/Model/Config/Select/StripWhitespace.php +3 -3
  17. app/code/community/Nexcessnet/Turpentine/Model/Config/Select/Toggle.php +0 -0
  18. app/code/community/Nexcessnet/Turpentine/Model/Config/Select/Version.php +4 -4
  19. app/code/community/Nexcessnet/Turpentine/Model/Core/Session.php +3 -3
  20. app/code/community/Nexcessnet/Turpentine/Model/Dummy/Request.php +87 -88
  21. app/code/community/Nexcessnet/Turpentine/Model/Observer/Ban.php +115 -115
  22. app/code/community/Nexcessnet/Turpentine/Model/Observer/Cron.php +21 -21
  23. app/code/community/Nexcessnet/Turpentine/Model/Observer/Debug.php +6 -6
  24. app/code/community/Nexcessnet/Turpentine/Model/Observer/Esi.php +174 -157
  25. app/code/community/Nexcessnet/Turpentine/Model/Observer/Varnish.php +51 -35
  26. app/code/community/Nexcessnet/Turpentine/Model/PageCache/Container/Notices.php +2 -2
  27. app/code/community/Nexcessnet/Turpentine/Model/Session.php +18 -19
  28. app/code/community/Nexcessnet/Turpentine/Model/Shim/Mage/Core/App.php +37 -37
  29. app/code/community/Nexcessnet/Turpentine/Model/Shim/Mage/Core/Config.php +5 -3
  30. app/code/community/Nexcessnet/Turpentine/Model/Shim/Mage/Core/Layout.php +8 -8
  31. app/code/community/Nexcessnet/Turpentine/Model/Varnish/Admin.php +45 -45
  32. app/code/community/Nexcessnet/Turpentine/Model/Varnish/Admin/Socket.php +119 -116
  33. app/code/community/Nexcessnet/Turpentine/Model/Varnish/Configurator/Abstract.php +213 -202
  34. app/code/community/Nexcessnet/Turpentine/Model/Varnish/Configurator/Version2.php +7 -7
  35. app/code/community/Nexcessnet/Turpentine/Model/Varnish/Configurator/Version3.php +7 -7
  36. app/code/community/Nexcessnet/Turpentine/Model/Varnish/Configurator/Version4.php +8 -8
  37. app/code/community/Nexcessnet/Turpentine/controllers/Adminhtml/CacheController.php +5 -5
  38. app/code/community/Nexcessnet/Turpentine/controllers/EsiController.php +110 -110
  39. app/code/community/Nexcessnet/Turpentine/controllers/Varnish/ManagementController.php +81 -81
  40. app/code/community/Nexcessnet/Turpentine/etc/cache.xml +0 -0
  41. app/code/community/Nexcessnet/Turpentine/etc/config.xml +14 -1
  42. app/code/community/Nexcessnet/Turpentine/etc/config.xml~ +14 -1
  43. app/code/community/Nexcessnet/Turpentine/etc/system.xml +13 -0
  44. app/code/community/Nexcessnet/Turpentine/misc/uuid.c +0 -0
  45. app/code/community/Nexcessnet/Turpentine/misc/version-2.vcl +16 -3
  46. app/code/community/Nexcessnet/Turpentine/misc/version-3.vcl +16 -4
  47. app/code/community/Nexcessnet/Turpentine/misc/version-4.vcl +15 -4
  48. app/design/adminhtml/default/default/layout/turpentine.xml +0 -0
  49. app/design/adminhtml/default/default/template/turpentine/varnish_management.phtml +0 -0
  50. app/design/frontend/base/default/layout/turpentine_esi.xml +131 -0
  51. app/design/frontend/base/default/template/turpentine/ajax.phtml +0 -0
  52. app/design/frontend/base/default/template/turpentine/esi.phtml +0 -0
  53. app/design/frontend/base/default/template/turpentine/notices.phtml +0 -0
  54. app/etc/modules/Nexcessnet_Turpentine.xml +0 -0
  55. package.xml +1 -1
app/code/community/Nexcessnet/Turpentine/Block/Adminhtml/Cache/Grid.php CHANGED
@@ -19,20 +19,20 @@ class Nexcessnet_Turpentine_Block_Adminhtml_Cache_Grid extends Mage_Adminhtml_Bl
19
  $fullPageEnabled = false;
20
  foreach ($collection as $key=>$item)
21
  {
22
- if($item->getStatus()==1 && ($item->getId()=='turpentine_pages' || $item->getId()=='turpentine_esi_blocks'))
23
  {
24
  $turpentineEnabled = true;
25
  }
26
- if($item->getStatus()==1 && $item->getId()=='full_page')
27
  {
28
  $fullPageEnabled = true;
29
  }
30
  }
31
- if($turpentineEnabled)
32
  {
33
  $collection->removeItemByKey('full_page');
34
  }
35
- if($fullPageEnabled)
36
  {
37
  $collection->removeItemByKey('turpentine_pages');
38
  $collection->removeItemByKey('turpentine_esi_blocks');
19
  $fullPageEnabled = false;
20
  foreach ($collection as $key=>$item)
21
  {
22
+ if ($item->getStatus() == 1 && ($item->getId() == 'turpentine_pages' || $item->getId() == 'turpentine_esi_blocks'))
23
  {
24
  $turpentineEnabled = true;
25
  }
26
+ if ($item->getStatus() == 1 && $item->getId() == 'full_page')
27
  {
28
  $fullPageEnabled = true;
29
  }
30
  }
31
+ if ($turpentineEnabled)
32
  {
33
  $collection->removeItemByKey('full_page');
34
  }
35
+ if ($fullPageEnabled)
36
  {
37
  $collection->removeItemByKey('turpentine_pages');
38
  $collection->removeItemByKey('turpentine_esi_blocks');
app/code/community/Nexcessnet/Turpentine/Block/Catalog/Product/List/Toolbar.php CHANGED
File without changes
app/code/community/Nexcessnet/Turpentine/Block/Core/Messages.php CHANGED
@@ -25,13 +25,13 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
25
  * can't use null because that is the default so no way to tell between
26
  * the default and not actually calling it
27
  */
28
- const NO_SINGLE_RENDER_TYPE = -1;
29
 
30
  /**
31
  * Hold the message type to call getHtml with
32
  * @var mixed
33
  */
34
- protected $_singleRenderType = null;
35
 
36
  /**
37
  * Sentinel to check if the toHtml method was skipped (getGroupedHtml was
@@ -41,7 +41,7 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
41
  *
42
  * @var boolean
43
  */
44
- protected $_directCall = false;
45
 
46
  /**
47
  * List of session types to load messages from for the "messages" block.
@@ -65,10 +65,10 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
65
  *
66
  * @var array
67
  */
68
- protected $_usedStorageTypes = array( 'core/session' );
69
 
70
  public function _prepareLayout() {
71
- if( $this->_fixMessages() ) {
72
  /* do nothing */
73
  return $this;
74
  } else {
@@ -82,11 +82,11 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
82
  * @param Mage_Core_Model_Message_Collection $messages
83
  * @return Mage_Core_Block_Messages
84
  */
85
- public function setMessages( Mage_Core_Model_Message_Collection $messages ) {
86
- if( $this->_fixMessages() ) {
87
- $this->_saveMessages( $messages->getItems() );
88
  } else {
89
- parent::setMessages( $messages );
90
  }
91
  return $this;
92
  }
@@ -97,11 +97,11 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
97
  * @param Mage_Core_Model_Message_Collection $messages
98
  * @return Mage_Core_Block_Messages
99
  */
100
- public function addMessages( Mage_Core_Model_Message_Collection $messages ) {
101
- if( $this->_fixMessages() ) {
102
- $this->_saveMessages( $messages->getItems() );
103
  } else {
104
- parent::addMessages( $messages );
105
  }
106
  return $this;
107
  }
@@ -112,11 +112,11 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
112
  * @param Mage_Core_Model_Message_Abstract $message
113
  * @return Mage_Core_Block_Messages
114
  */
115
- public function addMessage( Mage_Core_Model_Message_Abstract $message ) {
116
- if( $this->_fixMessages() ) {
117
- $this->_saveMessages( array( $message ) );
118
  } else {
119
- parent::addMessage( $message );
120
  }
121
  return $this;
122
  }
@@ -125,12 +125,11 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
125
  * Override this in case some dumb layout decides to use it instead of the
126
  * standard toHtml stuff
127
  *
128
- * @param mixed $type=self::NO_SINGLE_RENDER_TYPE
129
  * @return string
130
  */
131
- public function getHtml( $type=self::NO_SINGLE_RENDER_TYPE ) {
132
  $this->_singleRenderType = $type;
133
- return $this->_handleDirectCall( 'getHtml' )->toHtml();
134
  }
135
 
136
  /**
@@ -140,7 +139,7 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
140
  * @return string
141
  */
142
  public function getGroupedHtml() {
143
- return $this->_handleDirectCall( 'getGroupedHtml' )->toHtml();
144
  }
145
 
146
  /**
@@ -150,37 +149,38 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
150
  *
151
  * @param string $type
152
  */
153
- public function addStorageType( $type ) {
154
  $this->_usedStorageTypes[] = $type;
155
  }
156
 
157
  /**
158
  * Load layout options
159
  *
160
- * @return null
 
161
  */
162
- protected function _handleDirectCall( $methodCalled ) {
163
  // this doesn't actually do anything because _real_toHtml() won't be
164
  // called in this request context (unless the flash message isn't
165
  // actually supposed to be ajax/esi'd in)
166
  $this->_directCall = $methodCalled;
167
- if( $this->_fixMessages() ) {
168
  $layout = $this->getLayout();
169
- $layoutUpdate = $layout->getUpdate()->load( 'default' );
170
- if( Mage::app()->useCache( 'layout' ) ) {
171
  // this is skipped in the layout update load() if the "layout"
172
  // cache is enabled, which seems to cause the esi layout stuff
173
  // to not load, so we manually do it here
174
- foreach( $layoutUpdate->getHandles() as $handle ) {
175
- $layoutUpdate->merge( $handle );
176
  }
177
  }
178
  $layout->generateXml();
179
- $layoutShim = Mage::getSingleton( 'turpentine/shim_mage_core_layout' );
180
- foreach( $layout->getNode()->xpath(
181
- sprintf( '//reference[@name=\'%s\']/action',
182
- $this->getNameInLayout() ) ) as $node ) {
183
- $layoutShim->shim_generateAction( $node );
184
  }
185
  }
186
  return $this;
@@ -192,13 +192,13 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
192
  * @return string
193
  */
194
  protected function _toHtml() {
195
- if( $this->_fixMessages() ) {
196
- if( $this->_shouldUseInjection() ) {
197
  $html = $this->renderView();
198
  } else {
199
  $this->_loadMessages();
200
  $this->_loadSavedMessages();
201
- if ( count($this->getMessages()) ) {
202
  $html = $this->_real_toHtml();
203
  } else {
204
  // Prevent returning an empty <ul></ul>
@@ -219,7 +219,7 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
219
  */
220
  protected function _hasInjectOptions() {
221
  return $this->getEsiOptions() &&
222
- Mage::helper( 'turpentine/esi' )->shouldResponseUseEsi();
223
  }
224
 
225
  /**
@@ -241,7 +241,7 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
241
  * @return boolean
242
  */
243
  protected function _hasTemplateSet() {
244
- return (bool)$this->getTemplate();
245
  }
246
 
247
  /**
@@ -249,10 +249,10 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
249
  *
250
  * @return null
251
  */
252
- protected function _saveMessages( $messages ) {
253
- if( $this->_fixMessages() && !$this->_isEsiRequest() ) {
254
- Mage::getSingleton( 'turpentine/session' )
255
- ->saveMessages( $this->getNameInLayout(), $messages );
256
  }
257
  }
258
 
@@ -262,14 +262,14 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
262
  * @return null
263
  */
264
  protected function _loadMessages() {
265
- if( $this->getNameInLayout() == 'messages' ) {
266
- foreach( $this->_messageStorageTypes as $type ) {
267
- $storage = sprintf( '%s/session', $type );
268
- $this->addStorageType( $storage );
269
- $this->_loadMessagesFromStorage( $storage );
270
  }
271
  } else {
272
- $this->_loadMessagesFromStorage( 'core/session' );
273
  }
274
  }
275
 
@@ -279,9 +279,9 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
279
  * @return null
280
  */
281
  protected function _loadSavedMessages() {
282
- $session = Mage::getSingleton( 'turpentine/session' );
283
- foreach( $session->loadMessages( $this->getNameInLayout() ) as $msg ) {
284
- parent::addMessage( $msg );
285
  }
286
  $this->_clearMessages();
287
  }
@@ -292,10 +292,10 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
292
  * @param string $type
293
  * @return null
294
  */
295
- protected function _loadMessagesFromStorage( $type ) {
296
- foreach( Mage::getSingleton( $type )
297
- ->getMessages( true )->getItems() as $msg ) {
298
- parent::addMessage( $msg );
299
  }
300
  }
301
 
@@ -305,8 +305,8 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
305
  * @return null
306
  */
307
  protected function _clearMessages() {
308
- Mage::getSingleton( 'turpentine/session' )
309
- ->clearMessages( $this->getNameInLayout() );
310
  }
311
 
312
  /**
@@ -315,8 +315,8 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
315
  * @return string
316
  */
317
  protected function _real_toHtml() {
318
- if( !$this->_directCall ) {
319
- switch( $this->getNameInLayout() ) {
320
  case 'global_messages':
321
  $this->_directCall = 'getHtml';
322
  break;
@@ -326,9 +326,9 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
326
  break;
327
  }
328
  }
329
- switch( $this->_directCall ) {
330
  case 'getHtml':
331
- $html = parent::getHtml( $this->_singleRenderType );
332
  $this->_singleRenderType = self::NO_SINGLE_RENDER_TYPE;
333
  break;
334
  case 'getGroupedHtml':
@@ -346,7 +346,7 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
346
  * @return bool
347
  */
348
  protected function _fixMessages() {
349
- return Mage::helper( 'turpentine/esi' )->shouldFixFlashMessages();
350
  }
351
 
352
  /**
@@ -358,7 +358,7 @@ class Nexcessnet_Turpentine_Block_Core_Messages extends Mage_Core_Block_Messages
358
  * @return boolean
359
  */
360
  protected function _isEsiRequest() {
361
- return is_a( Mage::app()->getRequest(),
362
- 'Nexcessnet_Turpentine_Model_Dummy_Request' );
363
  }
364
  }
25
  * can't use null because that is the default so no way to tell between
26
  * the default and not actually calling it
27
  */
28
+ const NO_SINGLE_RENDER_TYPE = -1;
29
 
30
  /**
31
  * Hold the message type to call getHtml with
32
  * @var mixed
33
  */
34
+ protected $_singleRenderType = null;
35
 
36
  /**
37
  * Sentinel to check if the toHtml method was skipped (getGroupedHtml was
41
  *
42
  * @var boolean
43
  */
44
+ protected $_directCall = false;
45
 
46
  /**
47
  * List of session types to load messages from for the "messages" block.
65
  *
66
  * @var array
67
  */
68
+ protected $_usedStorageTypes = array('core/session');
69
 
70
  public function _prepareLayout() {
71
+ if ($this->_fixMessages()) {
72
  /* do nothing */
73
  return $this;
74
  } else {
82
  * @param Mage_Core_Model_Message_Collection $messages
83
  * @return Mage_Core_Block_Messages
84
  */
85
+ public function setMessages(Mage_Core_Model_Message_Collection $messages) {
86
+ if ($this->_fixMessages()) {
87
+ $this->_saveMessages($messages->getItems());
88
  } else {
89
+ parent::setMessages($messages);
90
  }
91
  return $this;
92
  }
97
  * @param Mage_Core_Model_Message_Collection $messages
98
  * @return Mage_Core_Block_Messages
99
  */
100
+ public function addMessages(Mage_Core_Model_Message_Collection $messages) {
101
+ if ($this->_fixMessages()) {
102
+ $this->_saveMessages($messages->getItems());
103
  } else {
104
+ parent::addMessages($messages);
105
  }
106
  return $this;
107
  }
112
  * @param Mage_Core_Model_Message_Abstract $message
113
  * @return Mage_Core_Block_Messages
114
  */
115
+ public function addMessage(Mage_Core_Model_Message_Abstract $message) {
116
+ if ($this->_fixMessages()) {
117
+ $this->_saveMessages(array($message));
118
  } else {
119
+ parent::addMessage($message);
120
  }
121
  return $this;
122
  }
125
  * Override this in case some dumb layout decides to use it instead of the
126
  * standard toHtml stuff
127
  *
 
128
  * @return string
129
  */
130
+ public function getHtml($type = self::NO_SINGLE_RENDER_TYPE) {
131
  $this->_singleRenderType = $type;
132
+ return $this->_handleDirectCall('getHtml')->toHtml();
133
  }
134
 
135
  /**
139
  * @return string
140
  */
141
  public function getGroupedHtml() {
142
+ return $this->_handleDirectCall('getGroupedHtml')->toHtml();
143
  }
144
 
145
  /**
149
  *
150
  * @param string $type
151
  */
152
+ public function addStorageType($type) {
153
  $this->_usedStorageTypes[] = $type;
154
  }
155
 
156
  /**
157
  * Load layout options
158
  *
159
+ * @param string $methodCalled
160
+ * @return Nexcessnet_Turpentine_Block_Core_Messages
161
  */
162
+ protected function _handleDirectCall($methodCalled) {
163
  // this doesn't actually do anything because _real_toHtml() won't be
164
  // called in this request context (unless the flash message isn't
165
  // actually supposed to be ajax/esi'd in)
166
  $this->_directCall = $methodCalled;
167
+ if ($this->_fixMessages()) {
168
  $layout = $this->getLayout();
169
+ $layoutUpdate = $layout->getUpdate()->load('default');
170
+ if (Mage::app()->useCache('layout')) {
171
  // this is skipped in the layout update load() if the "layout"
172
  // cache is enabled, which seems to cause the esi layout stuff
173
  // to not load, so we manually do it here
174
+ foreach ($layoutUpdate->getHandles() as $handle) {
175
+ $layoutUpdate->merge($handle);
176
  }
177
  }
178
  $layout->generateXml();
179
+ $layoutShim = Mage::getSingleton('turpentine/shim_mage_core_layout');
180
+ foreach ($layout->getNode()->xpath(
181
+ sprintf('//reference[@name=\'%s\']/action',
182
+ $this->getNameInLayout()) ) as $node) {
183
+ $layoutShim->shim_generateAction($node);
184
  }
185
  }
186
  return $this;
192
  * @return string
193
  */
194
  protected function _toHtml() {
195
+ if ($this->_fixMessages()) {
196
+ if ($this->_shouldUseInjection()) {
197
  $html = $this->renderView();
198
  } else {
199
  $this->_loadMessages();
200
  $this->_loadSavedMessages();
201
+ if (count($this->getMessages())) {
202
  $html = $this->_real_toHtml();
203
  } else {
204
  // Prevent returning an empty <ul></ul>
219
  */
220
  protected function _hasInjectOptions() {
221
  return $this->getEsiOptions() &&
222
+ Mage::helper('turpentine/esi')->shouldResponseUseEsi();
223
  }
224
 
225
  /**
241
  * @return boolean
242
  */
243
  protected function _hasTemplateSet() {
244
+ return (bool) $this->getTemplate();
245
  }
246
 
247
  /**
249
  *
250
  * @return null
251
  */
252
+ protected function _saveMessages($messages) {
253
+ if ($this->_fixMessages() && ! $this->_isEsiRequest()) {
254
+ Mage::getSingleton('turpentine/session')
255
+ ->saveMessages($this->getNameInLayout(), $messages);
256
  }
257
  }
258
 
262
  * @return null
263
  */
264
  protected function _loadMessages() {
265
+ if ($this->getNameInLayout() == 'messages') {
266
+ foreach ($this->_messageStorageTypes as $type) {
267
+ $storage = sprintf('%s/session', $type);
268
+ $this->addStorageType($storage);
269
+ $this->_loadMessagesFromStorage($storage);
270
  }
271
  } else {
272
+ $this->_loadMessagesFromStorage('core/session');
273
  }
274
  }
275
 
279
  * @return null
280
  */
281
  protected function _loadSavedMessages() {
282
+ $session = Mage::getSingleton('turpentine/session');
283
+ foreach ($session->loadMessages($this->getNameInLayout()) as $msg) {
284
+ parent::addMessage($msg);
285
  }
286
  $this->_clearMessages();
287
  }
292
  * @param string $type
293
  * @return null
294
  */
295
+ protected function _loadMessagesFromStorage($type) {
296
+ foreach (Mage::getSingleton($type)
297
+ ->getMessages(true)->getItems() as $msg) {
298
+ parent::addMessage($msg);
299
  }
300
  }
301
 
305
  * @return null
306
  */
307
  protected function _clearMessages() {
308
+ Mage::getSingleton('turpentine/session')
309
+ ->clearMessages($this->getNameInLayout());
310
  }
311
 
312
  /**
315
  * @return string
316
  */
317
  protected function _real_toHtml() {
318
+ if ( ! $this->_directCall) {
319
+ switch ($this->getNameInLayout()) {
320
  case 'global_messages':
321
  $this->_directCall = 'getHtml';
322
  break;
326
  break;
327
  }
328
  }
329
+ switch ($this->_directCall) {
330
  case 'getHtml':
331
+ $html = parent::getHtml($this->_singleRenderType);
332
  $this->_singleRenderType = self::NO_SINGLE_RENDER_TYPE;
333
  break;
334
  case 'getGroupedHtml':
346
  * @return bool
347
  */
348
  protected function _fixMessages() {
349
+ return Mage::helper('turpentine/esi')->shouldFixFlashMessages();
350
  }
351
 
352
  /**
358
  * @return boolean
359
  */
360
  protected function _isEsiRequest() {
361
+ return is_a(Mage::app()->getRequest(),
362
+ 'Nexcessnet_Turpentine_Model_Dummy_Request');
363
  }
364
  }
app/code/community/Nexcessnet/Turpentine/Block/Management.php CHANGED
@@ -34,7 +34,7 @@ class Nexcessnet_Turpentine_Block_Management
34
  * @return string
35
  */
36
  public function getFlushAllUrl() {
37
- return $this->getUrl( '*/varnish_management/flushAll' );
38
  }
39
 
40
  /**
@@ -43,7 +43,7 @@ class Nexcessnet_Turpentine_Block_Management
43
  * @return string
44
  */
45
  public function getFlushPartialUrl() {
46
- return $this->getUrl( '*/varnish_management/flushPartial' );
47
  }
48
 
49
  /**
@@ -52,7 +52,7 @@ class Nexcessnet_Turpentine_Block_Management
52
  * @return string
53
  */
54
  public function getFlushContentTypeUrl() {
55
- return $this->getUrl( '*/varnish_management/flushContentType' );
56
  }
57
 
58
  /**
@@ -61,7 +61,7 @@ class Nexcessnet_Turpentine_Block_Management
61
  * @return string
62
  */
63
  public function getApplyConfigUrl() {
64
- return $this->getUrl( '*/varnish_management/applyConfig' );
65
  }
66
 
67
  /**
@@ -88,7 +88,7 @@ class Nexcessnet_Turpentine_Block_Management
88
  * @param string $type
89
  * @return string
90
  */
91
- public function getSwitchNavigationUrl( $type ) {
92
  return $this->getUrl('*/varnish_management/switchNavigation', array('type' => $type));
93
  }
94
  }
34
  * @return string
35
  */
36
  public function getFlushAllUrl() {
37
+ return $this->getUrl('*/varnish_management/flushAll');
38
  }
39
 
40
  /**
43
  * @return string
44
  */
45
  public function getFlushPartialUrl() {
46
+ return $this->getUrl('*/varnish_management/flushPartial');
47
  }
48
 
49
  /**
52
  * @return string
53
  */
54
  public function getFlushContentTypeUrl() {
55
+ return $this->getUrl('*/varnish_management/flushContentType');
56
  }
57
 
58
  /**
61
  * @return string
62
  */
63
  public function getApplyConfigUrl() {
64
+ return $this->getUrl('*/varnish_management/applyConfig');
65
  }
66
 
67
  /**
88
  * @param string $type
89
  * @return string
90
  */
91
+ public function getSwitchNavigationUrl($type) {
92
  return $this->getUrl('*/varnish_management/switchNavigation', array('type' => $type));
93
  }
94
  }
app/code/community/Nexcessnet/Turpentine/Block/Notices.php CHANGED
File without changes
app/code/community/Nexcessnet/Turpentine/Block/Poll/ActivePoll.php CHANGED
@@ -24,8 +24,8 @@ class Nexcessnet_Turpentine_Block_Poll_Activepoll extends Mage_Poll_Block_Active
24
  public function setTemplate($template)
25
  {
26
  $this->_template = $template;
27
- $this->setPollTemplate('turpentine/ajax.phtml', 'poll' );
28
- $this->setPollTemplate('turpentine/ajax.phtml', 'results' );
29
  return $this;
30
  }
31
  }
24
  public function setTemplate($template)
25
  {
26
  $this->_template = $template;
27
+ $this->setPollTemplate('turpentine/ajax.phtml', 'poll');
28
+ $this->setPollTemplate('turpentine/ajax.phtml', 'results');
29
  return $this;
30
  }
31
  }
app/code/community/Nexcessnet/Turpentine/Block/Product/Compared.php CHANGED
@@ -23,7 +23,7 @@ class Nexcessnet_Turpentine_Block_Product_Compared extends Mage_Reports_Block_Pr
23
 
24
  protected function _toHtml()
25
  {
26
- if (!$this->getCount()) {
27
  return $this->renderView();
28
  }
29
 
23
 
24
  protected function _toHtml()
25
  {
26
+ if ( ! $this->getCount()) {
27
  return $this->renderView();
28
  }
29
 
app/code/community/Nexcessnet/Turpentine/Block/Product/Viewed.php CHANGED
@@ -23,7 +23,7 @@ class Nexcessnet_Turpentine_Block_Product_Viewed extends Mage_Reports_Block_Prod
23
 
24
  protected function _toHtml()
25
  {
26
- if (!$this->getCount()) {
27
  return $this->renderView();
28
  }
29
  $this->setRecentlyViewedProducts($this->getItemsCollection());
23
 
24
  protected function _toHtml()
25
  {
26
+ if ( ! $this->getCount()) {
27
  return $this->renderView();
28
  }
29
  $this->setRecentlyViewedProducts($this->getItemsCollection());
app/code/community/Nexcessnet/Turpentine/Helper/Ban.php CHANGED
@@ -27,20 +27,20 @@ class Nexcessnet_Turpentine_Helper_Ban extends Mage_Core_Helper_Abstract {
27
  * @param Mage_Catalog_Model_Product $product
28
  * @return string
29
  */
30
- public function getProductBanRegex( $product ) {
31
  $urlPatterns = array();
32
- foreach( $this->getParentProducts( $product ) as $parentProduct ) {
33
- if ( $parentProduct->getUrlKey() ) {
34
  $urlPatterns[] = $parentProduct->getUrlKey();
35
  }
36
  }
37
- if ( $product->getUrlKey() ) {
38
  $urlPatterns[] = $product->getUrlKey();
39
  }
40
- if ( empty($urlPatterns) ) {
41
  $urlPatterns[] = "##_NEVER_MATCH_##";
42
  }
43
- $pattern = sprintf( '(?:%s)', implode( '|', $urlPatterns ) );
44
  return $pattern;
45
  }
46
 
@@ -50,13 +50,13 @@ class Nexcessnet_Turpentine_Helper_Ban extends Mage_Core_Helper_Abstract {
50
  * @param Mage_Catalog_Model_Product $childProduct
51
  * @return array
52
  */
53
- public function getParentProducts( $childProduct ) {
54
  $parentProducts = array();
55
- foreach( array( 'configurable', 'grouped' ) as $pType ) {
56
- foreach( Mage::getModel( 'catalog/product_type_' . $pType )
57
- ->getParentIdsByChild( $childProduct->getId() ) as $parentId ) {
58
- $parentProducts[] = Mage::getModel( 'catalog/product' )
59
- ->load( $parentId );
60
  }
61
  }
62
  return $parentProducts;
27
  * @param Mage_Catalog_Model_Product $product
28
  * @return string
29
  */
30
+ public function getProductBanRegex($product) {
31
  $urlPatterns = array();
32
+ foreach ($this->getParentProducts($product) as $parentProduct) {
33
+ if ($parentProduct->getUrlKey()) {
34
  $urlPatterns[] = $parentProduct->getUrlKey();
35
  }
36
  }
37
+ if ($product->getUrlKey()) {
38
  $urlPatterns[] = $product->getUrlKey();
39
  }
40
+ if (empty($urlPatterns)) {
41
  $urlPatterns[] = "##_NEVER_MATCH_##";
42
  }
43
+ $pattern = sprintf('(?:%s)', implode('|', $urlPatterns));
44
  return $pattern;
45
  }
46
 
50
  * @param Mage_Catalog_Model_Product $childProduct
51
  * @return array
52
  */
53
+ public function getParentProducts($childProduct) {
54
  $parentProducts = array();
55
+ foreach (array('configurable', 'grouped') as $pType) {
56
+ foreach (Mage::getModel('catalog/product_type_'.$pType)
57
+ ->getParentIdsByChild($childProduct->getId()) as $parentId) {
58
+ $parentProducts[] = Mage::getModel('catalog/product')
59
+ ->load($parentId);
60
  }
61
  }
62
  return $parentProducts;
app/code/community/Nexcessnet/Turpentine/Helper/Cron.php CHANGED
@@ -51,7 +51,7 @@ class Nexcessnet_Turpentine_Helper_Cron extends Mage_Core_Helper_Abstract {
51
  * @return int
52
  */
53
  public function getAllowedRunTime() {
54
- return (int)ini_get( 'max_execution_time' );
55
  }
56
 
57
  /**
@@ -61,8 +61,8 @@ class Nexcessnet_Turpentine_Helper_Cron extends Mage_Core_Helper_Abstract {
61
  * @param string $url
62
  * @return bool
63
  */
64
- public function addUrlToCrawlerQueue( $url ) {
65
- return $this->addUrlsToCrawlerQueue( array( $url ) );
66
  }
67
 
68
  /**
@@ -72,18 +72,18 @@ class Nexcessnet_Turpentine_Helper_Cron extends Mage_Core_Helper_Abstract {
72
  * @param array $urls
73
  * @return int
74
  */
75
- public function addUrlsToCrawlerQueue( array $urls ) {
76
  // TODO: remove this debug message
77
- if( $this->getCrawlerDebugEnabled() ) {
78
- foreach( $urls as $url ) {
79
- Mage::helper( 'turpentine/debug' )->log(
80
  'Adding URL to queue: %s', $url );
81
  }
82
  }
83
  $oldQueue = $this->_readUrlQueue();
84
- $newQueue = array_unique( array_merge( $oldQueue, $urls ) );
85
- $this->_writeUrlQueue( $newQueue );
86
- $diff = count( $newQueue ) - count( $oldQueue );
87
  return $diff;
88
  }
89
 
@@ -94,8 +94,8 @@ class Nexcessnet_Turpentine_Helper_Cron extends Mage_Core_Helper_Abstract {
94
  */
95
  public function getNextUrl() {
96
  $urls = $this->_readUrlQueue();
97
- $nextUrl = array_shift( $urls );
98
- $this->_writeUrlQueue( $urls );
99
  return $nextUrl;
100
  }
101
 
@@ -114,15 +114,15 @@ class Nexcessnet_Turpentine_Helper_Cron extends Mage_Core_Helper_Abstract {
114
  * @return Varien_Http_Client
115
  */
116
  public function getCrawlerClient() {
117
- if( is_null( $this->_crawlerClient ) ) {
118
- $this->_crawlerClient = new Varien_Http_Client( null, array(
119
  'useragent' => sprintf(
120
  'Nexcessnet_Turpentine/%s Magento/%s Varien_Http_Client',
121
- Mage::helper( 'turpentine/data' )->getVersion(),
122
  Mage::getVersion() ),
123
  'keepalive' => true,
124
- ) );
125
- $this->_crawlerClient->setCookie( 'frontend', 'crawler-session' );
126
  }
127
  return $this->_crawlerClient;
128
  }
@@ -133,7 +133,7 @@ class Nexcessnet_Turpentine_Helper_Cron extends Mage_Core_Helper_Abstract {
133
  * @return bool
134
  */
135
  public function getCrawlerEnabled() {
136
- return Mage::getStoreConfig( 'turpentine_varnish/general/crawler_enable' );
137
  }
138
 
139
  /**
@@ -142,7 +142,7 @@ class Nexcessnet_Turpentine_Helper_Cron extends Mage_Core_Helper_Abstract {
142
  * @return bool
143
  */
144
  public function getCrawlerDebugEnabled() {
145
- return Mage::getStoreConfig( 'turpentine_varnish/general/crawler_debug' );
146
  }
147
 
148
  /**
@@ -157,31 +157,31 @@ class Nexcessnet_Turpentine_Helper_Cron extends Mage_Core_Helper_Abstract {
157
  Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
158
  Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG,
159
  );
160
- foreach( Mage::app()->getStores() as $storeId => $store ) {
161
- Mage::app()->setCurrentStore( $store );
162
- $baseUrl = $store->getBaseUrl( Mage_Core_Model_Store::URL_TYPE_LINK );
163
  $urls[] = $baseUrl;
164
- foreach( Mage::getModel( 'catalog/category' )
165
- ->getCollection( $storeId )
166
  ->addIsActiveFilter()
167
- as $cat ) {
168
  $urls[] = $cat->getUrl();
169
- foreach( $cat->getProductCollection( $storeId )
170
- ->addUrlRewrite( $cat->getId() )
171
- ->addAttributeToFilter( 'visibility', $visibility )
172
- as $prod ) {
173
  $urls[] = $prod->getProductUrl();
174
  }
175
  }
176
  $sitemap = (Mage::getConfig()->getNode('modules/MageWorx_XSitemap') !== FALSE) ?
177
  'xsitemap/cms_page' : 'sitemap/cms_page';
178
- foreach( Mage::getResourceModel( $sitemap )
179
- ->getCollection( $storeId ) as $item ) {
180
- $urls[] = $baseUrl . $item->getUrl();
181
  }
182
  }
183
- Mage::app()->setCurrentStore( $origStore );
184
- return array_unique( $urls );
185
  }
186
 
187
  /**
@@ -190,23 +190,23 @@ class Nexcessnet_Turpentine_Helper_Cron extends Mage_Core_Helper_Abstract {
190
  * @param Mage_Catalog_Model_Product $product
191
  * @return int
192
  */
193
- public function addProductToCrawlerQueue( $product ) {
194
  $productUrls = array();
195
  $origStore = Mage::app()->getStore();
196
- foreach( Mage::app()->getStores() as $storeId => $store ) {
197
- Mage::app()->setCurrentStore( $store );
198
  $baseUrl = $store->getBaseUrl(
199
  Mage_Core_Model_Store::URL_TYPE_LINK );
200
  $productUrls[] = $product->getProductUrl();
201
- foreach( $product->getCategoryIds() as $catId ) {
202
- $cat = Mage::getModel( 'catalog/category' )->load( $catId );
203
- $productUrls[] = rtrim( $baseUrl, '/' ) . '/' .
204
- ltrim( $product->getUrlModel()
205
- ->getUrlPath( $product, $cat ), '/' );
206
  }
207
  }
208
- Mage::app()->setCurrentStore( $origStore );
209
- return $this->addUrlsToCrawlerQueue( $productUrls );
210
  }
211
 
212
  /**
@@ -215,15 +215,15 @@ class Nexcessnet_Turpentine_Helper_Cron extends Mage_Core_Helper_Abstract {
215
  * @param Mage_Catalog_Model_Category $category
216
  * @return int
217
  */
218
- public function addCategoryToCrawlerQueue( $category ) {
219
  $catUrls = array();
220
  $origStore = Mage::app()->getStore();
221
- foreach( Mage::app()->getStores() as $storeId => $store ) {
222
- Mage::app()->setCurrentStore( $store );
223
  $catUrls[] = $category->getUrl();
224
  }
225
- Mage::app()->setCurrentStore( $origStore );
226
- return $this->addUrlsToCrawlerQueue( $catUrls );
227
  }
228
 
229
  /**
@@ -232,18 +232,18 @@ class Nexcessnet_Turpentine_Helper_Cron extends Mage_Core_Helper_Abstract {
232
  * @param int $cmsPageId
233
  * @return int
234
  */
235
- public function addCmsPageToCrawlerQueue( $cmsPageId ) {
236
- $page = Mage::getModel( 'cms/page' )->load( $cmsPageId );
237
  $pageUrls = array();
238
  $origStore = Mage::app()->getStore();
239
- foreach( Mage::app()->getStores() as $storeId => $store ) {
240
- Mage::app()->setCurrentStore( $store );
241
- $page->setStoreId( $storeId );
242
- $pageUrls[] = Mage::getUrl( null,
243
- array( '_direct' => $page->getIdentifier() ) );
244
  }
245
- Mage::app()->setCurrentStore( $origStore );
246
- return $this->addUrlsToCrawlerQueue( $pageUrls );
247
  }
248
 
249
  /**
@@ -253,8 +253,8 @@ class Nexcessnet_Turpentine_Helper_Cron extends Mage_Core_Helper_Abstract {
253
  */
254
  protected function _readUrlQueue() {
255
  $readQueue = @unserialize(
256
- Mage::app()->loadCache( self::CRAWLER_URLS_CACHE_ID ) );
257
- if( !is_array( $readQueue ) ) {
258
  // This is the first time the queue has been read since the last
259
  // cache flush (or the queue is corrupt)
260
  // Returning an empty array here would be the proper behavior,
@@ -271,8 +271,8 @@ class Nexcessnet_Turpentine_Helper_Cron extends Mage_Core_Helper_Abstract {
271
  * @param array $urls
272
  * @return null
273
  */
274
- protected function _writeUrlQueue( array $urls ) {
275
  return Mage::app()->saveCache(
276
- serialize( $urls ), self::CRAWLER_URLS_CACHE_ID );
277
  }
278
  }
51
  * @return int
52
  */
53
  public function getAllowedRunTime() {
54
+ return (int) ini_get('max_execution_time');
55
  }
56
 
57
  /**
61
  * @param string $url
62
  * @return bool
63
  */
64
+ public function addUrlToCrawlerQueue($url) {
65
+ return $this->addUrlsToCrawlerQueue(array($url));
66
  }
67
 
68
  /**
72
  * @param array $urls
73
  * @return int
74
  */
75
+ public function addUrlsToCrawlerQueue(array $urls) {
76
  // TODO: remove this debug message
77
+ if ($this->getCrawlerDebugEnabled()) {
78
+ foreach ($urls as $url) {
79
+ Mage::helper('turpentine/debug')->log(
80
  'Adding URL to queue: %s', $url );
81
  }
82
  }
83
  $oldQueue = $this->_readUrlQueue();
84
+ $newQueue = array_unique(array_merge($oldQueue, $urls));
85
+ $this->_writeUrlQueue($newQueue);
86
+ $diff = count($newQueue) - count($oldQueue);
87
  return $diff;
88
  }
89
 
94
  */
95
  public function getNextUrl() {
96
  $urls = $this->_readUrlQueue();
97
+ $nextUrl = array_shift($urls);
98
+ $this->_writeUrlQueue($urls);
99
  return $nextUrl;
100
  }
101
 
114
  * @return Varien_Http_Client
115
  */
116
  public function getCrawlerClient() {
117
+ if (is_null($this->_crawlerClient)) {
118
+ $this->_crawlerClient = new Varien_Http_Client(null, array(
119
  'useragent' => sprintf(
120
  'Nexcessnet_Turpentine/%s Magento/%s Varien_Http_Client',
121
+ Mage::helper('turpentine/data')->getVersion(),
122
  Mage::getVersion() ),
123
  'keepalive' => true,
124
+ ));
125
+ $this->_crawlerClient->setCookie('frontend', 'crawler-session');
126
  }
127
  return $this->_crawlerClient;
128
  }
133
  * @return bool
134
  */
135
  public function getCrawlerEnabled() {
136
+ return Mage::getStoreConfig('turpentine_varnish/general/crawler_enable');
137
  }
138
 
139
  /**
142
  * @return bool
143
  */
144
  public function getCrawlerDebugEnabled() {
145
+ return Mage::getStoreConfig('turpentine_varnish/general/crawler_debug');
146
  }
147
 
148
  /**
157
  Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
158
  Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG,
159
  );
160
+ foreach (Mage::app()->getStores() as $storeId => $store) {
161
+ Mage::app()->setCurrentStore($store);
162
+ $baseUrl = $store->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK);
163
  $urls[] = $baseUrl;
164
+ foreach (Mage::getModel('catalog/category')
165
+ ->getCollection($storeId)
166
  ->addIsActiveFilter()
167
+ as $cat) {
168
  $urls[] = $cat->getUrl();
169
+ foreach ($cat->getProductCollection($storeId)
170
+ ->addUrlRewrite($cat->getId())
171
+ ->addAttributeToFilter('visibility', $visibility)
172
+ as $prod) {
173
  $urls[] = $prod->getProductUrl();
174
  }
175
  }
176
  $sitemap = (Mage::getConfig()->getNode('modules/MageWorx_XSitemap') !== FALSE) ?
177
  'xsitemap/cms_page' : 'sitemap/cms_page';
178
+ foreach (Mage::getResourceModel($sitemap)
179
+ ->getCollection($storeId) as $item) {
180
+ $urls[] = $baseUrl.$item->getUrl();
181
  }
182
  }
183
+ Mage::app()->setCurrentStore($origStore);
184
+ return array_unique($urls);
185
  }
186
 
187
  /**
190
  * @param Mage_Catalog_Model_Product $product
191
  * @return int
192
  */
193
+ public function addProductToCrawlerQueue($product) {
194
  $productUrls = array();
195
  $origStore = Mage::app()->getStore();
196
+ foreach (Mage::app()->getStores() as $storeId => $store) {
197
+ Mage::app()->setCurrentStore($store);
198
  $baseUrl = $store->getBaseUrl(
199
  Mage_Core_Model_Store::URL_TYPE_LINK );
200
  $productUrls[] = $product->getProductUrl();
201
+ foreach ($product->getCategoryIds() as $catId) {
202
+ $cat = Mage::getModel('catalog/category')->load($catId);
203
+ $productUrls[] = rtrim($baseUrl, '/').'/'.
204
+ ltrim($product->getUrlModel()
205
+ ->getUrlPath($product, $cat), '/');
206
  }
207
  }
208
+ Mage::app()->setCurrentStore($origStore);
209
+ return $this->addUrlsToCrawlerQueue($productUrls);
210
  }
211
 
212
  /**
215
  * @param Mage_Catalog_Model_Category $category
216
  * @return int
217
  */
218
+ public function addCategoryToCrawlerQueue($category) {
219
  $catUrls = array();
220
  $origStore = Mage::app()->getStore();
221
+ foreach (Mage::app()->getStores() as $storeId => $store) {
222
+ Mage::app()->setCurrentStore($store);
223
  $catUrls[] = $category->getUrl();
224
  }
225
+ Mage::app()->setCurrentStore($origStore);
226
+ return $this->addUrlsToCrawlerQueue($catUrls);
227
  }
228
 
229
  /**
232
  * @param int $cmsPageId
233
  * @return int
234
  */
235
+ public function addCmsPageToCrawlerQueue($cmsPageId) {
236
+ $page = Mage::getModel('cms/page')->load($cmsPageId);
237
  $pageUrls = array();
238
  $origStore = Mage::app()->getStore();
239
+ foreach (Mage::app()->getStores() as $storeId => $store) {
240
+ Mage::app()->setCurrentStore($store);
241
+ $page->setStoreId($storeId);
242
+ $pageUrls[] = Mage::getUrl(null,
243
+ array('_direct' => $page->getIdentifier()));
244
  }
245
+ Mage::app()->setCurrentStore($origStore);
246
+ return $this->addUrlsToCrawlerQueue($pageUrls);
247
  }
248
 
249
  /**
253
  */
254
  protected function _readUrlQueue() {
255
  $readQueue = @unserialize(
256
+ Mage::app()->loadCache(self::CRAWLER_URLS_CACHE_ID) );
257
+ if ( ! is_array($readQueue)) {
258
  // This is the first time the queue has been read since the last
259
  // cache flush (or the queue is corrupt)
260
  // Returning an empty array here would be the proper behavior,
271
  * @param array $urls
272
  * @return null
273
  */
274
+ protected function _writeUrlQueue(array $urls) {
275
  return Mage::app()->saveCache(
276
+ serialize($urls), self::CRAWLER_URLS_CACHE_ID );
277
  }
278
  }
app/code/community/Nexcessnet/Turpentine/Helper/Data.php CHANGED
@@ -25,7 +25,7 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
25
  * Contains a newly generated v4 uuid whenever read, possibly not available
26
  * on all kernels
27
  */
28
- const UUID_SOURCE = '/proc/sys/kernel/random/uuid';
29
 
30
  /**
31
  * Compression level for serialization compression
@@ -38,21 +38,21 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
38
  /**
39
  * Hash algorithm to use in various cryptographic methods
40
  */
41
- const HASH_ALGORITHM = 'sha256';
42
 
43
  /**
44
  * Cookie name for the Varnish bypass
45
  *
46
  * @var string
47
  */
48
- const BYPASS_COOKIE_NAME = 'varnish_bypass';
49
 
50
  /**
51
  * encryption singleton thing
52
  *
53
  * @var Mage_Core_Model_Encryption
54
  */
55
- protected $_crypt = null;
56
 
57
  /**
58
  * Like built-in explode() but applies trim to each exploded element and
@@ -62,9 +62,9 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
62
  * @param string $data [description]
63
  * @return array
64
  */
65
- public function cleanExplode( $token, $data ) {
66
- return array_filter( array_map( 'trim',
67
- explode( $token, trim( $data ) ) ) );
68
  }
69
 
70
  /**
@@ -73,32 +73,32 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
73
  * @return string
74
  */
75
  public function generateUuid() {
76
- if( is_readable( self::UUID_SOURCE ) ) {
77
- $uuid = trim( file_get_contents( self::UUID_SOURCE ) );
78
- } elseif( function_exists( 'mt_rand' ) ) {
79
  /**
80
  * Taken from stackoverflow answer, possibly not the fastest or
81
  * strictly standards compliant
82
  * @link http://stackoverflow.com/a/2040279
83
  */
84
- $uuid = sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
85
  // 32 bits for "time_low"
86
- mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
87
 
88
  // 16 bits for "time_mid"
89
- mt_rand( 0, 0xffff ),
90
 
91
  // 16 bits for "time_hi_and_version",
92
  // four most significant bits holds version number 4
93
- mt_rand( 0, 0x0fff ) | 0x4000,
94
 
95
  // 16 bits, 8 bits for "clk_seq_hi_res",
96
  // 8 bits for "clk_seq_low",
97
  // two most significant bits holds zero and one for variant DCE1.1
98
- mt_rand( 0, 0x3fff ) | 0x8000,
99
 
100
  // 48 bits for "node"
101
- mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
102
  );
103
  } else {
104
  // chosen by dice roll, guaranteed to be random
@@ -114,7 +114,7 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
114
  */
115
  public function getVersion() {
116
  return Mage::getConfig()
117
- ->getModuleConfig( 'Nexcessnet_Turpentine' )->version;
118
  }
119
 
120
  /**
@@ -127,11 +127,11 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
127
  * @param string $str
128
  * @return string
129
  */
130
- public function urlBase64Encode( $str ) {
131
  return str_replace(
132
- array( '/', '+' ),
133
- array( '.', '-' ),
134
- base64_encode( $str ) );
135
  }
136
 
137
  /**
@@ -140,11 +140,11 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
140
  * @param string $str
141
  * @return string
142
  */
143
- public function urlBase64Decode( $str ) {
144
  return base64_decode(
145
  str_replace(
146
- array( '.', '-' ),
147
- array( '/', '+' ),
148
  $str ) );
149
  }
150
 
@@ -157,14 +157,14 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
157
  * @param mixed $data
158
  * @return string
159
  */
160
- public function freeze( $data ) {
161
- Varien_Profiler::start( 'turpentine::helper::data::freeze' );
162
  $frozenData = $this->urlBase64Encode(
163
  $this->_getCrypt()->encrypt(
164
  gzdeflate(
165
- serialize( $data ),
166
  self::COMPRESSION_LEVEL ) ) );
167
- Varien_Profiler::stop( 'turpentine::helper::data::freeze' );
168
  return $frozenData;
169
  }
170
 
@@ -174,13 +174,13 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
174
  * @param string $data
175
  * @return mixed
176
  */
177
- public function thaw( $data ) {
178
- Varien_Profiler::start( 'turpentine::helper::data::thaw' );
179
  $thawedData = unserialize(
180
  gzinflate(
181
  $this->_getCrypt()->decrypt(
182
- $this->urlBase64Decode( $data ) ) ) );
183
- Varien_Profiler::stop( 'turpentine::helper::data::thaw' );
184
  return $thawedData;
185
  }
186
 
@@ -190,9 +190,9 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
190
  * @param string $data
191
  * @return string
192
  */
193
- public function secureHash( $data ) {
194
  $salt = $this->_getCryptKey();
195
- return hash( self::HASH_ALGORITHM, sprintf( '%s:%s', $salt, $data ) );
196
  }
197
 
198
  /**
@@ -201,8 +201,8 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
201
  * @param string $data
202
  * @return string
203
  */
204
- public function getHmac( $data ) {
205
- return hash_hmac( self::HASH_ALGORITHM, $data, $this->_getCryptKey() );
206
  }
207
 
208
  /**
@@ -211,8 +211,8 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
211
  * @param array $key
212
  * @return string
213
  */
214
- public function getCacheKeyHash( $key ) {
215
- return sha1( implode( '|', array_values( $key ) ) );
216
  }
217
 
218
  /**
@@ -221,8 +221,8 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
221
  * @param Mage_Core_Model_Layout_Element $blockNode
222
  * @return array
223
  */
224
- public function getChildBlockNames( $blockNode ) {
225
- return array_unique( $this->_getChildBlockNames( $blockNode ) );
226
  }
227
 
228
  /**
@@ -231,12 +231,20 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
231
  * @param string|object $model
232
  * @return string
233
  */
234
- public function getModelName( $model ) {
235
- if( is_object( $model ) ) {
236
- $model = get_class( $model );
237
  }
238
- return strtolower( preg_replace(
239
- '~^[^_]+_([^_]+)_Model_(.+)$~', '$1/$2', $model ) );
 
 
 
 
 
 
 
 
240
  }
241
 
242
  /**
@@ -245,7 +253,7 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
245
  * @return bool
246
  */
247
  public function useFlashMessagesFix() {
248
- return (bool)Mage::getStoreConfig(
249
  'turpentine_varnish/general/ajax_messages' );
250
  }
251
 
@@ -256,7 +264,7 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
256
  * @return bool
257
  */
258
  public function useProductListToolbarFix() {
259
- return (bool)Mage::getStoreConfig(
260
  'turpentine_varnish/general/fix_product_toolbar' );
261
  }
262
 
@@ -266,7 +274,7 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
266
  * @return bool
267
  */
268
  public function getAutoApplyOnSave() {
269
- return (bool)Mage::getStoreConfig(
270
  'turpentine_varnish/general/auto_apply_on_save' );
271
  }
272
 
@@ -280,31 +288,31 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
280
  'turpentine_varnish/general/vcl_fix' );
281
  }
282
 
283
- /**
284
- * Get config value specifying when to strip VCL whitespaces
285
- *
286
- * @return string
287
- */
288
- public function getStripVclWhitespace() {
289
- return Mage::getStoreConfig(
290
- 'turpentine_varnish/general/strip_vcl_whitespace' );
291
- }
292
-
293
- /**
294
- * Check if VCL whitespaces should be stripped for the given action
295
- *
296
- * @param string $action can be either "apply", "save" or "download"
297
- * @return bool
298
- */
299
- public function shouldStripVclWhitespace($action) {
300
- $configValue = $this->getStripVclWhitespace();
301
- if ( $configValue==='always' ) {
302
- return true;
303
- } elseif ( $configValue==='apply' && $action==='apply' ) {
304
- return true;
305
- }
306
- return false;
307
- }
308
 
309
  /**
310
  * Get the cookie name for the Varnish bypass
@@ -321,19 +329,19 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
321
  * @param Mage_Core_Model_Layout_Element $blockNode
322
  * @return array
323
  */
324
- protected function _getChildBlockNames( $blockNode ) {
325
- Varien_Profiler::start( 'turpentine::helper::data::_getChildBlockNames' );
326
- if( $blockNode instanceof Mage_Core_Model_Layout_Element ) {
327
- $blockNames = array( (string)$blockNode['name'] );
328
- foreach( $blockNode->xpath( './block | ./reference' ) as $childBlockNode ) {
329
- $blockNames = array_merge( $blockNames,
330
- $this->_getChildBlockNames( $childBlockNode ) );
331
- if( $this->getLayout() instanceof Varien_Simplexml_Config ) {
332
- foreach( $this->getLayout()->getNode()->xpath( sprintf(
333
- '//reference[@name=\'%s\']', (string)$childBlockNode['name'] ) )
334
- as $childBlockLayoutNode ) {
335
- $blockNames = array_merge( $blockNames,
336
- $this->_getChildBlockNames( $childBlockLayoutNode ) );
337
 
338
  }
339
  }
@@ -341,7 +349,7 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
341
  } else {
342
  $blockNames = array();
343
  }
344
- Varien_Profiler::stop( 'turpentine::helper::data::_getChildBlockNames' );
345
  return $blockNames;
346
  }
347
 
@@ -354,9 +362,9 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
354
  * @return Mage_Core_Model_Encryption
355
  */
356
  protected function _getCrypt() {
357
- if( is_null( $this->_crypt ) ) {
358
  $this->_crypt = Varien_Crypt::factory()
359
- ->init( $this->_getCryptKey() );
360
  }
361
  return $this->_crypt;
362
  }
@@ -367,6 +375,6 @@ class Nexcessnet_Turpentine_Helper_Data extends Mage_Core_Helper_Abstract {
367
  * @return string
368
  */
369
  protected function _getCryptKey() {
370
- return (string)Mage::getConfig()->getNode( 'global/crypt/key' );
371
  }
372
  }
25
  * Contains a newly generated v4 uuid whenever read, possibly not available
26
  * on all kernels
27
  */
28
+ const UUID_SOURCE = '/proc/sys/kernel/random/uuid';
29
 
30
  /**
31
  * Compression level for serialization compression
38
  /**
39
  * Hash algorithm to use in various cryptographic methods
40
  */
41
+ const HASH_ALGORITHM = 'sha256';
42
 
43
  /**
44
  * Cookie name for the Varnish bypass
45
  *
46
  * @var string
47
  */
48
+ const BYPASS_COOKIE_NAME = 'varnish_bypass';
49
 
50
  /**
51
  * encryption singleton thing
52
  *
53
  * @var Mage_Core_Model_Encryption
54
  */
55
+ protected $_crypt = null;
56
 
57
  /**
58
  * Like built-in explode() but applies trim to each exploded element and
62
  * @param string $data [description]
63
  * @return array
64
  */
65
+ public function cleanExplode($token, $data) {
66
+ return array_filter(array_map('trim',
67
+ explode($token, trim($data))));
68
  }
69
 
70
  /**
73
  * @return string
74
  */
75
  public function generateUuid() {
76
+ if (is_readable(self::UUID_SOURCE)) {
77
+ $uuid = trim(file_get_contents(self::UUID_SOURCE));
78
+ } elseif (function_exists('mt_rand')) {
79
  /**
80
  * Taken from stackoverflow answer, possibly not the fastest or
81
  * strictly standards compliant
82
  * @link http://stackoverflow.com/a/2040279
83
  */
84
+ $uuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
85
  // 32 bits for "time_low"
86
+ mt_rand(0, 0xffff), mt_rand(0, 0xffff),
87
 
88
  // 16 bits for "time_mid"
89
+ mt_rand(0, 0xffff),
90
 
91
  // 16 bits for "time_hi_and_version",
92
  // four most significant bits holds version number 4
93
+ mt_rand(0, 0x0fff) | 0x4000,
94
 
95
  // 16 bits, 8 bits for "clk_seq_hi_res",
96
  // 8 bits for "clk_seq_low",
97
  // two most significant bits holds zero and one for variant DCE1.1
98
+ mt_rand(0, 0x3fff) | 0x8000,
99
 
100
  // 48 bits for "node"
101
+ mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
102
  );
103
  } else {
104
  // chosen by dice roll, guaranteed to be random
114
  */
115
  public function getVersion() {
116
  return Mage::getConfig()
117
+ ->getModuleConfig('Nexcessnet_Turpentine')->version;
118
  }
119
 
120
  /**
127
  * @param string $str
128
  * @return string
129
  */
130
+ public function urlBase64Encode($str) {
131
  return str_replace(
132
+ array('/', '+'),
133
+ array('.', '-'),
134
+ base64_encode($str) );
135
  }
136
 
137
  /**
140
  * @param string $str
141
  * @return string
142
  */
143
+ public function urlBase64Decode($str) {
144
  return base64_decode(
145
  str_replace(
146
+ array('.', '-'),
147
+ array('/', '+'),
148
  $str ) );
149
  }
150
 
157
  * @param mixed $data
158
  * @return string
159
  */
160
+ public function freeze($data) {
161
+ Varien_Profiler::start('turpentine::helper::data::freeze');
162
  $frozenData = $this->urlBase64Encode(
163
  $this->_getCrypt()->encrypt(
164
  gzdeflate(
165
+ serialize($data),
166
  self::COMPRESSION_LEVEL ) ) );
167
+ Varien_Profiler::stop('turpentine::helper::data::freeze');
168
  return $frozenData;
169
  }
170
 
174
  * @param string $data
175
  * @return mixed
176
  */
177
+ public function thaw($data) {
178
+ Varien_Profiler::start('turpentine::helper::data::thaw');
179
  $thawedData = unserialize(
180
  gzinflate(
181
  $this->_getCrypt()->decrypt(
182
+ $this->urlBase64Decode($data) ) ) );
183
+ Varien_Profiler::stop('turpentine::helper::data::thaw');
184
  return $thawedData;
185
  }
186
 
190
  * @param string $data
191
  * @return string
192
  */
193
+ public function secureHash($data) {
194
  $salt = $this->_getCryptKey();
195
+ return hash(self::HASH_ALGORITHM, sprintf('%s:%s', $salt, $data));
196
  }
197
 
198
  /**
201
  * @param string $data
202
  * @return string
203
  */
204
+ public function getHmac($data) {
205
+ return hash_hmac(self::HASH_ALGORITHM, $data, $this->_getCryptKey());
206
  }
207
 
208
  /**
211
  * @param array $key
212
  * @return string
213
  */
214
+ public function getCacheKeyHash($key) {
215
+ return sha1(implode('|', array_values($key)));
216
  }
217
 
218
  /**
221
  * @param Mage_Core_Model_Layout_Element $blockNode
222
  * @return array
223
  */
224
+ public function getChildBlockNames($blockNode) {
225
+ return array_unique($this->_getChildBlockNames($blockNode));
226
  }
227
 
228
  /**
231
  * @param string|object $model
232
  * @return string
233
  */
234
+ public function getModelName($model) {
235
+ if (is_object($model)) {
236
+ $model = get_class($model);
237
  }
238
+ // This guess may work if the extension uses its lowercased name as model group name.
239
+ $result = strtolower(preg_replace(
240
+ '~^[^_]+_([^_]+)_Model_(.+)$~', '$1/$2', $model ));
241
+ // This check is not expensive because the answer should come from Magento's classNameCache
242
+ $checkModel = Mage::getConfig()->getModelClassName($result);
243
+ if ('Mage_' == substr($checkModel, 0, 5) && ! class_exists($result)) {
244
+ // Fallback to full model name.
245
+ $result = $model;
246
+ }
247
+ return $result;
248
  }
249
 
250
  /**
253
  * @return bool
254
  */
255
  public function useFlashMessagesFix() {
256
+ return (bool) Mage::getStoreConfig(
257
  'turpentine_varnish/general/ajax_messages' );
258
  }
259
 
264
  * @return bool
265
  */
266
  public function useProductListToolbarFix() {
267
+ return (bool) Mage::getStoreConfig(
268
  'turpentine_varnish/general/fix_product_toolbar' );
269
  }
270
 
274
  * @return bool
275
  */
276
  public function getAutoApplyOnSave() {
277
+ return (bool) Mage::getStoreConfig(
278
  'turpentine_varnish/general/auto_apply_on_save' );
279
  }
280
 
288
  'turpentine_varnish/general/vcl_fix' );
289
  }
290
 
291
+ /**
292
+ * Get config value specifying when to strip VCL whitespaces
293
+ *
294
+ * @return string
295
+ */
296
+ public function getStripVclWhitespace() {
297
+ return Mage::getStoreConfig(
298
+ 'turpentine_varnish/general/strip_vcl_whitespace' );
299
+ }
300
+
301
+ /**
302
+ * Check if VCL whitespaces should be stripped for the given action
303
+ *
304
+ * @param string $action can be either "apply", "save" or "download"
305
+ * @return bool
306
+ */
307
+ public function shouldStripVclWhitespace($action) {
308
+ $configValue = $this->getStripVclWhitespace();
309
+ if ($configValue === 'always') {
310
+ return true;
311
+ } elseif ($configValue === 'apply' && $action === 'apply') {
312
+ return true;
313
+ }
314
+ return false;
315
+ }
316
 
317
  /**
318
  * Get the cookie name for the Varnish bypass
329
  * @param Mage_Core_Model_Layout_Element $blockNode
330
  * @return array
331
  */
332
+ protected function _getChildBlockNames($blockNode) {
333
+ Varien_Profiler::start('turpentine::helper::data::_getChildBlockNames');
334
+ if ($blockNode instanceof Mage_Core_Model_Layout_Element) {
335
+ $blockNames = array((string) $blockNode['name']);
336
+ foreach ($blockNode->xpath('./block | ./reference') as $childBlockNode) {
337
+ $blockNames = array_merge($blockNames,
338
+ $this->_getChildBlockNames($childBlockNode));
339
+ if ($this->getLayout() instanceof Varien_Simplexml_Config) {
340
+ foreach ($this->getLayout()->getNode()->xpath(sprintf(
341
+ '//reference[@name=\'%s\']', (string) $childBlockNode['name'] ))
342
+ as $childBlockLayoutNode) {
343
+ $blockNames = array_merge($blockNames,
344
+ $this->_getChildBlockNames($childBlockLayoutNode));
345
 
346
  }
347
  }
349
  } else {
350
  $blockNames = array();
351
  }
352
+ Varien_Profiler::stop('turpentine::helper::data::_getChildBlockNames');
353
  return $blockNames;
354
  }
355
 
362
  * @return Mage_Core_Model_Encryption
363
  */
364
  protected function _getCrypt() {
365
+ if (is_null($this->_crypt)) {
366
  $this->_crypt = Varien_Crypt::factory()
367
+ ->init($this->_getCryptKey());
368
  }
369
  return $this->_crypt;
370
  }
375
  * @return string
376
  */
377
  protected function _getCryptKey() {
378
+ return (string) Mage::getConfig()->getNode('global/crypt/key');
379
  }
380
  }
app/code/community/Nexcessnet/Turpentine/Helper/Debug.php CHANGED
@@ -26,13 +26,13 @@ class Nexcessnet_Turpentine_Helper_Debug extends Mage_Core_Helper_Abstract {
26
  * @param $message
27
  * @return string
28
  */
29
- public function logError( $message )
30
  {
31
- if ( func_num_args() > 1 ) {
32
- $message = $this->_prepareLogMessage( func_get_args() );
33
  }
34
 
35
- return $this->_log( Zend_Log::ERR, $message );
36
  }
37
 
38
  /**
@@ -41,13 +41,13 @@ class Nexcessnet_Turpentine_Helper_Debug extends Mage_Core_Helper_Abstract {
41
  * @param $message
42
  * @return string
43
  */
44
- public function logWarn( $message )
45
  {
46
- if ( func_num_args() > 1 ) {
47
- $message = $this->_prepareLogMessage( func_get_args() );
48
  }
49
 
50
- return $this->_log( Zend_Log::WARN, $message );
51
  }
52
 
53
  /**
@@ -56,13 +56,13 @@ class Nexcessnet_Turpentine_Helper_Debug extends Mage_Core_Helper_Abstract {
56
  * @param $message
57
  * @return string
58
  */
59
- public function logNotice( $message )
60
  {
61
- if ( func_num_args() > 1 ) {
62
- $message = $this->_prepareLogMessage( func_get_args() );
63
  }
64
 
65
- return $this->_log( Zend_Log::NOTICE, $message );
66
  }
67
 
68
  /**
@@ -71,13 +71,13 @@ class Nexcessnet_Turpentine_Helper_Debug extends Mage_Core_Helper_Abstract {
71
  * @param $message
72
  * @return string
73
  */
74
- public function logInfo( $message )
75
  {
76
- if ( func_num_args() > 1 ) {
77
- $message = $this->_prepareLogMessage( func_get_args() );
78
  }
79
 
80
- return $this->_log( Zend_Log::INFO, $message );
81
  }
82
 
83
  /**
@@ -86,17 +86,17 @@ class Nexcessnet_Turpentine_Helper_Debug extends Mage_Core_Helper_Abstract {
86
  * @param $message
87
  * @return string
88
  */
89
- public function logDebug( $message )
90
  {
91
- if( ! Mage::helper( 'turpentine/varnish' )->getVarnishDebugEnabled() ) {
92
  return;
93
  }
94
 
95
- if ( func_num_args() > 1 ) {
96
- $message = $this->_prepareLogMessage( func_get_args() );
97
  }
98
 
99
- return $this->_log( Zend_Log::DEBUG, $message );
100
  }
101
 
102
  /**
@@ -105,16 +105,16 @@ class Nexcessnet_Turpentine_Helper_Debug extends Mage_Core_Helper_Abstract {
105
  * @param array $args
106
  * @return string
107
  */
108
- protected function _prepareLogMessage( array $args )
109
  {
110
  $pattern = $args[0];
111
- $substitutes = array_slice( $args, 1 );
112
 
113
- if ( ! $this->_validatePattern( $pattern, $substitutes ) ) {
114
  return $pattern;
115
  }
116
 
117
- return vsprintf( $pattern, $substitutes );
118
  }
119
 
120
  /**
@@ -128,7 +128,7 @@ class Nexcessnet_Turpentine_Helper_Debug extends Mage_Core_Helper_Abstract {
128
  * @param array $arguments
129
  * @return bool
130
  */
131
- protected function _validatePattern( $pattern, $arguments )
132
  {
133
  return true;
134
  }
@@ -138,12 +138,12 @@ class Nexcessnet_Turpentine_Helper_Debug extends Mage_Core_Helper_Abstract {
138
  *
139
  * @param mixed $value
140
  */
141
- public function dump( $value ) {
142
- Mage::register( 'turpentine_nocache_flag', true, true );
143
- $this->logValue( $value );
144
- echo '<pre>' . PHP_EOL;
145
- var_dump( $value );
146
- echo '</pre>' . PHP_EOL;
147
  }
148
 
149
  /**
@@ -153,52 +153,51 @@ class Nexcessnet_Turpentine_Helper_Debug extends Mage_Core_Helper_Abstract {
153
  * @param mixed ...
154
  * @return null
155
  */
156
- public function log( $message ) {
157
  $args = func_get_args();
158
- return call_user_func_array( array( $this, 'logDebug' ), $args );
159
  }
160
 
161
  /**
162
  * Log a backtrace, can pass a already generated backtrace to use
163
  *
164
- * @param array $backTrace=null
165
  * @return null
166
  */
167
- public function logBackTrace( $backTrace=null ) {
168
- if( is_null( $backTrace ) ) {
169
  $backTrace = debug_backtrace();
170
- array_shift( $backTrace );
171
  }
172
- $btuuid = Mage::helper( 'turpentine/data' )->generateUuid();
173
- $this->log( 'TRACEBACK: START ** %s **', $btuuid );
174
- $this->log( 'TRACEBACK: URL: %s', $_SERVER['REQUEST_URI'] );
175
- for( $i=0; $i < count($backTrace); $i++ ) {
176
  $line = $backTrace[$i];
177
- $this->log( 'TRACEBACK: #%02d: %s:%d',
178
- $i, $line['file'], $line['line'] );
179
- $this->log( 'TRACEBACK: ==> %s%s%s(%s)',
180
- (is_object( @$line['object'] ) ?
181
- get_class( $line['object'] ) : @$line['class'] ),
182
  @$line['type'],
183
  $line['function'],
184
- $this->_backtrace_formatArgs( $line['args'] ) );
185
  }
186
- $this->log( 'TRACEBACK: END ** %s **', $btuuid );
187
  }
188
 
189
  /**
190
  * Like var_dump to the log
191
  *
192
  * @param mixed $value
193
- * @param string $name=null
194
  * @return null
195
  */
196
- public function logValue( $value, $name=null ) {
197
- if( is_null( $name ) ) {
198
  $name = 'VALUE';
199
  }
200
- $this->log( '%s => %s', $name,
201
- $this->_backtrace_formatArgsHelper( $value ) );
202
  }
203
 
204
  /**
@@ -208,40 +207,40 @@ class Nexcessnet_Turpentine_Helper_Debug extends Mage_Core_Helper_Abstract {
208
  * @param string $message
209
  * @return string
210
  */
211
- protected function _log( $level, $message ) {
212
- $message = 'TURPENTINE: ' . $message;
213
- Mage::log( $message, $level, $this->_getLogFileName() );
214
  return $message;
215
  }
216
 
217
- /**
218
- * Get the name of the log file to use
219
- * @return string
220
- */
221
- protected function _getLogFileName() {
222
- if ( $this->useCustomLogFile() ) {
223
- return $this->getCustomLogFileName();
224
- }
225
- return '';
226
- }
227
 
228
- /**
229
- * Check if custom log file should be used
230
- * @return bool
231
- */
232
- public function useCustomLogFile() {
233
- return Mage::getStoreConfigFlag(
234
- 'turpentine_varnish/logging/use_custom_log_file' );
235
- }
236
 
237
- /**
238
- * Get custom log file name
239
- * @return string
240
- */
241
- public function getCustomLogFileName() {
242
- return (string)Mage::getStoreConfig(
243
- 'turpentine_varnish/logging/custom_log_file_name' );
244
- }
245
 
246
  /**
247
  * Format a list of function arguments for the backtrace
@@ -249,10 +248,10 @@ class Nexcessnet_Turpentine_Helper_Debug extends Mage_Core_Helper_Abstract {
249
  * @param array $args
250
  * @return string
251
  */
252
- protected function _backtrace_formatArgs( $args ) {
253
- return implode( ', ',
254
  array_map(
255
- array( $this, '_backtrace_formatArgsHelper' ),
256
  $args
257
  )
258
  );
@@ -264,25 +263,25 @@ class Nexcessnet_Turpentine_Helper_Debug extends Mage_Core_Helper_Abstract {
264
  * @param mixed $arg
265
  * @return null
266
  */
267
- protected function _backtrace_formatArgsHelper( $arg ) {
268
  $value = $arg;
269
- if( is_object( $arg ) ) {
270
- $value = sprintf( 'OBJECT(%s)', get_class( $arg ) );
271
- } elseif( is_resource( $arg ) ) {
272
  $value = 'RESOURCE';
273
- } elseif( is_array( $arg ) ) {
274
  $value = 'ARRAY[%s](%s)';
275
  $c = array();
276
- foreach( $arg as $k => $v ) {
277
- $c[] = sprintf( '%s => %s', $k,
278
- $this->_backtrace_formatArgsHelper( $v ) );
279
  }
280
- $value = sprintf( $value, count( $arg ), implode( ', ', $c ) );
281
- } elseif( is_string( $arg ) ) {
282
- $value = sprintf( '\'%s\'', $arg );
283
- } elseif( is_bool( $arg ) ) {
284
  $value = $arg ? 'TRUE' : 'FALSE';
285
- } elseif( is_null( $arg ) ) {
286
  $value = 'NULL';
287
  }
288
  return $value;
26
  * @param $message
27
  * @return string
28
  */
29
+ public function logError($message)
30
  {
31
+ if (func_num_args() > 1) {
32
+ $message = $this->_prepareLogMessage(func_get_args());
33
  }
34
 
35
+ return $this->_log(Zend_Log::ERR, $message);
36
  }
37
 
38
  /**
41
  * @param $message
42
  * @return string
43
  */
44
+ public function logWarn($message)
45
  {
46
+ if (func_num_args() > 1) {
47
+ $message = $this->_prepareLogMessage(func_get_args());
48
  }
49
 
50
+ return $this->_log(Zend_Log::WARN, $message);
51
  }
52
 
53
  /**
56
  * @param $message
57
  * @return string
58
  */
59
+ public function logNotice($message)
60
  {
61
+ if (func_num_args() > 1) {
62
+ $message = $this->_prepareLogMessage(func_get_args());
63
  }
64
 
65
+ return $this->_log(Zend_Log::NOTICE, $message);
66
  }
67
 
68
  /**
71
  * @param $message
72
  * @return string
73
  */
74
+ public function logInfo($message)
75
  {
76
+ if (func_num_args() > 1) {
77
+ $message = $this->_prepareLogMessage(func_get_args());
78
  }
79
 
80
+ return $this->_log(Zend_Log::INFO, $message);
81
  }
82
 
83
  /**
86
  * @param $message
87
  * @return string
88
  */
89
+ public function logDebug($message)
90
  {
91
+ if ( ! Mage::helper('turpentine/varnish')->getVarnishDebugEnabled()) {
92
  return;
93
  }
94
 
95
+ if (func_num_args() > 1) {
96
+ $message = $this->_prepareLogMessage(func_get_args());
97
  }
98
 
99
+ return $this->_log(Zend_Log::DEBUG, $message);
100
  }
101
 
102
  /**
105
  * @param array $args
106
  * @return string
107
  */
108
+ protected function _prepareLogMessage(array $args)
109
  {
110
  $pattern = $args[0];
111
+ $substitutes = array_slice($args, 1);
112
 
113
+ if ( ! $this->_validatePattern($pattern, $substitutes)) {
114
  return $pattern;
115
  }
116
 
117
+ return vsprintf($pattern, $substitutes);
118
  }
119
 
120
  /**
128
  * @param array $arguments
129
  * @return bool
130
  */
131
+ protected function _validatePattern($pattern, $arguments)
132
  {
133
  return true;
134
  }
138
  *
139
  * @param mixed $value
140
  */
141
+ public function dump($value) {
142
+ Mage::register('turpentine_nocache_flag', true, true);
143
+ $this->logValue($value);
144
+ echo '<pre>'.PHP_EOL;
145
+ var_dump($value);
146
+ echo '</pre>'.PHP_EOL;
147
  }
148
 
149
  /**
153
  * @param mixed ...
154
  * @return null
155
  */
156
+ public function log($message) {
157
  $args = func_get_args();
158
+ return call_user_func_array(array($this, 'logDebug'), $args);
159
  }
160
 
161
  /**
162
  * Log a backtrace, can pass a already generated backtrace to use
163
  *
164
+ * @param array $backTrace
165
  * @return null
166
  */
167
+ public function logBackTrace($backTrace = null) {
168
+ if (is_null($backTrace)) {
169
  $backTrace = debug_backtrace();
170
+ array_shift($backTrace);
171
  }
172
+ $btuuid = Mage::helper('turpentine/data')->generateUuid();
173
+ $this->log('TRACEBACK: START ** %s **', $btuuid);
174
+ $this->log('TRACEBACK: URL: %s', $_SERVER['REQUEST_URI']);
175
+ for ($i = 0; $i < count($backTrace); $i++) {
176
  $line = $backTrace[$i];
177
+ $this->log('TRACEBACK: #%02d: %s:%d',
178
+ $i, $line['file'], $line['line']);
179
+ $this->log('TRACEBACK: ==> %s%s%s(%s)',
180
+ (is_object(@$line['object']) ?
181
+ get_class($line['object']) : @$line['class']),
182
  @$line['type'],
183
  $line['function'],
184
+ $this->_backtrace_formatArgs($line['args']));
185
  }
186
+ $this->log('TRACEBACK: END ** %s **', $btuuid);
187
  }
188
 
189
  /**
190
  * Like var_dump to the log
191
  *
192
  * @param mixed $value
 
193
  * @return null
194
  */
195
+ public function logValue($value, $name = null) {
196
+ if (is_null($name)) {
197
  $name = 'VALUE';
198
  }
199
+ $this->log('%s => %s', $name,
200
+ $this->_backtrace_formatArgsHelper($value));
201
  }
202
 
203
  /**
207
  * @param string $message
208
  * @return string
209
  */
210
+ protected function _log($level, $message) {
211
+ $message = 'TURPENTINE: '.$message;
212
+ Mage::log($message, $level, $this->_getLogFileName());
213
  return $message;
214
  }
215
 
216
+ /**
217
+ * Get the name of the log file to use
218
+ * @return string
219
+ */
220
+ protected function _getLogFileName() {
221
+ if ($this->useCustomLogFile()) {
222
+ return $this->getCustomLogFileName();
223
+ }
224
+ return '';
225
+ }
226
 
227
+ /**
228
+ * Check if custom log file should be used
229
+ * @return bool
230
+ */
231
+ public function useCustomLogFile() {
232
+ return Mage::getStoreConfigFlag(
233
+ 'turpentine_varnish/logging/use_custom_log_file' );
234
+ }
235
 
236
+ /**
237
+ * Get custom log file name
238
+ * @return string
239
+ */
240
+ public function getCustomLogFileName() {
241
+ return (string) Mage::getStoreConfig(
242
+ 'turpentine_varnish/logging/custom_log_file_name' );
243
+ }
244
 
245
  /**
246
  * Format a list of function arguments for the backtrace
248
  * @param array $args
249
  * @return string
250
  */
251
+ protected function _backtrace_formatArgs($args) {
252
+ return implode(', ',
253
  array_map(
254
+ array($this, '_backtrace_formatArgsHelper'),
255
  $args
256
  )
257
  );
263
  * @param mixed $arg
264
  * @return null
265
  */
266
+ protected function _backtrace_formatArgsHelper($arg) {
267
  $value = $arg;
268
+ if (is_object($arg)) {
269
+ $value = sprintf('OBJECT(%s)', get_class($arg));
270
+ } elseif (is_resource($arg)) {
271
  $value = 'RESOURCE';
272
+ } elseif (is_array($arg)) {
273
  $value = 'ARRAY[%s](%s)';
274
  $c = array();
275
+ foreach ($arg as $k => $v) {
276
+ $c[] = sprintf('%s => %s', $k,
277
+ $this->_backtrace_formatArgsHelper($v));
278
  }
279
+ $value = sprintf($value, count($arg), implode(', ', $c));
280
+ } elseif (is_string($arg)) {
281
+ $value = sprintf('\'%s\'', $arg);
282
+ } elseif (is_bool($arg)) {
283
  $value = $arg ? 'TRUE' : 'FALSE';
284
+ } elseif (is_null($arg)) {
285
  $value = 'NULL';
286
  }
287
  return $value;
app/code/community/Nexcessnet/Turpentine/Helper/Esi.php CHANGED
@@ -41,7 +41,7 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
41
  * @return bool
42
  */
43
  public function getEsiEnabled() {
44
- return Mage::app()->useCache( $this->getMageCacheName() );
45
  }
46
 
47
  /**
@@ -50,7 +50,7 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
50
  * @return bool
51
  */
52
  public function shouldResponseUseEsi() {
53
- return Mage::helper( 'turpentine/varnish' )->shouldResponseUseVarnish() &&
54
  $this->getEsiEnabled();
55
  }
56
 
@@ -60,8 +60,8 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
60
  * @return null
61
  */
62
  public function ensureEsiEnabled() {
63
- if( !$this->shouldResponseUseEsi() ) {
64
- Mage::throwException( 'ESI includes are not enabled' );
65
  }
66
  }
67
 
@@ -119,14 +119,14 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
119
  return self::ESI_HMAC_PARAM;
120
  }
121
 
122
- /**
123
- * Get referrer param
124
- *
125
- * @return string
126
- */
127
- public function getEsiReferrerParam() {
128
- return Mage_Core_Controller_Varien_Action::PARAM_NAME_BASE64_URL;
129
- }
130
 
131
  /**
132
  * Get whether ESI debugging is enabled or not
@@ -134,7 +134,7 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
134
  * @return bool
135
  */
136
  public function getEsiDebugEnabled() {
137
- return Mage::helper( 'turpentine/varnish' )
138
  ->getVarnishDebugEnabled();
139
  }
140
 
@@ -144,7 +144,7 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
144
  * @return bool
145
  */
146
  public function getEsiBlockLogEnabled() {
147
- return (bool)Mage::getStoreConfig(
148
  'turpentine_varnish/general/block_debug' );
149
  }
150
 
@@ -154,7 +154,7 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
154
  * @return bool
155
  */
156
  public function shouldFixFlashMessages() {
157
- return Mage::helper( 'turpentine/data' )->useFlashMessagesFix() &&
158
  Mage::app()->getStore()->getCode() !== 'admin';
159
  }
160
 
@@ -164,7 +164,7 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
164
  * @return string
165
  */
166
  public function getDummyUrl() {
167
- return Mage::getUrl( 'checkout/cart' );
168
  }
169
 
170
  /**
@@ -174,11 +174,10 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
174
  * turpentine/esi/getBlock while rendering ESI blocks. Not perfect, but may
175
  * be good enough
176
  *
177
- * @param string $url=null
178
  * @return Mage_Core_Controller_Request_Http
179
  */
180
- public function getDummyRequest( $url=null ) {
181
- if( $url === null ) {
182
  $url = $this->getDummyUrl();
183
  }
184
  $request = Mage::getModel('turpentine/dummy_request', $url);
@@ -198,7 +197,7 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
198
  /**
199
  * Get the list of cache clear events to include with every ESI block
200
  *
201
- * @return array
202
  */
203
  public function getDefaultCacheClearEvents() {
204
  $events = array(
@@ -211,19 +210,19 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
211
  /**
212
  * Get the list of events that should cause the ESI cache to be cleared
213
  *
214
- * @return array
215
  */
216
  public function getCacheClearEvents() {
217
- Varien_Profiler::start( 'turpentine::helper::esi::getCacheClearEvents' );
218
  $cacheKey = $this->getCacheClearEventsCacheKey();
219
- $events = @unserialize( Mage::app()->loadCache( $cacheKey ) );
220
- if( is_null( $events ) || $events === false ) {
221
  $events = $this->_loadEsiCacheClearEvents();
222
- Mage::app()->saveCache( serialize( $events ), $cacheKey,
223
- array( 'LAYOUT_GENERAL_CACHE_TAG' ) );
224
  }
225
- Varien_Profiler::stop( 'turpentine::helper::esi::getCacheClearEvents' );
226
- return array_merge( $this->getDefaultCacheClearEvents(), $events );
227
  }
228
 
229
  /**
@@ -232,7 +231,7 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
232
  * @return string
233
  */
234
  public function getDefaultEsiTtl() {
235
- return trim( Mage::getStoreConfig( 'web/cookie/cookie_lifetime' ) );
236
  }
237
 
238
  /**
@@ -242,18 +241,18 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
242
  *
243
  * @return string
244
  */
245
- public function getCorsOrigin( $url=null ) {
246
- if( is_null( $url ) ) {
247
  $baseUrl = Mage::getBaseUrl();
248
  } else {
249
  $baseUrl = $url;
250
  }
251
- $path = parse_url( $baseUrl, PHP_URL_PATH );
252
- $domain = parse_url( $baseUrl, PHP_URL_HOST );
253
  // there has to be a better way to just strip the path off
254
- return substr( $baseUrl, 0,
255
- strpos( $baseUrl, $path,
256
- strpos( $baseUrl, $domain ) ) );
257
  }
258
 
259
  /**
@@ -264,23 +263,23 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
264
  * @return Mage_Core_Model_Layout_Element|SimpleXMLElement
265
  */
266
  public function getLayoutXml() {
267
- Varien_Profiler::start( 'turpentine::helper::esi::getLayoutXml' );
268
- if( is_null( $this->_layoutXml ) ) {
269
- if( $useCache = Mage::app()->useCache( 'layout' ) ) {
270
  $cacheKey = $this->getFileLayoutUpdatesXmlCacheKey();
271
  $this->_layoutXml = simplexml_load_string(
272
- Mage::app()->loadCache( $cacheKey ) );
273
  }
274
  // this check is redundant if the layout cache is disabled
275
- if( !$this->_layoutXml ) {
276
  $this->_layoutXml = $this->_loadLayoutXml();
277
- if( $useCache ) {
278
- Mage::app()->saveCache( $this->_layoutXml->asXML(),
279
- $cacheKey, array( 'LAYOUT_GENERAL_CACHE_TAG' ) );
280
  }
281
  }
282
  }
283
- Varien_Profiler::stop( 'turpentine::helper::esi::getLayoutXml' );
284
  return $this->_layoutXml;
285
  }
286
 
@@ -291,14 +290,14 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
291
  */
292
  public function getCacheClearEventsCacheKey() {
293
  $design = Mage::getDesign();
294
- return Mage::helper( 'turpentine/data' )
295
- ->getCacheKeyHash( array(
296
  'FILE_LAYOUT_ESI_CACHE_EVENTS',
297
  $design->getArea(),
298
  $design->getPackageName(),
299
- $design->getTheme( 'layout' ),
300
  Mage::app()->getStore()->getId(),
301
- ) );
302
  }
303
 
304
  /**
@@ -308,14 +307,14 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
308
  */
309
  public function getFileLayoutUpdatesXmlCacheKey() {
310
  $design = Mage::getDesign();
311
- return Mage::helper( 'turpentine/data' )
312
- ->getCacheKeyHash( array(
313
  'FILE_LAYOUT_UPDATES_XML',
314
  $design->getArea(),
315
  $design->getPackageName(),
316
- $design->getTheme( 'layout' ),
317
  Mage::app()->getStore()->getId(),
318
- ) );
319
  }
320
 
321
  /**
@@ -327,8 +326,8 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
327
  * @param string $url url to pull content from
328
  * @return string
329
  */
330
- public function buildEsiIncludeFragment( $url ) {
331
- return sprintf( '<esi:include src="%s" />', $url );
332
  }
333
 
334
  /**
@@ -341,8 +340,8 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
341
  * @param string $content content to be removed
342
  * @return string
343
  */
344
- public function buildEsiRemoveFragment( $content ) {
345
- return sprintf( '<esi:remove>%s</esi>', $content );
346
  }
347
 
348
  /**
@@ -357,9 +356,9 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
357
  $this->getEsiScopeParam() => 'global',
358
  $this->getEsiCacheTypeParam() => 'private',
359
  );
360
- $esiUrl = Mage::getUrl( 'turpentine/esi/getFormKey', $urlOptions );
361
  // setting [web/unsecure/base_url] can be https://... but ESI can never be HTTPS
362
- $esiUrl = preg_replace( '|^https://|i', 'http://', $esiUrl );
363
  return $esiUrl;
364
  }
365
 
@@ -369,19 +368,19 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
369
  * @return array
370
  */
371
  protected function _loadEsiCacheClearEvents() {
372
- Varien_Profiler::start( 'turpentine::helper::esi::_loadEsiCacheClearEvents' );
373
  $layoutXml = $this->getLayoutXml();
374
  $events = $layoutXml->xpath(
375
  '//action[@method=\'setEsiOptions\']/params/flush_events/*' );
376
- if( $events ) {
377
- $events = array_unique( array_map(
378
- create_function( '$e',
379
- 'return (string)$e->getName();' ),
380
- $events ) );
381
  } else {
382
  $events = array();
383
  }
384
- Varien_Profiler::stop( 'turpentine::helper::esi::_loadEsiCacheClearEvents' );
385
  return $events;
386
  }
387
 
@@ -391,16 +390,16 @@ class Nexcessnet_Turpentine_Helper_Esi extends Mage_Core_Helper_Abstract {
391
  * @return Mage_Core_Model_Layout_Element
392
  */
393
  protected function _loadLayoutXml() {
394
- Varien_Profiler::start( 'turpentine::helper::esi::_loadLayoutXml' );
395
  $design = Mage::getDesign();
396
- $layoutXml = Mage::getSingleton( 'core/layout' )
397
  ->getUpdate()
398
  ->getFileLayoutUpdatesXml(
399
  $design->getArea(),
400
  $design->getPackageName(),
401
- $design->getTheme( 'layout' ),
402
  Mage::app()->getStore()->getId() );
403
- Varien_Profiler::stop( 'turpentine::helper::esi::_loadLayoutXml' );
404
  return $layoutXml;
405
  }
406
  }
41
  * @return bool
42
  */
43
  public function getEsiEnabled() {
44
+ return Mage::app()->useCache($this->getMageCacheName());
45
  }
46
 
47
  /**
50
  * @return bool
51
  */
52
  public function shouldResponseUseEsi() {
53
+ return Mage::helper('turpentine/varnish')->shouldResponseUseVarnish() &&
54
  $this->getEsiEnabled();
55
  }
56
 
60
  * @return null
61
  */
62
  public function ensureEsiEnabled() {
63
+ if ( ! $this->shouldResponseUseEsi()) {
64
+ Mage::throwException('ESI includes are not enabled');
65
  }
66
  }
67
 
119
  return self::ESI_HMAC_PARAM;
120
  }
121
 
122
+ /**
123
+ * Get referrer param
124
+ *
125
+ * @return string
126
+ */
127
+ public function getEsiReferrerParam() {
128
+ return Mage_Core_Controller_Varien_Action::PARAM_NAME_BASE64_URL;
129
+ }
130
 
131
  /**
132
  * Get whether ESI debugging is enabled or not
134
  * @return bool
135
  */
136
  public function getEsiDebugEnabled() {
137
+ return Mage::helper('turpentine/varnish')
138
  ->getVarnishDebugEnabled();
139
  }
140
 
144
  * @return bool
145
  */
146
  public function getEsiBlockLogEnabled() {
147
+ return (bool) Mage::getStoreConfig(
148
  'turpentine_varnish/general/block_debug' );
149
  }
150
 
154
  * @return bool
155
  */
156
  public function shouldFixFlashMessages() {
157
+ return Mage::helper('turpentine/data')->useFlashMessagesFix() &&
158
  Mage::app()->getStore()->getCode() !== 'admin';
159
  }
160
 
164
  * @return string
165
  */
166
  public function getDummyUrl() {
167
+ return Mage::getUrl('checkout/cart');
168
  }
169
 
170
  /**
174
  * turpentine/esi/getBlock while rendering ESI blocks. Not perfect, but may
175
  * be good enough
176
  *
 
177
  * @return Mage_Core_Controller_Request_Http
178
  */
179
+ public function getDummyRequest($url = null) {
180
+ if ($url === null) {
181
  $url = $this->getDummyUrl();
182
  }
183
  $request = Mage::getModel('turpentine/dummy_request', $url);
197
  /**
198
  * Get the list of cache clear events to include with every ESI block
199
  *
200
+ * @return string[]
201
  */
202
  public function getDefaultCacheClearEvents() {
203
  $events = array(
210
  /**
211
  * Get the list of events that should cause the ESI cache to be cleared
212
  *
213
+ * @return string[]
214
  */
215
  public function getCacheClearEvents() {
216
+ Varien_Profiler::start('turpentine::helper::esi::getCacheClearEvents');
217
  $cacheKey = $this->getCacheClearEventsCacheKey();
218
+ $events = @unserialize(Mage::app()->loadCache($cacheKey));
219
+ if (is_null($events) || $events === false) {
220
  $events = $this->_loadEsiCacheClearEvents();
221
+ Mage::app()->saveCache(serialize($events), $cacheKey,
222
+ array('LAYOUT_GENERAL_CACHE_TAG'));
223
  }
224
+ Varien_Profiler::stop('turpentine::helper::esi::getCacheClearEvents');
225
+ return array_merge($this->getDefaultCacheClearEvents(), $events);
226
  }
227
 
228
  /**
231
  * @return string
232
  */
233
  public function getDefaultEsiTtl() {
234
+ return trim(Mage::getStoreConfig('web/cookie/cookie_lifetime'));
235
  }
236
 
237
  /**
241
  *
242
  * @return string
243
  */
244
+ public function getCorsOrigin($url = null) {
245
+ if (is_null($url)) {
246
  $baseUrl = Mage::getBaseUrl();
247
  } else {
248
  $baseUrl = $url;
249
  }
250
+ $path = parse_url($baseUrl, PHP_URL_PATH);
251
+ $domain = parse_url($baseUrl, PHP_URL_HOST);
252
  // there has to be a better way to just strip the path off
253
+ return substr($baseUrl, 0,
254
+ strpos($baseUrl, $path,
255
+ strpos($baseUrl, $domain)));
256
  }
257
 
258
  /**
263
  * @return Mage_Core_Model_Layout_Element|SimpleXMLElement
264
  */
265
  public function getLayoutXml() {
266
+ Varien_Profiler::start('turpentine::helper::esi::getLayoutXml');
267
+ if (is_null($this->_layoutXml)) {
268
+ if ($useCache = Mage::app()->useCache('layout')) {
269
  $cacheKey = $this->getFileLayoutUpdatesXmlCacheKey();
270
  $this->_layoutXml = simplexml_load_string(
271
+ Mage::app()->loadCache($cacheKey) );
272
  }
273
  // this check is redundant if the layout cache is disabled
274
+ if ( ! $this->_layoutXml) {
275
  $this->_layoutXml = $this->_loadLayoutXml();
276
+ if ($useCache) {
277
+ Mage::app()->saveCache($this->_layoutXml->asXML(),
278
+ $cacheKey, array('LAYOUT_GENERAL_CACHE_TAG'));
279
  }
280
  }
281
  }
282
+ Varien_Profiler::stop('turpentine::helper::esi::getLayoutXml');
283
  return $this->_layoutXml;
284
  }
285
 
290
  */
291
  public function getCacheClearEventsCacheKey() {
292
  $design = Mage::getDesign();
293
+ return Mage::helper('turpentine/data')
294
+ ->getCacheKeyHash(array(
295
  'FILE_LAYOUT_ESI_CACHE_EVENTS',
296
  $design->getArea(),
297
  $design->getPackageName(),
298
+ $design->getTheme('layout'),
299
  Mage::app()->getStore()->getId(),
300
+ ));
301
  }
302
 
303
  /**
307
  */
308
  public function getFileLayoutUpdatesXmlCacheKey() {
309
  $design = Mage::getDesign();
310
+ return Mage::helper('turpentine/data')
311
+ ->getCacheKeyHash(array(
312
  'FILE_LAYOUT_UPDATES_XML',
313
  $design->getArea(),
314
  $design->getPackageName(),
315
+ $design->getTheme('layout'),
316
  Mage::app()->getStore()->getId(),
317
+ ));
318
  }
319
 
320
  /**
326
  * @param string $url url to pull content from
327
  * @return string
328
  */
329
+ public function buildEsiIncludeFragment($url) {
330
+ return sprintf('<esi:include src="%s" />', $url);
331
  }
332
 
333
  /**
340
  * @param string $content content to be removed
341
  * @return string
342
  */
343
+ public function buildEsiRemoveFragment($content) {
344
+ return sprintf('<esi:remove>%s</esi>', $content);
345
  }
346
 
347
  /**
356
  $this->getEsiScopeParam() => 'global',
357
  $this->getEsiCacheTypeParam() => 'private',
358
  );
359
+ $esiUrl = Mage::getUrl('turpentine/esi/getFormKey', $urlOptions);
360
  // setting [web/unsecure/base_url] can be https://... but ESI can never be HTTPS
361
+ $esiUrl = preg_replace('|^https://|i', 'http://', $esiUrl);
362
  return $esiUrl;
363
  }
364
 
368
  * @return array
369
  */
370
  protected function _loadEsiCacheClearEvents() {
371
+ Varien_Profiler::start('turpentine::helper::esi::_loadEsiCacheClearEvents');
372
  $layoutXml = $this->getLayoutXml();
373
  $events = $layoutXml->xpath(
374
  '//action[@method=\'setEsiOptions\']/params/flush_events/*' );
375
+ if ($events) {
376
+ $events = array_unique(array_map(
377
+ create_function('$e',
378
+ 'return (string)$e->getName();'),
379
+ $events ));
380
  } else {
381
  $events = array();
382
  }
383
+ Varien_Profiler::stop('turpentine::helper::esi::_loadEsiCacheClearEvents');
384
  return $events;
385
  }
386
 
390
  * @return Mage_Core_Model_Layout_Element
391
  */
392
  protected function _loadLayoutXml() {
393
+ Varien_Profiler::start('turpentine::helper::esi::_loadLayoutXml');
394
  $design = Mage::getDesign();
395
+ $layoutXml = Mage::getSingleton('core/layout')
396
  ->getUpdate()
397
  ->getFileLayoutUpdatesXml(
398
  $design->getArea(),
399
  $design->getPackageName(),
400
+ $design->getTheme('layout'),
401
  Mage::app()->getStore()->getId() );
402
+ Varien_Profiler::stop('turpentine::helper::esi::_loadLayoutXml');
403
  return $layoutXml;
404
  }
405
  }
app/code/community/Nexcessnet/Turpentine/Helper/Varnish.php CHANGED
@@ -21,7 +21,7 @@
21
 
22
  class Nexcessnet_Turpentine_Helper_Varnish extends Mage_Core_Helper_Abstract {
23
 
24
- const MAGE_CACHE_NAME = 'turpentine_pages';
25
 
26
  /**
27
  * Get whether Varnish caching is enabled or not
@@ -29,7 +29,7 @@ class Nexcessnet_Turpentine_Helper_Varnish extends Mage_Core_Helper_Abstract {
29
  * @return bool
30
  */
31
  public function getVarnishEnabled() {
32
- return Mage::app()->useCache( $this->getMageCacheName() );
33
  }
34
 
35
  /**
@@ -38,7 +38,7 @@ class Nexcessnet_Turpentine_Helper_Varnish extends Mage_Core_Helper_Abstract {
38
  * @return bool
39
  */
40
  public function getVarnishDebugEnabled() {
41
- return (bool)Mage::getStoreConfig(
42
  'turpentine_varnish/general/varnish_debug' );
43
  }
44
 
@@ -50,7 +50,7 @@ class Nexcessnet_Turpentine_Helper_Varnish extends Mage_Core_Helper_Abstract {
50
  */
51
  public function isRequestFromVarnish() {
52
  return $this->getSecretHandshake() ==
53
- Mage::app()->getRequest()->getHeader( 'X-Turpentine-Secret-Handshake' );
54
  }
55
 
56
  /**
@@ -89,18 +89,18 @@ class Nexcessnet_Turpentine_Helper_Varnish extends Mage_Core_Helper_Abstract {
89
  *
90
  * @param string $host [description]
91
  * @param string|int $port [description]
92
- * @param string $secretKey=null [description]
93
- * @param string $version=null [description]
94
  * @return Nexcessnet_Turpentine_Model_Varnish_Admin_Socket
95
  */
96
- public function getSocket( $host, $port, $secretKey=null, $version=null ) {
97
- $socket = Mage::getModel( 'turpentine/varnish_admin_socket',
98
- array( 'host' => $host, 'port' => $port ) );
99
- if( $secretKey ) {
100
- $socket->setAuthSecret( $secretKey );
101
  }
102
- if( $version ) {
103
- $socket->setVersion( $version );
104
  }
105
  return $socket;
106
  }
@@ -112,17 +112,17 @@ class Nexcessnet_Turpentine_Helper_Varnish extends Mage_Core_Helper_Abstract {
112
  */
113
  public function getSockets() {
114
  $sockets = array();
115
- $servers = Mage::helper( 'turpentine/data' )->cleanExplode( PHP_EOL,
116
- Mage::getStoreConfig( 'turpentine_varnish/servers/server_list' ) );
117
- $key = str_replace( '\n', PHP_EOL,
118
- Mage::getStoreConfig( 'turpentine_varnish/servers/auth_key' ) );
119
- $version = Mage::getStoreConfig( 'turpentine_varnish/servers/version' );
120
- if( $version == 'auto' ) {
121
  $version = null;
122
  }
123
- foreach( $servers as $server ) {
124
- $parts = explode( ':', $server );
125
- $sockets[] = $this->getSocket( $parts[0], $parts[1], $key, $version );
126
  }
127
  return $sockets;
128
  }
@@ -142,7 +142,7 @@ class Nexcessnet_Turpentine_Helper_Varnish extends Mage_Core_Helper_Abstract {
142
  * @return string
143
  */
144
  public function getDefaultTtl() {
145
- return Mage::getStoreConfig( 'turpentine_vcl/ttls/default_ttl' );
146
  }
147
 
148
  /**
@@ -152,7 +152,7 @@ class Nexcessnet_Turpentine_Helper_Varnish extends Mage_Core_Helper_Abstract {
152
  * @return bool
153
  */
154
  public function shouldFixProductListToolbar() {
155
- return Mage::helper( 'turpentine/data' )->useProductListToolbarFix() &&
156
  Mage::app()->getStore()->getCode() !== 'admin';
157
  }
158
 
@@ -162,8 +162,8 @@ class Nexcessnet_Turpentine_Helper_Varnish extends Mage_Core_Helper_Abstract {
162
  * @return boolean
163
  */
164
  public function isBypassEnabled() {
165
- $cookieName = Mage::helper( 'turpentine/data' )->getBypassCookieName();
166
- $cookieValue = Mage::getModel( 'core/cookie' )->get( $cookieName );
167
 
168
  return $cookieValue === $this->getSecretHandshake();
169
  }
@@ -180,7 +180,7 @@ class Nexcessnet_Turpentine_Helper_Varnish extends Mage_Core_Helper_Abstract {
180
  public function getFormKeyFixupActionsList() {
181
  $data = Mage::getStoreConfig(
182
  'turpentine_varnish/miscellaneous/formkey_fixup_actions' );
183
- $actions = array_filter( explode( PHP_EOL, trim( $data ) ) );
184
  return $actions;
185
  }
186
 
@@ -196,21 +196,21 @@ class Nexcessnet_Turpentine_Helper_Varnish extends Mage_Core_Helper_Abstract {
196
  public function csrfFixupNeeded() {
197
  $result = false;
198
  $isEnterprise = false; // ce
199
- if( method_exists( 'Mage', 'getEdition' ) ) {
200
- if( Mage::getEdition() === Mage::EDITION_ENTERPRISE ) {
201
  $isEnterprise = true;
202
  }
203
  } else {
204
- if( Mage::getConfig()->getModuleConfig( 'Enterprise_Enterprise' ) ) {
205
  $isEnterprise = true;
206
  }
207
  }
208
- if( $isEnterprise ) {
209
- if( version_compare( Mage::getVersion(), '1.13', '>=' ) ) {
210
  $result = true;
211
  }
212
  } else {
213
- if( version_compare( Mage::getVersion(), '1.8', '>=' ) ) {
214
  $result = true;
215
  }
216
  }
21
 
22
  class Nexcessnet_Turpentine_Helper_Varnish extends Mage_Core_Helper_Abstract {
23
 
24
+ const MAGE_CACHE_NAME = 'turpentine_pages';
25
 
26
  /**
27
  * Get whether Varnish caching is enabled or not
29
  * @return bool
30
  */
31
  public function getVarnishEnabled() {
32
+ return Mage::app()->useCache($this->getMageCacheName());
33
  }
34
 
35
  /**
38
  * @return bool
39
  */
40
  public function getVarnishDebugEnabled() {
41
+ return (bool) Mage::getStoreConfig(
42
  'turpentine_varnish/general/varnish_debug' );
43
  }
44
 
50
  */
51
  public function isRequestFromVarnish() {
52
  return $this->getSecretHandshake() ==
53
+ Mage::app()->getRequest()->getHeader('X-Turpentine-Secret-Handshake');
54
  }
55
 
56
  /**
89
  *
90
  * @param string $host [description]
91
  * @param string|int $port [description]
92
+ * @param string $secretKey [description]
93
+ * @param string $version [description]
94
  * @return Nexcessnet_Turpentine_Model_Varnish_Admin_Socket
95
  */
96
+ public function getSocket($host, $port, $secretKey = null, $version = null) {
97
+ $socket = Mage::getModel('turpentine/varnish_admin_socket',
98
+ array('host' => $host, 'port' => $port));
99
+ if ($secretKey) {
100
+ $socket->setAuthSecret($secretKey);
101
  }
102
+ if ($version) {
103
+ $socket->setVersion($version);
104
  }
105
  return $socket;
106
  }
112
  */
113
  public function getSockets() {
114
  $sockets = array();
115
+ $servers = Mage::helper('turpentine/data')->cleanExplode(PHP_EOL,
116
+ Mage::getStoreConfig('turpentine_varnish/servers/server_list'));
117
+ $key = str_replace('\n', PHP_EOL,
118
+ Mage::getStoreConfig('turpentine_varnish/servers/auth_key'));
119
+ $version = Mage::getStoreConfig('turpentine_varnish/servers/version');
120
+ if ($version == 'auto') {
121
  $version = null;
122
  }
123
+ foreach ($servers as $server) {
124
+ $parts = explode(':', $server);
125
+ $sockets[] = $this->getSocket($parts[0], $parts[1], $key, $version);
126
  }
127
  return $sockets;
128
  }
142
  * @return string
143
  */
144
  public function getDefaultTtl() {
145
+ return Mage::getStoreConfig('turpentine_vcl/ttls/default_ttl');
146
  }
147
 
148
  /**
152
  * @return bool
153
  */
154
  public function shouldFixProductListToolbar() {
155
+ return Mage::helper('turpentine/data')->useProductListToolbarFix() &&
156
  Mage::app()->getStore()->getCode() !== 'admin';
157
  }
158
 
162
  * @return boolean
163
  */
164
  public function isBypassEnabled() {
165
+ $cookieName = Mage::helper('turpentine/data')->getBypassCookieName();
166
+ $cookieValue = Mage::getModel('core/cookie')->get($cookieName);
167
 
168
  return $cookieValue === $this->getSecretHandshake();
169
  }
180
  public function getFormKeyFixupActionsList() {
181
  $data = Mage::getStoreConfig(
182
  'turpentine_varnish/miscellaneous/formkey_fixup_actions' );
183
+ $actions = array_filter(explode(PHP_EOL, trim($data)));
184
  return $actions;
185
  }
186
 
196
  public function csrfFixupNeeded() {
197
  $result = false;
198
  $isEnterprise = false; // ce
199
+ if (method_exists('Mage', 'getEdition')) {
200
+ if (Mage::getEdition() === Mage::EDITION_ENTERPRISE) {
201
  $isEnterprise = true;
202
  }
203
  } else {
204
+ if (Mage::getConfig()->getModuleConfig('Enterprise_Enterprise')) {
205
  $isEnterprise = true;
206
  }
207
  }
208
+ if ($isEnterprise) {
209
+ if (version_compare(Mage::getVersion(), '1.13', '>=')) {
210
  $result = true;
211
  }
212
  } else {
213
+ if (version_compare(Mage::getVersion(), '1.8', '>=')) {
214
  $result = true;
215
  }
216
  }
app/code/community/Nexcessnet/Turpentine/Model/Config/Select/LoadBalancing.php CHANGED
File without changes
app/code/community/Nexcessnet/Turpentine/Model/Config/Select/StripWhitespace.php CHANGED
@@ -23,9 +23,9 @@ class Nexcessnet_Turpentine_Model_Config_Select_stripWhitespace {
23
  public function toOptionArray() {
24
  $helper = Mage::helper('turpentine');
25
  return array(
26
- array( 'value' => 'always', 'label' => $helper->__( 'Always' ) ),
27
- array( 'value' => 'apply', 'label' => $helper->__( 'Only when applying directly to Varnish' ) ),
28
- array( 'value' => 'never', 'label' => $helper->__( 'Never' ) ),
29
  );
30
  }
31
  }
23
  public function toOptionArray() {
24
  $helper = Mage::helper('turpentine');
25
  return array(
26
+ array('value' => 'always', 'label' => $helper->__('Always')),
27
+ array('value' => 'apply', 'label' => $helper->__('Only when applying directly to Varnish')),
28
+ array('value' => 'never', 'label' => $helper->__('Never')),
29
  );
30
  }
31
  }
app/code/community/Nexcessnet/Turpentine/Model/Config/Select/Toggle.php CHANGED
File without changes
app/code/community/Nexcessnet/Turpentine/Model/Config/Select/Version.php CHANGED
@@ -23,10 +23,10 @@ class Nexcessnet_Turpentine_Model_Config_Select_Version {
23
  public function toOptionArray() {
24
  $helper = Mage::helper('turpentine');
25
  return array(
26
- array( 'value' => '2.1', 'label' => $helper->__( '2.1.x' ) ),
27
- array( 'value' => '3.0', 'label' => $helper->__( '3.0.x' ) ),
28
- array( 'value' => '4.0', 'label' => $helper->__( '4.0.x' ) ),
29
- array( 'value' => 'auto', 'label' => $helper->__( 'Auto' ) ),
30
  );
31
  }
32
  }
23
  public function toOptionArray() {
24
  $helper = Mage::helper('turpentine');
25
  return array(
26
+ array('value' => '2.1', 'label' => $helper->__('2.1.x')),
27
+ array('value' => '3.0', 'label' => $helper->__('3.0.x')),
28
+ array('value' => '4.0', 'label' => $helper->__('4.0.x')),
29
+ array('value' => 'auto', 'label' => $helper->__('Auto')),
30
  );
31
  }
32
  }
app/code/community/Nexcessnet/Turpentine/Model/Core/Session.php CHANGED
@@ -20,7 +20,7 @@
20
  */
21
  class Nexcessnet_Turpentine_Model_Core_Session extends Mage_Core_Model_Session
22
  {
23
- public function __construct($data=array())
24
  {
25
  $name = isset($data['name']) ? $data['name'] : null;
26
  $this->init('core', $name);
@@ -34,7 +34,7 @@ class Nexcessnet_Turpentine_Model_Core_Session extends Mage_Core_Model_Session
34
  public function getFormKey()
35
  {
36
  if (Mage::registry('replace_form_key') &&
37
- !Mage::app()->getRequest()->getParam('form_key', false)) {
38
  // flag request for ESI processing
39
  Mage::register('turpentine_esi_flag', true, true);
40
  return '{{form_key_esi_placeholder}}';
@@ -45,7 +45,7 @@ class Nexcessnet_Turpentine_Model_Core_Session extends Mage_Core_Model_Session
45
 
46
  public function real_getFormKey()
47
  {
48
- if (!$this->getData('_form_key')) {
49
  $this->setData('_form_key', Mage::helper('core')->getRandomString(16));
50
  }
51
  return $this->getData('_form_key');
20
  */
21
  class Nexcessnet_Turpentine_Model_Core_Session extends Mage_Core_Model_Session
22
  {
23
+ public function __construct($data = array())
24
  {
25
  $name = isset($data['name']) ? $data['name'] : null;
26
  $this->init('core', $name);
34
  public function getFormKey()
35
  {
36
  if (Mage::registry('replace_form_key') &&
37
+ ! Mage::app()->getRequest()->getParam('form_key', false)) {
38
  // flag request for ESI processing
39
  Mage::register('turpentine_esi_flag', true, true);
40
  return '{{form_key_esi_placeholder}}';
45
 
46
  public function real_getFormKey()
47
  {
48
+ if ( ! $this->getData('_form_key')) {
49
  $this->setData('_form_key', Mage::helper('core')->getRandomString(16));
50
  }
51
  return $this->getData('_form_key');
app/code/community/Nexcessnet/Turpentine/Model/Dummy/Request.php CHANGED
@@ -37,18 +37,18 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
37
  * @return void
38
  * @throws Zend_Controller_Request_Exception when invalid URI passed
39
  */
40
- public function __construct( $uri=null ) {
41
  $this->_initFakeSuperGlobals();
42
- $this->_fixupFakeSuperGlobals( $uri );
43
  try {
44
- parent::__construct( $uri );
45
- } catch( Exception $e ) {
46
- Mage::helper( 'turpentine/debug' )
47
- ->logError( 'Bad URI given to dummy request: ' . $uri );
48
- Mage::helper( 'turpentine/debug' )
49
  ->logBackTrace();
50
- Mage::logException( $e );
51
- if( Mage::helper( 'turpentine/esi' )->getEsiDebugEnabled() ) {
52
  throw $e;
53
  }
54
  }
@@ -62,23 +62,23 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
62
  * @param string $key
63
  * @return mixed
64
  */
65
- public function __get( $key ) {
66
- switch( true ) {
67
- case isset( $this->_params[$key] ):
68
  return $this->_params[$key];
69
- case isset( $this->GET[$key] ):
70
  return $this->GET[$key];
71
- case isset( $this->POST[$key] ):
72
  return $this->POST[$key];
73
- case isset( $_COOKIE[$key] ):
74
  return $_COOKIE[$key];
75
  case ($key == 'REQUEST_URI'):
76
  return $this->getRequestUri();
77
  case ($key == 'PATH_INFO'):
78
  return $this->getPathInfo();
79
- case isset( $this->SERVER[$key] ):
80
  return $this->SERVER[$key];
81
- case isset( $this->ENV[$key] ):
82
  return $this->ENV[$key];
83
  default:
84
  return null;
@@ -91,19 +91,19 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
91
  * @param string $key
92
  * @return boolean
93
  */
94
- public function __isset( $key ) {
95
  switch (true) {
96
- case isset( $this->_params[$key] ):
97
  return true;
98
- case isset( $this->GET[$key] ):
99
  return true;
100
- case isset( $this->POST[$key] ):
101
  return true;
102
- case isset( $_COOKIE[$key] ):
103
  return true;
104
- case isset( $this->SERVER[$key] ):
105
  return true;
106
- case isset( $this->ENV[$key] ):
107
  return true;
108
  default:
109
  return false;
@@ -117,8 +117,8 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
117
  * @param null|mixed $value
118
  * @return Zend_Controller_Request_Http
119
  */
120
- public function setQuery( $spec, $value=null ) {
121
- if ((null === $value) && !is_array($spec)) {
122
  #require_once 'Zend/Controller/Exception.php';
123
  throw new Zend_Controller_Exception('Invalid value passed to setQuery(); must be either array of values or key/value pair');
124
  }
@@ -142,11 +142,11 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
142
  * @param mixed $default Default value to use if key not found
143
  * @return mixed Returns null if key does not exist
144
  */
145
- public function getQuery( $key=null, $default=null ) {
146
- if( null === $key ) {
147
  return $this->GET;
148
  }
149
- return ( isset( $this->GET[$key] ) ) ? $this->GET[$key] : $default;
150
  }
151
 
152
  /**
@@ -159,7 +159,7 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
159
  * @param mixed $default Default value to use if key not found
160
  * @return mixed Returns null if key does not exist
161
  */
162
- public function getPost( $key=null, $default=null ) {
163
  if (null === $key) {
164
  return $this->POST;
165
  }
@@ -176,7 +176,7 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
176
  * @param mixed $default Default value to use if key not found
177
  * @return mixed Returns null if key does not exist
178
  */
179
- public function getServer( $key=null, $default=null ) {
180
  if (null === $key) {
181
  return $this->SERVER;
182
  }
@@ -193,7 +193,7 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
193
  * @param mixed $default Default value to use if key not found
194
  * @return mixed Returns null if key does not exist
195
  */
196
- public function getEnv( $key=null, $default=null ) {
197
  if (null === $key) {
198
  return $this->ENV;
199
  }
@@ -210,14 +210,14 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
210
  * @return string|false HTTP header value, or false if not found
211
  * @throws Zend_Controller_Request_Exception
212
  */
213
- public function getHeader( $header ) {
214
  if (empty($header)) {
215
  #require_once 'Zend/Controller/Request/Exception.php';
216
  throw new Zend_Controller_Request_Exception('An HTTP header name is required');
217
  }
218
 
219
  // Try to get it from the $_SERVER array first
220
- $temp = 'HTTP_' . strtoupper(str_replace('-', '_', $header));
221
  if (isset($this->SERVER[$temp])) {
222
  return $this->SERVER[$temp];
223
  }
@@ -249,7 +249,7 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
249
  * @param string $requestUri
250
  * @return Zend_Controller_Request_Http
251
  */
252
- public function setRequestUri( $requestUri=null ) {
253
  if ($requestUri === null) {
254
  if (isset($this->SERVER['HTTP_X_REWRITE_URL'])) { // check this first so IIS will catch
255
  $requestUri = $this->SERVER['HTTP_X_REWRITE_URL'];
@@ -264,19 +264,19 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
264
  } elseif (isset($this->SERVER['REQUEST_URI'])) {
265
  $requestUri = $this->SERVER['REQUEST_URI'];
266
  // Http proxy reqs setup request uri with scheme and host [and port] + the url path, only use url path
267
- $schemeAndHttpHost = $this->getScheme() . '://' . $this->getHttpHost();
268
  if (strpos($requestUri, $schemeAndHttpHost) === 0) {
269
  $requestUri = substr($requestUri, strlen($schemeAndHttpHost));
270
  }
271
  } elseif (isset($this->SERVER['ORIG_PATH_INFO'])) { // IIS 5.0, PHP as CGI
272
  $requestUri = $this->SERVER['ORIG_PATH_INFO'];
273
- if (!empty($this->SERVER['QUERY_STRING'])) {
274
- $requestUri .= '?' . $this->SERVER['QUERY_STRING'];
275
  }
276
  } else {
277
  return $this;
278
  }
279
- } elseif (!is_string($requestUri)) {
280
  return $this;
281
  } else {
282
  // Set GET items, if available
@@ -312,8 +312,8 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
312
  * @param mixed $baseUrl
313
  * @return Zend_Controller_Request_Http
314
  */
315
- public function setBaseUrl( $baseUrl=null ) {
316
- if ((null !== $baseUrl) && !is_string($baseUrl)) {
317
  return $this;
318
  }
319
 
@@ -338,7 +338,7 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
338
  $baseUrl = '';
339
  do {
340
  $seg = $segs[$index];
341
- $baseUrl = '/' . $seg . $baseUrl;
342
  ++$index;
343
  } while (($last > $index) && (false !== ($pos = strpos($path, $baseUrl))) && (0 != $pos));
344
  }
@@ -364,7 +364,7 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
364
  }
365
 
366
  $basename = basename($baseUrl);
367
- if (empty($basename) || !strpos($truncatedRequestUri, $basename)) {
368
  // no match whatsoever; set it blank
369
  $this->_baseUrl = '';
370
  return $this;
@@ -390,7 +390,7 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
390
  * @param string|null $basePath
391
  * @return Zend_Controller_Request_Http
392
  */
393
- public function setBasePath( $basePath=null ) {
394
  if ($basePath === null) {
395
  $filename = (isset($this->SERVER['SCRIPT_FILENAME']))
396
  ? basename($this->SERVER['SCRIPT_FILENAME'])
@@ -430,7 +430,7 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
430
  * @param mixed $default Default value to use if key not found
431
  * @return mixed
432
  */
433
- public function getParam( $key, $default=null ) {
434
  $keyName = (null !== ($alias = $this->getAlias($key))) ? $alias : $key;
435
 
436
  $paramSources = $this->getParamSources();
@@ -478,8 +478,8 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
478
  * @param bool $trimPort
479
  * @return string
480
  */
481
- public function getHttpHost( $trimPort=true ) {
482
- if (!isset($this->SERVER['HTTP_HOST'])) {
483
  return false;
484
  }
485
  if ($trimPort) {
@@ -497,11 +497,10 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
497
  *
498
  * @return Mage_Core_Controller_Request_Http
499
  */
500
- public function setPost( $key, $value=null ) {
501
  if (is_array($key)) {
502
  $this->POST = $key;
503
- }
504
- else {
505
  $this->POST[$key] = $value;
506
  }
507
  return $this;
@@ -525,30 +524,30 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
525
  * @param string $uri
526
  * @return null
527
  */
528
- protected function _fixupFakeSuperGlobals( $uri ) {
529
  $uri = str_replace('|', urlencode('|'), $uri);
530
- $parsedUrl = parse_url( $uri );
531
 
532
- if ( isset($parsedUrl['path']) ) {
533
  $this->SERVER['REQUEST_URI'] = $parsedUrl['path'];
534
  }
535
- if( isset( $parsedUrl['query'] ) && $parsedUrl['query'] ) {
536
  $this->SERVER['QUERY_STRING'] = $parsedUrl['query'];
537
- $this->SERVER['REQUEST_URI'] .= '?' . $this->SERVER['QUERY_STRING'];
538
  } else {
539
  $this->SERVER['QUERY_STRING'] = null;
540
  }
541
- parse_str( $this->SERVER['QUERY_STRING'], $this->GET );
542
- if( isset( $this->SERVER['SCRIPT_URI'] ) ) {
543
- $start = strpos( $this->SERVER['SCRIPT_URI'], '/', 9 );
544
- $sub = substr( $this->SERVER['SCRIPT_URI'], $start );
545
  $this->SERVER['SCRIPT_URI'] = substr(
546
- $this->SERVER['SCRIPT_URI'], 0, $start ) .
547
  @str_replace(
548
  $this->SERVER['SCRIPT_URL'], $parsedUrl['path'],
549
- $sub, $c=1 );
550
  }
551
- if( isset( $this->SERVER['SCRIPT_URL'] ) ) {
552
  $this->SERVER['SCRIPT_URL'] = $parsedUrl['path'];
553
  }
554
  }
@@ -563,14 +562,14 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
563
  * @return null
564
  */
565
  public function fakeRouterDispatch() {
566
- if( $this->_cmsRouterMatch() ) {
567
- Mage::helper( 'turpentine/debug' )->logDebug( 'Matched router: cms' );
568
- } elseif( $this->_standardRouterMatch() ) {
569
- Mage::helper( 'turpentine/debug' )->logDebug( 'Matched router: standard' );
570
- } elseif( $this->_defaultRouterMatch() ) {
571
- Mage::helper( 'turpentine/debug' )->logDebug( 'Matched router: default' );
572
  } else {
573
- Mage::helper( 'turpentine/debug' )->logDebug( 'No router match' );
574
  }
575
  }
576
 
@@ -586,7 +585,7 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
586
  $actionName = isset($noRoute[2]) ? $noRoute[2] : 'index';
587
 
588
  if (Mage::app()->getStore()->isAdmin()) {
589
- $adminFrontName = (string)Mage::getConfig()->getNode('admin/routers/adminhtml/args/frontName');
590
  if ($adminFrontName != $moduleName) {
591
  $moduleName = 'core';
592
  $controllerName = 'index';
@@ -608,7 +607,7 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
608
  * @return bool
609
  */
610
  protected function _standardRouterMatch() {
611
- $router = Mage::app()->getFrontController()->getRouter( 'standard' );
612
 
613
  // $router->fetchDefault();
614
 
@@ -626,14 +625,14 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
626
  if ($this->getModuleName()) {
627
  $module = $this->getModuleName();
628
  } else {
629
- if (!empty($p[0])) {
630
  $module = $p[0];
631
  } else {
632
  $module = $router->getFront()->getDefault('module');
633
  $this->setAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS, '');
634
  }
635
  }
636
- if (!$module) {
637
  if (Mage::app()->getStore()->isAdmin()) {
638
  $module = 'admin';
639
  } else {
@@ -661,7 +660,7 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
661
  if ($this->getControllerName()) {
662
  $controller = $this->getControllerName();
663
  } else {
664
- if (!empty($p[1])) {
665
  $controller = $p[1];
666
  } else {
667
  $controller = $front->getDefault('controller');
@@ -677,7 +676,7 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
677
  if ($this->getActionName()) {
678
  $action = $this->getActionName();
679
  } else {
680
- $action = !empty($p[2]) ? $p[2] : $front->getDefault('action');
681
  }
682
  }
683
 
@@ -685,21 +684,21 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
685
  // $router->_checkShouldBeSecure($this, '/'.$module.'/'.$controller.'/'.$action);
686
 
687
  // $controllerClassName = $router->_validateControllerClassName($realModule, $controller);
688
- $controllerClassName = $router->getControllerClassName( $realModule, $controller );
689
- if (!$controllerClassName) {
690
  continue;
691
  } else {
692
- $controllerFileName = $router->getControllerFileName( $realModule, $controller );
693
- if( !$router->validateControllerFileName( $controllerFileName ) ) {
694
  return false;
695
  }
696
- if (!class_exists($controllerClassName, false)) {
697
- if (!file_exists($controllerFileName)) {
698
  return false;
699
  }
700
  include_once $controllerFileName;
701
 
702
- if (!class_exists($controllerClassName, false)) {
703
  throw Mage::exception('Mage_Core', Mage::helper('core')->__('Controller file was loaded but class does not exist'));
704
  }
705
  }
@@ -708,7 +707,7 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
708
  // instantiate controller class
709
  $controllerInstance = Mage::getControllerInstance($controllerClassName, $this, $front->getResponse());
710
 
711
- if (!$controllerInstance->hasAction($action)) {
712
  continue;
713
  }
714
 
@@ -719,7 +718,7 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
719
  /**
720
  * if we did not found any suitable
721
  */
722
- if (!$found) {
723
  /*
724
  if ($router->_noRouteShouldBeApplied()) {
725
  $controller = 'index';
@@ -752,7 +751,7 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
752
 
753
  // set parameters from pathinfo
754
  for ($i = 3, $l = sizeof($p); $i < $l; $i += 2) {
755
- $this->setParam($p[$i], isset($p[$i+1]) ? urldecode($p[$i+1]) : '');
756
  }
757
 
758
  // dispatch action
@@ -768,7 +767,7 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
768
  * @return bool
769
  */
770
  protected function _cmsRouterMatch() {
771
- $router = Mage::app()->getFrontController()->getRouter( 'cms' );
772
 
773
  $identifier = trim($this->getPathInfo(), '/');
774
 
@@ -790,13 +789,13 @@ class Nexcessnet_Turpentine_Model_Dummy_Request extends
790
  return true;
791
  }
792
 
793
- if (!$condition->getContinue()) {
794
  return false;
795
  }
796
 
797
  $page = Mage::getModel('cms/page');
798
  $pageId = $page->checkIdentifier($identifier, Mage::app()->getStore()->getId());
799
- if (!$pageId) {
800
  return false;
801
  }
802
 
37
  * @return void
38
  * @throws Zend_Controller_Request_Exception when invalid URI passed
39
  */
40
+ public function __construct($uri = null) {
41
  $this->_initFakeSuperGlobals();
42
+ $this->_fixupFakeSuperGlobals($uri);
43
  try {
44
+ parent::__construct($uri);
45
+ } catch (Exception $e) {
46
+ Mage::helper('turpentine/debug')
47
+ ->logError('Bad URI given to dummy request: '.$uri);
48
+ Mage::helper('turpentine/debug')
49
  ->logBackTrace();
50
+ Mage::logException($e);
51
+ if (Mage::helper('turpentine/esi')->getEsiDebugEnabled()) {
52
  throw $e;
53
  }
54
  }
62
  * @param string $key
63
  * @return mixed
64
  */
65
+ public function __get($key) {
66
+ switch (true) {
67
+ case isset($this->_params[$key]):
68
  return $this->_params[$key];
69
+ case isset($this->GET[$key]):
70
  return $this->GET[$key];
71
+ case isset($this->POST[$key]):
72
  return $this->POST[$key];
73
+ case isset($_COOKIE[$key]):
74
  return $_COOKIE[$key];
75
  case ($key == 'REQUEST_URI'):
76
  return $this->getRequestUri();
77
  case ($key == 'PATH_INFO'):
78
  return $this->getPathInfo();
79
+ case isset($this->SERVER[$key]):
80
  return $this->SERVER[$key];
81
+ case isset($this->ENV[$key]):
82
  return $this->ENV[$key];
83
  default:
84
  return null;
91
  * @param string $key
92
  * @return boolean
93
  */
94
+ public function __isset($key) {
95
  switch (true) {
96
+ case isset($this->_params[$key]):
97
  return true;
98
+ case isset($this->GET[$key]):
99
  return true;
100
+ case isset($this->POST[$key]):
101
  return true;
102
+ case isset($_COOKIE[$key]):
103
  return true;
104
+ case isset($this->SERVER[$key]):
105
  return true;
106
+ case isset($this->ENV[$key]):
107
  return true;
108
  default:
109
  return false;
117
  * @param null|mixed $value
118
  * @return Zend_Controller_Request_Http
119
  */
120
+ public function setQuery($spec, $value = null) {
121
+ if ((null === $value) && ! is_array($spec)) {
122
  #require_once 'Zend/Controller/Exception.php';
123
  throw new Zend_Controller_Exception('Invalid value passed to setQuery(); must be either array of values or key/value pair');
124
  }
142
  * @param mixed $default Default value to use if key not found
143
  * @return mixed Returns null if key does not exist
144
  */
145
+ public function getQuery($key = null, $default = null) {
146
+ if (null === $key) {
147
  return $this->GET;
148
  }
149
+ return (isset($this->GET[$key])) ? $this->GET[$key] : $default;
150
  }
151
 
152
  /**
159
  * @param mixed $default Default value to use if key not found
160
  * @return mixed Returns null if key does not exist
161
  */
162
+ public function getPost($key = null, $default = null) {
163
  if (null === $key) {
164
  return $this->POST;
165
  }
176
  * @param mixed $default Default value to use if key not found
177
  * @return mixed Returns null if key does not exist
178
  */
179
+ public function getServer($key = null, $default = null) {
180
  if (null === $key) {
181
  return $this->SERVER;
182
  }
193
  * @param mixed $default Default value to use if key not found
194
  * @return mixed Returns null if key does not exist
195
  */
196
+ public function getEnv($key = null, $default = null) {
197
  if (null === $key) {
198
  return $this->ENV;
199
  }
210
  * @return string|false HTTP header value, or false if not found
211
  * @throws Zend_Controller_Request_Exception
212
  */
213
+ public function getHeader($header) {
214
  if (empty($header)) {
215
  #require_once 'Zend/Controller/Request/Exception.php';
216
  throw new Zend_Controller_Request_Exception('An HTTP header name is required');
217
  }
218
 
219
  // Try to get it from the $_SERVER array first
220
+ $temp = 'HTTP_'.strtoupper(str_replace('-', '_', $header));
221
  if (isset($this->SERVER[$temp])) {
222
  return $this->SERVER[$temp];
223
  }
249
  * @param string $requestUri
250
  * @return Zend_Controller_Request_Http
251
  */
252
+ public function setRequestUri($requestUri = null) {
253
  if ($requestUri === null) {
254
  if (isset($this->SERVER['HTTP_X_REWRITE_URL'])) { // check this first so IIS will catch
255
  $requestUri = $this->SERVER['HTTP_X_REWRITE_URL'];
264
  } elseif (isset($this->SERVER['REQUEST_URI'])) {
265
  $requestUri = $this->SERVER['REQUEST_URI'];
266
  // Http proxy reqs setup request uri with scheme and host [and port] + the url path, only use url path
267
+ $schemeAndHttpHost = $this->getScheme().'://'.$this->getHttpHost();
268
  if (strpos($requestUri, $schemeAndHttpHost) === 0) {
269
  $requestUri = substr($requestUri, strlen($schemeAndHttpHost));
270
  }
271
  } elseif (isset($this->SERVER['ORIG_PATH_INFO'])) { // IIS 5.0, PHP as CGI
272
  $requestUri = $this->SERVER['ORIG_PATH_INFO'];
273
+ if ( ! empty($this->SERVER['QUERY_STRING'])) {
274
+ $requestUri .= '?'.$this->SERVER['QUERY_STRING'];
275
  }
276
  } else {
277
  return $this;
278
  }
279
+ } elseif ( ! is_string($requestUri)) {
280
  return $this;
281
  } else {
282
  // Set GET items, if available
312
  * @param mixed $baseUrl
313
  * @return Zend_Controller_Request_Http
314
  */
315
+ public function setBaseUrl($baseUrl = null) {
316
+ if ((null !== $baseUrl) && ! is_string($baseUrl)) {
317
  return $this;
318
  }
319
 
338
  $baseUrl = '';
339
  do {
340
  $seg = $segs[$index];
341
+ $baseUrl = '/'.$seg.$baseUrl;
342
  ++$index;
343
  } while (($last > $index) && (false !== ($pos = strpos($path, $baseUrl))) && (0 != $pos));
344
  }
364
  }
365
 
366
  $basename = basename($baseUrl);
367
+ if (empty($basename) || ! strpos($truncatedRequestUri, $basename)) {
368
  // no match whatsoever; set it blank
369
  $this->_baseUrl = '';
370
  return $this;
390
  * @param string|null $basePath
391
  * @return Zend_Controller_Request_Http
392
  */
393
+ public function setBasePath($basePath = null) {
394
  if ($basePath === null) {
395
  $filename = (isset($this->SERVER['SCRIPT_FILENAME']))
396
  ? basename($this->SERVER['SCRIPT_FILENAME'])
430
  * @param mixed $default Default value to use if key not found
431
  * @return mixed
432
  */
433
+ public function getParam($key, $default = null) {
434
  $keyName = (null !== ($alias = $this->getAlias($key))) ? $alias : $key;
435
 
436
  $paramSources = $this->getParamSources();
478
  * @param bool $trimPort
479
  * @return string
480
  */
481
+ public function getHttpHost($trimPort = true) {
482
+ if ( ! isset($this->SERVER['HTTP_HOST'])) {
483
  return false;
484
  }
485
  if ($trimPort) {
497
  *
498
  * @return Mage_Core_Controller_Request_Http
499
  */
500
+ public function setPost($key, $value = null) {
501
  if (is_array($key)) {
502
  $this->POST = $key;
503
+ } else {
 
504
  $this->POST[$key] = $value;
505
  }
506
  return $this;
524
  * @param string $uri
525
  * @return null
526
  */
527
+ protected function _fixupFakeSuperGlobals($uri) {
528
  $uri = str_replace('|', urlencode('|'), $uri);
529
+ $parsedUrl = parse_url($uri);
530
 
531
+ if (isset($parsedUrl['path'])) {
532
  $this->SERVER['REQUEST_URI'] = $parsedUrl['path'];
533
  }
534
+ if (isset($parsedUrl['query']) && $parsedUrl['query']) {
535
  $this->SERVER['QUERY_STRING'] = $parsedUrl['query'];
536
+ $this->SERVER['REQUEST_URI'] .= '?'.$this->SERVER['QUERY_STRING'];
537
  } else {
538
  $this->SERVER['QUERY_STRING'] = null;
539
  }
540
+ parse_str($this->SERVER['QUERY_STRING'], $this->GET);
541
+ if (isset($this->SERVER['SCRIPT_URI'])) {
542
+ $start = strpos($this->SERVER['SCRIPT_URI'], '/', 9);
543
+ $sub = substr($this->SERVER['SCRIPT_URI'], $start);
544
  $this->SERVER['SCRIPT_URI'] = substr(
545
+ $this->SERVER['SCRIPT_URI'], 0, $start ).
546
  @str_replace(
547
  $this->SERVER['SCRIPT_URL'], $parsedUrl['path'],
548
+ $sub, $c = 1 );
549
  }
550
+ if (isset($this->SERVER['SCRIPT_URL'])) {
551
  $this->SERVER['SCRIPT_URL'] = $parsedUrl['path'];
552
  }
553
  }
562
  * @return null
563
  */
564
  public function fakeRouterDispatch() {
565
+ if ($this->_cmsRouterMatch()) {
566
+ Mage::helper('turpentine/debug')->logDebug('Matched router: cms');
567
+ } elseif ($this->_standardRouterMatch()) {
568
+ Mage::helper('turpentine/debug')->logDebug('Matched router: standard');
569
+ } elseif ($this->_defaultRouterMatch()) {
570
+ Mage::helper('turpentine/debug')->logDebug('Matched router: default');
571
  } else {
572
+ Mage::helper('turpentine/debug')->logDebug('No router match');
573
  }
574
  }
575
 
585
  $actionName = isset($noRoute[2]) ? $noRoute[2] : 'index';
586
 
587
  if (Mage::app()->getStore()->isAdmin()) {
588
+ $adminFrontName = (string) Mage::getConfig()->getNode('admin/routers/adminhtml/args/frontName');
589
  if ($adminFrontName != $moduleName) {
590
  $moduleName = 'core';
591
  $controllerName = 'index';
607
  * @return bool
608
  */
609
  protected function _standardRouterMatch() {
610
+ $router = Mage::app()->getFrontController()->getRouter('standard');
611
 
612
  // $router->fetchDefault();
613
 
625
  if ($this->getModuleName()) {
626
  $module = $this->getModuleName();
627
  } else {
628
+ if ( ! empty($p[0])) {
629
  $module = $p[0];
630
  } else {
631
  $module = $router->getFront()->getDefault('module');
632
  $this->setAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS, '');
633
  }
634
  }
635
+ if ( ! $module) {
636
  if (Mage::app()->getStore()->isAdmin()) {
637
  $module = 'admin';
638
  } else {
660
  if ($this->getControllerName()) {
661
  $controller = $this->getControllerName();
662
  } else {
663
+ if ( ! empty($p[1])) {
664
  $controller = $p[1];
665
  } else {
666
  $controller = $front->getDefault('controller');
676
  if ($this->getActionName()) {
677
  $action = $this->getActionName();
678
  } else {
679
+ $action = ! empty($p[2]) ? $p[2] : $front->getDefault('action');
680
  }
681
  }
682
 
684
  // $router->_checkShouldBeSecure($this, '/'.$module.'/'.$controller.'/'.$action);
685
 
686
  // $controllerClassName = $router->_validateControllerClassName($realModule, $controller);
687
+ $controllerClassName = $router->getControllerClassName($realModule, $controller);
688
+ if ( ! $controllerClassName) {
689
  continue;
690
  } else {
691
+ $controllerFileName = $router->getControllerFileName($realModule, $controller);
692
+ if ( ! $router->validateControllerFileName($controllerFileName)) {
693
  return false;
694
  }
695
+ if ( ! class_exists($controllerClassName, false)) {
696
+ if ( ! file_exists($controllerFileName)) {
697
  return false;
698
  }
699
  include_once $controllerFileName;
700
 
701
+ if ( ! class_exists($controllerClassName, false)) {
702
  throw Mage::exception('Mage_Core', Mage::helper('core')->__('Controller file was loaded but class does not exist'));
703
  }
704
  }
707
  // instantiate controller class
708
  $controllerInstance = Mage::getControllerInstance($controllerClassName, $this, $front->getResponse());
709
 
710
+ if ( ! $controllerInstance->hasAction($action)) {
711
  continue;
712
  }
713
 
718
  /**
719
  * if we did not found any suitable
720
  */
721
+ if ( ! $found) {
722
  /*
723
  if ($router->_noRouteShouldBeApplied()) {
724
  $controller = 'index';
751
 
752
  // set parameters from pathinfo
753
  for ($i = 3, $l = sizeof($p); $i < $l; $i += 2) {
754
+ $this->setParam($p[$i], isset($p[$i + 1]) ? urldecode($p[$i + 1]) : '');
755
  }
756
 
757
  // dispatch action
767
  * @return bool
768
  */
769
  protected function _cmsRouterMatch() {
770
+ $router = Mage::app()->getFrontController()->getRouter('cms');
771
 
772
  $identifier = trim($this->getPathInfo(), '/');
773
 
789
  return true;
790
  }
791
 
792
+ if ( ! $condition->getContinue()) {
793
  return false;
794
  }
795
 
796
  $page = Mage::getModel('cms/page');
797
  $pageId = $page->checkIdentifier($identifier, Mage::app()->getStore()->getId());
798
+ if ( ! $pageId) {
799
  return false;
800
  }
801
 
app/code/community/Nexcessnet/Turpentine/Model/Observer/Ban.php CHANGED
@@ -29,12 +29,12 @@ class Nexcessnet_Turpentine_Model_Observer_Ban extends Varien_Event_Observer {
29
  * Cache the varnish admin object
30
  * @var Nexcessnet_Turpentine_Model_Varnish_Admin
31
  */
32
- protected $_varnishAdmin = null;
33
  /**
34
  * Flag to prevent doing the ESI cache clear more than once per request
35
  * @var boolean
36
  */
37
- protected $_esiClearFlag = array();
38
 
39
  /**
40
  * Clear the ESI block cache for a specific client
@@ -46,23 +46,23 @@ class Nexcessnet_Turpentine_Model_Observer_Ban extends Varien_Event_Observer {
46
  * @param Varien_Object $eventObject
47
  * @return null
48
  */
49
- public function banClientEsiCache( $eventObject ) {
50
  $eventName = $eventObject->getEvent()->getName();
51
- if( Mage::helper( 'turpentine/esi' )->getEsiEnabled() &&
52
- !in_array( $eventName, $this->_esiClearFlag ) ) {
53
- $sessionId = Mage::app()->getRequest()->getCookie( 'frontend' );
54
- if( $sessionId ) {
55
  $result = $this->_getVarnishAdmin()->flushExpression(
56
  'obj.http.X-Varnish-Session', '==', $sessionId,
57
  '&&', 'obj.http.X-Turpentine-Flush-Events', '~',
58
  $eventName );
59
- Mage::dispatchEvent( 'turpentine_ban_client_esi_cache', $result );
60
- if( $this->_checkResult( $result ) ) {
61
- Mage::helper( 'turpentine/debug' )
62
- ->logDebug( 'Cleared ESI cache for client (%s) on event: %s',
63
- $sessionId, $eventName );
64
  } else {
65
- Mage::helper( 'turpentine/debug' )
66
  ->logWarn(
67
  'Failed to clear Varnish ESI cache for client: %s',
68
  $sessionId );
@@ -81,20 +81,20 @@ class Nexcessnet_Turpentine_Model_Observer_Ban extends Varien_Event_Observer {
81
  * @param Varien_Object $eventObject
82
  * @return null
83
  */
84
- public function banProductPageCache( $eventObject ) {
85
- if( Mage::helper( 'turpentine/varnish' )->getVarnishEnabled() ) {
86
- $banHelper = Mage::helper( 'turpentine/ban' );
87
  $product = $eventObject->getProduct();
88
- $urlPattern = $banHelper->getProductBanRegex( $product );
89
- $result = $this->_getVarnishAdmin()->flushUrl( $urlPattern );
90
- Mage::dispatchEvent( 'turpentine_ban_product_cache', $result );
91
- $cronHelper = Mage::helper( 'turpentine/cron' );
92
- if( $this->_checkResult( $result ) &&
93
- $cronHelper->getCrawlerEnabled() ) {
94
- $cronHelper->addProductToCrawlerQueue( $product );
95
- foreach( $banHelper->getParentProducts( $product )
96
- as $parentProduct ) {
97
- $cronHelper->addProductToCrawlerQueue( $parentProduct );
98
  }
99
  }
100
  }
@@ -109,27 +109,27 @@ class Nexcessnet_Turpentine_Model_Observer_Ban extends Varien_Event_Observer {
109
  * @param Varien_Object $eventObject
110
  * @return null
111
  */
112
- public function banProductPageCacheCheckStock( $eventObject ) {
113
- if( Mage::helper( 'turpentine/varnish' )->getVarnishEnabled() ) {
114
  $item = $eventObject->getItem();
115
- if( $item->getStockStatusChangedAutomatically() ||
116
- ( $item->getOriginalInventoryQty() <= 0 &&
117
  $item->getQty() > 0 &&
118
- $item->getQtyCorrection() > 0 ) ) {
119
- $banHelper = Mage::helper( 'turpentine/ban' );
120
- $cronHelper = Mage::helper( 'turpentine/cron' );
121
- $product = Mage::getModel( 'catalog/product' )
122
- ->load( $item->getProductId() );
123
- $urlPattern = $banHelper->getProductBanRegex( $product );
124
- $result = $this->_getVarnishAdmin()->flushUrl( $urlPattern );
125
- Mage::dispatchEvent( 'turpentine_ban_product_cache_check_stock',
126
- $result );
127
- if( $this->_checkResult( $result ) &&
128
- $cronHelper->getCrawlerEnabled() ) {
129
- $cronHelper->addProductToCrawlerQueue( $product );
130
- foreach( $banHelper->getParentProducts( $product )
131
- as $parentProduct ) {
132
- $cronHelper->addProductToCrawlerQueue( $parentProduct );
133
  }
134
  }
135
  }
@@ -145,15 +145,15 @@ class Nexcessnet_Turpentine_Model_Observer_Ban extends Varien_Event_Observer {
145
  * @param Varien_Object $eventObject
146
  * @return null
147
  */
148
- public function banCategoryCache( $eventObject ) {
149
- if( Mage::helper( 'turpentine/varnish' )->getVarnishEnabled() ) {
150
  $category = $eventObject->getCategory();
151
- $result = $this->_getVarnishAdmin()->flushUrl( $category->getUrlKey() );
152
- Mage::dispatchEvent( 'turpentine_ban_category_cache', $result );
153
- $cronHelper = Mage::helper( 'turpentine/cron' );
154
- if( $this->_checkResult( $result ) &&
155
- $cronHelper->getCrawlerEnabled() ) {
156
- $cronHelper->addCategoryToCrawlerQueue( $category );
157
  }
158
  }
159
  }
@@ -168,11 +168,11 @@ class Nexcessnet_Turpentine_Model_Observer_Ban extends Varien_Event_Observer {
168
  * @param Varien_Object $eventObject
169
  * @return null
170
  */
171
- public function banMediaCache( $eventObject ) {
172
- if( Mage::helper( 'turpentine/varnish' )->getVarnishEnabled() ) {
173
- $result = $this->_getVarnishAdmin()->flushUrl( 'media/(?:js|css)/' );
174
- Mage::dispatchEvent( 'turpentine_ban_media_cache', $result );
175
- $this->_checkResult( $result );
176
  }
177
  }
178
 
@@ -186,12 +186,12 @@ class Nexcessnet_Turpentine_Model_Observer_Ban extends Varien_Event_Observer {
186
  * @param Varien_Object $eventObject
187
  * @return null
188
  */
189
- public function banCatalogImagesCache( $eventObject ) {
190
- if( Mage::helper( 'turpentine/varnish' )->getVarnishEnabled() ) {
191
  $result = $this->_getVarnishAdmin()->flushUrl(
192
  'media/catalog/product/cache/' );
193
- Mage::dispatchEvent( 'turpentine_ban_catalog_images_cache', $result );
194
- $this->_checkResult( $result );
195
  }
196
  }
197
 
@@ -204,15 +204,15 @@ class Nexcessnet_Turpentine_Model_Observer_Ban extends Varien_Event_Observer {
204
  * @param Varien_Object $eventObject
205
  * @return null
206
  */
207
- public function banCmsPageCache( $eventObject ) {
208
- if( Mage::helper( 'turpentine/varnish' )->getVarnishEnabled() ) {
209
  $pageId = $eventObject->getDataObject()->getIdentifier();
210
- $result = $this->_getVarnishAdmin()->flushUrl( $pageId . '(?:\.html?)?$' );
211
- Mage::dispatchEvent( 'turpentine_ban_cms_page_cache', $result );
212
- $cronHelper = Mage::helper( 'turpentine/cron' );
213
- if( $this->_checkResult( $result ) &&
214
- $cronHelper->getCrawlerEnabled() ) {
215
- $cronHelper->addCmsPageToCrawlerQueue( $pageId );
216
  }
217
  }
218
  }
@@ -226,21 +226,21 @@ class Nexcessnet_Turpentine_Model_Observer_Ban extends Varien_Event_Observer {
226
  * @return null
227
  */
228
  public function banCmsPageRevisionCache($eventObject) {
229
- if ( Mage::helper( 'turpentine/varnish' )->getVarnishEnabled() ) {
230
  $pageId = $eventObject->getDataObject()->getPageId();
231
- $page = Mage::getModel( 'cms/page' )->load( $pageId );
232
 
233
  // Don't do anything if the page isn't found.
234
- if( !$page ) {
235
  return;
236
  }
237
  $pageIdentifier = $page->getIdentifier();
238
- $result = $this->_getVarnishAdmin()->flushUrl( $pageIdentifier . '(?:\.html?)?$' );
239
- Mage::dispatchEvent( 'turpentine_ban_cms_page_cache', $result );
240
- $cronHelper = Mage::helper( 'turpentine/cron' );
241
- if( $this->_checkResult( $result ) &&
242
- $cronHelper->getCrawlerEnabled() ) {
243
- $cronHelper->addCmsPageToCrawlerQueue( $pageIdentifier );
244
  }
245
  }
246
  }
@@ -256,11 +256,11 @@ class Nexcessnet_Turpentine_Model_Observer_Ban extends Varien_Event_Observer {
256
  * @param Varien_Object $eventObject
257
  * @return null
258
  */
259
- public function banAllCache( $eventObject ) {
260
- if( Mage::helper( 'turpentine/varnish' )->getVarnishEnabled() ) {
261
  $result = $this->_getVarnishAdmin()->flushAll();
262
- Mage::dispatchEvent( 'turpentine_ban_all_cache', $result );
263
- $this->_checkResult( $result );
264
  }
265
  }
266
 
@@ -273,20 +273,20 @@ class Nexcessnet_Turpentine_Model_Observer_Ban extends Varien_Event_Observer {
273
  * @param Varien_Object $eventObject
274
  * @return null
275
  */
276
- public function banCacheType( $eventObject ) {
277
- switch( $eventObject->getType() ) {
278
  //note this is the name of the container xml tag in config.xml,
279
  // **NOT** the cache tag name
280
- case Mage::helper( 'turpentine/esi' )->getMageCacheName():
281
- if( Mage::helper( 'turpentine/esi' )->getEsiEnabled() ) {
282
  $result = $this->_getVarnishAdmin()->flushUrl(
283
  '/turpentine/esi/getBlock/' );
284
- Mage::dispatchEvent( 'turpentine_ban_esi_cache', $result );
285
- $this->_checkResult( $result );
286
  }
287
  break;
288
- case Mage::helper( 'turpentine/varnish' )->getMageCacheName():
289
- $this->banAllCache( $eventObject );
290
  break;
291
  }
292
  }
@@ -297,7 +297,7 @@ class Nexcessnet_Turpentine_Model_Observer_Ban extends Varien_Event_Observer {
297
  * @param Varien_Object $eventObject
298
  * @return bool
299
  */
300
- public function banProductReview( $eventObject ) {
301
  $patterns = array();
302
  /* @var $review \Mage_Review_Model_Review*/
303
  $review = $eventObject->getObject();
@@ -305,30 +305,30 @@ class Nexcessnet_Turpentine_Model_Observer_Ban extends Varien_Event_Observer {
305
  /* @var $productCollection \Mage_Review_Model_Resource_Review_Product_Collection*/
306
  $productCollection = $review->getProductCollection();
307
 
308
- $products = $productCollection->addEntityFilter((int)$review->getEntityPkValue())->getItems();
309
 
310
- $productIds = array_unique( array_map(
311
- create_function( '$p', 'return $p->getEntityId();' ),
312
- $products ) );
313
- $patterns[] = sprintf( '/review/product/list/id/(?:%s)/category/',
314
- implode( '|', array_unique( $productIds ) ) );
315
- $patterns[] = sprintf( '/review/product/view/id/%d/',
316
- $review->getEntityId() );
317
  $productPatterns = array();
318
- foreach ( $products as $p ) {
319
- $urlKey = $p->getUrlModel()->formatUrlKey( $p->getName() );
320
- if ( $urlKey ) {
321
  $productPatterns[] = $urlKey;
322
  }
323
  }
324
- if ( !empty($productPatterns) ) {
325
- $productPatterns = array_unique( $productPatterns );
326
- $patterns[] = sprintf( '(?:%s)', implode( '|', $productPatterns ) );
327
  }
328
- $urlPattern = implode( '|', $patterns );
329
 
330
- $result = $this->_getVarnishAdmin()->flushUrl( $urlPattern );
331
- return $this->_checkResult( $result );
332
  }
333
 
334
  /**
@@ -337,11 +337,11 @@ class Nexcessnet_Turpentine_Model_Observer_Ban extends Varien_Event_Observer {
337
  * @param array $result stored as $socketName => $result
338
  * @return bool
339
  */
340
- protected function _checkResult( $result ) {
341
  $rvalue = true;
342
- foreach( $result as $socketName => $value ) {
343
- if( $value !== true ) {
344
- Mage::helper( 'turpentine/debug' )->logWarn(
345
  'Error in Varnish action result for server [%s]: %s',
346
  $socketName, $value );
347
  $rvalue = false;
@@ -356,8 +356,8 @@ class Nexcessnet_Turpentine_Model_Observer_Ban extends Varien_Event_Observer {
356
  * @return Nexcessnet_Turpentine_Model_Varnish_Admin
357
  */
358
  protected function _getVarnishAdmin() {
359
- if( is_null( $this->_varnishAdmin ) ) {
360
- $this->_varnishAdmin = Mage::getModel( 'turpentine/varnish_admin' );
361
  }
362
  return $this->_varnishAdmin;
363
  }
29
  * Cache the varnish admin object
30
  * @var Nexcessnet_Turpentine_Model_Varnish_Admin
31
  */
32
+ protected $_varnishAdmin = null;
33
  /**
34
  * Flag to prevent doing the ESI cache clear more than once per request
35
  * @var boolean
36
  */
37
+ protected $_esiClearFlag = array();
38
 
39
  /**
40
  * Clear the ESI block cache for a specific client
46
  * @param Varien_Object $eventObject
47
  * @return null
48
  */
49
+ public function banClientEsiCache($eventObject) {
50
  $eventName = $eventObject->getEvent()->getName();
51
+ if (Mage::helper('turpentine/esi')->getEsiEnabled() &&
52
+ ! in_array($eventName, $this->_esiClearFlag)) {
53
+ $sessionId = Mage::app()->getRequest()->getCookie('frontend');
54
+ if ($sessionId) {
55
  $result = $this->_getVarnishAdmin()->flushExpression(
56
  'obj.http.X-Varnish-Session', '==', $sessionId,
57
  '&&', 'obj.http.X-Turpentine-Flush-Events', '~',
58
  $eventName );
59
+ Mage::dispatchEvent('turpentine_ban_client_esi_cache', $result);
60
+ if ($this->_checkResult($result)) {
61
+ Mage::helper('turpentine/debug')
62
+ ->logDebug('Cleared ESI cache for client (%s) on event: %s',
63
+ $sessionId, $eventName);
64
  } else {
65
+ Mage::helper('turpentine/debug')
66
  ->logWarn(
67
  'Failed to clear Varnish ESI cache for client: %s',
68
  $sessionId );
81
  * @param Varien_Object $eventObject
82
  * @return null
83
  */
84
+ public function banProductPageCache($eventObject) {
85
+ if (Mage::helper('turpentine/varnish')->getVarnishEnabled()) {
86
+ $banHelper = Mage::helper('turpentine/ban');
87
  $product = $eventObject->getProduct();
88
+ $urlPattern = $banHelper->getProductBanRegex($product);
89
+ $result = $this->_getVarnishAdmin()->flushUrl($urlPattern);
90
+ Mage::dispatchEvent('turpentine_ban_product_cache', $result);
91
+ $cronHelper = Mage::helper('turpentine/cron');
92
+ if ($this->_checkResult($result) &&
93
+ $cronHelper->getCrawlerEnabled()) {
94
+ $cronHelper->addProductToCrawlerQueue($product);
95
+ foreach ($banHelper->getParentProducts($product)
96
+ as $parentProduct) {
97
+ $cronHelper->addProductToCrawlerQueue($parentProduct);
98
  }
99
  }
100
  }
109
  * @param Varien_Object $eventObject
110
  * @return null
111
  */
112
+ public function banProductPageCacheCheckStock($eventObject) {
113
+ if (Mage::helper('turpentine/varnish')->getVarnishEnabled()) {
114
  $item = $eventObject->getItem();
115
+ if ($item->getStockStatusChangedAutomatically() ||
116
+ ($item->getOriginalInventoryQty() <= 0 &&
117
  $item->getQty() > 0 &&
118
+ $item->getQtyCorrection() > 0)) {
119
+ $banHelper = Mage::helper('turpentine/ban');
120
+ $cronHelper = Mage::helper('turpentine/cron');
121
+ $product = Mage::getModel('catalog/product')
122
+ ->load($item->getProductId());
123
+ $urlPattern = $banHelper->getProductBanRegex($product);
124
+ $result = $this->_getVarnishAdmin()->flushUrl($urlPattern);
125
+ Mage::dispatchEvent('turpentine_ban_product_cache_check_stock',
126
+ $result);
127
+ if ($this->_checkResult($result) &&
128
+ $cronHelper->getCrawlerEnabled()) {
129
+ $cronHelper->addProductToCrawlerQueue($product);
130
+ foreach ($banHelper->getParentProducts($product)
131
+ as $parentProduct) {
132
+ $cronHelper->addProductToCrawlerQueue($parentProduct);
133
  }
134
  }
135
  }
145
  * @param Varien_Object $eventObject
146
  * @return null
147
  */
148
+ public function banCategoryCache($eventObject) {
149
+ if (Mage::helper('turpentine/varnish')->getVarnishEnabled()) {
150
  $category = $eventObject->getCategory();
151
+ $result = $this->_getVarnishAdmin()->flushUrl($category->getUrlKey());
152
+ Mage::dispatchEvent('turpentine_ban_category_cache', $result);
153
+ $cronHelper = Mage::helper('turpentine/cron');
154
+ if ($this->_checkResult($result) &&
155
+ $cronHelper->getCrawlerEnabled()) {
156
+ $cronHelper->addCategoryToCrawlerQueue($category);
157
  }
158
  }
159
  }
168
  * @param Varien_Object $eventObject
169
  * @return null
170
  */
171
+ public function banMediaCache($eventObject) {
172
+ if (Mage::helper('turpentine/varnish')->getVarnishEnabled()) {
173
+ $result = $this->_getVarnishAdmin()->flushUrl('media/(?:js|css)/');
174
+ Mage::dispatchEvent('turpentine_ban_media_cache', $result);
175
+ $this->_checkResult($result);
176
  }
177
  }
178
 
186
  * @param Varien_Object $eventObject
187
  * @return null
188
  */
189
+ public function banCatalogImagesCache($eventObject) {
190
+ if (Mage::helper('turpentine/varnish')->getVarnishEnabled()) {
191
  $result = $this->_getVarnishAdmin()->flushUrl(
192
  'media/catalog/product/cache/' );
193
+ Mage::dispatchEvent('turpentine_ban_catalog_images_cache', $result);
194
+ $this->_checkResult($result);
195
  }
196
  }
197
 
204
  * @param Varien_Object $eventObject
205
  * @return null
206
  */
207
+ public function banCmsPageCache($eventObject) {
208
+ if (Mage::helper('turpentine/varnish')->getVarnishEnabled()) {
209
  $pageId = $eventObject->getDataObject()->getIdentifier();
210
+ $result = $this->_getVarnishAdmin()->flushUrl($pageId.'(?:\.html?)?\/?$');
211
+ Mage::dispatchEvent('turpentine_ban_cms_page_cache', $result);
212
+ $cronHelper = Mage::helper('turpentine/cron');
213
+ if ($this->_checkResult($result) &&
214
+ $cronHelper->getCrawlerEnabled()) {
215
+ $cronHelper->addCmsPageToCrawlerQueue($pageId);
216
  }
217
  }
218
  }
226
  * @return null
227
  */
228
  public function banCmsPageRevisionCache($eventObject) {
229
+ if (Mage::helper('turpentine/varnish')->getVarnishEnabled()) {
230
  $pageId = $eventObject->getDataObject()->getPageId();
231
+ $page = Mage::getModel('cms/page')->load($pageId);
232
 
233
  // Don't do anything if the page isn't found.
234
+ if ( ! $page) {
235
  return;
236
  }
237
  $pageIdentifier = $page->getIdentifier();
238
+ $result = $this->_getVarnishAdmin()->flushUrl($pageIdentifier.'(?:\.html?)?$');
239
+ Mage::dispatchEvent('turpentine_ban_cms_page_cache', $result);
240
+ $cronHelper = Mage::helper('turpentine/cron');
241
+ if ($this->_checkResult($result) &&
242
+ $cronHelper->getCrawlerEnabled()) {
243
+ $cronHelper->addCmsPageToCrawlerQueue($pageIdentifier);
244
  }
245
  }
246
  }
256
  * @param Varien_Object $eventObject
257
  * @return null
258
  */
259
+ public function banAllCache($eventObject) {
260
+ if (Mage::helper('turpentine/varnish')->getVarnishEnabled()) {
261
  $result = $this->_getVarnishAdmin()->flushAll();
262
+ Mage::dispatchEvent('turpentine_ban_all_cache', $result);
263
+ $this->_checkResult($result);
264
  }
265
  }
266
 
273
  * @param Varien_Object $eventObject
274
  * @return null
275
  */
276
+ public function banCacheType($eventObject) {
277
+ switch ($eventObject->getType()) {
278
  //note this is the name of the container xml tag in config.xml,
279
  // **NOT** the cache tag name
280
+ case Mage::helper('turpentine/esi')->getMageCacheName():
281
+ if (Mage::helper('turpentine/esi')->getEsiEnabled()) {
282
  $result = $this->_getVarnishAdmin()->flushUrl(
283
  '/turpentine/esi/getBlock/' );
284
+ Mage::dispatchEvent('turpentine_ban_esi_cache', $result);
285
+ $this->_checkResult($result);
286
  }
287
  break;
288
+ case Mage::helper('turpentine/varnish')->getMageCacheName():
289
+ $this->banAllCache($eventObject);
290
  break;
291
  }
292
  }
297
  * @param Varien_Object $eventObject
298
  * @return bool
299
  */
300
+ public function banProductReview($eventObject) {
301
  $patterns = array();
302
  /* @var $review \Mage_Review_Model_Review*/
303
  $review = $eventObject->getObject();
305
  /* @var $productCollection \Mage_Review_Model_Resource_Review_Product_Collection*/
306
  $productCollection = $review->getProductCollection();
307
 
308
+ $products = $productCollection->addEntityFilter((int) $review->getEntityPkValue())->getItems();
309
 
310
+ $productIds = array_unique(array_map(
311
+ create_function('$p', 'return $p->getEntityId();'),
312
+ $products ));
313
+ $patterns[] = sprintf('/review/product/list/id/(?:%s)/category/',
314
+ implode('|', array_unique($productIds)));
315
+ $patterns[] = sprintf('/review/product/view/id/%d/',
316
+ $review->getEntityId());
317
  $productPatterns = array();
318
+ foreach ($products as $p) {
319
+ $urlKey = $p->getUrlModel()->formatUrlKey($p->getName());
320
+ if ($urlKey) {
321
  $productPatterns[] = $urlKey;
322
  }
323
  }
324
+ if ( ! empty($productPatterns)) {
325
+ $productPatterns = array_unique($productPatterns);
326
+ $patterns[] = sprintf('(?:%s)', implode('|', $productPatterns));
327
  }
328
+ $urlPattern = implode('|', $patterns);
329
 
330
+ $result = $this->_getVarnishAdmin()->flushUrl($urlPattern);
331
+ return $this->_checkResult($result);
332
  }
333
 
334
  /**
337
  * @param array $result stored as $socketName => $result
338
  * @return bool
339
  */
340
+ protected function _checkResult($result) {
341
  $rvalue = true;
342
+ foreach ($result as $socketName => $value) {
343
+ if ($value !== true) {
344
+ Mage::helper('turpentine/debug')->logWarn(
345
  'Error in Varnish action result for server [%s]: %s',
346
  $socketName, $value );
347
  $rvalue = false;
356
  * @return Nexcessnet_Turpentine_Model_Varnish_Admin
357
  */
358
  protected function _getVarnishAdmin() {
359
+ if (is_null($this->_varnishAdmin)) {
360
+ $this->_varnishAdmin = Mage::getModel('turpentine/varnish_admin');
361
  }
362
  return $this->_varnishAdmin;
363
  }
app/code/community/Nexcessnet/Turpentine/Model/Observer/Cron.php CHANGED
@@ -26,14 +26,14 @@ class Nexcessnet_Turpentine_Model_Observer_Cron extends Varien_Event_Observer {
26
  *
27
  * @var int
28
  */
29
- const MAX_CRAWL_TIME = 300;
30
 
31
  /**
32
  * Amount of time of execution time to leave for other cron processes
33
  *
34
  * @var int
35
  */
36
- const EXEC_TIME_BUFFER = 15;
37
 
38
  /**
39
  * Crawl available URLs in the queue until we get close to max_execution_time
@@ -42,19 +42,19 @@ class Nexcessnet_Turpentine_Model_Observer_Cron extends Varien_Event_Observer {
42
  * @param Varien_Object $eventObject
43
  * @return null
44
  */
45
- public function crawlUrls( $eventObject ) {
46
- $helper = Mage::helper( 'turpentine/cron' );
47
- if( $helper->getCrawlerEnabled() ) {
48
  $maxRunTime = $helper->getAllowedRunTime();
49
- if( $maxRunTime === 0 ) {
50
  $maxRunTime = self::MAX_CRAWL_TIME;
51
  }
52
  // just in case we have a silly short max_execution_time
53
- $maxRunTime = abs( $maxRunTime - self::EXEC_TIME_BUFFER );
54
- while( ( $helper->getRunTime() < $maxRunTime ) &&
55
- $url = $helper->getNextUrl() ) {
56
- if( !$this->_crawlUrl( $url ) ) {
57
- Mage::helper( 'turpentine/debug' )->logWarn(
58
  'Failed to crawl URL: %s', $url );
59
  }
60
  }
@@ -67,10 +67,10 @@ class Nexcessnet_Turpentine_Model_Observer_Cron extends Varien_Event_Observer {
67
  * @param Varien_Object $eventObject
68
  * @return null
69
  */
70
- public function queueAllUrls( $eventObject ) {
71
- $helper = Mage::helper( 'turpentine/cron' );
72
- if( $helper->getCrawlerEnabled() ) {
73
- $helper->addUrlsToCrawlerQueue( $helper->getAllUrls() );
74
  }
75
  }
76
 
@@ -80,14 +80,14 @@ class Nexcessnet_Turpentine_Model_Observer_Cron extends Varien_Event_Observer {
80
  * @param string $url
81
  * @return bool
82
  */
83
- protected function _crawlUrl( $url ) {
84
- $client = Mage::helper( 'turpentine/cron' )->getCrawlerClient();
85
- $client->setUri( $url );
86
- Mage::helper( 'turpentine/debug' )->logDebug( 'Crawling URL: %s', $url );
87
  try {
88
  $response = $client->request();
89
- } catch( Exception $e ) {
90
- Mage::helper( 'turpentine/debug' )->logWarn(
91
  'Error crawling URL (%s): %s',
92
  $url, $e->getMessage() );
93
  return false;
26
  *
27
  * @var int
28
  */
29
+ const MAX_CRAWL_TIME = 300;
30
 
31
  /**
32
  * Amount of time of execution time to leave for other cron processes
33
  *
34
  * @var int
35
  */
36
+ const EXEC_TIME_BUFFER = 15;
37
 
38
  /**
39
  * Crawl available URLs in the queue until we get close to max_execution_time
42
  * @param Varien_Object $eventObject
43
  * @return null
44
  */
45
+ public function crawlUrls($eventObject) {
46
+ $helper = Mage::helper('turpentine/cron');
47
+ if ($helper->getCrawlerEnabled()) {
48
  $maxRunTime = $helper->getAllowedRunTime();
49
+ if ($maxRunTime === 0) {
50
  $maxRunTime = self::MAX_CRAWL_TIME;
51
  }
52
  // just in case we have a silly short max_execution_time
53
+ $maxRunTime = abs($maxRunTime - self::EXEC_TIME_BUFFER);
54
+ while (($helper->getRunTime() < $maxRunTime) &&
55
+ $url = $helper->getNextUrl()) {
56
+ if ( ! $this->_crawlUrl($url)) {
57
+ Mage::helper('turpentine/debug')->logWarn(
58
  'Failed to crawl URL: %s', $url );
59
  }
60
  }
67
  * @param Varien_Object $eventObject
68
  * @return null
69
  */
70
+ public function queueAllUrls($eventObject) {
71
+ $helper = Mage::helper('turpentine/cron');
72
+ if ($helper->getCrawlerEnabled()) {
73
+ $helper->addUrlsToCrawlerQueue($helper->getAllUrls());
74
  }
75
  }
76
 
80
  * @param string $url
81
  * @return bool
82
  */
83
+ protected function _crawlUrl($url) {
84
+ $client = Mage::helper('turpentine/cron')->getCrawlerClient();
85
+ $client->setUri($url);
86
+ Mage::helper('turpentine/debug')->logDebug('Crawling URL: %s', $url);
87
  try {
88
  $response = $client->request();
89
+ } catch (Exception $e) {
90
+ Mage::helper('turpentine/debug')->logWarn(
91
  'Error crawling URL (%s): %s',
92
  $url, $e->getMessage() );
93
  return false;
app/code/community/Nexcessnet/Turpentine/Model/Observer/Debug.php CHANGED
@@ -27,9 +27,9 @@ class Nexcessnet_Turpentine_Model_Observer_Debug extends Varien_Event_Observer {
27
  * @param Varien_Object $eventObject
28
  * @return null
29
  */
30
- public function logEvent( $eventObject ) {
31
- Mage::helper( 'turpentine/debug' )->log( 'EVENT: %s',
32
- $eventObject->getEvent()->getName() );
33
  }
34
 
35
  /**
@@ -38,8 +38,8 @@ class Nexcessnet_Turpentine_Model_Observer_Debug extends Varien_Event_Observer {
38
  * @param Varien_Object $eventObject
39
  * @return null
40
  */
41
- public function logBackTrace( $eventObject ) {
42
- $this->logEvent( $eventObject );
43
- Mage::helper( 'turpentine/debug' )->logBackTrace();
44
  }
45
  }
27
  * @param Varien_Object $eventObject
28
  * @return null
29
  */
30
+ public function logEvent($eventObject) {
31
+ Mage::helper('turpentine/debug')->log('EVENT: %s',
32
+ $eventObject->getEvent()->getName());
33
  }
34
 
35
  /**
38
  * @param Varien_Object $eventObject
39
  * @return null
40
  */
41
+ public function logBackTrace($eventObject) {
42
+ $this->logEvent($eventObject);
43
+ Mage::helper('turpentine/debug')->logBackTrace();
44
  }
45
  }
app/code/community/Nexcessnet/Turpentine/Model/Observer/Esi.php CHANGED
@@ -28,7 +28,7 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
28
  * @param Varien_Object $eventObject
29
  * @return null
30
  */
31
- public function setCustomerGroupCookie( $eventObject ) {
32
  $customer = $eventObject->getCustomer();
33
  $cookie = Mage::getSingleton('core/cookie');
34
  if (Mage::getStoreConfig('persistent/options/enabled')) {
@@ -46,7 +46,7 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
46
  * @param Varien_Object $eventObject
47
  * @return null
48
  */
49
- public function removeCustomerGroupCookie( $eventObject ) {
50
  Mage::getSingleton('core/cookie')->delete('customer_group');
51
  }
52
 
@@ -58,14 +58,14 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
58
  * @param Varien_Object $eventObject
59
  * @return null
60
  */
61
- public function setFlagHeaders( $eventObject ) {
62
  $response = $eventObject->getResponse();
63
- if( Mage::helper( 'turpentine/esi' )->shouldResponseUseEsi() ) {
64
- $response->setHeader( 'X-Turpentine-Esi',
65
- Mage::registry( 'turpentine_esi_flag' ) ? '1' : '0' );
66
- Mage::helper( 'turpentine/debug' )->logDebug(
67
  'Set ESI flag header to: %s',
68
- ( Mage::registry( 'turpentine_esi_flag' ) ? '1' : '0' ) );
69
  }
70
  }
71
 
@@ -81,14 +81,14 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
81
  * @param Varien_Object $eventObject
82
  * @return null
83
  */
84
- public function checkCacheFlag( $eventObject ) {
85
- if( Mage::helper( 'turpentine/varnish' )->shouldResponseUseVarnish() ) {
86
  $layoutXml = $eventObject->getLayout()->getUpdate()->asSimplexml();
87
- foreach( $layoutXml->xpath( '//turpentine_cache_flag' ) as $node ) {
88
- foreach( $node->attributes() as $attr => $value ) {
89
- if( $attr == 'value' ) {
90
- if( !(string)$value ) {
91
- Mage::register( 'turpentine_nocache_flag', true, true );
92
  return; //only need to set the flag once
93
  }
94
  }
@@ -104,29 +104,29 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
104
  * @param Varien_Object $eventObject
105
  * @return null
106
  */
107
- public function checkRedirectUrl( $eventObject ) {
108
- $esiHelper = Mage::helper( 'turpentine/esi' );
109
  $url = $eventObject->getTransport()->getUrl();
110
- $referer = Mage::helper( 'core/http' )->getHttpReferer();
111
  $dummyUrl = $esiHelper->getDummyUrl();
112
- $reqUenc = Mage::helper( 'core' )->urlDecode(
113
- Mage::app()->getRequest()->getParam( 'uenc' ) );
114
-
115
- if( $this->_checkIsEsiUrl( $url ) ) {
116
- if( $this->_checkIsNotEsiUrl( $reqUenc ) &&
117
- Mage::getBaseUrl() == $url ) {
118
- $newUrl = $this->_fixupUencUrl( $reqUenc );
119
- } elseif( $this->_checkIsNotEsiUrl( $referer ) ) {
120
  $newUrl = $referer;
121
  } else {
122
  $newUrl = $dummyUrl;
123
  }
124
  // TODO: make sure this actually looks like a URL
125
- $eventObject->getTransport()->setUrl( $newUrl );
126
  }
127
 
128
- if( $eventObject->getTransport()->getUrl() != $url ) {
129
- Mage::helper( 'turpentine/debug' )->logDebug(
130
  'Detected redirect to ESI URL, changing: %s => %s',
131
  $url, $eventObject->getTransport()->getUrl() );
132
  }
@@ -138,16 +138,16 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
138
  * @param Varien_Object $eventObject
139
  * @return null
140
  */
141
- public function loadCacheClearEvents( $eventObject ) {
142
- Varien_Profiler::start( 'turpentine::observer::esi::loadCacheClearEvents' );
143
- $events = Mage::helper( 'turpentine/esi' )->getCacheClearEvents();
144
- $appShim = Mage::getSingleton( 'turpentine/shim_mage_core_app' );
145
- foreach( $events as $ccEvent ) {
146
- $appShim->shim_addEventObserver( 'global', $ccEvent,
147
- 'turpentine_ban_' . $ccEvent, 'singleton',
148
- 'turpentine/observer_ban', 'banClientEsiCache' );
149
  }
150
- Varien_Profiler::stop( 'turpentine::observer::esi::loadCacheClearEvents' );
151
  }
152
 
153
  /**
@@ -160,13 +160,13 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
160
  * @param Varien_Object $eventObject
161
  * @return null
162
  */
163
- public function addMessagesBlockRewrite( $eventObject ) {
164
- if( Mage::helper( 'turpentine/esi' )->shouldFixFlashMessages() ) {
165
- Varien_Profiler::start( 'turpentine::observer::esi::addMessagesBlockRewrite' );
166
- Mage::getSingleton( 'turpentine/shim_mage_core_app' )
167
- ->shim_addClassRewrite( 'block', 'core', 'messages',
168
- 'Nexcessnet_Turpentine_Block_Core_Messages' );
169
- Varien_Profiler::stop( 'turpentine::observer::esi::addMessagesBlockRewrite' );
170
  }
171
  }
172
 
@@ -177,14 +177,14 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
177
  * @param Varien_Object $eventObject
178
  * @return null
179
  */
180
- public function setReplaceFormKeyFlag( $eventObject ) {
181
- $esiHelper = Mage::helper( 'turpentine/esi' );
182
- $varnishHelper = Mage::helper( 'turpentine/varnish' );
183
  $request = Mage::app()->getRequest();
184
- if( $esiHelper->shouldResponseUseEsi() &&
185
  $varnishHelper->csrfFixupNeeded() &&
186
- !$request->isPost() ) {
187
- Mage::register( 'replace_form_key', true );
188
  }
189
  }
190
 
@@ -194,16 +194,16 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
194
  * @param Varien_Object $eventObject
195
  * @return null
196
  */
197
- public function replaceFormKeyPlaceholder( $eventObject ) {
198
- if( Mage::registry( 'replace_form_key' ) ) {
199
- $esiHelper = Mage::helper( 'turpentine/esi' );
200
  $response = $eventObject->getResponse();
201
  $responseBody = $response->getBody();
202
- $responseBody = str_replace( '{{form_key_esi_placeholder}}',
203
  $esiHelper->buildEsiIncludeFragment(
204
  $esiHelper->getFormKeyEsiUrl() ),
205
- $responseBody );
206
- $response->setBody( $responseBody );
207
  }
208
  }
209
 
@@ -217,35 +217,35 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
217
  * @param Varien_Object $eventObject
218
  * @return null
219
  */
220
- public function injectEsi( $eventObject ) {
221
  $blockObject = $eventObject->getBlock();
222
- $dataHelper = Mage::helper( 'turpentine/data' );
223
- $esiHelper = Mage::helper( 'turpentine/esi' );
224
- $debugHelper = Mage::helper( 'turpentine/debug' );
225
- if( $esiHelper->getEsiBlockLogEnabled() ) {
226
  $debugHelper->logInfo(
227
  'Checking ESI block candidate: %s',
228
  $blockObject->getNameInLayout() ? $blockObject->getNameInLayout() : $blockObject->getModuleName() );
229
  }
230
- if( $esiHelper->shouldResponseUseEsi() &&
231
  $blockObject instanceof Mage_Core_Block_Template &&
232
- $esiOptions = $blockObject->getEsiOptions() ) {
233
 
234
  if ((isset($esiOptions['disableEsiInjection'])) && ($esiOptions['disableEsiInjection'] == 1)) {
235
  return;
236
  }
237
 
238
- if( Mage::app()->getStore()->getCode() == 'admin' ) {
239
  // admin blocks are not allowed to be cached for now
240
  $debugHelper->logWarn(
241
  'Ignoring attempt to inject adminhtml block: %s',
242
  $blockObject->getNameInLayout() ? $blockObject->getNameInLayout() : $blockObject->getModuleName() );
243
  return;
244
- } elseif( $esiHelper->getEsiBlockLogEnabled() ) {
245
- $debugHelper->logInfo( 'Block check passed, injecting block: %s',
246
- $blockObject->getNameInLayout() ? $blockObject->getNameInLayout() : $blockObject->getModuleName() );
247
  }
248
- Varien_Profiler::start( 'turpentine::observer::esi::injectEsi' );
249
  $ttlParam = $esiHelper->getEsiTtlParam();
250
  $cacheTypeParam = $esiHelper->getEsiCacheTypeParam();
251
  $dataParam = $esiHelper->getEsiDataParam();
@@ -254,59 +254,59 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
254
  $scopeParam = $esiHelper->getEsiScopeParam();
255
  $referrerParam = $esiHelper->getEsiReferrerParam();
256
 
257
- $esiOptions = $this->_getDefaultEsiOptions( $esiOptions );
258
 
259
  // change the block's template to the stripped down ESI template
260
- switch( $esiOptions[$methodParam] ) {
261
  case 'ajax':
262
- $blockObject->setTemplate( 'turpentine/ajax.phtml' );
263
  break;
264
 
265
  case 'esi':
266
  default:
267
- $blockObject->setTemplate( 'turpentine/esi.phtml' );
268
  // flag request for ESI processing
269
- Mage::register( 'turpentine_esi_flag', true, true );
270
  }
271
 
272
  // esi data is the data needed to regenerate the ESI'd block
273
- $esiData = $this->_getEsiData( $blockObject, $esiOptions )->toArray();
274
- ksort( $esiData );
275
- $frozenData = $dataHelper->freeze( $esiData );
276
  $urlOptions = array(
277
  $methodParam => $esiOptions[$methodParam],
278
  $cacheTypeParam => $esiOptions[$cacheTypeParam],
279
  $ttlParam => $esiOptions[$ttlParam],
280
- $hmacParam => $dataHelper->getHmac( $frozenData ),
281
  $dataParam => $frozenData,
282
  );
283
- if( $esiOptions[$methodParam] == 'ajax' ) {
284
  $urlOptions['_secure'] = Mage::app()->getStore()
285
  ->isCurrentlySecure();
286
  }
287
- if( $esiOptions[$scopeParam] == 'page' ) {
288
- $urlOptions[$referrerParam] = Mage::helper('core')->urlEncode(
289
- Mage::getUrl('*/*/*', array('_use_rewrite' => true, '_current' => true))
290
  );
291
  }
292
 
293
- $esiUrl = Mage::getUrl( 'turpentine/esi/getBlock', $urlOptions );
294
- if( $esiOptions[$methodParam] == 'esi' ) {
295
  // setting [web/unsecure/base_url] can be https://... but ESI can never be HTTPS
296
- $esiUrl = preg_replace( '|^https://|i', 'http://', $esiUrl );
297
  }
298
- $blockObject->setEsiUrl( $esiUrl );
299
  // avoid caching the ESI template output to prevent the double-esi-
300
  // include/"ESI processing not enabled" bug
301
- foreach( array( 'lifetime', 'tags', 'key' ) as $dataKey ) {
302
- $blockObject->unsetData( 'cache_' . $dataKey );
303
  }
304
- if( strlen( $esiUrl ) > 2047 ) {
305
- Mage::helper( 'turpentine/debug' )->logWarn(
306
  'ESI url is probably too long (%d > 2047 characters): %s',
307
- strlen( $esiUrl ), $esiUrl );
308
  }
309
- Varien_Profiler::stop( 'turpentine::observer::esi::injectEsi' );
310
  } // else handle the block like normal and cache it inline with the page
311
  }
312
 
@@ -317,65 +317,65 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
317
  * @param array $esiOptions
318
  * @return Varien_Object
319
  */
320
- protected function _getEsiData( $blockObject, $esiOptions ) {
321
- Varien_Profiler::start( 'turpentine::observer::esi::_getEsiData' );
322
- $esiHelper = Mage::helper( 'turpentine/esi' );
323
  $cacheTypeParam = $esiHelper->getEsiCacheTypeParam();
324
  $scopeParam = $esiHelper->getEsiScopeParam();
325
  $methodParam = $esiHelper->getEsiMethodParam();
326
  $esiData = new Varien_Object();
327
- $esiData->setStoreId( Mage::app()->getStore()->getId() );
328
- $esiData->setNameInLayout( $blockObject->getNameInLayout() );
329
- $esiData->setBlockType( get_class( $blockObject ) );
330
- $esiData->setLayoutHandles( $this->_getBlockLayoutHandles( $blockObject ) );
331
- $esiData->setEsiMethod( $esiOptions[$methodParam] );
332
- if( $esiOptions[$cacheTypeParam] == 'private' || $esiOptions[$cacheTypeParam] == 'customer_group' ) {
333
- if( is_array( @$esiOptions['flush_events'] ) ) {
334
- $esiData->setFlushEvents( array_merge(
335
  $esiHelper->getDefaultCacheClearEvents(),
336
- array_keys( $esiOptions['flush_events'] ) ) );
337
  } else {
338
  $esiData->setFlushEvents(
339
  $esiHelper->getDefaultCacheClearEvents() );
340
  }
341
  }
342
- if( $esiOptions[$scopeParam] == 'page' ) {
343
- $esiData->setParentUrl( Mage::app()->getRequest()->getRequestString() );
344
  }
345
- if( is_array( $esiOptions['dummy_blocks'] ) ) {
346
  $dummyBlocks = array();
347
- foreach( $esiOptions['dummy_blocks'] as $key => $value ) {
348
- $dummyBlocks[] = ( empty($value) && !is_numeric($key) ) ? $key : $value;
349
  }
350
- $esiData->setDummyBlocks( $dummyBlocks );
351
  } else {
352
- Mage::helper( 'turpentine/debug' )->logWarn(
353
  'Invalid dummy_blocks for block: %s',
354
  $blockObject->getNameInLayout() );
355
  }
356
  $simpleRegistry = array();
357
  $complexRegistry = array();
358
- if( is_array( $esiOptions['registry_keys'] ) ) {
359
- foreach( $esiOptions['registry_keys'] as $key => $options ) {
360
- $value = Mage::registry( $key );
361
- if( $value ) {
362
- if( is_object( $value ) &&
363
- $value instanceof Mage_Core_Model_Abstract ) {
364
  $complexRegistry[$key] =
365
- $this->_getComplexRegistryData( $options, $value );
366
  } else {
367
  $simpleRegistry[$key] = $value;
368
  }
369
  }
370
  }
371
  } else {
372
- Mage::helper( 'turpentine/debug' )->logWarn(
373
  'Invalid registry_keys for block: %s',
374
  $blockObject->getNameInLayout() );
375
  }
376
- $esiData->setSimpleRegistry( $simpleRegistry );
377
- $esiData->setComplexRegistry( $complexRegistry );
378
- Varien_Profiler::stop( 'turpentine::observer::esi::_getEsiData' );
379
  return $esiData;
380
  }
381
 
@@ -399,35 +399,35 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
399
  * @param Mage_Core_Block_Template $block
400
  * @return array
401
  */
402
- protected function _getBlockLayoutHandles( $block ) {
403
- Varien_Profiler::start( 'turpentine::observer::esi::_getBlockLayoutHandles' );
404
  $layout = $block->getLayout();
405
- $layoutXml = Mage::helper( 'turpentine/esi' )->getLayoutXml();
406
  $activeHandles = array();
407
  // get the xml node representing the block we're working on (from the
408
  // default handle probably)
409
- $blockNode = current( $layout->getNode()->xpath( sprintf(
410
  '//block[@name=\'%s\']',
411
- $block->getNameInLayout() ) ) );
412
- $childBlocks = Mage::helper( 'turpentine/data' )
413
- ->getChildBlockNames( $blockNode );
414
- foreach( $childBlocks as $blockName ) {
415
- foreach( $layout->getUpdate()->getHandles() as $handle ) {
416
  // check if this handle has any block or reference tags that
417
  // refer to this block or a child block, unless the handle name
418
  // is blank
419
- if( $handle !== '' && ( strpos($handle, 'THEME') === 0 ||
420
- $layoutXml->xpath( sprintf(
421
- '//%s//*[@name=\'%s\']', $handle, $blockName ) ) ) ) {
422
  $activeHandles[] = $handle;
423
  }
424
  }
425
  }
426
- if( !$activeHandles ) {
427
  $activeHandles[] = 'default';
428
  }
429
- Varien_Profiler::stop( 'turpentine::observer::esi::_getBlockLayoutHandles' );
430
- return array_unique( $activeHandles );
431
  }
432
 
433
  /**
@@ -435,8 +435,8 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
435
  *
436
  * @return array
437
  */
438
- protected function _getDefaultEsiOptions( $options ) {
439
- $esiHelper = Mage::helper( 'turpentine/esi' );
440
  $ttlParam = $esiHelper->getEsiTtlParam();
441
  $methodParam = $esiHelper->getEsiMethodParam();
442
  $cacheTypeParam = $esiHelper->getEsiCacheTypeParam();
@@ -447,12 +447,12 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
447
  'dummy_blocks' => array(),
448
  'registry_keys' => array(),
449
  );
450
- $options = array_merge( $defaults, $options );
451
 
452
  // set the default TTL
453
- if( !isset( $options[$ttlParam] ) ) {
454
- if( $options[$cacheTypeParam] == 'private' || $options[$cacheTypeParam] == 'customer_group' ) {
455
- switch( $options[$methodParam] ) {
456
  case 'ajax':
457
  $options[$ttlParam] = '0';
458
  break;
@@ -463,7 +463,7 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
463
  break;
464
  }
465
  } else {
466
- $options[$ttlParam] = Mage::helper( 'turpentine/varnish' )
467
  ->getDefaultTtl();
468
  }
469
  }
@@ -478,12 +478,12 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
478
  * @param mixed $value
479
  * @return array
480
  */
481
- protected function _getComplexRegistryData( $valueOptions, $value ) {
482
  $idMethod = @$valueOptions['id_method'] ?
483
  $valueOptions['id_method'] : 'getId';
484
  $model = @$valueOptions['model'] ?
485
- $valueOptions['model'] : Mage::helper( 'turpentine/data' )
486
- ->getModelName( $value );
487
  $data = array(
488
  'model' => $model,
489
  'id' => $value->{$idMethod}(),
@@ -498,11 +498,11 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
498
  * @param string $uencUrl
499
  * @return string
500
  */
501
- protected function _fixupUencUrl( $uencUrl ) {
502
- $esiHelper = Mage::helper( 'turpentine/esi' );
503
  $corsOrigin = $esiHelper->getCorsOrigin();
504
- if( $corsOrigin != $esiHelper->getCorsOrigin( $uencUrl ) ) {
505
- return $corsOrigin . parse_url( $uencUrl, PHP_URL_PATH );
506
  } else {
507
  return $uencUrl;
508
  }
@@ -514,8 +514,8 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
514
  * @param string $url
515
  * @return bool
516
  */
517
- protected function _checkIsNotEsiUrl( $url ) {
518
- return $url && !preg_match( '~/turpentine/esi/getBlock/~', $url );
519
  }
520
 
521
  /**
@@ -524,18 +524,21 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
524
  * @param string $url
525
  * @return bool
526
  */
527
- protected function _checkIsEsiUrl( $url ) {
528
- return !$this->_checkIsNotEsiUrl( $url );
529
  }
530
 
531
  public function hookToControllerActionPreDispatch($observer) {
532
- if(Mage::helper( 'turpentine/data')->getVclFix() == 0 && $observer->getEvent()->getControllerAction()->getFullActionName() == 'checkout_cart_add') {
533
  Mage::dispatchEvent("add_to_cart_before", array('request' => $observer->getControllerAction()->getRequest()));
534
  }
 
 
 
535
  }
536
 
537
  public function hookToControllerActionPostDispatch($observer) {
538
- if($observer->getEvent()->getControllerAction()->getFullActionName() == 'checkout_cart_add') {
539
  Mage::dispatchEvent("add_to_cart_after", array('request' => $observer->getControllerAction()->getRequest()));
540
  }
541
  }
@@ -552,4 +555,18 @@ class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer {
552
  $request = $observer->getEvent()->getRequest()->getParams();
553
  //Mage::log("hookToAddToCartAfter ".print_r($request,true)." is added to cart.", null, 'carrinho.log', true);
554
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
555
  }
28
  * @param Varien_Object $eventObject
29
  * @return null
30
  */
31
+ public function setCustomerGroupCookie($eventObject) {
32
  $customer = $eventObject->getCustomer();
33
  $cookie = Mage::getSingleton('core/cookie');
34
  if (Mage::getStoreConfig('persistent/options/enabled')) {
46
  * @param Varien_Object $eventObject
47
  * @return null
48
  */
49
+ public function removeCustomerGroupCookie($eventObject) {
50
  Mage::getSingleton('core/cookie')->delete('customer_group');
51
  }
52
 
58
  * @param Varien_Object $eventObject
59
  * @return null
60
  */
61
+ public function setFlagHeaders($eventObject) {
62
  $response = $eventObject->getResponse();
63
+ if (Mage::helper('turpentine/esi')->shouldResponseUseEsi()) {
64
+ $response->setHeader('X-Turpentine-Esi',
65
+ Mage::registry('turpentine_esi_flag') ? '1' : '0');
66
+ Mage::helper('turpentine/debug')->logDebug(
67
  'Set ESI flag header to: %s',
68
+ (Mage::registry('turpentine_esi_flag') ? '1' : '0') );
69
  }
70
  }
71
 
81
  * @param Varien_Object $eventObject
82
  * @return null
83
  */
84
+ public function checkCacheFlag($eventObject) {
85
+ if (Mage::helper('turpentine/varnish')->shouldResponseUseVarnish()) {
86
  $layoutXml = $eventObject->getLayout()->getUpdate()->asSimplexml();
87
+ foreach ($layoutXml->xpath('//turpentine_cache_flag') as $node) {
88
+ foreach ($node->attributes() as $attr => $value) {
89
+ if ($attr == 'value') {
90
+ if ( ! (string) $value) {
91
+ Mage::register('turpentine_nocache_flag', true, true);
92
  return; //only need to set the flag once
93
  }
94
  }
104
  * @param Varien_Object $eventObject
105
  * @return null
106
  */
107
+ public function checkRedirectUrl($eventObject) {
108
+ $esiHelper = Mage::helper('turpentine/esi');
109
  $url = $eventObject->getTransport()->getUrl();
110
+ $referer = Mage::helper('core/http')->getHttpReferer();
111
  $dummyUrl = $esiHelper->getDummyUrl();
112
+ $reqUenc = Mage::helper('core')->urlDecode(
113
+ Mage::app()->getRequest()->getParam('uenc') );
114
+
115
+ if ($this->_checkIsEsiUrl($url)) {
116
+ if ($this->_checkIsNotEsiUrl($reqUenc) &&
117
+ Mage::getBaseUrl() == $url) {
118
+ $newUrl = $this->_fixupUencUrl($reqUenc);
119
+ } elseif ($this->_checkIsNotEsiUrl($referer)) {
120
  $newUrl = $referer;
121
  } else {
122
  $newUrl = $dummyUrl;
123
  }
124
  // TODO: make sure this actually looks like a URL
125
+ $eventObject->getTransport()->setUrl($newUrl);
126
  }
127
 
128
+ if ($eventObject->getTransport()->getUrl() != $url) {
129
+ Mage::helper('turpentine/debug')->logDebug(
130
  'Detected redirect to ESI URL, changing: %s => %s',
131
  $url, $eventObject->getTransport()->getUrl() );
132
  }
138
  * @param Varien_Object $eventObject
139
  * @return null
140
  */
141
+ public function loadCacheClearEvents($eventObject) {
142
+ Varien_Profiler::start('turpentine::observer::esi::loadCacheClearEvents');
143
+ $events = Mage::helper('turpentine/esi')->getCacheClearEvents();
144
+ $appShim = Mage::getSingleton('turpentine/shim_mage_core_app');
145
+ foreach ($events as $ccEvent) {
146
+ $appShim->shim_addEventObserver('global', $ccEvent,
147
+ 'turpentine_ban_'.$ccEvent, 'singleton',
148
+ 'turpentine/observer_ban', 'banClientEsiCache');
149
  }
150
+ Varien_Profiler::stop('turpentine::observer::esi::loadCacheClearEvents');
151
  }
152
 
153
  /**
160
  * @param Varien_Object $eventObject
161
  * @return null
162
  */
163
+ public function addMessagesBlockRewrite($eventObject) {
164
+ if (Mage::helper('turpentine/esi')->shouldFixFlashMessages()) {
165
+ Varien_Profiler::start('turpentine::observer::esi::addMessagesBlockRewrite');
166
+ Mage::getSingleton('turpentine/shim_mage_core_app')
167
+ ->shim_addClassRewrite('block', 'core', 'messages',
168
+ 'Nexcessnet_Turpentine_Block_Core_Messages');
169
+ Varien_Profiler::stop('turpentine::observer::esi::addMessagesBlockRewrite');
170
  }
171
  }
172
 
177
  * @param Varien_Object $eventObject
178
  * @return null
179
  */
180
+ public function setReplaceFormKeyFlag($eventObject) {
181
+ $esiHelper = Mage::helper('turpentine/esi');
182
+ $varnishHelper = Mage::helper('turpentine/varnish');
183
  $request = Mage::app()->getRequest();
184
+ if ($esiHelper->shouldResponseUseEsi() &&
185
  $varnishHelper->csrfFixupNeeded() &&
186
+ ! $request->isPost()) {
187
+ Mage::register('replace_form_key', true);
188
  }
189
  }
190
 
194
  * @param Varien_Object $eventObject
195
  * @return null
196
  */
197
+ public function replaceFormKeyPlaceholder($eventObject) {
198
+ if (Mage::registry('replace_form_key')) {
199
+ $esiHelper = Mage::helper('turpentine/esi');
200
  $response = $eventObject->getResponse();
201
  $responseBody = $response->getBody();
202
+ $responseBody = str_replace('{{form_key_esi_placeholder}}',
203
  $esiHelper->buildEsiIncludeFragment(
204
  $esiHelper->getFormKeyEsiUrl() ),
205
+ $responseBody);
206
+ $response->setBody($responseBody);
207
  }
208
  }
209
 
217
  * @param Varien_Object $eventObject
218
  * @return null
219
  */
220
+ public function injectEsi($eventObject) {
221
  $blockObject = $eventObject->getBlock();
222
+ $dataHelper = Mage::helper('turpentine/data');
223
+ $esiHelper = Mage::helper('turpentine/esi');
224
+ $debugHelper = Mage::helper('turpentine/debug');
225
+ if ($esiHelper->getEsiBlockLogEnabled()) {
226
  $debugHelper->logInfo(
227
  'Checking ESI block candidate: %s',
228
  $blockObject->getNameInLayout() ? $blockObject->getNameInLayout() : $blockObject->getModuleName() );
229
  }
230
+ if ($esiHelper->shouldResponseUseEsi() &&
231
  $blockObject instanceof Mage_Core_Block_Template &&
232
+ $esiOptions = $blockObject->getEsiOptions()) {
233
 
234
  if ((isset($esiOptions['disableEsiInjection'])) && ($esiOptions['disableEsiInjection'] == 1)) {
235
  return;
236
  }
237
 
238
+ if (Mage::app()->getStore()->getCode() == 'admin') {
239
  // admin blocks are not allowed to be cached for now
240
  $debugHelper->logWarn(
241
  'Ignoring attempt to inject adminhtml block: %s',
242
  $blockObject->getNameInLayout() ? $blockObject->getNameInLayout() : $blockObject->getModuleName() );
243
  return;
244
+ } elseif ($esiHelper->getEsiBlockLogEnabled()) {
245
+ $debugHelper->logInfo('Block check passed, injecting block: %s',
246
+ $blockObject->getNameInLayout() ? $blockObject->getNameInLayout() : $blockObject->getModuleName());
247
  }
248
+ Varien_Profiler::start('turpentine::observer::esi::injectEsi');
249
  $ttlParam = $esiHelper->getEsiTtlParam();
250
  $cacheTypeParam = $esiHelper->getEsiCacheTypeParam();
251
  $dataParam = $esiHelper->getEsiDataParam();
254
  $scopeParam = $esiHelper->getEsiScopeParam();
255
  $referrerParam = $esiHelper->getEsiReferrerParam();
256
 
257
+ $esiOptions = $this->_getDefaultEsiOptions($esiOptions);
258
 
259
  // change the block's template to the stripped down ESI template
260
+ switch ($esiOptions[$methodParam]) {
261
  case 'ajax':
262
+ $blockObject->setTemplate('turpentine/ajax.phtml');
263
  break;
264
 
265
  case 'esi':
266
  default:
267
+ $blockObject->setTemplate('turpentine/esi.phtml');
268
  // flag request for ESI processing
269
+ Mage::register('turpentine_esi_flag', true, true);
270
  }
271
 
272
  // esi data is the data needed to regenerate the ESI'd block
273
+ $esiData = $this->_getEsiData($blockObject, $esiOptions)->toArray();
274
+ ksort($esiData);
275
+ $frozenData = $dataHelper->freeze($esiData);
276
  $urlOptions = array(
277
  $methodParam => $esiOptions[$methodParam],
278
  $cacheTypeParam => $esiOptions[$cacheTypeParam],
279
  $ttlParam => $esiOptions[$ttlParam],
280
+ $hmacParam => $dataHelper->getHmac($frozenData),
281
  $dataParam => $frozenData,
282
  );
283
+ if ($esiOptions[$methodParam] == 'ajax') {
284
  $urlOptions['_secure'] = Mage::app()->getStore()
285
  ->isCurrentlySecure();
286
  }
287
+ if ($esiOptions[$scopeParam] == 'page') {
288
+ $urlOptions[$referrerParam] = Mage::helper('core')->urlEncode(
289
+ Mage::getUrl('*/*/*', array('_use_rewrite' => true, '_current' => true))
290
  );
291
  }
292
 
293
+ $esiUrl = Mage::getUrl('turpentine/esi/getBlock', $urlOptions);
294
+ if ($esiOptions[$methodParam] == 'esi') {
295
  // setting [web/unsecure/base_url] can be https://... but ESI can never be HTTPS
296
+ $esiUrl = preg_replace('|^https://|i', 'http://', $esiUrl);
297
  }
298
+ $blockObject->setEsiUrl($esiUrl);
299
  // avoid caching the ESI template output to prevent the double-esi-
300
  // include/"ESI processing not enabled" bug
301
+ foreach (array('lifetime', 'tags', 'key') as $dataKey) {
302
+ $blockObject->unsetData('cache_'.$dataKey);
303
  }
304
+ if (strlen($esiUrl) > 2047) {
305
+ Mage::helper('turpentine/debug')->logWarn(
306
  'ESI url is probably too long (%d > 2047 characters): %s',
307
+ strlen($esiUrl), $esiUrl );
308
  }
309
+ Varien_Profiler::stop('turpentine::observer::esi::injectEsi');
310
  } // else handle the block like normal and cache it inline with the page
311
  }
312
 
317
  * @param array $esiOptions
318
  * @return Varien_Object
319
  */
320
+ protected function _getEsiData($blockObject, $esiOptions) {
321
+ Varien_Profiler::start('turpentine::observer::esi::_getEsiData');
322
+ $esiHelper = Mage::helper('turpentine/esi');
323
  $cacheTypeParam = $esiHelper->getEsiCacheTypeParam();
324
  $scopeParam = $esiHelper->getEsiScopeParam();
325
  $methodParam = $esiHelper->getEsiMethodParam();
326
  $esiData = new Varien_Object();
327
+ $esiData->setStoreId(Mage::app()->getStore()->getId());
328
+ $esiData->setNameInLayout($blockObject->getNameInLayout());
329
+ $esiData->setBlockType(get_class($blockObject));
330
+ $esiData->setLayoutHandles($this->_getBlockLayoutHandles($blockObject));
331
+ $esiData->setEsiMethod($esiOptions[$methodParam]);
332
+ if ($esiOptions[$cacheTypeParam] == 'private' || $esiOptions[$cacheTypeParam] == 'customer_group') {
333
+ if (is_array(@$esiOptions['flush_events'])) {
334
+ $esiData->setFlushEvents(array_merge(
335
  $esiHelper->getDefaultCacheClearEvents(),
336
+ array_keys($esiOptions['flush_events']) ));
337
  } else {
338
  $esiData->setFlushEvents(
339
  $esiHelper->getDefaultCacheClearEvents() );
340
  }
341
  }
342
+ if ($esiOptions[$scopeParam] == 'page') {
343
+ $esiData->setParentUrl(Mage::app()->getRequest()->getRequestString());
344
  }
345
+ if (is_array($esiOptions['dummy_blocks'])) {
346
  $dummyBlocks = array();
347
+ foreach ($esiOptions['dummy_blocks'] as $key => $value) {
348
+ $dummyBlocks[] = (empty($value) && ! is_numeric($key)) ? $key : $value;
349
  }
350
+ $esiData->setDummyBlocks($dummyBlocks);
351
  } else {
352
+ Mage::helper('turpentine/debug')->logWarn(
353
  'Invalid dummy_blocks for block: %s',
354
  $blockObject->getNameInLayout() );
355
  }
356
  $simpleRegistry = array();
357
  $complexRegistry = array();
358
+ if (is_array($esiOptions['registry_keys'])) {
359
+ foreach ($esiOptions['registry_keys'] as $key => $options) {
360
+ $value = Mage::registry($key);
361
+ if ($value) {
362
+ if (is_object($value) &&
363
+ $value instanceof Mage_Core_Model_Abstract) {
364
  $complexRegistry[$key] =
365
+ $this->_getComplexRegistryData($options, $value);
366
  } else {
367
  $simpleRegistry[$key] = $value;
368
  }
369
  }
370
  }
371
  } else {
372
+ Mage::helper('turpentine/debug')->logWarn(
373
  'Invalid registry_keys for block: %s',
374
  $blockObject->getNameInLayout() );
375
  }
376
+ $esiData->setSimpleRegistry($simpleRegistry);
377
+ $esiData->setComplexRegistry($complexRegistry);
378
+ Varien_Profiler::stop('turpentine::observer::esi::_getEsiData');
379
  return $esiData;
380
  }
381
 
399
  * @param Mage_Core_Block_Template $block
400
  * @return array
401
  */
402
+ protected function _getBlockLayoutHandles($block) {
403
+ Varien_Profiler::start('turpentine::observer::esi::_getBlockLayoutHandles');
404
  $layout = $block->getLayout();
405
+ $layoutXml = Mage::helper('turpentine/esi')->getLayoutXml();
406
  $activeHandles = array();
407
  // get the xml node representing the block we're working on (from the
408
  // default handle probably)
409
+ $blockNode = current($layout->getNode()->xpath(sprintf(
410
  '//block[@name=\'%s\']',
411
+ $block->getNameInLayout() )));
412
+ $childBlocks = Mage::helper('turpentine/data')
413
+ ->getChildBlockNames($blockNode);
414
+ foreach ($childBlocks as $blockName) {
415
+ foreach ($layout->getUpdate()->getHandles() as $handle) {
416
  // check if this handle has any block or reference tags that
417
  // refer to this block or a child block, unless the handle name
418
  // is blank
419
+ if ($handle !== '' && (strpos($handle, 'THEME') === 0 ||
420
+ $layoutXml->xpath(sprintf(
421
+ '//%s//*[@name=\'%s\']', $handle, $blockName )))) {
422
  $activeHandles[] = $handle;
423
  }
424
  }
425
  }
426
+ if ( ! $activeHandles) {
427
  $activeHandles[] = 'default';
428
  }
429
+ Varien_Profiler::stop('turpentine::observer::esi::_getBlockLayoutHandles');
430
+ return array_unique($activeHandles);
431
  }
432
 
433
  /**
435
  *
436
  * @return array
437
  */
438
+ protected function _getDefaultEsiOptions($options) {
439
+ $esiHelper = Mage::helper('turpentine/esi');
440
  $ttlParam = $esiHelper->getEsiTtlParam();
441
  $methodParam = $esiHelper->getEsiMethodParam();
442
  $cacheTypeParam = $esiHelper->getEsiCacheTypeParam();
447
  'dummy_blocks' => array(),
448
  'registry_keys' => array(),
449
  );
450
+ $options = array_merge($defaults, $options);
451
 
452
  // set the default TTL
453
+ if ( ! isset($options[$ttlParam])) {
454
+ if ($options[$cacheTypeParam] == 'private' || $options[$cacheTypeParam] == 'customer_group') {
455
+ switch ($options[$methodParam]) {
456
  case 'ajax':
457
  $options[$ttlParam] = '0';
458
  break;
463
  break;
464
  }
465
  } else {
466
+ $options[$ttlParam] = Mage::helper('turpentine/varnish')
467
  ->getDefaultTtl();
468
  }
469
  }
478
  * @param mixed $value
479
  * @return array
480
  */
481
+ protected function _getComplexRegistryData($valueOptions, $value) {
482
  $idMethod = @$valueOptions['id_method'] ?
483
  $valueOptions['id_method'] : 'getId';
484
  $model = @$valueOptions['model'] ?
485
+ $valueOptions['model'] : Mage::helper('turpentine/data')
486
+ ->getModelName($value);
487
  $data = array(
488
  'model' => $model,
489
  'id' => $value->{$idMethod}(),
498
  * @param string $uencUrl
499
  * @return string
500
  */
501
+ protected function _fixupUencUrl($uencUrl) {
502
+ $esiHelper = Mage::helper('turpentine/esi');
503
  $corsOrigin = $esiHelper->getCorsOrigin();
504
+ if ($corsOrigin != $esiHelper->getCorsOrigin($uencUrl)) {
505
+ return $corsOrigin.parse_url($uencUrl, PHP_URL_PATH);
506
  } else {
507
  return $uencUrl;
508
  }
514
  * @param string $url
515
  * @return bool
516
  */
517
+ protected function _checkIsNotEsiUrl($url) {
518
+ return $url && ! preg_match('~/turpentine/esi/getBlock/~', $url);
519
  }
520
 
521
  /**
524
  * @param string $url
525
  * @return bool
526
  */
527
+ protected function _checkIsEsiUrl($url) {
528
+ return ! $this->_checkIsNotEsiUrl($url);
529
  }
530
 
531
  public function hookToControllerActionPreDispatch($observer) {
532
+ if (Mage::helper('turpentine/data')->getVclFix() == 0 && $observer->getEvent()->getControllerAction()->getFullActionName() == 'checkout_cart_add') {
533
  Mage::dispatchEvent("add_to_cart_before", array('request' => $observer->getControllerAction()->getRequest()));
534
  }
535
+ if ($observer->getEvent()->getControllerAction()->getFullActionName() == 'wishlist_index_index') {
536
+ Mage::dispatchEvent('wishlist_index_index_before', array('request' => $observer->getControllerAction()->getRequest()));
537
+ }
538
  }
539
 
540
  public function hookToControllerActionPostDispatch($observer) {
541
+ if ($observer->getEvent()->getControllerAction()->getFullActionName() == 'checkout_cart_add') {
542
  Mage::dispatchEvent("add_to_cart_after", array('request' => $observer->getControllerAction()->getRequest()));
543
  }
544
  }
555
  $request = $observer->getEvent()->getRequest()->getParams();
556
  //Mage::log("hookToAddToCartAfter ".print_r($request,true)." is added to cart.", null, 'carrinho.log', true);
557
  }
558
+
559
+ /**
560
+ * Set the form key on the add to wishlist request
561
+ *
562
+ * @param $observer
563
+ *
564
+ * @return Nexcessnet_Turpentine_Model_Observer_Esi
565
+ */
566
+ public function hookToAddToWishlistBefore($observer)
567
+ {
568
+ $key = Mage::getSingleton('core/session')->getFormKey();
569
+ $observer->getEvent()->getRequest()->setParam('form_key', $key);
570
+ return $this;
571
+ }
572
  }
app/code/community/Nexcessnet/Turpentine/Model/Observer/Varnish.php CHANGED
@@ -28,15 +28,15 @@ class Nexcessnet_Turpentine_Model_Observer_Varnish extends Varien_Event_Observer
28
  * @param mixed $eventObject
29
  * @return null
30
  */
31
- public function setCacheFlagHeader( $eventObject ) {
32
  $response = $eventObject->getResponse();
33
- if( Mage::helper( 'turpentine/varnish' )->shouldResponseUseVarnish() ) {
34
- $response->setHeader( 'X-Turpentine-Cache',
35
- Mage::registry( 'turpentine_nocache_flag' ) ? '0' : '1' );
36
- if( Mage::helper( 'turpentine/varnish' )->getVarnishDebugEnabled() ) {
37
- Mage::helper( 'turpentine/debug' )->logDebug(
38
- 'Set Varnish cache flag header to: ' .
39
- ( Mage::registry( 'turpentine_nocache_flag' ) ? '0' : '1' ) );
40
  }
41
  }
42
  }
@@ -47,11 +47,27 @@ class Nexcessnet_Turpentine_Model_Observer_Varnish extends Varien_Event_Observer
47
  * @param Varien_Object $eventObject
48
  * @return null
49
  */
50
- public function addProductListToolbarRewrite( $eventObject ) {
51
- if( Mage::helper( 'turpentine/varnish' )->shouldFixProductListToolbar() ) {
52
- Mage::getSingleton( 'turpentine/shim_mage_core_app' )
53
- ->shim_addClassRewrite( 'block', 'catalog', 'product_list_toolbar',
54
- 'Nexcessnet_Turpentine_Block_Catalog_Product_List_Toolbar' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  }
56
  }
57
 
@@ -61,33 +77,33 @@ class Nexcessnet_Turpentine_Model_Observer_Varnish extends Varien_Event_Observer
61
  * @param mixed $eventObject
62
  * @return null
63
  */
64
- public function adminSystemConfigChangedSection( $eventObject ) {
65
- if( Mage::helper( 'turpentine/varnish' )->getVarnishEnabled() &&
66
- Mage::helper( 'turpentine/data' )->getAutoApplyOnSave() ) {
67
- $result = Mage::getModel( 'turpentine/varnish_admin' )->applyConfig();
68
- $session = Mage::getSingleton( 'core/session' );
69
- foreach( $result as $name => $value ) {
70
- if( $value === true ) {
71
- $session->addSuccess( Mage::helper( 'turpentine/data' )
72
- ->__( 'VCL successfully applied to: ' . $name ) );
73
  } else {
74
- $session->addError( Mage::helper( 'turpentine/data' )
75
- ->__( sprintf( 'Failed to apply the VCL to %s: %s',
76
- $name, $value ) ) );
77
  }
78
  }
79
- $cfgr = Mage::getModel( 'turpentine/varnish_admin' )->getConfigurator();
80
- if( is_null( $cfgr ) ) {
81
- $session->addError( Mage::helper( 'turpentine/data' )
82
- ->__( 'Failed to load configurator' ) );
83
  } else {
84
- $result = $cfgr->save( $cfgr->generate() );
85
- if( $result[0] ) {
86
- $session->addSuccess( Mage::helper('turpentine/data' )
87
- ->__( 'The VCL file has been saved.' ) );
88
  } else {
89
- $session->addError( Mage::helper('turpentine/data' )
90
- ->__( 'Failed to save the VCL file: ' . $result[1]['message'] ) );
91
  }
92
  }
93
  }
28
  * @param mixed $eventObject
29
  * @return null
30
  */
31
+ public function setCacheFlagHeader($eventObject) {
32
  $response = $eventObject->getResponse();
33
+ if (Mage::helper('turpentine/varnish')->shouldResponseUseVarnish()) {
34
+ $response->setHeader('X-Turpentine-Cache',
35
+ Mage::registry('turpentine_nocache_flag') ? '0' : '1');
36
+ if (Mage::helper('turpentine/varnish')->getVarnishDebugEnabled()) {
37
+ Mage::helper('turpentine/debug')->logDebug(
38
+ 'Set Varnish cache flag header to: '.
39
+ (Mage::registry('turpentine_nocache_flag') ? '0' : '1') );
40
  }
41
  }
42
  }
47
  * @param Varien_Object $eventObject
48
  * @return null
49
  */
50
+ public function addProductListToolbarRewrite($eventObject) {
51
+ if (Mage::helper('turpentine/varnish')->shouldFixProductListToolbar()) {
52
+ Mage::getSingleton('turpentine/shim_mage_core_app')
53
+ ->shim_addClassRewrite('block', 'catalog', 'product_list_toolbar',
54
+ 'Nexcessnet_Turpentine_Block_Catalog_Product_List_Toolbar');
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Turpentine sets the fake cookie 'frontend=crawler-session' when a crawler is detected.
60
+ * This causes lock problems with Cm_RedisSession, because all crawler hits are requesting the same session lock.
61
+ * Cm_RedisSession provides the define CM_REDISSESSION_LOCKING_ENABLED to overrule if locking should be enabled.
62
+ *
63
+ * @param $eventObject
64
+ * @return null
65
+ */
66
+ public function fixCmRedisSessionLocks($eventObject) {
67
+ if (Mage::helper('core')->isModuleEnabled('Cm_RedisSession')) {
68
+ if ( ! empty($_COOKIE['frontend']) && 'crawler-session' == $_COOKIE['frontend']) {
69
+ define('CM_REDISSESSION_LOCKING_ENABLED', false);
70
+ }
71
  }
72
  }
73
 
77
  * @param mixed $eventObject
78
  * @return null
79
  */
80
+ public function adminSystemConfigChangedSection($eventObject) {
81
+ if (Mage::helper('turpentine/varnish')->getVarnishEnabled() &&
82
+ Mage::helper('turpentine/data')->getAutoApplyOnSave()) {
83
+ $result = Mage::getModel('turpentine/varnish_admin')->applyConfig();
84
+ $session = Mage::getSingleton('core/session');
85
+ foreach ($result as $name => $value) {
86
+ if ($value === true) {
87
+ $session->addSuccess(Mage::helper('turpentine/data')
88
+ ->__('VCL successfully applied to: '.$name));
89
  } else {
90
+ $session->addError(Mage::helper('turpentine/data')
91
+ ->__(sprintf('Failed to apply the VCL to %s: %s',
92
+ $name, $value)));
93
  }
94
  }
95
+ $cfgr = Mage::getModel('turpentine/varnish_admin')->getConfigurator();
96
+ if (is_null($cfgr)) {
97
+ $session->addError(Mage::helper('turpentine/data')
98
+ ->__('Failed to load configurator'));
99
  } else {
100
+ $result = $cfgr->save($cfgr->generate());
101
+ if ($result[0]) {
102
+ $session->addSuccess(Mage::helper('turpentine/data')
103
+ ->__('The VCL file has been saved.'));
104
  } else {
105
+ $session->addError(Mage::helper('turpentine/data')
106
+ ->__('Failed to save the VCL file: '.$result[1]['message']));
107
  }
108
  }
109
  }
app/code/community/Nexcessnet/Turpentine/Model/PageCache/Container/Notices.php CHANGED
@@ -28,7 +28,7 @@ class Nexcessnet_Turpentine_Model_PageCache_Container_Notices
28
  * @param string $content
29
  * @return boolean
30
  */
31
- public function applyWithoutApp( &$content ) {
32
  return false;
33
  }
34
 
@@ -39,7 +39,7 @@ class Nexcessnet_Turpentine_Model_PageCache_Container_Notices
39
  */
40
  protected function _renderBlock() {
41
  $block = new Nexcessnet_Turpentine_Block_Notices();
42
- $block->setTemplate( 'turpentine/notices.phtml' );
43
 
44
  return $block->toHtml();
45
  }
28
  * @param string $content
29
  * @return boolean
30
  */
31
+ public function applyWithoutApp(&$content) {
32
  return false;
33
  }
34
 
39
  */
40
  protected function _renderBlock() {
41
  $block = new Nexcessnet_Turpentine_Block_Notices();
42
+ $block->setTemplate('turpentine/notices.phtml');
43
 
44
  return $block->toHtml();
45
  }
app/code/community/Nexcessnet/Turpentine/Model/Session.php CHANGED
@@ -22,12 +22,12 @@
22
  class Nexcessnet_Turpentine_Model_Session extends Mage_Core_Model_Session_Abstract {
23
  protected $_namespace = 'turpentine';
24
 
25
- public function __construct( $data=array() ) {
26
- $sessionName = isset( $data['name'] ) ? $data['name'] : null;
27
- $this->init( $this->_namespace, $sessionName );
28
  Mage::dispatchEvent(
29
- sprintf( '%s_session_init', $this->_namespace ),
30
- array( sprintf( '%s_session', $this->_namespace ) => $this ) );
31
  }
32
 
33
  /**
@@ -37,11 +37,11 @@ class Nexcessnet_Turpentine_Model_Session extends Mage_Core_Model_Session_Abstra
37
  * @param array $messages
38
  * @return null
39
  */
40
- public function saveMessages( $blockName, $messages ) {
41
  $allMessages = $this->getMessages();
42
  $allMessages[$blockName] = array_merge(
43
- $this->loadMessages( $blockName ), $messages );
44
- $this->setMessages( $allMessages );
45
  }
46
 
47
  /**
@@ -50,9 +50,9 @@ class Nexcessnet_Turpentine_Model_Session extends Mage_Core_Model_Session_Abstra
50
  * @param string $blockName
51
  * @return array
52
  */
53
- public function loadMessages( $blockName ) {
54
  $messages = $this->getMessages();
55
- if( is_array( @$messages[$blockName] ) ) {
56
  return $messages[$blockName];
57
  } else {
58
  return array();
@@ -65,21 +65,20 @@ class Nexcessnet_Turpentine_Model_Session extends Mage_Core_Model_Session_Abstra
65
  * @param string $blockName
66
  * @return null
67
  */
68
- public function clearMessages( $blockName ) {
69
  $messages = $this->getMessages();
70
- unset( $messages[$blockName] );
71
- $this->setMessages( $messages );
72
  }
73
 
74
  /**
75
  * Retrieve the stored messages
76
  *
77
- * @param boolean $clear=false
78
  * @return array
79
  */
80
- public function getMessages( $clear=false ) {
81
- $messages = $this->getData( 'messages' );
82
- if( !is_array( $messages ) ) {
83
  $messages = array();
84
  }
85
  return $messages;
@@ -90,7 +89,7 @@ class Nexcessnet_Turpentine_Model_Session extends Mage_Core_Model_Session_Abstra
90
  *
91
  * @param array $messages
92
  */
93
- public function setMessages( $messages ) {
94
- $this->setData( 'messages', $messages );
95
  }
96
  }
22
  class Nexcessnet_Turpentine_Model_Session extends Mage_Core_Model_Session_Abstract {
23
  protected $_namespace = 'turpentine';
24
 
25
+ public function __construct($data = array()) {
26
+ $sessionName = isset($data['name']) ? $data['name'] : null;
27
+ $this->init($this->_namespace, $sessionName);
28
  Mage::dispatchEvent(
29
+ sprintf('%s_session_init', $this->_namespace),
30
+ array(sprintf('%s_session', $this->_namespace) => $this) );
31
  }
32
 
33
  /**
37
  * @param array $messages
38
  * @return null
39
  */
40
+ public function saveMessages($blockName, $messages) {
41
  $allMessages = $this->getMessages();
42
  $allMessages[$blockName] = array_merge(
43
+ $this->loadMessages($blockName), $messages );
44
+ $this->setMessages($allMessages);
45
  }
46
 
47
  /**
50
  * @param string $blockName
51
  * @return array
52
  */
53
+ public function loadMessages($blockName) {
54
  $messages = $this->getMessages();
55
+ if (is_array(@$messages[$blockName])) {
56
  return $messages[$blockName];
57
  } else {
58
  return array();
65
  * @param string $blockName
66
  * @return null
67
  */
68
+ public function clearMessages($blockName) {
69
  $messages = $this->getMessages();
70
+ unset($messages[$blockName]);
71
+ $this->setMessages($messages);
72
  }
73
 
74
  /**
75
  * Retrieve the stored messages
76
  *
 
77
  * @return array
78
  */
79
+ public function getMessages($clear = false) {
80
+ $messages = $this->getData('messages');
81
+ if ( ! is_array($messages)) {
82
  $messages = array();
83
  }
84
  return $messages;
89
  *
90
  * @param array $messages
91
  */
92
+ public function setMessages($messages) {
93
+ $this->setData('messages', $messages);
94
  }
95
  }
app/code/community/Nexcessnet/Turpentine/Model/Shim/Mage/Core/App.php CHANGED
@@ -35,9 +35,9 @@ class Nexcessnet_Turpentine_Model_Shim_Mage_Core_App extends Mage_Core_Model_App
35
  */
36
  public function shim_setRequest(Mage_Core_Controller_Request_Http $request) {
37
  $app = $this->_shim_getApp();
38
- if( method_exists( $app, 'setRequest' ) ) {
39
  // use the real setRequest if it's available
40
- $app->setRequest( $request );
41
  } else {
42
  $app->_request = $request;
43
  }
@@ -55,12 +55,12 @@ class Nexcessnet_Turpentine_Model_Shim_Mage_Core_App extends Mage_Core_Model_App
55
  * @param string $method name of the method to call
56
  * @return Nexcessnet_Turpentine_Model_Shim_Mage_Core_App
57
  */
58
- public function shim_addEventObserver( $area, $eventName, $obsName,
59
- $type=null, $class=null, $method=null ) {
60
  $eventConfig = new Varien_Simplexml_Config();
61
- $eventConfig->loadDom( $this->_shim_getEventDom(
62
- $area, $eventName, $obsName, $type, $class, $method ) );
63
- $this->_shim_getConfig()->extend( $eventConfig, true );
64
  // this wouldn't work if PHP had a sane object model
65
  $this->_shim_getApp()->_events[$area][$eventName] = null;
66
  /* clear the event area cache because by the time this gets executed all <global> events have already been
@@ -78,12 +78,12 @@ class Nexcessnet_Turpentine_Model_Shim_Mage_Core_App extends Mage_Core_Model_App
78
  * @param string $rewriteTarget full class name to rewrite to
79
  * @return Nexcessnet_Turpentine_Model_Shim_Mage_Core_App
80
  */
81
- public function shim_addClassRewrite( $type, $module, $class,
82
- $rewriteTarget ) {
83
  $rewriteConfig = new Varien_Simplexml_Config();
84
- $rewriteConfig->loadDom( $this->_shim_getRewriteDom(
85
- $type, $module, $class, $rewriteTarget ) );
86
- $this->_shim_getConfig()->extend( $rewriteConfig, true );
87
  $this->_shim_getConfigShim()->shim_setClassNameCache(
88
  $type, $module, $class, $rewriteTarget );
89
  return $this;
@@ -100,25 +100,25 @@ class Nexcessnet_Turpentine_Model_Shim_Mage_Core_App extends Mage_Core_Model_App
100
  * @param string $method
101
  * @return DOMDocument
102
  */
103
- protected function _shim_getEventDom( $area, $eventName, $obsName,
104
- $type=null, $class=null, $method=null ) {
105
- $dom = new DOMDocument( '1.0' );
106
- $config = $dom->createElement( 'config' );
107
  $observers = $config
108
- ->appendChild( $dom->createElement( $area ) )
109
- ->appendChild( $dom->createElement( 'events' ) )
110
- ->appendChild( $dom->createElement( $eventName ) )
111
- ->appendChild( $dom->createElement( 'observers' ) );
112
- $observer = $dom->createElement( $obsName );
113
- if( $class && $method ) {
114
- if( $type ) {
115
- $observer->appendChild( $dom->createElement( 'type', $type ) );
116
  }
117
- $observer->appendChild( $dom->createElement( 'class', $class ) );
118
- $observer->appendChild( $dom->createElement( 'method', $method ) );
119
  }
120
- $observers->appendChild( $observer );
121
- $dom->appendChild( $config );
122
  return $dom;
123
  }
124
 
@@ -131,14 +131,14 @@ class Nexcessnet_Turpentine_Model_Shim_Mage_Core_App extends Mage_Core_Model_App
131
  * @param string $className full class name to rewrite to
132
  * @return DOMDocument
133
  */
134
- protected function _shim_getRewriteDom( $groupType, $group, $class, $className ) {
135
- $dom = new DOMDocument( '1.0' );
136
- $dom->appendChild( $dom->createElement( 'config' ) )
137
- ->appendChild( $dom->createElement( 'global' ) )
138
- ->appendChild( $dom->createElement( $groupType . 's' ) )
139
- ->appendChild( $dom->createElement( $group ) )
140
- ->appendChild( $dom->createElement( 'rewrite' ) )
141
- ->appendChild( $dom->createElement( $class, $className ) );
142
  return $dom;
143
  }
144
 
@@ -166,6 +166,6 @@ class Nexcessnet_Turpentine_Model_Shim_Mage_Core_App extends Mage_Core_Model_App
166
  * @return Nexcessnet_Turpentine_Model_Shim_Mage_Core_Config
167
  */
168
  protected function _shim_getConfigShim() {
169
- return Mage::getModel( 'turpentine/shim_mage_core_config' );
170
  }
171
  }
35
  */
36
  public function shim_setRequest(Mage_Core_Controller_Request_Http $request) {
37
  $app = $this->_shim_getApp();
38
+ if (method_exists($app, 'setRequest')) {
39
  // use the real setRequest if it's available
40
+ $app->setRequest($request);
41
  } else {
42
  $app->_request = $request;
43
  }
55
  * @param string $method name of the method to call
56
  * @return Nexcessnet_Turpentine_Model_Shim_Mage_Core_App
57
  */
58
+ public function shim_addEventObserver($area, $eventName, $obsName,
59
+ $type = null, $class = null, $method = null) {
60
  $eventConfig = new Varien_Simplexml_Config();
61
+ $eventConfig->loadDom($this->_shim_getEventDom(
62
+ $area, $eventName, $obsName, $type, $class, $method ));
63
+ $this->_shim_getConfig()->extend($eventConfig, true);
64
  // this wouldn't work if PHP had a sane object model
65
  $this->_shim_getApp()->_events[$area][$eventName] = null;
66
  /* clear the event area cache because by the time this gets executed all <global> events have already been
78
  * @param string $rewriteTarget full class name to rewrite to
79
  * @return Nexcessnet_Turpentine_Model_Shim_Mage_Core_App
80
  */
81
+ public function shim_addClassRewrite($type, $module, $class,
82
+ $rewriteTarget) {
83
  $rewriteConfig = new Varien_Simplexml_Config();
84
+ $rewriteConfig->loadDom($this->_shim_getRewriteDom(
85
+ $type, $module, $class, $rewriteTarget ));
86
+ $this->_shim_getConfig()->extend($rewriteConfig, true);
87
  $this->_shim_getConfigShim()->shim_setClassNameCache(
88
  $type, $module, $class, $rewriteTarget );
89
  return $this;
100
  * @param string $method
101
  * @return DOMDocument
102
  */
103
+ protected function _shim_getEventDom($area, $eventName, $obsName,
104
+ $type = null, $class = null, $method = null) {
105
+ $dom = new DOMDocument('1.0');
106
+ $config = $dom->createElement('config');
107
  $observers = $config
108
+ ->appendChild($dom->createElement($area))
109
+ ->appendChild($dom->createElement('events'))
110
+ ->appendChild($dom->createElement($eventName))
111
+ ->appendChild($dom->createElement('observers'));
112
+ $observer = $dom->createElement($obsName);
113
+ if ($class && $method) {
114
+ if ($type) {
115
+ $observer->appendChild($dom->createElement('type', $type));
116
  }
117
+ $observer->appendChild($dom->createElement('class', $class));
118
+ $observer->appendChild($dom->createElement('method', $method));
119
  }
120
+ $observers->appendChild($observer);
121
+ $dom->appendChild($config);
122
  return $dom;
123
  }
124
 
131
  * @param string $className full class name to rewrite to
132
  * @return DOMDocument
133
  */
134
+ protected function _shim_getRewriteDom($groupType, $group, $class, $className) {
135
+ $dom = new DOMDocument('1.0');
136
+ $dom->appendChild($dom->createElement('config'))
137
+ ->appendChild($dom->createElement('global'))
138
+ ->appendChild($dom->createElement($groupType.'s'))
139
+ ->appendChild($dom->createElement($group))
140
+ ->appendChild($dom->createElement('rewrite'))
141
+ ->appendChild($dom->createElement($class, $className));
142
  return $dom;
143
  }
144
 
166
  * @return Nexcessnet_Turpentine_Model_Shim_Mage_Core_Config
167
  */
168
  protected function _shim_getConfigShim() {
169
+ return Mage::getModel('turpentine/shim_mage_core_config');
170
  }
171
  }
app/code/community/Nexcessnet/Turpentine/Model/Shim/Mage/Core/Config.php CHANGED
@@ -31,7 +31,7 @@ class Nexcessnet_Turpentine_Model_Shim_Mage_Core_Config extends Mage_Core_Model_
31
  * @param string $className full class name to rewrite to
32
  * @return string
33
  */
34
- public function shim_setClassNameCache( $groupType, $group, $class, $className ) {
35
  $config = Mage::getConfig();
36
  $prevValue = @$config->_classNameCache[$groupType][$group][$class];
37
  $config->_classNameCache[$groupType][$group][$class] = $className;
@@ -45,9 +45,11 @@ class Nexcessnet_Turpentine_Model_Shim_Mage_Core_Config extends Mage_Core_Model_
45
  * @param $area string The config area to clear (e.g. 'global')
46
  */
47
  public function unsetEventAreaCache($area) {
48
- if(version_compare(Mage::getVersion(),'1.11.0', '>=') // enterprise
49
- || version_compare(Mage::getVersion(), '1.6.0', '>=')) // community
 
50
  unset($this->_eventAreas[$area]);
 
51
  }
52
 
53
  }
31
  * @param string $className full class name to rewrite to
32
  * @return string
33
  */
34
+ public function shim_setClassNameCache($groupType, $group, $class, $className) {
35
  $config = Mage::getConfig();
36
  $prevValue = @$config->_classNameCache[$groupType][$group][$class];
37
  $config->_classNameCache[$groupType][$group][$class] = $className;
45
  * @param $area string The config area to clear (e.g. 'global')
46
  */
47
  public function unsetEventAreaCache($area) {
48
+ if (version_compare(Mage::getVersion(), '1.11.0', '>=') // enterprise
49
+ || version_compare(Mage::getVersion(), '1.6.0', '>=')) {
50
+ // community
51
  unset($this->_eventAreas[$area]);
52
+ }
53
  }
54
 
55
  }
app/code/community/Nexcessnet/Turpentine/Model/Shim/Mage/Core/Layout.php CHANGED
@@ -26,13 +26,13 @@ class Nexcessnet_Turpentine_Model_Shim_Mage_Core_Layout extends Mage_Core_Model_
26
  * @param Mage_Core_Model_Layout_Element $blockNode
27
  * @return null
28
  */
29
- public function shim_generateFullBlock( $blockNode ) {
30
  $layout = $this->_shim_getLayout();
31
- if( !( $parent = $blockNode->getParent() ) ) {
32
  $parent = new Varien_Object();
33
  }
34
- $layout->_generateBlock( $blockNode, $parent );
35
- return $layout->generateBlocks( $blockNode );
36
  }
37
 
38
  /**
@@ -41,11 +41,11 @@ class Nexcessnet_Turpentine_Model_Shim_Mage_Core_Layout extends Mage_Core_Model_
41
  * @param Mage_Core_Model_Layout_Element $node
42
  * @return Mage_Core_Model_Layout
43
  */
44
- public function shim_generateAction( $node ) {
45
- if( !( $parentNode = $node->getParent() ) ) {
46
  $parentNode = new Varien_Object();
47
  }
48
- return $this->_shim_getLayout()->_generateAction( $node, $parentNode );
49
  }
50
 
51
  /**
@@ -54,6 +54,6 @@ class Nexcessnet_Turpentine_Model_Shim_Mage_Core_Layout extends Mage_Core_Model_
54
  * @return Mage_Core_Model_Layout
55
  */
56
  protected function _shim_getLayout() {
57
- return Mage::getSingleton( 'core/layout' );
58
  }
59
  }
26
  * @param Mage_Core_Model_Layout_Element $blockNode
27
  * @return null
28
  */
29
+ public function shim_generateFullBlock($blockNode) {
30
  $layout = $this->_shim_getLayout();
31
+ if ( ! ($parent = $blockNode->getParent())) {
32
  $parent = new Varien_Object();
33
  }
34
+ $layout->_generateBlock($blockNode, $parent);
35
+ return $layout->generateBlocks($blockNode);
36
  }
37
 
38
  /**
41
  * @param Mage_Core_Model_Layout_Element $node
42
  * @return Mage_Core_Model_Layout
43
  */
44
+ public function shim_generateAction($node) {
45
+ if ( ! ($parentNode = $node->getParent())) {
46
  $parentNode = new Varien_Object();
47
  }
48
+ return $this->_shim_getLayout()->_generateAction($node, $parentNode);
49
  }
50
 
51
  /**
54
  * @return Mage_Core_Model_Layout
55
  */
56
  protected function _shim_getLayout() {
57
+ return Mage::getSingleton('core/layout');
58
  }
59
  }
app/code/community/Nexcessnet/Turpentine/Model/Varnish/Admin.php CHANGED
@@ -30,7 +30,7 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin {
30
  * @return bool
31
  */
32
  public function flushAll() {
33
- return $this->flushUrl( '.*' );
34
  }
35
 
36
  /**
@@ -39,15 +39,15 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin {
39
  * @param string $subPattern regex to match against URLs
40
  * @return bool
41
  */
42
- public function flushUrl( $subPattern ) {
43
  $result = array();
44
- foreach( Mage::helper( 'turpentine/varnish' )->getSockets() as $socket ) {
45
  $socketName = $socket->getConnectionString();
46
  try {
47
  // We don't use "ban_url" here, because we want to do lurker friendly bans.
48
  // Lurker friendly bans get cleaned up, so they don't slow down Varnish.
49
- $socket->ban( 'obj.http.X-Varnish-URL', '~', $subPattern );
50
- } catch( Mage_Core_Exception $e ) {
51
  $result[$socketName] = $e->getMessage();
52
  continue;
53
  }
@@ -65,11 +65,11 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin {
65
  public function flushExpression() {
66
  $args = func_get_args();
67
  $result = array();
68
- foreach( Mage::helper( 'turpentine/varnish' )->getSockets() as $socket ) {
69
  $socketName = $socket->getConnectionString();
70
  try {
71
- call_user_func_array( array( $socket, 'ban' ), $args );
72
- } catch( Mage_Core_Exception $e ) {
73
  $result[$socketName] = $e->getMessage();
74
  continue;
75
  }
@@ -84,7 +84,7 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin {
84
  * @param string $contentType
85
  * @return array
86
  */
87
- public function flushContentType( $contentType ) {
88
  return $this->flushExpression(
89
  'obj.http.Content-Type', '~', $contentType );
90
  }
@@ -96,22 +96,22 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin {
96
  */
97
  public function applyConfig() {
98
  $result = array();
99
- $helper = Mage::helper( 'turpentine' );
100
- foreach( Mage::helper( 'turpentine/varnish' )->getSockets() as $socket ) {
101
- $cfgr = Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract::getFromSocket( $socket );
102
  $socketName = $socket->getConnectionString();
103
- if( is_null( $cfgr ) ) {
104
  $result[$socketName] = 'Failed to load configurator';
105
  } else {
106
- $vcl = $cfgr->generate( $helper->shouldStripVclWhitespace('apply') );
107
- $vclName = Mage::helper( 'turpentine/data' )
108
- ->secureHash( microtime() );
109
  try {
110
- $this->_testEsiSyntaxParam( $socket );
111
- $socket->vcl_inline( $vclName, $vcl );
112
- sleep( 1 ); //this is probably not really needed
113
- $socket->vcl_use( $vclName );
114
- } catch( Mage_Core_Exception $e ) {
115
  $result[$socketName] = $e->getMessage();
116
  continue;
117
  }
@@ -127,50 +127,50 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin {
127
  * @return Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract
128
  */
129
  public function getConfigurator() {
130
- $sockets = Mage::helper( 'turpentine/varnish' )->getSockets();
131
- $cfgr = Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract::getFromSocket( $sockets[0] );
132
  return $cfgr;
133
  }
134
 
135
- protected function _testEsiSyntaxParam( $socket ) {
136
- $session = Mage::getSingleton( 'adminhtml/session' );
137
- $helper = Mage::helper( 'turpentine/varnish' );
138
  $result = false;
139
 
140
- if( $helper->csrfFixupNeeded() ) {
141
- if ( $socket->getVersion()==='4.0' ) {
142
  $paramName = 'feature';
143
- $value = $socket->param_show( $paramName );
144
  $value = explode("\n", $value['text']);
145
- if ( isset($value[1]) && strpos($value[1], '+esi_ignore_other_elements')!==false ) {
146
  $result = true;
147
  } else {
148
- $session->addWarning( 'Varnish <em>feature</em> param is ' .
149
- 'not set correctly, please see <a target="_blank" href="' .
150
- self::URL_ESI_SYNTAX_FIX . '">these instructions</a> ' .
151
- 'to fix this warning.' );
152
  }
153
  } else {
154
  $paramName = 'esi_syntax';
155
- $value = $socket->param_show( $paramName );
156
- if( preg_match( '~(\d)\s+\[bitmap\]~', $value['text'], $match ) ) {
157
- $value = hexdec( $match[1] );
158
- if( $value & self::MASK_ESI_SYNTAX ) { //bitwise intentional
159
  // setting is correct, all is fine
160
  $result = true;
161
  } else {
162
- $session->addWarning( 'Varnish <em>esi_syntax</em> param is ' .
163
- 'not set correctly, please see <a target="_blank" href="' .
164
- self::URL_ESI_SYNTAX_FIX . '">these instructions</a> ' .
165
- 'to fix this warning.' );
166
  }
167
  }
168
  }
169
 
170
- if ( $result===false ) {
171
  // error
172
- Mage::helper( 'turpentine/debug' )->logWarn(
173
- sprintf('Failed to parse param.show output to check %s value', $paramName ) );
174
  $result = true;
175
  }
176
  } else {
30
  * @return bool
31
  */
32
  public function flushAll() {
33
+ return $this->flushUrl('.*');
34
  }
35
 
36
  /**
39
  * @param string $subPattern regex to match against URLs
40
  * @return bool
41
  */
42
+ public function flushUrl($subPattern) {
43
  $result = array();
44
+ foreach (Mage::helper('turpentine/varnish')->getSockets() as $socket) {
45
  $socketName = $socket->getConnectionString();
46
  try {
47
  // We don't use "ban_url" here, because we want to do lurker friendly bans.
48
  // Lurker friendly bans get cleaned up, so they don't slow down Varnish.
49
+ $socket->ban('obj.http.X-Varnish-URL', '~', $subPattern);
50
+ } catch (Mage_Core_Exception $e) {
51
  $result[$socketName] = $e->getMessage();
52
  continue;
53
  }
65
  public function flushExpression() {
66
  $args = func_get_args();
67
  $result = array();
68
+ foreach (Mage::helper('turpentine/varnish')->getSockets() as $socket) {
69
  $socketName = $socket->getConnectionString();
70
  try {
71
+ call_user_func_array(array($socket, 'ban'), $args);
72
+ } catch (Mage_Core_Exception $e) {
73
  $result[$socketName] = $e->getMessage();
74
  continue;
75
  }
84
  * @param string $contentType
85
  * @return array
86
  */
87
+ public function flushContentType($contentType) {
88
  return $this->flushExpression(
89
  'obj.http.Content-Type', '~', $contentType );
90
  }
96
  */
97
  public function applyConfig() {
98
  $result = array();
99
+ $helper = Mage::helper('turpentine');
100
+ foreach (Mage::helper('turpentine/varnish')->getSockets() as $socket) {
101
+ $cfgr = Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract::getFromSocket($socket);
102
  $socketName = $socket->getConnectionString();
103
+ if (is_null($cfgr)) {
104
  $result[$socketName] = 'Failed to load configurator';
105
  } else {
106
+ $vcl = $cfgr->generate($helper->shouldStripVclWhitespace('apply'));
107
+ $vclName = Mage::helper('turpentine/data')
108
+ ->secureHash(microtime());
109
  try {
110
+ $this->_testEsiSyntaxParam($socket);
111
+ $socket->vcl_inline($vclName, $vcl);
112
+ sleep(1); //this is probably not really needed
113
+ $socket->vcl_use($vclName);
114
+ } catch (Mage_Core_Exception $e) {
115
  $result[$socketName] = $e->getMessage();
116
  continue;
117
  }
127
  * @return Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract
128
  */
129
  public function getConfigurator() {
130
+ $sockets = Mage::helper('turpentine/varnish')->getSockets();
131
+ $cfgr = Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract::getFromSocket($sockets[0]);
132
  return $cfgr;
133
  }
134
 
135
+ protected function _testEsiSyntaxParam($socket) {
136
+ $session = Mage::getSingleton('adminhtml/session');
137
+ $helper = Mage::helper('turpentine/varnish');
138
  $result = false;
139
 
140
+ if ($helper->csrfFixupNeeded()) {
141
+ if ($socket->getVersion() === '4.0') {
142
  $paramName = 'feature';
143
+ $value = $socket->param_show($paramName);
144
  $value = explode("\n", $value['text']);
145
+ if (isset($value[1]) && strpos($value[1], '+esi_ignore_other_elements') !== false) {
146
  $result = true;
147
  } else {
148
+ $session->addWarning('Varnish <em>feature</em> param is '.
149
+ 'not set correctly, please see <a target="_blank" href="'.
150
+ self::URL_ESI_SYNTAX_FIX.'">these instructions</a> '.
151
+ 'to fix this warning.');
152
  }
153
  } else {
154
  $paramName = 'esi_syntax';
155
+ $value = $socket->param_show($paramName);
156
+ if (preg_match('~(\d)\s+\[bitmap\]~', $value['text'], $match)) {
157
+ $value = hexdec($match[1]);
158
+ if ($value & self::MASK_ESI_SYNTAX) { //bitwise intentional
159
  // setting is correct, all is fine
160
  $result = true;
161
  } else {
162
+ $session->addWarning('Varnish <em>esi_syntax</em> param is '.
163
+ 'not set correctly, please see <a target="_blank" href="'.
164
+ self::URL_ESI_SYNTAX_FIX.'">these instructions</a> '.
165
+ 'to fix this warning.');
166
  }
167
  }
168
  }
169
 
170
+ if ($result === false) {
171
  // error
172
+ Mage::helper('turpentine/debug')->logWarn(
173
+ sprintf('Failed to parse param.show output to check %s value', $paramName) );
174
  $result = true;
175
  }
176
  } else {
app/code/community/Nexcessnet/Turpentine/Model/Varnish/Admin/Socket.php CHANGED
@@ -82,7 +82,7 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
82
  // varnish default, can only be changed at Varnish startup time
83
  // if data to write is over this limit the actual run-time limit is checked
84
  // and used
85
- const CLI_CMD_LENGTH_LIMIT = 8192;
86
 
87
  /**
88
  * Regexp to detect the varnish version number
@@ -93,7 +93,7 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
93
  /**
94
  * VCL config versions, should match config select values
95
  */
96
- static protected $_VERSIONS = array( '2.1', '3.0', '4.0' );
97
 
98
  /**
99
  * Varnish socket connection
@@ -108,23 +108,23 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
108
  protected $_timeout = 5;
109
  protected $_version = null; //auto-detect
110
 
111
- public function __construct( array $options=array() ) {
112
- foreach( $options as $key => $value ) {
113
- switch( $key ) {
114
  case 'host':
115
- $this->setHost( $value );
116
  break;
117
  case 'port':
118
- $this->setPort( $value );
119
  break;
120
  case 'auth_secret':
121
- $this->setAuthSecret( $value );
122
  break;
123
  case 'timeout':
124
- $this->setTimeout( $value );
125
  break;
126
  case 'version':
127
- $this->setVersion( $value );
128
  break;
129
  default:
130
  break;
@@ -157,10 +157,10 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
157
  * @param array $args method args
158
  * @return array
159
  */
160
- public function __call( $name, $args ) {
161
- array_unshift( $args, self::CODE_OK );
162
- array_unshift( $args, $this->_translateCommandMethod( $name ) );
163
- return call_user_func_array( array( $this, '_command' ), $args );
164
  }
165
 
166
  /**
@@ -169,7 +169,7 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
169
  * @return string
170
  */
171
  public function getConnectionString() {
172
- return sprintf( '%s:%d', $this->getHost(), $this->getPort() );
173
  }
174
 
175
  /**
@@ -186,7 +186,7 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
186
  *
187
  * @param string $host hostname or ip
188
  */
189
- public function setHost( $host ) {
190
  $this->_close();
191
  $this->_host = $host;
192
  return $this;
@@ -206,9 +206,9 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
206
  *
207
  * @param int $port
208
  */
209
- public function setPort( $port ) {
210
  $this->_close();
211
- $this->_port = (int)$port;
212
  return $this;
213
  }
214
 
@@ -217,7 +217,7 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
217
  *
218
  * @param string $authSecret
219
  */
220
- public function setAuthSecret( $authSecret=null ) {
221
  $this->_authSecret = $authSecret;
222
  return $this;
223
  }
@@ -227,10 +227,10 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
227
  *
228
  * @param int $timeout
229
  */
230
- public function setTimeout( $timeout ) {
231
- $this->_timeout = (int)$timeout;
232
- if( !is_null( $this->_varnishConn ) ) {
233
- stream_set_timeout( $this->_varnishConn, $this->_timeout );
234
  }
235
  return $this;
236
  }
@@ -240,11 +240,11 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
240
  *
241
  * @param string $version version from $_VERSIONS
242
  */
243
- public function setVersion( $version ) {
244
- if( in_array( $version, self::$_VERSIONS ) ) {
245
  $this->_version = $version;
246
  } else {
247
- Mage::throwException( 'Unsupported Varnish version: ' . $version );
248
  }
249
  }
250
 
@@ -254,7 +254,7 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
254
  * @return boolean
255
  */
256
  public function isConnected() {
257
- return !is_null( $this->_varnishConn );
258
  }
259
 
260
  /**
@@ -263,7 +263,7 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
263
  * @return string
264
  */
265
  public function getVersion() {
266
- if ( !$this->isConnected() ) {
267
  $this->_connect();
268
  }
269
  return $this->_version;
@@ -273,7 +273,7 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
273
  * Stop the Varnish instance
274
  */
275
  public function quit() {
276
- $this->_command( 'quit', self::CODE_CLOSE );
277
  $this->_close();
278
  }
279
 
@@ -283,8 +283,8 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
283
  * @return boolean
284
  */
285
  public function status() {
286
- $response = $this->_command( 'status' );
287
- if( !preg_match( '~Child in state (\w+)~', $response['text'], $match ) ) {
288
  return false;
289
  } else {
290
  return $match[1] === 'running';
@@ -297,8 +297,8 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
297
  * @return $this
298
  */
299
  public function stop() {
300
- if( $this->status() ) {
301
- $this->_command( 'stop' );
302
  }
303
  return $this;
304
  }
@@ -309,40 +309,40 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
309
  * @return $this
310
  */
311
  public function start() {
312
- $this->_command( 'start' );
313
  return $this;
314
  }
315
 
316
  /**
317
  * Establish a connection to the configured Varnish instance
318
  *
319
- * @return array
320
  */
321
  protected function _connect() {
322
- $this->_varnishConn = fsockopen( $this->_host, $this->_port, $errno,
323
- $errstr, $this->_timeout );
324
- if( !is_resource( $this->_varnishConn ) ) {
325
- Mage::throwException( sprintf(
326
  'Failed to connect to Varnish on [%s:%d]: (%d) %s',
327
- $this->_host, $this->_port, $errno, $errstr ) );
328
  }
329
 
330
- stream_set_blocking( $this->_varnishConn, 1 );
331
- stream_set_timeout( $this->_varnishConn, $this->_timeout );
332
 
333
  //varnish 2.0 doesn't spit out a banner on connection, this will need
334
  //to be changed if 2.0 support is ever added
335
  $banner = $this->_read();
336
- if( $banner['code'] === self::CODE_AUTH ) {
337
- $challenge = substr( $banner['text'], 0, 32 );
338
- $response = hash( 'sha256', sprintf( "%s\n%s%s\n", $challenge,
339
- $this->_authSecret, $challenge ) );
340
- $banner = $this->_command( 'auth', self::CODE_OK, $response );
341
  }
342
 
343
- if( $banner['code'] !== self::CODE_OK ) {
344
- Mage::throwException( 'Varnish admin authentication failed: ' .
345
- $banner['text'] );
346
  }
347
 
348
  if ($this->_version == null) { // If autodetecting
@@ -352,23 +352,26 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
352
  return $this->isConnected();
353
  }
354
 
 
 
 
355
  protected function _determineVersion($bannerText) {
356
  $bannerText = array_filter(explode("\n", $bannerText));
357
- if ( count($bannerText)<6 ) {
358
  // Varnish 2.0 does not spit out a banner on connect
359
  Mage::throwException('Varnish versions before 2.1 are not supported');
360
  }
361
- if ( count($bannerText)<7 ) {
362
  // Varnish before 3.0.4 does not spit out a version number
363
- $resp = $this->_write( 'help' )->_read();
364
- if( strpos( $resp['text'], 'ban.url' ) !== false ) {
365
  // Varnish versions 3.0 through 3.0.3 do not return a version banner.
366
  // To differentiate between 2.1 and 3.0, we check the existence of the ban.url command.
367
  return '3.0';
368
  }
369
  return '2.1';
370
- } elseif ( preg_match(self::REGEXP_VARNISH_VERSION, $bannerText[4], $matches)===1 ) {
371
- return $matches['vmajor'] . '.' . $matches['vminor'];
372
  } else {
373
  Mage::throwException('Unable to detect varnish version');
374
  }
@@ -380,8 +383,8 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
380
  * @return $this
381
  */
382
  protected function _close() {
383
- if( $this->isConnected() ) {
384
- fclose( $this->_varnishConn );
385
  $this->_varnishConn = null;
386
  }
387
  return $this;
@@ -393,39 +396,39 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
393
  * @param string $data data to write
394
  * @return $this
395
  */
396
- protected function _write( $data ) {
397
- if( is_null( $this->_varnishConn ) ) {
398
  $this->_connect();
399
  }
400
- $data = rtrim( $data ) . PHP_EOL;
401
- $dataLength = strlen( $data );
402
- if( $dataLength >= self::CLI_CMD_LENGTH_LIMIT ) {
403
- $cliBufferResponse = $this->param_show( 'cli_buffer' );
404
  $regexp = '~^cli_buffer\s+(\d+)\s+\[bytes\]~';
405
- if ( $this->getVersion()==='4.0' ) {
406
  // Varnish4 supports "16k" style notation
407
  $regexp = '~^cli_buffer\s+Value is:\s+(\d+)([k|m|g]{1})?\s+\[bytes\]~';
408
  }
409
- if( preg_match( $regexp, $cliBufferResponse['text'], $match ) ) {
410
- $realLimit = (int)$match[1];
411
- if ( isset($match[2]) ) {
412
- $factors = array('k'=>1,'m'=>2,'g'=>3);
413
  $realLimit *= pow(1024, $factors[$match[2]]);
414
  }
415
  } else {
416
- Mage::helper( 'turpentine/debug' )->logWarn(
417
  'Failed to determine Varnish cli_buffer limit, using default' );
418
  $realLimit = self::CLI_CMD_LENGTH_LIMIT;
419
  }
420
- if( $dataLength >= $realLimit ) {
421
- Mage::throwException( sprintf(
422
  'Varnish data to write over length limit by %d characters',
423
- $dataLength - $realLimit ) );
424
  }
425
  }
426
- if( ( $byteCount = fwrite( $this->_varnishConn, $data ) ) !== $dataLength ) {
427
- Mage::throwException( sprintf( 'Varnish socket write error: %d != %d',
428
- $byteCount, $dataLength ) );
429
  }
430
  return $this;
431
  }
@@ -438,29 +441,29 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
438
  protected function _read() {
439
  $code = null;
440
  $len = -1;
441
- while( !feof( $this->_varnishConn ) ) {
442
- $response = fgets( $this->_varnishConn, self::READ_CHUNK_SIZE );
443
- if( empty( $response ) ) {
444
- $streamMeta = stream_get_meta_data( $this->_varnishConn );
445
- if( $streamMeta['timed_out'] ) {
446
- Mage::throwException( 'Varnish admin socket timeout' );
447
  }
448
  }
449
- if( preg_match( '~^(\d{3}) (\d+)~', $response, $match ) ) {
450
- $code = (int)$match[1];
451
- $len = (int)$match[2];
452
  break;
453
  }
454
  }
455
 
456
- if( is_null( $code ) ) {
457
- Mage::throwException( 'Failed to read response code from Varnish' );
458
  } else {
459
- $response = array( 'code' => $code, 'text' => '' );
460
- while( !feof( $this->_varnishConn ) &&
461
- strlen( $response['text'] ) < $len ) {
462
- $response['text'] .= fgets( $this->_varnishConn,
463
- self::READ_CHUNK_SIZE );
464
  }
465
  return $response;
466
  }
@@ -469,32 +472,32 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
469
  /**
470
  * [_command description]
471
  * @param string $verb command name
472
- * @param integer $okCode=200 code that indicates command was successful
473
  * @param string ... command args
474
  * @return array
475
  */
476
- protected function _command( $verb, $okCode=200 ) {
477
  $params = func_get_args();
478
  //remove $verb
479
- array_shift( $params );
480
  //remove $okCode (if it exists)
481
- array_shift( $params );
482
  $cleanedParams = array();
483
- foreach( $params as $param ) {
484
- $cp = addcslashes( $param, "\"\\" );
485
- $cp = str_replace( PHP_EOL, '\n', $cp );
486
- $cleanedParams[] = sprintf( '"%s"', $cp );
487
  }
488
- $data = implode( ' ', array_merge(
489
- array( sprintf( '"%s"', $verb ) ),
490
- $cleanedParams ) );
491
- $response = $this->_write( $data )->_read();
492
- if( $response['code'] !== $okCode && !is_null( $okCode ) ) {
493
- Mage::helper( 'turpentine/debug' )->logDebug(
494
  'Error on Varnish command: %s', $data );
495
- Mage::throwException( sprintf(
496
  "Got unexpected response code from Varnish: %d\n%s",
497
- $response['code'], $response['text'] ) );
498
  } else {
499
  return $response;
500
  }
@@ -506,19 +509,19 @@ class Nexcessnet_Turpentine_Model_Varnish_Admin_Socket {
506
  * @param string $verb command to check
507
  * @return string
508
  */
509
- protected function _translateCommandMethod( $verb ) {
510
- $command = str_replace( '_', '.', $verb );
511
- switch( $this->getVersion() ) {
512
  case '2.1':
513
- $command = str_replace( 'ban', 'purge', $command );
514
  break;
515
- case '4.0':
516
  case '3.0':
517
- $command = str_replace( 'purge', 'ban', $command );
518
  break;
519
  default:
520
- Mage::throwException( 'Unrecognized Varnish version: ' .
521
- $this->_version );
522
  }
523
  return $command;
524
  }
82
  // varnish default, can only be changed at Varnish startup time
83
  // if data to write is over this limit the actual run-time limit is checked
84
  // and used
85
+ const CLI_CMD_LENGTH_LIMIT = 8192;
86
 
87
  /**
88
  * Regexp to detect the varnish version number
93
  /**
94
  * VCL config versions, should match config select values
95
  */
96
+ static protected $_VERSIONS = array('2.1', '3.0', '4.0');
97
 
98
  /**
99
  * Varnish socket connection
108
  protected $_timeout = 5;
109
  protected $_version = null; //auto-detect
110
 
111
+ public function __construct(array $options = array()) {
112
+ foreach ($options as $key => $value) {
113
+ switch ($key) {
114
  case 'host':
115
+ $this->setHost($value);
116
  break;
117
  case 'port':
118
+ $this->setPort($value);
119
  break;
120
  case 'auth_secret':
121
+ $this->setAuthSecret($value);
122
  break;
123
  case 'timeout':
124
+ $this->setTimeout($value);
125
  break;
126
  case 'version':
127
+ $this->setVersion($value);
128
  break;
129
  default:
130
  break;
157
  * @param array $args method args
158
  * @return array
159
  */
160
+ public function __call($name, $args) {
161
+ array_unshift($args, self::CODE_OK);
162
+ array_unshift($args, $this->_translateCommandMethod($name));
163
+ return call_user_func_array(array($this, '_command'), $args);
164
  }
165
 
166
  /**
169
  * @return string
170
  */
171
  public function getConnectionString() {
172
+ return sprintf('%s:%d', $this->getHost(), $this->getPort());
173
  }
174
 
175
  /**
186
  *
187
  * @param string $host hostname or ip
188
  */
189
+ public function setHost($host) {
190
  $this->_close();
191
  $this->_host = $host;
192
  return $this;
206
  *
207
  * @param int $port
208
  */
209
+ public function setPort($port) {
210
  $this->_close();
211
+ $this->_port = (int) $port;
212
  return $this;
213
  }
214
 
217
  *
218
  * @param string $authSecret
219
  */
220
+ public function setAuthSecret($authSecret = null) {
221
  $this->_authSecret = $authSecret;
222
  return $this;
223
  }
227
  *
228
  * @param int $timeout
229
  */
230
+ public function setTimeout($timeout) {
231
+ $this->_timeout = (int) $timeout;
232
+ if ( ! is_null($this->_varnishConn)) {
233
+ stream_set_timeout($this->_varnishConn, $this->_timeout);
234
  }
235
  return $this;
236
  }
240
  *
241
  * @param string $version version from $_VERSIONS
242
  */
243
+ public function setVersion($version) {
244
+ if (in_array($version, self::$_VERSIONS)) {
245
  $this->_version = $version;
246
  } else {
247
+ Mage::throwException('Unsupported Varnish version: '.$version);
248
  }
249
  }
250
 
254
  * @return boolean
255
  */
256
  public function isConnected() {
257
+ return ! is_null($this->_varnishConn);
258
  }
259
 
260
  /**
263
  * @return string
264
  */
265
  public function getVersion() {
266
+ if ( ! $this->isConnected()) {
267
  $this->_connect();
268
  }
269
  return $this->_version;
273
  * Stop the Varnish instance
274
  */
275
  public function quit() {
276
+ $this->_command('quit', self::CODE_CLOSE);
277
  $this->_close();
278
  }
279
 
283
  * @return boolean
284
  */
285
  public function status() {
286
+ $response = $this->_command('status');
287
+ if ( ! preg_match('~Child in state (\w+)~', $response['text'], $match)) {
288
  return false;
289
  } else {
290
  return $match[1] === 'running';
297
  * @return $this
298
  */
299
  public function stop() {
300
+ if ($this->status()) {
301
+ $this->_command('stop');
302
  }
303
  return $this;
304
  }
309
  * @return $this
310
  */
311
  public function start() {
312
+ $this->_command('start');
313
  return $this;
314
  }
315
 
316
  /**
317
  * Establish a connection to the configured Varnish instance
318
  *
319
+ * @return boolean
320
  */
321
  protected function _connect() {
322
+ $this->_varnishConn = fsockopen($this->_host, $this->_port, $errno,
323
+ $errstr, $this->_timeout);
324
+ if ( ! is_resource($this->_varnishConn)) {
325
+ Mage::throwException(sprintf(
326
  'Failed to connect to Varnish on [%s:%d]: (%d) %s',
327
+ $this->_host, $this->_port, $errno, $errstr ));
328
  }
329
 
330
+ stream_set_blocking($this->_varnishConn, 1);
331
+ stream_set_timeout($this->_varnishConn, $this->_timeout);
332
 
333
  //varnish 2.0 doesn't spit out a banner on connection, this will need
334
  //to be changed if 2.0 support is ever added
335
  $banner = $this->_read();
336
+ if ($banner['code'] === self::CODE_AUTH) {
337
+ $challenge = substr($banner['text'], 0, 32);
338
+ $response = hash('sha256', sprintf("%s\n%s%s\n", $challenge,
339
+ $this->_authSecret, $challenge));
340
+ $banner = $this->_command('auth', self::CODE_OK, $response);
341
  }
342
 
343
+ if ($banner['code'] !== self::CODE_OK) {
344
+ Mage::throwException('Varnish admin authentication failed: '.
345
+ $banner['text']);
346
  }
347
 
348
  if ($this->_version == null) { // If autodetecting
352
  return $this->isConnected();
353
  }
354
 
355
+ /**
356
+ * @param string $bannerText
357
+ */
358
  protected function _determineVersion($bannerText) {
359
  $bannerText = array_filter(explode("\n", $bannerText));
360
+ if (count($bannerText) < 6) {
361
  // Varnish 2.0 does not spit out a banner on connect
362
  Mage::throwException('Varnish versions before 2.1 are not supported');
363
  }
364
+ if (count($bannerText) < 7) {
365
  // Varnish before 3.0.4 does not spit out a version number
366
+ $resp = $this->_write('help')->_read();
367
+ if (strpos($resp['text'], 'ban.url') !== false) {
368
  // Varnish versions 3.0 through 3.0.3 do not return a version banner.
369
  // To differentiate between 2.1 and 3.0, we check the existence of the ban.url command.
370
  return '3.0';
371
  }
372
  return '2.1';
373
+ } elseif (preg_match(self::REGEXP_VARNISH_VERSION, $bannerText[4], $matches) === 1) {
374
+ return $matches['vmajor'].'.'.$matches['vminor'];
375
  } else {
376
  Mage::throwException('Unable to detect varnish version');
377
  }
383
  * @return $this
384
  */
385
  protected function _close() {
386
+ if ($this->isConnected()) {
387
+ fclose($this->_varnishConn);
388
  $this->_varnishConn = null;
389
  }
390
  return $this;
396
  * @param string $data data to write
397
  * @return $this
398
  */
399
+ protected function _write($data) {
400
+ if (is_null($this->_varnishConn)) {
401
  $this->_connect();
402
  }
403
+ $data = rtrim($data).PHP_EOL;
404
+ $dataLength = strlen($data);
405
+ if ($dataLength >= self::CLI_CMD_LENGTH_LIMIT) {
406
+ $cliBufferResponse = $this->param_show('cli_buffer');
407
  $regexp = '~^cli_buffer\s+(\d+)\s+\[bytes\]~';
408
+ if ($this->getVersion() === '4.0') {
409
  // Varnish4 supports "16k" style notation
410
  $regexp = '~^cli_buffer\s+Value is:\s+(\d+)([k|m|g]{1})?\s+\[bytes\]~';
411
  }
412
+ if (preg_match($regexp, $cliBufferResponse['text'], $match)) {
413
+ $realLimit = (int) $match[1];
414
+ if (isset($match[2])) {
415
+ $factors = array('k'=>1, 'm'=>2, 'g'=>3);
416
  $realLimit *= pow(1024, $factors[$match[2]]);
417
  }
418
  } else {
419
+ Mage::helper('turpentine/debug')->logWarn(
420
  'Failed to determine Varnish cli_buffer limit, using default' );
421
  $realLimit = self::CLI_CMD_LENGTH_LIMIT;
422
  }
423
+ if ($dataLength >= $realLimit) {
424
+ Mage::throwException(sprintf(
425
  'Varnish data to write over length limit by %d characters',
426
+ $dataLength - $realLimit ));
427
  }
428
  }
429
+ if (($byteCount = fwrite($this->_varnishConn, $data)) !== $dataLength) {
430
+ Mage::throwException(sprintf('Varnish socket write error: %d != %d',
431
+ $byteCount, $dataLength));
432
  }
433
  return $this;
434
  }
441
  protected function _read() {
442
  $code = null;
443
  $len = -1;
444
+ while ( ! feof($this->_varnishConn)) {
445
+ $response = fgets($this->_varnishConn, self::READ_CHUNK_SIZE);
446
+ if (empty($response)) {
447
+ $streamMeta = stream_get_meta_data($this->_varnishConn);
448
+ if ($streamMeta['timed_out']) {
449
+ Mage::throwException('Varnish admin socket timeout');
450
  }
451
  }
452
+ if (preg_match('~^(\d{3}) (\d+)~', $response, $match)) {
453
+ $code = (int) $match[1];
454
+ $len = (int) $match[2];
455
  break;
456
  }
457
  }
458
 
459
+ if (is_null($code)) {
460
+ Mage::throwException('Failed to read response code from Varnish');
461
  } else {
462
+ $response = array('code' => $code, 'text' => '');
463
+ while ( ! feof($this->_varnishConn) &&
464
+ strlen($response['text']) < $len) {
465
+ $response['text'] .= fgets($this->_varnishConn,
466
+ self::READ_CHUNK_SIZE);
467
  }
468
  return $response;
469
  }
472
  /**
473
  * [_command description]
474
  * @param string $verb command name
475
+ * @param integer $okCode code that indicates command was successful
476
  * @param string ... command args
477
  * @return array
478
  */
479
+ protected function _command($verb, $okCode = 200) {
480
  $params = func_get_args();
481
  //remove $verb
482
+ array_shift($params);
483
  //remove $okCode (if it exists)
484
+ array_shift($params);
485
  $cleanedParams = array();
486
+ foreach ($params as $param) {
487
+ $cp = addcslashes($param, "\"\\");
488
+ $cp = str_replace(PHP_EOL, '\n', $cp);
489
+ $cleanedParams[] = sprintf('"%s"', $cp);
490
  }
491
+ $data = implode(' ', array_merge(
492
+ array(sprintf('"%s"', $verb)),
493
+ $cleanedParams ));
494
+ $response = $this->_write($data)->_read();
495
+ if ($response['code'] !== $okCode && ! is_null($okCode)) {
496
+ Mage::helper('turpentine/debug')->logDebug(
497
  'Error on Varnish command: %s', $data );
498
+ Mage::throwException(sprintf(
499
  "Got unexpected response code from Varnish: %d\n%s",
500
+ $response['code'], $response['text'] ));
501
  } else {
502
  return $response;
503
  }
509
  * @param string $verb command to check
510
  * @return string
511
  */
512
+ protected function _translateCommandMethod($verb) {
513
+ $command = str_replace('_', '.', $verb);
514
+ switch ($this->getVersion()) {
515
  case '2.1':
516
+ $command = str_replace('ban', 'purge', $command);
517
  break;
518
+ case '4.0':
519
  case '3.0':
520
+ $command = str_replace('purge', 'ban', $command);
521
  break;
522
  default:
523
+ Mage::throwException('Unrecognized Varnish version: '.
524
+ $this->_version);
525
  }
526
  return $command;
527
  }
app/code/community/Nexcessnet/Turpentine/Model/Varnish/Configurator/Abstract.php CHANGED
@@ -21,7 +21,7 @@
21
 
22
  abstract class Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
23
 
24
- const VCL_CUSTOM_C_CODE_FILE = 'uuid.c';
25
 
26
  /**
27
  * Get the correct version of a configurator from a socket
@@ -29,31 +29,31 @@ abstract class Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
29
  * @param Nexcessnet_Turpentine_Model_Varnish_Admin_Socket $socket
30
  * @return Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract
31
  */
32
- static public function getFromSocket( $socket ) {
33
  try {
34
  $version = $socket->getVersion();
35
- } catch( Mage_Core_Exception $e ) {
36
- Mage::getSingleton( 'core/session' )
37
- ->addError( 'Error determining Varnish version: ' .
38
- $e->getMessage() );
39
  return null;
40
  }
41
- switch( $version ) {
42
  case '4.0':
43
  return Mage::getModel(
44
  'turpentine/varnish_configurator_version4',
45
- array( 'socket' => $socket ) );
46
 
47
  case '3.0':
48
  return Mage::getModel(
49
  'turpentine/varnish_configurator_version3',
50
- array( 'socket' => $socket ) );
51
  case '2.1':
52
  return Mage::getModel(
53
  'turpentine/varnish_configurator_version2',
54
- array( 'socket' => $socket ) );
55
  default:
56
- Mage::throwException( 'Unsupported Varnish version' );
57
  }
58
  }
59
 
@@ -72,11 +72,11 @@ abstract class Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
72
  'vcl_template' => null,
73
  );
74
 
75
- public function __construct( $options=array() ) {
76
- $this->_options = array_merge( $this->_options, $options );
77
  }
78
 
79
- abstract public function generate($doClean=true);
80
  // abstract protected function _getTemplateVars();
81
 
82
  /**
@@ -85,22 +85,22 @@ abstract class Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
85
  * @param string $generatedConfig config generated by @generate
86
  * @return null
87
  */
88
- public function save( $generatedConfig ) {
89
  $filename = $this->_getVclFilename();
90
- $dir = dirname( $filename );
91
- if( !is_dir( $dir ) ) {
92
  // this umask is probably redundant, but just in case...
93
- if( !mkdir( $dir, 0777 & ~umask(), true ) ) {
94
  $err = error_get_last();
95
- return array( false, $err );
96
  }
97
  }
98
- if( strlen( $generatedConfig ) !==
99
- file_put_contents( $filename, $generatedConfig ) ) {
100
  $err = error_get_last();
101
- return array( false, $err );
102
  }
103
- return array( true, null );
104
  }
105
 
106
  /**
@@ -109,9 +109,9 @@ abstract class Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
109
  * @param string $baseFilename
110
  * @return string
111
  */
112
- protected function _getVclTemplateFilename( $baseFilename ) {
113
- $extensionDir = Mage::getModuleDir( '', 'Nexcessnet_Turpentine' );
114
- return sprintf( '%s/misc/%s', $extensionDir, $baseFilename );
115
  }
116
 
117
  /**
@@ -121,8 +121,8 @@ abstract class Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
121
  */
122
  protected function _getVclFilename() {
123
  return $this->_formatTemplate(
124
- Mage::getStoreConfig( 'turpentine_varnish/servers/config_file' ),
125
- array( 'root_dir' => Mage::getBaseDir() ) );
126
  }
127
 
128
  /**
@@ -132,8 +132,8 @@ abstract class Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
132
  */
133
  protected function _getCustomIncludeFilename() {
134
  return $this->_formatTemplate(
135
- Mage::getStoreConfig( 'turpentine_varnish/servers/custom_include_file' ),
136
- array( 'root_dir' => Mage::getBaseDir() ) );
137
  }
138
 
139
  /**
@@ -144,13 +144,13 @@ abstract class Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
144
  * @param array $vars array of key => value replacements
145
  * @return string
146
  */
147
- protected function _formatTemplate( $template, array $vars ) {
148
- $needles = array_map( create_function( '$k', 'return "{{".$k."}}";' ),
149
- array_keys( $vars ) );
150
- $replacements = array_values( $vars );
151
  // do replacements, then delete unused template vars
152
- return preg_replace( '~{{[^}]+}}~', '',
153
- str_replace( $needles, $replacements, $template ) );
154
  }
155
 
156
  /**
@@ -159,8 +159,8 @@ abstract class Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
159
  * @param string $subroutine subroutine name
160
  * @return string
161
  */
162
- protected function _vcl_call( $subroutine ) {
163
- return sprintf( 'call %s;', $subroutine );
164
  }
165
 
166
  /**
@@ -172,10 +172,10 @@ abstract class Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
172
  * @return string
173
  */
174
  protected function _getAdminFrontname() {
175
- if( Mage::getStoreConfig( 'admin/url/use_custom_path' ) ) {
176
- return Mage::getStoreConfig( 'admin/url/custom_path' );
177
  } else {
178
- return (string)Mage::getConfig()->getNode(
179
  'admin/routers/adminhtml/args/frontName' );
180
  }
181
  }
@@ -186,14 +186,14 @@ abstract class Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
186
  * @return string
187
  */
188
  protected function _getNormalizeHostTarget() {
189
- $configHost = trim( Mage::getStoreConfig(
190
- 'turpentine_vcl/normalization/host_target' ) );
191
- if( $configHost ) {
192
  return $configHost;
193
  } else {
194
- $baseUrl = parse_url( Mage::getBaseUrl() );
195
- if( isset( $baseUrl['port'] ) ) {
196
- return sprintf( '%s:%d', $baseUrl['host'], $baseUrl['port'] );
197
  } else {
198
  return $baseUrl['host'];
199
  }
@@ -210,11 +210,11 @@ abstract class Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
210
  */
211
  public function getAllowedHostsRegex() {
212
  $hosts = array();
213
- foreach( Mage::app()->getStores() as $store ) {
214
- $hosts[] = parse_url( $store->getBaseUrl( Mage_Core_Model_Store::URL_TYPE_WEB , false ), PHP_URL_HOST );
215
  }
216
 
217
- $hosts = array_values(array_unique( $hosts ));
218
 
219
  $pattern = '('.implode('|', array_map("preg_quote", $hosts)).')';
220
  return $pattern;
@@ -232,8 +232,8 @@ abstract class Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
232
  return (pass);
233
  }
234
  EOS;
235
- return $this->_formatTemplate( $tpl, array(
236
- 'allowed_hosts_regex' => $this->getAllowedHostsRegex() ) );
237
  }
238
 
239
  /**
@@ -246,9 +246,9 @@ EOS;
246
  */
247
  public function getBaseUrlPathRegex() {
248
  $pattern = '^(%s)(?:(?:index|litespeed)\\.php/)?';
249
- return sprintf( $pattern, implode( '|',
250
- array_map( create_function( '$x', 'return preg_quote($x,"|");' ),
251
- $this->_getBaseUrlPaths() ) ) );
252
  }
253
 
254
  /**
@@ -258,22 +258,22 @@ EOS;
258
  */
259
  protected function _getBaseUrlPaths() {
260
  $paths = array();
261
- $linkTypes = array( Mage_Core_Model_Store::URL_TYPE_LINK,
262
  Mage_Core_Model_Store::URL_TYPE_JS,
263
  Mage_Core_Model_Store::URL_TYPE_SKIN,
264
- Mage_Core_Model_Store::URL_TYPE_MEDIA );
265
- foreach( Mage::app()->getStores() as $store ) {
266
- foreach( $linkTypes as $linkType ) {
267
- $paths[] = parse_url( $store->getBaseUrl( $linkType , false ),
268
- PHP_URL_PATH );
269
- $paths[] = parse_url( $store->getBaseUrl( $linkType , true ),
270
- PHP_URL_PATH );
271
  }
272
  }
273
- $paths = array_unique( $paths );
274
- usort( $paths, create_function( '$a, $b',
275
- 'return strlen( $b ) - strlen( $a );' ) );
276
- return array_values( $paths );
277
  }
278
 
279
  /**
@@ -283,9 +283,9 @@ EOS;
283
  * @return string
284
  */
285
  protected function _getUrlExcludes() {
286
- $urls = Mage::getStoreConfig( 'turpentine_vcl/urls/url_blacklist' );
287
- return implode( '|', array_merge( array( $this->_getAdminFrontname(), 'api' ),
288
- Mage::helper( 'turpentine/data' )->cleanExplode( PHP_EOL, $urls ) ) );
289
  }
290
 
291
  /**
@@ -294,7 +294,7 @@ EOS;
294
  * @return string
295
  */
296
  protected function _getDefaultTtl() {
297
- return Mage::helper( 'turpentine/varnish' )->getDefaultTtl();
298
  }
299
 
300
  /**
@@ -303,18 +303,18 @@ EOS;
303
  * @return string
304
  */
305
  protected function _getDefaultBackend() {
306
- $timeout = Mage::getStoreConfig( 'turpentine_vcl/backend/frontend_timeout' );
307
  $default_options = array(
308
- 'first_byte_timeout' => $timeout . 's',
309
- 'between_bytes_timeout' => $timeout . 's',
310
  );
311
- if ( Mage::getStoreConfig( 'turpentine_vcl/backend/load_balancing' ) != 'no' ) {
312
- return $this->_vcl_director( 'default', $default_options );
313
  } else {
314
- return $this->_vcl_backend( 'default',
315
- Mage::getStoreConfig( 'turpentine_vcl/backend/backend_host' ),
316
- Mage::getStoreConfig( 'turpentine_vcl/backend/backend_port' ),
317
- $default_options );
318
  }
319
  }
320
 
@@ -324,18 +324,18 @@ EOS;
324
  * @return string
325
  */
326
  protected function _getAdminBackend() {
327
- $timeout = Mage::getStoreConfig( 'turpentine_vcl/backend/admin_timeout' );
328
  $admin_options = array(
329
- 'first_byte_timeout' => $timeout . 's',
330
- 'between_bytes_timeout' => $timeout . 's',
331
  );
332
- if ( Mage::getStoreConfig( 'turpentine_vcl/backend/load_balancing' ) != 'no' ) {
333
- return $this->_vcl_director( 'admin', $admin_options );
334
  } else {
335
- return $this->_vcl_backend( 'admin',
336
- Mage::getStoreConfig( 'turpentine_vcl/backend/backend_host' ),
337
- Mage::getStoreConfig( 'turpentine_vcl/backend/backend_port' ),
338
- $admin_options );
339
  }
340
  }
341
 
@@ -348,7 +348,7 @@ EOS;
348
  * @return string
349
  */
350
  protected function _getGracePeriod() {
351
- return Mage::getStoreConfig( 'turpentine_vcl/ttls/grace_period' );
352
  }
353
 
354
  /**
@@ -357,7 +357,7 @@ EOS;
357
  * @return string
358
  */
359
  protected function _getEnableDebugHeaders() {
360
- return Mage::getStoreConfig( 'turpentine_varnish/general/varnish_debug' )
361
  ? 'true' : 'false';
362
  }
363
 
@@ -367,16 +367,16 @@ EOS;
367
  * @return string
368
  */
369
  protected function _getGetParamExcludes() {
370
- return implode( '|', Mage::helper( 'turpentine/data' )->cleanExplode( ',',
371
- Mage::getStoreConfig( 'turpentine_vcl/params/get_params' ) ) );
372
  }
373
 
374
  protected function _getIgnoreGetParameters()
375
  {
376
  /** @var Nexcessnet_Turpentine_Helper_Data $helper */
377
  $helper = Mage::helper('turpentine');
378
- $ignoredParameters = $helper->cleanExplode(',', Mage::getStoreConfig( 'turpentine_vcl/params/ignore_get_params'));
379
- return implode( '|', $ignoredParameters);
380
  }
381
 
382
  /**
@@ -393,7 +393,7 @@ EOS;
393
  * @return string
394
  */
395
  protected function _getGenerateSessionStart() {
396
- return Mage::getStoreConfig( 'turpentine_varnish/general/vcl_fix' )
397
  ? '/* -- REMOVED' : '';
398
  }
399
 
@@ -403,7 +403,7 @@ EOS;
403
  * @return string
404
  */
405
  protected function _getGenerateSessionEnd() {
406
- return Mage::getStoreConfig( 'turpentine_varnish/general/vcl_fix' )
407
  ? '-- */' : '';
408
  }
409
 
@@ -414,7 +414,7 @@ EOS;
414
  * @return string
415
  */
416
  protected function _getGenerateSession() {
417
- return Mage::getStoreConfigFlag( 'turpentine_varnish/general/vcl_fix' )
418
  ? 'return (pipe);' : 'call generate_session;';
419
  }
420
 
@@ -425,7 +425,7 @@ EOS;
425
  * @return string
426
  */
427
  protected function _getGenerateSessionExpires() {
428
- return Mage::getStoreConfig( 'turpentine_varnish/general/vcl_fix' )
429
  ? '# call generate_session_expires' : 'call generate_session_expires;';
430
  }
431
 
@@ -435,7 +435,17 @@ EOS;
435
  * @return string
436
  */
437
  protected function _getForceCacheStatic() {
438
- return Mage::getStoreConfig( 'turpentine_vcl/static/force_static' )
 
 
 
 
 
 
 
 
 
 
439
  ? 'true' : 'false';
440
  }
441
 
@@ -445,8 +455,8 @@ EOS;
445
  * @return string
446
  */
447
  protected function _getStaticExtensions() {
448
- return implode( '|', Mage::helper( 'turpentine/data' )->cleanExplode( ',',
449
- Mage::getStoreConfig( 'turpentine_vcl/static/exts' ) ) );
450
  }
451
 
452
  /**
@@ -455,7 +465,7 @@ EOS;
455
  * @return string
456
  */
457
  protected function _getStaticTtl() {
458
- return Mage::getStoreConfig( 'turpentine_vcl/ttls/static_ttl' );
459
  }
460
 
461
  /**
@@ -465,22 +475,22 @@ EOS;
465
  */
466
  protected function _getUrlTtls() {
467
  $str = array();
468
- $configTtls = Mage::helper( 'turpentine/data' )->cleanExplode( PHP_EOL,
469
- Mage::getStoreConfig( 'turpentine_vcl/ttls/url_ttls' ) );
470
  $ttls = array();
471
- foreach( $configTtls as $line ) {
472
- $ttls[] = explode( ',', trim( $line ) );
473
  }
474
- foreach( $ttls as $ttl ) {
475
- $str[] = sprintf( 'if (bereq.url ~ "%s%s") { set beresp.ttl = %ds; }',
476
- $this->getBaseUrlPathRegex(), $ttl[0], $ttl[1] );
477
  }
478
- $str = implode( ' else ', $str );
479
- if( $str ) {
480
- $str .= sprintf( ' else { set beresp.ttl = %ds; }',
481
- $this->_getDefaultTtl() );
482
  } else {
483
- $str = sprintf( 'set beresp.ttl = %ds;', $this->_getDefaultTtl() );
484
  }
485
  return $str;
486
  }
@@ -491,7 +501,7 @@ EOS;
491
  * @return string
492
  */
493
  protected function _getEnableCaching() {
494
- return Mage::helper( 'turpentine/varnish' )->getVarnishEnabled() ?
495
  'true' : 'false';
496
  }
497
 
@@ -501,8 +511,8 @@ EOS;
501
  * @return array
502
  */
503
  protected function _getDebugIps() {
504
- return Mage::helper( 'turpentine/data' )->cleanExplode( ',',
505
- Mage::getStoreConfig( 'dev/restrict/allow_ips' ) );
506
  }
507
 
508
  /**
@@ -511,8 +521,8 @@ EOS;
511
  * @return array
512
  */
513
  protected function _getCrawlerIps() {
514
- return Mage::helper( 'turpentine/data' )->cleanExplode( ',',
515
- Mage::getStoreConfig( 'turpentine_vcl/backend/crawlers' ) );
516
  }
517
 
518
  /**
@@ -521,10 +531,10 @@ EOS;
521
  * @return string
522
  */
523
  protected function _getCrawlerUserAgents() {
524
- return implode( '|', Mage::helper( 'turpentine/data' )
525
- ->cleanExplode( ',',
526
  Mage::getStoreConfig(
527
- 'turpentine_vcl/backend/crawler_user_agents' ) ) );
528
  }
529
 
530
  /**
@@ -535,7 +545,7 @@ EOS;
535
  * @return string
536
  */
537
  protected function _getLruFactor() {
538
- return Mage::getStoreConfig( 'turpentine_vcl/ttls/lru_factor' );
539
  }
540
 
541
  /**
@@ -548,19 +558,19 @@ EOS;
548
  */
549
  protected function _getAdvancedSessionValidationTargets() {
550
  $validation = array();
551
- if( Mage::getStoreConfig( 'web/session/use_remote_addr' ) ) {
552
  $validation[] = 'client.ip';
553
  }
554
- if( Mage::getStoreConfig( 'web/session/use_http_via' ) ) {
555
  $validation[] = 'req.http.Via';
556
  }
557
- if( Mage::getStoreConfig( 'web/session/use_http_x_forwarded_for' ) ) {
558
  $validation[] = 'req.http.X-Forwarded-For';
559
  }
560
- if( Mage::getStoreConfig(
561
  'web/session/use_http_user_agent' ) &&
562
- !Mage::getStoreConfig(
563
- 'turpentine_vcl/normalization/user_agent' ) ) {
564
  $validation[] = 'req.http.User-Agent';
565
  }
566
  return $validation;
@@ -572,12 +582,12 @@ EOS;
572
  * @param string $dirtyVcl generated vcl
573
  * @return string
574
  */
575
- protected function _cleanVcl( $dirtyVcl ) {
576
- return implode( PHP_EOL,
577
  array_filter(
578
- Mage::helper( 'turpentine/data' )
579
- ->cleanExplode( PHP_EOL, $dirtyVcl ),
580
- array( $this, '_cleanVclHelper' )
581
  )
582
  );
583
  }
@@ -588,11 +598,11 @@ EOS;
588
  * @param string $line
589
  * @return bool
590
  */
591
- protected function _cleanVclHelper( $line ) {
592
  return $line &&
593
- ( ( substr( $line, 0, 1 ) != '#' &&
594
- substr( $line, 0, 2 ) != '//' ) ||
595
- substr( $line, 0, 8 ) == '#include' );
596
  }
597
 
598
  /**
@@ -604,7 +614,7 @@ EOS;
604
  * @param array $options options
605
  * @return string
606
  */
607
- protected function _vcl_backend( $name, $host, $port, $options=array() ) {
608
  $tpl = <<<EOS
609
  backend {{name}} {
610
  .host = "{{host}}";
@@ -616,11 +626,11 @@ EOS;
616
  'port' => $port,
617
  'name' => $name,
618
  );
619
- $str = $this->_formatTemplate( $tpl, $vars );
620
- foreach( $options as $key => $value ) {
621
- $str .= sprintf( ' .%s = %s;', $key, $value ) . PHP_EOL;
622
  }
623
- $str .= '}' . PHP_EOL;
624
  return $str;
625
  }
626
 
@@ -631,33 +641,33 @@ EOS;
631
  * @param array $backendOptions options for each backend
632
  * @return string
633
  */
634
- protected function _vcl_director( $name, $backendOptions ) {
635
  $tpl = <<<EOS
636
  director {{name}} round-robin {
637
  {{backends}}
638
  }
639
  EOS;
640
- if ( 'admin' == $name && 'yes_admin' == Mage::getStoreConfig( 'turpentine_vcl/backend/load_balancing' ) ) {
641
- $backendNodes = Mage::helper( 'turpentine/data' )->cleanExplode( PHP_EOL,
642
- Mage::getStoreConfig( 'turpentine_vcl/backend/backend_nodes_admin' ) );
643
- $probeUrl = Mage::getStoreConfig( 'turpentine_vcl/backend/backend_probe_url_admin' );
644
  } else {
645
- $backendNodes = Mage::helper( 'turpentine/data' )->cleanExplode( PHP_EOL,
646
- Mage::getStoreConfig( 'turpentine_vcl/backend/backend_nodes' ) );
647
- $probeUrl = Mage::getStoreConfig( 'turpentine_vcl/backend/backend_probe_url' );
648
  }
649
  $backends = '';
650
- foreach ( $backendNodes as $backendNode ) {
651
- $parts = explode( ':', $backendNode, 2 );
652
- $host = ( empty($parts[0]) ) ? '127.0.0.1' : $parts[0];
653
- $port = ( empty($parts[1]) ) ? '80' : $parts[1];
654
- $backends .= $this->_vcl_director_backend( $host, $port, $probeUrl, $backendOptions );
655
  }
656
  $vars = array(
657
  'name' => $name,
658
  'backends' => $backends
659
  );
660
- return $this->_formatTemplate( $tpl, $vars );
661
  }
662
 
663
  /**
@@ -669,7 +679,7 @@ EOS;
669
  * @param array $options extra options for backend
670
  * @return string
671
  */
672
- protected function _vcl_director_backend( $host, $port, $probeUrl='', $options=array() ) {
673
  $tpl = <<<EOS
674
  {
675
  .backend = {
@@ -683,12 +693,12 @@ EOS;
683
  'port' => $port,
684
  'probe' => ''
685
  );
686
- if ( !empty( $probeUrl ) ) {
687
- $vars['probe'] = $this->_vcl_get_probe( $probeUrl );
688
  }
689
- $str = $this->_formatTemplate( $tpl, $vars );
690
- foreach( $options as $key => $value ) {
691
- $str .= sprintf( ' .%s = %s;', $key, $value ) . PHP_EOL;
692
  }
693
  $str .= <<<EOS
694
  }
@@ -703,9 +713,9 @@ EOS;
703
  * @param string $probeUrl URL to check if backend is up
704
  * @return string
705
  */
706
- protected function _vcl_get_probe( $probeUrl ) {
707
- $urlParts = parse_url( $probeUrl );
708
- if ( empty( $urlParts ) ) {
709
  // Malformed URL
710
  return '';
711
  } else {
@@ -721,7 +731,7 @@ EOS;
721
  'probe_host' => $urlParts['host'],
722
  'probe_path' => $urlParts['path']
723
  );
724
- return $this->_formatTemplate( $tpl, $vars );
725
  }
726
  }
727
 
@@ -732,18 +742,18 @@ EOS;
732
  * @param array $hosts list of hosts to add to the ACL
733
  * @return string
734
  */
735
- protected function _vcl_acl( $name, array $hosts ) {
736
  $tpl = <<<EOS
737
  acl {{name}} {
738
  {{hosts}}
739
  }
740
  EOS;
741
- $fmtHost = create_function( '$h', 'return sprintf(\'"%s";\',$h);' );
742
  $vars = array(
743
  'name' => $name,
744
- 'hosts' => implode( "\n ", array_map( $fmtHost, $hosts ) ),
745
  );
746
- return $this->_formatTemplate( $tpl, $vars );
747
  }
748
 
749
  /**
@@ -809,8 +819,8 @@ EOS;
809
  set req.http.Host = "{{normalize_host_target}}";
810
 
811
  EOS;
812
- return $this->_formatTemplate( $tpl, array(
813
- 'normalize_host_target' => $this->_getNormalizeHostTarget() ) );
814
  }
815
 
816
  /**
@@ -819,8 +829,8 @@ EOS;
819
  * @return string
820
  */
821
  protected function _getNormalizeCookieTarget() {
822
- return trim( Mage::getStoreConfig(
823
- 'turpentine_vcl/normalization/cookie_target' ) );
824
  }
825
 
826
  /**
@@ -829,8 +839,8 @@ EOS;
829
  * @return string
830
  */
831
  protected function _getNormalizeCookieRegex() {
832
- return trim( Mage::getStoreConfig(
833
- 'turpentine_vcl/normalization/cookie_regex' ) );
834
  }
835
 
836
  /**
@@ -839,11 +849,11 @@ EOS;
839
  * @return string
840
  */
841
  protected function _vcl_sub_maintenance_allowed_ips() {
842
- if((! $this->_getDebugIps()) || ! Mage::getStoreConfig( 'turpentine_vcl/maintenance/custom_vcl_synth' ) ) {
843
  return false;
844
  }
845
 
846
- switch(Mage::getStoreConfig( 'turpentine_varnish/servers/version' )) {
847
  case 4.0:
848
  $tpl = <<<EOS
849
  if (req.http.X-Forwarded-For) {
@@ -873,8 +883,8 @@ if (req.http.X-Forwarded-For) {
873
  EOS;
874
  }
875
 
876
- return $this->_formatTemplate( $tpl, array(
877
- 'debug_ips' => Mage::getStoreConfig( 'dev/restrict/allow_ips' ) ) );
878
  }
879
 
880
  /**
@@ -884,7 +894,7 @@ EOS;
884
  */
885
  protected function _vcl_sub_synth()
886
  {
887
- if ((!$this->_getDebugIps()) || !Mage::getStoreConfig('turpentine_vcl/maintenance/custom_vcl_synth')) {
888
  return false;
889
  }
890
 
@@ -942,6 +952,7 @@ EOS;
942
  'debug_headers' => $this->_getEnableDebugHeaders(),
943
  'grace_period' => $this->_getGracePeriod(),
944
  'force_cache_static' => $this->_getForceCacheStatic(),
 
945
  'generate_session_expires' => $this->_getGenerateSessionExpires(),
946
  'generate_session' => $this->_getGenerateSession(),
947
  'generate_session_start' => $this->_getGenerateSessionStart(),
@@ -950,46 +961,46 @@ EOS;
950
  'static_ttl' => $this->_getStaticTtl(),
951
  'url_ttls' => $this->_getUrlTtls(),
952
  'enable_caching' => $this->_getEnableCaching(),
953
- 'crawler_acl' => $this->_vcl_acl( 'crawler_acl',
954
- $this->_getCrawlerIps() ),
955
  'esi_cache_type_param' =>
956
- Mage::helper( 'turpentine/esi' )->getEsiCacheTypeParam(),
957
  'esi_method_param' =>
958
- Mage::helper( 'turpentine/esi' )->getEsiMethodParam(),
959
- 'esi_ttl_param' => Mage::helper( 'turpentine/esi' )->getEsiTtlParam(),
960
- 'secret_handshake' => Mage::helper( 'turpentine/varnish' )
961
  ->getSecretHandshake(),
962
  'crawler_user_agent_regex' => $this->_getCrawlerUserAgents(),
963
  // 'lru_factor' => $this->_getLruFactor(),
964
- 'debug_acl' => $this->_vcl_acl( 'debug_acl',
965
- $this->_getDebugIps() ),
966
  'custom_c_code' => file_get_contents(
967
- $this->_getVclTemplateFilename( self::VCL_CUSTOM_C_CODE_FILE ) ),
968
- 'esi_private_ttl' => Mage::helper( 'turpentine/esi' )
969
  ->getDefaultEsiTtl(),
970
  );
971
 
972
- if( (bool)Mage::getStoreConfig( 'turpentine_vcl/urls/bypass_cache_store_url') ) {
973
  $vars['allowed_hosts'] = $this->_vcl_sub_allowed_hosts_regex();
974
  }
975
 
976
- if( Mage::getStoreConfig( 'turpentine_vcl/normalization/encoding' ) ) {
977
  $vars['normalize_encoding'] = $this->_vcl_sub_normalize_encoding();
978
  }
979
- if( Mage::getStoreConfig( 'turpentine_vcl/normalization/user_agent' ) ) {
980
  $vars['normalize_user_agent'] = $this->_vcl_sub_normalize_user_agent();
981
  }
982
- if( Mage::getStoreConfig( 'turpentine_vcl/normalization/host' ) ) {
983
  $vars['normalize_host'] = $this->_vcl_sub_normalize_host();
984
  }
985
- if( Mage::getStoreConfig( 'turpentine_vcl/normalization/cookie_regex' ) ) {
986
  $vars['normalize_cookie_regex'] = $this->_getNormalizeCookieRegex();
987
  }
988
- if( Mage::getStoreConfig( 'turpentine_vcl/normalization/cookie_target' ) ) {
989
  $vars['normalize_cookie_target'] = $this->_getNormalizeCookieTarget();
990
  }
991
 
992
- if( Mage::getStoreConfig( 'turpentine_vcl/maintenance/enable' ) ) {
993
  // in vcl_recv set the allowed IPs otherwise load the vcl_error (v3)/vcl_synth (v4)
994
  $vars['maintenance_allowed_ips'] = $this->_vcl_sub_maintenance_allowed_ips();
995
  // set the vcl_error from Magento database
@@ -997,8 +1008,8 @@ EOS;
997
  }
998
 
999
  $customIncludeFile = $this->_getCustomIncludeFilename();
1000
- if( is_readable( $customIncludeFile ) ) {
1001
- $vars['custom_vcl_include'] = file_get_contents( $customIncludeFile );
1002
  }
1003
 
1004
  return $vars;
21
 
22
  abstract class Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
23
 
24
+ const VCL_CUSTOM_C_CODE_FILE = 'uuid.c';
25
 
26
  /**
27
  * Get the correct version of a configurator from a socket
29
  * @param Nexcessnet_Turpentine_Model_Varnish_Admin_Socket $socket
30
  * @return Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract
31
  */
32
+ static public function getFromSocket($socket) {
33
  try {
34
  $version = $socket->getVersion();
35
+ } catch (Mage_Core_Exception $e) {
36
+ Mage::getSingleton('core/session')
37
+ ->addError('Error determining Varnish version: '.
38
+ $e->getMessage());
39
  return null;
40
  }
41
+ switch ($version) {
42
  case '4.0':
43
  return Mage::getModel(
44
  'turpentine/varnish_configurator_version4',
45
+ array('socket' => $socket) );
46
 
47
  case '3.0':
48
  return Mage::getModel(
49
  'turpentine/varnish_configurator_version3',
50
+ array('socket' => $socket) );
51
  case '2.1':
52
  return Mage::getModel(
53
  'turpentine/varnish_configurator_version2',
54
+ array('socket' => $socket) );
55
  default:
56
+ Mage::throwException('Unsupported Varnish version');
57
  }
58
  }
59
 
72
  'vcl_template' => null,
73
  );
74
 
75
+ public function __construct($options = array()) {
76
+ $this->_options = array_merge($this->_options, $options);
77
  }
78
 
79
+ abstract public function generate($doClean = true);
80
  // abstract protected function _getTemplateVars();
81
 
82
  /**
85
  * @param string $generatedConfig config generated by @generate
86
  * @return null
87
  */
88
+ public function save($generatedConfig) {
89
  $filename = $this->_getVclFilename();
90
+ $dir = dirname($filename);
91
+ if ( ! is_dir($dir)) {
92
  // this umask is probably redundant, but just in case...
93
+ if ( ! mkdir($dir, 0777 & ~umask(), true)) {
94
  $err = error_get_last();
95
+ return array(false, $err);
96
  }
97
  }
98
+ if (strlen($generatedConfig) !==
99
+ file_put_contents($filename, $generatedConfig)) {
100
  $err = error_get_last();
101
+ return array(false, $err);
102
  }
103
+ return array(true, null);
104
  }
105
 
106
  /**
109
  * @param string $baseFilename
110
  * @return string
111
  */
112
+ protected function _getVclTemplateFilename($baseFilename) {
113
+ $extensionDir = Mage::getModuleDir('', 'Nexcessnet_Turpentine');
114
+ return sprintf('%s/misc/%s', $extensionDir, $baseFilename);
115
  }
116
 
117
  /**
121
  */
122
  protected function _getVclFilename() {
123
  return $this->_formatTemplate(
124
+ Mage::getStoreConfig('turpentine_varnish/servers/config_file'),
125
+ array('root_dir' => Mage::getBaseDir()) );
126
  }
127
 
128
  /**
132
  */
133
  protected function _getCustomIncludeFilename() {
134
  return $this->_formatTemplate(
135
+ Mage::getStoreConfig('turpentine_varnish/servers/custom_include_file'),
136
+ array('root_dir' => Mage::getBaseDir()) );
137
  }
138
 
139
  /**
144
  * @param array $vars array of key => value replacements
145
  * @return string
146
  */
147
+ protected function _formatTemplate($template, array $vars) {
148
+ $needles = array_map(create_function('$k', 'return "{{".$k."}}";'),
149
+ array_keys($vars));
150
+ $replacements = array_values($vars);
151
  // do replacements, then delete unused template vars
152
+ return preg_replace('~{{[^}]+}}~', '',
153
+ str_replace($needles, $replacements, $template));
154
  }
155
 
156
  /**
159
  * @param string $subroutine subroutine name
160
  * @return string
161
  */
162
+ protected function _vcl_call($subroutine) {
163
+ return sprintf('call %s;', $subroutine);
164
  }
165
 
166
  /**
172
  * @return string
173
  */
174
  protected function _getAdminFrontname() {
175
+ if (Mage::getStoreConfig('admin/url/use_custom_path')) {
176
+ return Mage::getStoreConfig('admin/url/custom_path');
177
  } else {
178
+ return (string) Mage::getConfig()->getNode(
179
  'admin/routers/adminhtml/args/frontName' );
180
  }
181
  }
186
  * @return string
187
  */
188
  protected function _getNormalizeHostTarget() {
189
+ $configHost = trim(Mage::getStoreConfig(
190
+ 'turpentine_vcl/normalization/host_target' ));
191
+ if ($configHost) {
192
  return $configHost;
193
  } else {
194
+ $baseUrl = parse_url(Mage::getBaseUrl());
195
+ if (isset($baseUrl['port'])) {
196
+ return sprintf('%s:%d', $baseUrl['host'], $baseUrl['port']);
197
  } else {
198
  return $baseUrl['host'];
199
  }
210
  */
211
  public function getAllowedHostsRegex() {
212
  $hosts = array();
213
+ foreach (Mage::app()->getStores() as $store) {
214
+ $hosts[] = parse_url($store->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB, false), PHP_URL_HOST);
215
  }
216
 
217
+ $hosts = array_values(array_unique($hosts));
218
 
219
  $pattern = '('.implode('|', array_map("preg_quote", $hosts)).')';
220
  return $pattern;
232
  return (pass);
233
  }
234
  EOS;
235
+ return $this->_formatTemplate($tpl, array(
236
+ 'allowed_hosts_regex' => $this->getAllowedHostsRegex() ));
237
  }
238
 
239
  /**
246
  */
247
  public function getBaseUrlPathRegex() {
248
  $pattern = '^(%s)(?:(?:index|litespeed)\\.php/)?';
249
+ return sprintf($pattern, implode('|',
250
+ array_map(create_function('$x', 'return preg_quote($x,"|");'),
251
+ $this->_getBaseUrlPaths())));
252
  }
253
 
254
  /**
258
  */
259
  protected function _getBaseUrlPaths() {
260
  $paths = array();
261
+ $linkTypes = array(Mage_Core_Model_Store::URL_TYPE_LINK,
262
  Mage_Core_Model_Store::URL_TYPE_JS,
263
  Mage_Core_Model_Store::URL_TYPE_SKIN,
264
+ Mage_Core_Model_Store::URL_TYPE_MEDIA);
265
+ foreach (Mage::app()->getStores() as $store) {
266
+ foreach ($linkTypes as $linkType) {
267
+ $paths[] = parse_url($store->getBaseUrl($linkType, false),
268
+ PHP_URL_PATH);
269
+ $paths[] = parse_url($store->getBaseUrl($linkType, true),
270
+ PHP_URL_PATH);
271
  }
272
  }
273
+ $paths = array_unique($paths);
274
+ usort($paths, create_function('$a, $b',
275
+ 'return strlen( $b ) - strlen( $a );'));
276
+ return array_values($paths);
277
  }
278
 
279
  /**
283
  * @return string
284
  */
285
  protected function _getUrlExcludes() {
286
+ $urls = Mage::getStoreConfig('turpentine_vcl/urls/url_blacklist');
287
+ return implode('|', array_merge(array($this->_getAdminFrontname(), 'api'),
288
+ Mage::helper('turpentine/data')->cleanExplode(PHP_EOL, $urls)));
289
  }
290
 
291
  /**
294
  * @return string
295
  */
296
  protected function _getDefaultTtl() {
297
+ return Mage::helper('turpentine/varnish')->getDefaultTtl();
298
  }
299
 
300
  /**
303
  * @return string
304
  */
305
  protected function _getDefaultBackend() {
306
+ $timeout = Mage::getStoreConfig('turpentine_vcl/backend/frontend_timeout');
307
  $default_options = array(
308
+ 'first_byte_timeout' => $timeout.'s',
309
+ 'between_bytes_timeout' => $timeout.'s',
310
  );
311
+ if (Mage::getStoreConfig('turpentine_vcl/backend/load_balancing') != 'no') {
312
+ return $this->_vcl_director('default', $default_options);
313
  } else {
314
+ return $this->_vcl_backend('default',
315
+ Mage::getStoreConfig('turpentine_vcl/backend/backend_host'),
316
+ Mage::getStoreConfig('turpentine_vcl/backend/backend_port'),
317
+ $default_options);
318
  }
319
  }
320
 
324
  * @return string
325
  */
326
  protected function _getAdminBackend() {
327
+ $timeout = Mage::getStoreConfig('turpentine_vcl/backend/admin_timeout');
328
  $admin_options = array(
329
+ 'first_byte_timeout' => $timeout.'s',
330
+ 'between_bytes_timeout' => $timeout.'s',
331
  );
332
+ if (Mage::getStoreConfig('turpentine_vcl/backend/load_balancing') != 'no') {
333
+ return $this->_vcl_director('admin', $admin_options);
334
  } else {
335
+ return $this->_vcl_backend('admin',
336
+ Mage::getStoreConfig('turpentine_vcl/backend/backend_host'),
337
+ Mage::getStoreConfig('turpentine_vcl/backend/backend_port'),
338
+ $admin_options);
339
  }
340
  }
341
 
348
  * @return string
349
  */
350
  protected function _getGracePeriod() {
351
+ return Mage::getStoreConfig('turpentine_vcl/ttls/grace_period');
352
  }
353
 
354
  /**
357
  * @return string
358
  */
359
  protected function _getEnableDebugHeaders() {
360
+ return Mage::getStoreConfig('turpentine_varnish/general/varnish_debug')
361
  ? 'true' : 'false';
362
  }
363
 
367
  * @return string
368
  */
369
  protected function _getGetParamExcludes() {
370
+ return implode('|', Mage::helper('turpentine/data')->cleanExplode(',',
371
+ Mage::getStoreConfig('turpentine_vcl/params/get_params')));
372
  }
373
 
374
  protected function _getIgnoreGetParameters()
375
  {
376
  /** @var Nexcessnet_Turpentine_Helper_Data $helper */
377
  $helper = Mage::helper('turpentine');
378
+ $ignoredParameters = $helper->cleanExplode(',', Mage::getStoreConfig('turpentine_vcl/params/ignore_get_params'));
379
+ return implode('|', $ignoredParameters);
380
  }
381
 
382
  /**
393
  * @return string
394
  */
395
  protected function _getGenerateSessionStart() {
396
+ return Mage::getStoreConfig('turpentine_varnish/general/vcl_fix')
397
  ? '/* -- REMOVED' : '';
398
  }
399
 
403
  * @return string
404
  */
405
  protected function _getGenerateSessionEnd() {
406
+ return Mage::getStoreConfig('turpentine_varnish/general/vcl_fix')
407
  ? '-- */' : '';
408
  }
409
 
414
  * @return string
415
  */
416
  protected function _getGenerateSession() {
417
+ return Mage::getStoreConfigFlag('turpentine_varnish/general/vcl_fix')
418
  ? 'return (pipe);' : 'call generate_session;';
419
  }
420
 
425
  * @return string
426
  */
427
  protected function _getGenerateSessionExpires() {
428
+ return Mage::getStoreConfig('turpentine_varnish/general/vcl_fix')
429
  ? '# call generate_session_expires' : 'call generate_session_expires;';
430
  }
431
 
435
  * @return string
436
  */
437
  protected function _getForceCacheStatic() {
438
+ return Mage::getStoreConfig('turpentine_vcl/static/force_static')
439
+ ? 'true' : 'false';
440
+ }
441
+
442
+ /**
443
+ * Get the Force Static Caching option
444
+ *
445
+ * @return string
446
+ */
447
+ protected function _getSimpleHashStatic() {
448
+ return Mage::getStoreConfig('turpentine_vcl/static/simple_hash')
449
  ? 'true' : 'false';
450
  }
451
 
455
  * @return string
456
  */
457
  protected function _getStaticExtensions() {
458
+ return implode('|', Mage::helper('turpentine/data')->cleanExplode(',',
459
+ Mage::getStoreConfig('turpentine_vcl/static/exts')));
460
  }
461
 
462
  /**
465
  * @return string
466
  */
467
  protected function _getStaticTtl() {
468
+ return Mage::getStoreConfig('turpentine_vcl/ttls/static_ttl');
469
  }
470
 
471
  /**
475
  */
476
  protected function _getUrlTtls() {
477
  $str = array();
478
+ $configTtls = Mage::helper('turpentine/data')->cleanExplode(PHP_EOL,
479
+ Mage::getStoreConfig('turpentine_vcl/ttls/url_ttls'));
480
  $ttls = array();
481
+ foreach ($configTtls as $line) {
482
+ $ttls[] = explode(',', trim($line));
483
  }
484
+ foreach ($ttls as $ttl) {
485
+ $str[] = sprintf('if (bereq.url ~ "%s%s") { set beresp.ttl = %ds; }',
486
+ $this->getBaseUrlPathRegex(), $ttl[0], $ttl[1]);
487
  }
488
+ $str = implode(' else ', $str);
489
+ if ($str) {
490
+ $str .= sprintf(' else { set beresp.ttl = %ds; }',
491
+ $this->_getDefaultTtl());
492
  } else {
493
+ $str = sprintf('set beresp.ttl = %ds;', $this->_getDefaultTtl());
494
  }
495
  return $str;
496
  }
501
  * @return string
502
  */
503
  protected function _getEnableCaching() {
504
+ return Mage::helper('turpentine/varnish')->getVarnishEnabled() ?
505
  'true' : 'false';
506
  }
507
 
511
  * @return array
512
  */
513
  protected function _getDebugIps() {
514
+ return Mage::helper('turpentine/data')->cleanExplode(',',
515
+ Mage::getStoreConfig('dev/restrict/allow_ips'));
516
  }
517
 
518
  /**
521
  * @return array
522
  */
523
  protected function _getCrawlerIps() {
524
+ return Mage::helper('turpentine/data')->cleanExplode(',',
525
+ Mage::getStoreConfig('turpentine_vcl/backend/crawlers'));
526
  }
527
 
528
  /**
531
  * @return string
532
  */
533
  protected function _getCrawlerUserAgents() {
534
+ return implode('|', Mage::helper('turpentine/data')
535
+ ->cleanExplode(',',
536
  Mage::getStoreConfig(
537
+ 'turpentine_vcl/backend/crawler_user_agents' )));
538
  }
539
 
540
  /**
545
  * @return string
546
  */
547
  protected function _getLruFactor() {
548
+ return Mage::getStoreConfig('turpentine_vcl/ttls/lru_factor');
549
  }
550
 
551
  /**
558
  */
559
  protected function _getAdvancedSessionValidationTargets() {
560
  $validation = array();
561
+ if (Mage::getStoreConfig('web/session/use_remote_addr')) {
562
  $validation[] = 'client.ip';
563
  }
564
+ if (Mage::getStoreConfig('web/session/use_http_via')) {
565
  $validation[] = 'req.http.Via';
566
  }
567
+ if (Mage::getStoreConfig('web/session/use_http_x_forwarded_for')) {
568
  $validation[] = 'req.http.X-Forwarded-For';
569
  }
570
+ if (Mage::getStoreConfig(
571
  'web/session/use_http_user_agent' ) &&
572
+ ! Mage::getStoreConfig(
573
+ 'turpentine_vcl/normalization/user_agent' )) {
574
  $validation[] = 'req.http.User-Agent';
575
  }
576
  return $validation;
582
  * @param string $dirtyVcl generated vcl
583
  * @return string
584
  */
585
+ protected function _cleanVcl($dirtyVcl) {
586
+ return implode(PHP_EOL,
587
  array_filter(
588
+ Mage::helper('turpentine/data')
589
+ ->cleanExplode(PHP_EOL, $dirtyVcl),
590
+ array($this, '_cleanVclHelper')
591
  )
592
  );
593
  }
598
  * @param string $line
599
  * @return bool
600
  */
601
+ protected function _cleanVclHelper($line) {
602
  return $line &&
603
+ ((substr($line, 0, 1) != '#' &&
604
+ substr($line, 0, 2) != '//') ||
605
+ substr($line, 0, 8) == '#include');
606
  }
607
 
608
  /**
614
  * @param array $options options
615
  * @return string
616
  */
617
+ protected function _vcl_backend($name, $host, $port, $options = array()) {
618
  $tpl = <<<EOS
619
  backend {{name}} {
620
  .host = "{{host}}";
626
  'port' => $port,
627
  'name' => $name,
628
  );
629
+ $str = $this->_formatTemplate($tpl, $vars);
630
+ foreach ($options as $key => $value) {
631
+ $str .= sprintf(' .%s = %s;', $key, $value).PHP_EOL;
632
  }
633
+ $str .= '}'.PHP_EOL;
634
  return $str;
635
  }
636
 
641
  * @param array $backendOptions options for each backend
642
  * @return string
643
  */
644
+ protected function _vcl_director($name, $backendOptions) {
645
  $tpl = <<<EOS
646
  director {{name}} round-robin {
647
  {{backends}}
648
  }
649
  EOS;
650
+ if ('admin' == $name && 'yes_admin' == Mage::getStoreConfig('turpentine_vcl/backend/load_balancing')) {
651
+ $backendNodes = Mage::helper('turpentine/data')->cleanExplode(PHP_EOL,
652
+ Mage::getStoreConfig('turpentine_vcl/backend/backend_nodes_admin'));
653
+ $probeUrl = Mage::getStoreConfig('turpentine_vcl/backend/backend_probe_url_admin');
654
  } else {
655
+ $backendNodes = Mage::helper('turpentine/data')->cleanExplode(PHP_EOL,
656
+ Mage::getStoreConfig('turpentine_vcl/backend/backend_nodes'));
657
+ $probeUrl = Mage::getStoreConfig('turpentine_vcl/backend/backend_probe_url');
658
  }
659
  $backends = '';
660
+ foreach ($backendNodes as $backendNode) {
661
+ $parts = explode(':', $backendNode, 2);
662
+ $host = (empty($parts[0])) ? '127.0.0.1' : $parts[0];
663
+ $port = (empty($parts[1])) ? '80' : $parts[1];
664
+ $backends .= $this->_vcl_director_backend($host, $port, $probeUrl, $backendOptions);
665
  }
666
  $vars = array(
667
  'name' => $name,
668
  'backends' => $backends
669
  );
670
+ return $this->_formatTemplate($tpl, $vars);
671
  }
672
 
673
  /**
679
  * @param array $options extra options for backend
680
  * @return string
681
  */
682
+ protected function _vcl_director_backend($host, $port, $probeUrl = '', $options = array()) {
683
  $tpl = <<<EOS
684
  {
685
  .backend = {
693
  'port' => $port,
694
  'probe' => ''
695
  );
696
+ if ( ! empty($probeUrl)) {
697
+ $vars['probe'] = $this->_vcl_get_probe($probeUrl);
698
  }
699
+ $str = $this->_formatTemplate($tpl, $vars);
700
+ foreach ($options as $key => $value) {
701
+ $str .= sprintf(' .%s = %s;', $key, $value).PHP_EOL;
702
  }
703
  $str .= <<<EOS
704
  }
713
  * @param string $probeUrl URL to check if backend is up
714
  * @return string
715
  */
716
+ protected function _vcl_get_probe($probeUrl) {
717
+ $urlParts = parse_url($probeUrl);
718
+ if (empty($urlParts)) {
719
  // Malformed URL
720
  return '';
721
  } else {
731
  'probe_host' => $urlParts['host'],
732
  'probe_path' => $urlParts['path']
733
  );
734
+ return $this->_formatTemplate($tpl, $vars);
735
  }
736
  }
737
 
742
  * @param array $hosts list of hosts to add to the ACL
743
  * @return string
744
  */
745
+ protected function _vcl_acl($name, array $hosts) {
746
  $tpl = <<<EOS
747
  acl {{name}} {
748
  {{hosts}}
749
  }
750
  EOS;
751
+ $fmtHost = create_function('$h', 'return sprintf(\'"%s";\',$h);');
752
  $vars = array(
753
  'name' => $name,
754
+ 'hosts' => implode("\n ", array_map($fmtHost, $hosts)),
755
  );
756
+ return $this->_formatTemplate($tpl, $vars);
757
  }
758
 
759
  /**
819
  set req.http.Host = "{{normalize_host_target}}";
820
 
821
  EOS;
822
+ return $this->_formatTemplate($tpl, array(
823
+ 'normalize_host_target' => $this->_getNormalizeHostTarget() ));
824
  }
825
 
826
  /**
829
  * @return string
830
  */
831
  protected function _getNormalizeCookieTarget() {
832
+ return trim(Mage::getStoreConfig(
833
+ 'turpentine_vcl/normalization/cookie_target' ));
834
  }
835
 
836
  /**
839
  * @return string
840
  */
841
  protected function _getNormalizeCookieRegex() {
842
+ return trim(Mage::getStoreConfig(
843
+ 'turpentine_vcl/normalization/cookie_regex' ));
844
  }
845
 
846
  /**
849
  * @return string
850
  */
851
  protected function _vcl_sub_maintenance_allowed_ips() {
852
+ if (( ! $this->_getDebugIps()) || ! Mage::getStoreConfig('turpentine_vcl/maintenance/custom_vcl_synth')) {
853
  return false;
854
  }
855
 
856
+ switch (Mage::getStoreConfig('turpentine_varnish/servers/version')) {
857
  case 4.0:
858
  $tpl = <<<EOS
859
  if (req.http.X-Forwarded-For) {
883
  EOS;
884
  }
885
 
886
+ return $this->_formatTemplate($tpl, array(
887
+ 'debug_ips' => Mage::getStoreConfig('dev/restrict/allow_ips') ));
888
  }
889
 
890
  /**
894
  */
895
  protected function _vcl_sub_synth()
896
  {
897
+ if (( ! $this->_getDebugIps()) || ! Mage::getStoreConfig('turpentine_vcl/maintenance/custom_vcl_synth')) {
898
  return false;
899
  }
900
 
952
  'debug_headers' => $this->_getEnableDebugHeaders(),
953
  'grace_period' => $this->_getGracePeriod(),
954
  'force_cache_static' => $this->_getForceCacheStatic(),
955
+ 'simple_hash_static' => $this->_getSimpleHashStatic(),
956
  'generate_session_expires' => $this->_getGenerateSessionExpires(),
957
  'generate_session' => $this->_getGenerateSession(),
958
  'generate_session_start' => $this->_getGenerateSessionStart(),
961
  'static_ttl' => $this->_getStaticTtl(),
962
  'url_ttls' => $this->_getUrlTtls(),
963
  'enable_caching' => $this->_getEnableCaching(),
964
+ 'crawler_acl' => $this->_vcl_acl('crawler_acl',
965
+ $this->_getCrawlerIps()),
966
  'esi_cache_type_param' =>
967
+ Mage::helper('turpentine/esi')->getEsiCacheTypeParam(),
968
  'esi_method_param' =>
969
+ Mage::helper('turpentine/esi')->getEsiMethodParam(),
970
+ 'esi_ttl_param' => Mage::helper('turpentine/esi')->getEsiTtlParam(),
971
+ 'secret_handshake' => Mage::helper('turpentine/varnish')
972
  ->getSecretHandshake(),
973
  'crawler_user_agent_regex' => $this->_getCrawlerUserAgents(),
974
  // 'lru_factor' => $this->_getLruFactor(),
975
+ 'debug_acl' => $this->_vcl_acl('debug_acl',
976
+ $this->_getDebugIps()),
977
  'custom_c_code' => file_get_contents(
978
+ $this->_getVclTemplateFilename(self::VCL_CUSTOM_C_CODE_FILE) ),
979
+ 'esi_private_ttl' => Mage::helper('turpentine/esi')
980
  ->getDefaultEsiTtl(),
981
  );
982
 
983
+ if ((bool) Mage::getStoreConfig('turpentine_vcl/urls/bypass_cache_store_url')) {
984
  $vars['allowed_hosts'] = $this->_vcl_sub_allowed_hosts_regex();
985
  }
986
 
987
+ if (Mage::getStoreConfig('turpentine_vcl/normalization/encoding')) {
988
  $vars['normalize_encoding'] = $this->_vcl_sub_normalize_encoding();
989
  }
990
+ if (Mage::getStoreConfig('turpentine_vcl/normalization/user_agent')) {
991
  $vars['normalize_user_agent'] = $this->_vcl_sub_normalize_user_agent();
992
  }
993
+ if (Mage::getStoreConfig('turpentine_vcl/normalization/host')) {
994
  $vars['normalize_host'] = $this->_vcl_sub_normalize_host();
995
  }
996
+ if (Mage::getStoreConfig('turpentine_vcl/normalization/cookie_regex')) {
997
  $vars['normalize_cookie_regex'] = $this->_getNormalizeCookieRegex();
998
  }
999
+ if (Mage::getStoreConfig('turpentine_vcl/normalization/cookie_target')) {
1000
  $vars['normalize_cookie_target'] = $this->_getNormalizeCookieTarget();
1001
  }
1002
 
1003
+ if (Mage::getStoreConfig('turpentine_vcl/maintenance/enable')) {
1004
  // in vcl_recv set the allowed IPs otherwise load the vcl_error (v3)/vcl_synth (v4)
1005
  $vars['maintenance_allowed_ips'] = $this->_vcl_sub_maintenance_allowed_ips();
1006
  // set the vcl_error from Magento database
1008
  }
1009
 
1010
  $customIncludeFile = $this->_getCustomIncludeFilename();
1011
+ if (is_readable($customIncludeFile)) {
1012
+ $vars['custom_vcl_include'] = file_get_contents($customIncludeFile);
1013
  }
1014
 
1015
  return $vars;
app/code/community/Nexcessnet/Turpentine/Model/Varnish/Configurator/Version2.php CHANGED
@@ -30,17 +30,17 @@ class Nexcessnet_Turpentine_Model_Varnish_Configurator_Version2
30
  * @param bool $doClean if true, VCL will be cleaned (whitespaces stripped, etc.)
31
  * @return string
32
  */
33
- public function generate($doClean=true) {
34
- $tplFile = $this->_getVclTemplateFilename( self::VCL_TEMPLATE_FILE );
35
- $vcl = $this->_formatTemplate( file_get_contents( $tplFile ),
36
- $this->_getTemplateVars() );
37
- return $doClean ? $this->_cleanVcl( $vcl ) : $vcl;
38
  }
39
 
40
  protected function _getAdvancedSessionValidation() {
41
  $validation = '';
42
- foreach( $this->_getAdvancedSessionValidationTargets() as $target ) {
43
- $validation .= sprintf( 'set req.hash += %s;' . PHP_EOL, $target );
44
  }
45
  return $validation;
46
  }
30
  * @param bool $doClean if true, VCL will be cleaned (whitespaces stripped, etc.)
31
  * @return string
32
  */
33
+ public function generate($doClean = true) {
34
+ $tplFile = $this->_getVclTemplateFilename(self::VCL_TEMPLATE_FILE);
35
+ $vcl = $this->_formatTemplate(file_get_contents($tplFile),
36
+ $this->_getTemplateVars());
37
+ return $doClean ? $this->_cleanVcl($vcl) : $vcl;
38
  }
39
 
40
  protected function _getAdvancedSessionValidation() {
41
  $validation = '';
42
+ foreach ($this->_getAdvancedSessionValidationTargets() as $target) {
43
+ $validation .= sprintf('set req.hash += %s;'.PHP_EOL, $target);
44
  }
45
  return $validation;
46
  }
app/code/community/Nexcessnet/Turpentine/Model/Varnish/Configurator/Version3.php CHANGED
@@ -30,17 +30,17 @@ class Nexcessnet_Turpentine_Model_Varnish_Configurator_Version3
30
  * @param bool $doClean if true, VCL will be cleaned (whitespaces stripped, etc.)
31
  * @return string
32
  */
33
- public function generate($doClean=true) {
34
- $tplFile = $this->_getVclTemplateFilename( self::VCL_TEMPLATE_FILE );
35
- $vcl = $this->_formatTemplate( file_get_contents( $tplFile ),
36
- $this->_getTemplateVars() );
37
- return $doClean ? $this->_cleanVcl( $vcl ) : $vcl;
38
  }
39
 
40
  protected function _getAdvancedSessionValidation() {
41
  $validation = '';
42
- foreach( $this->_getAdvancedSessionValidationTargets() as $target ) {
43
- $validation .= sprintf( 'hash_data(%s);' . PHP_EOL, $target );
44
  }
45
  return $validation;
46
  }
30
  * @param bool $doClean if true, VCL will be cleaned (whitespaces stripped, etc.)
31
  * @return string
32
  */
33
+ public function generate($doClean = true) {
34
+ $tplFile = $this->_getVclTemplateFilename(self::VCL_TEMPLATE_FILE);
35
+ $vcl = $this->_formatTemplate(file_get_contents($tplFile),
36
+ $this->_getTemplateVars());
37
+ return $doClean ? $this->_cleanVcl($vcl) : $vcl;
38
  }
39
 
40
  protected function _getAdvancedSessionValidation() {
41
  $validation = '';
42
+ foreach ($this->_getAdvancedSessionValidationTargets() as $target) {
43
+ $validation .= sprintf('hash_data(%s);'.PHP_EOL, $target);
44
  }
45
  return $validation;
46
  }
app/code/community/Nexcessnet/Turpentine/Model/Varnish/Configurator/Version4.php CHANGED
@@ -30,18 +30,18 @@ class Nexcessnet_Turpentine_Model_Varnish_Configurator_Version4
30
  * @param bool $doClean if true, VCL will be cleaned (whitespaces stripped, etc.)
31
  * @return string
32
  */
33
- public function generate($doClean=true) {
34
- $tplFile = $this->_getVclTemplateFilename( self::VCL_TEMPLATE_FILE );
35
- $vcl = $this->_formatTemplate( file_get_contents( $tplFile ),
36
- $this->_getTemplateVars() );
37
- return $doClean ? $this->_cleanVcl( $vcl ) : $vcl;
38
  }
39
 
40
- // TODO: Check this
41
  protected function _getAdvancedSessionValidation() {
42
  $validation = '';
43
- foreach( $this->_getAdvancedSessionValidationTargets() as $target ) {
44
- $validation .= sprintf( 'hash_data(%s);' . PHP_EOL, $target );
45
  }
46
  return $validation;
47
  }
30
  * @param bool $doClean if true, VCL will be cleaned (whitespaces stripped, etc.)
31
  * @return string
32
  */
33
+ public function generate($doClean = true) {
34
+ $tplFile = $this->_getVclTemplateFilename(self::VCL_TEMPLATE_FILE);
35
+ $vcl = $this->_formatTemplate(file_get_contents($tplFile),
36
+ $this->_getTemplateVars());
37
+ return $doClean ? $this->_cleanVcl($vcl) : $vcl;
38
  }
39
 
40
+ // TODO: Check this
41
  protected function _getAdvancedSessionValidation() {
42
  $validation = '';
43
+ foreach ($this->_getAdvancedSessionValidationTargets() as $target) {
44
+ $validation .= sprintf('hash_data(%s);'.PHP_EOL, $target);
45
  }
46
  return $validation;
47
  }
app/code/community/Nexcessnet/Turpentine/controllers/Adminhtml/CacheController.php CHANGED
@@ -26,13 +26,13 @@ class Nexcessnet_Turpentine_Adminhtml_CacheController extends Mage_Adminhtml_Cac
26
  }
27
  if ($updatedTypes > 0) {
28
  // disable FPC when Varnish cache is enabled:
29
- if($allTypes['turpentine_pages']==1 || $allTypes['turpentine_esi_blocks']==1)
30
  {
31
  $allTypes['full_page'] = 0;
32
- Mage::getSingleton('core/session')->addSuccess(Mage::helper('adminhtml')->__("Full page cache has been disabled since Varnish cache is enabled."));
33
- } else if ($allTypes['full_page']==1) {
34
- Mage::getSingleton('core/session')->addSuccess(Mage::helper('adminhtml')->__("Turpentine cache has been disabled since Full Page cache is enabled."));
35
- }
36
  // disable FPC when Varnish cache is enabled.
37
  Mage::app()->saveUseCache($allTypes);
38
  $this->_getSession()->addSuccess(Mage::helper('adminhtml')->__("%s cache type(s) enabled.", $updatedTypes));
26
  }
27
  if ($updatedTypes > 0) {
28
  // disable FPC when Varnish cache is enabled:
29
+ if ($allTypes['turpentine_pages'] == 1 || $allTypes['turpentine_esi_blocks'] == 1)
30
  {
31
  $allTypes['full_page'] = 0;
32
+ Mage::getSingleton('core/session')->addSuccess(Mage::helper('adminhtml')->__("Full page cache has been disabled since Varnish cache is enabled."));
33
+ } else if ($allTypes['full_page'] == 1) {
34
+ Mage::getSingleton('core/session')->addSuccess(Mage::helper('adminhtml')->__("Turpentine cache has been disabled since Full Page cache is enabled."));
35
+ }
36
  // disable FPC when Varnish cache is enabled.
37
  Mage::app()->saveUseCache($allTypes);
38
  $this->_getSession()->addSuccess(Mage::helper('adminhtml')->__("%s cache type(s) enabled.", $updatedTypes));
app/code/community/Nexcessnet/Turpentine/controllers/EsiController.php CHANGED
@@ -27,7 +27,7 @@ class Nexcessnet_Turpentine_EsiController extends Mage_Core_Controller_Front_Act
27
  * @return null
28
  */
29
  public function indexAction() {
30
- $this->getResponse()->setRedirect( Mage::getBaseUrl() );
31
  }
32
 
33
  /**
@@ -38,16 +38,16 @@ class Nexcessnet_Turpentine_EsiController extends Mage_Core_Controller_Front_Act
38
  public function getFormKeyAction() {
39
  $resp = $this->getResponse();
40
  $resp->setBody(
41
- Mage::getSingleton( 'core/session' )->real_getFormKey() );
42
- $resp->setHeader( 'X-Turpentine-Cache', '1' );
43
- $resp->setHeader( 'X-Turpentine-Flush-Events',
44
- implode( ',', Mage::helper( 'turpentine/esi' )
45
- ->getDefaultCacheClearEvents() ) );
46
- $resp->setHeader( 'X-Turpentine-Block', 'form_key' );
47
- Mage::register( 'turpentine_nocache_flag', false, true );
48
 
49
- Mage::helper( 'turpentine/debug' )->logDebug( 'Generated form_key: %s',
50
- $resp->getBody() );
51
  }
52
 
53
  /**
@@ -58,89 +58,89 @@ class Nexcessnet_Turpentine_EsiController extends Mage_Core_Controller_Front_Act
58
  public function getBlockAction() {
59
  $resp = $this->getResponse();
60
  $cacheFlag = false;
61
- if( Mage::helper( 'turpentine/esi' )->shouldResponseUseEsi() ) {
62
  $req = $this->getRequest();
63
- $esiHelper = Mage::helper( 'turpentine/esi' );
64
- $dataHelper = Mage::helper( 'turpentine/data' );
65
- $debugHelper = Mage::helper( 'turpentine/debug' );
66
- $esiDataHmac = $req->getParam( $esiHelper->getEsiHmacParam() );
67
- $esiDataParamValue = $req->getParam( $esiHelper->getEsiDataParam() );
68
- if( $esiDataHmac !== ( $hmac = $dataHelper->getHmac( $esiDataParamValue ) ) ) {
69
- $debugHelper->logWarn( 'ESI data HMAC mismatch, expected (%s) but received (%s)',
70
- $hmac, $esiDataHmac );
71
- $resp->setHttpResponseCode( 500 );
72
- $resp->setBody( 'ESI data is not valid' );
73
- } elseif( !( $esiDataArray = $dataHelper->thaw( $esiDataParamValue ) ) ) {
74
- $debugHelper->logWarn( 'Invalid ESI data in URL: %s',
75
- $esiDataParamValue );
76
- $resp->setHttpResponseCode( 500 );
77
- $resp->setBody( 'ESI data is not valid' );
78
- } elseif( !$esiHelper->getEsiDebugEnabled() &&
79
  $esiDataArray['esi_method'] !==
80
- $req->getParam( $esiHelper->getEsiMethodParam() ) ) {
81
- $resp->setHttpResponseCode( 403 );
82
- $resp->setBody( 'ESI method mismatch' );
83
- $debugHelper->logWarn( 'Blocking change of ESI method: %s -> %s',
84
  $esiDataArray['esi_method'],
85
- $req->getParam( $esiHelper->getEsiMethodParam() ) );
86
  } else {
87
- $esiData = new Varien_Object( $esiDataArray );
88
  $origRequest = Mage::app()->getRequest();
89
  Mage::app()->setCurrentStore(
90
- Mage::app()->getStore( $esiData->getStoreId() ) );
91
- $appShim = Mage::getModel( 'turpentine/shim_mage_core_app' );
92
- if( $referer = $this->_getRefererUrl() ) {
93
- $referer = htmlspecialchars_decode( $referer );
94
- $dummyRequest = Mage::helper( 'turpentine/esi' )
95
- ->getDummyRequest( $referer );
96
  } else {
97
- $dummyRequest = Mage::helper( 'turpentine/esi' )
98
  ->getDummyRequest();
99
  }
100
- $appShim->shim_setRequest( $dummyRequest );
101
- $block = $this->_getEsiBlock( $esiData );
102
- if( $block ) {
103
  $blockEsiOptions = $block->getEsiOptions();
104
- $block->setEsiOptions( false );
105
- $resp->setBody( $block->toHtml() );
106
- if( (int)$req->getParam( $esiHelper->getEsiTtlParam() ) > 0 ) {
107
  $cacheFlag = true;
108
- if ( isset( $blockEsiOptions['only_cache_if'] ) ) {
109
- switch ( $blockEsiOptions['only_cache_if'] ) {
110
  case 'empty':
111
- $cacheFlag = ( '' === $resp->getBody() );
112
  break;
113
  case 'no_text':
114
- $cacheFlag = ( '' === trim( strip_tags( $resp->getBody() ) ) );
115
  break;
116
  default:
117
  $cacheFlag = false;
118
  }
119
  }
120
  }
121
- if( $esiData->getEsiMethod() == 'ajax' ) {
122
- $resp->setHeader( 'Access-Control-Allow-Origin',
123
- $esiHelper->getCorsOrigin() );
124
  }
125
- if( !is_null( $flushEvents = $esiData->getFlushEvents() ) ) {
126
- $resp->setHeader( 'X-Turpentine-Flush-Events',
127
- implode( ',', $flushEvents ) );
128
  }
129
- if( $esiHelper->getEsiDebugEnabled() ) {
130
- $resp->setHeader( 'X-Turpentine-Block',
131
- $block->getNameInLayout() );
132
  }
133
  } else {
134
- $resp->setHttpResponseCode( 404 );
135
- $resp->setBody( 'ESI block not found' );
136
  }
137
- $appShim->shim_setRequest( $origRequest );
138
  }
139
  } else {
140
- $resp->setHttpResponseCode( 403 );
141
- $resp->setBody( 'ESI includes are not enabled' );
142
  }
143
- Mage::register( 'turpentine_nocache_flag', !$cacheFlag, true );
144
  }
145
 
146
  /**
@@ -152,10 +152,10 @@ class Nexcessnet_Turpentine_EsiController extends Mage_Core_Controller_Front_Act
152
  * @return null
153
  */
154
  public function postDispatch() {
155
- $flag = $this->getFlag( '', self::FLAG_NO_START_SESSION );
156
- $this->setFlag( '', self::FLAG_NO_START_SESSION, true );
157
  parent::postDispatch();
158
- $this->setFlag( '', self::FLAG_NO_START_SESSION, $flag );
159
  }
160
 
161
  /**
@@ -164,25 +164,25 @@ class Nexcessnet_Turpentine_EsiController extends Mage_Core_Controller_Front_Act
164
  * @param Varien_Object $esiData
165
  * @return Mage_Core_Block_Template|null
166
  */
167
- protected function _getEsiBlock( $esiData ) {
168
  $block = null;
169
- Varien_Profiler::start( 'turpentine::controller::esi::_getEsiBlock' );
170
- foreach( $esiData->getSimpleRegistry() as $key => $value ) {
171
- Mage::register( $key, $value, true );
172
  }
173
- foreach( $esiData->getComplexRegistry() as $key => $data ) {
174
- $value = Mage::getModel( $data['model'] );
175
- if( !is_object( $value ) ) {
176
- Mage::helper( 'turpentine/debug' )->logWarn(
177
  'Failed to register key/model: %s as %s(%s)',
178
  $key, $data['model'], $data['id'] );
179
  continue;
180
  } else {
181
- $value->load( $data['id'] );
182
- Mage::register( $key, $value, true );
183
  }
184
  }
185
- $layout = Mage::getSingleton( 'core/layout' );
186
 
187
  // dispatch event for adding handles to layout update
188
  Mage::dispatchEvent(
@@ -191,13 +191,13 @@ class Nexcessnet_Turpentine_EsiController extends Mage_Core_Controller_Front_Act
191
  );
192
 
193
  $layoutUpdate = $layout->getUpdate();
194
- $layoutUpdate->load( $this->_swapCustomerHandles(
195
- $esiData->getLayoutHandles() ) );
196
- foreach( $esiData->getDummyBlocks() as $blockName ) {
197
- $layout->createBlock( 'Mage_Core_Block_Template', $blockName );
198
  }
199
 
200
- if(!$this->getFlag('', self::FLAG_NO_DISPATCH_BLOCK_EVENT)) {
201
  Mage::dispatchEvent(
202
  'controller_action_layout_generate_xml_before',
203
  array('action'=>$this, 'layout'=>$layout)
@@ -206,33 +206,33 @@ class Nexcessnet_Turpentine_EsiController extends Mage_Core_Controller_Front_Act
206
  $layout->generateXml();
207
 
208
  /** @var Nexcessnet_Turpentine_Helper_Data $turpentineHelper */
209
- $turpentineHelper = Mage::helper( 'turpentine/data' )
210
- ->setLayout( $layout );
211
 
212
- $blockNode = current( $layout->getNode()->xpath(
213
- sprintf('//block[@name=\'%s\']',$esiData->getNameInLayout())
214
- ) );
215
 
216
- if( ! ($blockNode instanceof Mage_Core_Model_Layout_Element) ) {
217
- Mage::helper( 'turpentine/debug' )->logWarn(
218
  'No block node found with @name="%s"',
219
  $esiData->getNameInLayout() );
220
  return null;
221
  }
222
 
223
- $nodesToGenerate = $turpentineHelper->getChildBlockNames( $blockNode );
224
- Mage::getModel( 'turpentine/shim_mage_core_layout' )
225
- ->shim_generateFullBlock( $blockNode );
226
 
227
  //find addional blocks that aren't defined in the <block/> but via <reference name="%s">
228
- $referenceNodes = $layout->getNode()->xpath( sprintf(
229
  '//reference[@name=\'%s\']',
230
- $esiData->getNameInLayout() ) );
231
  if ($referenceNodes) {
232
  foreach ($referenceNodes as $referenceNode) {
233
  if ($referenceNode instanceof Mage_Core_Model_Layout_Element) {
234
  $referencesToGenerate = $turpentineHelper
235
- ->getChildBlockNames( $referenceNode );
236
  $nodesToGenerate =
237
  array_merge($nodesToGenerate, $referencesToGenerate);
238
  }
@@ -240,22 +240,22 @@ class Nexcessnet_Turpentine_EsiController extends Mage_Core_Controller_Front_Act
240
  }
241
 
242
  // dispatch event for adding xml layout elements
243
- if(!$this->getFlag('', self::FLAG_NO_DISPATCH_BLOCK_EVENT)) {
244
  Mage::dispatchEvent(
245
  'controller_action_layout_generate_blocks_before',
246
  array('action'=>$this, 'layout'=>$layout)
247
  );
248
  }
249
 
250
- foreach( array_unique($nodesToGenerate) as $nodeName ) {
251
- foreach( $layout->getNode()->xpath( sprintf(
252
- '//reference[@name=\'%s\']', $nodeName ) ) as $node ) {
253
- $layout->generateBlocks( $node );
254
  }
255
  }
256
- $block = $layout->getBlock( $esiData->getNameInLayout() );
257
 
258
- if(!$this->getFlag('', self::FLAG_NO_DISPATCH_BLOCK_EVENT)) {
259
  Mage::dispatchEvent(
260
  'controller_action_layout_generate_blocks_after',
261
  array('action'=>$this, 'layout'=>$layout)
@@ -263,7 +263,7 @@ class Nexcessnet_Turpentine_EsiController extends Mage_Core_Controller_Front_Act
263
  }
264
 
265
  $this->_isLayoutLoaded = true;
266
- Varien_Profiler::stop( 'turpentine::controller::esi::_getEsiBlock' );
267
  return $block;
268
  }
269
 
@@ -277,13 +277,13 @@ class Nexcessnet_Turpentine_EsiController extends Mage_Core_Controller_Front_Act
277
  * @param array $handles
278
  * @return array
279
  */
280
- protected function _swapCustomerHandles( $handles ) {
281
- if( Mage::helper( 'customer' )->isLoggedIn() ) {
282
- $replacement = array( 'customer_logged_out', 'customer_logged_in' );
283
  } else {
284
- $replacement = array( 'customer_logged_in', 'customer_logged_out' );
285
  }
286
- if( ( $pos = array_search( $replacement[0], $handles ) ) !== false ) {
287
  $handles[$pos] = $replacement[1];
288
  }
289
  return $handles;
27
  * @return null
28
  */
29
  public function indexAction() {
30
+ $this->getResponse()->setRedirect(Mage::getBaseUrl());
31
  }
32
 
33
  /**
38
  public function getFormKeyAction() {
39
  $resp = $this->getResponse();
40
  $resp->setBody(
41
+ Mage::getSingleton('core/session')->real_getFormKey() );
42
+ $resp->setHeader('X-Turpentine-Cache', '1');
43
+ $resp->setHeader('X-Turpentine-Flush-Events',
44
+ implode(',', Mage::helper('turpentine/esi')
45
+ ->getDefaultCacheClearEvents()));
46
+ $resp->setHeader('X-Turpentine-Block', 'form_key');
47
+ Mage::register('turpentine_nocache_flag', false, true);
48
 
49
+ Mage::helper('turpentine/debug')->logDebug('Generated form_key: %s',
50
+ $resp->getBody());
51
  }
52
 
53
  /**
58
  public function getBlockAction() {
59
  $resp = $this->getResponse();
60
  $cacheFlag = false;
61
+ if (Mage::helper('turpentine/esi')->shouldResponseUseEsi()) {
62
  $req = $this->getRequest();
63
+ $esiHelper = Mage::helper('turpentine/esi');
64
+ $dataHelper = Mage::helper('turpentine/data');
65
+ $debugHelper = Mage::helper('turpentine/debug');
66
+ $esiDataHmac = $req->getParam($esiHelper->getEsiHmacParam());
67
+ $esiDataParamValue = $req->getParam($esiHelper->getEsiDataParam());
68
+ if ($esiDataHmac !== ($hmac = $dataHelper->getHmac($esiDataParamValue))) {
69
+ $debugHelper->logWarn('ESI data HMAC mismatch, expected (%s) but received (%s)',
70
+ $hmac, $esiDataHmac);
71
+ $resp->setHttpResponseCode(500);
72
+ $resp->setBody('ESI data is not valid');
73
+ } elseif ( ! ($esiDataArray = $dataHelper->thaw($esiDataParamValue))) {
74
+ $debugHelper->logWarn('Invalid ESI data in URL: %s',
75
+ $esiDataParamValue);
76
+ $resp->setHttpResponseCode(500);
77
+ $resp->setBody('ESI data is not valid');
78
+ } elseif ( ! $esiHelper->getEsiDebugEnabled() &&
79
  $esiDataArray['esi_method'] !==
80
+ $req->getParam($esiHelper->getEsiMethodParam())) {
81
+ $resp->setHttpResponseCode(403);
82
+ $resp->setBody('ESI method mismatch');
83
+ $debugHelper->logWarn('Blocking change of ESI method: %s -> %s',
84
  $esiDataArray['esi_method'],
85
+ $req->getParam($esiHelper->getEsiMethodParam()));
86
  } else {
87
+ $esiData = new Varien_Object($esiDataArray);
88
  $origRequest = Mage::app()->getRequest();
89
  Mage::app()->setCurrentStore(
90
+ Mage::app()->getStore($esiData->getStoreId()) );
91
+ $appShim = Mage::getModel('turpentine/shim_mage_core_app');
92
+ if ($referer = $this->_getRefererUrl()) {
93
+ $referer = htmlspecialchars_decode($referer);
94
+ $dummyRequest = Mage::helper('turpentine/esi')
95
+ ->getDummyRequest($referer);
96
  } else {
97
+ $dummyRequest = Mage::helper('turpentine/esi')
98
  ->getDummyRequest();
99
  }
100
+ $appShim->shim_setRequest($dummyRequest);
101
+ $block = $this->_getEsiBlock($esiData);
102
+ if ($block) {
103
  $blockEsiOptions = $block->getEsiOptions();
104
+ $block->setEsiOptions(false);
105
+ $resp->setBody($block->toHtml());
106
+ if ((int) $req->getParam($esiHelper->getEsiTtlParam()) > 0) {
107
  $cacheFlag = true;
108
+ if (isset($blockEsiOptions['only_cache_if'])) {
109
+ switch ($blockEsiOptions['only_cache_if']) {
110
  case 'empty':
111
+ $cacheFlag = ('' === $resp->getBody());
112
  break;
113
  case 'no_text':
114
+ $cacheFlag = ('' === trim(strip_tags($resp->getBody())));
115
  break;
116
  default:
117
  $cacheFlag = false;
118
  }
119
  }
120
  }
121
+ if ($esiData->getEsiMethod() == 'ajax') {
122
+ $resp->setHeader('Access-Control-Allow-Origin',
123
+ $esiHelper->getCorsOrigin());
124
  }
125
+ if ( ! is_null($flushEvents = $esiData->getFlushEvents())) {
126
+ $resp->setHeader('X-Turpentine-Flush-Events',
127
+ implode(',', $flushEvents));
128
  }
129
+ if ($esiHelper->getEsiDebugEnabled()) {
130
+ $resp->setHeader('X-Turpentine-Block',
131
+ $block->getNameInLayout());
132
  }
133
  } else {
134
+ $resp->setHttpResponseCode(404);
135
+ $resp->setBody('ESI block not found');
136
  }
137
+ $appShim->shim_setRequest($origRequest);
138
  }
139
  } else {
140
+ $resp->setHttpResponseCode(403);
141
+ $resp->setBody('ESI includes are not enabled');
142
  }
143
+ Mage::register('turpentine_nocache_flag', ! $cacheFlag, true);
144
  }
145
 
146
  /**
152
  * @return null
153
  */
154
  public function postDispatch() {
155
+ $flag = $this->getFlag('', self::FLAG_NO_START_SESSION);
156
+ $this->setFlag('', self::FLAG_NO_START_SESSION, true);
157
  parent::postDispatch();
158
+ $this->setFlag('', self::FLAG_NO_START_SESSION, $flag);
159
  }
160
 
161
  /**
164
  * @param Varien_Object $esiData
165
  * @return Mage_Core_Block_Template|null
166
  */
167
+ protected function _getEsiBlock($esiData) {
168
  $block = null;
169
+ Varien_Profiler::start('turpentine::controller::esi::_getEsiBlock');
170
+ foreach ($esiData->getSimpleRegistry() as $key => $value) {
171
+ Mage::register($key, $value, true);
172
  }
173
+ foreach ($esiData->getComplexRegistry() as $key => $data) {
174
+ $value = Mage::getModel($data['model']);
175
+ if ( ! is_object($value)) {
176
+ Mage::helper('turpentine/debug')->logWarn(
177
  'Failed to register key/model: %s as %s(%s)',
178
  $key, $data['model'], $data['id'] );
179
  continue;
180
  } else {
181
+ $value->load($data['id']);
182
+ Mage::register($key, $value, true);
183
  }
184
  }
185
+ $layout = Mage::getSingleton('core/layout');
186
 
187
  // dispatch event for adding handles to layout update
188
  Mage::dispatchEvent(
191
  );
192
 
193
  $layoutUpdate = $layout->getUpdate();
194
+ $layoutUpdate->load($this->_swapCustomerHandles(
195
+ $esiData->getLayoutHandles() ));
196
+ foreach ($esiData->getDummyBlocks() as $blockName) {
197
+ $layout->createBlock('Mage_Core_Block_Template', $blockName);
198
  }
199
 
200
+ if ( ! $this->getFlag('', self::FLAG_NO_DISPATCH_BLOCK_EVENT)) {
201
  Mage::dispatchEvent(
202
  'controller_action_layout_generate_xml_before',
203
  array('action'=>$this, 'layout'=>$layout)
206
  $layout->generateXml();
207
 
208
  /** @var Nexcessnet_Turpentine_Helper_Data $turpentineHelper */
209
+ $turpentineHelper = Mage::helper('turpentine/data')
210
+ ->setLayout($layout);
211
 
212
+ $blockNode = current($layout->getNode()->xpath(
213
+ sprintf('//block[@name=\'%s\']', $esiData->getNameInLayout())
214
+ ));
215
 
216
+ if ( ! ($blockNode instanceof Mage_Core_Model_Layout_Element)) {
217
+ Mage::helper('turpentine/debug')->logWarn(
218
  'No block node found with @name="%s"',
219
  $esiData->getNameInLayout() );
220
  return null;
221
  }
222
 
223
+ $nodesToGenerate = $turpentineHelper->getChildBlockNames($blockNode);
224
+ Mage::getModel('turpentine/shim_mage_core_layout')
225
+ ->shim_generateFullBlock($blockNode);
226
 
227
  //find addional blocks that aren't defined in the <block/> but via <reference name="%s">
228
+ $referenceNodes = $layout->getNode()->xpath(sprintf(
229
  '//reference[@name=\'%s\']',
230
+ $esiData->getNameInLayout() ));
231
  if ($referenceNodes) {
232
  foreach ($referenceNodes as $referenceNode) {
233
  if ($referenceNode instanceof Mage_Core_Model_Layout_Element) {
234
  $referencesToGenerate = $turpentineHelper
235
+ ->getChildBlockNames($referenceNode);
236
  $nodesToGenerate =
237
  array_merge($nodesToGenerate, $referencesToGenerate);
238
  }
240
  }
241
 
242
  // dispatch event for adding xml layout elements
243
+ if ( ! $this->getFlag('', self::FLAG_NO_DISPATCH_BLOCK_EVENT)) {
244
  Mage::dispatchEvent(
245
  'controller_action_layout_generate_blocks_before',
246
  array('action'=>$this, 'layout'=>$layout)
247
  );
248
  }
249
 
250
+ foreach (array_unique($nodesToGenerate) as $nodeName) {
251
+ foreach ($layout->getNode()->xpath(sprintf(
252
+ '//reference[@name=\'%s\']', $nodeName )) as $node) {
253
+ $layout->generateBlocks($node);
254
  }
255
  }
256
+ $block = $layout->getBlock($esiData->getNameInLayout());
257
 
258
+ if ( ! $this->getFlag('', self::FLAG_NO_DISPATCH_BLOCK_EVENT)) {
259
  Mage::dispatchEvent(
260
  'controller_action_layout_generate_blocks_after',
261
  array('action'=>$this, 'layout'=>$layout)
263
  }
264
 
265
  $this->_isLayoutLoaded = true;
266
+ Varien_Profiler::stop('turpentine::controller::esi::_getEsiBlock');
267
  return $block;
268
  }
269
 
277
  * @param array $handles
278
  * @return array
279
  */
280
+ protected function _swapCustomerHandles($handles) {
281
+ if (Mage::helper('customer')->isLoggedIn()) {
282
+ $replacement = array('customer_logged_out', 'customer_logged_in');
283
  } else {
284
+ $replacement = array('customer_logged_in', 'customer_logged_out');
285
  }
286
+ if (($pos = array_search($replacement[0], $handles)) !== false) {
287
  $handles[$pos] = $replacement[1];
288
  }
289
  return $handles;
app/code/community/Nexcessnet/Turpentine/controllers/Varnish/ManagementController.php CHANGED
@@ -44,20 +44,20 @@ class Nexcessnet_Turpentine_Varnish_ManagementController
44
  * @return null
45
  */
46
  public function flushAllAction() {
47
- Mage::dispatchEvent( 'turpentine_varnish_flush_all' );
48
- $result = Mage::getModel( 'turpentine/varnish_admin' )->flushAll();
49
- foreach( $result as $name => $value ) {
50
- if( $value === true ) {
51
  $this->_getSession()
52
- ->addSuccess( Mage::helper( 'turpentine/data' )
53
- ->__( 'Flushed Varnish cache for: ' ) . $name );
54
  } else {
55
  $this->_getSession()
56
- ->addError( Mage::helper( 'turpentine/data' )
57
- ->__( 'Error flushing Varnish cache on: ' ) . $name );
58
  }
59
  }
60
- $this->_redirect( '*/cache' );
61
  }
62
 
63
  /**
@@ -68,27 +68,27 @@ class Nexcessnet_Turpentine_Varnish_ManagementController
68
  */
69
  public function flushPartialAction() {
70
  $postData = $this->getRequest()->getPost();
71
- if( !isset( $postData['pattern'] ) ) {
72
- $this->_getSession()->addError( $this->__( 'Missing URL post data' ) );
73
  } else {
74
  $pattern = $postData['pattern'];
75
- Mage::dispatchEvent( 'turpentine_varnish_flush_partial',
76
- array( 'pattern' => $pattern ) );
77
- $result = Mage::getModel( 'turpentine/varnish_admin' )
78
- ->flushUrl( $pattern );
79
- foreach( $result as $name => $value ) {
80
- if( $value === true ) {
81
  $this->_getSession()
82
- ->addSuccess( Mage::helper( 'turpentine/data' )
83
- ->__( 'Flushed matching URLs for: ' ) . $name );
84
  } else {
85
  $this->_getSession()
86
- ->addError( Mage::helper( 'turpentine/data' )
87
- ->__( 'Error flushing matching URLs on: ' ) . $name );
88
  }
89
  }
90
  }
91
- $this->_redirect( '*/cache' );
92
  }
93
 
94
  /**
@@ -98,23 +98,23 @@ class Nexcessnet_Turpentine_Varnish_ManagementController
98
  */
99
  public function flushContentTypeAction() {
100
  $postData = $this->getRequest()->getPost();
101
- if( !isset( $postData['ctype'] ) ) {
102
- $this->_getSession()->addError( $this->__( 'Missing URL post data' ) );
103
  } else {
104
  $ctype = $postData['ctype'];
105
- Mage::dispatchEvent( 'turpentine_varnish_flush_content_type',
106
- array( 'ctype' => $ctype ) );
107
- $result = Mage::getModel( 'turpentine/varnish_admin' )
108
- ->flushContentType( $ctype );
109
- foreach( $result as $name => $value ) {
110
- if( $value === true ) {
111
  $this->_getSession()
112
- ->addSuccess( Mage::helper( 'turpentine/data' )
113
- ->__( 'Flushed matching content-types for: ' ) . $name );
114
  } else {
115
  $this->_getSession()
116
- ->addError( Mage::helper( 'turpentine/data' )
117
- ->__( 'Error flushing matching content-types on: ' ) . $name );
118
  }
119
  }
120
  }
@@ -127,18 +127,18 @@ class Nexcessnet_Turpentine_Varnish_ManagementController
127
  * @return null
128
  */
129
  public function applyConfigAction() {
130
- Mage::dispatchEvent( 'turpentine_varnish_apply_config' );
131
- $result = Mage::getModel( 'turpentine/varnish_admin' )->applyConfig();
132
- foreach( $result as $name => $value ) {
133
- if( $value === true ) {
134
  $this->_getSession()
135
- ->addSuccess( Mage::helper( 'turpentine' )
136
- ->__( 'VCL successfully applied to ' . $name ) );
137
  } else {
138
  $this->_getSession()
139
- ->addError( Mage::helper( 'turpentine' )
140
- ->__( sprintf( 'Failed to apply the VCL to %s: %s',
141
- $name, $value ) ) );
142
  }
143
  }
144
  $this->_redirect('*/cache');
@@ -150,23 +150,23 @@ class Nexcessnet_Turpentine_Varnish_ManagementController
150
  * @return null
151
  */
152
  public function saveConfigAction() {
153
- $cfgr = Mage::getModel( 'turpentine/varnish_admin' )->getConfigurator();
154
- if( is_null( $cfgr ) ) {
155
  $this->_getSession()->addError(
156
- $this->__( 'Failed to load configurator' ) );
157
  } else {
158
- Mage::dispatchEvent( 'turpentine_varnish_save_config',
159
- array( 'cfgr' => $cfgr ) );
160
- $result = $cfgr->save( $cfgr->generate(
161
- Mage::helper('turpentine')->shouldStripVclWhitespace('save') ) );
162
- if( $result[0] ) {
163
  $this->_getSession()
164
- ->addSuccess( Mage::helper('turpentine')
165
- ->__('The VCL file has been saved.' ) );
166
  } else {
167
  $this->_getSession()
168
- ->addError( Mage::helper('turpentine')
169
- ->__('Failed to save the VCL file: ' . $result[1]['message'] ) );
170
  }
171
  }
172
  $this->_redirect('*/cache');
@@ -178,21 +178,21 @@ class Nexcessnet_Turpentine_Varnish_ManagementController
178
  * @return $this
179
  */
180
  public function getConfigAction() {
181
- $cfgr = Mage::getModel( 'turpentine/varnish_admin' )
182
  ->getConfigurator();
183
- if( is_null( $cfgr ) ) {
184
- $this->_getSession()->addError( $this->__( 'Failed to load configurator' ) );
185
- $this->_redirect( '*/cache' );
186
  } else {
187
  $vcl = $cfgr->generate(
188
- Mage::helper( 'turpentine' )->shouldStripVclWhitespace('download') );
189
  $this->getResponse()
190
- ->setHttpResponseCode( 200 )
191
- ->setHeader( 'Content-Type', 'text/plain', true )
192
- ->setHeader( 'Content-Length', strlen( $vcl ) )
193
- ->setHeader( 'Content-Disposition',
194
- 'attachment; filename=default.vcl' )
195
- ->setBody( $vcl );
196
  return $this;
197
  }
198
  }
@@ -203,39 +203,39 @@ class Nexcessnet_Turpentine_Varnish_ManagementController
203
  * @return void
204
  */
205
  public function switchNavigationAction() {
206
- $type = $this->getRequest()->get( 'type' );
207
- if( is_null( $type ) ) {
208
- $this->_redirect( 'noRoute' );
209
  return;
210
  }
211
 
212
- $cookieName = Mage::helper( 'turpentine' )->getBypassCookieName();
213
- $cookieModel = Mage::getModel( 'core/cookie' );
214
- $adminSession = Mage::getSingleton( 'adminhtml/session' );
215
 
216
- switch( $type ) {
217
  case 'default':
218
  $cookieModel->set(
219
  $cookieName,
220
- Mage::helper( 'turpentine/varnish' )->getSecretHandshake(),
221
  null, // period
222
  null, // path
223
  null, // domain
224
  false, // secure
225
  true ); // httponly
226
- $adminSession->addSuccess( Mage::helper( 'turpentine/data' )
227
- ->__( 'The Varnish bypass cookie has been successfully added.' ) );
228
  break;
229
 
230
  case 'varnish':
231
- $cookieModel->delete( $cookieName );
232
- $adminSession->addSuccess( Mage::helper( 'turpentine/data' )
233
- ->__( 'The Varnish bypass cookie has been successfully removed.' ) );
234
  break;
235
 
236
  default:
237
- $adminSession->addError( Mage::helper( 'turpentine/data' )
238
- ->__( 'The given navigation type is not supported!' ) );
239
  break;
240
  }
241
 
44
  * @return null
45
  */
46
  public function flushAllAction() {
47
+ Mage::dispatchEvent('turpentine_varnish_flush_all');
48
+ $result = Mage::getModel('turpentine/varnish_admin')->flushAll();
49
+ foreach ($result as $name => $value) {
50
+ if ($value === true) {
51
  $this->_getSession()
52
+ ->addSuccess(Mage::helper('turpentine/data')
53
+ ->__('Flushed Varnish cache for: ').$name);
54
  } else {
55
  $this->_getSession()
56
+ ->addError(Mage::helper('turpentine/data')
57
+ ->__('Error flushing Varnish cache on: ').$name);
58
  }
59
  }
60
+ $this->_redirect('*/cache');
61
  }
62
 
63
  /**
68
  */
69
  public function flushPartialAction() {
70
  $postData = $this->getRequest()->getPost();
71
+ if ( ! isset($postData['pattern'])) {
72
+ $this->_getSession()->addError($this->__('Missing URL post data'));
73
  } else {
74
  $pattern = $postData['pattern'];
75
+ Mage::dispatchEvent('turpentine_varnish_flush_partial',
76
+ array('pattern' => $pattern));
77
+ $result = Mage::getModel('turpentine/varnish_admin')
78
+ ->flushUrl($pattern);
79
+ foreach ($result as $name => $value) {
80
+ if ($value === true) {
81
  $this->_getSession()
82
+ ->addSuccess(Mage::helper('turpentine/data')
83
+ ->__('Flushed matching URLs for: ').$name);
84
  } else {
85
  $this->_getSession()
86
+ ->addError(Mage::helper('turpentine/data')
87
+ ->__('Error flushing matching URLs on: ').$name);
88
  }
89
  }
90
  }
91
+ $this->_redirect('*/cache');
92
  }
93
 
94
  /**
98
  */
99
  public function flushContentTypeAction() {
100
  $postData = $this->getRequest()->getPost();
101
+ if ( ! isset($postData['ctype'])) {
102
+ $this->_getSession()->addError($this->__('Missing URL post data'));
103
  } else {
104
  $ctype = $postData['ctype'];
105
+ Mage::dispatchEvent('turpentine_varnish_flush_content_type',
106
+ array('ctype' => $ctype));
107
+ $result = Mage::getModel('turpentine/varnish_admin')
108
+ ->flushContentType($ctype);
109
+ foreach ($result as $name => $value) {
110
+ if ($value === true) {
111
  $this->_getSession()
112
+ ->addSuccess(Mage::helper('turpentine/data')
113
+ ->__('Flushed matching content-types for: ').$name);
114
  } else {
115
  $this->_getSession()
116
+ ->addError(Mage::helper('turpentine/data')
117
+ ->__('Error flushing matching content-types on: ').$name);
118
  }
119
  }
120
  }
127
  * @return null
128
  */
129
  public function applyConfigAction() {
130
+ Mage::dispatchEvent('turpentine_varnish_apply_config');
131
+ $result = Mage::getModel('turpentine/varnish_admin')->applyConfig();
132
+ foreach ($result as $name => $value) {
133
+ if ($value === true) {
134
  $this->_getSession()
135
+ ->addSuccess(Mage::helper('turpentine')
136
+ ->__('VCL successfully applied to '.$name));
137
  } else {
138
  $this->_getSession()
139
+ ->addError(Mage::helper('turpentine')
140
+ ->__(sprintf('Failed to apply the VCL to %s: %s',
141
+ $name, $value)));
142
  }
143
  }
144
  $this->_redirect('*/cache');
150
  * @return null
151
  */
152
  public function saveConfigAction() {
153
+ $cfgr = Mage::getModel('turpentine/varnish_admin')->getConfigurator();
154
+ if (is_null($cfgr)) {
155
  $this->_getSession()->addError(
156
+ $this->__('Failed to load configurator') );
157
  } else {
158
+ Mage::dispatchEvent('turpentine_varnish_save_config',
159
+ array('cfgr' => $cfgr));
160
+ $result = $cfgr->save($cfgr->generate(
161
+ Mage::helper('turpentine')->shouldStripVclWhitespace('save') ));
162
+ if ($result[0]) {
163
  $this->_getSession()
164
+ ->addSuccess(Mage::helper('turpentine')
165
+ ->__('The VCL file has been saved.'));
166
  } else {
167
  $this->_getSession()
168
+ ->addError(Mage::helper('turpentine')
169
+ ->__('Failed to save the VCL file: '.$result[1]['message']));
170
  }
171
  }
172
  $this->_redirect('*/cache');
178
  * @return $this
179
  */
180
  public function getConfigAction() {
181
+ $cfgr = Mage::getModel('turpentine/varnish_admin')
182
  ->getConfigurator();
183
+ if (is_null($cfgr)) {
184
+ $this->_getSession()->addError($this->__('Failed to load configurator'));
185
+ $this->_redirect('*/cache');
186
  } else {
187
  $vcl = $cfgr->generate(
188
+ Mage::helper('turpentine')->shouldStripVclWhitespace('download') );
189
  $this->getResponse()
190
+ ->setHttpResponseCode(200)
191
+ ->setHeader('Content-Type', 'text/plain', true)
192
+ ->setHeader('Content-Length', strlen($vcl))
193
+ ->setHeader('Content-Disposition',
194
+ 'attachment; filename=default.vcl')
195
+ ->setBody($vcl);
196
  return $this;
197
  }
198
  }
203
  * @return void
204
  */
205
  public function switchNavigationAction() {
206
+ $type = $this->getRequest()->get('type');
207
+ if (is_null($type)) {
208
+ $this->_redirect('noRoute');
209
  return;
210
  }
211
 
212
+ $cookieName = Mage::helper('turpentine')->getBypassCookieName();
213
+ $cookieModel = Mage::getModel('core/cookie');
214
+ $adminSession = Mage::getSingleton('adminhtml/session');
215
 
216
+ switch ($type) {
217
  case 'default':
218
  $cookieModel->set(
219
  $cookieName,
220
+ Mage::helper('turpentine/varnish')->getSecretHandshake(),
221
  null, // period
222
  null, // path
223
  null, // domain
224
  false, // secure
225
  true ); // httponly
226
+ $adminSession->addSuccess(Mage::helper('turpentine/data')
227
+ ->__('The Varnish bypass cookie has been successfully added.'));
228
  break;
229
 
230
  case 'varnish':
231
+ $cookieModel->delete($cookieName);
232
+ $adminSession->addSuccess(Mage::helper('turpentine/data')
233
+ ->__('The Varnish bypass cookie has been successfully removed.'));
234
  break;
235
 
236
  default:
237
+ $adminSession->addError(Mage::helper('turpentine/data')
238
+ ->__('The given navigation type is not supported!'));
239
  break;
240
  }
241
 
app/code/community/Nexcessnet/Turpentine/etc/cache.xml CHANGED
File without changes
app/code/community/Nexcessnet/Turpentine/etc/config.xml CHANGED
@@ -20,7 +20,7 @@
20
  <config>
21
  <modules>
22
  <Nexcessnet_Turpentine>
23
- <version>0.6.7</version>
24
  </Nexcessnet_Turpentine>
25
  </modules>
26
  <default>
@@ -85,6 +85,7 @@
85
  <static>
86
  <force_static>1</force_static>
87
  <exts>css,js,jpe?g,png,gif,ico,swf</exts>
 
88
  </static>
89
  </turpentine_vcl>
90
  </default>
@@ -301,6 +302,10 @@
301
  <class>turpentine/observer_varnish</class>
302
  <method>addProductListToolbarRewrite</method>
303
  </turpentine_varnish_controller_front_init_before>
 
 
 
 
304
  <turpentine_esi_set_replace_form_key_flag>
305
  <class>turpentine/observer_esi</class>
306
  <method>setReplaceFormKeyFlag</method>
@@ -468,6 +473,14 @@
468
  </add_to_cart_after>
469
  </observers>
470
  </add_to_cart_after-->
 
 
 
 
 
 
 
 
471
  </events>
472
  </frontend>
473
  <admin>
20
  <config>
21
  <modules>
22
  <Nexcessnet_Turpentine>
23
+ <version>0.6.8</version>
24
  </Nexcessnet_Turpentine>
25
  </modules>
26
  <default>
85
  <static>
86
  <force_static>1</force_static>
87
  <exts>css,js,jpe?g,png,gif,ico,swf</exts>
88
+ <simple_hash>1</simple_hash>
89
  </static>
90
  </turpentine_vcl>
91
  </default>
302
  <class>turpentine/observer_varnish</class>
303
  <method>addProductListToolbarRewrite</method>
304
  </turpentine_varnish_controller_front_init_before>
305
+ <turpentine_varnish_fix_cm_redissession_locks>
306
+ <class>turpentine/observer_varnish</class>
307
+ <method>fixCmRedisSessionLocks</method>
308
+ </turpentine_varnish_fix_cm_redissession_locks>
309
  <turpentine_esi_set_replace_form_key_flag>
310
  <class>turpentine/observer_esi</class>
311
  <method>setReplaceFormKeyFlag</method>
473
  </add_to_cart_after>
474
  </observers>
475
  </add_to_cart_after-->
476
+ <wishlist_index_index_before>
477
+ <observers>
478
+ <wishlist_index_index_before>
479
+ <class>turpentine/observer_esi</class>
480
+ ><method>hookToAddToWishlistBefore</method>
481
+ </wishlist_index_index_before>
482
+ </observers>
483
+ </wishlist_index_index_before>
484
  </events>
485
  </frontend>
486
  <admin>
app/code/community/Nexcessnet/Turpentine/etc/config.xml~ CHANGED
@@ -20,7 +20,7 @@
20
  <config>
21
  <modules>
22
  <Nexcessnet_Turpentine>
23
- <version>0.6.6</version>
24
  </Nexcessnet_Turpentine>
25
  </modules>
26
  <default>
@@ -85,6 +85,7 @@
85
  <static>
86
  <force_static>1</force_static>
87
  <exts>css,js,jpe?g,png,gif,ico,swf</exts>
 
88
  </static>
89
  </turpentine_vcl>
90
  </default>
@@ -301,6 +302,10 @@
301
  <class>turpentine/observer_varnish</class>
302
  <method>addProductListToolbarRewrite</method>
303
  </turpentine_varnish_controller_front_init_before>
 
 
 
 
304
  <turpentine_esi_set_replace_form_key_flag>
305
  <class>turpentine/observer_esi</class>
306
  <method>setReplaceFormKeyFlag</method>
@@ -468,6 +473,14 @@
468
  </add_to_cart_after>
469
  </observers>
470
  </add_to_cart_after-->
 
 
 
 
 
 
 
 
471
  </events>
472
  </frontend>
473
  <admin>
20
  <config>
21
  <modules>
22
  <Nexcessnet_Turpentine>
23
+ <version>0.6.7</version>
24
  </Nexcessnet_Turpentine>
25
  </modules>
26
  <default>
85
  <static>
86
  <force_static>1</force_static>
87
  <exts>css,js,jpe?g,png,gif,ico,swf</exts>
88
+ <simple_hash>1</simple_hash>
89
  </static>
90
  </turpentine_vcl>
91
  </default>
302
  <class>turpentine/observer_varnish</class>
303
  <method>addProductListToolbarRewrite</method>
304
  </turpentine_varnish_controller_front_init_before>
305
+ <turpentine_varnish_fix_cm_redissession_locks>
306
+ <class>turpentine/observer_varnish</class>
307
+ <method>fixCmRedisSessionLocks</method>
308
+ </turpentine_varnish_fix_cm_redissession_locks>
309
  <turpentine_esi_set_replace_form_key_flag>
310
  <class>turpentine/observer_esi</class>
311
  <method>setReplaceFormKeyFlag</method>
473
  </add_to_cart_after>
474
  </observers>
475
  </add_to_cart_after-->
476
+ <wishlist_index_index_before>
477
+ <observers>
478
+ <wishlist_index_index_before>
479
+ <class>turpentine/observer_esi</class>
480
+ ><method>hookToAddToWishlistBefore</method>
481
+ </wishlist_index_index_before>
482
+ </observers>
483
+ </wishlist_index_index_before>
484
  </events>
485
  </frontend>
486
  <admin>
app/code/community/Nexcessnet/Turpentine/etc/system.xml CHANGED
@@ -587,6 +587,19 @@
587
  <show_in_website>0</show_in_website>
588
  <show_in_store>0</show_in_store>
589
  </exts>
 
 
 
 
 
 
 
 
 
 
 
 
 
590
  </fields>
591
  </static>
592
  <maintenance translate="label" module="turpentine">
587
  <show_in_website>0</show_in_website>
588
  <show_in_store>0</show_in_store>
589
  </exts>
590
+ <simple_hash translate="label" module="turpentine">
591
+ <label>Use Simple Hash</label>
592
+ <comment>Always serve the same version of a static file. Ignore domain, cookies and browser version. Saves memory and lowers cache misses.</comment>
593
+ <depends>
594
+ <force_static>1</force_static>
595
+ </depends>
596
+ <frontend_type>select</frontend_type>
597
+ <source_model>turpentine/config_select_toggle</source_model>
598
+ <sort_order>30</sort_order>
599
+ <show_in_default>1</show_in_default>
600
+ <show_in_website>0</show_in_website>
601
+ <show_in_store>0</show_in_store>
602
+ </simple_hash>
603
  </fields>
604
  </static>
605
  <maintenance translate="label" module="turpentine">
app/code/community/Nexcessnet/Turpentine/misc/uuid.c CHANGED
File without changes
app/code/community/Nexcessnet/Turpentine/misc/version-2.vcl CHANGED
@@ -100,9 +100,11 @@ sub vcl_recv {
100
  }
101
 
102
  # varnish 2.1 doesn't support bare booleans so we have to add these
103
- # as headers to the req so they've available throught the VCL
104
  set req.http.X-Opt-Enable-Caching = "{{enable_caching}}";
105
  set req.http.X-Opt-Force-Static-Caching = "{{force_cache_static}}";
 
 
106
  set req.http.X-Opt-Enable-Get-Excludes = "{{enable_get_excludes}}";
107
  set req.http.X-Opt-Send-Unmodified-Url = "{{send_unmodified_url}}";
108
 
@@ -186,6 +188,7 @@ sub vcl_recv {
186
  # don't need cookies for static assets
187
  remove req.http.Cookie;
188
  remove req.http.X-Varnish-Faked-Session;
 
189
  return (lookup);
190
  }
191
  # this doesn't need a enable_url_excludes because we can be reasonably
@@ -202,7 +205,7 @@ sub vcl_recv {
202
  req.url ~ "(?:[?&](?:{{get_param_excludes}})(?=[&=]|$))") {
203
  return (pass);
204
  }
205
- if ({{enable_get_ignored}} && req.url ~ "[?&]({{get_param_ignored}})=") {
206
  # Strip out ignored GET related parameters
207
  set req.url = regsuball(req.url, "(?:(\?)?|&)(?:{{get_param_ignored}})=[^&]+", "\1");
208
  set req.url = regsuball(req.url, "(?:(\?)&|\?$)", "\1");
@@ -234,8 +237,18 @@ sub vcl_pipe {
234
  # }
235
 
236
  sub vcl_hash {
 
 
 
 
 
 
 
 
 
 
237
 
238
- if({{send_unmodified_url}} && req.http.X-Varnish-Cache-Url) {
239
  set req.hash += req.http.X-Varnish-Cache-Url;
240
  } else {
241
  set req.hash += req.url;
100
  }
101
 
102
  # varnish 2.1 doesn't support bare booleans so we have to add these
103
+ # as headers to the req so they've available through the VCL
104
  set req.http.X-Opt-Enable-Caching = "{{enable_caching}}";
105
  set req.http.X-Opt-Force-Static-Caching = "{{force_cache_static}}";
106
+ set req.http.X-Opt-Simple-Hash-Static = "{{simple_hash_static}}";
107
+ set req.http.X-Opt-Enable-Get-Ignored = "{{enable_get_ignored}}";
108
  set req.http.X-Opt-Enable-Get-Excludes = "{{enable_get_excludes}}";
109
  set req.http.X-Opt-Send-Unmodified-Url = "{{send_unmodified_url}}";
110
 
188
  # don't need cookies for static assets
189
  remove req.http.Cookie;
190
  remove req.http.X-Varnish-Faked-Session;
191
+ set req.http.X-Varnish-Static = "1";
192
  return (lookup);
193
  }
194
  # this doesn't need a enable_url_excludes because we can be reasonably
205
  req.url ~ "(?:[?&](?:{{get_param_excludes}})(?=[&=]|$))") {
206
  return (pass);
207
  }
208
+ if (req.http.X-Opt-Enable-Get-Ignored == "true" && req.url ~ "[?&]({{get_param_ignored}})=") {
209
  # Strip out ignored GET related parameters
210
  set req.url = regsuball(req.url, "(?:(\?)?|&)(?:{{get_param_ignored}})=[^&]+", "\1");
211
  set req.url = regsuball(req.url, "(?:(\?)&|\?$)", "\1");
237
  # }
238
 
239
  sub vcl_hash {
240
+ # For static files we keep the hash simple and don't add the domain.
241
+ # This saves memory when a static file is used on multiple domains.
242
+ if (req.http.X-Opt-Simple-Hash-Static == "true" && req.http.X-Varnish-Static) {
243
+ set req.hash += req.url;
244
+ if (req.http.Accept-Encoding) {
245
+ # make sure we give back the right encoding
246
+ set req.hash += req.http.Accept-Encoding;
247
+ }
248
+ return (hash);
249
+ }
250
 
251
+ if(req.http.X-Opt-Send-Unmodified-Url == "true" && req.http.X-Varnish-Cache-Url) {
252
  set req.hash += req.http.X-Varnish-Cache-Url;
253
  } else {
254
  set req.hash += req.url;
app/code/community/Nexcessnet/Turpentine/misc/version-3.vcl CHANGED
@@ -28,10 +28,6 @@ C{
28
 
29
  import std;
30
 
31
- ## Custom VCL Logic
32
-
33
- {{custom_vcl_include}}
34
-
35
  ## Backends
36
 
37
  {{default_backend}}
@@ -185,6 +181,7 @@ sub vcl_recv {
185
  # don't need cookies for static assets
186
  unset req.http.Cookie;
187
  unset req.http.X-Varnish-Faked-Session;
 
188
  return (lookup);
189
  }
190
  # this doesn't need a enable_url_excludes because we can be reasonably
@@ -233,6 +230,16 @@ sub vcl_pipe {
233
  # }
234
 
235
  sub vcl_hash {
 
 
 
 
 
 
 
 
 
 
236
 
237
  if({{send_unmodified_url}} && req.http.X-Varnish-Cache-Url) {
238
  hash_data(req.http.X-Varnish-Cache-Url);
@@ -423,3 +430,8 @@ sub vcl_deliver {
423
  unset resp.http.X-Varnish-Set-Cookie;
424
  }
425
  }
 
 
 
 
 
28
 
29
  import std;
30
 
 
 
 
 
31
  ## Backends
32
 
33
  {{default_backend}}
181
  # don't need cookies for static assets
182
  unset req.http.Cookie;
183
  unset req.http.X-Varnish-Faked-Session;
184
+ set req.http.X-Varnish-Static = 1;
185
  return (lookup);
186
  }
187
  # this doesn't need a enable_url_excludes because we can be reasonably
230
  # }
231
 
232
  sub vcl_hash {
233
+ # For static files we keep the hash simple and don't add the domain.
234
+ # This saves memory when a static file is used on multiple domains.
235
+ if ({{simple_hash_static}} && req.http.X-Varnish-Static) {
236
+ hash_data(req.url);
237
+ if (req.http.Accept-Encoding) {
238
+ # make sure we give back the right encoding
239
+ hash_data(req.http.Accept-Encoding);
240
+ }
241
+ return (hash);
242
+ }
243
 
244
  if({{send_unmodified_url}} && req.http.X-Varnish-Cache-Url) {
245
  hash_data(req.http.X-Varnish-Cache-Url);
430
  unset resp.http.X-Varnish-Set-Cookie;
431
  }
432
  }
433
+
434
+ ## Custom VCL Logic
435
+
436
+ {{custom_vcl_include}}
437
+
app/code/community/Nexcessnet/Turpentine/misc/version-4.vcl CHANGED
@@ -29,10 +29,6 @@ C{
29
 
30
  import std;
31
 
32
- ## Custom VCL Logic
33
-
34
- {{custom_vcl_include}}
35
-
36
  ## Backends
37
 
38
  {{default_backend}}
@@ -183,6 +179,7 @@ sub vcl_recv {
183
  # don't need cookies for static assets
184
  unset req.http.Cookie;
185
  unset req.http.X-Varnish-Faked-Session;
 
186
  return (hash);
187
  }
188
  # this doesn't need a enable_url_excludes because we can be reasonably
@@ -237,6 +234,16 @@ sub vcl_pipe {
237
  # }
238
 
239
  sub vcl_hash {
 
 
 
 
 
 
 
 
 
 
240
 
241
  if({{send_unmodified_url}} && req.http.X-Varnish-Cache-Url) {
242
  hash_data(req.http.X-Varnish-Cache-Url);
@@ -424,3 +431,7 @@ sub vcl_deliver {
424
  unset resp.http.X-Varnish-Set-Cookie;
425
  }
426
  }
 
 
 
 
29
 
30
  import std;
31
 
 
 
 
 
32
  ## Backends
33
 
34
  {{default_backend}}
179
  # don't need cookies for static assets
180
  unset req.http.Cookie;
181
  unset req.http.X-Varnish-Faked-Session;
182
+ set req.http.X-Varnish-Static = 1;
183
  return (hash);
184
  }
185
  # this doesn't need a enable_url_excludes because we can be reasonably
234
  # }
235
 
236
  sub vcl_hash {
237
+ # For static files we keep the hash simple and don't add the domain.
238
+ # This saves memory when a static file is used on multiple domains.
239
+ if ({{simple_hash_static}} && req.http.X-Varnish-Static) {
240
+ hash_data(req.url);
241
+ if (req.http.Accept-Encoding) {
242
+ # make sure we give back the right encoding
243
+ hash_data(req.http.Accept-Encoding);
244
+ }
245
+ return (lookup);
246
+ }
247
 
248
  if({{send_unmodified_url}} && req.http.X-Varnish-Cache-Url) {
249
  hash_data(req.http.X-Varnish-Cache-Url);
431
  unset resp.http.X-Varnish-Set-Cookie;
432
  }
433
  }
434
+
435
+ ## Custom VCL Logic
436
+
437
+ {{custom_vcl_include}}
app/design/adminhtml/default/default/layout/turpentine.xml CHANGED
File without changes
app/design/adminhtml/default/default/template/turpentine/varnish_management.phtml CHANGED
File without changes
app/design/frontend/base/default/layout/turpentine_esi.xml CHANGED
@@ -44,6 +44,7 @@
44
  <wishlist_item_save_after/>
45
  <wishlist_item_delete_after/>
46
  <sales_quote_save_after/>
 
47
  </flush_events>
48
  </params>
49
  </action>
@@ -137,6 +138,16 @@
137
  </params>
138
  </action>
139
  </reference>
 
 
 
 
 
 
 
 
 
 
140
  </default>
141
 
142
  <!-- Blocks only visible when logged in -->
@@ -282,6 +293,126 @@
282
  <turpentine_cache_flag value="0"/>
283
  </checkout_onepage_failure>
284
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  <!-- End Checkout -->
286
 
287
  <!-- Customer Account -->
44
  <wishlist_item_save_after/>
45
  <wishlist_item_delete_after/>
46
  <sales_quote_save_after/>
47
+ <controller_action_layout_render_before_catalogsearch_result_index />
48
  </flush_events>
49
  </params>
50
  </action>
138
  </params>
139
  </action>
140
  </reference>
141
+
142
+ <reference name="global_cookie_notice">
143
+ <action method="setEsiOptions">
144
+ <params>
145
+ <access>private</access>
146
+ <only_cache_if>no_text</only_cache_if>
147
+ </params>
148
+ </action>
149
+ </reference>
150
+
151
  </default>
152
 
153
  <!-- Blocks only visible when logged in -->
293
  <turpentine_cache_flag value="0"/>
294
  </checkout_onepage_failure>
295
 
296
+ <checkout_prime_debug>
297
+ <turpentine_cache_flag value="0"/>
298
+ </checkout_prime_debug>
299
+
300
+ <checkout_prime_index>
301
+ <turpentine_cache_flag value="0"/>
302
+ </checkout_prime_index>
303
+
304
+ <checkout_prime_login_step_info>
305
+ <turpentine_cache_flag value="0"/>
306
+ </checkout_prime_login_step_info>
307
+
308
+ <checkout_prime_payment_step_info>
309
+ <turpentine_cache_flag value="0"/>
310
+ </checkout_prime_payment_step_info>
311
+
312
+ <checkout_prime_progress>
313
+ <turpentine_cache_flag value="0"/>
314
+ </checkout_prime_progress>
315
+
316
+ <checkout_prime_review>
317
+ <turpentine_cache_flag value="0"/>
318
+ </checkout_prime_review>
319
+
320
+ <checkout_prime_savepayment>
321
+ <turpentine_cache_flag value="0"/>
322
+ </checkout_prime_savepayment>
323
+
324
+ <checkout_prime_shipping_step_info>
325
+ <turpentine_cache_flag value="0"/>
326
+ </checkout_prime_shipping_step_info>
327
+
328
+ <checkout_prime_getstepinfo>
329
+ <turpentine_cache_flag value="0"/>
330
+ </checkout_prime_getstepinfo>
331
+
332
+ <checkout_prime_saveorder>
333
+ <turpentine_cache_flag value="0"/>
334
+ </checkout_prime_saveorder>
335
+
336
+ <checkout_prime_getaddress>
337
+ <turpentine_cache_flag value="0"/>
338
+ </checkout_prime_getaddress>
339
+
340
+ <checkout_prime_savemethod>
341
+ <turpentine_cache_flag value="0"/>
342
+ </checkout_prime_savemethod>
343
+
344
+ <checkout_prime_failure>
345
+ <turpentine_cache_flag value="0"/>
346
+ </checkout_prime_failure>
347
+
348
+ <checkout_prime_saveshippingmethod>
349
+ <turpentine_cache_flag value="0"/>
350
+ </checkout_prime_saveshippingmethod>
351
+
352
+ <checkout_prime_savecoupon>
353
+ <turpentine_cache_flag value="0"/>
354
+ </checkout_prime_savecoupon>
355
+
356
+ <checkout_prime_savebilling>
357
+ <turpentine_cache_flag value="0"/>
358
+ </checkout_prime_savebilling>
359
+
360
+ <checkout_prime_success>
361
+ <turpentine_cache_flag value="0"/>
362
+ </checkout_prime_success>
363
+
364
+ <checkout_prime_saveshipping>
365
+ <turpentine_cache_flag value="0"/>
366
+ </checkout_prime_saveshipping>
367
+
368
+ <checkout_prime_shippingmethod>
369
+ <turpentine_cache_flag value="0"/>
370
+ </checkout_prime_shippingmethod>
371
+
372
+ <checkout_prime_getadditional>
373
+ <turpentine_cache_flag value="0"/>
374
+ </checkout_prime_getadditional>
375
+
376
+ <gomage_checkout_onepage_index>
377
+ <turpentine_cache_flag value="0"/>
378
+ </gomage_checkout_onepage_index>
379
+
380
+ <gomage_checkout_onepage_methods>
381
+ <turpentine_cache_flag value="0"/>
382
+ </gomage_checkout_onepage_methods>
383
+
384
+ <gomage_checkout_onepage_paymentmethod>
385
+ <turpentine_cache_flag value="0"/>
386
+ </gomage_checkout_onepage_paymentmethod>
387
+
388
+ <gomage_checkout_onepage_centinel>
389
+ <turpentine_cache_flag value="0"/>
390
+ </gomage_checkout_onepage_centinel>
391
+
392
+ <gomage_checkout_onepage_review>
393
+ <turpentine_cache_flag value="0"/>
394
+ </gomage_checkout_onepage_review>
395
+
396
+ <gomage_checkout_onepage_customerlogin>
397
+ <turpentine_cache_flag value="0"/>
398
+ </gomage_checkout_onepage_customerlogin>
399
+
400
+ <gomage_checkout_onepage_review>
401
+ <turpentine_cache_flag value="0"/>
402
+ </gomage_checkout_onepage_review>
403
+
404
+ <gomage_checkout_onepage_forgotpassword>
405
+ <turpentine_cache_flag value="0"/>
406
+ </gomage_checkout_onepage_forgotpassword>
407
+
408
+ <gomage_checkout_onepage_ajax>
409
+ <turpentine_cache_flag value="0"/>
410
+ </gomage_checkout_onepage_ajax>
411
+
412
+ <gomage_checkout_onepage_save>
413
+ <turpentine_cache_flag value="0"/>
414
+ </gomage_checkout_onepage_save>
415
+
416
  <!-- End Checkout -->
417
 
418
  <!-- Customer Account -->
app/design/frontend/base/default/template/turpentine/ajax.phtml CHANGED
File without changes
app/design/frontend/base/default/template/turpentine/esi.phtml CHANGED
File without changes
app/design/frontend/base/default/template/turpentine/notices.phtml CHANGED
File without changes
app/etc/modules/Nexcessnet_Turpentine.xml CHANGED
File without changes
package.xml CHANGED
@@ -1,2 +1,2 @@
1
  <?xml version='1.0' encoding='utf-8'?>
2
- <package><name>Nexcessnet_Turpentine</name><license uri="http://opensource.org/licenses/GPL-2.0">GPLv2</license><notes>Supports Magento v1.6 and later</notes><time>11:51:06</time><__packager>build_package.py v0.0.3</__packager><summary>Improves Magento support for Varnish caching and generates 2.1 and 3.0 compatible VCLs.</summary><stability>stable</stability><__commit_hash>c5e7ba20e9d703f3e6832850d90d9479ee0aa19f</__commit_hash><version>0.6.7</version><extends /><contents><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file hash="a0bd4a5632b369b058c0ec5262e0cc49" name="turpentine.xml" /></dir><dir name="template"><dir name="turpentine"><file hash="b564606032d111537d02c8da63470c39" name="varnish_management.phtml" /></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file hash="45405f2d1c0b5e915ffbd7da261d7ed0" name="turpentine_esi.xml" /></dir><dir name="template"><dir name="turpentine"><file hash="50798888953fd1550e4347c39e395d0a" name="notices.phtml" /><file hash="b268c48251ccfccf5c775d3e85513584" name="esi.phtml" /><file hash="02f341fdfd5194752e88cae9933cfcdb" name="ajax.phtml" /></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file hash="58848d4d90973bfd63b466ea181352a5" name="Nexcessnet_Turpentine.xml" /></dir></target><target name="magecommunity"><dir name="Nexcessnet"><dir name="Turpentine"><dir name="Helper"><file hash="7934848bff8108cfc67e34e0571bd271" name="Esi.php" /><file hash="802e269b0c80131efbb070309fdc610f" name="Varnish.php" /><file hash="913d0762f9df7696f1217f82791f1b78" name="Cron.php" /><file hash="0ee525f0fba5236f05ad2289fe2f2292" name="Data.php" /><file hash="6b637be4eac4c924fc1f02b2d49699c3" name="Ban.php" /><file hash="4a448ad2fe5b5a253a37d3f4aa3dd1bb" name="Debug.php" /></dir><dir name="misc"><file hash="05abb0bc318ae439f3a6bf53ba11f32a" name="version-3.vcl" /><file hash="1f3a0abeea9acb6d2ec33839dc82012c" name="version-4.vcl" /><file hash="ba5d5c7263cd90eea3785953e3549041" name="uuid.c" /><file hash="af0bd785669e738819536bb806a7ba13" name="version-2.vcl" /></dir><dir name="etc"><file hash="015d30af2e06ffae50e92291592be6d8" name="system.xml" /><file hash="db67350fe497dcb4482f47e297c349f7" name="config.xml~" /><file hash="3b608fbcca3d307833d10604dff23966" name="cache.xml" /><file hash="2a4bc61f3c6c68fc970707f8828f4046" name="config.xml" /></dir><dir name="controllers"><file hash="c871a1b17344f7e1e267a614bd8e7d5e" name="EsiController.php" /><dir name="Adminhtml"><file hash="fb44492ff908e0dd28a4fa62e382bd3e" name="CacheController.php" /></dir><dir name="Varnish"><file hash="625118bfe342139b7fd9464c05d1b0a6" name="ManagementController.php" /></dir></dir><dir name="Model"><file hash="c2cb79001524617febbfddf099d09f37" name="Session.php" /><dir name="Shim"><dir name="Mage"><dir name="Core"><file hash="9e5d87f0aa84c9fb1541db83aba69abd" name="Config.php" /><file hash="821bff6c2fb372e3ffb39abf6453b3f8" name="Layout.php" /><file hash="4a1aa246373520936f0e4b5b3a3baf25" name="App.php" /></dir></dir></dir><dir name="PageCache"><dir name="Container"><file hash="139e8a9bfa209316036e798fff654a8a" name="Notices.php" /></dir></dir><dir name="Dummy"><file hash="f6611808da53ffa00561a8f76b26016e" name="Request.php" /></dir><dir name="Varnish"><file hash="d174c8dc29d3c4ab34ac0ee57f519d76" name="Admin.php" /><dir name="Admin"><file hash="69828f635e7ce3378fb9aaf861be0b3c" name="Socket.php" /></dir><dir name="Configurator"><file hash="b831b872fcb05d9c723149159db0eed1" name="Version2.php" /><file hash="82d0abe0123272e59e6c319dfdd4e9dc" name="Version3.php" /><file hash="179b9529f2eef55964d25e56b85291a7" name="Version4.php" /><file hash="0672d5ca172564bc4e9457fdfc0a5264" name="Abstract.php" /></dir></dir><dir name="Observer"><file hash="bcc39edc7065ad9d94235211b9e940ca" name="Esi.php" /><file hash="7244a8ce600e980d612409595b9b6b9b" name="Varnish.php" /><file hash="a34e79218e8ca1fefad303b9399bda9d" name="Cron.php" /><file hash="e3e1542dfcf56f2353dd62e39cfd3b98" name="Ban.php" /><file hash="9d57fad69ff42b71c66ca26bc3372317" name="Debug.php" /></dir><dir name="Core"><file hash="d4f63abc6d34c923c6e64a522b6fc36e" name="Session.php" /></dir><dir name="Config"><dir name="Select"><file hash="2e01b14592189b3f6a8a05be5ef4c69c" name="StripWhitespace.php" /><file hash="15b5296a7f7bc719331f14d34308013b" name="Version.php" /><file hash="2a4648995fc87472b2ac33b35a7d69e5" name="LoadBalancing.php" /><file hash="9348c5e58037fd97d89b84ccab4ef2d0" name="Toggle.php" /></dir></dir></dir><dir name="Block"><file hash="e9b03d651a8da9b1d32c4fd2f4781792" name="Management.php" /><file hash="390cf75d04b1b098cad562229b649c2d" name="Notices.php" /><dir name="Adminhtml"><dir name="Cache"><file hash="798cf7afa80e0a06be2b8c6cb2bef02b" name="Grid.php" /></dir></dir><dir name="Catalog"><dir name="Product"><dir name="List"><file hash="ce9fca4c273987759f284fe31c1597f5" name="Toolbar.php" /></dir></dir></dir><dir name="Product"><file hash="56ac2e90d0eed7eaadaf4517c1ad77ff" name="Compared.php" /><file hash="f72d0718ccd2895cbf4fc1cbc24bf90c" name="Viewed.php" /></dir><dir name="Core"><file hash="b34cad980a3e5da9860b21a7aa7a0b0f" name="Messages.php" /></dir><dir name="Poll"><file hash="bf9ca23a445776435e38e6c8be9976ea" name="ActivePoll.php" /></dir></dir></dir></dir></target></contents><dependencies><required><php><min>5.2.13</min><max>6.0.0</max></php></required></dependencies><authors><author><name>Chris Wells</name><user>nexcess_net</user><email>clwells@nexcess.net</email></author><author><name>Alex Headley</name><user>aheadley_nex</user><email>aheadley@nexcess.net</email></author></authors><date>2015-10-12</date><compatibile /><channel>community</channel><description>Turpentine is a Magento extension to improve Magento's compatibility with Varnish, a very-fast caching reverse-proxy. By default, Varnish doesn't cache requests with cookies and Magento sends the frontend cookie with every request causing a (near) zero hit-rate for Varnish's cache. Turpentine provides Varnish configuration files (VCLs) to work with Magento and modifies Magento's behaviour to significantly improve the cache hit rate.</description></package>
1
  <?xml version='1.0' encoding='utf-8'?>
2
+ <package><name>Nexcessnet_Turpentine</name><license uri="http://opensource.org/licenses/GPL-2.0">GPLv2</license><notes>Supports Magento v1.6 and later</notes><time>11:49:02</time><__packager>build_package.py v0.0.3</__packager><summary>Improves Magento support for Varnish caching and generates 2.1 and 3.0 compatible VCLs.</summary><stability>stable</stability><__commit_hash>6ffc75169f63f3fda7d2f1196b341e0db498064d</__commit_hash><version>0.6.8</version><extends /><contents><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file hash="a0bd4a5632b369b058c0ec5262e0cc49" name="turpentine.xml" /></dir><dir name="template"><dir name="turpentine"><file hash="b564606032d111537d02c8da63470c39" name="varnish_management.phtml" /></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file hash="d121558e4cd5775b0845ebeec5909b97" name="turpentine_esi.xml" /></dir><dir name="template"><dir name="turpentine"><file hash="50798888953fd1550e4347c39e395d0a" name="notices.phtml" /><file hash="b268c48251ccfccf5c775d3e85513584" name="esi.phtml" /><file hash="02f341fdfd5194752e88cae9933cfcdb" name="ajax.phtml" /></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file hash="58848d4d90973bfd63b466ea181352a5" name="Nexcessnet_Turpentine.xml" /></dir></target><target name="magecommunity"><dir name="Nexcessnet"><dir name="Turpentine"><dir name="Helper"><file hash="7f156b5d3f3aafd56f8ec67f4d70d436" name="Esi.php" /><file hash="99ec12c46fd42fbfabdb191c4af7fbe6" name="Varnish.php" /><file hash="33855dc76575297ecaf41a8a39a63937" name="Cron.php" /><file hash="c1a55b8d3bdb780fcd3315d214e94b01" name="Data.php" /><file hash="c6068752ae71f7fbf58208263d94880d" name="Ban.php" /><file hash="66399790e7dda35e709b346889a21b1b" name="Debug.php" /></dir><dir name="misc"><file hash="f8368123a257cb25ee7db63ec54cce12" name="version-3.vcl" /><file hash="19c6a4be3cb30f9fb1f27208f66e559b" name="version-4.vcl" /><file hash="ba5d5c7263cd90eea3785953e3549041" name="uuid.c" /><file hash="9c07f16b0d2b692578cc6dab15a11804" name="version-2.vcl" /></dir><dir name="etc"><file hash="445c765560917715d906012fafd23866" name="system.xml" /><file hash="259cbde597af72e828691f3450fb6fbe" name="config.xml~" /><file hash="3b608fbcca3d307833d10604dff23966" name="cache.xml" /><file hash="461e177605479f55c3430d863552f10e" name="config.xml" /></dir><dir name="controllers"><file hash="9963ddff7c13d5d087aa3dbdffcd1532" name="EsiController.php" /><dir name="Adminhtml"><file hash="9ed581279364b21ead6ad07ff951d90e" name="CacheController.php" /></dir><dir name="Varnish"><file hash="36ed74dba513b500b7a25175d43a4d71" name="ManagementController.php" /></dir></dir><dir name="Model"><file hash="ffd2af1c58782a2086422b2077f00282" name="Session.php" /><dir name="Shim"><dir name="Mage"><dir name="Core"><file hash="5912fa8ef25346f2a21316d8ea5de867" name="Config.php" /><file hash="ee6924c626916a8edd49b6037809204a" name="Layout.php" /><file hash="85e9e378b8fd0ab504c751a69d0b28a6" name="App.php" /></dir></dir></dir><dir name="PageCache"><dir name="Container"><file hash="6e3b54ae5968af644952b00cd96a3f32" name="Notices.php" /></dir></dir><dir name="Dummy"><file hash="07e4db6d82110e523d1400dcfec60830" name="Request.php" /></dir><dir name="Varnish"><file hash="b264dc1982cef539b8dc2c86aa34c5c3" name="Admin.php" /><dir name="Admin"><file hash="304cdb4970dec60460433163d5532533" name="Socket.php" /></dir><dir name="Configurator"><file hash="d4d66168e43a62ceab30226b44b9e98b" name="Version2.php" /><file hash="c0c0d52175e72b95c059345a31b5de31" name="Version3.php" /><file hash="870922083925f5120e4ec52f279a8870" name="Version4.php" /><file hash="eea0cbf3c779a9d9ce8b38f33aa7d333" name="Abstract.php" /></dir></dir><dir name="Observer"><file hash="d92dc22addfd90ed5b929e8cb17b8002" name="Esi.php" /><file hash="16e4975274e8c3454bf2226d5a0558e6" name="Varnish.php" /><file hash="ca77c52f1d5338102691573caa308e2c" name="Cron.php" /><file hash="1c6d12a23a14549cbf59be272c922c40" name="Ban.php" /><file hash="4f67e6d7c35891451391b13a0eec9847" name="Debug.php" /></dir><dir name="Core"><file hash="e715e7991e7cd8e3081f105b07acf00f" name="Session.php" /></dir><dir name="Config"><dir name="Select"><file hash="f411ae6da3c2154e78e0f7e845212166" name="StripWhitespace.php" /><file hash="403dcea1f19b377f30af5f89297d9a69" name="Version.php" /><file hash="2a4648995fc87472b2ac33b35a7d69e5" name="LoadBalancing.php" /><file hash="9348c5e58037fd97d89b84ccab4ef2d0" name="Toggle.php" /></dir></dir></dir><dir name="Block"><file hash="5584baf2ebba7e0fe7e9491a46a6e4cf" name="Management.php" /><file hash="390cf75d04b1b098cad562229b649c2d" name="Notices.php" /><dir name="Adminhtml"><dir name="Cache"><file hash="8265061356f8096fc82c88334b4effc9" name="Grid.php" /></dir></dir><dir name="Catalog"><dir name="Product"><dir name="List"><file hash="ce9fca4c273987759f284fe31c1597f5" name="Toolbar.php" /></dir></dir></dir><dir name="Product"><file hash="e907d4de82aba5be25272127674a10e3" name="Compared.php" /><file hash="c86f7e0571583011932b8bad37aa5acd" name="Viewed.php" /></dir><dir name="Core"><file hash="2b4c814c8aa426fa586459716d7c2659" name="Messages.php" /></dir><dir name="Poll"><file hash="1fa406956ddf42e5afb34b2a96cccecc" name="ActivePoll.php" /></dir></dir></dir></dir></target></contents><dependencies><required><php><min>5.2.13</min><max>6.0.0</max></php></required></dependencies><authors><author><name>Chris Wells</name><user>nexcess_net</user><email>clwells@nexcess.net</email></author><author><name>Alex Headley</name><user>aheadley_nex</user><email>aheadley@nexcess.net</email></author></authors><date>2016-01-14</date><compatibile /><channel>community</channel><description>Turpentine is a Magento extension to improve Magento's compatibility with Varnish, a very-fast caching reverse-proxy. By default, Varnish doesn't cache requests with cookies and Magento sends the frontend cookie with every request causing a (near) zero hit-rate for Varnish's cache. Turpentine provides Varnish configuration files (VCLs) to work with Magento and modifies Magento's behaviour to significantly improve the cache hit rate.</description></package>