SPL-StandardPHPLibrary
multipleiterator.inc
Go to the documentation of this file.
00001 <?php
00019 class MultipleIterator implements Iterator
00020 {
00022     private $iterators;
00023 
00025     private $flags;
00026 
00028     const MIT_NEED_ANY = 0;
00029 
00031     const MIT_NEED_ALL  = 1;
00032 
00034     const MIT_KEYS_NUMERIC  = 0;
00035 
00037     const MIT_KEYS_ASSOC  = 2;
00038 
00042     public function __construct($flags = self::MIT_NEED_ALL|self::MIT_KEYS_NUMERIC)
00043     {
00044         $this->iterators = new SplObjectStorage();
00045         $this->flags = $flags;
00046     }
00047 
00049     public function getFlags()
00050     {
00051         return $this->flags;
00052     }
00053 
00055     public function setFlags($flags)
00056     {
00057         $this->flags = $flags;
00058     }
00059 
00066     public function attachIterator(Iterator $iter, $inf = NULL)
00067     {
00068 
00069         if (!is_null($inf))
00070         {
00071             if (!is_int($inf) && !is_string($inf))
00072             {
00073                 throw new IllegalValueException('Inf must be NULL, integer or string');
00074             }
00075             foreach($this->iterators as $iter)
00076             {
00077                 if ($inf == $this->iterators->getInfo())
00078                 {
00079                     throw new IllegalValueException('Key duplication error');
00080                 }
00081             }
00082         }
00083         $this->iterators->attach($iter, $inf);
00084     }
00085 
00087     public function detachIterator(Iterator $iter)
00088     {
00089         $this->iterators->detach($iter);
00090     }
00091 
00095     public function containsIterator(Iterator $iter)
00096     {
00097         return $this->iterator->contains($iter);
00098     }
00099 
00101     public function countIterators()
00102     {
00103         return $this->iterators->count();
00104     }
00105 
00107     public function rewind()
00108     {
00109         foreach($this->iterators as $iter)
00110         {
00111             $iter->rewind();
00112         }
00113     }
00114 
00122     public function valid()
00123     {
00124         if (!sizeof($this->iterators)) {
00125             return false;
00126         }
00127         // The following code is an optimized version that executes as few
00128         // valid() calls as necessary and that only checks the flags once.
00129         $expect = $this->flags & self::MIT_NEED_ALL ? true : false;
00130         foreach($this->iterators as $iter)
00131         {
00132             if ($expect != $iter->valid())
00133             {
00134                 return !$expect;
00135             }
00136         }
00137         return $expect;
00138     }
00139 
00143     public function next()
00144     {
00145         foreach($this->iterators as $iter)
00146         {
00147             $iter->next();
00148         }
00149     }
00150 
00157     public function current()
00158     {
00159         if (!sizeof($this->iterators))
00160         {
00161             return false;
00162         }
00163         $retval = array();
00164         foreach($this->iterators as $iter)
00165         {
00166             if ($it->valid())
00167             {
00168                 if ($this->flags & self::MIT_KEYS_ASSOC)
00169                 {
00170                     $key = $this->iterators->getInfo();
00171                     if (is_null($key))
00172                     {
00173                         throw new IllegalValueException('Sub-Iterator is associated with NULL');
00174                     }
00175                     $retval[$key] = $iter->current();
00176                 }
00177                 else
00178                 {
00179                     $retval[] = $iter->current();
00180                 }
00181             }
00182             else if ($this->flags & self::MIT_NEED_ALL)
00183             {
00184                 throw new RuntimeException('Called current() with non valid sub iterator');
00185             }
00186             else
00187             {
00188                 $retval[] = NULL;
00189             }
00190         }
00191         return $retval;
00192     }
00193 
00199     public function key()
00200     {
00201         if (!sizeof($this->iterators))
00202         {
00203             return false;
00204         }
00205         $retval = array();
00206         foreach($this->iterators as $iter)
00207         {
00208             if ($it->valid())
00209             {
00210                 $retval[] = $iter->key();
00211             }
00212             else if ($this->flags & self::MIT_NEED_ALL)
00213             {
00214                 throw new LogicException('Called key() with non valid sub iterator');
00215             }
00216             else
00217             {
00218                 $retval[] = NULL;
00219             }
00220         }
00221         return $retval;
00222     }
00223 }