PartialHelper.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. <?php
  2. /*
  3. * This file is part of the symfony package.
  4. * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. /**
  10. * PartialHelper.
  11. *
  12. * @package symfony
  13. * @subpackage helper
  14. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  15. * @version SVN: $Id: PartialHelper.php 13463 2008-11-28 15:35:54Z fabien $
  16. */
  17. /**
  18. * Evaluates and echoes a component slot.
  19. * The component name is deduced from the definition of the view.yml
  20. * For a variable to be accessible to the component and its partial,
  21. * it has to be passed in the second argument.
  22. *
  23. * <b>Example:</b>
  24. * <code>
  25. * include_component_slot('sidebar', array('myvar' => 12345));
  26. * </code>
  27. *
  28. * @param string slot name
  29. * @param array variables to be made accessible to the component
  30. *
  31. * @see get_component_slot, include_partial, include_component
  32. */
  33. function include_component_slot($name, $vars = array())
  34. {
  35. echo get_component_slot($name, $vars);
  36. }
  37. /**
  38. * Evaluates and returns a component slot.
  39. * The syntax is similar to the one of include_component_slot.
  40. *
  41. * <b>Example:</b>
  42. * <code>
  43. * echo get_component_slot('sidebar', array('myvar' => 12345));
  44. * </code>
  45. *
  46. * @param string $name slot name
  47. * @param array $vars variables to be made accessible to the component
  48. *
  49. * @return string result of the component execution
  50. * @see get_component_slot, include_partial, include_component
  51. */
  52. function get_component_slot($name, $vars = array())
  53. {
  54. $viewInstance = sfContext::getInstance()->get('view_instance');
  55. if (!$viewInstance->hasComponentSlot($name))
  56. {
  57. // cannot find component slot
  58. throw new sfConfigurationException(sprintf('The component slot "%s" is not set.', $name));
  59. }
  60. if ($componentSlot = $viewInstance->getComponentSlot($name))
  61. {
  62. return get_component($componentSlot[0], $componentSlot[1], $vars);
  63. }
  64. }
  65. /**
  66. * Returns true if component slot exists.
  67. *
  68. * @param string slot name
  69. * @return bool true if component slot exists, false otherwise
  70. */
  71. function has_component_slot($name)
  72. {
  73. $viewInstance = sfContext::getInstance()->get('view_instance');
  74. // check to see if one is defined
  75. if (!$viewInstance->hasComponentSlot($name))
  76. {
  77. return false;
  78. }
  79. // check to see if component slot is empty (null)
  80. if ($viewInstance->getComponentSlot($name))
  81. {
  82. return true;
  83. }
  84. return false;
  85. }
  86. /**
  87. * Evaluates and echoes a component.
  88. * For a variable to be accessible to the component and its partial,
  89. * it has to be passed in the third argument.
  90. *
  91. * <b>Example:</b>
  92. * <code>
  93. * include_component('mymodule', 'mypartial', array('myvar' => 12345));
  94. * </code>
  95. *
  96. * @param string $moduleName module name
  97. * @param string $componentName component name
  98. * @param array $vars variables to be made accessible to the component
  99. *
  100. * @see get_component, include_partial, include_component_slot
  101. */
  102. function include_component($moduleName, $componentName, $vars = array())
  103. {
  104. echo get_component($moduleName, $componentName, $vars);
  105. }
  106. /**
  107. * Evaluates and returns a component.
  108. * The syntax is similar to the one of include_component.
  109. *
  110. * <b>Example:</b>
  111. * <code>
  112. * echo get_component('mymodule', 'mypartial', array('myvar' => 12345));
  113. * </code>
  114. *
  115. * @param string $moduleName module name
  116. * @param string $componentName component name
  117. * @param array $vars variables to be made accessible to the component
  118. *
  119. * @return string result of the component execution
  120. * @see include_component
  121. */
  122. function get_component($moduleName, $componentName, $vars = array())
  123. {
  124. $context = sfContext::getInstance();
  125. $actionName = '_'.$componentName;
  126. $class = sfConfig::get('mod_'.$moduleName.'_partial_view_class', 'sf').'PartialView';
  127. $view = new $class($context, $moduleName, $actionName, '');
  128. $view->setPartialVars($vars);
  129. if ($retval = $view->getCache())
  130. {
  131. return $retval;
  132. }
  133. $allVars = _call_component($moduleName, $componentName, $vars);
  134. if (!is_null($allVars))
  135. {
  136. // render
  137. $view->getAttributeHolder()->add($allVars);
  138. return $view->render();
  139. }
  140. }
  141. /**
  142. * Evaluates and echoes a partial.
  143. * The partial name is composed as follows: 'mymodule/mypartial'.
  144. * The partial file name is _mypartial.php and is looked for in modules/mymodule/templates/.
  145. * If the partial name doesn't include a module name,
  146. * then the partial file is searched for in the caller's template/ directory.
  147. * If the module name is 'global', then the partial file is looked for in myapp/templates/.
  148. * For a variable to be accessible to the partial, it has to be passed in the second argument.
  149. *
  150. * <b>Example:</b>
  151. * <code>
  152. * include_partial('mypartial', array('myvar' => 12345));
  153. * </code>
  154. *
  155. * @param string $templateName partial name
  156. * @param array $vars variables to be made accessible to the partial
  157. *
  158. * @see get_partial, include_component
  159. */
  160. function include_partial($templateName, $vars = array())
  161. {
  162. echo get_partial($templateName, $vars);
  163. }
  164. /**
  165. * Evaluates and returns a partial.
  166. * The syntax is similar to the one of include_partial
  167. *
  168. * <b>Example:</b>
  169. * <code>
  170. * echo get_partial('mypartial', array('myvar' => 12345));
  171. * </code>
  172. *
  173. * @param string $templateName partial name
  174. * @param array $vars variables to be made accessible to the partial
  175. *
  176. * @return string result of the partial execution
  177. * @see include_partial
  178. */
  179. function get_partial($templateName, $vars = array())
  180. {
  181. $context = sfContext::getInstance();
  182. // partial is in another module?
  183. if (false !== $sep = strpos($templateName, '/'))
  184. {
  185. $moduleName = substr($templateName, 0, $sep);
  186. $templateName = substr($templateName, $sep + 1);
  187. }
  188. else
  189. {
  190. $moduleName = $context->getActionStack()->getLastEntry()->getModuleName();
  191. }
  192. $actionName = '_'.$templateName;
  193. $class = sfConfig::get('mod_'.$moduleName.'_partial_view_class', 'sf').'PartialView';
  194. $view = new $class($context, $moduleName, $actionName, '');
  195. $view->setPartialVars($vars);
  196. return $view->render();
  197. }
  198. /**
  199. * Begins the capturing of the slot.
  200. *
  201. * @param string $name slot name
  202. * @param string $value The slot content
  203. *
  204. * @see end_slot
  205. */
  206. function slot($name, $value = null)
  207. {
  208. $context = sfContext::getInstance();
  209. $response = $context->getResponse();
  210. $slot_names = sfConfig::get('symfony.view.slot_names', array());
  211. if (in_array($name, $slot_names))
  212. {
  213. throw new sfCacheException(sprintf('A slot named "%s" is already started.', $name));
  214. }
  215. if (sfConfig::get('sf_logging_enabled'))
  216. {
  217. $context->getEventDispatcher()->notify(new sfEvent(null, 'application.log', array(sprintf('Set slot "%s"', $name))));
  218. }
  219. if (!is_null($value))
  220. {
  221. $response->setSlot($name, $value);
  222. return;
  223. }
  224. $slot_names[] = $name;
  225. $response->setSlot($name, '');
  226. sfConfig::set('symfony.view.slot_names', $slot_names);
  227. ob_start();
  228. ob_implicit_flush(0);
  229. }
  230. /**
  231. * Stops the content capture and save the content in the slot.
  232. *
  233. * @see slot
  234. */
  235. function end_slot()
  236. {
  237. $content = ob_get_clean();
  238. $response = sfContext::getInstance()->getResponse();
  239. $slot_names = sfConfig::get('symfony.view.slot_names', array());
  240. if (!$slot_names)
  241. {
  242. throw new sfCacheException('No slot started.');
  243. }
  244. $name = array_pop($slot_names);
  245. $response->setSlot($name, $content);
  246. sfConfig::set('symfony.view.slot_names', $slot_names);
  247. }
  248. /**
  249. * Returns true if the slot exists.
  250. *
  251. * @param string $name slot name
  252. *
  253. * @return bool true, if the slot exists
  254. * @see get_slot, include_slot
  255. */
  256. function has_slot($name)
  257. {
  258. return array_key_exists($name, sfContext::getInstance()->getResponse()->getSlots());
  259. }
  260. /**
  261. * Evaluates and echoes a slot.
  262. *
  263. * <b>Example:</b>
  264. * <code>
  265. * include_slot('navigation');
  266. * </code>
  267. *
  268. * @param string $name slot name
  269. *
  270. * @see has_slot, get_slot
  271. */
  272. function include_slot($name)
  273. {
  274. return ($v = get_slot($name)) ? print $v : false;
  275. }
  276. /**
  277. * Evaluates and returns a slot.
  278. *
  279. * <b>Example:</b>
  280. * <code>
  281. * echo get_slot('navigation');
  282. * </code>
  283. *
  284. * @param string $name slot name
  285. *
  286. * @return string content of the slot
  287. * @see has_slot, include_slot
  288. */
  289. function get_slot($name)
  290. {
  291. $context = sfContext::getInstance();
  292. $slots = $context->getResponse()->getSlots();
  293. if (sfConfig::get('sf_logging_enabled'))
  294. {
  295. $context->getEventDispatcher()->notify(new sfEvent(null, 'application.log', array(sprintf('Get slot "%s"', $name))));
  296. }
  297. return isset($slots[$name]) ? $slots[$name] : '';
  298. }
  299. function _call_component($moduleName, $componentName, $vars)
  300. {
  301. $context = sfContext::getInstance();
  302. $controller = $context->getController();
  303. if (!$controller->componentExists($moduleName, $componentName))
  304. {
  305. // cannot find component
  306. throw new sfConfigurationException(sprintf('The component does not exist: "%s", "%s".', $moduleName, $componentName));
  307. }
  308. // create an instance of the action
  309. $componentInstance = $controller->getComponent($moduleName, $componentName);
  310. // load component's module config file
  311. require($context->getConfigCache()->checkConfig('modules/'.$moduleName.'/config/module.yml'));
  312. // pass unescaped vars to the component
  313. $componentInstance->getVarHolder()->add(sfOutputEscaper::unescape($vars));
  314. // dispatch component
  315. $componentToRun = 'execute'.ucfirst($componentName);
  316. if (!method_exists($componentInstance, $componentToRun))
  317. {
  318. if (!method_exists($componentInstance, 'execute'))
  319. {
  320. // component not found
  321. throw new sfInitializationException(sprintf('sfComponent initialization failed for module "%s", component "%s".', $moduleName, $componentName));
  322. }
  323. $componentToRun = 'execute';
  324. }
  325. if (sfConfig::get('sf_logging_enabled'))
  326. {
  327. $context->getEventDispatcher()->notify(new sfEvent(null, 'application.log', array(sprintf('Call "%s->%s()'.'"', $moduleName, $componentToRun))));
  328. }
  329. // run component
  330. if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled'))
  331. {
  332. $timer = sfTimerManager::getTimer(sprintf('Component "%s/%s"', $moduleName, $componentName));
  333. }
  334. $retval = $componentInstance->$componentToRun($context->getRequest());
  335. if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled'))
  336. {
  337. $timer->addTime();
  338. }
  339. return sfView::NONE == $retval ? null : $componentInstance->getVarHolder()->getAll();
  340. }