-
-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add support for type aliases (#118)
* Working prototype * Style fixes * Add arg type to config validator callback * Inject type mapper as optional service * Add tests * Test without type mapper service * With and without type mapper * Assert service exists vs not * Apply linter diff * Add doc * Rename config key to type_map * Define type mapper service in xml * Make type mapper final * Do not use deprecated static test container * Use forward compatible test container access * Fix condition for removing enum normalizer * Address deprecation error * lint * Add test for custom type mapper * lint * test compatibility w earlier versions * Use legacy password hashing in MySQL for old php versions * Add doc, drop symfony param, resolve wrong var naming * doc fixes * Fix mysql in workflow, run on 8.2, no fail-fast
- Loading branch information
1 parent
9373f11
commit 9ad0d28
Showing
16 changed files
with
458 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,9 @@ | ||
name: "tests" | ||
|
||
on: ["pull_request", "push"] | ||
on: | ||
pull_request: ~ | ||
push: | ||
branches: [main] | ||
|
||
jobs: | ||
run: | ||
|
@@ -14,19 +17,35 @@ jobs: | |
- "7.4" | ||
- "8.0" | ||
- "8.1" | ||
- "8.2" | ||
dependencies: | ||
- highest | ||
include: | ||
- php-version: "8.1" | ||
dependencies: lowest | ||
- php-version: "8.2" | ||
dependencies: lowest | ||
fail-fast: false | ||
|
||
services: | ||
database: | ||
image: mysql:8 | ||
ports: | ||
- 3306:3306 | ||
options: --health-cmd "mysqladmin ping" --health-interval 10s --health-timeout 5s --health-retries 10 | ||
env: | ||
MYSQL_ROOT_PASSWORD: odmroot | ||
MYSQL_DATABASE: odm | ||
MYSQL_USER: odm | ||
MYSQL_PASSWORD: odm | ||
|
||
steps: | ||
- name: Start MySQL | ||
- name: Use legacy password hashing in MySQL | ||
if: ${{ contains(fromJson('["7.1", "7.2", "7.3"]'), matrix.php-version) }} | ||
env: | ||
MYSQL_PWD: root | ||
MYSQL_PWD: odmroot | ||
run: | | ||
sudo systemctl start mysql.service | ||
mysql -uroot -e "create database odm"; | ||
mysql -h127.0.0.1 -uroot -e "ALTER USER odm IDENTIFIED WITH mysql_native_password BY 'odm'" | ||
- name: Start PostgreSQL | ||
run: | | ||
|
@@ -54,7 +73,7 @@ jobs: | |
|
||
- name: Run tests (MySQL) | ||
env: | ||
DATABASE_URL: mysql://root:root@localhost/odm?serverVersion=8.0 | ||
DATABASE_URL: mysql://odm:[email protected]/odm?serverVersion=8.0 | ||
run: php vendor/bin/simple-phpunit | ||
|
||
- name: Run tests (PostgreSQL) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?php | ||
|
||
/* | ||
* (c) Kévin Dunglas <[email protected]> | ||
* | ||
* This source file is subject to the MIT license that is bundled | ||
* with this source code in the file LICENSE. | ||
*/ | ||
|
||
namespace Dunglas\DoctrineJsonOdm\Bundle\DependencyInjection; | ||
|
||
use Symfony\Component\Config\Definition\Builder\TreeBuilder; | ||
use Symfony\Component\Config\Definition\ConfigurationInterface; | ||
|
||
final class Configuration implements ConfigurationInterface | ||
{ | ||
/** | ||
* @return TreeBuilder | ||
*/ | ||
public function getConfigTreeBuilder() | ||
{ | ||
$treeBuilder = new TreeBuilder('dunglas_doctrine_json_odm'); | ||
|
||
$treeBuilder->getRootNode() | ||
->children() | ||
->arrayNode('type_map') | ||
->defaultValue([]) | ||
->useAttributeAsKey('type') | ||
->scalarPrototype() | ||
->cannotBeEmpty() | ||
->validate() | ||
->ifTrue(static function (string $v): bool { | ||
return !class_exists($v); | ||
}) | ||
->thenInvalid('Use fully qualified classnames as type values') | ||
->end() | ||
->end() | ||
->end() | ||
->end(); | ||
|
||
return $treeBuilder; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,13 +9,34 @@ | |
|
||
namespace Dunglas\DoctrineJsonOdm; | ||
|
||
use Symfony\Component\Serializer\Encoder\DecoderInterface; | ||
use Symfony\Component\Serializer\Encoder\EncoderInterface; | ||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; | ||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface; | ||
|
||
/** | ||
* @internal | ||
* | ||
* @author Kévin Dunglas <[email protected]> | ||
*/ | ||
trait SerializerTrait | ||
{ | ||
/** | ||
* @var TypeMapperInterface|null | ||
*/ | ||
private $typeMapper; | ||
|
||
/** | ||
* @param (NormalizerInterface|DenormalizerInterface)[] $normalizers | ||
* @param (EncoderInterface|DecoderInterface)[] $encoders | ||
*/ | ||
public function __construct(array $normalizers = [], array $encoders = [], ?TypeMapperInterface $typeMapper = null) | ||
{ | ||
parent::__construct($normalizers, $encoders); | ||
|
||
$this->typeMapper = $typeMapper; | ||
} | ||
|
||
/** | ||
* @param mixed $data | ||
* @param string|null $format | ||
|
@@ -27,7 +48,13 @@ 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)]; | ||
$typeName = \get_class($data); | ||
|
||
if ($this->typeMapper) { | ||
$typeName = $this->typeMapper->getTypeByClass($typeName); | ||
} | ||
|
||
$typeData = [self::KEY_TYPE => $typeName]; | ||
$valueData = is_scalar($normalizedData) ? [self::KEY_SCALAR => $normalizedData] : $normalizedData; | ||
$normalizedData = array_merge($typeData, $valueData); | ||
} | ||
|
@@ -44,6 +71,11 @@ public function denormalize($data, $type, $format = null, array $context = []) | |
{ | ||
if (\is_array($data) && (isset($data[self::KEY_TYPE]))) { | ||
$keyType = $data[self::KEY_TYPE]; | ||
|
||
if ($this->typeMapper) { | ||
$keyType = $this->typeMapper->getClassByType($keyType); | ||
} | ||
|
||
unset($data[self::KEY_TYPE]); | ||
|
||
$data = $data[self::KEY_SCALAR] ?? $data; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
<?php | ||
|
||
/* | ||
* (c) Kévin Dunglas <[email protected]> | ||
* | ||
* This source file is subject to the MIT license that is bundled | ||
* with this source code in the file LICENSE. | ||
*/ | ||
|
||
namespace Dunglas\DoctrineJsonOdm; | ||
|
||
/** | ||
* Allows using string constants in place of class names. | ||
*/ | ||
final class TypeMapper implements TypeMapperInterface | ||
{ | ||
/** | ||
* @var array<string, class-string> | ||
*/ | ||
private $typeToClass; | ||
|
||
/** | ||
* @var array<class-string, string> | ||
*/ | ||
private $classToType; | ||
|
||
/** | ||
* @param array<class-string, string> $typeToClass | ||
*/ | ||
public function __construct(array $typeToClass) | ||
{ | ||
$this->typeToClass = $typeToClass; | ||
$this->classToType = array_flip($typeToClass); | ||
} | ||
|
||
/** | ||
* Falls back to class name itself. | ||
* | ||
* @param class-string $class | ||
*/ | ||
public function getTypeByClass(string $class): string | ||
{ | ||
return $this->classToType[$class] ?? $class; | ||
} | ||
|
||
/** | ||
* Falls back to type name itself – it might as well be a class. | ||
* | ||
* @return class-string | ||
*/ | ||
public function getClassByType(string $type): string | ||
{ | ||
return $this->typeToClass[$type] ?? $type; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?php | ||
|
||
/* | ||
* (c) Kévin Dunglas <[email protected]> | ||
* | ||
* This source file is subject to the MIT license that is bundled | ||
* with this source code in the file LICENSE. | ||
*/ | ||
|
||
namespace Dunglas\DoctrineJsonOdm; | ||
|
||
/** | ||
* Allows using string constants in place of class names. | ||
*/ | ||
interface TypeMapperInterface | ||
{ | ||
/** | ||
* Resolve type name from class. | ||
* | ||
* @param class-string $class | ||
*/ | ||
public function getTypeByClass(string $class): string; | ||
|
||
/** | ||
* Resolve class from type name. | ||
* | ||
* @return class-string | ||
*/ | ||
public function getClassByType(string $type): string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.