Skip to content

Commit

Permalink
Merge 19cec16 into 5e72fe2
Browse files Browse the repository at this point in the history
  • Loading branch information
Toflar committed Jul 10, 2019
2 parents 5e72fe2 + 19cec16 commit 6a40dec
Show file tree
Hide file tree
Showing 16 changed files with 378 additions and 172 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -3,3 +3,4 @@
/phpunit.xml
/tests/Fixtures/cache
/tests/Fixtures/logs
/var
15 changes: 10 additions & 5 deletions .travis.yml
@@ -1,4 +1,5 @@
language: php
dist: xenial

cache:
directories:
Expand All @@ -20,27 +21,31 @@ env:
- MYSQL_DBNAME="travis_ci_test"

php:
- 5.5
- 5.6
- 7.0
- 7.1
- 7.2
- 7.3
- 7.4snapshot
- nightly

matrix:
fast_finish: true
include:
- php: 7.1
env: deps=low
env: deps=low SYMFONY_PHPUNIT_VERSION=5.7.27
- php: 7.1
env: deps=beta
- php: 7.2
env: deps=low
env: deps=low SYMFONY_PHPUNIT_VERSION=5.7.27
- php: 7.2
env: deps=beta
- php: 7.3
env: deps=low SYMFONY_PHPUNIT_VERSION=5.7.27
- php: 7.3
env: deps=beta
allow_failures:
- env: deps=beta
- php: nightly
- php: 7.4snapshot

before_install:
- phpenv config-rm xdebug.ini || echo "xdebug not available"
Expand Down
24 changes: 13 additions & 11 deletions README.md
Expand Up @@ -7,16 +7,16 @@ An Object-Document Mapper (ODM) for [Doctrine ORM](http://www.doctrine-project.o
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/20cf915b-1554-4f89-8772-ef0f913ec759/mini.png)](https://insight.sensiolabs.com/projects/20cf915b-1554-4f89-8772-ef0f913ec759)
[![StyleCI](https://styleci.io/repos/57223826/shield)](https://styleci.io/repos/57223826)

Did you ever dreamed of a tool creating powerful data models mixing traditional efficient relational mappings with modern
Did you ever dream of a tool creating powerful data models mixing traditional, efficient relational mappings with modern
schema-less and NoSQL-like ones?

With Doctrine JSON ODM, it's now possible to create and query such hybrid data models with ease. Thanks to [modern JSON
types of RDBMS](http://www.postgresql.org/docs/current/static/datatype-json.html), querying schema-less documents is easy,
powerful and [fast as hell (similar in performance to a MongoDB database)](http://www.enterprisedb.com/postgres-plus-edb-blog/marc-linster/postgres-outperforms-mongodb-and-ushers-new-developer-reality)!
You can even [define indexes](http://www.postgresql.org/docs/current/static/datatype-json.html#JSON-INDEXING) for those documents.

Doctrine JSON ODM allows to store PHP objects as JSON documents in modern dynamic columns of RDBMS.
It works with JSON and JSONB columns of PostgreSQL (>= 9.4) and the JSON column of MySQL (>= 5.7.8).
Doctrine JSON ODM allows to store PHP objects as JSON documents in modern, dynamic columns of an RDBMS.
It works with JSON and JSONB columns of PostgreSQL (>= 9.4) and the JSON column type of MySQL (>= 5.7.8).

For more information about concepts behind Doctrine JSON ODM, take a look at [the presentation given by Benjamin Eberlei at Symfony Catalunya 2016](https://qafoo.com/resources/presentations/symfony_catalunya_2016/doctrine_orm_and_nosql.html).

Expand All @@ -26,27 +26,27 @@ To install the library, use [Composer](https://getcomposer.org/), the PHP packag

composer require dunglas/doctrine-json-odm

If you are using [Symfony 4+](https://symfony.com) or [API Platform](https://api-platform.com), you have nothing more to do!
If you are using [Symfony 4+](https://symfony.com) or [API Platform](https://api-platform.com), you don't need to do anything else!
If you use Doctrine directly, use a bootstrap code similar to the following:

```php
<?php

require_once __DIR__.'/../vendor/autoload.php'; // Adapt to your path
require_once __DIR__.'/../vendor/autoload.php'; // Adjust to your path

use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Tools\Setup;
use Dunglas\DoctrineJsonOdm\Normalizer\ObjectNormalizer;
use Dunglas\DoctrineJsonOdm\Serializer;
use Dunglas\DoctrineJsonOdm\Type\JsonDocumentType;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer as BaseObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;

if (!Type::hasType('json_document')) {
Type::addType('json_document', JsonDocumentType::class);
Type::getType('json_document')->setSerializer(
new Serializer([new ObjectNormalizer(new BaseObjectNormalizer())], [new JsonEncoder()])
new Serializer([new ArrayDenormalizer(), new ObjectNormalizer()], [new JsonEncoder()])
);
}

Expand All @@ -67,7 +67,9 @@ return EntityManager::create($conn, $config);

## Install with Symfony 2 and 3

The library comes with a bundle for the [Symfony](https://symfony.com) framework. If you use Symfony 4+, it is automatically registered. For Symfony 2 and 3, you must register it yourself:
The library comes with a bundle for the [Symfony](https://symfony.com) framework. If you use Symfony 4+ and Symfony
Flex, it is automatically registered thanks to [its recipe](https://github.com/symfony/recipes-contrib/tree/master/dunglas/doctrine-json-odm).
For Symfony 2 and 3, you must register it yourself:

```php
// ...
Expand Down Expand Up @@ -103,7 +105,7 @@ then, it is stored in a dynamic JSON column in the database.

When the object will be hydrated, the JSON content of this column is transformed back to its original values, thanks again
to the Symfony Serializer.
All PHP objects and structures will be preserved (if you use Symfony >= 3.1, see the FAQ).
All PHP objects and structures will be preserved.

You can store any type of (serializable) PHP data structures in properties mapped using the `json_document` type.

Expand Down
18 changes: 9 additions & 9 deletions composer.json
Expand Up @@ -13,17 +13,17 @@
}
],
"require": {
"php": "^5.5.9 || ^7.0",
"doctrine/orm": "^2.5",
"symfony/property-access": "^2.8 || ^3.0 || ^4.0",
"symfony/property-info": "^2.8 || ^3.0 || ^4.0",
"symfony/serializer": "^2.8 || ^3.0 || ^4.0"
"php": "^7.1",
"doctrine/orm": "^2.6.3",
"symfony/property-access": "^3.4 || ^4.1",
"symfony/property-info": "^3.4 || ^4.1",
"symfony/serializer": "^3.4 || ^4.1"
},
"require-dev": {
"doctrine/doctrine-bundle": "^1.6",
"symfony/finder": "^2.8 || ^3.0 || ^4.0",
"symfony/framework-bundle": "^2.8 || ^3.0 || ^4.0",
"symfony/phpunit-bridge": "^3.3 || ^4.0"
"doctrine/doctrine-bundle": "^1.8",
"symfony/finder": "^3.4 || ^4.1",
"symfony/framework-bundle": "^3.4 || ^4.1",
"symfony/phpunit-bridge": "^4.3"
},
"suggest": {
"symfony/framework-bundle": "To use the provided bundle.",
Expand Down
8 changes: 3 additions & 5 deletions phpunit.xml.dist
Expand Up @@ -7,6 +7,9 @@
>
<php>
<ini name="error_reporting" value="-1" />
<server name="KERNEL_DIR" value="tests/Fixtures" />
<server name="KERNEL_CLASS" value="AppKernel" />
<server name="SYMFONY_DEPRECATIONS_HELPER" value="max[self]=0" />
</php>

<testsuites>
Expand All @@ -15,11 +18,6 @@
</testsuite>
</testsuites>

<php>
<server name="KERNEL_DIR" value="tests/Fixtures" />
<server name="KERNEL_CLASS" value="AppKernel" />
</php>

<filter>
<whitelist>
<directory>.</directory>
Expand Down
17 changes: 3 additions & 14 deletions src/Bundle/Resources/config/services.xml
Expand Up @@ -5,21 +5,10 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
<service id="dunglas_doctrine_json_odm.normalizer.raw_object" class="Symfony\Component\Serializer\Normalizer\ObjectNormalizer" public="false">
<argument type="service" id="serializer.mapping.class_metadata_factory" on-invalid="ignore" />
<argument>null</argument><!-- name converter -->
<argument type="service" id="serializer.property_accessor" />
<argument type="service" id="property_info" on-invalid="ignore" />
<argument type="service" id="serializer.mapping.class_discriminator_resolver" on-invalid="ignore" />
</service>

<service id="dunglas_doctrine_json_odm.normalizer.object" class="Dunglas\DoctrineJsonOdm\Normalizer\ObjectNormalizer" public="false">
<argument type="service" id="dunglas_doctrine_json_odm.normalizer.raw_object" />
</service>

<service id="dunglas_doctrine_json_odm.serializer" class="Symfony\Component\Serializer\Serializer" public="true">
<service id="dunglas_doctrine_json_odm.serializer" class="Dunglas\DoctrineJsonOdm\Serializer" public="true">
<argument type="collection">
<argument type="service" id="dunglas_doctrine_json_odm.normalizer.object" />
<argument type="service" id="serializer.denormalizer.array" />
<argument type="service" id="serializer.normalizer.object" />
</argument>

<argument type="collection">
Expand Down
111 changes: 0 additions & 111 deletions src/Normalizer/ObjectNormalizer.php

This file was deleted.

52 changes: 52 additions & 0 deletions src/Serializer.php
@@ -0,0 +1,52 @@
<?php

/*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Dunglas\DoctrineJsonOdm;

use Symfony\Component\Serializer\Serializer as BaseSerializer;

final class Serializer extends BaseSerializer
{
private const KEY_TYPE = '#type';
private const KEY_SCALAR = '#scalar';

public function normalize($data, $format = null, array $context = [])
{
$normalizedData = parent::normalize($data, $format, $context);

if (is_object($data)) {
$typeData = [self::KEY_TYPE => get_class($data)];
$valueData = is_scalar($normalizedData) ? [self::KEY_SCALAR => $normalizedData] : $normalizedData;
$normalizedData = array_merge($typeData, $valueData);
}

return $normalizedData;
}

public function denormalize($data, $class, $format = null, array $context = [])
{
if (is_array($data) && (isset($data[self::KEY_TYPE]))) {
$type = $data[self::KEY_TYPE];
unset($data[self::KEY_TYPE]);

$data = $data[self::KEY_SCALAR] ?? $data;
$data = $this->denormalize($data, $type, $format, $context);

return parent::denormalize($data, $type, $format, $context);
}

if (is_iterable($data)) {
$class = ($class === '') ? 'stdClass' : $class;

return parent::denormalize($data, $class.'[]', $format, $context);
}

return $data;
}
}
29 changes: 29 additions & 0 deletions tests/AbstractKernelTestCase.php
@@ -0,0 +1,29 @@
<?php

/*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Dunglas\DoctrineJsonOdm\Tests;

use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

abstract class AbstractKernelTestCase extends KernelTestCase
{
/**
* @var Application
*/
protected $application;

protected function setUp()
{
$this->bootKernel();

$this->application = new Application(self::$kernel);
$this->application->setAutoExit(false);
}
}

0 comments on commit 6a40dec

Please sign in to comment.