Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 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 &lt;string&gt;-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 &lt;real&gt; if $value is a float, &lt;integer&gt; 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 &lt;real&gt; or &lt;integer&gt;-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 &lt;date&gt;-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 &lt;true&gt; if $value is a true, &lt;false&gt; 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 &lt;true&gt; or &lt;false&gt;-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 &lt;data&gt;-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 &lt;array&gt;-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 &lt;dict&gt;-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