Skip to content

Commit 26c2ebc

Browse files
author
Alexandre Gaigalas
committed
hhvm RecursiveTreeIterator support
This code is from the PHP source itself. It's required to run Respect\Validation on hhvm, which lacks the class. By adding it to the library folder, it's loaded automatically by our testing routines. Further documentation should be written, but only after a stable build for hhvm appears on Travis.
1 parent 0d5d6d6 commit 26c2ebc

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

library/RecursiveTreeIterator.php

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

0 commit comments

Comments
 (0)