diff --git a/src/Metadata/CachingMetadataFactory.php b/src/Metadata/CachingMetadataFactory.php index 35f553f2eec8ba76c06abd80f66dc5a468ef404d..13cdec961e774be0b1a76236aaf470ae855d2a15 100644 --- a/src/Metadata/CachingMetadataFactory.php +++ b/src/Metadata/CachingMetadataFactory.php @@ -21,7 +21,7 @@ namespace Irstea\NgModelGeneratorBundle\Metadata; use Doctrine\Common\Cache\ArrayCache; use Doctrine\Common\Cache\Cache; -use Irstea\NgModelGeneratorBundle\Models\PHPClass; +use Irstea\NgModelGeneratorBundle\Models\ClassName; /** * Class CachingMetadataFactory. @@ -49,7 +49,7 @@ final class CachingMetadataFactory implements MetadataFactoryInterface /** * {@inheritdoc} */ - public function isResource(PHPClass $class): bool + public function isResource(ClassName $class): bool { return $this->inner->isResource($class); } @@ -57,7 +57,7 @@ final class CachingMetadataFactory implements MetadataFactoryInterface /** * {@inheritdoc} */ - public function getResourceMetadata(PHPClass $class): ResourceMetadata + public function getResourceMetadata(ClassName $class): ResourceMetadata { return $this->memoize(__METHOD__, $class->getFullName(), function () use ($class) { return $this->inner->getResourceMetadata($class); diff --git a/src/Metadata/ClassHierarchy.php b/src/Metadata/ClassHierarchy.php index 743cb650147634d1b50943e7e61baa0dad868555..8f1b536c30570dfef375d27f72558251b11e278f 100644 --- a/src/Metadata/ClassHierarchy.php +++ b/src/Metadata/ClassHierarchy.php @@ -19,7 +19,7 @@ namespace Irstea\NgModelGeneratorBundle\Metadata; -use Irstea\NgModelGeneratorBundle\Models\PHPClass; +use Irstea\NgModelGeneratorBundle\Models\ClassName; /** * Interface ClassHierarchy. @@ -27,16 +27,16 @@ use Irstea\NgModelGeneratorBundle\Models\PHPClass; interface ClassHierarchy { /** - * @param PHPClass $class + * @param ClassName $class * - * @return PHPClass|null + * @return ClassName|null */ - public function getParent(PHPClass $class): ?PHPClass; + public function getParent(ClassName $class): ?ClassName; /** - * @param PHPClass $class + * @param ClassName $class * - * @return PHPClass[] + * @return ClassName[] */ - public function getChildren(PHPClass $class): array; + public function getChildren(ClassName $class): array; } diff --git a/src/Metadata/MetadataFactory.php b/src/Metadata/MetadataFactory.php index b15e8dc6a5f29f18fc4b086a1c7bc041b8003715..8c2348525def988297efa52dd21a3bd55d23e1fa 100644 --- a/src/Metadata/MetadataFactory.php +++ b/src/Metadata/MetadataFactory.php @@ -30,6 +30,7 @@ use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface; use ApiPlatform\Core\Metadata\Resource\ResourceMetadata as APIResourceMetadata; use ApiPlatform\Core\PathResolver\OperationPathResolverInterface; use Doctrine\Common\Inflector\Inflector; +use Irstea\NgModelGeneratorBundle\Models\ClassName; use Irstea\NgModelGeneratorBundle\Models\PHPClass; use Psr\Container\ContainerInterface; use Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface; @@ -116,7 +117,7 @@ final class MetadataFactory implements MetadataFactoryInterface /** * {@inheritdoc} */ - public function isResource(PHPClass $class): bool + public function isResource(ClassName $class): bool { return $this->resourceClassResolver->isResourceClass($class->getFullName()); } @@ -124,7 +125,7 @@ final class MetadataFactory implements MetadataFactoryInterface /** * {@inheritdoc} */ - public function getResourceMetadata(PHPClass $class): ResourceMetadata + public function getResourceMetadata(ClassName $class): ResourceMetadata { $className = $class->getFullName(); $metadata = $this->resourceMetadataFactory->create($className); @@ -177,11 +178,11 @@ final class MetadataFactory implements MetadataFactoryInterface } /** - * @param PHPClass $class + * @param ClassName $class * * @return OperationMetadata[] */ - private function getOperations(PHPClass $class): array + private function getOperations(ClassName $class): array { $resourceMetadata = $this->resourceMetadataFactory->create($class->getFullName()); @@ -200,7 +201,7 @@ final class MetadataFactory implements MetadataFactoryInterface } /** - * @param PHPClass $class + * @param ClassName $class * @param APIResourceMetadata $resourceMetadata * @param string $name * @param string $type @@ -209,7 +210,7 @@ final class MetadataFactory implements MetadataFactoryInterface * @return OperationMetadata */ private function getOperation( - PHPClass $class, + ClassName $class, APIResourceMetadata $resourceMetadata, string $name, string $type, @@ -279,12 +280,12 @@ final class MetadataFactory implements MetadataFactoryInterface } /** - * @param PHPClass $class - * @param array $filterIds + * @param ClassName $class + * @param array $filterIds * * @return FilterInterface[] */ - private function getFilters(PHPClass $class, array $filterIds): array + private function getFilters(ClassName $class, array $filterIds): array { $filters = []; @@ -307,7 +308,7 @@ final class MetadataFactory implements MetadataFactoryInterface * @parma string $operationName * * @param OperationDef|null $opDef - * @param PHPClass $class + * @param ClassName $class * @param bool $normalization * @param string[] $groups * @@ -319,7 +320,7 @@ final class MetadataFactory implements MetadataFactoryInterface */ private function getOperationSerialization( ?OperationDef $opDef, - PHPClass $class, + ClassName $class, bool $normalization, array $groups ): SerializationMetadata { @@ -334,7 +335,7 @@ final class MetadataFactory implements MetadataFactoryInterface } /** - * @param PHPClass $class + * @param ClassName $class * @param bool $normalization * @param OperationDef $opDef * @param string[] $groups @@ -345,7 +346,7 @@ final class MetadataFactory implements MetadataFactoryInterface * * @return SerializationMetadata */ - private function doGetSerialization(PHPClass $class, bool $normalization, ?OperationDef $opDef, array $groups): SerializationMetadata + private function doGetSerialization(ClassName $class, bool $normalization, ?OperationDef $opDef, array $groups): SerializationMetadata { if ($normalization) { $metadata = $this->resourceMetadataFactory->create($class->getFullName()); @@ -374,25 +375,23 @@ final class MetadataFactory implements MetadataFactoryInterface /** @var RepresentationMetadata[] $reprs */ $representations = []; - /** @var string[] $queue */ - $queue = [$class->getFullName()]; + /** @var ClassName[] $queue */ + $queue = [$class]; while ($queue) { - /** @var string $currentName */ - $currentName = array_shift($queue); - $current = PHPClass::get($currentName); + $current = array_shift($queue); - if (isset($representations[$currentName]) || !$this->isResource($current)) { + if (isset($representations[$current->getFullName()]) || !$this->isResource($current)) { continue; } $parent = $this->classHierarchy->getParent($current); if ($parent) { - $queue[] = $parent->getFullName(); + $queue[] = $parent; } foreach ($this->classHierarchy->getChildren($current) as $children) { - $queue[] = $children->getFullName(); + $queue[] = $children; } $propertiesMeta = $this->getPropertiesMeta($current, $groups); @@ -406,20 +405,22 @@ final class MetadataFactory implements MetadataFactoryInterface $properties[$propertyName] = $property; $type = $property->getLeafType(); if ($type->getClassName()) { - $queue[] = $type->getClassName(); + $queue[] = PHPClass::get($type->getClassName()); } } - $name = ($current->is($class) ? $selfNamePrefix : $otherNamePrefix) . $current->getBaseName(); + $name = ($current === $class ? $selfNamePrefix : $otherNamePrefix) . $current->getBaseName(); - $representations[$currentName] = new RepresentationMetadata($name, $current, $parent, $properties); + $abstract = (new \ReflectionClass($current->getFullName()))->isAbstract(); + + $representations[$current->getFullName()] = new RepresentationMetadata($name, $current, $parent, $properties, $abstract); } return new SerializationMetadata($class, $groups, $normalization, $representations); } /** - * @param PHPClass $class + * @param ClassName $class * @param string $name * @param APIPropertyMetadata $property * @@ -427,13 +428,13 @@ final class MetadataFactory implements MetadataFactoryInterface * * @internal */ - public function filterGetProperty(PHPClass $class, string $name, APIPropertyMetadata $property): bool + public function filterGetProperty(ClassName $class, string $name, APIPropertyMetadata $property): bool { return $property->isIdentifier() || $property->isReadable() || $property->isReadableLink(); } /** - * @param PHPClass $class + * @param ClassName $class * @param string $name * @param APIPropertyMetadata $property * @@ -441,13 +442,13 @@ final class MetadataFactory implements MetadataFactoryInterface * * @internal */ - public function filterCreateProperty(PHPClass $class, string $name, APIPropertyMetadata $property): bool + public function filterCreateProperty(ClassName $class, string $name, APIPropertyMetadata $property): bool { return $property->isWritable() || $property->isWritableLink() || ($property->isInitializable() ?: false); } /** - * @param PHPClass $class + * @param ClassName $class * @param string $name * @param APIPropertyMetadata $property * @@ -455,13 +456,13 @@ final class MetadataFactory implements MetadataFactoryInterface * * @internal */ - public function filterUpdateProperty(PHPClass $class, string $name, APIPropertyMetadata $property): bool + public function filterUpdateProperty(ClassName $class, string $name, APIPropertyMetadata $property): bool { return $this->filterGetProperty($class, $name, $property) || $property->isWritable() || $property->isWritableLink(); } /** - * @param PHPClass $class + * @param ClassName $class * @param string $name * @param APIPropertyMetadata $property * @@ -469,21 +470,21 @@ final class MetadataFactory implements MetadataFactoryInterface * * @internal */ - public function filterAnyProperty(PHPClass $class, string $name, APIPropertyMetadata $property): bool + public function filterAnyProperty(ClassName $class, string $name, APIPropertyMetadata $property): bool { return true; } /** - * @param PHPClass $class - * @param array $groups + * @param ClassName $class + * @param array $groups * * @throws \ApiPlatform\Core\Exception\PropertyNotFoundException * @throws \ApiPlatform\Core\Exception\ResourceClassNotFoundException * * @return APIPropertyMetadata[] */ - private function getPropertiesMeta(PHPClass $class, array $groups): array + private function getPropertiesMeta(ClassName $class, array $groups): array { $properties = []; $options = $groups ? ['serializer_groups' => $groups] : []; @@ -504,13 +505,13 @@ final class MetadataFactory implements MetadataFactoryInterface } /** - * @param PHPClass $class + * @param ClassName $class * @param string $propertyName * @param APIPropertyMetadata $propertyMeta * * @return PropertyMetadata */ - private function mapProperty(PHPClass $class, string $propertyName, APIPropertyMetadata $propertyMeta): PropertyMetadata + private function mapProperty(ClassName $class, string $propertyName, APIPropertyMetadata $propertyMeta): PropertyMetadata { $leafType = $typeMeta = $propertyMeta->getType(); diff --git a/src/Metadata/MetadataFactoryInterface.php b/src/Metadata/MetadataFactoryInterface.php index 42dfa79f199d2b7122876dbd0f67ef977a28431f..00c45858a3d7ae83386bdd34016c9c3f42cd6956 100644 --- a/src/Metadata/MetadataFactoryInterface.php +++ b/src/Metadata/MetadataFactoryInterface.php @@ -19,7 +19,7 @@ namespace Irstea\NgModelGeneratorBundle\Metadata; -use Irstea\NgModelGeneratorBundle\Models\PHPClass; +use Irstea\NgModelGeneratorBundle\Models\ClassName; /** * Interface MetadataFactoryInterface. @@ -27,18 +27,18 @@ use Irstea\NgModelGeneratorBundle\Models\PHPClass; interface MetadataFactoryInterface { /** - * @param PHPClass $class + * @param ClassName $class * * @return bool */ - public function isResource(PHPClass $class): bool; + public function isResource(ClassName $class): bool; /** - * @param PHPClass $class + * @param ClassName $class * * @return ResourceMetadata */ - public function getResourceMetadata(PHPClass $class): ResourceMetadata; + public function getResourceMetadata(ClassName $class): ResourceMetadata; /** * @return PaginationMetadata diff --git a/src/Metadata/RepresentationMetadata.php b/src/Metadata/RepresentationMetadata.php index 6145b37550eba34822b212dc07a452c0b67dd62c..7aae54791e76103966026ce7ecbcf9ace3490921 100644 --- a/src/Metadata/RepresentationMetadata.php +++ b/src/Metadata/RepresentationMetadata.php @@ -19,12 +19,12 @@ namespace Irstea\NgModelGeneratorBundle\Metadata; -use Irstea\NgModelGeneratorBundle\Models\PHPClass; +use Irstea\NgModelGeneratorBundle\Models\ClassName; /** * Class RepresentationMetadata. */ -final class RepresentationMetadata implements \JsonSerializable +final class RepresentationMetadata implements ClassName { /** * @var string @@ -32,12 +32,12 @@ final class RepresentationMetadata implements \JsonSerializable private $name; /** - * @var PHPClass + * @var ClassName */ private $class; /** - * @var null|PHPClass + * @var null|ClassName */ private $parent; @@ -50,11 +50,11 @@ final class RepresentationMetadata implements \JsonSerializable * RepresentationMetadata constructor. * * @param string $name - * @param PHPClass $class - * @param PHPClass|null $parent + * @param ClassName $class + * @param ClassName|null $parent * @param PropertyMetadata[] $properties */ - public function __construct(string $name, PHPClass $class, ?PHPClass $parent, array $properties) + public function __construct(string $name, ClassName $class, ?ClassName $parent, array $properties, bool $abstract) { $this->class = $class; $this->parent = $parent; @@ -78,21 +78,43 @@ final class RepresentationMetadata implements \JsonSerializable } /** - * Get class. - * - * @return PHPClass + * {@inheritdoc} + */ + public function getNamespace(): string + { + return $this->class->getNamespace(); + } + + /** + * {@inheritdoc} + */ + public function getBaseName(): string + { + return $this->class->getBaseName(); + } + + /** + * {@inheritdoc} + */ + public function getFullName(): string + { + return $this->class->getFullName(); + } + + /** + * {@inheritdoc} */ - public function getClass(): PHPClass + public function __toString() { - return $this->class; + return $this->class->__toString(); } /** * Get parent. * - * @return null|PHPClass + * @return null|ClassName */ - public function getParent(): ?PHPClass + public function getParent(): ?ClassName { return $this->parent; } diff --git a/src/Metadata/ResourceClassHierarchy.php b/src/Metadata/ResourceClassHierarchy.php index e4bed6fefb279486fbc41fcefff1a251d6e0dae2..a751dcb64dc6e4cb17e90c3d15575cd16ce510ad 100644 --- a/src/Metadata/ResourceClassHierarchy.php +++ b/src/Metadata/ResourceClassHierarchy.php @@ -20,6 +20,7 @@ namespace Irstea\NgModelGeneratorBundle\Metadata; use ApiPlatform\Core\Metadata\Resource\ResourceNameCollection; +use Irstea\NgModelGeneratorBundle\Models\ClassName; use Irstea\NgModelGeneratorBundle\Models\PHPClass; /** @@ -27,10 +28,10 @@ use Irstea\NgModelGeneratorBundle\Models\PHPClass; */ final class ResourceClassHierarchy implements ClassHierarchy { - /** @var PHPClass[] */ + /** @var ClassName[] */ private $parents = []; - /** @var PHPClass[][] */ + /** @var ClassName[][] */ private $children = []; /** @@ -44,16 +45,16 @@ final class ResourceClassHierarchy implements ClassHierarchy } /** - * @param PHPClass $class + * @param ClassName $class */ - private function preload(PHPClass $class): void + private function preload(ClassName $class): void { $className = $class->getFullName(); if (\array_key_exists($className, $this->parents)) { return; } - $parent = $class->getReflection()->getParentClass(); + $parent = new \ReflectionClass($class->getFullName()); if (!$parent) { $this->parents[$className] = null; @@ -72,7 +73,7 @@ final class ResourceClassHierarchy implements ClassHierarchy /** * {@inheritdoc} */ - public function getParent(PHPClass $class): ?PHPClass + public function getParent(ClassName $class): ?ClassName { $this->preload($class); @@ -82,7 +83,7 @@ final class ResourceClassHierarchy implements ClassHierarchy /** * {@inheritdoc} */ - public function getChildren(PHPClass $class): array + public function getChildren(ClassName $class): array { $this->preload($class); diff --git a/src/Metadata/ResourceMetadata.php b/src/Metadata/ResourceMetadata.php index 628786ae6cdd8303ed57011b5c29ef466c46312c..6b53e5026c4969ab2409828a6b322d9e180f9ce3 100644 --- a/src/Metadata/ResourceMetadata.php +++ b/src/Metadata/ResourceMetadata.php @@ -19,17 +19,17 @@ namespace Irstea\NgModelGeneratorBundle\Metadata; -use Irstea\NgModelGeneratorBundle\Models\PHPClass; +use Irstea\NgModelGeneratorBundle\Models\ClassName; /** * Class ResourceMetadata. */ -class ResourceMetadata implements \JsonSerializable +class ResourceMetadata implements ClassName { - /** @var PHPClass */ + /** @var ClassName */ private $class; - /** @var PHPClass|null */ + /** @var ClassName|null */ private $parentClass; /** @var string */ @@ -41,16 +41,14 @@ class ResourceMetadata implements \JsonSerializable /** @var OperationMetadata[] */ private $operations = []; - /** - * @var SerializationMetadata - */ + /** @var SerializationMetadata */ private $defaultNormalization; /** * ResourceMetadata constructor. * - * @param PHPClass $class - * @param PHPClass|null $parentClass + * @param ClassName $class + * @param ClassName|null $parentClass * @param string $shortName * @param string $description * @param bool $abstract @@ -58,8 +56,8 @@ class ResourceMetadata implements \JsonSerializable * @param OperationMetadata[] $operations */ public function __construct( - PHPClass $class, - ?PHPClass $parentClass, + ClassName $class, + ?ClassName $parentClass, string $shortName, string $description, bool $abstract, @@ -79,31 +77,43 @@ class ResourceMetadata implements \JsonSerializable } /** - * Get className. - * - * @return string + * {@inheritdoc} */ - public function getClassName(): string + public function getNamespace(): string { - return $this->class->getFullName(); + return $this->class->getNamespace(); } /** - * Get shortName. - * - * @return string + * {@inheritdoc} */ - public function getShortName(): string + public function getBaseName(): string { return $this->class->getBaseName(); } + /** + * {@inheritdoc} + */ + public function getFullName(): string + { + return $this->class->getFullName(); + } + + /** + * {@inheritdoc} + */ + public function __toString() + { + return $this->getFullName(); + } + /** * Get parentClass. * - * @return PHPClass|null + * @return ClassName|null */ - public function getParentClass(): ?PHPClass + public function getParentClass(): ?ClassName { return $this->parentClass; } @@ -138,16 +148,6 @@ class ResourceMetadata implements \JsonSerializable return $this->abstract; } - /** - * Get class. - * - * @return PHPClass - */ - public function getClass(): PHPClass - { - return $this->class; - } - /** * Get operations. * diff --git a/src/Metadata/SerializationMetadata.php b/src/Metadata/SerializationMetadata.php index e9a47e11fd19569457cf2d531e5aca74bd303f21..bd76426d0dbd1a67b946fbd5c2f1ec88de5ed164 100644 --- a/src/Metadata/SerializationMetadata.php +++ b/src/Metadata/SerializationMetadata.php @@ -19,42 +19,34 @@ namespace Irstea\NgModelGeneratorBundle\Metadata; -use Irstea\NgModelGeneratorBundle\Models\PHPClass; +use Irstea\NgModelGeneratorBundle\Models\ClassName; /** * Class SerializationMetadata. */ -final class SerializationMetadata implements \JsonSerializable +final class SerializationMetadata implements ClassName { - /** - * @var PHPClass - */ + /** @var ClassName */ private $root; - /** - * @var string[] - */ + /** @var string[] */ private $groups; - /** - * @var bool - */ + /** @var bool */ private $normalization; - /** - * @var RepresentationMetadata[] - */ + /** @var RepresentationMetadata[] */ private $representations = []; /** * SerializationMetadata constructor. * - * @param PHPClass $root + * @param ClassName $root * @param string[] $groups * @param bool $normalization * @param RepresentationMetadata[] $representations */ - public function __construct(PHPClass $root, array $groups, bool $normalization, array $representations) + public function __construct(ClassName $root, array $groups, bool $normalization, array $representations) { $this->groups = $groups; sort($this->groups); @@ -63,7 +55,7 @@ final class SerializationMetadata implements \JsonSerializable $this->normalization = $normalization; foreach ($representations as $representation) { - $this->representations[$representation->getClass()->getFullName()] = $representation; + $this->representations[$representation->getFullName()] = $representation; } ksort($this->representations); } @@ -81,21 +73,43 @@ final class SerializationMetadata implements \JsonSerializable /** * Get root. * - * @return PHPClass + * @return ClassName */ - public function getRoot(): PHPClass + public function getRoot(): ClassName { return $this->root; } /** - * @param PHPClass|string $class - * - * @return bool + * {@inheritdoc} + */ + public function getNamespace(): string + { + return $this->root->getNamespace(); + } + + /** + * {@inheritdoc} + */ + public function getBaseName(): string + { + return $this->root->getBaseName(); + } + + /** + * {@inheritdoc} + */ + public function getFullName(): string + { + return $this->root->getFullName(); + } + + /** + * {@inheritdoc} */ - public function isRoot($class): bool + public function __toString() { - return $this->root === PHPClass::get($class); + return $this->root->__toString(); } /** @@ -109,21 +123,21 @@ final class SerializationMetadata implements \JsonSerializable } /** - * @param PHPClass $class + * @param ClassName $class * * @return bool */ - public function hasRepresentationOf(PHPClass $class): bool + public function hasRepresentationOf(ClassName $class): bool { return isset($this->representations[$class->getFullName()]); } /** - * @param PHPClass $class + * @param ClassName $class * * @return RepresentationMetadata */ - public function getRepresentationOf(PHPClass $class): RepresentationMetadata + public function getRepresentationOf(ClassName $class): RepresentationMetadata { return $this->representations[$class->getFullName()]; } @@ -139,15 +153,15 @@ final class SerializationMetadata implements \JsonSerializable } /** - * @return PHPClass[] + * @return ClassName[] */ public function getRootSubClasses(): array { $subclasses = []; - $rootClassName = $this->getRoot()->getFullName(); + $rootClassName = $this->getFullName(); foreach ($this->representations as $className => $meta) { if (\is_subclass_of($className, $rootClassName, true)) { - $subclasses[$className] = PHPClass::get($className); + $subclasses[$className] = $meta; } } diff --git a/src/ModelGenerator.php b/src/ModelGenerator.php index 4266323d4d9c37308d39fcf0a4e1ca7d57ee5215..03f5408295d782ceebc8f21bb74d21f306489b8e 100644 --- a/src/ModelGenerator.php +++ b/src/ModelGenerator.php @@ -26,6 +26,7 @@ use Irstea\NgModelGeneratorBundle\Exceptions\TypeError; use Irstea\NgModelGeneratorBundle\Iterators\IteratorBuilder; use Irstea\NgModelGeneratorBundle\Metadata\MetadataFactoryInterface; use Irstea\NgModelGeneratorBundle\Metadata\ResourceMetadata; +use Irstea\NgModelGeneratorBundle\Models\ClassName; use Irstea\NgModelGeneratorBundle\Models\Declaration; use Irstea\NgModelGeneratorBundle\Models\PHPClass; use Irstea\NgModelGeneratorBundle\Models\Types\Alias; @@ -271,11 +272,11 @@ final class ModelGenerator $repositories = []; /** - * @var PHPClass + * @var ClassName * @var ResourceMetadata $resourceMeta */ foreach ($this->getResourceMetadata() as $class => $resourceMeta) { - $repoName = $resourceMeta->getShortName() . 'Repository'; + $repoName = $resourceMeta->getBaseName() . 'Repository'; try { $repositories[$repoName] = $this->typeFactory->getOrCreate( @@ -313,7 +314,7 @@ final class ModelGenerator throw new TypeError( sprintf( 'No property found for %s (groups: [%s])', - $resourceMeta->getShortName(), + $resourceMeta->getBaseName(), implode(', ', $defaultNormalization->getGroups()) ) ); @@ -323,7 +324,7 @@ final class ModelGenerator throw new TypeError( sprintf( 'No identifier found for %s (groups: [%s])', - $resourceMeta->getShortName(), + $resourceMeta->getBaseName(), implode(', ', $defaultNormalization->getGroups()) ) ); @@ -336,6 +337,6 @@ final class ModelGenerator $operations[] = $mapper(); } - return new Repository($resourceMeta->getClass(), $defaultRepr, $identifier, $operations); + return new Repository($resourceMeta, $defaultRepr, $identifier, $operations); } } diff --git a/src/Models/ClassInfo.php b/src/Models/ClassInfo.php index 0d1ada9ea3a8076d181a15f6d449a39eaf76a50b..e317e8fbe78830fb73a0bd602844070b401eca7a 100644 --- a/src/Models/ClassInfo.php +++ b/src/Models/ClassInfo.php @@ -19,24 +19,24 @@ namespace Irstea\NgModelGeneratorBundle\Models; +use Irstea\NgModelGeneratorBundle\Exceptions\DomainException; use Irstea\NgModelGeneratorBundle\Metadata\PropertyMetadata; -use Irstea\NgModelGeneratorBundle\Models\Types\Objects\Property; /** * Class ClassInfo. */ -final class ClassInfo implements \JsonSerializable +final class ClassInfo implements ClassName { public const UNDEFINED = 'UNDEFINED'; public const IRI = 'IRI'; public const UNION = 'UNION'; public const INTERFACE = 'INTERFACE'; - /** @var PHPClass */ - private $resource; + /** @var ClassName */ + private $class; - /** @var self|null */ - private $parent; + /** @var self|null|false */ + private $parent = false; /** @var PropertyMetadata[] */ private $virtualProperties = []; @@ -51,33 +51,58 @@ final class ClassInfo implements \JsonSerializable private $type = self::UNDEFINED; /** @var bool */ - private $isAbstract; + private $abstract; /** * ClassInfo constructor. * - * @param PHPClass $resource + * @param ClassName $class * @param PropertyMetadata[] $properties - * @param bool $isAbstract + * @param bool $abstract */ - public function __construct(PHPClass $resource, array $properties = [], bool $isAbstract) + public function __construct(ClassName $class, array $properties = [], bool $abstract) { - $this->resource = $resource; - $this->isAbstract = $isAbstract; + $this->class = $class; + $this->abstract = $abstract; foreach ($properties as $property) { $this->virtualProperties[$property->getName()] = $property; } + $this->concreteProperties = $abstract ? [] : $this->virtualProperties; } /** - * Get resource. + * {@inheritdoc} + */ + public function getNamespace(): string + { + return $this->class->getNamespace(); + } + + /** + * {@inheritdoc} + */ + public function getBaseName(): string + { + return $this->class->getBaseName(); + } + + /** + * {@inheritdoc} + */ + public function getFullName(): string + { + return $this->class->getFullName(); + } + + /** + * Get class. * - * @return PHPClass + * @return ClassName */ - public function getResource(): PHPClass + public function getClass(): ClassName { - return $this->resource; + return $this->class; } /** @@ -101,13 +126,13 @@ final class ClassInfo implements \JsonSerializable } /** - * Get isAbstract. + * Get abstract. * * @return bool */ public function isAbstract(): bool { - return $this->isAbstract; + return $this->abstract; } /** @@ -187,6 +212,15 @@ final class ClassInfo implements \JsonSerializable return $this->type === $type; } + + /** + * @return string + */ + public function __toString() + { + return $this->getClass()->getFullName(); + } + /** * Fait remonter les propriétés communes des sous-classes. */ diff --git a/src/Models/ClassName.php b/src/Models/ClassName.php new file mode 100644 index 0000000000000000000000000000000000000000..7309c8be618d26b67dbac5dd6e37a782b159c945 --- /dev/null +++ b/src/Models/ClassName.php @@ -0,0 +1,50 @@ +<?php declare(strict_types=1); +/* + * irstea/ng-model-generator-bundle generates Typescript interfaces for Angular using api-platform metadata. + * Copyright (C) 2018 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\Models; + +/** + * Interface ClassName. + */ +interface ClassName extends \JsonSerializable +{ + /** + * Get namespace. + * + * @return string + */ + public function getNamespace(): string; + + /** + * Get baseName. + * + * @return string + */ + public function getBaseName(): string; + + /** + * @return string + */ + public function getFullName(): string; + + /** + * @return string + */ + public function __toString(); +} diff --git a/src/Models/PHPClass.php b/src/Models/PHPClass.php index 40a3d96b2fad3d995e4f7107816402fc7af889bb..e6ff765c10b85d4a92889c1b97ac97b39e93ac13 100644 --- a/src/Models/PHPClass.php +++ b/src/Models/PHPClass.php @@ -24,7 +24,7 @@ use Irstea\NgModelGeneratorBundle\Exceptions\InvalidArgumentException; /** * Class PHPClass. */ -final class PHPClass implements \JsonSerializable +final class PHPClass implements ClassName { /** @var string */ private $namespace; @@ -72,34 +72,6 @@ final class PHPClass implements \JsonSerializable return $this->namespace . $this->baseName; } - /** - * @return bool - */ - public function exists(): bool - { - return class_exists($this->getFullName()); - } - - /** - * @throws \ReflectionException - * - * @return \ReflectionClass - */ - public function getReflection(): \ReflectionClass - { - return new \ReflectionClass($this->getFullName()); - } - - /** - * @param string|PHPClass $class - * - * @return bool - */ - public function is($class): bool - { - return $this === self::get($class); - } - /** * @return string */ @@ -128,13 +100,13 @@ final class PHPClass implements \JsonSerializable } /** - * @param self|string $name + * @param ClassName|string $name * - * @return self + * @return ClassName */ - public static function get($name): self + public static function get($name): ClassName { - if ($name instanceof self) { + if ($name instanceof ClassName) { return $name; } diff --git a/src/Models/Types/Objects/Repository.php b/src/Models/Types/Objects/Repository.php index 733eb78a699078726c58526d9d1d7ab4b0c26a90..42f2b4fb184556549db3da629a573d2d66af7540 100644 --- a/src/Models/Types/Objects/Repository.php +++ b/src/Models/Types/Objects/Repository.php @@ -20,7 +20,7 @@ namespace Irstea\NgModelGeneratorBundle\Models\Types\Objects; use Doctrine\Common\Inflector\Inflector; -use Irstea\NgModelGeneratorBundle\Models\PHPClass; +use Irstea\NgModelGeneratorBundle\Models\ClassName; use Irstea\NgModelGeneratorBundle\Models\Types\Operations\Operation; use Irstea\NgModelGeneratorBundle\Models\Types\Operations\Path; use Irstea\NgModelGeneratorBundle\Models\Types\Type; @@ -31,7 +31,7 @@ use Irstea\NgModelGeneratorBundle\TypescriptHelper; */ final class Repository extends ClassType { - /** @var PHPClass */ + /** @var ClassName */ private $resource; /** @var Operation[] */ @@ -49,13 +49,13 @@ final class Repository extends ClassType /** * Repository constructor. * - * @param PHPClass $resource + * @param ClassName $resource * @param Type $resourceType * @param Property $identifier * @param Operation[] $operations * @param string $description */ - public function __construct(PHPClass $resource, Type $resourceType, Property $identifier, array $operations, string $description = '') + public function __construct(ClassName $resource, Type $resourceType, Property $identifier, array $operations, string $description = '') { parent::__construct( $resource->getBaseName() . 'Repository', diff --git a/src/Models/Types/Resources/IRI.php b/src/Models/Types/Resources/IRI.php index b3ed4f154110296d1d9cf7f13f5652afe260a7c6..ad5cf346ad2c586028d26049b000483252d11719 100644 --- a/src/Models/Types/Resources/IRI.php +++ b/src/Models/Types/Resources/IRI.php @@ -19,7 +19,7 @@ namespace Irstea\NgModelGeneratorBundle\Models\Types\Resources; -use Irstea\NgModelGeneratorBundle\Models\PHPClass; +use Irstea\NgModelGeneratorBundle\Models\ClassName; use Irstea\NgModelGeneratorBundle\Models\Types\AbstractType; /** @@ -27,13 +27,13 @@ use Irstea\NgModelGeneratorBundle\Models\Types\AbstractType; */ final class IRI extends AbstractType { - /** @var PHPClass[] */ + /** @var ClassName[] */ private $resources; /** * IRI constructor. * - * @param PHPClass[] $resources + * @param ClassName[] $resources */ public function __construct(array $resources) { @@ -46,7 +46,7 @@ final class IRI extends AbstractType private function getNames(): array { return array_map( - function (PHPClass $t): string { + function (ClassName $t): string { return $t->getBaseName(); }, $this->resources diff --git a/src/Models/Types/Resources/Representation.php b/src/Models/Types/Resources/Representation.php index cb976ba51392b3aef1afa5949dc8152f77aaa626..87c89d12999aac889adccee3eec26d65ce10923c 100644 --- a/src/Models/Types/Resources/Representation.php +++ b/src/Models/Types/Resources/Representation.php @@ -19,42 +19,58 @@ namespace Irstea\NgModelGeneratorBundle\Models\Types\Resources; -use Irstea\NgModelGeneratorBundle\Models\PHPClass; +use Irstea\NgModelGeneratorBundle\Models\ClassName; use Irstea\NgModelGeneratorBundle\Models\Types\Objects\InterfaceType; use Irstea\NgModelGeneratorBundle\Models\Types\Type; /** * Class Representation. */ -final class Representation extends InterfaceType +final class Representation extends InterfaceType implements ClassName { - /** @var PHPClass */ + /** @var ClassName */ private $resource; /** * {@inheritdoc} */ - public function __construct(PHPClass $resource, string $name, ?Type $parent, $properties = [], string $description = '', array $children = []) + public function __construct(ClassName $resource, string $name, ?Type $parent, $properties = [], string $description = '', array $children = []) { parent::__construct($name, $parent, $properties, $description, $children); $this->resource = $resource; } /** - * @return string + * {@inheritdoc} + */ + public function getNamespace(): string + { + return $this->resource->getNamespace(); + } + + /** + * {@inheritdoc} */ - public function getResourceName(): string + public function getBaseName(): string { return $this->resource->getBaseName(); } + /** + * {@inheritdoc} + */ + public function getFullName(): string + { + return $this->resource->getFullName(); + } + /** * {@inheritdoc} */ public function checkType(string $expr, bool $explicit = false): string { if (!$explicit) { - return sprintf('%sRepository.isValidResource(%s)', $this->getResourceName(), $expr); + return sprintf('%sRepository.isValidResource(%s)', $this->getBaseName(), $expr); } return parent::checkType($expr, false); diff --git a/src/PathParser.php b/src/PathParser.php index d0b5466ec3ed0c4f510bc7612e48a83c7b4aa3cb..bbf7e2b2e3daec5459a5412a002dfb4889e48462 100644 --- a/src/PathParser.php +++ b/src/PathParser.php @@ -19,7 +19,7 @@ namespace Irstea\NgModelGeneratorBundle; -use Irstea\NgModelGeneratorBundle\Models\PHPClass; +use Irstea\NgModelGeneratorBundle\Models\ClassName; use Irstea\NgModelGeneratorBundle\Models\Types\BuiltinType; use Irstea\NgModelGeneratorBundle\Models\Types\Objects\Property; use Irstea\NgModelGeneratorBundle\Models\Types\Operations\Parameter; @@ -37,16 +37,16 @@ final class PathParser implements PathParserInterface /** @var Property[] */ private $properties; - /** @var PHPClass */ + /** @var ClassName */ private $resource; /** * PathParser constructor. * - * @param PHPClass $resource + * @param ClassName $resource * @param Property[] $properties */ - public function __construct(PHPClass $resource, array $properties) + public function __construct(ClassName $resource, array $properties) { $this->properties = $properties; $this->resource = $resource; diff --git a/src/SerializationMapper.php b/src/SerializationMapper.php index 9f36310a7c3557c04295fe6b0d9ec33e05900873..d2b0fc0e7005d903ed46b4c88cec679ab0bfa7b1 100644 --- a/src/SerializationMapper.php +++ b/src/SerializationMapper.php @@ -24,6 +24,7 @@ use Irstea\NgModelGeneratorBundle\Metadata\PropertyMetadata; use Irstea\NgModelGeneratorBundle\Metadata\RepresentationMetadata; use Irstea\NgModelGeneratorBundle\Metadata\SerializationMetadata; use Irstea\NgModelGeneratorBundle\Models\ClassInfo; +use Irstea\NgModelGeneratorBundle\Models\ClassName; use Irstea\NgModelGeneratorBundle\Models\PHPClass; use Irstea\NgModelGeneratorBundle\Models\Types\Alias; use Irstea\NgModelGeneratorBundle\Models\Types\ArrayType; @@ -157,19 +158,17 @@ final class SerializationMapper implements TypeFactoryInterface */ private function mapRepresentation(RepresentationMetadata $repr): Type { - $resourceClass = $repr->getClass(); - - $classInfo = $this->getClassInfo($resourceClass); + $classInfo = $this->getClassInfo($repr); if ($classInfo->isUnion()) { $types = []; foreach ($classInfo->iterateInterfaceDescendants() as $child) { - $types[] = $this->get($child->getResource()->getFullName()); + $types[] = $this->get($child->getClass()->getFullName()); } switch (\count($types)) { case 0: - throw new DomainException(sprintf('Union with no children: %s', $resourceClass)); + throw new DomainException(sprintf('Union with no children: %s', $repr)); case 1: return new Reference($types[0]); default: @@ -178,36 +177,36 @@ final class SerializationMapper implements TypeFactoryInterface } if ($classInfo->isIRI()) { - return new IRI([$resourceClass]); + return new IRI([$repr]); } if (!$classInfo->isInterface()) { - throw new DomainException(sprintf('Cannot map %s', $resourceClass->getFullName())); + throw new DomainException(sprintf('Cannot map %s', $repr)); } $parent = null; $parentInfo = $classInfo->getParent(); if ($parentInfo !== null && $parentInfo->isInterface()) { - $parent = $this->get($parentInfo->getResource()->getFullName()); + $parent = $this->get($parentInfo->getFullName()); } $properties = $this->mapProperties($classInfo); $desc = []; - $desc[] = 'Resource: ' . $resourceClass->getFullName(); + $desc[] = 'Resource: ' . $repr; $desc[] = 'Direction: ' . ($this->serialization->isNormalization() ? 'response' : 'request'); $desc[] = sprintf('Serialization groups: %s', implode(', ', $this->serialization->getGroups()) ?: '-'); $desc = trim(implode("\n", $desc)); $children = []; - /* @var PHPClass $class */ + /* @var ClassName $class */ foreach ($classInfo->getChildren() as $child) { if ($child->isInterface()) { - $children[] = $this->get($child->getResource()->getFullName()); + $children[] = $this->get($child->getFullName()); } } - return new Representation($resourceClass, $repr->getName(), $parent, $properties, $desc, $children); + return new Representation($repr, $repr->getName(), $parent, $properties, $desc, $children); } /** @@ -219,7 +218,7 @@ final class SerializationMapper implements TypeFactoryInterface { $resources = []; foreach ($classInfo->iterateConcreteDescendants() as $child) { - $resources[] = $child->getResource(); + $resources[] = $child; } return new IRI($resources); @@ -248,7 +247,7 @@ final class SerializationMapper implements TypeFactoryInterface throw new DomainException( sprintf( 'Resource %s must have at most one identifier, found %d', - $classInfo->getResource()->getBaseName(), + $classInfo->getBaseName(), $identifierCount ) ); @@ -286,7 +285,7 @@ final class SerializationMapper implements TypeFactoryInterface { $types = []; foreach ($classInfo->iterateConcreteDescendants() as $child) { - $types[] = StringConst::get($child->getResource()->getBaseName()); + $types[] = StringConst::get($child->getBaseName()); } return Union::create($types); @@ -342,13 +341,13 @@ final class SerializationMapper implements TypeFactoryInterface } /** - * @param PHPClass $class + * @param ClassName $class * * @return ClassInfo */ - private function getClassInfo(PHPClass $class): ClassInfo + private function getClassInfo(ClassName $class): ClassInfo { - if (!isset($this->classInfo)) { + if ($this->classInfo === null) { $this->init(); } @@ -361,8 +360,11 @@ final class SerializationMapper implements TypeFactoryInterface // Crée les instances de métadonnées sur les ressources foreach ($reprs as $className => $repr) { - $class = $repr->getClass(); - $this->classInfo[$className] = new ClassInfo($class, $repr->getProperties(), $class->getReflection()->isAbstract()); + $this->classInfo[$className] = new ClassInfo( + $repr, + $repr->getProperties(), + $repr->isAbstract() + ); } // Crée les liens de parenté diff --git a/tests/PHPClassTest.php b/tests/Models/PHPClassTest.php similarity index 82% rename from tests/PHPClassTest.php rename to tests/Models/PHPClassTest.php index fc49a6052e7b0935d9ff647ebd6b9213259c1603..c6b2c5dab1a115f24a976d037139a1e60007efc3 100644 --- a/tests/PHPClassTest.php +++ b/tests/Models/PHPClassTest.php @@ -17,7 +17,7 @@ * <https://www.gnu.org/licenses/>. */ -namespace Irstea\NgModelGeneratorBundle\Tests; +namespace Irstea\NgModelGeneratorBundle\Tests\Models; use Irstea\NgModelGeneratorBundle\Models\PHPClass; use PHPUnit\Framework\TestCase; @@ -98,28 +98,4 @@ class PHPClassTest extends TestCase [PHPClass::class], ]; } - - /** - * @param $expected - * @param $fqcn - * - * @dataProvider existsTestCases - */ - public function testExists(bool $expected, string $fqcn) - { - $class = PHPClass::get($fqcn); - self::assertEquals($expected, $class->exists()); - } - - /** - * @return array - */ - public function existsTestCases(): array - { - return [ - [false, 'Foo'], - [true, \stdClass::class], - [true, PHPClass::class], - ]; - } }