From 17c96fc39642637e5ee93f14f36e1d104cbcdd2a Mon Sep 17 00:00:00 2001 From: Toby Griffiths Date: Tue, 31 Oct 2017 21:44:18 +0000 Subject: [PATCH 1/2] Added test for expected operations config --- .../ApiPlatformCoreAnnotationGeneratorTest.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php b/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php index b2a7c857..e0d8d1e1 100644 --- a/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php +++ b/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php @@ -48,6 +48,13 @@ public function setUp() ], ], 'MyEnum' => ['resource' => $myEnum], + 'WithOperations' => [ + 'resource' => new \EasyRdf_Resource('http://schema.org/WithOperations', $graph), + 'operations' => [ + 'item' => ['get' => ["route_name" => "api_about_get"]], + 'collection' => [], + ], + ], ] ); } @@ -57,6 +64,11 @@ public function testGenerateClassAnnotations() $this->assertSame(['@ApiResource(iri="http://schema.org/Res")'], $this->generator->generateClassAnnotations('Res')); } + public function testGenerateClassAnnotationsWithOperations() + { + $this->assertSame(['@ApiResource(iri="http://schema.org/WithOperations", itemOperations={"get"={"route_name"="api_about_get"}}, collectionOperations={})'], $this->generator->generateClassAnnotations('WithOperations')); + } + public function testGenerateFieldAnnotations() { $this->assertSame(['@ApiProperty(iri="http://schema.org/prop")'], $this->generator->generateFieldAnnotations('Res', 'prop')); From 8fc6df106cc719653c393bc4d27129389e834ae6 Mon Sep 17 00:00:00 2001 From: Toby Griffiths Date: Tue, 31 Oct 2017 21:44:31 +0000 Subject: [PATCH 2/2] Added support for operations class annotations --- .../ApiPlatformCoreAnnotationGenerator.php | 85 ++++++++++++++++++- 1 file changed, 81 insertions(+), 4 deletions(-) diff --git a/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php b/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php index 16532dc8..23b8148a 100644 --- a/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php +++ b/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php @@ -16,13 +16,16 @@ use ApiPlatform\Core\Annotation\ApiProperty; use ApiPlatform\Core\Annotation\ApiResource; use ApiPlatform\SchemaGenerator\TypesGenerator; +use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; +use Symfony\Component\OptionsResolver\Options; +use Symfony\Component\OptionsResolver\OptionsResolver; /** * Generates API Platform core annotations. * * @author Kévin Dunglas * - * @see https://github.com/api-platform/core + * @see https://github.com/api-platform/core */ final class ApiPlatformCoreAnnotationGenerator extends AbstractAnnotationGenerator { @@ -31,19 +34,93 @@ final class ApiPlatformCoreAnnotationGenerator extends AbstractAnnotationGenerat */ public function generateClassAnnotations(string $className): array { - $resource = $this->classes[$className]['resource']; + $class = $this->classes[$className]; + + $resource = $class['resource']; + + $arguments = [sprintf('iri="%s"', $resource->getUri())]; + + if (isset($class['operations'])) { + $operations = $this->validateClassOperations((array)$class['operations']); + foreach ($operations as $operationTarget => $targetOperations) { + $targetArguments = []; + foreach ($targetOperations as $method => $methodConfig) { + $methodConfig = $this->validateClassOperationMethodConfig($methodConfig); + $methodArguments = []; + foreach ($methodConfig as $key => $value) { + $methodArguments[] = sprintf('"%s"="%s"', $key, $value); + } + $targetArguments[] = sprintf('"%s"={%s}', $method, implode(', ', $methodArguments)); + } + $arguments[] = sprintf('%sOperations={%s}', $operationTarget, implode(', ', $targetArguments)); + } + } + + return [sprintf('@ApiResource(%s)', implode(', ', $arguments))]; + } + + + /** + * Verifies that the operations config is valid + * + * @param array $operations + * + * @return array + */ + private function validateClassOperations(array $operations) + { + $resolver = new OptionsResolver(); + $resolver->setDefaults(['item' => [], 'collection' => []]); + $resolver->setAllowedTypes('item', 'array'); + $resolver->setAllowedTypes('collection', 'array'); - return [sprintf('@ApiResource(iri="%s")', $resource->getUri())]; + return $resolver->resolve($operations); } + + /** + * Validates the individual method config for an item/collection operation annotation + * + * @param array $methodConfig + * + * @return array + */ + private function validateClassOperationMethodConfig(array $methodConfig) + { + $resolver = new OptionsResolver(); + + $resolver->setDefined(['method', 'route_name']); + $resolver->setAllowedTypes('method', 'string'); + $resolver->setAllowedTypes('route_name', 'string'); + $resolver->setNormalizer( + 'route_name', + function (Options $options, $value) { + if (isset($options['method'])) { + throw new InvalidOptionsException('You must provide only \'method\' or \'route_name\', but not both'); + } + + return $value; + } + ); + + return $resolver->resolve($methodConfig); + } + + /** * {@inheritdoc} */ public function generateFieldAnnotations(string $className, string $fieldName): array { - return $this->classes[$className]['fields'][$fieldName]['isCustom'] ? [] : [sprintf('@ApiProperty(iri="http://schema.org/%s")', $fieldName)]; + return $this->classes[$className]['fields'][$fieldName]['isCustom'] ? [] : [ + sprintf( + '@ApiProperty(iri="http://schema.org/%s")', + $fieldName + ), + ]; } + /** * {@inheritdoc} */