File indexing completed on 2024-05-12 06:03:07

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_Tag
0017  * @subpackage ItemList
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_Tag_Taggable
0025  */
0026 // require_once 'Zend/Tag/Taggable.php';
0027 
0028 /**
0029  * @category   Zend
0030  * @package    Zend_Tag
0031  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0032  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0033  */
0034 class Zend_Tag_ItemList implements Countable, SeekableIterator, ArrayAccess
0035 {
0036     /**
0037      * Items in this list
0038      *
0039      * @var array
0040      */
0041     protected $_items = array();
0042 
0043     /**
0044      * Count all items
0045      *
0046      * @return integer
0047      */
0048     public function count()
0049     {
0050         return count($this->_items);
0051     }
0052 
0053     /**
0054      * Spread values in the items relative to their weight
0055      *
0056      * @param  array $values
0057      * @throws Zend_Tag_Exception When value list is empty
0058      * @return void
0059      */
0060     public function spreadWeightValues(array $values)
0061     {
0062         // Don't allow an empty value list
0063         if (count($values) === 0) {
0064             // require_once 'Zend/Tag/Exception.php';
0065             throw new Zend_Tag_Exception('Value list may not be empty');
0066         }
0067 
0068         // Re-index the array
0069         $values = array_values($values);
0070 
0071         // If just a single value is supplied simply assign it to to all tags
0072         if (count($values) === 1) {
0073             foreach ($this->_items as $item) {
0074                 $item->setParam('weightValue', $values[0]);
0075             }
0076         } else {
0077             // Calculate min- and max-weight
0078             $minWeight = null;
0079             $maxWeight = null;
0080 
0081             foreach ($this->_items as $item) {
0082                 if ($minWeight === null && $maxWeight === null) {
0083                     $minWeight = $item->getWeight();
0084                     $maxWeight = $item->getWeight();
0085                 } else {
0086                     $minWeight = min($minWeight, $item->getWeight());
0087                     $maxWeight = max($maxWeight, $item->getWeight());
0088                 }
0089             }
0090 
0091             // Calculate the thresholds
0092             $steps      = count($values);
0093             $delta      = ($maxWeight - $minWeight) / ($steps - 1);
0094             $thresholds = array();
0095 
0096             for ($i = 0; $i < $steps; $i++) {
0097                 $thresholds[$i] = floor(100 * log(($minWeight + $i * $delta) + 2));
0098             }
0099 
0100             // Then assign the weight values
0101             foreach ($this->_items as $item) {
0102                 $threshold = floor(100 * log($item->getWeight() + 2));
0103 
0104                 for ($i = 0; $i < $steps; $i++) {
0105                     if ($threshold <= $thresholds[$i]) {
0106                         $item->setParam('weightValue', $values[$i]);
0107                         break;
0108                     }
0109                 }
0110             }
0111         }
0112     }
0113 
0114     /**
0115      * Seek to an absolute positio
0116      *
0117      * @param  integer $index
0118      * @throws OutOfBoundsException When the seek position is invalid
0119      * @return void
0120      */
0121     public function seek($index)
0122     {
0123         $this->rewind();
0124         $position = 0;
0125 
0126         while ($position < $index && $this->valid()) {
0127             $this->next();
0128             $position++;
0129         }
0130 
0131         if (!$this->valid()) {
0132             throw new OutOfBoundsException('Invalid seek position');
0133         }
0134     }
0135 
0136     /**
0137      * Return the current element
0138      *
0139      * @return mixed
0140      */
0141     public function current()
0142     {
0143         return current($this->_items);
0144     }
0145 
0146     /**
0147      * Move forward to next element
0148      *
0149      * @return mixed
0150      */
0151     public function next()
0152     {
0153         return next($this->_items);
0154     }
0155 
0156     /**
0157      * Return the key of the current element
0158      *
0159      * @return mixed
0160      */
0161     public function key()
0162     {
0163         return key($this->_items);
0164     }
0165 
0166     /**
0167      * Check if there is a current element after calls to rewind() or next()
0168      *
0169      * @return boolean
0170      */
0171     public function valid()
0172     {
0173         return ($this->current() !== false);
0174     }
0175 
0176     /**
0177      * Rewind the Iterator to the first element
0178      *
0179      * @return void
0180      */
0181     public function rewind()
0182     {
0183         reset($this->_items);
0184     }
0185 
0186     /**
0187      * Check if an offset exists
0188      *
0189      * @param  mixed $offset
0190      * @return boolean
0191      */
0192     public function offsetExists($offset) {
0193         return array_key_exists($offset, $this->_items);
0194     }
0195 
0196     /**
0197      * Get the value of an offset
0198      *
0199      * @param  mixed $offset
0200      * @return Zend_Tag_Taggable
0201      */
0202     public function offsetGet($offset) {
0203         return $this->_items[$offset];
0204     }
0205 
0206     /**
0207      * Append a new item
0208      *
0209      * @param  mixed          $offset
0210      * @param  Zend_Tag_Taggable $item
0211      * @throws OutOfBoundsException When item does not implement Zend_Tag_Taggable
0212      * @return void
0213      */
0214     public function offsetSet($offset, $item) {
0215         // We need to make that check here, as the method signature must be
0216         // compatible with ArrayAccess::offsetSet()
0217         if (!($item instanceof Zend_Tag_Taggable)) {
0218             // require_once 'Zend/Tag/Exception.php';
0219             throw new Zend_Tag_Exception('Item must implement Zend_Tag_Taggable');
0220         }
0221 
0222         if ($offset === null) {
0223             $this->_items[] = $item;
0224         } else {
0225             $this->_items[$offset] = $item;
0226         }
0227     }
0228 
0229     /**
0230      * Unset an item
0231      *
0232      * @param  mixed $offset
0233      * @return void
0234      */
0235     public function offsetUnset($offset) {
0236         unset($this->_items[$offset]);
0237     }
0238 }