fix memory limit issue wirh entity list

Allow to disable mapping of entity list to avoid memory limit error on long list
This commit is contained in:
Stéphane Reuille 2014-11-10 16:38:40 +01:00
parent a8f047c78a
commit dc20b249e7
10 changed files with 137 additions and 4 deletions

View File

@ -132,6 +132,7 @@ class Configuration implements ConfigurationInterface
}) })
->end() ->end()
->end() ->end()
->booleanNode('entity_to_choice')->defaultValue(true)->end()
->end() ->end()
->end() ->end()
->arrayNode('swagger') ->arrayNode('swagger')

View File

@ -41,6 +41,7 @@ class NelmioApiDocExtension extends Extension
$container->setParameter('nelmio_api_doc.sandbox.request_format.method', $config['sandbox']['request_format']['method']); $container->setParameter('nelmio_api_doc.sandbox.request_format.method', $config['sandbox']['request_format']['method']);
$container->setParameter('nelmio_api_doc.sandbox.request_format.default_format', $config['sandbox']['request_format']['default_format']); $container->setParameter('nelmio_api_doc.sandbox.request_format.default_format', $config['sandbox']['request_format']['default_format']);
$container->setParameter('nelmio_api_doc.sandbox.request_format.formats', $config['sandbox']['request_format']['formats']); $container->setParameter('nelmio_api_doc.sandbox.request_format.formats', $config['sandbox']['request_format']['formats']);
$container->setParameter('nelmio_api_doc.sandbox.entity_to_choice', $config['sandbox']['entity_to_choice']);
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('formatters.xml'); $loader->load('formatters.xml');

View File

@ -35,6 +35,11 @@ class FormTypeParser implements ParserInterface
*/ */
protected $formRegistry; protected $formRegistry;
/**
* @var boolean
*/
protected $entityToChoice;
/** /**
* @var array * @var array
*/ */
@ -52,9 +57,10 @@ class FormTypeParser implements ParserInterface
'file' => DataTypes::FILE, 'file' => DataTypes::FILE,
); );
public function __construct(FormFactoryInterface $formFactory) public function __construct(FormFactoryInterface $formFactory, $entityToChoice)
{ {
$this->formFactory = $formFactory; $this->formFactory = $formFactory;
$this->entityToChoice = (boolean) $entityToChoice;
} }
/** /**
@ -254,7 +260,11 @@ class FormTypeParser implements ParserInterface
if (($choices = $config->getOption('choices')) && is_array($choices) && count($choices)) { if (($choices = $config->getOption('choices')) && is_array($choices) && count($choices)) {
$parameters[$name]['format'] = json_encode($choices); $parameters[$name]['format'] = json_encode($choices);
} elseif (($choiceList = $config->getOption('choice_list')) && $choiceList instanceof ChoiceListInterface) { } elseif (($choiceList = $config->getOption('choice_list')) && $choiceList instanceof ChoiceListInterface) {
if (('entity' === $config->getType()->getName() && false === $this->entityToChoice)) {
$choices = array();
} else {
$choices = $this->handleChoiceListValues($choiceList); $choices = $this->handleChoiceListValues($choiceList);
}
if (is_array($choices) && count($choices)) { if (is_array($choices) && count($choices)) {
$parameters[$name]['format'] = json_encode($choices); $parameters[$name]['format'] = json_encode($choices);
} }

View File

@ -10,6 +10,7 @@
<services> <services>
<service id="nelmio_api_doc.parser.form_type_parser" class="%nelmio_api_doc.parser.form_type_parser.class%"> <service id="nelmio_api_doc.parser.form_type_parser" class="%nelmio_api_doc.parser.form_type_parser.class%">
<argument type="service" id="form.factory" /> <argument type="service" id="form.factory" />
<argument>%nelmio_api_doc.sandbox.entity_to_choice%</argument>
<tag name="nelmio_api_doc.extractor.parser" /> <tag name="nelmio_api_doc.extractor.parser" />
</service> </service>
</services> </services>

View File

@ -370,6 +370,9 @@ nelmio_api_doc:
default_format: json # default is `json`, default_format: json # default is `json`,
# default content format to request (see formats) # default content format to request (see formats)
entity_to_choice: false # default is `true`, if `false`, entity collection
# will not be mapped as choice
``` ```
### Command ### Command
@ -543,6 +546,7 @@ nelmio_api_doc:
# Required if http delivery is selected. # Required if http delivery is selected.
type: ~ # One of "basic"; "bearer" type: ~ # One of "basic"; "bearer"
custom_endpoint: false custom_endpoint: false
entity_to_choice: true
swagger: swagger:
api_base_path: /api api_base_path: /api
swagger_version: '1.2' swagger_version: '1.2'

View File

@ -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\Fixtures\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\ChoiceList\SimpleChoiceList;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class EntityType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\EntityTest',
));
return;
}
public function getParent()
{
return 'choice';
}
public function getName()
{
return 'entity';
}
}

View File

@ -26,6 +26,7 @@ class ImprovedTestType extends AbstractType
->add('c2', 'choice', array('choices' => array('m' => 'Male', 'f' => 'Female'), 'multiple' => true)) ->add('c2', 'choice', array('choices' => array('m' => 'Male', 'f' => 'Female'), 'multiple' => true))
->add('c3', 'choice', array('choices' => array())) ->add('c3', 'choice', array('choices' => array()))
->add('c4', 'choice', array('choice_list' => new SimpleChoiceList(array('foo' => 'bar', 'bazgroup' => array('baz' => 'Buzz'))))) ->add('c4', 'choice', array('choice_list' => new SimpleChoiceList(array('foo' => 'bar', 'bazgroup' => array('baz' => 'Buzz')))))
->add('e1', new EntityType(), array('choice_list' => new SimpleChoiceList(array('foo' => 'bar', 'bazgroup' => array('baz' => 'Buzz')))))
; ;
} }

View File

@ -0,0 +1,19 @@
<?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;
use Symfony\Component\Validator\Constraints as Assert;
class EntityTest
{
}

View File

@ -26,4 +26,5 @@ class ImprovedTest
public $c2; public $c2;
public $c3; public $c3;
public $c4; public $c4;
public $e1;
} }

View File

@ -24,10 +24,33 @@ class FormTypeParserTest extends \PHPUnit_Framework_TestCase
$formFactoryBuilder->addExtension(new CoreExtension()); $formFactoryBuilder->addExtension(new CoreExtension());
$formFactoryBuilder->addTypeExtension(new DescriptionFormTypeExtension()); $formFactoryBuilder->addTypeExtension(new DescriptionFormTypeExtension());
$formFactory = $formFactoryBuilder->getFormFactory(); $formFactory = $formFactoryBuilder->getFormFactory();
$formTypeParser = new FormTypeParser($formFactory); $formTypeParser = new FormTypeParser($formFactory, $entityToChoice = true);
set_error_handler(array('Nelmio\ApiDocBundle\Tests\WebTestCase', 'handleDeprecation')); set_error_handler(array('Nelmio\ApiDocBundle\Tests\WebTestCase', 'handleDeprecation'));
trigger_error('test', E_USER_DEPRECATED); trigger_error('test', E_USER_DEPRECATED);
$output = $formTypeParser->parse($typeName);
restore_error_handler();
$this->assertEquals($expected, $output);
}
/**
* @dataProvider dataTestParseWithoutEntity
*/
public function testParseWithoutEntity($typeName, $expected)
{
$resolvedTypeFactory = new ResolvedFormTypeFactory();
$formFactoryBuilder = new FormFactoryBuilder();
$formFactoryBuilder->setResolvedTypeFactory($resolvedTypeFactory);
$formFactoryBuilder->addExtension(new CoreExtension());
$formFactoryBuilder->addTypeExtension(new DescriptionFormTypeExtension());
$formFactory = $formFactoryBuilder->getFormFactory();
$formTypeParser = new FormTypeParser($formFactory, $entityToChoice = false);
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(); restore_error_handler();
@ -36,6 +59,31 @@ class FormTypeParserTest extends \PHPUnit_Framework_TestCase
public function dataTestParse() public function dataTestParse()
{ {
return $this->expectedData(true);
}
public function dataTestParseWithoutEntity()
{
return $this->expectedData(false);
}
protected function expectedData($entityToChoice)
{
$entityData = array(
'dataType' => 'choice',
'actualType' => DataTypes::ENUM,
'subType' => null,
'default' => null,
'required' => true,
'description' => '',
'readonly' => false
);
if ($entityToChoice) {
$entityData['format'] = json_encode(array('foo' => 'bar', 'baz' => 'Buzz'));
}
return array( return array(
array( array(
array('class' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Form\TestType', 'options' => array()), array('class' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Form\TestType', 'options' => array()),
@ -389,6 +437,7 @@ class FormTypeParserTest extends \PHPUnit_Framework_TestCase
'readonly' => false, 'readonly' => false,
'format' => json_encode(array('foo' => 'bar', 'baz' => 'Buzz')), 'format' => json_encode(array('foo' => 'bar', 'baz' => 'Buzz')),
), ),
'e1' => $entityData
), ),
), ),
array( array(
@ -531,5 +580,7 @@ class FormTypeParserTest extends \PHPUnit_Framework_TestCase
), ),
), ),
); );
} }
} }