/library/Zend/View/Helper/Navigation.php

https://github.com/zucchi/zf2 · PHP · 343 lines · 131 code · 33 blank · 179 comment · 16 complexity · a762c26bcd857749283f618fde79a8a9 MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. * @package Zend_View
  9. */
  10. namespace Zend\View\Helper;
  11. use Zend\Navigation\AbstractContainer;
  12. use Zend\ServiceManager\ServiceLocatorAwareInterface;
  13. use Zend\View\Exception;
  14. use Zend\View\Helper\Navigation\AbstractHelper as AbstractNavigationHelper;
  15. use Zend\View\Helper\Navigation\HelperInterface as NavigationHelper;
  16. /**
  17. * Proxy helper for retrieving navigational helpers and forwarding calls
  18. *
  19. * @category Zend
  20. * @package Zend_View
  21. * @subpackage Helper
  22. */
  23. class Navigation extends AbstractNavigationHelper
  24. {
  25. /**
  26. * View helper namespace
  27. *
  28. * @var string
  29. */
  30. const NS = 'Zend\View\Helper\Navigation';
  31. /**
  32. * @var Navigation\PluginManager
  33. */
  34. protected $plugins;
  35. /**
  36. * Default proxy to use in {@link render()}
  37. *
  38. * @var string
  39. */
  40. protected $defaultProxy = 'menu';
  41. /**
  42. * Indicates whether or not a given helper has been injected
  43. *
  44. * @var array
  45. */
  46. protected $injected = array();
  47. /**
  48. * Whether container should be injected when proxying
  49. *
  50. * @var bool
  51. */
  52. protected $injectContainer = true;
  53. /**
  54. * Whether ACL should be injected when proxying
  55. *
  56. * @var bool
  57. */
  58. protected $injectAcl = true;
  59. /**
  60. * Whether translator should be injected when proxying
  61. *
  62. * @var bool
  63. */
  64. protected $injectTranslator = true;
  65. /**
  66. * Helper entry point
  67. *
  68. * @param string|AbstractContainer $container container to operate on
  69. * @return Navigation
  70. */
  71. public function __invoke($container = null)
  72. {
  73. if (null !== $container) {
  74. $this->setContainer($container);
  75. }
  76. return $this;
  77. }
  78. /**
  79. * Magic overload: Proxy to other navigation helpers or the container
  80. *
  81. * Examples of usage from a view script or layout:
  82. * <code>
  83. * // proxy to Menu helper and render container:
  84. * echo $this->navigation()->menu();
  85. *
  86. * // proxy to Breadcrumbs helper and set indentation:
  87. * $this->navigation()->breadcrumbs()->setIndent(8);
  88. *
  89. * // proxy to container and find all pages with 'blog' route:
  90. * $blogPages = $this->navigation()->findAllByRoute('blog');
  91. * </code>
  92. *
  93. * @param string $method helper name or method name in
  94. * container
  95. * @param array $arguments [optional] arguments to pass
  96. * @return mixed returns what the proxied call returns
  97. * @throws \Zend\View\Exception\ExceptionInterface if proxying to a helper, and the
  98. * helper is not an instance of the
  99. * interface specified in
  100. * {@link findHelper()}
  101. * @throws \Zend\Navigation\Exception\ExceptionInterface if method does not exist in container
  102. */
  103. public function __call($method, array $arguments = array())
  104. {
  105. // check if call should proxy to another helper
  106. $helper = $this->findHelper($method, false);
  107. if ($helper) {
  108. if ($helper instanceof ServiceLocatorAwareInterface && $this->getServiceLocator()) {
  109. $helper->setServiceLocator($this->getServiceLocator());
  110. }
  111. return call_user_func_array($helper, $arguments);
  112. }
  113. // default behaviour: proxy call to container
  114. return parent::__call($method, $arguments);
  115. }
  116. /**
  117. * Set manager for retrieving navigation helpers
  118. *
  119. * @param Navigation\PluginManager $plugins
  120. * @return Navigation
  121. */
  122. public function setPluginManager(Navigation\PluginManager $plugins)
  123. {
  124. $renderer = $this->getView();
  125. if ($renderer) {
  126. $plugins->setRenderer($renderer);
  127. }
  128. $this->plugins = $plugins;
  129. return $this;
  130. }
  131. /**
  132. * Retrieve plugin loader for navigation helpers
  133. *
  134. * Lazy-loads an instance of Navigation\HelperLoader if none currently
  135. * registered.
  136. *
  137. * @return Navigation\PluginManager
  138. */
  139. public function getPluginManager()
  140. {
  141. if (null === $this->plugins) {
  142. $this->setPluginManager(new Navigation\PluginManager());
  143. }
  144. return $this->plugins;
  145. }
  146. /**
  147. * Returns the helper matching $proxy
  148. *
  149. * The helper must implement the interface
  150. * {@link Zend\View\Helper\Navigation\Helper}.
  151. *
  152. * @param string $proxy helper name
  153. * @param bool $strict [optional] whether
  154. * exceptions should be
  155. * thrown if something goes
  156. * wrong. Default is true.
  157. * @return \Zend\View\Helper\Navigation\HelperInterface helper instance
  158. * @throws Exception\RuntimeException if $strict is true and
  159. * helper cannot be found
  160. */
  161. public function findHelper($proxy, $strict = true)
  162. {
  163. $plugins = $this->getPluginManager();
  164. if (!$plugins->has($proxy)) {
  165. if ($strict) {
  166. throw new Exception\RuntimeException(sprintf(
  167. 'Failed to find plugin for %s',
  168. $proxy
  169. ));
  170. }
  171. return false;
  172. }
  173. $helper = $plugins->get($proxy);
  174. $class = get_class($helper);
  175. if (!isset($this->injected[$class])) {
  176. $this->inject($helper);
  177. $this->injected[$class] = true;
  178. }
  179. return $helper;
  180. }
  181. /**
  182. * Injects container, ACL, and translator to the given $helper if this
  183. * helper is configured to do so
  184. *
  185. * @param NavigationHelper $helper helper instance
  186. * @return void
  187. */
  188. protected function inject(NavigationHelper $helper)
  189. {
  190. if ($this->getInjectContainer() && !$helper->hasContainer()) {
  191. $helper->setContainer($this->getContainer());
  192. }
  193. if ($this->getInjectAcl()) {
  194. if (!$helper->hasAcl()) {
  195. $helper->setAcl($this->getAcl());
  196. }
  197. if (!$helper->hasRole()) {
  198. $helper->setRole($this->getRole());
  199. }
  200. }
  201. if ($this->getInjectTranslator() && !$helper->hasTranslator()) {
  202. $helper->setTranslator(
  203. $this->getTranslator(), $this->getTranslatorTextDomain()
  204. );
  205. }
  206. }
  207. // Accessors:
  208. /**
  209. * Sets the default proxy to use in {@link render()}
  210. *
  211. * @param string $proxy default proxy
  212. * @return \Zend\View\Helper\Navigation fluent interface, returns self
  213. */
  214. public function setDefaultProxy($proxy)
  215. {
  216. $this->defaultProxy = (string) $proxy;
  217. return $this;
  218. }
  219. /**
  220. * Returns the default proxy to use in {@link render()}
  221. *
  222. * @return string the default proxy to use in {@link render()}
  223. */
  224. public function getDefaultProxy()
  225. {
  226. return $this->defaultProxy;
  227. }
  228. /**
  229. * Sets whether container should be injected when proxying
  230. *
  231. * @param bool $injectContainer [optional] whether container should
  232. * be injected when proxying. Default
  233. * is true.
  234. * @return \Zend\View\Helper\Navigation fluent interface, returns self
  235. */
  236. public function setInjectContainer($injectContainer = true)
  237. {
  238. $this->injectContainer = (bool) $injectContainer;
  239. return $this;
  240. }
  241. /**
  242. * Returns whether container should be injected when proxying
  243. *
  244. * @return bool whether container should be injected when proxying
  245. */
  246. public function getInjectContainer()
  247. {
  248. return $this->injectContainer;
  249. }
  250. /**
  251. * Sets whether ACL should be injected when proxying
  252. *
  253. * @param bool $injectAcl [optional] whether ACL should be
  254. * injected when proxying. Default is
  255. * true.
  256. * @return \Zend\View\Helper\Navigation fluent interface, returns self
  257. */
  258. public function setInjectAcl($injectAcl = true)
  259. {
  260. $this->injectAcl = (bool) $injectAcl;
  261. return $this;
  262. }
  263. /**
  264. * Returns whether ACL should be injected when proxying
  265. *
  266. * @return bool whether ACL should be injected when proxying
  267. */
  268. public function getInjectAcl()
  269. {
  270. return $this->injectAcl;
  271. }
  272. /**
  273. * Sets whether translator should be injected when proxying
  274. *
  275. * @param bool $injectTranslator [optional] whether translator should
  276. * be injected when proxying. Default
  277. * is true.
  278. * @return Navigation fluent interface, returns self
  279. */
  280. public function setInjectTranslator($injectTranslator = true)
  281. {
  282. $this->injectTranslator = (bool) $injectTranslator;
  283. return $this;
  284. }
  285. /**
  286. * Returns whether translator should be injected when proxying
  287. *
  288. * @return bool whether translator should be injected when proxying
  289. */
  290. public function getInjectTranslator()
  291. {
  292. return $this->injectTranslator;
  293. }
  294. // Zend\View\Helper\Navigation\Helper:
  295. /**
  296. * Renders helper
  297. *
  298. * @param \Zend\Navigation\AbstractContainer $container [optional] container to
  299. * render. Default is to
  300. * render the container
  301. * registered in the helper.
  302. * @return string helper output
  303. * @throws Exception\RuntimeException if helper cannot be found
  304. */
  305. public function render($container = null)
  306. {
  307. $helper = $this->findHelper($this->getDefaultProxy());
  308. return $helper->render($container);
  309. }
  310. }