Merge branch '3.4' into 4.2
* 3.4: Show more accurate message in profiler when missing stopwatch CS Fixes: Not double split with one array argument Remove redundant animation prefixes Remove redundant `box-sizing` prefixes Rework firewall access denied rule fixed CS Fix missing $extraDirs when open_basedir returns
This commit is contained in:
commit
b13a23fe45
@ -126,14 +126,12 @@ class UserPasswordEncoderCommandTest extends WebTestCase
|
||||
|
||||
public function testEncodePasswordEmptySaltOutput()
|
||||
{
|
||||
$this->passwordEncoderCommandTester->execute(
|
||||
[
|
||||
'command' => 'security:encode-password',
|
||||
'password' => 'p@ssw0rd',
|
||||
'user-class' => 'Symfony\Component\Security\Core\User\User',
|
||||
'--empty-salt' => true,
|
||||
]
|
||||
);
|
||||
$this->passwordEncoderCommandTester->execute([
|
||||
'command' => 'security:encode-password',
|
||||
'password' => 'p@ssw0rd',
|
||||
'user-class' => 'Symfony\Component\Security\Core\User\User',
|
||||
'--empty-salt' => true,
|
||||
]);
|
||||
|
||||
$this->assertContains('Password encoding succeeded', $this->passwordEncoderCommandTester->getDisplay());
|
||||
$this->assertContains(' Encoded password p@ssw0rd', $this->passwordEncoderCommandTester->getDisplay());
|
||||
|
@ -97,7 +97,11 @@
|
||||
|
||||
<h2>Execution timeline</h2>
|
||||
|
||||
{% if collector.events is empty %}
|
||||
{% if not collector.isStopwatchInstalled() %}
|
||||
<div class="empty">
|
||||
<p>The Stopwatch component is not installed. If you want to see timing events, run: <code>composer require symfony/stopwatch</code>.</p>
|
||||
</div>
|
||||
{% elseif collector.events is empty %}
|
||||
<div class="empty">
|
||||
<p>No timing events have been recorded. Check that symfony/stopwatch is installed and debugging enabled in the kernel.</p>
|
||||
</div>
|
||||
|
@ -5,8 +5,6 @@
|
||||
background-color: #222;
|
||||
border-top-left-radius: 4px;
|
||||
bottom: 0;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
display: none;
|
||||
height: 36px;
|
||||
@ -36,8 +34,6 @@
|
||||
}
|
||||
|
||||
.sf-toolbarreset * {
|
||||
-webkit-box-sizing: content-box;
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
vertical-align: baseline;
|
||||
letter-spacing: normal;
|
||||
@ -371,21 +367,8 @@ div.sf-toolbar .sf-toolbar-block a:hover {
|
||||
text-align: right;
|
||||
}
|
||||
.sf-ajax-request-loading {
|
||||
-webkit-animation: sf-blink .5s ease-in-out infinite;
|
||||
-o-animation: sf-blink .5s ease-in-out infinite;
|
||||
-moz-animation: sf-blink .5s ease-in-out infinite;
|
||||
animation: sf-blink .5s ease-in-out infinite;
|
||||
}
|
||||
@-webkit-keyframes sf-blink {
|
||||
0% { background: #222; }
|
||||
50% { background: #444; }
|
||||
100% { background: #222; }
|
||||
}
|
||||
@-moz-keyframes sf-blink {
|
||||
0% { background: #222; }
|
||||
50% { background: #444; }
|
||||
100% { background: #222; }
|
||||
}
|
||||
@keyframes sf-blink {
|
||||
0% { background: #222; }
|
||||
50% { background: #444; }
|
||||
|
@ -18,7 +18,7 @@
|
||||
"require": {
|
||||
"php": "^7.1.3",
|
||||
"symfony/config": "^4.2",
|
||||
"symfony/http-kernel": "~4.2",
|
||||
"symfony/http-kernel": "^4.2.6",
|
||||
"symfony/routing": "~3.4|~4.0",
|
||||
"symfony/twig-bundle": "~4.2",
|
||||
"symfony/var-dumper": "~3.4|~4.0",
|
||||
|
@ -205,38 +205,36 @@ class DateIntervalType extends AbstractType
|
||||
}));
|
||||
};
|
||||
|
||||
$resolver->setDefaults(
|
||||
[
|
||||
'with_years' => true,
|
||||
'with_months' => true,
|
||||
'with_days' => true,
|
||||
'with_weeks' => false,
|
||||
'with_hours' => false,
|
||||
'with_minutes' => false,
|
||||
'with_seconds' => false,
|
||||
'with_invert' => false,
|
||||
'years' => range(0, 100),
|
||||
'months' => range(0, 12),
|
||||
'weeks' => range(0, 52),
|
||||
'days' => range(0, 31),
|
||||
'hours' => range(0, 24),
|
||||
'minutes' => range(0, 60),
|
||||
'seconds' => range(0, 60),
|
||||
'widget' => 'choice',
|
||||
'input' => 'dateinterval',
|
||||
'placeholder' => $placeholderDefault,
|
||||
'by_reference' => true,
|
||||
'error_bubbling' => false,
|
||||
// If initialized with a \DateInterval object, FormType initializes
|
||||
// this option to "\DateInterval". Since the internal, normalized
|
||||
// representation is not \DateInterval, but an array, we need to unset
|
||||
// this option.
|
||||
'data_class' => null,
|
||||
'compound' => $compound,
|
||||
'empty_data' => $emptyData,
|
||||
'labels' => [],
|
||||
]
|
||||
);
|
||||
$resolver->setDefaults([
|
||||
'with_years' => true,
|
||||
'with_months' => true,
|
||||
'with_days' => true,
|
||||
'with_weeks' => false,
|
||||
'with_hours' => false,
|
||||
'with_minutes' => false,
|
||||
'with_seconds' => false,
|
||||
'with_invert' => false,
|
||||
'years' => range(0, 100),
|
||||
'months' => range(0, 12),
|
||||
'weeks' => range(0, 52),
|
||||
'days' => range(0, 31),
|
||||
'hours' => range(0, 24),
|
||||
'minutes' => range(0, 60),
|
||||
'seconds' => range(0, 60),
|
||||
'widget' => 'choice',
|
||||
'input' => 'dateinterval',
|
||||
'placeholder' => $placeholderDefault,
|
||||
'by_reference' => true,
|
||||
'error_bubbling' => false,
|
||||
// If initialized with a \DateInterval object, FormType initializes
|
||||
// this option to "\DateInterval". Since the internal, normalized
|
||||
// representation is not \DateInterval, but an array, we need to unset
|
||||
// this option.
|
||||
'data_class' => null,
|
||||
'compound' => $compound,
|
||||
'empty_data' => $emptyData,
|
||||
'labels' => [],
|
||||
]);
|
||||
$resolver->setNormalizer('placeholder', $placeholderNormalizer);
|
||||
$resolver->setNormalizer('labels', $labelsNormalizer);
|
||||
|
||||
|
@ -144,12 +144,10 @@ class DefaultChoiceListFactoryTest extends TestCase
|
||||
|
||||
public function testCreateFromChoicesGrouped()
|
||||
{
|
||||
$list = $this->factory->createListFromChoices(
|
||||
[
|
||||
'Group 1' => ['A' => $this->obj1, 'B' => $this->obj2],
|
||||
'Group 2' => ['C' => $this->obj3, 'D' => $this->obj4],
|
||||
]
|
||||
);
|
||||
$list = $this->factory->createListFromChoices([
|
||||
'Group 1' => ['A' => $this->obj1, 'B' => $this->obj2],
|
||||
'Group 2' => ['C' => $this->obj3, 'D' => $this->obj4],
|
||||
]);
|
||||
|
||||
$this->assertObjectListWithGeneratedValues($list);
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ class TimeDataCollector extends DataCollector implements LateDataCollectorInterf
|
||||
'token' => $response->headers->get('X-Debug-Token'),
|
||||
'start_time' => $startTime * 1000,
|
||||
'events' => [],
|
||||
'stopwatch_installed' => \class_exists(Stopwatch::class, false),
|
||||
];
|
||||
}
|
||||
|
||||
@ -139,6 +140,14 @@ class TimeDataCollector extends DataCollector implements LateDataCollectorInterf
|
||||
return $this->data['start_time'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool whether or not the stopwatch component is installed
|
||||
*/
|
||||
public function isStopwatchInstalled()
|
||||
{
|
||||
return $this->data['stopwatch_installed'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -15,6 +15,7 @@ use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\DataCollector\TimeDataCollector;
|
||||
use Symfony\Component\Stopwatch\Stopwatch;
|
||||
|
||||
/**
|
||||
* @group time-sensitive
|
||||
@ -51,5 +52,6 @@ class TimeDataCollectorTest extends TestCase
|
||||
|
||||
$c->collect($request, new Response());
|
||||
$this->assertEquals(123456000, $c->getStartTime());
|
||||
$this->assertSame(\class_exists(Stopwatch::class, false), $c->isStopwatchInstalled());
|
||||
}
|
||||
}
|
||||
|
@ -851,13 +851,11 @@ class OptionsResolverTest extends TestCase
|
||||
$this->resolver->setDefined('foo');
|
||||
$this->resolver->setAllowedTypes('foo', 'int[][]');
|
||||
|
||||
$this->resolver->resolve(
|
||||
[
|
||||
'foo' => [
|
||||
[1.2],
|
||||
],
|
||||
]
|
||||
);
|
||||
$this->resolver->resolve([
|
||||
'foo' => [
|
||||
[1.2],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1918,13 +1916,11 @@ class OptionsResolverTest extends TestCase
|
||||
1, 2,
|
||||
],
|
||||
],
|
||||
], $this->resolver->resolve(
|
||||
[
|
||||
'foo' => [
|
||||
[1, 2],
|
||||
],
|
||||
]
|
||||
));
|
||||
], $this->resolver->resolve([
|
||||
'foo' => [
|
||||
[1, 2],
|
||||
],
|
||||
]));
|
||||
}
|
||||
|
||||
public function testNested2Arrays()
|
||||
@ -1964,17 +1960,15 @@ class OptionsResolverTest extends TestCase
|
||||
$this->resolver->setDefined('foo');
|
||||
$this->resolver->setAllowedTypes('foo', 'float[][][][]');
|
||||
|
||||
$this->resolver->resolve(
|
||||
[
|
||||
'foo' => [
|
||||
$this->resolver->resolve([
|
||||
'foo' => [
|
||||
[
|
||||
[
|
||||
[
|
||||
[1, 2],
|
||||
],
|
||||
[1, 2],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -51,7 +51,7 @@ class ExecutableFinder
|
||||
public function find($name, $default = null, array $extraDirs = [])
|
||||
{
|
||||
if (ini_get('open_basedir')) {
|
||||
$searchPath = explode(PATH_SEPARATOR, ini_get('open_basedir'));
|
||||
$searchPath = array_merge(explode(PATH_SEPARATOR, ini_get('open_basedir')), $extraDirs);
|
||||
$dirs = [];
|
||||
foreach ($searchPath as $path) {
|
||||
// Silencing against https://bugs.php.net/69240
|
||||
|
@ -131,8 +131,6 @@ class ExceptionListener
|
||||
} catch (\Exception $e) {
|
||||
$event->setException($e);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (null !== $this->logger) {
|
||||
@ -150,7 +148,7 @@ class ExceptionListener
|
||||
$subRequest = $this->httpUtils->createRequest($event->getRequest(), $this->errorPage);
|
||||
$subRequest->attributes->set(Security::ACCESS_DENIED_ERROR, $exception);
|
||||
|
||||
$event->setResponse($event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true));
|
||||
$event->setResponse($event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST));
|
||||
$event->allowCustomResponseCode();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
|
@ -130,10 +130,8 @@ class ExceptionListenerTest extends TestCase
|
||||
{
|
||||
$event = $this->createEvent($exception);
|
||||
|
||||
$accessDeniedHandler = $this->getMockBuilder('Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface')->getMock();
|
||||
$accessDeniedHandler->expects($this->once())->method('handle')->will($this->returnValue(new Response('error')));
|
||||
$listener = $this->createExceptionListener(null, $this->createTrustResolver(true), null, null, null, $this->createCustomAccessDeniedHandler(new Response('error')));
|
||||
|
||||
$listener = $this->createExceptionListener(null, $this->createTrustResolver(true), null, null, null, $accessDeniedHandler);
|
||||
$listener->onKernelException($event);
|
||||
|
||||
$this->assertEquals('error', $event->getResponse()->getContent());
|
||||
@ -147,16 +145,51 @@ class ExceptionListenerTest extends TestCase
|
||||
{
|
||||
$event = $this->createEvent($exception);
|
||||
|
||||
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
|
||||
$tokenStorage->expects($this->once())->method('getToken')->will($this->returnValue($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock()));
|
||||
|
||||
$listener = $this->createExceptionListener($tokenStorage, $this->createTrustResolver(false), null, $this->createEntryPoint());
|
||||
$listener = $this->createExceptionListener($this->createTokenStorage(), $this->createTrustResolver(false), null, $this->createEntryPoint());
|
||||
$listener->onKernelException($event);
|
||||
|
||||
$this->assertEquals('OK', $event->getResponse()->getContent());
|
||||
$this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAccessDeniedExceptionProvider
|
||||
*/
|
||||
public function testAccessDeniedExceptionNotFullFledgedAndWithAccessDeniedHandlerAndWithoutErrorPage(\Exception $exception, \Exception $eventException = null)
|
||||
{
|
||||
$event = $this->createEvent($exception);
|
||||
|
||||
$listener = $this->createExceptionListener($this->createTokenStorage(), $this->createTrustResolver(false), null, $this->createEntryPoint(), null, $this->createCustomAccessDeniedHandler(new Response('denied', 403)));
|
||||
$listener->onKernelException($event);
|
||||
|
||||
$this->assertEquals('denied', $event->getResponse()->getContent());
|
||||
$this->assertEquals(403, $event->getResponse()->getStatusCode());
|
||||
$this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAccessDeniedExceptionProvider
|
||||
*/
|
||||
public function testAccessDeniedExceptionNotFullFledgedAndWithoutAccessDeniedHandlerAndWithErrorPage(\Exception $exception, \Exception $eventException = null)
|
||||
{
|
||||
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
|
||||
$kernel->expects($this->once())->method('handle')->will($this->returnValue(new Response('Unauthorized', 401)));
|
||||
|
||||
$event = $this->createEvent($exception, $kernel);
|
||||
|
||||
$httpUtils = $this->getMockBuilder('Symfony\Component\Security\Http\HttpUtils')->getMock();
|
||||
$httpUtils->expects($this->once())->method('createRequest')->will($this->returnValue(Request::create('/error')));
|
||||
|
||||
$listener = $this->createExceptionListener($this->createTokenStorage(), $this->createTrustResolver(true), $httpUtils, null, '/error');
|
||||
$listener->onKernelException($event);
|
||||
|
||||
$this->assertTrue($event->isAllowingCustomResponseCode());
|
||||
|
||||
$this->assertEquals('Unauthorized', $event->getResponse()->getContent());
|
||||
$this->assertEquals(401, $event->getResponse()->getStatusCode());
|
||||
$this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
|
||||
}
|
||||
|
||||
public function getAccessDeniedExceptionProvider()
|
||||
{
|
||||
return [
|
||||
@ -168,6 +201,22 @@ class ExceptionListenerTest extends TestCase
|
||||
];
|
||||
}
|
||||
|
||||
private function createTokenStorage()
|
||||
{
|
||||
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
|
||||
$tokenStorage->expects($this->once())->method('getToken')->will($this->returnValue($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock()));
|
||||
|
||||
return $tokenStorage;
|
||||
}
|
||||
|
||||
private function createCustomAccessDeniedHandler(Response $response)
|
||||
{
|
||||
$accessDeniedHandler = $this->getMockBuilder('Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface')->getMock();
|
||||
$accessDeniedHandler->expects($this->once())->method('handle')->will($this->returnValue($response));
|
||||
|
||||
return $accessDeniedHandler;
|
||||
}
|
||||
|
||||
private function createEntryPoint(Response $response = null)
|
||||
{
|
||||
$entryPoint = $this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock();
|
||||
|
@ -20,11 +20,10 @@ class YamlFileDumperTest extends TestCase
|
||||
public function testTreeFormatCatalogue()
|
||||
{
|
||||
$catalogue = new MessageCatalogue('en');
|
||||
$catalogue->add(
|
||||
[
|
||||
'foo.bar1' => 'value1',
|
||||
'foo.bar2' => 'value2',
|
||||
]);
|
||||
$catalogue->add([
|
||||
'foo.bar1' => 'value1',
|
||||
'foo.bar2' => 'value2',
|
||||
]);
|
||||
|
||||
$dumper = new YamlFileDumper();
|
||||
|
||||
@ -34,11 +33,10 @@ class YamlFileDumperTest extends TestCase
|
||||
public function testLinearFormatCatalogue()
|
||||
{
|
||||
$catalogue = new MessageCatalogue('en');
|
||||
$catalogue->add(
|
||||
[
|
||||
'foo.bar1' => 'value1',
|
||||
'foo.bar2' => 'value2',
|
||||
]);
|
||||
$catalogue->add([
|
||||
'foo.bar1' => 'value1',
|
||||
'foo.bar2' => 'value2',
|
||||
]);
|
||||
|
||||
$dumper = new YamlFileDumper();
|
||||
|
||||
|
@ -54,11 +54,9 @@ class ChoiceValidatorTest extends ConstraintValidatorTestCase
|
||||
{
|
||||
$this->validator->validate(
|
||||
null,
|
||||
new Choice(
|
||||
[
|
||||
'choices' => ['foo', 'bar'],
|
||||
]
|
||||
)
|
||||
new Choice([
|
||||
'choices' => ['foo', 'bar'],
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertNoViolation();
|
||||
@ -100,6 +98,7 @@ class ChoiceValidatorTest extends ConstraintValidatorTestCase
|
||||
|
||||
public function testValidChoiceCallbackClosure()
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
$constraint = new Choice(
|
||||
[
|
||||
'callback' => function () {
|
||||
@ -107,6 +106,14 @@ class ChoiceValidatorTest extends ConstraintValidatorTestCase
|
||||
},
|
||||
]
|
||||
);
|
||||
=======
|
||||
$constraint = new Choice([
|
||||
'strict' => true,
|
||||
'callback' => function () {
|
||||
return ['foo', 'bar'];
|
||||
},
|
||||
]);
|
||||
>>>>>>> 3.4
|
||||
|
||||
$this->validator->validate('bar', $constraint);
|
||||
|
||||
|
Reference in New Issue
Block a user