multipleiterator.inc [plain text]
<?php
class MultipleIterator implements Iterator
{
private $iterators;
private $flags;
const MIT_NEED_ANY = 0;
const MIT_NEED_ALL = 1;
const MIT_KEYS_NUMERIC = 0;
const MIT_KEYS_ASSOC = 2;
public function __construct($flags = self::MIT_NEED_ALL|self::MIT_KEYS_NUMERIC)
{
$this->iterators = new SplObjectStorage();
$this->flags = $flags;
}
public function getFlags()
{
return $this->flags;
}
public function setFlags($flags)
{
$this->flags = $flags;
}
public function attachIterator(Iterator $iter, $inf = NULL)
{
if (!is_null($inf))
{
if (!is_int($inf) && !is_string($inf))
{
throw new IllegalValueException('Inf must be NULL, integer or string');
}
foreach($this->iterators as $iter)
{
if ($inf == $this->iterators->getInfo())
{
throw new IllegalValueException('Key duplication error');
}
}
}
$this->iterators->attach($iter, $inf);
}
public function detachIterator(Iterator $iter)
{
$this->iterators->detach($iter);
}
public function containsIterator(Iterator $iter)
{
return $this->iterator->contains($iter);
}
public function countIterators()
{
return $this->iterators->count();
}
public function rewind()
{
foreach($this->iterators as $iter)
{
$iter->rewind();
}
}
public function valid()
{
if (!sizeof($this->iterators)) {
return false;
}
$expect = $this->flags & self::MIT_NEED_ALL ? true : false;
foreach($this->iterators as $iter)
{
if ($expect != $iter->valid())
{
return !$expect;
}
}
return $expect;
}
public function next()
{
foreach($this->iterators as $iter)
{
$iter->next();
}
}
public function current()
{
if (!sizeof($this->iterators))
{
return false;
}
$retval = array();
foreach($this->iterators as $iter)
{
if ($iter->valid())
{
if ($this->flags & self::MIT_KEYS_ASSOC)
{
$key = $this->iterators->getInfo();
if (is_null($key))
{
throw new IllegalValueException('Sub-Iterator is associated with NULL');
}
$retval[$key] = $iter->current();
}
else
{
$retval[] = $iter->current();
}
}
else if ($this->flags & self::MIT_NEED_ALL)
{
throw new RuntimeException('Called current() with non valid sub iterator');
}
else
{
$retval[] = NULL;
}
}
return $retval;
}
public function key()
{
if (!sizeof($this->iterators))
{
return false;
}
$retval = array();
foreach($this->iterators as $iter)
{
if ($iter->valid())
{
$retval[] = $iter->key();
}
else if ($this->flags & self::MIT_NEED_ALL)
{
throw new LogicException('Called key() with non valid sub iterator');
}
else
{
$retval[] = NULL;
}
}
return $retval;
}
}