mirror of
https://github.com/retailcrm/NelmioApiDocBundle.git
synced 2025-02-02 15:51:48 +03:00
added a ParserInterface, refactored how Parsers are registered in the ApiDocExtractor, changed formType to inputClass in ApiDocExtractor
This commit is contained in:
parent
a18bbb0013
commit
06e3a2256b
@ -26,7 +26,7 @@ class ApiDoc
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $formType = null;
|
||||
private $inputClass = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
@ -70,8 +70,8 @@ class ApiDoc
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
if (isset($data['formType'])) {
|
||||
$this->formType = $data['formType'];
|
||||
if (isset($data['inputClass'])) {
|
||||
$this->inputClass = $data['inputClass'];
|
||||
} elseif (isset($data['filters'])) {
|
||||
foreach ($data['filters'] as $filter) {
|
||||
if (!isset($filter['name'])) {
|
||||
@ -121,9 +121,9 @@ class ApiDoc
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getFormType()
|
||||
public function getInputClass()
|
||||
{
|
||||
return $this->formType;
|
||||
return $this->inputClass;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -228,6 +228,10 @@ class ApiDoc
|
||||
$data['requirements'] = $requirements;
|
||||
}
|
||||
|
||||
if ($inputClass = $this->inputClass) {
|
||||
$data['inputClass'] = $inputClass;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
23
DependencyInjection/RegisterExtractorClassParsersPass.php
Normal file
23
DependencyInjection/RegisterExtractorClassParsersPass.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Nelmio\ApiDocBundle\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
class RegisterExtractorClassParsersPass implements CompilerPassInterface
|
||||
{
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (false === $container->hasDefinition('nelmio_api_doc.extractor.api_doc_extractor')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$definition = $container->getDefinition('nelmio_api_doc.extractor.api_doc_extractor');
|
||||
|
||||
foreach ($container->findTaggedServiceIds('nelmio_api_doc.extractor.class_parser') as $id => $attributes) {
|
||||
$definition->addMethodCall('registerParser', array(new Reference($id)));
|
||||
}
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@ namespace Nelmio\ApiDocBundle\Extractor;
|
||||
|
||||
use Doctrine\Common\Annotations\Reader;
|
||||
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
|
||||
use Nelmio\ApiDocBundle\Parser\FormTypeParser;
|
||||
use Nelmio\ApiDocBundle\Parser\ParserInterface;
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
@ -41,16 +41,15 @@ class ApiDocExtractor
|
||||
private $reader;
|
||||
|
||||
/**
|
||||
* @var \Nelmio\ApiDocBundle\Parser\FormTypeParser
|
||||
* @var array \Nelmio\ApiDocBundle\Parser\ParserInterface
|
||||
*/
|
||||
private $parser;
|
||||
private $parsers = array();
|
||||
|
||||
public function __construct(ContainerInterface $container, RouterInterface $router, Reader $reader, FormTypeParser $parser)
|
||||
public function __construct(ContainerInterface $container, RouterInterface $router, Reader $reader)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->router = $router;
|
||||
$this->reader = $reader;
|
||||
$this->parser = $parser;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -179,6 +178,17 @@ class ApiDocExtractor
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a class parser to use for parsing input class metadata
|
||||
*
|
||||
* @param ParserInterface $parser
|
||||
* @return void
|
||||
*/
|
||||
public function registerParser(ParserInterface $parser)
|
||||
{
|
||||
$this->parsers[] = $parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new ApiDoc instance with more data.
|
||||
*
|
||||
@ -215,9 +225,15 @@ class ApiDocExtractor
|
||||
// doc
|
||||
$annotation->setDocumentation($this->getDocCommentText($method));
|
||||
|
||||
// formType
|
||||
if (null !== $formType = $annotation->getFormType()) {
|
||||
$parameters = $this->parser->parse($formType);
|
||||
// inputClass
|
||||
if (null !== $inputClass = $annotation->getInputClass()) {
|
||||
$parameters = array();
|
||||
|
||||
foreach ($this->parsers as $parser) {
|
||||
if ($parser->supportsClass($inputClass)) {
|
||||
$parameters = $parser->parse($inputClass);
|
||||
}
|
||||
}
|
||||
|
||||
if ('PUT' === $method) {
|
||||
// All parameters are optional with PUT (update)
|
||||
|
@ -3,7 +3,15 @@
|
||||
namespace Nelmio\ApiDocBundle;
|
||||
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Nelmio\ApiDocBundle\DependencyInjection\RegisterExtractorClassParsersPass;
|
||||
|
||||
class NelmioApiDocBundle extends Bundle
|
||||
{
|
||||
public function build(ContainerBuilder $container)
|
||||
{
|
||||
parent::build($container);
|
||||
|
||||
$container->addCompilerPass(new RegisterExtractorClassParsersPass());
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ namespace Nelmio\ApiDocBundle\Parser;
|
||||
use Symfony\Component\Form\FormBuilder;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
|
||||
class FormTypeParser
|
||||
class FormTypeParser implements ParserInterface
|
||||
{
|
||||
/**
|
||||
* @var \Symfony\Component\Form\FormFactoryInterface
|
||||
@ -41,13 +41,20 @@ class FormTypeParser
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of data where each data is an array with the following keys:
|
||||
* - dataType
|
||||
* - required
|
||||
* - description
|
||||
*
|
||||
* @param string|\Symfony\Component\Form\FormTypeInterface $type
|
||||
* @return array
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsClass($class)
|
||||
{
|
||||
if (is_string($class) && class_exists($class)) {
|
||||
$ref = new \ReflectionClass($class);
|
||||
return ($ref->implementsInterface('Nelmio\ApiDocBundle\Parser\ParserInterface'));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function parse($type)
|
||||
{
|
||||
@ -71,6 +78,7 @@ class FormTypeParser
|
||||
'dataType' => $bestType,
|
||||
'required' => $config->getRequired(),
|
||||
'description' => $config->getAttribute('description'),
|
||||
'readonly' => false,
|
||||
);
|
||||
}
|
||||
|
||||
|
40
Parser/ParserInterface.php
Normal file
40
Parser/ParserInterface.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\Parser;
|
||||
|
||||
/**
|
||||
* This is the interface parsers must implement in order to be registered in the ApiDocExtractor.
|
||||
*/
|
||||
interface ParserInterface
|
||||
{
|
||||
/**
|
||||
* Return true/false whether this class supports parsing the given class.
|
||||
*
|
||||
* @param string $item The string name of the class to parse.
|
||||
* @return boolean
|
||||
*/
|
||||
function supportsClass($className);
|
||||
|
||||
/**
|
||||
* Returns an array of class property metadata where each item is a key (the property name) and
|
||||
* an array of data with the following keys:
|
||||
* - dataType string
|
||||
* - required boolean
|
||||
* - description string
|
||||
* - readonly boolean
|
||||
*
|
||||
* @param string $class The string name of the class to parse.
|
||||
* @return array
|
||||
*/
|
||||
function parse($className);
|
||||
|
||||
}
|
@ -14,6 +14,7 @@
|
||||
<services>
|
||||
<service id="nelmio_api_doc.parser.form_type_parser" class="%nelmio_api_doc.parser.form_type_parser.class%">
|
||||
<argument type="service" id="form.factory" />
|
||||
<tag name="nelmio_api_doc.extractor.class_parser" />
|
||||
</service>
|
||||
<service id="nelmio_api_doc.formatter.abstract_formatter" class="%nelmio_api_doc.formatter.abstract_formatter.class%" />
|
||||
<service id="nelmio_api_doc.formatter.markdown_formatter" class="%nelmio_api_doc.formatter.markdown_formatter.class%"
|
||||
|
@ -14,7 +14,6 @@
|
||||
<argument type="service" id="service_container"/>
|
||||
<argument type="service" id="router" />
|
||||
<argument type="service" id="annotation_reader" />
|
||||
<argument type="service" id="nelmio_api_doc.parser.form_type_parser" />
|
||||
</service>
|
||||
|
||||
<service id="nelmio_api_doc.form.extension.description_form_type_extension" class="%nelmio_api_doc.form.extension.description_form_type_extension.class%">
|
||||
|
@ -27,7 +27,7 @@ class ApiDocTest extends TestCase
|
||||
$this->assertFalse(isset($array['filters']));
|
||||
$this->assertFalse($annot->isResource());
|
||||
$this->assertFalse(isset($array['description']));
|
||||
$this->assertNull($annot->getFormType());
|
||||
$this->assertNull($annot->getInputClass());
|
||||
}
|
||||
|
||||
public function testConstructWithInvalidData()
|
||||
@ -44,7 +44,7 @@ class ApiDocTest extends TestCase
|
||||
$this->assertFalse(isset($array['filters']));
|
||||
$this->assertFalse($annot->isResource());
|
||||
$this->assertFalse(isset($array['description']));
|
||||
$this->assertNull($annot->getFormType());
|
||||
$this->assertNull($annot->getInputClass());
|
||||
}
|
||||
|
||||
public function testConstruct()
|
||||
@ -60,14 +60,14 @@ class ApiDocTest extends TestCase
|
||||
$this->assertFalse(isset($array['filters']));
|
||||
$this->assertFalse($annot->isResource());
|
||||
$this->assertEquals($data['description'], $array['description']);
|
||||
$this->assertNull($annot->getFormType());
|
||||
$this->assertNull($annot->getInputClass());
|
||||
}
|
||||
|
||||
public function testConstructDefinesAFormType()
|
||||
{
|
||||
$data = array(
|
||||
'description' => 'Heya',
|
||||
'formType' => 'My\Form\Type',
|
||||
'inputClass' => 'My\Form\Type',
|
||||
);
|
||||
|
||||
$annot = new ApiDoc($data);
|
||||
@ -77,7 +77,7 @@ class ApiDocTest extends TestCase
|
||||
$this->assertFalse(isset($array['filters']));
|
||||
$this->assertFalse($annot->isResource());
|
||||
$this->assertEquals($data['description'], $array['description']);
|
||||
$this->assertEquals($data['formType'], $annot->getFormType());
|
||||
$this->assertEquals($data['inputClass'], $annot->getInputClass());
|
||||
}
|
||||
|
||||
public function testConstructMethodIsResource()
|
||||
@ -85,7 +85,7 @@ class ApiDocTest extends TestCase
|
||||
$data = array(
|
||||
'resource' => true,
|
||||
'description' => 'Heya',
|
||||
'formType' => 'My\Form\Type',
|
||||
'inputClass' => 'My\Form\Type',
|
||||
);
|
||||
|
||||
$annot = new ApiDoc($data);
|
||||
@ -95,7 +95,7 @@ class ApiDocTest extends TestCase
|
||||
$this->assertFalse(isset($array['filters']));
|
||||
$this->assertTrue($annot->isResource());
|
||||
$this->assertEquals($data['description'], $array['description']);
|
||||
$this->assertEquals($data['formType'], $annot->getFormType());
|
||||
$this->assertEquals($data['inputClass'], $annot->getInputClass());
|
||||
}
|
||||
|
||||
public function testConstructMethodResourceIsFalse()
|
||||
@ -103,7 +103,7 @@ class ApiDocTest extends TestCase
|
||||
$data = array(
|
||||
'resource' => false,
|
||||
'description' => 'Heya',
|
||||
'formType' => 'My\Form\Type',
|
||||
'inputClass' => 'My\Form\Type',
|
||||
);
|
||||
|
||||
$annot = new ApiDoc($data);
|
||||
@ -113,7 +113,7 @@ class ApiDocTest extends TestCase
|
||||
$this->assertFalse(isset($array['filters']));
|
||||
$this->assertFalse($annot->isResource());
|
||||
$this->assertEquals($data['description'], $array['description']);
|
||||
$this->assertEquals($data['formType'], $annot->getFormType());
|
||||
$this->assertEquals($data['inputClass'], $annot->getInputClass());
|
||||
}
|
||||
|
||||
public function testConstructMethodHasFilters()
|
||||
@ -135,7 +135,7 @@ class ApiDocTest extends TestCase
|
||||
$this->assertEquals(array('a-filter' => array()), $array['filters']);
|
||||
$this->assertTrue($annot->isResource());
|
||||
$this->assertEquals($data['description'], $array['description']);
|
||||
$this->assertNull($annot->getFormType());
|
||||
$this->assertNull($annot->getInputClass());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -158,7 +158,7 @@ class ApiDocTest extends TestCase
|
||||
$data = array(
|
||||
'resource' => true,
|
||||
'description' => 'Heya',
|
||||
'formType' => 'My\Form\Type',
|
||||
'inputClass' => 'My\Form\Type',
|
||||
'filters' => array(
|
||||
array('name' => 'a-filter'),
|
||||
),
|
||||
@ -171,6 +171,6 @@ class ApiDocTest extends TestCase
|
||||
$this->assertFalse(isset($array['filters']));
|
||||
$this->assertTrue($annot->isResource());
|
||||
$this->assertEquals($data['description'], $array['description']);
|
||||
$this->assertEquals($data['formType'], $annot->getFormType());
|
||||
$this->assertEquals($data['inputClass'], $annot->getInputClass());
|
||||
}
|
||||
}
|
||||
|
@ -39,28 +39,28 @@ class ApiDocExtractorTest extends WebTestCase
|
||||
$this->assertTrue($a1->isResource());
|
||||
$this->assertEquals('index action', $a1->getDescription());
|
||||
$this->assertTrue(is_array($array1['filters']));
|
||||
$this->assertNull($a1->getFormType());
|
||||
$this->assertNull($a1->getInputClass());
|
||||
|
||||
$a1 = $data[1]['annotation'];
|
||||
$array1 = $a1->toArray();
|
||||
$this->assertTrue($a1->isResource());
|
||||
$this->assertEquals('index action', $a1->getDescription());
|
||||
$this->assertTrue(is_array($array1['filters']));
|
||||
$this->assertNull($a1->getFormType());
|
||||
$this->assertNull($a1->getInputClass());
|
||||
|
||||
$a2 = $data[2]['annotation'];
|
||||
$array2 = $a2->toArray();
|
||||
$this->assertFalse($a2->isResource());
|
||||
$this->assertEquals('create test', $a2->getDescription());
|
||||
$this->assertFalse(isset($array2['filters']));
|
||||
$this->assertEquals('Nelmio\ApiDocBundle\Tests\Fixtures\Form\TestType', $a2->getFormType());
|
||||
$this->assertEquals('Nelmio\ApiDocBundle\Tests\Fixtures\Form\TestType', $a2->getInputClass());
|
||||
|
||||
$a2 = $data[3]['annotation'];
|
||||
$array2 = $a2->toArray();
|
||||
$this->assertFalse($a2->isResource());
|
||||
$this->assertEquals('create test', $a2->getDescription());
|
||||
$this->assertFalse(isset($array2['filters']));
|
||||
$this->assertEquals('Nelmio\ApiDocBundle\Tests\Fixtures\Form\TestType', $a2->getFormType());
|
||||
$this->assertEquals('Nelmio\ApiDocBundle\Tests\Fixtures\Form\TestType', $a2->getInputClass());
|
||||
}
|
||||
|
||||
public function testGet()
|
||||
@ -76,7 +76,7 @@ class ApiDocExtractorTest extends WebTestCase
|
||||
|
||||
$array = $annotation->toArray();
|
||||
$this->assertTrue(is_array($array['filters']));
|
||||
$this->assertNull($annotation->getFormType());
|
||||
$this->assertNull($annotation->getInputClass());
|
||||
|
||||
$annotation2 = $extractor->get('nemlio.test.controller:indexAction', 'test_service_route_1');
|
||||
$annotation2->getRoute()
|
||||
|
@ -35,7 +35,7 @@ class TestController
|
||||
/**
|
||||
* @ApiDoc(
|
||||
* description="create test",
|
||||
* formType="Nelmio\ApiDocBundle\Tests\Fixtures\Form\TestType"
|
||||
* inputClass="Nelmio\ApiDocBundle\Tests\Fixtures\Form\TestType"
|
||||
* )
|
||||
*/
|
||||
public function postTestAction()
|
||||
@ -76,7 +76,7 @@ class TestController
|
||||
/**
|
||||
* @ApiDoc(
|
||||
* description="create another test",
|
||||
* formType="dependency_type"
|
||||
* inputClass="dependency_type"
|
||||
* )
|
||||
*/
|
||||
public function anotherPostAction()
|
||||
|
Loading…
x
Reference in New Issue
Block a user