Merge branch '3.4' into 4.0
* 3.4:
[Bridge/Twig] fix composer.json
bug #26086 [FrameworkBundle] Fix using annotation_reader in compiler pass to inject configured cache provider
[WebProfilerBundle] Fix anchor CSS
[HttpKernel] Send new session cookie from AbstractTestSessionListener after session invalidation
[WebProfilerBundle] Tweak default route name
updated StopwatchEvent phpdoc due to the additional of optional float precision introduced in 0db8d7fb6a
Retro-fit proxy code to make it deterministic for older proxy manager implementations
Yaml parser regression with comments and non-strings
Fix undiscoverablility of SymfonyTestsListenerForV7
Fixed broken tests
[TwigBridge] Apply some changes to support Bootstrap4-stable
This commit is contained in:
commit
2871a96fa7
@ -9,7 +9,7 @@
|
|||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Symfony\Bridge\PhpUnit;
|
namespace Symfony\Bridge\PhpUnit\Legacy;
|
||||||
|
|
||||||
use PHPUnit\Framework\Test;
|
use PHPUnit\Framework\Test;
|
||||||
use PHPUnit\Framework\TestListener;
|
use PHPUnit\Framework\TestListener;
|
||||||
|
@ -13,6 +13,7 @@ namespace Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper;
|
|||||||
|
|
||||||
use ProxyManager\Generator\ClassGenerator;
|
use ProxyManager\Generator\ClassGenerator;
|
||||||
use ProxyManager\GeneratorStrategy\BaseGeneratorStrategy;
|
use ProxyManager\GeneratorStrategy\BaseGeneratorStrategy;
|
||||||
|
use ProxyManager\Version;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\DependencyInjection\Definition;
|
use Symfony\Component\DependencyInjection\Definition;
|
||||||
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface;
|
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface;
|
||||||
@ -88,27 +89,43 @@ EOF;
|
|||||||
*/
|
*/
|
||||||
public function getProxyCode(Definition $definition)
|
public function getProxyCode(Definition $definition)
|
||||||
{
|
{
|
||||||
return preg_replace(
|
$code = $this->classGenerator->generate($this->generateProxyClass($definition));
|
||||||
|
|
||||||
|
$code = preg_replace(
|
||||||
'/(\$this->initializer[0-9a-f]++) && \1->__invoke\(\$this->(valueHolder[0-9a-f]++), (.*?), \1\);/',
|
'/(\$this->initializer[0-9a-f]++) && \1->__invoke\(\$this->(valueHolder[0-9a-f]++), (.*?), \1\);/',
|
||||||
'$1 && ($1->__invoke(\$$2, $3, $1) || 1) && $this->$2 = \$$2;',
|
'$1 && ($1->__invoke(\$$2, $3, $1) || 1) && $this->$2 = \$$2;',
|
||||||
$this->classGenerator->generate($this->generateProxyClass($definition))
|
$code
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (version_compare(self::getProxyManagerVersion(), '2.2', '<')) {
|
||||||
|
$code = preg_replace(
|
||||||
|
'/((?:\$(?:this|initializer|instance)->)?(?:publicProperties|initializer|valueHolder))[0-9a-f]++/',
|
||||||
|
'${1}'.$this->getIdentifierSuffix($definition),
|
||||||
|
$code
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $code;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function getProxyManagerVersion(): string
|
||||||
|
{
|
||||||
|
if (!\class_exists(Version::class)) {
|
||||||
|
return '0.0.1';
|
||||||
|
}
|
||||||
|
|
||||||
|
return defined(Version::class.'::VERSION') ? Version::VERSION : Version::getVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Produces the proxy class name for the given definition.
|
* Produces the proxy class name for the given definition.
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
private function getProxyClassName(Definition $definition)
|
private function getProxyClassName(Definition $definition): string
|
||||||
{
|
{
|
||||||
return preg_replace('/^.*\\\\/', '', $definition->getClass()).'_'.substr(hash('sha256', $definition->getClass().$this->salt), -7);
|
return preg_replace('/^.*\\\\/', '', $definition->getClass()).'_'.$this->getIdentifierSuffix($definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private function generateProxyClass(Definition $definition): ClassGenerator
|
||||||
* @return ClassGenerator
|
|
||||||
*/
|
|
||||||
private function generateProxyClass(Definition $definition)
|
|
||||||
{
|
{
|
||||||
$generatedClass = new ClassGenerator($this->getProxyClassName($definition));
|
$generatedClass = new ClassGenerator($this->getProxyClassName($definition));
|
||||||
|
|
||||||
@ -116,4 +133,9 @@ EOF;
|
|||||||
|
|
||||||
return $generatedClass;
|
return $generatedClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getIdentifierSuffix(Definition $definition): string
|
||||||
|
{
|
||||||
|
return substr(hash('sha256', $definition->getClass().$this->salt), -7);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,14 @@ class ProxyDumperTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDeterministicProxyCode()
|
||||||
|
{
|
||||||
|
$definition = new Definition(__CLASS__);
|
||||||
|
$definition->setLazy(true);
|
||||||
|
|
||||||
|
$this->assertSame($this->dumper->getProxyCode($definition), $this->dumper->getProxyCode($definition));
|
||||||
|
}
|
||||||
|
|
||||||
public function testGetProxyFactoryCode()
|
public function testGetProxyFactoryCode()
|
||||||
{
|
{
|
||||||
$definition = new Definition(__CLASS__);
|
$definition = new Definition(__CLASS__);
|
||||||
|
@ -259,6 +259,6 @@ class CodeExtension extends AbstractExtension
|
|||||||
$line .= '</span>';
|
$line .= '</span>';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $line;
|
return trim($line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,25 @@
|
|||||||
{# Widgets #}
|
{# Widgets #}
|
||||||
|
|
||||||
{% block money_widget -%}
|
{% block money_widget -%}
|
||||||
{% if not valid %}
|
{%- set prepend = not (money_pattern starts with '{{') -%}
|
||||||
{% set group_class = ' form-control is-invalid' %}
|
{%- set append = not (money_pattern ends with '}}') -%}
|
||||||
{% set valid = true %}
|
{%- if prepend or append -%}
|
||||||
{% endif %}
|
<div class="input-group{{ group_class|default('') }}">
|
||||||
{{- parent() -}}
|
{%- if prepend -%}
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<span class="input-group-text">{{ money_pattern|replace({ '{{ widget }}':''}) }}</span>
|
||||||
|
</div>
|
||||||
|
{%- endif -%}
|
||||||
|
{{- block('form_widget_simple') -}}
|
||||||
|
{%- if append -%}
|
||||||
|
<div class="input-group-append">
|
||||||
|
<span class="input-group-text">{{ money_pattern|replace({ '{{ widget }}':''}) }}</span>
|
||||||
|
</div>
|
||||||
|
{%- endif -%}
|
||||||
|
</div>
|
||||||
|
{%- else -%}
|
||||||
|
{{- block('form_widget_simple') -}}
|
||||||
|
{%- endif -%}
|
||||||
{%- endblock money_widget %}
|
{%- endblock money_widget %}
|
||||||
|
|
||||||
{% block datetime_widget -%}
|
{% block datetime_widget -%}
|
||||||
@ -39,7 +53,6 @@
|
|||||||
{% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control is-invalid')|trim}) -%}
|
{% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control is-invalid')|trim}) -%}
|
||||||
{% set valid = true %}
|
{% set valid = true %}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
|
|
||||||
{%- if widget == 'single_text' -%}
|
{%- if widget == 'single_text' -%}
|
||||||
{{- block('form_widget_simple') -}}
|
{{- block('form_widget_simple') -}}
|
||||||
{%- else -%}
|
{%- else -%}
|
||||||
@ -80,7 +93,9 @@
|
|||||||
<div class="input-group{{ not valid ? ' form-control is-invalid' }}">
|
<div class="input-group{{ not valid ? ' form-control is-invalid' }}">
|
||||||
{% set valid = true %}
|
{% set valid = true %}
|
||||||
{{- block('form_widget_simple') -}}
|
{{- block('form_widget_simple') -}}
|
||||||
<span class="input-group-addon">%</span>
|
<div class="input-group-append">
|
||||||
|
<span class="input-group-text">%</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{%- endblock percent_widget %}
|
{%- endblock percent_widget %}
|
||||||
|
|
||||||
@ -93,7 +108,7 @@
|
|||||||
|
|
||||||
{%- block widget_attributes -%}
|
{%- block widget_attributes -%}
|
||||||
{%- if not valid %}
|
{%- if not valid %}
|
||||||
{% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control is-invalid')|trim}) %}
|
{% set attr = attr|merge({class: (attr.class|default('') ~ ' is-invalid')|trim}) %}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
{{ parent() }}
|
{{ parent() }}
|
||||||
{%- endblock widget_attributes -%}
|
{%- endblock widget_attributes -%}
|
||||||
@ -105,15 +120,14 @@
|
|||||||
|
|
||||||
{% block checkbox_widget -%}
|
{% block checkbox_widget -%}
|
||||||
{%- set parent_label_class = parent_label_class|default(label_attr.class|default('')) -%}
|
{%- set parent_label_class = parent_label_class|default(label_attr.class|default('')) -%}
|
||||||
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-check-input')|trim}) -%}
|
{%- if 'checkbox-custom' in parent_label_class -%}
|
||||||
{% if 'checkbox-inline' in parent_label_class %}
|
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' custom-control-input')|trim}) -%}
|
||||||
{{- form_label(form, null, { widget: parent() }) -}}
|
<div class="custom-control custom-checkbox{{ 'checkbox-inline' in parent_label_class ? ' custom-control-inline' }}">
|
||||||
{% elseif 'form-check-inline' in parent_label_class %}
|
|
||||||
<div class="form-check{{ not valid ? ' form-control is-invalid' }} form-check-inline">
|
|
||||||
{{- form_label(form, null, { widget: parent() }) -}}
|
{{- form_label(form, null, { widget: parent() }) -}}
|
||||||
</div>
|
</div>
|
||||||
{% else -%}
|
{%- else -%}
|
||||||
<div class="form-check{{ not valid ? ' form-control is-invalid' }}">
|
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-check-input')|trim}) -%}
|
||||||
|
<div class="form-check{{ 'checkbox-inline' in parent_label_class ? ' form-check-inline' }}">
|
||||||
{{- form_label(form, null, { widget: parent() }) -}}
|
{{- form_label(form, null, { widget: parent() }) -}}
|
||||||
</div>
|
</div>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
@ -121,18 +135,21 @@
|
|||||||
|
|
||||||
{% block radio_widget -%}
|
{% block radio_widget -%}
|
||||||
{%- set parent_label_class = parent_label_class|default(label_attr.class|default('')) -%}
|
{%- set parent_label_class = parent_label_class|default(label_attr.class|default('')) -%}
|
||||||
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-check-input')|trim}) -%}
|
{%- if 'radio-custom' in parent_label_class -%}
|
||||||
{%- if 'radio-inline' in parent_label_class -%}
|
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' custom-control-input')|trim}) -%}
|
||||||
{{- form_label(form, null, { widget: parent() }) -}}
|
<div class="custom-control custom-radio{{ 'radio-inline' in parent_label_class ? ' custom-control-inline' }}">
|
||||||
|
{{- form_label(form, null, { widget: parent() }) -}}
|
||||||
|
</div>
|
||||||
{%- else -%}
|
{%- else -%}
|
||||||
<div class="form-check{{ not valid ? ' form-control is-invalid' }}">
|
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-check-input')|trim}) -%}
|
||||||
|
<div class="form-check{{ 'radio-inline' in parent_label_class ? ' form-check-inline' }}">
|
||||||
{{- form_label(form, null, { widget: parent() }) -}}
|
{{- form_label(form, null, { widget: parent() }) -}}
|
||||||
</div>
|
</div>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- endblock radio_widget %}
|
{%- endblock radio_widget %}
|
||||||
|
|
||||||
{% block choice_widget_expanded -%}
|
{% block choice_widget_expanded -%}
|
||||||
{% if '-inline' in label_attr.class|default('') -%}
|
<div {{ block('widget_container_attributes') }}>
|
||||||
{%- for child in form %}
|
{%- for child in form %}
|
||||||
{{- form_widget(child, {
|
{{- form_widget(child, {
|
||||||
parent_label_class: label_attr.class|default(''),
|
parent_label_class: label_attr.class|default(''),
|
||||||
@ -140,20 +157,7 @@
|
|||||||
valid: valid,
|
valid: valid,
|
||||||
}) -}}
|
}) -}}
|
||||||
{% endfor -%}
|
{% endfor -%}
|
||||||
{%- else -%}
|
</div>
|
||||||
{%- if not valid -%}
|
|
||||||
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-control is-invalid')|trim}) %}
|
|
||||||
{%- endif -%}
|
|
||||||
<div {{ block('widget_container_attributes') }}>
|
|
||||||
{%- for child in form %}
|
|
||||||
{{- form_widget(child, {
|
|
||||||
parent_label_class: label_attr.class|default(''),
|
|
||||||
translation_domain: choice_translation_domain,
|
|
||||||
valid: true,
|
|
||||||
}) -}}
|
|
||||||
{% endfor -%}
|
|
||||||
</div>
|
|
||||||
{%- endif %}
|
|
||||||
{%- endblock choice_widget_expanded %}
|
{%- endblock choice_widget_expanded %}
|
||||||
|
|
||||||
{# Labels #}
|
{# Labels #}
|
||||||
@ -162,7 +166,7 @@
|
|||||||
{% if label is not same as(false) -%}
|
{% if label is not same as(false) -%}
|
||||||
{%- if compound is defined and compound -%}
|
{%- if compound is defined and compound -%}
|
||||||
{%- set element = 'legend' -%}
|
{%- set element = 'legend' -%}
|
||||||
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-legend')|trim}) -%}
|
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-label')|trim}) -%}
|
||||||
{%- else -%}
|
{%- else -%}
|
||||||
{%- set label_attr = label_attr|merge({for: id, class: (label_attr.class|default('') ~ ' form-control-label')|trim}) -%}
|
{%- set label_attr = label_attr|merge({for: id, class: (label_attr.class|default('') ~ ' form-control-label')|trim}) -%}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
@ -179,19 +183,26 @@
|
|||||||
{% set label = name|humanize %}
|
{% set label = name|humanize %}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
<{{ element|default('label') }}{% if label_attr %}{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}{% endif %}>{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}{% block form_label_errors %}{{- form_errors(form) -}}{% endblock form_label_errors %}</{{ element|default('label') }}>
|
<{{ element|default('label') }}{% if label_attr %}{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}{% endif %}>{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}{{- form_errors(form) -}}</{{ element|default('label') }}>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- endblock form_label %}
|
{%- endblock form_label %}
|
||||||
|
|
||||||
{% block checkbox_radio_label -%}
|
{% block checkbox_radio_label -%}
|
||||||
{#- Do not display the label if widget is not defined in order to prevent double label rendering -#}
|
{#- Do not display the label if widget is not defined in order to prevent double label rendering -#}
|
||||||
{%- if widget is defined -%}
|
{%- if widget is defined -%}
|
||||||
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' form-check-label')|trim}) -%}
|
{%- if parent_label_class is defined and ('checkbox-custom' in parent_label_class or 'radio-custom' in parent_label_class) -%}
|
||||||
|
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' custom-control-label')|trim}) -%}
|
||||||
|
{%- else %}
|
||||||
|
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' form-check-label')|trim}) -%}
|
||||||
|
{%- endif %}
|
||||||
|
{%- if not compound -%}
|
||||||
|
{% set label_attr = label_attr|merge({'for': id}) %}
|
||||||
|
{%- endif -%}
|
||||||
{%- if required -%}
|
{%- if required -%}
|
||||||
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) -%}
|
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) -%}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- if parent_label_class is defined -%}
|
{%- if parent_label_class is defined -%}
|
||||||
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ parent_label_class)|trim}) -%}
|
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ parent_label_class)|replace({'checkbox-inline': '', 'radio-inline': '', 'checkbox-custom': '', 'radio-custom': ''})|trim}) -%}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- if label is not same as(false) and label is empty -%}
|
{%- if label is not same as(false) and label is empty -%}
|
||||||
{%- if label_format is not empty -%}
|
{%- if label_format is not empty -%}
|
||||||
@ -203,8 +214,11 @@
|
|||||||
{%- set label = name|humanize -%}
|
{%- set label = name|humanize -%}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
|
|
||||||
|
{{ widget|raw }}
|
||||||
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>
|
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>
|
||||||
{{- widget|raw }} {{ label is not same as(false) ? (translation_domain is same as(false) ? label : label|trans({}, translation_domain)) -}}
|
{{- label is not same as(false) ? (translation_domain is same as(false) ? label : label|trans({}, translation_domain)) -}}
|
||||||
|
{{- form_errors(form) -}}
|
||||||
</label>
|
</label>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- endblock checkbox_radio_label %}
|
{%- endblock checkbox_radio_label %}
|
||||||
@ -225,12 +239,12 @@
|
|||||||
|
|
||||||
{% block form_errors -%}
|
{% block form_errors -%}
|
||||||
{%- if errors|length > 0 -%}
|
{%- if errors|length > 0 -%}
|
||||||
<div class="{% if form is not rootform %}invalid-feedback{% else %}alert alert-danger{% endif %}">
|
<div class="{% if form is not rootform %}invalid-feedback d-block{% else %}alert alert-danger{% endif %}">
|
||||||
<ul class="list-unstyled mb-0">
|
<ul class="list-unstyled mb-0">
|
||||||
{%- for error in errors -%}
|
{%- for error in errors -%}
|
||||||
<li>{{ error.message }}</li>
|
<li>{{ error.message }}</li>
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endblock form_errors %}
|
{%- endblock form_errors %}
|
||||||
|
@ -147,7 +147,7 @@
|
|||||||
|
|
||||||
{% block choice_label -%}
|
{% block choice_label -%}
|
||||||
{# remove the checkbox-inline and radio-inline class, it's only useful for embed labels #}
|
{# remove the checkbox-inline and radio-inline class, it's only useful for embed labels #}
|
||||||
{%- set label_attr = label_attr|merge({class: label_attr.class|default('')|replace({'checkbox-inline': '', 'radio-inline': ''})|trim}) -%}
|
{%- set label_attr = label_attr|merge({class: label_attr.class|default('')|replace({'checkbox-inline': '', 'radio-inline': '', 'checkbox-custom': '', 'radio-custom': ''})|trim}) -%}
|
||||||
{{- block('form_label') -}}
|
{{- block('form_label') -}}
|
||||||
{% endblock choice_label %}
|
{% endblock choice_label %}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
"symfony/asset": "~3.4|~4.0",
|
"symfony/asset": "~3.4|~4.0",
|
||||||
"symfony/dependency-injection": "~3.4|~4.0",
|
"symfony/dependency-injection": "~3.4|~4.0",
|
||||||
"symfony/finder": "~3.4|~4.0",
|
"symfony/finder": "~3.4|~4.0",
|
||||||
"symfony/form": "~3.4|~4.0",
|
"symfony/form": "^3.4.5|^4.0.5",
|
||||||
"symfony/http-foundation": "~3.4|~4.0",
|
"symfony/http-foundation": "~3.4|~4.0",
|
||||||
"symfony/http-kernel": "~3.4|~4.0",
|
"symfony/http-kernel": "~3.4|~4.0",
|
||||||
"symfony/polyfill-intl-icu": "~1.0",
|
"symfony/polyfill-intl-icu": "~1.0",
|
||||||
@ -41,7 +41,7 @@
|
|||||||
"symfony/workflow": "~3.4|~4.0"
|
"symfony/workflow": "~3.4|~4.0"
|
||||||
},
|
},
|
||||||
"conflict": {
|
"conflict": {
|
||||||
"symfony/form": "<3.4",
|
"symfony/form": "<3.4.5|<4.0.5,>=4.0",
|
||||||
"symfony/console": "<3.4"
|
"symfony/console": "<3.4"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
|
@ -26,16 +26,16 @@ class AddAnnotationsCachedReaderPass implements CompilerPassInterface
|
|||||||
{
|
{
|
||||||
// "annotations.cached_reader" is wired late so that any passes using
|
// "annotations.cached_reader" is wired late so that any passes using
|
||||||
// "annotation_reader" at build time don't get any cache
|
// "annotation_reader" at build time don't get any cache
|
||||||
if ($container->hasDefinition('annotations.cached_reader')) {
|
foreach ($container->findTaggedServiceIds('annotations.cached_reader') as $id => $tags) {
|
||||||
$reader = $container->getDefinition('annotations.cached_reader');
|
$reader = $container->getDefinition($id);
|
||||||
$properties = $reader->getProperties();
|
$properties = $reader->getProperties();
|
||||||
|
|
||||||
if (isset($properties['cacheProviderBackup'])) {
|
if (isset($properties['cacheProviderBackup'])) {
|
||||||
$provider = $properties['cacheProviderBackup']->getValues()[0];
|
$provider = $properties['cacheProviderBackup']->getValues()[0];
|
||||||
unset($properties['cacheProviderBackup']);
|
unset($properties['cacheProviderBackup']);
|
||||||
$reader->setProperties($properties);
|
$reader->setProperties($properties);
|
||||||
$container->set('annotations.cached_reader', null);
|
$container->set($id, null);
|
||||||
$container->setDefinition('annotations.cached_reader', $reader->replaceArgument(1, $provider));
|
$container->setDefinition($id, $reader->replaceArgument(1, $provider));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
|
|||||||
class UnusedTagsPass implements CompilerPassInterface
|
class UnusedTagsPass implements CompilerPassInterface
|
||||||
{
|
{
|
||||||
private $whitelist = array(
|
private $whitelist = array(
|
||||||
|
'annotations.cached_reader',
|
||||||
'cache.pool.clearer',
|
'cache.pool.clearer',
|
||||||
'console.command',
|
'console.command',
|
||||||
'container.hot_path',
|
'container.hot_path',
|
||||||
|
@ -1116,7 +1116,9 @@ class FrameworkExtension extends Extension
|
|||||||
->replaceArgument(2, $config['debug'])
|
->replaceArgument(2, $config['debug'])
|
||||||
// temporary property to lazy-reference the cache provider without using it until AddAnnotationsCachedReaderPass runs
|
// temporary property to lazy-reference the cache provider without using it until AddAnnotationsCachedReaderPass runs
|
||||||
->setProperty('cacheProviderBackup', new ServiceClosureArgument(new Reference($cacheService)))
|
->setProperty('cacheProviderBackup', new ServiceClosureArgument(new Reference($cacheService)))
|
||||||
|
->addTag('annotations.cached_reader')
|
||||||
;
|
;
|
||||||
|
|
||||||
$container->setAlias('annotation_reader', 'annotations.cached_reader')->setPrivate(true);
|
$container->setAlias('annotation_reader', 'annotations.cached_reader')->setPrivate(true);
|
||||||
$container->setAlias(Reader::class, new Alias('annotations.cached_reader', false));
|
$container->setAlias(Reader::class, new Alias('annotations.cached_reader', false));
|
||||||
} else {
|
} else {
|
||||||
|
@ -25,6 +25,7 @@ use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
|||||||
use Symfony\Component\Cache\Adapter\ProxyAdapter;
|
use Symfony\Component\Cache\Adapter\ProxyAdapter;
|
||||||
use Symfony\Component\Cache\Adapter\RedisAdapter;
|
use Symfony\Component\Cache\Adapter\RedisAdapter;
|
||||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||||
|
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\DependencyInjection\Definition;
|
use Symfony\Component\DependencyInjection\Definition;
|
||||||
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
|
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
|
||||||
@ -582,10 +583,12 @@ abstract class FrameworkExtensionTest extends TestCase
|
|||||||
|
|
||||||
public function testAnnotations()
|
public function testAnnotations()
|
||||||
{
|
{
|
||||||
$container = $this->createContainerFromFile('full');
|
$container = $this->createContainerFromFile('full', array(), true, false);
|
||||||
|
$container->addCompilerPass(new TestAnnotationsPass());
|
||||||
|
$container->compile();
|
||||||
|
|
||||||
$this->assertEquals($container->getParameter('kernel.cache_dir').'/annotations', $container->getDefinition('annotations.filesystem_cache')->getArgument(0));
|
$this->assertEquals($container->getParameter('kernel.cache_dir').'/annotations', $container->getDefinition('annotations.filesystem_cache')->getArgument(0));
|
||||||
$this->assertSame('annotations.filesystem_cache', (string) $container->getDefinition('annotations.cached_reader')->getArgument(1));
|
$this->assertSame('annotations.filesystem_cache', (string) $container->getDefinition('annotation_reader')->getArgument(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFileLinkFormat()
|
public function testFileLinkFormat()
|
||||||
@ -1029,10 +1032,10 @@ abstract class FrameworkExtensionTest extends TestCase
|
|||||||
), $data)));
|
), $data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function createContainerFromFile($file, $data = array(), $resetCompilerPasses = true)
|
protected function createContainerFromFile($file, $data = array(), $resetCompilerPasses = true, $compile = true)
|
||||||
{
|
{
|
||||||
$cacheKey = md5(get_class($this).$file.serialize($data));
|
$cacheKey = md5(get_class($this).$file.serialize($data));
|
||||||
if (isset(self::$containerCache[$cacheKey])) {
|
if ($compile && isset(self::$containerCache[$cacheKey])) {
|
||||||
return self::$containerCache[$cacheKey];
|
return self::$containerCache[$cacheKey];
|
||||||
}
|
}
|
||||||
$container = $this->createContainer($data);
|
$container = $this->createContainer($data);
|
||||||
@ -1043,7 +1046,12 @@ abstract class FrameworkExtensionTest extends TestCase
|
|||||||
$container->getCompilerPassConfig()->setOptimizationPasses(array());
|
$container->getCompilerPassConfig()->setOptimizationPasses(array());
|
||||||
$container->getCompilerPassConfig()->setRemovingPasses(array());
|
$container->getCompilerPassConfig()->setRemovingPasses(array());
|
||||||
}
|
}
|
||||||
$container->getCompilerPassConfig()->setBeforeRemovingPasses(array(new AddAnnotationsCachedReaderPass(), new AddConstraintValidatorsPass(), new TranslatorPass('translator.default', 'translation.reader')));
|
$container->getCompilerPassConfig()->setBeforeRemovingPasses(array(new AddConstraintValidatorsPass(), new TranslatorPass('translator.default', 'translation.reader')));
|
||||||
|
$container->getCompilerPassConfig()->setAfterRemovingPasses(array(new AddAnnotationsCachedReaderPass()));
|
||||||
|
|
||||||
|
if (!$compile) {
|
||||||
|
return $container;
|
||||||
|
}
|
||||||
$container->compile();
|
$container->compile();
|
||||||
|
|
||||||
return self::$containerCache[$cacheKey] = $container;
|
return self::$containerCache[$cacheKey] = $container;
|
||||||
@ -1136,3 +1144,15 @@ abstract class FrameworkExtensionTest extends TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simulates ReplaceAliasByActualDefinitionPass.
|
||||||
|
*/
|
||||||
|
class TestAnnotationsPass implements CompilerPassInterface
|
||||||
|
{
|
||||||
|
public function process(ContainerBuilder $container)
|
||||||
|
{
|
||||||
|
$container->setDefinition('annotation_reader', $container->getDefinition('annotations.cached_reader'));
|
||||||
|
$container->removeDefinition('annotations.cached_reader');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
|
|
||||||
<div class="sf-toolbar-info-piece">
|
<div class="sf-toolbar-info-piece">
|
||||||
<b>Route name</b>
|
<b>Route name</b>
|
||||||
<span>{{ collector.route|default('NONE') }}</span>
|
<span>{{ collector.route|default('n/a') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="sf-toolbar-info-piece">
|
<div class="sf-toolbar-info-piece">
|
||||||
|
@ -68,7 +68,7 @@ a.doc:hover {
|
|||||||
|
|
||||||
.anchor {
|
.anchor {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: block;
|
display: inline-block;
|
||||||
top: -7em;
|
top: -7em;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ abstract class AbstractBootstrap4HorizontalLayoutTest extends AbstractBootstrap4
|
|||||||
|
|
||||||
$this->assertMatchesXpath($html,
|
$this->assertMatchesXpath($html,
|
||||||
'/legend
|
'/legend
|
||||||
[@class="col-form-label col-sm-2 col-form-legend required"]
|
[@class="col-form-label col-sm-2 col-form-label required"]
|
||||||
[.="[trans]Name[/trans]"]
|
[.="[trans]Name[/trans]"]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
@ -144,7 +144,7 @@ abstract class AbstractBootstrap4HorizontalLayoutTest extends AbstractBootstrap4
|
|||||||
|
|
||||||
$this->assertMatchesXpath($html,
|
$this->assertMatchesXpath($html,
|
||||||
'/legend
|
'/legend
|
||||||
[@class="col-sm-2 col-form-legend required"]
|
[@class="col-sm-2 col-form-label required"]
|
||||||
[.="[trans]Custom label[/trans]"]
|
[.="[trans]Custom label[/trans]"]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
|
@ -53,7 +53,7 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
|
|
||||||
$this->assertMatchesXpath($html,
|
$this->assertMatchesXpath($html,
|
||||||
'/legend
|
'/legend
|
||||||
[@class="col-form-legend required"]
|
[@class="col-form-label required"]
|
||||||
[.="[trans]Name[/trans]"]
|
[.="[trans]Name[/trans]"]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
@ -144,7 +144,7 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
|
|
||||||
$this->assertMatchesXpath($html,
|
$this->assertMatchesXpath($html,
|
||||||
'/legend
|
'/legend
|
||||||
[@class="col-form-legend required"]
|
[@class="col-form-label required"]
|
||||||
[.="[trans]Custom label[/trans]"]
|
[.="[trans]Custom label[/trans]"]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
@ -184,12 +184,10 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
'/div
|
'/div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class form-check-input"][@checked="checked"][@value="1"]
|
||||||
[.=" [trans]Name[/trans]"]
|
/following-sibling::label
|
||||||
|
[.="[trans]Name[/trans]"]
|
||||||
[@class="form-check-label required"]
|
[@class="form-check-label required"]
|
||||||
[
|
|
||||||
./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class form-check-input"][@checked="checked"][@value="1"]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
@ -234,20 +232,16 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
./div
|
./div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
|
||||||
[.=" [trans]Choice&A[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]Choice&A[/trans]"]
|
||||||
./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
|
||||||
[.=" [trans]Choice&B[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]Choice&B[/trans]"]
|
||||||
./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::input[@type="hidden"][@id="name__token"]
|
/following-sibling::input[@type="hidden"][@id="name__token"]
|
||||||
]
|
]
|
||||||
@ -263,11 +257,9 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
'/div
|
'/div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class form-check-input"][not(@checked)]
|
||||||
[.=" [trans]Name[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]Name[/trans]"]
|
||||||
./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class form-check-input"][not(@checked)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
@ -283,11 +275,9 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
'/div
|
'/div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class form-check-input"][@value="foo&bar"]
|
||||||
[.=" [trans]Name[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]Name[/trans]"]
|
||||||
./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class form-check-input"][@value="foo&bar"]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
@ -307,20 +297,16 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
./div
|
./div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
|
||||||
[.=" [trans]Choice&A[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]Choice&A[/trans]"]
|
||||||
./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
|
||||||
[.=" [trans]Choice&B[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]Choice&B[/trans]"]
|
||||||
./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::input[@type="hidden"][@id="name__token"]
|
/following-sibling::input[@type="hidden"][@id="name__token"]
|
||||||
]
|
]
|
||||||
@ -343,18 +329,14 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
./div
|
./div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
|
||||||
[
|
/following-sibling::label
|
||||||
./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
|
||||||
[
|
/following-sibling::label
|
||||||
./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::input[@type="hidden"][@id="name__token"]
|
/following-sibling::input[@type="hidden"][@id="name__token"]
|
||||||
]
|
]
|
||||||
@ -383,28 +365,22 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
./div
|
./div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
|
||||||
[.=" [trans]label.&a[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]label.&a[/trans]"]
|
||||||
./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
|
||||||
[
|
/following-sibling::label
|
||||||
./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_2"][@value="&c"][not(@checked)]
|
||||||
[.=" [trans]label.&c[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]label.&c[/trans]"]
|
||||||
./input[@type="radio"][@name="name"][@id="name_2"][@value="&c"][not(@checked)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::input[@type="hidden"][@id="name__token"]
|
/following-sibling::input[@type="hidden"][@id="name__token"]
|
||||||
]
|
]
|
||||||
@ -429,18 +405,14 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
./div
|
./div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
|
||||||
[
|
/following-sibling::label
|
||||||
./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
|
||||||
[
|
/following-sibling::label
|
||||||
./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::input[@type="hidden"][@id="name__token"]
|
/following-sibling::input[@type="hidden"][@id="name__token"]
|
||||||
]
|
]
|
||||||
@ -463,20 +435,16 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
./div
|
./div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
|
||||||
[.=" Choice&A"]
|
/following-sibling::label
|
||||||
[
|
[.="Choice&A"]
|
||||||
./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
|
||||||
[.=" Choice&B"]
|
/following-sibling::label
|
||||||
[
|
[.="Choice&B"]
|
||||||
./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::input[@type="hidden"][@id="name__token"]
|
/following-sibling::input[@type="hidden"][@id="name__token"]
|
||||||
]
|
]
|
||||||
@ -499,20 +467,16 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
./div
|
./div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
|
||||||
[.=" [trans]Choice&A[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]Choice&A[/trans]"]
|
||||||
./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)][@class="foo&bar form-check-input"]
|
||||||
[.=" [trans]Choice&B[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]Choice&B[/trans]"]
|
||||||
./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)][@class="foo&bar form-check-input"]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::input[@type="hidden"][@id="name__token"]
|
/following-sibling::input[@type="hidden"][@id="name__token"]
|
||||||
]
|
]
|
||||||
@ -536,29 +500,23 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
./div
|
./div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_placeholder"][not(@checked)]
|
||||||
[.=" [trans]Test&Me[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]Test&Me[/trans]"]
|
||||||
./input[@type="radio"][@name="name"][@id="name_placeholder"][not(@checked)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_0"][@checked]
|
||||||
[.=" [trans]Choice&A[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]Choice&A[/trans]"]
|
||||||
./input[@type="radio"][@name="name"][@id="name_0"][@checked]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)]
|
||||||
[.=" [trans]Choice&B[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]Choice&B[/trans]"]
|
||||||
./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::input[@type="hidden"][@id="name__token"]
|
/following-sibling::input[@type="hidden"][@id="name__token"]
|
||||||
]
|
]
|
||||||
@ -583,29 +541,23 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
./div
|
./div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_placeholder"][not(@checked)]
|
||||||
[.=" Placeholder&Not&Translated"]
|
/following-sibling::label
|
||||||
[
|
[.="Placeholder&Not&Translated"]
|
||||||
./input[@type="radio"][@name="name"][@id="name_placeholder"][not(@checked)]
|
]
|
||||||
]
|
/following-sibling::div
|
||||||
|
[@class="form-check"]
|
||||||
|
[
|
||||||
|
./input[@type="radio"][@name="name"][@id="name_0"][@checked]
|
||||||
|
/following-sibling::label
|
||||||
|
[.="Choice&A"]
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)]
|
||||||
[.=" Choice&A"]
|
/following-sibling::label
|
||||||
[
|
[.="Choice&B"]
|
||||||
./input[@type="radio"][@name="name"][@id="name_0"][@checked]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
/following-sibling::div
|
|
||||||
[@class="form-check"]
|
|
||||||
[
|
|
||||||
./label
|
|
||||||
[.=" Choice&B"]
|
|
||||||
[
|
|
||||||
./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::input[@type="hidden"][@id="name__token"]
|
/following-sibling::input[@type="hidden"][@id="name__token"]
|
||||||
]
|
]
|
||||||
@ -627,20 +579,16 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
./div
|
./div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_0"][@checked]
|
||||||
[.=" [trans]Choice&A[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]Choice&A[/trans]"]
|
||||||
./input[@type="radio"][@name="name"][@id="name_0"][@checked]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)]
|
||||||
[.=" [trans]Choice&B[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]Choice&B[/trans]"]
|
||||||
./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::input[@type="hidden"][@id="name__token"]
|
/following-sibling::input[@type="hidden"][@id="name__token"]
|
||||||
]
|
]
|
||||||
@ -663,29 +611,23 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
./div
|
./div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)]
|
||||||
[.=" [trans]Choice&A[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]Choice&A[/trans]"]
|
||||||
./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)]
|
||||||
[.=" [trans]Choice&B[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]Choice&B[/trans]"]
|
||||||
./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)]
|
||||||
[.=" [trans]Choice&C[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]Choice&C[/trans]"]
|
||||||
./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::input[@type="hidden"][@id="name__token"]
|
/following-sibling::input[@type="hidden"][@id="name__token"]
|
||||||
]
|
]
|
||||||
@ -708,18 +650,14 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
./div
|
./div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked]
|
||||||
[
|
/following-sibling::label
|
||||||
./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)]
|
||||||
[
|
/following-sibling::label
|
||||||
./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::input[@type="hidden"][@id="name__token"]
|
/following-sibling::input[@type="hidden"][@id="name__token"]
|
||||||
]
|
]
|
||||||
@ -748,28 +686,22 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
./div
|
./div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked]
|
||||||
[.=" [trans]label.&a[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]label.&a[/trans]"]
|
||||||
./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)]
|
||||||
[
|
/following-sibling::label
|
||||||
./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="checkbox"][@name="name[]"][@id="name_2"][@value="&c"][not(@checked)]
|
||||||
[.=" [trans]label.&c[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]label.&c[/trans]"]
|
||||||
./input[@type="checkbox"][@name="name[]"][@id="name_2"][@value="&c"][not(@checked)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::input[@type="hidden"][@id="name__token"]
|
/following-sibling::input[@type="hidden"][@id="name__token"]
|
||||||
]
|
]
|
||||||
@ -794,18 +726,14 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
./div
|
./div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked]
|
||||||
[
|
/following-sibling::label
|
||||||
./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)]
|
||||||
[
|
/following-sibling::label
|
||||||
./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::input[@type="hidden"][@id="name__token"]
|
/following-sibling::input[@type="hidden"][@id="name__token"]
|
||||||
]
|
]
|
||||||
@ -829,29 +757,23 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
./div
|
./div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)]
|
||||||
[.=" Choice&A"]
|
/following-sibling::label
|
||||||
[
|
[.="Choice&A"]
|
||||||
./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)]
|
||||||
[.=" Choice&B"]
|
/following-sibling::label
|
||||||
[
|
[.="Choice&B"]
|
||||||
./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)]
|
||||||
[.=" Choice&C"]
|
/following-sibling::label
|
||||||
[
|
[.="Choice&C"]
|
||||||
./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::input[@type="hidden"][@id="name__token"]
|
/following-sibling::input[@type="hidden"][@id="name__token"]
|
||||||
]
|
]
|
||||||
@ -875,29 +797,23 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
./div
|
./div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)]
|
||||||
[.=" [trans]Choice&A[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]Choice&A[/trans]"]
|
||||||
./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)][@class="foo&bar form-check-input"]
|
||||||
[.=" [trans]Choice&B[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]Choice&B[/trans]"]
|
||||||
./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)][@class="foo&bar form-check-input"]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::div
|
/following-sibling::div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)]
|
||||||
[.=" [trans]Choice&C[/trans]"]
|
/following-sibling::label
|
||||||
[
|
[.="[trans]Choice&C[/trans]"]
|
||||||
./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
/following-sibling::input[@type="hidden"][@id="name__token"]
|
/following-sibling::input[@type="hidden"][@id="name__token"]
|
||||||
]
|
]
|
||||||
@ -913,17 +829,15 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
'/div
|
'/div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input
|
||||||
|
[@id="my&id"]
|
||||||
|
[@type="radio"]
|
||||||
|
[@name="name"]
|
||||||
|
[@class="my&class form-check-input"]
|
||||||
|
[@checked="checked"]
|
||||||
|
[@value="1"]
|
||||||
|
/following-sibling::label
|
||||||
[@class="form-check-label required"]
|
[@class="form-check-label required"]
|
||||||
[
|
|
||||||
./input
|
|
||||||
[@id="my&id"]
|
|
||||||
[@type="radio"]
|
|
||||||
[@name="name"]
|
|
||||||
[@class="my&class form-check-input"]
|
|
||||||
[@checked="checked"]
|
|
||||||
[@value="1"]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
@ -937,16 +851,14 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
'/div
|
'/div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input
|
||||||
|
[@id="my&id"]
|
||||||
|
[@type="radio"]
|
||||||
|
[@name="name"]
|
||||||
|
[@class="my&class form-check-input"]
|
||||||
|
[not(@checked)]
|
||||||
|
/following-sibling::label
|
||||||
[@class="form-check-label required"]
|
[@class="form-check-label required"]
|
||||||
[
|
|
||||||
./input
|
|
||||||
[@id="my&id"]
|
|
||||||
[@type="radio"]
|
|
||||||
[@name="name"]
|
|
||||||
[@class="my&class form-check-input"]
|
|
||||||
[not(@checked)]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
@ -962,16 +874,15 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
'/div
|
'/div
|
||||||
[@class="form-check"]
|
[@class="form-check"]
|
||||||
[
|
[
|
||||||
./label
|
./input
|
||||||
|
[@id="my&id"]
|
||||||
|
[@type="radio"]
|
||||||
|
[@name="name"]
|
||||||
|
[@class="my&class form-check-input"]
|
||||||
|
[@value="foo&bar"]
|
||||||
|
/following-sibling::label
|
||||||
[@class="form-check-label required"]
|
[@class="form-check-label required"]
|
||||||
[
|
[@for="my&id"]
|
||||||
./input
|
|
||||||
[@id="my&id"]
|
|
||||||
[@type="radio"]
|
|
||||||
[@name="name"]
|
|
||||||
[@class="my&class form-check-input"]
|
|
||||||
[@value="foo&bar"]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
@ -996,6 +907,61 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
$this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class form-control-file')),
|
$this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class form-control-file')),
|
||||||
'/input
|
'/input
|
||||||
[@type="file"]
|
[@type="file"]
|
||||||
|
'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMoney()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\MoneyType', 1234.56, array(
|
||||||
|
'currency' => 'EUR',
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')),
|
||||||
|
'/div
|
||||||
|
[@class="input-group"]
|
||||||
|
[
|
||||||
|
./div
|
||||||
|
[@class="input-group-prepend"]
|
||||||
|
[
|
||||||
|
./span
|
||||||
|
[@class="input-group-text"]
|
||||||
|
[contains(.., "€")]
|
||||||
|
]
|
||||||
|
/following-sibling::input
|
||||||
|
[@id="my&id"]
|
||||||
|
[@type="text"]
|
||||||
|
[@name="name"]
|
||||||
|
[@class="my&class form-control"]
|
||||||
|
[@value="1234.56"]
|
||||||
|
]
|
||||||
|
'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPercent()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\PercentType', 0.1);
|
||||||
|
|
||||||
|
$this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')),
|
||||||
|
'/div
|
||||||
|
[@class="input-group"]
|
||||||
|
[
|
||||||
|
./input
|
||||||
|
[@id="my&id"]
|
||||||
|
[@type="text"]
|
||||||
|
[@name="name"]
|
||||||
|
[@class="my&class form-control"]
|
||||||
|
[@value="10"]
|
||||||
|
/following-sibling::div
|
||||||
|
[@class="input-group-append"]
|
||||||
|
[
|
||||||
|
./span
|
||||||
|
[@class="input-group-text"]
|
||||||
|
[contains(.., "%")]
|
||||||
|
]
|
||||||
|
|
||||||
|
]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,8 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
|||||||
*/
|
*/
|
||||||
abstract class AbstractTestSessionListener implements EventSubscriberInterface
|
abstract class AbstractTestSessionListener implements EventSubscriberInterface
|
||||||
{
|
{
|
||||||
|
private $sessionId;
|
||||||
|
|
||||||
public function onKernelRequest(GetResponseEvent $event)
|
public function onKernelRequest(GetResponseEvent $event)
|
||||||
{
|
{
|
||||||
if (!$event->isMasterRequest()) {
|
if (!$event->isMasterRequest()) {
|
||||||
@ -44,7 +46,8 @@ abstract class AbstractTestSessionListener implements EventSubscriberInterface
|
|||||||
$cookies = $event->getRequest()->cookies;
|
$cookies = $event->getRequest()->cookies;
|
||||||
|
|
||||||
if ($cookies->has($session->getName())) {
|
if ($cookies->has($session->getName())) {
|
||||||
$session->setId($cookies->get($session->getName()));
|
$this->sessionId = $cookies->get($session->getName());
|
||||||
|
$session->setId($this->sessionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,9 +69,10 @@ abstract class AbstractTestSessionListener implements EventSubscriberInterface
|
|||||||
$session->save();
|
$session->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($session instanceof Session ? !$session->isEmpty() : $wasStarted) {
|
if ($session instanceof Session ? !$session->isEmpty() || $session->getId() !== $this->sessionId : $wasStarted) {
|
||||||
$params = session_get_cookie_params();
|
$params = session_get_cookie_params();
|
||||||
$event->getResponse()->headers->setCookie(new Cookie($session->getName(), $session->getId(), 0 === $params['lifetime'] ? 0 : time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly']));
|
$event->getResponse()->headers->setCookie(new Cookie($session->getName(), $session->getId(), 0 === $params['lifetime'] ? 0 : time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly']));
|
||||||
|
$this->sessionId = $session->getId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,8 +13,10 @@ namespace Symfony\Component\HttpKernel\Tests\EventListener;
|
|||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
|
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
|
||||||
|
use Symfony\Component\HttpFoundation\Cookie;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||||
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||||
use Symfony\Component\HttpKernel\EventListener\SessionListener;
|
use Symfony\Component\HttpKernel\EventListener\SessionListener;
|
||||||
@ -86,6 +88,22 @@ class TestSessionListenerTest extends TestCase
|
|||||||
$this->assertSame(array(), $response->headers->getCookies());
|
$this->assertSame(array(), $response->headers->getCookies());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testEmptySessionWithNewSessionIdDoesSendCookie()
|
||||||
|
{
|
||||||
|
$this->sessionHasBeenStarted();
|
||||||
|
$this->sessionIsEmpty();
|
||||||
|
$this->fixSessionId('456');
|
||||||
|
|
||||||
|
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
|
||||||
|
$request = Request::create('/', 'GET', array(), array(new Cookie('MOCKSESSID', '123')));
|
||||||
|
$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
|
||||||
|
$this->listener->onKernelRequest($event);
|
||||||
|
|
||||||
|
$response = $this->filterResponse(new Request(), HttpKernelInterface::MASTER_REQUEST);
|
||||||
|
|
||||||
|
$this->assertNotEmpty($response->headers->getCookies());
|
||||||
|
}
|
||||||
|
|
||||||
public function testUnstartedSessionIsNotSave()
|
public function testUnstartedSessionIsNotSave()
|
||||||
{
|
{
|
||||||
$this->sessionHasNotBeenStarted();
|
$this->sessionHasNotBeenStarted();
|
||||||
@ -150,6 +168,13 @@ class TestSessionListenerTest extends TestCase
|
|||||||
->will($this->returnValue(true));
|
->will($this->returnValue(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function fixSessionId($sessionId)
|
||||||
|
{
|
||||||
|
$this->session->expects($this->any())
|
||||||
|
->method('getId')
|
||||||
|
->will($this->returnValue($sessionId));
|
||||||
|
}
|
||||||
|
|
||||||
private function getSession()
|
private function getSession()
|
||||||
{
|
{
|
||||||
$mock = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\Session')
|
$mock = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\Session')
|
||||||
|
@ -150,7 +150,7 @@ class StopwatchEvent
|
|||||||
/**
|
/**
|
||||||
* Gets the relative time of the start of the first period.
|
* Gets the relative time of the start of the first period.
|
||||||
*
|
*
|
||||||
* @return int The time (in milliseconds)
|
* @return int|float The time (in milliseconds)
|
||||||
*/
|
*/
|
||||||
public function getStartTime()
|
public function getStartTime()
|
||||||
{
|
{
|
||||||
@ -160,7 +160,7 @@ class StopwatchEvent
|
|||||||
/**
|
/**
|
||||||
* Gets the relative time of the end of the last period.
|
* Gets the relative time of the end of the last period.
|
||||||
*
|
*
|
||||||
* @return int The time (in milliseconds)
|
* @return int|float The time (in milliseconds)
|
||||||
*/
|
*/
|
||||||
public function getEndTime()
|
public function getEndTime()
|
||||||
{
|
{
|
||||||
@ -172,7 +172,7 @@ class StopwatchEvent
|
|||||||
/**
|
/**
|
||||||
* Gets the duration of the events (including all periods).
|
* Gets the duration of the events (including all periods).
|
||||||
*
|
*
|
||||||
* @return int The duration (in milliseconds)
|
* @return int|float The duration (in milliseconds)
|
||||||
*/
|
*/
|
||||||
public function getDuration()
|
public function getDuration()
|
||||||
{
|
{
|
||||||
|
@ -372,54 +372,39 @@ class Parser
|
|||||||
|
|
||||||
// try to parse the value as a multi-line string as a last resort
|
// try to parse the value as a multi-line string as a last resort
|
||||||
if (0 === $this->currentLineNb) {
|
if (0 === $this->currentLineNb) {
|
||||||
$parseError = false;
|
|
||||||
$previousLineWasNewline = false;
|
$previousLineWasNewline = false;
|
||||||
$previousLineWasTerminatedWithBackslash = false;
|
$previousLineWasTerminatedWithBackslash = false;
|
||||||
$value = '';
|
$value = '';
|
||||||
|
|
||||||
foreach ($this->lines as $line) {
|
foreach ($this->lines as $line) {
|
||||||
try {
|
if ('' === trim($line)) {
|
||||||
if (isset($line[0]) && ('"' === $line[0] || "'" === $line[0])) {
|
$value .= "\n";
|
||||||
$parsedLine = $line;
|
} elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) {
|
||||||
} else {
|
$value .= ' ';
|
||||||
$parsedLine = Inline::parse($line, $flags, $this->refs);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_string($parsedLine)) {
|
if ('' !== trim($line) && '\\' === substr($line, -1)) {
|
||||||
$parseError = true;
|
$value .= ltrim(substr($line, 0, -1));
|
||||||
break;
|
} elseif ('' !== trim($line)) {
|
||||||
}
|
$value .= trim($line);
|
||||||
|
}
|
||||||
|
|
||||||
if ('' === trim($parsedLine)) {
|
if ('' === trim($line)) {
|
||||||
$value .= "\n";
|
$previousLineWasNewline = true;
|
||||||
} elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) {
|
$previousLineWasTerminatedWithBackslash = false;
|
||||||
$value .= ' ';
|
} elseif ('\\' === substr($line, -1)) {
|
||||||
}
|
$previousLineWasNewline = false;
|
||||||
|
$previousLineWasTerminatedWithBackslash = true;
|
||||||
if ('' !== trim($parsedLine) && '\\' === substr($parsedLine, -1)) {
|
} else {
|
||||||
$value .= ltrim(substr($parsedLine, 0, -1));
|
$previousLineWasNewline = false;
|
||||||
} elseif ('' !== trim($parsedLine)) {
|
$previousLineWasTerminatedWithBackslash = false;
|
||||||
$value .= trim($parsedLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('' === trim($parsedLine)) {
|
|
||||||
$previousLineWasNewline = true;
|
|
||||||
$previousLineWasTerminatedWithBackslash = false;
|
|
||||||
} elseif ('\\' === substr($parsedLine, -1)) {
|
|
||||||
$previousLineWasNewline = false;
|
|
||||||
$previousLineWasTerminatedWithBackslash = true;
|
|
||||||
} else {
|
|
||||||
$previousLineWasNewline = false;
|
|
||||||
$previousLineWasTerminatedWithBackslash = false;
|
|
||||||
}
|
|
||||||
} catch (ParseException $e) {
|
|
||||||
$parseError = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$parseError) {
|
try {
|
||||||
return Inline::parse(trim($value));
|
return Inline::parse(trim($value));
|
||||||
|
} catch (ParseException $e) {
|
||||||
|
// fall-through to the ParseException thrown below
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -672,6 +672,42 @@ EOT;
|
|||||||
$this->assertSame($expected, $this->parser->parse($yaml));
|
$this->assertSame($expected, $this->parser->parse($yaml));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testNonStringFollowedByCommentEmbeddedInMapping()
|
||||||
|
{
|
||||||
|
$yaml = <<<'EOT'
|
||||||
|
a:
|
||||||
|
b:
|
||||||
|
{}
|
||||||
|
# comment
|
||||||
|
d:
|
||||||
|
1.1
|
||||||
|
# another comment
|
||||||
|
EOT;
|
||||||
|
$expected = array(
|
||||||
|
'a' => array(
|
||||||
|
'b' => array(),
|
||||||
|
'd' => 1.1,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertSame($expected, $this->parser->parse($yaml));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMultiLineStringLastResortParsing()
|
||||||
|
{
|
||||||
|
$yaml = <<<'EOT'
|
||||||
|
test:
|
||||||
|
You can have things that don't look like strings here
|
||||||
|
true
|
||||||
|
yes you can
|
||||||
|
EOT;
|
||||||
|
$expected = array(
|
||||||
|
'test' => 'You can have things that don\'t look like strings here true yes you can',
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertSame($expected, $this->parser->parse($yaml));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
|
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user