private function propsToXML($properties)
{
$namespaces = array('mix' => "http://www.jcp.org/jcr/mix/1.0", 'nt' => "http://www.jcp.org/jcr/nt/1.0", 'xs' => "http://www.w3.org/2001/XMLSchema", 'jcr' => "http://www.jcp.org/jcr/1.0", 'sv' => "http://www.jcp.org/jcr/sv/1.0", 'rep' => "internal");
$doms = array('stringDom' => array(), 'numericalDom' => array());
$binaryData = $references = array();
foreach ($properties as $property) {
$targetDoms = array('stringDom');
switch ($property->getType()) {
case PropertyType::WEAKREFERENCE:
case PropertyType::REFERENCE:
$references[$property->getName()] = array('type' => $property->getType(), 'values' => $property->isMultiple() ? $property->getString() : array($property->getString()));
case PropertyType::NAME:
case PropertyType::URI:
case PropertyType::PATH:
case PropertyType::STRING:
$values = $property->getString();
break;
case PropertyType::DECIMAL:
$values = $property->getDecimal();
$targetDoms[] = 'numericalDom';
break;
case PropertyType::BOOLEAN:
$values = array_map('intval', (array) $property->getBoolean());
break;
case PropertyType::LONG:
$values = $property->getLong();
$targetDoms[] = 'numericalDom';
break;
case PropertyType::BINARY:
if ($property->isNew() || $property->isModified()) {
$values = array();
foreach ((array) $property->getValueForStorage() as $stream) {
if (null === $stream) {
$binary = '';
} else {
$binary = stream_get_contents($stream);
fclose($stream);
}
$binaryData[$property->getName()][] = $binary;
$length = strlen($binary);
$values[] = $length;
}
} else {
$values = $property->getLength();
if (!$property->isMultiple() && empty($values)) {
$values = array(0);
}
}
break;
case PropertyType::DATE:
$values = $property->getDate();
if ($values instanceof \DateTime) {
$values = array($values);
}
foreach ((array) $values as $key => $date) {
if ($date instanceof \DateTime) {
// do not modify the instance which is associated with the node.
$date = clone $date;
// normalize to UTC for storage.
$date->setTimezone(new \DateTimeZone('UTC'));
}
$values[$key] = $date;
}
$values = $this->valueConverter->convertType($values, PropertyType::STRING);
break;
case PropertyType::DOUBLE:
$values = $property->getDouble();
$targetDoms[] = 'numericalDom';
break;
default:
throw new RepositoryException('unknown type ' . $property->getType());
}
foreach ($targetDoms as $targetDom) {
$doms[$targetDom][] = array('name' => $property->getName(), 'type' => PropertyType::nameFromValue($property->getType()), 'multiple' => $property->isMultiple(), 'lengths' => (array) $property->getLength(), 'values' => $values);
}
}
$ret = array('stringDom' => null, 'numericalDom' => null, 'binaryData' => $binaryData, 'references' => $references);
foreach ($doms as $targetDom => $properties) {
$dom = new \DOMDocument('1.0', 'UTF-8');
$rootNode = $dom->createElement('sv:node');
foreach ($namespaces as $namespace => $uri) {
$rootNode->setAttribute('xmlns:' . $namespace, $uri);
}
$dom->appendChild($rootNode);
foreach ($properties as $property) {
/* @var $property Property */
$propertyNode = $dom->createElement('sv:property');
$propertyNode->setAttribute('sv:name', $property['name']);
$propertyNode->setAttribute('sv:type', $property['type']);
$propertyNode->setAttribute('sv:multi-valued', $property['multiple'] ? '1' : '0');
$lengths = (array) $property['lengths'];
foreach ((array) $property['values'] as $key => $value) {
$element = $propertyNode->appendChild($dom->createElement('sv:value'));
$element->appendChild($dom->createTextNode($value));
if (isset($lengths[$key])) {
$lengthAttribute = $dom->createAttribute('length');
$lengthAttribute->value = $lengths[$key];
$element->appendChild($lengthAttribute);
}
}
$rootNode->appendChild($propertyNode);
}
if (count($properties)) {
$ret[$targetDom] = $dom;
}
}
return $ret;
}