See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]
1 <?php 2 /** 3 * Data-Types for CFPropertyList as defined by Apple. 4 * {@link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists} 5 * @author Rodney Rehm <rodney.rehm@medialize.de> 6 * @author Christian Kruse <cjk@wwwtech.de> 7 * @package plist 8 * @subpackage plist.types 9 * @version $Id$ 10 */ 11 namespace CFPropertyList; 12 use \DOMDocument, \Iterator, \ArrayAccess; 13 14 /** 15 * Base-Class of all CFTypes used by CFPropertyList 16 * @author Rodney Rehm <rodney.rehm@medialize.de> 17 * @author Christian Kruse <cjk@wwwtech.de> 18 * @package plist 19 * @subpackage plist.types 20 * @version $Id$ 21 * @example example-create-01.php Using the CFPropertyList API 22 * @example example-create-02.php Using CFPropertyList::guess() 23 * @example example-create-03.php Using CFPropertyList::guess() with {@link CFDate} and {@link CFData} 24 */ 25 abstract class CFType { 26 /** 27 * CFType nodes 28 * @var array 29 */ 30 protected $value = null; 31 32 /** 33 * Create new CFType. 34 * @param mixed $value Value of CFType 35 */ 36 public function __construct($value=null) { 37 $this->setValue($value); 38 } 39 40 /************************************************************************************************ 41 * M A G I C P R O P E R T I E S 42 ************************************************************************************************/ 43 44 /** 45 * Get the CFType's value 46 * @return mixed CFType's value 47 */ 48 public function getValue() { 49 return $this->value; 50 } 51 52 /** 53 * Set the CFType's value 54 * @return void 55 */ 56 public function setValue($value) { 57 $this->value = $value; 58 } 59 60 /************************************************************************************************ 61 * S E R I A L I Z I N G 62 ************************************************************************************************/ 63 64 /** 65 * Get XML-Node. 66 * @param DOMDocument $doc DOMDocument to create DOMNode in 67 * @param string $nodeName Name of element to create 68 * @return DOMNode Node created based on CType 69 * @uses $value as nodeValue 70 */ 71 public function toXML(DOMDocument $doc, $nodeName) { 72 $node = $doc->createElement($nodeName); 73 $text = $doc->createTextNode($this->value); 74 $node->appendChild($text); 75 return $node; 76 } 77 78 /** 79 * convert value to binary representation 80 * @param CFBinaryPropertyList The binary property list object 81 * @return The offset in the object table 82 */ 83 public abstract function toBinary(CFBinaryPropertyList &$bplist); 84 85 /** 86 * Get CFType's value. 87 * @return mixed primitive value 88 * @uses $value for retrieving primitive of CFType 89 */ 90 public function toArray() { 91 return $this->getValue(); 92 } 93 94 } 95 96 /** 97 * String Type of CFPropertyList 98 * @author Rodney Rehm <rodney.rehm@medialize.de> 99 * @author Christian Kruse <cjk@wwwtech.de> 100 * @package plist 101 * @subpackage plist.types 102 */ 103 class CFString extends CFType { 104 /** 105 * Get XML-Node. 106 * @param DOMDocument $doc DOMDocument to create DOMNode in 107 * @param string $nodeName For compatibility reasons; just ignore it 108 * @return DOMNode <string>-Element 109 */ 110 public function toXML(DOMDocument $doc,$nodeName="") { 111 return parent::toXML($doc, 'string'); 112 } 113 114 /** 115 * convert value to binary representation 116 * @param CFBinaryPropertyList The binary property list object 117 * @return The offset in the object table 118 */ 119 public function toBinary(CFBinaryPropertyList &$bplist) { 120 return $bplist->stringToBinary($this->value); 121 } 122 } 123 124 class CFUid extends CFType { 125 public 126 function toXML(DOMDocument $doc,$nodeName="") { 127 $obj = new CFDictionary(array('CF$UID' => new CFNumber($this->value))); 128 return $obj->toXml($doc); 129 } 130 131 public 132 function toBinary(CFBinaryPropertyList &$bplist) { 133 return $bplist->uidToBinary($this->value); 134 } 135 } 136 137 /** 138 * Number Type of CFPropertyList 139 * @author Rodney Rehm <rodney.rehm@medialize.de> 140 * @author Christian Kruse <cjk@wwwtech.de> 141 * @package plist 142 * @subpackage plist.types 143 */ 144 class CFNumber extends CFType { 145 /** 146 * Get XML-Node. 147 * Returns <real> if $value is a float, <integer> if $value is an integer. 148 * @param DOMDocument $doc DOMDocument to create DOMNode in 149 * @param string $nodeName For compatibility reasons; just ignore it 150 * @return DOMNode <real> or <integer>-Element 151 */ 152 public function toXML(DOMDocument $doc,$nodeName="") { 153 $ret = 'real'; 154 if(intval($this->value) == $this->value && !is_float($this->value) && strpos($this->value,'.') === false) { 155 $this->value = intval($this->value); 156 $ret = 'integer'; 157 } 158 return parent::toXML($doc, $ret); 159 } 160 161 /** 162 * convert value to binary representation 163 * @param CFBinaryPropertyList The binary property list object 164 * @return The offset in the object table 165 */ 166 public function toBinary(CFBinaryPropertyList &$bplist) { 167 return $bplist->numToBinary($this->value); 168 } 169 } 170 171 /** 172 * Date Type of CFPropertyList 173 * Note: CFDate uses Unix timestamp (epoch) to store dates internally 174 * @author Rodney Rehm <rodney.rehm@medialize.de> 175 * @author Christian Kruse <cjk@wwwtech.de> 176 * @package plist 177 * @subpackage plist.types 178 */ 179 class CFDate extends CFType { 180 const TIMESTAMP_APPLE = 0; 181 const TIMESTAMP_UNIX = 1; 182 const DATE_DIFF_APPLE_UNIX = 978307200; 183 184 /** 185 * Create new Date CFType. 186 * @param integer $value timestamp to set 187 * @param integer $format format the timestamp is specified in, use {@link TIMESTAMP_APPLE} or {@link TIMESTAMP_UNIX}, defaults to {@link TIMESTAMP_APPLE} 188 * @uses setValue() to convert the timestamp 189 */ 190 function __construct($value,$format=CFDate::TIMESTAMP_UNIX) { 191 $this->setValue($value,$format); 192 } 193 194 /** 195 * Set the Date CFType's value. 196 * @param integer $value timestamp to set 197 * @param integer $format format the timestamp is specified in, use {@link TIMESTAMP_APPLE} or {@link TIMESTAMP_UNIX}, defaults to {@link TIMESTAMP_UNIX} 198 * @return void 199 * @uses TIMESTAMP_APPLE to determine timestamp type 200 * @uses TIMESTAMP_UNIX to determine timestamp type 201 * @uses DATE_DIFF_APPLE_UNIX to convert Apple-timestamp to Unix-timestamp 202 */ 203 function setValue($value,$format=CFDate::TIMESTAMP_UNIX) { 204 if($format == CFDate::TIMESTAMP_UNIX) $this->value = $value; 205 else $this->value = $value + CFDate::DATE_DIFF_APPLE_UNIX; 206 } 207 208 /** 209 * Get the Date CFType's value. 210 * @param integer $format format the timestamp is specified in, use {@link TIMESTAMP_APPLE} or {@link TIMESTAMP_UNIX}, defaults to {@link TIMESTAMP_UNIX} 211 * @return integer Unix timestamp 212 * @uses TIMESTAMP_APPLE to determine timestamp type 213 * @uses TIMESTAMP_UNIX to determine timestamp type 214 * @uses DATE_DIFF_APPLE_UNIX to convert Unix-timestamp to Apple-timestamp 215 */ 216 function getValue($format=CFDate::TIMESTAMP_UNIX) { 217 if($format == CFDate::TIMESTAMP_UNIX) return $this->value; 218 else return $this->value - CFDate::DATE_DIFF_APPLE_UNIX; 219 } 220 221 /** 222 * Get XML-Node. 223 * @param DOMDocument $doc DOMDocument to create DOMNode in 224 * @param string $nodeName For compatibility reasons; just ignore it 225 * @return DOMNode <date>-Element 226 */ 227 public function toXML(DOMDocument $doc,$nodeName="") { 228 $text = $doc->createTextNode(gmdate("Y-m-d\TH:i:s\Z",$this->getValue())); 229 $node = $doc->createElement("date"); 230 $node->appendChild($text); 231 return $node; 232 } 233 234 /** 235 * convert value to binary representation 236 * @param CFBinaryPropertyList The binary property list object 237 * @return The offset in the object table 238 */ 239 public function toBinary(CFBinaryPropertyList &$bplist) { 240 return $bplist->dateToBinary($this->value); 241 } 242 243 /** 244 * Create a UNIX timestamp from a PList date string 245 * @param string $val The date string (e.g. "2009-05-13T20:23:43Z") 246 * @return integer The UNIX timestamp 247 * @throws PListException when encountering an unknown date string format 248 */ 249 public static function dateValue($val) { 250 //2009-05-13T20:23:43Z 251 if(!preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z/',$val,$matches)) throw new PListException("Unknown date format: $val"); 252 return gmmktime($matches[4],$matches[5],$matches[6],$matches[2],$matches[3],$matches[1]); 253 } 254 } 255 256 /** 257 * Boolean Type of CFPropertyList 258 * @author Rodney Rehm <rodney.rehm@medialize.de> 259 * @author Christian Kruse <cjk@wwwtech.de> 260 * @package plist 261 * @subpackage plist.types 262 */ 263 class CFBoolean extends CFType { 264 /** 265 * Get XML-Node. 266 * Returns <true> if $value is a true, <false> if $value is false. 267 * @param DOMDocument $doc DOMDocument to create DOMNode in 268 * @param string $nodeName For compatibility reasons; just ignore it 269 * @return DOMNode <true> or <false>-Element 270 */ 271 public function toXML(DOMDocument $doc,$nodeName="") { 272 return $doc->createElement($this->value ? 'true' : 'false'); 273 } 274 275 /** 276 * convert value to binary representation 277 * @param CFBinaryPropertyList The binary property list object 278 * @return The offset in the object table 279 */ 280 public function toBinary(CFBinaryPropertyList &$bplist) { 281 return $bplist->boolToBinary($this->value); 282 } 283 284 } 285 286 /** 287 * Data Type of CFPropertyList 288 * Note: Binary data is base64-encoded. 289 * @author Rodney Rehm <rodney.rehm@medialize.de> 290 * @author Christian Kruse <cjk@wwwtech.de> 291 * @package plist 292 * @subpackage plist.types 293 */ 294 class CFData extends CFType { 295 /** 296 * Create new Data CFType 297 * @param string $value data to be contained by new object 298 * @param boolean $already_coded if true $value will not be base64-encoded, defaults to false 299 */ 300 public function __construct($value=null,$already_coded=false) { 301 if($already_coded) $this->value = $value; 302 else $this->setValue($value); 303 } 304 305 /** 306 * Set the CFType's value and base64-encode it. 307 * <b>Note:</b> looks like base64_encode has troubles with UTF-8 encoded strings 308 * @return void 309 */ 310 public function setValue($value) { 311 //if(function_exists('mb_check_encoding') && mb_check_encoding($value, 'UTF-8')) $value = utf8_decode($value); 312 $this->value = base64_encode($value); 313 } 314 315 /** 316 * Get base64 encoded data 317 * @return string The base64 encoded data value 318 */ 319 public function getCodedValue() { 320 return $this->value; 321 } 322 323 /** 324 * Get the base64-decoded CFType's value. 325 * @return mixed CFType's value 326 */ 327 public function getValue() { 328 return base64_decode($this->value); 329 } 330 331 /** 332 * Get XML-Node. 333 * @param DOMDocument $doc DOMDocument to create DOMNode in 334 * @param string $nodeName For compatibility reasons; just ignore it 335 * @return DOMNode <data>-Element 336 */ 337 public function toXML(DOMDocument $doc,$nodeName="") { 338 return parent::toXML($doc, 'data'); 339 } 340 341 /** 342 * convert value to binary representation 343 * @param CFBinaryPropertyList The binary property list object 344 * @return The offset in the object table 345 */ 346 public function toBinary(CFBinaryPropertyList &$bplist) { 347 return $bplist->dataToBinary($this->getValue()); 348 } 349 } 350 351 /** 352 * Array Type of CFPropertyList 353 * @author Rodney Rehm <rodney.rehm@medialize.de> 354 * @author Christian Kruse <cjk@wwwtech.de> 355 * @package plist 356 * @subpackage plist.types 357 */ 358 class CFArray extends CFType implements Iterator, ArrayAccess { 359 /** 360 * Position of iterator {@link http://php.net/manual/en/class.iterator.php} 361 * @var integer 362 */ 363 protected $iteratorPosition = 0; 364 365 366 /** 367 * Create new CFType. 368 * @param array $value Value of CFType 369 */ 370 public function __construct($value=array()) { 371 $this->value = $value; 372 } 373 374 /** 375 * Set the CFType's value 376 * <b>Note:</b> this dummy does nothing 377 * @return void 378 */ 379 public function setValue($value) { 380 } 381 382 /** 383 * Add CFType to collection. 384 * @param CFType $value CFType to add to collection, defaults to null which results in an empty {@link CFString} 385 * @return void 386 * @uses $value for adding $value 387 */ 388 public function add(CFType $value=null) { 389 // anything but CFType is null, null is an empty string - sad but true 390 if( !$value ) 391 $value = new CFString(); 392 393 $this->value[] = $value; 394 } 395 396 /** 397 * Get CFType from collection. 398 * @param integer $key Key of CFType to retrieve from collection 399 * @return CFType CFType found at $key, null else 400 * @uses $value for retrieving CFType of $key 401 */ 402 public function get($key) { 403 if(isset($this->value[$key])) return $this->value[$key]; 404 return null; 405 } 406 407 /** 408 * Remove CFType from collection. 409 * @param integer $key Key of CFType to removes from collection 410 * @return CFType removed CFType, null else 411 * @uses $value for removing CFType of $key 412 */ 413 public function del($key) { 414 if(isset($this->value[$key])) unset($this->value[$key]); 415 } 416 417 418 /************************************************************************************************ 419 * S E R I A L I Z I N G 420 ************************************************************************************************/ 421 422 /** 423 * Get XML-Node. 424 * @param DOMDocument $doc DOMDocument to create DOMNode in 425 * @param string $nodeName For compatibility reasons; just ignore it 426 * @return DOMNode <array>-Element 427 */ 428 public function toXML(DOMDocument $doc,$nodeName="") { 429 $node = $doc->createElement('array'); 430 431 foreach($this->value as $value) $node->appendChild($value->toXML($doc)); 432 return $node; 433 } 434 435 /** 436 * convert value to binary representation 437 * @param CFBinaryPropertyList The binary property list object 438 * @return The offset in the object table 439 */ 440 public function toBinary(CFBinaryPropertyList &$bplist) { 441 return $bplist->arrayToBinary($this); 442 } 443 444 /** 445 * Get CFType's value. 446 * @return array primitive value 447 * @uses $value for retrieving primitive of CFType 448 */ 449 public function toArray() { 450 $a = array(); 451 foreach($this->value as $value) $a[] = $value->toArray(); 452 return $a; 453 } 454 455 456 /************************************************************************************************ 457 * I T E R A T O R I N T E R F A C E 458 ************************************************************************************************/ 459 460 /** 461 * Rewind {@link $iteratorPosition} to first position (being 0) 462 * @link http://php.net/manual/en/iterator.rewind.php 463 * @return void 464 * @uses $iteratorPosition set to 0 465 */ 466 public function rewind() { 467 $this->iteratorPosition = 0; 468 } 469 470 /** 471 * Get Iterator's current {@link CFType} identified by {@link $iteratorPosition} 472 * @link http://php.net/manual/en/iterator.current.php 473 * @return CFType current Item 474 * @uses $iteratorPosition identify current key 475 */ 476 public function current() { 477 return $this->value[$this->iteratorPosition]; 478 } 479 480 /** 481 * Get Iterator's current key identified by {@link $iteratorPosition} 482 * @link http://php.net/manual/en/iterator.key.php 483 * @return string key of the current Item 484 * @uses $iteratorPosition identify current key 485 */ 486 public function key() { 487 return $this->iteratorPosition; 488 } 489 490 /** 491 * Increment {@link $iteratorPosition} to address next {@see CFType} 492 * @link http://php.net/manual/en/iterator.next.php 493 * @return void 494 * @uses $iteratorPosition increment by 1 495 */ 496 public function next() { 497 $this->iteratorPosition++; 498 } 499 500 /** 501 * Test if {@link $iteratorPosition} addresses a valid element of {@link $value} 502 * @link http://php.net/manual/en/iterator.valid.php 503 * @return boolean true if current position is valid, false else 504 * @uses $iteratorPosition test if within {@link $iteratorKeys} 505 * @uses $iteratorPosition test if within {@link $value} 506 */ 507 public function valid() { 508 return isset($this->value[$this->iteratorPosition]); 509 } 510 511 /************************************************************************************************ 512 * ArrayAccess I N T E R F A C E 513 ************************************************************************************************/ 514 515 /** 516 * Determine if the array's key exists 517 * @param string $key the key to check 518 * @return bool true if the offset exists, false if not 519 * @link http://php.net/manual/en/arrayaccess.offsetexists.php 520 * @uses $value to check if $key exists 521 * @author Sean Coates <sean@php.net> 522 */ 523 public function offsetExists($key) { 524 return isset($this->value[$key]); 525 } 526 527 /** 528 * Fetch a specific key from the CFArray 529 * @param string $key the key to check 530 * @return mixed the value associated with the key; null if the key is not found 531 * @link http://php.net/manual/en/arrayaccess.offsetget.php 532 * @uses get() to get the key's value 533 * @author Sean Coates <sean@php.net> 534 */ 535 public function offsetGet($key) { 536 return $this->get($key); 537 } 538 539 /** 540 * Set a value in the array 541 * @param string $key the key to set 542 * @param string $value the value to set 543 * @return void 544 * @link http://php.net/manual/en/arrayaccess.offsetset.php 545 * @uses setValue() to set the key's new value 546 * @author Sean Coates <sean@php.net> 547 */ 548 public function offsetSet($key, $value) { 549 return $this->setValue($value); 550 } 551 552 /** 553 * Unsets a value in the array 554 * <b>Note:</b> this dummy does nothing 555 * @param string $key the key to set 556 * @return void 557 * @link http://php.net/manual/en/arrayaccess.offsetunset.php 558 * @author Sean Coates <sean@php.net> 559 */ 560 public function offsetUnset($key) { 561 562 } 563 564 565 } 566 567 /** 568 * Array Type of CFPropertyList 569 * @author Rodney Rehm <rodney.rehm@medialize.de> 570 * @author Christian Kruse <cjk@wwwtech.de> 571 * @package plist 572 * @subpackage plist.types 573 */ 574 class CFDictionary extends CFType implements Iterator { 575 /** 576 * Position of iterator {@link http://php.net/manual/en/class.iterator.php} 577 * @var integer 578 */ 579 protected $iteratorPosition = 0; 580 581 /** 582 * List of Keys for numerical iterator access {@link http://php.net/manual/en/class.iterator.php} 583 * @var array 584 */ 585 protected $iteratorKeys = null; 586 587 588 /** 589 * Create new CFType. 590 * @param array $value Value of CFType 591 */ 592 public function __construct($value=array()) { 593 $this->value = $value; 594 } 595 596 /** 597 * Set the CFType's value 598 * <b>Note:</b> this dummy does nothing 599 * @return void 600 */ 601 public function setValue($value) { 602 } 603 604 /** 605 * Add CFType to collection. 606 * @param string $key Key to add to collection 607 * @param CFType $value CFType to add to collection, defaults to null which results in an empty {@link CFString} 608 * @return void 609 * @uses $value for adding $key $value pair 610 */ 611 public function add($key, CFType $value=null) { 612 // anything but CFType is null, null is an empty string - sad but true 613 if( !$value ) 614 $value = new CFString(); 615 616 $this->value[$key] = $value; 617 } 618 619 /** 620 * Get CFType from collection. 621 * @param string $key Key of CFType to retrieve from collection 622 * @return CFType CFType found at $key, null else 623 * @uses $value for retrieving CFType of $key 624 */ 625 public function get($key) { 626 if(isset($this->value[$key])) return $this->value[$key]; 627 return null; 628 } 629 630 /** 631 * Generic getter (magic) 632 * @param integer $key Key of CFType to retrieve from collection 633 * @return CFType CFType found at $key, null else 634 * @link http://php.net/oop5.overloading 635 * @uses get() to retrieve the key's value 636 * @author Sean Coates <sean@php.net> 637 */ 638 public function __get($key) { 639 return $this->get($key); 640 } 641 642 /** 643 * Remove CFType from collection. 644 * @param string $key Key of CFType to removes from collection 645 * @return CFType removed CFType, null else 646 * @uses $value for removing CFType of $key 647 */ 648 public function del($key) { 649 if(isset($this->value[$key])) unset($this->value[$key]); 650 } 651 652 653 /************************************************************************************************ 654 * S E R I A L I Z I N G 655 ************************************************************************************************/ 656 657 /** 658 * Get XML-Node. 659 * @param DOMDocument $doc DOMDocument to create DOMNode in 660 * @param string $nodeName For compatibility reasons; just ignore it 661 * @return DOMNode <dict>-Element 662 */ 663 public function toXML(DOMDocument $doc,$nodeName="") { 664 $node = $doc->createElement('dict'); 665 666 foreach($this->value as $key => $value) { 667 $node->appendChild($doc->createElement('key', $key)); 668 $node->appendChild($value->toXML($doc)); 669 } 670 671 return $node; 672 } 673 674 /** 675 * convert value to binary representation 676 * @param CFBinaryPropertyList The binary property list object 677 * @return The offset in the object table 678 */ 679 public function toBinary(CFBinaryPropertyList &$bplist) { 680 return $bplist->dictToBinary($this); 681 } 682 683 /** 684 * Get CFType's value. 685 * @return array primitive value 686 * @uses $value for retrieving primitive of CFType 687 */ 688 public function toArray() { 689 $a = array(); 690 691 foreach($this->value as $key => $value) $a[$key] = $value->toArray(); 692 return $a; 693 } 694 695 696 /************************************************************************************************ 697 * I T E R A T O R I N T E R F A C E 698 ************************************************************************************************/ 699 700 /** 701 * Rewind {@link $iteratorPosition} to first position (being 0) 702 * @link http://php.net/manual/en/iterator.rewind.php 703 * @return void 704 * @uses $iteratorPosition set to 0 705 * @uses $iteratorKeys store keys of {@link $value} 706 */ 707 public function rewind() { 708 $this->iteratorPosition = 0; 709 $this->iteratorKeys = array_keys($this->value); 710 } 711 712 /** 713 * Get Iterator's current {@link CFType} identified by {@link $iteratorPosition} 714 * @link http://php.net/manual/en/iterator.current.php 715 * @return CFType current Item 716 * @uses $iteratorPosition identify current key 717 * @uses $iteratorKeys identify current value 718 */ 719 public function current() { 720 return $this->value[$this->iteratorKeys[$this->iteratorPosition]]; 721 } 722 723 /** 724 * Get Iterator's current key identified by {@link $iteratorPosition} 725 * @link http://php.net/manual/en/iterator.key.php 726 * @return string key of the current Item 727 * @uses $iteratorPosition identify current key 728 * @uses $iteratorKeys identify current value 729 */ 730 public function key() { 731 return $this->iteratorKeys[$this->iteratorPosition]; 732 } 733 734 /** 735 * Increment {@link $iteratorPosition} to address next {@see CFType} 736 * @link http://php.net/manual/en/iterator.next.php 737 * @return void 738 * @uses $iteratorPosition increment by 1 739 */ 740 public function next() { 741 $this->iteratorPosition++; 742 } 743 744 /** 745 * Test if {@link $iteratorPosition} addresses a valid element of {@link $value} 746 * @link http://php.net/manual/en/iterator.valid.php 747 * @return boolean true if current position is valid, false else 748 * @uses $iteratorPosition test if within {@link $iteratorKeys} 749 * @uses $iteratorPosition test if within {@link $value} 750 */ 751 public function valid() { 752 return isset($this->iteratorKeys[$this->iteratorPosition]) && isset($this->value[$this->iteratorKeys[$this->iteratorPosition]]); 753 } 754 755 } 756 757 # eof
title
Description
Body
title
Description
Body
title
Description
Body
title
Body