425 lines
10 KiB
PHP
425 lines
10 KiB
PHP
<?php
|
|
/**
|
|
* Zend Framework
|
|
*
|
|
* LICENSE
|
|
*
|
|
* This source file is subject to the new BSD license that is bundled
|
|
* with this package in the file LICENSE.txt.
|
|
* It is also available through the world-wide-web at this URL:
|
|
* http://framework.zend.com/license/new-bsd
|
|
* If you did not receive a copy of the license and are unable to
|
|
* obtain it through the world-wide-web, please send an email
|
|
* to license@zend.com so we can send you a copy immediately.
|
|
*
|
|
* @category Zend
|
|
* @package Zend_EventManager
|
|
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
|
* @license http://framework.zend.com/license/new-bsd New BSD License
|
|
*/
|
|
|
|
if (version_compare(PHP_VERSION, '5.3.0', '<')) {
|
|
class SplStack implements Iterator, ArrayAccess, Countable
|
|
{
|
|
/**
|
|
* Delete items during iteration
|
|
*/
|
|
const IT_MODE_DELETE = 1;
|
|
|
|
/**
|
|
* Keep items during iteration
|
|
*/
|
|
const IT_MODE_KEEP = 0;
|
|
|
|
/**
|
|
* Mode used when iterating
|
|
* @var int
|
|
*/
|
|
protected $mode = self::IT_MODE_KEEP;
|
|
|
|
/**
|
|
* Count of elements in the stack
|
|
*
|
|
* @var int
|
|
*/
|
|
protected $count = 0;
|
|
|
|
/**
|
|
* Data represented by this stack
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $data = array();
|
|
|
|
/**
|
|
* Sorted stack of values
|
|
*
|
|
* @var false|array
|
|
*/
|
|
protected $stack = false;
|
|
|
|
/**
|
|
* Set the iterator mode
|
|
*
|
|
* Must be set to one of IT_MODE_DELETE or IT_MODE_KEEP
|
|
*
|
|
* @todo Currently, IteratorMode is ignored, as we use the default (keep); should this be implemented?
|
|
* @param int $mode
|
|
* @return void
|
|
* @throws InvalidArgumentException
|
|
*/
|
|
public function setIteratorMode($mode)
|
|
{
|
|
$expected = array(
|
|
self::IT_MODE_DELETE => true,
|
|
self::IT_MODE_KEEP => true,
|
|
);
|
|
|
|
if (!isset($expected[$mode])) {
|
|
throw new InvalidArgumentException(sprintf('Invalid iterator mode specified ("%s")', $mode));
|
|
}
|
|
|
|
$this->mode = $mode;
|
|
}
|
|
|
|
/**
|
|
* Return last element in the stack
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function bottom()
|
|
{
|
|
$this->rewind();
|
|
$value = array_pop($this->stack);
|
|
array_push($this->stack, $value);
|
|
return $value;
|
|
}
|
|
|
|
/**
|
|
* Countable: return count of items in the stack
|
|
*
|
|
* @return int
|
|
*/
|
|
public function count()
|
|
{
|
|
return $this->count;
|
|
}
|
|
|
|
/**
|
|
* Iterator: return current item in the stack
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function current()
|
|
{
|
|
if (!$this->stack) {
|
|
$this->rewind();
|
|
}
|
|
return current($this->stack);
|
|
}
|
|
|
|
/**
|
|
* Get iteration mode
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getIteratorMode()
|
|
{
|
|
return $this->mode;
|
|
}
|
|
|
|
/**
|
|
* Is the stack empty?
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isEmpty()
|
|
{
|
|
return ($this->count === 0);
|
|
}
|
|
|
|
/**
|
|
* Iterator: return key of current item in the stack
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function key()
|
|
{
|
|
if (!$this->stack) {
|
|
$this->rewind();
|
|
}
|
|
return key($this->stack);
|
|
}
|
|
|
|
/**
|
|
* Iterator: advance pointer to next item in the stack
|
|
*
|
|
* @return void
|
|
*/
|
|
public function next()
|
|
{
|
|
if (!$this->stack) {
|
|
$this->rewind();
|
|
}
|
|
return next($this->stack);
|
|
}
|
|
|
|
/**
|
|
* ArrayAccess: does an item exist at the specified offset?
|
|
*
|
|
* @param mixed $index
|
|
* @return bool
|
|
*/
|
|
public function offsetExists($index)
|
|
{
|
|
return array_key_exists($index, $this->data);
|
|
}
|
|
|
|
/**
|
|
* ArrayAccess: get the item at the specified offset
|
|
*
|
|
* @param mixed $index
|
|
* @return mixed
|
|
* @throws OutOfRangeException
|
|
*/
|
|
public function offsetGet($index)
|
|
{
|
|
if (!$this->offsetExists($index)) {
|
|
throw OutOfRangeException(sprintf('Invalid index ("%s") specified', $index));
|
|
}
|
|
return $this->data[$index];
|
|
}
|
|
|
|
/**
|
|
* ArrayAccess: add an item at the specified offset
|
|
*
|
|
* @param mixed $index
|
|
* @param mixed $newval
|
|
* @return void
|
|
*/
|
|
public function offsetSet($index, $newval)
|
|
{
|
|
$this->data[$index] = $newval;
|
|
$this->stack = false;
|
|
$this->count++;
|
|
}
|
|
|
|
/**
|
|
* ArrayAccess: unset the item at the specified offset
|
|
*
|
|
* @param mixed $index
|
|
* @return void
|
|
* @throws OutOfRangeException
|
|
*/
|
|
public function offsetUnset($index)
|
|
{
|
|
if (!$this->offsetExists($index)) {
|
|
throw OutOfRangeException(sprintf('Invalid index ("%s") specified', $index));
|
|
}
|
|
unset($this->data[$index]);
|
|
$this->stack = false;
|
|
$this->count--;
|
|
}
|
|
|
|
/**
|
|
* Pop a node from the end of the stack
|
|
*
|
|
* @return mixed
|
|
* @throws RuntimeException
|
|
*/
|
|
public function pop()
|
|
{
|
|
$val = array_pop($this->data);
|
|
$this->stack = false;
|
|
$this->count--;
|
|
return $val;
|
|
}
|
|
|
|
/**
|
|
* Move the iterator to the previous node
|
|
*
|
|
* @todo Does this need to be implemented?
|
|
* @return void
|
|
*/
|
|
public function prev()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Push an element to the list
|
|
*
|
|
* @param mixed $value
|
|
* @return void
|
|
*/
|
|
public function push($value)
|
|
{
|
|
array_push($this->data, $value);
|
|
$this->count++;
|
|
$this->stack = false;
|
|
}
|
|
|
|
/**
|
|
* Iterator: rewind to beginning of stack
|
|
*
|
|
* @return void
|
|
*/
|
|
public function rewind()
|
|
{
|
|
if (is_array($this->stack)) {
|
|
return reset($this->stack);
|
|
}
|
|
$this->stack = array_reverse($this->data, true);
|
|
}
|
|
|
|
/**
|
|
* Serialize the storage
|
|
*
|
|
* @return string
|
|
*/
|
|
public function serialize()
|
|
{
|
|
return serialize($this->data);
|
|
}
|
|
|
|
/**
|
|
* Shifts a node from the beginning of the list
|
|
*
|
|
* @return mixed
|
|
* @throws RuntimeException
|
|
*/
|
|
public function shift()
|
|
{
|
|
$val = array_shift($this->data);
|
|
$this->stack = false;
|
|
$this->count--;
|
|
return $val;
|
|
}
|
|
|
|
/**
|
|
* Peek at the top node of the stack
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function top()
|
|
{
|
|
$this->rewind();
|
|
$value = array_shift($this->stack);
|
|
array_unshift($this->stack, $value);
|
|
return $value;
|
|
}
|
|
|
|
/**
|
|
* Unserialize the storage
|
|
*
|
|
* @param string
|
|
* @return void
|
|
*/
|
|
public function unserialize($serialized)
|
|
{
|
|
$this->data = unserialize($serialized);
|
|
$this->stack = false;
|
|
}
|
|
|
|
/**
|
|
* Unshift a node onto the beginning of the list
|
|
*
|
|
* @param mixed $value
|
|
* @return void
|
|
*/
|
|
public function unshift($value)
|
|
{
|
|
array_unshift($this->data, $value);
|
|
$this->count++;
|
|
$this->stack = false;
|
|
}
|
|
|
|
/**
|
|
* Iterator: is the current pointer valid?
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function valid()
|
|
{
|
|
$key = key($this->stack);
|
|
$var = ($key !== null && $key !== false);
|
|
return $var;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Collection of signal handler return values
|
|
*
|
|
* @category Zend
|
|
* @package Zend_EventManager
|
|
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
|
* @license http://framework.zend.com/license/new-bsd New BSD License
|
|
*/
|
|
class Zend_EventManager_ResponseCollection extends SplStack
|
|
{
|
|
protected $stopped = false;
|
|
|
|
/**
|
|
* Did the last response provided trigger a short circuit of the stack?
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function stopped()
|
|
{
|
|
return $this->stopped;
|
|
}
|
|
|
|
/**
|
|
* Mark the collection as stopped (or its opposite)
|
|
*
|
|
* @param bool $flag
|
|
* @return Zend_EventManager_ResponseCollection
|
|
*/
|
|
public function setStopped($flag)
|
|
{
|
|
$this->stopped = (bool) $flag;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Convenient access to the first handler return value.
|
|
*
|
|
* @return mixed The first handler return value
|
|
*/
|
|
public function first()
|
|
{
|
|
return parent::bottom();
|
|
}
|
|
|
|
/**
|
|
* Convenient access to the last handler return value.
|
|
*
|
|
* If the collection is empty, returns null. Otherwise, returns value
|
|
* returned by last handler.
|
|
*
|
|
* @return mixed The last handler return value
|
|
*/
|
|
public function last()
|
|
{
|
|
if (count($this) === 0) {
|
|
return null;
|
|
}
|
|
return parent::top();
|
|
}
|
|
|
|
/**
|
|
* Check if any of the responses match the given value.
|
|
*
|
|
* @param mixed $value The value to look for among responses
|
|
*/
|
|
public function contains($value)
|
|
{
|
|
foreach ($this as $response) {
|
|
if ($response === $value) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|