bug #11436 fix signal handling in wait() on calls to stop() (xabbuh, romainneutron)
This PR was merged into the 2.3 branch. Discussion ---------- fix signal handling in wait() on calls to stop() | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #11286 | License | MIT | Doc PR | ``wait()`` throws an exception when the process was terminated by a signal. This should not happen when the termination was requested by calling the ``stop()`` method (for example, inside a callback which is passed to ``wait()``). Commits -------5939d34
[Process] Fix unit tests in sigchild environmenteb68662
[Process] fix signal handling in wait()94ffc4f
bug #11469 [BrowserKit] Fixed server HTTP_HOST port uri conversion (bcremer, fabpot)103fd88
[BrowserKit] refactor code and fix unquoted regexf401ab9
Fixed server HTTP_HOST port uri conversion045cbc5
bug #11425 Fix issue described in #11421 (Ben, ben-rosio)f5bfa9b
bug #11423 Pass a Scope instance instead of a scope name when cloning a container in the GrahpvizDumper (jakzal)3177be5
minor #11464 [Translator] Use quote to surround invalid locale (lyrixx)c9742ef
[Translator] Use quote to surround invalid locale4dbe0e1
bug #11120 [2.3][Process] Reduce I/O load on Windows platform (romainneutron)797d814
bug #11342 [2.3][Form] Check if IntlDateFormatter constructor returned a valid object before using it (romainneutron)0b5348e
minor #11441 [Translator] Optimize assertLocale regexp (Jérémy Derussé)537c39b
Optimize assertLocale regexp4cf50e8
Bring code into standard9f4313c
[Process] Add test to verify fix for issue #1142102eb765
[Process] Fixes issue #114216787669
[DependencyInjection] Pass a Scope instance instead of a scope name.9572918
bug #11411 [Validator] Backported #11410 to 2.3: Object initializers are called only once per object (webmozart)291cbf9
[Validator] Backported #11410 to 2.3: Object initializers are called only once per objectefab884
bug #11403 [Translator][FrameworkBundle] Added @ to the list of allowed chars in Translator (takeit)3176f8b
[Translator][FrameworkBundle] Added @ to the list of allowed chars in Translator91e32f8
bug #11381 [2.3] [Process] Use correct test for empty string in UnixPipes (whs, romainneutron)45df2f3
minor #11397 [2.3][Process] Fix unit tests on Windows platform (romainneutron)cec0a45
[Process] Adjust PR #11264, make it Windows compatible and fix CSd418935
[Process] Fix unit tests on Windows platformff0bb01
[Process] Reduce I/O load on Windows platformace5a29
bumped Symfony version to 2.3.1975e07e6
updated VERSION for 2.3.184a12f4d
update CONTRIBUTORS for 2.3.1898b891d
updated CHANGELOG for 2.3.1806a80fb
Validate locales sets intos translator06fc97e
feature #11367 [HttpFoundation] Fix to prevent magic bytes injection in JSONP responses... (CVE-2014-4671) (Andrew Moore)3c54659
minor #11387 [2.3] [Validator] Fix UserPassword validator translation (redstar504)73d50ed
Fix UserPassword validator translation93a970c
bug #11386 Remove Spaceless Blocks from Twig Form Templates (chrisguitarguy)8f9ed3e
Remove Spaceless Blocks from Twig Form Templates9e1ea4a
[Process] Use correct test for empty string in UnixPipes6af3d05
[HttpFoundation] Fix to prevent magic bytes injection in JSONP responses (Prevents CVE-2014-4671)ebf967d
[Form] Check if IntlDateFormatter constructor returned a valid object before using it
This commit is contained in:
commit
c548bd861a
@ -7,6 +7,14 @@ in 2.3 minor versions.
|
|||||||
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
|
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
|
||||||
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v2.3.0...v2.3.1
|
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v2.3.0...v2.3.1
|
||||||
|
|
||||||
|
* 2.3.18 (2014-07-15)
|
||||||
|
|
||||||
|
* [Security] Forced validate of locales passed to the translator
|
||||||
|
* feature #11367 [HttpFoundation] Fix to prevent magic bytes injection in JSONP responses... (CVE-2014-4671) (Andrew Moore)
|
||||||
|
* bug #11386 Remove Spaceless Blocks from Twig Form Templates (chrisguitarguy)
|
||||||
|
* bug #9719 [TwigBundle] fix configuration tree for paths (mdavis1982, cordoval)
|
||||||
|
* bug #11244 [HttpFoundation] Remove body-related headers when sending the response, if body is empty (SimonSimCity)
|
||||||
|
|
||||||
* 2.3.17 (2014-07-07)
|
* 2.3.17 (2014-07-07)
|
||||||
|
|
||||||
* bug #11238 [Translation] Added unescaping of ids in PoFileLoader (JustBlackBird)
|
* bug #11238 [Translation] Added unescaping of ids in PoFileLoader (JustBlackBird)
|
||||||
|
@ -19,8 +19,8 @@ Symfony2 is the result of the work of many people who made the code better
|
|||||||
- Ryan Weaver (weaverryan)
|
- Ryan Weaver (weaverryan)
|
||||||
- Lukas Kahwe Smith (lsmith)
|
- Lukas Kahwe Smith (lsmith)
|
||||||
- Jeremy Mikola (jmikola)
|
- Jeremy Mikola (jmikola)
|
||||||
- Jean-François Simon (jfsimon)
|
|
||||||
- Romain Neutron (romain)
|
- Romain Neutron (romain)
|
||||||
|
- Jean-François Simon (jfsimon)
|
||||||
- Benjamin Eberlei (beberlei)
|
- Benjamin Eberlei (beberlei)
|
||||||
- Igor Wiedler (igorw)
|
- Igor Wiedler (igorw)
|
||||||
- Hugo Hamon (hhamon)
|
- Hugo Hamon (hhamon)
|
||||||
@ -44,18 +44,18 @@ Symfony2 is the result of the work of many people who made the code better
|
|||||||
- Wouter De Jong (wouterj)
|
- Wouter De Jong (wouterj)
|
||||||
- Eric Clemmons (ericclemmons)
|
- Eric Clemmons (ericclemmons)
|
||||||
- Nicolas Grekas (nicolas-grekas)
|
- Nicolas Grekas (nicolas-grekas)
|
||||||
|
- Andrej Hudec (pulzarraider)
|
||||||
- Deni
|
- Deni
|
||||||
- Henrik Westphal (snc)
|
- Henrik Westphal (snc)
|
||||||
- Dariusz Górecki (canni)
|
- Dariusz Górecki (canni)
|
||||||
- Andrej Hudec (pulzarraider)
|
|
||||||
- Arnout Boks (aboks)
|
- Arnout Boks (aboks)
|
||||||
|
- Christian Raue
|
||||||
- Michel Weimerskirch (mweimerskirch)
|
- Michel Weimerskirch (mweimerskirch)
|
||||||
- Lee McDermott
|
- Lee McDermott
|
||||||
- Brandon Turner
|
- Brandon Turner
|
||||||
- Douglas Greenshields (shieldo)
|
- Douglas Greenshields (shieldo)
|
||||||
- Daniel Holmes (dholmes)
|
- Daniel Holmes (dholmes)
|
||||||
- Jordan Alliot (jalliot)
|
- Jordan Alliot (jalliot)
|
||||||
- Christian Raue
|
|
||||||
- John Wards (johnwards)
|
- John Wards (johnwards)
|
||||||
- Fran Moreno (franmomu)
|
- Fran Moreno (franmomu)
|
||||||
- Bart van den Burg (burgov)
|
- Bart van den Burg (burgov)
|
||||||
@ -75,21 +75,21 @@ Symfony2 is the result of the work of many people who made the code better
|
|||||||
- Fabien Pennequin (fabienpennequin)
|
- Fabien Pennequin (fabienpennequin)
|
||||||
- Jacob Dreesen (jdreesen)
|
- Jacob Dreesen (jdreesen)
|
||||||
- Gábor Egyed (1ed)
|
- Gábor Egyed (1ed)
|
||||||
|
- Ait Boudad Abdellatif (aitboudad)
|
||||||
- Adrien Brault (adrienbrault)
|
- Adrien Brault (adrienbrault)
|
||||||
- Michal Piotrowski (eventhorizon)
|
- Michal Piotrowski (eventhorizon)
|
||||||
- Ait Boudad Abdellatif (aitboudad)
|
|
||||||
- Robert Schönthal (digitalkaoz)
|
- Robert Schönthal (digitalkaoz)
|
||||||
- Juti Noppornpitak (shiroyuki)
|
- Juti Noppornpitak (shiroyuki)
|
||||||
- Sebastian Hörl (blogsh)
|
- Sebastian Hörl (blogsh)
|
||||||
- Daniel Gomes (danielcsgomes)
|
- Daniel Gomes (danielcsgomes)
|
||||||
- Hidenori Goto (hidenorigoto)
|
- Hidenori Goto (hidenorigoto)
|
||||||
- Peter Kokot (maastermedia)
|
- Peter Kokot (maastermedia)
|
||||||
|
- Christian Flothmann (xabbuh)
|
||||||
- Jérémie Augustin (jaugustin)
|
- Jérémie Augustin (jaugustin)
|
||||||
- David Buchmann (dbu)
|
- David Buchmann (dbu)
|
||||||
- Jérôme Tamarelle (gromnan)
|
- Jérôme Tamarelle (gromnan)
|
||||||
- Tigran Azatyan (tigranazatyan)
|
- Tigran Azatyan (tigranazatyan)
|
||||||
- Javier Eguiluz (javier.eguiluz)
|
- Javier Eguiluz (javier.eguiluz)
|
||||||
- Christian Flothmann (xabbuh)
|
|
||||||
- Rafael Dohms (rdohms)
|
- Rafael Dohms (rdohms)
|
||||||
- Richard Shank (iampersistent)
|
- Richard Shank (iampersistent)
|
||||||
- Gordon Franke (gimler)
|
- Gordon Franke (gimler)
|
||||||
@ -146,6 +146,7 @@ Symfony2 is the result of the work of many people who made the code better
|
|||||||
- Manuel Reinhard (sprain)
|
- Manuel Reinhard (sprain)
|
||||||
- Danny Berger (dpb587)
|
- Danny Berger (dpb587)
|
||||||
- Xavier Montaña Carreras (xmontana)
|
- Xavier Montaña Carreras (xmontana)
|
||||||
|
- Michele Orselli (orso)
|
||||||
- Xavier Perez
|
- Xavier Perez
|
||||||
- Arjen Brouwer (arjenjb)
|
- Arjen Brouwer (arjenjb)
|
||||||
- Katsuhiro OGAWA
|
- Katsuhiro OGAWA
|
||||||
@ -168,7 +169,6 @@ Symfony2 is the result of the work of many people who made the code better
|
|||||||
- Robert Kiss (kepten)
|
- Robert Kiss (kepten)
|
||||||
- Kim Hemsø Rasmussen (kimhemsoe)
|
- Kim Hemsø Rasmussen (kimhemsoe)
|
||||||
- Wouter Van Hecke
|
- Wouter Van Hecke
|
||||||
- Michele Orselli (orso)
|
|
||||||
- Michael Holm (hollo)
|
- Michael Holm (hollo)
|
||||||
- Marc Weistroff (futurecat)
|
- Marc Weistroff (futurecat)
|
||||||
- Pierre-Yves LEBECQ (pylebecq)
|
- Pierre-Yves LEBECQ (pylebecq)
|
||||||
@ -231,6 +231,7 @@ Symfony2 is the result of the work of many people who made the code better
|
|||||||
- Ismael Ambrosi (iambrosi)
|
- Ismael Ambrosi (iambrosi)
|
||||||
- Shein Alexey
|
- Shein Alexey
|
||||||
- Issei Murasawa (issei_m)
|
- Issei Murasawa (issei_m)
|
||||||
|
- hacfi (hifi)
|
||||||
- Joe Lencioni
|
- Joe Lencioni
|
||||||
- Kai
|
- Kai
|
||||||
- Xavier HAUSHERR
|
- Xavier HAUSHERR
|
||||||
@ -274,6 +275,7 @@ Symfony2 is the result of the work of many people who made the code better
|
|||||||
- François-Xavier de Guillebon (de-gui_f)
|
- François-Xavier de Guillebon (de-gui_f)
|
||||||
- boombatower
|
- boombatower
|
||||||
- Fabrice Bernhard (fabriceb)
|
- Fabrice Bernhard (fabriceb)
|
||||||
|
- Clément Gautier (clementgautier)
|
||||||
- Fabian Lange (codingfabian)
|
- Fabian Lange (codingfabian)
|
||||||
- Yoshio HANAWA
|
- Yoshio HANAWA
|
||||||
- Baptiste Clavié (talus)
|
- Baptiste Clavié (talus)
|
||||||
@ -294,11 +296,11 @@ Symfony2 is the result of the work of many people who made the code better
|
|||||||
- Maks Slesarenko
|
- Maks Slesarenko
|
||||||
- Markus Lanthaler (lanthaler)
|
- Markus Lanthaler (lanthaler)
|
||||||
- Vicent Soria Durá (vicentgodella)
|
- Vicent Soria Durá (vicentgodella)
|
||||||
|
- Chris Wilkinson (thewilkybarkid)
|
||||||
- Ioan Negulescu
|
- Ioan Negulescu
|
||||||
- Andrew Udvare (audvare)
|
- Andrew Udvare (audvare)
|
||||||
- alexpods
|
- alexpods
|
||||||
- Erik Trapman (eriktrapman)
|
- Erik Trapman (eriktrapman)
|
||||||
- hacfi (hifi)
|
|
||||||
- De Cock Xavier (xdecock)
|
- De Cock Xavier (xdecock)
|
||||||
- Alex Pott
|
- Alex Pott
|
||||||
- Norbert Orzechowicz (norzechowicz)
|
- Norbert Orzechowicz (norzechowicz)
|
||||||
@ -365,6 +367,7 @@ Symfony2 is the result of the work of many people who made the code better
|
|||||||
- Arturs Vonda
|
- Arturs Vonda
|
||||||
- Sascha Grossenbacher
|
- Sascha Grossenbacher
|
||||||
- Ben Davies (bendavies)
|
- Ben Davies (bendavies)
|
||||||
|
- Simon Schick (simonsimcity)
|
||||||
- Hossein Bukhamsin
|
- Hossein Bukhamsin
|
||||||
- Paweł Wacławczyk (pwc)
|
- Paweł Wacławczyk (pwc)
|
||||||
- Oleg Zinchenko (cystbear)
|
- Oleg Zinchenko (cystbear)
|
||||||
@ -372,6 +375,7 @@ Symfony2 is the result of the work of many people who made the code better
|
|||||||
- Johannes Klauss (cloppy)
|
- Johannes Klauss (cloppy)
|
||||||
- Evan Villemez
|
- Evan Villemez
|
||||||
- fzerorubigd
|
- fzerorubigd
|
||||||
|
- Benjamin Grandfond (benjamin)
|
||||||
- Tiago Brito (blackmx)
|
- Tiago Brito (blackmx)
|
||||||
- Richard van den Brand (ricbra)
|
- Richard van den Brand (ricbra)
|
||||||
- develop
|
- develop
|
||||||
@ -403,7 +407,6 @@ Symfony2 is the result of the work of many people who made the code better
|
|||||||
- Marek Štípek (maryo)
|
- Marek Štípek (maryo)
|
||||||
- John Bohn (jbohn)
|
- John Bohn (jbohn)
|
||||||
- Jakub Škvára (jskvara)
|
- Jakub Škvára (jskvara)
|
||||||
- Chris Wilkinson (thewilkybarkid)
|
|
||||||
- Andrew Hilobok (hilobok)
|
- Andrew Hilobok (hilobok)
|
||||||
- Christian Soronellas (theunic)
|
- Christian Soronellas (theunic)
|
||||||
- Jérôme Vieilledent (lolautruche)
|
- Jérôme Vieilledent (lolautruche)
|
||||||
@ -532,7 +535,6 @@ Symfony2 is the result of the work of many people who made the code better
|
|||||||
- jfcixmedia
|
- jfcixmedia
|
||||||
- Martijn Evers
|
- Martijn Evers
|
||||||
- Benjamin Paap (benjaminpaap)
|
- Benjamin Paap (benjaminpaap)
|
||||||
- Simon Schick (simonsimcity)
|
|
||||||
- Christian
|
- Christian
|
||||||
- Sergii Smertin (nfx)
|
- Sergii Smertin (nfx)
|
||||||
- Eddie Jaoude
|
- Eddie Jaoude
|
||||||
@ -550,6 +552,7 @@ Symfony2 is the result of the work of many people who made the code better
|
|||||||
- Benoit Garret
|
- Benoit Garret
|
||||||
- DerManoMann
|
- DerManoMann
|
||||||
- Asmir Mustafic (goetas)
|
- Asmir Mustafic (goetas)
|
||||||
|
- Julien Bianchi (jubianchi)
|
||||||
- Marcin Chwedziak
|
- Marcin Chwedziak
|
||||||
- Roland Franssen (ro0)
|
- Roland Franssen (ro0)
|
||||||
- Maciej Malarz
|
- Maciej Malarz
|
||||||
@ -562,20 +565,22 @@ Symfony2 is the result of the work of many people who made the code better
|
|||||||
- kaiwa
|
- kaiwa
|
||||||
- Albert Ganiev (helios-ag)
|
- Albert Ganiev (helios-ag)
|
||||||
- Neil Katin
|
- Neil Katin
|
||||||
|
- David Otton
|
||||||
- peter
|
- peter
|
||||||
- Artem Kolesnikov (tyomo4ka)
|
- Artem Kolesnikov (tyomo4ka)
|
||||||
- Gustavo Adrian
|
- Gustavo Adrian
|
||||||
- Clément Gautier (clementgautier)
|
|
||||||
- Yannick
|
- Yannick
|
||||||
- Luc Vieillescazes (iamluc)
|
- Luc Vieillescazes (iamluc)
|
||||||
- Eduardo García Sanz (coma)
|
- Eduardo García Sanz (coma)
|
||||||
- David de Boer (ddeboer)
|
- David de Boer (ddeboer)
|
||||||
- Brooks Boyd
|
- Brooks Boyd
|
||||||
- Roger Webb
|
- Roger Webb
|
||||||
|
- Dmitriy Simushev
|
||||||
- Max Voloshin (maxvoloshin)
|
- Max Voloshin (maxvoloshin)
|
||||||
- Nicolas Fabre (nfabre)
|
- Nicolas Fabre (nfabre)
|
||||||
- Raul Rodriguez (raul782)
|
- Raul Rodriguez (raul782)
|
||||||
- Patrick Landolt (scube)
|
- Patrick Landolt (scube)
|
||||||
|
- WybrenKoelmans
|
||||||
- Derek Lambert
|
- Derek Lambert
|
||||||
- Felicitus
|
- Felicitus
|
||||||
- Krzysztof Przybyszewski
|
- Krzysztof Przybyszewski
|
||||||
@ -730,6 +735,7 @@ Symfony2 is the result of the work of many people who made the code better
|
|||||||
- catch
|
- catch
|
||||||
- Alexandre Segura
|
- Alexandre Segura
|
||||||
- Josef Cech
|
- Josef Cech
|
||||||
|
- Nate (frickenate)
|
||||||
- Matthew Foster (mfoster)
|
- Matthew Foster (mfoster)
|
||||||
- Maximilian Reichel (phramz)
|
- Maximilian Reichel (phramz)
|
||||||
- Paul Seiffert (seiffert)
|
- Paul Seiffert (seiffert)
|
||||||
@ -750,7 +756,6 @@ Symfony2 is the result of the work of many people who made the code better
|
|||||||
- Andrey Ryaguzov
|
- Andrey Ryaguzov
|
||||||
- Gunther Konig
|
- Gunther Konig
|
||||||
- František Bereň
|
- František Bereň
|
||||||
- Benjamin Grandfond (benjamin)
|
|
||||||
- Christoph Nissle (derstoffel)
|
- Christoph Nissle (derstoffel)
|
||||||
- Ionel Scutelnicu (ionelscutelnicu)
|
- Ionel Scutelnicu (ionelscutelnicu)
|
||||||
- Johnny Peck (johnnypeck)
|
- Johnny Peck (johnnypeck)
|
||||||
@ -875,6 +880,7 @@ Symfony2 is the result of the work of many people who made the code better
|
|||||||
- Yorkie Chadwick (yorkie76)
|
- Yorkie Chadwick (yorkie76)
|
||||||
- Yanick Witschi
|
- Yanick Witschi
|
||||||
- Ondrej Mirtes
|
- Ondrej Mirtes
|
||||||
|
- akimsko
|
||||||
- Youpie
|
- Youpie
|
||||||
- srsbiz
|
- srsbiz
|
||||||
- Nicolas A. Bérard-Nault
|
- Nicolas A. Bérard-Nault
|
||||||
@ -1010,6 +1016,7 @@ Symfony2 is the result of the work of many people who made the code better
|
|||||||
- Adam Monsen (meonkeys)
|
- Adam Monsen (meonkeys)
|
||||||
- ollie harridge (ollietb)
|
- ollie harridge (ollietb)
|
||||||
- Paweł Szczepanek (pauluz)
|
- Paweł Szczepanek (pauluz)
|
||||||
|
- Christian López Espínola (penyaskito)
|
||||||
- Petr Jaroš (petajaros)
|
- Petr Jaroš (petajaros)
|
||||||
- Philipp Hoffmann (philipphoffmann)
|
- Philipp Hoffmann (philipphoffmann)
|
||||||
- Alex Carol (picard89)
|
- Alex Carol (picard89)
|
||||||
|
@ -1,393 +1,313 @@
|
|||||||
{# Widgets #}
|
{# Widgets #}
|
||||||
|
|
||||||
{% block form_widget %}
|
{% block form_widget -%}
|
||||||
{% spaceless %}
|
|
||||||
{% if compound %}
|
{% if compound %}
|
||||||
{{ block('form_widget_compound') }}
|
{{- block('form_widget_compound') -}}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ block('form_widget_simple') }}
|
{{- block('form_widget_simple') -}}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endspaceless %}
|
{%- endblock form_widget %}
|
||||||
{% endblock form_widget %}
|
|
||||||
|
|
||||||
{% block form_widget_simple %}
|
{% block form_widget_simple -%}
|
||||||
{% spaceless %}
|
{%- set type = type|default('text') -%}
|
||||||
{% set type = type|default('text') %}
|
|
||||||
<input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/>
|
<input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/>
|
||||||
{% endspaceless %}
|
{%- endblock form_widget_simple %}
|
||||||
{% endblock form_widget_simple %}
|
|
||||||
|
|
||||||
{% block form_widget_compound %}
|
{% block form_widget_compound -%}
|
||||||
{% spaceless %}
|
|
||||||
<div {{ block('widget_container_attributes') }}>
|
<div {{ block('widget_container_attributes') }}>
|
||||||
{% if form.parent is empty %}
|
{%- if form.parent is empty -%}
|
||||||
{{ form_errors(form) }}
|
{{ form_errors(form) }}
|
||||||
{% endif %}
|
{%- endif -%}
|
||||||
{{ block('form_rows') }}
|
{{- block('form_rows') -}}
|
||||||
{{ form_rest(form) }}
|
{{- form_rest(form) -}}
|
||||||
</div>
|
</div>
|
||||||
{% endspaceless %}
|
{%- endblock form_widget_compound %}
|
||||||
{% endblock form_widget_compound %}
|
|
||||||
|
|
||||||
{% block collection_widget %}
|
{% block collection_widget -%}
|
||||||
{% spaceless %}
|
|
||||||
{% if prototype is defined %}
|
{% if prototype is defined %}
|
||||||
{% set attr = attr|merge({'data-prototype': form_row(prototype) }) %}
|
{%- set attr = attr|merge({'data-prototype': form_row(prototype) }) -%}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ block('form_widget') }}
|
{{- block('form_widget') -}}
|
||||||
{% endspaceless %}
|
{%- endblock collection_widget %}
|
||||||
{% endblock collection_widget %}
|
|
||||||
|
|
||||||
{% block textarea_widget %}
|
{% block textarea_widget -%}
|
||||||
{% spaceless %}
|
|
||||||
<textarea {{ block('widget_attributes') }}>{{ value }}</textarea>
|
<textarea {{ block('widget_attributes') }}>{{ value }}</textarea>
|
||||||
{% endspaceless %}
|
{%- endblock textarea_widget %}
|
||||||
{% endblock textarea_widget %}
|
|
||||||
|
|
||||||
{% block choice_widget %}
|
{% block choice_widget -%}
|
||||||
{% spaceless %}
|
|
||||||
{% if expanded %}
|
{% if expanded %}
|
||||||
{{ block('choice_widget_expanded') }}
|
{{- block('choice_widget_expanded') -}}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ block('choice_widget_collapsed') }}
|
{{- block('choice_widget_collapsed') -}}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endspaceless %}
|
{%- endblock choice_widget %}
|
||||||
{% endblock choice_widget %}
|
|
||||||
|
|
||||||
{% block choice_widget_expanded %}
|
{% block choice_widget_expanded -%}
|
||||||
{% spaceless %}
|
|
||||||
<div {{ block('widget_container_attributes') }}>
|
<div {{ block('widget_container_attributes') }}>
|
||||||
{% for child in form %}
|
{% for child in form %}
|
||||||
{{ form_widget(child) }}
|
{{- form_widget(child) -}}
|
||||||
{{ form_label(child) }}
|
{{- form_label(child) -}}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endspaceless %}
|
{%- endblock choice_widget_expanded %}
|
||||||
{% endblock choice_widget_expanded %}
|
|
||||||
|
|
||||||
{% block choice_widget_collapsed %}
|
{% block choice_widget_collapsed -%}
|
||||||
{% spaceless %}
|
|
||||||
{% if required and empty_value is none and not empty_value_in_choices and not multiple %}
|
{% if required and empty_value is none and not empty_value_in_choices and not multiple %}
|
||||||
{% set required = false %}
|
{% set required = false %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
|
<select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
|
||||||
{% if empty_value is not none %}
|
{% if empty_value is not none -%}
|
||||||
<option value=""{% if required and value is empty %} selected="selected"{% endif %}>{{ empty_value|trans({}, translation_domain) }}</option>
|
<option value=""{% if required and value is empty %} selected="selected"{% endif %}>{{ empty_value|trans({}, translation_domain) }}</option>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% if preferred_choices|length > 0 %}
|
{%- if preferred_choices|length > 0 -%}
|
||||||
{% set options = preferred_choices %}
|
{% set options = preferred_choices %}
|
||||||
{{ block('choice_widget_options') }}
|
{{- block('choice_widget_options') -}}
|
||||||
{% if choices|length > 0 and separator is not none %}
|
{% if choices|length > 0 and separator is not none -%}
|
||||||
<option disabled="disabled">{{ separator }}</option>
|
<option disabled="disabled">{{ separator }}</option>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endif %}
|
{%- endif -%}
|
||||||
{% set options = choices %}
|
{% set options = choices -%}
|
||||||
{{ block('choice_widget_options') }}
|
{{- block('choice_widget_options') -}}
|
||||||
</select>
|
</select>
|
||||||
{% endspaceless %}
|
{%- endblock choice_widget_collapsed %}
|
||||||
{% endblock choice_widget_collapsed %}
|
|
||||||
|
|
||||||
{% block choice_widget_options %}
|
{% block choice_widget_options -%}
|
||||||
{% spaceless %}
|
|
||||||
{% for group_label, choice in options %}
|
{% for group_label, choice in options %}
|
||||||
{% if choice is iterable %}
|
{%- if choice is iterable -%}
|
||||||
<optgroup label="{{ group_label|trans({}, translation_domain) }}">
|
<optgroup label="{{ group_label|trans({}, translation_domain) }}">
|
||||||
{% set options = choice %}
|
{% set options = choice %}
|
||||||
{{ block('choice_widget_options') }}
|
{{- block('choice_widget_options') -}}
|
||||||
</optgroup>
|
</optgroup>
|
||||||
{% else %}
|
{%- else -%}
|
||||||
<option value="{{ choice.value }}"{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>{{ choice.label|trans({}, translation_domain) }}</option>
|
<option value="{{ choice.value }}"{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>{{ choice.label|trans({}, translation_domain) }}</option>
|
||||||
{% endif %}
|
{%- endif -%}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endspaceless %}
|
{%- endblock choice_widget_options %}
|
||||||
{% endblock choice_widget_options %}
|
|
||||||
|
|
||||||
{% block checkbox_widget %}
|
{% block checkbox_widget -%}
|
||||||
{% spaceless %}
|
|
||||||
<input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
|
<input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
|
||||||
{% endspaceless %}
|
{%- endblock checkbox_widget %}
|
||||||
{% endblock checkbox_widget %}
|
|
||||||
|
|
||||||
{% block radio_widget %}
|
{% block radio_widget -%}
|
||||||
{% spaceless %}
|
|
||||||
<input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
|
<input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
|
||||||
{% endspaceless %}
|
{%- endblock radio_widget %}
|
||||||
{% endblock radio_widget %}
|
|
||||||
|
|
||||||
{% block datetime_widget %}
|
{% block datetime_widget -%}
|
||||||
{% spaceless %}
|
|
||||||
{% if widget == 'single_text' %}
|
{% if widget == 'single_text' %}
|
||||||
{{ block('form_widget_simple') }}
|
{{- block('form_widget_simple') -}}
|
||||||
{% else %}
|
{% else -%}
|
||||||
<div {{ block('widget_container_attributes') }}>
|
<div {{ block('widget_container_attributes') }}>
|
||||||
{{ form_errors(form.date) }}
|
{{- form_errors(form.date) -}}
|
||||||
{{ form_errors(form.time) }}
|
{{- form_errors(form.time) -}}
|
||||||
{{ form_widget(form.date) }}
|
{{- form_widget(form.date) -}}
|
||||||
{{ form_widget(form.time) }}
|
{{- form_widget(form.time) -}}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endspaceless %}
|
{%- endblock datetime_widget %}
|
||||||
{% endblock datetime_widget %}
|
|
||||||
|
|
||||||
{% block date_widget %}
|
{% block date_widget -%}
|
||||||
{% spaceless %}
|
{% if widget == 'single_text' -%}
|
||||||
{% if widget == 'single_text' %}
|
|
||||||
{{ block('form_widget_simple') }}
|
{{ block('form_widget_simple') }}
|
||||||
{% else %}
|
{%- else -%}
|
||||||
<div {{ block('widget_container_attributes') }}>
|
<div {{ block('widget_container_attributes') }}>
|
||||||
{{ date_pattern|replace({
|
{{- date_pattern|replace({
|
||||||
'{{ year }}': form_widget(form.year),
|
'{{ year }}': form_widget(form.year),
|
||||||
'{{ month }}': form_widget(form.month),
|
'{{ month }}': form_widget(form.month),
|
||||||
'{{ day }}': form_widget(form.day),
|
'{{ day }}': form_widget(form.day),
|
||||||
})|raw }}
|
})|raw -}}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endspaceless %}
|
{%- endblock date_widget %}
|
||||||
{% endblock date_widget %}
|
|
||||||
|
|
||||||
{% block time_widget %}
|
{% block time_widget -%}
|
||||||
{% spaceless %}
|
{% if widget == 'single_text' -%}
|
||||||
{% if widget == 'single_text' %}
|
|
||||||
{{ block('form_widget_simple') }}
|
{{ block('form_widget_simple') }}
|
||||||
{% else %}
|
{%- else -%}
|
||||||
{% set vars = widget == 'text' ? { 'attr': { 'size': 1 }} : {} %}
|
{% set vars = widget == 'text' ? { 'attr': { 'size': 1 }} : {} -%}
|
||||||
<div {{ block('widget_container_attributes') }}>
|
<div {{ block('widget_container_attributes') }}>
|
||||||
{{ form_widget(form.hour, vars) }}{% if with_minutes %}:{{ form_widget(form.minute, vars) }}{% endif %}{% if with_seconds %}:{{ form_widget(form.second, vars) }}{% endif %}
|
{{ form_widget(form.hour, vars) }}{% if with_minutes %}:{{ form_widget(form.minute, vars) }}{% endif %}{% if with_seconds %}:{{ form_widget(form.second, vars) }}{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endspaceless %}
|
{%- endblock time_widget %}
|
||||||
{% endblock time_widget %}
|
|
||||||
|
|
||||||
{% block number_widget %}
|
{% block number_widget -%}
|
||||||
{% spaceless %}
|
|
||||||
{# type="number" doesn't work with floats #}
|
{# type="number" doesn't work with floats #}
|
||||||
{% set type = type|default('text') %}
|
{%- set type = type|default('text') -%}
|
||||||
{{ block('form_widget_simple') }}
|
{{ block('form_widget_simple') }}
|
||||||
{% endspaceless %}
|
{%- endblock number_widget %}
|
||||||
{% endblock number_widget %}
|
|
||||||
|
|
||||||
{% block integer_widget %}
|
{% block integer_widget -%}
|
||||||
{% spaceless %}
|
|
||||||
{% set type = type|default('number') %}
|
{% set type = type|default('number') %}
|
||||||
{{ block('form_widget_simple') }}
|
{{- block('form_widget_simple') -}}
|
||||||
{% endspaceless %}
|
{%- endblock integer_widget %}
|
||||||
{% endblock integer_widget %}
|
|
||||||
|
|
||||||
{% block money_widget %}
|
{% block money_widget -%}
|
||||||
{% spaceless %}
|
|
||||||
{{ money_pattern|replace({ '{{ widget }}': block('form_widget_simple') })|raw }}
|
{{ money_pattern|replace({ '{{ widget }}': block('form_widget_simple') })|raw }}
|
||||||
{% endspaceless %}
|
{%- endblock money_widget %}
|
||||||
{% endblock money_widget %}
|
|
||||||
|
|
||||||
{% block url_widget %}
|
{% block url_widget -%}
|
||||||
{% spaceless %}
|
{% set type = type|default('url') -%}
|
||||||
{% set type = type|default('url') %}
|
|
||||||
{{ block('form_widget_simple') }}
|
{{ block('form_widget_simple') }}
|
||||||
{% endspaceless %}
|
{%- endblock url_widget %}
|
||||||
{% endblock url_widget %}
|
|
||||||
|
|
||||||
{% block search_widget %}
|
{% block search_widget -%}
|
||||||
{% spaceless %}
|
{% set type = type|default('search') -%}
|
||||||
{% set type = type|default('search') %}
|
|
||||||
{{ block('form_widget_simple') }}
|
{{ block('form_widget_simple') }}
|
||||||
{% endspaceless %}
|
{%- endblock search_widget %}
|
||||||
{% endblock search_widget %}
|
|
||||||
|
|
||||||
{% block percent_widget %}
|
{% block percent_widget -%}
|
||||||
{% spaceless %}
|
{% set type = type|default('text') -%}
|
||||||
{% set type = type|default('text') %}
|
|
||||||
{{ block('form_widget_simple') }} %
|
{{ block('form_widget_simple') }} %
|
||||||
{% endspaceless %}
|
{%- endblock percent_widget %}
|
||||||
{% endblock percent_widget %}
|
|
||||||
|
|
||||||
{% block password_widget %}
|
{% block password_widget -%}
|
||||||
{% spaceless %}
|
{% set type = type|default('password') -%}
|
||||||
{% set type = type|default('password') %}
|
|
||||||
{{ block('form_widget_simple') }}
|
{{ block('form_widget_simple') }}
|
||||||
{% endspaceless %}
|
{%- endblock password_widget %}
|
||||||
{% endblock password_widget %}
|
|
||||||
|
|
||||||
{% block hidden_widget %}
|
{% block hidden_widget -%}
|
||||||
{% spaceless %}
|
{% set type = type|default('hidden') -%}
|
||||||
{% set type = type|default('hidden') %}
|
|
||||||
{{ block('form_widget_simple') }}
|
{{ block('form_widget_simple') }}
|
||||||
{% endspaceless %}
|
{%- endblock hidden_widget %}
|
||||||
{% endblock hidden_widget %}
|
|
||||||
|
|
||||||
{% block email_widget %}
|
{% block email_widget -%}
|
||||||
{% spaceless %}
|
{% set type = type|default('email') -%}
|
||||||
{% set type = type|default('email') %}
|
|
||||||
{{ block('form_widget_simple') }}
|
{{ block('form_widget_simple') }}
|
||||||
{% endspaceless %}
|
{%- endblock email_widget %}
|
||||||
{% endblock email_widget %}
|
|
||||||
|
|
||||||
{% block button_widget %}
|
{% block button_widget -%}
|
||||||
{% spaceless %}
|
{% if label is empty -%}
|
||||||
{% if label is empty %}
|
|
||||||
{% set label = name|humanize %}
|
{% set label = name|humanize %}
|
||||||
{% endif %}
|
{%- endif -%}
|
||||||
<button type="{{ type|default('button') }}" {{ block('button_attributes') }}>{{ label|trans({}, translation_domain) }}</button>
|
<button type="{{ type|default('button') }}" {{ block('button_attributes') }}>{{ label|trans({}, translation_domain) }}</button>
|
||||||
{% endspaceless %}
|
{%- endblock button_widget %}
|
||||||
{% endblock button_widget %}
|
|
||||||
|
|
||||||
{% block submit_widget %}
|
{% block submit_widget -%}
|
||||||
{% spaceless %}
|
{% set type = type|default('submit') -%}
|
||||||
{% set type = type|default('submit') %}
|
|
||||||
{{ block('button_widget') }}
|
{{ block('button_widget') }}
|
||||||
{% endspaceless %}
|
{%- endblock submit_widget %}
|
||||||
{% endblock submit_widget %}
|
|
||||||
|
|
||||||
{% block reset_widget %}
|
{% block reset_widget -%}
|
||||||
{% spaceless %}
|
{% set type = type|default('reset') -%}
|
||||||
{% set type = type|default('reset') %}
|
|
||||||
{{ block('button_widget') }}
|
{{ block('button_widget') }}
|
||||||
{% endspaceless %}
|
{%- endblock reset_widget %}
|
||||||
{% endblock reset_widget %}
|
|
||||||
|
|
||||||
{# Labels #}
|
{# Labels #}
|
||||||
|
|
||||||
{% block form_label %}
|
{% block form_label -%}
|
||||||
{% spaceless %}
|
|
||||||
{% if label is not sameas(false) %}
|
{% if label is not sameas(false) %}
|
||||||
{% if not compound %}
|
{%- if not compound -%}
|
||||||
{% set label_attr = label_attr|merge({'for': id}) %}
|
{% set label_attr = label_attr|merge({'for': id}) %}
|
||||||
{% endif %}
|
{%- 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 label is empty %}
|
{%- if label is empty -%}
|
||||||
{% set label = name|humanize %}
|
{% set label = name|humanize %}
|
||||||
{% endif %}
|
{%- endif -%}
|
||||||
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ label|trans({}, translation_domain) }}</label>
|
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ label|trans({}, translation_domain) }}</label>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endspaceless %}
|
{%- endblock form_label %}
|
||||||
{% endblock form_label %}
|
|
||||||
|
|
||||||
{% block button_label %}{% endblock %}
|
{% block button_label -%}{%- endblock %}
|
||||||
|
|
||||||
{# Rows #}
|
{# Rows #}
|
||||||
|
|
||||||
{% block repeated_row %}
|
{% block repeated_row -%}
|
||||||
{% spaceless %}
|
|
||||||
{#
|
{#
|
||||||
No need to render the errors here, as all errors are mapped
|
No need to render the errors here, as all errors are mapped
|
||||||
to the first child (see RepeatedTypeValidatorExtension).
|
to the first child (see RepeatedTypeValidatorExtension).
|
||||||
#}
|
#}
|
||||||
{{ block('form_rows') }}
|
{{- block('form_rows') }}
|
||||||
{% endspaceless %}
|
{%- endblock repeated_row %}
|
||||||
{% endblock repeated_row %}
|
|
||||||
|
|
||||||
{% block form_row %}
|
{% block form_row -%}
|
||||||
{% spaceless %}
|
|
||||||
<div>
|
<div>
|
||||||
{{ form_label(form) }}
|
{{- form_label(form) -}}
|
||||||
{{ form_errors(form) }}
|
{{- form_errors(form) -}}
|
||||||
{{ form_widget(form) }}
|
{{- form_widget(form) -}}
|
||||||
</div>
|
</div>
|
||||||
{% endspaceless %}
|
{%- endblock form_row %}
|
||||||
{% endblock form_row %}
|
|
||||||
|
|
||||||
{% block button_row %}
|
{% block button_row -%}
|
||||||
{% spaceless %}
|
|
||||||
<div>
|
<div>
|
||||||
{{ form_widget(form) }}
|
{{- form_widget(form) -}}
|
||||||
</div>
|
</div>
|
||||||
{% endspaceless %}
|
{%- endblock button_row %}
|
||||||
{% endblock button_row %}
|
|
||||||
|
|
||||||
{% block hidden_row %}
|
{% block hidden_row -%}
|
||||||
{{ form_widget(form) }}
|
{{ form_widget(form) }}
|
||||||
{% endblock hidden_row %}
|
{%- endblock hidden_row %}
|
||||||
|
|
||||||
{# Misc #}
|
{# Misc #}
|
||||||
|
|
||||||
{% block form %}
|
{% block form -%}
|
||||||
{% spaceless %}
|
|
||||||
{{ form_start(form) }}
|
{{ form_start(form) }}
|
||||||
{{ form_widget(form) }}
|
{{- form_widget(form) -}}
|
||||||
{{ form_end(form) }}
|
{{ form_end(form) }}
|
||||||
{% endspaceless %}
|
{%- endblock form %}
|
||||||
{% endblock form %}
|
|
||||||
|
|
||||||
{% block form_start %}
|
{% block form_start -%}
|
||||||
{% spaceless %}
|
|
||||||
{% set method = method|upper %}
|
{% set method = method|upper %}
|
||||||
{% if method in ["GET", "POST"] %}
|
{%- if method in ["GET", "POST"] -%}
|
||||||
{% set form_method = method %}
|
{% set form_method = method %}
|
||||||
{% else %}
|
{%- else -%}
|
||||||
{% set form_method = "POST" %}
|
{% set form_method = "POST" %}
|
||||||
{% endif %}
|
{%- endif -%}
|
||||||
<form method="{{ form_method|lower }}" action="{{ action }}"{% for attrname, attrvalue in attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}{% if multipart %} enctype="multipart/form-data"{% endif %}>
|
<form method="{{ form_method|lower }}" action="{{ action }}"{% for attrname, attrvalue in attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}{% if multipart %} enctype="multipart/form-data"{% endif %}>
|
||||||
{% if form_method != method %}
|
{%- if form_method != method -%}
|
||||||
<input type="hidden" name="_method" value="{{ method }}" />
|
<input type="hidden" name="_method" value="{{ method }}" />
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endspaceless %}
|
{%- endblock form_start %}
|
||||||
{% endblock form_start %}
|
|
||||||
|
|
||||||
{% block form_end %}
|
{% block form_end -%}
|
||||||
{% spaceless %}
|
{% if not render_rest is defined or render_rest -%}
|
||||||
{% if not render_rest is defined or render_rest %}
|
|
||||||
{{ form_rest(form) }}
|
{{ form_rest(form) }}
|
||||||
{% endif %}
|
{%- endif -%}
|
||||||
</form>
|
</form>
|
||||||
{% endspaceless %}
|
{%- endblock form_end %}
|
||||||
{% endblock form_end %}
|
|
||||||
|
|
||||||
{% block form_enctype %}
|
{% block form_enctype -%}
|
||||||
{% spaceless %}
|
|
||||||
{% if multipart %}enctype="multipart/form-data"{% endif %}
|
{% if multipart %}enctype="multipart/form-data"{% endif %}
|
||||||
{% endspaceless %}
|
{%- endblock form_enctype %}
|
||||||
{% endblock form_enctype %}
|
|
||||||
|
|
||||||
{% block form_errors %}
|
{% block form_errors -%}
|
||||||
{% spaceless %}
|
{% if errors|length > 0 -%}
|
||||||
{% if errors|length > 0 %}
|
|
||||||
<ul>
|
<ul>
|
||||||
{% for error in errors %}
|
{%- for error in errors -%}
|
||||||
<li>{{ error.message }}</li>
|
<li>{{ error.message }}</li>
|
||||||
{% endfor %}
|
{%- endfor -%}
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endspaceless %}
|
{%- endblock form_errors %}
|
||||||
{% endblock form_errors %}
|
|
||||||
|
|
||||||
{% block form_rest %}
|
{% block form_rest -%}
|
||||||
{% spaceless %}
|
{% for child in form -%}
|
||||||
{% for child in form %}
|
{% if not child.rendered -%}
|
||||||
{% if not child.rendered %}
|
|
||||||
{{ form_row(child) }}
|
{{ form_row(child) }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endfor %}
|
{%- endfor %}
|
||||||
{% endspaceless %}
|
{%- endblock form_rest %}
|
||||||
{% endblock form_rest %}
|
|
||||||
|
|
||||||
{# Support #}
|
{# Support #}
|
||||||
|
|
||||||
{% block form_rows %}
|
{% block form_rows -%}
|
||||||
{% spaceless %}
|
{% for child in form -%}
|
||||||
{% for child in form %}
|
|
||||||
{{ form_row(child) }}
|
{{ form_row(child) }}
|
||||||
{% endfor %}
|
{%- endfor %}
|
||||||
{% endspaceless %}
|
{%- endblock form_rows %}
|
||||||
{% endblock form_rows %}
|
|
||||||
|
|
||||||
{% block widget_attributes %}
|
{% block widget_attributes -%}
|
||||||
{% spaceless %}
|
|
||||||
id="{{ id }}" name="{{ full_name }}"{% if read_only %} readonly="readonly"{% endif %}{% if disabled %} disabled="disabled"{% endif %}{% if required %} required="required"{% endif %}{% if max_length %} maxlength="{{ max_length }}"{% endif %}{% if pattern %} pattern="{{ pattern }}"{% endif %}
|
id="{{ id }}" name="{{ full_name }}"{% if read_only %} readonly="readonly"{% endif %}{% if disabled %} disabled="disabled"{% endif %}{% if required %} required="required"{% endif %}{% if max_length %} maxlength="{{ max_length }}"{% endif %}{% if pattern %} pattern="{{ pattern }}"{% endif %}
|
||||||
{% for attrname, attrvalue in attr %}{% if attrname in ['placeholder', 'title'] %}{{ attrname }}="{{ attrvalue|trans({}, translation_domain) }}" {% else %}{{ attrname }}="{{ attrvalue }}" {% endif %}{% endfor %}
|
{% for attrname, attrvalue in attr %}{% if attrname in ['placeholder', 'title'] %}{{ attrname }}="{{ attrvalue|trans({}, translation_domain) }}" {% else %}{{ attrname }}="{{ attrvalue }}" {% endif %}{% endfor %}
|
||||||
{% endspaceless %}
|
{%- endblock widget_attributes %}
|
||||||
{% endblock widget_attributes %}
|
|
||||||
|
|
||||||
{% block widget_container_attributes %}
|
{% block widget_container_attributes -%}
|
||||||
{% spaceless %}
|
|
||||||
{% if id is not empty %}id="{{ id }}" {% endif %}
|
{% if id is not empty %}id="{{ id }}" {% endif %}
|
||||||
{% for attrname, attrvalue in attr %}{{ attrname }}="{{ attrvalue }}" {% endfor %}
|
{%- for attrname, attrvalue in attr %}{{ attrname }}="{{ attrvalue }}" {% endfor %}
|
||||||
{% endspaceless %}
|
{%- endblock widget_container_attributes %}
|
||||||
{% endblock widget_container_attributes %}
|
|
||||||
|
|
||||||
{% block button_attributes %}
|
{% block button_attributes -%}
|
||||||
{% spaceless %}
|
|
||||||
id="{{ id }}" name="{{ full_name }}"{% if disabled %} disabled="disabled"{% endif %}
|
id="{{ id }}" name="{{ full_name }}"{% if disabled %} disabled="disabled"{% endif %}
|
||||||
{% for attrname, attrvalue in attr %}{{ attrname }}="{{ attrvalue }}" {% endfor %}
|
{%- for attrname, attrvalue in attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}
|
||||||
{% endspaceless %}
|
{%- endblock button_attributes %}
|
||||||
{% endblock button_attributes %}
|
|
||||||
|
@ -1,52 +1,44 @@
|
|||||||
{% use "form_div_layout.html.twig" %}
|
{% use "form_div_layout.html.twig" %}
|
||||||
|
|
||||||
{% block form_row %}
|
{% block form_row -%}
|
||||||
{% spaceless %}
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{{ form_label(form) }}
|
{{- form_label(form) -}}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{ form_errors(form) }}
|
{{- form_errors(form) -}}
|
||||||
{{ form_widget(form) }}
|
{{- form_widget(form) -}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endspaceless %}
|
{%- endblock form_row %}
|
||||||
{% endblock form_row %}
|
|
||||||
|
|
||||||
{% block button_row %}
|
{% block button_row -%}
|
||||||
{% spaceless %}
|
|
||||||
<tr>
|
<tr>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>
|
<td>
|
||||||
{{ form_widget(form) }}
|
{{- form_widget(form) -}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endspaceless %}
|
{%- endblock button_row %}
|
||||||
{% endblock button_row %}
|
|
||||||
|
|
||||||
{% block hidden_row %}
|
{% block hidden_row -%}
|
||||||
{% spaceless %}
|
|
||||||
<tr style="display: none">
|
<tr style="display: none">
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
{{ form_widget(form) }}
|
{{- form_widget(form) -}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endspaceless %}
|
{%- endblock hidden_row %}
|
||||||
{% endblock hidden_row %}
|
|
||||||
|
|
||||||
{% block form_widget_compound %}
|
{% block form_widget_compound -%}
|
||||||
{% spaceless %}
|
|
||||||
<table {{ block('widget_container_attributes') }}>
|
<table {{ block('widget_container_attributes') }}>
|
||||||
{% if form.parent is empty and errors|length > 0 %}
|
{% if form.parent is empty and errors|length > 0 -%}
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
{{ form_errors(form) }}
|
{{- form_errors(form) -}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{{ block('form_rows') }}
|
{{- block('form_rows') -}}
|
||||||
{{ form_rest(form) }}
|
{{- form_rest(form) -}}
|
||||||
</table>
|
</table>
|
||||||
{% endspaceless %}
|
{%- endblock form_widget_compound %}
|
||||||
{% endblock form_widget_compound %}
|
|
||||||
|
@ -45,7 +45,7 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
$translator = $this->getTranslator($this->getLoader());
|
$translator = $this->getTranslator($this->getLoader());
|
||||||
$translator->setLocale('fr');
|
$translator->setLocale('fr');
|
||||||
$translator->setFallbackLocales(array('en', 'es', 'pt-PT', 'pt_BR'));
|
$translator->setFallbackLocales(array('en', 'es', 'pt-PT', 'pt_BR', 'fr.UTF-8', 'sr@latin'));
|
||||||
|
|
||||||
$this->assertEquals('foo (FR)', $translator->trans('foo'));
|
$this->assertEquals('foo (FR)', $translator->trans('foo'));
|
||||||
$this->assertEquals('bar (EN)', $translator->trans('bar'));
|
$this->assertEquals('bar (EN)', $translator->trans('bar'));
|
||||||
@ -54,6 +54,8 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals('no translation', $translator->trans('no translation'));
|
$this->assertEquals('no translation', $translator->trans('no translation'));
|
||||||
$this->assertEquals('foobarfoo (PT-PT)', $translator->trans('foobarfoo'));
|
$this->assertEquals('foobarfoo (PT-PT)', $translator->trans('foobarfoo'));
|
||||||
$this->assertEquals('other choice 1 (PT-BR)', $translator->transChoice('other choice', 1));
|
$this->assertEquals('other choice 1 (PT-BR)', $translator->transChoice('other choice', 1));
|
||||||
|
$this->assertEquals('foobarbaz (fr.UTF-8)', $translator->trans('foobarbaz'));
|
||||||
|
$this->assertEquals('foobarbax (sr@latin)', $translator->trans('foobarbax'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testTransWithCaching()
|
public function testTransWithCaching()
|
||||||
@ -61,7 +63,7 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
// prime the cache
|
// prime the cache
|
||||||
$translator = $this->getTranslator($this->getLoader(), array('cache_dir' => $this->tmpDir));
|
$translator = $this->getTranslator($this->getLoader(), array('cache_dir' => $this->tmpDir));
|
||||||
$translator->setLocale('fr');
|
$translator->setLocale('fr');
|
||||||
$translator->setFallbackLocales(array('en', 'es', 'pt-PT', 'pt_BR'));
|
$translator->setFallbackLocales(array('en', 'es', 'pt-PT', 'pt_BR', 'fr.UTF-8', 'sr@latin'));
|
||||||
|
|
||||||
$this->assertEquals('foo (FR)', $translator->trans('foo'));
|
$this->assertEquals('foo (FR)', $translator->trans('foo'));
|
||||||
$this->assertEquals('bar (EN)', $translator->trans('bar'));
|
$this->assertEquals('bar (EN)', $translator->trans('bar'));
|
||||||
@ -70,12 +72,14 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals('no translation', $translator->trans('no translation'));
|
$this->assertEquals('no translation', $translator->trans('no translation'));
|
||||||
$this->assertEquals('foobarfoo (PT-PT)', $translator->trans('foobarfoo'));
|
$this->assertEquals('foobarfoo (PT-PT)', $translator->trans('foobarfoo'));
|
||||||
$this->assertEquals('other choice 1 (PT-BR)', $translator->transChoice('other choice', 1));
|
$this->assertEquals('other choice 1 (PT-BR)', $translator->transChoice('other choice', 1));
|
||||||
|
$this->assertEquals('foobarbaz (fr.UTF-8)', $translator->trans('foobarbaz'));
|
||||||
|
$this->assertEquals('foobarbax (sr@latin)', $translator->trans('foobarbax'));
|
||||||
|
|
||||||
// do it another time as the cache is primed now
|
// do it another time as the cache is primed now
|
||||||
$loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
|
$loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
|
||||||
$translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir));
|
$translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir));
|
||||||
$translator->setLocale('fr');
|
$translator->setLocale('fr');
|
||||||
$translator->setFallbackLocales(array('en', 'es', 'pt-PT', 'pt_BR'));
|
$translator->setFallbackLocales(array('en', 'es', 'pt-PT', 'pt_BR', 'fr.UTF-8', 'sr@latin'));
|
||||||
|
|
||||||
$this->assertEquals('foo (FR)', $translator->trans('foo'));
|
$this->assertEquals('foo (FR)', $translator->trans('foo'));
|
||||||
$this->assertEquals('bar (EN)', $translator->trans('bar'));
|
$this->assertEquals('bar (EN)', $translator->trans('bar'));
|
||||||
@ -84,6 +88,8 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals('no translation', $translator->trans('no translation'));
|
$this->assertEquals('no translation', $translator->trans('no translation'));
|
||||||
$this->assertEquals('foobarfoo (PT-PT)', $translator->trans('foobarfoo'));
|
$this->assertEquals('foobarfoo (PT-PT)', $translator->trans('foobarfoo'));
|
||||||
$this->assertEquals('other choice 1 (PT-BR)', $translator->transChoice('other choice', 1));
|
$this->assertEquals('other choice 1 (PT-BR)', $translator->transChoice('other choice', 1));
|
||||||
|
$this->assertEquals('foobarbaz (fr.UTF-8)', $translator->trans('foobarbaz'));
|
||||||
|
$this->assertEquals('foobarbax (sr@latin)', $translator->trans('foobarbax'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetLocale()
|
public function testGetLocale()
|
||||||
@ -175,6 +181,20 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
'other choice' => '{0} other choice 0 (PT-BR)|{1} other choice 1 (PT-BR)|]1,Inf] other choice inf (PT-BR)',
|
'other choice' => '{0} other choice 0 (PT-BR)|{1} other choice 1 (PT-BR)|]1,Inf] other choice inf (PT-BR)',
|
||||||
))))
|
))))
|
||||||
;
|
;
|
||||||
|
$loader
|
||||||
|
->expects($this->at(5))
|
||||||
|
->method('load')
|
||||||
|
->will($this->returnValue($this->getCatalogue('fr.UTF-8', array(
|
||||||
|
'foobarbaz' => 'foobarbaz (fr.UTF-8)',
|
||||||
|
))))
|
||||||
|
;
|
||||||
|
$loader
|
||||||
|
->expects($this->at(6))
|
||||||
|
->method('load')
|
||||||
|
->will($this->returnValue($this->getCatalogue('sr@latin', array(
|
||||||
|
'foobarbax' => 'foobarbax (sr@latin)',
|
||||||
|
))))
|
||||||
|
;
|
||||||
|
|
||||||
return $loader;
|
return $loader;
|
||||||
}
|
}
|
||||||
@ -205,6 +225,8 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
$translator->addResource('loader', 'foo', 'es');
|
$translator->addResource('loader', 'foo', 'es');
|
||||||
$translator->addResource('loader', 'foo', 'pt-PT'); // European Portuguese
|
$translator->addResource('loader', 'foo', 'pt-PT'); // European Portuguese
|
||||||
$translator->addResource('loader', 'foo', 'pt_BR'); // Brazilian Portuguese
|
$translator->addResource('loader', 'foo', 'pt_BR'); // Brazilian Portuguese
|
||||||
|
$translator->addResource('loader', 'foo', 'fr.UTF-8');
|
||||||
|
$translator->addResource('loader', 'foo', 'sr@latin'); // Latin Serbian
|
||||||
|
|
||||||
return $translator;
|
return $translator;
|
||||||
}
|
}
|
||||||
|
@ -97,8 +97,10 @@ class Translator extends BaseTranslator
|
|||||||
|
|
||||||
$fallbackContent = '';
|
$fallbackContent = '';
|
||||||
$current = '';
|
$current = '';
|
||||||
|
$replacementPattern = '/[^a-z0-9_]/i';
|
||||||
foreach ($this->computeFallbackLocales($locale) as $fallback) {
|
foreach ($this->computeFallbackLocales($locale) as $fallback) {
|
||||||
$fallbackSuffix = ucfirst(str_replace('-', '_', $fallback));
|
$fallbackSuffix = ucfirst(preg_replace($replacementPattern, '_', $fallback));
|
||||||
|
$currentSuffix = ucfirst(preg_replace($replacementPattern, '_', $current));
|
||||||
|
|
||||||
$fallbackContent .= sprintf(<<<EOF
|
$fallbackContent .= sprintf(<<<EOF
|
||||||
\$catalogue%s = new MessageCatalogue('%s', %s);
|
\$catalogue%s = new MessageCatalogue('%s', %s);
|
||||||
@ -110,7 +112,7 @@ EOF
|
|||||||
$fallbackSuffix,
|
$fallbackSuffix,
|
||||||
$fallback,
|
$fallback,
|
||||||
var_export($this->catalogues[$fallback]->all(), true),
|
var_export($this->catalogues[$fallback]->all(), true),
|
||||||
ucfirst(str_replace('-', '_', $current)),
|
$currentSuffix,
|
||||||
$fallbackSuffix
|
$fallbackSuffix
|
||||||
);
|
);
|
||||||
$current = $fallback;
|
$current = $fallback;
|
||||||
|
@ -304,7 +304,7 @@ abstract class Client
|
|||||||
$uri = $this->getAbsoluteUri($uri);
|
$uri = $this->getAbsoluteUri($uri);
|
||||||
|
|
||||||
if (isset($server['HTTP_HOST'])) {
|
if (isset($server['HTTP_HOST'])) {
|
||||||
$uri = preg_replace('{^(https?\://)'.parse_url($uri, PHP_URL_HOST).'}', '${1}'.$server['HTTP_HOST'], $uri);
|
$uri = preg_replace('{^(https?\://)'.preg_quote($this->extractHost($uri)).'}', '${1}'.$server['HTTP_HOST'], $uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($server['HTTPS'])) {
|
if (isset($server['HTTPS'])) {
|
||||||
@ -317,12 +317,7 @@ abstract class Client
|
|||||||
$server['HTTP_REFERER'] = $this->history->current()->getUri();
|
$server['HTTP_REFERER'] = $this->history->current()->getUri();
|
||||||
}
|
}
|
||||||
|
|
||||||
$server['HTTP_HOST'] = parse_url($uri, PHP_URL_HOST);
|
$server['HTTP_HOST'] = $this->extractHost($uri);
|
||||||
|
|
||||||
if ($port = parse_url($uri, PHP_URL_PORT)) {
|
|
||||||
$server['HTTP_HOST'] .= ':'.$port;
|
|
||||||
}
|
|
||||||
|
|
||||||
$server['HTTPS'] = 'https' == parse_url($uri, PHP_URL_SCHEME);
|
$server['HTTPS'] = 'https' == parse_url($uri, PHP_URL_SCHEME);
|
||||||
|
|
||||||
$this->internalRequest = new Request($uri, $method, $parameters, $files, $this->cookieJar->allValues($uri), $server, $content);
|
$this->internalRequest = new Request($uri, $method, $parameters, $files, $this->cookieJar->allValues($uri), $server, $content);
|
||||||
@ -619,4 +614,15 @@ abstract class Client
|
|||||||
|
|
||||||
return $server;
|
return $server;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function extractHost($uri)
|
||||||
|
{
|
||||||
|
$host = parse_url($uri, PHP_URL_HOST);
|
||||||
|
|
||||||
|
if ($port = parse_url($uri, PHP_URL_PORT)) {
|
||||||
|
return $host.':'.$port;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $host;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,6 +210,24 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals('http://www.example.com/foo/bar', $client->getRequest()->getUri(), '->request() uses the previous request for relative URLs');
|
$this->assertEquals('http://www.example.com/foo/bar', $client->getRequest()->getUri(), '->request() uses the previous request for relative URLs');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testRequestURIConversionByServerHost()
|
||||||
|
{
|
||||||
|
$client = new TestClient();
|
||||||
|
|
||||||
|
$server = array('HTTP_HOST' => 'www.exampl+e.com:8000');
|
||||||
|
$parameters = array();
|
||||||
|
$files = array();
|
||||||
|
|
||||||
|
$client->request('GET', 'http://exampl+e.com', $parameters, $files, $server);
|
||||||
|
$this->assertEquals('http://www.exampl+e.com:8000', $client->getRequest()->getUri(), '->request() uses HTTP_HOST to add port');
|
||||||
|
|
||||||
|
$client->request('GET', 'http://exampl+e.com:8888', $parameters, $files, $server);
|
||||||
|
$this->assertEquals('http://www.exampl+e.com:8000', $client->getRequest()->getUri(), '->request() uses HTTP_HOST to modify existing port');
|
||||||
|
|
||||||
|
$client->request('GET', 'http://exampl+e.com:8000', $parameters, $files, $server);
|
||||||
|
$this->assertEquals('http://www.exampl+e.com:8000', $client->getRequest()->getUri(), '->request() uses HTTP_HOST respects correct set port');
|
||||||
|
}
|
||||||
|
|
||||||
public function testRequestReferer()
|
public function testRequestReferer()
|
||||||
{
|
{
|
||||||
$client = new TestClient();
|
$client = new TestClient();
|
||||||
|
@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\Parameter;
|
|||||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||||
|
use Symfony\Component\DependencyInjection\Scope;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GraphvizDumper dumps a service container as a graphviz file.
|
* GraphvizDumper dumps a service container as a graphviz file.
|
||||||
@ -193,8 +194,8 @@ class GraphvizDumper extends Dumper
|
|||||||
$container->setDefinitions($this->container->getDefinitions());
|
$container->setDefinitions($this->container->getDefinitions());
|
||||||
$container->setAliases($this->container->getAliases());
|
$container->setAliases($this->container->getAliases());
|
||||||
$container->setResources($this->container->getResources());
|
$container->setResources($this->container->getResources());
|
||||||
foreach ($this->container->getScopes() as $scope) {
|
foreach ($this->container->getScopes() as $scope => $parentScope) {
|
||||||
$container->addScope($scope);
|
$container->addScope(new Scope($scope, $parentScope));
|
||||||
}
|
}
|
||||||
foreach ($this->container->getExtensions() as $extension) {
|
foreach ($this->container->getExtensions() as $extension) {
|
||||||
$container->registerExtension($extension);
|
$container->registerExtension($extension);
|
||||||
|
@ -62,4 +62,11 @@ class GraphvizDumperTest extends \PHPUnit_Framework_TestCase
|
|||||||
$dumper = new GraphvizDumper($container);
|
$dumper = new GraphvizDumper($container);
|
||||||
$this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services14.dot')), $dumper->dump(), '->dump() dumps services');
|
$this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services14.dot')), $dumper->dump(), '->dump() dumps services');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDumpWithScopes()
|
||||||
|
{
|
||||||
|
$container = include self::$fixturesPath.'/containers/container18.php';
|
||||||
|
$dumper = new GraphvizDumper($container);
|
||||||
|
$this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services18.dot')), $dumper->dump(), '->dump() dumps services');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
use Symfony\Component\DependencyInjection\Scope;
|
||||||
|
|
||||||
|
$container = new ContainerBuilder();
|
||||||
|
$container->addScope(new Scope('request'));
|
||||||
|
$container->
|
||||||
|
register('foo', 'FooClass')->
|
||||||
|
setScope('request')
|
||||||
|
;
|
||||||
|
$container->compile();
|
||||||
|
|
||||||
|
return $container;
|
@ -0,0 +1,8 @@
|
|||||||
|
digraph sc {
|
||||||
|
ratio="compress"
|
||||||
|
node [fontsize="11" fontname="Arial" shape="record"];
|
||||||
|
edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"];
|
||||||
|
|
||||||
|
node_foo [label="foo\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
|
||||||
|
node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"];
|
||||||
|
}
|
@ -152,6 +152,8 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer
|
|||||||
* Returns a preconfigured IntlDateFormatter instance
|
* Returns a preconfigured IntlDateFormatter instance
|
||||||
*
|
*
|
||||||
* @return \IntlDateFormatter
|
* @return \IntlDateFormatter
|
||||||
|
*
|
||||||
|
* @throws TransformationFailedException in case the date formatter can not be constructed.
|
||||||
*/
|
*/
|
||||||
protected function getIntlDateFormatter()
|
protected function getIntlDateFormatter()
|
||||||
{
|
{
|
||||||
@ -162,6 +164,12 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer
|
|||||||
$pattern = $this->pattern;
|
$pattern = $this->pattern;
|
||||||
|
|
||||||
$intlDateFormatter = new \IntlDateFormatter(\Locale::getDefault(), $dateFormat, $timeFormat, $timezone, $calendar, $pattern);
|
$intlDateFormatter = new \IntlDateFormatter(\Locale::getDefault(), $dateFormat, $timeFormat, $timezone, $calendar, $pattern);
|
||||||
|
|
||||||
|
// new \intlDateFormatter may return null instead of false in case of failure, see https://bugs.php.net/bug.php?id=66323
|
||||||
|
if (!$intlDateFormatter) {
|
||||||
|
throw new TransformationFailedException(intl_get_error_message(), intl_get_error_code());
|
||||||
|
}
|
||||||
|
|
||||||
$intlDateFormatter->setLenient(false);
|
$intlDateFormatter->setLenient(false);
|
||||||
|
|
||||||
return $intlDateFormatter;
|
return $intlDateFormatter;
|
||||||
|
@ -77,6 +77,12 @@ class DateType extends AbstractType
|
|||||||
$calendar,
|
$calendar,
|
||||||
$pattern
|
$pattern
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// new \intlDateFormatter may return null instead of false in case of failure, see https://bugs.php.net/bug.php?id=66323
|
||||||
|
if (!$formatter) {
|
||||||
|
throw new InvalidOptionsException(intl_get_error_message(), intl_get_error_code());
|
||||||
|
}
|
||||||
|
|
||||||
$formatter->setLenient(false);
|
$formatter->setLenient(false);
|
||||||
|
|
||||||
if ('choice' === $options['widget']) {
|
if ('choice' === $options['widget']) {
|
||||||
|
@ -111,7 +111,7 @@ class JsonResponse extends Response
|
|||||||
// Not using application/javascript for compatibility reasons with older browsers.
|
// Not using application/javascript for compatibility reasons with older browsers.
|
||||||
$this->headers->set('Content-Type', 'text/javascript');
|
$this->headers->set('Content-Type', 'text/javascript');
|
||||||
|
|
||||||
return $this->setContent(sprintf('%s(%s);', $this->callback, $this->data));
|
return $this->setContent(sprintf('/**/%s(%s);', $this->callback, $this->data));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only set the header when there is none or when it equals 'text/javascript' (from a previous update with callback)
|
// Only set the header when there is none or when it equals 'text/javascript' (from a previous update with callback)
|
||||||
|
@ -155,7 +155,7 @@ class JsonResponseTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
$response = JsonResponse::create(array('foo' => 'bar'))->setCallback('callback');
|
$response = JsonResponse::create(array('foo' => 'bar'))->setCallback('callback');
|
||||||
|
|
||||||
$this->assertEquals('callback({"foo":"bar"});', $response->getContent());
|
$this->assertEquals('/**/callback({"foo":"bar"});', $response->getContent());
|
||||||
$this->assertEquals('text/javascript', $response->headers->get('Content-Type'));
|
$this->assertEquals('text/javascript', $response->headers->get('Content-Type'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,11 +59,11 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
|||||||
protected $startTime;
|
protected $startTime;
|
||||||
protected $loadClassCache;
|
protected $loadClassCache;
|
||||||
|
|
||||||
const VERSION = '2.3.18-DEV';
|
const VERSION = '2.3.19-DEV';
|
||||||
const VERSION_ID = '20318';
|
const VERSION_ID = '20319';
|
||||||
const MAJOR_VERSION = '2';
|
const MAJOR_VERSION = '2';
|
||||||
const MINOR_VERSION = '3';
|
const MINOR_VERSION = '3';
|
||||||
const RELEASE_VERSION = '18';
|
const RELEASE_VERSION = '19';
|
||||||
const EXTRA_VERSION = 'DEV';
|
const EXTRA_VERSION = 'DEV';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,8 +59,7 @@ class ExecutableFinder
|
|||||||
if (is_dir($path)) {
|
if (is_dir($path)) {
|
||||||
$dirs[] = $path;
|
$dirs[] = $path;
|
||||||
} else {
|
} else {
|
||||||
$file = str_replace(dirname($path), '', $path);
|
if (basename($path) == $name && is_executable($path)) {
|
||||||
if ($file == $name && is_executable($path)) {
|
|
||||||
return $path;
|
return $path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,8 @@ class Process
|
|||||||
/** @var ProcessPipes */
|
/** @var ProcessPipes */
|
||||||
private $processPipes;
|
private $processPipes;
|
||||||
|
|
||||||
|
private $latestSignal;
|
||||||
|
|
||||||
private static $sigchild;
|
private static $sigchild;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -321,7 +323,7 @@ class Process
|
|||||||
usleep(1000);
|
usleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->processInformation['signaled']) {
|
if ($this->processInformation['signaled'] && $this->processInformation['termsig'] !== $this->latestSignal) {
|
||||||
throw new RuntimeException(sprintf('The process has been signaled with signal "%s".', $this->processInformation['termsig']));
|
throw new RuntimeException(sprintf('The process has been signaled with signal "%s".', $this->processInformation['termsig']));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -661,7 +663,8 @@ class Process
|
|||||||
throw new RuntimeException('Unable to kill the process');
|
throw new RuntimeException('Unable to kill the process');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
proc_terminate($this->process);
|
// given `SIGTERM` may not be defined and that `proc_terminate` uses the constant value and not the constant itself, we use the same here
|
||||||
|
$this->doSignal(15, false);
|
||||||
do {
|
do {
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
} while ($this->isRunning() && microtime(true) < $timeoutMicro);
|
} while ($this->isRunning() && microtime(true) < $timeoutMicro);
|
||||||
@ -1158,6 +1161,7 @@ class Process
|
|||||||
$this->stdout = null;
|
$this->stdout = null;
|
||||||
$this->stderr = null;
|
$this->stderr = null;
|
||||||
$this->process = null;
|
$this->process = null;
|
||||||
|
$this->latestSignal = null;
|
||||||
$this->status = self::STATUS_READY;
|
$this->status = self::STATUS_READY;
|
||||||
$this->incrementalOutputOffset = 0;
|
$this->incrementalOutputOffset = 0;
|
||||||
$this->incrementalErrorOutputOffset = 0;
|
$this->incrementalErrorOutputOffset = 0;
|
||||||
@ -1201,6 +1205,8 @@ class Process
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->latestSignal = $signal;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,6 +284,8 @@ class ProcessPipes
|
|||||||
private function readStreams($blocking, $close = false)
|
private function readStreams($blocking, $close = false)
|
||||||
{
|
{
|
||||||
if (empty($this->pipes)) {
|
if (empty($this->pipes)) {
|
||||||
|
usleep(Process::TIMEOUT_PRECISION * 1E4);
|
||||||
|
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,11 +315,11 @@ class ProcessPipes
|
|||||||
$type = array_search($pipe, $this->pipes);
|
$type = array_search($pipe, $this->pipes);
|
||||||
|
|
||||||
$data = '';
|
$data = '';
|
||||||
while ($dataread = fread($pipe, self::CHUNK_SIZE)) {
|
while ('' !== $dataread = (string) fread($pipe, self::CHUNK_SIZE)) {
|
||||||
$data .= $dataread;
|
$data .= $dataread;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($data) {
|
if ('' !== $data) {
|
||||||
$read[$type] = $data;
|
$read[$type] = $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,6 +287,19 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testZeroAsOutput()
|
||||||
|
{
|
||||||
|
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
|
||||||
|
// see http://stackoverflow.com/questions/7105433/windows-batch-echo-without-new-line
|
||||||
|
$p = $this->getProcess('echo | set /p dummyName=0');
|
||||||
|
} else {
|
||||||
|
$p = $this->getProcess('printf 0');
|
||||||
|
}
|
||||||
|
|
||||||
|
$p->run();
|
||||||
|
$this->assertSame('0', $p->getOutput());
|
||||||
|
}
|
||||||
|
|
||||||
public function testExitCodeCommandFailed()
|
public function testExitCodeCommandFailed()
|
||||||
{
|
{
|
||||||
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
|
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
|
||||||
@ -583,7 +596,14 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
|
|||||||
}
|
}
|
||||||
$duration = microtime(true) - $start;
|
$duration = microtime(true) - $start;
|
||||||
|
|
||||||
$this->assertLessThan($timeout + Process::TIMEOUT_PRECISION, $duration);
|
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
|
||||||
|
// Windows is a bit slower as it read file handles, then allow twice the precision
|
||||||
|
$maxDuration = $timeout + 2 * Process::TIMEOUT_PRECISION;
|
||||||
|
} else {
|
||||||
|
$maxDuration = $timeout + Process::TIMEOUT_PRECISION;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertLessThan($maxDuration, $duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCheckTimeoutOnNonStartedProcess()
|
public function testCheckTimeoutOnNonStartedProcess()
|
||||||
|
@ -47,9 +47,9 @@ class ExecutableFinderTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->setPath(dirname(PHP_BINARY));
|
$this->setPath(dirname(PHP_BINARY));
|
||||||
|
|
||||||
$finder = new ExecutableFinder;
|
$finder = new ExecutableFinder;
|
||||||
$result = $finder->find(basename(PHP_BINARY));
|
$result = $finder->find($this->getPhpBinaryName());
|
||||||
|
|
||||||
$this->assertEquals($result, PHP_BINARY);
|
$this->assertSamePath(PHP_BINARY, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFindWithDefault()
|
public function testFindWithDefault()
|
||||||
@ -83,9 +83,9 @@ class ExecutableFinderTest extends \PHPUnit_Framework_TestCase
|
|||||||
$extraDirs = array(dirname(PHP_BINARY));
|
$extraDirs = array(dirname(PHP_BINARY));
|
||||||
|
|
||||||
$finder = new ExecutableFinder;
|
$finder = new ExecutableFinder;
|
||||||
$result = $finder->find(basename(PHP_BINARY), null, $extraDirs);
|
$result = $finder->find($this->getPhpBinaryName(), null, $extraDirs);
|
||||||
|
|
||||||
$this->assertEquals(PHP_BINARY, $result);
|
$this->assertSamePath(PHP_BINARY, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFindWithOpenBaseDir()
|
public function testFindWithOpenBaseDir()
|
||||||
@ -105,8 +105,43 @@ class ExecutableFinderTest extends \PHPUnit_Framework_TestCase
|
|||||||
ini_set('open_basedir', dirname(PHP_BINARY).PATH_SEPARATOR.'/');
|
ini_set('open_basedir', dirname(PHP_BINARY).PATH_SEPARATOR.'/');
|
||||||
|
|
||||||
$finder = new ExecutableFinder;
|
$finder = new ExecutableFinder;
|
||||||
$result = $finder->find(basename(PHP_BINARY));
|
$result = $finder->find($this->getPhpBinaryName());
|
||||||
|
|
||||||
$this->assertEquals(PHP_BINARY, $result);
|
$this->assertSamePath(PHP_BINARY, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFindProcessInOpenBasedir()
|
||||||
|
{
|
||||||
|
if (ini_get('open_basedir')) {
|
||||||
|
$this->markTestSkipped('Cannot test when open_basedir is set');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!defined('PHP_BINARY')) {
|
||||||
|
$this->markTestSkipped('Requires the PHP_BINARY constant');
|
||||||
|
}
|
||||||
|
|
||||||
|
$execPath = __DIR__.'/SignalListener.php';
|
||||||
|
|
||||||
|
$this->setPath('');
|
||||||
|
ini_set('open_basedir', PHP_BINARY.PATH_SEPARATOR.'/');
|
||||||
|
|
||||||
|
$finder = new ExecutableFinder();
|
||||||
|
$result = $finder->find($this->getPhpBinaryName(), false);
|
||||||
|
|
||||||
|
$this->assertSamePath(PHP_BINARY, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function assertSamePath($expected, $tested)
|
||||||
|
{
|
||||||
|
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
|
||||||
|
$this->assertEquals(strtolower($expected), strtolower($tested));
|
||||||
|
} else {
|
||||||
|
$this->assertEquals($expected, $tested);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getPhpBinaryName()
|
||||||
|
{
|
||||||
|
return basename(PHP_BINARY, defined('PHP_WINDOWS_VERSION_BUILD') ? '.exe' : '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,6 +211,11 @@ class SigchildDisabledProcessTest extends AbstractProcessTest
|
|||||||
$this->markTestSkipped('Signal is not supported in sigchild environment');
|
$this->markTestSkipped('Signal is not supported in sigchild environment');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testRunProcessWithTimeout()
|
||||||
|
{
|
||||||
|
$this->markTestSkipped('Signal (required for timeout) is not supported in sigchild environment');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -120,6 +120,21 @@ class SigchildEnabledProcessTest extends AbstractProcessTest
|
|||||||
parent::testStartAfterATimeout();
|
parent::testStartAfterATimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testStopWithTimeoutIsActuallyWorking()
|
||||||
|
{
|
||||||
|
$this->markTestSkipped('Stopping with signal is not supported in sigchild environment');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRunProcessWithTimeout()
|
||||||
|
{
|
||||||
|
$this->markTestSkipped('Signal (required for timeout) is not supported in sigchild environment');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCheckTimeoutOnStartedProcess()
|
||||||
|
{
|
||||||
|
$this->markTestSkipped('Signal (required for timeout) is not supported in sigchild environment');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -147,6 +147,57 @@ class SimpleProcessTest extends AbstractProcessTest
|
|||||||
parent::testSignalWithWrongNonIntSignal();
|
parent::testSignalWithWrongNonIntSignal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testStopTerminatesProcessCleanly()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$process = $this->getProcess('php -r "echo \'foo\'; sleep(1); echo \'bar\';"');
|
||||||
|
$process->run(function () use ($process) {
|
||||||
|
$process->stop();
|
||||||
|
});
|
||||||
|
} catch (RuntimeException $e) {
|
||||||
|
$this->fail('A call to stop() is not expected to cause wait() to throw a RuntimeException');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testKillSignalTerminatesProcessCleanly()
|
||||||
|
{
|
||||||
|
$this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. The process can not be signaled.');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$process = $this->getProcess('php -r "echo \'foo\'; sleep(1); echo \'bar\';"');
|
||||||
|
$process->run(function () use ($process) {
|
||||||
|
if ($process->isRunning()) {
|
||||||
|
$process->signal(SIGKILL);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (RuntimeException $e) {
|
||||||
|
$this->fail('A call to signal() is not expected to cause wait() to throw a RuntimeException');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTermSignalTerminatesProcessCleanly()
|
||||||
|
{
|
||||||
|
$this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. The process can not be signaled.');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$process = $this->getProcess('php -r "echo \'foo\'; sleep(1); echo \'bar\';"');
|
||||||
|
$process->run(function () use ($process) {
|
||||||
|
if ($process->isRunning()) {
|
||||||
|
$process->signal(SIGTERM);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (RuntimeException $e) {
|
||||||
|
$this->fail('A call to signal() is not expected to cause wait() to throw a RuntimeException');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testStopWithTimeoutIsActuallyWorking()
|
||||||
|
{
|
||||||
|
$this->skipIfPHPSigchild();
|
||||||
|
|
||||||
|
parent::testStopWithTimeoutIsActuallyWorking();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -17,6 +17,33 @@ use Symfony\Component\Translation\Loader\ArrayLoader;
|
|||||||
|
|
||||||
class TranslatorTest extends \PHPUnit_Framework_TestCase
|
class TranslatorTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getInvalidLocalesTests
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function testConstructorInvalidLocale($locale)
|
||||||
|
{
|
||||||
|
$translator = new Translator($locale, new MessageSelector());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getValidLocalesTests
|
||||||
|
*/
|
||||||
|
public function testConstructorValidLocale($locale)
|
||||||
|
{
|
||||||
|
$translator = new Translator($locale, new MessageSelector());
|
||||||
|
|
||||||
|
$this->assertEquals($locale, $translator->getLocale());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testConstructorWithoutLocale()
|
||||||
|
{
|
||||||
|
$translator = new Translator(null, new MessageSelector());
|
||||||
|
|
||||||
|
$this->assertNull($translator->getLocale());
|
||||||
|
}
|
||||||
|
|
||||||
public function testSetGetLocale()
|
public function testSetGetLocale()
|
||||||
{
|
{
|
||||||
$translator = new Translator('en', new MessageSelector());
|
$translator = new Translator('en', new MessageSelector());
|
||||||
@ -27,6 +54,27 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals('fr', $translator->getLocale());
|
$this->assertEquals('fr', $translator->getLocale());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getInvalidLocalesTests
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function testSetInvalidLocale($locale)
|
||||||
|
{
|
||||||
|
$translator = new Translator('fr', new MessageSelector());
|
||||||
|
$translator->setLocale($locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getValidLocalesTests
|
||||||
|
*/
|
||||||
|
public function testSetValidLocale($locale)
|
||||||
|
{
|
||||||
|
$translator = new Translator($locale, new MessageSelector());
|
||||||
|
$translator->setLocale($locale);
|
||||||
|
|
||||||
|
$this->assertEquals($locale, $translator->getLocale());
|
||||||
|
}
|
||||||
|
|
||||||
public function testSetFallbackLocales()
|
public function testSetFallbackLocales()
|
||||||
{
|
{
|
||||||
$translator = new Translator('en', new MessageSelector());
|
$translator = new Translator('en', new MessageSelector());
|
||||||
@ -55,6 +103,26 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals('bar (fr)', $translator->trans('bar'));
|
$this->assertEquals('bar (fr)', $translator->trans('bar'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getInvalidLocalesTests
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function testSetFallbackInvalidLocales($locale)
|
||||||
|
{
|
||||||
|
$translator = new Translator('fr', new MessageSelector());
|
||||||
|
$translator->setFallbackLocales(array('fr', $locale));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getValidLocalesTests
|
||||||
|
*/
|
||||||
|
public function testSetFallbackValidLocales($locale)
|
||||||
|
{
|
||||||
|
$translator = new Translator($locale, new MessageSelector());
|
||||||
|
$translator->setFallbackLocales(array('fr', $locale));
|
||||||
|
// no assertion. this method just asserts that no exception is thrown
|
||||||
|
}
|
||||||
|
|
||||||
public function testTransWithFallbackLocale()
|
public function testTransWithFallbackLocale()
|
||||||
{
|
{
|
||||||
$translator = new Translator('fr_FR', new MessageSelector());
|
$translator = new Translator('fr_FR', new MessageSelector());
|
||||||
@ -67,6 +135,26 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals('foobar', $translator->trans('bar'));
|
$this->assertEquals('foobar', $translator->trans('bar'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getInvalidLocalesTests
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function testAddResourceInvalidLocales($locale)
|
||||||
|
{
|
||||||
|
$translator = new Translator('fr', new MessageSelector());
|
||||||
|
$translator->addResource('array', array('foo' => 'foofoo'), $locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getValidLocalesTests
|
||||||
|
*/
|
||||||
|
public function testAddResourceValidLocales($locale)
|
||||||
|
{
|
||||||
|
$translator = new Translator('fr', new MessageSelector());
|
||||||
|
$translator->addResource('array', array('foo' => 'foofoo'), $locale);
|
||||||
|
// no assertion. this method just asserts that no exception is thrown
|
||||||
|
}
|
||||||
|
|
||||||
public function testAddResourceAfterTrans()
|
public function testAddResourceAfterTrans()
|
||||||
{
|
{
|
||||||
$translator = new Translator('fr', new MessageSelector());
|
$translator = new Translator('fr', new MessageSelector());
|
||||||
@ -164,6 +252,32 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals($expected, $translator->trans($id, $parameters, $domain, $locale));
|
$this->assertEquals($expected, $translator->trans($id, $parameters, $domain, $locale));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getInvalidLocalesTests
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function testTransInvalidLocale($locale)
|
||||||
|
{
|
||||||
|
$translator = new Translator('en', new MessageSelector());
|
||||||
|
$translator->addLoader('array', new ArrayLoader());
|
||||||
|
$translator->addResource('array', array('foo' => 'foofoo'), 'en');
|
||||||
|
|
||||||
|
$translator->trans('foo', array(), '', $locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getValidLocalesTests
|
||||||
|
*/
|
||||||
|
public function testTransValidLocale($locale)
|
||||||
|
{
|
||||||
|
$translator = new Translator('en', new MessageSelector());
|
||||||
|
$translator->addLoader('array', new ArrayLoader());
|
||||||
|
$translator->addResource('array', array('foo' => 'foofoo'), 'en');
|
||||||
|
|
||||||
|
$translator->trans('foo', array(), '', $locale);
|
||||||
|
// no assertion. this method just asserts that no exception is thrown
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getFlattenedTransTests
|
* @dataProvider getFlattenedTransTests
|
||||||
*/
|
*/
|
||||||
@ -188,6 +302,32 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals($expected, $translator->transChoice($id, $number, $parameters, $domain, $locale));
|
$this->assertEquals($expected, $translator->transChoice($id, $number, $parameters, $domain, $locale));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getInvalidLocalesTests
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function testTransChoiceInvalidLocale($locale)
|
||||||
|
{
|
||||||
|
$translator = new Translator('en', new MessageSelector());
|
||||||
|
$translator->addLoader('array', new ArrayLoader());
|
||||||
|
$translator->addResource('array', array('foo' => 'foofoo'), 'en');
|
||||||
|
|
||||||
|
$translator->transChoice('foo', 1, array(), '', $locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getValidLocalesTests
|
||||||
|
*/
|
||||||
|
public function testTransChoiceValidLocale($locale)
|
||||||
|
{
|
||||||
|
$translator = new Translator('en', new MessageSelector());
|
||||||
|
$translator->addLoader('array', new ArrayLoader());
|
||||||
|
$translator->addResource('array', array('foo' => 'foofoo'), 'en');
|
||||||
|
|
||||||
|
$translator->transChoice('foo', 1, array(), '', $locale);
|
||||||
|
// no assertion. this method just asserts that no exception is thrown
|
||||||
|
}
|
||||||
|
|
||||||
public function getTransFileTests()
|
public function getTransFileTests()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
@ -257,6 +397,40 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getInvalidLocalesTests()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array('fr FR'),
|
||||||
|
array('français'),
|
||||||
|
array('fr+en'),
|
||||||
|
array('utf#8'),
|
||||||
|
array('fr&en'),
|
||||||
|
array('fr~FR'),
|
||||||
|
array(' fr'),
|
||||||
|
array('fr '),
|
||||||
|
array('fr*'),
|
||||||
|
array('fr/FR'),
|
||||||
|
array('fr\\FR'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValidLocalesTests()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array(''),
|
||||||
|
array(null),
|
||||||
|
array('fr'),
|
||||||
|
array('francais'),
|
||||||
|
array('FR'),
|
||||||
|
array('frFR'),
|
||||||
|
array('fr-FR'),
|
||||||
|
array('fr_FR'),
|
||||||
|
array('fr.FR'),
|
||||||
|
array('fr-FR.UTF8'),
|
||||||
|
array('sr@latin'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function testTransChoiceFallback()
|
public function testTransChoiceFallback()
|
||||||
{
|
{
|
||||||
$translator = new Translator('ru', new MessageSelector());
|
$translator = new Translator('ru', new MessageSelector());
|
||||||
|
@ -59,11 +59,13 @@ class Translator implements TranslatorInterface
|
|||||||
* @param string $locale The locale
|
* @param string $locale The locale
|
||||||
* @param MessageSelector|null $selector The message selector for pluralization
|
* @param MessageSelector|null $selector The message selector for pluralization
|
||||||
*
|
*
|
||||||
|
* @throws \InvalidArgumentException If a locale contains invalid characters
|
||||||
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function __construct($locale, MessageSelector $selector = null)
|
public function __construct($locale, MessageSelector $selector = null)
|
||||||
{
|
{
|
||||||
$this->locale = $locale;
|
$this->setLocale($locale);
|
||||||
$this->selector = $selector ?: new MessageSelector();
|
$this->selector = $selector ?: new MessageSelector();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,6 +90,8 @@ class Translator implements TranslatorInterface
|
|||||||
* @param string $locale The locale
|
* @param string $locale The locale
|
||||||
* @param string $domain The domain
|
* @param string $domain The domain
|
||||||
*
|
*
|
||||||
|
* @throws \InvalidArgumentException If the locale contains invalid characters
|
||||||
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function addResource($format, $resource, $locale, $domain = null)
|
public function addResource($format, $resource, $locale, $domain = null)
|
||||||
@ -96,6 +100,8 @@ class Translator implements TranslatorInterface
|
|||||||
$domain = 'messages';
|
$domain = 'messages';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->assertValidLocale($locale);
|
||||||
|
|
||||||
$this->resources[$locale][] = array($format, $resource, $domain);
|
$this->resources[$locale][] = array($format, $resource, $domain);
|
||||||
|
|
||||||
if (in_array($locale, $this->fallbackLocales)) {
|
if (in_array($locale, $this->fallbackLocales)) {
|
||||||
@ -112,6 +118,7 @@ class Translator implements TranslatorInterface
|
|||||||
*/
|
*/
|
||||||
public function setLocale($locale)
|
public function setLocale($locale)
|
||||||
{
|
{
|
||||||
|
$this->assertValidLocale($locale);
|
||||||
$this->locale = $locale;
|
$this->locale = $locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,6 +137,8 @@ class Translator implements TranslatorInterface
|
|||||||
*
|
*
|
||||||
* @param string|array $locales The fallback locale(s)
|
* @param string|array $locales The fallback locale(s)
|
||||||
*
|
*
|
||||||
|
* @throws \InvalidArgumentException If a locale contains invalid characters
|
||||||
|
*
|
||||||
* @deprecated since 2.3, to be removed in 3.0. Use setFallbackLocales() instead.
|
* @deprecated since 2.3, to be removed in 3.0. Use setFallbackLocales() instead.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
@ -144,6 +153,8 @@ class Translator implements TranslatorInterface
|
|||||||
*
|
*
|
||||||
* @param array $locales The fallback locales
|
* @param array $locales The fallback locales
|
||||||
*
|
*
|
||||||
|
* @throws \InvalidArgumentException If a locale contains invalid characters
|
||||||
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setFallbackLocales(array $locales)
|
public function setFallbackLocales(array $locales)
|
||||||
@ -151,6 +162,10 @@ class Translator implements TranslatorInterface
|
|||||||
// needed as the fallback locales are linked to the already loaded catalogues
|
// needed as the fallback locales are linked to the already loaded catalogues
|
||||||
$this->catalogues = array();
|
$this->catalogues = array();
|
||||||
|
|
||||||
|
foreach ($locales as $locale) {
|
||||||
|
$this->assertValidLocale($locale);
|
||||||
|
}
|
||||||
|
|
||||||
$this->fallbackLocales = $locales;
|
$this->fallbackLocales = $locales;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,6 +190,8 @@ class Translator implements TranslatorInterface
|
|||||||
{
|
{
|
||||||
if (null === $locale) {
|
if (null === $locale) {
|
||||||
$locale = $this->getLocale();
|
$locale = $this->getLocale();
|
||||||
|
} else {
|
||||||
|
$this->assertValidLocale($locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null === $domain) {
|
if (null === $domain) {
|
||||||
@ -197,6 +214,8 @@ class Translator implements TranslatorInterface
|
|||||||
{
|
{
|
||||||
if (null === $locale) {
|
if (null === $locale) {
|
||||||
$locale = $this->getLocale();
|
$locale = $this->getLocale();
|
||||||
|
} else {
|
||||||
|
$this->assertValidLocale($locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null === $domain) {
|
if (null === $domain) {
|
||||||
@ -279,4 +298,18 @@ class Translator implements TranslatorInterface
|
|||||||
|
|
||||||
return array_unique($locales);
|
return array_unique($locales);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the locale is valid, throws an Exception if not.
|
||||||
|
*
|
||||||
|
* @param string $locale Locale to tests
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException If the locale contains invalid characters
|
||||||
|
*/
|
||||||
|
private function assertValidLocale($locale)
|
||||||
|
{
|
||||||
|
if (1 !== preg_match('/^[a-z0-9@_\\.\\-]*$/i', $locale)) {
|
||||||
|
throw new \InvalidArgumentException(sprintf('Invalid "%s" locale.', $locale));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,8 @@ interface TranslatorInterface
|
|||||||
* @param string $domain The domain for the message
|
* @param string $domain The domain for the message
|
||||||
* @param string $locale The locale
|
* @param string $locale The locale
|
||||||
*
|
*
|
||||||
|
* @throws \InvalidArgumentException If the locale contains invalid characters
|
||||||
|
*
|
||||||
* @return string The translated string
|
* @return string The translated string
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
@ -43,6 +45,8 @@ interface TranslatorInterface
|
|||||||
* @param string $domain The domain for the message
|
* @param string $domain The domain for the message
|
||||||
* @param string $locale The locale
|
* @param string $locale The locale
|
||||||
*
|
*
|
||||||
|
* @throws \InvalidArgumentException If the locale contains invalid characters
|
||||||
|
*
|
||||||
* @return string The translated string
|
* @return string The translated string
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
@ -54,6 +58,8 @@ interface TranslatorInterface
|
|||||||
*
|
*
|
||||||
* @param string $locale The locale
|
* @param string $locale The locale
|
||||||
*
|
*
|
||||||
|
* @throws \InvalidArgumentException If the locale contains invalid characters
|
||||||
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function setLocale($locale);
|
public function setLocale($locale);
|
||||||
|
@ -176,7 +176,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="47">
|
<trans-unit id="47">
|
||||||
<source>This value should be the user current password.</source>
|
<source>This value should be the user current password.</source>
|
||||||
<target>This value should be the user current password.</target>
|
<target>This value should be the user's current password.</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="48">
|
<trans-unit id="48">
|
||||||
<source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
|
<source>This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters.</source>
|
||||||
|
@ -35,6 +35,7 @@ class Entity extends EntityParent implements EntityInterface
|
|||||||
public $reference;
|
public $reference;
|
||||||
private $internal;
|
private $internal;
|
||||||
public $data = 'Overridden data';
|
public $data = 'Overridden data';
|
||||||
|
public $initialized = false;
|
||||||
|
|
||||||
public function __construct($internal = null)
|
public function __construct($internal = null)
|
||||||
{
|
{
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Validator\Tests;
|
namespace Symfony\Component\Validator\Tests;
|
||||||
|
|
||||||
|
use Symfony\Component\Validator\Constraints\Callback;
|
||||||
|
use Symfony\Component\Validator\ExecutionContextInterface;
|
||||||
use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory;
|
use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory;
|
||||||
use Symfony\Component\Validator\Constraints\Valid;
|
use Symfony\Component\Validator\Constraints\Valid;
|
||||||
use Symfony\Component\Validator\Tests\Fixtures\Reference;
|
use Symfony\Component\Validator\Tests\Fixtures\Reference;
|
||||||
@ -561,4 +563,50 @@ class ValidationVisitorTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$this->visitor->validate($entity, 'Default', '');
|
$this->visitor->validate($entity, 'Default', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testInitializeObjectsOnFirstValidation()
|
||||||
|
{
|
||||||
|
$test = $this;
|
||||||
|
$entity = new Entity();
|
||||||
|
$entity->initialized = false;
|
||||||
|
|
||||||
|
// prepare initializers that set "initialized" to true
|
||||||
|
$initializer1 = $this->getMock('Symfony\\Component\\Validator\\ObjectInitializerInterface');
|
||||||
|
$initializer2 = $this->getMock('Symfony\\Component\\Validator\\ObjectInitializerInterface');
|
||||||
|
|
||||||
|
$initializer1->expects($this->once())
|
||||||
|
->method('initialize')
|
||||||
|
->with($entity)
|
||||||
|
->will($this->returnCallback(function ($object) {
|
||||||
|
$object->initialized = true;
|
||||||
|
}));
|
||||||
|
|
||||||
|
$initializer2->expects($this->once())
|
||||||
|
->method('initialize')
|
||||||
|
->with($entity);
|
||||||
|
|
||||||
|
$this->visitor = new ValidationVisitor('Root', $this->metadataFactory, new ConstraintValidatorFactory(), new DefaultTranslator(), null, array(
|
||||||
|
$initializer1,
|
||||||
|
$initializer2
|
||||||
|
));
|
||||||
|
|
||||||
|
// prepare constraint which
|
||||||
|
// * checks that "initialized" is set to true
|
||||||
|
// * validates the object again
|
||||||
|
$callback = function ($object, ExecutionContextInterface $context) use ($test) {
|
||||||
|
$test->assertTrue($object->initialized);
|
||||||
|
|
||||||
|
// validate again in same group
|
||||||
|
$context->validate($object);
|
||||||
|
|
||||||
|
// validate again in other group
|
||||||
|
$context->validate($object, '', 'SomeGroup');
|
||||||
|
};
|
||||||
|
|
||||||
|
$this->metadata->addConstraint(new Callback(array($callback)));
|
||||||
|
|
||||||
|
$this->visitor->validate($entity, 'Default', '');
|
||||||
|
|
||||||
|
$this->assertTrue($entity->initialized);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,16 +127,19 @@ class ValidationVisitor implements ValidationVisitorInterface, GlobalExecutionCo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize if the object wasn't initialized before
|
||||||
|
if (!isset($this->validatedObjects[$hash])) {
|
||||||
|
foreach ($this->objectInitializers as $initializer) {
|
||||||
|
if (!$initializer instanceof ObjectInitializerInterface) {
|
||||||
|
throw new \LogicException('Validator initializers must implement ObjectInitializerInterface.');
|
||||||
|
}
|
||||||
|
$initializer->initialize($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Remember validating this object before starting and possibly
|
// Remember validating this object before starting and possibly
|
||||||
// traversing the object graph
|
// traversing the object graph
|
||||||
$this->validatedObjects[$hash][$group] = true;
|
$this->validatedObjects[$hash][$group] = true;
|
||||||
|
|
||||||
foreach ($this->objectInitializers as $initializer) {
|
|
||||||
if (!$initializer instanceof ObjectInitializerInterface) {
|
|
||||||
throw new \LogicException('Validator initializers must implement ObjectInitializerInterface.');
|
|
||||||
}
|
|
||||||
$initializer->initialize($value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate arrays recursively by default, otherwise every driver needs
|
// Validate arrays recursively by default, otherwise every driver needs
|
||||||
|
Reference in New Issue
Block a user