1<?php 2 3/** @file recursivetreeiterator.inc 4 * @ingroup SPL 5 * @brief class RecursiveTreeIterator 6 * @author Marcus Boerger, Johannes Schlueter 7 * @date 2005 - 2009 8 * 9 * SPL - Standard PHP Library 10 */ 11 12 13/** @ingroup SPL 14 * @brief RecursiveIteratorIterator to generate ASCII graphic trees for the 15 * entries in a RecursiveIterator 16 * @author Marcus Boerger, Johannes Schlueter 17 * @version 1.1 18 * @since PHP 5.3 19 */ 20class RecursiveTreeIterator extends RecursiveIteratorIterator 21{ 22 const BYPASS_CURRENT = 0x00000004; 23 const BYPASS_KEY = 0x00000008; 24 25 private $rit_flags; 26 27 /** 28 * @param it iterator to use as inner iterator 29 * @param rit_flags flags passed to RecursiveIteratoIterator (parent) 30 * @param cit_flags flags passed to RecursiveCachingIterator (for hasNext) 31 * @param mode mode passed to RecursiveIteratoIterator (parent) 32 */ 33 function __construct(RecursiveIterator $it, $rit_flags = self::BYPASS_KEY, $cit_flags = CachingIterator::CATCH_GET_CHILD, $mode = self::SELF_FIRST) 34 { 35 parent::__construct(new RecursiveCachingIterator($it, $cit_flags), $mode, $rit_flags); 36 $this->rit_flags = $rit_flags; 37 } 38 39 private $prefix = array(0=>'', 1=>'| ', 2=>' ', 3=>'|-', 4=>'\-', 5=>''); 40 41 /** Prefix used to start elements. */ 42 const PREFIX_LEFT = 0; 43 /** Prefix used if $level < depth and hasNext($level) == true. */ 44 const PREFIX_MID_HAS_NEXT = 1; 45 /** Prefix used if $level < depth and hasNext($level) == false. */ 46 const PREFIX_MID_LAST = 2; 47 /** Prefix used if $level == depth and hasNext($level) == true. */ 48 const PREFIX_END_HAS_NEXT = 3; 49 /** Prefix used if $level == depth and hasNext($level) == false. */ 50 const PREFIX_END_LAST = 4; 51 /** Prefix used right in front of the current element. */ 52 const PREFIX_RIGHT = 5; 53 54 /** 55 * Set prefix part as used in getPrefix() and stored in $prefix. 56 * @param $part any PREFIX_* const. 57 * @param $value new prefix string for specified part. 58 * @throws OutOfRangeException if 0 > $part or $part > 5. 59 */ 60 function setPrefixPart($part, $value) 61 { 62 if (0 > $part || $part > 5) { 63 throw new OutOfRangeException(); 64 } 65 $this->prefix[$part] = (string)$value; 66 } 67 68 /** @return string to place in front of current element 69 */ 70 function getPrefix() 71 { 72 $tree = ''; 73 for ($level = 0; $level < $this->getDepth(); $level++) 74 { 75 $tree .= $this->getSubIterator($level)->hasNext() ? $this->prefix[1] : $this->prefix[2]; 76 } 77 $tree .= $this->getSubIterator($level)->hasNext() ? $this->prefix[3] : $this->prefix[4]; 78 79 return $this->prefix[0] . $tree . $this->prefix[5]; 80 } 81 82 /** @return string presentation build for current element 83 */ 84 function getEntry() 85 { 86 return @(string)parent::current(); 87 } 88 89 /** @return string to place after the current element 90 */ 91 function getPostfix() 92 { 93 return ''; 94 } 95 96 /** @return the current element prefixed and postfixed 97 */ 98 function current() 99 { 100 if ($this->rit_flags & self::BYPASS_CURRENT) 101 { 102 return parent::current(); 103 } 104 else 105 { 106 return $this->getPrefix() . $this->getEntry() . $this->getPostfix(); 107 } 108 } 109 110 /** @return the current key prefixed and postfixed 111 */ 112 function key() 113 { 114 if ($this->rit_flags & self::BYPASS_KEY) 115 { 116 return parent::key(); 117 } 118 else 119 { 120 return $this->getPrefix() . parent::key() . $this->getPostfix(); 121 } 122 } 123 124 /** Aggregates the inner iterator 125 */ 126 function __call($func, $params) 127 { 128 return call_user_func_array(array($this->getSubIterator(), $func), $params); 129 } 130} 131 132?>