1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Nexcess.net Turpentine Extension for Magento |
5
|
|
|
* Copyright (C) 2012 Nexcess.net L.L.C. |
6
|
|
|
* |
7
|
|
|
* This program is free software; you can redistribute it and/or modify |
8
|
|
|
* it under the terms of the GNU General Public License as published by |
9
|
|
|
* the Free Software Foundation; either version 2 of the License, or |
10
|
|
|
* (at your option) any later version. |
11
|
|
|
* |
12
|
|
|
* This program is distributed in the hope that it will be useful, |
13
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
14
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15
|
|
|
* GNU General Public License for more details. |
16
|
|
|
* |
17
|
|
|
* You should have received a copy of the GNU General Public License along |
18
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc., |
19
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
20
|
|
|
*/ |
21
|
|
|
|
22
|
|
|
class Nexcessnet_Turpentine_Model_Observer_Esi extends Varien_Event_Observer { |
23
|
|
|
/** |
24
|
|
|
* Set a cookie with the customer group id when customer logs in |
25
|
|
|
* |
26
|
|
|
* Events: customer_login |
27
|
|
|
* |
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')) { |
35
|
|
|
$cookie->set('customer_group', $customer->getGroupId(), Mage::getStoreConfig('persistent/options/lifetime')); |
36
|
|
|
} else { |
37
|
|
|
$cookie->set('customer_group', $customer->getGroupId()); |
38
|
|
|
} |
39
|
|
|
} |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Destroy the cookie with the customer group when customer logs out |
43
|
|
|
* |
44
|
|
|
* Events: customer_logout |
45
|
|
|
* |
46
|
|
|
* @param Varien_Object $eventObject |
47
|
|
|
* @return null |
48
|
|
|
*/ |
49
|
|
|
public function removeCustomerGroupCookie($eventObject) { |
50
|
|
|
Mage::getSingleton('core/cookie')->delete('customer_group'); |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Check the ESI flag and set the ESI header if needed |
55
|
|
|
* |
56
|
|
|
* Events: http_response_send_before |
57
|
|
|
* |
58
|
|
|
* @param Varien_Object $eventObject |
59
|
|
|
* @return null |
60
|
|
|
*/ |
61
|
|
View Code Duplication |
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
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* Allows disabling page-caching by setting the cache flag on a controller |
74
|
|
|
* |
75
|
|
|
* <customer_account> |
76
|
|
|
* <turpentine_cache_flag value="0" /> |
77
|
|
|
* </customer_account> |
78
|
|
|
* |
79
|
|
|
* Events: controller_action_layout_generate_blocks_after |
80
|
|
|
* |
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
|
|
|
} |
95
|
|
|
} |
96
|
|
|
} |
97
|
|
|
} |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* On controller redirects, check the target URL and set to home page |
102
|
|
|
* if it would otherwise go to a getBlock URL |
103
|
|
|
* |
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
|
|
|
} |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* Load the cache clear events from stored config |
137
|
|
|
* |
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
|
|
|
/** |
154
|
|
|
* Add the core/messages block rewrite if the flash message fix is enabled |
155
|
|
|
* |
156
|
|
|
* The core/messages block is rewritten because it doesn't use a template |
157
|
|
|
* we can replace with an ESI include tag, just dumps out a block of |
158
|
|
|
* hard-coded HTML and also frequently skips the toHtml method |
159
|
|
|
* |
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
|
|
|
|
173
|
|
|
/** |
174
|
|
|
* Check the magento version and runtime env and set the replace_form_key |
175
|
|
|
* flag if needed |
176
|
|
|
* |
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
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* Replace the form key placeholder with the ESI include fragment |
193
|
|
|
* |
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
|
|
|
|
210
|
|
|
/** |
211
|
|
|
* Encode block data in URL then replace with ESI template |
212
|
|
|
* |
213
|
|
|
* @link https://github.com/nexcess/magento-turpentine/wiki/ESI_Cache_Policy |
214
|
|
|
* |
215
|
|
|
* Events: core_block_abstract_to_html_before |
216
|
|
|
* |
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
|
|
|
$debugHelper->logInfo("-- block testing: shouldResponseUseEsi = ".$esiHelper->shouldResponseUseEsi()); |
231
|
|
|
$debugHelper->logInfo("-- block testing: instanceof Mage_Core_Block_Template = ".$blockObject instanceof Mage_Core_Block_Template); |
|
|
|
|
232
|
|
|
$debugHelper->logInfo("-- block testing: Esi Options = ".print_r($blockObject->getEsiOptions(), true)); |
233
|
|
|
} |
234
|
|
|
if ($esiHelper->shouldResponseUseEsi() && |
235
|
|
|
$blockObject instanceof Mage_Core_Block_Template && |
|
|
|
|
236
|
|
|
$esiOptions = $blockObject->getEsiOptions()) { |
237
|
|
|
|
238
|
|
|
if ((isset($esiOptions['disableEsiInjection'])) && ($esiOptions['disableEsiInjection'] == 1)) { |
239
|
|
|
if ($esiHelper->getEsiBlockLogEnabled()) { |
240
|
|
|
$debugHelper->logInfo("-- ESI Injection disabled"); |
241
|
|
|
} |
242
|
|
|
return; |
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
if (Mage::app()->getStore()->getCode() == 'admin') { |
246
|
|
|
// admin blocks are not allowed to be cached for now |
247
|
|
|
$debugHelper->logWarn( |
248
|
|
|
'Ignoring attempt to inject adminhtml block: %s', |
249
|
|
|
$blockObject->getNameInLayout() ? $blockObject->getNameInLayout() : $blockObject->getModuleName() ); |
250
|
|
|
return; |
251
|
|
|
} elseif ($esiHelper->getEsiBlockLogEnabled()) { |
252
|
|
|
$debugHelper->logInfo('Block check passed, injecting block: %s', |
253
|
|
|
$blockObject->getNameInLayout() ? $blockObject->getNameInLayout() : $blockObject->getModuleName()); |
254
|
|
|
} |
255
|
|
|
Varien_Profiler::start('turpentine::observer::esi::injectEsi'); |
256
|
|
|
$ttlParam = $esiHelper->getEsiTtlParam(); |
257
|
|
|
$cacheTypeParam = $esiHelper->getEsiCacheTypeParam(); |
258
|
|
|
$dataParam = $esiHelper->getEsiDataParam(); |
259
|
|
|
$methodParam = $esiHelper->getEsiMethodParam(); |
260
|
|
|
$hmacParam = $esiHelper->getEsiHmacParam(); |
261
|
|
|
$scopeParam = $esiHelper->getEsiScopeParam(); |
262
|
|
|
$referrerParam = $esiHelper->getEsiReferrerParam(); |
263
|
|
|
|
264
|
|
|
$esiOptions = $this->_getDefaultEsiOptions($esiOptions); |
265
|
|
|
|
266
|
|
|
// change the block's template to the stripped down ESI template |
267
|
|
|
switch ($esiOptions[$methodParam]) { |
268
|
|
|
case 'ajax': |
269
|
|
|
$blockObject->setTemplate('turpentine/ajax.phtml'); |
270
|
|
|
break; |
271
|
|
|
|
272
|
|
|
case 'esi': |
273
|
|
|
default: |
274
|
|
|
$blockObject->setTemplate('turpentine/esi.phtml'); |
275
|
|
|
// flag request for ESI processing |
276
|
|
|
Mage::register('turpentine_esi_flag', true, true); |
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
// esi data is the data needed to regenerate the ESI'd block |
280
|
|
|
$esiData = $this->_getEsiData($blockObject, $esiOptions)->toArray(); |
281
|
|
|
ksort($esiData); |
282
|
|
|
$frozenData = $dataHelper->freeze($esiData); |
283
|
|
|
$urlOptions = array( |
284
|
|
|
$methodParam => $esiOptions[$methodParam], |
285
|
|
|
$cacheTypeParam => $esiOptions[$cacheTypeParam], |
286
|
|
|
$ttlParam => $esiOptions[$ttlParam], |
287
|
|
|
$hmacParam => $dataHelper->getHmac($frozenData), |
288
|
|
|
$dataParam => $frozenData, |
289
|
|
|
); |
290
|
|
|
if ($esiOptions[$methodParam] == 'ajax') { |
291
|
|
|
$urlOptions['_secure'] = Mage::app()->getStore() |
292
|
|
|
->isCurrentlySecure(); |
293
|
|
|
} |
294
|
|
|
if ($esiOptions[$scopeParam] == 'page') { |
295
|
|
|
$urlOptions[$referrerParam] = Mage::helper('core')->urlEncode( |
296
|
|
|
Mage::getUrl('*/*/*', array('_use_rewrite' => true, '_current' => true)) |
297
|
|
|
); |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
/** |
301
|
|
|
* Keep params from original url |
302
|
|
|
*/ |
303
|
|
|
$urlOptions['_query'] = Mage::app()->getRequest()->getParams(); |
304
|
|
|
|
305
|
|
|
$esiUrl = Mage::getUrl('turpentine/esi/getBlock', $urlOptions); |
306
|
|
|
if ($esiOptions[$methodParam] == 'esi') { |
307
|
|
|
// setting [web/unsecure/base_url] can be https://... but ESI can never be HTTPS |
308
|
|
|
$esiUrl = preg_replace('|^https://|i', 'http://', $esiUrl); |
309
|
|
|
} |
310
|
|
|
$blockObject->setEsiUrl($esiUrl); |
311
|
|
|
// avoid caching the ESI template output to prevent the double-esi- |
312
|
|
|
// include/"ESI processing not enabled" bug |
313
|
|
|
foreach (array('lifetime', 'tags', 'key') as $dataKey) { |
314
|
|
|
$blockObject->unsetData('cache_'.$dataKey); |
315
|
|
|
} |
316
|
|
|
if (strlen($esiUrl) > 2047) { |
317
|
|
|
Mage::helper('turpentine/debug')->logWarn( |
318
|
|
|
'ESI url is probably too long (%d > 2047 characters): %s', |
319
|
|
|
strlen($esiUrl), $esiUrl ); |
320
|
|
|
} |
321
|
|
|
Varien_Profiler::stop('turpentine::observer::esi::injectEsi'); |
322
|
|
|
} // else handle the block like normal and cache it inline with the page |
323
|
|
|
} |
324
|
|
|
|
325
|
|
|
/** |
326
|
|
|
* Generate ESI data to be encoded in URL |
327
|
|
|
* |
328
|
|
|
* @param Mage_Core_Block_Template $blockObject |
329
|
|
|
* @param array $esiOptions |
330
|
|
|
* @return Varien_Object |
331
|
|
|
*/ |
332
|
|
|
protected function _getEsiData($blockObject, $esiOptions) { |
333
|
|
|
Varien_Profiler::start('turpentine::observer::esi::_getEsiData'); |
334
|
|
|
$esiHelper = Mage::helper('turpentine/esi'); |
335
|
|
|
$cacheTypeParam = $esiHelper->getEsiCacheTypeParam(); |
336
|
|
|
$scopeParam = $esiHelper->getEsiScopeParam(); |
337
|
|
|
$methodParam = $esiHelper->getEsiMethodParam(); |
338
|
|
|
$esiData = new Varien_Object(); |
339
|
|
|
$esiData->setStoreId(Mage::app()->getStore()->getId()); |
340
|
|
|
$esiData->setDesignPackage(Mage::getDesign()->getPackageName()); |
341
|
|
|
$esiData->setDesignTheme(Mage::getDesign()->getTheme('layout')); |
342
|
|
|
$esiData->setNameInLayout($blockObject->getNameInLayout()); |
343
|
|
|
$esiData->setBlockType(get_class($blockObject)); |
344
|
|
|
$esiData->setLayoutHandles($this->_getBlockLayoutHandles($blockObject)); |
345
|
|
|
$esiData->setEsiMethod($esiOptions[$methodParam]); |
346
|
|
|
if ($esiOptions[$cacheTypeParam] == 'private' || $esiOptions[$cacheTypeParam] == 'customer_group') { |
347
|
|
|
if (is_array(@$esiOptions['flush_events'])) { |
348
|
|
|
$esiData->setFlushEvents(array_merge( |
349
|
|
|
$esiHelper->getDefaultCacheClearEvents(), |
350
|
|
|
array_keys($esiOptions['flush_events']) )); |
351
|
|
|
} else { |
352
|
|
|
$esiData->setFlushEvents( |
353
|
|
|
$esiHelper->getDefaultCacheClearEvents() ); |
354
|
|
|
} |
355
|
|
|
} |
356
|
|
|
if ($esiOptions[$scopeParam] == 'page') { |
357
|
|
|
$esiData->setParentUrl(Mage::app()->getRequest()->getRequestString()); |
358
|
|
|
} |
359
|
|
|
if (is_array($esiOptions['dummy_blocks'])) { |
360
|
|
|
$dummyBlocks = array(); |
361
|
|
|
foreach ($esiOptions['dummy_blocks'] as $key => $value) { |
362
|
|
|
$dummyBlocks[] = (empty($value) && ! is_numeric($key)) ? $key : $value; |
363
|
|
|
} |
364
|
|
|
$esiData->setDummyBlocks($dummyBlocks); |
365
|
|
|
} else { |
366
|
|
|
Mage::helper('turpentine/debug')->logWarn( |
367
|
|
|
'Invalid dummy_blocks for block: %s', |
368
|
|
|
$blockObject->getNameInLayout() ); |
369
|
|
|
} |
370
|
|
|
$simpleRegistry = array(); |
371
|
|
|
$complexRegistry = array(); |
372
|
|
|
if (is_array($esiOptions['registry_keys'])) { |
373
|
|
|
foreach ($esiOptions['registry_keys'] as $key => $options) { |
374
|
|
|
$value = Mage::registry($key); |
375
|
|
|
if ($value) { |
376
|
|
|
if (is_object($value) && |
377
|
|
|
$value instanceof Mage_Core_Model_Abstract) { |
|
|
|
|
378
|
|
|
$complexRegistry[$key] = |
379
|
|
|
$this->_getComplexRegistryData($options, $value); |
380
|
|
|
} else { |
381
|
|
|
$simpleRegistry[$key] = $value; |
382
|
|
|
} |
383
|
|
|
} |
384
|
|
|
} |
385
|
|
|
} else { |
386
|
|
|
Mage::helper('turpentine/debug')->logWarn( |
387
|
|
|
'Invalid registry_keys for block: %s', |
388
|
|
|
$blockObject->getNameInLayout() ); |
389
|
|
|
} |
390
|
|
|
$esiData->setSimpleRegistry($simpleRegistry); |
391
|
|
|
$esiData->setComplexRegistry($complexRegistry); |
392
|
|
|
Varien_Profiler::stop('turpentine::observer::esi::_getEsiData'); |
393
|
|
|
return $esiData; |
394
|
|
|
} |
395
|
|
|
|
396
|
|
|
/** |
397
|
|
|
* Get the active layout handles for this block and any child blocks |
398
|
|
|
* |
399
|
|
|
* This is probably kind of slow since it uses a bunch of xpath searches |
400
|
|
|
* but this was the easiest way to get the info needed. Should be a target |
401
|
|
|
* for future optimization |
402
|
|
|
* |
403
|
|
|
* There is an issue with encoding the used handles in the URL, if the used |
404
|
|
|
* handles change (ex customer logs in), the cached version of the page will |
405
|
|
|
* still have the old handles encoded in it's ESI url. This can lead to |
406
|
|
|
* weirdness like the "Log in" link displaying for already logged in |
407
|
|
|
* visitors on pages that were initially visited by not-logged-in visitors. |
408
|
|
|
* Not sure of a solution for this yet. |
409
|
|
|
* |
410
|
|
|
* Above problem is currently solved by EsiController::_swapCustomerHandles() |
411
|
|
|
* but it would be best to find a more general solution to this. |
412
|
|
|
* |
413
|
|
|
* @param Mage_Core_Block_Template $block |
414
|
|
|
* @return array |
415
|
|
|
*/ |
416
|
|
|
protected function _getBlockLayoutHandles($block) { |
417
|
|
|
Varien_Profiler::start('turpentine::observer::esi::_getBlockLayoutHandles'); |
418
|
|
|
$layout = $block->getLayout(); |
419
|
|
|
$layoutXml = Mage::helper('turpentine/esi')->getLayoutXml(); |
420
|
|
|
$activeHandles = array(); |
421
|
|
|
// get the xml node representing the block we're working on (from the |
422
|
|
|
// default handle probably) |
423
|
|
|
$blockNode = Mage::helper('turpentine/esi')->getEsiLayoutBlockNode( |
424
|
|
|
$layout, $block->getNameInLayout()); |
425
|
|
|
$childBlocks = Mage::helper('turpentine/data') |
426
|
|
|
->getChildBlockNames($blockNode); |
427
|
|
|
foreach ($childBlocks as $blockName) { |
428
|
|
|
foreach ($layout->getUpdate()->getHandles() as $handle) { |
429
|
|
|
// check if this handle has any block or reference tags that |
430
|
|
|
// refer to this block or a child block, unless the handle name |
431
|
|
|
// is blank |
432
|
|
|
if ($handle !== '' && (strpos($handle, 'THEME') === 0 || |
433
|
|
|
$layoutXml->xpath(sprintf( |
434
|
|
|
'//%s//*[@name=\'%s\']', $handle, $blockName )))) { |
435
|
|
|
$activeHandles[] = $handle; |
436
|
|
|
} |
437
|
|
|
} |
438
|
|
|
} |
439
|
|
|
if ( ! $activeHandles) { |
|
|
|
|
440
|
|
|
$activeHandles[] = 'default'; |
441
|
|
|
} |
442
|
|
|
Varien_Profiler::stop('turpentine::observer::esi::_getBlockLayoutHandles'); |
443
|
|
|
return array_unique($activeHandles); |
444
|
|
|
} |
445
|
|
|
|
446
|
|
|
/** |
447
|
|
|
* Get the default ESI options |
448
|
|
|
* |
449
|
|
|
* @return array |
450
|
|
|
*/ |
451
|
|
|
protected function _getDefaultEsiOptions($options) { |
452
|
|
|
$esiHelper = Mage::helper('turpentine/esi'); |
453
|
|
|
$ttlParam = $esiHelper->getEsiTtlParam(); |
454
|
|
|
$methodParam = $esiHelper->getEsiMethodParam(); |
455
|
|
|
$cacheTypeParam = $esiHelper->getEsiCacheTypeParam(); |
456
|
|
|
$defaults = array( |
457
|
|
|
$esiHelper->getEsiMethodParam() => 'esi', |
458
|
|
|
$esiHelper->getEsiScopeParam() => 'global', |
459
|
|
|
$esiHelper->getEsiCacheTypeParam() => 'public', |
460
|
|
|
'dummy_blocks' => array(), |
461
|
|
|
'registry_keys' => array(), |
462
|
|
|
); |
463
|
|
|
$options = array_merge($defaults, $options); |
464
|
|
|
|
465
|
|
|
// set the default TTL |
466
|
|
|
if ( ! isset($options[$ttlParam])) { |
467
|
|
|
if ($options[$cacheTypeParam] == 'private' || $options[$cacheTypeParam] == 'customer_group') { |
468
|
|
|
switch ($options[$methodParam]) { |
469
|
|
|
case 'ajax': |
470
|
|
|
$options[$ttlParam] = '0'; |
471
|
|
|
break; |
472
|
|
|
|
473
|
|
|
case 'esi': |
474
|
|
|
default: |
475
|
|
|
$options[$ttlParam] = $esiHelper->getDefaultEsiTtl(); |
476
|
|
|
break; |
477
|
|
|
} |
478
|
|
|
} else { |
479
|
|
|
$options[$ttlParam] = Mage::helper('turpentine/varnish') |
480
|
|
|
->getDefaultTtl(); |
481
|
|
|
} |
482
|
|
|
} |
483
|
|
|
|
484
|
|
|
return $options; |
485
|
|
|
} |
486
|
|
|
|
487
|
|
|
/** |
488
|
|
|
* Get the complex registry entry data |
489
|
|
|
* |
490
|
|
|
* @param array $valueOptions |
491
|
|
|
* @param mixed $value |
492
|
|
|
* @return array |
493
|
|
|
*/ |
494
|
|
|
protected function _getComplexRegistryData($valueOptions, $value) { |
495
|
|
|
$idMethod = @$valueOptions['id_method'] ? |
496
|
|
|
$valueOptions['id_method'] : 'getId'; |
497
|
|
|
$model = @$valueOptions['model'] ? |
498
|
|
|
$valueOptions['model'] : Mage::helper('turpentine/data') |
499
|
|
|
->getModelName($value); |
500
|
|
|
$data = array( |
501
|
|
|
'model' => $model, |
502
|
|
|
'id' => $value->{$idMethod}(), |
503
|
|
|
); |
504
|
|
|
return $data; |
505
|
|
|
} |
506
|
|
|
|
507
|
|
|
/** |
508
|
|
|
* Fix a URL to ensure it uses Magento's base URL instead of the backend |
509
|
|
|
* URL |
510
|
|
|
* |
511
|
|
|
* @param string $uencUrl |
512
|
|
|
* @return string |
513
|
|
|
*/ |
514
|
|
|
protected function _fixupUencUrl($uencUrl) { |
515
|
|
|
$esiHelper = Mage::helper('turpentine/esi'); |
516
|
|
|
$corsOrigin = $esiHelper->getCorsOrigin(); |
517
|
|
|
if ($corsOrigin != $esiHelper->getCorsOrigin($uencUrl)) { |
518
|
|
|
return $corsOrigin.parse_url($uencUrl, PHP_URL_PATH); |
519
|
|
|
} else { |
520
|
|
|
return $uencUrl; |
521
|
|
|
} |
522
|
|
|
} |
523
|
|
|
|
524
|
|
|
/** |
525
|
|
|
* Check if a URL *is not* for the /turpentine/esi/getBlock/ action |
526
|
|
|
* |
527
|
|
|
* @param string $url |
528
|
|
|
* @return bool |
529
|
|
|
*/ |
530
|
|
|
protected function _checkIsNotEsiUrl($url) { |
531
|
|
|
return $url && ! preg_match('~/turpentine/esi/getBlock/~', $url); |
532
|
|
|
} |
533
|
|
|
|
534
|
|
|
/** |
535
|
|
|
* Check if a URL *is* for the /turpentine/esi/getBlock/ action |
536
|
|
|
* |
537
|
|
|
* @param string $url |
538
|
|
|
* @return bool |
539
|
|
|
*/ |
540
|
|
|
protected function _checkIsEsiUrl($url) { |
541
|
|
|
return ! $this->_checkIsNotEsiUrl($url); |
542
|
|
|
} |
543
|
|
|
|
544
|
|
|
public function hookToControllerActionPreDispatch($observer) { |
545
|
|
View Code Duplication |
if (Mage::helper('turpentine/data')->getVclFix() == 0 && $observer->getEvent()->getControllerAction()->getFullActionName() == 'checkout_cart_add') { |
|
|
|
|
546
|
|
|
Mage::dispatchEvent("add_to_cart_before", array('request' => $observer->getControllerAction()->getRequest())); |
547
|
|
|
} |
548
|
|
View Code Duplication |
if ($observer->getEvent()->getControllerAction()->getFullActionName() == 'wishlist_index_index') { |
|
|
|
|
549
|
|
|
Mage::dispatchEvent('wishlist_index_index_before', array('request' => $observer->getControllerAction()->getRequest())); |
550
|
|
|
} |
551
|
|
|
} |
552
|
|
|
|
553
|
|
|
public function hookToControllerActionPostDispatch($observer) { |
554
|
|
View Code Duplication |
if ($observer->getEvent()->getControllerAction()->getFullActionName() == 'checkout_cart_add') { |
|
|
|
|
555
|
|
|
Mage::dispatchEvent("add_to_cart_after", array('request' => $observer->getControllerAction()->getRequest())); |
556
|
|
|
} |
557
|
|
|
} |
558
|
|
|
|
559
|
|
|
public function hookToAddToCartBefore($observer) { |
560
|
|
|
//Mage::log("hookToAddToCartBefore-antes ".print_r($observer->getEvent()->getRequest()->getParams(),true)." will be added to cart.", null, 'carrinho.log', true); |
561
|
|
|
$key = Mage::getSingleton('core/session')->getFormKey(); |
562
|
|
|
$observer->getEvent()->getRequest()->setParam('form_key', $key); |
563
|
|
|
$request = $observer->getEvent()->getRequest()->getParams(); |
|
|
|
|
564
|
|
|
//Mage::log("hookToAddToCartBefore ".print_r($request,true)." will be added to cart.", null, 'carrinho.log', true); |
565
|
|
|
} |
566
|
|
|
|
567
|
|
|
public function hookToAddToCartAfter($observer) { |
568
|
|
|
$request = $observer->getEvent()->getRequest()->getParams(); |
|
|
|
|
569
|
|
|
//Mage::log("hookToAddToCartAfter ".print_r($request,true)." is added to cart.", null, 'carrinho.log', true); |
570
|
|
|
} |
571
|
|
|
|
572
|
|
|
/** |
573
|
|
|
* Set the form key on the add to wishlist request |
574
|
|
|
* |
575
|
|
|
* @param $observer |
576
|
|
|
* |
577
|
|
|
* @return Nexcessnet_Turpentine_Model_Observer_Esi |
578
|
|
|
*/ |
579
|
|
|
public function hookToAddToWishlistBefore($observer) |
580
|
|
|
{ |
581
|
|
|
$key = Mage::getSingleton('core/session')->getFormKey(); |
582
|
|
|
$observer->getEvent()->getRequest()->setParam('form_key', $key); |
583
|
|
|
return $this; |
584
|
|
|
} |
585
|
|
|
} |
586
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.