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