Merge branch '2.8' into 3.2

* 2.8:
  Misspelled word
  Display a better error design when the toolbar cannot be displayed
  do not validate empty values
  [Console] fix description of INF default values
  [PropertyAccess] Fix TypeError discard
  [Validator] Throw exception on Comparison constraints null options
  Identify tty tests in Component/Process
  [Security] Fix annotation
This commit is contained in:
Fabien Potencier 2017-07-03 11:06:20 +03:00
commit d051ef42b3
32 changed files with 183 additions and 32 deletions

View File

@ -63,6 +63,10 @@ class UniqueEntityValidator extends ConstraintValidator
throw new ConstraintDefinitionException('At least one field has to be specified.');
}
if (null === $entity) {
return;
}
if ($constraint->em) {
$em = $this->registry->getManager($constraint->em);

View File

@ -522,3 +522,33 @@
display: none;
}
}
/***** Error Toolbar *****/
.sf-error-toolbar .sf-toolbarreset {
background: #222;
color: #f5f5f5;
font: 13px/36px Arial, sans-serif;
height: 36px;
padding: 0 15px;
text-align: left;
}
.sf-error-toolbar .sf-toolbarreset svg {
height: auto;
}
.sf-error-toolbar .sf-toolbarreset a {
color: #99cdd8;
margin-left: 5px;
text-decoration: underline;
}
.sf-error-toolbar .sf-toolbarreset a:hover {
text-decoration: none;
}
.sf-error-toolbar .sf-toolbarreset .sf-toolbar-icon {
float: left;
padding: 5px 0;
margin-right: 10px;
}

View File

@ -96,17 +96,15 @@
})
},
function(xhr) {
var errorToolbarHtml = '
<style>
.sfErrorToolbar { background: #222; bottom: 0; color: #f5f5f5; font: 13px/36px Arial, sans-serif; height: 36px; padding: 0 15px; position: fixed; width: 100%; }
.sfErrorToolbar a { color: #99cdd8; margin-left: 5px; text-decoration: underline; }
.sfErrorToolbar a:hover { text-decoration: none; }
</style>
<div class="sfErrorToolbar">An error occurred while loading the web debug toolbar. <a href="{{ path("_profiler", { "token": token }) }}">Open the web profiler.</a></div>
';
if (xhr.status !== 0) {
window.document.body.insertAdjacentHTML('beforeend', errorToolbarHtml);
var sfwdt = document.getElementById('sfwdt{{ token }}');
sfwdt.innerHTML = '\
<div class="sf-toolbarreset">\
<div class="sf-toolbar-icon"><svg width="26" height="28" xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" viewBox="0 0 26 28" enable-background="new 0 0 26 28" xml:space="preserve"><path fill="#FFFFFF" d="M13 0C5.8 0 0 5.8 0 13c0 7.2 5.8 13 13 13c7.2 0 13-5.8 13-13C26 5.8 20.2 0 13 0z M20 7.5 c-0.6 0-1-0.3-1-0.9c0-0.2 0-0.4 0.2-0.6c0.1-0.3 0.2-0.3 0.2-0.4c0-0.3-0.5-0.4-0.7-0.4c-2 0.1-2.5 2.7-2.9 4.8l-0.2 1.1 c1.1 0.2 1.9 0 2.4-0.3c0.6-0.4-0.2-0.8-0.1-1.3C18 9.2 18.4 9 18.7 8.9c0.5 0 0.8 0.5 0.8 1c0 0.8-1.1 2-3.3 1.9 c-0.3 0-0.5 0-0.7-0.1L15 14.1c-0.4 1.7-0.9 4.1-2.6 6.2c-1.5 1.8-3.1 2.1-3.8 2.1c-1.3 0-2.1-0.6-2.2-1.6c0-0.9 0.8-1.4 1.3-1.4 c0.7 0 1.2 0.5 1.2 1.1c0 0.5-0.2 0.6-0.4 0.7c-0.1 0.1-0.3 0.2-0.3 0.4c0 0.1 0.1 0.3 0.4 0.3c0.5 0 0.9-0.3 1.2-0.5 c1.3-1 1.7-2.9 2.4-6.2l0.1-0.8c0.2-1.1 0.5-2.3 0.8-3.5c-0.9-0.7-1.4-1.5-2.6-1.8c-0.8-0.2-1.3 0-1.7 0.4C8.4 10 8.6 10.7 9 11.1 l0.7 0.7c0.8 0.9 1.3 1.7 1.1 2.7c-0.3 1.6-2.1 2.8-4.3 2.1c-1.9-0.6-2.2-1.9-2-2.7c0.2-0.6 0.7-0.8 1.2-0.6 c0.5 0.2 0.7 0.8 0.6 1.3c0 0.1 0 0.1-0.1 0.3C6 15 5.9 15.2 5.9 15.3c-0.1 0.4 0.4 0.7 0.8 0.8c0.8 0.3 1.7-0.2 1.9-0.9 c0.2-0.6-0.2-1.1-0.4-1.2l-0.8-0.9c-0.4-0.4-1.2-1.5-0.8-2.8c0.2-0.5 0.5-1 0.9-1.4c1-0.7 2-0.8 3-0.6c1.3 0.4 1.9 1.2 2.8 1.9 c0.5-1.3 1.1-2.6 2-3.8c0.9-1 2-1.7 3.3-1.8C20 4.8 21 5.4 21 6.3C21 6.7 20.8 7.5 20 7.5z"/></svg></div>\
An error occurred while loading the web debug toolbar. <a href="{{ path("_profiler", { "token": token }) }}">Open the web profiler.</a>\
</div>\
';
sfwdt.setAttribute('class', 'sf-toolbar sf-error-toolbar');
}
},
{ maxTries: 5 }

View File

@ -103,7 +103,7 @@ class JsonDescriptor extends Descriptor
'is_required' => $argument->isRequired(),
'is_array' => $argument->isArray(),
'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $argument->getDescription()),
'default' => $argument->getDefault(),
'default' => INF === $argument->getDefault() ? 'INF' : $argument->getDefault(),
);
}
@ -121,7 +121,7 @@ class JsonDescriptor extends Descriptor
'is_value_required' => $option->isValueRequired(),
'is_multiple' => $option->isArray(),
'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $option->getDescription()),
'default' => $option->getDefault(),
'default' => INF === $option->getDefault() ? 'INF' : $option->getDefault(),
);
}

View File

@ -262,6 +262,10 @@ class TextDescriptor extends Descriptor
*/
private function formatDefaultValue($default)
{
if (INF === $default) {
return 'INF';
}
if (is_string($default)) {
$default = OutputFormatter::escape($default);
} elseif (is_array($default)) {

View File

@ -32,6 +32,7 @@ class ObjectsProvider
'input_argument_3' => new InputArgument('argument_name', InputArgument::OPTIONAL, 'argument description', 'default_value'),
'input_argument_4' => new InputArgument('argument_name', InputArgument::REQUIRED, "multiline\nargument description"),
'input_argument_with_style' => new InputArgument('argument_name', InputArgument::OPTIONAL, 'argument description', '<comment>style</>'),
'input_argument_with_default_inf_value' => new InputArgument('argument_name', InputArgument::OPTIONAL, 'argument description', INF),
);
}
@ -46,6 +47,7 @@ class ObjectsProvider
'input_option_6' => new InputOption('option_name', array('o', 'O'), InputOption::VALUE_REQUIRED, 'option with multiple shortcuts'),
'input_option_with_style' => new InputOption('option_name', 'o', InputOption::VALUE_REQUIRED, 'option description', '<comment>style</>'),
'input_option_with_style_array' => new InputOption('option_name', 'o', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'option description', array('<comment>Hello</comment>', '<info>world</info>')),
'input_option_with_default_inf_value' => new InputOption('option_name', 'o', InputOption::VALUE_OPTIONAL, 'option description', INF),
);
}

View File

@ -0,0 +1,7 @@
{
"name": "argument_name",
"is_required": false,
"is_array": false,
"description": "argument description",
"default": "INF"
}

View File

@ -0,0 +1,7 @@
**argument_name:**
* Name: argument_name
* Is required: no
* Is array: no
* Description: argument description
* Default: `INF`

View File

@ -0,0 +1 @@
<info>argument_name</info> argument description<comment> [default: INF]</comment>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<argument name="argument_name" is_required="0" is_array="0">
<description>argument description</description>
<defaults>
<default>INF</default>
</defaults>
</argument>

View File

@ -0,0 +1,9 @@
{
"name": "--option_name",
"shortcut": "-o",
"accept_value": true,
"is_value_required": false,
"is_multiple": false,
"description": "option description",
"default": "INF"
}

View File

@ -0,0 +1,9 @@
**option_name:**
* Name: `--option_name`
* Shortcut: `-o`
* Accept value: yes
* Is value required: no
* Is multiple: no
* Description: option description
* Default: `INF`

View File

@ -0,0 +1 @@
<info>-o, --option_name[=OPTION_NAME]</info> option description<comment> [default: INF]</comment>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<option name="--option_name" shortcut="-o" accept_value="1" is_value_required="0" is_multiple="0">
<description>option description</description>
<defaults>
<default>INF</default>
</defaults>
</option>

View File

@ -435,6 +435,9 @@ class ProcessTest extends TestCase
$this->assertGreaterThan(0, $process->getExitCode());
}
/**
* @group tty
*/
public function testTTYCommand()
{
if ('\\' === DIRECTORY_SEPARATOR) {
@ -450,6 +453,9 @@ class ProcessTest extends TestCase
$this->assertSame(Process::STATUS_TERMINATED, $process->getStatus());
}
/**
* @group tty
*/
public function testTTYCommandExitCode()
{
if ('\\' === DIRECTORY_SEPARATOR) {

View File

@ -269,7 +269,7 @@ class PropertyAccessor implements PropertyAccessorInterface
private static function throwInvalidArgumentException($message, $trace, $i)
{
if (isset($trace[$i]['file']) && __FILE__ === $trace[$i]['file']) {
if (isset($trace[$i]['file']) && __FILE__ === $trace[$i]['file'] && isset($trace[$i]['args'][0])) {
$pos = strpos($message, $delim = 'must be of the type ') ?: (strpos($message, $delim = 'must be an instance of ') ?: strpos($message, $delim = 'must implement interface '));
$pos += strlen($delim);
$type = $trace[$i]['args'][0];

View File

@ -0,0 +1,31 @@
<?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\PropertyAccess\Tests\Fixtures;
/**
* @author Kévin Dunglas <dunglas@gmail.com>
*/
class ReturnTyped
{
public function getFoos(): array
{
return 'It doesn\'t respect the return type on purpose';
}
public function addFoo(\DateTime $dateTime)
{
}
public function removeFoo(\DateTime $dateTime)
{
}
}

View File

@ -15,6 +15,7 @@ use PHPUnit\Framework\TestCase;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\PropertyAccess\Exception\NoSuchIndexException;
use Symfony\Component\PropertyAccess\PropertyAccessor;
use Symfony\Component\PropertyAccess\Tests\Fixtures\ReturnTyped;
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClass;
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassMagicCall;
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassMagicGet;
@ -650,4 +651,16 @@ class PropertyAccessorTest extends TestCase
$this->propertyAccessor->setValue($object, 'property', 'foo');
}
/**
* @requires PHP 7
*
* @expectedException \TypeError
*/
public function testDoNotDiscardReturnTypeError()
{
$object = new ReturnTyped();
$this->propertyAccessor->setValue($object, 'foos', array(new \DateTime()));
}
}

View File

@ -27,7 +27,7 @@ class UsernamePasswordToken extends AbstractToken
* Constructor.
*
* @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 mixed $credentials This usually is the password of the user
* @param string $providerKey The provider key
* @param (RoleInterface|string)[] $roles An array of roles
*

View File

@ -39,6 +39,10 @@ class UserPasswordValidator extends ConstraintValidator
throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\UserPassword');
}
if (null === $password || '' === $password) {
return;
}
$user = $this->tokenStorage->getToken()->getUser();
if (!$user instanceof UserInterface) {

View File

@ -30,6 +30,10 @@ abstract class AbstractComparison extends Constraint
*/
public function __construct($options = null)
{
if (null === $options) {
$options = array();
}
if (is_array($options) && !isset($options['value'])) {
throw new ConstraintDefinitionException(sprintf(
'The %s constraint requires the "value" option to be set.',

View File

@ -47,7 +47,7 @@ class UrlValidator extends ConstraintValidator
throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Url');
}
if (null === $value) {
if (null === $value || '' === $value) {
return;
}

View File

@ -76,7 +76,7 @@
</trans-unit>
<trans-unit id="19">
<source>This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.</source>
<target>Cette chaine est trop longue. Elle doit avoir au maximum {{ limit }} caractère.|Cette chaine est trop longue. Elle doit avoir au maximum {{ limit }} caractères.</target>
<target>Cette chaîne est trop longue. Elle doit avoir au maximum {{ limit }} caractère.|Cette chaîne est trop longue. Elle doit avoir au maximum {{ limit }} caractères.</target>
</trans-unit>
<trans-unit id="20">
<source>This value should be {{ limit }} or more.</source>
@ -84,7 +84,7 @@
</trans-unit>
<trans-unit id="21">
<source>This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more.</source>
<target>Cette chaine est trop courte. Elle doit avoir au minimum {{ limit }} caractère.|Cette chaine est trop courte. Elle doit avoir au minimum {{ limit }} caractères.</target>
<target>Cette chaîne est trop courte. Elle doit avoir au minimum {{ limit }} caractère.|Cette chaîne est trop courte. Elle doit avoir au minimum {{ limit }} caractères.</target>
</trans-unit>
<trans-unit id="22">
<source>This value should not be blank.</source>
@ -180,7 +180,7 @@
</trans-unit>
<trans-unit id="48">
<source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
<target>Cette chaine doit avoir exactement {{ limit }} caractère.|Cette chaine doit avoir exactement {{ limit }} caractères.</target>
<target>Cette chaîne doit avoir exactement {{ limit }} caractère.|Cette chaîne doit avoir exactement {{ limit }} caractères.</target>
</trans-unit>
<trans-unit id="49">
<source>The file was only partially uploaded.</source>

View File

@ -65,14 +65,21 @@ abstract class AbstractComparisonValidatorTestCase extends ConstraintValidatorTe
return $result;
}
public function provideInvalidConstraintOptions()
{
return array(
array(null),
array(array()),
);
}
/**
* @dataProvider provideInvalidConstraintOptions
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
*/
public function testThrowsConstraintExceptionIfNoValueOrProperty()
public function testThrowsConstraintExceptionIfNoValueOrProperty($options)
{
$comparison = $this->createConstraint(array());
$this->validator->validate('some value', $comparison);
$this->createConstraint($options);
}
/**
@ -163,11 +170,11 @@ abstract class AbstractComparisonValidatorTestCase extends ConstraintValidatorTe
abstract public function provideInvalidComparisons();
/**
* @param array $options Options for the constraint
* @param array|null $options Options for the constraint
*
* @return Constraint
*/
abstract protected function createConstraint(array $options);
abstract protected function createConstraint(array $options = null);
/**
* @return string|null

View File

@ -24,7 +24,7 @@ class EqualToValidatorTest extends AbstractComparisonValidatorTestCase
return new EqualToValidator();
}
protected function createConstraint(array $options)
protected function createConstraint(array $options = null)
{
return new EqualTo($options);
}

View File

@ -24,7 +24,7 @@ class GreaterThanOrEqualValidatorTest extends AbstractComparisonValidatorTestCas
return new GreaterThanOrEqualValidator();
}
protected function createConstraint(array $options)
protected function createConstraint(array $options = null)
{
return new GreaterThanOrEqual($options);
}

View File

@ -24,7 +24,7 @@ class GreaterThanValidatorTest extends AbstractComparisonValidatorTestCase
return new GreaterThanValidator();
}
protected function createConstraint(array $options)
protected function createConstraint(array $options = null)
{
return new GreaterThan($options);
}

View File

@ -24,7 +24,7 @@ class IdenticalToValidatorTest extends AbstractComparisonValidatorTestCase
return new IdenticalToValidator();
}
protected function createConstraint(array $options)
protected function createConstraint(array $options = null)
{
return new IdenticalTo($options);
}

View File

@ -24,7 +24,7 @@ class LessThanOrEqualValidatorTest extends AbstractComparisonValidatorTestCase
return new LessThanOrEqualValidator();
}
protected function createConstraint(array $options)
protected function createConstraint(array $options = null)
{
return new LessThanOrEqual($options);
}

View File

@ -24,7 +24,7 @@ class LessThanValidatorTest extends AbstractComparisonValidatorTestCase
return new LessThanValidator();
}
protected function createConstraint(array $options)
protected function createConstraint(array $options = null)
{
return new LessThan($options);
}

View File

@ -24,7 +24,7 @@ class NotEqualToValidatorTest extends AbstractComparisonValidatorTestCase
return new NotEqualToValidator();
}
protected function createConstraint(array $options)
protected function createConstraint(array $options = null)
{
return new NotEqualTo($options);
}

View File

@ -24,7 +24,7 @@ class NotIdenticalToValidatorTest extends AbstractComparisonValidatorTestCase
return new NotIdenticalToValidator();
}
protected function createConstraint(array $options)
protected function createConstraint(array $options = null)
{
return new NotIdenticalTo($options);
}