Merge branch '2.8'

* 2.8: (28 commits)
  Detect Mintty for color support on Windows
  Detect Mintty for color support on Windows
  [WebProfilerBundle] Fix search button click listener
  [Form][Type Date/Time] added choice_translation_domain option.
  Massively simplifying the BC and deprecated-throwing code thanks to suggestions by stof in #15870
  Making all "debug" messages use the debug router
  Making GuardTokenInterface extend TokenInterface
  Updating behavior to not continue after an authenticator has set the response
  Add a group for tests of the finder against the FTP server
  Fix trigger_error calls
  Fix legacy security tests
  tweaking message related to configuration edge case that we want to be helpful with
  Minor tweaks - lowering the required security-http requirement and nulling out a test field
  Fix license headers
  Fix license headers
  Fix license headers
  Ensure the ClockMock is loaded before using it in the testsuite
  Allow serializer 3.0 in the PropertyInfo component
  Add the replace rules for the security-guard component
  Forbid serializing a Crawler
  ...
This commit is contained in:
Fabien Potencier 2015-09-27 12:13:28 +02:00
commit 8d7b498665
88 changed files with 742 additions and 192 deletions

View File

@ -52,6 +52,7 @@
"symfony/security": "2.99.99",
"symfony/security-core": "self.version",
"symfony/security-csrf": "self.version",
"symfony/security-guard": "self.version",
"symfony/security-http": "self.version",
"symfony/security-bundle": "self.version",
"symfony/serializer": "self.version",

View File

@ -2,12 +2,12 @@
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bridge\Doctrine\Tests\DependencyInjection\CompilerPass;

View File

@ -2,12 +2,12 @@
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bridge\Doctrine\Tests\DependencyInjection;

View File

@ -133,7 +133,7 @@ class DeprecationErrorHandler
private static function hasColorSupport()
{
if ('\\' === DIRECTORY_SEPARATOR) {
return false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI');
return false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI') || 'xterm' === getenv('TERM');
}
return defined('STDOUT') && function_exists('posix_isatty') && @posix_isatty(STDOUT);

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Doctrine\Common\Annotations\AnnotationRegistry;
use Symfony\Bridge\PhpUnit\DeprecationErrorHandler;

View File

@ -80,7 +80,7 @@
{% if datetime is not defined or false == datetime -%}
<div {{ block('widget_container_attributes') -}}>
{%- endif -%}
{{- form_widget(form.hour) }}:{{ form_widget(form.minute) }}{% if with_seconds %}:{{ form_widget(form.second) }}{% endif %}
{{- form_widget(form.hour) }}{% if with_minutes %}:{{ form_widget(form.minute) }}{% endif %}{% if with_seconds %}:{{ form_widget(form.second) }}{% endif %}
{% if datetime is not defined or false == datetime -%}
</div>
{%- endif -%}

View File

@ -97,8 +97,12 @@ class TemplateFinder implements TemplateFinderInterface
*/
private function findTemplatesInBundle(BundleInterface $bundle)
{
$templates = $this->findTemplatesInFolder($bundle->getPath().'/Resources/views');
$name = $bundle->getName();
$templates = array_merge(
$this->findTemplatesInFolder($bundle->getPath().'/Resources/views'),
$this->findTemplatesInFolder($this->rootDir.'/'.$name.'/views')
);
$templates = array_unique($templates);
foreach ($templates as $i => $template) {
$templates[$i] = $template->set('bundle', $name);

View File

@ -100,9 +100,9 @@ EOF
private function validate($content, $file = null)
{
$this->parser = new Parser();
$parser = new Parser();
try {
$this->parser->parse($content);
$parser->parse($content);
} catch (ParseException $e) {
return array('file' => $file, 'valid' => false, 'message' => $e->getMessage());
}

View File

@ -46,10 +46,11 @@ class TemplateFinderTest extends TestCase
$finder->findAllTemplates()
);
$this->assertCount(6, $templates, '->findAllTemplates() find all templates in the bundles and global folders');
$this->assertCount(7, $templates, '->findAllTemplates() find all templates in the bundles and global folders');
$this->assertContains('BaseBundle::base.format.engine', $templates);
$this->assertContains('BaseBundle::this.is.a.template.format.engine', $templates);
$this->assertContains('BaseBundle:controller:base.format.engine', $templates);
$this->assertContains('BaseBundle:controller:custom.format.engine', $templates);
$this->assertContains('::this.is.a.template.format.engine', $templates);
$this->assertContains('::resource.format.engine', $templates);
}

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Tests\Command\CacheClearCommand;
use Symfony\Bundle\FrameworkBundle\Console\Application;

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Tests\Command\CacheClearCommand\Fixture;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestBundle;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestBundle;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestBundle;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestBundle;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;

View File

@ -357,7 +357,6 @@ class MainConfiguration implements ConfigurationInterface
),
'my_entity_provider' => array('entity' => array('class' => 'SecurityBundle:User', 'property' => 'username')),
))
->disallowNewKeysInSubsequentConfigs()
->isRequired()
->requiresAtLeastOneElement()
->useAttributeAsKey('name')

View File

@ -94,7 +94,7 @@ class GuardAuthenticationFactory implements SecurityFactoryInterface
// explode if they've configured the entry_point, but there is already one
if ($config['entry_point']) {
throw new \LogicException(sprintf(
'The guard authentication provider cannot use the "%s" entry_point because another entry point is already configured by another provider! Either remove the other provider or move the entry_point configuration as a root key under your firewall',
'The guard authentication provider cannot use the "%s" entry_point because another entry point is already configured by another provider! Either remove the other provider or move the entry_point configuration as a root key under your firewall (i.e. at the same level as "guard").',
$config['entry_point']
));
}

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\SecurityBundle\Tests\DataCollector;
use Symfony\Bundle\SecurityBundle\DataCollector\SecurityDataCollector;

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\SecurityBundle\Tests\Functional;
/*

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
return array(
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
new Symfony\Bundle\SecurityBundle\SecurityBundle(),

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
return array(
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new Symfony\Bundle\SecurityBundle\SecurityBundle(),

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
return array(
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new Symfony\Bundle\SecurityBundle\SecurityBundle(),

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
return array(
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\FormLoginBundle\FormLoginBundle;
use Symfony\Bundle\TwigBundle\TwigBundle;
use Symfony\Bundle\SecurityBundle\SecurityBundle;

View File

@ -390,6 +390,13 @@
e.preventDefault();
var toggle = e.target || e.srcElement;
/* needed because when the toggle contains HTML contents, user can click */
/* on any of those elements instead of their parent '.sf-toggle' element */
while (!Sfjs.hasClass(toggle, 'sf-toggle')) {
toggle = toggle.parentNode;
}
var element = document.querySelector(toggle.getAttribute('data-toggle-selector'));
Sfjs.toggleClass(element, 'sf-toggle-hidden');

View File

@ -89,7 +89,7 @@ class StreamOutput extends Output
*
* Colorization is disabled if not supported by the stream:
*
* - Windows without Ansicon and ConEmu
* - Windows without Ansicon, ConEmu or Mintty
* - non tty consoles
*
* @return bool true if the stream supports colorization, false otherwise
@ -97,7 +97,7 @@ class StreamOutput extends Output
protected function hasColorSupport()
{
if (DIRECTORY_SEPARATOR === '\\') {
return false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI');
return false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI') || 'xterm' === getenv('TERM');
}
return function_exists('posix_isatty') && @posix_isatty($this->stream);

View File

@ -16,6 +16,8 @@ use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\Console\Tests;
require_once __DIR__.'/../ClockMock.php';
class ProgressBarTest extends \PHPUnit_Framework_TestCase
{
protected function setUp()

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Console\Tests\Style;
use PHPUnit_Framework_TestCase;

View File

@ -46,7 +46,6 @@ class CheckReferenceValidityPass implements CompilerPassInterface
}
$this->currentId = $id;
$this->currentDefinition = $definition;
$this->validateReferences($definition->getArguments());
$this->validateReferences($definition->getMethodCalls());

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\ContainerBuilder;

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
use Symfony\Component\DependencyInjection\Alias;

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
use Symfony\Component\DependencyInjection\Compiler\ExtensionCompilerPass;

View File

@ -325,6 +325,17 @@ class Crawler extends \SplObjectStorage
}
}
// Serializing and unserializing a crawler creates DOM objects in a corrupted state. DOM elements are not properly serializable.
public function unserialize($serialized)
{
throw new \BadMethodCallException('A Crawler cannot be serialized.');
}
public function serialize()
{
throw new \BadMethodCallException('A Crawler cannot be serialized.');
}
/**
* Returns a node given its position in the node list.
*

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
$operators = array('not', '!', 'or', '||', '&&', 'and', '|', '^', '&', '==', '===', '!=', '!==', '<', '>', '>=', '<=', 'not in', 'in', '..', '+', '-', '~', '*', '/', '%', 'matches', '**');
$operators = array_combine($operators, array_map('strlen', $operators));
arsort($operators);

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\ExpressionLanguage\Tests;
use Symfony\Component\ExpressionLanguage\Expression;

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\ExpressionLanguage\Tests;
use Symfony\Component\ExpressionLanguage\Node\ConstantNode;

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Filesystem\Tests;
use Symfony\Component\Filesystem\LockHandler;

View File

@ -2,12 +2,12 @@
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Finder\Tests\Iterator;
@ -16,42 +16,36 @@ use Symfony\Component\Finder\Iterator\RecursiveDirectoryIterator;
class RecursiveDirectoryIteratorTest extends IteratorTestCase
{
/**
* @dataProvider getPaths
*
* @param string $path
* @param bool $seekable
* @param array $contains
* @param string $message
* @group network
*/
public function testRewind($path, $seekable, $contains, $message = null)
public function testRewindOnFtp()
{
try {
$i = new RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS);
$i = new RecursiveDirectoryIterator('ftp://ftp.mozilla.org/', \RecursiveDirectoryIterator::SKIP_DOTS);
} catch (\UnexpectedValueException $e) {
$this->markTestSkipped(sprintf('Unsupported stream "%s".', $path));
$this->markTestSkipped('Unsupported stream "ftp".');
}
$i->rewind();
$this->assertTrue(true, $message);
$this->assertTrue(true);
}
/**
* @dataProvider getPaths
*
* @param string $path
* @param bool $seekable
* @param array $contains
* @param string $message
* @group network
*/
public function testSeek($path, $seekable, $contains, $message = null)
public function testSeekOnFtp()
{
try {
$i = new RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS);
$i = new RecursiveDirectoryIterator('ftp://ftp.mozilla.org/', \RecursiveDirectoryIterator::SKIP_DOTS);
} catch (\UnexpectedValueException $e) {
$this->markTestSkipped(sprintf('Unsupported stream "%s".', $path));
$this->markTestSkipped('Unsupported stream "ftp".');
}
$contains = array(
'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'README',
'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'pub',
);
$actual = array();
$i->seek(0);
@ -62,18 +56,4 @@ class RecursiveDirectoryIteratorTest extends IteratorTestCase
$this->assertEquals($contains, $actual);
}
public function getPaths()
{
$data = array();
// ftp
$contains = array(
'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'README',
'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'pub',
);
$data[] = array('ftp://ftp.mozilla.org/', false, $contains);
return $data;
}
}

View File

@ -14,6 +14,7 @@ CHANGELOG
2.8.0
-----
* added option "choice_translation_domain" to DateType, TimeType and DateTimeType.
* deprecated option "read_only" in favor of "attr['readonly']"
* added the html5 "range" FormType
* deprecated the "cascade_validation" option in favor of setting "constraints"

View File

@ -116,6 +116,7 @@ class DateTimeType extends AbstractType
'days',
'empty_value',
'placeholder',
'choice_translation_domain',
'required',
'translation_domain',
'html5',
@ -131,6 +132,7 @@ class DateTimeType extends AbstractType
'with_seconds',
'empty_value',
'placeholder',
'choice_translation_domain',
'required',
'translation_domain',
'html5',
@ -245,6 +247,7 @@ class DateTimeType extends AbstractType
$resolver->setDefined(array(
'empty_value', // deprecated
'placeholder',
'choice_translation_domain',
'years',
'months',
'days',

View File

@ -94,10 +94,13 @@ class DateType extends AbstractType
// Only pass a subset of the options to children
$yearOptions['choices'] = $this->formatTimestamps($formatter, '/y+/', $this->listYears($options['years']));
$yearOptions['placeholder'] = $options['placeholder']['year'];
$yearOptions['choice_translation_domain'] = $options['choice_translation_domain']['year'];
$monthOptions['choices'] = $this->formatTimestamps($formatter, '/[M|L]+/', $this->listMonths($options['months']));
$monthOptions['placeholder'] = $options['placeholder']['month'];
$monthOptions['choice_translation_domain'] = $options['choice_translation_domain']['month'];
$dayOptions['choices'] = $this->formatTimestamps($formatter, '/d+/', $this->listDays($options['days']));
$dayOptions['placeholder'] = $options['placeholder']['day'];
$dayOptions['choice_translation_domain'] = $options['choice_translation_domain']['day'];
}
// Append generic carry-along options
@ -205,6 +208,23 @@ class DateType extends AbstractType
);
};
$choiceTranslationDomainNormalizer = function (Options $options, $choiceTranslationDomain) {
if (is_array($choiceTranslationDomain)) {
$default = false;
return array_replace(
array('year' => $default, 'month' => $default, 'day' => $default),
$choiceTranslationDomain
);
};
return array(
'year' => $choiceTranslationDomain,
'month' => $choiceTranslationDomain,
'day' => $choiceTranslationDomain,
);
};
$format = function (Options $options) {
return $options['widget'] === 'single_text' ? DateType::HTML5_FORMAT : DateType::DEFAULT_FORMAT;
};
@ -231,10 +251,12 @@ class DateType extends AbstractType
// this option.
'data_class' => null,
'compound' => $compound,
'choice_translation_domain' => false,
));
$resolver->setNormalizer('empty_value', $placeholderNormalizer);
$resolver->setNormalizer('placeholder', $placeholderNormalizer);
$resolver->setNormalizer('choice_translation_domain', $choiceTranslationDomainNormalizer);
$resolver->setAllowedValues('input', array(
'datetime',

View File

@ -69,6 +69,7 @@ class TimeType extends AbstractType
// Only pass a subset of the options to children
$hourOptions['choices'] = $hours;
$hourOptions['placeholder'] = $options['placeholder']['hour'];
$hourOptions['choice_translation_domain'] = $options['choice_translation_domain']['hour'];
if ($options['with_minutes']) {
foreach ($options['minutes'] as $minute) {
@ -77,6 +78,7 @@ class TimeType extends AbstractType
$minuteOptions['choices'] = $minutes;
$minuteOptions['placeholder'] = $options['placeholder']['minute'];
$minuteOptions['choice_translation_domain'] = $options['choice_translation_domain']['minute'];
}
if ($options['with_seconds']) {
@ -88,6 +90,7 @@ class TimeType extends AbstractType
$secondOptions['choices'] = $seconds;
$secondOptions['placeholder'] = $options['placeholder']['second'];
$secondOptions['choice_translation_domain'] = $options['choice_translation_domain']['second'];
}
// Append generic carry-along options
@ -194,6 +197,23 @@ class TimeType extends AbstractType
);
};
$choiceTranslationDomainNormalizer = function (Options $options, $choiceTranslationDomain) {
if (is_array($choiceTranslationDomain)) {
$default = false;
return array_replace(
array('hour' => $default, 'minute' => $default, 'second' => $default),
$choiceTranslationDomain
);
};
return array(
'hour' => $choiceTranslationDomain,
'minute' => $choiceTranslationDomain,
'second' => $choiceTranslationDomain,
);
};
$resolver->setDefaults(array(
'hours' => range(0, 23),
'minutes' => range(0, 59),
@ -217,10 +237,12 @@ class TimeType extends AbstractType
// this option.
'data_class' => null,
'compound' => $compound,
'choice_translation_domain' => false,
));
$resolver->setNormalizer('empty_value', $placeholderNormalizer);
$resolver->setNormalizer('placeholder', $placeholderNormalizer);
$resolver->setNormalizer('choice_translation_domain', $choiceTranslationDomainNormalizer);
$resolver->setAllowedValues('input', array(
'datetime',

View File

@ -854,6 +854,10 @@ class FormConfigBuilder implements FormConfigBuilderInterface
*/
public function setAutoInitialize($initialize)
{
if ($this->locked) {
throw new BadMethodCallException('FormConfigBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
}
$this->autoInitialize = (bool) $initialize;
return $this;

View File

@ -3,7 +3,7 @@
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.

View File

@ -3,7 +3,7 @@
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.

View File

@ -3,7 +3,7 @@
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.

View File

@ -484,4 +484,57 @@ class DateTimeTypeTest extends TestCase
$this->assertSame(array(), iterator_to_array($form['time']->getErrors()));
$this->assertSame(array($error), iterator_to_array($form->getErrors()));
}
public function testPassDefaultChoiceTranslationDomain()
{
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\DateTimeType', null, array(
'with_seconds' => true,
));
$view = $form->createView();
$this->assertFalse($view['date']['year']->vars['choice_translation_domain']);
$this->assertFalse($view['date']['month']->vars['choice_translation_domain']);
$this->assertFalse($view['date']['day']->vars['choice_translation_domain']);
$this->assertFalse($view['time']['hour']->vars['choice_translation_domain']);
$this->assertFalse($view['time']['minute']->vars['choice_translation_domain']);
$this->assertFalse($view['time']['second']->vars['choice_translation_domain']);
}
public function testPassChoiceTranslationDomainAsString()
{
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\DateTimeType', null, array(
'choice_translation_domain' => 'messages',
'with_seconds' => true,
));
$view = $form->createView();
$this->assertSame('messages', $view['date']['year']->vars['choice_translation_domain']);
$this->assertSame('messages', $view['date']['month']->vars['choice_translation_domain']);
$this->assertSame('messages', $view['date']['day']->vars['choice_translation_domain']);
$this->assertSame('messages', $view['time']['hour']->vars['choice_translation_domain']);
$this->assertSame('messages', $view['time']['minute']->vars['choice_translation_domain']);
$this->assertSame('messages', $view['time']['second']->vars['choice_translation_domain']);
}
public function testPassChoiceTranslationDomainAsArray()
{
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\DateTimeType', null, array(
'choice_translation_domain' => array(
'year' => 'foo',
'month' => 'test',
'hour' => 'foo',
'second' => 'test',
),
'with_seconds' => true,
));
$view = $form->createView();
$this->assertSame('foo', $view['date']['year']->vars['choice_translation_domain']);
$this->assertSame('test', $view['date']['month']->vars['choice_translation_domain']);
$this->assertFalse($view['date']['day']->vars['choice_translation_domain']);
$this->assertSame('foo', $view['time']['hour']->vars['choice_translation_domain']);
$this->assertFalse($view['time']['minute']->vars['choice_translation_domain']);
$this->assertSame('test', $view['time']['second']->vars['choice_translation_domain']);
}
}

View File

@ -922,4 +922,41 @@ class DateTypeTest extends TestCase
$this->assertEquals($listChoices, $view['year']->vars['choices']);
}
public function testPassDefaultChoiceTranslationDomain()
{
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\DateType');
$view = $form->createView();
$this->assertFalse($view['year']->vars['choice_translation_domain']);
$this->assertFalse($view['month']->vars['choice_translation_domain']);
$this->assertFalse($view['day']->vars['choice_translation_domain']);
}
public function testPassChoiceTranslationDomainAsString()
{
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\DateType', null, array(
'choice_translation_domain' => 'messages',
));
$view = $form->createView();
$this->assertSame('messages', $view['year']->vars['choice_translation_domain']);
$this->assertSame('messages', $view['month']->vars['choice_translation_domain']);
$this->assertSame('messages', $view['day']->vars['choice_translation_domain']);
}
public function testPassChoiceTranslationDomainAsArray()
{
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\DateType', null, array(
'choice_translation_domain' => array(
'year' => 'foo',
'day' => 'test',
),
));
$view = $form->createView();
$this->assertSame('foo', $view['year']->vars['choice_translation_domain']);
$this->assertFalse($view['month']->vars['choice_translation_domain']);
$this->assertSame('test', $view['day']->vars['choice_translation_domain']);
}
}

View File

@ -707,4 +707,42 @@ class TimeTypeTest extends TestCase
'seconds' => 'bad value',
));
}
public function testPassDefaultChoiceTranslationDomain()
{
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\TimeType');
$view = $form->createView();
$this->assertFalse($view['hour']->vars['choice_translation_domain']);
$this->assertFalse($view['minute']->vars['choice_translation_domain']);
}
public function testPassChoiceTranslationDomainAsString()
{
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\TimeType', null, array(
'choice_translation_domain' => 'messages',
'with_seconds' => true,
));
$view = $form->createView();
$this->assertSame('messages', $view['hour']->vars['choice_translation_domain']);
$this->assertSame('messages', $view['minute']->vars['choice_translation_domain']);
$this->assertSame('messages', $view['second']->vars['choice_translation_domain']);
}
public function testPassChoiceTranslationDomainAsArray()
{
$form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\TimeType', null, array(
'choice_translation_domain' => array(
'hour' => 'foo',
'second' => 'test',
),
'with_seconds' => true,
));
$view = $form->createView();
$this->assertSame('foo', $view['hour']->vars['choice_translation_domain']);
$this->assertFalse($view['minute']->vars['choice_translation_domain']);
$this->assertSame('test', $view['second']->vars['choice_translation_domain']);
}
}

View File

@ -3,7 +3,7 @@
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.

View File

@ -3,7 +3,7 @@
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.

View File

@ -1,13 +1,13 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Tests\Extension\Validator;

View File

@ -1,13 +1,13 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Tests\Extension\Validator;

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Tests\Util;
use Symfony\Component\Form\Util\StringUtil;

View File

@ -64,7 +64,7 @@ class NativeSessionStorage implements SessionStorageInterface
* ("auto_start", is not supported as it tells PHP to start a session before
* PHP starts to execute user-land code. Setting during runtime has no effect).
*
* cache_limiter, "nocache" (use "0" to prevent headers from being sent entirely).
* cache_limiter, "" (use "0" to prevent headers from being sent entirely).
* cookie_domain, ""
* cookie_httponly, ""
* cookie_lifetime, "0"

View File

@ -34,6 +34,7 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
private $clonesIndex = 0;
private $rootRefs;
private $charset;
private $requestStack;
private $dumper;
private $dumperIsInjected;

View File

@ -154,7 +154,6 @@ class Esi implements SurrogateInterface
*/
public function process(Request $request, Response $response)
{
$this->request = $request;
$type = $response->headers->get('Content-Type');
if (empty($type)) {
$type = 'text/html';

View File

@ -113,7 +113,6 @@ class Ssi implements SurrogateInterface
*/
public function process(Request $request, Response $response)
{
$this->request = $request;
$type = $response->headers->get('Content-Type');
if (empty($type)) {
$type = 'text/html';

View File

@ -3,7 +3,7 @@
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.

View File

@ -28,6 +28,7 @@ class HttpCacheTestCase extends \PHPUnit_Framework_TestCase
protected $responses;
protected $catch;
protected $esi;
protected $store;
protected function setUp()
{

View File

@ -23,7 +23,7 @@ class TestMultipleHttpKernel extends HttpKernel implements ControllerResolverInt
protected $bodies = array();
protected $statuses = array();
protected $headers = array();
protected $call = false;
protected $called = false;
protected $backendRequest;
public function __construct($responses)
@ -75,6 +75,6 @@ class TestMultipleHttpKernel extends HttpKernel implements ControllerResolverInt
public function reset()
{
$this->call = false;
$this->called = false;
}
}

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Runs a PHP script that can be stopped only with a SIGKILL (9) signal for 3 seconds.
*

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
define('ERR_SELECT_FAILED', 1);
define('ERR_TIMEOUT', 2);
define('ERR_READ_FAILED', 3);

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
// required for signal handling
declare (ticks = 1);

View File

@ -1,7 +1,7 @@
<?php
/*
* This file is new3 of the Symfony package.
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*

View File

@ -26,8 +26,8 @@
"php": ">=5.3.9"
},
"require-dev": {
"symfony/phpunit-bridge": "~2.7",
"symfony/serializer": "~2.7",
"symfony/phpunit-bridge": "~2.7|~3.0.0",
"symfony/serializer": "~2.7|~3.0.0",
"phpdocumentor/reflection": "^1.0.7",
"doctrine/annotations": "~1.0"
},

View File

@ -77,7 +77,7 @@ class AccessDecisionManager implements AccessDecisionManagerInterface
*/
public function supportsAttribute($attribute)
{
@trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.');
@trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.', E_USER_DEPRECATED);
foreach ($this->voters as $voter) {
if ($voter->supportsAttribute($attribute)) {
@ -93,7 +93,7 @@ class AccessDecisionManager implements AccessDecisionManagerInterface
*/
public function supportsClass($class)
{
@trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.');
@trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.', E_USER_DEPRECATED);
foreach ($this->voters as $voter) {
if ($voter->supportsClass($class)) {

View File

@ -26,7 +26,7 @@ abstract class AbstractVoter implements VoterInterface
*/
public function supportsAttribute($attribute)
{
@trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.');
@trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.', E_USER_DEPRECATED);
return in_array($attribute, $this->getSupportedAttributes());
}
@ -36,7 +36,7 @@ abstract class AbstractVoter implements VoterInterface
*/
public function supportsClass($class)
{
@trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.');
@trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.', E_USER_DEPRECATED);
foreach ($this->getSupportedClasses() as $supportedClass) {
if ($supportedClass === $class || is_subclass_of($class, $supportedClass)) {
@ -70,12 +70,6 @@ abstract class AbstractVoter implements VoterInterface
$vote = self::ACCESS_ABSTAIN;
$class = get_class($object);
$reflector = new \ReflectionMethod($this, 'voteOnAttribute');
$isNewOverwritten = $reflector->getDeclaringClass()->getName() !== 'Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter';
if (!$isNewOverwritten) {
@trigger_error(sprintf("The AbstractVoter::isGranted method is deprecated since 2.8 and won't be called anymore in 3.0. Override voteOnAttribute() instead.", $reflector->class), E_USER_DEPRECATED);
}
foreach ($attributes as $attribute) {
if (!$this->supports($attribute, $class)) {
continue;
@ -84,16 +78,9 @@ abstract class AbstractVoter implements VoterInterface
// as soon as at least one attribute is supported, default is to deny access
$vote = self::ACCESS_DENIED;
if ($isNewOverwritten) {
if ($this->voteOnAttribute($attribute, $object, $token)) {
// grant access as soon as at least one voter returns a positive response
return self::ACCESS_GRANTED;
}
} else {
if ($this->isGranted($attribute, $object, $token->getUser())) {
// grant access as soon as at least one voter returns a positive response
return self::ACCESS_GRANTED;
}
if ($this->voteOnAttribute($attribute, $object, $token)) {
// grant access as soon as at least one voter returns a positive response
return self::ACCESS_GRANTED;
}
}
@ -115,7 +102,7 @@ abstract class AbstractVoter implements VoterInterface
*/
protected function supports($attribute, $class)
{
@trigger_error('The getSupportedClasses and getSupportedAttributes methods are deprecated since version 2.8 and will be removed in version 3.0. Overwrite supports instead.');
@trigger_error('The getSupportedClasses and getSupportedAttributes methods are deprecated since version 2.8 and will be removed in version 3.0. Overwrite supports instead.', E_USER_DEPRECATED);
$classIsSupported = false;
foreach ($this->getSupportedClasses() as $supportedClass) {
@ -159,7 +146,7 @@ abstract class AbstractVoter implements VoterInterface
*/
protected function getSupportedClasses()
{
@trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.');
@trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.', E_USER_DEPRECATED);
}
/**
@ -171,7 +158,7 @@ abstract class AbstractVoter implements VoterInterface
*/
protected function getSupportedAttributes()
{
@trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.');
@trigger_error('The '.__METHOD__.' is deprecated since version 2.8 and will be removed in version 3.0.', E_USER_DEPRECATED);
}
/**
@ -191,7 +178,8 @@ abstract class AbstractVoter implements VoterInterface
*/
protected function isGranted($attribute, $object, $user = null)
{
return false;
// forces isGranted() or voteOnAttribute() to be overridden
throw new \BadMethodCallException(sprintf('You must override the voteOnAttribute() method in "%s".', get_class($this)));
}
/**
@ -211,6 +199,9 @@ abstract class AbstractVoter implements VoterInterface
*/
protected function voteOnAttribute($attribute, $object, TokenInterface $token)
{
return false;
// the user should override this method, and not rely on the deprecated isGranted()
@trigger_error(sprintf("The AbstractVoter::isGranted() method is deprecated since 2.8 and won't be called anymore in 3.0. Override voteOnAttribute() in %s instead.", get_class($this)), E_USER_DEPRECATED);
return $this->isGranted($attribute, $object, $token->getUser());
}
}

View File

@ -19,17 +19,10 @@ use Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter;
*/
class AbstractVoterTest extends \PHPUnit_Framework_TestCase
{
/**
* @var AbstractVoter
*/
private $voter;
private $token;
protected function setUp()
{
$this->voter = new VoterFixture();
$tokenMock = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
$tokenMock
->expects($this->any())
@ -44,7 +37,9 @@ class AbstractVoterTest extends \PHPUnit_Framework_TestCase
*/
public function testVote($expectedVote, $object, $attributes, $message)
{
$this->assertEquals($expectedVote, $this->voter->vote($this->token, $object, $attributes), $message);
$voter = new VoterFixture();
$this->assertEquals($expectedVote, $voter->vote($this->token, $object, $attributes), $message);
}
/**
@ -58,6 +53,16 @@ class AbstractVoterTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($expectedVote, $voter->vote($this->token, $object, $attributes), $message);
}
/**
* @group legacy
* @expectedException \BadMethodCallException
*/
public function testNoOverriddenMethodsThrowsException()
{
$voter = new DeprecatedVoterNothingImplementedFixture();
$voter->vote($this->token, new ObjectFixture(), array('foo'));
}
public function getData()
{
return array(
@ -113,6 +118,23 @@ class DeprecatedVoterFixture extends AbstractVoter
}
}
class DeprecatedVoterNothingImplementedFixture extends AbstractVoter
{
protected function getSupportedClasses()
{
return array(
'Symfony\Component\Security\Core\Tests\Authorization\Voter\ObjectFixture',
);
}
protected function getSupportedAttributes()
{
return array('foo', 'bar', 'baz');
}
// this is a bad voter that hasn't overridden isGranted or voteOnAttribute
}
class ObjectFixture
{
}

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Core\Tests\Authorization\Voter;
use Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter;

View File

@ -43,9 +43,9 @@ final class SecureRandom implements SecureRandomInterface
$this->logger = $logger;
// determine whether to use OpenSSL
if (!function_exists('openssl_random_pseudo_bytes')) {
if (!function_exists('random_bytes') && !function_exists('openssl_random_pseudo_bytes')) {
if (null !== $this->logger) {
$this->logger->notice('It is recommended that you enable the "openssl" extension for random number generation.');
$this->logger->notice('It is recommended that you install the "paragonie/random_compat" library or enable the "openssl" extension for random number generation.');
}
$this->useOpenSsl = false;
} else {
@ -58,6 +58,10 @@ final class SecureRandom implements SecureRandomInterface
*/
public function nextBytes($nbBytes)
{
if (function_exists('random_bytes')) {
return random_bytes($nbBytes);
}
// try OpenSSL
if ($this->useOpenSsl) {
$bytes = openssl_random_pseudo_bytes($nbBytes, $strong);

View File

@ -66,7 +66,7 @@ class GuardAuthenticationListener implements ListenerInterface
public function handle(GetResponseEvent $event)
{
if (null !== $this->logger) {
$this->logger->info('Checking for guard authentication credentials.', array('firewall_key' => $this->providerKey, 'authenticators' => count($this->guardAuthenticators)));
$this->logger->debug('Checking for guard authentication credentials.', array('firewall_key' => $this->providerKey, 'authenticators' => count($this->guardAuthenticators)));
}
foreach ($this->guardAuthenticators as $key => $guardAuthenticator) {
@ -75,6 +75,12 @@ class GuardAuthenticationListener implements ListenerInterface
$uniqueGuardKey = $this->providerKey.'_'.$key;
$this->executeGuardAuthenticator($uniqueGuardKey, $guardAuthenticator, $event);
if ($event->hasResponse()) {
$this->logger->debug(sprintf('The "%s" authenticator set the response. Any later authenticator will not be called', get_class($guardAuthenticator)));
break;
}
}
}
@ -83,7 +89,7 @@ class GuardAuthenticationListener implements ListenerInterface
$request = $event->getRequest();
try {
if (null !== $this->logger) {
$this->logger->info('Calling getCredentials on guard configurator.', array('firewall_key' => $this->providerKey, 'authenticator' => get_class($guardAuthenticator)));
$this->logger->debug('Calling getCredentials() on guard configurator.', array('firewall_key' => $this->providerKey, 'authenticator' => get_class($guardAuthenticator)));
}
// allow the authenticator to fetch authentication info from the request
@ -98,7 +104,7 @@ class GuardAuthenticationListener implements ListenerInterface
$token = new PreAuthenticationGuardToken($credentials, $uniqueGuardKey);
if (null !== $this->logger) {
$this->logger->info('Passing guard token information to the GuardAuthenticationProvider', array('firewall_key' => $this->providerKey, 'authenticator' => get_class($guardAuthenticator)));
$this->logger->debug('Passing guard token information to the GuardAuthenticationProvider', array('firewall_key' => $this->providerKey, 'authenticator' => get_class($guardAuthenticator)));
}
// pass the token into the AuthenticationManager system
// this indirectly calls GuardAuthenticationProvider::authenticate()
@ -130,13 +136,13 @@ class GuardAuthenticationListener implements ListenerInterface
$response = $this->guardHandler->handleAuthenticationSuccess($token, $request, $guardAuthenticator, $this->providerKey);
if ($response instanceof Response) {
if (null !== $this->logger) {
$this->logger->info('Guard authenticator set success response.', array('response' => $response, 'authenticator' => get_class($guardAuthenticator)));
$this->logger->debug('Guard authenticator set success response.', array('response' => $response, 'authenticator' => get_class($guardAuthenticator)));
}
$event->setResponse($response);
} else {
if (null !== $this->logger) {
$this->logger->info('Guard authenticator set no success response: request continues.', array('authenticator' => get_class($guardAuthenticator)));
$this->logger->debug('Guard authenticator set no success response: request continues.', array('authenticator' => get_class($guardAuthenticator)));
}
}
@ -167,7 +173,7 @@ class GuardAuthenticationListener implements ListenerInterface
{
if (null === $this->rememberMeServices) {
if (null !== $this->logger) {
$this->logger->info('Remember me skipped: it is not configured for the firewall.', array('authenticator' => get_class($guardAuthenticator)));
$this->logger->debug('Remember me skipped: it is not configured for the firewall.', array('authenticator' => get_class($guardAuthenticator)));
}
return;
@ -175,7 +181,7 @@ class GuardAuthenticationListener implements ListenerInterface
if (!$guardAuthenticator->supportsRememberMe()) {
if (null !== $this->logger) {
$this->logger->info('Remember me skipped: your authenticator does not support it.', array('authenticator' => get_class($guardAuthenticator)));
$this->logger->debug('Remember me skipped: your authenticator does not support it.', array('authenticator' => get_class($guardAuthenticator)));
}
return;

View File

@ -79,6 +79,36 @@ class GuardAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
$listener->handle($this->event);
}
public function testHandleSuccessStopsAfterResponseIsSet()
{
$authenticator1 = $this->getMock('Symfony\Component\Security\Guard\GuardAuthenticatorInterface');
$authenticator2 = $this->getMock('Symfony\Component\Security\Guard\GuardAuthenticatorInterface');
// mock the first authenticator to fail, and set a Response
$authenticator1
->expects($this->once())
->method('getCredentials')
->willThrowException(new AuthenticationException());
$this->guardAuthenticatorHandler
->expects($this->once())
->method('handleAuthenticationFailure')
->willReturn(new Response());
// the second authenticator should *never* be called
$authenticator2
->expects($this->never())
->method('getCredentials');
$listener = new GuardAuthenticationListener(
$this->guardAuthenticatorHandler,
$this->authenticationManager,
'my_firewall',
array($authenticator1, $authenticator2),
$this->logger
);
$listener->handle($this->event);
}
public function testHandleSuccessWithRememberMe()
{
$authenticator = $this->getMock('Symfony\Component\Security\Guard\GuardAuthenticatorInterface');
@ -201,7 +231,10 @@ class GuardAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
$this->request = new Request(array(), array(), array(), array(), array(), array());
$this->event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false);
$this->event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
->disableOriginalConstructor()
->setMethods(array('getRequest'))
->getMock();
$this->event
->expects($this->any())
->method('getRequest')
@ -218,5 +251,6 @@ class GuardAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
$this->event = null;
$this->logger = null;
$this->request = null;
$this->rememberMeServices = null;
}
}

View File

@ -11,6 +11,8 @@
namespace Symfony\Component\Security\Guard\Token;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
/**
* A marker interface that both guard tokens implement.
*
@ -20,6 +22,6 @@ namespace Symfony\Component\Security\Guard\Token;
*
* @author Ryan Weaver <ryan@knpuniversity.com>
*/
interface GuardTokenInterface
interface GuardTokenInterface extends TokenInterface
{
}

View File

@ -24,6 +24,7 @@
"replace": {
"symfony/security-core": "self.version",
"symfony/security-csrf": "self.version",
"symfony/security-guard": "self.version",
"symfony/security-http": "self.version"
},
"require-dev": {
@ -41,10 +42,11 @@
"suggest": {
"symfony/class-loader": "For using the ACL generateSql script",
"symfony/finder": "For using the ACL generateSql script",
"symfony/form": "",
"symfony/validator": "For using the user password constraint",
"symfony/routing": "For using the HttpUtils class to create sub-requests, redirect the user, and match URLs",
"doctrine/dbal": "For using the built-in ACL implementation",
"symfony/expression-language": "For using the expression voter"
"symfony/expression-language": "For using the expression voter",
"paragonie/random_compat": ""
},
"autoload": {
"psr-4": { "Symfony\\Component\\Security\\": "" }

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Serializer\Normalizer;
/*

View File

@ -17,6 +17,9 @@ use Symfony\Component\Serializer\Normalizer\CustomNormalizer;
class JsonEncoderTest extends \PHPUnit_Framework_TestCase
{
private $encoder;
private $serializer;
protected function setUp()
{
$this->encoder = new JsonEncoder();

View File

@ -41,21 +41,21 @@ class SerializerTest extends \PHPUnit_Framework_TestCase
*/
public function testNormalizeNoMatch()
{
$this->serializer = new Serializer(array($this->getMock('Symfony\Component\Serializer\Normalizer\CustomNormalizer')));
$this->serializer->normalize(new \stdClass(), 'xml');
$serializer = new Serializer(array($this->getMock('Symfony\Component\Serializer\Normalizer\CustomNormalizer')));
$serializer->normalize(new \stdClass(), 'xml');
}
public function testNormalizeTraversable()
{
$this->serializer = new Serializer(array(), array('json' => new JsonEncoder()));
$result = $this->serializer->serialize(new TraversableDummy(), 'json');
$serializer = new Serializer(array(), array('json' => new JsonEncoder()));
$result = $serializer->serialize(new TraversableDummy(), 'json');
$this->assertEquals('{"foo":"foo","bar":"bar"}', $result);
}
public function testNormalizeGivesPriorityToInterfaceOverTraversable()
{
$this->serializer = new Serializer(array(new CustomNormalizer()), array('json' => new JsonEncoder()));
$result = $this->serializer->serialize(new NormalizableTraversableDummy(), 'json');
$serializer = new Serializer(array(new CustomNormalizer()), array('json' => new JsonEncoder()));
$result = $serializer->serialize(new NormalizableTraversableDummy(), 'json');
$this->assertEquals('{"foo":"normalizedFoo","bar":"normalizedBar"}', $result);
}
@ -64,8 +64,8 @@ class SerializerTest extends \PHPUnit_Framework_TestCase
*/
public function testNormalizeOnDenormalizer()
{
$this->serializer = new Serializer(array(new TestDenormalizer()), array());
$this->assertTrue($this->serializer->normalize(new \stdClass(), 'json'));
$serializer = new Serializer(array(new TestDenormalizer()), array());
$this->assertTrue($serializer->normalize(new \stdClass(), 'json'));
}
/**
@ -73,8 +73,8 @@ class SerializerTest extends \PHPUnit_Framework_TestCase
*/
public function testDenormalizeNoMatch()
{
$this->serializer = new Serializer(array($this->getMock('Symfony\Component\Serializer\Normalizer\CustomNormalizer')));
$this->serializer->denormalize('foo', 'stdClass');
$serializer = new Serializer(array($this->getMock('Symfony\Component\Serializer\Normalizer\CustomNormalizer')));
$serializer->denormalize('foo', 'stdClass');
}
/**
@ -82,40 +82,40 @@ class SerializerTest extends \PHPUnit_Framework_TestCase
*/
public function testDenormalizeOnNormalizer()
{
$this->serializer = new Serializer(array(new TestNormalizer()), array());
$serializer = new Serializer(array(new TestNormalizer()), array());
$data = array('title' => 'foo', 'numbers' => array(5, 3));
$this->assertTrue($this->serializer->denormalize(json_encode($data), 'stdClass', 'json'));
$this->assertTrue($serializer->denormalize(json_encode($data), 'stdClass', 'json'));
}
public function testCustomNormalizerCanNormalizeCollectionsAndScalar()
{
$this->serializer = new Serializer(array(new TestNormalizer()), array());
$this->assertNull($this->serializer->normalize(array('a', 'b')));
$this->assertNull($this->serializer->normalize(new \ArrayObject(array('c', 'd'))));
$this->assertNull($this->serializer->normalize(array()));
$this->assertNull($this->serializer->normalize('test'));
$serializer = new Serializer(array(new TestNormalizer()), array());
$this->assertNull($serializer->normalize(array('a', 'b')));
$this->assertNull($serializer->normalize(new \ArrayObject(array('c', 'd'))));
$this->assertNull($serializer->normalize(array()));
$this->assertNull($serializer->normalize('test'));
}
public function testSerialize()
{
$this->serializer = new Serializer(array(new GetSetMethodNormalizer()), array('json' => new JsonEncoder()));
$serializer = new Serializer(array(new GetSetMethodNormalizer()), array('json' => new JsonEncoder()));
$data = array('title' => 'foo', 'numbers' => array(5, 3));
$result = $this->serializer->serialize(Model::fromArray($data), 'json');
$result = $serializer->serialize(Model::fromArray($data), 'json');
$this->assertEquals(json_encode($data), $result);
}
public function testSerializeScalar()
{
$this->serializer = new Serializer(array(), array('json' => new JsonEncoder()));
$result = $this->serializer->serialize('foo', 'json');
$serializer = new Serializer(array(), array('json' => new JsonEncoder()));
$result = $serializer->serialize('foo', 'json');
$this->assertEquals('"foo"', $result);
}
public function testSerializeArrayOfScalars()
{
$this->serializer = new Serializer(array(), array('json' => new JsonEncoder()));
$serializer = new Serializer(array(), array('json' => new JsonEncoder()));
$data = array('foo', array(5, 3));
$result = $this->serializer->serialize($data, 'json');
$result = $serializer->serialize($data, 'json');
$this->assertEquals(json_encode($data), $result);
}
@ -124,9 +124,9 @@ class SerializerTest extends \PHPUnit_Framework_TestCase
*/
public function testSerializeNoEncoder()
{
$this->serializer = new Serializer(array(), array());
$serializer = new Serializer(array(), array());
$data = array('title' => 'foo', 'numbers' => array(5, 3));
$this->serializer->serialize($data, 'json');
$serializer->serialize($data, 'json');
}
/**
@ -134,26 +134,26 @@ class SerializerTest extends \PHPUnit_Framework_TestCase
*/
public function testSerializeNoNormalizer()
{
$this->serializer = new Serializer(array(), array('json' => new JsonEncoder()));
$serializer = new Serializer(array(), array('json' => new JsonEncoder()));
$data = array('title' => 'foo', 'numbers' => array(5, 3));
$this->serializer->serialize(Model::fromArray($data), 'json');
$serializer->serialize(Model::fromArray($data), 'json');
}
public function testDeserialize()
{
$this->serializer = new Serializer(array(new GetSetMethodNormalizer()), array('json' => new JsonEncoder()));
$serializer = new Serializer(array(new GetSetMethodNormalizer()), array('json' => new JsonEncoder()));
$data = array('title' => 'foo', 'numbers' => array(5, 3));
$result = $this->serializer->deserialize(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json');
$result = $serializer->deserialize(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json');
$this->assertEquals($data, $result->toArray());
}
public function testDeserializeUseCache()
{
$this->serializer = new Serializer(array(new GetSetMethodNormalizer()), array('json' => new JsonEncoder()));
$serializer = new Serializer(array(new GetSetMethodNormalizer()), array('json' => new JsonEncoder()));
$data = array('title' => 'foo', 'numbers' => array(5, 3));
$this->serializer->deserialize(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json');
$serializer->deserialize(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json');
$data = array('title' => 'bar', 'numbers' => array(2, 8));
$result = $this->serializer->deserialize(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json');
$result = $serializer->deserialize(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json');
$this->assertEquals($data, $result->toArray());
}
@ -162,9 +162,9 @@ class SerializerTest extends \PHPUnit_Framework_TestCase
*/
public function testDeserializeNoNormalizer()
{
$this->serializer = new Serializer(array(), array('json' => new JsonEncoder()));
$serializer = new Serializer(array(), array('json' => new JsonEncoder()));
$data = array('title' => 'foo', 'numbers' => array(5, 3));
$this->serializer->deserialize(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json');
$serializer->deserialize(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json');
}
/**
@ -172,9 +172,9 @@ class SerializerTest extends \PHPUnit_Framework_TestCase
*/
public function testDeserializeWrongNormalizer()
{
$this->serializer = new Serializer(array(new CustomNormalizer()), array('json' => new JsonEncoder()));
$serializer = new Serializer(array(new CustomNormalizer()), array('json' => new JsonEncoder()));
$data = array('title' => 'foo', 'numbers' => array(5, 3));
$this->serializer->deserialize(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json');
$serializer->deserialize(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json');
}
/**
@ -182,45 +182,45 @@ class SerializerTest extends \PHPUnit_Framework_TestCase
*/
public function testDeserializeNoEncoder()
{
$this->serializer = new Serializer(array(), array());
$serializer = new Serializer(array(), array());
$data = array('title' => 'foo', 'numbers' => array(5, 3));
$this->serializer->deserialize(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json');
$serializer->deserialize(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json');
}
public function testDeserializeSupported()
{
$this->serializer = new Serializer(array(new GetSetMethodNormalizer()), array());
$serializer = new Serializer(array(new GetSetMethodNormalizer()), array());
$data = array('title' => 'foo', 'numbers' => array(5, 3));
$this->assertTrue($this->serializer->supportsDenormalization(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json'));
$this->assertTrue($serializer->supportsDenormalization(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json'));
}
public function testDeserializeNotSupported()
{
$this->serializer = new Serializer(array(new GetSetMethodNormalizer()), array());
$serializer = new Serializer(array(new GetSetMethodNormalizer()), array());
$data = array('title' => 'foo', 'numbers' => array(5, 3));
$this->assertFalse($this->serializer->supportsDenormalization(json_encode($data), 'stdClass', 'json'));
$this->assertFalse($serializer->supportsDenormalization(json_encode($data), 'stdClass', 'json'));
}
public function testDeserializeNotSupportedMissing()
{
$this->serializer = new Serializer(array(), array());
$serializer = new Serializer(array(), array());
$data = array('title' => 'foo', 'numbers' => array(5, 3));
$this->assertFalse($this->serializer->supportsDenormalization(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json'));
$this->assertFalse($serializer->supportsDenormalization(json_encode($data), '\Symfony\Component\Serializer\Tests\Model', 'json'));
}
public function testEncode()
{
$this->serializer = new Serializer(array(), array('json' => new JsonEncoder()));
$serializer = new Serializer(array(), array('json' => new JsonEncoder()));
$data = array('foo', array(5, 3));
$result = $this->serializer->encode($data, 'json');
$result = $serializer->encode($data, 'json');
$this->assertEquals(json_encode($data), $result);
}
public function testDecode()
{
$this->serializer = new Serializer(array(), array('json' => new JsonEncoder()));
$serializer = new Serializer(array(), array('json' => new JsonEncoder()));
$data = array('foo', array(5, 3));
$result = $this->serializer->decode(json_encode($data), 'json');
$result = $serializer->decode(json_encode($data), 'json');
$this->assertEquals($data, $result);
}

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraint;

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraint;

View File

@ -310,6 +310,10 @@
<source>This value does not match the expected {{ charset }} charset.</source>
<target>Ez az érték nem az elvárt {{ charset }} karakterkódolást használja.</target>
</trans-unit>
<trans-unit id="81">
<source>This is not a valid Business Identifier Code (BIC).</source>
<target>Érvénytelen nemzetközi bankazonosító kód (BIC/SWIFT).</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Validator\Tests\Constraints;
use Symfony\Component\Validator\Constraints\BicValidator;

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Validator\Tests\Mapping\Loader;
use Symfony\Component\Validator\Mapping\ClassMetadata;

View File

@ -44,6 +44,16 @@ class RecursiveContextualValidator implements ContextualValidatorInterface
*/
private $context;
/**
* @var string
*/
private $defaultPropertyPath;
/**
* @var array
*/
private $defaultGroups;
/**
* @var MetadataFactoryInterface
*/

View File

@ -448,7 +448,7 @@ class CliDumper extends AbstractDumper
}
if ('\\' === DIRECTORY_SEPARATOR) {
static::$defaultColors = @(false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI'));
static::$defaultColors = @(false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI') || 'xterm' === getenv('TERM'));
} elseif (function_exists('posix_isatty')) {
$h = stream_get_meta_data($this->outputStream) + array('wrapper_type' => null);
$h = 'Output' === $h['stream_type'] && 'PHP' === $h['wrapper_type'] ? fopen('php://stdout', 'wb') : $this->outputStream;

View File

@ -1,13 +1,13 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Exception;