Added Feature #12066: Added constants throughout the core for LF, CR, TAB (Thanks...
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_xml.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2009 Kasper Skaarhoj (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 * $Id$
31 * Revised for TYPO3 3.6 July/2003 by Kasper Skaarhoj
32 *
33 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
34 */
35 /**
36 * [CLASS/FUNCTION INDEX of SCRIPT]
37 *
38 *
39 *
40 * 86: class t3lib_xml
41 * 102: function t3lib_xml($topLevelName)
42 * 113: function setRecFields($table,$list)
43 * 122: function getResult()
44 * 132: function WAPHeader()
45 * 144: function renderHeader()
46 * 155: function renderFooter()
47 * 167: function newLevel($name,$beginEndFlag=0,$params=array())
48 * 192: function output($content)
49 * 208: function indent($b)
50 * 224: function renderRecords($table,$res)
51 * 237: function addRecord($table,$row)
52 * 255: function getRowInXML($table,$row)
53 * 271: function utf8($content)
54 * 281: function substNewline($string)
55 * 292: function fieldWrap($field,$value)
56 * 301: function WAPback()
57 * 315: function addLine($str)
58 *
59 * TOTAL FUNCTIONS: 17
60 * (This index is automatically created/updated by the extension "extdeveval")
61 *
62 */
63
64
65
66
67
68
69
70
71
72
73
74
75
76 /**
77 * XML class, Used to create XML output from input rows.
78 * Doesn't contain a lot of advanced features - pretty straight forward, practical stuff
79 * You are encouraged to use this class in your own applications.
80 *
81 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
82 * @package TYPO3
83 * @subpackage t3lib
84 * @see user_xmlversion, user_wapversion
85 */
86 class t3lib_xml {
87 var $topLevelName = 'typo3_test'; // Top element name
88 var $XML_recFields = array(); // Contains a list of fields for each table which should be presented in the XML output
89
90 var $XMLIndent=0;
91 var $Icode='';
92 var $XMLdebug=0;
93 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.
94 var $lines=array();
95
96 /**
97 * Constructor, setting topLevelName to the input var
98 *
99 * @param string Top Level Name
100 * @return void
101 */
102 function t3lib_xml($topLevelName) {
103 $this->topLevelName = $topLevelName;
104 }
105
106 /**
107 * When outputting a input record in XML only fields listed in $this->XML_recFields for the current table will be rendered.
108 *
109 * @param string Table name
110 * @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.
111 * @return void
112 */
113 function setRecFields($table,$list) {
114 $this->XML_recFields[$table]=$list;
115 }
116
117 /**
118 * Returns the result of the XML rendering, basically this is imploding the internal ->lines array with linebreaks.
119 *
120 * @return string
121 */
122 function getResult() {
123 $content = implode(LF,$this->lines);
124 return $this->output($content);
125 }
126
127 /**
128 * Initialize WML (WAP) document with <?xml + <!DOCTYPE header tags and setting ->topLevelName as the first level.
129 *
130 * @return void
131 */
132 function WAPHeader() {
133 $this->lines[]='<?xml version="1.0"?>';
134 $this->lines[]='<!DOCTYPE '.$this->topLevelName.' PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">';
135 $this->newLevel($this->topLevelName,1);
136 }
137
138 /**
139 * Initialize "anonymous" XML document with <?xml + <!DOCTYPE header tags and setting ->topLevelName as the first level.
140 * Encoding is set to UTF-8!
141 *
142 * @return void
143 */
144 function renderHeader() {
145 $this->lines[]='<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
146 $this->lines[]='<!DOCTYPE '.$this->topLevelName.'>';
147 $this->newLevel($this->topLevelName,1);
148 }
149
150 /**
151 * Sets the footer (of ->topLevelName)
152 *
153 * @return void
154 */
155 function renderFooter() {
156 $this->newLevel($this->topLevelName,0);
157 }
158
159 /**
160 * Indents/Outdents a new level named, $name
161 *
162 * @param string The name of the new element for this level
163 * @param boolean If false, then this function call will *end* the level, otherwise create it.
164 * @param array Array of attributes in key/value pairs which will be added to the element (tag), $name
165 * @return void
166 */
167 function newLevel($name,$beginEndFlag=0,$params=array()) {
168 if ($beginEndFlag) {
169 $pList='';
170 if (count($params)) {
171 $par=array();
172 reset($params);
173 while(list($key,$val)=each($params)) {
174 $par[]=$key.'="'.htmlspecialchars($val).'"';
175 }
176 $pList=' '.implode(' ',$par);
177 }
178 $this->lines[]=$this->Icode.'<'.$name.$pList.'>';
179 $this->indent(1);
180 } else {
181 $this->indent(0);
182 $this->lines[]=$this->Icode.'</'.$name.'>';
183 }
184 }
185
186 /**
187 * 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
188 *
189 * @param string The XML content to output
190 * @return string Output
191 */
192 function output($content) {
193 if ($this->XMLdebug) {
194 return '<pre>'.htmlspecialchars($content).'</pre>
195 <hr /><font color="red">Size: '.strlen($content).'</font>';
196 } else {
197 return $content;
198 }
199 }
200
201 /**
202 * Increments/Decrements Indentation counter, ->XMLIndent
203 * 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)
204 *
205 * @param boolean If true the XMLIndent var is increased, otherwise decreased
206 * @return string ->Icode - the prefix string with TAB-chars.
207 */
208 function indent($b) {
209 if ($b) $this->XMLIndent++; else $this->XMLIndent--;
210 $this->Icode='';
211 for ($a=0;$a<$this->XMLIndent;$a++) {
212 $this->Icode.=TAB;
213 }
214 return $this->Icode;
215 }
216
217 /**
218 * Takes a SQL result for $table and traverses it, adding rows
219 *
220 * @param string Tablename
221 * @param pointer SQL resource pointer, should be reset
222 * @return void
223 */
224 function renderRecords($table,$res) {
225 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
226 $this->addRecord($table,$row);
227 }
228 }
229
230 /**
231 * Adds record, $row, from table, $table, to the internal array of XML-lines
232 *
233 * @param string Table name
234 * @param array The row to add to XML structure from the table name
235 * @return void
236 */
237 function addRecord($table,$row) {
238 $this->lines[]=$this->Icode.'<'.$table.' uid="'.$row["uid"].'">';
239 $this->indent(1);
240 $this->getRowInXML($table,$row);
241 $this->indent(0);
242 $this->lines[]=$this->Icode.'</'.$table.'>';
243 }
244
245 /**
246 * Internal function for adding the actual content of the $row from $table to the internal structure.
247 * 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!)
248 * 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.
249 *
250 * @param string Table name
251 * @param array Row from table to add.
252 * @return void
253 * @access private
254 */
255 function getRowInXML($table,$row) {
256 $fields = t3lib_div::trimExplode(',',$this->XML_recFields[$table],1);
257 reset($fields);
258 while(list(,$field)=each($fields)) {
259 if ($row[$field] || $this->includeNonEmptyValues) {
260 $this->lines[]=$this->Icode.$this->fieldWrap($field,$this->substNewline($this->utf8(htmlspecialchars($row[$field]))));
261 }
262 }
263 }
264
265 /**
266 * UTF-8 encodes the input content (from ISO-8859-1!)
267 *
268 * @param string String content to UTF-8 encode
269 * @return string Encoded content.
270 */
271 function utf8($content) {
272 return utf8_encode($content);
273 }
274
275 /**
276 * Substitutes LF characters with a '<newline/>' tag.
277 *
278 * @param string Input value
279 * @return string Processed input value
280 */
281 function substNewline($string) {
282 return str_replace(LF,'<newline/>',$string);
283 }
284
285 /**
286 * Wraps the value in tags with element name, $field.
287 *
288 * @param string Fieldname from a record - will be the element name
289 * @param string Value from the field - will be wrapped in the elements.
290 * @return string The wrapped string.
291 */
292 function fieldWrap($field,$value) {
293 return '<'.$field.'>'.$value.'</'.$field.'>';
294 }
295
296 /**
297 * Creates the BACK button for WAP documents
298 *
299 * @return void
300 */
301 function WAPback() {
302 $this->newLevel('template',1);
303 $this->newLevel('do',1,array('type'=>'accept','label'=>'Back'));
304 $this->addLine('<prev/>');
305 $this->newLevel('do');
306 $this->newLevel('template');
307 }
308
309 /**
310 * Add a line to the internal XML structure (automatically prefixed with ->Icode.
311 *
312 * @param string Line to add to the $this->lines array
313 * @return void
314 */
315 function addLine($str) {
316 $this->lines[]=$this->Icode.$str;
317 }
318 }
319
320
321 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_xml.php']) {
322 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_xml.php']);
323 }
324 ?>