Browse Source

merge master

mattw 12 years ago
parent
commit
14d18e755d

+ 7 - 1
.travis.yml

@@ -6,4 +6,10 @@ php:
 
 before_script:
     - curl -s http://getcomposer.org/installer | php
-    - php composer.phar install --dev
+    - php composer.phar install --dev
+
+script: phpunit --coverage-clover clover
+
+after_success:
+    - curl -sL https://bit.ly/artifact-uploader | php
+

+ 2 - 1
DependencyInjection/Compiler/CustomHandlersPass.php

@@ -38,7 +38,8 @@ class CustomHandlersPass implements CompilerPassInterface
 
         foreach ($container->findTaggedServiceIds('jms_serializer.subscribing_handler') as $id => $tags) {
             $class = $container->getDefinition($id)->getClass();
-            if ( ! is_subclass_of($class, 'JMS\SerializerBundle\Serializer\Handler\SubscribingHandlerInterface')) {
+            $ref = new \ReflectionClass($class);
+            if ( ! $ref->implementsInterface('JMS\SerializerBundle\Serializer\Handler\SubscribingHandlerInterface')) {
                 throw new \RuntimeException(sprintf('The service "%s" must implement the SubscribingHandlerInterface.', $id));
             }
 

+ 7 - 3
DependencyInjection/Compiler/RegisterEventListenersAndSubscribersPass.php

@@ -3,6 +3,7 @@
 namespace JMS\SerializerBundle\DependencyInjection\Compiler;
 
 use JMS\SerializerBundle\Serializer\EventDispatcher\EventDispatcher;
+use JMS\SerializerBundle\Serializer\EventDispatcher\EventSubscriberInterface;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
 use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
 
@@ -31,9 +32,12 @@ class RegisterEventListenersAndSubscribersPass implements CompilerPassInterface
         }
 
         foreach ($container->findTaggedServiceIds('jms_serializer.event_subscriber') as $id => $tags) {
-            $subscriberDefinition = $container->getDefinition($id);
-            $subscriberClass = $subscriberDefinition->getClass();
-            if ( ! is_subclass_of($subscriberClass, 'JMS\SerializerBundle\Serializer\EventDispatcher\EventSubscriberInterface')) {
+            $subscriberDefinition = $container->getDefinition($id);
+            $subscriberClass = $container->getDefinition($id)->getClass();
+            
+            $subscriberClassReflectionObj = new \ReflectionClass($subscriberClass);
+            
+            if ( ! $subscriberClassReflectionObj->implementsInterface('JMS\SerializerBundle\Serializer\EventDispatcher\EventSubscriberInterface') ) {
                 throw new \RuntimeException(sprintf('The service "%s" (class: %s) does not implement the EventSubscriberInterface.', $id, $subscriberClass));
             }
 

+ 9 - 3
Resources/doc/reference/annotations.rst

@@ -193,8 +193,9 @@ by the object iself.
 @Type
 ~~~~~
 This annotation can be defined on a property to specify the type of that property.
-This annotation must only be defined when you want to be able to deserialize an
-object.
+For deserialization, this annotation must be defined. For serialization, you may
+define it in order to enhance the produced output; for example, you may want to
+force a certain format to be used for DateTime types.
 
 Available Types:
 
@@ -219,7 +220,12 @@ Available Types:
 |                           | Examples: array<string, string>,                 |
 |                           | array<string, MyNamespace\MyObject>, etc.        |
 +---------------------------+--------------------------------------------------+
-| DateTime                  | PHP's DateTime object                            |
+| DateTime                  | PHP's DateTime object (default format/timezone)  |
++---------------------------+--------------------------------------------------+
+| DateTime<"format">        | PHP's DateTime object (custom format/default     |
+|                           | timezone)                                        |
++---------------------------+--------------------------------------------------+
+| DateTime<"format", "zone">| PHP's DateTime object (custom format/timezone)   |
 +---------------------------+--------------------------------------------------+
 | T                         | Where T is a fully qualified class name.         |
 +---------------------------+--------------------------------------------------+

+ 5 - 3
Serializer/Exclusion/GroupsExclusionStrategy.php

@@ -24,12 +24,14 @@ use JMS\SerializerBundle\Exception\RuntimeException;
 
 class GroupsExclusionStrategy implements ExclusionStrategyInterface
 {
+    const DEFAULT_GROUP = 'Default';
+
     private $groups = array();
 
     public function __construct(array $groups)
     {
         if (empty($groups)) {
-            throw new RuntimeException('Empty group array may not be configured for GroupsExclusionStrategy');
+            $groups = array(self::DEFAULT_GROUP);
         }
 
         foreach ($groups as $group) {
@@ -47,8 +49,8 @@ class GroupsExclusionStrategy implements ExclusionStrategyInterface
      */
     public function shouldSkipProperty(PropertyMetadata $property, $object = null)
     {
-        if (!$property->groups) {
-            return true;
+        if ( ! $property->groups) {
+            return ! isset($this->groups[self::DEFAULT_GROUP]);
         }
 
         foreach ($property->groups as $group) {

+ 10 - 1
Serializer/GraphNavigator.php

@@ -95,8 +95,17 @@ final class GraphNavigator
      */
     public function accept($data, array $type = null, VisitorInterface $visitor)
     {
-        // determine type if not given
+        // If the type was not given, we infer the most specific type from the
+        // input data in serialization mode.
         if (null === $type) {
+            if (self::DIRECTION_DESERIALIZATION === $this->direction) {
+                $msg = 'The type must be given for all properties when deserializing.';
+                if (null !== $path = $this->getCurrentPath()) {
+                    $msg .= ' Path: '.$path;
+                }
+
+                throw new \RuntimeException($msg);
+            }
 
             $typeName = gettype($data);
             if ('object' === $typeName) {

+ 1 - 1
Serializer/Serializer.php

@@ -70,7 +70,7 @@ class Serializer implements SerializerInterface
 
     public function setGroups($groups)
     {
-        if (!$groups) {
+        if ( ! $groups) {
             $this->exclusionStrategy = null;
 
             return;

+ 1 - 1
Tests/Serializer/Fixture/Article.php

@@ -1,6 +1,6 @@
 <?php
 
-namespace JMS\SerializerBundle\Tests\Serializer\Fixture;
+namespace JMS\SerializerBundle\Tests\Fixtures;
 
 use JMS\SerializerBundle\Serializer\JsonDeserializationVisitor;
 use JMS\SerializerBundle\Serializer\XmlDeserializationVisitor;

+ 1 - 1
Tests/Fixtures/GroupsObject.php

@@ -37,7 +37,7 @@ class GroupsObject
     private $foobar;
 
     /**
-     * @Groups({"bar"})
+     * @Groups({"bar", "Default"})
      * @Type("string")
      */
     private $bar;

+ 14 - 13
Tests/Serializer/BaseSerializationTest.php

@@ -69,7 +69,7 @@ use JMS\SerializerBundle\Tests\Fixtures\Price;
 use JMS\SerializerBundle\Tests\Fixtures\SimpleObject;
 use JMS\SerializerBundle\Tests\Fixtures\ObjectWithNullProperty;
 use JMS\SerializerBundle\Tests\Fixtures\SimpleObjectProxy;
-use JMS\SerializerBundle\Tests\Serializer\Fixture\Article;
+use JMS\SerializerBundle\Tests\Fixtures\Article;
 use JMS\SerializerBundle\Tests\Fixtures\Input;
 use JMS\SerializerBundle\Tests\Fixtures\ObjectWithEmptyHash;
 use Metadata\MetadataFactory;
@@ -318,7 +318,7 @@ abstract class BaseSerializationTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($this->getContent('article'), $result);
 
         if ($this->hasDeserializer()) {
-            $this->assertEquals($article, $this->deserialize($result, 'JMS\SerializerBundle\Tests\Serializer\Fixture\Article'));
+            $this->assertEquals($article, $this->deserialize($result, 'JMS\SerializerBundle\Tests\Fixtures\Article'));
         }
     }
 
@@ -480,23 +480,24 @@ abstract class BaseSerializationTest extends \PHPUnit_Framework_TestCase
 
     public function testGroups()
     {
-        $serializer =  $this->serializer;
-
         $groupsObject = new GroupsObject();
 
-        $this->assertEquals($this->getContent('groups_all'), $serializer->serialize($groupsObject, $this->getFormat()));
+        $this->assertEquals($this->getContent('groups_all'), $this->serializer->serialize($groupsObject, $this->getFormat()));
+
+        $this->serializer->setGroups(array("foo"));
+        $this->assertEquals($this->getContent('groups_foo'), $this->serializer->serialize($groupsObject, $this->getFormat()));
 
-        $serializer->setGroups(array("foo"));
-        $this->assertEquals($this->getContent('groups_foo'), $serializer->serialize($groupsObject, $this->getFormat()));
+        $this->serializer->setGroups(array("foo", "bar"));
+        $this->assertEquals($this->getContent('groups_foobar'), $this->serializer->serialize($groupsObject, $this->getFormat()));
 
-        $serializer->setGroups(array("foo", "bar"));
-        $this->assertEquals($this->getContent('groups_foobar'), $serializer->serialize($groupsObject, $this->getFormat()));
+        $this->serializer->setGroups(null);
+        $this->assertEquals($this->getContent('groups_all'), $this->serializer->serialize($groupsObject, $this->getFormat()));
 
-        $serializer->setGroups(null);
-        $this->assertEquals($this->getContent('groups_all'), $serializer->serialize($groupsObject, $this->getFormat()));
+        $this->serializer->setGroups(array());
+        $this->assertEquals($this->getContent('groups_all'), $this->serializer->serialize($groupsObject, $this->getFormat()));
 
-        $serializer->setGroups(array());
-        $this->assertEquals($this->getContent('groups_all'), $serializer->serialize($groupsObject, $this->getFormat()));
+        $this->serializer->setGroups(array('Default'));
+        $this->assertEquals($this->getContent('groups_default'), $this->serializer->serialize($groupsObject, $this->getFormat()));
     }
 
     public function testVirtualProperty()

+ 1 - 0
Tests/Serializer/JsonSerializationTest.php

@@ -76,6 +76,7 @@ class JsonSerializationTest extends BaseSerializationTest
             $outputs['groups_all'] = '{"foo":"foo","foobar":"foobar","bar":"bar","none":"none"}';
             $outputs['groups_foo'] = '{"foo":"foo","foobar":"foobar"}';
             $outputs['groups_foobar'] = '{"foo":"foo","foobar":"foobar","bar":"bar"}';
+            $outputs['groups_default'] = '{"bar":"bar","none":"none"}';
             $outputs['virtual_properties'] = '{"exist_field":"value","virtual_value":"value","test":"other-name"}';
             $outputs['virtual_properties_low'] = '{"low":1}';
             $outputs['virtual_properties_high'] = '{"high":8}';

+ 5 - 0
Tests/Serializer/xml/groups_default.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<result>
+  <bar><![CDATA[bar]]></bar>
+  <none><![CDATA[none]]></none>
+</result>

+ 2 - 0
Tests/Serializer/yml/groups_default.yml

@@ -0,0 +1,2 @@
+bar: bar
+none: none

+ 1 - 1
UPGRADING.md

@@ -12,7 +12,7 @@ Upgrading From 0.9 to 1.0
     would use the new handler system, if you instead were handling an arbitrary number of
     possibly unknown types, you would use the event system.
 
-    Please see the documentation for how to set-uup one of these.
+    Please see the documentation for how to set-up one of these.
 
 - Configuration