Sfoglia il codice sorgente

re-worked documentation

Johannes M. Schmitt 13 anni fa
parent
commit
8d2fccd27b

+ 6 - 2
README.md

@@ -5,5 +5,9 @@ Documentation:
 [Resources/doc](https://github.com/schmittjoh/JMSSerializerBundle/blob/master/Resources/doc/index.rst)
     
 
-License:
-[Resources/meta/LICENSE](https://github.com/schmittjoh/JMSSerializerBundle/blob/master/Resources/meta/LICENSE)
+Code License:
+[Resources/meta/LICENSE](https://github.com/schmittjoh/JMSSerializerBundle/blob/master/Resources/meta/LICENSE)
+
+
+Documentation License:
+[Resources/doc/LICENSE](https://github.com/schmittjoh/JMSSerializerBundle/blob/master/Resources/doc/LICENSE)

File diff suppressed because it is too large
+ 55 - 0
Resources/doc/LICENSE


+ 94 - 0
Resources/doc/configuration.rst

@@ -0,0 +1,94 @@
+Configuration
+=============
+
+Initial Configuration
+---------------------
+JMSSerializerBundle requires no initial configuration to get you started.
+
+Reference
+---------
+
+Below you find a reference of all configuration options with their default
+values:
+
+.. configuration-block ::
+
+    .. code-block :: yaml
+    
+        # config.yml
+        jms_serializer:
+            handlers:
+                object_based: false
+                datetime:
+                    format: "Y-m-dTH:i:s" # ISO8601
+                    default_timezone: "UTC" # defaults to whatever timezone set in php.ini or via date_default_timezone_set
+                array_collection: true
+                form_error: true
+                constraint_violation: true
+    
+            property_naming:
+                separator:  _
+                lower_case: true
+    
+            metadata:
+                cache: file
+                debug: "%kernel.debug%"
+                file_cache:
+                    dir: "%kernel.cache_dir%/serializer"
+    
+                # Using auto-detection, the mapping files for each bundle will be
+                # expected in the Resources/config/serializer directory.
+                #
+                # Example:
+                # class: My\FooBundle\Entity\User
+                # expected path: @MyFooBundle/Resources/config/serializer/Entity.User.(yml|xml|php)
+                auto_detection: true
+    
+                # if you don't want to use auto-detection, you can also define the
+                # namespace prefix and the corresponding directory explicitly
+                directories:
+                    any-name:
+                        namespace_prefix: "My\\FooBundle"
+                        path: "@MyFooBundle/Resources/config/serializer"
+                    another-name:
+                        namespace_prefix: "My\\BarBundle"
+                        path: "@MyBarBundle/Resources/config/serializer"    
+
+    .. code-block :: xml
+    
+        <!-- config.xml -->
+        <jms-serializer>
+            <handlers>
+                <object-based />
+                <datetime 
+                    format="Y-mdTH:i:s"
+                    default-timezone="UTC" />
+                <array-collection />
+                <form-error />
+                <constraint-violation /> 
+            </handlers>
+            
+            <property-naming
+                seperator="_"
+                lower-case="true" />
+                
+            <metadata
+                cache="file"
+                debug="%kernel.debug%"
+                auto-detection="true">
+                
+                <file-cache dir="%kernel.cache_dir%/serializer" />
+                
+                <!-- If auto-detection is enabled, mapping files for each bundle will
+                     be expected in the Resources/config/serializer directory. 
+                     
+                     Example:
+                     class: My\FooBundle\Entity\User
+                     expected path: @MyFooBundle/Resources/config/serializer/Entity.User.(yml|xml|php)
+                -->
+                <directory
+                    namespace-prefix="My\FooBundle"
+                    path="@MyFooBundle/Resources/config/serializer" />
+            </metadata>
+        </jms-serializer>
+    

+ 7 - 0
Resources/doc/cookbook.rst

@@ -0,0 +1,7 @@
+Cookbook
+========
+
+.. toctree ::
+    :glob:
+
+    cookbook/*

+ 91 - 87
Resources/doc/extending.rst

@@ -1,87 +1,91 @@
-Extending The Serializer
-========================
-
-This document details the different extension points, and how you can utilize
-them to change the default behavior of the serializer.
-
-Custom De-/Serialization Handlers
----------------------------------
-This allows you to change the way of how a specifc type is being de-/serialized.
-
-Any handler must implement either the ``SerializationHandlerInterface``, or
-``DeserializationHandlerInterface``, or both. This bundle already comes with
-some handlers which you find in the Serializer/Handler folder, and which you
-can use as a starting point.
-
-Custom handlers are normal services, and thus can have dependencies on any
-other service available in the dependency injection container.
-
-After you have written your handler, you can write a service definition. Such
-as the following::
-
-    <service id="acme_foo.serializer.my_handler"
-             class="Acme\FooBundle\Serializer\MyHandler"
-             public="false"
-             />
-             
-What is left to do is to publish our new handler to this bundle. So it gets
-picked up, and wired correctly. In order to do this, this bundle uses a 
-configuration system similar to that of the SecurityBundle. Each handler needs 
-a corresponding definition factory::
-
-    <?php
-    
-    namespace Acme\FooBundle\DependencyInjection\Factory;
-    
-    use JMS\SerializerBundle\DependencyInjection\HandlerFactoryInterface;
-    
-    class MyHandlerFactory implements HandlerFactoryInterface
-    {
-        public function getConfigKey()
-        {
-            return 'acme_foo_my';
-        }
-        
-        public function getType(array $config)
-        {
-            return self::TYPE_SERIALIZATION | self::TYPE_DESERIALIZATION;
-        }
-        
-        public function addConfiguration(ArrayNodeDefinition $builder)
-        {
-            $builder
-                ->children()
-                    ->scalarNode('foo')->end()
-                    ->scalarNode('bar')->end()
-                ->end()
-            ;
-        }
-        
-        public function getHandlerId(ContainerBuilder $container, array $config)
-        {
-            return 'acme_foo.serializer.my_handler';
-        }
-    }
-    
-This factory is responsible for setting up the configuration for your handler
-in the ``addConfiguration`` method, and then process that configuration in the
-``getHandlerId`` method. 
-
-The last thing left to do, is to add this factory to this bundle. This is
-done by adding a ``configureSerializerExtension`` to your bundle class::
-
-    <?php
-    
-    namespace Acme\FooBundle;
-    
-    use Acme\FooBundle\DependencyInjection\Factory\FooFactory;
-    use JMS\SerializerBundle\DependencyInjection\JMSSerializerExtension;
-    use Symfony\Component\HttpKernel\Bundle\Bundle;
-    
-    class AcmeFooBundle extends Bundle
-    {
-        public function configureSerializerExtension(JMSSerializerExtension $ext)
-        {
-            $ext->addHandlerFactory(new FooFactory());
-        }
-    }
+Custom De-/Serialization Handlers
+---------------------------------
+This allows you to change the way of how a specifc type is being de-/serialized.
+
+Any handler must implement either the ``SerializationHandlerInterface``, or
+``DeserializationHandlerInterface``, or both. This bundle already comes with
+some handlers which you find in the Serializer/Handler folder, and which you
+can use as a starting point.
+
+Custom handlers are normal services, and thus can have dependencies on any
+other service available in the dependency injection container.
+
+After you have written your handler, you can write a service definition. Such
+as the following::
+
+    <service id="acme_foo.serializer.my_handler"
+             class="Acme\FooBundle\Serializer\MyHandler"
+             public="false"
+             />
+             
+What is left to do is to publish our new handler to this bundle. So it gets
+picked up, and wired correctly. In order to do this, this bundle uses a 
+configuration system similar to that of the SecurityBundle. Each handler needs 
+a corresponding definition factory::
+
+    <?php
+    
+    namespace Acme\FooBundle\DependencyInjection\Factory;
+    
+    use JMS\SerializerBundle\DependencyInjection\HandlerFactoryInterface;
+    
+    class MyHandlerFactory implements HandlerFactoryInterface
+    {
+        public function getConfigKey()
+        {
+            return 'acme_foo_my';
+        }
+        
+        public function getType(array $config)
+        {
+            return self::TYPE_SERIALIZATION | self::TYPE_DESERIALIZATION;
+        }
+        
+        public function addConfiguration(ArrayNodeDefinition $builder)
+        {
+            $builder
+                ->children()
+                    ->scalarNode('foo')->end()
+                    ->scalarNode('bar')->end()
+                ->end()
+            ;
+        }
+        
+        public function getHandlerId(ContainerBuilder $container, array $config)
+        {
+            return 'acme_foo.serializer.my_handler';
+        }
+    }
+    
+This factory is responsible for setting up the configuration for your handler
+in the ``addConfiguration`` method, and then process that configuration in the
+``getHandlerId`` method. 
+
+The last thing left to do, is to add this factory to this bundle. This is
+done by adding a ``configureSerializerExtension`` to your bundle class::
+
+    <?php
+    
+    namespace Acme\FooBundle;
+    
+    use Acme\FooBundle\DependencyInjection\Factory\FooFactory;
+    use JMS\SerializerBundle\DependencyInjection\JMSSerializerExtension;
+    use Symfony\Component\HttpKernel\Bundle\Bundle;
+    
+    class AcmeFooBundle extends Bundle
+    {
+        public function configureSerializerExtension(JMSSerializerExtension $ext)
+        {
+            $ext->addHandlerFactory(new FooFactory());
+        }
+    }
+
+Enabling Your Handler
+---------------------
+
+TODO: Add example config
+
+.. tip ::
+    
+    The order in which the handlers are listed in the "handlers" section defines
+    in which they are called while processing. 

+ 30 - 0
Resources/doc/cookbook/exclusion_strategies.rst

@@ -0,0 +1,30 @@
+Defining which properties should be serialized
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The default exclusion policy is to exclude nothing, that is all properties of the
+object will be serialized. If you only want to expose a few of the properties,
+then it is easier to change the exclusion policy, and only mark these few properties:
+
+.. code-block :: php
+
+    <?php
+
+    use JMS\SerializerBundle\Annotation\ExclusionPolicy;
+    use JMS\SerializerBundle\Annotation\Expose;
+
+    /**
+     * The following annotations tells the serializer to skip all properties which
+     * have not marked with @Expose.
+     *
+     * @ExclusionPolicy("all")
+     */
+    class MyObject
+    {
+        private $foo;
+        private $bar;
+
+        /**
+         * @Expose
+         */
+        private $name;
+    }

+ 27 - 0
Resources/doc/cookbook/metadata_for_third_party.rst

@@ -0,0 +1,27 @@
+Overriding Metadata
+~~~~~~~~~~~~~~~~~~~
+
+Sometimes you want to serialize objects which are shipped by a third-party bundle. 
+Such a third-party bundle might not ship with metadata that suits your needs, or 
+possibly none, at all. In such a case, you can override the default location that
+is searched for metadata with a path that is under your control.
+
+.. configuration-block ::
+
+    .. code-block :: yaml
+    
+        jms_serializer:
+            metadata:
+                directories:
+                    FOSUB:
+                        namespace_prefix: "FOS\\UserBundle"
+                        path: "%kernel.root_dir%/serializer/FOSUB"
+
+    .. code-block :: xml
+    
+        <jms-serializer>
+            <metadata>
+                <directory namespace_prefix="FOS\UserBundle"
+                           path="%kernel.root_dir%/serializer/FOSUB" />
+            </metadata>
+        </jms-serializer>

+ 35 - 0
Resources/doc/cookbook/versioning_objects.rst

@@ -0,0 +1,35 @@
+Versioning Objects
+------------------
+JMSSerializerBundle comes by default with a very neat feature which allows
+you to add versioning support to your objects, e.g. if you want to
+expose them via an API that is consumed by a third-party:
+
+::
+
+    <?php
+
+    class VersionedObject
+    {
+        /**
+         * @Until("1.0.x")
+         */
+        private $name;
+
+        /**
+         * @Since("1.1")
+         * @SerializedName("name")
+         */
+        private $name2;
+    }
+    
+.. note ::
+
+    ``@Until``, and ``@Since`` both accept a standardized PHP version number.
+
+If you have annotated your objects like above, you can serializing different
+versions like this::
+
+    <?php
+
+    $serializer->setVersion('1.0');
+    $serializer->serialize(new VersionObject(), 'json');

+ 43 - 632
Resources/doc/index.rst

@@ -1,642 +1,53 @@
-========
-Overview
-========
+JMSSerializerBundle
+===================
 
-This bundle allows you to easily serialize/unserialize objects. Main features
-include:
-
-- able to handle circular references, and object graphs of any depth without
-  writing a single line of code
-- serialize/unserialize objects using annotations to describe metadata
-- supports versioning out of the box
-- easily customizable as most logic is implemented using clearly defined
-  interfaces
-- can be configured via annotations, YAML, XML, or PHP
-
-
-Installation
+Introduction
 ------------
-First, checkout a copy of the code. Just add the following to the ``deps`` 
-file of your Symfony Standard Distribution::
-
-    [JMSSerializerBundle]
-        git=git://github.com/schmittjoh/JMSSerializerBundle.git
-        target=bundles/JMS/SerializerBundle
-
-Then register the bundle with your kernel::
-
-    // in AppKernel::registerBundles()
-    $bundles = array(
-        // ...
-        new JMS\SerializerBundle\JMSSerializerBundle($this),
-        // ...
-    );
-
-This bundle also requires the Metadata library (**you need the 1.1 version, not the 1.0
-version** which ships with the Symfony Standard Edition.)::
-
-    [metadata]
-        git=http://github.com/schmittjoh/metadata.git
-        version=1.1.0
 
-Make sure that you also register the namespaces with the autoloader::
+JMSSerializerBundle allows you to serialize your objects into a requested
+output format such as JSON, XML, or YAML, and vice versa. It provides you 
+with a rich toolset which empowers you to adapt the output to your specific
+needs.
 
-    // app/autoload.php
-    $loader->registerNamespaces(array(
-        // ...
-        'JMS'              => __DIR__.'/../vendor/bundles',
-        'Metadata'         => __DIR__.'/../vendor/metadata/src',
-        // ...
-    ));
+Built-in features include:
 
-Now use the ``vendors`` script to clone the newly added repositories 
-into your project::
+- (de-)serialize object graphs of any complexity including circular references
+- supports many built-in PHP types (such as dates)
+- integrates with Doctrine ORM, et. al.
+- supports versioning, e.g. for APIs
+- configurable via PHP, XML, YAML, or annotations
 
-    php bin/vendors install
-
-Configuration
+Documentation
 -------------
-Below is the default configuration, you don't need to change it unless it doesn't
-suit your needs::
-
-    jms_serializer:
-        handlers:
-            object_based: false
-            datetime:
-                format: <ISO8601 (Y-m-dTH:i:s)>
-                default_timezone: <timezone set in php.ini or via date_default_timezone_set>
-            array_collection: true
-            form_error: true
-            constraint_violation: true
-
-        property_naming:
-            separator:  _
-            lower_case: true
-
-        metadata:
-            cache: file
-            debug: %kernel.debug%
-            file_cache:
-                dir: %kernel.cache_dir%/serializer
-
-            # Using auto-detection, the mapping files for each bundle will be
-            # expected in the Resources/config/serializer directory.
-            #
-            # Example:
-            # class: My\FooBundle\Entity\User
-            # expected path: @MyFooBundle/Resources/config/serializer/Entity.User.(yml|xml|php)
-            auto_detection: true
-
-            # if you don't want to use auto-detection, you can also define the
-            # namespace prefix and the corresponding directory explicitly
-            directories:
-                any-name:
-                    namespace_prefix: My\FooBundle
-                    path: @MyFooBundle/Resources/config/serializer
-                another-name:
-                    namespace_prefix: My\BarBundle
-                    path: @MyBarBundle/Resources/config/serializer
-
-Note the order in which the handlers are listed in the "handlers" section defines
-in which they are called while processing. See "extending.rst" for details for how
-to define custom handlers, which then also need to be configured as shown here.
-
-Usage
------
-
-De-/Serializing Objects
-~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    $serializer = $container->get('serializer');
-    $serializer->serialize(new MyObject(), 'json');
-    $serializer->serialize(new MyObject(), 'xml');
-
-The serializer supports JSON, and XML out-of-the-box, and can also handle
-many custom XML features (see below).
-
-The serializer can also be accessed via a Twig filter and will default to
-"json"::
-
-    {{ myObject | serialize | raw }}
-    {{ myObject | serialize('xml') | raw }}
-
-Overriding Metadata
-~~~~~~~~~~~~~~~~~~~
-
-Sometimes you want to serialize objects which are shipped by a third-party bundle. 
-Such a third-party bundle might not ship with metadata that suits your needs, or 
-possibly none, at all. In such a case, you can override the default location that
-is searched for metadata with a path that is under your control.
-
-::
-
-    jms_serializer:
-        metadata:
-            directories:
-                FOSUB:
-                    namespace_prefix: FOS\UserBundle
-                    path: %kernel.root_dir%/serializer/FOSUB
-
-
-Versioning
-~~~~~~~~~~
-
-The bundle allows you to have different versions of your objects. This can be
-achieved by using the @Since, and @Until annotation which both accept a
-standardized PHP version number.
-
-::
-
-    <?php
-
-    class VersionedObject
-    {
-        /**
-         * @Until("1.0.x")
-         */
-        private $name;
-
-        /**
-         * @Since("1.1")
-         * @SerializedName("name")
-         */
-        private $name2;
-    }
-
-If you have annotated your objects like above, you can serializing different
-versions like this::
-
-    <?php
-
-    $serializer->setVersion('1.0');
-    $serializer->serialize(new VersionObject(), 'json');
-
-
-Defining which properties should be serialized
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The default exclusion policy is to exclude nothing, that is all properties of the
-object will be serialized. If you only want to expose a few of the properties,
-then it is easier to change the exclusion policy, and only mark these few properties::
-
-    <?php
-
-    use JMS\SerializerBundle\Annotation\ExclusionPolicy;
-    use JMS\SerializerBundle\Annotation\Expose;
-
-    /**
-     * The following annotations tells the serializer to skip all properties which
-     * have not marked with @Expose.
-     *
-     * @ExclusionPolicy("all")
-     */
-    class MyObject
-    {
-        private $foo;
-        private $bar;
-
-        /**
-         * @Expose
-         */
-        private $name;
-    }
-
-Lifecycle Callbacks
-~~~~~~~~~~~~~~~~~~~
-If you need to run some custom logic during the serialization process, you can use
-one of these lifecycle callbacks: @PreSerialize, @PostSerialize, or @PostDeserialize
-
-Annotations
------------
-
-@ExclusionPolicy
-~~~~~~~~~~~~~~~~
-This annotation can be defined on a class to indicate the exclusion strategy
-that should be used for the class.
-
-+----------+----------------------------------------------------------------+
-| Policy   | Description                                                    |
-+==========+================================================================+
-| all      | all properties are excluded by default; only properties marked |
-|          | with @Expose will be serialized/unserialized                   |
-+----------+----------------------------------------------------------------+
-| none     | no properties are excluded by default; all properties except   |
-|          | those marked with @Exclude will be serialized/unserialized     |
-+----------+----------------------------------------------------------------+
-
-@Exclude
-~~~~~~~~
-This annotation can be defined on a property to indicate that the property should
-not be serialized/unserialized. Works only in combination with NoneExclusionPolicy.
-
-@Expose
-~~~~~~~
-This annotation can be defined on a property to indicate that the property should
-be serialized/unserialized. Works only in combination with AllExclusionPolicy.
-
-@SerializedName
-~~~~~~~~~~~~~~~
-This annotation can be defined on a property to define the serialized name for a
-property. If this is not defined, the property will be translated from camel-case
-to a lower-cased underscored name, e.g. camelCase -> camel_case.
-
-@Since
-~~~~~~
-This annotation can be defined on a property to specify starting from which
-version this property is available. If an earlier version is serialized, then
-this property is excluded automatically. The version must be in a format that is
-understood by PHP's ``version_compare`` function.
-
-@Until
-~~~~~~
-This annotation can be defined on a property to specify until which version this
-property was available. If a later version is serialized, then this property is
-excluded automatically. The version must be in a format that is understood by
-PHP's ``version_compare`` function.
-
-@AccessType
-~~~~~~~~~~~
-This annotation can be defined on a property, or a class to specify in which way
-the properties should be accessed. By default, the serializer will retrieve, or
-set the value via reflection, but you may change this to use a public method instead::
-
-    /** @AccessType("public_method") */
-    class User
-    {
-        private $name;
-        
-        public function getName()
-        {
-            return $this->name;
-        }
-        
-        public function setName($name)
-        {
-            $this->name = trim($name);
-        }
-    }
-
-@Accessor
-~~~~~~~~~
-This annotation can be defined on a property to specify which public method should
-be called to retrieve, or set the value of the given property::
-
-    class User
-    {
-        private $id;
-        
-        /** @Accessor(getter="getTrimmedName") */
-        private $name;
-        
-        // ...
-        public function getTrimmedName()
-        {
-            return trim($this->name);
-        }
-        
-        public function setName($name)
-        {
-            $this->name = $name;
-        }
-    }
-
-@AccessorOrder
-~~~~~~~~~~~~~~
-This annotation can be defined on a class to control the order of properties. By 
-default the order is undefined, but you may change it to either "alphabetical", or
-"custom".
-
-::
 
-    /** 
-     * @AccessorOrder("alphabetical") 
-     * 
-     * Resulting Property Order: id, name
-     */
-    class User
-    {
-        private $id;
-        private $name;
-    }
+.. toctree ::
+    :hidden:
     
-    /**
-     * @AccessorOrder("custom", custom = {"name", "id"})
-     *
-     * Resulting Property Order: name, id
-     */
-    class User
-    {
-        private $id;
-        private $name;
-    }
-
-@Inline
-~~~~~~~~
-This annotation can be defined on a property to indicate that the data of the property
-should be inlined. 
-
-**Note**: This only works for serialization, the serializer will not be able to deserialize
-objects with this annotation. Also, AccessorOrder will be using the name of the property
-to determine the order.
-
-@ReadOnly
-~~~~~~~~
-This annotation can be defined on a property to indicate that the data of the property
-is read only and cannot be set during deserialization.
-
-@PreSerialize
-~~~~~~~~~~~~~
-This annotation can be defined on a method which is supposed to be called before
-the serialization of the object starts.
-
-@PostSerialize
-~~~~~~~~~~~~~~
-This annotation can be defined on a method which is then called directly after the
-object has been serialized.
-
-@PostDeserialize
-~~~~~~~~~~~~~~~~
-This annotation can be defined on a method which is supposed to be called after
-the object has been deserialized.
-
-@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.
-
-Available Types:
-
-+---------------------------+--------------------------------------------------+
-| Type                      | Description                                      |
-+===========================+==================================================+
-| boolean                   | Primitive boolean                                |
-+---------------------------+--------------------------------------------------+
-| integer                   | Primitive integer                                |
-+---------------------------+--------------------------------------------------+
-| double                    | Primitive double                                 |
-+---------------------------+--------------------------------------------------+
-| string                    | Primitive string                                 |
-+---------------------------+--------------------------------------------------+
-| array                     | An array with arbitrary keys, and values.        |
-+---------------------------+--------------------------------------------------+
-| array<T>                  | A list of type T (T can be any available type).  |
-|                           | Examples:                                        |
-|                           | array<string>, array<MyNamespace\MyObject>, etc. |
-+---------------------------+--------------------------------------------------+
-| array<K, V>               | A map of keys of type K to values of type V.     |
-|                           | Examples: array<string, string>,                 |
-|                           | array<string, MyNamespace\MyObject>, etc.        |
-+---------------------------+--------------------------------------------------+
-| DateTime                  | PHP's DateTime object                            |
-+---------------------------+--------------------------------------------------+
-| T                         | Where T is a fully qualified class name.         |
-+---------------------------+--------------------------------------------------+
-| ArrayCollection<T>        | Similar to array<T>, but will be deserialized    |
-|                           | into Doctrine's ArrayCollection class.           |
-+---------------------------+--------------------------------------------------+
-| ArrayCollection<K, V>     | Similar to array<K, V>, but will be deserialized |
-|                           | into Doctrine's ArrayCollection class.           |
-+---------------------------+--------------------------------------------------+
-
-Examples::
-
-    <?php
-
-    namespace MyNamespace;
-
-    use JMS\SerializerBundle\Annotation\Type;
-
-    class BlogPost
-    {
-        /**
-         * @Type("ArrayCollection<MyNamespace\Comment>")
-         */
-        private $comments;
-
-        /**
-         * @Type("string")
-         */
-        private $title;
-
-        /**
-         * @Type("MyNamespace\Author")
-         */
-        private $author;
-
-        /**
-         * @Type("DateTime")
-         */
-        private $createdAt;
-
-        /**
-         * @Type("boolean")
-         */
-        private $published;
-
-        /**
-         * @Type("array<string, string>")
-         */
-        private $keyValueStore;
-    }
-
-@XmlRoot
-~~~~~~~~
-This allows you to specify the name of the top-level element.
-
-::
-
-    <?php
-
-    use JMS\SerializerBundle\Annotation\XmlRoot;
-
-    /** @XmlRoot("user") */
-    class User
-    {
-        private $name = 'Johannes';
-    }
-
-Resulting XML::
-
-    <user>
-        <name><![CDATA[Johannes]]></name>
-    </user>
-
-@XmlAttribute
-~~~~~~~~~~~~~
-This allows you to mark properties which should be set as attributes,
-and not as child elements.
-
-::
-
-    <?php
-
-    use JMS\SerializerBundle\Annotation\XmlAttribute;
-
-    class User
-    {
-        /** @XmlAttribute */
-        private $id = 1;
-        private $name = 'Johannes';
-    }
-
-Resulting XML::
-
-    <result id="1">
-        <name><![CDATA[Johannes]]></name>
-    </result>
-    
-@XmlValue
-~~~~~~~~~
-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.
-
-::
-
-    <?php
-    
-    use JMS\SerializerBundle\Annotation\XmlAttribute;
-    use JMS\SerializerBundle\Annotation\XmlValue;
-    use JMS\SerializerBundle\Annotation\XmlRoot;
-    
-    /** @XmlRoot("price") */
-    class Price
-    {
-        /** @XmlAttribute */
-        private $currency = 'EUR';
-        
-        /** @XmlValue */
-        private $amount = 1.23;
-    }
-    
-Resulting XML::
-
-    <price currency="EUR">1.23</price>
-
-@XmlList
-~~~~~~~~
-This allows you to define several properties of how arrays should be
-serialized. This is very similar to @XmlMap, and should be used if the
-keys of the array are not important.
-
-::
-
-    <?php
-
-    use JMS\SerializerBundle\Annotation\XmlList;
-    use JMS\SerializerBundle\Annotation\XmlRoot;
-
-    /** @XmlRoot("post") */
-    class Post
-    {
-        /**
-         * @XmlList(inline = true, entry = "comment")
-         */
-        private $comments = array(
-            new Comment('Foo'),
-            new Comment('Bar'),
-        );
-    }
-
-    class Comment
-    {
-        private $text;
-
-        public function __construct($text)
-        {
-            $this->text = $text;
-        }
-    }
-
-Resulting XML::
-
-    <post>
-        <comment>
-            <text><![CDATA[Foo]]></text>
-        </comment>
-        <comment>
-            <text><![CDATA[Bar]]></text>
-        </comment>
-    </post>
-
-@XmlMap
-~~~~~~~
-Similar to @XmlList, but the keys of the array are meaningful.
-
-XML Reference
--------------
-::
-
-    <!-- MyBundle\Resources\config\serializer\ClassName.xml -->
-    <?xml version="1.0" encoding="UTF-8">
-    <serializer>
-        <class name="Fully\Qualified\ClassName" exclusion-policy="ALL" xml-root-name="foo-bar" exclude="true"
-            accessor-order="custom" custom-accessor-order="propertyName1,propertyName2,...,propertyNameN"
-            access-type="public_method">
-            <property name="some-property"
-                      exclude="true"
-                      expose="true"
-                      type="string"
-                      serialized-name="foo"
-                      since-version="1.0"
-                      until-version="1.1"
-                      xml-attribute="true"
-                      access-type="public_method"
-                      accessor-getter="getSomeProperty"
-                      accessor-setter="setSomeProperty"
-                      inline="true"
-                      read-only="true"
-            >
-                <!-- You can also specify the type as element which is necessary if
-                     your type contains "<" or ">" characters. -->
-                <type><![CDATA[]]></type>
-                <xml-list inline="true" entry-name="foobar" />
-                <xml-map inline="true" key-attribute-name="foo" entry-name="bar" />
-            </property>
-            <callback-method name="foo" type="pre-serialize" />
-            <callback-method name="bar" type="post-serialize" />
-            <callback-method name="baz" type="post-deserialize" />
-        </class>
-    </serializer>
-
-YAML Reference
---------------
-::
-
-    # MyBundle\Resources\config\serializer\ClassName.yml
-    Fully\Qualified\ClassName:
-        exclusion_policy: ALL
-        xml_root_name: foobar
-        exclude: true
-        access_type: public_method # defaults to property
-        accessor_order: custom
-        custom_accessor_order: [propertyName1, propertyName2, ..., propertyNameN]
-        properties:
-            some-property:
-                exclude: true
-                expose: true
-                access_type: public_method # defaults to property
-                type: string
-                serialized_name: foo
-                since_version: 1.0
-                until_version: 1.1
-                xml_attribute: true
-                inline: true
-                read_only: true
-                xml_list:
-                    inline: true
-                    entry_name: foo
-                xml_map:
-                    inline: true
-                    key_attribute_name: foo
-                    entry_name: bar
-        callback_methods:
-            pre_serialize: [foo, bar]
-            post_serialize: [foo, bar]
-            post_deserialize: [foo, bar]
-
-
+    installation
+    configuration
+    usage
+    reference
+    cookbook
+
+- :doc:`Installation <installation>`
+- :doc:`Configuration <configuration>`
+- :doc:`Usage <usage>`
+- Recipies
+    * :doc:`Custom Handlers </cookbook/custom_handlers>`
+    * :doc:`/cookbook/exclusion_strategies`
+- Reference
+    * :doc:`Annotations </reference/annotations>`
+    * :doc:`XML Reference </reference/xml_reference>`
+    * :doc:`YML Reference </reference/yml_reference>`
+
+License
+-------
+
+The code is released under the business-friendly `Apache2 license`_. 
+
+Documentation is subject to the `Attribution-NonCommercial-NoDerivs 3.0 Unported
+license`_.
+
+.. _Apache2 license: http://www.apache.org/licenses/LICENSE-2.0.html
+.. _Attribution-NonCommercial-NoDerivs 3.0 Unported license: http://creativecommons.org/licenses/by-nc-nd/3.0/
 

+ 101 - 0
Resources/doc/installation.rst

@@ -0,0 +1,101 @@
+Installation
+============
+
+1. Using Composer (recommended)
+-------------------------------
+
+To install JMSSerializerBundle with Composer just add the following to your
+`composer.json` file:
+
+.. code-block :: js
+
+    // composer.json
+    {
+        // ...
+        require: {
+            // ...
+            "jms/serializer_bundle": "master-dev"
+        }
+    }
+    
+.. note ::
+
+    Please replace `master-dev` in the snippet above with the latest stable
+    branch, for example ``1.0.*``.
+    
+Then, you can install the new dependencies by running Composer's ``update``
+command from the directory where your ``composer.json`` file is located:
+
+.. code-block :: bash
+
+    $ php composer.phar update
+    
+Now, Composer will automatically download all required files, and install them
+for you. All that is left to do is to update your ``AppKernel.php`` file, and
+register the new bundle:
+
+.. code-block :: php
+
+    <?php
+
+    // in AppKernel::registerBundles()
+    $bundles = array(
+        // ...
+        new JMS\SerializerBundle\JMSSerializerBundle($this),
+        // ...
+    );
+    
+2. Using the ``deps`` file (Symfony 2.0.x)
+------------------------------------------
+
+First, checkout a copy of the code. Just add the following to the ``deps`` 
+file of your Symfony Standard Distribution:
+
+.. code-block :: ini
+
+    [JMSSerializerBundle]
+        git=git://github.com/schmittjoh/JMSSerializerBundle.git
+        target=bundles/JMS/SerializerBundle
+
+Then register the bundle with your kernel:
+
+.. code-block :: php
+
+    <?php
+
+    // in AppKernel::registerBundles()
+    $bundles = array(
+        // ...
+        new JMS\SerializerBundle\JMSSerializerBundle($this),
+        // ...
+    );
+
+This bundle also requires the Metadata library (**you need the 1.1 version, not the 1.0
+version** which ships with the Symfony Standard Edition.):
+
+.. code-block :: ini
+
+    [metadata]
+        git=http://github.com/schmittjoh/metadata.git
+        version=1.1.0
+
+Make sure that you also register the namespaces with the autoloader:
+
+.. code-block :: php
+
+    <?php
+
+    // app/autoload.php
+    $loader->registerNamespaces(array(
+        // ...
+        'JMS'              => __DIR__.'/../vendor/bundles',
+        'Metadata'         => __DIR__.'/../vendor/metadata/src',
+        // ...
+    ));
+
+Now use the ``vendors`` script to clone the newly added repositories 
+into your project:
+
+.. code-block :: bash
+
+    $ php bin/vendors install

+ 8 - 0
Resources/doc/reference.rst

@@ -0,0 +1,8 @@
+Reference
+=========
+
+.. toctree ::
+    :glob:
+    :maxdepth: 1
+    
+    reference/*

+ 357 - 0
Resources/doc/reference/annotations.rst

@@ -0,0 +1,357 @@
+Annotations
+-----------
+
+@ExclusionPolicy
+~~~~~~~~~~~~~~~~
+This annotation can be defined on a class to indicate the exclusion strategy
+that should be used for the class.
+
++----------+----------------------------------------------------------------+
+| Policy   | Description                                                    |
++==========+================================================================+
+| all      | all properties are excluded by default; only properties marked |
+|          | with @Expose will be serialized/unserialized                   |
++----------+----------------------------------------------------------------+
+| none     | no properties are excluded by default; all properties except   |
+|          | those marked with @Exclude will be serialized/unserialized     |
++----------+----------------------------------------------------------------+
+
+@Exclude
+~~~~~~~~
+This annotation can be defined on a property to indicate that the property should
+not be serialized/unserialized. Works only in combination with NoneExclusionPolicy.
+
+@Expose
+~~~~~~~
+This annotation can be defined on a property to indicate that the property should
+be serialized/unserialized. Works only in combination with AllExclusionPolicy.
+
+@SerializedName
+~~~~~~~~~~~~~~~
+This annotation can be defined on a property to define the serialized name for a
+property. If this is not defined, the property will be translated from camel-case
+to a lower-cased underscored name, e.g. camelCase -> camel_case.
+
+@Since
+~~~~~~
+This annotation can be defined on a property to specify starting from which
+version this property is available. If an earlier version is serialized, then
+this property is excluded automatically. The version must be in a format that is
+understood by PHP's ``version_compare`` function.
+
+@Until
+~~~~~~
+This annotation can be defined on a property to specify until which version this
+property was available. If a later version is serialized, then this property is
+excluded automatically. The version must be in a format that is understood by
+PHP's ``version_compare`` function.
+
+@AccessType
+~~~~~~~~~~~
+This annotation can be defined on a property, or a class to specify in which way
+the properties should be accessed. By default, the serializer will retrieve, or
+set the value via reflection, but you may change this to use a public method instead::
+
+    /** @AccessType("public_method") */
+    class User
+    {
+        private $name;
+        
+        public function getName()
+        {
+            return $this->name;
+        }
+        
+        public function setName($name)
+        {
+            $this->name = trim($name);
+        }
+    }
+
+@Accessor
+~~~~~~~~~
+This annotation can be defined on a property to specify which public method should
+be called to retrieve, or set the value of the given property::
+
+    class User
+    {
+        private $id;
+        
+        /** @Accessor(getter="getTrimmedName") */
+        private $name;
+        
+        // ...
+        public function getTrimmedName()
+        {
+            return trim($this->name);
+        }
+        
+        public function setName($name)
+        {
+            $this->name = $name;
+        }
+    }
+
+@AccessorOrder
+~~~~~~~~~~~~~~
+This annotation can be defined on a class to control the order of properties. By 
+default the order is undefined, but you may change it to either "alphabetical", or
+"custom".
+
+::
+
+    /** 
+     * @AccessorOrder("alphabetical") 
+     * 
+     * Resulting Property Order: id, name
+     */
+    class User
+    {
+        private $id;
+        private $name;
+    }
+    
+    /**
+     * @AccessorOrder("custom", custom = {"name", "id"})
+     *
+     * Resulting Property Order: name, id
+     */
+    class User
+    {
+        private $id;
+        private $name;
+    }
+
+@Inline
+~~~~~~~~
+This annotation can be defined on a property to indicate that the data of the property
+should be inlined. 
+
+**Note**: This only works for serialization, the serializer will not be able to deserialize
+objects with this annotation. Also, AccessorOrder will be using the name of the property
+to determine the order.
+
+@ReadOnly
+~~~~~~~~~
+This annotation can be defined on a property to indicate that the data of the property
+is read only and cannot be set during deserialization.
+
+@PreSerialize
+~~~~~~~~~~~~~
+This annotation can be defined on a method which is supposed to be called before
+the serialization of the object starts.
+
+@PostSerialize
+~~~~~~~~~~~~~~
+This annotation can be defined on a method which is then called directly after the
+object has been serialized.
+
+@PostDeserialize
+~~~~~~~~~~~~~~~~
+This annotation can be defined on a method which is supposed to be called after
+the object has been deserialized.
+
+@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.
+
+Available Types:
+
++---------------------------+--------------------------------------------------+
+| Type                      | Description                                      |
++===========================+==================================================+
+| boolean                   | Primitive boolean                                |
++---------------------------+--------------------------------------------------+
+| integer                   | Primitive integer                                |
++---------------------------+--------------------------------------------------+
+| double                    | Primitive double                                 |
++---------------------------+--------------------------------------------------+
+| string                    | Primitive string                                 |
++---------------------------+--------------------------------------------------+
+| array                     | An array with arbitrary keys, and values.        |
++---------------------------+--------------------------------------------------+
+| array<T>                  | A list of type T (T can be any available type).  |
+|                           | Examples:                                        |
+|                           | array<string>, array<MyNamespace\MyObject>, etc. |
++---------------------------+--------------------------------------------------+
+| array<K, V>               | A map of keys of type K to values of type V.     |
+|                           | Examples: array<string, string>,                 |
+|                           | array<string, MyNamespace\MyObject>, etc.        |
++---------------------------+--------------------------------------------------+
+| DateTime                  | PHP's DateTime object                            |
++---------------------------+--------------------------------------------------+
+| T                         | Where T is a fully qualified class name.         |
++---------------------------+--------------------------------------------------+
+| ArrayCollection<T>        | Similar to array<T>, but will be deserialized    |
+|                           | into Doctrine's ArrayCollection class.           |
++---------------------------+--------------------------------------------------+
+| ArrayCollection<K, V>     | Similar to array<K, V>, but will be deserialized |
+|                           | into Doctrine's ArrayCollection class.           |
++---------------------------+--------------------------------------------------+
+
+Examples::
+
+    <?php
+
+    namespace MyNamespace;
+
+    use JMS\SerializerBundle\Annotation\Type;
+
+    class BlogPost
+    {
+        /**
+         * @Type("ArrayCollection<MyNamespace\Comment>")
+         */
+        private $comments;
+
+        /**
+         * @Type("string")
+         */
+        private $title;
+
+        /**
+         * @Type("MyNamespace\Author")
+         */
+        private $author;
+
+        /**
+         * @Type("DateTime")
+         */
+        private $createdAt;
+
+        /**
+         * @Type("boolean")
+         */
+        private $published;
+
+        /**
+         * @Type("array<string, string>")
+         */
+        private $keyValueStore;
+    }
+
+@XmlRoot
+~~~~~~~~
+This allows you to specify the name of the top-level element.
+
+::
+
+    <?php
+
+    use JMS\SerializerBundle\Annotation\XmlRoot;
+
+    /** @XmlRoot("user") */
+    class User
+    {
+        private $name = 'Johannes';
+    }
+
+Resulting XML::
+
+    <user>
+        <name><![CDATA[Johannes]]></name>
+    </user>
+
+@XmlAttribute
+~~~~~~~~~~~~~
+This allows you to mark properties which should be set as attributes,
+and not as child elements.
+
+::
+
+    <?php
+
+    use JMS\SerializerBundle\Annotation\XmlAttribute;
+
+    class User
+    {
+        /** @XmlAttribute */
+        private $id = 1;
+        private $name = 'Johannes';
+    }
+
+Resulting XML::
+
+    <result id="1">
+        <name><![CDATA[Johannes]]></name>
+    </result>
+    
+@XmlValue
+~~~~~~~~~
+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.
+
+::
+
+    <?php
+    
+    use JMS\SerializerBundle\Annotation\XmlAttribute;
+    use JMS\SerializerBundle\Annotation\XmlValue;
+    use JMS\SerializerBundle\Annotation\XmlRoot;
+    
+    /** @XmlRoot("price") */
+    class Price
+    {
+        /** @XmlAttribute */
+        private $currency = 'EUR';
+        
+        /** @XmlValue */
+        private $amount = 1.23;
+    }
+    
+Resulting XML::
+
+    <price currency="EUR">1.23</price>
+
+@XmlList
+~~~~~~~~
+This allows you to define several properties of how arrays should be
+serialized. This is very similar to @XmlMap, and should be used if the
+keys of the array are not important.
+
+::
+
+    <?php
+
+    use JMS\SerializerBundle\Annotation\XmlList;
+    use JMS\SerializerBundle\Annotation\XmlRoot;
+
+    /** @XmlRoot("post") */
+    class Post
+    {
+        /**
+         * @XmlList(inline = true, entry = "comment")
+         */
+        private $comments = array(
+            new Comment('Foo'),
+            new Comment('Bar'),
+        );
+    }
+
+    class Comment
+    {
+        private $text;
+
+        public function __construct($text)
+        {
+            $this->text = $text;
+        }
+    }
+
+Resulting XML::
+
+    <post>
+        <comment>
+            <text><![CDATA[Foo]]></text>
+        </comment>
+        <comment>
+            <text><![CDATA[Bar]]></text>
+        </comment>
+    </post>
+
+@XmlMap
+~~~~~~~
+Similar to @XmlList, but the keys of the array are meaningful.

+ 35 - 0
Resources/doc/reference/xml_reference.rst

@@ -0,0 +1,35 @@
+XML Reference
+-------------
+::
+
+    <!-- MyBundle\Resources\config\serializer\ClassName.xml -->
+    <?xml version="1.0" encoding="UTF-8">
+    <serializer>
+        <class name="Fully\Qualified\ClassName" exclusion-policy="ALL" xml-root-name="foo-bar" exclude="true"
+            accessor-order="custom" custom-accessor-order="propertyName1,propertyName2,...,propertyNameN"
+            access-type="public_method">
+            <property name="some-property"
+                      exclude="true"
+                      expose="true"
+                      type="string"
+                      serialized-name="foo"
+                      since-version="1.0"
+                      until-version="1.1"
+                      xml-attribute="true"
+                      access-type="public_method"
+                      accessor-getter="getSomeProperty"
+                      accessor-setter="setSomeProperty"
+                      inline="true"
+                      read-only="true"
+            >
+                <!-- You can also specify the type as element which is necessary if
+                     your type contains "<" or ">" characters. -->
+                <type><![CDATA[]]></type>
+                <xml-list inline="true" entry-name="foobar" />
+                <xml-map inline="true" key-attribute-name="foo" entry-name="bar" />
+            </property>
+            <callback-method name="foo" type="pre-serialize" />
+            <callback-method name="bar" type="post-serialize" />
+            <callback-method name="baz" type="post-deserialize" />
+        </class>
+    </serializer>

+ 35 - 0
Resources/doc/reference/yml_reference.rst

@@ -0,0 +1,35 @@
+YAML Reference
+--------------
+::
+
+    # MyBundle\Resources\config\serializer\ClassName.yml
+    Fully\Qualified\ClassName:
+        exclusion_policy: ALL
+        xml_root_name: foobar
+        exclude: true
+        access_type: public_method # defaults to property
+        accessor_order: custom
+        custom_accessor_order: [propertyName1, propertyName2, ..., propertyNameN]
+        properties:
+            some-property:
+                exclude: true
+                expose: true
+                access_type: public_method # defaults to property
+                type: string
+                serialized_name: foo
+                since_version: 1.0
+                until_version: 1.1
+                xml_attribute: true
+                inline: true
+                read_only: true
+                xml_list:
+                    inline: true
+                    entry_name: foo
+                xml_map:
+                    inline: true
+                    key_attribute_name: foo
+                    entry_name: bar
+        callback_methods:
+            pre_serialize: [foo, bar]
+            post_serialize: [foo, bar]
+            post_deserialize: [foo, bar]

+ 45 - 0
Resources/doc/usage.rst

@@ -0,0 +1,45 @@
+Usage
+=====
+
+Serializing Objects
+-------------------
+Most common usage is probably to serialize objects. This can be achieved
+very easily:
+
+.. configuration-block ::
+
+    .. code-block :: php
+    
+        <?php
+        
+        $serializer = $container->get('serializer');
+        $serializer->serialize($object, 'json');
+        $serializer->serialize($object, 'xml');
+        $serializer->serialize($object, 'yml');
+    
+    .. code-block :: jinja
+    
+        {{ object | serialize }} {# uses JSON #}
+        {{ object | serialize('json') }}
+        {{ object | serialize('xml') }}
+        {{ object | serialize('yml') }}
+        
+Deserializing Objects
+---------------------
+You can also deserialize objects from their XML, or JSON representation. For
+example, when accepting data via an API.
+
+.. code-block :: php
+
+    <?php
+    
+    $serializer = $container->get('serializer');
+    $object = $serializer->deserialize($jsonData, 'MyNamespace\MyObject', 'json');
+    
+More Resources
+--------------
+
+- :doc:`Customizing which data should be (de-)serialized </cookbook/exclusion_strategies>`
+- :doc:`Adding custom serialization handlers </cookbook/custom_handlers>`
+- :doc:`(De-)Serializing third-party objects </cookbook/metadata_for_third_party>`
+- :doc:`Versioning Objects </cookbook/versioning_objects>`