diff --git a/Command/DumpApiDocCommand.php b/Command/DumpApiDocCommand.php index dc45201..50d205b 100644 --- a/Command/DumpApiDocCommand.php +++ b/Command/DumpApiDocCommand.php @@ -17,6 +17,8 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Filesystem\Filesystem; use Nelmio\ApiDocBundle\ApiDocGenerator; +use Doctrine\Common\Annotations\AnnotationReader; +use WizardsRest\Annotation\Exposable; /** * Class GenerateSwaggerDocumentationCommand @@ -29,6 +31,8 @@ class DumpApiDocCommand extends Command */ private $generator; + private $reader; + /** * DumpApiDocCommand constructor. * @@ -39,6 +43,8 @@ public function __construct(ApiDocGenerator $generator, $name = null) { $this->generator = $generator; + $this->reader = new AnnotationReader(); + parent::__construct($name); } @@ -70,6 +76,7 @@ protected function execute(InputInterface $input, OutputInterface $output) if ($this->isJsonApi($apiDoc) && isset($apiDoc['definitions'])) { $apiDoc['definitions'] = $this->removeIdFromDefinitions($apiDoc['definitions']); + $apiDoc['definitions'] = $this->removeRelationsFromDefinitions($apiDoc['definitions']); } $jsonSchema = json_encode($apiDoc, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); @@ -125,6 +132,46 @@ private function removeIdFromDefinitions(array $definitionList) return $definitionList; } + /** + * Relationships are managed as HATEOAS in jsonapi. + * + * @param array $definitionList + * + * @return array + */ + private function removeRelationsFromDefinitions(array $definitionList) + { + foreach ($definitionList as $definitionName => $definition) { + if (isset($definition['properties'])) { + foreach ($definition['properties'] as $propertyId => $property) { + // if property is a relationship + if (isset($property['$ref']) || isset($property['items']['$ref'])) { + // check in the entity s actually a relation + try { + $reflection = new \ReflectionClass( + sprintf('App\\Entity\\%s', ucfirst($definitionName)) + ); + if ( + $reflection + && $reflection->hasProperty($propertyId) + && null === $this->reader->getPropertyAnnotation( + $reflection->getProperty($propertyId), + Exposable::class + ) + ) { + unset($definitionList[$definitionName]['properties'][$propertyId]); + } + } catch (\Exception $exception) { + // property is not a relation. skip. + } + } + } + } + } + + return $definitionList; + } + private function isJsonApi($apiDoc) { return isset($apiDoc['produces']) && in_array('application/vnd.api+json', $apiDoc['produces']); diff --git a/composer.json b/composer.json index 1b1f417..a394378 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,8 @@ "require": { "php": ">5.5", "nelmio/api-doc-bundle": "^3.3.1", - "symfony/console": "^4" + "symfony/console": "^4", + "wizards/rest-bundle": "^0.9.7" }, "require-dev": { "phpunit/phpunit": ">5.7"