Merge branch '5.2' into 5.x
* 5.2: [Uid] fix checking for valid UUIDs [Validator] Fix DebugCommand check parent types for label_format and translation_domain [HttpKernel] Configure the ErrorHandler even when it is overriden Allow relative path to composer cache [RateLimiter] Fix infinite values with NoLimiter
This commit is contained in:
commit
3141873bf0
@ -154,6 +154,18 @@ $COMPOSER = file_exists($COMPOSER = $oldPwd.'/composer.phar')
|
||||
? ('#!/usr/bin/env php' === file_get_contents($COMPOSER, false, null, 0, 18) ? $PHP : '').' '.escapeshellarg($COMPOSER) // detect shell wrappers by looking at the shebang
|
||||
: 'composer';
|
||||
|
||||
$prevCacheDir = getenv('COMPOSER_CACHE_DIR');
|
||||
if ($prevCacheDir) {
|
||||
if (false === $absoluteCacheDir = realpath($prevCacheDir)) {
|
||||
@mkdir($prevCacheDir, 0777, true);
|
||||
$absoluteCacheDir = realpath($prevCacheDir);
|
||||
}
|
||||
if ($absoluteCacheDir) {
|
||||
putenv("COMPOSER_CACHE_DIR=$absoluteCacheDir");
|
||||
} else {
|
||||
$prevCacheDir = false;
|
||||
}
|
||||
}
|
||||
$SYMFONY_PHPUNIT_REMOVE = $getEnvVar('SYMFONY_PHPUNIT_REMOVE', 'phpspec/prophecy'.($PHPUNIT_VERSION < 6.0 ? ' symfony/yaml' : ''));
|
||||
$configurationHash = md5(implode(\PHP_EOL, [md5_file(__FILE__), $SYMFONY_PHPUNIT_REMOVE, (int) $PHPUNIT_REMOVE_RETURN_TYPEHINT]));
|
||||
$PHPUNIT_VERSION_DIR = sprintf('phpunit-%s-%d', $PHPUNIT_VERSION, $PHPUNIT_REMOVE_RETURN_TYPEHINT);
|
||||
@ -236,6 +248,9 @@ if (!file_exists("$PHPUNIT_DIR/$PHPUNIT_VERSION_DIR/phpunit") || $configurationH
|
||||
// --no-suggest is not in the list to keep compat with composer 1.0, which is shipped with Ubuntu 16.04LTS
|
||||
$exit = proc_close(proc_open("$q$COMPOSER install --no-dev --prefer-dist --no-progress $q", [], $p, getcwd()));
|
||||
putenv('COMPOSER_ROOT_VERSION'.(false !== $prevRoot ? '='.$prevRoot : ''));
|
||||
if ($prevCacheDir) {
|
||||
putenv("COMPOSER_CACHE_DIR=$prevCacheDir");
|
||||
}
|
||||
if ($exit) {
|
||||
exit($exit);
|
||||
}
|
||||
|
@ -154,7 +154,11 @@ class ViolationMapper implements ViolationMapperInterface
|
||||
$messageTemplate = $violation->getMessageTemplate();
|
||||
|
||||
if (false !== strpos($message, '{{ label }}') || false !== strpos($messageTemplate, '{{ label }}')) {
|
||||
$labelFormat = $scope->getConfig()->getOption('label_format');
|
||||
$form = $scope;
|
||||
|
||||
do {
|
||||
$labelFormat = $form->getConfig()->getOption('label_format');
|
||||
} while (null === $labelFormat && null !== $form = $form->getParent());
|
||||
|
||||
if (null !== $labelFormat) {
|
||||
$label = str_replace(
|
||||
@ -180,10 +184,16 @@ class ViolationMapper implements ViolationMapperInterface
|
||||
}
|
||||
|
||||
if (null !== $this->translator) {
|
||||
$form = $scope;
|
||||
|
||||
do {
|
||||
$translationDomain = $form->getConfig()->getOption('translation_domain');
|
||||
} while (null === $translationDomain && null !== $form = $form->getParent());
|
||||
|
||||
$label = $this->translator->trans(
|
||||
$label,
|
||||
$scope->getConfig()->getOption('label_translation_parameters', []),
|
||||
$scope->getConfig()->getOption('translation_domain')
|
||||
$translationDomain
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1742,6 +1742,50 @@ class ViolationMapperTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function testLabelFormatDefinedByParentType()
|
||||
{
|
||||
$form = $this->getForm('', null, null, [], false, true, [
|
||||
'label_format' => 'form.%name%',
|
||||
]);
|
||||
$child = $this->getForm('foo', 'foo');
|
||||
$form->add($child);
|
||||
|
||||
$violation = new ConstraintViolation('Message "{{ label }}"', null, [], null, 'data.foo', null);
|
||||
$this->mapper->mapViolation($violation, $form);
|
||||
|
||||
$errors = iterator_to_array($child->getErrors());
|
||||
|
||||
$this->assertCount(1, $errors, $child->getName().' should have an error, but has none');
|
||||
$this->assertSame('Message "form.foo"', $errors[0]->getMessage());
|
||||
}
|
||||
|
||||
public function testLabelPlaceholderTranslatedWithTranslationDomainDefinedByParentType()
|
||||
{
|
||||
$translator = $this->createMock(TranslatorInterface::class);
|
||||
$translator->expects($this->any())
|
||||
->method('trans')
|
||||
->with('foo', [], 'domain')
|
||||
->willReturn('translated foo label')
|
||||
;
|
||||
$this->mapper = new ViolationMapper(null, $translator);
|
||||
|
||||
$form = $this->getForm('', null, null, [], false, true, [
|
||||
'translation_domain' => 'domain',
|
||||
]);
|
||||
$child = $this->getForm('foo', 'foo', null, [], false, true, [
|
||||
'label' => 'foo',
|
||||
]);
|
||||
$form->add($child);
|
||||
|
||||
$violation = new ConstraintViolation('Message "{{ label }}"', null, [], null, 'data.foo', null);
|
||||
$this->mapper->mapViolation($violation, $form);
|
||||
|
||||
$errors = iterator_to_array($child->getErrors());
|
||||
|
||||
$this->assertCount(1, $errors, $child->getName().' should have an error, but has none');
|
||||
$this->assertSame('Message "translated foo label"', $errors[0]->getMessage());
|
||||
}
|
||||
|
||||
public function testTranslatorNotCalledWithoutLabel()
|
||||
{
|
||||
$renderer = $this->getMockBuilder(FormRenderer::class)
|
||||
|
@ -32,6 +32,7 @@ use Symfony\Component\HttpKernel\KernelEvents;
|
||||
*/
|
||||
class DebugHandlersListener implements EventSubscriberInterface
|
||||
{
|
||||
private $earlyHandler;
|
||||
private $exceptionHandler;
|
||||
private $logger;
|
||||
private $deprecationLogger;
|
||||
@ -53,6 +54,10 @@ class DebugHandlersListener implements EventSubscriberInterface
|
||||
*/
|
||||
public function __construct(callable $exceptionHandler = null, LoggerInterface $logger = null, $levels = \E_ALL, ?int $throwAt = \E_ALL, bool $scream = true, $fileLinkFormat = null, bool $scope = true, LoggerInterface $deprecationLogger = null)
|
||||
{
|
||||
$handler = set_exception_handler('var_dump');
|
||||
$this->earlyHandler = \is_array($handler) ? $handler[0] : null;
|
||||
restore_exception_handler();
|
||||
|
||||
$this->exceptionHandler = $exceptionHandler;
|
||||
$this->logger = $logger;
|
||||
$this->levels = null === $levels ? \E_ALL : $levels;
|
||||
@ -80,6 +85,10 @@ class DebugHandlersListener implements EventSubscriberInterface
|
||||
$handler = \is_array($handler) ? $handler[0] : null;
|
||||
restore_exception_handler();
|
||||
|
||||
if (!$handler instanceof ErrorHandler) {
|
||||
$handler = $this->earlyHandler;
|
||||
}
|
||||
|
||||
if ($handler instanceof ErrorHandler) {
|
||||
if ($this->logger || $this->deprecationLogger) {
|
||||
$this->setDefaultLoggers($handler);
|
||||
|
@ -29,12 +29,12 @@ final class NoLimiter implements LimiterInterface
|
||||
{
|
||||
public function reserve(int $tokens = 1, ?float $maxTime = null): Reservation
|
||||
{
|
||||
return new Reservation(time(), new RateLimit(\INF, new \DateTimeImmutable(), true, \INF));
|
||||
return new Reservation(time(), new RateLimit(\PHP_INT_MAX, new \DateTimeImmutable(), true, \PHP_INT_MAX));
|
||||
}
|
||||
|
||||
public function consume(int $tokens = 1): RateLimit
|
||||
{
|
||||
return new RateLimit(\INF, new \DateTimeImmutable(), true, \INF);
|
||||
return new RateLimit(\PHP_INT_MAX, new \DateTimeImmutable(), true, \PHP_INT_MAX);
|
||||
}
|
||||
|
||||
public function reset(): void
|
||||
|
@ -0,0 +1,32 @@
|
||||
<?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\RateLimiter\Tests\Policy;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\RateLimiter\Policy\NoLimiter;
|
||||
use Symfony\Component\RateLimiter\RateLimit;
|
||||
use Symfony\Component\RateLimiter\Reservation;
|
||||
|
||||
class NoLimiterTest extends TestCase
|
||||
{
|
||||
public function testConsume()
|
||||
{
|
||||
$limiter = new NoLimiter();
|
||||
$this->assertInstanceOf(RateLimit::class, $limiter->consume());
|
||||
}
|
||||
|
||||
public function testReserve()
|
||||
{
|
||||
$limiter = new NoLimiter();
|
||||
$this->assertInstanceOf(Reservation::class, $limiter->reserve());
|
||||
}
|
||||
}
|
@ -40,7 +40,7 @@ class BinaryUtil
|
||||
// 0x01b21dd213814000 is the number of 100-ns intervals between the
|
||||
// UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.
|
||||
private const TIME_OFFSET_INT = 0x01b21dd213814000;
|
||||
private const TIME_OFFSET_COM = "\xfe\x4d\xe2\x2d\xec\x7e\xc0\x00";
|
||||
private const TIME_OFFSET_COM2 = "\xfe\x4d\xe2\x2d\xec\x7e\xc0\x00";
|
||||
|
||||
public static function toBase(string $bytes, array $map): string
|
||||
{
|
||||
@ -121,9 +121,15 @@ class BinaryUtil
|
||||
}
|
||||
|
||||
$time = str_pad(hex2bin($time), 8, "\0", \STR_PAD_LEFT);
|
||||
$time = self::add($time, self::TIME_OFFSET_COM);
|
||||
$time[0] = $time[0] & "\x7F";
|
||||
$time = self::add($time, self::TIME_OFFSET_COM2);
|
||||
|
||||
return self::toBase($time, self::BASE10) / 10000000;
|
||||
if ($time >= self::TIME_OFFSET_COM2) {
|
||||
$time = -1 * self::toBase($time ^ "\xff\xff\xff\xff\xff\xff\xff\xff", self::BASE10);
|
||||
} else {
|
||||
$time[0] = $time[0] & "\x7F";
|
||||
$time = self::toBase($time, self::BASE10);
|
||||
}
|
||||
|
||||
return $time / 10000000;
|
||||
}
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ class Ulid extends AbstractUid
|
||||
if (\PHP_INT_SIZE >= 8) {
|
||||
$time = base_convert($time, 10, 32);
|
||||
} else {
|
||||
$time = bin2hex(BinaryUtil::fromBase($time, BinaryUtil::BASE10));
|
||||
$time = str_pad(bin2hex(BinaryUtil::fromBase($time, BinaryUtil::BASE10)), 12, '0', \STR_PAD_LEFT);
|
||||
$time = sprintf('%s%04s%04s',
|
||||
base_convert(substr($time, 0, 2), 16, 32),
|
||||
base_convert(substr($time, 2, 5), 16, 32),
|
||||
|
@ -22,11 +22,7 @@ class Uuid extends AbstractUid
|
||||
|
||||
public function __construct(string $uuid)
|
||||
{
|
||||
try {
|
||||
$type = uuid_type($uuid);
|
||||
} catch (\ValueError $e) {
|
||||
throw new \InvalidArgumentException(sprintf('Invalid UUID%s: "%s".', static::TYPE ? 'v'.static::TYPE : '', $uuid), 0, $e);
|
||||
}
|
||||
$type = uuid_is_valid($uuid) ? uuid_type($uuid) : false;
|
||||
|
||||
if (false === $type || \UUID_TYPE_INVALID === $type || (static::TYPE ?: $type) !== $type) {
|
||||
throw new \InvalidArgumentException(sprintf('Invalid UUID%s: "%s".', static::TYPE ? 'v'.static::TYPE : '', $uuid));
|
||||
@ -59,13 +55,11 @@ class Uuid extends AbstractUid
|
||||
return new static($uuid);
|
||||
}
|
||||
|
||||
try {
|
||||
$type = uuid_type($uuid);
|
||||
} catch (\ValueError $e) {
|
||||
throw new \InvalidArgumentException(sprintf('Invalid UUID%s: "%s".', static::TYPE ? 'v'.static::TYPE : '', $uuid), 0, $e);
|
||||
if (!uuid_is_valid($uuid)) {
|
||||
throw new \InvalidArgumentException(sprintf('Invalid UUID%s: "%s".', static::TYPE ? 'v'.static::TYPE : '', $uuid));
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
switch (uuid_type($uuid)) {
|
||||
case UuidV1::TYPE: return new UuidV1($uuid);
|
||||
case UuidV3::TYPE: return new UuidV3($uuid);
|
||||
case UuidV4::TYPE: return new UuidV4($uuid);
|
||||
@ -114,7 +108,7 @@ class Uuid extends AbstractUid
|
||||
return uuid_is_valid($uuid);
|
||||
}
|
||||
|
||||
return static::TYPE === uuid_type($uuid);
|
||||
return uuid_is_valid($uuid) && static::TYPE === uuid_type($uuid);
|
||||
}
|
||||
|
||||
public function toBinary(): string
|
||||
|
@ -182,7 +182,7 @@ EOF
|
||||
|
||||
$namespace = $matches[1] ?? null;
|
||||
|
||||
if (false === preg_match('/class +([^{ ]+)/', $fileContent, $matches)) {
|
||||
if (!preg_match('/class +([^{ ]+)/', $fileContent, $matches)) {
|
||||
// no class found
|
||||
continue;
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Validator\Tests\Dummy;
|
||||
|
||||
trait TraitPass
|
||||
{
|
||||
}
|
Reference in New Issue
Block a user