This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
symfony/src/Symfony/Bundle/FrameworkBundle
Fabien Potencier 279dc46756 feature #24375 [Serializer] Serialize and deserialize from abstract classes (sroze)
This PR was squashed before being merged into the 4.1-dev branch (closes #24375).

Discussion
----------

[Serializer] Serialize and deserialize from abstract classes

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | ø
| License       | MIT
| Doc PR        | Not yet

This PR adds a feature in the Serializer: allow to serialize and de-serialize abstract classes. Such feature is especially useful when dealing with domain objects.

# Example

Let's take the example of the following objects:
- `CodeRepository` defines a set of properties like `name` and `url`
- `GitHubCodeRepository` and `BitBucketCodeRepository` extends from the abstract `CodeRepository` class and adds a few properties.
- `Project` has a relation with a `codeRepository`, which has a type `CodeRepository`.

At the moment, the serializer can't serialize/deserialize correctly this `Project` object has it doesn't know how to deal with this `CodeRepository` abstract object.

This feature allows the serializer to deal with such situation. The `ObjectNormalizer` has now access to a `ClassDiscriminatorResolver` that knows, for a given abstract class:
- Is the "type" property it needs to read/write to uniquely identify each sub-class
- What's the name of the "type" for each sub-class mapping

# Usage without Framework Bundle

```php
$discriminatorResolver = new ClassDiscriminatorResolver();
$discriminatorResolver->addClassMapping(CodeRepository::class, new ClassDiscriminatorMapping('type', [
    'github' => GitHubCodeRepository::class,
    'bitbucket' => BitBucketCodeRepository::class,
]));

$serializer = new Serializer(array(new ObjectNormalizer(null, null, null, null, $discriminatorResolver)), array('json' => new JsonEncoder()));

$serialized = $serializer->serialize(new GitHubCodeRepository());
// {"type": "github"}

$repository = $serializer->unserialize($serialized, CodeRepository::class, 'json');
// GitHubCodeRepository

```

# Usage with the Framework Bundle

```yaml
framework:
    serializer:
        discriminator_class_mapping:
            App\CodeRepository:
                 type_property: type
                 mapping:
                    github: App\GitHubCodeRepository
                    bitbucket: App\BitBucketCodeRepository
```

# Usage with Annotations/XML/YAML

```php
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;

/**
 * @DiscriminatorMap(typeProperty="type", mapping={
 *    "first"="Symfony\Component\Serializer\Tests\Fixtures\AbstractDummyFirstChild",
 *    "second"="Symfony\Component\Serializer\Tests\Fixtures\AbstractDummySecondChild"
 * })
 */
abstract class AbstractDummy
{
    public $foo;

    public function __construct($foo = null)
    {
        $this->foo = $foo;
    }
}
```

# TODO

- [x] Working as standalone
- [x] Working with the framework bundle
- [x] Tests on mapping classes

Commits
-------

4c6e05b7ee [Serializer] Serialize and deserialize from abstract classes
2017-12-07 10:34:02 -08:00
..
CacheWarmer Merge branch '3.4' 2017-11-09 18:30:28 +01:00
Command feature #24216 added clean option to assets install command (robinlehrmann) 2017-12-07 08:16:48 -08:00
Console Merge branch '3.4' into 4.0 2017-12-04 11:02:29 -08:00
Controller [FrameworkBundle] Improve the DX of TemplateController when using SF 4 2017-12-01 19:56:17 +01:00
DataCollector [FrameworkBundle] Extends the RequestDataCollector 2016-03-30 19:02:53 +02:00
DependencyInjection feature #24375 [Serializer] Serialize and deserialize from abstract classes (sroze) 2017-12-07 10:34:02 -08:00
EventListener Remove useless docblocks 2017-10-29 10:49:53 +01:00
HttpCache Replace more docblocks by type-hints 2017-11-07 15:45:01 +01:00
Kernel [DI] Turn services and aliases private by default, with BC layer 2017-09-19 11:28:48 +02:00
Resources [Serializer] Serialize and deserialize from abstract classes 2017-12-07 10:34:01 -08:00
Routing [FrameworkBundle] Allow to pass a logger instance to the Router 2017-11-05 18:05:58 +01:00
Templating remove more kernel.root_dir parameter refs 2017-11-23 19:10:15 +01:00
Test Merge branch '3.4' 2017-10-28 18:54:10 +02:00
Tests Merge branch '4.0' 2017-12-04 13:32:14 +01:00
Translation Merge branch '3.3' into 3.4 2017-11-05 17:10:10 +01:00
.gitignore Added missing files .gitignore 2013-07-21 14:12:18 +02:00
CHANGELOG.md feature #24826 [FrameworkBundle] Allow to pass a logger instance to the Router (ogizanagi) 2017-12-01 06:36:20 -08:00
Client.php Merge branch '2.8' into 3.3 2017-11-07 12:58:40 +01:00
composer.json Merge branch '4.0' 2017-12-04 13:32:14 +01:00
FrameworkBundle.php Merge branch '3.4' 2017-11-09 18:30:28 +01:00
LICENSE updated LICENSE year 2017-01-02 12:30:00 -08:00
phpunit.xml.dist Merge branch '3.2' 2017-04-12 07:14:56 -07:00
README.md add readme files where missing 2016-03-07 11:36:15 +01:00