| [ Index ] |
|
Code source de phpMyVisites 2.3 |
1 <?PHP 2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 3 4 /** 5 * XML_Serializer 6 * 7 * Creates XML documents from PHP data structures like arrays, objects or scalars. 8 * 9 * PHP versions 4 and 5 10 * 11 * LICENSE: This source file is subject to version 3.0 of the PHP license 12 * that is available through the world-wide-web at the following URI: 13 * http://www.php.net/license/3_0.txt. If you did not receive a copy of 14 * the PHP License and are unable to obtain it through the web, please 15 * send a note to license@php.net so we can mail you a copy immediately. 16 * 17 * @category XML 18 * @package XML_Serializer 19 * @author Stephan Schmidt <schst@php.net> 20 * @copyright 1997-2005 The PHP Group 21 * @license http://www.php.net/license/3_0.txt PHP License 3.0 22 * @version CVS: $Id: Serializer.php,v 1.1 2005/12/06 01:50:39 matthieu_ Exp $ 23 * @link http://pear.php.net/package/XML_Serializer 24 * @see XML_Unserializer 25 */ 26 27 /** 28 * uses PEAR error management 29 */ 30 require_once 'PEAR.php'; 31 32 /** 33 * uses XML_Util to create XML tags 34 */ 35 require_once 'Xml/Util.php'; 36 37 /** 38 * option: string used for indentation 39 * 40 * Possible values: 41 * - any string (default is any string) 42 */ 43 define('XML_SERIALIZER_OPTION_INDENT', 'indent'); 44 45 /** 46 * option: string used for linebreaks 47 * 48 * Possible values: 49 * - any string (default is \n) 50 */ 51 define('XML_SERIALIZER_OPTION_LINEBREAKS', 'linebreak'); 52 53 /** 54 * option: enable type hints 55 * 56 * Possible values: 57 * - true 58 * - false 59 */ 60 define('XML_SERIALIZER_OPTION_TYPEHINTS', 'typeHints'); 61 62 /** 63 * option: add an XML declaration 64 * 65 * Possible values: 66 * - true 67 * - false 68 */ 69 define('XML_SERIALIZER_OPTION_XML_DECL_ENABLED', 'addDecl'); 70 71 /** 72 * option: encoding of the document 73 * 74 * Possible values: 75 * - any valid encoding 76 * - null (default) 77 */ 78 define('XML_SERIALIZER_OPTION_XML_ENCODING', 'encoding'); 79 80 /** 81 * option: default name for tags 82 * 83 * Possible values: 84 * - any string (XML_Serializer_Tag is default) 85 */ 86 define('XML_SERIALIZER_OPTION_DEFAULT_TAG', 'defaultTagName'); 87 88 /** 89 * option: use classname for objects in indexed arrays 90 * 91 * Possible values: 92 * - true (default) 93 * - false 94 */ 95 define('XML_SERIALIZER_OPTION_CLASSNAME_AS_TAGNAME', 'classAsTagName'); 96 97 /** 98 * option: attribute where original key is stored 99 * 100 * Possible values: 101 * - any string (default is _originalKey) 102 */ 103 define('XML_SERIALIZER_OPTION_ATTRIBUTE_KEY', 'keyAttribute'); 104 105 /** 106 * option: attribute for type (only if typeHints => true) 107 * 108 * Possible values: 109 * - any string (default is _type) 110 */ 111 define('XML_SERIALIZER_OPTION_ATTRIBUTE_TYPE', 'typeAttribute'); 112 113 /** 114 * option: attribute for class (only if typeHints => true) 115 * 116 * Possible values: 117 * - any string (default is _class) 118 */ 119 define('XML_SERIALIZER_OPTION_ATTRIBUTE_CLASS', 'classAttribute'); 120 121 /** 122 * option: scalar values (strings, ints,..) will be serialized as attribute 123 * 124 * Possible values: 125 * - true 126 * - false (default) 127 */ 128 define('XML_SERIALIZER_OPTION_SCALAR_AS_ATTRIBUTES', 'scalarAsAttributes'); 129 130 /** 131 * option: prepend string for attributes 132 * 133 * Possible values: 134 * - any string (default is any string) 135 */ 136 define('XML_SERIALIZER_OPTION_PREPEND_ATTRIBUTES', 'prependAttributes'); 137 138 /** 139 * option: indent the attributes, if set to '_auto', it will indent attributes so they all start at the same column 140 * 141 * Possible values: 142 * - true 143 * - false (default) 144 */ 145 define('XML_SERIALIZER_OPTION_INDENT_ATTRIBUTES', 'indentAttributes'); 146 147 /** 148 * option: use 'simplexml' to use parent name as tagname if transforming an indexed array 149 * 150 * Possible values: 151 * - XML_SERIALIZER_MODE_DEFAULT (default) 152 * - XML_SERIALIZER_MODE_SIMPLEXML 153 */ 154 define('XML_SERIALIZER_OPTION_MODE', 'mode'); 155 156 /** 157 * option: add a doctype declaration 158 * 159 * Possible values: 160 * - true 161 * - false (default) 162 */ 163 define('XML_SERIALIZER_OPTION_DOCTYPE_ENABLED', 'addDoctype'); 164 165 /** 166 * option: supply a string or an array with id and uri ({@see XML_Util::getDoctypeDeclaration()} 167 * 168 * Possible values: 169 * - string 170 * - array 171 */ 172 define('XML_SERIALIZER_OPTION_DOCTYPE', 'doctype'); 173 174 /** 175 * option: name of the root tag 176 * 177 * Possible values: 178 * - string 179 * - null (default) 180 */ 181 define('XML_SERIALIZER_OPTION_ROOT_NAME', 'rootName'); 182 183 /** 184 * option: attributes of the root tag 185 * 186 * Possible values: 187 * - array 188 */ 189 define('XML_SERIALIZER_OPTION_ROOT_ATTRIBS', 'rootAttributes'); 190 191 /** 192 * option: all values in this key will be treated as attributes 193 * 194 * Possible values: 195 * - array 196 */ 197 define('XML_SERIALIZER_OPTION_ATTRIBUTES_KEY', 'attributesArray'); 198 199 /** 200 * option: this value will be used directly as content, instead of creating a new tag, may only be used in conjuction with attributesArray 201 * 202 * Possible values: 203 * - string 204 * - null (default) 205 */ 206 define('XML_SERIALIZER_OPTION_CONTENT_KEY', 'contentName'); 207 208 /** 209 * option: this value will be used in a comment, instead of creating a new tag 210 * 211 * Possible values: 212 * - string 213 * - null (default) 214 */ 215 define('XML_SERIALIZER_OPTION_COMMENT_KEY', 'commentName'); 216 217 /** 218 * option: tag names that will be changed 219 * 220 * Possible values: 221 * - array 222 */ 223 define('XML_SERIALIZER_OPTION_TAGMAP', 'tagMap'); 224 225 /** 226 * option: function that will be applied before serializing 227 * 228 * Possible values: 229 * - any valid PHP callback 230 */ 231 define('XML_SERIALIZER_OPTION_ENCODE_FUNC', 'encodeFunction'); 232 233 /** 234 * option: function that will be applied before serializing 235 * 236 * Possible values: 237 * - string 238 * - null (default) 239 */ 240 define('XML_SERIALIZER_OPTION_NAMESPACE', 'namespace'); 241 242 /** 243 * option: type of entities to replace 244 * 245 * Possible values: 246 * - XML_SERIALIZER_ENTITIES_NONE 247 * - XML_SERIALIZER_ENTITIES_XML (default) 248 * - XML_SERIALIZER_ENTITIES_XML_REQUIRED 249 * - XML_SERIALIZER_ENTITIES_HTML 250 */ 251 define('XML_SERIALIZER_OPTION_ENTITIES', 'replaceEntities'); 252 253 /** 254 * option: whether to return the result of the serialization from serialize() 255 * 256 * Possible values: 257 * - true 258 * - false (default) 259 */ 260 define('XML_SERIALIZER_OPTION_RETURN_RESULT', 'returnResult'); 261 262 /** 263 * option: whether to ignore properties that are set to null 264 * 265 * Possible values: 266 * - true 267 * - false (default) 268 */ 269 define('XML_SERIALIZER_OPTION_IGNORE_NULL', 'ignoreNull'); 270 271 /** 272 * default mode 273 */ 274 define('XML_SERIALIZER_MODE_DEFAULT', 'default'); 275 276 /** 277 * SimpleXML mode 278 * 279 * When serializing indexed arrays, the key of the parent value is used as a tagname. 280 */ 281 define('XML_SERIALIZER_MODE_SIMPLEXML', 'simplexml'); 282 283 /** 284 * error code for no serialization done 285 */ 286 define('XML_SERIALIZER_ERROR_NO_SERIALIZATION', 51); 287 288 /** 289 * do not replace entitites 290 */ 291 define('XML_SERIALIZER_ENTITIES_NONE', XML_UTIL_ENTITIES_NONE); 292 293 /** 294 * replace all XML entitites 295 * This setting will replace <, >, ", ' and & 296 */ 297 define('XML_SERIALIZER_ENTITIES_XML', XML_UTIL_ENTITIES_XML); 298 299 /** 300 * replace only required XML entitites 301 * This setting will replace <, " and & 302 */ 303 define('XML_SERIALIZER_ENTITIES_XML_REQUIRED', XML_UTIL_ENTITIES_XML_REQUIRED); 304 305 /** 306 * replace HTML entitites 307 * @link http://www.php.net/htmlentities 308 */ 309 define('XML_SERIALIZER_ENTITIES_HTML', XML_UTIL_ENTITIES_HTML); 310 311 /** 312 * Creates XML documents from PHP data structures like arrays, objects or scalars. 313 * 314 * this class can be used in two modes: 315 * 316 * 1. create an XML document from an array or object that is processed by other 317 * applications. That means, you can create a RDF document from an array in the 318 * following format: 319 * 320 * $data = array( 321 * 'channel' => array( 322 * 'title' => 'Example RDF channel', 323 * 'link' => 'http://www.php-tools.de', 324 * 'image' => array( 325 * 'title' => 'Example image', 326 * 'url' => 'http://www.php-tools.de/image.gif', 327 * 'link' => 'http://www.php-tools.de' 328 * ), 329 * array( 330 * 'title' => 'Example item', 331 * 'link' => 'http://example.com' 332 * ), 333 * array( 334 * 'title' => 'Another Example item', 335 * 'link' => 'http://example.org' 336 * ) 337 * ) 338 * ); 339 * 340 * to create a RDF document from this array do the following: 341 * 342 * require_once 'XML/Serializer.php'; 343 * 344 * $options = array( 345 * XML_SERIALIZER_OPTION_INDENT => "\t", // indent with tabs 346 * XML_SERIALIZER_OPTION_LINEBREAKS => "\n", // use UNIX line breaks 347 * XML_SERIALIZER_OPTION_ROOT_NAME => 'rdf:RDF', // root tag 348 * XML_SERIALIZER_OPTION_DEFAULT_TAG => 'item' // tag for values with numeric keys 349 * ); 350 * 351 * $serializer = new XML_Serializer($options); 352 * $rdf = $serializer->serialize($data); 353 * 354 * You will get a complete XML document that can be processed like any RDF document. 355 * 356 * 2. this classes can be used to serialize any data structure in a way that it can 357 * later be unserialized again. 358 * XML_Serializer will store the type of the value and additional meta information 359 * in attributes of the surrounding tag. This meat information can later be used 360 * to restore the original data structure in PHP. If you want XML_Serializer 361 * to add meta information to the tags, add 362 * 363 * XML_SERIALIZER_OPTION_TYPEHINTS => true 364 * 365 * to the options array in the constructor. 366 * 367 * @category XML 368 * @package XML_Serializer 369 * @author Stephan Schmidt <schst@php.net> 370 * @copyright 1997-2005 The PHP Group 371 * @license http://www.php.net/license/3_0.txt PHP License 3.0 372 * @version Release: 0.16.0 373 * @link http://pear.php.net/package/XML_Serializer 374 * @see XML_Unserializer 375 */ 376 class XML_Serializer extends PEAR 377 { 378 /** 379 * list of all available options 380 * 381 * @access private 382 * @var array 383 */ 384 var $_knownOptions = array( 385 XML_SERIALIZER_OPTION_INDENT, 386 XML_SERIALIZER_OPTION_LINEBREAKS, 387 XML_SERIALIZER_OPTION_TYPEHINTS, 388 XML_SERIALIZER_OPTION_XML_DECL_ENABLED, 389 XML_SERIALIZER_OPTION_XML_ENCODING, 390 XML_SERIALIZER_OPTION_DEFAULT_TAG, 391 XML_SERIALIZER_OPTION_CLASSNAME_AS_TAGNAME, 392 XML_SERIALIZER_OPTION_ATTRIBUTE_KEY, 393 XML_SERIALIZER_OPTION_ATTRIBUTE_TYPE, 394 XML_SERIALIZER_OPTION_ATTRIBUTE_CLASS, 395 XML_SERIALIZER_OPTION_SCALAR_AS_ATTRIBUTES, 396 XML_SERIALIZER_OPTION_PREPEND_ATTRIBUTES, 397 XML_SERIALIZER_OPTION_INDENT_ATTRIBUTES, 398 XML_SERIALIZER_OPTION_MODE, 399 XML_SERIALIZER_OPTION_DOCTYPE_ENABLED, 400 XML_SERIALIZER_OPTION_DOCTYPE, 401 XML_SERIALIZER_OPTION_ROOT_NAME, 402 XML_SERIALIZER_OPTION_ROOT_ATTRIBS, 403 XML_SERIALIZER_OPTION_ATTRIBUTES_KEY, 404 XML_SERIALIZER_OPTION_CONTENT_KEY, 405 XML_SERIALIZER_OPTION_COMMENT_KEY, 406 XML_SERIALIZER_OPTION_TAGMAP, 407 XML_SERIALIZER_OPTION_ENCODE_FUNC, 408 XML_SERIALIZER_OPTION_NAMESPACE, 409 XML_SERIALIZER_OPTION_ENTITIES, 410 XML_SERIALIZER_OPTION_RETURN_RESULT, 411 XML_SERIALIZER_OPTION_IGNORE_NULL, 412 ); 413 414 /** 415 * default options for the serialization 416 * 417 * @access private 418 * @var array 419 */ 420 var $_defaultOptions = array( 421 XML_SERIALIZER_OPTION_INDENT => '', // string used for indentation 422 XML_SERIALIZER_OPTION_LINEBREAKS => "\n", // string used for newlines 423 XML_SERIALIZER_OPTION_TYPEHINTS => false, // automatically add type hin attributes 424 XML_SERIALIZER_OPTION_XML_DECL_ENABLED => false, // add an XML declaration 425 XML_SERIALIZER_OPTION_XML_ENCODING => null, // encoding specified in the XML declaration 426 XML_SERIALIZER_OPTION_DEFAULT_TAG => 'XML_Serializer_Tag', // tag used for indexed arrays or invalid names 427 XML_SERIALIZER_OPTION_CLASSNAME_AS_TAGNAME => false, // use classname for objects in indexed arrays 428 XML_SERIALIZER_OPTION_ATTRIBUTE_KEY => '_originalKey', // attribute where original key is stored 429 XML_SERIALIZER_OPTION_ATTRIBUTE_TYPE => '_type', // attribute for type (only if typeHints => true) 430 XML_SERIALIZER_OPTION_ATTRIBUTE_CLASS => '_class', // attribute for class of objects (only if typeHints => true) 431 XML_SERIALIZER_OPTION_SCALAR_AS_ATTRIBUTES => false, // scalar values (strings, ints,..) will be serialized as attribute 432 XML_SERIALIZER_OPTION_PREPEND_ATTRIBUTES => '', // prepend string for attributes 433 XML_SERIALIZER_OPTION_INDENT_ATTRIBUTES => false, // indent the attributes, if set to '_auto', it will indent attributes so they all start at the same column 434 XML_SERIALIZER_OPTION_MODE => XML_SERIALIZER_MODE_DEFAULT, // use XML_SERIALIZER_MODE_SIMPLEXML to use parent name as tagname if transforming an indexed array 435 XML_SERIALIZER_OPTION_DOCTYPE_ENABLED => false, // add a doctype declaration 436 XML_SERIALIZER_OPTION_DOCTYPE => null, // supply a string or an array with id and uri ({@see XML_Util::getDoctypeDeclaration()} 437 XML_SERIALIZER_OPTION_ROOT_NAME => null, // name of the root tag 438 XML_SERIALIZER_OPTION_ROOT_ATTRIBS => array(), // attributes of the root tag 439 XML_SERIALIZER_OPTION_ATTRIBUTES_KEY => null, // all values in this key will be treated as attributes 440 XML_SERIALIZER_OPTION_CONTENT_KEY => null, // this value will be used directly as content, instead of creating a new tag, may only be used in conjuction with attributesArray 441 XML_SERIALIZER_OPTION_COMMENT_KEY => null, // this value will be used directly as comment, instead of creating a new tag, may only be used in conjuction with attributesArray 442 XML_SERIALIZER_OPTION_TAGMAP => array(), // tag names that will be changed 443 XML_SERIALIZER_OPTION_ENCODE_FUNC => null, // function that will be applied before serializing 444 XML_SERIALIZER_OPTION_NAMESPACE => null, // namespace to use 445 XML_SERIALIZER_OPTION_ENTITIES => XML_SERIALIZER_ENTITIES_XML, // type of entities to replace, 446 XML_SERIALIZER_OPTION_RETURN_RESULT => false, // serialize() returns the result of the serialization instead of true 447 XML_SERIALIZER_OPTION_IGNORE_NULL => false // ignore properties that are set to null 448 ); 449 450 /** 451 * options for the serialization 452 * 453 * @access public 454 * @var array 455 */ 456 var $options = array(); 457 458 /** 459 * current tag depth 460 * 461 * @access private 462 * @var integer 463 */ 464 var $_tagDepth = 0; 465 466 /** 467 * serilialized representation of the data 468 * 469 * @access private 470 * @var string 471 */ 472 var $_serializedData = null; 473 474 /** 475 * constructor 476 * 477 * @access public 478 * @param mixed $options array containing options for the serialization 479 */ 480 function XML_Serializer( $options = null ) 481 { 482 $this->PEAR(); 483 if (is_array($options)) { 484 $this->options = array_merge($this->_defaultOptions, $options); 485 } else { 486 $this->options = $this->_defaultOptions; 487 } 488 } 489 490 /** 491 * return API version 492 * 493 * @access public 494 * @static 495 * @return string $version API version 496 */ 497 function apiVersion() 498 { 499 return '1.0.0'; 500 } 501 502 /** 503 * reset all options to default options 504 * 505 * @access public 506 * @see setOption(), XML_Serializer() 507 */ 508 function resetOptions() 509 { 510 $this->options = $this->_defaultOptions; 511 } 512 513 /** 514 * set an option 515 * 516 * You can use this method if you do not want to set all options in the constructor 517 * 518 * @access public 519 * @see resetOption(), XML_Serializer() 520 */ 521 function setOption($name, $value) 522 { 523 $this->options[$name] = $value; 524 } 525 526 /** 527 * sets several options at once 528 * 529 * You can use this method if you do not want to set all options in the constructor 530 * 531 * @access public 532 * @see resetOption(), XML_Unserializer(), setOption() 533 */ 534 function setOptions($options) 535 { 536 $this->options = array_merge($this->options, $options); 537 } 538 539 /** 540 * serialize data 541 * 542 * @access public 543 * @param mixed $data data to serialize 544 * @return boolean true on success, pear error on failure 545 */ 546 function serialize($data, $options = null) 547 { 548 // if options have been specified, use them instead 549 // of the previously defined ones 550 if (is_array($options)) { 551 $optionsBak = $this->options; 552 if (isset($options['overrideOptions']) && $options['overrideOptions'] == true) { 553 $this->options = array_merge($this->_defaultOptions, $options); 554 } else { 555 $this->options = array_merge($this->options, $options); 556 } 557 } else { 558 $optionsBak = null; 559 } 560 561 // start depth is zero 562 $this->_tagDepth = 0; 563 564 $rootAttributes = $this->options[XML_SERIALIZER_OPTION_ROOT_ATTRIBS]; 565 if (is_array($this->options[XML_SERIALIZER_OPTION_NAMESPACE])) { 566 $rootAttributes['xmlns:'.$this->options[XML_SERIALIZER_OPTION_NAMESPACE][0]] = $this->options[XML_SERIALIZER_OPTION_NAMESPACE][1]; 567 } 568 569 $this->_serializedData = ''; 570 // serialize an array 571 if (is_array($data)) { 572 if (isset($this->options[XML_SERIALIZER_OPTION_ROOT_NAME])) { 573 $tagName = $this->options[XML_SERIALIZER_OPTION_ROOT_NAME]; 574 } else { 575 $tagName = 'array'; 576 } 577 578 $this->_serializedData .= $this->_serializeArray($data, $tagName, $rootAttributes); 579 } 580 // serialize an object 581 elseif (is_object($data)) { 582 if (isset($this->options[XML_SERIALIZER_OPTION_ROOT_NAME])) { 583 $tagName = $this->options[XML_SERIALIZER_OPTION_ROOT_NAME]; 584 } else { 585 $tagName = get_class($data); 586 } 587 $this->_serializedData .= $this->_serializeObject($data, $tagName, $rootAttributes); 588 } 589 590 // add doctype declaration 591 if ($this->options[XML_SERIALIZER_OPTION_DOCTYPE_ENABLED] === true) { 592 $this->_serializedData = XML_Util::getDoctypeDeclaration($tagName, $this->options[XML_SERIALIZER_OPTION_DOCTYPE]) 593 . $this->options[XML_SERIALIZER_OPTION_LINEBREAKS] 594 . $this->_serializedData; 595 } 596 597 // build xml declaration 598 if ($this->options[XML_SERIALIZER_OPTION_XML_DECL_ENABLED]) { 599 $atts = array(); 600 $this->_serializedData = XML_Util::getXMLDeclaration('1.0', $this->options[XML_SERIALIZER_OPTION_XML_ENCODING]) 601 . $this->options[XML_SERIALIZER_OPTION_LINEBREAKS] 602 . $this->_serializedData; 603 } 604 605 if ($this->options[XML_SERIALIZER_OPTION_RETURN_RESULT] === true) { 606 $result = $this->_serializedData; 607 } else { 608 $result = true; 609 } 610 611 if ($optionsBak !== null) { 612 $this->options = $optionsBak; 613 } 614 615 return $result; 616 } 617 618 /** 619 * get the result of the serialization 620 * 621 * @access public 622 * @return string serialized XML 623 */ 624 function getSerializedData() 625 { 626 if ($this->_serializedData == null) { 627 return $this->raiseError('No serialized data available. Use XML_Serializer::serialize() first.', XML_SERIALIZER_ERROR_NO_SERIALIZATION); 628 } 629 return $this->_serializedData; 630 } 631 632 /** 633 * serialize any value 634 * 635 * This method checks for the type of the value and calls the appropriate method 636 * 637 * @access private 638 * @param mixed $value 639 * @param string $tagName 640 * @param array $attributes 641 * @return string 642 */ 643 function _serializeValue($value, $tagName = null, $attributes = array()) 644 { 645 if (is_array($value)) { 646 $xml = $this->_serializeArray($value, $tagName, $attributes); 647 } elseif (is_object($value)) { 648 $xml = $this->_serializeObject($value, $tagName); 649 } else { 650 $tag = array( 651 'qname' => $tagName, 652 'attributes' => $attributes, 653 'content' => $value 654 ); 655 $xml = $this->_createXMLTag($tag); 656 } 657 return $xml; 658 } 659 660 /** 661 * serialize an array 662 * 663 * @access private 664 * @param array $array array to serialize 665 * @param string $tagName name of the root tag 666 * @param array $attributes attributes for the root tag 667 * @return string $string serialized data 668 * @uses XML_Util::isValidName() to check, whether key has to be substituted 669 */ 670 function _serializeArray(&$array, $tagName = null, $attributes = array()) 671 { 672 $_content = null; 673 $_comment = null; 674 675 // check for comment 676 if ($this->options[XML_SERIALIZER_OPTION_COMMENT_KEY] !== null) { 677 if (isset($array[$this->options[XML_SERIALIZER_OPTION_COMMENT_KEY]])) { 678 $_comment = $array[$this->options[XML_SERIALIZER_OPTION_COMMENT_KEY]]; 679 unset($array[$this->options[XML_SERIALIZER_OPTION_COMMENT_KEY]]); 680 } 681 } 682 683 /** 684 * check for special attributes 685 */ 686 if ($this->options[XML_SERIALIZER_OPTION_ATTRIBUTES_KEY] !== null) { 687 if (isset($array[$this->options[XML_SERIALIZER_OPTION_ATTRIBUTES_KEY]])) { 688 $attributes = $array[$this->options[XML_SERIALIZER_OPTION_ATTRIBUTES_KEY]]; 689 unset($array[$this->options[XML_SERIALIZER_OPTION_ATTRIBUTES_KEY]]); 690 } 691 /** 692 * check for special content 693 */ 694 if ($this->options[XML_SERIALIZER_OPTION_CONTENT_KEY] !== null) { 695 if (isset($array[$this->options[XML_SERIALIZER_OPTION_CONTENT_KEY]])) { 696 $_content = $array[$this->options[XML_SERIALIZER_OPTION_CONTENT_KEY]]; 697 unset($array[$this->options[XML_SERIALIZER_OPTION_CONTENT_KEY]]); 698 } 699 } 700 } 701 702 if ($this->options[XML_SERIALIZER_OPTION_IGNORE_NULL] === true) { 703 foreach (array_keys($array) as $key) { 704 if (is_null($array[$key])) { 705 unset($array[$key]); 706 } 707 } 708 } 709 710 /* 711 * if mode is set to simpleXML, check whether 712 * the array is associative or indexed 713 */ 714 if (is_array($array) && !empty($array) && $this->options[XML_SERIALIZER_OPTION_MODE] == XML_SERIALIZER_MODE_SIMPLEXML) { 715 $indexed = true; 716 foreach ($array as $key => $val) { 717 if (!is_int($key)) { 718 $indexed = false; 719 break; 720 } 721 } 722 723 if ($indexed && $this->options[XML_SERIALIZER_OPTION_MODE] == XML_SERIALIZER_MODE_SIMPLEXML) { 724 $string = ''; 725 foreach ($array as $key => $val) { 726 $string .= $this->_serializeValue( $val, $tagName, $attributes); 727 728 $string .= $this->options[XML_SERIALIZER_OPTION_LINEBREAKS]; 729 // do indentation 730 if ($this->options[XML_SERIALIZER_OPTION_INDENT]!==null && $this->_tagDepth>0) { 731 $string .= str_repeat($this->options[XML_SERIALIZER_OPTION_INDENT], $this->_tagDepth); 732 } 733 } 734 return rtrim($string); 735 } 736 } 737 738 if ($this->options[XML_SERIALIZER_OPTION_SCALAR_AS_ATTRIBUTES] === true) { 739 $this->expectError('*'); 740 foreach ($array as $key => $value) { 741 if (is_scalar($value) && (XML_Util::isValidName($key) === true)) { 742 unset($array[$key]); 743 $attributes[$this->options[XML_SERIALIZER_OPTION_PREPEND_ATTRIBUTES].$key] = $value; 744 } 745 } 746 $this->popExpect(); 747 } 748 749 // check for empty array => create empty tag 750 if (empty($array)) { 751 $tag = array( 752 'qname' => $tagName, 753 'content' => $_content, 754 'attributes' => $attributes 755 ); 756 } else { 757 $this->_tagDepth++; 758 $tmp = $this->options[XML_SERIALIZER_OPTION_LINEBREAKS]; 759 foreach ($array as $key => $value) { 760 // do indentation 761 if ($this->options[XML_SERIALIZER_OPTION_INDENT]!==null && $this->_tagDepth>0) { 762 $tmp .= str_repeat($this->options[XML_SERIALIZER_OPTION_INDENT], $this->_tagDepth); 763 } 764 765 if (isset($this->options[XML_SERIALIZER_OPTION_TAGMAP][$key])) { 766 $key = $this->options[XML_SERIALIZER_OPTION_TAGMAP][$key]; 767 } 768 769 // copy key 770 $origKey = $key; 771 $this->expectError('*'); 772 // key cannot be used as tagname => use default tag 773 $valid = XML_Util::isValidName($key); 774 $this->popExpect(); 775 if (PEAR::isError($valid)) { 776 if ($this->options[XML_SERIALIZER_OPTION_CLASSNAME_AS_TAGNAME] && is_object($value)) { 777 $key = get_class($value); 778 } else { 779 $key = $this->options[XML_SERIALIZER_OPTION_DEFAULT_TAG]; 780 } 781 } 782 $atts = array(); 783 if ($this->options[XML_SERIALIZER_OPTION_TYPEHINTS] === true) { 784 $atts[$this->options[XML_SERIALIZER_OPTION_ATTRIBUTE_TYPE]] = gettype($value); 785 if ($key !== $origKey) { 786 $atts[$this->options[XML_SERIALIZER_OPTION_ATTRIBUTE_KEY]] = (string)$origKey; 787 } 788 789 } 790 791 $tmp .= $this->_createXMLTag(array( 792 'qname' => $key, 793 'attributes' => $atts, 794 'content' => $value ) 795 ); 796 $tmp .= $this->options[XML_SERIALIZER_OPTION_LINEBREAKS]; 797 } 798 799 $this->_tagDepth--; 800 if ($this->options[XML_SERIALIZER_OPTION_INDENT]!==null && $this->_tagDepth>0) { 801 $tmp .= str_repeat($this->options[XML_SERIALIZER_OPTION_INDENT], $this->_tagDepth); 802 } 803 804 if (trim($tmp) === '') { 805 $tmp = null; 806 } 807 808 $tag = array( 809 'qname' => $tagName, 810 'content' => $tmp, 811 'attributes' => $attributes 812 ); 813 } 814 if ($this->options[XML_SERIALIZER_OPTION_TYPEHINTS] === true) { 815 if (!isset($tag['attributes'][$this->options[XML_SERIALIZER_OPTION_ATTRIBUTE_TYPE]])) { 816 $tag['attributes'][$this->options[XML_SERIALIZER_OPTION_ATTRIBUTE_TYPE]] = 'array'; 817 } 818 } 819 820 $string = ''; 821 if (!is_null($_comment)) { 822 $string .= XML_Util::createComment($_comment); 823 $string .= $this->options[XML_SERIALIZER_OPTION_LINEBREAKS]; 824 if ($this->options[XML_SERIALIZER_OPTION_INDENT]!==null && $this->_tagDepth>0) { 825 $string .= str_repeat($this->options[XML_SERIALIZER_OPTION_INDENT], $this->_tagDepth); 826 } 827 } 828 $string .= $this->_createXMLTag($tag, false); 829 return $string; 830 } 831 832 /** 833 * serialize an object 834 * 835 * @access private 836 * @param object $object object to serialize 837 * @return string $string serialized data 838 */ 839 function _serializeObject(&$object, $tagName = null, $attributes = array()) 840 { 841 // check for magic function 842 if (method_exists($object, '__sleep')) { 843 $object->__sleep(); 844 } 845 846 $tmp = $this->options[XML_SERIALIZER_OPTION_LINEBREAKS]; 847 $properties = get_object_vars($object); 848 if (empty($tagName)) { 849 $tagName = get_class($object); 850 } 851 852 // typehints activated? 853 if ($this->options[XML_SERIALIZER_OPTION_TYPEHINTS] === true) { 854 $attributes[$this->options[XML_SERIALIZER_OPTION_ATTRIBUTE_TYPE]] = 'object'; 855 $attributes[$this->options[XML_SERIALIZER_OPTION_ATTRIBUTE_CLASS]] = get_class($object); 856 } 857 858 $string = $this->_serializeArray($properties, $tagName, $attributes); 859 return $string; 860 } 861 862 /** 863 * create a tag from an array 864 * this method awaits an array in the following format 865 * array( 866 * 'qname' => $tagName, 867 * 'attributes' => array(), 868 * 'content' => $content, // optional 869 * 'namespace' => $namespace // optional 870 * 'namespaceUri' => $namespaceUri // optional 871 * ) 872 * 873 * @access private 874 * @param array $tag tag definition 875 * @param boolean $replaceEntities whether to replace XML entities in content or not 876 * @return string $string XML tag 877 */ 878 function _createXMLTag( $tag, $firstCall = true ) 879 { 880 // build fully qualified tag name 881 if ($this->options[XML_SERIALIZER_OPTION_NAMESPACE] !== null) { 882 if (is_array($this->options[XML_SERIALIZER_OPTION_NAMESPACE])) { 883 $tag['qname'] = $this->options[XML_SERIALIZER_OPTION_NAMESPACE][0] . ':' . $tag['qname']; 884 } else { 885 $tag['qname'] = $this->options[XML_SERIALIZER_OPTION_NAMESPACE] . ':' . $tag['qname']; 886 } 887 } 888 889 // attribute indentation 890 if ($this->options[XML_SERIALIZER_OPTION_INDENT_ATTRIBUTES] !== false) { 891 $multiline = true; 892 $indent = str_repeat($this->options[XML_SERIALIZER_OPTION_INDENT], $this->_tagDepth); 893 894 if ($this->options[XML_SERIALIZER_OPTION_INDENT_ATTRIBUTES] == '_auto') { 895 $indent .= str_repeat(' ', (strlen($tag['qname'])+2)); 896 897 } else { 898 $indent .= $this->options[XML_SERIALIZER_OPTION_INDENT_ATTRIBUTES]; 899 } 900 } else { 901 $multiline = false; 902 $indent = false; 903 } 904 905 // replace XML entities (only needed, if this is not a nested call) 906 if ($firstCall === true) { 907 $replaceEntities = $this->options[XML_SERIALIZER_OPTION_ENTITIES]; 908 } else { 909 $replaceEntities = XML_SERIALIZER_ENTITIES_NONE; 910 } 911 912 if (is_array($tag['content'])) { 913 if (empty($tag['content'])) { 914 $tag['content'] = ''; 915 } 916 } elseif(is_scalar($tag['content']) && (string)$tag['content'] == '') { 917 $tag['content'] = ''; 918 } 919 920 if (is_scalar($tag['content']) || is_null($tag['content'])) { 921 if ($this->options[XML_SERIALIZER_OPTION_ENCODE_FUNC]) { 922 if ($firstCall === true) { 923 $tag['content'] = call_user_func($this->options[XML_SERIALIZER_OPTION_ENCODE_FUNC], $tag['content']); 924 } 925 $tag['attributes'] = array_map($this->options[XML_SERIALIZER_OPTION_ENCODE_FUNC], $tag['attributes']); 926 } 927 $tag = XML_Util::createTagFromArray($tag, $replaceEntities, $multiline, $indent, $this->options[XML_SERIALIZER_OPTION_LINEBREAKS]); 928 } elseif (is_array($tag['content'])) { 929 $tag = $this->_serializeArray($tag['content'], $tag['qname'], $tag['attributes']); 930 } elseif (is_object($tag['content'])) { 931 $tag = $this->_serializeObject($tag['content'], $tag['qname'], $tag['attributes']); 932 } elseif (is_resource($tag['content'])) { 933 settype($tag['content'], 'string'); 934 if ($this->options[XML_SERIALIZER_OPTION_ENCODE_FUNC]) { 935 if ($replaceEntities === true) { 936 $tag['content'] = call_user_func($this->options[XML_SERIALIZER_OPTION_ENCODE_FUNC], $tag['content']); 937 } 938 $tag['attributes'] = array_map($this->options[XML_SERIALIZER_OPTION_ENCODE_FUNC], $tag['attributes']); 939 } 940 $tag = XML_Util::createTagFromArray($tag, $replaceEntities); 941 } 942 return $tag; 943 } 944 } 945 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Mon Nov 26 14:10:01 2007 | par Balluche grâce à PHPXref 0.7 |
|