diff --git a/src/php/ContextCache.php b/src/php/ContextCache.php new file mode 100644 index 0000000000000000000000000000000000000000..8d84c0f05b17cf73c3f5e6a0fceba44fcd935652 --- /dev/null +++ b/src/php/ContextCache.php @@ -0,0 +1,71 @@ +<?php declare(strict_types=1); +/** + * Copyright (C) 2019 IRSTEA + * All rights reserved. + * + * @copyright 2019 IRSTEA + * @author guillaume.perreal + */ + + +namespace Irstea\NgModelGeneratorBundle; + + +use Irstea\NgModelGeneratorBundle\Metadata\SerializationMetadata; +use Irstea\NgModelGeneratorBundle\Models\Types\Factory\ContextInterface; + +/** + * Class ContextCache + */ +final class ContextCache implements ContextFactoryInterface +{ + /** + * @var ContextFactoryInterface + */ + private $contextFactory; + + + /** @var ContextInterface[] */ + private $cache = []; + + + /** + * ContextCache constructor. + * @param ContextFactoryInterface $contextFactory + */ + public function __construct(ContextFactoryInterface $contextFactory) + { + + $this->contextFactory = $contextFactory; + } + + /** + * {@inheritDoc} + */ + public function create(SerializationMetadata $serialization, bool $withAtFields): ContextInterface + { + $key = $this->getCacheKey($serialization, $withAtFields); + + if (!isset($this->cache[$key])) { + $this->cache[$key] = $this->contextFactory->create($serialization, $withAtFields); + } + + return $this->cache[$key]; + } + + /** + * @param SerializationMetadata $serialization + * @param bool $withAtFields + * @return string + */ + private function getCacheKey(SerializationMetadata $serialization, bool $withAtFields): string + { + return sprintf( + '%s:%s:%s:%s', + $serialization->getRoot(), + $serialization->isNormalization() ? 'norm' : 'denorm', + $withAtFields ? 'with' : 'without', + implode(',', $serialization->getGroups()) + ); + } +} diff --git a/src/php/ContextFactory.php b/src/php/ContextFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..bbefa823f21280c1f934d1456f7ff76ee2a19a45 --- /dev/null +++ b/src/php/ContextFactory.php @@ -0,0 +1,89 @@ +<?php declare(strict_types=1); +/* + * This file is part of "irstea/ng-model-generator-bundle". + * + * "irstea/ng-model-generator-bundle" generates Typescript interfaces for Angular using api-platform metadata. + * Copyright (C) 2018-2019 IRSTEA + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License and the GNU + * Lesser General Public License along with this program. If not, see + * <https://www.gnu.org/licenses/>. + */ + +namespace Irstea\NgModelGeneratorBundle; + +use Irstea\NgModelGeneratorBundle\Metadata\SerializationMetadata; +use Irstea\NgModelGeneratorBundle\Models\Types\Factory\BuiltinTypeFactory; +use Irstea\NgModelGeneratorBundle\Models\Types\Factory\CollectionTypeFactory; +use Irstea\NgModelGeneratorBundle\Models\Types\Factory\CompositeTypeFactory; +use Irstea\NgModelGeneratorBundle\Models\Types\Factory\Context; +use Irstea\NgModelGeneratorBundle\Models\Types\Factory\ContextInterface; +use Irstea\NgModelGeneratorBundle\Models\Types\Factory\DeferrableTypeFactory; +use Irstea\NgModelGeneratorBundle\Models\Types\Factory\NullableTypeFactory; +use Irstea\NgModelGeneratorBundle\Models\Types\Factory\ReflectionTypeFactory; +use Irstea\NgModelGeneratorBundle\Models\Types\Factory\TypeCache; +use Irstea\NgModelGeneratorBundle\Models\Types\Factory\TypeFactoryInterface; +use Symfony\Component\PropertyInfo\PropertyInfoExtractor; + +/** + * Class ContextFactory. + */ +final class ContextFactory implements ContextFactoryInterface +{ + /** @var TypeFactoryInterface */ + private $nullableTypeFactory; + + /** @var TypeFactoryInterface */ + private $collectionTypeFactory; + + /** @var TypeFactoryInterface */ + private $reflectionTypeFactory; + + /** @var TypeFactoryInterface */ + private $builtinTypeFactory; + + /** + * ContextFactory constructor. + * @param PropertyInfoExtractor $propertyInfoExtractor + */ + public function __construct(PropertyInfoExtractor $propertyInfoExtractor) + { + $this->nullableTypeFactory = new NullableTypeFactory(); + $this->collectionTypeFactory = new CollectionTypeFactory(); + $this->reflectionTypeFactory = TypeCache::decorate(new ReflectionTypeFactory($propertyInfoExtractor)); + $this->builtinTypeFactory = BuiltinTypeFactory::createDefault(); + } + + /** + * {@inheritDoc} + */ + public function create(SerializationMetadata $serialization, bool $withAtFields): ContextInterface + { + $serializationMapper = new SerializationMapper($serialization, $withAtFields); + + $typeFactory = TypeCache::decorate( + new CompositeTypeFactory([ + $this->nullableTypeFactory, + $this->collectionTypeFactory, + DeferrableTypeFactory::decorate( + new CompositeTypeFactory([ + $serializationMapper, + $this->reflectionTypeFactory + ]) + ), + $this->builtinTypeFactory + ]) + ); + + return new Context($typeFactory); + } +} diff --git a/src/php/SerializationMapperFactoryInterface.php b/src/php/ContextFactoryInterface.php similarity index 83% rename from src/php/SerializationMapperFactoryInterface.php rename to src/php/ContextFactoryInterface.php index 3b8362c36143f0c92d6bd4a9990173315a485e4b..6fa9f1959fd747cadc46473a8b588a33733e0560 100644 --- a/src/php/SerializationMapperFactoryInterface.php +++ b/src/php/ContextFactoryInterface.php @@ -22,17 +22,18 @@ namespace Irstea\NgModelGeneratorBundle; use Irstea\NgModelGeneratorBundle\Metadata\SerializationMetadata; +use Irstea\NgModelGeneratorBundle\Models\Types\Factory\ContextInterface; /** - * Class SerializationMapperFactoryInterface. + * Class ContextFactoryInterface. */ -interface SerializationMapperFactoryInterface +interface ContextFactoryInterface { /** * @param SerializationMetadata $serialization - * @param bool $withAtFields + * @param bool $withAtFields * - * @return SerializationMapper + * @return ContextInterface */ - public function create(SerializationMetadata $serialization, bool $withAtFields): SerializationMapper; + public function create(SerializationMetadata $serialization, bool $withAtFields): ContextInterface; } diff --git a/src/php/ModelGenerator.php b/src/php/ModelGenerator.php index bc0f02ebfc645dd28d221062f0908bb3861e5a3a..63ac7cee60ce071499d89b68aed6b541c3677b88 100644 --- a/src/php/ModelGenerator.php +++ b/src/php/ModelGenerator.php @@ -31,6 +31,7 @@ use Irstea\NgModelGeneratorBundle\Models\ClassName; use Irstea\NgModelGeneratorBundle\Models\Declaration; use Irstea\NgModelGeneratorBundle\Models\PHPClass; use Irstea\NgModelGeneratorBundle\Models\Types\Factory\TypeFactoryInterface; +use Irstea\NgModelGeneratorBundle\Models\Types\Factory\TypeHelper; use Irstea\NgModelGeneratorBundle\Models\Types\Objects\Property; use Irstea\NgModelGeneratorBundle\Models\Types\Objects\Repository; use Irstea\NgModelGeneratorBundle\Models\Types\Type; @@ -51,25 +52,25 @@ final class ModelGenerator /** @var Documentation */ private $documentation; - /** @var SerializationMapperFactoryInterface */ - private $serializationMapperFactory; + /** @var ContextFactoryInterface */ + private $contextFactory; /** * Serializer constructor. * * @param MetadataFactoryInterface $metadataFactory - * @param SerializationMapperFactoryInterface $serializationMapperFactory + * @param ContextFactoryInterface $contextFactory * @param TypeFactoryInterface $typeFactory * @param Environment $twigEnv */ public function __construct( MetadataFactoryInterface $metadataFactory, - SerializationMapperFactoryInterface $serializationMapperFactory, + ContextFactoryInterface $contextFactory, Environment $twigEnv ) { $this->metadataFactory = $metadataFactory; $this->twigEnv = $twigEnv; - $this->serializationMapperFactory = $serializationMapperFactory; + $this->contextFactory = $contextFactory; } /** @@ -223,14 +224,14 @@ final class ModelGenerator { $defaultNormalization = $resourceMeta->getDefaultNormalization(); - $defaultNormalizationMapper = $this->serializationMapperFactory->create($defaultNormalization, true); + $defaultContext = $this->contextFactory->create($defaultNormalization, true); /** * @var Type * @var Property $identifier * @var Property[] $properties */ - [$defaultRepr, $identifier, $properties] = $defaultNormalizationMapper->getResourceData(); + [$defaultRepr, $identifier, $properties] = $defaultContext->createType(TypeHelper::fromClassName($resourceMeta->getFullName())); if (!$properties) { printf( @@ -268,7 +269,7 @@ final class ModelGenerator } foreach ($opsMeta as $operation) { - $mapper = new OperationMapper($this->typeFactory, $this->serializationMapperFactory, $pathParser, $operation, $iri); + $mapper = new OperationMapper($this->contextFactory, $pathParser, $operation, $iri); $operations[] = $mapper(); } diff --git a/src/php/Models/Types/Factory/AbstractTypeFactoryDecorator.php b/src/php/Models/Types/Factory/AbstractTypeFactoryDecorator.php index 6bd6c84db710fa675774ac395630730c3f570755..98ca281e6bf9955155e42e95bb38deeb9fef3eb7 100644 --- a/src/php/Models/Types/Factory/AbstractTypeFactoryDecorator.php +++ b/src/php/Models/Types/Factory/AbstractTypeFactoryDecorator.php @@ -39,7 +39,7 @@ abstract class AbstractTypeFactoryDecorator implements TypeFactoryInterface * * @param TypeFactoryInterface $decorated */ - public function __construct(TypeFactoryInterface $decorated) + protected function __construct(TypeFactoryInterface $decorated) { $this->decorated = $decorated; } @@ -59,4 +59,13 @@ abstract class AbstractTypeFactoryDecorator implements TypeFactoryInterface { return $this->decorated->createType($type, $context); } + + /** + * @param TypeFactoryInterface $decorated + * @return TypeFactoryInterface + */ + public static function decorate(TypeFactoryInterface $decorated): TypeFactoryInterface + { + return new static($decorated); + } } diff --git a/src/php/Models/Types/Factory/CollectionTypeFactory.php b/src/php/Models/Types/Factory/CollectionTypeFactory.php index 7e3ef073c7e8d6b514bc846ba504994c87b2fc39..efac62781466b8a22bff16f5c8b031ba58ffe439 100644 --- a/src/php/Models/Types/Factory/CollectionTypeFactory.php +++ b/src/php/Models/Types/Factory/CollectionTypeFactory.php @@ -30,13 +30,20 @@ use Symfony\Component\PropertyInfo\Type as PropertyType; /** * Class CollectionTypeFactory. */ -final class CollectionTypeFactory +final class CollectionTypeFactory implements TypeFactoryInterface { + + /** + * {@inheritDoc} + */ public function supportsType(PropertyType $type, ContextInterface $context): bool { return $type->isCollection(); } + /** + * {@inheritDoc} + */ public function createType(PropertyType $type, ContextInterface $context): Type { Assertion::true($this->supportsType($type, $context)); diff --git a/src/php/OperationMapper.php b/src/php/OperationMapper.php index 30c35ff095b3801ad50027fdf26c1a52f137f2d9..4bef97f987f9cc30b328a96f60e299036f709279 100644 --- a/src/php/OperationMapper.php +++ b/src/php/OperationMapper.php @@ -31,6 +31,7 @@ use Irstea\NgModelGeneratorBundle\Models\Types\AbstractCollection; use Irstea\NgModelGeneratorBundle\Models\Types\ArrayType; use Irstea\NgModelGeneratorBundle\Models\Types\BuiltinType; use Irstea\NgModelGeneratorBundle\Models\Types\Factory\TypeFactoryInterface; +use Irstea\NgModelGeneratorBundle\Models\Types\Factory\TypeHelper; use Irstea\NgModelGeneratorBundle\Models\Types\Objects\AnonymousObject; use Irstea\NgModelGeneratorBundle\Models\Types\Objects\InterfaceType; use Irstea\NgModelGeneratorBundle\Models\Types\Objects\Property; @@ -48,17 +49,14 @@ use Irstea\NgModelGeneratorBundle\Models\Types\Union; */ final class OperationMapper { - /** @var TypeFactoryInterface */ - private $typeFactory; - /** @var OperationMetadata */ private $operation; /** @var PathParserInterface */ private $pathParser; - /** @var SerializationMapperFactoryInterface */ - private $serializationMapperFactory; + /** @var ContextFactoryInterface */ + private $contextFactory; /** @var Path|null */ private $iri; @@ -67,20 +65,18 @@ final class OperationMapper * OperationMapper constructor. * * @param TypeFactoryInterface $typeFactory - * @param SerializationMapperFactoryInterface $serializationMapperFactory + * @param ContextFactoryInterface $contextFactory * @param PathParserInterface $pathParser * @param OperationMetadata $operation * @param Path|null $iri */ public function __construct( - TypeFactoryInterface $typeFactory, - SerializationMapperFactoryInterface $serializationMapperFactory, + ContextFactoryInterface $contextFactory, PathParserInterface $pathParser, OperationMetadata $operation, ?Path $iri ) { - $this->typeFactory = $typeFactory; - $this->serializationMapperFactory = $serializationMapperFactory; + $this->contextFactory = $contextFactory; $this->operation = $operation; $this->pathParser = $pathParser; $this->iri = $iri; @@ -139,13 +135,13 @@ final class OperationMapper $opParameters[] = new Parameter('body', $requestBody); $body[] = 'options.body = body;'; } - - $filterProperties = $this->getFilterProperties(); - if ($filterProperties) { - [$filterBody, $filterParam] = $this->buildFilterBody($filterProperties, 'options.params'); - $body = array_merge($body, $filterBody); - $opParameters[] = $filterParam; - } +// +// $filterProperties = $this->getFilterProperties(); +// if ($filterProperties) { +// [$filterBody, $filterParam] = $this->buildFilterBody($filterProperties, 'options.params'); +// $body = array_merge($body, $filterBody); +// $opParameters[] = $filterParam; +// } $opParameters[] = new Parameter('options', Placeholder::get('RequestOptions'), false, '{}'); $callParameters[] = 'options'; @@ -177,12 +173,12 @@ final class OperationMapper */ private function mapSerialization(SerializationMetadata $serializationMetadata): Type { - $mapper = $this->serializationMapperFactory->create( + $context = $this->contextFactory->create( $serializationMetadata, !$this->operation->getOpDef()->isCreateItem() ); - return $mapper->create($serializationMetadata->getRoot()->getFullName()); + return $context->createType(TypeHelper::fromClassName($serializationMetadata->getRoot()->getFullName())); } /** @@ -222,187 +218,187 @@ final class OperationMapper return $clientCall; } - - /** - * @return Property[] - */ - private function getFilterProperties(): array - { - /** @var Property[] $properties */ - $properties = []; - - $pagination = $this->operation->getPagination(); - if ($pagination && $pagination->isEnabled()) { - $intType = BuiltinType::get('number'); - - $pageName = $pagination->getPageParameterName(); - $properties[] = new Property($pageName, 'Requested page', $intType, false, true, false, $pageName); - - if ($pagination->isClientItemsPerPage()) { - $pageSizeName = $pagination->getItemsPerPageParameterName(); - $properties[] = new Property($pageSizeName, 'Page size', $intType, false, true, false, $pageSizeName); - } - } - - $rootClass = $this->operation->getClassName(); - - foreach ($this->operation->getFilters() as $filter) { - $filterType = PHPClass::get(get_class($filter))->getBaseName(); - - foreach ($filter->getDescription($this->operation->getResource()->getFullName()) as $name => $filterDesc) { - $type = $this->typeFactory->create($filterDesc['type']); - - if (isset($filterDesc['property']) && is_string($filterDesc['property'])) { - $propType = $this->resolvePropertyType($rootClass, $filterDesc['property']); - if ($propType) { - $type = $propType; - } - } - - /** @var string $alphanumName */ - $alphanumName = preg_replace('/\W+/', '_', $name); - $propName = Inflector::camelize($alphanumName); - - $type = $this->resolveFilterType($filterType, $type); - - $type = $this->getSingularType($type); - $propName = Inflector::singularize($propName); - if (!empty($filterDesc['is_collection']) || substr($name, strlen($name) - 2) === '[]') { - $type = new ArrayType($type); - $propName .= 'In'; - } - - $properties[] = new Property($propName, '', $type, false, true, false, $name); - } - } - - /** @var Property[] $propDict */ - $propDict = []; - foreach ($properties as $property) { - $name = $property->getName(); - if (isset($propDict[$name])) { - if ($propDict[$name]->getOriginalName() !== $property->getOriginalName()) { - throw new InvalidArgumentException(sprintf("filter property conflict: $name")); - } - $mergedeType = Union::create([$propDict[$name]->getType(), $property->getType()]); - $mergedNullable = $propDict[$name]->isNullable() || $property->isNullable(); - $propDict[$name] = new Property($name, '', $mergedeType, false, $mergedNullable, false, $property->getOriginalName()); - } else { - $propDict[$name] = $property; - } - } - - return $propDict; - } - - /** - * @param string $class - * @param string $property - * - * @return Type|null - */ - private function resolvePropertyType(string $class, string $property): ?Type - { - /** @var AnonymousObject|null $type */ - $type = $this->typeFactory->create($class)->findType(AnonymousObject::class); - if (!$type || !$type->hasProperty($property)) { - return null; - } - - return $type->getProperty($property)->getType(); - } - - /** - * @param string $filterType - * @param Type $baseType - * - * @return Type - */ - private function resolveFilterType(string $filterType, Type $baseType): Type - { - switch ($filterType) { - case 'DateFilter': - return BuiltinType::get('Date'); - - case 'NumericFilter': - return BuiltinType::get('number'); - break; - - case 'OrderFilter': - return $this->typeFactory->create('Ordering'); - - case 'BooleanFilter': - case 'ExistFilter': - return BuiltinType::get('boolean'); - } - - return $baseType; - } - - /** - * @param Type $type - * - * @return Type - */ - private function getSingularType(Type $type): Type - { - if ($type instanceof AbstractCollection) { - return $type->getValueType(); - } - if ($type instanceof Reference) { - return $this->getSingularType($type->getTarget()); - } - - return $type; - } - - /** - * @param Property[] $filterProperties - * @param string $varName - * - * @return array - */ - private function buildFilterBody(array $filterProperties, string $varName): array - { - $filterName = Inflector::classify( - $this->operation->getOpDef()->getName() - . $this->operation->getResource()->getBaseName() - . 'Filters' - ); - $filterType = new InterfaceType( - $filterName, - null, - $filterProperties, - sprintf( - 'Search filter(s) of %sRepository.%s', - $this->operation->getResource()->getBaseName(), - $this->operation->getName() - ) - ); - $this->typeFactory->add($filterName, $filterType); - - $body = ["if (filters && typeof filters === 'object') {"]; - $body[] = " if (!$varName) {"; - $body[] = " $varName = {};"; - $body[] = ' }'; - foreach ($filterProperties as $property) { - $assignation = sprintf( - ' %s = %s;', - $property->getUsage($varName, true), - $property->getType()->castToStringOrStringArray($property->getUsage('filters')) - ); - if ($property->isNullable()) { - $body[] = sprintf( - " if (%s) {\n %s\n }", - TypescriptHelper::propertyTestor('filters', $property->getName()), - $assignation - ); - } else { - $body[] = $assignation; - } - } - $body[] = '}'; - - return [$body, new Parameter('filters', $filterType, true)]; - } +//// +//// /** +//// * @return Property[] +//// */ +//// private function getFilterProperties(): array +//// { +//// /** @var Property[] $properties */ +//// $properties = []; +//// +//// $pagination = $this->operation->getPagination(); +//// if ($pagination && $pagination->isEnabled()) { +//// $intType = BuiltinType::get('number'); +//// +//// $pageName = $pagination->getPageParameterName(); +//// $properties[] = new Property($pageName, 'Requested page', $intType, false, true, false, $pageName); +//// +//// if ($pagination->isClientItemsPerPage()) { +//// $pageSizeName = $pagination->getItemsPerPageParameterName(); +//// $properties[] = new Property($pageSizeName, 'Page size', $intType, false, true, false, $pageSizeName); +//// } +//// } +//// +//// $rootClass = $this->operation->getClassName(); +//// +//// foreach ($this->operation->getFilters() as $filter) { +//// $filterType = PHPClass::get(get_class($filter))->getBaseName(); +//// +//// foreach ($filter->getDescription($this->operation->getResource()->getFullName()) as $name => $filterDesc) { +//// $type = $this->typeFactory->create($filterDesc['type']); +//// +//// if (isset($filterDesc['property']) && is_string($filterDesc['property'])) { +//// $propType = $this->resolvePropertyType($rootClass, $filterDesc['property']); +//// if ($propType) { +//// $type = $propType; +//// } +//// } +//// +//// /** @var string $alphanumName */ +//// $alphanumName = preg_replace('/\W+/', '_', $name); +//// $propName = Inflector::camelize($alphanumName); +//// +//// $type = $this->resolveFilterType($filterType, $type); +//// +//// $type = $this->getSingularType($type); +//// $propName = Inflector::singularize($propName); +//// if (!empty($filterDesc['is_collection']) || substr($name, strlen($name) - 2) === '[]') { +//// $type = new ArrayType($type); +//// $propName .= 'In'; +//// } +//// +//// $properties[] = new Property($propName, '', $type, false, true, false, $name); +//// } +//// } +//// +//// /** @var Property[] $propDict */ +//// $propDict = []; +//// foreach ($properties as $property) { +//// $name = $property->getName(); +//// if (isset($propDict[$name])) { +//// if ($propDict[$name]->getOriginalName() !== $property->getOriginalName()) { +//// throw new InvalidArgumentException(sprintf("filter property conflict: $name")); +//// } +//// $mergedeType = Union::create([$propDict[$name]->getType(), $property->getType()]); +//// $mergedNullable = $propDict[$name]->isNullable() || $property->isNullable(); +//// $propDict[$name] = new Property($name, '', $mergedeType, false, $mergedNullable, false, $property->getOriginalName()); +//// } else { +//// $propDict[$name] = $property; +//// } +//// } +//// +//// return $propDict; +//// } +// +// /** +// * @param string $class +// * @param string $property +// * +// * @return Type|null +// */ +// private function resolvePropertyType(string $class, string $property): ?Type +// { +// /** @var AnonymousObject|null $type */ +// $type = $this->typeFactory->create($class)->findType(AnonymousObject::class); +// if (!$type || !$type->hasProperty($property)) { +// return null; +// } +// +// return $type->getProperty($property)->getType(); +// } +// +// /** +// * @param string $filterType +// * @param Type $baseType +// * +// * @return Type +// */ +// private function resolveFilterType(string $filterType, Type $baseType): Type +// { +// switch ($filterType) { +// case 'DateFilter': +// return BuiltinType::get('Date'); +// +// case 'NumericFilter': +// return BuiltinType::get('number'); +// break; +// +// case 'OrderFilter': +// return $this->typeFactory->create('Ordering'); +// +// case 'BooleanFilter': +// case 'ExistFilter': +// return BuiltinType::get('boolean'); +// } +// +// return $baseType; +// } +// +// /** +// * @param Type $type +// * +// * @return Type +// */ +// private function getSingularType(Type $type): Type +// { +// if ($type instanceof AbstractCollection) { +// return $type->getValueType(); +// } +// if ($type instanceof Reference) { +// return $this->getSingularType($type->getTarget()); +// } +// +// return $type; +// } +// +// /** +// * @param Property[] $filterProperties +// * @param string $varName +// * +// * @return array +// */ +// private function buildFilterBody(array $filterProperties, string $varName): array +// { +// $filterName = Inflector::classify( +// $this->operation->getOpDef()->getName() +// . $this->operation->getResource()->getBaseName() +// . 'Filters' +// ); +// $filterType = new InterfaceType( +// $filterName, +// null, +// $filterProperties, +// sprintf( +// 'Search filter(s) of %sRepository.%s', +// $this->operation->getResource()->getBaseName(), +// $this->operation->getName() +// ) +// ); +// $this->typeFactory->add($filterName, $filterType); +// +// $body = ["if (filters && typeof filters === 'object') {"]; +// $body[] = " if (!$varName) {"; +// $body[] = " $varName = {};"; +// $body[] = ' }'; +// foreach ($filterProperties as $property) { +// $assignation = sprintf( +// ' %s = %s;', +// $property->getUsage($varName, true), +// $property->getType()->castToStringOrStringArray($property->getUsage('filters')) +// ); +// if ($property->isNullable()) { +// $body[] = sprintf( +// " if (%s) {\n %s\n }", +// TypescriptHelper::propertyTestor('filters', $property->getName()), +// $assignation +// ); +// } else { +// $body[] = $assignation; +// } +// } +// $body[] = '}'; +// +// return [$body, new Parameter('filters', $filterType, true)]; +// } } diff --git a/src/php/Resources/config/config.xml b/src/php/Resources/config/config.xml index ee6e7442d8f1769b2ccec066999e9f626d2d8334..a45b0d974c1ee862e982046f16d5671d7604a36a 100644 --- a/src/php/Resources/config/config.xml +++ b/src/php/Resources/config/config.xml @@ -57,13 +57,21 @@ lazy="true" > <argument id="Irstea\NgModelGeneratorBundle\Metadata\MetadataFactory" type="service"/> - <argument id="Irstea\NgModelGeneratorBundle\SerializationMapperFactory" type="service"/> + <argument id="Irstea\NgModelGeneratorBundle\ContextFactory" type="service"/> <argument id="twig" type="service"/> </service> - <service id="Irstea\NgModelGeneratorBundle\SerializationMapperFactory" + <service id="Irstea\NgModelGeneratorBundle\ContextFactory" lazy="true" > + <argument id="property_info" type="service"/> + </service> + + <service id="Irstea\NgModelGeneratorBundle\ContextCache" + lazy="true" + decorates="Irstea\NgModelGeneratorBundle\ContextFactory" + > + <argument id="Irstea\NgModelGeneratorBundle\ContextCache.inner" type="service"/> </service> <service id="ApiPlatform\Core\Documentation\Documentation" lazy="true"> @@ -74,10 +82,6 @@ <argument>%api_platform.formats%</argument> </service> - <service id="Irstea\NgModelGeneratorBundle\Models\Types\Factory\BuiltinTypeProvider" lazy="true"> - <argument id="Irstea\NgModelGeneratorBundle\Metadata\MetadataFactory" type="service"/> - </service> - <service id="ApiPlatform\Core\Metadata\Resource\ResourceNameCollection" lazy="true" public="false"> <factory service="api_platform.metadata.resource.name_collection_factory" method="create"/> </service> diff --git a/src/php/SerializationMapperFactory.php b/src/php/SerializationMapperFactory.php deleted file mode 100644 index 1e78889e84c844630c5d8401ad3a87ac866899a2..0000000000000000000000000000000000000000 --- a/src/php/SerializationMapperFactory.php +++ /dev/null @@ -1,56 +0,0 @@ -<?php declare(strict_types=1); -/* - * This file is part of "irstea/ng-model-generator-bundle". - * - * "irstea/ng-model-generator-bundle" generates Typescript interfaces for Angular using api-platform metadata. - * Copyright (C) 2018-2019 IRSTEA - * - * This program is free software: you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License and the GNU - * Lesser General Public License along with this program. If not, see - * <https://www.gnu.org/licenses/>. - */ - -namespace Irstea\NgModelGeneratorBundle; - -use Irstea\NgModelGeneratorBundle\Metadata\SerializationMetadata; - -/** - * Class SerializationMapperFactory. - */ -final class SerializationMapperFactory implements SerializationMapperFactoryInterface -{ - /** @var SerializationMapper[] */ - private $cache = []; - - /** - * @param SerializationMetadata $serialization - * @param bool $withAtFields - * - * @return SerializationMapper - */ - public function create(SerializationMetadata $serialization, bool $withAtFields): SerializationMapper - { - $key = sprintf( - '%s:%s:%s:%s', - $serialization->getRoot(), - $serialization->isNormalization() ? 'norm' : 'denorm', - $withAtFields ? 'with' : 'without', - implode(',', $serialization->getGroups()) - ); - - if (!isset($this->cache[$key])) { - $this->cache[$key] = new SerializationMapper($serialization, $withAtFields); - } - - return $this->cache[$key]; - } -}