MDL-24368 prevent infinite loops when caching can not be disabled
[moodle.git] / lib / xmlize.php
CommitLineData
b3afe824 1<?php
2
a93ea924 3/**
4 * xmlize.php - xmlize() is by Hans Anderson, {@link http://www.hansanderson.com/contact/}
b3afe824 5 *
6 * Ye Ole "Feel Free To Use it However" License [PHP, BSD, GPL].
7 * some code in xml_depth is based on code written by other PHPers
8 * as well as one Perl script. Poor programming practice and organization
9 * on my part is to blame for the credit these people aren't receiving.
10 * None of the code was copyrighted, though.
11 *
b868d3d9 12 * @package moodlecore
a93ea924 13 * @author Hans Anderson
14 * @version This is a stable release, 1.0. I don't foresee any changes, but you
15 * might check {@link http://www.hansanderson.com/php/xml/} to see
b868d3d9 16 * @copyright Hans Anderson
17 * @license Feel Free To Use it However
a93ea924 18 */
19
20/**
21 * Create xml formatted output from an array.
b3afe824 22 *
a93ea924 23 * usage:<br>
24 * <code>
25 * $xml = xmlize($array);
26 * </code>
27 * See the function {@link traverse_xmlize()} for information about the
b3afe824 28 * structure of the array, it's much easier to explain by showing you.
29 * Be aware that the array is somewhat tricky. I use xmlize all the time,
a93ea924 30 * but still need to use {@link traverse_xmlize()} quite often to show me the structure!
b3afe824 31 *
a93ea924 32 * THIS IS A PHP 5 VERSION:
33 *
34 * This modified version basically has a new optional parameter
35 * to specify an OUTPUT encoding. If not specified, it defaults to UTF-8.
36 * I recommend you to read this PHP bug. There you can see how PHP4, PHP5.0.0
37 * and PHP5.0.2 will handle this.
38 * {@link http://bugs.php.net/bug.php?id=29711}
39 * Ciao, Eloy :-)
40 *
41 *
42 * @author Hans Anderson
43 * @param array $data The array to be converted
143c1eb9 44 * @param int $WHITE If set to 1 allows the parser to skip "space" characters in xml document. Default is 1
a93ea924 45 * @param string $encoding Specify an OUTPUT encoding. If not specified, it defaults to UTF-8.
46 * @return array
b3afe824 47 */
b7976058 48function xmlize($data, $WHITE=1, $encoding='UTF-8') {
b3afe824 49
50 $data = trim($data);
51 $vals = $index = $array = array();
b7976058 52 $parser = xml_parser_create($encoding);
b3afe824 53 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
54 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, $WHITE);
55 xml_parse_into_struct($parser, $data, $vals, $index);
56 xml_parser_free($parser);
57
58 $i = 0;
20355e5a 59
60 if (empty($vals)) {
61 // XML file is invalid or empty, return false
62 return false;
63 }
b3afe824 64
65 $tagname = $vals[$i]['tag'];
66 if ( isset ($vals[$i]['attributes'] ) )
67 {
68 $array[$tagname]['@'] = $vals[$i]['attributes'];
69 } else {
70 $array[$tagname]['@'] = array();
71 }
72
73 $array[$tagname]["#"] = xml_depth($vals, $i);
74
75
76 return $array;
77}
78
a93ea924 79/**
80 * @internal You don't need to do anything with this function, it's called by
81 * xmlize. It's a recursive function, calling itself as it goes deeper
b3afe824 82 * into the xml levels. If you make any improvements, please let me know.
da72d76d 83 * @access private
b3afe824 84 */
b3afe824 85function xml_depth($vals, &$i) {
86 $children = array();
87
88 if ( isset($vals[$i]['value']) )
89 {
90 array_push($children, $vals[$i]['value']);
91 }
92
93 while (++$i < count($vals)) {
94
95 switch ($vals[$i]['type']) {
96
97 case 'open':
98
99 if ( isset ( $vals[$i]['tag'] ) )
100 {
101 $tagname = $vals[$i]['tag'];
102 } else {
103 $tagname = '';
104 }
105
106 if ( isset ( $children[$tagname] ) )
107 {
108 $size = sizeof($children[$tagname]);
109 } else {
110 $size = 0;
111 }
112
113 if ( isset ( $vals[$i]['attributes'] ) ) {
114 $children[$tagname][$size]['@'] = $vals[$i]["attributes"];
115
116 }
117
118 $children[$tagname][$size]['#'] = xml_depth($vals, $i);
119
120 break;
121
122
123 case 'cdata':
124 array_push($children, $vals[$i]['value']);
125 break;
126
127 case 'complete':
128 $tagname = $vals[$i]['tag'];
129
130 if( isset ($children[$tagname]) )
131 {
132 $size = sizeof($children[$tagname]);
133 } else {
134 $size = 0;
135 }
136
137 if( isset ( $vals[$i]['value'] ) )
138 {
139 $children[$tagname][$size]["#"] = $vals[$i]['value'];
140 } else {
141 $children[$tagname][$size]["#"] = '';
142 }
143
144 if ( isset ($vals[$i]['attributes']) ) {
145 $children[$tagname][$size]['@']
146 = $vals[$i]['attributes'];
147 }
148
149 break;
150
151 case 'close':
152 return $children;
153 break;
154 }
155
156 }
157
158 return $children;
159
160
161}
162
163
a93ea924 164/**
165 * This helps you understand the structure of the array {@link xmlize()} outputs
b3afe824 166 *
a93ea924 167 * Function by acebone@f2s.com, a HUGE help!<br>
168 * Usage:<br>
169 * <code>
b3afe824 170 * traverse_xmlize($xml, 'xml_');
171 * print '<pre>' . implode("", $traverse_array . '</pre>';
a93ea924 172 * </code>
173 * @author acebone@f2s.com
174 * @param array $array ?
175 * @param string $arrName ?
176 * @param int $level ?
177 * @return int
178 * @todo Finish documenting this function
b3afe824 179 */
a93ea924 180function traverse_xmlize($array, $arrName = 'array', $level = 0) {
b3afe824 181
182 foreach($array as $key=>$val)
183 {
184 if ( is_array($val) )
185 {
a93ea924 186 traverse_xmlize($val, $arrName . '[' . $key . ']', $level + 1);
b3afe824 187 } else {
188 $GLOBALS['traverse_array'][] = '$' . $arrName . '[' . $key . '] = "' . $val . "\"\n";
189 }
190 }
191
192 return 1;
193
194}
195
20355e5a 196?>