Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into bugfix/xml-list-nam…
Browse files Browse the repository at this point in the history
…espace
  • Loading branch information
Björn Bösel committed Jan 11, 2017
2 parents eeb3e45 + f14e7ec commit 20de51f
Show file tree
Hide file tree
Showing 23 changed files with 358 additions and 16 deletions.
62 changes: 62 additions & 0 deletions doc/reference/annotations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,68 @@ Resulting XML:
<name><![CDATA[Johannes]]></name>
</result>
@XmlDiscriminator
~~~~~~~~~~~~~~~~~
This annotation allows to modify the behaviour of @Discriminator regarding handling of XML.


Available Options:

+-------------------------------------+--------------------------------------------------+
| Type | Description |
+=====================================+==================================================+
| attribute | use an attribute instead of a child node |
+-------------------------------------+--------------------------------------------------+
| cdata | render child node content with or without cdata |
+-------------------------------------+--------------------------------------------------+

Example for "attribute":
.. code-block :: php
<?php
use JMS\Serializer\Annotation\Discriminator;
use JMS\Serializer\Annotation\XmlDiscriminator;
/**
* @Discriminator(field = "type", map = {"car": "Car", "moped": "Moped"}, groups={"foo", "bar"})
* @XmlDiscriminator(attribute=true)
*/
abstract class Vehicle { }
class Car extends Vehicle { }
Resulting XML:

.. code-block :: xml
<vehicle type="car" />
Example for "cdata":

.. code-block :: php
<?php
use JMS\Serializer\Annotation\Discriminator;
use JMS\Serializer\Annotation\XmlDiscriminator;
/**
* @Discriminator(field = "type", map = {"car": "Car", "moped": "Moped"}, groups={"foo", "bar"})
* @XmlDiscriminator(attribute=true)
*/
abstract class Vehicle { }
class Car extends Vehicle { }
Resulting XML:

.. code-block :: xml
<vehicle><type>car</type></vehicle>
@XmlValue
~~~~~~~~~
This allows you to mark properties which should be set as the value of the
Expand Down
1 change: 1 addition & 0 deletions doc/reference/xml_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ XML Reference
accessor-order="custom" custom-accessor-order="propertyName1,propertyName2,...,propertyNameN"
access-type="public_method" discriminator-field-name="type" read-only="false">
<xml-namespace prefix="atom" uri="http://www.w3.org/2005/Atom"/>
<xml-discriminator attribute="true" cdata="false"/>
<discriminator-class value="some-value">ClassName</discriminator-class>
<discriminator-groups>
<group>foo</group>
Expand Down
3 changes: 3 additions & 0 deletions doc/reference/yml_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ YAML Reference
map:
some-value: ClassName
groups: [foo, bar]
xml_attribute: true
xml_element:
cdata: false
virtual_properties:
getSomeProperty:
serialized_name: foo
Expand Down
37 changes: 37 additions & 0 deletions src/JMS/Serializer/Annotation/XmlDiscriminator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

/*
* Copyright 2016 Björn Bösel <bjoern.boesel@twt.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace JMS\Serializer\Annotation;


/**
* @Annotation
* @Target("CLASS")
*/
class XmlDiscriminator
{
/**
* @var boolean
*/
public $attribute = false;

/**
* @var boolean
*/
public $cdata = true;
}
2 changes: 1 addition & 1 deletion src/JMS/Serializer/Exclusion/GroupsExclusionStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ private function getGroupsFor(Context $navigatorContext)
foreach ($paths as $index => $path) {
if (!array_key_exists($path, $groups)) {
if ($index > 0) {
$groups = array('Default');
$groups = array(self::DEFAULT_GROUP);
}

break;
Expand Down
5 changes: 5 additions & 0 deletions src/JMS/Serializer/GraphNavigator.php
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,11 @@ private function resolveMetadata($data, ClassMetadata $metadata)
$typeValue = (string) $data[$metadata->discriminatorFieldName];
break;

// Check XML attribute for discriminatorFieldName
case is_object($data) && $metadata->xmlDiscriminatorAttribute && isset($data[$metadata->discriminatorFieldName]):
$typeValue = (string) $data[$metadata->discriminatorFieldName];
break;

case is_object($data) && isset($data->{$metadata->discriminatorFieldName}):
$typeValue = (string) $data->{$metadata->discriminatorFieldName};
break;
Expand Down
15 changes: 15 additions & 0 deletions src/JMS/Serializer/Metadata/ClassMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ class ClassMetadata extends MergeableClassMetadata
public $discriminatorMap = array();
public $discriminatorGroups = array();

public $xmlDiscriminatorAttribute = false;
public $xmlDiscriminatorCData = true;

public function setDiscriminator($fieldName, array $map, array $groups = array())
{
if (empty($fieldName)) {
Expand Down Expand Up @@ -203,6 +206,8 @@ public function merge(MergeableInterface $object)
$this->discriminatorGroups
);
$discriminatorProperty->serializedName = $this->discriminatorFieldName;
$discriminatorProperty->xmlAttribute = $this->xmlDiscriminatorAttribute;
$discriminatorProperty->xmlElementCData = $this->xmlDiscriminatorCData;
$this->propertyMetadata[$this->discriminatorFieldName] = $discriminatorProperty;
}

Expand Down Expand Up @@ -249,6 +254,8 @@ public function serialize()
$this->discriminatorGroups,
parent::serialize(),
'discriminatorGroups' => $this->discriminatorGroups,
'xmlDiscriminatorAttribute' => $this->xmlDiscriminatorAttribute,
'xmlDiscriminatorCData' => $this->xmlDiscriminatorCData,
));
}

Expand Down Expand Up @@ -279,6 +286,14 @@ public function unserialize($str)
$this->discriminatorGroups = $deserializedData['discriminatorGroups'];
}

if (isset($deserializedData['xmlDiscriminatorAttribute'])) {
$this->xmlDiscriminatorAttribute = $deserializedData['xmlDiscriminatorAttribute'];
}

if (isset($deserializedData['xmlDiscriminatorCData'])) {
$this->xmlDiscriminatorCData = $deserializedData['xmlDiscriminatorCData'];
}

parent::unserialize($parentStr);
}

Expand Down
4 changes: 4 additions & 0 deletions src/JMS/Serializer/Metadata/Driver/AnnotationDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
namespace JMS\Serializer\Metadata\Driver;

use JMS\Serializer\Annotation\Discriminator;
use JMS\Serializer\Annotation\XmlDiscriminator;
use JMS\Serializer\GraphNavigator;
use JMS\Serializer\Annotation\HandlerCallback;
use JMS\Serializer\Annotation\AccessorOrder;
Expand Down Expand Up @@ -99,6 +100,9 @@ public function loadMetadataForClass(\ReflectionClass $class)
} else {
$classMetadata->setDiscriminator($annot->field, $annot->map, $annot->groups);
}
} elseif ($annot instanceof XmlDiscriminator) {
$classMetadata->xmlDiscriminatorAttribute = (bool) $annot->attribute;
$classMetadata->xmlDiscriminatorCData = (bool) $annot->cdata;
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/JMS/Serializer/Metadata/Driver/XmlDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,15 @@ protected function loadMetadataFromFile(\ReflectionClass $class, $path)
$metadata->registerNamespace((string) $xmlNamespace->attributes()->uri, $prefix);
}

foreach ($elem->xpath('./xml-discriminator') as $xmlDiscriminator) {
if (isset($xmlDiscriminator->attributes()->attribute)) {
$metadata->xmlDiscriminatorAttribute = (string) $xmlDiscriminator->attributes()->attribute === 'true';
}
if (isset($xmlDiscriminator->attributes()->cdata)) {
$metadata->xmlDiscriminatorCData = (string) $xmlDiscriminator->attributes()->cdata === 'true';
}
}

foreach ($elem->xpath('./virtual-property') as $method) {
if ( ! isset($method->attributes()->method)) {
throw new RuntimeException('The method attribute must be set for all virtual-property elements.');
Expand Down
10 changes: 10 additions & 0 deletions src/JMS/Serializer/Metadata/Driver/YamlDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,16 @@ private function addClassProperties(ClassMetadata $metadata, array $config)
}
$groups = isset($config['discriminator']['groups']) ? $config['discriminator']['groups'] : array();
$metadata->setDiscriminator($config['discriminator']['field_name'], $config['discriminator']['map'], $groups);

if (isset($config['discriminator']['xml_attribute'])) {
$metadata->xmlDiscriminatorAttribute = (bool) $config['discriminator']['xml_attribute'];
}
if (isset($config['discriminator']['xml_element'])) {
if (isset($config['discriminator']['xml_element']['cdata'])) {
$metadata->xmlDiscriminatorCData = (bool) $config['discriminator']['xml_element']['cdata'];
}
}

}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,21 +48,21 @@ public function getExclusionRules()
[['foo'], ['bar'], true],
[['bar'], ['foo'], true],

[['foo', 'Default'], [], false],
[['foo', GroupsExclusionStrategy::DEFAULT_GROUP], [], false],
[['foo', 'bar'], [], true],
[['foo', 'bar'], ['Default'], true],
[['foo', 'bar'], [GroupsExclusionStrategy::DEFAULT_GROUP], true],
[['foo', 'bar'], ['foo'], false],

[['foo', 'Default'], ['test'], true],
[['foo', 'Default', 'test'], ['test'], false],
[['foo', GroupsExclusionStrategy::DEFAULT_GROUP], ['test'], true],
[['foo', GroupsExclusionStrategy::DEFAULT_GROUP, 'test'], ['test'], false],

[['foo'], ['Default'], true],
[['Default'], [], false],
[[], ['Default'], false],
[['Default'], ['Default'], false],
[['Default', 'foo'], ['Default'], false],
[['Default'], ['Default','foo'], false],
[['foo'], ['Default','foo'], false],
[['foo'], [GroupsExclusionStrategy::DEFAULT_GROUP], true],
[[GroupsExclusionStrategy::DEFAULT_GROUP], [], false],
[[], [GroupsExclusionStrategy::DEFAULT_GROUP], false],
[[GroupsExclusionStrategy::DEFAULT_GROUP], [GroupsExclusionStrategy::DEFAULT_GROUP], false],
[[GroupsExclusionStrategy::DEFAULT_GROUP, 'foo'], [GroupsExclusionStrategy::DEFAULT_GROUP], false],
[[GroupsExclusionStrategy::DEFAULT_GROUP], [GroupsExclusionStrategy::DEFAULT_GROUP, 'foo'], false],
[['foo'], [GroupsExclusionStrategy::DEFAULT_GROUP, 'foo'], false],
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

/*
* Copyright 2016 Björn Bösel <bjoern.boesel@twt.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace JMS\Serializer\Tests\Fixtures\Discriminator;

class ObjectWithXmlAttributeDiscriminatorChild extends ObjectWithXmlAttributeDiscriminatorParent
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

/*
* Copyright 2016 Björn Bösel <bjoern.boesel@twt.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace JMS\Serializer\Tests\Fixtures\Discriminator;

use JMS\Serializer\Annotation as Serializer;

/**
* @Serializer\Discriminator(field = "type", map = {
* "child": "JMS\Serializer\Tests\Fixtures\Discriminator\ObjectWithXmlAttributeDiscriminatorChild"
* })
* @Serializer\XmlDiscriminator(attribute=true, cdata=false)
*/
class ObjectWithXmlAttributeDiscriminatorParent
{

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

/*
* Copyright 2016 Björn Bösel <bjoern.boesel@twt.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace JMS\Serializer\Tests\Fixtures\Discriminator;

class ObjectWithXmlNotCDataDiscriminatorChild extends ObjectWithXmlNotCDataDiscriminatorParent
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

/*
* Copyright 2016 Björn Bösel <bjoern.boesel@twt.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace JMS\Serializer\Tests\Fixtures\Discriminator;

use JMS\Serializer\Annotation as Serializer;

/**
* @Serializer\Discriminator(field = "type", map = {
* "child": "JMS\Serializer\Tests\Fixtures\Discriminator\ObjectWithXmlNotCDataDiscriminatorChild"
* })
* @Serializer\XmlDiscriminator(cdata=false)
*/
class ObjectWithXmlNotCDataDiscriminatorParent
{

}
Loading

0 comments on commit 20de51f

Please sign in to comment.