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