/** * Get first (and only) child, or complete collection. * @param string $cftype if set to true returned value will be CFArray instead of an array in case of a collection * @return CFType|array CFType or list of CFTypes known to the PropertyList * @uses $value for retrieving CFTypes */ public function getValue($cftype = false) { if (count($this->value) === 1) { $t = array_values($this->value); return $t[0]; } if ($cftype) { $t = new CFArray(); foreach ($this->value as $value) { if ($value instanceof CFType) { $t->add($value); } } return $t; } return $this->value; }
/** * Create CFType-structure by guessing the data-types. * {@link CFArray}, {@link CFDictionary}, {@link CFBoolean}, {@link CFNumber} and {@link CFString} can be created, {@link CFDate} and {@link CFData} cannot. * <br /><b>Note:</b>Distinguishing between {@link CFArray} and {@link CFDictionary} is done by examining the keys. * Keys must be strictly incrementing integers to evaluate to a {@link CFArray}. * Since PHP does not offer a function to test for associative arrays, * this test causes the input array to be walked twice and thus work rather slow on large collections. * If you work with large arrays and can live with all arrays evaluating to {@link CFDictionary}, * feel free to set the appropriate flag. * <br /><b>Note:</b> If $value is an instance of CFType it is simply returned. * <br /><b>Note:</b> If $value is neither a CFType, array, numeric, boolean nor string, it is omitted. * @param mixed $value Value to convert to CFType * @param boolean $autoDictionary if true {@link CFArray}-detection is bypassed and arrays will be returned as {@link CFDictionary}. * @return CFType CFType based on guessed type * @uses isAssociativeArray() to check if an array only has numeric indexes */ public function toCFType($value) { switch (true) { case $value instanceof CFType: return $value; break; case is_object($value): // DateTime should be CFDate if (class_exists('DateTime') && $value instanceof DateTime) { return new CFDate($value->getTimestamp()); } // convert possible objects to arrays, arrays will be arrays if ($this->objectToArrayMethod && is_callable(array($value, $this->objectToArrayMethod))) { $value = call_user_func(array($value, $this->objectToArrayMethod)); } if (!is_array($value)) { if ($this->suppressExceptions) { return $this->defaultValue(); } throw new PListException('Could not determine CFType for object of type ' . get_class($value)); } /* break; omitted */ /* break; omitted */ case $value instanceof Iterator: case is_array($value): // test if $value is simple or associative array if (!$this->autoDictionary) { if (!$this->isAssociativeArray($value)) { $t = new CFArray(); foreach ($value as $v) { $t->add($this->toCFType($v)); } return $t; } } $t = new CFDictionary(); foreach ($value as $k => $v) { $t->add($k, $this->toCFType($v)); } return $t; break; case is_bool($value): return new CFBoolean($value); break; case is_string($value): return new CFString($value); break; case is_null($value): return new CFString(); break; case is_resource($value): if ($this->suppressExceptions) { return $this->defaultValue(); } throw new PListException('Could not determine CFType for resource of type ' . get_resource_type($value)); break; case is_numeric($value): return new CFNumber($value); break; default: if ($this->suppressExceptions) { return $this->defaultValue(); } throw new PListException('Could not determine CFType for ' . gettype($value)); break; } }