Merge branch '2.8' into 3.1
* 2.8: [Twig] Fix deprecations with Twig 1.29 Fixed typo Fix email address fix the docblock in regard to the role argument [VarDumper] fix tests when xdebug is enabled Fix merge [Cache] Fix dumping SplDoublyLinkedList iter mode [Console] fixed PHP7 Errors when not using Dispatcher Regression test for missing controller arguments fix a test checking for a value [Form][DX] FileType "multiple" fixes fixed CS [TwigBundle] Fix twig loader registered twice [WebProfilerBundle] Fix dump block is unfairly restrained [Console] Fix wrong handling of multiline arg/opt descriptions [DependencyInjection] PhpDumper.php: hasReference() should not search references in lazy service arguments. [Form] fixed "empty_value" option deprecation Cast result to int before adding to it
This commit is contained in:
commit
73099f3555
@ -72,8 +72,7 @@ class TwigExtractorTest extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Twig_Error
|
||||
* @expectedExceptionMessageRegExp /Unclosed "block" in ".*extractor(\/|\\)syntax_error\.twig" at line 1/
|
||||
* @expectedException \Twig_Error
|
||||
* @dataProvider resourcesWithSyntaxErrorsProvider
|
||||
*/
|
||||
public function testExtractSyntaxError($resources)
|
||||
@ -82,7 +81,19 @@ class TwigExtractorTest extends \PHPUnit_Framework_TestCase
|
||||
$twig->addExtension(new TranslationExtension($this->getMock('Symfony\Component\Translation\TranslatorInterface')));
|
||||
|
||||
$extractor = new TwigExtractor($twig);
|
||||
$extractor->extract($resources, new MessageCatalogue('en'));
|
||||
|
||||
try {
|
||||
$extractor->extract($resources, new MessageCatalogue('en'));
|
||||
} catch (\Twig_Error $e) {
|
||||
if (method_exists($e, 'getSourceContext')) {
|
||||
$this->assertSame(dirname(__DIR__).strtr('/Fixtures/extractor/syntax_error.twig', '/', DIRECTORY_SEPARATOR), $e->getFile());
|
||||
$this->assertSame(1, $e->getLine());
|
||||
$this->assertSame('Unclosed "block".', $e->getMessage());
|
||||
} else {
|
||||
$this->expectExceptionMessageRegExp('/Unclosed "block" in ".*extractor(\\/|\\\\)syntax_error\\.twig" at line 1/');
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,10 +61,14 @@ class TwigExtractor extends AbstractFileExtractor implements ExtractorInterface
|
||||
try {
|
||||
$this->extractTemplate(file_get_contents($file->getPathname()), $catalogue);
|
||||
} catch (\Twig_Error $e) {
|
||||
if ($file instanceof SplFileInfo) {
|
||||
$e->setTemplateName($file->getRelativePathname());
|
||||
} elseif ($file instanceof \SplFileInfo) {
|
||||
$e->setTemplateName($file->getRealPath() ?: $file->getPathname());
|
||||
if ($file instanceof \SplFileInfo) {
|
||||
$path = $file->getRealPath() ?: $file->getPathname();
|
||||
$name = $file instanceof SplFileInfo ? $file->getRelativePathname() : $path;
|
||||
if (method_exists($e, 'setSourceContext')) {
|
||||
$e->setSourceContext(new \Twig_Source('', $name, $path));
|
||||
} else {
|
||||
$e->setTemplateName($name);
|
||||
}
|
||||
}
|
||||
|
||||
throw $e;
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Bundle\TwigBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
@ -69,7 +70,7 @@ class ExtensionPass implements CompilerPassInterface
|
||||
$loader->addTag('twig.loader');
|
||||
$loader->setMethodCalls($container->getDefinition('twig.loader.filesystem')->getMethodCalls());
|
||||
|
||||
$container->setDefinition('twig.loader.filesystem', $loader);
|
||||
$container->setAlias('twig.loader.filesystem', new Alias('twig.loader.native_filesystem', false));
|
||||
}
|
||||
|
||||
if ($container->has('assets.packages')) {
|
||||
|
@ -52,7 +52,13 @@ class TwigEngine extends BaseEngine implements EngineInterface
|
||||
if ($name instanceof TemplateReference) {
|
||||
try {
|
||||
// try to get the real name of the template where the error occurred
|
||||
$e->setTemplateName(sprintf('%s', $this->locator->locate($this->parser->parse($e->getTemplateName()))));
|
||||
$name = $e->getTemplateName();
|
||||
$path = (string) $this->locator->locate($this->parser->parse($name));
|
||||
if (method_exists($e, 'setSourceContext')) {
|
||||
$e->setSourceContext(new \Twig_Source('', $name, $path));
|
||||
} else {
|
||||
$e->setTemplateName($path);
|
||||
}
|
||||
} catch (\Exception $e2) {
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
.sf-reset .traces li {
|
||||
ccolor: #222;
|
||||
color: #222;
|
||||
font-size: 14px;
|
||||
padding: 5px 0;
|
||||
list-style-type: decimal;
|
||||
|
@ -113,9 +113,11 @@
|
||||
<ul id="menu-profiler">
|
||||
{% for name, template in templates %}
|
||||
{% set menu -%}
|
||||
{% with { collector: profile.getcollector(name), profiler_markup_version: profiler_markup_version } %}
|
||||
{{- block('menu', template) -}}
|
||||
{% endwith %}
|
||||
{% if block('menu', template) is defined %}
|
||||
{% with { collector: profile.getcollector(name), profiler_markup_version: profiler_markup_version } %}
|
||||
{{- block('menu', template) -}}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{%- endset %}
|
||||
{% if menu is not empty %}
|
||||
<li class="{{ name }} {{ name == panel ? 'selected' : '' }}">
|
||||
|
@ -366,11 +366,13 @@
|
||||
border-color: #777;
|
||||
border-radius: 0;
|
||||
margin: 6px 0 12px 0;
|
||||
width: 200px;
|
||||
}
|
||||
.sf-toolbar-block-dump pre.sf-dump:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.sf-toolbar-block-dump .sf-toolbar-info-piece {
|
||||
display: block;
|
||||
}
|
||||
.sf-toolbar-block-dump .sf-toolbar-info-piece .sf-toolbar-file-line {
|
||||
color: #AAA;
|
||||
margin-left: 4px;
|
||||
|
@ -26,15 +26,17 @@
|
||||
|
||||
<div id="sfToolbarMainContent-{{ token }}" class="sf-toolbarreset clear-fix" data-no-turbolink>
|
||||
{% for name, template in templates %}
|
||||
{% with {
|
||||
collector: profile.getcollector(name),
|
||||
profiler_url: profiler_url,
|
||||
token: profile.token,
|
||||
name: name,
|
||||
profiler_markup_version: profiler_markup_version
|
||||
} %}
|
||||
{{ block('toolbar', template) }}
|
||||
{% endwith %}
|
||||
{% if block('toolbar', template) is defined %}
|
||||
{% with {
|
||||
collector: profile.getcollector(name),
|
||||
profiler_url: profiler_url,
|
||||
token: profile.token,
|
||||
name: name,
|
||||
profiler_markup_version: profiler_markup_version
|
||||
} %}
|
||||
{{ block('toolbar', template) }}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if 'normal' != position %}
|
||||
|
@ -817,7 +817,13 @@ class Application
|
||||
}
|
||||
|
||||
if (null === $this->dispatcher) {
|
||||
return $command->run($input, $output);
|
||||
try {
|
||||
return $command->run($input, $output);
|
||||
} catch (\Exception $e) {
|
||||
throw $e;
|
||||
} catch (\Throwable $e) {
|
||||
throw new FatalThrowableError($e);
|
||||
}
|
||||
}
|
||||
|
||||
// bind before the console.command event, so the listeners have access to input options/arguments
|
||||
|
@ -38,13 +38,13 @@ class TextDescriptor extends Descriptor
|
||||
}
|
||||
|
||||
$totalWidth = isset($options['total_width']) ? $options['total_width'] : strlen($argument->getName());
|
||||
$spacingWidth = $totalWidth - strlen($argument->getName()) + 2;
|
||||
$spacingWidth = $totalWidth - strlen($argument->getName());
|
||||
|
||||
$this->writeText(sprintf(' <info>%s</info>%s%s%s',
|
||||
$this->writeText(sprintf(' <info>%s</info> %s%s%s',
|
||||
$argument->getName(),
|
||||
str_repeat(' ', $spacingWidth),
|
||||
// + 17 = 2 spaces + <info> + </info> + 2 spaces
|
||||
preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 17), $argument->getDescription()),
|
||||
// + 4 = 2 spaces before <info>, 2 spaces after </info>
|
||||
preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $argument->getDescription()),
|
||||
$default
|
||||
), $options);
|
||||
}
|
||||
@ -75,13 +75,13 @@ class TextDescriptor extends Descriptor
|
||||
sprintf('--%s%s', $option->getName(), $value)
|
||||
);
|
||||
|
||||
$spacingWidth = $totalWidth - strlen($synopsis) + 2;
|
||||
$spacingWidth = $totalWidth - strlen($synopsis);
|
||||
|
||||
$this->writeText(sprintf(' <info>%s</info>%s%s%s%s',
|
||||
$this->writeText(sprintf(' <info>%s</info> %s%s%s%s',
|
||||
$synopsis,
|
||||
str_repeat(' ', $spacingWidth),
|
||||
// + 17 = 2 spaces + <info> + </info> + 2 spaces
|
||||
preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 17), $option->getDescription()),
|
||||
// + 4 = 2 spaces before <info>, 2 spaces after </info>
|
||||
preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $option->getDescription()),
|
||||
$default,
|
||||
$option->isArray() ? '<comment> (multiple values allowed)</comment>' : ''
|
||||
), $options);
|
||||
|
@ -952,6 +952,24 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertContains('before.foo.caught.after.', $tester->getDisplay());
|
||||
}
|
||||
|
||||
public function testRunWithError()
|
||||
{
|
||||
$this->setExpectedException('Exception', 'dymerr');
|
||||
|
||||
$application = new Application();
|
||||
$application->setAutoExit(false);
|
||||
$application->setCatchExceptions(false);
|
||||
|
||||
$application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) {
|
||||
$output->write('dym.');
|
||||
|
||||
throw new \Error('dymerr');
|
||||
});
|
||||
|
||||
$tester = new ApplicationTester($application);
|
||||
$tester->run(array('command' => 'dym'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
* @expectedExceptionMessage caught
|
||||
|
@ -1,2 +1,2 @@
|
||||
<info>argument_name</info> multiline
|
||||
argument description
|
||||
argument description
|
||||
|
@ -1,2 +1,2 @@
|
||||
<info>-o, --option_name=OPTION_NAME</info> multiline
|
||||
option description
|
||||
option description
|
||||
|
@ -60,15 +60,19 @@ class CheckCircularReferencesPass implements CompilerPassInterface
|
||||
$id = $node->getId();
|
||||
|
||||
if (empty($this->checkedNodes[$id])) {
|
||||
$searchKey = array_search($id, $this->currentPath);
|
||||
$this->currentPath[] = $id;
|
||||
|
||||
if (false !== $searchKey) {
|
||||
throw new ServiceCircularReferenceException($id, array_slice($this->currentPath, $searchKey));
|
||||
// don't check circular dependencies for lazy services
|
||||
if (!$node->getValue() || !$node->getValue()->isLazy()) {
|
||||
$searchKey = array_search($id, $this->currentPath);
|
||||
$this->currentPath[] = $id;
|
||||
|
||||
if (false !== $searchKey) {
|
||||
throw new ServiceCircularReferenceException($id, array_slice($this->currentPath, $searchKey));
|
||||
}
|
||||
|
||||
$this->checkOutEdges($node->getOutEdges());
|
||||
}
|
||||
|
||||
$this->checkOutEdges($node->getOutEdges());
|
||||
|
||||
$this->checkedNodes[$id] = true;
|
||||
array_pop($this->currentPath);
|
||||
}
|
||||
|
@ -1201,6 +1201,13 @@ EOF;
|
||||
$visited[$argumentId] = true;
|
||||
|
||||
$service = $this->container->getDefinition($argumentId);
|
||||
|
||||
// if the proxy manager is enabled, disable searching for references in lazy services,
|
||||
// as these services will be instantiated lazily and don't have direct related references.
|
||||
if ($service->isLazy() && !$this->getProxyDumper() instanceof NullDumper) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$arguments = array_merge($service->getMethodCalls(), $service->getArguments(), $service->getProperties());
|
||||
|
||||
if ($this->hasReference($id, $arguments, $deep, $visited)) {
|
||||
|
@ -346,21 +346,22 @@ class XmlFileLoader extends FileLoader
|
||||
$arg->setAttribute('key', $arg->getAttribute('name'));
|
||||
}
|
||||
|
||||
if (!$arg->hasAttribute('key')) {
|
||||
$key = !$arguments ? 0 : max(array_keys($arguments)) + 1;
|
||||
} else {
|
||||
$key = $arg->getAttribute('key');
|
||||
}
|
||||
|
||||
// parameter keys are case insensitive
|
||||
if ('parameter' == $name && $lowercase) {
|
||||
$key = strtolower($key);
|
||||
}
|
||||
|
||||
// this is used by DefinitionDecorator to overwrite a specific
|
||||
// argument of the parent definition
|
||||
if ($arg->hasAttribute('index')) {
|
||||
$key = 'index_'.$arg->getAttribute('index');
|
||||
} elseif (!$arg->hasAttribute('key')) {
|
||||
// Append an empty argument, then fetch its key to overwrite it later
|
||||
$arguments[] = null;
|
||||
$keys = array_keys($arguments);
|
||||
$key = array_pop($keys);
|
||||
} else {
|
||||
$key = $arg->getAttribute('key');
|
||||
|
||||
// parameter keys are case insensitive
|
||||
if ('parameter' == $name && $lowercase) {
|
||||
$key = strtolower($key);
|
||||
}
|
||||
}
|
||||
|
||||
switch ($arg->getAttribute('type')) {
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Tests\Dumper;
|
||||
|
||||
use DummyProxyDumper;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||
@ -19,6 +20,8 @@ use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Variable;
|
||||
use Symfony\Component\ExpressionLanguage\Expression;
|
||||
|
||||
require_once __DIR__.'/../Fixtures/includes/classes.php';
|
||||
|
||||
class PhpDumperTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected static $fixturesPath;
|
||||
@ -314,4 +317,52 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase
|
||||
$container = new \Symfony_DI_PhpDumper_Test_Properties_Before_Method_Calls();
|
||||
$this->assertTrue($container->get('bar')->callPassed(), '->dump() initializes properties before method calls');
|
||||
}
|
||||
|
||||
public function testCircularReferenceAllowanceForLazyServices()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->register('foo', 'stdClass')->addArgument(new Reference('bar'));
|
||||
$container->register('bar', 'stdClass')->setLazy(true)->addArgument(new Reference('foo'));
|
||||
$container->compile();
|
||||
|
||||
$dumper = new PhpDumper($container);
|
||||
$dumper->dump();
|
||||
}
|
||||
|
||||
public function testCircularReferenceAllowanceForInlinedDefinitionsForLazyServices()
|
||||
{
|
||||
/*
|
||||
* test graph:
|
||||
* [connection] -> [event_manager] --> [entity_manager](lazy)
|
||||
* |
|
||||
* --(call)- addEventListener ("@lazy_service")
|
||||
*
|
||||
* [lazy_service](lazy) -> [entity_manager](lazy)
|
||||
*
|
||||
*/
|
||||
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$eventManagerDefinition = new Definition('stdClass');
|
||||
|
||||
$connectionDefinition = $container->register('connection', 'stdClass');
|
||||
$connectionDefinition->addArgument($eventManagerDefinition);
|
||||
|
||||
$container->register('entity_manager', 'stdClass')
|
||||
->setLazy(true)
|
||||
->addArgument(new Reference('connection'));
|
||||
|
||||
$lazyServiceDefinition = $container->register('lazy_service', 'stdClass');
|
||||
$lazyServiceDefinition->setLazy(true);
|
||||
$lazyServiceDefinition->addArgument(new Reference('entity_manager'));
|
||||
|
||||
$eventManagerDefinition->addMethodCall('addEventListener', array(new Reference('lazy_service')));
|
||||
|
||||
$container->compile();
|
||||
|
||||
$dumper = new PhpDumper($container);
|
||||
|
||||
$dumper->setProxyDumper(new DummyProxyDumper());
|
||||
$dumper->dump();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as ProxyDumper;
|
||||
|
||||
function sc_configure($instance)
|
||||
{
|
||||
$instance->configure();
|
||||
@ -76,3 +79,21 @@ class MethodCallClass
|
||||
return $this->callPassed;
|
||||
}
|
||||
}
|
||||
|
||||
class DummyProxyDumper implements ProxyDumper
|
||||
{
|
||||
public function isProxyCandidate(Definition $definition)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getProxyFactoryCode(Definition $definition, $id)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getProxyCode(Definition $definition)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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="foo" class="Foo">
|
||||
<argument key="type">foo</argument>
|
||||
<argument>bar</argument>
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
@ -570,4 +570,13 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->assertTrue($container->has('bar'));
|
||||
}
|
||||
|
||||
public function testArgumentWithKeyOutsideCollection()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
|
||||
$loader->load('with_key_outside_collection.xml');
|
||||
|
||||
$this->assertSame(array('type' => 'foo', 'bar'), $container->getDefinition('foo')->getArguments());
|
||||
}
|
||||
}
|
||||
|
@ -12,12 +12,37 @@
|
||||
namespace Symfony\Component\Form\Extension\Core\Type;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\OptionsResolver\Options;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class FileType extends AbstractType
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
if ($options['multiple']) {
|
||||
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
|
||||
$form = $event->getForm();
|
||||
$data = $event->getData();
|
||||
|
||||
// submitted data for an input file (not required) without choosing any file
|
||||
if (array(null) === $data) {
|
||||
$emptyData = $form->getConfig()->getEmptyData();
|
||||
|
||||
$data = is_callable($emptyData) ? call_user_func($emptyData, $form, $data) : $emptyData;
|
||||
$event->setData($data);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -39,9 +64,7 @@ class FileType extends AbstractType
|
||||
*/
|
||||
public function finishView(FormView $view, FormInterface $form, array $options)
|
||||
{
|
||||
$view
|
||||
->vars['multipart'] = true
|
||||
;
|
||||
$view->vars['multipart'] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,10 +72,18 @@ class FileType extends AbstractType
|
||||
*/
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$dataClass = function (Options $options) {
|
||||
return $options['multiple'] ? null : 'Symfony\Component\HttpFoundation\File\File';
|
||||
};
|
||||
|
||||
$emptyData = function (Options $options) {
|
||||
return $options['multiple'] ? array() : null;
|
||||
};
|
||||
|
||||
$resolver->setDefaults(array(
|
||||
'compound' => false,
|
||||
'data_class' => 'Symfony\Component\HttpFoundation\File\File',
|
||||
'empty_data' => null,
|
||||
'data_class' => $dataClass,
|
||||
'empty_data' => $emptyData,
|
||||
'multiple' => false,
|
||||
));
|
||||
}
|
||||
|
@ -44,6 +44,33 @@ class FileTypeTest extends \Symfony\Component\Form\Test\TypeTestCase
|
||||
$this->assertNull($form->getData());
|
||||
}
|
||||
|
||||
public function testSubmitEmptyMultiple()
|
||||
{
|
||||
$form = $this->factory->createBuilder('Symfony\Component\Form\Extension\Core\Type\FileType', null, array(
|
||||
'multiple' => true,
|
||||
))->getForm();
|
||||
|
||||
// submitted data when an input file is uploaded without choosing any file
|
||||
$form->submit(array(null));
|
||||
|
||||
$this->assertSame(array(), $form->getData());
|
||||
}
|
||||
|
||||
public function testSetDataMultiple()
|
||||
{
|
||||
$form = $this->factory->createBuilder('Symfony\Component\Form\Extension\Core\Type\FileType', null, array(
|
||||
'multiple' => true,
|
||||
))->getForm();
|
||||
|
||||
$data = array(
|
||||
$this->createUploadedFileMock('abcdef', 'first.jpg', true),
|
||||
$this->createUploadedFileMock('zyxwvu', 'second.jpg', true),
|
||||
);
|
||||
|
||||
$form->setData($data);
|
||||
$this->assertSame($data, $form->getData());
|
||||
}
|
||||
|
||||
public function testSubmitMultiple()
|
||||
{
|
||||
$form = $this->factory->createBuilder('Symfony\Component\Form\Extension\Core\Type\FileType', null, array(
|
||||
|
@ -36,6 +36,13 @@ class ControllerResolver implements ArgumentResolverInterface, ControllerResolve
|
||||
*/
|
||||
private $supportsVariadic;
|
||||
|
||||
/**
|
||||
* If scalar types exists.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $supportsScalarTypes;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
@ -46,6 +53,7 @@ class ControllerResolver implements ArgumentResolverInterface, ControllerResolve
|
||||
$this->logger = $logger;
|
||||
|
||||
$this->supportsVariadic = method_exists('ReflectionParameter', 'isVariadic');
|
||||
$this->supportsScalarTypes = method_exists('ReflectionParameter', 'getType');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -140,7 +148,7 @@ class ControllerResolver implements ArgumentResolverInterface, ControllerResolve
|
||||
$arguments[] = $request;
|
||||
} elseif ($param->isDefaultValueAvailable()) {
|
||||
$arguments[] = $param->getDefaultValue();
|
||||
} elseif ($param->allowsNull()) {
|
||||
} elseif ($this->supportsScalarTypes && $param->hasType() && $param->allowsNull()) {
|
||||
$arguments[] = null;
|
||||
} else {
|
||||
if (is_array($controller)) {
|
||||
|
@ -227,6 +227,20 @@ class ControllerResolverTest extends \PHPUnit_Framework_TestCase
|
||||
$mock->getController($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
* @group legacy
|
||||
*/
|
||||
public function testIfExceptionIsThrownWhenMissingAnArgument()
|
||||
{
|
||||
$resolver = new ControllerResolver();
|
||||
$request = Request::create('/');
|
||||
|
||||
$controller = array($this, 'controllerMethod1');
|
||||
|
||||
$resolver->getArguments($request, $controller);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 7.1
|
||||
* @group legacy
|
||||
|
@ -33,7 +33,7 @@ abstract class AbstractToken implements TokenInterface
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param RoleInterface[]|string[] $roles An array of roles
|
||||
* @param (RoleInterface|string)[] $roles An array of roles
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
|
@ -29,7 +29,7 @@ class PreAuthenticatedToken extends AbstractToken
|
||||
* @param string|object $user The user can be a UserInterface instance, or an object implementing a __toString method or the username as a regular string
|
||||
* @param mixed $credentials The user credentials
|
||||
* @param string $providerKey The provider key
|
||||
* @param RoleInterface[]|string[] $roles An array of roles
|
||||
* @param (RoleInterface|string)[] $roles An array of roles
|
||||
*/
|
||||
public function __construct($user, $credentials, $providerKey, array $roles = array())
|
||||
{
|
||||
|
@ -29,7 +29,7 @@ class UsernamePasswordToken extends AbstractToken
|
||||
* @param string|object $user The username (like a nickname, email address, etc.), or a UserInterface instance or an object implementing a __toString method
|
||||
* @param string $credentials This usually is the password of the user
|
||||
* @param string $providerKey The provider key
|
||||
* @param RoleInterface[]|string[] $roles An array of roles
|
||||
* @param (RoleInterface|string)[] $roles An array of roles
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
|
@ -21,7 +21,7 @@ use Symfony\Component\Security\Core\User\UserInterface;
|
||||
* If you're using Guard authentication, you *must* use a class that implements
|
||||
* GuardTokenInterface as your authenticated token (like this class).
|
||||
*
|
||||
* @author Ryan Weaver <ryan@knpuniversity.com>n@gmail.com>
|
||||
* @author Ryan Weaver <ryan@knpuniversity.com>
|
||||
*/
|
||||
class PostAuthenticationGuardToken extends AbstractToken implements GuardTokenInterface
|
||||
{
|
||||
|
@ -71,7 +71,7 @@ class SplCaster
|
||||
$c->setIteratorMode(\SplDoublyLinkedList::IT_MODE_KEEP | $mode & ~\SplDoublyLinkedList::IT_MODE_DELETE);
|
||||
|
||||
$a += array(
|
||||
$prefix.'mode' => new ConstStub((($mode & \SplDoublyLinkedList::IT_MODE_LIFO) ? 'IT_MODE_LIFO' : 'IT_MODE_FIFO').' | '.(($mode & \SplDoublyLinkedList::IT_MODE_KEEP) ? 'IT_MODE_KEEP' : 'IT_MODE_DELETE'), $mode),
|
||||
$prefix.'mode' => new ConstStub((($mode & \SplDoublyLinkedList::IT_MODE_LIFO) ? 'IT_MODE_LIFO' : 'IT_MODE_FIFO').' | '.(($mode & \SplDoublyLinkedList::IT_MODE_DELETE) ? 'IT_MODE_DELETE' : 'IT_MODE_KEEP'), $mode),
|
||||
$prefix.'dllist' => iterator_to_array($c),
|
||||
);
|
||||
$c->setIteratorMode($mode);
|
||||
|
@ -147,6 +147,10 @@ EOTXT
|
||||
*/
|
||||
public function testGenerator()
|
||||
{
|
||||
if (extension_loaded('xdebug')) {
|
||||
$this->markTestSkipped('xdebug is active');
|
||||
}
|
||||
|
||||
$g = new GeneratorDemo();
|
||||
$g = $g->baz();
|
||||
$r = new \ReflectionGenerator($g);
|
||||
|
@ -117,4 +117,30 @@ SplFileObject {
|
||||
EOTXT;
|
||||
$this->assertDumpMatchesFormat($dump, $var);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideCastSplDoublyLinkedList
|
||||
*/
|
||||
public function testCastSplDoublyLinkedList($modeValue, $modeDump)
|
||||
{
|
||||
$var = new \SplDoublyLinkedList();
|
||||
$var->setIteratorMode($modeValue);
|
||||
$dump = <<<EOTXT
|
||||
SplDoublyLinkedList {
|
||||
%Amode: $modeDump
|
||||
dllist: []
|
||||
}
|
||||
EOTXT;
|
||||
$this->assertDumpMatchesFormat($dump, $var);
|
||||
}
|
||||
|
||||
public function provideCastSplDoublyLinkedList()
|
||||
{
|
||||
return array(
|
||||
array(\SplDoublyLinkedList::IT_MODE_FIFO, 'IT_MODE_FIFO | IT_MODE_KEEP'),
|
||||
array(\SplDoublyLinkedList::IT_MODE_LIFO, 'IT_MODE_LIFO | IT_MODE_KEEP'),
|
||||
array(\SplDoublyLinkedList::IT_MODE_FIFO | \SplDoublyLinkedList::IT_MODE_DELETE, 'IT_MODE_FIFO | IT_MODE_DELETE'),
|
||||
array(\SplDoublyLinkedList::IT_MODE_LIFO | \SplDoublyLinkedList::IT_MODE_DELETE, 'IT_MODE_LIFO | IT_MODE_DELETE'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -137,6 +137,10 @@ EOTXT;
|
||||
|
||||
public function testJsonCast()
|
||||
{
|
||||
if (ini_get('xdebug.overload_var_dump') == 2) {
|
||||
$this->markTestSkipped('xdebug is active');
|
||||
}
|
||||
|
||||
$data = (array) json_decode('{"1":{}}');
|
||||
|
||||
$cloner = new VarCloner();
|
||||
|
Reference in New Issue
Block a user