Development

/branches/1.0/lib/helper/PartialHelper.php

You must first sign up to be able to contribute.

root/branches/1.0/lib/helper/PartialHelper.php

Revision 17468, 12.3 kB (checked in by fabien, 6 years ago)

[1.0, 1.1, 1.2, 1.3] fixed cache manager when the cache partial or component is not from the same module as the same action (closes #6265, #5814)

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Rev Date
Line 
1 <?php
2
3 /*
4  * This file is part of the symfony package.
5  * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 /**
12  * PartialHelper.
13  *
14  * @package    symfony
15  * @subpackage helper
16  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17  * @version    SVN: $Id$
18  */
19
20 /**
21  * Evaluates and echoes a component slot.
22  * The component name is deduced from the definition of the view.yml
23  * For a variable to be accessible to the component and its partial,
24  * it has to be passed in the second argument.
25  *
26  * <b>Example:</b>
27  * <code>
28  *  include_component_slot('sidebar', array('myvar' => 12345));
29  * </code>
30  *
31  * @param  string slot name
32  * @param  array variables to be made accessible to the component
33  * @return void
34  * @see    get_component_slot, include_partial, include_component
35  */
36 function include_component_slot($name, $vars = array())
37 {
38   echo get_component_slot($name, $vars);
39 }
40
41 /**
42  * Evaluates and returns a component slot.
43  * The syntax is similar to the one of include_component_slot.
44  *
45  * <b>Example:</b>
46  * <code>
47  *  echo get_component_slot('sidebar', array('myvar' => 12345));
48  * </code>
49  *
50  * @param  string slot name
51  * @param  array variables to be made accessible to the component
52  * @return string result of the component execution
53  * @see    get_component_slot, include_partial, include_component
54  */
55 function get_component_slot($name, $vars = array())
56 {
57   $context = sfContext::getInstance();
58
59   $actionStackEntry = $context->getController()->getActionStack()->getLastEntry();
60   $viewInstance     = $actionStackEntry->getViewInstance();
61
62   if (!$viewInstance->hasComponentSlot($name))
63   {
64     // cannot find component slot
65     $error = 'The component slot "%s" is not set';
66     $error = sprintf($error, $name);
67
68     throw new sfConfigurationException($error);
69   }
70
71   if ($componentSlot = $viewInstance->getComponentSlot($name))
72   {
73     return get_component($componentSlot[0], $componentSlot[1], $vars);
74   }
75 }
76
77 /**
78  * Evaluates and echoes a component.
79  * For a variable to be accessible to the component and its partial,
80  * it has to be passed in the third argument.
81  *
82  * <b>Example:</b>
83  * <code>
84  *  include_component('mymodule', 'mypartial', array('myvar' => 12345));
85  * </code>
86  *
87  * @param  string module name
88  * @param  string component name
89  * @param  array variables to be made accessible to the component
90  * @return void
91  * @see    get_component, include_partial, include_component_slot
92  */
93 function include_component($moduleName, $componentName, $vars = array())
94 {
95   echo get_component($moduleName, $componentName, $vars);
96 }
97
98 /**
99  * Evaluates and returns a component.
100  * The syntax is similar to the one of include_component.
101  *
102  * <b>Example:</b>
103  * <code>
104  *  echo get_component('mymodule', 'mypartial', array('myvar' => 12345));
105  * </code>
106  *
107  * @param  string module name
108  * @param  string component name
109  * @param  array variables to be made accessible to the component
110  * @return string result of the component execution
111  * @see    include_component
112  */
113 function get_component($moduleName, $componentName, $vars = array())
114 {
115   $context = sfContext::getInstance();
116   $actionName = '_'.$componentName;
117
118   // check cache
119   if ($cacheManager = $context->getViewCacheManager())
120   {
121     if ($retval = _get_cache($cacheManager, $moduleName, $actionName, $vars))
122     {
123       return $retval;
124     }
125   }
126
127   $controller = $context->getController();
128
129   if (!$controller->componentExists($moduleName, $componentName))
130   {
131     // cannot find component
132     $error = 'The component does not exist: "%s", "%s"';
133     $error = sprintf($error, $moduleName, $componentName);
134
135     throw new sfConfigurationException($error);
136   }
137
138   // create an instance of the action
139   $componentInstance = $controller->getComponent($moduleName, $componentName);
140
141   // initialize the action
142   if (!$componentInstance->initialize($context))
143   {
144     // component failed to initialize
145     $error = 'Component initialization failed for module "%s", component "%s"';
146     $error = sprintf($error, $moduleName, $componentName);
147
148     throw new sfInitializationException($error);
149   }
150
151   // load component's module config file
152   require(sfConfigCache::getInstance()->checkConfig(sfConfig::get('sf_app_module_dir_name').'/'.$moduleName.'/'.sfConfig::get('sf_app_module_config_dir_name').'/module.yml'));
153
154   $componentInstance->getVarHolder()->add($vars);
155
156   // dispatch component
157   $componentToRun = 'execute'.ucfirst($componentName);
158   if (!method_exists($componentInstance, $componentToRun))
159   {
160     if (!method_exists($componentInstance, 'execute'))
161     {
162       // component not found
163       $error = 'sfComponent initialization failed for module "%s", component "%s"';
164       $error = sprintf($error, $moduleName, $componentName);
165       throw new sfInitializationException($error);
166     }
167
168     $componentToRun = 'execute';
169   }
170
171   if (sfConfig::get('sf_logging_enabled'))
172   {
173     $context->getLogger()->info('{PartialHelper} call "'.$moduleName.'->'.$componentToRun.'()'.'"');
174   }
175
176   // run component
177   if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled'))
178   {
179     $timer = sfTimerManager::getTimer(sprintf('Component "%s/%s"', $moduleName, $componentName));
180   }
181
182   $retval = $componentInstance->$componentToRun();
183
184   if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled'))
185   {
186     $timer->addTime();
187   }
188
189   if ($retval != sfView::NONE)
190   {
191     // render
192     $view = new sfPartialView();
193     $view->initialize($context, $moduleName, $actionName, '');
194
195     $retval = $view->render($componentInstance->getVarHolder()->getAll());
196
197     if ($cacheManager && (!sfConfig::get('sf_lazy_cache_key') || $cacheManager->isActionCacheable($moduleName, $actionName)))
198     {
199       $uri = _get_cache_uri($moduleName, $actionName, $vars);
200       $retval = _set_cache($cacheManager, $uri, $retval);
201     }
202
203     return $retval;
204   }
205 }
206
207 /**
208  * Evaluates and echoes a partial.
209  * The partial name is composed as follows: 'mymodule/mypartial'.
210  * The partial file name is _mypartial.php and is looked for in modules/mymodule/templates/.
211  * If the partial name doesn't include a module name,
212  * then the partial file is searched for in the caller's template/ directory.
213  * If the module name is 'global', then the partial file is looked for in myapp/templates/.
214  * For a variable to be accessible to the partial, it has to be passed in the second argument.
215  *
216  * <b>Example:</b>
217  * <code>
218  *  include_partial('mypartial', array('myvar' => 12345));
219  * </code>
220  *
221  * @param  string partial name
222  * @param  array variables to be made accessible to the partial
223  * @return void
224  * @see    get_partial, include_component
225  */
226 function include_partial($templateName, $vars = array())
227 {
228   echo get_partial($templateName, $vars);
229 }
230
231 /**
232  * Evaluates and returns a partial.
233  * The syntax is similar to the one of include_partial
234  *
235  * <b>Example:</b>
236  * <code>
237  *  echo get_partial('mypartial', array('myvar' => 12345));
238  * </code>
239  *
240  * @param  string partial name
241  * @param  array variables to be made accessible to the partial
242  * @return string result of the partial execution
243  * @see    include_partial
244  */
245 function get_partial($templateName, $vars = array())
246 {
247   $context = sfContext::getInstance();
248
249   // partial is in another module?
250   if (false !== $sep = strpos($templateName, '/'))
251   {
252     $moduleName   = substr($templateName, 0, $sep);
253     $templateName = substr($templateName, $sep + 1);
254   }
255   else
256   {
257     $moduleName = $context->getActionStack()->getLastEntry()->getModuleName();
258   }
259   $actionName = '_'.$templateName;
260
261   if ($cacheManager = $context->getViewCacheManager())
262   {
263     if ($retval = _get_cache($cacheManager, $moduleName, $actionName, $vars))
264     {
265       return $retval;
266     }
267   }
268
269   $view = new sfPartialView();
270   $view->initialize($context, $moduleName, $actionName, '');
271   $retval = $view->render($vars);
272
273   if ($cacheManager && (!sfConfig::get('sf_lazy_cache_key') || $cacheManager->isActionCacheable($moduleName, $actionName)))
274   {
275     $uri = _get_cache_uri($moduleName, $actionName, $vars);
276     $retval = _set_cache($cacheManager, $uri, $retval);
277   }
278
279   return $retval;
280 }
281
282 function _get_cache($cacheManager, $moduleName, $actionName = null, $vars = array())
283 {
284   if (!$cacheManager->isActionCacheable($moduleName, $actionName))
285   {
286     return null;
287   }
288
289   $uri = _get_cache_uri($moduleName, $actionName, $vars);
290   $retval = $cacheManager->get($uri);
291
292   if (sfConfig::get('sf_web_debug'))
293   {
294     $retval = sfWebDebug::getInstance()->decorateContentWithDebug($uri, $retval, false);
295   }
296
297   return $retval;
298 }
299
300 function _get_cache_uri($moduleName, $actionName, & $vars = array())
301 {
302   return '@sf_cache_partial?module='.$moduleName.'&action='.$actionName.'&sf_cache_key='._get_cache_key($vars);
303 }
304
305 function _get_cache_key(& $vars = array())
306 {
307   if (!isset($vars['sf_cache_key']))
308   {
309     if (sfConfig::get('sf_logging_enabled'))
310     {
311       sfContext::getInstance()->getLogger()->info('{PartialHelper} Generate cache key');
312     }
313
314     $vars['sf_cache_key'] = md5(serialize($vars));
315   }
316
317   return $vars['sf_cache_key'];
318 }
319
320 function _set_cache($cacheManager, $uri, $retval)
321 {
322   $saved = $cacheManager->set($retval, $uri);
323
324   if ($saved && sfConfig::get('sf_web_debug'))
325   {
326     $retval = sfWebDebug::getInstance()->decorateContentWithDebug($uri, $retval, true);
327   }
328
329   return $retval;
330 }
331
332 /**
333  * Begins the capturing of the slot.
334  *
335  * @param  string slot name
336  * @return void
337  * @see    end_slot
338  */
339 function slot($name)
340 {
341   $context = sfContext::getInstance();
342   $response = $context->getResponse();
343
344   $slots = $response->getParameter('slots', array(), 'symfony/view/sfView/slot');
345   $slot_names = $response->getParameter('slot_names', array(), 'symfony/view/sfView/slot');
346   if (in_array($name, $slot_names))
347   {
348     throw new sfCacheException(sprintf('A slot named "%s" is already started.', $name));
349   }
350
351   $slot_names[] = $name;
352   $slots[$name] = '';
353
354   $response->setParameter('slots', $slots, 'symfony/view/sfView/slot');
355   $response->setParameter('slot_names', $slot_names, 'symfony/view/sfView/slot');
356
357   if (sfConfig::get('sf_logging_enabled'))
358   {
359     $context->getLogger()->info(sprintf('{PartialHelper} set slot "%s"', $name));
360   }
361
362   ob_start();
363   ob_implicit_flush(0);
364 }
365
366 /**
367  * Stops the content capture and save the content in the slot.
368  *
369  * @return void
370  * @see    slot
371  */
372 function end_slot()
373 {
374   $content = ob_get_clean();
375
376   $response = sfContext::getInstance()->getResponse();
377   $slots = $response->getParameter('slots', array(), 'symfony/view/sfView/slot');
378   $slot_names = $response->getParameter('slot_names', array(), 'symfony/view/sfView/slot');
379   if (!$slot_names)
380   {
381     throw new sfCacheException('No slot started.');
382   }
383
384   $name = array_pop($slot_names);
385   $slots[$name] = $content;
386
387   $response->setParameter('slots', $slots, 'symfony/view/sfView/slot');
388   $response->setParameter('slot_names', $slot_names, 'symfony/view/sfView/slot');
389 }
390
391 /**
392  * Returns true if the slot exists.
393  *
394  * @param  string slot name
395  * @return boolean true, if the slot exists
396  * @see    get_slot, include_slot
397  */
398 function has_slot($name)
399 {
400   $response = sfContext::getInstance()->getResponse();
401   $slots = $response->getParameter('slots', array(), 'symfony/view/sfView/slot');
402
403   return array_key_exists($name, $slots);
404 }
405
406 /**
407  * Evaluates and echoes a slot.
408  *
409  * <b>Example:</b>
410  * <code>
411  *  include_slot('navigation');
412  * </code>
413  *
414  * @param  string slot name
415  * @return void
416  * @see    has_slot, get_slot
417  */
418 function include_slot($name)
419 {
420   $context = sfContext::getInstance();
421   $slots = $context->getResponse()->getParameter('slots', array(), 'symfony/view/sfView/slot');
422
423   if (sfConfig::get('sf_logging_enabled'))
424   {
425     $context->getLogger()->info(sprintf('{PartialHelper} get slot "%s"', $name));
426   }
427
428   if (isset($slots[$name]))
429   {
430     echo $slots[$name];
431
432     return true;
433   }
434   else
435   {
436     return false;
437   }
438 }
439
440 /**
441  * Evaluates and returns a slot.
442  *
443  * <b>Example:</b>
444  * <code>
445  *  echo get_slot('navigation');
446  * </code>
447  *
448  * @param  string slot name
449  * @return string content of the slot
450  * @see    has_slot, include_slot
451  */
452 function get_slot($name)
453 {
454   $context = sfContext::getInstance();
455   $slots = $context->getResponse()->getParameter('slots', array(), 'symfony/view/sfView/slot');
456
457   if (sfConfig::get('sf_logging_enabled'))
458   {
459     $context->getLogger()->info(sprintf('{PartialHelper} get slot "%s"', $name));
460   }
461
462   return isset($slots[$name]) ? $slots[$name] : '';
463 }
464
Note: See TracBrowser for help on using the browser.