private function doMarshal($mappedObject, WriterHelper $writer)
{
$className = get_class($mappedObject);
$classMetadata = $this->classMetadataFactory->getMetadataFor($className);
if (!$this->classMetadataFactory->hasMetadataFor($className)) {
throw MarshallerException::mappingNotFoundForClass($className);
}
// PreMarshall Hook
if ($classMetadata->hasLifecycleCallbacks(Events::preMarshal)) {
$classMetadata->invokeLifecycleCallbacks(Events::preMarshal, $mappedObject);
}
if (isset($this->visited[spl_object_hash($mappedObject)])) {
return;
}
$this->visited[spl_object_hash($mappedObject)] = true;
$writer->startElement($classMetadata->getXmlName());
$namespaces = $classMetadata->getXmlNamespaces();
if (!empty($namespaces)) {
foreach ($namespaces as $namespace) {
$writer->writeNamespace($namespace['url'], $namespace['prefix']);
}
}
// build ordered field mappings for this class
$fieldMappings = $classMetadata->getFieldMappings();
$orderedMap = array();
if (!empty($fieldMappings)) {
foreach ($fieldMappings as $fieldMapping) {
$orderedMap[$fieldMapping['node']][] = $fieldMapping;
}
}
// do attributes
if (array_key_exists(ClassMetadata::XML_ATTRIBUTE, $orderedMap)) {
foreach ($orderedMap[ClassMetadata::XML_ATTRIBUTE] as $fieldMapping) {
$fieldName = $fieldMapping['fieldName'];
$fieldValue = $classMetadata->getFieldValue($mappedObject, $fieldName);
if ($classMetadata->isRequired($fieldName) && $fieldValue === null) {
throw MarshallerException::fieldRequired($className, $fieldName);
}
if ($fieldValue !== null || $classMetadata->isNullable($fieldName)) {
$this->writeAttribute($writer, $classMetadata, $fieldName, $fieldValue);
}
}
}
// do text
if (array_key_exists(ClassMetadata::XML_TEXT, $orderedMap)) {
foreach ($orderedMap[ClassMetadata::XML_TEXT] as $fieldMapping) {
$fieldName = $fieldMapping['fieldName'];
$fieldValue = $classMetadata->getFieldValue($mappedObject, $fieldName);
if ($classMetadata->isRequired($fieldName) && $fieldValue === null) {
throw MarshallerException::fieldRequired($className, $fieldName);
}
if ($fieldValue !== null || $classMetadata->isNullable($fieldName)) {
$this->writeText($writer, $classMetadata, $fieldName, $fieldValue);
}
}
}
// do elements
if (array_key_exists(ClassMetadata::XML_ELEMENT, $orderedMap)) {
foreach ($orderedMap[ClassMetadata::XML_ELEMENT] as $fieldMapping) {
$fieldName = $fieldMapping['fieldName'];
$fieldValue = $classMetadata->getFieldValue($mappedObject, $fieldName);
if ($classMetadata->isRequired($fieldName) && $fieldValue === null) {
throw MarshallerException::fieldRequired($className, $fieldName);
}
if ($fieldValue !== null || $classMetadata->isNullable($fieldName)) {
$this->writeElement($writer, $classMetadata, $fieldName, $fieldValue);
}
}
}
// do value
if (array_key_exists(ClassMetadata::XML_VALUE, $orderedMap)) {
foreach ($orderedMap[ClassMetadata::XML_VALUE] as $fieldMapping) {
$fieldName = $fieldMapping['fieldName'];
$fieldValue = $classMetadata->getFieldValue($mappedObject, $fieldName);
if ($classMetadata->isRequired($fieldName) && $fieldValue === null) {
throw MarshallerException::fieldRequired($className, $fieldName);
}
if ($fieldValue !== null || $classMetadata->isNullable($fieldName)) {
$type = $classMetadata->getTypeOfField($fieldName);
$writer->writeValue(Type::getType($type)->convertToXmlValue($fieldValue));
}
}
}
// PostMarshal hook
if ($classMetadata->hasLifecycleCallbacks(Events::postMarshal)) {
$classMetadata->invokeLifecycleCallbacks(Events::postMarshal, $mappedObject);
}
$writer->endElement();
}