[BUGFIX] Prevent compression of scripts that use ajax.php
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_xml.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Contains class for creating XML output from records
29 *
30 * Revised for TYPO3 3.6 July/2003 by Kasper Skårhøj
31 *
32 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
33 */
34
35
36 /**
37 * XML class, Used to create XML output from input rows.
38 * Doesn't contain a lot of advanced features - pretty straight forward, practical stuff
39 * You are encouraged to use this class in your own applications.
40 *
41 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
42 * @package TYPO3
43 * @subpackage t3lib
44 * @see user_xmlversion, user_wapversion
45 */
46 class t3lib_xml {
47 var $topLevelName = 'typo3_test'; // Top element name
48 var $XML_recFields = array(); // Contains a list of fields for each table which should be presented in the XML output
49
50 var $XMLIndent = 0;
51 var $Icode = '';
52 var $XMLdebug = 0;
53 var $includeNonEmptyValues = 0; // if set, all fields from records are rendered no matter their content. If not set, only 'true' (that is '' or zero) fields make it to the document.
54 var $lines = array();
55
56 /**
57 * Constructor, setting topLevelName to the input var
58 *
59 * @param string Top Level Name
60 * @return void
61 */
62 function __construct($topLevelName) {
63 $this->topLevelName = $topLevelName;
64 }
65
66 /**
67 * Compatibility constructor.
68 *
69 * @param string Top Level Name
70 * @deprecated since TYPO3 4.6 and will be removed in TYPO3 4.8. Use __construct() instead.
71 */
72 public function t3lib_xml($topLevelName) {
73 t3lib_div::logDeprecatedFunction();
74 // Note: we cannot call $this->__construct() here because it would call the derived class constructor and cause recursion
75 // This code uses official PHP behavior (http://www.php.net/manual/en/language.oop5.basic.php) when $this in the
76 // statically called non-static method inherits $this from the caller's scope.
77 t3lib_xml::__construct($topLevelName);
78 }
79
80 /**
81 * When outputting a input record in XML only fields listed in $this->XML_recFields for the current table will be rendered.
82 *
83 * @param string Table name
84 * @param string Commalist of fields names from the table, $table, which is supposed to be rendered in the XML output. If a field is not in this list, it is not rendered.
85 * @return void
86 */
87 function setRecFields($table, $list) {
88 $this->XML_recFields[$table] = $list;
89 }
90
91 /**
92 * Returns the result of the XML rendering, basically this is imploding the internal ->lines array with linebreaks.
93 *
94 * @return string
95 */
96 function getResult() {
97 $content = implode(LF, $this->lines);
98 return $this->output($content);
99 }
100
101 /**
102 * Initialize WML (WAP) document with <?xml + <!DOCTYPE header tags and setting ->topLevelName as the first level.
103 *
104 * @return void
105 */
106 function WAPHeader() {
107 $this->lines[] = '<?xml version="1.0"?>';
108 $this->lines[] = '<!DOCTYPE ' . $this->topLevelName . ' PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">';
109 $this->newLevel($this->topLevelName, 1);
110 }
111
112 /**
113 * Initialize "anonymous" XML document with <?xml + <!DOCTYPE header tags and setting ->topLevelName as the first level.
114 * Encoding is set to UTF-8!
115 *
116 * @return void
117 */
118 function renderHeader() {
119 $this->lines[] = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
120 $this->lines[] = '<!DOCTYPE ' . $this->topLevelName . '>';
121 $this->newLevel($this->topLevelName, 1);
122 }
123
124 /**
125 * Sets the footer (of ->topLevelName)
126 *
127 * @return void
128 */
129 function renderFooter() {
130 $this->newLevel($this->topLevelName, 0);
131 }
132
133 /**
134 * Indents/Outdents a new level named, $name
135 *
136 * @param string The name of the new element for this level
137 * @param boolean If FALSE, then this function call will *end* the level, otherwise create it.
138 * @param array Array of attributes in key/value pairs which will be added to the element (tag), $name
139 * @return void
140 */
141 function newLevel($name, $beginEndFlag = 0, $params = array()) {
142 if ($beginEndFlag) {
143 $pList = '';
144 if (count($params)) {
145 $par = array();
146 foreach ($params as $key => $val) {
147 $par[] = $key . '="' . htmlspecialchars($val) . '"';
148 }
149 $pList = ' ' . implode(' ', $par);
150 }
151 $this->lines[] = $this->Icode . '<' . $name . $pList . '>';
152 $this->indent(1);
153 } else {
154 $this->indent(0);
155 $this->lines[] = $this->Icode . '</' . $name . '>';
156 }
157 }
158
159 /**
160 * Function that will return the content from string $content. If the internal ->XMLdebug flag is set the content returned will be formatted in <pre>-tags
161 *
162 * @param string The XML content to output
163 * @return string Output
164 */
165 function output($content) {
166 if ($this->XMLdebug) {
167 return '<pre>' . htmlspecialchars($content) . '</pre>
168 <hr /><font color="red">Size: ' . strlen($content) . '</font>';
169 } else {
170 return $content;
171 }
172 }
173
174 /**
175 * Increments/Decrements Indentation counter, ->XMLIndent
176 * Sets and returns ->Icode variable which is a line prefix consisting of a number of tab-chars corresponding to the indent-levels of the current posision (->XMLindent)
177 *
178 * @param boolean If TRUE the XMLIndent var is increased, otherwise decreased
179 * @return string ->Icode - the prefix string with TAB-chars.
180 */
181 function indent($b) {
182 if ($b) {
183 $this->XMLIndent++;
184 } else {
185 $this->XMLIndent--;
186 }
187 $this->Icode = '';
188 for ($a = 0; $a < $this->XMLIndent; $a++) {
189 $this->Icode .= TAB;
190 }
191 return $this->Icode;
192 }
193
194 /**
195 * Takes a SQL result for $table and traverses it, adding rows
196 *
197 * @param string Tablename
198 * @param pointer SQL resource pointer, should be reset
199 * @return void
200 */
201 function renderRecords($table, $res) {
202 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
203 $this->addRecord($table, $row);
204 }
205 }
206
207 /**
208 * Adds record, $row, from table, $table, to the internal array of XML-lines
209 *
210 * @param string Table name
211 * @param array The row to add to XML structure from the table name
212 * @return void
213 */
214 function addRecord($table, $row) {
215 $this->lines[] = $this->Icode . '<' . $table . ' uid="' . $row["uid"] . '">';
216 $this->indent(1);
217 $this->getRowInXML($table, $row);
218 $this->indent(0);
219 $this->lines[] = $this->Icode . '</' . $table . '>';
220 }
221
222 /**
223 * Internal function for adding the actual content of the $row from $table to the internal structure.
224 * Notice that only fields from $table that are listed in $this->XML_recFields[$table] (set by setRecFields()) will be rendered (and in the order found in that array!)
225 * Content from the row will be htmlspecialchar()'ed, UTF-8 encoded and have LF (newlines) exchanged for '<newline/>' tags. The element name for a value equals the fieldname from the record.
226 *
227 * @param string Table name
228 * @param array Row from table to add.
229 * @return void
230 * @access private
231 */
232 function getRowInXML($table, $row) {
233 $fields = t3lib_div::trimExplode(',', $this->XML_recFields[$table], 1);
234 foreach ($fields as $field) {
235 if ($row[$field] || $this->includeNonEmptyValues) {
236 $this->lines[] = $this->Icode . $this->fieldWrap($field, $this->substNewline($this->utf8(htmlspecialchars($row[$field]))));
237 }
238 }
239 }
240
241 /**
242 * UTF-8 encodes the input content (from ISO-8859-1!)
243 *
244 * @param string String content to UTF-8 encode
245 * @return string Encoded content.
246 */
247 function utf8($content) {
248 return utf8_encode($content);
249 }
250
251 /**
252 * Substitutes LF characters with a '<newline/>' tag.
253 *
254 * @param string Input value
255 * @return string Processed input value
256 */
257 function substNewline($string) {
258 return str_replace(LF, '<newline/>', $string);
259 }
260
261 /**
262 * Wraps the value in tags with element name, $field.
263 *
264 * @param string Fieldname from a record - will be the element name
265 * @param string Value from the field - will be wrapped in the elements.
266 * @return string The wrapped string.
267 */
268 function fieldWrap($field, $value) {
269 return '<' . $field . '>' . $value . '</' . $field . '>';
270 }
271
272 /**
273 * Creates the BACK button for WAP documents
274 *
275 * @return void
276 */
277 function WAPback() {
278 $this->newLevel('template', 1);
279 $this->newLevel('do', 1, array('type' => 'accept', 'label' => 'Back'));
280 $this->addLine('<prev/>');
281 $this->newLevel('do');
282 $this->newLevel('template');
283 }
284
285 /**
286 * Add a line to the internal XML structure (automatically prefixed with ->Icode.
287 *
288 * @param string Line to add to the $this->lines array
289 * @return void
290 */
291 function addLine($str) {
292 $this->lines[] = $this->Icode . $str;
293 }
294 }
295
296
297 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_xml.php'])) {
298 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_xml.php']);
299 }
300 ?>