Transform in a bundle

This commit is contained in:
Ener-Getick 2016-07-12 00:33:55 +02:00
parent 827d5ea152
commit 42a2aefb41
No known key found for this signature in database
GPG Key ID: 9E5D2DB67BF054DD
17 changed files with 357 additions and 25 deletions

9
.gitignore vendored
View File

@ -1,3 +1,6 @@
/vendor/*
composer.lock
.php_cs.cache
/vendor/
/composer.lock
/.php_cs.cache
/phpunit.xml
/Tests/Functional/cache
/Tests/Functional/logs

View File

@ -1,9 +1,9 @@
language: php
php:
- 5.5
- 5.6
- 7.0
- 7.1
- hhvm
sudo: false
@ -26,4 +26,4 @@ matrix:
before_install:
- composer self-update
install: composer update $COMPOSER_FLAGS --prefer-dist
install: composer update $COMPOSER_FLAGS

View File

@ -0,0 +1,28 @@
<?php
/*
* This file is part of the ApiDocBundle package.
*
* (c) EXSyst
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace EXSyst\Bundle\ApiDocBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
class AddExtractorsPass implements CompilerPassInterface
{
use PriorityTaggedServiceTrait;
public function process(ContainerBuilder $container)
{
$extractors = $this->findAndSortTaggedServices('exsyst_api_doc.extractor', $container);
$container->getDefinition('exsyst_api_doc.generator')->replaceArgument(0, $extractors);
}
}

View File

@ -0,0 +1,28 @@
<?php
/*
* This file is part of the ApiDocBundle package.
*
* (c) EXSyst
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace EXSyst\Bundle\ApiDocBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
class AddRoutingExtractorsPass implements CompilerPassInterface
{
use PriorityTaggedServiceTrait;
public function process(ContainerBuilder $container)
{
$extractors = $this->findAndSortTaggedServices('exsyst_api_doc.routing_extractor', $container);
$container->getDefinition('exsyst_api_doc.extractors.routing')->replaceArgument(2, $extractors);
}
}

View File

@ -0,0 +1,26 @@
<?php
/*
* This file is part of the ApiDocBundle package.
*
* (c) EXSyst
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace EXSyst\Bundle\ApiDocBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('exsyst_api_doc');
return $treeBuilder;
}
}

View File

@ -0,0 +1,39 @@
<?php
/*
* This file is part of the ApiDocBundle package.
*
* (c) EXSyst
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace EXSyst\Bundle\ApiDocBundle\DependencyInjection;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class EXSystApiDocExtension extends Extension
{
/**
* {@inheritdoc}
*/
public function getAlias()
{
return 'exsyst_api_doc';
}
/**
* {@inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$config = $this->processConfiguration(new Configuration(), $configs);
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.xml');
}
}

43
EXSystApiDocBundle.php Normal file
View File

@ -0,0 +1,43 @@
<?php
/*
* This file is part of the ApiDocBundle package.
*
* (c) EXSyst
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace EXSyst\Bundle\ApiDocBundle;
use EXSyst\Bundle\ApiDocBundle\DependencyInjection\Compiler\AddExtractorsPass;
use EXSyst\Bundle\ApiDocBundle\DependencyInjection\Compiler\AddRoutingExtractorsPass;
use EXSyst\Bundle\ApiDocBundle\DependencyInjection\EXSystApiDocExtension;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class EXSystApiDocBundle extends Bundle
{
/**
* {@inheritdoc}
*/
public function build(ContainerBuilder $container)
{
$container->addCompilerPass(new AddExtractorsPass());
$container->addCompilerPass(new AddRoutingExtractorsPass());
}
/**
* {@inheritdoc}
*/
public function getContainerExtension()
{
if (null === $this->extension) {
$this->extension = new EXSystApiDocExtension();
}
if ($this->extension) {
return $this->extension;
}
}
}

View File

@ -37,12 +37,13 @@ class NelmioAnnotationExtractor implements RouteExtractorInterface
}
$annotation = $this->annotationReader->getMethodAnnotation($reflectionMethod, ApiDoc::class);
// some fields aren't available otherwise
$annotationArray = $annotation->toArray();
if (null === $annotation) {
return;
}
// some fields aren't available otherwise
$annotationArray = $annotation->toArray();
foreach ($this->getOperations($api, $route) as $operation) {
if ($annotation->getDescription()) {
$operation->setDescription($annotation->getDescription());

View File

@ -27,7 +27,7 @@ trait RouteExtractorTrait
*/
private function getOperations(Swagger $api, Route $route)
{
$path = $swagger->getPaths()->get($route->getPath());
$path = $api->getPaths()->get($route->getPath());
$methods = $route->getMethods() ?: Swagger::$METHODS;
foreach ($methods as $method) {
$method = strtolower($method);

View File

@ -26,7 +26,7 @@ class RouteMetadataExtractor implements RouteExtractorInterface
foreach ($route->getRequirements() as $parameterName => $requirement) {
$parameter = $operation->getParameters()->get($parameterName, 'path');
$parameter->setRequired(true);
$parameter->setType(swagger\Swagger::T_STRING);
$parameter->setType(Swagger::T_STRING);
$parameter->setFormat($requirement);
}
}

View File

@ -18,7 +18,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouterInterface;
class RouteExtractor implements ExtractorInterface
class RoutingExtractor implements ExtractorInterface
{
private $routeExtractors;
@ -37,13 +37,12 @@ class RouteExtractor implements ExtractorInterface
/**
* @return Swagger
*/
public function extract()
public function extractIn(Swagger $swagger)
{
if (0 === count($this->routeExtractors)) {
return;
}
$swagger = new Swagger();
foreach ($this->getRoutes() as $route) {
// if able to resolve the controller
if ($method = $this->getReflectionMethod($route->getDefault('_controller'))) {
@ -53,8 +52,6 @@ class RouteExtractor implements ExtractorInterface
}
}
}
return $swagger;
}
/**

View File

@ -0,0 +1,32 @@
<?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="exsyst_api_doc.generator" class="EXSyst\Bundle\ApiDocBundle\ApiDocGenerator">
<argument type="collection" />
</service>
<!-- Extractors -->
<service id="exsyst_api_doc.extractors.routing" class="EXSyst\Bundle\ApiDocBundle\Extractor\RoutingExtractor" public="false">
<argument type="service" id="router" />
<argument type="service" id="controller_name_converter" />
<argument type="collection" />
<tag name="exsyst_api_doc.extractor" priority="-100" />
</service>
<!-- Routing Extractors -->
<service id="exsyst_api_doc.routing_extractors.route_metadata" class="EXSyst\Bundle\ApiDocBundle\Extractor\Routing\RouteMetadataExtractor" public="false">
<tag name="exsyst_api_doc.routing_extractor" />
</service>
<service id="exsyst_api_doc.routing_extractors.nelmio_annotation" class="EXSyst\Bundle\ApiDocBundle\Extractor\Routing\NelmioAnnotationExtractor" public="false">
<argument type="service" id="annotation_reader" />
<tag name="exsyst_api_doc.routing_extractor" />
</service>
</services>
</container>

View File

@ -0,0 +1,24 @@
<?php
/*
* This file is part of the ApiDocBundle package.
*
* (c) EXSyst
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace EXSyst\Bundle\ApiDocBundle\Tests\Functional\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class ApiController
{
/**
* @Route("/test/{user}", methods={"GET"}, schemes={"https"}, requirements={"user"="/foo/"})
*/
public function userAction()
{
}
}

View File

@ -0,0 +1,46 @@
<?php
/*
* This file is part of the ApiDocBundle package.
*
* (c) EXSyst
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace EXSyst\Bundle\ApiDocBundle\Tests\Functional;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class FunctionalTest extends WebTestCase
{
public function testUserActionApiController()
{
$api = $this->getSwaggerDefinition();
$paths = $api->getPaths();
$this->assertTrue($paths->has('/test/{user}'));
$action = $paths->get('/test/{user}');
$this->assertTrue($action->hasOperation('get'));
$operation = $action->getOperation('get');
$this->assertEquals(['https'], $operation->getSchemes()->toArray());
$parameters = $operation->getParameters();
$this->assertTrue($parameters->search('user', 'path'));
$parameter = $parameters->find('user', 'path');
$this->assertTrue($parameter->getRequired());
$this->assertEquals('string', $parameter->getType());
$this->assertEquals('/foo/', $parameter->getFormat());
}
private function getSwaggerDefinition()
{
static::createClient();
return static::$kernel->getContainer()->get('exsyst_api_doc.generator')->extract();
}
}

View File

@ -0,0 +1,54 @@
<?php
/*
* This file is part of the ApiDocBundle package.
*
* (c) EXSyst
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use EXSyst\Bundle\ApiDocBundle\EXSystApiDocBundle;
use Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Routing\RouteCollectionBuilder;
class TestKernel extends Kernel
{
use MicroKernelTrait;
/**
* {@inheritdoc}
*/
public function registerBundles()
{
return [
new FrameworkBundle(),
new SensioFrameworkExtraBundle(),
new EXSystApiDocBundle(),
];
}
/**
* {@inheritdoc}
*/
protected function configureRoutes(RouteCollectionBuilder $routes)
{
$routes->import(__DIR__.'/Controller/', '/', 'annotation');
}
/**
* {@inheritdoc}
*/
protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader)
{
$c->loadFromExtension('framework', [
'secret' => 'MySecretKey',
'test' => null,
]);
}
}

View File

@ -9,13 +9,15 @@
}
],
"require": {
"php": ">=5.5",
"symfony/framework-bundle": "^2.7|^3.0",
"php": ">=5.6",
"symfony/framework-bundle": "^3.2@dev",
"gossi/swagger": "^0.2"
},
"require-dev": {
"nelmio/api-doc-bundle": "^2.0",
"symfony/phpunit-bridge": "^2.7|^3.0"
"symfony/browser-kit": "~2.8|~3.0",
"symfony/phpunit-bridge": "^3.2@dev",
"sensio/framework-extra-bundle": "~3.0",
"nelmio/api-doc-bundle": "^2.0"
},
"suggest": {
"nelmio/api-doc-bundle": "For using the ApiDoc annotation."
@ -29,5 +31,7 @@
"branch-alias": {
"dev-master": "0.1.x-dev"
}
}
},
"prefer-stable": true,
"minimum-stability": "dev"
}

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- http://phpunit.de/manual/4.1/en/appendixes.configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.6/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php"
@ -9,17 +10,23 @@
<php>
<ini name="error_reporting" value="-1" />
</php>
<testsuites>
<testsuite name="EXSyst Api Doc Bundle Test Suite">
<directory>./Tests/</directory>
<testsuite name="Project Test Suite">
<directory>Tests</directory>
</testsuite>
</testsuites>
<php>
<server name="KERNEL_DIR" value="Tests/Functional/" />
</php>
<filter>
<whitelist>
<directory>./</directory>
<directory>.</directory>
<exclude>
<directory>./vendor</directory>
<directory>./Tests/</directory>
<directory>Tests</directory>
<directory>vendor</directory>
</exclude>
</whitelist>
</filter>