1 | <?php |
---|
2 | |
---|
3 | /** |
---|
4 | * Zend Framework |
---|
5 | * |
---|
6 | * LICENSE |
---|
7 | * |
---|
8 | * This source file is subject to the new BSD license that is bundled |
---|
9 | * with this package in the file LICENSE.txt. |
---|
10 | * It is also available through the world-wide-web at this URL: |
---|
11 | * http://framework.zend.com/license/new-bsd |
---|
12 | * If you did not receive a copy of the license and are unable to |
---|
13 | * obtain it through the world-wide-web, please send an email |
---|
14 | * to license@zend.com so we can send you a copy immediately. |
---|
15 | * |
---|
16 | * @category Zend |
---|
17 | * @package Zend_Gdata |
---|
18 | * @subpackage App |
---|
19 | * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) |
---|
20 | * @license http://framework.zend.com/license/new-bsd New BSD License |
---|
21 | * @version $Id: Base.php 24594 2012-01-05 21:27:01Z matthew $ |
---|
22 | */ |
---|
23 | |
---|
24 | /** |
---|
25 | * @see Zend_Gdata_App_Util |
---|
26 | */ |
---|
27 | require_once 'Zend/Gdata/App/Util.php'; |
---|
28 | |
---|
29 | /** |
---|
30 | * Abstract class for all XML elements |
---|
31 | * |
---|
32 | * @category Zend |
---|
33 | * @package Zend_Gdata |
---|
34 | * @subpackage App |
---|
35 | * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) |
---|
36 | * @license http://framework.zend.com/license/new-bsd New BSD License |
---|
37 | */ |
---|
38 | abstract class Zend_Gdata_App_Base |
---|
39 | { |
---|
40 | |
---|
41 | /** |
---|
42 | * @var string The XML element name, including prefix if desired |
---|
43 | */ |
---|
44 | protected $_rootElement = null; |
---|
45 | |
---|
46 | /** |
---|
47 | * @var string The XML namespace prefix |
---|
48 | */ |
---|
49 | protected $_rootNamespace = 'atom'; |
---|
50 | |
---|
51 | /** |
---|
52 | * @var string The XML namespace URI - takes precedence over lookup up the |
---|
53 | * corresponding URI for $_rootNamespace |
---|
54 | */ |
---|
55 | protected $_rootNamespaceURI = null; |
---|
56 | |
---|
57 | /** |
---|
58 | * @var array Leftover elements which were not handled |
---|
59 | */ |
---|
60 | protected $_extensionElements = array(); |
---|
61 | |
---|
62 | /** |
---|
63 | * @var array Leftover attributes which were not handled |
---|
64 | */ |
---|
65 | protected $_extensionAttributes = array(); |
---|
66 | |
---|
67 | /** |
---|
68 | * @var string XML child text node content |
---|
69 | */ |
---|
70 | protected $_text = null; |
---|
71 | |
---|
72 | /** |
---|
73 | * @var array Memoized results from calls to lookupNamespace() to avoid |
---|
74 | * expensive calls to getGreatestBoundedValue(). The key is in the |
---|
75 | * form 'prefix-majorVersion-minorVersion', and the value is the |
---|
76 | * output from getGreatestBoundedValue(). |
---|
77 | */ |
---|
78 | protected static $_namespaceLookupCache = array(); |
---|
79 | |
---|
80 | /** |
---|
81 | * List of namespaces, as a three-dimensional array. The first dimension |
---|
82 | * represents the namespace prefix, the second dimension represents the |
---|
83 | * minimum major protocol version, and the third dimension is the minimum |
---|
84 | * minor protocol version. Null keys are NOT allowed. |
---|
85 | * |
---|
86 | * When looking up a namespace for a given prefix, the greatest version |
---|
87 | * number (both major and minor) which is less than the effective version |
---|
88 | * should be used. |
---|
89 | * |
---|
90 | * @see lookupNamespace() |
---|
91 | * @see registerNamespace() |
---|
92 | * @see registerAllNamespaces() |
---|
93 | * @var array |
---|
94 | */ |
---|
95 | protected $_namespaces = array( |
---|
96 | 'atom' => array( |
---|
97 | 1 => array( |
---|
98 | 0 => 'http://www.w3.org/2005/Atom' |
---|
99 | ) |
---|
100 | ), |
---|
101 | 'app' => array( |
---|
102 | 1 => array( |
---|
103 | 0 => 'http://purl.org/atom/app#' |
---|
104 | ), |
---|
105 | 2 => array( |
---|
106 | 0 => 'http://www.w3.org/2007/app' |
---|
107 | ) |
---|
108 | ) |
---|
109 | ); |
---|
110 | |
---|
111 | public function __construct() |
---|
112 | { |
---|
113 | } |
---|
114 | |
---|
115 | /** |
---|
116 | * Returns the child text node of this element |
---|
117 | * This represents any raw text contained within the XML element |
---|
118 | * |
---|
119 | * @return string Child text node |
---|
120 | */ |
---|
121 | public function getText($trim = true) |
---|
122 | { |
---|
123 | if ($trim) { |
---|
124 | return trim($this->_text); |
---|
125 | } else { |
---|
126 | return $this->_text; |
---|
127 | } |
---|
128 | } |
---|
129 | |
---|
130 | /** |
---|
131 | * Sets the child text node of this element |
---|
132 | * This represents any raw text contained within the XML element |
---|
133 | * |
---|
134 | * @param string $value Child text node |
---|
135 | * @return Zend_Gdata_App_Base Returns an object of the same type as 'this' to provide a fluent interface. |
---|
136 | */ |
---|
137 | public function setText($value) |
---|
138 | { |
---|
139 | $this->_text = $value; |
---|
140 | return $this; |
---|
141 | } |
---|
142 | |
---|
143 | /** |
---|
144 | * Returns an array of all elements not matched to data model classes |
---|
145 | * during the parsing of the XML |
---|
146 | * |
---|
147 | * @return array All elements not matched to data model classes during parsing |
---|
148 | */ |
---|
149 | public function getExtensionElements() |
---|
150 | { |
---|
151 | return $this->_extensionElements; |
---|
152 | } |
---|
153 | |
---|
154 | /** |
---|
155 | * Sets an array of all elements not matched to data model classes |
---|
156 | * during the parsing of the XML. This method can be used to add arbitrary |
---|
157 | * child XML elements to any data model class. |
---|
158 | * |
---|
159 | * @param array $value All extension elements |
---|
160 | * @return Zend_Gdata_App_Base Returns an object of the same type as 'this' to provide a fluent interface. |
---|
161 | */ |
---|
162 | public function setExtensionElements($value) |
---|
163 | { |
---|
164 | $this->_extensionElements = $value; |
---|
165 | return $this; |
---|
166 | } |
---|
167 | |
---|
168 | /** |
---|
169 | * Returns an array of all extension attributes not transformed into data |
---|
170 | * model properties during parsing of the XML. Each element of the array |
---|
171 | * is a hashed array of the format: |
---|
172 | * array('namespaceUri' => string, 'name' => string, 'value' => string); |
---|
173 | * |
---|
174 | * @return array All extension attributes |
---|
175 | */ |
---|
176 | public function getExtensionAttributes() |
---|
177 | { |
---|
178 | return $this->_extensionAttributes; |
---|
179 | } |
---|
180 | |
---|
181 | /** |
---|
182 | * Sets an array of all extension attributes not transformed into data |
---|
183 | * model properties during parsing of the XML. Each element of the array |
---|
184 | * is a hashed array of the format: |
---|
185 | * array('namespaceUri' => string, 'name' => string, 'value' => string); |
---|
186 | * This can be used to add arbitrary attributes to any data model element |
---|
187 | * |
---|
188 | * @param array $value All extension attributes |
---|
189 | * @return Zend_Gdata_App_Base Returns an object of the same type as 'this' to provide a fluent interface. |
---|
190 | */ |
---|
191 | public function setExtensionAttributes($value) |
---|
192 | { |
---|
193 | $this->_extensionAttributes = $value; |
---|
194 | return $this; |
---|
195 | } |
---|
196 | |
---|
197 | /** |
---|
198 | * Retrieves a DOMElement which corresponds to this element and all |
---|
199 | * child properties. This is used to build an entry back into a DOM |
---|
200 | * and eventually XML text for sending to the server upon updates, or |
---|
201 | * for application storage/persistence. |
---|
202 | * |
---|
203 | * @param DOMDocument $doc The DOMDocument used to construct DOMElements |
---|
204 | * @return DOMElement The DOMElement representing this element and all |
---|
205 | * child properties. |
---|
206 | */ |
---|
207 | public function getDOM($doc = null, $majorVersion = 1, $minorVersion = null) |
---|
208 | { |
---|
209 | if ($doc === null) { |
---|
210 | $doc = new DOMDocument('1.0', 'utf-8'); |
---|
211 | } |
---|
212 | if ($this->_rootNamespaceURI != null) { |
---|
213 | $element = $doc->createElementNS($this->_rootNamespaceURI, $this->_rootElement); |
---|
214 | } elseif ($this->_rootNamespace !== null) { |
---|
215 | if (strpos($this->_rootElement, ':') === false) { |
---|
216 | $elementName = $this->_rootNamespace . ':' . $this->_rootElement; |
---|
217 | } else { |
---|
218 | $elementName = $this->_rootElement; |
---|
219 | } |
---|
220 | $element = $doc->createElementNS($this->lookupNamespace($this->_rootNamespace), $elementName); |
---|
221 | } else { |
---|
222 | $element = $doc->createElement($this->_rootElement); |
---|
223 | } |
---|
224 | if ($this->_text != null) { |
---|
225 | $element->appendChild($element->ownerDocument->createTextNode($this->_text)); |
---|
226 | } |
---|
227 | foreach ($this->_extensionElements as $extensionElement) { |
---|
228 | $element->appendChild($extensionElement->getDOM($element->ownerDocument)); |
---|
229 | } |
---|
230 | foreach ($this->_extensionAttributes as $attribute) { |
---|
231 | $element->setAttribute($attribute['name'], $attribute['value']); |
---|
232 | } |
---|
233 | return $element; |
---|
234 | } |
---|
235 | |
---|
236 | /** |
---|
237 | * Given a child DOMNode, tries to determine how to map the data into |
---|
238 | * object instance members. If no mapping is defined, Extension_Element |
---|
239 | * objects are created and stored in an array. |
---|
240 | * |
---|
241 | * @param DOMNode $child The DOMNode needed to be handled |
---|
242 | */ |
---|
243 | protected function takeChildFromDOM($child) |
---|
244 | { |
---|
245 | if ($child->nodeType == XML_TEXT_NODE) { |
---|
246 | $this->_text = $child->nodeValue; |
---|
247 | } else { |
---|
248 | $extensionElement = new Zend_Gdata_App_Extension_Element(); |
---|
249 | $extensionElement->transferFromDOM($child); |
---|
250 | $this->_extensionElements[] = $extensionElement; |
---|
251 | } |
---|
252 | } |
---|
253 | |
---|
254 | /** |
---|
255 | * Given a DOMNode representing an attribute, tries to map the data into |
---|
256 | * instance members. If no mapping is defined, the name and value are |
---|
257 | * stored in an array. |
---|
258 | * |
---|
259 | * @param DOMNode $attribute The DOMNode attribute needed to be handled |
---|
260 | */ |
---|
261 | protected function takeAttributeFromDOM($attribute) |
---|
262 | { |
---|
263 | $arrayIndex = ($attribute->namespaceURI != '')?( |
---|
264 | $attribute->namespaceURI . ':' . $attribute->name): |
---|
265 | $attribute->name; |
---|
266 | $this->_extensionAttributes[$arrayIndex] = |
---|
267 | array('namespaceUri' => $attribute->namespaceURI, |
---|
268 | 'name' => $attribute->localName, |
---|
269 | 'value' => $attribute->nodeValue); |
---|
270 | } |
---|
271 | |
---|
272 | /** |
---|
273 | * Transfers each child and attribute into member variables. |
---|
274 | * This is called when XML is received over the wire and the data |
---|
275 | * model needs to be built to represent this XML. |
---|
276 | * |
---|
277 | * @param DOMNode $node The DOMNode that represents this object's data |
---|
278 | */ |
---|
279 | public function transferFromDOM($node) |
---|
280 | { |
---|
281 | foreach ($node->childNodes as $child) { |
---|
282 | $this->takeChildFromDOM($child); |
---|
283 | } |
---|
284 | foreach ($node->attributes as $attribute) { |
---|
285 | $this->takeAttributeFromDOM($attribute); |
---|
286 | } |
---|
287 | } |
---|
288 | |
---|
289 | /** |
---|
290 | * Parses the provided XML text and generates data model classes for |
---|
291 | * each know element by turning the XML text into a DOM tree and calling |
---|
292 | * transferFromDOM($element). The first data model element with the same |
---|
293 | * name as $this->_rootElement is used and the child elements are |
---|
294 | * recursively parsed. |
---|
295 | * |
---|
296 | * @param string $xml The XML text to parse |
---|
297 | */ |
---|
298 | public function transferFromXML($xml) |
---|
299 | { |
---|
300 | if ($xml) { |
---|
301 | // Load the feed as an XML DOMDocument object |
---|
302 | @ini_set('track_errors', 1); |
---|
303 | $doc = new DOMDocument(); |
---|
304 | $success = @$doc->loadXML($xml); |
---|
305 | @ini_restore('track_errors'); |
---|
306 | if (!$success) { |
---|
307 | require_once 'Zend/Gdata/App/Exception.php'; |
---|
308 | throw new Zend_Gdata_App_Exception("DOMDocument cannot parse XML: $php_errormsg"); |
---|
309 | } |
---|
310 | $element = $doc->getElementsByTagName($this->_rootElement)->item(0); |
---|
311 | if (!$element) { |
---|
312 | require_once 'Zend/Gdata/App/Exception.php'; |
---|
313 | throw new Zend_Gdata_App_Exception('No root <' . $this->_rootElement . '> element'); |
---|
314 | } |
---|
315 | $this->transferFromDOM($element); |
---|
316 | } else { |
---|
317 | require_once 'Zend/Gdata/App/Exception.php'; |
---|
318 | throw new Zend_Gdata_App_Exception('XML passed to transferFromXML cannot be null'); |
---|
319 | } |
---|
320 | } |
---|
321 | |
---|
322 | /** |
---|
323 | * Converts this element and all children into XML text using getDOM() |
---|
324 | * |
---|
325 | * @return string XML content |
---|
326 | */ |
---|
327 | public function saveXML() |
---|
328 | { |
---|
329 | $element = $this->getDOM(); |
---|
330 | return $element->ownerDocument->saveXML($element); |
---|
331 | } |
---|
332 | |
---|
333 | /** |
---|
334 | * Alias for saveXML() returns XML content for this element and all |
---|
335 | * children |
---|
336 | * |
---|
337 | * @return string XML content |
---|
338 | */ |
---|
339 | public function getXML() |
---|
340 | { |
---|
341 | return $this->saveXML(); |
---|
342 | } |
---|
343 | |
---|
344 | /** |
---|
345 | * Alias for saveXML() |
---|
346 | * |
---|
347 | * Can be overridden by children to provide more complex representations |
---|
348 | * of entries. |
---|
349 | * |
---|
350 | * @return string Encoded string content |
---|
351 | */ |
---|
352 | public function encode() |
---|
353 | { |
---|
354 | return $this->saveXML(); |
---|
355 | } |
---|
356 | |
---|
357 | /** |
---|
358 | * Get the full version of a namespace prefix |
---|
359 | * |
---|
360 | * Looks up a prefix (atom:, etc.) in the list of registered |
---|
361 | * namespaces and returns the full namespace URI if |
---|
362 | * available. Returns the prefix, unmodified, if it's not |
---|
363 | * registered. |
---|
364 | * |
---|
365 | * @param string $prefix The namespace prefix to lookup. |
---|
366 | * @param integer $majorVersion The major protocol version in effect. |
---|
367 | * Defaults to '1'. |
---|
368 | * @param integer $minorVersion The minor protocol version in effect. |
---|
369 | * Defaults to null (use latest). |
---|
370 | * @return string |
---|
371 | */ |
---|
372 | public function lookupNamespace($prefix, |
---|
373 | $majorVersion = 1, |
---|
374 | $minorVersion = null) |
---|
375 | { |
---|
376 | // Check for a memoized result |
---|
377 | $key = $prefix . ' ' . |
---|
378 | ($majorVersion === null ? 'NULL' : $majorVersion) . |
---|
379 | ' '. ($minorVersion === null ? 'NULL' : $minorVersion); |
---|
380 | if (array_key_exists($key, self::$_namespaceLookupCache)) |
---|
381 | return self::$_namespaceLookupCache[$key]; |
---|
382 | // If no match, return the prefix by default |
---|
383 | $result = $prefix; |
---|
384 | |
---|
385 | // Find tuple of keys that correspond to the namespace we should use |
---|
386 | if (isset($this->_namespaces[$prefix])) { |
---|
387 | // Major version search |
---|
388 | $nsData = $this->_namespaces[$prefix]; |
---|
389 | $foundMajorV = Zend_Gdata_App_Util::findGreatestBoundedValue( |
---|
390 | $majorVersion, $nsData); |
---|
391 | // Minor version search |
---|
392 | $nsData = $nsData[$foundMajorV]; |
---|
393 | $foundMinorV = Zend_Gdata_App_Util::findGreatestBoundedValue( |
---|
394 | $minorVersion, $nsData); |
---|
395 | // Extract NS |
---|
396 | $result = $nsData[$foundMinorV]; |
---|
397 | } |
---|
398 | |
---|
399 | // Memoize result |
---|
400 | self::$_namespaceLookupCache[$key] = $result; |
---|
401 | |
---|
402 | return $result; |
---|
403 | } |
---|
404 | |
---|
405 | /** |
---|
406 | * Add a namespace and prefix to the registered list |
---|
407 | * |
---|
408 | * Takes a prefix and a full namespace URI and adds them to the |
---|
409 | * list of registered namespaces for use by |
---|
410 | * $this->lookupNamespace(). |
---|
411 | * |
---|
412 | * WARNING: Currently, registering a namespace will NOT invalidate any |
---|
413 | * memoized data stored in $_namespaceLookupCache. Under normal |
---|
414 | * use, this behavior is acceptable. If you are adding |
---|
415 | * contradictory data to the namespace lookup table, you must |
---|
416 | * call flushNamespaceLookupCache(). |
---|
417 | * |
---|
418 | * @param string $prefix The namespace prefix |
---|
419 | * @param string $namespaceUri The full namespace URI |
---|
420 | * @param integer $majorVersion The major protocol version in effect. |
---|
421 | * Defaults to '1'. |
---|
422 | * @param integer $minorVersion The minor protocol version in effect. |
---|
423 | * Defaults to null (use latest). |
---|
424 | * @return void |
---|
425 | */ |
---|
426 | public function registerNamespace($prefix, |
---|
427 | $namespaceUri, |
---|
428 | $majorVersion = 1, |
---|
429 | $minorVersion = 0) |
---|
430 | { |
---|
431 | $this->_namespaces[$prefix][$majorVersion][$minorVersion] = |
---|
432 | $namespaceUri; |
---|
433 | } |
---|
434 | |
---|
435 | /** |
---|
436 | * Flush namespace lookup cache. |
---|
437 | * |
---|
438 | * Empties the namespace lookup cache. Call this function if you have |
---|
439 | * added data to the namespace lookup table that contradicts values that |
---|
440 | * may have been cached during a previous call to lookupNamespace(). |
---|
441 | */ |
---|
442 | public static function flushNamespaceLookupCache() |
---|
443 | { |
---|
444 | self::$_namespaceLookupCache = array(); |
---|
445 | } |
---|
446 | |
---|
447 | /** |
---|
448 | * Add an array of namespaces to the registered list. |
---|
449 | * |
---|
450 | * Takes an array in the format of: |
---|
451 | * namespace prefix, namespace URI, major protocol version, |
---|
452 | * minor protocol version and adds them with calls to ->registerNamespace() |
---|
453 | * |
---|
454 | * @param array $namespaceArray An array of namespaces. |
---|
455 | * @return void |
---|
456 | */ |
---|
457 | public function registerAllNamespaces($namespaceArray) |
---|
458 | { |
---|
459 | foreach($namespaceArray as $namespace) { |
---|
460 | $this->registerNamespace( |
---|
461 | $namespace[0], $namespace[1], $namespace[2], $namespace[3]); |
---|
462 | } |
---|
463 | } |
---|
464 | |
---|
465 | |
---|
466 | /** |
---|
467 | * Magic getter to allow access like $entry->foo to call $entry->getFoo() |
---|
468 | * Alternatively, if no getFoo() is defined, but a $_foo protected variable |
---|
469 | * is defined, this is returned. |
---|
470 | * |
---|
471 | * TODO Remove ability to bypass getFoo() methods?? |
---|
472 | * |
---|
473 | * @param string $name The variable name sought |
---|
474 | */ |
---|
475 | public function __get($name) |
---|
476 | { |
---|
477 | $method = 'get'.ucfirst($name); |
---|
478 | if (method_exists($this, $method)) { |
---|
479 | return call_user_func(array(&$this, $method)); |
---|
480 | } else if (property_exists($this, "_${name}")) { |
---|
481 | return $this->{'_' . $name}; |
---|
482 | } else { |
---|
483 | require_once 'Zend/Gdata/App/InvalidArgumentException.php'; |
---|
484 | throw new Zend_Gdata_App_InvalidArgumentException( |
---|
485 | 'Property ' . $name . ' does not exist'); |
---|
486 | } |
---|
487 | } |
---|
488 | |
---|
489 | /** |
---|
490 | * Magic setter to allow acces like $entry->foo='bar' to call |
---|
491 | * $entry->setFoo('bar') automatically. |
---|
492 | * |
---|
493 | * Alternatively, if no setFoo() is defined, but a $_foo protected variable |
---|
494 | * is defined, this is returned. |
---|
495 | * |
---|
496 | * TODO Remove ability to bypass getFoo() methods?? |
---|
497 | * |
---|
498 | * @param string $name |
---|
499 | * @param string $value |
---|
500 | */ |
---|
501 | public function __set($name, $val) |
---|
502 | { |
---|
503 | $method = 'set'.ucfirst($name); |
---|
504 | if (method_exists($this, $method)) { |
---|
505 | return call_user_func(array(&$this, $method), $val); |
---|
506 | } else if (isset($this->{'_' . $name}) || ($this->{'_' . $name} === null)) { |
---|
507 | $this->{'_' . $name} = $val; |
---|
508 | } else { |
---|
509 | require_once 'Zend/Gdata/App/InvalidArgumentException.php'; |
---|
510 | throw new Zend_Gdata_App_InvalidArgumentException( |
---|
511 | 'Property ' . $name . ' does not exist'); |
---|
512 | } |
---|
513 | } |
---|
514 | |
---|
515 | /** |
---|
516 | * Magic __isset method |
---|
517 | * |
---|
518 | * @param string $name |
---|
519 | */ |
---|
520 | public function __isset($name) |
---|
521 | { |
---|
522 | $rc = new ReflectionClass(get_class($this)); |
---|
523 | $privName = '_' . $name; |
---|
524 | if (!($rc->hasProperty($privName))) { |
---|
525 | require_once 'Zend/Gdata/App/InvalidArgumentException.php'; |
---|
526 | throw new Zend_Gdata_App_InvalidArgumentException( |
---|
527 | 'Property ' . $name . ' does not exist'); |
---|
528 | } else { |
---|
529 | if (isset($this->{$privName})) { |
---|
530 | if (is_array($this->{$privName})) { |
---|
531 | if (count($this->{$privName}) > 0) { |
---|
532 | return true; |
---|
533 | } else { |
---|
534 | return false; |
---|
535 | } |
---|
536 | } else { |
---|
537 | return true; |
---|
538 | } |
---|
539 | } else { |
---|
540 | return false; |
---|
541 | } |
---|
542 | } |
---|
543 | } |
---|
544 | |
---|
545 | /** |
---|
546 | * Magic __unset method |
---|
547 | * |
---|
548 | * @param string $name |
---|
549 | */ |
---|
550 | public function __unset($name) |
---|
551 | { |
---|
552 | if (isset($this->{'_' . $name})) { |
---|
553 | if (is_array($this->{'_' . $name})) { |
---|
554 | $this->{'_' . $name} = array(); |
---|
555 | } else { |
---|
556 | $this->{'_' . $name} = null; |
---|
557 | } |
---|
558 | } |
---|
559 | } |
---|
560 | |
---|
561 | /** |
---|
562 | * Magic toString method allows using this directly via echo |
---|
563 | * Works best in PHP >= 4.2.0 |
---|
564 | * |
---|
565 | * @return string The text representation of this object |
---|
566 | */ |
---|
567 | public function __toString() |
---|
568 | { |
---|
569 | return $this->getText(); |
---|
570 | } |
---|
571 | |
---|
572 | } |
---|