* (bug 24009) Include implicit groups in action=query&list=users&usprop=groups
[lhc/web/wiklou.git] / includes / api / ApiFormatYaml_spyc.php
1 <?php
2 /**
3 * Spyc -- A Simple PHP YAML Class
4 * @version 0.2.3 -- 2006-02-04
5 * @author Chris Wanstrath <chris@ozmm.org>
6 * @see http://spyc.sourceforge.net/
7 * @copyright Copyright 2005-2006 Chris Wanstrath
8 * @license http://www.opensource.org/licenses/mit-license.php MIT License
9 */
10
11 /**
12 * The Simple PHP YAML Class.
13 *
14 * This class can be used to read a YAML file and convert its contents
15 * into a PHP array. It currently supports a very limited subsection of
16 * the YAML spec.
17 *
18 * @ingroup API
19 */
20 class Spyc {
21
22 /**
23 * Dump YAML from PHP array statically
24 *
25 * The dump method, when supplied with an array, will do its best
26 * to convert the array into friendly YAML. Pretty simple. Feel free to
27 * save the returned string as nothing.yml and pass it around.
28 *
29 * Oh, and you can decide how big the indent is and what the wordwrap
30 * for folding is. Pretty cool -- just pass in 'false' for either if
31 * you want to use the default.
32 *
33 * Indent's default is 2 spaces, wordwrap's default is 40 characters. And
34 * you can turn off wordwrap by passing in 0.
35 *
36 * @return string
37 * @param $array Array: PHP array
38 * @param $indent Integer: Pass in false to use the default, which is 2
39 * @param $wordwrap Integer: Pass in 0 for no wordwrap, false for default (40)
40 */
41 public static function YAMLDump( $array, $indent = false, $wordwrap = false ) {
42 $spyc = new Spyc;
43 return $spyc->dump( $array, $indent, $wordwrap );
44 }
45
46 /**
47 * Dump PHP array to YAML
48 *
49 * The dump method, when supplied with an array, will do its best
50 * to convert the array into friendly YAML. Pretty simple. Feel free to
51 * save the returned string as tasteful.yml and pass it around.
52 *
53 * Oh, and you can decide how big the indent is and what the wordwrap
54 * for folding is. Pretty cool -- just pass in 'false' for either if
55 * you want to use the default.
56 *
57 * Indent's default is 2 spaces, wordwrap's default is 40 characters. And
58 * you can turn off wordwrap by passing in 0.
59 *
60 * @public
61 * @return string
62 * @param $array Array: PHP array
63 * @param $indent Integer: Pass in false to use the default, which is 2
64 * @param $wordwrap Integer: Pass in 0 for no wordwrap, false for default (40)
65 */
66 function dump( $array, $indent = false, $wordwrap = false ) {
67 // Dumps to some very clean YAML. We'll have to add some more features
68 // and options soon. And better support for folding.
69
70 // New features and options.
71 if ( $indent === false or !is_numeric( $indent ) ) {
72 $this->_dumpIndent = 2;
73 } else {
74 $this->_dumpIndent = $indent;
75 }
76
77 if ( $wordwrap === false or !is_numeric( $wordwrap ) ) {
78 $this->_dumpWordWrap = 40;
79 } else {
80 $this->_dumpWordWrap = $wordwrap;
81 }
82
83 // New YAML document
84 $string = "---\n";
85
86 // Start at the base of the array and move through it.
87 foreach ( $array as $key => $value ) {
88 $string .= $this->_yamlize( $key, $value, 0 );
89 }
90 return $string;
91 }
92
93 /**** Private Properties ****/
94
95 private $_haveRefs;
96 private $_allNodes;
97 private $_lastIndent;
98 private $_lastNode;
99 private $_inBlock;
100 private $_isInline;
101 private $_dumpIndent;
102 private $_dumpWordWrap;
103
104 /**** Private Methods ****/
105
106 /**
107 * Attempts to convert a key / value array item to YAML
108 * @return string
109 * @param $key The name of the key
110 * @param $value The value of the item
111 * @param $indent The indent of the current node
112 */
113 private function _yamlize( $key, $value, $indent ) {
114 if ( is_array( $value ) ) {
115 // It has children. What to do?
116 // Make it the right kind of item
117 $string = $this->_dumpNode( $key, null, $indent );
118 // Add the indent
119 $indent += $this->_dumpIndent;
120 // Yamlize the array
121 $string .= $this->_yamlizeArray( $value, $indent );
122 } elseif ( !is_array( $value ) ) {
123 // It doesn't have children. Yip.
124 $string = $this->_dumpNode( $key, $value, $indent );
125 }
126 return $string;
127 }
128
129 /**
130 * Attempts to convert an array to YAML
131 * @return string
132 * @param $array The array you want to convert
133 * @param $indent The indent of the current level
134 */
135 private function _yamlizeArray( $array, $indent ) {
136 if ( is_array( $array ) ) {
137 $string = '';
138 foreach ( $array as $key => $value ) {
139 $string .= $this->_yamlize( $key, $value, $indent );
140 }
141 return $string;
142 } else {
143 return false;
144 }
145 }
146
147 /**
148 * Find out whether a string needs to be output as a literal rather than in plain style.
149 * Added by Roan Kattouw 13-03-2008
150 * @param $value The string to check
151 * @return bool
152 */
153 function _needLiteral( $value ) {
154 // Check whether the string contains # or : or begins with any of:
155 // [ - ? , [ ] { } ! * & | > ' " % @ ` ]
156 // or is a number or contains newlines
157 return (bool)( gettype( $value ) == "string" &&
158 ( is_numeric( $value ) ||
159 strpos( $value, "\n" ) ||
160 preg_match( "/[#:]/", $value ) ||
161 preg_match( "/^[-?,[\]{}!*&|>'\"%@`]/", $value ) ) );
162 }
163
164 /**
165 * Returns YAML from a key and a value
166 * @return string
167 * @param $key The name of the key
168 * @param $value The value of the item
169 * @param $indent The indent of the current node
170 */
171 private function _dumpNode( $key, $value, $indent ) {
172 // do some folding here, for blocks
173 if ( $this->_needLiteral( $value ) ) {
174 $value = $this->_doLiteralBlock( $value, $indent );
175 } else {
176 $value = $this->_doFolding( $value, $indent );
177 }
178
179 $spaces = str_repeat( ' ', $indent );
180
181 if ( is_int( $key ) ) {
182 // It's a sequence
183 if ( $value !== '' && !is_null( $value ) )
184 $string = $spaces . '- ' . $value . "\n";
185 else
186 $string = $spaces . "-\n";
187 } else {
188 if ( $key == '*' ) // bug 21922 - Quote asterix used as keys
189 $key = "'*'";
190
191 // It's mapped
192 if ( $value !== '' && !is_null( $value ) )
193 $string = $spaces . $key . ': ' . $value . "\n";
194 else
195 $string = $spaces . $key . ":\n";
196 }
197 return $string;
198 }
199
200 /**
201 * Creates a literal block for dumping
202 * @return string
203 * @param $value
204 * @param $indent int The value of the indent
205 */
206 private function _doLiteralBlock( $value, $indent ) {
207 $exploded = explode( "\n", $value );
208 $newValue = '|-';
209 $indent += $this->_dumpIndent;
210 $spaces = str_repeat( ' ', $indent );
211 foreach ( $exploded as $line ) {
212 $newValue .= "\n" . $spaces . trim( $line );
213 }
214 return $newValue;
215 }
216
217 /**
218 * Folds a string of text, if necessary
219 * @return string
220 * @param $value The string you wish to fold
221 */
222 private function _doFolding( $value, $indent ) {
223 // Don't do anything if wordwrap is set to 0
224 if ( $this->_dumpWordWrap === 0 ) {
225 return $value;
226 }
227
228 if ( strlen( $value ) > $this->_dumpWordWrap ) {
229 $indent += $this->_dumpIndent;
230 $indent = str_repeat( ' ', $indent );
231 $wrapped = wordwrap( $value, $this->_dumpWordWrap, "\n$indent" );
232 $value = ">-\n" . $indent . $wrapped;
233 }
234 return $value;
235 }
236 }