Skip to content

Commit

Permalink
Add xml mapping driver to References extension
Browse files Browse the repository at this point in the history
  • Loading branch information
aramalipoor committed Jul 5, 2015
1 parent 148a2f5 commit 7303ec2
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 16 deletions.
109 changes: 109 additions & 0 deletions lib/Gedmo/References/Mapping/Driver/Xml.php
@@ -0,0 +1,109 @@
<?php

namespace Gedmo\References\Mapping\Driver;

use Gedmo\Mapping\Driver\Xml as BaseXml;
use Gedmo\Exception\InvalidMappingException;

/**
* This is a xml mapping driver for References
* behavioral extension. Used for extraction of extended
* metadata from xml specifically for References
* extension.
*
* @author Aram Alipoor <aram.alipoor@gmail.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class Xml extends BaseXml
{
/**
* @var array
*/
private $validTypes = array(
'document',
'entity'
);

/**
* @var array
*/
private $validReferences = array(
'referenceOne',
'referenceMany',
'referenceManyEmbed'
);

/**
* {@inheritDoc}
*/
public function readExtendedMetadata($meta, array &$config)
{
/**
* @var \SimpleXmlElement $xml
*/
$xml = $this->_getMapping($meta->name);
$xmlDoctrine = $xml;

$xml = $xml->children(self::GEDMO_NAMESPACE_URI);

if ($xmlDoctrine->getName() === 'entity' || $xmlDoctrine->getName() === 'document' || $xmlDoctrine->getName() === 'mapped-superclass') {
if (isset($xml->reference)) {
/**
* @var \SimpleXMLElement $element
*/
foreach ($xml->reference as $element) {
if (!$this->_isAttributeSet($element, 'type')) {
throw new InvalidMappingException("Reference type (document or entity) is not set in class - {$meta->name}");
}

$type = $this->_getAttribute($element, 'type');
if (!in_array($type, $this->validTypes)) {
throw new InvalidMappingException(
$type .
' is not a valid reference type, valid types are: ' .
implode(', ', $this->validTypes)
);
}

$reference = $this->_getAttribute($element, 'reference');
if (!in_array($reference, $this->validReferences)) {
throw new InvalidMappingException(
$reference .
' is not a valid reference, valid references are: ' .
implode(', ', $this->validReferences)
);
}

if (!$this->_isAttributeSet($element, 'field')) {
throw new InvalidMappingException("Reference field is not set in class - {$meta->name}");
}
$field = $this->_getAttribute($element, 'field');

if (!$this->_isAttributeSet($element, 'class')) {
throw new InvalidMappingException("Reference field is not set in class - {$meta->name}");
}
$class = $this->_getAttribute($element, 'class');

if (!$this->_isAttributeSet($element, 'identifier')) {
throw new InvalidMappingException("Reference identifier is not set in class - {$meta->name}");
}
$identifier = $this->_getAttribute($element, 'identifier');

$config[$reference][$field] = array(
'field' => $field,
'type' => $type,
'class' => $class,
'identifier' => $identifier
);

if (!$this->_isAttributeSet($element, 'mappedBy')) {
$config[$reference][$field]['mappedBy'] = $this->_getAttribute($element, 'mappedBy');
}
if (!$this->_isAttributeSet($element, 'inversedBy')) {
$config[$reference][$field]['inversedBy'] = $this->_getAttribute($element, 'inversedBy');
}
}
}
}
}
}
6 changes: 0 additions & 6 deletions lib/Gedmo/References/ReferencesListener.php
Expand Up @@ -154,12 +154,6 @@ private function updateReferences(EventArgs $eventArgs)
$manager = $this->getManager($mapping['type']);
$identifier = $ea->getIdentifier($manager, $referencedObject);

if (null === $identifier) {
$manager->persist($referencedObject);
$manager->flush();
$identifier = $ea->getIdentifier($manager, $referencedObject);
}

$meta->setFieldValue(
$object,
$mapping['identifier'],
Expand Down
34 changes: 25 additions & 9 deletions schemas/orm/doctrine-extensions-mapping-2-2.xsd
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://gediminasm.org/schemas/orm/doctrine-extensions-mapping"
xmlns:gedmo="http://gediminasm.org/schemas/orm/doctrine-extensions-mapping"
elementFormDefault="qualified">
targetNamespace="http://gediminasm.org/schemas/orm/doctrine-extensions-mapping"
xmlns:gedmo="http://gediminasm.org/schemas/orm/doctrine-extensions-mapping"
elementFormDefault="qualified">

<xs:annotation>
<xs:documentation><![CDATA[
Expand All @@ -14,12 +14,12 @@
]]></xs:documentation>
</xs:annotation>

<!--
It would be nice if we could force the gedmo with only necessary elements into each of doctrine elements.
Patches that do that are more than welcome.
Please note, that marking e.g filed element in xml document with xsi:type is not an option as we need to allow other
people to push their own additional attributes/elements into the same field element and they should not extend our schema
-->
<!--
It would be nice if we could force the gedmo with only necessary elements into each of doctrine elements.
Patches that do that are more than welcome.
Please note, that marking e.g filed element in xml document with xsi:type is not an option as we need to allow other
people to push their own additional attributes/elements into the same field element and they should not extend our schema
-->

<!-- entity -->
<xs:element name="translation" type="gedmo:translation"/>
Expand Down Expand Up @@ -60,6 +60,22 @@ people to push their own additional attributes/elements into the same field elem
<xs:attribute name="locking-timeout" type="xs:integer" default="3" />
</xs:complexType>

<xs:complexType name="reference">
<xs:attribute name="type" type="gedmo:reference-type" use="required" />
<xs:attribute name="field" type="xs:string" use="required" />
<xs:attribute name="identifier" type="xs:string" use="required" />
<xs:attribute name="class" type="xs:string" use="required" />
<xs:attribute name="mappedBy" type="xs:string" use="optional" />
<xs:attribute name="inversedBy" type="xs:string" use="optional" />
</xs:complexType>

<xs:simpleType name="reference-type">
<xs:restriction base="xs:token">
<xs:enumeration value="document"/>
<xs:enumeration value="entity"/>
</xs:restriction>
</xs:simpleType>

<xs:complexType name="tree-closure">
<xs:attribute name="class" type="xs:string" use="required" />
</xs:complexType>
Expand Down
2 changes: 1 addition & 1 deletion tests/Gedmo/References/ReferencesListenerTest.php
Expand Up @@ -163,7 +163,7 @@ public function testShouldPopulateReferenceManyEmbedWithLazyCollectionInstance()
$appleTV->addMetadata( $tvMetadata );
$samsungTV->addMetadata( $tvMetadata );
$this->dm->persist( $samsungTV );
$this->dm->persist($appleTV);
$this->dm->persist( $appleTV );
$this->dm->flush();

$this->assertEquals($appleTV->getMetadatas()->first(), $tvMetadata);
Expand Down

0 comments on commit 7303ec2

Please sign in to comment.