recursivecachingiterator.inc 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. <?php
  2. /** @file recursivecachingiterator.inc
  3. * @ingroup SPL
  4. * @brief class RecursiveCachingIterator
  5. * @author Marcus Boerger
  6. * @date 2003 - 2009
  7. *
  8. * SPL - Standard PHP Library
  9. */
  10. /**
  11. * @brief Cached recursive iteration over another Iterator
  12. * @author Marcus Boerger
  13. * @version 1.2
  14. * @since PHP 5.1
  15. *
  16. * @see CachingIterator
  17. */
  18. class RecursiveCachingIterator extends CachingIterator implements RecursiveIterator
  19. {
  20. private $hasChildren;
  21. private $getChildren;
  22. /** Construct from another iterator
  23. *
  24. * @param it Iterator to cache
  25. * @param flags Bitmask:
  26. * - CALL_TOSTRING (whether to call __toString() for every element)
  27. * - CATCH_GET_CHILD (whether to catch exceptions when trying to get childs)
  28. */
  29. function __construct(RecursiveIterator $it, $flags = self::CALL_TOSTRING)
  30. {
  31. parent::__construct($it, $flags);
  32. }
  33. /** Rewind Iterator
  34. */
  35. function rewind();
  36. {
  37. $this->hasChildren = false;
  38. $this->getChildren = NULL;
  39. parent::rewind();
  40. }
  41. /** Forward to next element if necessary then an Iterator for the Children
  42. * will be created.
  43. */
  44. function next()
  45. {
  46. if ($this->hasChildren = $this->it->hasChildren())
  47. {
  48. try
  49. {
  50. $child = $this->it->getChildren();
  51. if (!$this->ref)
  52. {
  53. $this->ref = new ReflectionClass($this);
  54. }
  55. $this->getChildren = $ref->newInstance($child, $this->flags);
  56. }
  57. catch(Exception $e)
  58. {
  59. if (!$this->flags & self::CATCH_GET_CHILD)
  60. {
  61. throw $e;
  62. }
  63. $this->hasChildren = false;
  64. $this->getChildren = NULL;
  65. }
  66. } else
  67. {
  68. $this->getChildren = NULL;
  69. }
  70. parent::next();
  71. }
  72. private $ref;
  73. /** @return whether the current element has children
  74. * @note The check whether the Iterator for the children can be created was
  75. * already executed. Hence when flag CATCH_GET_CHILD was given in
  76. * constructor this function returns false so that getChildren does
  77. * not try to access those children.
  78. */
  79. function hasChildren()
  80. {
  81. return $this->hasChildren;
  82. }
  83. /** @return An Iterator for the children
  84. */
  85. function getChildren()
  86. {
  87. return $this->getChildren;
  88. }
  89. }
  90. ?>