File indexing completed on 2024-12-22 05:37:14

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_View
0017  * @subpackage Helper
0018  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0019  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0020  * @version    $Id$
0021  */
0022 
0023 /**
0024  * @see Zend_View_Helper_Navigation_HelperAbstract
0025  */
0026 // require_once 'Zend/View/Helper/Navigation/HelperAbstract.php';
0027 
0028 /**
0029  * Proxy helper for retrieving navigational helpers and forwarding calls
0030  *
0031  * @category   Zend
0032  * @package    Zend_View
0033  * @subpackage Helper
0034  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0035  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0036  * @method Zend_View_Helper_Navigation_Breadcrumbs breadcrumbs
0037  * @method Zend_View_Helper_Navigation_Links links
0038  * @method Zend_View_Helper_Navigation_Menu menu
0039  * @method Zend_View_Helper_Navigation_Sitemap sitemap
0040  */
0041 class Zend_View_Helper_Navigation
0042     extends Zend_View_Helper_Navigation_HelperAbstract
0043 {
0044     /**
0045      * View helper namespace
0046      *
0047      * @var string
0048      */
0049     const NS = 'Zend_View_Helper_Navigation';
0050 
0051     /**
0052      * Default proxy to use in {@link render()}
0053      *
0054      * @var string
0055      */
0056     protected $_defaultProxy = 'menu';
0057 
0058     /**
0059      * Contains references to proxied helpers
0060      *
0061      * @var array
0062      */
0063     protected $_helpers = array();
0064 
0065     /**
0066      * Whether container should be injected when proxying
0067      *
0068      * @var bool
0069      */
0070     protected $_injectContainer = true;
0071 
0072     /**
0073      * Whether ACL should be injected when proxying
0074      *
0075      * @var bool
0076      */
0077     protected $_injectAcl = true;
0078 
0079     /**
0080      * Whether translator should be injected when proxying
0081      *
0082      * @var bool
0083      */
0084     protected $_injectTranslator = true;
0085 
0086     /**
0087      * Helper entry point
0088      *
0089      * @param  Zend_Navigation_Container $container  [optional] container to
0090      *                                               operate on
0091      * @return Zend_View_Helper_Navigation           fluent interface, returns
0092      *                                               self
0093      */
0094     public function navigation(Zend_Navigation_Container $container = null)
0095     {
0096         if (null !== $container) {
0097             $this->setContainer($container);
0098         }
0099 
0100         return $this;
0101     }
0102 
0103     /**
0104      * Magic overload: Proxy to other navigation helpers or the container
0105      *
0106      * Examples of usage from a view script or layout:
0107      * <code>
0108      * // proxy to Menu helper and render container:
0109      * echo $this->navigation()->menu();
0110      *
0111      * // proxy to Breadcrumbs helper and set indentation:
0112      * $this->navigation()->breadcrumbs()->setIndent(8);
0113      *
0114      * // proxy to container and find all pages with 'blog' route:
0115      * $blogPages = $this->navigation()->findAllByRoute('blog');
0116      * </code>
0117      *
0118      * @param  string $method             helper name or method name in
0119      *                                    container
0120      * @param  array  $arguments          [optional] arguments to pass
0121      * @return mixed                      returns what the proxied call returns
0122      * @throws Zend_View_Exception        if proxying to a helper, and the
0123      *                                    helper is not an instance of the
0124      *                                    interface specified in
0125      *                                    {@link findHelper()}
0126      * @throws Zend_Navigation_Exception  if method does not exist in container
0127      */
0128     public function __call($method, array $arguments = array())
0129     {
0130         // check if call should proxy to another helper
0131         if ($helper = $this->findHelper($method, false)) {
0132             return call_user_func_array(array($helper, $method), $arguments);
0133         }
0134 
0135         // default behaviour: proxy call to container
0136         return parent::__call($method, $arguments);
0137     }
0138 
0139     /**
0140      * Returns the helper matching $proxy
0141      *
0142      * The helper must implement the interface
0143      * {@link Zend_View_Helper_Navigation_Helper}.
0144      *
0145      * @param string $proxy                        helper name
0146      * @param bool   $strict                       [optional] whether
0147      *                                             exceptions should be
0148      *                                             thrown if something goes
0149      *                                             wrong. Default is true.
0150      * @return Zend_View_Helper_Navigation_Helper  helper instance
0151      * @throws Zend_Loader_PluginLoader_Exception  if $strict is true and
0152      *                                             helper cannot be found
0153      * @throws Zend_View_Exception                 if $strict is true and
0154      *                                             helper does not implement
0155      *                                             the specified interface
0156      */
0157     public function findHelper($proxy, $strict = true)
0158     {
0159         if (isset($this->_helpers[$proxy])) {
0160             return $this->_helpers[$proxy];
0161         }
0162 
0163         if (!$this->view->getPluginLoader('helper')->getPaths(self::NS)) {
0164             // Add navigation helper path at the beginning
0165             $paths = $this->view->getHelperPaths();
0166             $this->view->setHelperPath(null);
0167             
0168             $this->view->addHelperPath(
0169                     str_replace('_', '/', self::NS),
0170                     self::NS);
0171             
0172             foreach ($paths as $ns => $path) {
0173                 $this->view->addHelperPath($path, $ns);
0174             }
0175         }
0176 
0177         if ($strict) {
0178             $helper = $this->view->getHelper($proxy);
0179         } else {
0180             try {
0181                 $helper = $this->view->getHelper($proxy);
0182             } catch (Zend_Loader_PluginLoader_Exception $e) {
0183                 return null;
0184             }
0185         }
0186 
0187         if (!$helper instanceof Zend_View_Helper_Navigation_Helper) {
0188             if ($strict) {
0189                 // require_once 'Zend/View/Exception.php';
0190                 $e = new Zend_View_Exception(sprintf(
0191                         'Proxy helper "%s" is not an instance of ' .
0192                         'Zend_View_Helper_Navigation_Helper',
0193                         get_class($helper)));
0194                 $e->setView($this->view);
0195                 throw $e;
0196             }
0197 
0198             return null;
0199         }
0200 
0201         $this->_inject($helper);
0202         $this->_helpers[$proxy] = $helper;
0203 
0204         return $helper;
0205     }
0206 
0207     /**
0208      * Injects container, ACL, and translator to the given $helper if this
0209      * helper is configured to do so
0210      *
0211      * @param  Zend_View_Helper_Navigation_Helper $helper  helper instance
0212      * @return void
0213      */
0214     protected function _inject(Zend_View_Helper_Navigation_Helper $helper)
0215     {
0216         if ($this->getInjectContainer() && !$helper->hasContainer()) {
0217             $helper->setContainer($this->getContainer());
0218         }
0219 
0220         if ($this->getInjectAcl()) {
0221             if (!$helper->hasAcl()) {
0222                 $helper->setAcl($this->getAcl());
0223             }
0224             if (!$helper->hasRole()) {
0225                 $helper->setRole($this->getRole());
0226             }
0227         }
0228 
0229         if ($this->getInjectTranslator() && !$helper->hasTranslator()) {
0230             $helper->setTranslator($this->getTranslator());
0231         }
0232     }
0233 
0234     // Accessors:
0235 
0236     /**
0237      * Sets the default proxy to use in {@link render()}
0238      *
0239      * @param  string $proxy                default proxy
0240      * @return Zend_View_Helper_Navigation  fluent interface, returns self
0241      */
0242     public function setDefaultProxy($proxy)
0243     {
0244         $this->_defaultProxy = (string) $proxy;
0245         return $this;
0246     }
0247 
0248     /**
0249      * Returns the default proxy to use in {@link render()}
0250      *
0251      * @return string  the default proxy to use in {@link render()}
0252      */
0253     public function getDefaultProxy()
0254     {
0255         return $this->_defaultProxy;
0256     }
0257 
0258     /**
0259      * Sets whether container should be injected when proxying
0260      *
0261      * @param bool $injectContainer         [optional] whether container should
0262      *                                      be injected when proxying. Default
0263      *                                      is true.
0264      * @return Zend_View_Helper_Navigation  fluent interface, returns self
0265      */
0266     public function setInjectContainer($injectContainer = true)
0267     {
0268         $this->_injectContainer = (bool) $injectContainer;
0269         return $this;
0270     }
0271 
0272     /**
0273      * Returns whether container should be injected when proxying
0274      *
0275      * @return bool  whether container should be injected when proxying
0276      */
0277     public function getInjectContainer()
0278     {
0279         return $this->_injectContainer;
0280     }
0281 
0282     /**
0283      * Sets whether ACL should be injected when proxying
0284      *
0285      * @param  bool $injectAcl              [optional] whether ACL should be
0286      *                                      injected when proxying. Default is
0287      *                                      true.
0288      * @return Zend_View_Helper_Navigation  fluent interface, returns self
0289      */
0290     public function setInjectAcl($injectAcl = true)
0291     {
0292         $this->_injectAcl = (bool) $injectAcl;
0293         return $this;
0294     }
0295 
0296     /**
0297      * Returns whether ACL should be injected when proxying
0298      *
0299      * @return bool  whether ACL should be injected when proxying
0300      */
0301     public function getInjectAcl()
0302     {
0303         return $this->_injectAcl;
0304     }
0305 
0306     /**
0307      * Sets whether translator should be injected when proxying
0308      *
0309      * @param  bool $injectTranslator       [optional] whether translator should
0310      *                                      be injected when proxying. Default
0311      *                                      is true.
0312      * @return Zend_View_Helper_Navigation  fluent interface, returns self
0313      */
0314     public function setInjectTranslator($injectTranslator = true)
0315     {
0316         $this->_injectTranslator = (bool) $injectTranslator;
0317         return $this;
0318     }
0319 
0320     /**
0321      * Returns whether translator should be injected when proxying
0322      *
0323      * @return bool  whether translator should be injected when proxying
0324      */
0325     public function getInjectTranslator()
0326     {
0327         return $this->_injectTranslator;
0328     }
0329 
0330     // Zend_View_Helper_Navigation_Helper:
0331 
0332     /**
0333      * Renders helper
0334      *
0335      * @param  Zend_Navigation_Container $container  [optional] container to
0336      *                                               render. Default is to
0337      *                                               render the container
0338      *                                               registered in the helper.
0339      * @return string                                helper output
0340      * @throws Zend_Loader_PluginLoader_Exception    if helper cannot be found
0341      * @throws Zend_View_Exception                   if helper doesn't implement
0342      *                                               the interface specified in
0343      *                                               {@link findHelper()}
0344      */
0345     public function render(Zend_Navigation_Container $container = null)
0346     {
0347         $helper = $this->findHelper($this->getDefaultProxy());
0348         return $helper->render($container);
0349     }
0350 }