web/lib/Zend/EventManager/ResponseCollection.php
changeset 808 6b6c2214f778
child 1230 68c69c656a2c
equal deleted inserted replaced
807:877f952ae2bd 808:6b6c2214f778
       
     1 <?php
       
     2 /**
       
     3  * Zend Framework
       
     4  *
       
     5  * LICENSE
       
     6  *
       
     7  * This source file is subject to the new BSD license that is bundled
       
     8  * with this package in the file LICENSE.txt.
       
     9  * It is also available through the world-wide-web at this URL:
       
    10  * http://framework.zend.com/license/new-bsd
       
    11  * If you did not receive a copy of the license and are unable to
       
    12  * obtain it through the world-wide-web, please send an email
       
    13  * to license@zend.com so we can send you a copy immediately.
       
    14  *
       
    15  * @category   Zend
       
    16  * @package    Zend_EventManager
       
    17  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
       
    18  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    19  */
       
    20 
       
    21 if (version_compare(PHP_VERSION, '5.3.0', '<')) {
       
    22     class SplStack implements Iterator, ArrayAccess, Countable
       
    23     {
       
    24         /**
       
    25          * Delete items during iteration
       
    26          */
       
    27         const IT_MODE_DELETE = 1;
       
    28 
       
    29         /**
       
    30          * Keep items during iteration
       
    31          */
       
    32         const IT_MODE_KEEP = 0;
       
    33 
       
    34         /**
       
    35          * Mode used when iterating
       
    36          * @var int
       
    37          */
       
    38         protected $mode = self::IT_MODE_KEEP;
       
    39 
       
    40         /**
       
    41          * Count of elements in the stack 
       
    42          * 
       
    43          * @var int
       
    44          */
       
    45         protected $count = 0;
       
    46 
       
    47         /**
       
    48          * Data represented by this stack
       
    49          * 
       
    50          * @var array
       
    51          */
       
    52         protected $data = array();
       
    53 
       
    54         /**
       
    55          * Sorted stack of values
       
    56          * 
       
    57          * @var false|array
       
    58          */
       
    59         protected $stack = false;
       
    60 
       
    61         /**
       
    62          * Set the iterator mode
       
    63          *
       
    64          * Must be set to one of IT_MODE_DELETE or IT_MODE_KEEP
       
    65          * 
       
    66          * @todo   Currently, IteratorMode is ignored, as we use the default (keep); should this be implemented?
       
    67          * @param  int $mode 
       
    68          * @return void
       
    69          * @throws InvalidArgumentException
       
    70          */
       
    71         public function setIteratorMode($mode)
       
    72         {
       
    73             $expected = array(
       
    74                 self::IT_MODE_DELETE => true,
       
    75                 self::IT_MODE_KEEP => true,
       
    76             );
       
    77 
       
    78             if (!isset($expected[$mode])) {
       
    79                 throw new InvalidArgumentException(sprintf('Invalid iterator mode specified ("%s")', $mode));
       
    80             }
       
    81 
       
    82             $this->mode = $mode;
       
    83         }
       
    84 
       
    85         /**
       
    86          * Return last element in the stack
       
    87          * 
       
    88          * @return mixed
       
    89          */
       
    90         public function bottom()
       
    91         {
       
    92             $this->rewind();
       
    93             $value = array_pop($this->stack);
       
    94             array_push($this->stack, $value);
       
    95             return $value;
       
    96         }
       
    97 
       
    98         /**
       
    99          * Countable: return count of items in the stack
       
   100          * 
       
   101          * @return int
       
   102          */
       
   103         public function count()
       
   104         {
       
   105             return $this->count;
       
   106         }
       
   107 
       
   108         /**
       
   109          * Iterator: return current item in the stack
       
   110          * 
       
   111          * @return mixed
       
   112          */
       
   113         public function current()
       
   114         {
       
   115             if (!$this->stack) {
       
   116                 $this->rewind();
       
   117             }
       
   118             return current($this->stack);
       
   119         }
       
   120 
       
   121         /**
       
   122          * Get iteration mode
       
   123          * 
       
   124          * @return int
       
   125          */
       
   126         public function getIteratorMode()
       
   127         {
       
   128             return $this->mode;
       
   129         }
       
   130 
       
   131         /**
       
   132          * Is the stack empty?
       
   133          *
       
   134          * @return bool
       
   135          */
       
   136         public function isEmpty()
       
   137         {
       
   138             return ($this->count === 0);
       
   139         }
       
   140 
       
   141         /**
       
   142          * Iterator: return key of current item in the stack
       
   143          *
       
   144          * @return mixed
       
   145          */
       
   146         public function key()
       
   147         {
       
   148             if (!$this->stack) {
       
   149                 $this->rewind();
       
   150             }
       
   151             return key($this->stack);
       
   152         }
       
   153 
       
   154         /**
       
   155          * Iterator: advance pointer to next item in the stack
       
   156          * 
       
   157          * @return void
       
   158          */
       
   159         public function next()
       
   160         {
       
   161             if (!$this->stack) {
       
   162                 $this->rewind();
       
   163             }
       
   164             return next($this->stack);
       
   165         }
       
   166 
       
   167         /**
       
   168          * ArrayAccess: does an item exist at the specified offset?
       
   169          * 
       
   170          * @param  mixed $index 
       
   171          * @return bool
       
   172          */
       
   173         public function offsetExists($index)
       
   174         {
       
   175             return array_key_exists($index, $this->data);
       
   176         }
       
   177 
       
   178         /**
       
   179          * ArrayAccess: get the item at the specified offset
       
   180          * 
       
   181          * @param  mixed $index 
       
   182          * @return mixed
       
   183          * @throws OutOfRangeException
       
   184          */
       
   185         public function offsetGet($index)
       
   186         {
       
   187             if (!$this->offsetExists($index)) {
       
   188                 throw OutOfRangeException(sprintf('Invalid index ("%s") specified', $index));
       
   189             }
       
   190             return $this->data[$index];
       
   191         }
       
   192 
       
   193         /**
       
   194          * ArrayAccess: add an item at the specified offset
       
   195          * 
       
   196          * @param  mixed $index 
       
   197          * @param  mixed $newval 
       
   198          * @return void
       
   199          */
       
   200         public function offsetSet($index, $newval)
       
   201         {
       
   202             $this->data[$index] = $newval;
       
   203             $this->stack = false;
       
   204             $this->count++;
       
   205         }
       
   206 
       
   207         /**
       
   208          * ArrayAccess: unset the item at the specified offset
       
   209          * 
       
   210          * @param  mixed $index 
       
   211          * @return void
       
   212          * @throws OutOfRangeException
       
   213          */
       
   214         public function offsetUnset($index)
       
   215         {
       
   216             if (!$this->offsetExists($index)) {
       
   217                 throw OutOfRangeException(sprintf('Invalid index ("%s") specified', $index));
       
   218             }
       
   219             unset($this->data[$index]);
       
   220             $this->stack = false;
       
   221             $this->count--;
       
   222         }
       
   223 
       
   224         /**
       
   225          * Pop a node from the end of the stack
       
   226          *
       
   227          * @return mixed
       
   228          * @throws RuntimeException
       
   229          */
       
   230         public function pop()
       
   231         {
       
   232             $val         = array_pop($this->data);
       
   233             $this->stack = false;
       
   234             $this->count--;
       
   235             return $val;
       
   236         }
       
   237 
       
   238         /**
       
   239          * Move the iterator to the previous node
       
   240          *
       
   241          * @todo   Does this need to be implemented?
       
   242          * @return void
       
   243          */
       
   244         public function prev()
       
   245         {
       
   246         }
       
   247 
       
   248         /**
       
   249          * Push an element to the list
       
   250          * 
       
   251          * @param  mixed $value 
       
   252          * @return void
       
   253          */
       
   254         public function push($value)
       
   255         {
       
   256             array_push($this->data, $value);
       
   257             $this->count++;
       
   258             $this->stack  = false;
       
   259         }
       
   260 
       
   261         /**
       
   262          * Iterator: rewind to beginning of stack
       
   263          * 
       
   264          * @return void
       
   265          */
       
   266         public function rewind()
       
   267         {
       
   268             if (is_array($this->stack)) {
       
   269                 return reset($this->stack);
       
   270             }
       
   271             $this->stack = array_reverse($this->data, true);
       
   272         }
       
   273 
       
   274         /**
       
   275          * Serialize the storage
       
   276          *
       
   277          * @return string
       
   278          */
       
   279         public function serialize()
       
   280         {
       
   281             return serialize($this->data);
       
   282         }
       
   283 
       
   284         /**
       
   285          * Shifts a node from the beginning of the list
       
   286          *
       
   287          * @return mixed
       
   288          * @throws RuntimeException
       
   289          */
       
   290         public function shift()
       
   291         {
       
   292             $val         = array_shift($this->data);
       
   293             $this->stack = false;
       
   294             $this->count--;
       
   295             return $val;
       
   296         }
       
   297 
       
   298         /**
       
   299          * Peek at the top node of the stack
       
   300          * 
       
   301          * @return mixed
       
   302          */
       
   303         public function top()
       
   304         {
       
   305             $this->rewind();
       
   306             $value = array_shift($this->stack);
       
   307             array_unshift($this->stack, $value);
       
   308             return $value;
       
   309         }
       
   310 
       
   311         /**
       
   312          * Unserialize the storage
       
   313          *
       
   314          * @param  string
       
   315          * @return void
       
   316          */
       
   317         public function unserialize($serialized)
       
   318         {
       
   319             $this->data  = unserialize($serialized);
       
   320             $this->stack = false;
       
   321         }
       
   322 
       
   323         /**
       
   324          * Unshift a node onto the beginning of the list
       
   325          *
       
   326          * @param  mixed $value
       
   327          * @return void
       
   328          */
       
   329         public function unshift($value)
       
   330         {
       
   331             array_unshift($this->data, $value);
       
   332             $this->count++;
       
   333             $this->stack  = false;
       
   334         }
       
   335         
       
   336         /**
       
   337          * Iterator: is the current pointer valid?
       
   338          *
       
   339          * @return bool
       
   340          */
       
   341         public function valid()
       
   342         {
       
   343             $key = key($this->stack);
       
   344             $var = ($key !== null && $key !== false);
       
   345             return $var;
       
   346         }
       
   347     }
       
   348 }
       
   349 
       
   350 /**
       
   351  * Collection of signal handler return values
       
   352  *
       
   353  * @category   Zend
       
   354  * @package    Zend_EventManager
       
   355  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
       
   356  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
   357  */
       
   358 class Zend_EventManager_ResponseCollection extends SplStack 
       
   359 {
       
   360     protected $stopped = false;
       
   361 
       
   362     /**
       
   363      * Did the last response provided trigger a short circuit of the stack?
       
   364      * 
       
   365      * @return bool
       
   366      */
       
   367     public function stopped()
       
   368     {
       
   369         return $this->stopped;
       
   370     }
       
   371 
       
   372     /**
       
   373      * Mark the collection as stopped (or its opposite)
       
   374      * 
       
   375      * @param  bool $flag 
       
   376      * @return Zend_EventManager_ResponseCollection
       
   377      */
       
   378     public function setStopped($flag)
       
   379     {
       
   380         $this->stopped = (bool) $flag;
       
   381         return $this;
       
   382     }
       
   383 
       
   384     /**
       
   385      * Convenient access to the first handler return value.
       
   386      *
       
   387      * @return mixed The first handler return value
       
   388      */
       
   389     public function first()
       
   390     {
       
   391         return parent::bottom();
       
   392     }
       
   393 
       
   394     /**
       
   395      * Convenient access to the last handler return value.
       
   396      *
       
   397      * If the collection is empty, returns null. Otherwise, returns value
       
   398      * returned by last handler.
       
   399      *
       
   400      * @return mixed The last handler return value
       
   401      */
       
   402     public function last()
       
   403     {
       
   404         if (count($this) === 0) {
       
   405             return null;
       
   406         }
       
   407         return parent::top();
       
   408     }
       
   409 
       
   410     /**
       
   411      * Check if any of the responses match the given value.
       
   412      *
       
   413      * @param  mixed $value The value to look for among responses
       
   414      */
       
   415     public function contains($value)
       
   416     {
       
   417         foreach ($this as $response) {
       
   418             if ($response === $value) {
       
   419                 return true;
       
   420             }
       
   421         }
       
   422         return false;
       
   423     }
       
   424 }