2003-11-09 14:05:36 +00:00
|
|
|
<?php
|
|
|
|
|
2004-10-29 20:58:58 +00:00
|
|
|
/** @file recursiveiteratoriterator.inc
|
2004-10-31 19:05:37 +00:00
|
|
|
* @ingroup SPL
|
2004-10-29 20:58:58 +00:00
|
|
|
* @brief class RecursiveIteratorIterator
|
|
|
|
* @author Marcus Boerger
|
|
|
|
* @date 2003 - 2004
|
|
|
|
*
|
|
|
|
* SPL - Standard PHP Library
|
|
|
|
*/
|
|
|
|
|
|
|
|
define('RIT_LEAVES_ONLY', 0);
|
|
|
|
define('RIT_SELF_FIRST', 1);
|
|
|
|
define('RIT_CHILD_FIRST', 2);
|
|
|
|
|
2003-11-09 14:05:36 +00:00
|
|
|
/**
|
|
|
|
* @brief Iterates through recursive iterators
|
|
|
|
* @author Marcus Boerger
|
2004-10-29 20:58:58 +00:00
|
|
|
* @version 1.1
|
2003-11-09 14:05:36 +00:00
|
|
|
*
|
2004-11-01 18:11:39 +00:00
|
|
|
* The objects of this class are created by instances of RecursiveIterator.
|
|
|
|
* Elements of those iterators may be traversable themselves. If so these
|
|
|
|
* sub elements are recursed into.
|
2003-11-09 14:05:36 +00:00
|
|
|
*/
|
2004-10-29 20:12:57 +00:00
|
|
|
class RecursiveIteratorIterator implements OuterIterator
|
2003-11-09 14:05:36 +00:00
|
|
|
{
|
|
|
|
protected $ait = array();
|
|
|
|
protected $count = 0;
|
|
|
|
|
2004-10-29 20:58:58 +00:00
|
|
|
/** Construct from RecursiveIterator
|
|
|
|
*
|
|
|
|
* @param it RecursiveIterator to iterate
|
|
|
|
* @param flags Operation mode:
|
|
|
|
* - RIT_LEAVES_ONLY only show leaves
|
|
|
|
* - RIT_SELF_FIRST show parents prior to their childs
|
|
|
|
* - RIT_CHILD_FIRST show all childs prior to their parent
|
|
|
|
*/
|
|
|
|
function __construct(RecursiveIterator $it, $flags)
|
2003-11-22 20:51:15 +00:00
|
|
|
{
|
2003-11-09 14:05:36 +00:00
|
|
|
$this->ait[0] = $it;
|
|
|
|
}
|
|
|
|
|
2004-10-29 20:58:58 +00:00
|
|
|
/** Rewind to top iterator as set in constructor
|
|
|
|
*/
|
2003-11-22 20:51:15 +00:00
|
|
|
function rewind()
|
|
|
|
{
|
|
|
|
while ($this->count) {
|
|
|
|
unset($this->ait[$this->count--]);
|
2004-11-01 22:54:12 +00:00
|
|
|
$this->endChildren();
|
2003-11-09 14:05:36 +00:00
|
|
|
}
|
|
|
|
$this->ait[0]->rewind();
|
|
|
|
$this->ait[0]->recursed = false;
|
|
|
|
}
|
|
|
|
|
2004-10-29 20:58:58 +00:00
|
|
|
/** @return whether iterator is valid
|
|
|
|
*/
|
2004-03-08 17:33:31 +00:00
|
|
|
function valid()
|
2003-11-22 20:51:15 +00:00
|
|
|
{
|
2003-11-09 14:05:36 +00:00
|
|
|
$count = $this->count;
|
2003-11-22 20:51:15 +00:00
|
|
|
while ($count) {
|
2003-11-09 14:05:36 +00:00
|
|
|
$it = $this->ait[$count];
|
2004-03-08 17:33:31 +00:00
|
|
|
if ($it->valid()) {
|
2003-11-09 14:05:36 +00:00
|
|
|
return true;
|
|
|
|
}
|
2003-11-22 20:51:15 +00:00
|
|
|
$count--;
|
2004-11-01 22:54:12 +00:00
|
|
|
$this->endChildren();
|
2003-11-09 14:05:36 +00:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2004-11-01 18:11:39 +00:00
|
|
|
/** @return current key
|
2004-10-29 20:58:58 +00:00
|
|
|
*/
|
2003-11-22 20:51:15 +00:00
|
|
|
function key()
|
|
|
|
{
|
|
|
|
$it = $this->ait[$this->count];
|
2003-11-09 14:05:36 +00:00
|
|
|
return $it->key();
|
|
|
|
}
|
|
|
|
|
2004-10-29 20:58:58 +00:00
|
|
|
/** @return current element
|
|
|
|
*/
|
2003-11-22 20:51:15 +00:00
|
|
|
function current()
|
|
|
|
{
|
|
|
|
$it = $this->ait[$this->count];
|
2003-11-09 14:05:36 +00:00
|
|
|
return $it->current();
|
|
|
|
}
|
|
|
|
|
2004-10-29 20:58:58 +00:00
|
|
|
/** Forward to next element
|
|
|
|
*/
|
2003-11-22 20:51:15 +00:00
|
|
|
function next()
|
|
|
|
{
|
2003-11-09 14:05:36 +00:00
|
|
|
while ($this->count) {
|
2003-11-22 20:51:15 +00:00
|
|
|
$it = $this->ait[$this->count];
|
2004-03-08 17:33:31 +00:00
|
|
|
if ($it->valid()) {
|
2003-11-09 14:05:36 +00:00
|
|
|
if (!$it->recursed && $it->hasChildren()) {
|
|
|
|
$it->recursed = true;
|
|
|
|
$sub = $it->getChildren();
|
|
|
|
$sub->recursed = false;
|
|
|
|
$sub->rewind();
|
2004-03-08 17:33:31 +00:00
|
|
|
if ($sub->valid()) {
|
2003-11-22 20:51:15 +00:00
|
|
|
$this->ait[++$this->count] = $sub;
|
2004-01-23 21:03:20 +00:00
|
|
|
if (!$sub instanceof RecursiveIterator) {
|
2003-11-09 14:05:36 +00:00
|
|
|
throw new Exception(get_class($sub).'::getChildren() must return an object that implements RecursiveIterator');
|
2004-11-01 22:54:12 +00:00
|
|
|
}
|
|
|
|
$this->beginChildren();
|
2003-11-09 14:05:36 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
unset($sub);
|
|
|
|
}
|
|
|
|
$it->next();
|
|
|
|
$it->recursed = false;
|
2004-03-08 17:33:31 +00:00
|
|
|
if ($it->valid()) {
|
2003-11-09 14:05:36 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
$it->recursed = false;
|
|
|
|
}
|
2003-11-22 20:51:15 +00:00
|
|
|
if ($this->count) {
|
|
|
|
unset($this->ait[$this->count--]);
|
|
|
|
$it = $this->ait[$this->count];
|
2004-11-01 22:54:12 +00:00
|
|
|
$this->endChildren();
|
2003-11-09 14:05:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-10-29 20:58:58 +00:00
|
|
|
|
|
|
|
/** @return Sub Iterator at given level or if unspecified the current sub
|
|
|
|
* Iterator
|
|
|
|
*/
|
2003-11-22 20:51:15 +00:00
|
|
|
function getSubIterator($level = NULL)
|
|
|
|
{
|
|
|
|
if (is_null($level)) {
|
|
|
|
$level = $this->count;
|
|
|
|
}
|
|
|
|
return @$this->ait[$level];
|
|
|
|
}
|
|
|
|
|
2004-10-29 20:12:57 +00:00
|
|
|
/**
|
|
|
|
* @return The inner iterator
|
|
|
|
*/
|
|
|
|
function getInnerIterator()
|
|
|
|
{
|
|
|
|
return $this->it;
|
|
|
|
}
|
|
|
|
|
2004-10-29 20:58:58 +00:00
|
|
|
/** @return Current Depth (Number of parents)
|
|
|
|
*/
|
2003-11-22 20:51:15 +00:00
|
|
|
function getDepth()
|
|
|
|
{
|
|
|
|
return $this->level;
|
2003-11-09 14:05:36 +00:00
|
|
|
}
|
2004-11-01 22:54:12 +00:00
|
|
|
|
|
|
|
/** Called right after calling getChildren()
|
|
|
|
*/
|
|
|
|
function beginChildren()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Called after current child iterator is invalid
|
|
|
|
*/
|
|
|
|
function endChildren()
|
|
|
|
{
|
|
|
|
}
|
2003-11-09 14:05:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
?>
|