Merge branch '2.5'
* 2.5: (43 commits) [Form] Fix PHPDoc for builder setData methods The underlying data variable is typed as mixed whereas the methods paramers where typed as array. fixed CS [Intl] Improved bundle reader implementations [Console] guarded against invalid aliases switch before_script to before_install and script to install fixed typo [HttpFoundation] Request - URI - comment improvements [Validator] The ratio of the ImageValidator is rounded to two decimals now [Security] Added more tests remove `service` parameter type from XSD [Intl] Added exception handler to command line scripts [Intl] Fixed a few bugs in TextBundleWriter [Intl] Updated icu.ini up to ICU 53 [Intl] Removed non-working $fallback argument from ArrayAccessibleResourceBundle Use separated function to resolve command and related arguments [SwiftmailerBridge] Bump allowed versions of swiftmailer [FrameworkBundle] Remove invalid markup [Intl] Added "internal" tag to all classes under Symfony\Component\Intl\ResourceBundle Remove routes for removed WebProfiler actions [Security] Fix usage of unexistent method in DoctrineAclCache. ... Conflicts: src/Symfony/Bundle/FrameworkBundle/Command/ServerRunCommand.php src/Symfony/Component/HttpKernel/HttpCache/Esi.php src/Symfony/Component/HttpKernel/Kernel.php src/Symfony/Component/Translation/Tests/Dumper/XliffFileDumperTest.php src/Symfony/Component/Yaml/Parser.php src/Symfony/Component/Yaml/Tests/InlineTest.php
This commit is contained in:
commit
4677e92ffe
@ -14,7 +14,7 @@ matrix:
|
||||
|
||||
services: mongodb
|
||||
|
||||
before_script:
|
||||
before_install:
|
||||
- travis_retry sudo apt-get install parallel
|
||||
- sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm-nightly" ]; then echo "" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini; fi;'
|
||||
- sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm-nightly" ]; then echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;'
|
||||
@ -22,9 +22,15 @@ before_script:
|
||||
- sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm-nightly" ]; then echo "extension = memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;'
|
||||
- sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm-nightly" ]; then echo "extension = memcache.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;'
|
||||
- sudo locale-gen fr_FR.UTF-8 && sudo update-locale
|
||||
<<<<<<< HEAD
|
||||
- COMPOSER_ROOT_VERSION=dev-master composer --prefer-source --dev install
|
||||
=======
|
||||
>>>>>>> 2.4
|
||||
# - sh -c 'if [ "$TRAVIS_PHP_VERSION" != "5.3.3" ]; then phpunit --self-update; fi;'
|
||||
|
||||
install:
|
||||
- COMPOSER_ROOT_VERSION=dev-master composer --prefer-source install
|
||||
|
||||
script:
|
||||
- ls -d src/Symfony/*/* | parallel --gnu --keep-order 'echo "Running {} tests"; phpunit --exclude-group tty,benchmark {};'
|
||||
- echo "Running tests requiring tty"; phpunit --group tty
|
||||
|
@ -7,6 +7,59 @@ 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 between two versions, go to https://github.com/symfony/symfony/compare/v2.3.0...v2.3.1
|
||||
|
||||
* 2.3.19 (2014-09-03)
|
||||
|
||||
* security #11832 CVE-2014-6072 (fabpot)
|
||||
* security #11831 CVE-2014-5245 (stof)
|
||||
* security #11830 CVE-2014-4931 (aitboudad, Jérémy Derussé)
|
||||
* security #11829 CVE-2014-6061 (damz, fabpot)
|
||||
* security #11828 CVE-2014-5244 (nicolas-grekas, larowlan)
|
||||
* bug #10197 [FrameworkBundle] PhpExtractor bugfix and improvements (mtibben)
|
||||
* bug #11772 [Filesystem] Add FTP stream wrapper context option to enable overwrite (Damian Sromek)
|
||||
* bug #11788 [Yaml] fixed mapping keys containing a quoted # (hvt, fabpot)
|
||||
* bug #11160 [DoctrineBridge] Abstract Doctrine Subscribers with tags (merk)
|
||||
* bug #11768 [ClassLoader] Add a __call() method to XcacheClassLoader (tstoeckler)
|
||||
* bug #11726 [Filesystem Component] mkdir race condition fix #11626 (kcassam)
|
||||
* bug #11677 [YAML] resolve variables in inlined YAML (xabbuh)
|
||||
* bug #11639 [DependencyInjection] Fixed factory service not within the ServiceReferenceGraph. (boekkooi)
|
||||
* bug #11778 [Validator] Fixed wrong translations for Collection constraints (samicemalone)
|
||||
* bug #11756 [DependencyInjection] fix @return anno created by PhpDumper (jakubkulhan)
|
||||
* bug #11711 [DoctrineBridge] Fix empty parameter logging in the dbal logger (jakzal)
|
||||
* bug #11692 [DomCrawler] check for the correct field type (xabbuh)
|
||||
* bug #11672 [Routing] fix handling of nullable XML attributes (xabbuh)
|
||||
* bug #11624 [DomCrawler] fix the axes handling in a bc way (xabbuh)
|
||||
* bug #11676 [Form] Fixed #11675 ValueToDuplicatesTransformer accept "0" value (Nek-)
|
||||
* bug #11695 [Validators] Fixed failing tests requiring ICU 52.1 which are skipped otherwise (webmozart)
|
||||
* bug #11529 [WebProfilerBundle] Fixed double height of canvas (hason)
|
||||
* bug #11641 [WebProfilerBundle ] Fix toolbar vertical alignment (blaugueux)
|
||||
* bug #11559 [Validator] Convert objects to string in comparison validators (webmozart)
|
||||
* feature #11510 [HttpFoundation] MongoDbSessionHandler supports auto expiry via configurable expiry_field (catchamonkey)
|
||||
* bug #11408 [HttpFoundation] Update QUERY_STRING when overrideGlobals (yguedidi)
|
||||
* bug #11633 [FrameworkBundle] add missing attribute to XSD (xabbuh)
|
||||
* bug #11601 [Validator] Allow basic auth in url when using UrlValidator. (blaugueux)
|
||||
* bug #11609 [Console] fixed style creation when providing an unknown tag option (fabpot)
|
||||
* bug #10914 [HttpKernel] added an analyze of environment parameters for built-in server (mauchede)
|
||||
* bug #11598 [Finder] Shell escape and windows support (Gordon Franke, gimler)
|
||||
* bug #11499 [BrowserKit] Fixed relative redirects for ambiguous paths (pkruithof)
|
||||
* bug #11516 [BrowserKit] Fix browser kit redirect with ports (dakota)
|
||||
* bug #11545 [Bundle][FrameworkBundle] built-in server: exit when docroot does not exist (xabbuh)
|
||||
* bug #11560 Plural fix (1emming)
|
||||
* bug #11558 [DependencyInjection] Fixed missing 'factory-class' attribute in XmlDumper output (kerdany)
|
||||
* bug #11548 [Component][DomCrawler] fix axes handling in Crawler::filterXPath() (xabbuh)
|
||||
* bug #11422 [DependencyInjection] Self-referenced 'service_container' service breaks garbage collection (sun)
|
||||
* bug #11428 [Serializer] properly handle null data when denormalizing (xabbuh)
|
||||
* bug #10687 [Validator] Fixed string conversion in constraint violations (eagleoneraptor, webmozart)
|
||||
* bug #11475 [EventDispatcher] don't count empty listeners (xabbuh)
|
||||
* bug #11436 fix signal handling in wait() on calls to stop() (xabbuh, romainneutron)
|
||||
* bug #11469 [BrowserKit] Fixed server HTTP_HOST port uri conversion (bcremer, fabpot)
|
||||
* bug #11425 Fix issue described in #11421 (Ben, ben-rosio)
|
||||
* bug #11423 Pass a Scope instance instead of a scope name when cloning a container in the GrahpvizDumper (jakzal)
|
||||
* bug #11120 [Process] Reduce I/O load on Windows platform (romainneutron)
|
||||
* bug #11342 [Form] Check if IntlDateFormatter constructor returned a valid object before using it (romainneutron)
|
||||
* bug #11411 [Validator] Backported #11410 to 2.3: Object initializers are called only once per object (webmozart)
|
||||
* bug #11403 [Translator][FrameworkBundle] Added @ to the list of allowed chars in Translator (takeit)
|
||||
* bug #11381 [Process] Use correct test for empty string in UnixPipes (whs, romainneutron)
|
||||
|
||||
* 2.3.18 (2014-07-15)
|
||||
|
||||
* [Security] Forced validate of locales passed to the translator
|
||||
|
@ -7,6 +7,61 @@ in 2.4 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 between two versions, go to https://github.com/symfony/symfony/compare/v2.4.0...v2.4.1
|
||||
|
||||
* 2.4.9 (2014-09-03)
|
||||
|
||||
* security #11832 CVE-2014-6072 (fabpot)
|
||||
* security #11831 CVE-2014-5245 (stof)
|
||||
* security #11830 CVE-2014-4931 (aitboudad, Jérémy Derussé)
|
||||
* security #11829 CVE-2014-6061 (damz, fabpot)
|
||||
* security #11828 CVE-2014-5244 (nicolas-grekas, larowlan)
|
||||
* bug #10197 [FrameworkBundle] PhpExtractor bugfix and improvements (mtibben)
|
||||
* bug #11772 [Filesystem] Add FTP stream wrapper context option to enable overwrite (Damian Sromek)
|
||||
* bug #11788 [Yaml] fixed mapping keys containing a quoted # (hvt, fabpot)
|
||||
* bug #11160 [DoctrineBridge] Abstract Doctrine Subscribers with tags (merk)
|
||||
* bug #11768 [ClassLoader] Add a __call() method to XcacheClassLoader (tstoeckler)
|
||||
* bug #11726 [Filesystem Component] mkdir race condition fix #11626 (kcassam)
|
||||
* bug #11677 [YAML] resolve variables in inlined YAML (xabbuh)
|
||||
* bug #11639 [DependencyInjection] Fixed factory service not within the ServiceReferenceGraph. (boekkooi)
|
||||
* bug #11778 [Validator] Fixed wrong translations for Collection constraints (samicemalone)
|
||||
* bug #11756 [DependencyInjection] fix @return anno created by PhpDumper (jakubkulhan)
|
||||
* bug #11711 [DoctrineBridge] Fix empty parameter logging in the dbal logger (jakzal)
|
||||
* bug #11692 [DomCrawler] check for the correct field type (xabbuh)
|
||||
* bug #11672 [Routing] fix handling of nullable XML attributes (xabbuh)
|
||||
* bug #11624 [DomCrawler] fix the axes handling in a bc way (xabbuh)
|
||||
* bug #11676 [Form] Fixed #11675 ValueToDuplicatesTransformer accept "0" value (Nek-)
|
||||
* bug #11695 [Validators] Fixed failing tests requiring ICU 52.1 which are skipped otherwise (webmozart)
|
||||
* bug #11529 [WebProfilerBundle] Fixed double height of canvas (hason)
|
||||
* bug #11641 [WebProfilerBundle ] Fix toolbar vertical alignment (blaugueux)
|
||||
* bug #11559 [Validator] Convert objects to string in comparison validators (webmozart)
|
||||
* feature #11510 [HttpFoundation] MongoDbSessionHandler supports auto expiry via configurable expiry_field (catchamonkey)
|
||||
* bug #11408 [HttpFoundation] Update QUERY_STRING when overrideGlobals (yguedidi)
|
||||
* bug #11633 [FrameworkBundle] add missing attribute to XSD (xabbuh)
|
||||
* bug #11601 [Validator] Allow basic auth in url when using UrlValidator. (blaugueux)
|
||||
* bug #11609 [Console] fixed style creation when providing an unknown tag option (fabpot)
|
||||
* bug #10914 [HttpKernel] added an analyze of environment parameters for built-in server (mauchede)
|
||||
* bug #11598 [Finder] Shell escape and windows support (Gordon Franke, gimler)
|
||||
* bug #11499 [BrowserKit] Fixed relative redirects for ambiguous paths (pkruithof)
|
||||
* bug #11516 [BrowserKit] Fix browser kit redirect with ports (dakota)
|
||||
* bug #11545 [Bundle][FrameworkBundle] built-in server: exit when docroot does not exist (xabbuh)
|
||||
* bug #11560 Plural fix (1emming)
|
||||
* bug #11558 [DependencyInjection] Fixed missing 'factory-class' attribute in XmlDumper output (kerdany)
|
||||
* bug #11548 [Component][DomCrawler] fix axes handling in Crawler::filterXPath() (xabbuh)
|
||||
* bug #11422 [DependencyInjection] Self-referenced 'service_container' service breaks garbage collection (sun)
|
||||
* bug #11428 [Serializer] properly handle null data when denormalizing (xabbuh)
|
||||
* bug #10687 [Validator] Fixed string conversion in constraint violations (eagleoneraptor, webmozart)
|
||||
* bug #11475 [EventDispatcher] don't count empty listeners (xabbuh)
|
||||
* bug #11436 fix signal handling in wait() on calls to stop() (xabbuh, romainneutron)
|
||||
* bug #11469 [BrowserKit] Fixed server HTTP_HOST port uri conversion (bcremer, fabpot)
|
||||
* bug #11425 Fix issue described in #11421 (Ben, ben-rosio)
|
||||
* bug #11423 Pass a Scope instance instead of a scope name when cloning a container in the GrahpvizDumper (jakzal)
|
||||
* bug #11448 [MonologBridge] fixed Console handler priorities (fabpot)
|
||||
* bug #11120 [Process] Reduce I/O load on Windows platform (romainneutron)
|
||||
* bug #11342 [Form] Check if IntlDateFormatter constructor returned a valid object before using it (romainneutron)
|
||||
* bug #11439 [ExpressionLanguage] Fixed double quoted string literals containing sharps (pylebecq)
|
||||
* bug #11411 [Validator] Backported #11410 to 2.3: Object initializers are called only once per object (webmozart)
|
||||
* bug #11403 [Translator][FrameworkBundle] Added @ to the list of allowed chars in Translator (takeit)
|
||||
* bug #11381 [Process] Use correct test for empty string in UnixPipes (whs, romainneutron)
|
||||
|
||||
* 2.4.8 (2014-07-15)
|
||||
|
||||
* [Security] Forced validate of locales passed to the translator
|
||||
|
@ -7,6 +7,50 @@ in 2.5 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 between two versions, go to https://github.com/symfony/symfony/compare/v2.5.0...v2.5.1
|
||||
|
||||
* 2.5.4 (2014-09-03)
|
||||
|
||||
* security #11832 CVE-2014-6072 (fabpot)
|
||||
* security #11831 CVE-2014-5245 (stof)
|
||||
* security #11830 CVE-2014-4931 (aitboudad, Jérémy Derussé)
|
||||
* security #11829 CVE-2014-6061 (damz, fabpot)
|
||||
* security #11828 CVE-2014-5244 (nicolas-grekas, larowlan)
|
||||
* bug #10197 [FrameworkBundle] PhpExtractor bugfix and improvements (mtibben)
|
||||
* bug #11772 [Filesystem] Add FTP stream wrapper context option to enable overwrite (Damian Sromek)
|
||||
* bug #11791 [Process] fix mustRun() in sigchild environments (xabbuh)
|
||||
* bug #11788 [Yaml] fixed mapping keys containing a quoted # (hvt, fabpot)
|
||||
* bug #11787 fixed DateComparator if file does not exist (avi123)
|
||||
* bug #11160 [DoctrineBridge] Abstract Doctrine Subscribers with tags (merk)
|
||||
* bug #11768 [ClassLoader] Add a __call() method to XcacheClassLoader (tstoeckler)
|
||||
* bug #11739 [Validator] Pass strict argument into the strict email validator (brianfreytag)
|
||||
* bug #11749 [TwigBundle] Remove hard dependency of RequestContext in AssetsExtension (pgodel)
|
||||
* bug #11726 [Filesystem Component] mkdir race condition fix #11626 (kcassam)
|
||||
* bug #11677 [YAML] resolve variables in inlined YAML (xabbuh)
|
||||
* bug #11639 [DependencyInjection] Fixed factory service not within the ServiceReferenceGraph. (boekkooi)
|
||||
* bug #11778 [Validator] Fixed wrong translations for Collection constraints (samicemalone)
|
||||
* bug #11756 [DependencyInjection] fix @return anno created by PhpDumper (jakubkulhan)
|
||||
* bug #11711 [DoctrineBridge] Fix empty parameter logging in the dbal logger (jakzal)
|
||||
* bug #11692 [DomCrawler] check for the correct field type (xabbuh)
|
||||
* bug #11672 [Routing] fix handling of nullable XML attributes (xabbuh)
|
||||
* bug #11624 [DomCrawler] fix the axes handling in a bc way (xabbuh)
|
||||
* bug #11676 [Form] Fixed #11675 ValueToDuplicatesTransformer accept "0" value (Nek-)
|
||||
* bug #11695 [Validators] Fixed failing tests requiring ICU 52.1 which are skipped otherwise (webmozart)
|
||||
* bug #11584 [FrameworkBundle] Fixed validator factory definition when the Validator API is "auto" for PHP < 5.3.9 (webmozart)
|
||||
* bug #11645 [Form] Fixed ValidatorExtension to work with the 2.5 Validation API (webmozart)
|
||||
* bug #11529 [WebProfilerBundle] Fixed double height of canvas (hason)
|
||||
* bug #11666 [DIC] Fixed: anonymous services are always private (lyrixx)
|
||||
* bug #11641 [WebProfilerBundle ] Fix toolbar vertical alignment (blaugueux)
|
||||
* bug #11637 fix dependencies on HttpFoundation component (xabbuh)
|
||||
* bug #11559 [Validator] Convert objects to string in comparison validators (webmozart)
|
||||
* feature #11510 [HttpFoundation] MongoDbSessionHandler supports auto expiry via configurable expiry_field (catchamonkey)
|
||||
* bug #11408 [HttpFoundation] Update QUERY_STRING when overrideGlobals (yguedidi)
|
||||
* bug #11625 [FrameworkBundle] resolve parameters before the configs are processed in the config:debug command (xabbuh)
|
||||
* bug #11633 [FrameworkBundle] add missing attribute to XSD (xabbuh)
|
||||
* bug #11601 [Validator] Allow basic auth in url when using UrlValidator. (blaugueux)
|
||||
* bug #11609 [Console] fixed style creation when providing an unknown tag option (fabpot)
|
||||
* bug #10914 [HttpKernel] added an analyze of environment parameters for built-in server (mauchede)
|
||||
* bug #11598 [Finder] Shell escape and windows support (Gordon Franke, gimler)
|
||||
* bug #11582 [DoctrineBridge] Changed UniqueEntityValidator to use the 2.5 Validation API (webmozart)
|
||||
|
||||
* 2.5.3 (2014-08-06)
|
||||
|
||||
* bug #11571 [Form] Fixed FormValidator compatibility with the non-BC 2.5 Validation API (webmozart)
|
||||
|
116
CONTRIBUTORS.md
116
CONTRIBUTORS.md
@ -18,38 +18,39 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Joseph Bielawski (stloyd)
|
||||
- Ryan Weaver (weaverryan)
|
||||
- Lukas Kahwe Smith (lsmith)
|
||||
- Jeremy Mikola (jmikola)
|
||||
- Romain Neutron (romain)
|
||||
- Jeremy Mikola (jmikola)
|
||||
- Jean-François Simon (jfsimon)
|
||||
- Benjamin Eberlei (beberlei)
|
||||
- Igor Wiedler (igorw)
|
||||
- Hugo Hamon (hhamon)
|
||||
- Eriksen Costa (eriksencosta)
|
||||
- Martin Hasoň (hason)
|
||||
- Eriksen Costa (eriksencosta)
|
||||
- Jonathan Wage (jwage)
|
||||
- Alexandre Salomé (alexandresalome)
|
||||
- William Durand (couac)
|
||||
- ornicar
|
||||
- stealth35 (stealth35)
|
||||
- Grégoire Pineau (lyrixx)
|
||||
- Alexander Mols (asm89)
|
||||
- Bulat Shakirzyanov (avalanche123)
|
||||
- Grégoire Pineau (lyrixx)
|
||||
- Nicolas Grekas (nicolas-grekas)
|
||||
- Francis Besset (francisbesset)
|
||||
- Saša Stamenković (umpirsky)
|
||||
- Miha Vrhovnik
|
||||
- Henrik Bjørnskov (henrikbjorn)
|
||||
- Konstantin Kudryashov (everzet)
|
||||
- Wouter De Jong (wouterj)
|
||||
- Christian Flothmann (xabbuh)
|
||||
- Bilal Amarni (bamarni)
|
||||
- Florin Patan (florinpatan)
|
||||
- Wouter De Jong (wouterj)
|
||||
- Eric Clemmons (ericclemmons)
|
||||
- Nicolas Grekas (nicolas-grekas)
|
||||
- Andrej Hudec (pulzarraider)
|
||||
- Deni
|
||||
- Henrik Westphal (snc)
|
||||
- Dariusz Górecki (canni)
|
||||
- Arnout Boks (aboks)
|
||||
- Christian Raue
|
||||
- Arnout Boks (aboks)
|
||||
- Michel Weimerskirch (mweimerskirch)
|
||||
- Lee McDermott
|
||||
- Brandon Turner
|
||||
@ -61,11 +62,11 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Bart van den Burg (burgov)
|
||||
- Antoine Hérault (herzult)
|
||||
- Toni Uebernickel (havvg)
|
||||
- Arnaud Le Blanc (arnaud-lb)
|
||||
- Luis Cordova (cordoval)
|
||||
- Arnaud Le Blanc (arnaud-lb)
|
||||
- Tim Nagel (merk)
|
||||
- Kevin Bond (kbond)
|
||||
- Brice BERNARD (brikou)
|
||||
- Tim Nagel (merk)
|
||||
- marc.weistroff
|
||||
- lenar
|
||||
- Włodzimierz Gajda (gajdaw)
|
||||
@ -74,25 +75,25 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Florian Voutzinos (florianv)
|
||||
- Fabien Pennequin (fabienpennequin)
|
||||
- Jacob Dreesen (jdreesen)
|
||||
- Adrien Brault (adrienbrault)
|
||||
- Gábor Egyed (1ed)
|
||||
- Ait Boudad Abdellatif (aitboudad)
|
||||
- Adrien Brault (adrienbrault)
|
||||
- Michal Piotrowski (eventhorizon)
|
||||
- Gordon Franke (gimler)
|
||||
- Robert Schönthal (digitalkaoz)
|
||||
- Juti Noppornpitak (shiroyuki)
|
||||
- Sebastian Hörl (blogsh)
|
||||
- Daniel Gomes (danielcsgomes)
|
||||
- Hidenori Goto (hidenorigoto)
|
||||
- Peter Kokot (maastermedia)
|
||||
- Christian Flothmann (xabbuh)
|
||||
- Jérémie Augustin (jaugustin)
|
||||
- David Buchmann (dbu)
|
||||
- Pablo Godel (pgodel)
|
||||
- Jérémie Augustin (jaugustin)
|
||||
- Rafael Dohms (rdohms)
|
||||
- Jérôme Tamarelle (gromnan)
|
||||
- Tigran Azatyan (tigranazatyan)
|
||||
- Javier Eguiluz (javier.eguiluz)
|
||||
- Rafael Dohms (rdohms)
|
||||
- Richard Shank (iampersistent)
|
||||
- Gordon Franke (gimler)
|
||||
- Eric GELOEN (gelo)
|
||||
- Helmer Aaviksoo
|
||||
- Sebastiaan Stok (sstok)
|
||||
@ -103,7 +104,6 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Jonathan Ingram (jonathaningram)
|
||||
- Artur Kotyrba
|
||||
- Guilherme Blanco (guilhermeblanco)
|
||||
- Pablo Godel (pgodel)
|
||||
- Clemens Tolboom
|
||||
- Dmitrii Chekaliuk (lazyhammer)
|
||||
- Clément JOBEILI (dator)
|
||||
@ -114,10 +114,13 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Dennis Benkert (denderello)
|
||||
- Rouven Weßling (realityking)
|
||||
- Benjamin Dulau (dbenjamin)
|
||||
- Stefano Sala (stefano.sala)
|
||||
- Andreas Hucks (meandmymonkey)
|
||||
- Andréia Bohner (andreia)
|
||||
- Noel Guilbert (noel)
|
||||
- Charles Sarrazin (csarrazi)
|
||||
- bronze1man
|
||||
- sun (sun)
|
||||
- Larry Garfield (crell)
|
||||
- Martin Schuhfuß (usefulthink)
|
||||
- Thomas Rabaix (rande)
|
||||
@ -131,10 +134,9 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- jeff
|
||||
- Justin Hileman (bobthecow)
|
||||
- Sven Paulus (subsven)
|
||||
- Andréia Bohner (andreia)
|
||||
- Lars Strojny (lstrojny)
|
||||
- Joel Wurtz (brouznouf)
|
||||
- Rui Marinho (ruimarinho)
|
||||
- sun (sun)
|
||||
- Julien Brochet (mewt)
|
||||
- Tugdual Saunier (tucksaun)
|
||||
- Sergey Linnik (linniksa)
|
||||
@ -152,12 +154,11 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Katsuhiro OGAWA
|
||||
- Peter Rehm (rpet)
|
||||
- Alif Rachmawadi
|
||||
- Pierre-Yves LEBECQ (pylebecq)
|
||||
- Matthias Pigulla (mpdude)
|
||||
- Stefano Sala (stefano.sala)
|
||||
- Joseph Rouff (rouffj)
|
||||
- Félix Labrecque (woodspire)
|
||||
- GordonsLondon
|
||||
- Lars Strojny (lstrojny)
|
||||
- Jan Sorgalla (jsor)
|
||||
- Ray
|
||||
- Chekote
|
||||
@ -168,14 +169,17 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Beau Simensen (simensen)
|
||||
- Robert Kiss (kepten)
|
||||
- Kim Hemsø Rasmussen (kimhemsoe)
|
||||
- Tom Van Looy (tvlooy)
|
||||
- Wouter Van Hecke
|
||||
- Peter Kruithof (pkruithof)
|
||||
- Michael Holm (hollo)
|
||||
- Marc Weistroff (futurecat)
|
||||
- Pierre-Yves LEBECQ (pylebecq)
|
||||
- Roman Marintšenko (inori)
|
||||
- Chris Smith (cs278)
|
||||
- Florian Klein (docteurklein)
|
||||
- Manuel Kiessling (manuelkiessling)
|
||||
- Atsuhiro KUBO (iteman)
|
||||
- Issei Murasawa (issei_m)
|
||||
- Bertrand Zuchuat (garfield-fr)
|
||||
- Gabor Toth (tgabi333)
|
||||
- realmfoo
|
||||
@ -184,6 +188,7 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Grégoire Passault (gregwar)
|
||||
- Uwe Jäger (uwej711)
|
||||
- Aurelijus Valeiša (aurelijus)
|
||||
- Jan Decavele (jandc)
|
||||
- Gustavo Piltcher
|
||||
- Stepan Tanasiychuk (stfalcon)
|
||||
- Tiago Ribeiro (fixe)
|
||||
@ -191,10 +196,12 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Adrian Rudnik (kreischweide)
|
||||
- Francesc Rosàs (frosas)
|
||||
- Julien Galenski (ruian)
|
||||
- Eugene Leonovich (rybakit)
|
||||
- Bongiraud Dominique
|
||||
- janschoenherr
|
||||
- Marco Pivetta (ocramius)
|
||||
- Ricard Clau (ricardclau)
|
||||
- Jérémy DERUSSÉ (jderusse)
|
||||
- Kévin Dunglas (dunglas)
|
||||
- Erin Millard
|
||||
- Matthew Lewinski (lewinski)
|
||||
@ -204,8 +211,6 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Gyula Sallai (salla)
|
||||
- Inal DJAFAR (inalgnu)
|
||||
- Christian Gärtner (dagardner)
|
||||
- Tom Van Looy (tvlooy)
|
||||
- Peter Kruithof (pkruithof)
|
||||
- Felix Labrecque
|
||||
- Yaroslav Kiliba
|
||||
- Sébastien Lavoie (lavoiesl)
|
||||
@ -219,18 +224,17 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Philipp Kräutli (pkraeutli)
|
||||
- Kirill chEbba Chebunin (chebba)
|
||||
- Greg Thornton (xdissent)
|
||||
- Atsuhiro KUBO (iteman)
|
||||
- Grégoire Paris (greg0ire)
|
||||
- julien pauli (jpauli)
|
||||
- Costin Bereveanu (schniper)
|
||||
- Loïc Chardonnet (gnusat)
|
||||
- Marek Kalnik (marekkalnik)
|
||||
- Andrew Moore (finewolf)
|
||||
- Tamas Szijarto
|
||||
- Pavel Volokitin (pvolok)
|
||||
- Tobias Naumann (tna)
|
||||
- Ismael Ambrosi (iambrosi)
|
||||
- Shein Alexey
|
||||
- Issei Murasawa (issei_m)
|
||||
- hacfi (hifi)
|
||||
- Joe Lencioni
|
||||
- Kai
|
||||
@ -240,7 +244,6 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Miha Vrhovnik
|
||||
- Alessandro Desantis
|
||||
- hubert lecorche (hlecorche)
|
||||
- Eugene Leonovich (rybakit)
|
||||
- Oscar Cubo Medina (ocubom)
|
||||
- Karel Souffriau
|
||||
- Christophe L. (christophelau)
|
||||
@ -264,6 +267,8 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Tobias Sjösten (tobiassjosten)
|
||||
- vagrant
|
||||
- Asier Illarramendi (doup)
|
||||
- Chris Sedlmayr (catchamonkey)
|
||||
- Seb Koelen
|
||||
- Christoph Mewes (xrstf)
|
||||
- Vitaliy Tverdokhlib (vitaliytv)
|
||||
- Dirk Pahl (dirkaholic)
|
||||
@ -289,15 +294,17 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Iker Ibarguren (ikerib)
|
||||
- Ricardo Oliveira (ricardolotr)
|
||||
- ondrowan
|
||||
- Andrew Moore (finewolf)
|
||||
- Vyacheslav Salakhutdinov (megazoll)
|
||||
- Daniel Wehner
|
||||
- Evan S Kaufman (evanskaufman)
|
||||
- mcben
|
||||
- Maks Slesarenko
|
||||
- mmoreram
|
||||
- Markus Lanthaler (lanthaler)
|
||||
- Vicent Soria Durá (vicentgodella)
|
||||
- Chris Wilkinson (thewilkybarkid)
|
||||
- Ioan Negulescu
|
||||
- Jakub Škvára (jskvara)
|
||||
- Andrew Udvare (audvare)
|
||||
- alexpods
|
||||
- Erik Trapman (eriktrapman)
|
||||
@ -326,11 +333,13 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Pavel Campr (pcampr)
|
||||
- Geoffrey Tran (geoff)
|
||||
- Jan Behrens
|
||||
- Sebastian Krebs
|
||||
- Christopher Davis (chrisguitarguy)
|
||||
- Thomas Lallement (raziel057)
|
||||
- alcaeus
|
||||
- vitaliytv
|
||||
- Markus Bachmann (baachi)
|
||||
- Jérémy DERUSSÉ (jderusse)
|
||||
- Sebastian Blum
|
||||
- aubx
|
||||
- Ricky Su (ricky)
|
||||
- Gildas Quéméner (gquemener)
|
||||
@ -342,6 +351,7 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Chris Boden (cboden)
|
||||
- Pierre du Plessis (pierredup)
|
||||
- Josip Kruslin
|
||||
- Hany el-Kerdany
|
||||
- Wang Jingyu
|
||||
- Åsmund Garfors
|
||||
- Javier López (loalf)
|
||||
@ -368,6 +378,7 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Sascha Grossenbacher
|
||||
- Ben Davies (bendavies)
|
||||
- Simon Schick (simonsimcity)
|
||||
- redstar504
|
||||
- Hossein Bukhamsin
|
||||
- Paweł Wacławczyk (pwc)
|
||||
- Oleg Zinchenko (cystbear)
|
||||
@ -375,10 +386,12 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Johannes Klauss (cloppy)
|
||||
- Evan Villemez
|
||||
- fzerorubigd
|
||||
- Thomas Ploch
|
||||
- Benjamin Grandfond (benjamin)
|
||||
- Tiago Brito (blackmx)
|
||||
- Richard van den Brand (ricbra)
|
||||
- develop
|
||||
- Vincent AUBERT (vincent)
|
||||
- Tomasz Kowalczyk (thunderer)
|
||||
- Mark Sonnabaum
|
||||
- Mathieu Lemoine
|
||||
@ -390,8 +403,8 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- yclian
|
||||
- Pascal Helfenstein
|
||||
- Baldur Rensch (brensch)
|
||||
- Barry vd. Heuvel (barryvdh)
|
||||
- Alex Xandra Albert Sim
|
||||
- Daniel Wehner
|
||||
- Yuen-Chi Lian
|
||||
- Besnik Br
|
||||
- Joshua Nye
|
||||
@ -406,8 +419,8 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Josiah (josiah)
|
||||
- Marek Štípek (maryo)
|
||||
- John Bohn (jbohn)
|
||||
- Jakub Škvára (jskvara)
|
||||
- Andrew Hilobok (hilobok)
|
||||
- Matthieu Auger (matthieuauger)
|
||||
- Christian Soronellas (theunic)
|
||||
- Jérôme Vieilledent (lolautruche)
|
||||
- Degory Valentine
|
||||
@ -418,8 +431,11 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Olivier Maisonneuve (olineuve)
|
||||
- Francis Turmel (fturmel)
|
||||
- cgonzalez
|
||||
- Ben
|
||||
- Jayson Xu (superjavason)
|
||||
- Tobias Nyholm (tobias)
|
||||
- Jaik Dean (jaikdean)
|
||||
- Harm van Tilborg
|
||||
- Jan Prieser
|
||||
- James Michael DuPont
|
||||
- Tom Klingenberg
|
||||
@ -436,6 +452,7 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Maksim Kotlyar (makasim)
|
||||
- Neil Ferreira
|
||||
- Dmitry Parnas (parnas)
|
||||
- Emanuele Iannone
|
||||
- Tony Malzhacker
|
||||
- Cyril Quintin (cyqui)
|
||||
- Gerard van Helden (drm)
|
||||
@ -454,6 +471,7 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- abdul malik ikhsan (samsonasik)
|
||||
- Sarah Khalil (saro0h)
|
||||
- Timothée Barray (tyx)
|
||||
- Benjamin Laugueux (yzalis)
|
||||
- Christian Morgan
|
||||
- Alexander Miehe (engerim)
|
||||
- Titouan Galopin (tgalopin)
|
||||
@ -468,6 +486,7 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Michael Roterman (wtfzdotnet)
|
||||
- Arno Geurts
|
||||
- Adán Lobato (adanlobato)
|
||||
- Matthew Davis (mdavis1982)
|
||||
- Maks
|
||||
- Gábor Tóth
|
||||
- Daniel Cestari
|
||||
@ -486,6 +505,7 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Christian Jul Jensen
|
||||
- The Whole Life to Learn
|
||||
- Liverbool (liverbool)
|
||||
- Sam Malone
|
||||
- Phan Thanh Ha (haphan)
|
||||
- Chris Jones (leek)
|
||||
- Colin O'Dell (colinodell)
|
||||
@ -499,11 +519,13 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- fabios
|
||||
- Sander Coolen (scoolen)
|
||||
- Nicolas Le Goff (nlegoff)
|
||||
- Ariel Ferrandini (aferrandini)
|
||||
- Manuele Menozzi
|
||||
- Anton Babenko (antonbabenko)
|
||||
- Irmantas Šiupšinskas (irmantas)
|
||||
- Danilo Silva
|
||||
- Zachary Tong (polyfractal)
|
||||
- Hryhorii Hrebiniuk
|
||||
- dantleech
|
||||
- Tero Alén (tero)
|
||||
- DerManoMann
|
||||
@ -524,11 +546,14 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Jeremy David (jeremy.david)
|
||||
- Troy McCabe
|
||||
- Ville Mattila
|
||||
- Boris Vujicic (boris.vujicic)
|
||||
- Max Beutel
|
||||
- Catalin Dan
|
||||
- Warnar Boekkooi
|
||||
- Piotr Antosik (antek88)
|
||||
- Artem Lopata
|
||||
- Marcos Quesada (marcos_quesada)
|
||||
- Matthew Vickery (mattvick)
|
||||
- Dan Finnie
|
||||
- Ken Marfilla (marfillaster)
|
||||
- benatespina (benatespina)
|
||||
@ -548,7 +573,6 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Daniel Mecke (daniel_mecke)
|
||||
- Matteo Giachino (matteosister)
|
||||
- Alex Demchenko (pilot)
|
||||
- Vincent AUBERT (vincent)
|
||||
- Benoit Garret
|
||||
- DerManoMann
|
||||
- Asmir Mustafic (goetas)
|
||||
@ -573,6 +597,7 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Luc Vieillescazes (iamluc)
|
||||
- Eduardo García Sanz (coma)
|
||||
- David de Boer (ddeboer)
|
||||
- Gilles Doge (gido)
|
||||
- Brooks Boyd
|
||||
- Roger Webb
|
||||
- Dmitriy Simushev
|
||||
@ -596,7 +621,9 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- heccjj
|
||||
- Alexandre Melard
|
||||
- Sergey Yuferev
|
||||
- Tobias Stöckler
|
||||
- Mario Young
|
||||
- Jakub Kulhan
|
||||
- Mo Di (modi)
|
||||
- Jeroen van den Enden (stoefke)
|
||||
- Quique Porta (quiqueporta)
|
||||
@ -604,6 +631,7 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- ConneXNL
|
||||
- Aharon Perkel
|
||||
- Abdul.Mohsen B. A. A
|
||||
- Benoît Burnichon
|
||||
- Malaney J. Hill
|
||||
- Cédric Girard (enk_)
|
||||
- Oriol Mangas Abellan (oriolman)
|
||||
@ -640,12 +668,14 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Ilya Biryukov
|
||||
- Jason Desrosiers
|
||||
- m.chwedziak
|
||||
- Endre Fejes
|
||||
- Lance McNearney
|
||||
- Giorgio Premi
|
||||
- caponica
|
||||
- Matt Daum (daum)
|
||||
- Alberto Pirovano (geezmo)
|
||||
- Pete Mitchell (peterjmit)
|
||||
- Tom Corrigan (tomcorrigan)
|
||||
- Martin Pärtel
|
||||
- Evgeniy (ewgraf)
|
||||
- Patrick Daley (padrig)
|
||||
@ -653,9 +683,11 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Max Summe
|
||||
- WedgeSama
|
||||
- Felds Liscia
|
||||
- Maxime Veber (nek-)
|
||||
- Tadcka
|
||||
- Beth Binkovitz
|
||||
- Romain Geissler
|
||||
- Benjamin Cremer (bcremer)
|
||||
- Marcus Stöhr (dafish)
|
||||
- Emmanuel Vella (emmanuel.vella)
|
||||
- Carsten Nielsen (phreaknerd)
|
||||
@ -665,8 +697,8 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Adrien Samson (adriensamson)
|
||||
- Samuel Gordalina (gordalina)
|
||||
- Max Romanovsky (maxromanovsky)
|
||||
- Rafał Muszyński (rafmus90)
|
||||
- Timothy Anido (xanido)
|
||||
- Sebastian Krebs
|
||||
- Rick Prent
|
||||
- Martin Eckhardt
|
||||
- Jon Gotlin (jongotlin)
|
||||
@ -689,7 +721,6 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Sebastian Ionescu
|
||||
- Thomas Ploch
|
||||
- Simon Neidhold
|
||||
- Seb Koelen
|
||||
- Kevin Dew
|
||||
- James Cowgill
|
||||
- Jeremy Livingston (jeremylivingston)
|
||||
@ -707,6 +738,7 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Hoffmann András
|
||||
- Olivier
|
||||
- pscheit
|
||||
- moldcraft
|
||||
- Ramon Kleiss (akathos)
|
||||
- Nicolas Badey (nico-b)
|
||||
- Shane Preece (shane)
|
||||
@ -717,7 +749,6 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Gunnar Lium (gunnarlium)
|
||||
- Tiago Garcia (tiagojsag)
|
||||
- Bouke Haarsma
|
||||
- Harm van Tilborg
|
||||
- Martin Eckhardt
|
||||
- Denis Zunke
|
||||
- Jonathan Poston
|
||||
@ -748,12 +779,15 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Michal Gebauer
|
||||
- Gleb Sidora
|
||||
- David Stone
|
||||
- Javier Spagnoletti (phansys)
|
||||
- Pablo Maria Martelletti (pmartelletti)
|
||||
- Yassine Guedidi (yguedidi)
|
||||
- Luis Muñoz
|
||||
- Andreas
|
||||
- Strate
|
||||
- Thomas Chmielowiec
|
||||
- Andrey Ryaguzov
|
||||
- Manatsawin Hanmongkolchai
|
||||
- Gunther Konig
|
||||
- František Bereň
|
||||
- Christoph Nissle (derstoffel)
|
||||
@ -766,11 +800,13 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Grayson Koonce (breerly)
|
||||
- Benjamin Zikarsky (bzikarsky)
|
||||
- Matt Robinson (inanimatt)
|
||||
- Karim Cassam Chenaï (ka)
|
||||
- Nicolas Bastien (nicolas_bastien)
|
||||
- Andy Stanberry
|
||||
- Luiz “Felds” Liscia
|
||||
- Thomas Rothe
|
||||
- alefranz
|
||||
- avi123
|
||||
- alsar
|
||||
- Mike Meier
|
||||
- Warwick
|
||||
@ -798,10 +834,10 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Daan van Renterghem
|
||||
- Bram Van der Sype (brammm)
|
||||
- Julien Moulin (lizjulien)
|
||||
- Matthieu Auger (matthieuauger)
|
||||
- Kevin Decherf
|
||||
- dened
|
||||
- Sam Ward
|
||||
- Walther Lalk
|
||||
- devel
|
||||
- Trevor Suarez
|
||||
- gedrox
|
||||
@ -858,6 +894,7 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Klaas Naaijkens
|
||||
- Rafał
|
||||
- Adria Lopez (adlpz)
|
||||
- Rosio (ben-rosio)
|
||||
- Masao Maeda (brtriver)
|
||||
- Darius Leskauskas (darles)
|
||||
- Dave Hulbert (dave1010)
|
||||
@ -871,7 +908,6 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Ian Jenkins (jenkoian)
|
||||
- Jorge Martin (jorgemartind)
|
||||
- Kevin Herrera (kherge)
|
||||
- Matthew Davis (mdavis1982)
|
||||
- Muriel (metalmumu)
|
||||
- Michaël Perrin (michael.perrin)
|
||||
- Pablo Monterde Perez (plebs)
|
||||
@ -904,6 +940,7 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- goohib
|
||||
- Xavier HAUSHERR
|
||||
- Cas
|
||||
- Maxime Douailin
|
||||
- Myke79
|
||||
- Brian Debuire
|
||||
- Sylvain Lorinet
|
||||
@ -928,6 +965,7 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- cmfcmf
|
||||
- Drew Butler
|
||||
- Steve Müller
|
||||
- Andras Ratz
|
||||
- andreabreu98
|
||||
- Thomas Schulz
|
||||
- Michael Schneider
|
||||
@ -939,12 +977,12 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Ondrej Slinták
|
||||
- vlechemin
|
||||
- Brian Corrigan
|
||||
- Brian Freytag
|
||||
- Skorney
|
||||
- mieszko4
|
||||
- datibbaw
|
||||
- Markus Staab
|
||||
- Pierre-Louis LAUNAY
|
||||
- Thomas Ploch
|
||||
- djama
|
||||
- Eduardo Conceição
|
||||
- Jon Cave
|
||||
@ -960,6 +998,7 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Sergiy Sokolenko
|
||||
- dinitrol
|
||||
- Penny Leach
|
||||
- g123456789l
|
||||
- oscartv
|
||||
- DanSync
|
||||
- Peter Zwosta
|
||||
@ -982,7 +1021,6 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Daniel Basten (axhm3a)
|
||||
- Bill Hance (billhance)
|
||||
- Bernd Matzner (bmatzner)
|
||||
- Chris Sedlmayr (catchamonkey)
|
||||
- Choong Wei Tjeng (choonge)
|
||||
- Kousuke Ebihara (co3k)
|
||||
- Loïc Vernet (coil)
|
||||
@ -991,6 +1029,7 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Damon Jones (damon__jones)
|
||||
- Daniel Londero (dlondero)
|
||||
- Adel ELHAIBA (eadel)
|
||||
- Damián Nohales (eagleoneraptor)
|
||||
- Elliot Anderson (elliot)
|
||||
- Fabien D. (fabd)
|
||||
- Sorin Gitlan (forapathy)
|
||||
@ -1006,11 +1045,14 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Jorge Maiden (jorgemaiden)
|
||||
- Justin Rainbow (jrainbow)
|
||||
- JuntaTom (juntatom)
|
||||
- Johnson Page (jwpage)
|
||||
- Sébastien Armand (khepin)
|
||||
- Krzysztof Menżyk (krymen)
|
||||
- samuel laulhau (lalop)
|
||||
- Laurent Bachelier (laurentb)
|
||||
- Jérôme Parmentier (lctrs)
|
||||
- Matthieu Moquet (mattketmo)
|
||||
- Morgan Auchede (mauchede)
|
||||
- Moritz Borgmann (mborgmann)
|
||||
- Matt Drollette (mdrollette)
|
||||
- Adam Monsen (meonkeys)
|
||||
@ -1053,8 +1095,10 @@ Symfony2 is the result of the work of many people who made the code better
|
||||
- Philipp Scheit
|
||||
- max
|
||||
- Mohamed Karnichi (amiral)
|
||||
- Jeroen De Dauw (jeroendedauw)
|
||||
- Muharrem Demirci (mdemirci)
|
||||
- Evgeny Z (meze)
|
||||
- Michiel Boeckaert (milio)
|
||||
- Nicolas de Marqué (nicola)
|
||||
- Kevin (oxfouzer)
|
||||
- Pierre Geyer (ptheg)
|
||||
|
@ -17,7 +17,7 @@
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"swiftmailer/swiftmailer": ">=4.2.0,<5.1-dev"
|
||||
"swiftmailer/swiftmailer": ">=4.2.0,<6.0-dev"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/http-kernel": ""
|
||||
|
@ -130,6 +130,14 @@ EOF
|
||||
->locateResource(sprintf('@FrameworkBundle/Resources/config/router_%s.php', $env))
|
||||
;
|
||||
|
||||
if (!file_exists($router)) {
|
||||
$output->writeln(sprintf('<error>The given router script "%s" does not exist</error>', $router));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
$router = realpath($router);
|
||||
|
||||
return new ProcessBuilder(array(PHP_BINARY, '-S', $input->getArgument('address'), $router));
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,6 @@
|
||||
<div <?php echo $view['form']->block($form, 'widget_container_attributes') ?>>
|
||||
<?php if (!$form->parent && $errors): ?>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<?php echo $view['form']->errors($form) ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif ?>
|
||||
<?php echo $view['form']->block($form, 'form_rows') ?>
|
||||
<?php echo $view['form']->rest($form) ?>
|
||||
|
@ -1,6 +1,10 @@
|
||||
<table <?php echo $view['form']->block($form, 'widget_container_attributes') ?>>
|
||||
<?php if (!$form->parent): ?>
|
||||
<?php if (!$form->parent && $errors): ?>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<?php echo $view['form']->errors($form) ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif ?>
|
||||
<?php echo $view['form']->block($form, 'form_rows') ?>
|
||||
<?php echo $view['form']->rest($form) ?>
|
||||
|
@ -24,14 +24,6 @@
|
||||
<default key="_controller">web_profiler.controller.profiler:infoAction</default>
|
||||
</route>
|
||||
|
||||
<route id="_profiler_import" pattern="/import">
|
||||
<default key="_controller">web_profiler.controller.profiler:importAction</default>
|
||||
</route>
|
||||
|
||||
<route id="_profiler_export" pattern="/export/{token}.txt">
|
||||
<default key="_controller">web_profiler.controller.profiler:exportAction</default>
|
||||
</route>
|
||||
|
||||
<route id="_profiler_phpinfo" pattern="/phpinfo">
|
||||
<default key="_controller">web_profiler.controller.profiler:phpinfoAction</default>
|
||||
</route>
|
||||
|
@ -521,11 +521,11 @@ class Command
|
||||
|
||||
$placeholders = array(
|
||||
'%command.name%',
|
||||
'%command.full_name%'
|
||||
'%command.full_name%',
|
||||
);
|
||||
$replacements = array(
|
||||
$name,
|
||||
$_SERVER['PHP_SELF'].' '.$name
|
||||
$_SERVER['PHP_SELF'].' '.$name,
|
||||
);
|
||||
|
||||
return str_replace($placeholders, $replacements, $this->getHelp());
|
||||
@ -534,7 +534,7 @@ class Command
|
||||
/**
|
||||
* Sets the aliases for the command.
|
||||
*
|
||||
* @param array $aliases An array of aliases for the command
|
||||
* @param string[] $aliases An array of aliases for the command
|
||||
*
|
||||
* @return Command The current instance
|
||||
*
|
||||
@ -544,6 +544,10 @@ class Command
|
||||
*/
|
||||
public function setAliases($aliases)
|
||||
{
|
||||
if (!is_array($aliases) && !$aliases instanceof \Traversable) {
|
||||
throw new \InvalidArgumentException('$aliases must be an array or an instance of \Traversable');
|
||||
}
|
||||
|
||||
foreach ($aliases as $alias) {
|
||||
$this->validateName($alias);
|
||||
}
|
||||
|
@ -56,6 +56,10 @@ class YamlFileLoader extends FileLoader
|
||||
|
||||
// parameters
|
||||
if (isset($content['parameters'])) {
|
||||
if (!is_array($content['parameters'])) {
|
||||
throw new InvalidArgumentException(sprintf('The "parameters" key should contain an array in %s. Check your YAML syntax.', $file));
|
||||
}
|
||||
|
||||
foreach ($content['parameters'] as $key => $value) {
|
||||
$this->container->setParameter($key, $this->resolveServices($value));
|
||||
}
|
||||
@ -93,7 +97,15 @@ class YamlFileLoader extends FileLoader
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_array($content['imports'])) {
|
||||
throw new InvalidArgumentException(sprintf('The "imports" key should contain an array in %s. Check your YAML syntax.', $file));
|
||||
}
|
||||
|
||||
foreach ($content['imports'] as $import) {
|
||||
if (!is_array($import)) {
|
||||
throw new InvalidArgumentException(sprintf('The values in the "imports" key should be arrays in %s. Check your YAML syntax.', $file));
|
||||
}
|
||||
|
||||
$this->setCurrentDir(dirname($file));
|
||||
$this->import($import['resource'], null, isset($import['ignore_errors']) ? (bool) $import['ignore_errors'] : false, $file);
|
||||
}
|
||||
@ -111,6 +123,10 @@ class YamlFileLoader extends FileLoader
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_array($content['services'])) {
|
||||
throw new InvalidArgumentException(sprintf('The "services" key should contain an array in %s. Check your YAML syntax.', $file));
|
||||
}
|
||||
|
||||
foreach ($content['services'] as $id => $service) {
|
||||
$this->parseDefinition($id, $service, $file);
|
||||
}
|
||||
@ -131,7 +147,13 @@ class YamlFileLoader extends FileLoader
|
||||
$this->container->setAlias($id, substr($service, 1));
|
||||
|
||||
return;
|
||||
} elseif (isset($service['alias'])) {
|
||||
}
|
||||
|
||||
if (!is_array($service)) {
|
||||
throw new InvalidArgumentException(sprintf('A service definition must be an array or a string starting with "@" but %s found for service "%s" in %s. Check your YAML syntax.', gettype($service), $id, $file));
|
||||
}
|
||||
|
||||
if (isset($service['alias'])) {
|
||||
$public = !array_key_exists('public', $service) || (bool) $service['public'];
|
||||
$this->container->setAlias($id, new Alias($service['alias'], $public));
|
||||
|
||||
@ -205,6 +227,10 @@ class YamlFileLoader extends FileLoader
|
||||
}
|
||||
|
||||
if (isset($service['calls'])) {
|
||||
if (!is_array($service['calls'])) {
|
||||
throw new InvalidArgumentException(sprintf('Parameter "calls" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
|
||||
}
|
||||
|
||||
foreach ($service['calls'] as $call) {
|
||||
$args = isset($call[1]) ? $this->resolveServices($call[1]) : array();
|
||||
$definition->addMethodCall($call[0], $args);
|
||||
@ -213,10 +239,14 @@ class YamlFileLoader extends FileLoader
|
||||
|
||||
if (isset($service['tags'])) {
|
||||
if (!is_array($service['tags'])) {
|
||||
throw new InvalidArgumentException(sprintf('Parameter "tags" must be an array for service "%s" in %s.', $id, $file));
|
||||
throw new InvalidArgumentException(sprintf('Parameter "tags" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
|
||||
}
|
||||
|
||||
foreach ($service['tags'] as $tag) {
|
||||
if (!is_array($tag)) {
|
||||
throw new InvalidArgumentException(sprintf('A "tags" entry must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
|
||||
}
|
||||
|
||||
if (!isset($tag['name'])) {
|
||||
throw new InvalidArgumentException(sprintf('A "tags" entry is missing a "name" key for service "%s" in %s.', $id, $file));
|
||||
}
|
||||
@ -226,7 +256,7 @@ class YamlFileLoader extends FileLoader
|
||||
|
||||
foreach ($tag as $attribute => $value) {
|
||||
if (!is_scalar($value) && null !== $value) {
|
||||
throw new InvalidArgumentException(sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s" in %s.', $id, $name, $attribute, $file));
|
||||
throw new InvalidArgumentException(sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s" in %s. Check your YAML syntax.', $id, $name, $attribute, $file));
|
||||
}
|
||||
}
|
||||
|
||||
@ -285,7 +315,7 @@ class YamlFileLoader extends FileLoader
|
||||
}
|
||||
|
||||
if (!is_array($content)) {
|
||||
throw new InvalidArgumentException(sprintf('The service file "%s" is not valid.', $file));
|
||||
throw new InvalidArgumentException(sprintf('The service file "%s" is not valid. It should contain an array. Check your YAML syntax.', $file));
|
||||
}
|
||||
|
||||
foreach (array_keys($content) as $namespace) {
|
||||
@ -311,9 +341,9 @@ class YamlFileLoader extends FileLoader
|
||||
/**
|
||||
* Resolves services.
|
||||
*
|
||||
* @param string $value
|
||||
* @param string|array $value
|
||||
*
|
||||
* @return Reference
|
||||
* @return array|string|Reference
|
||||
*/
|
||||
private function resolveServices($value)
|
||||
{
|
||||
|
@ -158,7 +158,6 @@
|
||||
<xsd:simpleType name="parameter_type">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="collection" />
|
||||
<xsd:enumeration value="service" />
|
||||
<xsd:enumeration value="string" />
|
||||
<xsd:enumeration value="constant" />
|
||||
</xsd:restriction>
|
||||
|
@ -23,7 +23,6 @@
|
||||
<parameter>bar</parameter>
|
||||
</parameter>
|
||||
</parameter>
|
||||
<parameter key="foo_bar" type="service" id="foo_bar" />
|
||||
<parameter key="MixedCase" type="collection"> <!-- Should be lower cased -->
|
||||
<parameter key="MixedCaseKey">value</parameter> <!-- Should stay mixed case -->
|
||||
</parameter>
|
||||
|
@ -0,0 +1,4 @@
|
||||
services:
|
||||
method_call1:
|
||||
class: FooClass
|
||||
calls: foo
|
@ -0,0 +1,2 @@
|
||||
imports:
|
||||
- foo.yml
|
@ -0,0 +1,2 @@
|
||||
imports:
|
||||
foo:bar
|
@ -0,0 +1,2 @@
|
||||
parameters:
|
||||
foo:bar
|
@ -0,0 +1,2 @@
|
||||
services:
|
||||
foo: bar
|
@ -0,0 +1 @@
|
||||
services: foo
|
@ -0,0 +1,6 @@
|
||||
services:
|
||||
foo_service:
|
||||
class: FooClass
|
||||
tags:
|
||||
# tag is not an array
|
||||
- foo
|
@ -110,7 +110,6 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
'a string',
|
||||
array('foo', 'bar'),
|
||||
),
|
||||
'foo_bar' => new Reference('foo_bar'),
|
||||
'mixedcase' => array('MixedCaseKey' => 'value'),
|
||||
'constant' => PHP_EOL,
|
||||
);
|
||||
@ -147,7 +146,6 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
'a string',
|
||||
array('foo', 'bar'),
|
||||
),
|
||||
'foo_bar' => new Reference('foo_bar'),
|
||||
'mixedcase' => array('MixedCaseKey' => 'value'),
|
||||
'constant' => PHP_EOL,
|
||||
'bar' => '%foo%',
|
||||
|
@ -13,7 +13,6 @@ namespace Symfony\Component\DependencyInjection\Tests\Loader;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\Config\Loader\Loader;
|
||||
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
|
||||
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
|
||||
@ -70,6 +69,29 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideInvalidFiles
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function testLoadInvalidFile($file)
|
||||
{
|
||||
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
|
||||
|
||||
$loader->load($file.'.yml');
|
||||
}
|
||||
|
||||
public function provideInvalidFiles()
|
||||
{
|
||||
return array(
|
||||
array('bad_parameters'),
|
||||
array('bad_imports'),
|
||||
array('bad_import'),
|
||||
array('bad_services'),
|
||||
array('bad_service'),
|
||||
array('bad_calls'),
|
||||
);
|
||||
}
|
||||
|
||||
public function testLoadParameters()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
@ -173,7 +195,7 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
|
||||
}
|
||||
|
||||
public function testNonArrayTagThrowsException()
|
||||
public function testNonArrayTagsThrowsException()
|
||||
{
|
||||
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
|
||||
try {
|
||||
@ -185,6 +207,16 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage A "tags" entry must be an array for service
|
||||
*/
|
||||
public function testNonArrayTagThrowsException()
|
||||
{
|
||||
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
|
||||
$loader->load('badtag4.yml');
|
||||
}
|
||||
|
||||
public function testTagWithoutNameThrowsException()
|
||||
{
|
||||
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));
|
||||
|
@ -425,7 +425,7 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface
|
||||
*
|
||||
* This method should not be invoked.
|
||||
*
|
||||
* @param array $data
|
||||
* @param mixed $data
|
||||
*
|
||||
* @throws BadMethodCallException
|
||||
*/
|
||||
|
@ -70,9 +70,17 @@ class ViolationPath implements \IteratorAggregate, PropertyPathInterface
|
||||
break;
|
||||
}
|
||||
|
||||
// All the following index items (regardless if .children is
|
||||
// explicitly used) are children and grand-children
|
||||
for (; $i < $l && $path->isIndex($i); ++$i) {
|
||||
$this->elements[] = $elements[$i];
|
||||
$this->isIndex[] = true;
|
||||
$this->mapsForm[] = true;
|
||||
}
|
||||
|
||||
// Rewind the pointer as the last element above didn't match
|
||||
// (even if the pointer was moved forward)
|
||||
--$i;
|
||||
} elseif ('data' === $elements[$i] && $path->isProperty($i)) {
|
||||
// Skip element "data"
|
||||
++$i;
|
||||
|
@ -242,7 +242,7 @@ class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormB
|
||||
throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
|
||||
}
|
||||
|
||||
return new \ArrayIterator($this->children);
|
||||
return new \ArrayIterator($this->all());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -212,7 +212,7 @@ interface FormConfigBuilderInterface extends FormConfigInterface
|
||||
/**
|
||||
* Sets the initial data of the form.
|
||||
*
|
||||
* @param array $data The data of the form in application format.
|
||||
* @param mixed $data The data of the form in application format.
|
||||
*
|
||||
* @return self The configuration object.
|
||||
*/
|
||||
|
@ -761,14 +761,14 @@ class ViolationMapperTest extends \PHPUnit_Framework_TestCase
|
||||
array(self::LEVEL_2, 'address', '[address]', 'street', '[office][street]', 'data[address][office][street].prop'),
|
||||
|
||||
// Edge cases which must not occur
|
||||
array(self::LEVEL_1, 'address', 'address', 'street', 'street', 'children[address][street]'),
|
||||
array(self::LEVEL_1, 'address', 'address', 'street', 'street', 'children[address][street].prop'),
|
||||
array(self::LEVEL_1, 'address', 'address', 'street', '[street]', 'children[address][street]'),
|
||||
array(self::LEVEL_1, 'address', 'address', 'street', '[street]', 'children[address][street].prop'),
|
||||
array(self::LEVEL_1, 'address', '[address]', 'street', 'street', 'children[address][street]'),
|
||||
array(self::LEVEL_1, 'address', '[address]', 'street', 'street', 'children[address][street].prop'),
|
||||
array(self::LEVEL_1, 'address', '[address]', 'street', '[street]', 'children[address][street]'),
|
||||
array(self::LEVEL_1, 'address', '[address]', 'street', '[street]', 'children[address][street].prop'),
|
||||
array(self::LEVEL_2, 'address', 'address', 'street', 'street', 'children[address][street]'),
|
||||
array(self::LEVEL_2, 'address', 'address', 'street', 'street', 'children[address][street].prop'),
|
||||
array(self::LEVEL_2, 'address', 'address', 'street', '[street]', 'children[address][street]'),
|
||||
array(self::LEVEL_2, 'address', 'address', 'street', '[street]', 'children[address][street].prop'),
|
||||
array(self::LEVEL_2, 'address', '[address]', 'street', 'street', 'children[address][street]'),
|
||||
array(self::LEVEL_2, 'address', '[address]', 'street', 'street', 'children[address][street].prop'),
|
||||
array(self::LEVEL_2, 'address', '[address]', 'street', '[street]', 'children[address][street]'),
|
||||
array(self::LEVEL_2, 'address', '[address]', 'street', '[street]', 'children[address][street].prop'),
|
||||
|
||||
array(self::LEVEL_0, 'address', 'person.address', 'street', 'street', 'children[person].children[address].children[street]'),
|
||||
array(self::LEVEL_0, 'address', 'person.address', 'street', 'street', 'children[person].children[address].data.street'),
|
||||
|
@ -30,7 +30,8 @@ class ViolationPathTest extends \PHPUnit_Framework_TestCase
|
||||
)),
|
||||
array('children[address][street]', array(
|
||||
array('address', true, true),
|
||||
), 'children[address]'),
|
||||
array('street', true, true),
|
||||
), 'children[address].children[street]'),
|
||||
array('children[address].data', array(
|
||||
array('address', true, true),
|
||||
), 'children[address]'),
|
||||
|
@ -1044,9 +1044,9 @@ class Request
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested URI.
|
||||
* Returns the requested URI (path and query string).
|
||||
*
|
||||
* @return string The raw URI (i.e. not urldecoded)
|
||||
* @return string The raw URI (i.e. not URI decoded)
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
@ -1073,9 +1073,9 @@ class Request
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a normalized URI for the Request.
|
||||
* Generates a normalized URI (URL) for the Request.
|
||||
*
|
||||
* @return string A normalized URI for the Request
|
||||
* @return string A normalized URI (URL) for the Request
|
||||
*
|
||||
* @see getQueryString()
|
||||
*
|
||||
|
@ -281,9 +281,9 @@ class Esi implements SurrogateInterface
|
||||
throw new \RuntimeException('Unable to process an ESI tag without a "src" attribute.');
|
||||
}
|
||||
|
||||
return sprintf('<?php echo $this->surrogate->handle($this, \'%s\', \'%s\', %s) ?>'."\n",
|
||||
$options['src'],
|
||||
isset($options['alt']) ? $options['alt'] : null,
|
||||
return sprintf('<?php echo $this->surrogate->handle($this, %s, %s, %s) ?>'."\n",
|
||||
var_export($options['src'], true),
|
||||
var_export(isset($options['alt']) ? $options['alt'] : '', true),
|
||||
isset($options['onerror']) && 'continue' == $options['onerror'] ? 'true' : 'false'
|
||||
);
|
||||
}
|
||||
|
@ -103,6 +103,11 @@ class EsiTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('foo <?php echo $this->surrogate->handle($this, \'...\', \'alt\', true) ?>'."\n", $response->getContent());
|
||||
$this->assertEquals('ESI', $response->headers->get('x-body-eval'));
|
||||
|
||||
$response = new Response('foo <esi:comment text="some comment" /><esi:include src="foo\'" alt="bar\'" onerror="continue" />');
|
||||
$esi->process($request, $response);
|
||||
|
||||
$this->assertEquals("foo <?php echo \$this->esi->handle(\$this, 'foo\\'', 'bar\\'', true) ?>"."\n", $response->getContent());
|
||||
|
||||
$response = new Response('foo <esi:include src="..." />');
|
||||
$esi->process($request, $response);
|
||||
|
||||
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Exception;
|
||||
|
||||
/**
|
||||
* Thrown when an invalid entry of a resource bundle was requested.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class MissingResourceException extends RuntimeException
|
||||
{
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Exception;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class ResourceBundleNotFoundException extends RuntimeException
|
||||
{
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Exception;
|
||||
|
||||
/**
|
||||
* Thrown when a method argument had an unexpected type.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class UnexpectedTypeException extends InvalidArgumentException
|
||||
{
|
||||
public function __construct($value, $expectedType)
|
||||
{
|
||||
parent::__construct(sprintf('Expected argument of type "%s", "%s" given', $expectedType, is_object($value) ? get_class($value) : gettype($value)));
|
||||
}
|
||||
}
|
48
src/Symfony/Component/Intl/Locale.php
Normal file
48
src/Symfony/Component/Intl/Locale.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl;
|
||||
|
||||
/**
|
||||
* Provides access to locale-related data.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class Locale extends \Locale
|
||||
{
|
||||
/**
|
||||
* Returns the fallback locale for a given locale, if any
|
||||
*
|
||||
* @param string $locale The ICU locale code to find the fallback for.
|
||||
*
|
||||
* @return string|null The ICU locale code of the fallback locale, or null
|
||||
* if no fallback exists
|
||||
*/
|
||||
public static function getFallback($locale)
|
||||
{
|
||||
if (false === $pos = strrpos($locale, '_')) {
|
||||
if ('root' === $locale) {
|
||||
return;
|
||||
}
|
||||
|
||||
return 'root';
|
||||
}
|
||||
|
||||
return substr($locale, 0, $pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* This class must not be instantiated.
|
||||
*/
|
||||
private function __construct() {}
|
||||
}
|
@ -17,6 +17,8 @@ use Symfony\Component\Intl\ResourceBundle\Reader\StructuredBundleReaderInterface
|
||||
* Base class for {@link ResourceBundleInterface} implementations.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
abstract class AbstractBundle implements ResourceBundleInterface
|
||||
{
|
||||
|
@ -17,6 +17,8 @@ use Symfony\Component\Intl\Exception\RuntimeException;
|
||||
* Compiles .txt resource bundles to binary .res files.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class BundleCompiler implements BundleCompilerInterface
|
||||
{
|
||||
|
@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\ResourceBundle\Compiler;
|
||||
* Compiles a resource bundle.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
interface BundleCompilerInterface
|
||||
{
|
||||
|
@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\ResourceBundle;
|
||||
* Default implementation of {@link CurrencyBundleInterface}.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class CurrencyBundle extends AbstractBundle implements CurrencyBundleInterface
|
||||
{
|
||||
|
@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\ResourceBundle;
|
||||
* Default implementation of {@link LanguageBundleInterface}.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class LanguageBundle extends AbstractBundle implements LanguageBundleInterface
|
||||
{
|
||||
|
@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\ResourceBundle;
|
||||
* Default implementation of {@link LocaleBundleInterface}.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class LocaleBundle extends AbstractBundle implements LocaleBundleInterface
|
||||
{
|
||||
|
@ -1,42 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\ResourceBundle\Reader;
|
||||
|
||||
/**
|
||||
* Base class for {@link BundleReaderInterface} implementations.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
abstract class AbstractBundleReader implements BundleReaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLocales($path)
|
||||
{
|
||||
$extension = '.' . $this->getFileExtension();
|
||||
$locales = glob($path . '/*' . $extension);
|
||||
|
||||
// Remove file extension and sort
|
||||
array_walk($locales, function (&$locale) use ($extension) { $locale = basename($locale, $extension); });
|
||||
sort($locales);
|
||||
|
||||
return $locales;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the extension of locale files in this bundle.
|
||||
*
|
||||
* @return string The file extension (without leading dot).
|
||||
*/
|
||||
abstract protected function getFileExtension();
|
||||
}
|
@ -11,15 +11,17 @@
|
||||
|
||||
namespace Symfony\Component\Intl\ResourceBundle\Reader;
|
||||
|
||||
use Symfony\Component\Intl\Exception\RuntimeException;
|
||||
use Symfony\Component\Intl\Exception\ResourceBundleNotFoundException;
|
||||
use Symfony\Component\Intl\ResourceBundle\Util\ArrayAccessibleResourceBundle;
|
||||
|
||||
/**
|
||||
* Reads binary .res resource bundles.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class BinaryBundleReader extends AbstractBundleReader implements BundleReaderInterface
|
||||
class BinaryBundleReader implements BundleReaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@ -29,28 +31,39 @@ class BinaryBundleReader extends AbstractBundleReader implements BundleReaderInt
|
||||
// Point for future extension: Modify this class so that it works also
|
||||
// if the \ResourceBundle class is not available.
|
||||
try {
|
||||
$bundle = new \ResourceBundle($locale, $path);
|
||||
// Never enable fallback. We want to know if a bundle cannot be found
|
||||
$bundle = new \ResourceBundle($locale, $path, false);
|
||||
} catch (\Exception $e) {
|
||||
// HHVM compatibility: constructor throws on invalid resource
|
||||
$bundle = null;
|
||||
}
|
||||
|
||||
// The bundle is NULL if the path does not look like a resource bundle
|
||||
// (i.e. contain a bunch of *.res files)
|
||||
if (null === $bundle) {
|
||||
throw new RuntimeException(sprintf(
|
||||
'Could not load the resource bundle "%s/%s.res".',
|
||||
throw new ResourceBundleNotFoundException(sprintf(
|
||||
'The resource bundle "%s/%s.res" could not be found.',
|
||||
$path,
|
||||
$locale
|
||||
));
|
||||
}
|
||||
|
||||
// Other possible errors are U_USING_FALLBACK_WARNING and U_ZERO_ERROR,
|
||||
// which are OK for us.
|
||||
return new ArrayAccessibleResourceBundle($bundle);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getFileExtension()
|
||||
public function getLocales($path)
|
||||
{
|
||||
return 'res';
|
||||
$locales = glob($path.'/*.res');
|
||||
|
||||
// Remove file extension and sort
|
||||
array_walk($locales, function (&$locale) { $locale = basename($locale, '.res'); });
|
||||
sort($locales);
|
||||
|
||||
return $locales;
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ use Symfony\Component\Intl\ResourceBundle\Util\RingBuffer;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class BufferedBundleReader implements BundleReaderInterface
|
||||
{
|
||||
|
@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\ResourceBundle\Reader;
|
||||
* Reads resource bundle files.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
interface BundleReaderInterface
|
||||
{
|
||||
|
@ -11,29 +11,27 @@
|
||||
|
||||
namespace Symfony\Component\Intl\ResourceBundle\Reader;
|
||||
|
||||
use Symfony\Component\Intl\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Intl\Exception\ResourceBundleNotFoundException;
|
||||
use Symfony\Component\Intl\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Reads .php resource bundles.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class PhpBundleReader extends AbstractBundleReader implements BundleReaderInterface
|
||||
class PhpBundleReader implements BundleReaderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function read($path, $locale)
|
||||
{
|
||||
if ('en' !== $locale) {
|
||||
throw new InvalidArgumentException('Only the locale "en" is supported.');
|
||||
}
|
||||
|
||||
$fileName = $path.'/'.$locale.'.php';
|
||||
|
||||
if (!file_exists($fileName)) {
|
||||
throw new RuntimeException(sprintf(
|
||||
throw new ResourceBundleNotFoundException(sprintf(
|
||||
'The resource bundle "%s/%s.php" does not exist.',
|
||||
$path,
|
||||
$locale
|
||||
@ -54,8 +52,14 @@ class PhpBundleReader extends AbstractBundleReader implements BundleReaderInterf
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getFileExtension()
|
||||
public function getLocales($path)
|
||||
{
|
||||
return 'php';
|
||||
$locales = glob($path.'/*.php');
|
||||
|
||||
// Remove file extension and sort
|
||||
array_walk($locales, function (&$locale) { $locale = basename($locale, '.php'); });
|
||||
sort($locales);
|
||||
|
||||
return $locales;
|
||||
}
|
||||
}
|
||||
|
@ -11,14 +11,20 @@
|
||||
|
||||
namespace Symfony\Component\Intl\ResourceBundle\Reader;
|
||||
|
||||
use Symfony\Component\Intl\Exception\MissingResourceException;
|
||||
use Symfony\Component\Intl\Exception\OutOfBoundsException;
|
||||
use Symfony\Component\Intl\Exception\ResourceBundleNotFoundException;
|
||||
use Symfony\Component\Intl\Locale;
|
||||
use Symfony\Component\Intl\ResourceBundle\Util\RecursiveArrayAccess;
|
||||
|
||||
/**
|
||||
* A structured reader wrapping an existing resource bundle reader.
|
||||
* Default implementation of {@link StructuredBundleReaderInterface}.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @see StructuredResourceBundleBundleReaderInterface
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class StructuredBundleReader implements StructuredBundleReaderInterface
|
||||
{
|
||||
@ -27,6 +33,13 @@ class StructuredBundleReader implements StructuredBundleReaderInterface
|
||||
*/
|
||||
private $reader;
|
||||
|
||||
/**
|
||||
* A mapping of locale aliases to locales
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $localeAliases = array();
|
||||
|
||||
/**
|
||||
* Creates an entry reader based on the given resource bundle reader.
|
||||
*
|
||||
@ -37,6 +50,21 @@ class StructuredBundleReader implements StructuredBundleReaderInterface
|
||||
$this->reader = $reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a mapping of locale aliases to locales.
|
||||
*
|
||||
* This mapping is used when reading entries and merging them with their
|
||||
* fallback locales. If an entry is read for a locale alias (e.g. "mo")
|
||||
* that points to a locale with a fallback locale ("ro_MD"), the reader
|
||||
* can continue at the correct fallback locale ("ro").
|
||||
*
|
||||
* @param array $localeAliases A mapping of locale aliases to locales
|
||||
*/
|
||||
public function setLocaleAliases($localeAliases)
|
||||
{
|
||||
$this->localeAliases = $localeAliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -48,66 +76,117 @@ class StructuredBundleReader implements StructuredBundleReaderInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLocales($path)
|
||||
public function readEntry($path, $locale, array $indices, $fallback = true)
|
||||
{
|
||||
return $this->reader->getLocales($path);
|
||||
$entry = null;
|
||||
$isMultiValued = false;
|
||||
$readSucceeded = false;
|
||||
$exception = null;
|
||||
$currentLocale = $locale;
|
||||
$testedLocales = array();
|
||||
|
||||
while (null !== $currentLocale) {
|
||||
// Resolve any aliases to their target locales
|
||||
if (isset($this->localeAliases[$currentLocale])) {
|
||||
$currentLocale = $this->localeAliases[$currentLocale];
|
||||
}
|
||||
|
||||
try {
|
||||
$data = $this->reader->read($path, $currentLocale);
|
||||
$currentEntry = RecursiveArrayAccess::get($data, $indices);
|
||||
$readSucceeded = true;
|
||||
|
||||
$isCurrentTraversable = $currentEntry instanceof \Traversable;
|
||||
$isCurrentMultiValued = $isCurrentTraversable || is_array($currentEntry);
|
||||
|
||||
// Return immediately if fallback is disabled or we are dealing
|
||||
// with a scalar non-null entry
|
||||
if (!$fallback || (!$isCurrentMultiValued && null !== $currentEntry)) {
|
||||
return $currentEntry;
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Fallback is enabled, entry is either multi-valued or NULL
|
||||
// =========================================================
|
||||
|
||||
// If entry is multi-valued, convert to array
|
||||
if ($isCurrentTraversable) {
|
||||
$currentEntry = iterator_to_array($currentEntry);
|
||||
}
|
||||
|
||||
// If previously read entry was multi-valued too, merge them
|
||||
if ($isCurrentMultiValued && $isMultiValued) {
|
||||
$currentEntry = array_merge($currentEntry, $entry);
|
||||
}
|
||||
|
||||
// Keep the previous entry if the current entry is NULL
|
||||
if (null !== $currentEntry) {
|
||||
$entry = $currentEntry;
|
||||
}
|
||||
|
||||
// If this or the previous entry was multi-valued, we are dealing
|
||||
// with a merged, multi-valued entry now
|
||||
$isMultiValued = $isMultiValued || $isCurrentMultiValued;
|
||||
} catch (ResourceBundleNotFoundException $e) {
|
||||
// Continue if there is a fallback locale for the current
|
||||
// locale
|
||||
$exception = $e;
|
||||
} catch (OutOfBoundsException $e) {
|
||||
// Remember exception and rethrow if we cannot find anything in
|
||||
// the fallback locales either
|
||||
$exception = $e;
|
||||
}
|
||||
|
||||
// Remember which locales we tried
|
||||
$testedLocales[] = $currentLocale.'.res';
|
||||
|
||||
// Check whether fallback is allowed
|
||||
if (!$fallback) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Then determine fallback locale
|
||||
$currentLocale = Locale::getFallback($currentLocale);
|
||||
}
|
||||
|
||||
// Multi-valued entry was merged
|
||||
if ($isMultiValued) {
|
||||
return $entry;
|
||||
}
|
||||
|
||||
// Entry is still NULL, but no read error occurred
|
||||
if ($readSucceeded) {
|
||||
return $entry;
|
||||
}
|
||||
|
||||
// Entry is still NULL, read error occurred. Throw an exception
|
||||
// containing the detailed path and locale
|
||||
$errorMessage = sprintf(
|
||||
'Couldn\'t read the indices [%s] from "%s/%s.res".',
|
||||
implode('][', $indices),
|
||||
$path,
|
||||
$locale
|
||||
);
|
||||
|
||||
// Append fallback locales, if any
|
||||
if (count($testedLocales) > 1) {
|
||||
// Remove original locale
|
||||
array_shift($testedLocales);
|
||||
|
||||
$errorMessage .= sprintf(
|
||||
' The indices also couldn\'t be found in the fallback locale(s) "%s".',
|
||||
implode('", "', $testedLocales)
|
||||
);
|
||||
}
|
||||
|
||||
throw new MissingResourceException($errorMessage, 0, $exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function readEntry($path, $locale, array $indices, $fallback = true)
|
||||
public function getLocales($path)
|
||||
{
|
||||
$data = $this->reader->read($path, $locale);
|
||||
|
||||
$entry = RecursiveArrayAccess::get($data, $indices);
|
||||
$multivalued = is_array($entry) || $entry instanceof \Traversable;
|
||||
|
||||
if (!($fallback && (null === $entry || $multivalued))) {
|
||||
return $entry;
|
||||
}
|
||||
|
||||
if (null !== ($fallbackLocale = $this->getFallbackLocale($locale))) {
|
||||
$parentEntry = $this->readEntry($path, $fallbackLocale, $indices, true);
|
||||
|
||||
if ($entry || $parentEntry) {
|
||||
$multivalued = $multivalued || is_array($parentEntry) || $parentEntry instanceof \Traversable;
|
||||
|
||||
if ($multivalued) {
|
||||
if ($entry instanceof \Traversable) {
|
||||
$entry = iterator_to_array($entry);
|
||||
}
|
||||
|
||||
if ($parentEntry instanceof \Traversable) {
|
||||
$parentEntry = iterator_to_array($parentEntry);
|
||||
}
|
||||
|
||||
$entry = array_merge(
|
||||
$parentEntry ?: array(),
|
||||
$entry ?: array()
|
||||
);
|
||||
} else {
|
||||
$entry = null === $entry ? $parentEntry : $entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fallback locale for a given locale, if any
|
||||
*
|
||||
* @param string $locale The locale to find the fallback for.
|
||||
*
|
||||
* @return string|null The fallback locale, or null if no parent exists
|
||||
*/
|
||||
private function getFallbackLocale($locale)
|
||||
{
|
||||
if (false === $pos = strrpos($locale, '_')) {
|
||||
return;
|
||||
}
|
||||
|
||||
return substr($locale, 0, $pos);
|
||||
return $this->reader->getLocales($path);
|
||||
}
|
||||
}
|
||||
|
@ -11,10 +11,14 @@
|
||||
|
||||
namespace Symfony\Component\Intl\ResourceBundle\Reader;
|
||||
|
||||
use Symfony\Component\Intl\Exception\MissingResourceException;
|
||||
|
||||
/**
|
||||
* Reads individual entries of a resource file.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
interface StructuredBundleReaderInterface extends BundleReaderInterface
|
||||
{
|
||||
@ -43,8 +47,9 @@ interface StructuredBundleReaderInterface extends BundleReaderInterface
|
||||
* in the requested locale.
|
||||
*
|
||||
* @return mixed Returns an array or {@link \ArrayAccess} instance for
|
||||
* complex data, a scalar value for simple data and NULL
|
||||
* if the given path could not be accessed.
|
||||
* complex data and a scalar value for simple data.
|
||||
*
|
||||
* @throws MissingResourceException If the indices cannot be accessed
|
||||
*/
|
||||
public function readEntry($path, $locale, array $indices, $fallback = true);
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\ResourceBundle;
|
||||
* Default implementation of {@link RegionBundleInterface}.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class RegionBundle extends AbstractBundle implements RegionBundleInterface
|
||||
{
|
||||
|
@ -19,6 +19,8 @@ use Symfony\Component\Intl\ResourceBundle\Writer\PhpBundleWriter;
|
||||
* Compiles a number of resource bundles based on predefined compilation rules.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class BundleTransformer
|
||||
{
|
||||
|
@ -18,6 +18,8 @@ use Symfony\Component\Intl\ResourceBundle\Compiler\BundleCompilerInterface;
|
||||
* Default implementation of {@link CompilationContextInterface}.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class CompilationContext implements CompilationContextInterface
|
||||
{
|
||||
|
@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\ResourceBundle\Transformer;
|
||||
* Stores contextual information for resource bundle compilation.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
interface CompilationContextInterface
|
||||
{
|
||||
|
@ -21,6 +21,8 @@ use Symfony\Component\Intl\Util\IcuVersion;
|
||||
* The rule for compiling the currency bundle.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class CurrencyBundleTransformationRule implements TransformationRuleInterface
|
||||
{
|
||||
|
@ -20,6 +20,8 @@ use Symfony\Component\Intl\Util\IcuVersion;
|
||||
* The rule for compiling the language bundle.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class LanguageBundleTransformationRule implements TransformationRuleInterface
|
||||
{
|
||||
|
@ -21,6 +21,8 @@ use Symfony\Component\Intl\ResourceBundle\Writer\TextBundleWriter;
|
||||
* The rule for compiling the locale bundle.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class LocaleBundleTransformationRule implements TransformationRuleInterface
|
||||
{
|
||||
|
@ -20,6 +20,8 @@ use Symfony\Component\Intl\Util\IcuVersion;
|
||||
* The rule for compiling the region bundle.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class RegionBundleTransformationRule implements TransformationRuleInterface
|
||||
{
|
||||
|
@ -18,6 +18,8 @@ use Symfony\Component\Intl\ResourceBundle\Transformer\StubbingContextInterface;
|
||||
* Contains instruction for compiling a resource bundle.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
interface TransformationRuleInterface
|
||||
{
|
||||
|
@ -15,6 +15,8 @@ use Symfony\Component\Filesystem\Filesystem;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class StubbingContext implements StubbingContextInterface
|
||||
{
|
||||
|
@ -13,6 +13,8 @@ namespace Symfony\Component\Intl\ResourceBundle\Transformer;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
interface StubbingContextInterface
|
||||
{
|
||||
|
@ -20,6 +20,8 @@ use Symfony\Component\Intl\Exception\BadMethodCallException;
|
||||
* This class can be removed once that bug is fixed.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class ArrayAccessibleResourceBundle implements \ArrayAccess, \IteratorAggregate, \Countable
|
||||
{
|
||||
@ -30,16 +32,16 @@ class ArrayAccessibleResourceBundle implements \ArrayAccess, \IteratorAggregate,
|
||||
$this->bundleImpl = $bundleImpl;
|
||||
}
|
||||
|
||||
public function get($offset, $fallback = null)
|
||||
public function get($offset)
|
||||
{
|
||||
$value = $this->bundleImpl->get($offset, $fallback);
|
||||
$value = $this->bundleImpl->get($offset);
|
||||
|
||||
return $value instanceof \ResourceBundle ? new static($value) : $value;
|
||||
}
|
||||
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return null !== $this->bundleImpl[$offset];
|
||||
return null !== $this->bundleImpl->get($offset);
|
||||
}
|
||||
|
||||
public function offsetGet($offset)
|
||||
|
@ -11,19 +11,35 @@
|
||||
|
||||
namespace Symfony\Component\Intl\ResourceBundle\Util;
|
||||
|
||||
use Symfony\Component\Intl\Exception\OutOfBoundsException;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class RecursiveArrayAccess
|
||||
{
|
||||
public static function get($array, array $indices)
|
||||
{
|
||||
foreach ($indices as $index) {
|
||||
if (!$array instanceof \ArrayAccess && !is_array($array)) {
|
||||
return;
|
||||
// Use array_key_exists() for arrays, isset() otherwise
|
||||
if (is_array($array)) {
|
||||
if (array_key_exists($index, $array)) {
|
||||
$array = $array[$index];
|
||||
continue;
|
||||
}
|
||||
} elseif ($array instanceof \ArrayAccess) {
|
||||
if (isset($array[$index])) {
|
||||
$array = $array[$index];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$array = $array[$index];
|
||||
throw new OutOfBoundsException(sprintf(
|
||||
'The index %s does not exist.',
|
||||
$index
|
||||
));
|
||||
}
|
||||
|
||||
return $array;
|
||||
|
@ -21,6 +21,8 @@ use Symfony\Component\Intl\Exception\OutOfBoundsException;
|
||||
* then the second and so on.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class RingBuffer implements \ArrayAccess
|
||||
{
|
||||
|
@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\ResourceBundle\Writer;
|
||||
* Writes resource bundle files.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
interface BundleWriterInterface
|
||||
{
|
||||
|
@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\ResourceBundle\Writer;
|
||||
* Writes .php resource bundles.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class PhpBundleWriter implements BundleWriterInterface
|
||||
{
|
||||
|
@ -11,26 +11,31 @@
|
||||
|
||||
namespace Symfony\Component\Intl\ResourceBundle\Writer;
|
||||
|
||||
use Symfony\Component\Intl\Exception\UnexpectedTypeException;
|
||||
|
||||
/**
|
||||
* Writes .txt resource bundles.
|
||||
*
|
||||
* The resulting files can be converted to binary .res files using the
|
||||
* {@link \Symfony\Component\Intl\ResourceBundle\Transformer\BundleCompiler}.
|
||||
* The resulting files can be converted to binary .res files using a
|
||||
* {@link \Symfony\Component\Intl\ResourceBundle\Compiler\BundleCompilerInterface}
|
||||
* implementation.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @see http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class TextBundleWriter implements BundleWriterInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function write($path, $locale, $data)
|
||||
public function write($path, $locale, $data, $fallback = true)
|
||||
{
|
||||
$file = fopen($path.'/'.$locale.'.txt', 'w');
|
||||
|
||||
$this->writeResourceBundle($file, $locale, $data);
|
||||
$this->writeResourceBundle($file, $locale, $data, $fallback);
|
||||
|
||||
fclose($file);
|
||||
}
|
||||
@ -41,14 +46,16 @@ class TextBundleWriter implements BundleWriterInterface
|
||||
* @param resource $file The file handle to write to.
|
||||
* @param string $bundleName The name of the bundle.
|
||||
* @param mixed $value The value of the node.
|
||||
* @param bool $fallback Whether the resource bundle should be merged
|
||||
* with the fallback locale.
|
||||
*
|
||||
* @see http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt
|
||||
*/
|
||||
private function writeResourceBundle($file, $bundleName, $value)
|
||||
private function writeResourceBundle($file, $bundleName, $value, $fallback)
|
||||
{
|
||||
fwrite($file, $bundleName);
|
||||
|
||||
$this->writeTable($file, $value, 0);
|
||||
$this->writeTable($file, $value, 0, $fallback);
|
||||
|
||||
fwrite($file, "\n");
|
||||
}
|
||||
@ -72,16 +79,25 @@ class TextBundleWriter implements BundleWriterInterface
|
||||
return;
|
||||
}
|
||||
|
||||
if ($value instanceof \Traversable) {
|
||||
$value = iterator_to_array($value);
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
if (count($value) === count(array_filter($value, 'is_int'))) {
|
||||
$intValues = count($value) === count(array_filter($value, 'is_int'));
|
||||
|
||||
$keys = array_keys($value);
|
||||
|
||||
// check that the keys are 0-indexed and ascending
|
||||
$intKeys = $keys === range(0, count($keys) - 1);
|
||||
|
||||
if ($intValues && $intKeys) {
|
||||
$this->writeIntVector($file, $value, $indentation);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$keys = array_keys($value);
|
||||
|
||||
if (count($keys) === count(array_filter($keys, 'is_int'))) {
|
||||
if ($intKeys) {
|
||||
$this->writeArray($file, $value, $indentation);
|
||||
|
||||
return;
|
||||
@ -181,15 +197,34 @@ class TextBundleWriter implements BundleWriterInterface
|
||||
* Writes a "table" node.
|
||||
*
|
||||
* @param resource $file The file handle to write to.
|
||||
* @param array $value The value of the node.
|
||||
* @param array|\Traversable $value The value of the node.
|
||||
* @param int $indentation The number of levels to indent.
|
||||
* @param bool $fallback Whether the table should be merged
|
||||
* with the fallback locale.
|
||||
*
|
||||
* @throws UnexpectedTypeException When $value is not an array and not a
|
||||
* \Traversable instance.
|
||||
*/
|
||||
private function writeTable($file, array $value, $indentation)
|
||||
private function writeTable($file, $value, $indentation, $fallback = true)
|
||||
{
|
||||
if (!is_array($value) && !$value instanceof \Traversable) {
|
||||
throw new UnexpectedTypeException($value, 'array or \Traversable');
|
||||
}
|
||||
|
||||
if (!$fallback) {
|
||||
fwrite($file, ":table(nofallback)");
|
||||
}
|
||||
|
||||
fwrite($file, "{\n");
|
||||
|
||||
foreach ($value as $key => $entry) {
|
||||
fwrite($file, str_repeat(' ', $indentation + 1));
|
||||
|
||||
// escape colons, otherwise they are interpreted as resource types
|
||||
if (false !== strpos($key, ':') || false !== strpos($key, ' ')) {
|
||||
$key = '"'.$key.'"';
|
||||
}
|
||||
|
||||
fwrite($file, $key);
|
||||
|
||||
$this->writeResource($file, $entry, $indentation + 1);
|
||||
|
@ -67,3 +67,27 @@ function get_icu_version_from_genrb($genrb)
|
||||
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
set_exception_handler(function (\Exception $exception) {
|
||||
echo "\n";
|
||||
|
||||
$cause = $exception;
|
||||
$root = true;
|
||||
|
||||
while (null !== $cause) {
|
||||
if (!$root) {
|
||||
echo "Caused by\n";
|
||||
}
|
||||
|
||||
echo get_class($cause).": ".$cause->getMessage()."\n";
|
||||
echo "\n";
|
||||
echo $cause->getFile().":".$cause->getLine()."\n";
|
||||
foreach ($cause->getTrace() as $trace) {
|
||||
echo $trace['file'].":".$trace['line']."\n";
|
||||
}
|
||||
echo "\n";
|
||||
|
||||
$cause = $cause->getPrevious();
|
||||
$root = false;
|
||||
}
|
||||
});
|
||||
|
@ -8,3 +8,5 @@
|
||||
49 = http://source.icu-project.org/repos/icu/icu/tags/release-49-1-2/source
|
||||
50 = http://source.icu-project.org/repos/icu/icu/tags/release-50-1-2/source
|
||||
51 = http://source.icu-project.org/repos/icu/icu/tags/release-51-2/source
|
||||
52 = http://source.icu-project.org/repos/icu/icu/tags/release-52-1/source
|
||||
53 = http://source.icu-project.org/repos/icu/icu/tags/release-53-1/source
|
||||
|
@ -1,64 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Tests\ResourceBundle\Reader;
|
||||
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class AbstractBundleReaderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
private $directory;
|
||||
|
||||
/**
|
||||
* @var Filesystem
|
||||
*/
|
||||
private $filesystem;
|
||||
|
||||
/**
|
||||
* @var \PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
private $reader;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->directory = sys_get_temp_dir() . '/AbstractBundleReaderTest/' . rand(1000, 9999);
|
||||
$this->filesystem = new Filesystem();
|
||||
$this->reader = $this->getMockForAbstractClass('Symfony\Component\Intl\ResourceBundle\Reader\AbstractBundleReader');
|
||||
|
||||
$this->filesystem->mkdir($this->directory);
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
$this->filesystem->remove($this->directory);
|
||||
}
|
||||
|
||||
public function testGetLocales()
|
||||
{
|
||||
$this->filesystem->touch($this->directory . '/en.foo');
|
||||
$this->filesystem->touch($this->directory . '/de.foo');
|
||||
$this->filesystem->touch($this->directory . '/fr.foo');
|
||||
$this->filesystem->touch($this->directory . '/bo.txt');
|
||||
$this->filesystem->touch($this->directory . '/gu.bin');
|
||||
$this->filesystem->touch($this->directory . '/s.lol');
|
||||
|
||||
$this->reader->expects($this->any())
|
||||
->method('getFileExtension')
|
||||
->will($this->returnValue('foo'));
|
||||
|
||||
$sortedLocales = array('de', 'en', 'fr');
|
||||
|
||||
$this->assertSame($sortedLocales, $this->reader->getLocales($this->directory));
|
||||
}
|
||||
}
|
@ -33,19 +33,61 @@ class BinaryBundleReaderTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testReadReturnsArrayAccess()
|
||||
{
|
||||
$data = $this->reader->read(__DIR__ . '/Fixtures', 'en');
|
||||
$data = $this->reader->read(__DIR__.'/Fixtures/res', 'ro');
|
||||
|
||||
$this->assertInstanceOf('\ArrayAccess', $data);
|
||||
$this->assertSame('Bar', $data['Foo']);
|
||||
$this->assertFalse(isset($data['ExistsNot']));
|
||||
}
|
||||
|
||||
public function testReadFollowsAlias()
|
||||
{
|
||||
// "alias" = "ro"
|
||||
$data = $this->reader->read(__DIR__.'/Fixtures/res', 'alias');
|
||||
|
||||
$this->assertInstanceOf('\ArrayAccess', $data);
|
||||
$this->assertSame('Bar', $data['Foo']);
|
||||
$this->assertFalse(isset($data['ExistsNot']));
|
||||
}
|
||||
|
||||
public function testReadDoesNotFollowFallback()
|
||||
{
|
||||
// "ro_MD" -> "ro"
|
||||
$data = $this->reader->read(__DIR__.'/Fixtures/res', 'ro_MD');
|
||||
|
||||
$this->assertInstanceOf('\ArrayAccess', $data);
|
||||
$this->assertSame('Bam', $data['Baz']);
|
||||
$this->assertFalse(isset($data['Foo']));
|
||||
$this->assertNull($data['Foo']);
|
||||
$this->assertFalse(isset($data['ExistsNot']));
|
||||
}
|
||||
|
||||
public function testReadDoesNotFollowFallbackAlias()
|
||||
{
|
||||
// "mo" = "ro_MD" -> "ro"
|
||||
$data = $this->reader->read(__DIR__.'/Fixtures/res', 'mo');
|
||||
|
||||
$this->assertInstanceOf('\ArrayAccess', $data);
|
||||
$this->assertSame('Bam', $data['Baz'], 'data from the aliased locale can be accessed');
|
||||
$this->assertFalse(isset($data['Foo']));
|
||||
$this->assertNull($data['Foo']);
|
||||
$this->assertFalse(isset($data['ExistsNot']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Intl\Exception\RuntimeException
|
||||
* @expectedException \Symfony\Component\Intl\Exception\ResourceBundleNotFoundException
|
||||
*/
|
||||
public function testReadFailsIfNonExistingLocale()
|
||||
{
|
||||
$this->reader->read(__DIR__ . '/Fixtures', 'foo');
|
||||
$this->reader->read(__DIR__.'/Fixtures/res', 'foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Intl\Exception\ResourceBundleNotFoundException
|
||||
*/
|
||||
public function testReadFailsIfNonExistingFallbackLocale()
|
||||
{
|
||||
$this->reader->read(__DIR__.'/Fixtures/res', 'ro_AT');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,6 +95,6 @@ class BinaryBundleReaderTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testReadFailsIfNonExistingDirectory()
|
||||
{
|
||||
$this->reader->read(__DIR__ . '/foo', 'en');
|
||||
$this->reader->read(__DIR__.'/foo', 'ro');
|
||||
}
|
||||
}
|
||||
|
17
src/Symfony/Component/Intl/Tests/ResourceBundle/Reader/Fixtures/build.sh
Executable file
17
src/Symfony/Component/Intl/Tests/ResourceBundle/Reader/Fixtures/build.sh
Executable file
@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ -z "$ICU_BUILD_DIR" ]; then
|
||||
echo "Please set the ICU_BUILD_DIR environment variable"
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ ! -d "$ICU_BUILD_DIR" ]; then
|
||||
echo "The directory $ICU_BUILD_DIR pointed at by ICU_BUILD_DIR does not exist"
|
||||
exit
|
||||
fi
|
||||
|
||||
DIR=`dirname $0`
|
||||
|
||||
rm $DIR/res/*.res
|
||||
|
||||
LD_LIBRARY_PATH=$ICU_BUILD_DIR/lib $ICU_BUILD_DIR/bin/genrb -d $DIR/res $DIR/txt/*.txt
|
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
return array(
|
||||
'Foo' => 'Bar',
|
||||
);
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,3 @@
|
||||
alias{
|
||||
"%%ALIAS"{"ro"}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
mo{
|
||||
"%%ALIAS"{"ro_MD"}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
ro{
|
||||
Foo{"Bar"}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
ro_MD{
|
||||
Baz{"Bam"}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
root{
|
||||
/**
|
||||
* so genrb doesn't issue warnings
|
||||
*/
|
||||
___{""}
|
||||
}
|
@ -30,7 +30,7 @@ class PhpBundleReaderTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testReadReturnsArray()
|
||||
{
|
||||
$data = $this->reader->read(__DIR__ . '/Fixtures', 'en');
|
||||
$data = $this->reader->read(__DIR__.'/Fixtures/php', 'en');
|
||||
|
||||
$this->assertTrue(is_array($data));
|
||||
$this->assertSame('Bar', $data['Foo']);
|
||||
@ -38,11 +38,11 @@ class PhpBundleReaderTest extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Intl\Exception\InvalidArgumentException
|
||||
* @expectedException \Symfony\Component\Intl\Exception\ResourceBundleNotFoundException
|
||||
*/
|
||||
public function testReadFailsIfLocaleOtherThanEn()
|
||||
public function testReadFailsIfNonExistingLocale()
|
||||
{
|
||||
$this->reader->read(__DIR__ . '/Fixtures', 'foo');
|
||||
$this->reader->read(__DIR__.'/Fixtures/php', 'foo');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\Intl\Tests\ResourceBundle\Reader;
|
||||
|
||||
use Symfony\Component\Intl\Exception\ResourceBundleNotFoundException;
|
||||
use Symfony\Component\Intl\ResourceBundle\Reader\StructuredBundleReader;
|
||||
|
||||
/**
|
||||
@ -30,73 +31,146 @@ class StructuredBundleReaderTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
private $readerImpl;
|
||||
|
||||
private static $data = array(
|
||||
'Entries' => array(
|
||||
'Foo' => 'Bar',
|
||||
'Bar' => 'Baz',
|
||||
),
|
||||
'Foo' => 'Bar',
|
||||
'Version' => '2.0',
|
||||
);
|
||||
|
||||
private static $fallbackData = array(
|
||||
'Entries' => array(
|
||||
'Foo' => 'Foo',
|
||||
'Bam' => 'Lah',
|
||||
),
|
||||
'Baz' => 'Foo',
|
||||
'Version' => '1.0',
|
||||
);
|
||||
|
||||
private static $mergedData = array(
|
||||
// no recursive merging -> too complicated
|
||||
'Entries' => array(
|
||||
'Foo' => 'Bar',
|
||||
'Bar' => 'Baz',
|
||||
),
|
||||
'Baz' => 'Foo',
|
||||
'Version' => '2.0',
|
||||
'Foo' => 'Bar',
|
||||
);
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->readerImpl = $this->getMock('Symfony\Component\Intl\ResourceBundle\Reader\StructuredBundleReaderInterface');
|
||||
$this->reader = new StructuredBundleReader($this->readerImpl);
|
||||
}
|
||||
|
||||
public function testGetLocales()
|
||||
public function testForwardCallToRead()
|
||||
{
|
||||
$locales = array('en', 'de', 'fr');
|
||||
|
||||
$this->readerImpl->expects($this->once())
|
||||
->method('getLocales')
|
||||
->with(self::RES_DIR)
|
||||
->will($this->returnValue($locales));
|
||||
|
||||
$this->assertSame($locales, $this->reader->getLocales(self::RES_DIR));
|
||||
}
|
||||
|
||||
public function testRead()
|
||||
{
|
||||
$data = array('foo', 'bar');
|
||||
|
||||
$this->readerImpl->expects($this->once())
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en')
|
||||
->will($this->returnValue($data));
|
||||
->with(self::RES_DIR, 'root')
|
||||
->will($this->returnValue(self::$data));
|
||||
|
||||
$this->assertSame($data, $this->reader->read(self::RES_DIR, 'en'));
|
||||
$this->assertSame(self::$data, $this->reader->read(self::RES_DIR, 'root'));
|
||||
}
|
||||
|
||||
public function testReadEntryNoParams()
|
||||
public function testReadEntireDataFileIfNoIndicesGiven()
|
||||
{
|
||||
$data = array('foo', 'bar');
|
||||
|
||||
$this->readerImpl->expects($this->once())
|
||||
$this->readerImpl->expects($this->at(0))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en')
|
||||
->will($this->returnValue($data));
|
||||
->will($this->returnValue(self::$data));
|
||||
|
||||
$this->assertSame($data, $this->reader->readEntry(self::RES_DIR, 'en', array()));
|
||||
$this->readerImpl->expects($this->at(1))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'root')
|
||||
->will($this->returnValue(self::$fallbackData));
|
||||
|
||||
$this->assertSame(self::$mergedData, $this->reader->readEntry(self::RES_DIR, 'en', array()));
|
||||
}
|
||||
|
||||
public function testReadEntryWithParam()
|
||||
public function testReadExistingEntry()
|
||||
{
|
||||
$data = array('Foo' => array('Bar' => 'Baz'));
|
||||
|
||||
$this->readerImpl->expects($this->once())
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en')
|
||||
->will($this->returnValue($data));
|
||||
->with(self::RES_DIR, 'root')
|
||||
->will($this->returnValue(self::$data));
|
||||
|
||||
$this->assertSame('Baz', $this->reader->readEntry(self::RES_DIR, 'en', array('Foo', 'Bar')));
|
||||
$this->assertSame('Bar', $this->reader->readEntry(self::RES_DIR, 'root', array('Entries', 'Foo')));
|
||||
}
|
||||
|
||||
public function testReadEntryWithUnresolvablePath()
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Intl\Exception\MissingResourceException
|
||||
*/
|
||||
public function testReadNonExistingEntry()
|
||||
{
|
||||
$data = array('Foo' => 'Baz');
|
||||
|
||||
$this->readerImpl->expects($this->once())
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en')
|
||||
->will($this->returnValue($data));
|
||||
->with(self::RES_DIR, 'root')
|
||||
->will($this->returnValue(self::$data));
|
||||
|
||||
$this->assertNull($this->reader->readEntry(self::RES_DIR, 'en', array('Foo', 'Bar')));
|
||||
$this->reader->readEntry(self::RES_DIR, 'root', array('Entries', 'NonExisting'));
|
||||
}
|
||||
|
||||
public function readMergedEntryProvider()
|
||||
public function testFallbackIfEntryDoesNotExist()
|
||||
{
|
||||
$this->readerImpl->expects($this->at(0))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en_GB')
|
||||
->will($this->returnValue(self::$data));
|
||||
|
||||
$this->readerImpl->expects($this->at(1))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en')
|
||||
->will($this->returnValue(self::$fallbackData));
|
||||
|
||||
$this->assertSame('Lah', $this->reader->readEntry(self::RES_DIR, 'en_GB', array('Entries', 'Bam')));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Intl\Exception\MissingResourceException
|
||||
*/
|
||||
public function testDontFallbackIfEntryDoesNotExistAndFallbackDisabled()
|
||||
{
|
||||
$this->readerImpl->expects($this->once())
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en_GB')
|
||||
->will($this->returnValue(self::$data));
|
||||
|
||||
$this->reader->readEntry(self::RES_DIR, 'en_GB', array('Entries', 'Bam'), false);
|
||||
}
|
||||
|
||||
public function testFallbackIfLocaleDoesNotExist()
|
||||
{
|
||||
$this->readerImpl->expects($this->at(0))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en_GB')
|
||||
->will($this->throwException(new ResourceBundleNotFoundException()));
|
||||
|
||||
$this->readerImpl->expects($this->at(1))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en')
|
||||
->will($this->returnValue(self::$fallbackData));
|
||||
|
||||
$this->assertSame('Lah', $this->reader->readEntry(self::RES_DIR, 'en_GB', array('Entries', 'Bam')));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Intl\Exception\MissingResourceException
|
||||
*/
|
||||
public function testDontFallbackIfLocaleDoesNotExistAndFallbackDisabled()
|
||||
{
|
||||
$this->readerImpl->expects($this->once())
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en_GB')
|
||||
->will($this->throwException(new ResourceBundleNotFoundException()));
|
||||
|
||||
$this->reader->readEntry(self::RES_DIR, 'en_GB', array('Entries', 'Bam'), false);
|
||||
}
|
||||
|
||||
public function provideMergeableValues()
|
||||
{
|
||||
return array(
|
||||
array('foo', null, 'foo'),
|
||||
@ -110,114 +184,182 @@ class StructuredBundleReaderTest extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider readMergedEntryProvider
|
||||
* @dataProvider provideMergeableValues
|
||||
*/
|
||||
public function testReadMergedEntryNoParams($childData, $parentData, $result)
|
||||
public function testMergeDataWithFallbackData($childData, $parentData, $result)
|
||||
{
|
||||
if (null === $childData || is_array($childData)) {
|
||||
$this->readerImpl->expects($this->at(0))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en')
|
||||
->will($this->returnValue($childData));
|
||||
|
||||
$this->readerImpl->expects($this->at(1))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'root')
|
||||
->will($this->returnValue($parentData));
|
||||
} else {
|
||||
$this->readerImpl->expects($this->once())
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en')
|
||||
->will($this->returnValue($childData));
|
||||
}
|
||||
|
||||
$this->assertSame($result, $this->reader->readEntry(self::RES_DIR, 'en', array(), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideMergeableValues
|
||||
*/
|
||||
public function testDontMergeDataIfFallbackDisabled($childData, $parentData, $result)
|
||||
{
|
||||
$this->readerImpl->expects($this->once())
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en_GB')
|
||||
->will($this->returnValue($childData));
|
||||
|
||||
if (null === $childData || is_array($childData)) {
|
||||
$this->readerImpl->expects($this->at(1))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en')
|
||||
->will($this->returnValue($parentData));
|
||||
}
|
||||
|
||||
$this->assertSame($result, $this->reader->readEntry(self::RES_DIR, 'en_GB', array(), true));
|
||||
$this->assertSame($childData, $this->reader->readEntry(self::RES_DIR, 'en_GB', array(), false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider readMergedEntryProvider
|
||||
* @dataProvider provideMergeableValues
|
||||
*/
|
||||
public function testReadMergedEntryWithParams($childData, $parentData, $result)
|
||||
public function testMergeExistingEntryWithExistingFallbackEntry($childData, $parentData, $result)
|
||||
{
|
||||
if (null === $childData || is_array($childData)) {
|
||||
$this->readerImpl->expects($this->at(0))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en')
|
||||
->will($this->returnValue(array('Foo' => array('Bar' => $childData))));
|
||||
|
||||
$this->readerImpl->expects($this->at(1))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'root')
|
||||
->will($this->returnValue(array('Foo' => array('Bar' => $parentData))));
|
||||
} else {
|
||||
$this->readerImpl->expects($this->once())
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en')
|
||||
->will($this->returnValue(array('Foo' => array('Bar' => $childData))));
|
||||
}
|
||||
|
||||
$this->assertSame($result, $this->reader->readEntry(self::RES_DIR, 'en', array('Foo', 'Bar'), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideMergeableValues
|
||||
*/
|
||||
public function testMergeNonExistingEntryWithExistingFallbackEntry($childData, $parentData, $result)
|
||||
{
|
||||
$this->readerImpl->expects($this->at(0))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en_GB')
|
||||
->will($this->returnValue(array('Foo' => 'Baz')));
|
||||
|
||||
$this->readerImpl->expects($this->at(1))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en')
|
||||
->will($this->returnValue(array('Foo' => array('Bar' => $parentData))));
|
||||
|
||||
$this->assertSame($parentData, $this->reader->readEntry(self::RES_DIR, 'en_GB', array('Foo', 'Bar'), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideMergeableValues
|
||||
*/
|
||||
public function testMergeExistingEntryWithNonExistingFallbackEntry($childData, $parentData, $result)
|
||||
{
|
||||
if (null === $childData || is_array($childData)) {
|
||||
$this->readerImpl->expects($this->at(0))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en_GB')
|
||||
->will($this->returnValue(array('Foo' => array('Bar' => $childData))));
|
||||
|
||||
if (null === $childData || is_array($childData)) {
|
||||
$this->readerImpl->expects($this->at(1))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en')
|
||||
->will($this->returnValue(array('Foo' => array('Bar' => $parentData))));
|
||||
}
|
||||
|
||||
$this->assertSame($result, $this->reader->readEntry(self::RES_DIR, 'en_GB', array('Foo', 'Bar'), true));
|
||||
}
|
||||
|
||||
public function testReadMergedEntryWithUnresolvablePath()
|
||||
{
|
||||
$this->readerImpl->expects($this->at(0))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en_GB')
|
||||
->will($this->returnValue(array('Foo' => 'Baz')));
|
||||
|
||||
$this->readerImpl->expects($this->at(1))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en')
|
||||
->will($this->returnValue(array('Foo' => 'Bar')));
|
||||
|
||||
$this->assertNull($this->reader->readEntry(self::RES_DIR, 'en_GB', array('Foo', 'Bar'), true));
|
||||
}
|
||||
|
||||
public function testReadMergedEntryWithUnresolvablePathInParent()
|
||||
{
|
||||
$this->readerImpl->expects($this->at(0))
|
||||
} else {
|
||||
$this->readerImpl->expects($this->once())
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en_GB')
|
||||
->will($this->returnValue(array('Foo' => array('Bar' => array('three')))));
|
||||
|
||||
$this->readerImpl->expects($this->at(1))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en')
|
||||
->will($this->returnValue(array('Foo' => 'Bar')));
|
||||
|
||||
$result = array('three');
|
||||
|
||||
$this->assertSame($result, $this->reader->readEntry(self::RES_DIR, 'en_GB', array('Foo', 'Bar'), true));
|
||||
->will($this->returnValue(array('Foo' => array('Bar' => $childData))));
|
||||
}
|
||||
|
||||
public function testReadMergedEntryWithUnresolvablePathInChild()
|
||||
{
|
||||
$this->readerImpl->expects($this->at(0))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en_GB')
|
||||
->will($this->returnValue(array('Foo' => 'Baz')));
|
||||
|
||||
$this->readerImpl->expects($this->at(1))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en')
|
||||
->will($this->returnValue(array('Foo' => array('Bar' => array('one', 'two')))));
|
||||
|
||||
$result = array('one', 'two');
|
||||
|
||||
$this->assertSame($result, $this->reader->readEntry(self::RES_DIR, 'en_GB', array('Foo', 'Bar'), true));
|
||||
$this->assertSame($childData, $this->reader->readEntry(self::RES_DIR, 'en_GB', array('Foo', 'Bar'), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider readMergedEntryProvider
|
||||
* @expectedException \Symfony\Component\Intl\Exception\MissingResourceException
|
||||
*/
|
||||
public function testReadMergedEntryWithTraversables($childData, $parentData, $result)
|
||||
public function testFailIfEntryFoundNeitherInParentNorChild()
|
||||
{
|
||||
$this->readerImpl->expects($this->at(0))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en_GB')
|
||||
->will($this->returnValue(array('Foo' => 'Baz')));
|
||||
|
||||
$this->readerImpl->expects($this->at(1))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en')
|
||||
->will($this->returnValue(array('Foo' => 'Bar')));
|
||||
|
||||
$this->reader->readEntry(self::RES_DIR, 'en_GB', array('Foo', 'Bar'), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideMergeableValues
|
||||
*/
|
||||
public function testMergeTraversables($childData, $parentData, $result)
|
||||
{
|
||||
$parentData = is_array($parentData) ? new \ArrayObject($parentData) : $parentData;
|
||||
$childData = is_array($childData) ? new \ArrayObject($childData) : $childData;
|
||||
|
||||
if (null === $childData || $childData instanceof \ArrayObject) {
|
||||
$this->readerImpl->expects($this->at(0))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en_GB')
|
||||
->will($this->returnValue(array('Foo' => array('Bar' => $childData))));
|
||||
|
||||
if (null === $childData || $childData instanceof \ArrayObject) {
|
||||
$this->readerImpl->expects($this->at(1))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en')
|
||||
->will($this->returnValue(array('Foo' => array('Bar' => $parentData))));
|
||||
} else {
|
||||
$this->readerImpl->expects($this->once())
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'en_GB')
|
||||
->will($this->returnValue(array('Foo' => array('Bar' => $childData))));
|
||||
}
|
||||
|
||||
$this->assertSame($result, $this->reader->readEntry(self::RES_DIR, 'en_GB', array('Foo', 'Bar'), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideMergeableValues
|
||||
*/
|
||||
public function testFollowLocaleAliases($childData, $parentData, $result)
|
||||
{
|
||||
$this->reader->setLocaleAliases(array('mo' => 'ro_MD'));
|
||||
|
||||
if (null === $childData || is_array($childData)) {
|
||||
$this->readerImpl->expects($this->at(0))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'ro_MD')
|
||||
->will($this->returnValue(array('Foo' => array('Bar' => $childData))));
|
||||
|
||||
// Read fallback locale of aliased locale ("ro_MD" -> "ro")
|
||||
$this->readerImpl->expects($this->at(1))
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'ro')
|
||||
->will($this->returnValue(array('Foo' => array('Bar' => $parentData))));
|
||||
} else {
|
||||
$this->readerImpl->expects($this->once())
|
||||
->method('read')
|
||||
->with(self::RES_DIR, 'ro_MD')
|
||||
->will($this->returnValue(array('Foo' => array('Bar' => $childData))));
|
||||
}
|
||||
|
||||
$this->assertSame($result, $this->reader->readEntry(self::RES_DIR, 'mo', array('Foo', 'Bar'), true));
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,22 @@ en{
|
||||
2,
|
||||
3,
|
||||
}
|
||||
NotAnIntVector{
|
||||
0:int{0}
|
||||
2:int{1}
|
||||
1:int{2}
|
||||
3:int{3}
|
||||
}
|
||||
IntVectorWithStringKeys{
|
||||
a:int{0}
|
||||
b:int{1}
|
||||
c:int{2}
|
||||
}
|
||||
TableWithIntKeys{
|
||||
0:int{0}
|
||||
1:int{1}
|
||||
3:int{3}
|
||||
}
|
||||
FalseBoolean{"false"}
|
||||
TrueBoolean{"true"}
|
||||
Null{""}
|
||||
|
@ -0,0 +1,3 @@
|
||||
en_nofallback:table(nofallback){
|
||||
Entry{"Value"}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
escaped{
|
||||
"EntryWith:Colon"{"Value"}
|
||||
"Entry With Spaces"{"Value"}
|
||||
}
|
@ -54,6 +54,9 @@ class TextBundleWriterTest extends \PHPUnit_Framework_TestCase
|
||||
'Array' => array('foo', 'bar', array('Key' => 'value')),
|
||||
'Integer' => 5,
|
||||
'IntVector' => array(0, 1, 2, 3),
|
||||
'NotAnIntVector' => array(0 => 0, 2 => 1, 1 => 2, 3 => 3),
|
||||
'IntVectorWithStringKeys' => array('a' => 0, 'b' => 1, 'c' => 2),
|
||||
'TableWithIntKeys' => array(0 => 0, 1 => 1, 3 => 3),
|
||||
'FalseBoolean' => false,
|
||||
'TrueBoolean' => true,
|
||||
'Null' => null,
|
||||
@ -64,4 +67,49 @@ class TextBundleWriterTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->assertFileEquals(__DIR__.'/Fixtures/en.txt', $this->directory.'/en.txt');
|
||||
}
|
||||
|
||||
public function testWriteTraversable()
|
||||
{
|
||||
$this->writer->write($this->directory, 'en', new \ArrayIterator(array(
|
||||
'Entry1' => new \ArrayIterator(array(
|
||||
'Array' => array('foo', 'bar', array('Key' => 'value')),
|
||||
'Integer' => 5,
|
||||
'IntVector' => array(0, 1, 2, 3),
|
||||
'NotAnIntVector' => array(0 => 0, 2 => 1, 1 => 2, 3 => 3),
|
||||
'IntVectorWithStringKeys' => array('a' => 0, 'b' => 1, 'c' => 2),
|
||||
'TableWithIntKeys' => array(0 => 0, 1 => 1, 3 => 3),
|
||||
'FalseBoolean' => false,
|
||||
'TrueBoolean' => true,
|
||||
'Null' => null,
|
||||
'Float' => 1.23,
|
||||
)),
|
||||
'Entry2' => 'String',
|
||||
)));
|
||||
|
||||
$this->assertFileEquals(__DIR__.'/Fixtures/en.txt', $this->directory.'/en.txt');
|
||||
}
|
||||
|
||||
public function testWriteNoFallback()
|
||||
{
|
||||
$data = array(
|
||||
'Entry' => 'Value'
|
||||
);
|
||||
|
||||
$this->writer->write($this->directory, 'en_nofallback', $data, $fallback = false);
|
||||
|
||||
$this->assertFileEquals(__DIR__.'/Fixtures/en_nofallback.txt', $this->directory.'/en_nofallback.txt');
|
||||
}
|
||||
|
||||
public function testEscapeKeysIfNecessary()
|
||||
{
|
||||
$this->writer->write($this->directory, 'escaped', array(
|
||||
// Keys with colons must be escaped, otherwise the part after the
|
||||
// colon is interpreted as resource type
|
||||
'EntryWith:Colon' => 'Value',
|
||||
// Keys with spaces must be escaped
|
||||
'Entry With Spaces' => 'Value',
|
||||
));
|
||||
|
||||
$this->assertFileEquals(__DIR__.'/Fixtures/escaped.txt', $this->directory.'/escaped.txt');
|
||||
}
|
||||
}
|
||||
|
@ -29,13 +29,15 @@ class PhpExecutableFinder
|
||||
/**
|
||||
* Finds The PHP executable.
|
||||
*
|
||||
* @param bool $includeArgs Whether or not include command arguments
|
||||
*
|
||||
* @return string|false The PHP executable path or false if it cannot be found
|
||||
*/
|
||||
public function find()
|
||||
public function find($includeArgs = true)
|
||||
{
|
||||
// HHVM support
|
||||
if (defined('HHVM_VERSION')) {
|
||||
return (false !== ($hhvm = getenv('PHP_BINARY')) ? $hhvm : PHP_BINARY).' --php';
|
||||
return (false !== ($hhvm = getenv('PHP_BINARY')) ? $hhvm : PHP_BINARY).($includeArgs ? ' '.implode(' ', $this->findArguments()) : '');
|
||||
}
|
||||
|
||||
// PHP_BINARY return the current sapi executable
|
||||
@ -64,4 +66,21 @@ class PhpExecutableFinder
|
||||
|
||||
return $this->executableFinder->find('php', false, $dirs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the PHP executable arguments.
|
||||
*
|
||||
* @return array The PHP executable arguments
|
||||
*/
|
||||
public function findArguments()
|
||||
{
|
||||
$arguments = array();
|
||||
|
||||
// HHVM support
|
||||
if (defined('HHVM_VERSION')) {
|
||||
$arguments[] = '--php';
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
}
|
||||
|
@ -414,6 +414,7 @@ class Process
|
||||
* @return Process
|
||||
*
|
||||
* @throws RuntimeException In case the process is already running
|
||||
* @throws LogicException if an idle timeout is set
|
||||
*/
|
||||
public function disableOutput()
|
||||
{
|
||||
@ -910,6 +911,7 @@ class Process
|
||||
*
|
||||
* @return self The current Process instance.
|
||||
*
|
||||
* @throws LogicException if the output is disabled
|
||||
* @throws InvalidArgumentException if the timeout is negative
|
||||
*/
|
||||
public function setIdleTimeout($timeout)
|
||||
@ -1342,6 +1344,8 @@ class Process
|
||||
* @param int|float|null $timeout
|
||||
*
|
||||
* @return float|null
|
||||
*
|
||||
* @throws InvalidArgumentException if the given timeout is a negative number
|
||||
*/
|
||||
private function validateTimeout($timeout)
|
||||
{
|
||||
|
@ -34,10 +34,43 @@ class PhpExecutableFinderTest extends \PHPUnit_Framework_TestCase
|
||||
//not executable PHP_PATH
|
||||
putenv('PHP_PATH=/not/executable/php');
|
||||
$this->assertFalse($f->find(), '::find() returns false for not executable PHP');
|
||||
$this->assertFalse($f->find(false), '::find() returns false for not executable PHP');
|
||||
|
||||
//executable PHP_PATH
|
||||
putenv('PHP_PATH='.$current);
|
||||
$this->assertEquals($f->find(), $current, '::find() returns the executable PHP');
|
||||
$this->assertEquals($f->find(false), $current, '::find() returns the executable PHP');
|
||||
}
|
||||
|
||||
/**
|
||||
* tests find() with the env var PHP_PATH
|
||||
*/
|
||||
public function testFindWithHHVM()
|
||||
{
|
||||
if (!defined('HHVM_VERSION')) {
|
||||
$this->markTestSkipped('Should be executed in HHVM context.');
|
||||
}
|
||||
|
||||
$f = new PhpExecutableFinder();
|
||||
|
||||
$current = $f->find();
|
||||
|
||||
$this->assertEquals($f->find(), $current.' --php', '::find() returns the executable PHP');
|
||||
$this->assertEquals($f->find(false), $current, '::find() returns the executable PHP');
|
||||
}
|
||||
|
||||
/**
|
||||
* tests find() with the env var PHP_PATH
|
||||
*/
|
||||
public function testFindArguments()
|
||||
{
|
||||
$f = new PhpExecutableFinder();
|
||||
|
||||
if (defined('HHVM_VERSION')) {
|
||||
$this->assertEquals($f->findArguments(), array('--php'), '::findArguments() returns HHVM arguments');
|
||||
} else {
|
||||
$this->assertEquals($f->findArguments(), array(), '::findArguments() returns no arguments');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Symfony\Component\Security\Acl\Domain;
|
||||
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
use Doctrine\Common\Cache\CacheProvider;
|
||||
use Symfony\Component\Security\Acl\Model\AclCacheInterface;
|
||||
use Symfony\Component\Security\Acl\Model\AclInterface;
|
||||
use Symfony\Component\Security\Acl\Model\ObjectIdentityInterface;
|
||||
@ -55,7 +56,9 @@ class DoctrineAclCache implements AclCacheInterface
|
||||
*/
|
||||
public function clearCache()
|
||||
{
|
||||
$this->cache->deleteByPrefix($this->prefix);
|
||||
if ($this->cache instanceof CacheProvider) {
|
||||
$this->cache->deleteAll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,6 +73,48 @@ class AccessDecisionManagerTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame($expected, $manager->decide($token, array('ROLE_FOO')));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getStrategiesWith2RolesTests
|
||||
*/
|
||||
public function testStrategiesWith2Roles($token, $strategy, $voter, $expected)
|
||||
{
|
||||
$manager = new AccessDecisionManager(array($voter), $strategy);
|
||||
|
||||
$this->assertSame($expected, $manager->decide($token, array('ROLE_FOO', 'ROLE_BAR')));
|
||||
}
|
||||
|
||||
public function getStrategiesWith2RolesTests()
|
||||
{
|
||||
$token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
|
||||
|
||||
return array(
|
||||
array($token, 'affirmative', $this->getVoter(VoterInterface::ACCESS_DENIED), false),
|
||||
array($token, 'affirmative', $this->getVoter(VoterInterface::ACCESS_GRANTED), true),
|
||||
|
||||
array($token, 'consensus', $this->getVoter(VoterInterface::ACCESS_DENIED), false),
|
||||
array($token, 'consensus', $this->getVoter(VoterInterface::ACCESS_GRANTED), true),
|
||||
|
||||
array($token, 'unanimous', $this->getVoterFor2Roles($token, VoterInterface::ACCESS_DENIED, VoterInterface::ACCESS_DENIED), false),
|
||||
array($token, 'unanimous', $this->getVoterFor2Roles($token, VoterInterface::ACCESS_DENIED, VoterInterface::ACCESS_GRANTED), false),
|
||||
array($token, 'unanimous', $this->getVoterFor2Roles($token, VoterInterface::ACCESS_GRANTED, VoterInterface::ACCESS_DENIED), false),
|
||||
array($token, 'unanimous', $this->getVoterFor2Roles($token, VoterInterface::ACCESS_GRANTED, VoterInterface::ACCESS_GRANTED), true),
|
||||
);
|
||||
}
|
||||
|
||||
protected function getVoterFor2Roles($token, $vote1, $vote2)
|
||||
{
|
||||
$voter = $this->getMock('Symfony\Component\Security\Core\Authorization\Voter\VoterInterface');
|
||||
$voter->expects($this->exactly(2))
|
||||
->method('vote')
|
||||
->will($this->returnValueMap(array(
|
||||
array($token, null, array("ROLE_FOO"),$vote1),
|
||||
array($token, null, array("ROLE_BAR"),$vote2),
|
||||
)))
|
||||
;
|
||||
|
||||
return $voter;
|
||||
}
|
||||
|
||||
public function getStrategyTests()
|
||||
{
|
||||
return array(
|
||||
|
@ -13,11 +13,49 @@ namespace Symfony\Component\Security\Core\Tests\Util;
|
||||
|
||||
use Symfony\Component\Security\Core\Util\StringUtils;
|
||||
|
||||
/**
|
||||
* Data from PHP.net's hash_equals tests
|
||||
*/
|
||||
class StringUtilsTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testEquals()
|
||||
public function dataProviderTrue()
|
||||
{
|
||||
$this->assertTrue(StringUtils::equals('password', 'password'));
|
||||
$this->assertFalse(StringUtils::equals('password', 'foo'));
|
||||
return array(
|
||||
array('same', 'same'),
|
||||
array('', ''),
|
||||
array(123, 123),
|
||||
array(null, ''),
|
||||
array(null, null),
|
||||
);
|
||||
}
|
||||
|
||||
public function dataProviderFalse()
|
||||
{
|
||||
return array(
|
||||
array('not1same', 'not2same'),
|
||||
array('short', 'longer'),
|
||||
array('longer', 'short'),
|
||||
array('', 'notempty'),
|
||||
array('notempty', ''),
|
||||
array(123, 'NaN'),
|
||||
array('NaN', 123),
|
||||
array(null, 123),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataProviderTrue
|
||||
*/
|
||||
public function testEqualsTrue($known, $user)
|
||||
{
|
||||
$this->assertTrue(StringUtils::equals($known, $user));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataProviderFalse
|
||||
*/
|
||||
public function testEqualsFalse($known, $user)
|
||||
{
|
||||
$this->assertFalse(StringUtils::equals($known, $user));
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ class StringUtils
|
||||
* Compares two strings.
|
||||
*
|
||||
* This method implements a constant-time algorithm to compare strings.
|
||||
* Regardless of the used implementation, it will leak length information.
|
||||
*
|
||||
* @param string $knownString The string of known length to compare against
|
||||
* @param string $userInput The string that the user can control
|
||||
@ -35,6 +36,13 @@ class StringUtils
|
||||
*/
|
||||
public static function equals($knownString, $userInput)
|
||||
{
|
||||
$knownString = (string) $knownString;
|
||||
$userInput = (string) $userInput;
|
||||
|
||||
if (function_exists('hash_equals')) {
|
||||
return hash_equals($knownString, $userInput);
|
||||
}
|
||||
|
||||
$knownLen = strlen($knownString);
|
||||
$userLen = strlen($userInput);
|
||||
|
||||
@ -45,7 +53,7 @@ class StringUtils
|
||||
$result = $knownLen - $userLen;
|
||||
|
||||
// Note that we ALWAYS iterate over the user-supplied length
|
||||
// This is to prevent leaking length information
|
||||
// This is to mitigate leaking length information
|
||||
for ($i = 0; $i < $userLen; $i++) {
|
||||
$result |= (ord($knownString[$i]) ^ ord($userInput[$i]));
|
||||
}
|
||||
|
@ -67,8 +67,11 @@ class XliffFileDumper extends FileDumper
|
||||
$s = $translation->appendChild($dom->createElement('source'));
|
||||
$s->appendChild($dom->createTextNode($source));
|
||||
|
||||
// Does the target contain characters requiring a CDATA section?
|
||||
$text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
|
||||
|
||||
$t = $translation->appendChild($dom->createElement('target'));
|
||||
$t->appendChild($dom->createTextNode($target));
|
||||
$t->appendChild($text);
|
||||
|
||||
$metadata = $messages->getMetadata($source, $domain);
|
||||
if (null !== $metadata && array_key_exists('notes', $metadata) && is_array($metadata['notes'])) {
|
||||
|
@ -19,7 +19,11 @@ class XliffFileDumperTest extends \PHPUnit_Framework_TestCase
|
||||
public function testDump()
|
||||
{
|
||||
$catalogue = new MessageCatalogue('en_US');
|
||||
$catalogue->add(array('foo' => 'bar', 'key' => ''));
|
||||
$catalogue->add(array(
|
||||
'foo' => 'bar',
|
||||
'key' => '',
|
||||
'key.with.cdata' => '<source> & <target>',
|
||||
));
|
||||
$catalogue->setMetadata('foo', array('notes' => array(array('priority' => 1, 'from' => 'bar', 'content' => 'baz'))));
|
||||
$catalogue->setMetadata('key', array('notes' => array(array('content' => 'baz'), array('content' => 'qux'))));
|
||||
|
||||
@ -27,7 +31,10 @@ class XliffFileDumperTest extends \PHPUnit_Framework_TestCase
|
||||
$dumper = new XliffFileDumper();
|
||||
$dumper->dump($catalogue, array('path' => $tempDir, 'default_locale' => 'fr_FR'));
|
||||
|
||||
$this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources-clean.xlf'), file_get_contents($tempDir.'/messages.en_US.xlf'));
|
||||
$this->assertEquals(
|
||||
file_get_contents(__DIR__.'/../fixtures/resources-clean.xlf'),
|
||||
file_get_contents($tempDir.'/messages.en_US.xlf')
|
||||
);
|
||||
|
||||
unlink($tempDir.'/messages.en_US.xlf');
|
||||
}
|
||||
|
@ -13,6 +13,10 @@
|
||||
<note>baz</note>
|
||||
<note>qux</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="18e6a493872558d949b4c16ea1fa6ab6" resname="key.with.cdata">
|
||||
<source>key.with.cdata</source>
|
||||
<target><![CDATA[<source> & <target>]]></target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -67,7 +67,7 @@ class ImageValidator extends FileValidator
|
||||
if ($width < $constraint->minWidth) {
|
||||
$this->context->addViolation($constraint->minWidthMessage, array(
|
||||
'{{ width }}' => $width,
|
||||
'{{ min_width }}' => $constraint->minWidth
|
||||
'{{ min_width }}' => $constraint->minWidth,
|
||||
));
|
||||
|
||||
return;
|
||||
@ -82,7 +82,7 @@ class ImageValidator extends FileValidator
|
||||
if ($width > $constraint->maxWidth) {
|
||||
$this->context->addViolation($constraint->maxWidthMessage, array(
|
||||
'{{ width }}' => $width,
|
||||
'{{ max_width }}' => $constraint->maxWidth
|
||||
'{{ max_width }}' => $constraint->maxWidth,
|
||||
));
|
||||
|
||||
return;
|
||||
@ -97,7 +97,7 @@ class ImageValidator extends FileValidator
|
||||
if ($height < $constraint->minHeight) {
|
||||
$this->context->addViolation($constraint->minHeightMessage, array(
|
||||
'{{ height }}' => $height,
|
||||
'{{ min_height }}' => $constraint->minHeight
|
||||
'{{ min_height }}' => $constraint->minHeight,
|
||||
));
|
||||
|
||||
return;
|
||||
@ -112,12 +112,12 @@ class ImageValidator extends FileValidator
|
||||
if ($height > $constraint->maxHeight) {
|
||||
$this->context->addViolation($constraint->maxHeightMessage, array(
|
||||
'{{ height }}' => $height,
|
||||
'{{ max_height }}' => $constraint->maxHeight
|
||||
'{{ max_height }}' => $constraint->maxHeight,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
$ratio = $width / $height;
|
||||
$ratio = round($width / $height, 2);
|
||||
|
||||
if (null !== $constraint->minRatio) {
|
||||
if (!is_numeric((string) $constraint->minRatio)) {
|
||||
@ -127,7 +127,7 @@ class ImageValidator extends FileValidator
|
||||
if ($ratio < $constraint->minRatio) {
|
||||
$this->context->addViolation($constraint->minRatioMessage, array(
|
||||
'{{ ratio }}' => $ratio,
|
||||
'{{ min_ratio }}' => $constraint->minRatio
|
||||
'{{ min_ratio }}' => $constraint->minRatio,
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -140,7 +140,7 @@ class ImageValidator extends FileValidator
|
||||
if ($ratio > $constraint->maxRatio) {
|
||||
$this->context->addViolation($constraint->maxRatioMessage, array(
|
||||
'{{ ratio }}' => $ratio,
|
||||
'{{ max_ratio }}' => $constraint->maxRatio
|
||||
'{{ max_ratio }}' => $constraint->maxRatio,
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -148,21 +148,21 @@ class ImageValidator extends FileValidator
|
||||
if (!$constraint->allowSquare && $width == $height) {
|
||||
$this->context->addViolation($constraint->allowSquareMessage, array(
|
||||
'{{ width }}' => $width,
|
||||
'{{ height }}' => $height
|
||||
'{{ height }}' => $height,
|
||||
));
|
||||
}
|
||||
|
||||
if (!$constraint->allowLandscape && $width > $height) {
|
||||
$this->context->addViolation($constraint->allowLandscapeMessage, array(
|
||||
'{{ width }}' => $width,
|
||||
'{{ height }}' => $height
|
||||
'{{ height }}' => $height,
|
||||
));
|
||||
}
|
||||
|
||||
if (!$constraint->allowPortrait && $width < $height) {
|
||||
$this->context->addViolation($constraint->allowPortraitMessage, array(
|
||||
'{{ width }}' => $width,
|
||||
'{{ height }}' => $height
|
||||
'{{ height }}' => $height,
|
||||
));
|
||||
}
|
||||
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 57 B |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user