Merge branch '4.4'
* 4.4: [Form][Validator] Generate accept attribute with file constraint and mime types option [Security/Core] align defaults for sodium with PHP 7.4 fix inline handling when dumping tagged values [HttpClient] fix canceling responses in a streaming loop [Messenger] Flatten collection of stamps collected by the traceable middleware [Messenger][Profiler] Remove cutting caster to dump full objects [WebProfilerBundle] mark all classes as internal Decoupling TwigBundle and using the new ErrorRenderer mechanism [HttpClient] rewind streams created from strings [PropertyAccess] Fix PropertyAccessorCollectionTest [HttpClient] rewind stream when using Psr18Client Typo in web profiler [4.3] Remove dead test fixtures [Routing] Fix CHANGELOG relax some date parser patterns adapt tests [Form] Repeat preferred choices in the main list Avoid getting right to left style
This commit is contained in:
commit
b3eb9720de
@ -237,7 +237,7 @@ Validator
|
|||||||
WebProfilerBundle
|
WebProfilerBundle
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
* Deprecated the `ExceptionController::templateExists()` method
|
* Deprecated the `ExceptionController` class in favor of `ExceptionErrorController`
|
||||||
* Deprecated the `TemplateManager::templateExists()` method
|
* Deprecated the `TemplateManager::templateExists()` method
|
||||||
|
|
||||||
WebServerBundle
|
WebServerBundle
|
||||||
|
@ -604,6 +604,11 @@ Yaml
|
|||||||
* The parser is now stricter and will throw a `ParseException` when a
|
* The parser is now stricter and will throw a `ParseException` when a
|
||||||
mapping is found inside a multi-line string.
|
mapping is found inside a multi-line string.
|
||||||
|
|
||||||
|
WebProfilerBundle
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
* Removed the `ExceptionController` class, use `ExceptionErrorController` instead.
|
||||||
|
|
||||||
WebServerBundle
|
WebServerBundle
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
@ -848,7 +848,7 @@ class EntityTypeTest extends BaseTypeTest
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertEquals([3 => new ChoiceView($entity3, '3', 'Baz'), 2 => new ChoiceView($entity2, '2', 'Bar')], $field->createView()->vars['preferred_choices']);
|
$this->assertEquals([3 => new ChoiceView($entity3, '3', 'Baz'), 2 => new ChoiceView($entity2, '2', 'Bar')], $field->createView()->vars['preferred_choices']);
|
||||||
$this->assertEquals([1 => new ChoiceView($entity1, '1', 'Foo')], $field->createView()->vars['choices']);
|
$this->assertEquals([1 => new ChoiceView($entity1, '1', 'Foo'), 2 => new ChoiceView($entity2, '2', 'Bar'), 3 => new ChoiceView($entity3, '3', 'Baz')], $field->createView()->vars['choices']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testOverrideChoicesWithPreferredChoices()
|
public function testOverrideChoicesWithPreferredChoices()
|
||||||
@ -868,7 +868,7 @@ class EntityTypeTest extends BaseTypeTest
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertEquals([3 => new ChoiceView($entity3, '3', 'Baz')], $field->createView()->vars['preferred_choices']);
|
$this->assertEquals([3 => new ChoiceView($entity3, '3', 'Baz')], $field->createView()->vars['preferred_choices']);
|
||||||
$this->assertEquals([2 => new ChoiceView($entity2, '2', 'Bar')], $field->createView()->vars['choices']);
|
$this->assertEquals([2 => new ChoiceView($entity2, '2', 'Bar'), 3 => new ChoiceView($entity3, '3', 'Baz')], $field->createView()->vars['choices']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDisallowChoicesThatAreNotIncludedChoicesSingleIdentifier()
|
public function testDisallowChoicesThatAreNotIncludedChoicesSingleIdentifier()
|
||||||
|
@ -524,8 +524,9 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
|
|||||||
./option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
|
./option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
|
||||||
/following-sibling::option[@disabled="disabled"][not(@selected)][.="-- sep --"]
|
/following-sibling::option[@disabled="disabled"][not(@selected)][.="-- sep --"]
|
||||||
/following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
|
/following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
|
||||||
|
/following-sibling::option[@value="&b"][.="[trans]Choice&B[/trans]"]
|
||||||
]
|
]
|
||||||
[count(./option)=3]
|
[count(./option)=4]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -547,8 +548,9 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
|
|||||||
[
|
[
|
||||||
./option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
|
./option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
|
||||||
/following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
|
/following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
|
||||||
|
/following-sibling::option[@value="&b"][.="[trans]Choice&B[/trans]"]
|
||||||
]
|
]
|
||||||
[count(./option)=2]
|
[count(./option)=3]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -571,8 +573,9 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
|
|||||||
./option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
|
./option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
|
||||||
/following-sibling::option[@disabled="disabled"][not(@selected)][.=""]
|
/following-sibling::option[@disabled="disabled"][not(@selected)][.=""]
|
||||||
/following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
|
/following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
|
||||||
|
/following-sibling::option[@value="&b"][.="[trans]Choice&B[/trans]"]
|
||||||
]
|
]
|
||||||
[count(./option)=3]
|
[count(./option)=4]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -589,7 +592,7 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
|
|||||||
$this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
|
$this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
|
||||||
'/select
|
'/select
|
||||||
[@class="my&class form-control"]
|
[@class="my&class form-control"]
|
||||||
[count(./option)=2]
|
[count(./option)=5]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,8 @@ CHANGELOG
|
|||||||
* Added button to clear the ajax request tab
|
* Added button to clear the ajax request tab
|
||||||
* Deprecated the `ExceptionController::templateExists()` method
|
* Deprecated the `ExceptionController::templateExists()` method
|
||||||
* Deprecated the `TemplateManager::templateExists()` method
|
* Deprecated the `TemplateManager::templateExists()` method
|
||||||
|
* Deprecated the `ExceptionController` in favor of `ExceptionErrorController`
|
||||||
|
* Marked all classes of the WebProfilerBundle as internal
|
||||||
|
|
||||||
4.3.0
|
4.3.0
|
||||||
-----
|
-----
|
||||||
|
@ -18,10 +18,15 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|||||||
use Symfony\Component\HttpKernel\Profiler\Profiler;
|
use Symfony\Component\HttpKernel\Profiler\Profiler;
|
||||||
use Twig\Environment;
|
use Twig\Environment;
|
||||||
|
|
||||||
|
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', ExceptionController::class, ExceptionErrorController::class), E_USER_DEPRECATED);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ExceptionController.
|
* ExceptionController.
|
||||||
*
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* @deprecated since Symfony 4.4, use the ExceptionErrorController instead.
|
||||||
|
* @internal since Symfony 4.4
|
||||||
*/
|
*/
|
||||||
class ExceptionController
|
class ExceptionController
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
<?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\WebProfilerBundle\Controller;
|
||||||
|
|
||||||
|
use Symfony\Component\ErrorRenderer\ErrorRenderer\HtmlErrorRenderer;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
use Symfony\Component\HttpKernel\Profiler\Profiler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the exception panel.
|
||||||
|
*
|
||||||
|
* @author Yonel Ceruto <yonelceruto@gmail.com>
|
||||||
|
*/
|
||||||
|
class ExceptionErrorController
|
||||||
|
{
|
||||||
|
private $htmlErrorRenderer;
|
||||||
|
private $profiler;
|
||||||
|
|
||||||
|
public function __construct(HtmlErrorRenderer $htmlErrorRenderer, ?Profiler $profiler)
|
||||||
|
{
|
||||||
|
$this->htmlErrorRenderer = $htmlErrorRenderer;
|
||||||
|
$this->profiler = $profiler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the exception panel stacktrace for the given token.
|
||||||
|
*/
|
||||||
|
public function body(string $token): Response
|
||||||
|
{
|
||||||
|
if (null === $this->profiler) {
|
||||||
|
throw new NotFoundHttpException('The profiler must be enabled.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$exception = $this->profiler->loadProfile($token)
|
||||||
|
->getCollector('exception')
|
||||||
|
->getException()
|
||||||
|
;
|
||||||
|
|
||||||
|
return new Response($this->htmlErrorRenderer->getBody($exception));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the exception panel stylesheet.
|
||||||
|
*/
|
||||||
|
public function stylesheet(): Response
|
||||||
|
{
|
||||||
|
return new Response($this->htmlErrorRenderer->getStylesheet());
|
||||||
|
}
|
||||||
|
}
|
@ -24,6 +24,8 @@ use Twig\Environment;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* @internal since Symfony 4.4
|
||||||
*/
|
*/
|
||||||
class ProfilerController
|
class ProfilerController
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,8 @@ use Twig\Environment;
|
|||||||
* RouterController.
|
* RouterController.
|
||||||
*
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* @internal since Symfony 4.4
|
||||||
*/
|
*/
|
||||||
class RouterController
|
class RouterController
|
||||||
{
|
{
|
||||||
|
@ -21,6 +21,8 @@ use Twig\Environment;
|
|||||||
*
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
* @author Artur Wielogórski <wodor@wodor.net>
|
* @author Artur Wielogórski <wodor@wodor.net>
|
||||||
|
*
|
||||||
|
* @internal since Symfony 4.4
|
||||||
*/
|
*/
|
||||||
class TemplateManager
|
class TemplateManager
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,13 @@
|
|||||||
<argument type="service" id="twig" />
|
<argument type="service" id="twig" />
|
||||||
<argument>%kernel.debug%</argument>
|
<argument>%kernel.debug%</argument>
|
||||||
<argument type="service" id="debug.file_link_formatter" />
|
<argument type="service" id="debug.file_link_formatter" />
|
||||||
<argument type="service" id="error_renderer.renderer.html" on-invalid="null" />
|
<argument type="service" id="error_renderer.renderer.html" />
|
||||||
|
<deprecated>The "%service_id%" service is deprecated since Symfony 4.4, use the "web_profiler.controller.exception_error" service instead.</deprecated>
|
||||||
|
</service>
|
||||||
|
|
||||||
|
<service id="web_profiler.controller.exception_error" class="Symfony\Bundle\WebProfilerBundle\Controller\ExceptionErrorController" public="true">
|
||||||
|
<argument type="service" id="error_renderer.renderer.html" />
|
||||||
|
<argument type="service" id="profiler" on-invalid="null" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="web_profiler.csp.handler" class="Symfony\Bundle\WebProfilerBundle\Csp\ContentSecurityPolicyHandler">
|
<service id="web_profiler.csp.handler" class="Symfony\Bundle\WebProfilerBundle\Csp\ContentSecurityPolicyHandler">
|
||||||
|
@ -37,11 +37,11 @@
|
|||||||
</route>
|
</route>
|
||||||
|
|
||||||
<route id="_profiler_exception" path="/{token}/exception">
|
<route id="_profiler_exception" path="/{token}/exception">
|
||||||
<default key="_controller">web_profiler.controller.exception::showAction</default>
|
<default key="_controller">web_profiler.controller.exception_error::body</default>
|
||||||
</route>
|
</route>
|
||||||
|
|
||||||
<route id="_profiler_exception_css" path="/{token}/exception.css">
|
<route id="_profiler_exception_css" path="/{token}/exception.css">
|
||||||
<default key="_controller">web_profiler.controller.exception::cssAction</default>
|
<default key="_controller">web_profiler.controller.exception_error::stylesheet</default>
|
||||||
</route>
|
</route>
|
||||||
|
|
||||||
</routes>
|
</routes>
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
{{ include('@Twig/exception.css.twig') }}
|
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
max-width: auto;
|
max-width: auto;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
{% if collector.hasexception %}
|
{% if collector.hasexception %}
|
||||||
<style>
|
<style>
|
||||||
{{ render(path('_profiler_exception_css', { token: token })) }}
|
{{ render(path('_profiler_exception_css', { token: token })) }}
|
||||||
|
{{ include('@WebProfiler/Collector/exception.css.twig') }}
|
||||||
</style>
|
</style>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ parent() }}
|
{{ parent() }}
|
||||||
|
@ -663,7 +663,7 @@
|
|||||||
</table>
|
</table>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="empty">
|
<div class="empty">
|
||||||
<p>No options where passed when constructing this form.</p>
|
<p>No options were passed when constructing this form.</p>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -119,8 +119,8 @@
|
|||||||
<span class="label status-error">exception</span>
|
<span class="label status-error">exception</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a class="toggle-button">
|
<a class="toggle-button">
|
||||||
<span class="icon icon-close">{{ include('@Twig/images/icon-minus-square.svg') }}</span>
|
<span class="icon icon-close">{{ include('@WebProfiler/images/icon-minus-square.svg') }}</span>
|
||||||
<span class="icon icon-open">{{ include('@Twig/images/icon-plus-square.svg') }}</span>
|
<span class="icon icon-open">{{ include('@WebProfiler/images/icon-plus-square.svg') }}</span>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<meta charset="{{ _charset }}" />
|
<meta charset="{{ _charset }}" />
|
||||||
<meta name="robots" content="noindex,nofollow" />
|
<meta name="robots" content="noindex,nofollow" />
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
<title>Symfony Profiler</title>
|
<title>{% block title %}Symfony Profiler{% endblock %}</title>
|
||||||
<link rel="icon" type="image/x-icon" sizes="16x16" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAFEUlEQVR4AZVXA4wm2RMf27bXDM/+3/+sYBGfrbVtezc6BWtzfPbYXtvDL9906t6v0vWl05me7q1JzXuvvu4yXnvZgJ9hH6bwZYXLFR739vauUGuDwhq1L1N4Uv/tRYUhFjwcg49hn6aYr1V4TiGp86CoP9Oh1tV414KnM6t9fHymKUZ3DAI0hW4b1AyK3lE8phh5OxWeoJgUGhi5mLm95YzBwcHuhIQEV1JSEoWGhoKWHxYWFmenhJ/B5W0GwZpDt5Ovry9lZWWRyWOu5ORk7JsUpogsq5gnmISTU+HKQoLFQv/qq6/os88+I+EVFRUlSsRZ5oRiVmwlXMWShQkahUdERJCfnx/vd+3aRTU1NXTixAmqrq6mK1eu0PTp05mnrmD+QK6XhLO0XP2O2FJAQICRjjMU4P1PP/1EfX19NGfOHM8Z0N7ezueQkBBXYGAgSWIaQ5Em2T5QzFNSUig9PV3OHOe4uDjZ87p//34C7Nm7x/NcRUUFAX799Vec8Y7m7+8Pz92SfBDXr7VwPYRbxn/MmDG8Tps2jQBd3V30/PPPe35/6qmnaPXq1TR69Gg+h4eHiwwosdLT4dBkQDSXWmJiIq/vv/8+/fvvv3ThwgWqr6+n/Px8oyCmAerq6jy03Nxc2Yv7ySSjQzrmi4i92fVpaWlYOZ79/f2MW7dtpSlTptDp06epo6ODPvroI850ASiGdyZOnEjXrl2jyspKT4XA9cgjkaPL/D8UWG62HokieyQQoKSkRGiMs2bNotraWmprayOBNWvWyO+scGdnp5zF/WYvLEb8TwpRykp1MV7feust6uzqJMD169fpueeeY/rDDz/MKzzgdrsJoGkaffvtt/TFF19wQsIDmzZtssojt+6Fo1CgzKiAvAB3DRs2jAULtLS0eErPGB5Ad3c3lZaWUnFxMfeAd955h5+JjY3FaqXAPwhBnRCNySK4b98+Aoilv/z6i/zGggSk1g0opWupAMvGP91yt96zadWqVdTc3Ezz58/31LOAy+US6zgHBP766y+mDR8+HBUgFWSnQI2EAFnqlpcaGxsJIFkMN8L9AnPnzmX6jRs3SACeAi0vL888JwYPgTEJpauhnADo6/LSgQMHCHD37l2Cp15//XXq7eslgKb+Fi1exM9lZmbaCDclIcpQQhATE4OVsrOzuamg+cyePZuzG64Hrlu3jp9ZuWolCdy+fZueeOIJpkdHR1sLHqgM0Yh0bTRz1m7fvp2KiopYkYKCApo8ebLZIwzlFeXSOXEnsLPe2Ij+p5DbYYdOdOtDQ0rNjFya5sTcsGGDcTDZoXTcNoVBMoxWyzDS2yXmOyeUtGSskmDjx4/nRgPAfBDmMpZtUIbRcsi2GsfSD2QYyd2OcdmyZSSwdu1apuXk5GB16v4bak0yX0imyIUEgwNovFTglhMZGcm0srIy43zAVUxuTLbW4xn17Fci23wly9dngUummrTaixcvMpOtW7fiiBwQpqKYU9efHuxDJE5hC9wvL9TW1RLg+PHjPGTQ8wsLC4WpDC5Y5UR4k5qKMSLT6lqeAiX0nuAaMmSI9sMPP9CZM2foyJEj9O677wpTVIuTjidNp0HibvttoH9E5OMqbWKkSaNSlojldoLF7TEP+nUEmKI62y1kOBINbVaNarcI0PuGGUlHyfYvLHg7/jhFSFYqZh0P8KHSptd5ksOPU3tvqAEUot/hFmOIYJLp87wGe9Dwm95eg5xa/R8G6d8U5EcFhwAAAABJRU5ErkJggg==">
|
<link rel="icon" type="image/x-icon" sizes="16x16" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAFEUlEQVR4AZVXA4wm2RMf27bXDM/+3/+sYBGfrbVtezc6BWtzfPbYXtvDL9906t6v0vWl05me7q1JzXuvvu4yXnvZgJ9hH6bwZYXLFR739vauUGuDwhq1L1N4Uv/tRYUhFjwcg49hn6aYr1V4TiGp86CoP9Oh1tV414KnM6t9fHymKUZ3DAI0hW4b1AyK3lE8phh5OxWeoJgUGhi5mLm95YzBwcHuhIQEV1JSEoWGhoKWHxYWFmenhJ/B5W0GwZpDt5Ovry9lZWWRyWOu5ORk7JsUpogsq5gnmISTU+HKQoLFQv/qq6/os88+I+EVFRUlSsRZ5oRiVmwlXMWShQkahUdERJCfnx/vd+3aRTU1NXTixAmqrq6mK1eu0PTp05mnrmD+QK6XhLO0XP2O2FJAQICRjjMU4P1PP/1EfX19NGfOHM8Z0N7ezueQkBBXYGAgSWIaQ5Em2T5QzFNSUig9PV3OHOe4uDjZ87p//34C7Nm7x/NcRUUFAX799Vec8Y7m7+8Pz92SfBDXr7VwPYRbxn/MmDG8Tps2jQBd3V30/PPPe35/6qmnaPXq1TR69Gg+h4eHiwwosdLT4dBkQDSXWmJiIq/vv/8+/fvvv3ThwgWqr6+n/Px8oyCmAerq6jy03Nxc2Yv7ySSjQzrmi4i92fVpaWlYOZ79/f2MW7dtpSlTptDp06epo6ODPvroI850ASiGdyZOnEjXrl2jyspKT4XA9cgjkaPL/D8UWG62HokieyQQoKSkRGiMs2bNotraWmprayOBNWvWyO+scGdnp5zF/WYvLEb8TwpRykp1MV7feust6uzqJMD169fpueeeY/rDDz/MKzzgdrsJoGkaffvtt/TFF19wQsIDmzZtssojt+6Fo1CgzKiAvAB3DRs2jAULtLS0eErPGB5Ad3c3lZaWUnFxMfeAd955h5+JjY3FaqXAPwhBnRCNySK4b98+Aoilv/z6i/zGggSk1g0opWupAMvGP91yt96zadWqVdTc3Ezz58/31LOAy+US6zgHBP766y+mDR8+HBUgFWSnQI2EAFnqlpcaGxsJIFkMN8L9AnPnzmX6jRs3SACeAi0vL888JwYPgTEJpauhnADo6/LSgQMHCHD37l2Cp15//XXq7eslgKb+Fi1exM9lZmbaCDclIcpQQhATE4OVsrOzuamg+cyePZuzG64Hrlu3jp9ZuWolCdy+fZueeOIJpkdHR1sLHqgM0Yh0bTRz1m7fvp2KiopYkYKCApo8ebLZIwzlFeXSOXEnsLPe2Ij+p5DbYYdOdOtDQ0rNjFya5sTcsGGDcTDZoXTcNoVBMoxWyzDS2yXmOyeUtGSskmDjx4/nRgPAfBDmMpZtUIbRcsi2GsfSD2QYyd2OcdmyZSSwdu1apuXk5GB16v4bak0yX0imyIUEgwNovFTglhMZGcm0srIy43zAVUxuTLbW4xn17Fci23wly9dngUummrTaixcvMpOtW7fiiBwQpqKYU9efHuxDJE5hC9wvL9TW1RLg+PHjPGTQ8wsLC4WpDC5Y5UR4k5qKMSLT6lqeAiX0nuAaMmSI9sMPP9CZM2foyJEj9O677wpTVIuTjidNp0HibvttoH9E5OMqbWKkSaNSlojldoLF7TEP+nUEmKI62y1kOBINbVaNarcI0PuGGUlHyfYvLHg7/jhFSFYqZh0P8KHSptd5ksOPU3tvqAEUot/hFmOIYJLp87wGe9Dwm95eg5xa/R8G6d8U5EcFhwAAAABJRU5ErkJggg==">
|
||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
z-index: 99999;
|
z-index: 99999;
|
||||||
|
direction: ltr;
|
||||||
|
|
||||||
/* neutralize the aliasing defined by external CSS styles */
|
/* neutralize the aliasing defined by external CSS styles */
|
||||||
-webkit-font-smoothing: subpixel-antialiased;
|
-webkit-font-smoothing: subpixel-antialiased;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends '@Twig/layout.html.twig' %}
|
{% extends '@WebProfiler/Profiler/base.html.twig' %}
|
||||||
|
|
||||||
{% block title 'Redirection Intercepted' %}
|
{% block title 'Redirection Intercepted' %}
|
||||||
|
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1408 960V832q0-26-19-45t-45-19H448q-26 0-45 19t-19 45v128q0 26 19 45t45 19h896q26 0 45-19t19-45zm256-544v960q0 119-84.5 203.5T1376 1664H416q-119 0-203.5-84.5T128 1376V416q0-119 84.5-203.5T416 128h960q119 0 203.5 84.5T1664 416z"/></svg>
|
After Width: | Height: | Size: 337 B |
@ -0,0 +1 @@
|
|||||||
|
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1408 960V832q0-26-19-45t-45-19h-320V448q0-26-19-45t-45-19H832q-26 0-45 19t-19 45v320H448q-26 0-45 19t-19 45v128q0 26 19 45t45 19h320v320q0 26 19 45t45 19h128q26 0 45-19t19-45v-320h320q26 0 45-19t19-45zm256-544v960q0 119-84.5 203.5T1376 1664H416q-119 0-203.5-84.5T128 1376V416q0-119 84.5-203.5T416 128h960q119 0 203.5 84.5T1664 416z"/></svg>
|
After Width: | Height: | Size: 442 B |
@ -54,7 +54,7 @@ class WebProfilerExtensionTest extends TestCase
|
|||||||
$this->kernel = $this->getMockBuilder('Symfony\\Component\\HttpKernel\\KernelInterface')->getMock();
|
$this->kernel = $this->getMockBuilder('Symfony\\Component\\HttpKernel\\KernelInterface')->getMock();
|
||||||
|
|
||||||
$this->container = new ContainerBuilder();
|
$this->container = new ContainerBuilder();
|
||||||
$this->container->register('error_renderer.renderer.html', HtmlErrorRenderer::class);
|
$this->container->register('error_renderer.renderer.html', HtmlErrorRenderer::class)->setPublic(true);
|
||||||
$this->container->register('event_dispatcher', EventDispatcher::class)->setPublic(true);
|
$this->container->register('event_dispatcher', EventDispatcher::class)->setPublic(true);
|
||||||
$this->container->register('router', $this->getMockClass('Symfony\\Component\\Routing\\RouterInterface'))->setPublic(true);
|
$this->container->register('router', $this->getMockClass('Symfony\\Component\\Routing\\RouterInterface'))->setPublic(true);
|
||||||
$this->container->register('twig', 'Twig\Environment')->setPublic(true);
|
$this->container->register('twig', 'Twig\Environment')->setPublic(true);
|
||||||
@ -92,10 +92,11 @@ class WebProfilerExtensionTest extends TestCase
|
|||||||
|
|
||||||
$extension = new WebProfilerExtension();
|
$extension = new WebProfilerExtension();
|
||||||
$extension->load([[]], $this->container);
|
$extension->load([[]], $this->container);
|
||||||
|
$this->container->removeDefinition('web_profiler.controller.exception');
|
||||||
|
|
||||||
$this->assertFalse($this->container->has('web_profiler.debug_toolbar'));
|
$this->assertFalse($this->container->has('web_profiler.debug_toolbar'));
|
||||||
|
|
||||||
$this->assertSaneContainer($this->getCompiledContainer());
|
self::assertSaneContainer($this->getCompiledContainer());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -105,10 +106,11 @@ class WebProfilerExtensionTest extends TestCase
|
|||||||
{
|
{
|
||||||
$extension = new WebProfilerExtension();
|
$extension = new WebProfilerExtension();
|
||||||
$extension->load([['toolbar' => $toolbarEnabled, 'intercept_redirects' => $interceptRedirects]], $this->container);
|
$extension->load([['toolbar' => $toolbarEnabled, 'intercept_redirects' => $interceptRedirects]], $this->container);
|
||||||
|
$this->container->removeDefinition('web_profiler.controller.exception');
|
||||||
|
|
||||||
$this->assertSame($listenerInjected, $this->container->has('web_profiler.debug_toolbar'));
|
$this->assertSame($listenerInjected, $this->container->has('web_profiler.debug_toolbar'));
|
||||||
|
|
||||||
$this->assertSaneContainer($this->getCompiledContainer(), '', ['web_profiler.csp.handler']);
|
self::assertSaneContainer($this->getCompiledContainer(), '', ['web_profiler.csp.handler']);
|
||||||
|
|
||||||
if ($listenerInjected) {
|
if ($listenerInjected) {
|
||||||
$this->assertSame($listenerEnabled, $this->container->get('web_profiler.debug_toolbar')->isEnabled());
|
$this->assertSame($listenerEnabled, $this->container->get('web_profiler.debug_toolbar')->isEnabled());
|
||||||
|
@ -22,6 +22,8 @@ use Twig\TwigFunction;
|
|||||||
* Twig extension for the profiler.
|
* Twig extension for the profiler.
|
||||||
*
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* @internal since Symfony 4.4
|
||||||
*/
|
*/
|
||||||
class WebProfilerExtension extends ProfilerExtension
|
class WebProfilerExtension extends ProfilerExtension
|
||||||
{
|
{
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"php": "^7.2.9",
|
"php": "^7.2.9",
|
||||||
"symfony/config": "^4.4|^5.0",
|
"symfony/config": "^4.4|^5.0",
|
||||||
|
"symfony/error-renderer": "^4.4|^5.0",
|
||||||
"symfony/http-kernel": "^4.4|^5.0",
|
"symfony/http-kernel": "^4.4|^5.0",
|
||||||
"symfony/routing": "^4.4|^5.0",
|
"symfony/routing": "^4.4|^5.0",
|
||||||
"symfony/twig-bundle": "^4.4|^5.0",
|
"symfony/twig-bundle": "^4.4|^5.0",
|
||||||
|
@ -22,7 +22,9 @@ CHANGELOG
|
|||||||
4.4.0
|
4.4.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
* preferred choices are repeated in the list of all choices
|
||||||
* deprecated using `int` or `float` as data for the `NumberType` when the `input` option is set to `string`
|
* deprecated using `int` or `float` as data for the `NumberType` when the `input` option is set to `string`
|
||||||
|
* The type guesser guesses the HTML accept attribute when a mime type is configured in the File or Image constraint.
|
||||||
|
|
||||||
4.3.0
|
4.3.0
|
||||||
-----
|
-----
|
||||||
|
@ -157,9 +157,9 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
|
|||||||
if ($isPreferred && false !== $preferredKey = $isPreferred($choice, $key, $value)) {
|
if ($isPreferred && false !== $preferredKey = $isPreferred($choice, $key, $value)) {
|
||||||
$preferredViews[$nextIndex] = $view;
|
$preferredViews[$nextIndex] = $view;
|
||||||
$preferredViewsOrder[$nextIndex] = $preferredKey;
|
$preferredViewsOrder[$nextIndex] = $preferredKey;
|
||||||
} else {
|
|
||||||
$otherViews[$nextIndex] = $view;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$otherViews[$nextIndex] = $view;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function addChoiceViewsFromStructuredValues($values, $label, $choices, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$preferredViewsOrder, &$otherViews)
|
private static function addChoiceViewsFromStructuredValues($values, $label, $choices, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$preferredViewsOrder, &$otherViews)
|
||||||
|
@ -122,7 +122,12 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface
|
|||||||
|
|
||||||
case 'Symfony\Component\Validator\Constraints\File':
|
case 'Symfony\Component\Validator\Constraints\File':
|
||||||
case 'Symfony\Component\Validator\Constraints\Image':
|
case 'Symfony\Component\Validator\Constraints\Image':
|
||||||
return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\FileType', [], Guess::HIGH_CONFIDENCE);
|
$options = [];
|
||||||
|
if ($constraint->mimeTypes) {
|
||||||
|
$options = ['attr' => ['accept' => implode(',', (array) $constraint->mimeTypes)]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\FileType', $options, Guess::HIGH_CONFIDENCE);
|
||||||
|
|
||||||
case 'Symfony\Component\Validator\Constraints\Language':
|
case 'Symfony\Component\Validator\Constraints\Language':
|
||||||
return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\LanguageType', [], Guess::HIGH_CONFIDENCE);
|
return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\LanguageType', [], Guess::HIGH_CONFIDENCE);
|
||||||
|
@ -741,8 +741,9 @@ abstract class AbstractLayoutTest extends FormIntegrationTestCase
|
|||||||
./option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
|
./option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
|
||||||
/following-sibling::option[@disabled="disabled"][not(@selected)][.="-- sep --"]
|
/following-sibling::option[@disabled="disabled"][not(@selected)][.="-- sep --"]
|
||||||
/following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
|
/following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
|
||||||
|
/following-sibling::option[@value="&b"][.="[trans]Choice&B[/trans]"]
|
||||||
]
|
]
|
||||||
[count(./option)=3]
|
[count(./option)=4]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -763,8 +764,9 @@ abstract class AbstractLayoutTest extends FormIntegrationTestCase
|
|||||||
[
|
[
|
||||||
./option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
|
./option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
|
||||||
/following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
|
/following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
|
||||||
|
/following-sibling::option[@value="&b"][.="[trans]Choice&B[/trans]"]
|
||||||
]
|
]
|
||||||
[count(./option)=2]
|
[count(./option)=3]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -786,8 +788,9 @@ abstract class AbstractLayoutTest extends FormIntegrationTestCase
|
|||||||
./option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
|
./option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
|
||||||
/following-sibling::option[@disabled="disabled"][not(@selected)][.=""]
|
/following-sibling::option[@disabled="disabled"][not(@selected)][.=""]
|
||||||
/following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
|
/following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
|
||||||
|
/following-sibling::option[@value="&b"][.="[trans]Choice&B[/trans]"]
|
||||||
]
|
]
|
||||||
[count(./option)=3]
|
[count(./option)=4]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -803,7 +806,7 @@ abstract class AbstractLayoutTest extends FormIntegrationTestCase
|
|||||||
|
|
||||||
$this->assertWidgetMatchesXpath($form->createView(), [],
|
$this->assertWidgetMatchesXpath($form->createView(), [],
|
||||||
'/select
|
'/select
|
||||||
[count(./option)=2]
|
[count(./option)=5]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -739,6 +739,8 @@ class DefaultChoiceListFactoryTest extends TestCase
|
|||||||
$this->assertEquals(new ChoiceListView(
|
$this->assertEquals(new ChoiceListView(
|
||||||
[
|
[
|
||||||
0 => new ChoiceView($this->obj1, '0', 'A'),
|
0 => new ChoiceView($this->obj1, '0', 'A'),
|
||||||
|
1 => new ChoiceView($this->obj2, '1', 'B'),
|
||||||
|
2 => new ChoiceView($this->obj3, '2', 'C'),
|
||||||
3 => new ChoiceView($this->obj4, '3', 'D'),
|
3 => new ChoiceView($this->obj4, '3', 'D'),
|
||||||
], [
|
], [
|
||||||
1 => new ChoiceView($this->obj2, '1', 'B'),
|
1 => new ChoiceView($this->obj2, '1', 'B'),
|
||||||
@ -752,6 +754,8 @@ class DefaultChoiceListFactoryTest extends TestCase
|
|||||||
$this->assertEquals(new ChoiceListView(
|
$this->assertEquals(new ChoiceListView(
|
||||||
[
|
[
|
||||||
'w' => new ChoiceView($this->obj1, '0', 'A'),
|
'w' => new ChoiceView($this->obj1, '0', 'A'),
|
||||||
|
'x' => new ChoiceView($this->obj2, '1', 'B'),
|
||||||
|
'y' => new ChoiceView($this->obj3, '2', 'C'),
|
||||||
'z' => new ChoiceView($this->obj4, '3', 'D'),
|
'z' => new ChoiceView($this->obj4, '3', 'D'),
|
||||||
], [
|
], [
|
||||||
'x' => new ChoiceView($this->obj2, '1', 'B'),
|
'x' => new ChoiceView($this->obj2, '1', 'B'),
|
||||||
@ -765,6 +769,18 @@ class DefaultChoiceListFactoryTest extends TestCase
|
|||||||
$this->assertEquals(new ChoiceListView(
|
$this->assertEquals(new ChoiceListView(
|
||||||
[
|
[
|
||||||
0 => new ChoiceView($this->obj1, '0', 'A'),
|
0 => new ChoiceView($this->obj1, '0', 'A'),
|
||||||
|
1 => new ChoiceView(
|
||||||
|
$this->obj2,
|
||||||
|
'1',
|
||||||
|
'B',
|
||||||
|
['attr1' => 'value1']
|
||||||
|
),
|
||||||
|
2 => new ChoiceView(
|
||||||
|
$this->obj3,
|
||||||
|
'2',
|
||||||
|
'C',
|
||||||
|
['attr2' => 'value2']
|
||||||
|
),
|
||||||
3 => new ChoiceView($this->obj4, '3', 'D'),
|
3 => new ChoiceView($this->obj4, '3', 'D'),
|
||||||
], [
|
], [
|
||||||
1 => new ChoiceView(
|
1 => new ChoiceView(
|
||||||
@ -789,11 +805,17 @@ class DefaultChoiceListFactoryTest extends TestCase
|
|||||||
[
|
[
|
||||||
'Group 1' => new ChoiceGroupView(
|
'Group 1' => new ChoiceGroupView(
|
||||||
'Group 1',
|
'Group 1',
|
||||||
[0 => new ChoiceView($this->obj1, '0', 'A')]
|
[
|
||||||
|
0 => new ChoiceView($this->obj1, '0', 'A'),
|
||||||
|
1 => new ChoiceView($this->obj2, '1', 'B'),
|
||||||
|
]
|
||||||
),
|
),
|
||||||
'Group 2' => new ChoiceGroupView(
|
'Group 2' => new ChoiceGroupView(
|
||||||
'Group 2',
|
'Group 2',
|
||||||
[3 => new ChoiceView($this->obj4, '3', 'D')]
|
[
|
||||||
|
2 => new ChoiceView($this->obj3, '2', 'C'),
|
||||||
|
3 => new ChoiceView($this->obj4, '3', 'D'),
|
||||||
|
]
|
||||||
),
|
),
|
||||||
], [
|
], [
|
||||||
'Group 1' => new ChoiceGroupView(
|
'Group 1' => new ChoiceGroupView(
|
||||||
|
@ -1731,7 +1731,9 @@ class ChoiceTypeTest extends BaseTypeTest
|
|||||||
|
|
||||||
$this->assertEquals([
|
$this->assertEquals([
|
||||||
0 => new ChoiceView('a', 'a', 'A'),
|
0 => new ChoiceView('a', 'a', 'A'),
|
||||||
|
1 => new ChoiceView('b', 'b', 'B'),
|
||||||
2 => new ChoiceView('c', 'c', 'C'),
|
2 => new ChoiceView('c', 'c', 'C'),
|
||||||
|
3 => new ChoiceView('d', 'd', 'D'),
|
||||||
], $view->vars['choices']);
|
], $view->vars['choices']);
|
||||||
$this->assertEquals([
|
$this->assertEquals([
|
||||||
1 => new ChoiceView('b', 'b', 'B'),
|
1 => new ChoiceView('b', 'b', 'B'),
|
||||||
@ -1750,9 +1752,11 @@ class ChoiceTypeTest extends BaseTypeTest
|
|||||||
$this->assertEquals([
|
$this->assertEquals([
|
||||||
'Symfony' => new ChoiceGroupView('Symfony', [
|
'Symfony' => new ChoiceGroupView('Symfony', [
|
||||||
0 => new ChoiceView('a', 'a', 'Bernhard'),
|
0 => new ChoiceView('a', 'a', 'Bernhard'),
|
||||||
|
1 => new ChoiceView('b', 'b', 'Fabien'),
|
||||||
2 => new ChoiceView('c', 'c', 'Kris'),
|
2 => new ChoiceView('c', 'c', 'Kris'),
|
||||||
]),
|
]),
|
||||||
'Doctrine' => new ChoiceGroupView('Doctrine', [
|
'Doctrine' => new ChoiceGroupView('Doctrine', [
|
||||||
|
3 => new ChoiceView('d', 'd', 'Jon'),
|
||||||
4 => new ChoiceView('e', 'e', 'Roman'),
|
4 => new ChoiceView('e', 'e', 'Roman'),
|
||||||
]),
|
]),
|
||||||
], $view->vars['choices']);
|
], $view->vars['choices']);
|
||||||
|
@ -16,6 +16,7 @@ use Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser;
|
|||||||
use Symfony\Component\Form\Guess\Guess;
|
use Symfony\Component\Form\Guess\Guess;
|
||||||
use Symfony\Component\Form\Guess\ValueGuess;
|
use Symfony\Component\Form\Guess\ValueGuess;
|
||||||
use Symfony\Component\Validator\Constraints\Email;
|
use Symfony\Component\Validator\Constraints\Email;
|
||||||
|
use Symfony\Component\Validator\Constraints\File;
|
||||||
use Symfony\Component\Validator\Constraints\IsTrue;
|
use Symfony\Component\Validator\Constraints\IsTrue;
|
||||||
use Symfony\Component\Validator\Constraints\Length;
|
use Symfony\Component\Validator\Constraints\Length;
|
||||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||||
@ -107,6 +108,43 @@ class ValidatorTypeGuesserTest extends TestCase
|
|||||||
$this->assertNull($result);
|
$this->assertNull($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGuessMimeTypesForConstraintWithMimeTypesValue()
|
||||||
|
{
|
||||||
|
$mineTypes = ['image/png', 'image/jpeg'];
|
||||||
|
$constraint = new File(['mimeTypes' => $mineTypes]);
|
||||||
|
$typeGuess = $this->guesser->guessTypeForConstraint($constraint);
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Form\Guess\TypeGuess', $typeGuess);
|
||||||
|
$this->assertArrayHasKey('attr', $typeGuess->getOptions());
|
||||||
|
$this->assertArrayHasKey('accept', $typeGuess->getOptions()['attr']);
|
||||||
|
$this->assertEquals(implode(',', $mineTypes), $typeGuess->getOptions()['attr']['accept']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGuessMimeTypesForConstraintWithoutMimeTypesValue()
|
||||||
|
{
|
||||||
|
$constraint = new File();
|
||||||
|
$typeGuess = $this->guesser->guessTypeForConstraint($constraint);
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Form\Guess\TypeGuess', $typeGuess);
|
||||||
|
$this->assertArrayNotHasKey('attr', $typeGuess->getOptions());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGuessMimeTypesForConstraintWithMimeTypesStringValue()
|
||||||
|
{
|
||||||
|
$constraint = new File(['mimeTypes' => 'image/*']);
|
||||||
|
$typeGuess = $this->guesser->guessTypeForConstraint($constraint);
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Form\Guess\TypeGuess', $typeGuess);
|
||||||
|
$this->assertArrayHasKey('attr', $typeGuess->getOptions());
|
||||||
|
$this->assertArrayHasKey('accept', $typeGuess->getOptions()['attr']);
|
||||||
|
$this->assertEquals('image/*', $typeGuess->getOptions()['attr']['accept']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGuessMimeTypesForConstraintWithMimeTypesEmptyStringValue()
|
||||||
|
{
|
||||||
|
$constraint = new File(['mimeTypes' => '']);
|
||||||
|
$typeGuess = $this->guesser->guessTypeForConstraint($constraint);
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Form\Guess\TypeGuess', $typeGuess);
|
||||||
|
$this->assertArrayNotHasKey('attr', $typeGuess->getOptions());
|
||||||
|
}
|
||||||
|
|
||||||
public function maxLengthTypeProvider()
|
public function maxLengthTypeProvider()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
@ -100,7 +100,13 @@ final class HttplugClient implements HttpClient, RequestFactory, StreamFactory,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (\is_string($body ?? '')) {
|
if (\is_string($body ?? '')) {
|
||||||
return $this->client->createStream($body ?? '');
|
$body = $this->client->createStream($body ?? '');
|
||||||
|
|
||||||
|
if ($body->isSeekable()) {
|
||||||
|
$body->seek(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $body;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (\is_resource($body)) {
|
if (\is_resource($body)) {
|
||||||
|
@ -78,9 +78,15 @@ final class Psr18Client implements ClientInterface, RequestFactoryInterface, Str
|
|||||||
public function sendRequest(RequestInterface $request): ResponseInterface
|
public function sendRequest(RequestInterface $request): ResponseInterface
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$body = $request->getBody();
|
||||||
|
|
||||||
|
if ($body->isSeekable()) {
|
||||||
|
$body->seek(0);
|
||||||
|
}
|
||||||
|
|
||||||
$response = $this->client->request($request->getMethod(), (string) $request->getUri(), [
|
$response = $this->client->request($request->getMethod(), (string) $request->getUri(), [
|
||||||
'headers' => $request->getHeaders(),
|
'headers' => $request->getHeaders(),
|
||||||
'body' => (string) $request->getBody(),
|
'body' => $body->getContents(),
|
||||||
'http_version' => '1.0' === $request->getProtocolVersion() ? '1.0' : null,
|
'http_version' => '1.0' === $request->getProtocolVersion() ? '1.0' : null,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -93,8 +99,13 @@ final class Psr18Client implements ClientInterface, RequestFactoryInterface, Str
|
|||||||
}
|
}
|
||||||
|
|
||||||
$body = isset(class_uses($response)[ResponseTrait::class]) ? $response->toStream(false) : StreamWrapper::createResource($response, $this->client);
|
$body = isset(class_uses($response)[ResponseTrait::class]) ? $response->toStream(false) : StreamWrapper::createResource($response, $this->client);
|
||||||
|
$body = $this->streamFactory->createStreamFromResource($body);
|
||||||
|
|
||||||
return $psrResponse->withBody($this->streamFactory->createStreamFromResource($body));
|
if ($body->isSeekable()) {
|
||||||
|
$body->seek(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $psrResponse->withBody($body);
|
||||||
} catch (TransportExceptionInterface $e) {
|
} catch (TransportExceptionInterface $e) {
|
||||||
if ($e instanceof \InvalidArgumentException) {
|
if ($e instanceof \InvalidArgumentException) {
|
||||||
throw new Psr18RequestException($e, $request);
|
throw new Psr18RequestException($e, $request);
|
||||||
@ -125,7 +136,13 @@ final class Psr18Client implements ClientInterface, RequestFactoryInterface, Str
|
|||||||
*/
|
*/
|
||||||
public function createStream(string $content = ''): StreamInterface
|
public function createStream(string $content = ''): StreamInterface
|
||||||
{
|
{
|
||||||
return $this->streamFactory->createStream($content);
|
$stream = $this->streamFactory->createStream($content);
|
||||||
|
|
||||||
|
if ($stream->isSeekable()) {
|
||||||
|
$stream->seek(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,6 +78,15 @@ class MockResponse implements ResponseInterface
|
|||||||
return null !== $type ? $this->info[$type] ?? null : $this->info;
|
return null !== $type ? $this->info[$type] ?? null : $this->info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function cancel(): void
|
||||||
|
{
|
||||||
|
$this->info['error'] = 'Response has been canceled.';
|
||||||
|
$this->body = null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
@ -150,8 +159,11 @@ class MockResponse implements ResponseInterface
|
|||||||
foreach ($responses as $response) {
|
foreach ($responses as $response) {
|
||||||
$id = $response->id;
|
$id = $response->id;
|
||||||
|
|
||||||
if (!$response->body) {
|
if (null === $response->body) {
|
||||||
// Last chunk
|
// Canceled response
|
||||||
|
$response->body = [];
|
||||||
|
} elseif ([] === $response->body) {
|
||||||
|
// Error chunk
|
||||||
$multi->handlesActivity[$id][] = null;
|
$multi->handlesActivity[$id][] = null;
|
||||||
$multi->handlesActivity[$id][] = null !== $response->info['error'] ? new TransportException($response->info['error']) : null;
|
$multi->handlesActivity[$id][] = null !== $response->info['error'] ? new TransportException($response->info['error']) : null;
|
||||||
} elseif (null === $chunk = array_shift($response->body)) {
|
} elseif (null === $chunk = array_shift($response->body)) {
|
||||||
@ -242,7 +254,7 @@ class MockResponse implements ResponseInterface
|
|||||||
|
|
||||||
// populate info related to headers
|
// populate info related to headers
|
||||||
$info = $mock->getInfo() ?: [];
|
$info = $mock->getInfo() ?: [];
|
||||||
$response->info['http_code'] = ($info['http_code'] ?? 0) ?: $mock->getStatusCode(false) ?: 200;
|
$response->info['http_code'] = ($info['http_code'] ?? 0) ?: $mock->getStatusCode() ?: 200;
|
||||||
$response->addResponseHeaders($info['response_headers'] ?? [], $response->info, $response->headers);
|
$response->addResponseHeaders($info['response_headers'] ?? [], $response->info, $response->headers);
|
||||||
$dlSize = isset($response->headers['content-encoding']) ? 0 : (int) ($response->headers['content-length'][0] ?? 0);
|
$dlSize = isset($response->headers['content-encoding']) ? 0 : (int) ($response->headers['content-length'][0] ?? 0);
|
||||||
|
|
||||||
|
@ -349,7 +349,7 @@ trait ResponseTrait
|
|||||||
|
|
||||||
unset($multi->handlesActivity[$j]);
|
unset($multi->handlesActivity[$j]);
|
||||||
|
|
||||||
if ($chunk instanceof FirstChunk && null === $response->initializer) {
|
if ($chunk instanceof FirstChunk && null === $response->initializer && null === $response->info['error']) {
|
||||||
// Ensure the HTTP status code is always checked
|
// Ensure the HTTP status code is always checked
|
||||||
$response->getHeaders(true);
|
$response->getHeaders(true);
|
||||||
} elseif ($chunk instanceof ErrorChunk && !$chunk->didThrow()) {
|
} elseif ($chunk instanceof ErrorChunk && !$chunk->didThrow()) {
|
||||||
|
@ -33,7 +33,7 @@ class DayTransformer extends Transformer
|
|||||||
*/
|
*/
|
||||||
public function getReverseMatchingRegExp(int $length): string
|
public function getReverseMatchingRegExp(int $length): string
|
||||||
{
|
{
|
||||||
return 1 === $length ? '\d{1,2}' : '\d{'.$length.'}';
|
return 1 === $length ? '\d{1,2}' : '\d{1,'.$length.'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -104,7 +104,7 @@ class MonthTransformer extends Transformer
|
|||||||
$regExp = '[JFMASOND]';
|
$regExp = '[JFMASOND]';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$regExp = '\d{'.$length.'}';
|
$regExp = '\d{1,'.$length.'}';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ class YearTransformer extends Transformer
|
|||||||
*/
|
*/
|
||||||
public function getReverseMatchingRegExp(int $length): string
|
public function getReverseMatchingRegExp(int $length): string
|
||||||
{
|
{
|
||||||
return 2 === $length ? '\d{2}' : '\d{4}';
|
return 2 === $length ? '\d{2}' : '\d{1,4}';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -600,6 +600,7 @@ abstract class AbstractIntlDateFormatterTest extends TestCase
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
['y-M-d', '1970-1-1', 0],
|
['y-M-d', '1970-1-1', 0],
|
||||||
|
['y-MM-d', '1970-1-1', 0],
|
||||||
['y-MMM-d', '1970-Jan-1', 0],
|
['y-MMM-d', '1970-Jan-1', 0],
|
||||||
['y-MMMM-d', '1970-January-1', 0],
|
['y-MMMM-d', '1970-January-1', 0],
|
||||||
];
|
];
|
||||||
@ -618,6 +619,7 @@ abstract class AbstractIntlDateFormatterTest extends TestCase
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
['y-M-d', '1970-1-1', 0],
|
['y-M-d', '1970-1-1', 0],
|
||||||
|
['y-M-dd', '1970-1-1', 0],
|
||||||
['y-M-dd', '1970-1-01', 0],
|
['y-M-dd', '1970-1-01', 0],
|
||||||
['y-M-ddd', '1970-1-001', 0],
|
['y-M-ddd', '1970-1-001', 0],
|
||||||
];
|
];
|
||||||
|
@ -183,6 +183,17 @@ class IntlDateFormatterTest extends AbstractIntlDateFormatterTest
|
|||||||
return $this->notImplemented(parent::parseQuarterProvider());
|
return $this->notImplemented(parent::parseQuarterProvider());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testParseThreeDigitsYears()
|
||||||
|
{
|
||||||
|
if (PHP_INT_SIZE < 8) {
|
||||||
|
$this->markTestSkipped('Parsing three digits years requires a 64bit PHP.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$formatter = $this->getDefaultDateFormatter('yyyy-M-d');
|
||||||
|
$this->assertSame(-32157648000, $formatter->parse('950-12-19'));
|
||||||
|
$this->assertIsIntlSuccess($formatter, 'U_ZERO_ERROR', IntlGlobals::U_ZERO_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
protected function getDateFormatter($locale, $datetype, $timetype, $timezone = null, $calendar = IntlDateFormatter::GREGORIAN, $pattern = null)
|
protected function getDateFormatter($locale, $datetype, $timetype, $timezone = null, $calendar = IntlDateFormatter::GREGORIAN, $pattern = null)
|
||||||
{
|
{
|
||||||
return new IntlDateFormatter($locale, $datetype, $timetype, $timezone, $calendar, $pattern);
|
return new IntlDateFormatter($locale, $datetype, $timetype, $timezone, $calendar, $pattern);
|
||||||
|
@ -79,6 +79,19 @@ class MessengerDataCollector extends DataCollector implements LateDataCollectorI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function getCasters()
|
||||||
|
{
|
||||||
|
$casters = parent::getCasters();
|
||||||
|
|
||||||
|
// Unset the default caster truncating collectors data.
|
||||||
|
unset($casters['*']);
|
||||||
|
|
||||||
|
return $casters;
|
||||||
|
}
|
||||||
|
|
||||||
private function collectMessage(string $busName, array $tracedMessage)
|
private function collectMessage(string $busName, array $tracedMessage)
|
||||||
{
|
{
|
||||||
$message = $tracedMessage['message'];
|
$message = $tracedMessage['message'];
|
||||||
|
@ -62,7 +62,7 @@ class TraceableMessageBusTest extends TestCase
|
|||||||
unset($actualTracedMessage['callTime']); // don't check, too variable
|
unset($actualTracedMessage['callTime']); // don't check, too variable
|
||||||
$this->assertEquals([
|
$this->assertEquals([
|
||||||
'message' => $message,
|
'message' => $message,
|
||||||
'stamps' => [[$stamp]],
|
'stamps' => [$stamp],
|
||||||
'caller' => [
|
'caller' => [
|
||||||
'name' => 'TraceableMessageBusTest.php',
|
'name' => 'TraceableMessageBusTest.php',
|
||||||
'file' => __FILE__,
|
'file' => __FILE__,
|
||||||
|
@ -31,7 +31,7 @@ class TraceableMessageBus implements MessageBusInterface
|
|||||||
{
|
{
|
||||||
$envelope = Envelope::wrap($message, $stamps);
|
$envelope = Envelope::wrap($message, $stamps);
|
||||||
$context = [
|
$context = [
|
||||||
'stamps' => array_values($envelope->all()),
|
'stamps' => array_merge([], ...array_values($envelope->all())),
|
||||||
'message' => $envelope->getMessage(),
|
'message' => $envelope->getMessage(),
|
||||||
'caller' => $this->getCaller(),
|
'caller' => $this->getCaller(),
|
||||||
'callTime' => microtime(true),
|
'callTime' => microtime(true),
|
||||||
|
@ -43,6 +43,28 @@ class PropertyAccessorCollectionTest_Car
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PropertyAccessorCollectionTest_CarOnlyAdder
|
||||||
|
{
|
||||||
|
public function addAxis($axis)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAxes()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PropertyAccessorCollectionTest_CarOnlyRemover
|
||||||
|
{
|
||||||
|
public function removeAxis($axis)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAxes()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class PropertyAccessorCollectionTest_CarNoAdderAndRemover
|
class PropertyAccessorCollectionTest_CarNoAdderAndRemover
|
||||||
{
|
{
|
||||||
public function getAxes()
|
public function getAxes()
|
||||||
@ -143,25 +165,25 @@ abstract class PropertyAccessorCollectionTest extends PropertyAccessorArrayAcces
|
|||||||
|
|
||||||
public function testIsWritableReturnsTrueIfAdderAndRemoverExists()
|
public function testIsWritableReturnsTrueIfAdderAndRemoverExists()
|
||||||
{
|
{
|
||||||
$car = $this->getMockBuilder(__CLASS__.'_Car')->getMock();
|
$car = new PropertyAccessorCollectionTest_Car();
|
||||||
$this->assertTrue($this->propertyAccessor->isWritable($car, 'axes'));
|
$this->assertTrue($this->propertyAccessor->isWritable($car, 'axes'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testIsWritableReturnsFalseIfOnlyAdderExists()
|
public function testIsWritableReturnsFalseIfOnlyAdderExists()
|
||||||
{
|
{
|
||||||
$car = $this->getMockBuilder(__CLASS__.'_CarOnlyAdder')->getMock();
|
$car = new PropertyAccessorCollectionTest_CarOnlyAdder();
|
||||||
$this->assertFalse($this->propertyAccessor->isWritable($car, 'axes'));
|
$this->assertFalse($this->propertyAccessor->isWritable($car, 'axes'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testIsWritableReturnsFalseIfOnlyRemoverExists()
|
public function testIsWritableReturnsFalseIfOnlyRemoverExists()
|
||||||
{
|
{
|
||||||
$car = $this->getMockBuilder(__CLASS__.'_CarOnlyRemover')->getMock();
|
$car = new PropertyAccessorCollectionTest_CarOnlyRemover();
|
||||||
$this->assertFalse($this->propertyAccessor->isWritable($car, 'axes'));
|
$this->assertFalse($this->propertyAccessor->isWritable($car, 'axes'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testIsWritableReturnsFalseIfNoAdderNorRemoverExists()
|
public function testIsWritableReturnsFalseIfNoAdderNorRemoverExists()
|
||||||
{
|
{
|
||||||
$car = $this->getMockBuilder(__CLASS__.'_CarNoAdderAndRemover')->getMock();
|
$car = new PropertyAccessorCollectionTest_CarNoAdderAndRemover();
|
||||||
$this->assertFalse($this->propertyAccessor->isWritable($car, 'axes'));
|
$this->assertFalse($this->propertyAccessor->isWritable($car, 'axes'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +193,7 @@ abstract class PropertyAccessorCollectionTest extends PropertyAccessorArrayAcces
|
|||||||
*/
|
*/
|
||||||
public function testSetValueFailsIfAdderAndRemoverExistButValueIsNotTraversable()
|
public function testSetValueFailsIfAdderAndRemoverExistButValueIsNotTraversable()
|
||||||
{
|
{
|
||||||
$car = $this->getMockBuilder(__CLASS__.'_Car')->getMock();
|
$car = new PropertyAccessorCollectionTest_Car();
|
||||||
|
|
||||||
$this->propertyAccessor->setValue($car, 'axes', 'Not an array or Traversable');
|
$this->propertyAccessor->setValue($car, 'axes', 'Not an array or Traversable');
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ CHANGELOG
|
|||||||
Instead of overwriting them, use `__serialize` and `__unserialize` as extension points which are forward compatible
|
Instead of overwriting them, use `__serialize` and `__unserialize` as extension points which are forward compatible
|
||||||
with the new serialization methods in PHP 7.4.
|
with the new serialization methods in PHP 7.4.
|
||||||
* exposed `utf8` Route option, defaults "locale" and "format" in configuration loaders and configurators
|
* exposed `utf8` Route option, defaults "locale" and "format" in configuration loaders and configurators
|
||||||
* added support for invokable route loader services
|
* added support for invokable service route loaders
|
||||||
|
|
||||||
4.2.0
|
4.2.0
|
||||||
-----
|
-----
|
||||||
|
@ -30,7 +30,7 @@ final class NativePasswordEncoder implements PasswordEncoderInterface, SelfSalti
|
|||||||
public function __construct(int $opsLimit = null, int $memLimit = null, int $cost = null)
|
public function __construct(int $opsLimit = null, int $memLimit = null, int $cost = null)
|
||||||
{
|
{
|
||||||
$cost = $cost ?? 13;
|
$cost = $cost ?? 13;
|
||||||
$opsLimit = $opsLimit ?? max(6, \defined('SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE') ? \SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE : 6);
|
$opsLimit = $opsLimit ?? max(4, \defined('SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE') ? \SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE : 4);
|
||||||
$memLimit = $memLimit ?? max(64 * 1024 * 1024, \defined('SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE') ? \SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE : 64 * 1024 * 1024);
|
$memLimit = $memLimit ?? max(64 * 1024 * 1024, \defined('SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE') ? \SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE : 64 * 1024 * 1024);
|
||||||
|
|
||||||
if (3 > $opsLimit) {
|
if (3 > $opsLimit) {
|
||||||
|
@ -34,7 +34,7 @@ final class SodiumPasswordEncoder implements PasswordEncoderInterface, SelfSalti
|
|||||||
throw new LogicException('Libsodium is not available. You should either install the sodium extension, upgrade to PHP 7.2+ or use a different encoder.');
|
throw new LogicException('Libsodium is not available. You should either install the sodium extension, upgrade to PHP 7.2+ or use a different encoder.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->opsLimit = $opsLimit ?? max(6, \defined('SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE') ? \SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE : 6);
|
$this->opsLimit = $opsLimit ?? max(4, \defined('SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE') ? \SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE : 4);
|
||||||
$this->memLimit = $memLimit ?? max(64 * 1024 * 1024, \defined('SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE') ? \SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE : 64 * 1024 * 2014);
|
$this->memLimit = $memLimit ?? max(64 * 1024 * 1024, \defined('SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE') ? \SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE : 64 * 1024 * 2014);
|
||||||
|
|
||||||
if (3 > $this->opsLimit) {
|
if (3 > $this->opsLimit) {
|
||||||
|
@ -380,7 +380,3 @@ class ArrayDenormalizerDummy implements DenormalizerInterface, SerializerAwareIn
|
|||||||
$this->serializer = $serializer;
|
$this->serializer = $serializer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class ObjectSerializerDenormalizer implements SerializerInterface, DenormalizerInterface
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Yaml;
|
namespace Symfony\Component\Yaml;
|
||||||
|
|
||||||
|
use Symfony\Component\Yaml\Tag\TaggedValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dumper dumps PHP variables to YAML strings.
|
* Dumper dumps PHP variables to YAML strings.
|
||||||
*
|
*
|
||||||
@ -56,7 +58,7 @@ class Dumper
|
|||||||
$dumpObjectAsInlineMap = empty((array) $input);
|
$dumpObjectAsInlineMap = empty((array) $input);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($inline <= 0 || (!\is_array($input) && $dumpObjectAsInlineMap) || empty($input)) {
|
if ($inline <= 0 || (!\is_array($input) && !$input instanceof TaggedValue && $dumpObjectAsInlineMap) || empty($input)) {
|
||||||
$output .= $prefix.Inline::dump($input, $flags);
|
$output .= $prefix.Inline::dump($input, $flags);
|
||||||
} else {
|
} else {
|
||||||
$dumpAsMap = Inline::isHash($input);
|
$dumpAsMap = Inline::isHash($input);
|
||||||
@ -75,6 +77,19 @@ class Dumper
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($value instanceof TaggedValue) {
|
||||||
|
$output .= sprintf('%s%s !%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', $value->getTag());
|
||||||
|
|
||||||
|
if ($inline - 1 <= 0) {
|
||||||
|
$output .= ' '.$this->dump($value->getValue(), $inline - 1, 0, $flags)."\n";
|
||||||
|
} else {
|
||||||
|
$output .= "\n";
|
||||||
|
$output .= $this->dump($value->getValue(), $inline - 1, $dumpAsMap ? $indent + $this->indentation : $indent + 2, $flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$dumpObjectAsInlineMap = true;
|
$dumpObjectAsInlineMap = true;
|
||||||
|
|
||||||
if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \ArrayObject || $value instanceof \stdClass)) {
|
if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \ArrayObject || $value instanceof \stdClass)) {
|
||||||
|
@ -14,6 +14,7 @@ namespace Symfony\Component\Yaml\Tests;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Yaml\Dumper;
|
use Symfony\Component\Yaml\Dumper;
|
||||||
use Symfony\Component\Yaml\Parser;
|
use Symfony\Component\Yaml\Parser;
|
||||||
|
use Symfony\Component\Yaml\Tag\TaggedValue;
|
||||||
use Symfony\Component\Yaml\Yaml;
|
use Symfony\Component\Yaml\Yaml;
|
||||||
|
|
||||||
class DumperTest extends TestCase
|
class DumperTest extends TestCase
|
||||||
@ -368,6 +369,94 @@ outer2:
|
|||||||
inner2: c
|
inner2: c
|
||||||
inner3: { deep1: d, deep2: e }
|
inner3: { deep1: d, deep2: e }
|
||||||
|
|
||||||
|
YAML;
|
||||||
|
$this->assertSame($expected, $yaml);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDumpingTaggedValueSequenceRespectsInlineLevel()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
new TaggedValue('user', [
|
||||||
|
'username' => 'jane',
|
||||||
|
]),
|
||||||
|
new TaggedValue('user', [
|
||||||
|
'username' => 'john',
|
||||||
|
]),
|
||||||
|
];
|
||||||
|
|
||||||
|
$yaml = $this->dumper->dump($data, 2);
|
||||||
|
|
||||||
|
$expected = <<<YAML
|
||||||
|
- !user
|
||||||
|
username: jane
|
||||||
|
- !user
|
||||||
|
username: john
|
||||||
|
|
||||||
|
YAML;
|
||||||
|
$this->assertSame($expected, $yaml);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDumpingTaggedValueSequenceWithInlinedTagValues()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
new TaggedValue('user', [
|
||||||
|
'username' => 'jane',
|
||||||
|
]),
|
||||||
|
new TaggedValue('user', [
|
||||||
|
'username' => 'john',
|
||||||
|
]),
|
||||||
|
];
|
||||||
|
|
||||||
|
$yaml = $this->dumper->dump($data, 1);
|
||||||
|
|
||||||
|
$expected = <<<YAML
|
||||||
|
- !user { username: jane }
|
||||||
|
- !user { username: john }
|
||||||
|
|
||||||
|
YAML;
|
||||||
|
$this->assertSame($expected, $yaml);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDumpingTaggedValueMapRespectsInlineLevel()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'user1' => new TaggedValue('user', [
|
||||||
|
'username' => 'jane',
|
||||||
|
]),
|
||||||
|
'user2' => new TaggedValue('user', [
|
||||||
|
'username' => 'john',
|
||||||
|
]),
|
||||||
|
];
|
||||||
|
|
||||||
|
$yaml = $this->dumper->dump($data, 2);
|
||||||
|
|
||||||
|
$expected = <<<YAML
|
||||||
|
user1: !user
|
||||||
|
username: jane
|
||||||
|
user2: !user
|
||||||
|
username: john
|
||||||
|
|
||||||
|
YAML;
|
||||||
|
$this->assertSame($expected, $yaml);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDumpingTaggedValueMapWithInlinedTagValues()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'user1' => new TaggedValue('user', [
|
||||||
|
'username' => 'jane',
|
||||||
|
]),
|
||||||
|
'user2' => new TaggedValue('user', [
|
||||||
|
'username' => 'john',
|
||||||
|
]),
|
||||||
|
];
|
||||||
|
|
||||||
|
$yaml = $this->dumper->dump($data, 1);
|
||||||
|
|
||||||
|
$expected = <<<YAML
|
||||||
|
user1: !user { username: jane }
|
||||||
|
user2: !user { username: john }
|
||||||
|
|
||||||
YAML;
|
YAML;
|
||||||
$this->assertSame($expected, $yaml);
|
$this->assertSame($expected, $yaml);
|
||||||
}
|
}
|
||||||
|
@ -505,6 +505,21 @@ abstract class HttpClientTestCase extends TestCase
|
|||||||
$response->getHeaders();
|
$response->getHeaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCancelInStream()
|
||||||
|
{
|
||||||
|
$client = $this->getHttpClient(__FUNCTION__);
|
||||||
|
$response = $client->request('GET', 'http://localhost:8057/404');
|
||||||
|
|
||||||
|
foreach ($client->stream($response) as $chunk) {
|
||||||
|
$response->cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->expectException(TransportExceptionInterface::class);
|
||||||
|
|
||||||
|
foreach ($client->stream($response) as $chunk) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function testOnProgressCancel()
|
public function testOnProgressCancel()
|
||||||
{
|
{
|
||||||
$client = $this->getHttpClient(__FUNCTION__);
|
$client = $this->getHttpClient(__FUNCTION__);
|
||||||
|
Reference in New Issue
Block a user