Skip to content

Commit

Permalink
Merge pull request #187 from mvrhov/noCdata
Browse files Browse the repository at this point in the history
No CData
  • Loading branch information
schmittjoh committed Dec 4, 2013
2 parents d9f2e4e + efffbe2 commit 22daa25
Show file tree
Hide file tree
Showing 30 changed files with 236 additions and 8 deletions.
25 changes: 25 additions & 0 deletions doc/reference/annotations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,8 @@ Resulting XML:
This allows you to mark properties which should be set as the value of the
current element. Note that this has the limitation that any additional
properties of that object must have the @XmlAttribute annotation.
XMlValue also has property cdata. Which has the same meaning as the one in
XMLElement.

.. code-block :: php
Expand Down Expand Up @@ -508,3 +510,26 @@ Resulting XML:
.. code-block :: xml
<result name="firstname" value="Adrien"/>
@XmlElement
~~~~~~~~
This annotation can be defined on a property to add additional xml serialization/deserialization properties.

.. code-block :: php
<?php
use JMS\Serializer\Annotation\XmlElement;
class User
{
/**
* @XmlElement(cdata=false)
*/
private $id = 'my_id;
}
Resulting XML:

.. code-block :: xml
<id>my_id</id>
1 change: 1 addition & 0 deletions doc/reference/xml_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ XML Reference
<type><![CDATA[]]></type>
<xml-list inline="true" entry-name="foobar" />
<xml-map inline="true" key-attribute-name="foo" entry-name="bar" />
<xml-element cdata="false" />
</property>
<callback-method name="foo" type="pre-serialize" />
<callback-method name="bar" type="post-serialize" />
Expand Down
2 changes: 2 additions & 0 deletions doc/reference/yml_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ YAML Reference
key_attribute_name: foo
entry_name: bar
xml_attribute_map: true
xml_element:
cdata: false
max_depth: 2

handler_callbacks:
Expand Down
31 changes: 31 additions & 0 deletions src/JMS/Serializer/Annotation/XmlElement.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

/*
* Copyright 2013 Johannes M. Schmitt <[email protected]>
*
* 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({"PROPERTY","METHOD"})
*/
final class XmlElement
{
/**
* @var boolean
*/
public $cdata = true;
}
4 changes: 4 additions & 0 deletions src/JMS/Serializer/Annotation/XmlValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,8 @@
*/
final class XmlValue
{
/**
* @var boolean
*/
public $cdata = true;
}
12 changes: 11 additions & 1 deletion src/JMS/Serializer/Handler/DateHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@
use JMS\Serializer\Exception\RuntimeException;
use JMS\Serializer\VisitorInterface;
use JMS\Serializer\GraphNavigator;
use JMS\Serializer\XmlSerializationVisitor;

class DateHandler implements SubscribingHandlerInterface
{
private $defaultFormat;
private $defaultTimezone;
private $xmlCData;

public static function getSubscribingMethods()
{
Expand All @@ -55,21 +57,29 @@ public static function getSubscribingMethods()
return $methods;
}

public function __construct($defaultFormat = \DateTime::ISO8601, $defaultTimezone = 'UTC')
public function __construct($defaultFormat = \DateTime::ISO8601, $defaultTimezone = 'UTC', $xmlCData = true)
{
$this->defaultFormat = $defaultFormat;
$this->defaultTimezone = new \DateTimeZone($defaultTimezone);
$this->xmlCData = $xmlCData;
}

public function serializeDateTime(VisitorInterface $visitor, \DateTime $date, array $type, Context $context)
{
if ($visitor instanceof XmlSerializationVisitor && false === $this->xmlCData) {
return $visitor->visitSimpleString($date->format($this->getFormat($type)), $type, $context);
}
return $visitor->visitString($date->format($this->getFormat($type)), $type, $context);
}

public function serializeDateInterval(VisitorInterface $visitor, \DateInterval $date, array $type, Context $context)
{
$iso8601DateIntervalString = $this->format($date);

if ($visitor instanceof XmlSerializationVisitor && false === $this->xmlCData) {
return $visitor->visitSimpleString($iso8601DateIntervalString, $type, $context);
}

return $visitor->visitString($iso8601DateIntervalString, $type, $context);
}

Expand Down
5 changes: 5 additions & 0 deletions src/JMS/Serializer/Metadata/Driver/AnnotationDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@
use JMS\Serializer\Annotation\XmlList;
use JMS\Serializer\Annotation\XmlValue;
use JMS\Serializer\Annotation\XmlKeyValuePairs;
use JMS\Serializer\Annotation\XmlElement;
use JMS\Serializer\Annotation\PostSerialize;
use JMS\Serializer\Annotation\PostDeserialize;
use JMS\Serializer\Annotation\PreSerialize;
use JMS\Serializer\Annotation\VirtualProperty;
use JMS\Serializer\Metadata\XmlElementMetadata;
use Metadata\MethodMetadata;
use Doctrine\Common\Annotations\Reader;
use JMS\Serializer\Annotation\Type;
Expand Down Expand Up @@ -169,6 +171,9 @@ public function loadMetadataForClass(\ReflectionClass $class)
$propertyMetadata->xmlAttribute = true;
} elseif ($annot instanceof XmlValue) {
$propertyMetadata->xmlValue = true;
$propertyMetadata->xmlElementCData = $annot->cdata;
} elseif ($annot instanceof XmlElement) {
$propertyMetadata->xmlElementCData = $annot->cdata;
} elseif ($annot instanceof AccessType) {
$accessType = $annot->type;
} elseif ($annot instanceof ReadOnly) {
Expand Down
7 changes: 7 additions & 0 deletions src/JMS/Serializer/Metadata/Driver/XmlDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,13 @@ protected function loadMetadataFromFile(\ReflectionClass $class, $path)
}
}

if (isset($pElem->{'xml-element'})) {
$colConfig = $pElem->{'xml-element'};
if (isset($colConfig->attributes()->cdata)) {
$pMetadata->xmlElementCData = 'true' === (string) $colConfig->attributes()->cdata;
}
}

if (isset($pElem->attributes()->{'xml-attribute'})) {
$pMetadata->xmlAttribute = 'true' === (string) $pElem->attributes()->{'xml-attribute'};
}
Expand Down
7 changes: 7 additions & 0 deletions src/JMS/Serializer/Metadata/Driver/YamlDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,13 @@ protected function loadMetadataFromFile(\ReflectionClass $class, $file)
}
}

if (isset($pConfig['xml_element'])) {
$colConfig = $pConfig['xml_element'];
if (isset($colConfig['cdata'])) {
$pMetadata->xmlElementCData = (Boolean) $colConfig['cdata'];
}
}

if (isset($pConfig['xml_attribute'])) {
$pMetadata->xmlAttribute = (Boolean) $pConfig['xml_attribute'];
}
Expand Down
3 changes: 3 additions & 0 deletions src/JMS/Serializer/Metadata/PropertyMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class PropertyMetadata extends BasePropertyMetadata
public $xmlAttribute = false;
public $xmlValue = false;
public $xmlKeyValuePairs = false;
public $xmlElementCData = true;
public $getter;
public $setter;
public $inline = false;
Expand Down Expand Up @@ -109,6 +110,7 @@ public function serialize()
$this->xmlAttribute,
$this->xmlValue,
$this->xmlKeyValuePairs,
$this->xmlElementCData,
$this->getter,
$this->setter,
$this->inline,
Expand All @@ -134,6 +136,7 @@ public function unserialize($str)
$this->xmlAttribute,
$this->xmlValue,
$this->xmlKeyValuePairs,
$this->xmlElementCData,
$this->getter,
$this->setter,
$this->inline,
Expand Down
2 changes: 2 additions & 0 deletions src/JMS/Serializer/Metadata/StaticPropertyMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public function serialize()
$this->xmlAttribute,
$this->xmlValue,
$this->xmlKeyValuePairs,
$this->xmlElementCData,
$this->getter,
$this->setter,
$this->inline,
Expand All @@ -84,6 +85,7 @@ public function unserialize($str)
$this->xmlAttribute,
$this->xmlValue,
$this->xmlKeyValuePairs,
$this->xmlElementCData,
$this->getter,
$this->setter,
$this->inline,
Expand Down
2 changes: 2 additions & 0 deletions src/JMS/Serializer/Metadata/VirtualPropertyMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public function serialize()
$this->xmlAttribute,
$this->xmlValue,
$this->xmlKeyValuePairs,
$this->xmlElementCData,
$this->getter,
$this->setter,
$this->inline,
Expand All @@ -82,6 +83,7 @@ public function unserialize($str)
$this->xmlAttribute,
$this->xmlValue,
$this->xmlKeyValuePairs,
$this->xmlElementCData,
$this->getter,
$this->setter,
$this->inline,
Expand Down
32 changes: 30 additions & 2 deletions src/JMS/Serializer/XmlSerializationVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,34 @@ public function visitNull($data, array $type, Context $context)
}

public function visitString($data, array $type, Context $context)
{

if (null !== $this->currentMetadata) {
$doCData = $this->currentMetadata->xmlElementCData;
} else {
$doCData = true;
}

if (null === $this->document) {
$this->document = $this->createDocument(null, null, true);
$this->currentNode->appendChild($doCData ? $this->document->createCDATASection($data) : $this->document->createTextNode((string) $data));

return;
}

return $doCData ? $this->document->createCDATASection($data) : $this->document->createTextNode((string) $data);
}

public function visitSimpleString($data, array $type, Context $context)
{
if (null === $this->document) {
$this->document = $this->createDocument(null, null, true);
$this->currentNode->appendChild($this->document->createCDATASection($data));
$this->currentNode->appendChild($this->document->createTextNode((string) $data));

return;
}

return $this->document->createCDATASection($data);
return $this->document->createTextNode((string) $data);
}

public function visitBoolean($data, array $type, Context $context)
Expand Down Expand Up @@ -179,7 +198,10 @@ public function visitProperty(PropertyMetadata $metadata, $object, Context $cont
}

if ($metadata->xmlAttribute) {
$this->setCurrentMetadata($metadata);
$node = $this->navigator->accept($v, $metadata->type, $context);
$this->revertCurrentMetadata();

if (!$node instanceof \DOMCharacterData) {
throw new RuntimeException(sprintf('Unsupported value for XML attribute. Expected character data, but got %s.', json_encode($v)));
}
Expand All @@ -197,7 +219,10 @@ public function visitProperty(PropertyMetadata $metadata, $object, Context $cont
if ($metadata->xmlValue) {
$this->hasValue = true;

$this->setCurrentMetadata($metadata);
$node = $this->navigator->accept($v, $metadata->type, $context);
$this->revertCurrentMetadata();

if (!$node instanceof \DOMCharacterData) {
throw new RuntimeException(sprintf('Unsupported value for property %s::$%s. Expected character data, but got %s.', $metadata->reflection->class, $metadata->reflection->name, is_object($node) ? get_class($node) : gettype($node)));
}
Expand All @@ -213,7 +238,10 @@ public function visitProperty(PropertyMetadata $metadata, $object, Context $cont
}

foreach ($v as $key => $value) {
$this->setCurrentMetadata($metadata);
$node = $this->navigator->accept($value, null, $context);
$this->revertCurrentMetadata();

if (!$node instanceof \DOMCharacterData) {
throw new RuntimeException(sprintf('Unsupported value for a XML attribute map value. Expected character data, but got %s.', json_encode($v)));
}
Expand Down
8 changes: 8 additions & 0 deletions tests/JMS/Serializer/Tests/Fixtures/BlogPost.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use JMS\Serializer\Annotation\XmlRoot;
use JMS\Serializer\Annotation\XmlAttribute;
use JMS\Serializer\Annotation\XmlList;
use JMS\Serializer\Annotation\XmlElement;
use JMS\Serializer\Annotation\Groups;
use Doctrine\Common\Collections\ArrayCollection;
use PhpCollection\Map;
Expand All @@ -32,6 +33,13 @@
/** @XmlRoot("blog-post") */
class BlogPost
{
/**
* @Type("string")
* @XmlElement(cdata=false)
* @Groups({"comments","post"})
*/
private $id = 'what_a_nice_id';

/**
* @Type("string")
* @Groups({"comments","post"})
Expand Down
3 changes: 2 additions & 1 deletion tests/JMS/Serializer/Tests/Fixtures/Person.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use JMS\Serializer\Annotation\XmlAttribute;
use JMS\Serializer\Annotation\XmlValue;
use JMS\Serializer\Annotation\XmlRoot;
use JMS\Serializer\Annotation\XmlElement;
use JMS\Serializer\Annotation\Type;

/**
Expand All @@ -30,7 +31,7 @@ class Person
{
/**
* @Type("string")
* @XmlValue
* @XmlValue(cdata=false)
*/
public $name;

Expand Down
14 changes: 14 additions & 0 deletions tests/JMS/Serializer/Tests/Metadata/Driver/BaseDriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ public function testLoadBlogPostMetadata()
$this->assertNotNull($m);
$this->assertEquals('blog-post', $m->xmlRootName);

$p = new PropertyMetadata($m->name, 'id');
$p->type = array('name' => 'string', 'params' => array());
$p->groups = array("comments","post");
$p->xmlElementCData = false;
$this->assertEquals($p, $m->propertyMetadata['id']);

$p = new PropertyMetadata($m->name, 'title');
$p->type = array('name' => 'string', 'params' => array());
$p->groups = array("comments","post");
Expand Down Expand Up @@ -152,6 +158,14 @@ public function testMaxDepth()
$this->assertEquals(2, $m->propertyMetadata['children']->maxDepth);
}

public function testPersonCData()
{
$m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\Person'));

$this->assertNotNull($m);
$this->assertFalse($m->propertyMetadata['name']->xmlElementCData);
}

/**
* @return DriverInterface
*/
Expand Down
6 changes: 6 additions & 0 deletions tests/JMS/Serializer/Tests/Metadata/Driver/php/BlogPost.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
$metadata = new ClassMetadata('JMS\Serializer\Tests\Fixtures\BlogPost');
$metadata->xmlRootName = 'blog-post';

$pMetadata = new PropertyMetadata('JMS\Serializer\Tests\Fixtures\BlogPost', 'id');
$pMetadata->setType('string');
$pMetadata->groups = array('comments','post');
$pMetadata->xmlElementCData = false;
$metadata->addPropertyMetadata($pMetadata);

$pMetadata = new PropertyMetadata('JMS\Serializer\Tests\Fixtures\BlogPost', 'title');
$pMetadata->setType('string');
$pMetadata->groups = array('comments','post');
Expand Down
Loading

0 comments on commit 22daa25

Please sign in to comment.