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 }