Skip to content

Commit

Permalink
Enhanced DunglasApiBundle support
Browse files Browse the repository at this point in the history
  • Loading branch information
dunglas committed Apr 29, 2015
1 parent ad70ff9 commit 79c1c4e
Show file tree
Hide file tree
Showing 16 changed files with 465 additions and 257 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ matrix:

before_script:
- composer self-update
- sh -c 'if [ "$SYMFONY_VERSION" != "dev-master" ] && [ "$SYMFONY_VERSION" != "2.6.*" ]; then sed -i "/dunglas\/json-ld-api-bundle/d;/symfony\/serializer/d" composer.json; fi;'
- sh -c 'if [ "$SYMFONY_VERSION" != "dev-master" ] && [ "$SYMFONY_VERSION" != "2.6.*" ]; then sed -i "/dunglas\/api-bundle/d;/symfony\/serializer/d" composer.json; fi;'
- sh -c 'if [ "$SYMFONY_VERSION" != "" ]; then composer require --no-update symfony/symfony=$SYMFONY_VERSION; fi;'
- composer install

Expand Down
4 changes: 2 additions & 2 deletions DependencyInjection/LoadExtractorParsersPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ public function process(ContainerBuilder $container)
}

// DunglasJsonLdApiBundle may or may not be installed, if it is, load that config as well
if ($container->hasDefinition('dunglas_json_ld_api.resource_collection')) {
$loader->load('services.dunglas_json_ld_api.xml');
if ($container->hasDefinition('api.resource_collection')) {
$loader->load('services.dunglas_api.xml');
}
}
}
193 changes: 193 additions & 0 deletions Extractor/AnnotationsProvider/DunglasApiProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
<?php

/*
* This file is part of the NelmioApiDocBundle.
*
* (c) Nelmio <hello@nelm.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Nelmio\ApiDocBundle\Extractor\AnnotationsProvider;

use Dunglas\ApiBundle\Api\Operation\OperationInterface;
use Dunglas\ApiBundle\Api\ResourceCollectionInterface;
use Dunglas\ApiBundle\Api\ResourceInterface;
use Dunglas\ApiBundle\Hydra\ApiDocumentationBuilderInterface;
use Dunglas\ApiBundle\Mapping\ClassMetadataFactoryInterface;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use Nelmio\ApiDocBundle\Extractor\AnnotationsProviderInterface;
use Nelmio\ApiDocBundle\Parser\DunglasApiParser;

/**
* Creates ApiDoc annotations for DunglasApiBundle.
*
* @author Kévin Dunglas <dunglas@gmail.com>
*/
class DunglasApiProvider implements AnnotationsProviderInterface
{
/**
* @var ResourceCollectionInterface
*/
private $resourceCollection;
/**
* @var ApiDocumentationBuilderInterface
*/
private $apiDocumentationBuilder;
/**
* @var ClassMetadataFactoryInterface
*/
private $classMetadataFactory;

public function __construct(
ResourceCollectionInterface $resourceCollection,
ApiDocumentationBuilderInterface $apiDocumentationBuilder,
ClassMetadataFactoryInterface $classMetadataFactory
) {
$this->resourceCollection = $resourceCollection;
$this->apiDocumentationBuilder = $apiDocumentationBuilder;
$this->classMetadataFactory = $classMetadataFactory;
}

/**
* {@inheritdoc}
*/
public function getAnnotations()
{
$annotations = [];
$hydraDoc = $this->apiDocumentationBuilder->getApiDocumentation();
$entrypointHydraDoc = $this->getResourceHydraDoc($hydraDoc, '#Entrypoint');

/**
* @var ResourceInterface
*/
foreach ($this->resourceCollection as $resource) {
$classMetadata = $this->classMetadataFactory->getMetadataFor($resource->getEntityClass());
$prefixedShortName = ($iri = $classMetadata->getIri()) ? $iri : '#'.$resource->getShortName();
$resourceHydraDoc = $this->getResourceHydraDoc($hydraDoc, $prefixedShortName);

if ($hydraDoc) {
foreach ($resource->getCollectionOperations() as $operation) {
$annotations[] = $this->getApiDoc(true, $resource, $operation, $resourceHydraDoc, $entrypointHydraDoc);
}

foreach ($resource->getItemOperations() as $operation) {
$annotations[] = $this->getApiDoc(false, $resource, $operation, $resourceHydraDoc);
}
}
}

return $annotations;
}

/**
* Builds ApiDoc annotation from DunglasApiBundle data.
*
* @param bool $collection
* @param ResourceInterface $resource
* @param OperationInterface $operation
* @param array $resourceHydraDoc
* @param array $entrypointHydraDoc
*
* @return ApiDoc
*/
private function getApiDoc(
$collection,
ResourceInterface $resource,
OperationInterface $operation,
array $resourceHydraDoc,
array $entrypointHydraDoc = []
) {
$method = $operation->getRoute()->getMethods()[0];

if ($collection) {
$operationHydraDoc = $this->getCollectionOperationHydraDoc($resource->getShortName(), $method, $entrypointHydraDoc);
} else {
$operationHydraDoc = $this->getOperationHydraDoc($operation->getRoute()->getMethods()[0], $resourceHydraDoc);
}

$route = $operation->getRoute();

$data = [
'resource' => $route->getPath(),
'description' => $operationHydraDoc['hydra:title'],
'resourceDescription' => $resourceHydraDoc['hydra:title'],
];

$entityClass = $resource->getEntityClass();

if (isset($operationHydraDoc['expects']) && 'owl:Nothing' !== $operationHydraDoc['expects']) {
$data['input'] = sprintf('%s:%s', DunglasApiParser::IN_PREFIX, $entityClass);
}

if (isset($operationHydraDoc['returns']) && 'owl:Nothing' !== $operationHydraDoc['returns']) {
$data['output'] = sprintf('%s:%s', DunglasApiParser::OUT_PREFIX, $entityClass);
}

$data['filters'] = [];
foreach ($resource->getFilters() as $filter) {
$data['filters'][] = ['name' => $filter->getName()];
}

$apiDoc = new ApiDoc($data);
$apiDoc->setRoute($route);

return $apiDoc;
}

/**
* Gets Hydra documentation for the given resource.
*
* @param array $hydraApiDoc
* @param string $prefixedShortName
*
* @return array|null
*/
private function getResourceHydraDoc(array $hydraApiDoc, $prefixedShortName)
{
foreach ($hydraApiDoc['hydra:supportedClass'] as $supportedClass) {
if ($supportedClass['@id'] === $prefixedShortName) {
return $supportedClass;
}
}
}

/**
* Gets the Hydra documentation of a given operation.
*
* @param string $method
* @param array $hydraDoc
*
* @return array|null
*/
private function getOperationHydraDoc($method, array $hydraDoc)
{
foreach ($hydraDoc['hydra:supportedOperation'] as $supportedOperation) {
if ($supportedOperation['hydra:method'] === $method) {
return $supportedOperation;
}
}
}

/**
* Gets the Hydra documentation for the collection operation.
*
* @param string $shortName
* @param string $method
* @param array $hydraEntrypointDoc
*
* @return array|null
*/
private function getCollectionOperationHydraDoc($shortName, $method, array $hydraEntrypointDoc)
{
$propertyName = '#Entrypoint/'.lcfirst($shortName);

foreach ($hydraEntrypointDoc['hydra:supportedProperty'] as $supportedProperty) {
$hydraProperty = $supportedProperty['hydra:property'];
if ($hydraProperty['@id'] === $propertyName) {
return $this->getOperationHydraDoc($method, $hydraProperty);
}
}
}
}
98 changes: 0 additions & 98 deletions Extractor/AnnotationsProvider/DunglasJsonLdApiProvider.php

This file was deleted.

Loading

0 comments on commit 79c1c4e

Please sign in to comment.