-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #95 from jolicode/feat/api-platform-integration
Api platform integration
- Loading branch information
Showing
27 changed files
with
605 additions
and
25 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
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,16 @@ | ||
# Api Platform integration | ||
|
||
> [!WARNING] | ||
> The api platform integration is in a experimental state, and may change in the future. | ||
> Some behavior may not be handled correctly, and some features may not be implemented. | ||
> | ||
> If you find a bug or missing feature, please report it on the [issue tracker](https://github.com/jolicode/automapper/issues). | ||
This bundle provides a way to integrate with [Api Platform](https://api-platform.com/) by generating the mappers for you. | ||
|
||
It injects extra data in the mappers when we map a Resource class to or from an array. | ||
|
||
You have to enable the `api_platform` option in the configuration to use this feature. | ||
|
||
If you have custom normalizer with some logic inside you will have to convert this logic with our library way of doing things. | ||
[See our migrate guide](migrate.md) for more information. |
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,73 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace AutoMapper\EventListener\ApiPlatform; | ||
|
||
use ApiPlatform\Api\ResourceClassResolverInterface; | ||
use ApiPlatform\Metadata\HttpOperation; | ||
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface; | ||
use AutoMapper\Event\GenerateMapperEvent; | ||
use AutoMapper\Event\PropertyMetadataEvent; | ||
use AutoMapper\Event\SourcePropertyMetadata; | ||
use AutoMapper\Event\TargetPropertyMetadata; | ||
use AutoMapper\Provider\ApiPlatform\IriProvider; | ||
use AutoMapper\Transformer\ApiPlatform\JsonLdContextTransformer; | ||
use AutoMapper\Transformer\ApiPlatform\JsonLdIdTransformer; | ||
use AutoMapper\Transformer\FixedValueTransformer; | ||
use AutoMapper\Transformer\PropertyTransformer\PropertyTransformer; | ||
|
||
final readonly class JsonLdListener | ||
{ | ||
public function __construct( | ||
private ResourceClassResolverInterface $resourceClassResolver, | ||
private ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory, | ||
) { | ||
} | ||
|
||
public function __invoke(GenerateMapperEvent $event): void | ||
{ | ||
if ($event->mapperMetadata->target === 'array' && $this->resourceClassResolver->isResourceClass($event->mapperMetadata->source)) { | ||
$event->properties['@id'] = new PropertyMetadataEvent( | ||
mapperMetadata: $event->mapperMetadata, | ||
source: new SourcePropertyMetadata('@id'), | ||
target: new TargetPropertyMetadata('@id'), | ||
transformer: new PropertyTransformer(JsonLdIdTransformer::class), | ||
if: "(context['normalizer_format'] ?? false) === 'jsonld'", | ||
disableGroupsCheck: true, | ||
); | ||
|
||
$operation = $this->resourceMetadataCollectionFactory->create($event->mapperMetadata->source)->getOperation(); | ||
|
||
$types = $operation instanceof HttpOperation ? $operation->getTypes() : null; | ||
|
||
if (null === $types) { | ||
$types = [$operation->getShortName()]; | ||
} | ||
|
||
$fixedTypes = 1 === \count($types) ? $types[0] : $types; | ||
|
||
$event->properties['@type'] = new PropertyMetadataEvent( | ||
mapperMetadata: $event->mapperMetadata, | ||
source: new SourcePropertyMetadata('@type'), | ||
target: new TargetPropertyMetadata('@type'), | ||
transformer: new FixedValueTransformer($fixedTypes), | ||
if: "(context['normalizer_format'] ?? false) === 'jsonld'", | ||
disableGroupsCheck: true, | ||
); | ||
|
||
$event->properties['@context'] = new PropertyMetadataEvent( | ||
mapperMetadata: $event->mapperMetadata, | ||
source: new SourcePropertyMetadata('@context'), | ||
target: new TargetPropertyMetadata('@context'), | ||
transformer: new PropertyTransformer(JsonLdContextTransformer::class, ['forced_resource_class' => $event->mapperMetadata->source]), | ||
if: "(context['normalizer_format'] ?? false) === 'jsonld' and (context['jsonld_has_context'] ?? false) === false and (context['depth'] ?? 0) <= 1", | ||
disableGroupsCheck: true, | ||
); | ||
} | ||
|
||
if ($event->mapperMetadata->source === 'array' && $this->resourceClassResolver->isResourceClass($event->mapperMetadata->target)) { | ||
$event->provider = IriProvider::class; | ||
} | ||
} | ||
} |
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 | ||
|
||
declare(strict_types=1); | ||
|
||
namespace AutoMapper\Provider\ApiPlatform; | ||
|
||
use ApiPlatform\Api\IriConverterInterface; | ||
use ApiPlatform\Api\ResourceClassResolverInterface; | ||
use AutoMapper\MapperContext; | ||
use AutoMapper\Provider\EarlyReturn; | ||
use AutoMapper\Provider\ProviderInterface; | ||
|
||
final readonly class IriProvider implements ProviderInterface | ||
{ | ||
public function __construct( | ||
private IriConverterInterface $iriConverter, | ||
private ResourceClassResolverInterface $resourceClassResolver | ||
) { | ||
} | ||
|
||
public function provide(string $targetType, mixed $source, array $context): object|array|null | ||
{ | ||
if (($context[MapperContext::NORMALIZER_FORMAT] ?? false) !== 'jsonld') { | ||
return null; | ||
} | ||
|
||
$isResource = $this->resourceClassResolver->isResourceClass($targetType); | ||
|
||
if (!$isResource) { | ||
return null; | ||
} | ||
|
||
if (\is_string($source)) { | ||
return new EarlyReturn($this->iriConverter->getResourceFromIri($source)); | ||
} | ||
|
||
if (!\is_array($source) || !\array_key_exists('@id', $source) || !\is_string($source['@id'])) { | ||
return null; | ||
} | ||
|
||
return $this->iriConverter->getResourceFromIri($source['@id']); | ||
} | ||
} |
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,40 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Symfony\Component\DependencyInjection\Loader\Configurator; | ||
|
||
use AutoMapper\Event\GenerateMapperEvent; | ||
use AutoMapper\EventListener\ApiPlatform\JsonLdListener; | ||
use AutoMapper\Provider\ApiPlatform\IriProvider; | ||
use AutoMapper\Transformer\ApiPlatform\JsonLdContextTransformer; | ||
use AutoMapper\Transformer\ApiPlatform\JsonLdIdTransformer; | ||
|
||
return static function (ContainerConfigurator $container) { | ||
$container->services() | ||
->set(JsonLdListener::class) | ||
->args([ | ||
service('api_platform.resource_class_resolver'), | ||
service('api_platform.metadata.resource.metadata_collection_factory'), | ||
]) | ||
->tag('kernel.event_listener', ['event' => GenerateMapperEvent::class, 'priority' => 0]) | ||
|
||
->set(JsonLdIdTransformer::class) | ||
->args([service('api_platform.iri_converter')]) | ||
->tag('automapper.property_transformer', ['priority' => 0]) | ||
|
||
->set(JsonLdContextTransformer::class) | ||
->args([ | ||
service('api_platform.jsonld.context_builder'), | ||
service('api_platform.resource_class_resolver'), | ||
]) | ||
->tag('automapper.property_transformer', ['priority' => 0]) | ||
|
||
->set(IriProvider::class) | ||
->args([ | ||
service('api_platform.iri_converter'), | ||
service('api_platform.resource_class_resolver'), | ||
]) | ||
->tag('automapper.provider', ['priority' => 0]) | ||
; | ||
}; |
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,42 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace AutoMapper\Transformer\ApiPlatform; | ||
|
||
use ApiPlatform\Api\ResourceClassResolverInterface; | ||
use ApiPlatform\JsonLd\AnonymousContextBuilderInterface; | ||
use ApiPlatform\JsonLd\ContextBuilderInterface; | ||
use AutoMapper\Transformer\PropertyTransformer\PropertyTransformerInterface; | ||
|
||
final readonly class JsonLdContextTransformer implements PropertyTransformerInterface | ||
{ | ||
public function __construct( | ||
private ContextBuilderInterface $contextBuilder, | ||
private ResourceClassResolverInterface $resourceClassResolver, | ||
) { | ||
} | ||
|
||
public function transform(mixed $value, object|array $source, array $context): mixed | ||
{ | ||
if (!\is_object($source)) { | ||
return null; | ||
} | ||
|
||
$resourceClass = $context['forced_resource_class'] ?? $this->resourceClassResolver->isResourceClass($source::class) ? $this->resourceClassResolver->getResourceClass($source) : null; | ||
|
||
if (null === $resourceClass) { | ||
if ($this->contextBuilder instanceof AnonymousContextBuilderInterface) { | ||
return $this->contextBuilder->getAnonymousResourceContext($source, ($context['output'] ?? []) + ['api_resource' => $context['api_resource'] ?? null]); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
if (isset($context['jsonld_embed_context'])) { | ||
return $this->contextBuilder->getResourceContext($resourceClass); | ||
} | ||
|
||
return $this->contextBuilder->getResourceContextUri($resourceClass); | ||
} | ||
} |
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,25 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace AutoMapper\Transformer\ApiPlatform; | ||
|
||
use ApiPlatform\Api\IriConverterInterface; | ||
use AutoMapper\Transformer\PropertyTransformer\PropertyTransformerInterface; | ||
|
||
final readonly class JsonLdIdTransformer implements PropertyTransformerInterface | ||
{ | ||
public function __construct( | ||
private IriConverterInterface $iriConverter | ||
) { | ||
} | ||
|
||
public function transform(mixed $value, object|array $source, array $context): mixed | ||
{ | ||
if (\is_array($source)) { | ||
return null; | ||
} | ||
|
||
return $this->iriConverter->getIriFromResource($source); | ||
} | ||
} |
Oops, something went wrong.