Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 81 additions & 4 deletions src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 <dunglas@gmail.com>
*
* @see https://github.com/api-platform/core
* @see https://github.com/api-platform/core
*/
final class ApiPlatformCoreAnnotationGenerator extends AbstractAnnotationGenerator
{
Expand All @@ -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}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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' => [],
],
],
]
);
}
Expand All @@ -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'));
Expand Down