mirror of
https://github.com/retailcrm/NelmioApiDocBundle.git
synced 2025-02-02 15:51:48 +03:00
Merge pull request #585 from dunglas/dunglasjsonldapibundle
DunglasJsonLdApiBundle support
This commit is contained in:
commit
26fe302a5a
@ -12,13 +12,17 @@ matrix:
|
|||||||
env: SYMFONY_VERSION='2.3.*'
|
env: SYMFONY_VERSION='2.3.*'
|
||||||
- php: 5.5
|
- php: 5.5
|
||||||
env: SYMFONY_VERSION='2.4.*'
|
env: SYMFONY_VERSION='2.4.*'
|
||||||
|
- php: 5.5
|
||||||
|
env: SYMFONY_VERSION='2.6.*'
|
||||||
- php: 5.5
|
- php: 5.5
|
||||||
env: SYMFONY_VERSION='dev-master'
|
env: SYMFONY_VERSION='dev-master'
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- env: SYMFONY_VERSION=dev-master
|
- php: 5.5
|
||||||
|
env: SYMFONY_VERSION='dev-master'
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- composer self-update
|
- 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" != "" ]; then composer require --no-update symfony/symfony=$SYMFONY_VERSION; fi;'
|
- sh -c 'if [ "$SYMFONY_VERSION" != "" ]; then composer require --no-update symfony/symfony=$SYMFONY_VERSION; fi;'
|
||||||
- composer install
|
- composer install
|
||||||
|
|
||||||
|
40
DependencyInjection/AnnotationsProviderCompilerPass.php
Normal file
40
DependencyInjection/AnnotationsProviderCompilerPass.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?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\DependencyInjection;
|
||||||
|
|
||||||
|
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AnnotationsProvider compiler pass.
|
||||||
|
*
|
||||||
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
|
*/
|
||||||
|
class AnnotationsProviderCompilerPass implements CompilerPassInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function process(ContainerBuilder $container)
|
||||||
|
{
|
||||||
|
$annotationsProviders = array();
|
||||||
|
foreach ($container->findTaggedServiceIds('nelmio_api_doc.extractor.annotations_provider') as $id => $attributes) {
|
||||||
|
$annotationsProviders[] = new Reference($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
$container
|
||||||
|
->getDefinition('nelmio_api_doc.extractor.api_doc_extractor')
|
||||||
|
->replaceArgument(6, $annotationsProviders)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
@ -29,6 +29,6 @@ class ExtractorHandlerCompilerPass implements CompilerPassInterface
|
|||||||
|
|
||||||
$container
|
$container
|
||||||
->getDefinition('nelmio_api_doc.extractor.api_doc_extractor')
|
->getDefinition('nelmio_api_doc.extractor.api_doc_extractor')
|
||||||
->replaceArgument(4, $handlers);
|
->replaceArgument(5, $handlers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,5 +32,10 @@ class LoadExtractorParsersPass implements CompilerPassInterface
|
|||||||
if ($container->hasDefinition('jms_serializer.serializer')) {
|
if ($container->hasDefinition('jms_serializer.serializer')) {
|
||||||
$loader->load('services.jms.xml');
|
$loader->load('services.jms.xml');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DunglasJsonLdApiBundle may or may not be installed, if it is, load that config as well
|
||||||
|
if ($container->hasDefinition('dunglas_json_ld_api.resources')) {
|
||||||
|
$loader->load('services.dunglas_json_ld_api.xml');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
95
Extractor/AnnotationsProvider/DunglasJsonLdApiProvider.php
Normal file
95
Extractor/AnnotationsProvider/DunglasJsonLdApiProvider.php
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<?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 Doctrine\Common\Annotations\Reader;
|
||||||
|
use Dunglas\JsonLdApiBundle\JsonLd\Resource;
|
||||||
|
use Dunglas\JsonLdApiBundle\JsonLd\Resources;
|
||||||
|
use Dunglas\JsonLdApiBundle\Mapping\ClassMetadataFactory;
|
||||||
|
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
|
||||||
|
use Nelmio\ApiDocBundle\Extractor\AnnotationsProviderInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates ApiDoc annotations for DunglasJsonLdApiBundle.
|
||||||
|
*
|
||||||
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
|
*/
|
||||||
|
class DunglasJsonLdApiProvider implements AnnotationsProviderInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Resources
|
||||||
|
*/
|
||||||
|
private $resources;
|
||||||
|
/**
|
||||||
|
* @var ClassMetadataFactory
|
||||||
|
*/
|
||||||
|
private $classMetadataFactory;
|
||||||
|
|
||||||
|
public function __construct(Resources $resources, ClassMetadataFactory $classMetadataFactory)
|
||||||
|
{
|
||||||
|
$this->resources = $resources;
|
||||||
|
$this->classMetadataFactory = $classMetadataFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getAnnotations()
|
||||||
|
{
|
||||||
|
$annotations = [];
|
||||||
|
foreach ($this->resources as $resource) {
|
||||||
|
$resource->getRouteCollection(); // Populate !route
|
||||||
|
|
||||||
|
foreach ($resource->getCollectionOperations() as $operation) {
|
||||||
|
$annotations[] = $this->getApiDoc($resource, $operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($resource->getItemOperations() as $operation) {
|
||||||
|
$annotations[] = $this->getApiDoc($resource, $operation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $annotations;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds ApiDoc annotation from DunglasJsonLdApiBundle data.
|
||||||
|
*
|
||||||
|
* @param Resource $resource
|
||||||
|
* @param array $operation
|
||||||
|
*
|
||||||
|
* @return ApiDoc
|
||||||
|
*/
|
||||||
|
private function getApiDoc(Resource $resource, array $operation)
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'resource' => $operation['!route_path'],
|
||||||
|
'description' => $operation['rdfs:label'],
|
||||||
|
'resourceDescription' => $this->classMetadataFactory->getMetadataFor($resource->getEntityClass())->getDescription(),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (isset($operation['expects']) && $operation['expects'] !== 'owl:Nothing') {
|
||||||
|
$data['input'] = $resource->getEntityClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($operation['returns']) && $operation['returns'] !== 'owl:Nothing') {
|
||||||
|
$data['output'] = $resource->getEntityClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['filters'] = $resource->getFilters();
|
||||||
|
|
||||||
|
$apiDoc = new ApiDoc($data);
|
||||||
|
$apiDoc->setRoute($operation['!route']);
|
||||||
|
|
||||||
|
return $apiDoc;
|
||||||
|
}
|
||||||
|
}
|
29
Extractor/AnnotationsProviderInterface.php
Normal file
29
Extractor/AnnotationsProviderInterface.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?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;
|
||||||
|
|
||||||
|
use Symfony\Component\Routing\Route;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for annotations providers.
|
||||||
|
*
|
||||||
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
|
*/
|
||||||
|
interface AnnotationsProviderInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns an array ApiDoc annotations.
|
||||||
|
*
|
||||||
|
* @return \Nelmio\ApiDocBundle\Annotation\ApiDoc[]
|
||||||
|
*/
|
||||||
|
public function getAnnotations();
|
||||||
|
}
|
@ -18,6 +18,7 @@ use Nelmio\ApiDocBundle\DataTypes;
|
|||||||
use Nelmio\ApiDocBundle\Parser\ParserInterface;
|
use Nelmio\ApiDocBundle\Parser\ParserInterface;
|
||||||
use Nelmio\ApiDocBundle\Parser\PostParserInterface;
|
use Nelmio\ApiDocBundle\Parser\PostParserInterface;
|
||||||
use Nelmio\ApiDocBundle\Util\DocCommentExtractor;
|
use Nelmio\ApiDocBundle\Util\DocCommentExtractor;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser;
|
||||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\Routing\Route;
|
use Symfony\Component\Routing\Route;
|
||||||
@ -47,6 +48,11 @@ class ApiDocExtractor
|
|||||||
*/
|
*/
|
||||||
private $commentExtractor;
|
private $commentExtractor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ControllerNameParser
|
||||||
|
*/
|
||||||
|
protected $controllerNameParser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var ParserInterface[]
|
* @var ParserInterface[]
|
||||||
*/
|
*/
|
||||||
@ -57,13 +63,20 @@ class ApiDocExtractor
|
|||||||
*/
|
*/
|
||||||
protected $handlers;
|
protected $handlers;
|
||||||
|
|
||||||
public function __construct(ContainerInterface $container, RouterInterface $router, Reader $reader, DocCommentExtractor $commentExtractor, array $handlers)
|
/**
|
||||||
|
* @var AnnotationsProviderInterface[]
|
||||||
|
*/
|
||||||
|
protected $annotationsProviders;
|
||||||
|
|
||||||
|
public function __construct(ContainerInterface $container, RouterInterface $router, Reader $reader, DocCommentExtractor $commentExtractor, ControllerNameParser $controllerNameParser, array $handlers, array $annotationsProviders)
|
||||||
{
|
{
|
||||||
$this->container = $container;
|
$this->container = $container;
|
||||||
$this->router = $router;
|
$this->router = $router;
|
||||||
$this->reader = $reader;
|
$this->reader = $reader;
|
||||||
$this->commentExtractor = $commentExtractor;
|
$this->commentExtractor = $commentExtractor;
|
||||||
$this->handlers = $handlers;
|
$this->controllerNameParser = $controllerNameParser;
|
||||||
|
$this->handlers = $handlers;
|
||||||
|
$this->annotationsProviders = $annotationsProviders;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -125,6 +138,13 @@ class ApiDocExtractor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($this->annotationsProviders as $annotationProvider) {
|
||||||
|
foreach ($annotationProvider->getAnnotations() as $annotation) {
|
||||||
|
$route = $annotation->getRoute();
|
||||||
|
$array[] = array('annotation' => $this->extractData($annotation, $route, $this->getReflectionMethod($route->getDefault('_controller'))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rsort($resources);
|
rsort($resources);
|
||||||
foreach ($array as $index => $element) {
|
foreach ($array as $index => $element) {
|
||||||
$hasResource = false;
|
$hasResource = false;
|
||||||
@ -181,6 +201,10 @@ class ApiDocExtractor
|
|||||||
*/
|
*/
|
||||||
public function getReflectionMethod($controller)
|
public function getReflectionMethod($controller)
|
||||||
{
|
{
|
||||||
|
if (false === strpos($controller, '::') && 2 === substr_count($controller, ':')) {
|
||||||
|
$controller = $this->controllerNameParser->parse($controller);
|
||||||
|
}
|
||||||
|
|
||||||
if (preg_match('#(.+)::([\w]+)#', $controller, $matches)) {
|
if (preg_match('#(.+)::([\w]+)#', $controller, $matches)) {
|
||||||
$class = $matches[1];
|
$class = $matches[1];
|
||||||
$method = $matches[2];
|
$method = $matches[2];
|
||||||
|
@ -13,6 +13,7 @@ namespace Nelmio\ApiDocBundle\Extractor;
|
|||||||
|
|
||||||
use Doctrine\Common\Annotations\Reader;
|
use Doctrine\Common\Annotations\Reader;
|
||||||
use Nelmio\ApiDocBundle\Util\DocCommentExtractor;
|
use Nelmio\ApiDocBundle\Util\DocCommentExtractor;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser;
|
||||||
use Symfony\Component\Config\ConfigCache;
|
use Symfony\Component\Config\ConfigCache;
|
||||||
use Symfony\Component\Config\Resource\FileResource;
|
use Symfony\Component\Config\Resource\FileResource;
|
||||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
@ -37,11 +38,13 @@ class CachingApiDocExtractor extends ApiDocExtractor
|
|||||||
RouterInterface $router,
|
RouterInterface $router,
|
||||||
Reader $reader,
|
Reader $reader,
|
||||||
DocCommentExtractor $commentExtractor,
|
DocCommentExtractor $commentExtractor,
|
||||||
|
ControllerNameParser $controllerNameParser,
|
||||||
array $handlers,
|
array $handlers,
|
||||||
|
array $annotationsProviders,
|
||||||
$cacheFile,
|
$cacheFile,
|
||||||
$debug = false
|
$debug = false
|
||||||
) {
|
) {
|
||||||
parent::__construct($container, $router, $reader, $commentExtractor, $handlers);
|
parent::__construct($container, $router, $reader, $commentExtractor, $controllerNameParser, $handlers, $annotationsProviders);
|
||||||
$this->cacheFile = $cacheFile;
|
$this->cacheFile = $cacheFile;
|
||||||
$this->cache = new ConfigCache($this->cacheFile, $debug);
|
$this->cache = new ConfigCache($this->cacheFile, $debug);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Nelmio\ApiDocBundle;
|
namespace Nelmio\ApiDocBundle;
|
||||||
|
|
||||||
|
use Nelmio\ApiDocBundle\DependencyInjection\AnnotationsProviderCompilerPass;
|
||||||
use Nelmio\ApiDocBundle\DependencyInjection\SwaggerConfigCompilerPass;
|
use Nelmio\ApiDocBundle\DependencyInjection\SwaggerConfigCompilerPass;
|
||||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
@ -18,6 +19,7 @@ class NelmioApiDocBundle extends Bundle
|
|||||||
$container->addCompilerPass(new LoadExtractorParsersPass());
|
$container->addCompilerPass(new LoadExtractorParsersPass());
|
||||||
$container->addCompilerPass(new RegisterExtractorParsersPass());
|
$container->addCompilerPass(new RegisterExtractorParsersPass());
|
||||||
$container->addCompilerPass(new ExtractorHandlerCompilerPass());
|
$container->addCompilerPass(new ExtractorHandlerCompilerPass());
|
||||||
|
$container->addCompilerPass(new AnnotationsProviderCompilerPass());
|
||||||
$container->addCompilerPass(new SwaggerConfigCompilerPass());
|
$container->addCompilerPass(new SwaggerConfigCompilerPass());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
93
Parser/DunglasJsonLdApiParser.php
Normal file
93
Parser/DunglasJsonLdApiParser.php
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<?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\Parser;
|
||||||
|
|
||||||
|
use Dunglas\JsonLdApiBundle\JsonLd\Resources;
|
||||||
|
use Dunglas\JsonLdApiBundle\Mapping\ClassMetadataFactory;
|
||||||
|
use Nelmio\ApiDocBundle\DataTypes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use DunglasJsonLdApi to extract input and output information.
|
||||||
|
*
|
||||||
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
|
*/
|
||||||
|
class DunglasJsonLdApiParser implements ParserInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Resources
|
||||||
|
*/
|
||||||
|
private $resources;
|
||||||
|
/**
|
||||||
|
* @var ClassMetadataFactory
|
||||||
|
*/
|
||||||
|
private $classMetadataFactory;
|
||||||
|
|
||||||
|
public function __construct(Resources $resources, ClassMetadataFactory $classMetadataFactory)
|
||||||
|
{
|
||||||
|
$this->resources = $resources;
|
||||||
|
$this->classMetadataFactory = $classMetadataFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function supports(array $item)
|
||||||
|
{
|
||||||
|
return null !== $this->resources->getResourceForEntity($item['class']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function parse(array $item)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var $resource \Dunglas\JsonLdApiBundle\JsonLd\Resource
|
||||||
|
*/
|
||||||
|
$resource = $this->resources->getResourceForEntity($item['class']);
|
||||||
|
$classMetadata = $this->classMetadataFactory->getMetadataFor(
|
||||||
|
$resource->getEntityClass(),
|
||||||
|
$resource->getNormalizationGroups(),
|
||||||
|
$resource->getDenormalizationGroups(),
|
||||||
|
$resource->getValidationGroups()
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
foreach ($classMetadata->getAttributes() as $attribute) {
|
||||||
|
$data[$attribute->getName()] = [
|
||||||
|
'required' => $attribute->isRequired(),
|
||||||
|
'description' => $attribute->getDescription(),
|
||||||
|
'readonly' => $attribute->isReadable() && !$attribute->isWritable(),
|
||||||
|
'class' => $resource->getEntityClass(),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (isset($attribute->getTypes()[0])) {
|
||||||
|
$type = $attribute->getTypes()[0];
|
||||||
|
if ($type->isCollection()) {
|
||||||
|
$dataType = DataTypes::COLLECTION;
|
||||||
|
} elseif ('object' === $type->getType()) {
|
||||||
|
if ('DateTime' === $type->getClass()) {
|
||||||
|
$dataType = DataTypes::DATETIME;
|
||||||
|
} else {
|
||||||
|
$dataType = DataTypes::STRING;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$dataType = $type->getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
$data[$attribute->getName()]['dataType'] = $dataType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
22
Resources/config/services.dunglas_json_ld_api.xml
Normal file
22
Resources/config/services.dunglas_json_ld_api.xml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" ?>
|
||||||
|
<container xmlns="http://symfony.com/schema/dic/services"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||||
|
|
||||||
|
<services>
|
||||||
|
<service id="nelmio_api_doc.annotations_provider.dunglas_json_ld_api_annotation_provider" class="Nelmio\ApiDocBundle\Extractor\AnnotationsProvider\DunglasJsonLdApiProvider">
|
||||||
|
<argument type="service" id="dunglas_json_ld_api.resources" />
|
||||||
|
<argument type="service" id="dunglas_json_ld_api.mapping.class_metadata_factory" />
|
||||||
|
|
||||||
|
<tag name="nelmio_api_doc.extractor.annotations_provider" />
|
||||||
|
</service>
|
||||||
|
|
||||||
|
<service id="nelmio_api_doc.parser.dunglas_json_ld_api_parser" class="Nelmio\ApiDocBundle\Parser\DunglasJsonLdApiParser">
|
||||||
|
<argument type="service" id="dunglas_json_ld_api.resources" />
|
||||||
|
<argument type="service" id="dunglas_json_ld_api.mapping.class_metadata_factory" />
|
||||||
|
|
||||||
|
<tag name="nelmio_api_doc.extractor.parser" />
|
||||||
|
</service>
|
||||||
|
</services>
|
||||||
|
|
||||||
|
</container>
|
@ -19,14 +19,20 @@
|
|||||||
</parameters>
|
</parameters>
|
||||||
|
|
||||||
<services>
|
<services>
|
||||||
<service id='nelmio_api_doc.doc_comment_extractor' class="%nelmio_api_doc.doc_comment_extractor.class%" />
|
<service id="nelmio_api_doc.doc_comment_extractor" class="%nelmio_api_doc.doc_comment_extractor.class%" />
|
||||||
|
|
||||||
|
<service id="nelmio_api_doc.controller_name_parser" class="Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser" public="false">
|
||||||
|
<argument type="service" id="kernel" />
|
||||||
|
</service>
|
||||||
|
|
||||||
<service id="nelmio_api_doc.extractor.api_doc_extractor" class="%nelmio_api_doc.extractor.api_doc_extractor.class%">
|
<service id="nelmio_api_doc.extractor.api_doc_extractor" class="%nelmio_api_doc.extractor.api_doc_extractor.class%">
|
||||||
<argument type="service" id="service_container"/>
|
<argument type="service" id="service_container" />
|
||||||
<argument type="service" id="router" />
|
<argument type="service" id="router" />
|
||||||
<argument type="service" id="annotation_reader" />
|
<argument type="service" id="annotation_reader" />
|
||||||
<argument type="service" id="nelmio_api_doc.doc_comment_extractor" />
|
<argument type="service" id="nelmio_api_doc.doc_comment_extractor" />
|
||||||
<argument type="collection"/>
|
<argument type="service" id="nelmio_api_doc.controller_name_parser" />
|
||||||
|
<argument type="collection" />
|
||||||
|
<argument type="collection" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="nelmio_api_doc.form.extension.description_form_type_extension" class="%nelmio_api_doc.form.extension.description_form_type_extension.class%">
|
<service id="nelmio_api_doc.form.extension.description_form_type_extension" class="%nelmio_api_doc.form.extension.description_form_type_extension.class%">
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
<?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\Tests\Extractor\AnnotationsProvider;
|
||||||
|
|
||||||
|
use Nelmio\ApiDocBundle\Tests\WebTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
|
*/
|
||||||
|
class DunglasJsonLdApiProviderTest extends WebTestCase
|
||||||
|
{
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
if (!class_exists('Dunglas\JsonLdApiBundle\DunglasJsonLdApiBundle')) {
|
||||||
|
$this->markTestSkipped(
|
||||||
|
'DunglasJsonLdApiBundle is not available.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetAnnotations()
|
||||||
|
{
|
||||||
|
$container = $this->getContainer();
|
||||||
|
$provider = $container->get('nelmio_api_doc.annotations_provider.dunglas_json_ld_api_annotation_provider');
|
||||||
|
|
||||||
|
$annotations = $provider->getAnnotations();
|
||||||
|
$this->assertCount(5, $annotations);
|
||||||
|
|
||||||
|
foreach ($annotations as $annotation) {
|
||||||
|
$this->assertInstanceOf('Nelmio\ApiDocBundle\Annotation\ApiDoc', $annotation);
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Routing\Route', $annotation->getRoute());
|
||||||
|
$this->assertTrue('' != $annotation->getDescription());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,8 +17,6 @@ use Nelmio\ApiDocBundle\Tests\WebTestCase;
|
|||||||
|
|
||||||
class ApiDocExtractorTest extends WebTestCase
|
class ApiDocExtractorTest extends WebTestCase
|
||||||
{
|
{
|
||||||
const ROUTES_QUANTITY = 33;
|
|
||||||
|
|
||||||
public function testAll()
|
public function testAll()
|
||||||
{
|
{
|
||||||
$container = $this->getContainer();
|
$container = $this->getContainer();
|
||||||
@ -27,14 +25,22 @@ class ApiDocExtractorTest extends WebTestCase
|
|||||||
$data = $extractor->all();
|
$data = $extractor->all();
|
||||||
restore_error_handler();
|
restore_error_handler();
|
||||||
|
|
||||||
|
if(class_exists('Dunglas\JsonLdApiBundle\DunglasJsonLdApiBundle')) {
|
||||||
|
$routesQuantity = 38;
|
||||||
|
$httpsKey = 25;
|
||||||
|
} else {
|
||||||
|
$routesQuantity = 33;
|
||||||
|
$httpsKey = 20;
|
||||||
|
}
|
||||||
|
|
||||||
$this->assertTrue(is_array($data));
|
$this->assertTrue(is_array($data));
|
||||||
$this->assertCount(self::ROUTES_QUANTITY, $data);
|
$this->assertCount($routesQuantity, $data);
|
||||||
|
|
||||||
$cacheFile = $container->getParameter('kernel.cache_dir') . '/api-doc.cache';
|
$cacheFile = $container->getParameter('kernel.cache_dir') . '/api-doc.cache';
|
||||||
$this->assertFileExists($cacheFile);
|
$this->assertFileExists($cacheFile);
|
||||||
$this->assertEquals(file_get_contents($cacheFile), serialize($data));
|
$this->assertEquals(file_get_contents($cacheFile), serialize($data));
|
||||||
|
|
||||||
foreach ($data as $d) {
|
foreach ($data as $key => $d) {
|
||||||
$this->assertTrue(is_array($d));
|
$this->assertTrue(is_array($d));
|
||||||
$this->assertArrayHasKey('annotation', $d);
|
$this->assertArrayHasKey('annotation', $d);
|
||||||
$this->assertArrayHasKey('resource', $d);
|
$this->assertArrayHasKey('resource', $d);
|
||||||
@ -76,9 +82,8 @@ class ApiDocExtractorTest extends WebTestCase
|
|||||||
$this->assertTrue($a4->isResource());
|
$this->assertTrue($a4->isResource());
|
||||||
$this->assertEquals('TestResource', $a4->getResource());
|
$this->assertEquals('TestResource', $a4->getResource());
|
||||||
|
|
||||||
$a3 = $data[20]['annotation'];
|
$a3 = $data[$httpsKey]['annotation'];
|
||||||
$this->assertTrue($a3->getHttps());
|
$this->assertTrue($a3->getHttps());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGet()
|
public function testGet()
|
||||||
|
28
Tests/Fixtures/Model/Popo.php
Normal file
28
Tests/Fixtures/Model/Popo.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?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\Tests\Fixtures\Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
|
*/
|
||||||
|
class Popo
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $foo;
|
||||||
|
}
|
@ -26,17 +26,20 @@ class AppKernel extends Kernel
|
|||||||
|
|
||||||
public function registerBundles()
|
public function registerBundles()
|
||||||
{
|
{
|
||||||
return array(
|
$bundles = array(
|
||||||
new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
|
new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
|
||||||
new \Symfony\Bundle\TwigBundle\TwigBundle(),
|
new \Symfony\Bundle\TwigBundle\TwigBundle(),
|
||||||
new \JMS\SerializerBundle\JMSSerializerBundle($this),
|
new \JMS\SerializerBundle\JMSSerializerBundle($this),
|
||||||
new \Nelmio\ApiDocBundle\NelmioApiDocBundle(),
|
new \Nelmio\ApiDocBundle\NelmioApiDocBundle(),
|
||||||
new \Nelmio\ApiDocBundle\Tests\Fixtures\NelmioApiDocTestBundle(),
|
new \Nelmio\ApiDocBundle\Tests\Fixtures\NelmioApiDocTestBundle(),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
public function init()
|
if (class_exists('Dunglas\JsonLdApiBundle\DunglasJsonLdApiBundle')) {
|
||||||
{
|
$bundles[] = new \Doctrine\Bundle\DoctrineBundle\DoctrineBundle();
|
||||||
|
$bundles[] = new \Dunglas\JsonLdApiBundle\DunglasJsonLdApiBundle();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $bundles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRootDir()
|
public function getRootDir()
|
||||||
@ -57,6 +60,10 @@ class AppKernel extends Kernel
|
|||||||
public function registerContainerConfiguration(LoaderInterface $loader)
|
public function registerContainerConfiguration(LoaderInterface $loader)
|
||||||
{
|
{
|
||||||
$loader->load(__DIR__.'/config/'.$this->environment.'.yml');
|
$loader->load(__DIR__.'/config/'.$this->environment.'.yml');
|
||||||
|
|
||||||
|
if (class_exists('Dunglas\JsonLdApiBundle\DunglasJsonLdApiBundle')) {
|
||||||
|
$loader->load(__DIR__.'/config/dunglas_json_ld_api.yml');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function serialize()
|
public function serialize()
|
||||||
|
22
Tests/Fixtures/app/config/dunglas_json_ld_api.yml
Normal file
22
Tests/Fixtures/app/config/dunglas_json_ld_api.yml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
doctrine:
|
||||||
|
dbal:
|
||||||
|
driver: "pdo_sqlite"
|
||||||
|
path: "%kernel.cache_dir%/db.sqlite"
|
||||||
|
charset: "UTF8"
|
||||||
|
|
||||||
|
orm:
|
||||||
|
auto_generate_proxy_classes: "%kernel.debug%"
|
||||||
|
auto_mapping: true
|
||||||
|
|
||||||
|
framework:
|
||||||
|
router: { resource: "%kernel.root_dir%/config/dunglas_json_ld_api_routing.yml" }
|
||||||
|
|
||||||
|
dunglas_json_ld_api:
|
||||||
|
title: API
|
||||||
|
description: Test API
|
||||||
|
|
||||||
|
services:
|
||||||
|
dunglas_json_ld_api.popo:
|
||||||
|
class: "Dunglas\JsonLdApiBundle\JsonLd\Resource"
|
||||||
|
arguments: [ "Nelmio\\ApiDocBundle\\Tests\\Fixtures\\Model\\Popo" ]
|
||||||
|
tags: [ { name: "json-ld.resource" } ]
|
@ -0,0 +1,9 @@
|
|||||||
|
main:
|
||||||
|
resource: "routing.yml"
|
||||||
|
|
||||||
|
dunglas_json_ld_api_doc:
|
||||||
|
resource: "@DunglasJsonLdApiBundle/Resources/config/routing.xml"
|
||||||
|
|
||||||
|
dunglas_json_ld_api:
|
||||||
|
resource: "."
|
||||||
|
type: "json-ld"
|
@ -239,3 +239,4 @@ test_route_25:
|
|||||||
defaults: { _controller: NelmioApiDocTestBundle:Test:withLinkAction }
|
defaults: { _controller: NelmioApiDocTestBundle:Test:withLinkAction }
|
||||||
requirements:
|
requirements:
|
||||||
_method: GET
|
_method: GET
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -45,54 +45,137 @@ class SwaggerFormatterTest extends WebTestCase
|
|||||||
|
|
||||||
$actual = $this->formatter->format($data, null);
|
$actual = $this->formatter->format($data, null);
|
||||||
|
|
||||||
$expected = array(
|
if (class_exists('Dunglas\JsonLdApiBundle\DunglasJsonLdApiBundle')) {
|
||||||
'swaggerVersion' => '1.2',
|
$expected = array (
|
||||||
'apiVersion' => '3.14',
|
'swaggerVersion' => '1.2',
|
||||||
'info' =>
|
'apis' =>
|
||||||
array(
|
array (
|
||||||
'title' => 'Nelmio Swagger',
|
0 =>
|
||||||
'description' => 'Testing Swagger integration.',
|
array (
|
||||||
'TermsOfServiceUrl' => 'https://github.com',
|
'path' => '/other-resources',
|
||||||
'contact' => 'user@domain.tld',
|
'description' => 'Operations on another resource.',
|
||||||
'license' => 'MIT',
|
),
|
||||||
'licenseUrl' => 'http://opensource.org/licenses/MIT',
|
1 =>
|
||||||
),
|
array (
|
||||||
'authorizations' =>
|
'path' => '/resources',
|
||||||
array(
|
'description' => 'Operations on resource.',
|
||||||
'apiKey' => array(
|
),
|
||||||
'type' => 'apiKey',
|
2 =>
|
||||||
'passAs' => 'header',
|
array (
|
||||||
'keyname' => 'access_token',
|
'path' => '/tests',
|
||||||
)
|
'description' => NULL,
|
||||||
),
|
),
|
||||||
'apis' =>
|
3 =>
|
||||||
array(
|
array (
|
||||||
array(
|
'path' => '/tests',
|
||||||
'path' => '/other-resources',
|
'description' => NULL,
|
||||||
'description' => 'Operations on another resource.',
|
),
|
||||||
|
4 =>
|
||||||
|
array (
|
||||||
|
'path' => '/tests2',
|
||||||
|
'description' => NULL,
|
||||||
|
),
|
||||||
|
5 =>
|
||||||
|
array (
|
||||||
|
'path' => '/TestResource',
|
||||||
|
'description' => NULL,
|
||||||
|
),
|
||||||
|
6 =>
|
||||||
|
array (
|
||||||
|
'path' => '/others',
|
||||||
|
'description' => '',
|
||||||
|
),
|
||||||
|
7 =>
|
||||||
|
array (
|
||||||
|
'path' => '/others',
|
||||||
|
'description' => '',
|
||||||
|
),
|
||||||
|
8 =>
|
||||||
|
array (
|
||||||
|
'path' => '/others',
|
||||||
|
'description' => '',
|
||||||
|
),
|
||||||
|
9 =>
|
||||||
|
array (
|
||||||
|
'path' => '/others',
|
||||||
|
'description' => '',
|
||||||
|
),
|
||||||
|
10 =>
|
||||||
|
array (
|
||||||
|
'path' => '/others',
|
||||||
|
'description' => '',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
array(
|
'apiVersion' => '3.14',
|
||||||
'path' => '/resources',
|
'info' =>
|
||||||
'description' => 'Operations on resource.',
|
array (
|
||||||
|
'title' => 'Nelmio Swagger',
|
||||||
|
'description' => 'Testing Swagger integration.',
|
||||||
|
'TermsOfServiceUrl' => 'https://github.com',
|
||||||
|
'contact' => 'user@domain.tld',
|
||||||
|
'license' => 'MIT',
|
||||||
|
'licenseUrl' => 'http://opensource.org/licenses/MIT',
|
||||||
),
|
),
|
||||||
array(
|
'authorizations' =>
|
||||||
'path' => '/tests',
|
array (
|
||||||
'description' => null,
|
'apiKey' =>
|
||||||
|
array (
|
||||||
|
'type' => 'apiKey',
|
||||||
|
'passAs' => 'header',
|
||||||
|
'keyname' => 'access_token',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$expected = array(
|
||||||
|
'swaggerVersion' => '1.2',
|
||||||
|
'apiVersion' => '3.14',
|
||||||
|
'info' =>
|
||||||
array(
|
array(
|
||||||
'path' => '/tests',
|
'title' => 'Nelmio Swagger',
|
||||||
'description' => null,
|
'description' => 'Testing Swagger integration.',
|
||||||
|
'TermsOfServiceUrl' => 'https://github.com',
|
||||||
|
'contact' => 'user@domain.tld',
|
||||||
|
'license' => 'MIT',
|
||||||
|
'licenseUrl' => 'http://opensource.org/licenses/MIT',
|
||||||
),
|
),
|
||||||
|
'authorizations' =>
|
||||||
array(
|
array(
|
||||||
'path' => '/tests2',
|
'apiKey' => array(
|
||||||
'description' => null,
|
'type' => 'apiKey',
|
||||||
|
'passAs' => 'header',
|
||||||
|
'keyname' => 'access_token',
|
||||||
|
)
|
||||||
),
|
),
|
||||||
|
'apis' =>
|
||||||
array(
|
array(
|
||||||
'path' => '/TestResource',
|
array(
|
||||||
'description' => null,
|
'path' => '/other-resources',
|
||||||
|
'description' => 'Operations on another resource.',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'path' => '/resources',
|
||||||
|
'description' => 'Operations on resource.',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'path' => '/tests',
|
||||||
|
'description' => null,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'path' => '/tests',
|
||||||
|
'description' => null,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'path' => '/tests2',
|
||||||
|
'description' => null,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'path' => '/TestResource',
|
||||||
|
'description' => null,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
}
|
||||||
|
|
||||||
$this->assertEquals($expected, $actual);
|
$this->assertEquals($expected, $actual);
|
||||||
|
|
||||||
|
51
Tests/Parser/DunglasJsonLdApiParserTest.php
Normal file
51
Tests/Parser/DunglasJsonLdApiParserTest.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?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 NelmioApiDocBundle\Tests\Parser;
|
||||||
|
|
||||||
|
use Nelmio\ApiDocBundle\Tests\WebTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
|
*/
|
||||||
|
class DunglasJsonLdApiParserTest extends WebTestCase
|
||||||
|
{
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
if (!class_exists('Dunglas\JsonLdApiBundle\DunglasJsonLdApiBundle')) {
|
||||||
|
$this->markTestSkipped(
|
||||||
|
'DunglasJsonLdApiBundle is not available.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testParser()
|
||||||
|
{
|
||||||
|
$container = $this->getContainer();
|
||||||
|
$parser = $container->get('nelmio_api_doc.parser.dunglas_json_ld_api_parser');
|
||||||
|
|
||||||
|
$item = array('class' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\Popo');
|
||||||
|
|
||||||
|
$expected = array (
|
||||||
|
'foo' =>
|
||||||
|
array (
|
||||||
|
'required' => false,
|
||||||
|
'description' => '',
|
||||||
|
'readonly' => false,
|
||||||
|
'class' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\Popo',
|
||||||
|
'dataType' => 'string',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertTrue($parser->supports($item));
|
||||||
|
$this->assertEquals($expected, $parser->parse($item));
|
||||||
|
}
|
||||||
|
}
|
@ -25,7 +25,11 @@ class FormTypeParserTest extends \PHPUnit_Framework_TestCase
|
|||||||
$formFactoryBuilder->addTypeExtension(new DescriptionFormTypeExtension());
|
$formFactoryBuilder->addTypeExtension(new DescriptionFormTypeExtension());
|
||||||
$formFactory = $formFactoryBuilder->getFormFactory();
|
$formFactory = $formFactoryBuilder->getFormFactory();
|
||||||
$formTypeParser = new FormTypeParser($formFactory);
|
$formTypeParser = new FormTypeParser($formFactory);
|
||||||
|
|
||||||
|
set_error_handler(array('Nelmio\ApiDocBundle\Tests\WebTestCase', 'handleDeprecation'));
|
||||||
|
trigger_error('test', E_USER_DEPRECATED);
|
||||||
$output = $formTypeParser->parse($typeName);
|
$output = $formTypeParser->parse($typeName);
|
||||||
|
restore_error_handler();
|
||||||
|
|
||||||
$this->assertEquals($expected, $output);
|
$this->assertEquals($expected, $output);
|
||||||
}
|
}
|
||||||
|
@ -30,14 +30,17 @@
|
|||||||
"symfony/validator": "~2.1",
|
"symfony/validator": "~2.1",
|
||||||
"symfony/yaml": "~2.1",
|
"symfony/yaml": "~2.1",
|
||||||
"symfony/form": "~2.1",
|
"symfony/form": "~2.1",
|
||||||
|
"symfony/serializer": "~2.7@dev",
|
||||||
"friendsofsymfony/rest-bundle": "~1.0",
|
"friendsofsymfony/rest-bundle": "~1.0",
|
||||||
"jms/serializer-bundle": ">=0.11",
|
"jms/serializer-bundle": ">=0.11",
|
||||||
|
"dunglas/json-ld-api-bundle": "dev-master",
|
||||||
"sensio/framework-extra-bundle": "~3.0"
|
"sensio/framework-extra-bundle": "~3.0"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"symfony/form": "For using form definitions as input.",
|
"symfony/form": "For using form definitions as input.",
|
||||||
"symfony/validator": "For making use of validator information in the doc.",
|
"symfony/validator": "For making use of validator information in the doc.",
|
||||||
"friendsofsymfony/rest-bundle": "For making use of REST information in the doc.",
|
"friendsofsymfony/rest-bundle": "For making use of REST information in the doc.",
|
||||||
|
"dunglas/json-ld-api-bundle": "For making use of resources definitions of DunglasJsonLdApiBundle.",
|
||||||
"jms/serializer": "For making use of serializer information in the doc."
|
"jms/serializer": "For making use of serializer information in the doc."
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user