* * * content * * * @param Writer $writer * @param string[] $values * @return void */ function enum(Writer $writer, array $values) { foreach ($values as $value) { $writer->writeElement($value); } } /** * The valueObject serializer turns a simple PHP object into a classname. * * Every public property will be encoded as an xml element with the same * name, in the XML namespace as specified. * * Values that are set to null or an empty array are not serialized. To * serialize empty properties, you must specify them as an empty string. * * @param Writer $writer * @param object $valueObject * @param string $namespace */ function valueObject(Writer $writer, $valueObject, $namespace) { foreach (get_object_vars($valueObject) as $key => $val) { if (is_array($val)) { // If $val is an array, it has a special meaning. We need to // generate one child element for each item in $val foreach ($val as $child) { $writer->writeElement('{' . $namespace . '}' . $key, $child); } } elseif ($val !== null) { $writer->writeElement('{' . $namespace . '}' . $key, $val); } } } /** * This serializer helps you serialize xml structures that look like * this: * * * ... * ... * ... * * * In that previous example, this serializer just serializes the item element, * and this could be called like this: * * repeatingElements($writer, $items, '{}item'); * * @param Writer $writer * @param array $items A list of items sabre/xml can serialize. * @param string $childElementName Element name in clark-notation * @return void */ function repeatingElements(Writer $writer, array $items, $childElementName) { foreach ($items as $item) { $writer->writeElement($childElementName, $item); } } /** * This function is the 'default' serializer that is able to serialize most * things, and delegates to other serializers if needed. * * The standardSerializer supports a wide-array of values. * * $value may be a string or integer, it will just write out the string as text. * $value may be an instance of XmlSerializable or Element, in which case it * calls it's xmlSerialize() method. * $value may be a PHP callback/function/closure, in case we call the callback * and give it the Writer as an argument. * $value may be a an object, and if it's in the classMap we automatically call * the correct serializer for it. * $value may be null, in which case we do nothing. * * If $value is an array, the array must look like this: * * [ * [ * 'name' => '{namespaceUri}element-name', * 'value' => '...', * 'attributes' => [ 'attName' => 'attValue' ] * ] * [, * 'name' => '{namespaceUri}element-name2', * 'value' => '...', * ] * ] * * This would result in xml like: * * * ... * * * ... * * * The value property may be any value standardSerializer supports, so you can * nest data-structures this way. Both value and attributes are optional. * * Alternatively, you can also specify the array using this syntax: * * [ * [ * '{namespaceUri}element-name' => '...', * '{namespaceUri}element-name2' => '...', * ] * ] * * This is excellent for simple key->value structures, and here you can also * specify anything for the value. * * You can even mix the two array syntaxes. * * @param Writer $writer * @param string|int|float|bool|array|object * @return void */ function standardSerializer(Writer $writer, $value) { if (is_scalar($value)) { // String, integer, float, boolean $writer->text($value); } elseif ($value instanceof XmlSerializable) { // XmlSerializable classes or Element classes. $value->xmlSerialize($writer); } elseif (is_object($value) && isset($writer->classMap[get_class($value)])) { // It's an object which class appears in the classmap. $writer->classMap[get_class($value)]($writer, $value); } elseif (is_callable($value)) { // A callback $value($writer); } elseif (is_null($value)) { // nothing! } elseif (is_array($value) && array_key_exists('name', $value)) { // if the array had a 'name' element, we assume that this array // describes a 'name' and optionally 'attributes' and 'value'. $name = $value['name']; $attributes = isset($value['attributes']) ? $value['attributes'] : []; $value = isset($value['value']) ? $value['value'] : null; $writer->startElement($name); $writer->writeAttributes($attributes); $writer->write($value); $writer->endElement(); } elseif (is_array($value)) { foreach ($value as $name => $item) { if (is_int($name)) { // This item has a numeric index. We just loop through the // array and throw it back in the writer. standardSerializer($writer, $item); } elseif (is_string($name) && is_array($item) && isset($item['attributes'])) { // The key is used for a name, but $item has 'attributes' and // possibly 'value' $writer->startElement($name); $writer->writeAttributes($item['attributes']); if (isset($item['value'])) { $writer->write($item['value']); } $writer->endElement(); } elseif (is_string($name)) { // This was a plain key-value array. $writer->startElement($name); $writer->write($item); $writer->endElement(); } else { throw new InvalidArgumentException('The writer does not know how to serialize arrays with keys of type: ' . gettype($name)); } } } elseif (is_object($value)) { throw new InvalidArgumentException('The writer cannot serialize objects of class: ' . get_class($value)); } else { throw new InvalidArgumentException('The writer cannot serialize values of type: ' . gettype($value)); } }