File indexing completed on 2024-12-29 05:27:31

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_Controller
0017  * @subpackage Zend_Controller_Action
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  * @category   Zend
0025  * @package    Zend_Controller
0026  * @subpackage Zend_Controller_Action
0027  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0028  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0029  */
0030 class Zend_Controller_Action_HelperBroker_PriorityStack implements IteratorAggregate, ArrayAccess, Countable
0031 {
0032 
0033     protected $_helpersByPriority = array();
0034     protected $_helpersByNameRef  = array();
0035     protected $_nextDefaultPriority = 1;
0036 
0037     /**
0038      * Magic property overloading for returning helper by name
0039      *
0040      * @param string $helperName    The helper name
0041      * @return Zend_Controller_Action_Helper_Abstract
0042      */
0043     public function __get($helperName)
0044     {
0045         if (!array_key_exists($helperName, $this->_helpersByNameRef)) {
0046             return false;
0047         }
0048 
0049         return $this->_helpersByNameRef[$helperName];
0050     }
0051 
0052     /**
0053      * Magic property overloading for returning if helper is set by name
0054      *
0055      * @param string $helperName    The helper name
0056      * @return Zend_Controller_Action_Helper_Abstract
0057      */
0058     public function __isset($helperName)
0059     {
0060         return array_key_exists($helperName, $this->_helpersByNameRef);
0061     }
0062 
0063     /**
0064      * Magic property overloading for unsetting if helper is exists by name
0065      *
0066      * @param string $helperName    The helper name
0067      * @return Zend_Controller_Action_Helper_Abstract
0068      */
0069     public function __unset($helperName)
0070     {
0071         return $this->offsetUnset($helperName);
0072     }
0073 
0074     /**
0075      * push helper onto the stack
0076      *
0077      * @param Zend_Controller_Action_Helper_Abstract $helper
0078      * @return Zend_Controller_Action_HelperBroker_PriorityStack
0079      */
0080     public function push(Zend_Controller_Action_Helper_Abstract $helper)
0081     {
0082         $this->offsetSet($this->getNextFreeHigherPriority(), $helper);
0083         return $this;
0084     }
0085 
0086     /**
0087      * Return something iterable
0088      *
0089      * @return array
0090      */
0091     public function getIterator()
0092     {
0093         return new ArrayObject($this->_helpersByPriority);
0094     }
0095 
0096     /**
0097      * offsetExists()
0098      *
0099      * @param int|string $priorityOrHelperName
0100      * @return Zend_Controller_Action_HelperBroker_PriorityStack
0101      */
0102     public function offsetExists($priorityOrHelperName)
0103     {
0104         if (is_string($priorityOrHelperName)) {
0105             return array_key_exists($priorityOrHelperName, $this->_helpersByNameRef);
0106         } else {
0107             return array_key_exists($priorityOrHelperName, $this->_helpersByPriority);
0108         }
0109     }
0110 
0111     /**
0112      * offsetGet()
0113      *
0114      * @param int|string $priorityOrHelperName
0115      * @return Zend_Controller_Action_HelperBroker_PriorityStack
0116      */
0117     public function offsetGet($priorityOrHelperName)
0118     {
0119         if (!$this->offsetExists($priorityOrHelperName)) {
0120             // require_once 'Zend/Controller/Action/Exception.php';
0121             throw new Zend_Controller_Action_Exception('A helper with priority ' . $priorityOrHelperName . ' does not exist.');
0122         }
0123 
0124         if (is_string($priorityOrHelperName)) {
0125             return $this->_helpersByNameRef[$priorityOrHelperName];
0126         } else {
0127             return $this->_helpersByPriority[$priorityOrHelperName];
0128         }
0129     }
0130 
0131     /**
0132      * offsetSet()
0133      *
0134      * @param int $priority
0135      * @param Zend_Controller_Action_Helper_Abstract $helper
0136      * @return Zend_Controller_Action_HelperBroker_PriorityStack
0137      */
0138     public function offsetSet($priority, $helper)
0139     {
0140         $priority = (int) $priority;
0141 
0142         if (!$helper instanceof Zend_Controller_Action_Helper_Abstract) {
0143             // require_once 'Zend/Controller/Action/Exception.php';
0144             throw new Zend_Controller_Action_Exception('$helper must extend Zend_Controller_Action_Helper_Abstract.');
0145         }
0146 
0147         if (array_key_exists($helper->getName(), $this->_helpersByNameRef)) {
0148             // remove any object with the same name to retain BC compailitbility
0149             // @todo At ZF 2.0 time throw an exception here.
0150             $this->offsetUnset($helper->getName());
0151         }
0152 
0153         if (array_key_exists($priority, $this->_helpersByPriority)) {
0154             $priority = $this->getNextFreeHigherPriority($priority);  // ensures LIFO
0155             trigger_error("A helper with the same priority already exists, reassigning to $priority", E_USER_WARNING);
0156         }
0157 
0158         $this->_helpersByPriority[$priority] = $helper;
0159         $this->_helpersByNameRef[$helper->getName()] = $helper;
0160 
0161         if ($priority == ($nextFreeDefault = $this->getNextFreeHigherPriority($this->_nextDefaultPriority))) {
0162             $this->_nextDefaultPriority = $nextFreeDefault;
0163         }
0164 
0165         krsort($this->_helpersByPriority);  // always make sure priority and LIFO are both enforced
0166         return $this;
0167     }
0168 
0169     /**
0170      * offsetUnset()
0171      *
0172      * @param int|string $priorityOrHelperName Priority integer or the helper name
0173      * @return Zend_Controller_Action_HelperBroker_PriorityStack
0174      */
0175     public function offsetUnset($priorityOrHelperName)
0176     {
0177         if (!$this->offsetExists($priorityOrHelperName)) {
0178             // require_once 'Zend/Controller/Action/Exception.php';
0179             throw new Zend_Controller_Action_Exception('A helper with priority or name ' . $priorityOrHelperName . ' does not exist.');
0180         }
0181 
0182         if (is_string($priorityOrHelperName)) {
0183             $helperName = $priorityOrHelperName;
0184             $helper = $this->_helpersByNameRef[$helperName];
0185             $priority = array_search($helper, $this->_helpersByPriority, true);
0186         } else {
0187             $priority = $priorityOrHelperName;
0188             $helperName = $this->_helpersByPriority[$priorityOrHelperName]->getName();
0189         }
0190 
0191         unset($this->_helpersByNameRef[$helperName]);
0192         unset($this->_helpersByPriority[$priority]);
0193         return $this;
0194     }
0195 
0196     /**
0197      * return the count of helpers
0198      *
0199      * @return int
0200      */
0201     public function count()
0202     {
0203         return count($this->_helpersByPriority);
0204     }
0205 
0206     /**
0207      * Find the next free higher priority.  If an index is given, it will
0208      * find the next free highest priority after it.
0209      *
0210      * @param int $indexPriority OPTIONAL
0211      * @return int
0212      */
0213     public function getNextFreeHigherPriority($indexPriority = null)
0214     {
0215         if ($indexPriority == null) {
0216             $indexPriority = $this->_nextDefaultPriority;
0217         }
0218 
0219         $priorities = array_keys($this->_helpersByPriority);
0220 
0221         while (in_array($indexPriority, $priorities)) {
0222             $indexPriority++;
0223         }
0224 
0225         return $indexPriority;
0226     }
0227 
0228     /**
0229      * Find the next free lower priority.  If an index is given, it will
0230      * find the next free lower priority before it.
0231      *
0232      * @param int $indexPriority
0233      * @return int
0234      */
0235     public function getNextFreeLowerPriority($indexPriority = null)
0236     {
0237         if ($indexPriority == null) {
0238             $indexPriority = $this->_nextDefaultPriority;
0239         }
0240 
0241         $priorities = array_keys($this->_helpersByPriority);
0242 
0243         while (in_array($indexPriority, $priorities)) {
0244             $indexPriority--;
0245         }
0246 
0247         return $indexPriority;
0248     }
0249 
0250     /**
0251      * return the highest priority
0252      *
0253      * @return int
0254      */
0255     public function getHighestPriority()
0256     {
0257         return max(array_keys($this->_helpersByPriority));
0258     }
0259 
0260     /**
0261      * return the lowest priority
0262      *
0263      * @return int
0264      */
0265     public function getLowestPriority()
0266     {
0267         return min(array_keys($this->_helpersByPriority));
0268     }
0269 
0270     /**
0271      * return the helpers referenced by name
0272      *
0273      * @return array
0274      */
0275     public function getHelpersByName()
0276     {
0277         return $this->_helpersByNameRef;
0278     }
0279 
0280 }