diff --git a/.composer/composer.json b/.composer/composer.json
deleted file mode 100644
index d69e9f7626d55..0000000000000
--- a/.composer/composer.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "require": {
- "hirak/prestissimo": "^0.1.18"
- }
-}
diff --git a/.composer/composer.lock b/.composer/composer.lock
deleted file mode 100644
index 7027e21d9ac4b..0000000000000
--- a/.composer/composer.lock
+++ /dev/null
@@ -1,70 +0,0 @@
-{
- "_readme": [
- "This file locks the dependencies of your project to a known state",
- "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
- "This file is @generated automatically"
- ],
- "hash": "e02685ff7d2409d34fa87e306fc86ec5",
- "content-hash": "2854c05c76a78113c693dbbdd3f9c518",
- "packages": [
- {
- "name": "hirak/prestissimo",
- "version": "0.1.18",
- "source": {
- "type": "git",
- "url": "https://github.com/hirak/prestissimo.git",
- "reference": "84e9fb79ec18a4428c5a0c032eacac640d89be5d"
- },
- "dist": {
- "type": "zip",
- "url": "https://codeload.github.com/hirak/prestissimo/legacy.zip/84e9fb79ec18a4428c5a0c032eacac640d89be5d",
- "reference": "84e9fb79ec18a4428c5a0c032eacac640d89be5d",
- "shasum": ""
- },
- "require": {
- "composer-plugin-api": "~1.0.0-alpha10",
- "ext-curl": "*",
- "php": ">=5.3.2"
- },
- "require-dev": {
- "composer/composer": "1.0.0-alpha10",
- "phpunit/phpunit": "^4.8",
- "squizlabs/php_codesniffer": "^2.5"
- },
- "type": "composer-plugin",
- "extra": {
- "class": "Hirak\\Prestissimo\\Plugin"
- },
- "autoload": {
- "psr-4": {
- "Hirak\\Prestissimo\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Hiraku NAKANO",
- "email": "hiraku@tojiru.net"
- }
- ],
- "description": "composer parallel install plugin",
- "keywords": [
- "install",
- "parallel",
- "speedup"
- ],
- "time": "2016-03-17 13:53:53"
- }
- ],
- "packages-dev": [],
- "aliases": [],
- "minimum-stability": "stable",
- "stability-flags": [],
- "prefer-stable": false,
- "prefer-lowest": false,
- "platform": [],
- "platform-dev": []
-}
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 7ed7b20e228ae..71c775edb8ae7 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,6 +1,6 @@
| Q | A
| ------------- | ---
-| Branch? | "master" for new features / 2.3, 2.7, 2.8 or 3.0 for fixes
+| Branch? | "master" for new features / 2.7, 2.8, 3.0 or 3.1 for fixes
| Bug fix? | yes/no
| New feature? | yes/no
| BC breaks? | yes/no
diff --git a/.travis.php b/.travis.php
index 511e05008a335..7618c272e88ee 100644
--- a/.travis.php
+++ b/.travis.php
@@ -1,20 +1,19 @@
$_SERVER['argc']) {
- echo "Usage: commit-range branch dir1 dir2 ... dirN\n";
+ echo "Usage: branch dir1 dir2 ... dirN\n";
exit(1);
}
$dirs = $_SERVER['argv'];
array_shift($dirs);
-$range = array_shift($dirs);
$branch = array_shift($dirs);
$packages = array();
$flags = PHP_VERSION_ID >= 50400 ? JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE : 0;
foreach ($dirs as $dir) {
- if (!`git diff --name-only $range -- $dir`) {
+ if (!`git diff --name-only $branch...HEAD -- $dir`) {
continue;
}
echo "$dir\n";
diff --git a/.travis.yml b/.travis.yml
index 4718a1090ac7b..778d0e9c04db2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -17,7 +17,11 @@ env:
matrix:
include:
+ # Use the newer stack for HHVM as HHVM does not support Precise anymore since a long time and so Precise has an outdated version
- php: hhvm
+ sudo: required
+ dist: trusty
+ group: edge
- php: 5.3
- php: 5.4
- php: 5.5
@@ -35,12 +39,13 @@ cache:
services: mongodb
before_install:
+ - stty cols 120
- PHP=$TRAVIS_PHP_VERSION
# Matrix lines for intermediate PHP versions are skipped for pull requests
- - if [[ ! $deps && ! $PHP = ${MIN_PHP%.*} && $PHP != hhvm && $TRAVIS_PULL_REQUEST != false ]]; then deps=skip; skip=1; fi
+ - if [[ ! $deps && ! $PHP = ${MIN_PHP%.*} && ! $PHP = hhvm* && $TRAVIS_PULL_REQUEST != false ]]; then deps=skip; skip=1; fi
# A sigchild-enabled-PHP is used to test the Process component on the lowest PHP matrix line
- if [[ ! $deps && $PHP = ${MIN_PHP%.*} && ! -d php-$MIN_PHP/sapi ]]; then wget http://museum.php.net/php5/php-$MIN_PHP.tar.bz2 -O - | tar -xj; (cd php-$MIN_PHP; ./configure --enable-sigchild --enable-pcntl; make -j2); fi
- - if [[ $PHP != hhvm ]]; then INI_FILE=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; else INI_FILE=/etc/hhvm/php.ini; fi
+ - if [[ ! $PHP = hhvm* ]]; then INI_FILE=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; else INI_FILE=/etc/hhvm/php.ini; fi
- if [[ ! $skip ]]; then echo memory_limit = -1 >> $INI_FILE; fi
- if [[ ! $skip ]]; then echo session.gc_probability = 0 >> $INI_FILE; fi
- if [[ ! $skip && $PHP = 5.* ]]; then echo extension = mongo.so >> $INI_FILE; fi
@@ -49,18 +54,17 @@ before_install:
- if [[ ! $skip && $PHP = 7.* ]]; then (echo yes | pecl install -f apcu-5.1.2 && echo apc.enable_cli = 1 >> $INI_FILE); fi
- if [[ ! $deps && $PHP = 5.* ]]; then (cd src/Symfony/Component/Debug/Resources/ext && phpize && ./configure && make && echo extension = $(pwd)/modules/symfony_debug.so >> $INI_FILE); fi
- if [[ ! $skip && $PHP = 5.* ]]; then pecl install -f memcached-2.1.0; fi
- - if [[ ! $skip && $PHP != hhvm ]]; then echo extension = ldap.so >> $INI_FILE; fi
- - if [[ ! $skip && $PHP != hhvm ]]; then phpenv config-rm xdebug.ini; fi
+ - if [[ ! $skip && ! $PHP = hhvm* ]]; then echo extension = ldap.so >> $INI_FILE; fi
+ - if [[ ! $skip && ! $PHP = hhvm* ]]; then phpenv config-rm xdebug.ini; fi
- if [[ ! $skip ]]; then composer self-update --stable; fi
- - if [[ ! $skip ]]; then cp .composer/* ~/.composer/; composer global install; fi
+ - if [[ ! $skip ]]; then cp .composer/* ~/.composer/; fi
- if [[ ! $skip ]]; then ./phpunit install; fi
- - if [[ ! $skip && $deps ]]; then composer global remove hirak/prestissimo; fi
- if [[ ! $skip ]]; then export PHPUNIT=$(readlink -f ./phpunit); fi
install:
- if [[ ! $skip ]]; then COMPONENTS=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n'); fi
# Create local composer packages for each patched components and reference them in composer.json files when cross-testing components
- - if [[ ! $skip && $deps ]]; then php .travis.php $TRAVIS_COMMIT_RANGE $TRAVIS_BRANCH $COMPONENTS; fi
+ - if [[ ! $skip && $deps ]]; then php .travis.php $TRAVIS_BRANCH $COMPONENTS; fi
# For the master branch when deps=high, the version before master is checked out and tested with the locally patched components
- if [[ $deps = high && $TRAVIS_BRANCH = master ]]; then SYMFONY_VERSION=$(git ls-remote --heads | grep -o '/[1-9].*' | tail -n 1 | sed s/.//); else SYMFONY_VERSION=$(cat composer.json | grep '^ *"dev-master". *"[1-9]' | grep -o '[0-9.]*'); fi
- if [[ $deps = high && $TRAVIS_BRANCH = master ]]; then git fetch origin $SYMFONY_VERSION; git checkout -m FETCH_HEAD; COMPONENTS=$(find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist -printf '%h\n'); ./phpunit install; fi
@@ -69,12 +73,13 @@ install:
- export COMPOSER_ROOT_VERSION=$SYMFONY_VERSION.x-dev
- if [[ ! $deps ]]; then composer update; else export SYMFONY_DEPRECATIONS_HELPER=weak; fi
- if [[ $TRAVIS_BRANCH = master ]]; then export SYMFONY_PHPUNIT_OVERLOAD=1; fi
- - if [[ $PHP != hhvm ]]; then php -i; else hhvm --php -r 'print_r($_SERVER);print_r(ini_get_all());'; fi
+ - if [[ ! $PHP = hhvm* ]]; then php -i; else hhvm --php -r 'print_r($_SERVER);print_r(ini_get_all());'; fi
script:
- if [[ $skip ]]; then echo -e "\\n\\e[1;34mIntermediate PHP version $PHP is skipped for pull requests.\\e[0m"; fi
- - if [[ ! $deps ]]; then echo "$COMPONENTS" | parallel --gnu '$PHPUNIT --exclude-group tty,benchmark,intl-data {}'; fi
- - if [[ ! $deps ]]; then echo -e "\\nRunning tests requiring tty"; $PHPUNIT --group tty; fi
+ - if [[ ! $deps && ! $PHP = hhvm* ]]; then echo "$COMPONENTS" | parallel --gnu '$PHPUNIT --exclude-group tty,benchmark,intl-data {}'; fi
+ - if [[ ! $deps && ! $PHP = hhvm* ]]; then echo -e "\\nRunning tests requiring tty"; $PHPUNIT --group tty; fi
+ - if [[ ! $deps && $PHP = hhvm* ]]; then $PHPUNIT --exclude-group benchmark,intl-data; fi
- if [[ ! $deps && $PHP = ${MIN_PHP%.*} ]]; then echo -e "1\\n0" | xargs -I{} sh -c 'echo "\\nPHP --enable-sigchild enhanced={}" && ENHANCE_SIGCHLD={} php-$MIN_PHP/sapi/cli/php .phpunit/phpunit-4.8/phpunit --colors=always src/Symfony/Component/Process/'; fi
- if [[ $deps = high ]]; then echo "$COMPONENTS" | parallel --gnu -j10% 'cd {}; composer update --no-progress --ansi; $PHPUNIT --exclude-group tty,benchmark,intl-data'$LEGACY; fi
- if [[ $deps = low ]]; then echo "$COMPONENTS" | parallel --gnu -j10% 'cd {}; composer update --no-progress --ansi --prefer-lowest --prefer-stable; $PHPUNIT --exclude-group tty,benchmark,intl-data'; fi
diff --git a/CHANGELOG-2.3.md b/CHANGELOG-2.3.md
index d0ca6221aca02..2758f011f3cfd 100644
--- a/CHANGELOG-2.3.md
+++ b/CHANGELOG-2.3.md
@@ -7,6 +7,27 @@ 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.42 (2016-05-30)
+
+ * bug #18908 [DependencyInjection] force enabling the external XML entity loaders (xabbuh)
+ * bug #18893 [DependencyInjection] Skip deep reference check for 'service_container' (RobertMe)
+ * bug #18812 Catch \Throwable (fprochazka)
+ * bug #18821 [Form] Removed UTC specification with timestamp (francisbesset)
+ * bug #18861 Fix for #18843 (inso)
+ * bug #18907 [Routing] Fix the annotation loader taking a class constant as a beginning of a class name (jakzal, nicolas-grekas)
+ * bug #18864 [Console][DX] Fixed ambiguous error message when using a duplicate option shortcut (peterrehm)
+ * bug #18844 [Yaml] fix exception contexts (xabbuh)
+ * bug #18840 [Yaml] properly handle unindented collections (xabbuh)
+ * bug #18839 People - person singularization (Keeo)
+ * bug #18828 [Yaml] chomp newlines only at the end of YAML documents (xabbuh)
+ * bug #18635 [Console] Prevent fatal error when calling Command::getHelper without helperSet (chalasr)
+ * bug #18761 [Form] Modified iterator_to_array's 2nd parameter to false in ViolationMapper (issei-m)
+
+* 2.3.41 (2016-05-09)
+
+ * security #18733 limited the maximum length of a submitted username (fabpot)
+ * bug #18709 [DependencyInjection] top-level anonymous services must be public (xabbuh)
+
* 2.3.40 (2016-04-29)
* bug #18246 [DependencyInjection] fix ambiguous services schema (backbone87)
diff --git a/CHANGELOG-2.7.md b/CHANGELOG-2.7.md
index cfe286f2a4caf..235f166764c2d 100644
--- a/CHANGELOG-2.7.md
+++ b/CHANGELOG-2.7.md
@@ -7,6 +7,32 @@ in 2.7 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.7.0...v2.7.1
+* 2.7.14 (2016-06-06)
+
+ * bug #18908 [DependencyInjection] force enabling the external XML entity loaders (xabbuh)
+ * bug #18893 [DependencyInjection] Skip deep reference check for 'service_container' (RobertMe)
+ * bug #18812 Catch \Throwable (fprochazka)
+ * bug #18821 [Form] Removed UTC specification with timestamp (francisbesset)
+ * bug #18861 Fix for #18843 (inso)
+ * bug #18907 [Routing] Fix the annotation loader taking a class constant as a beginning of a class name (jakzal, nicolas-grekas)
+ * bug #18879 [Console] SymfonyStyle: Align multi-line/very-long-line blocks (chalasr)
+ * bug #18864 [Console][DX] Fixed ambiguous error message when using a duplicate option shortcut (peterrehm)
+ * bug #18883 Fix js comment in profiler (linnaea)
+ * bug #18844 [Yaml] fix exception contexts (xabbuh)
+ * bug #18840 [Yaml] properly handle unindented collections (xabbuh)
+ * bug #18813 Catch \Throwable (fprochazka)
+ * bug #18839 People - person singularization (Keeo)
+ * bug #18828 [Yaml] chomp newlines only at the end of YAML documents (xabbuh)
+ * bug #18814 Fixed server status command when port has been omitted (peterrehm)
+ * bug #18799 Use levenshtein level for better Bundle matching (j0k3r)
+ * bug #18413 [WebProfilerBundle] Fix CORS ajax security issues (romainneutron)
+ * bug #18507 [BUG] Delete class 'control-group' in bootstrap 3 (Philippe Degeeter)
+ * bug #18747 [Form] Modified iterator_to_array's 2nd parameter to false in ViolationMapper (issei-m)
+ * bug #18635 [Console] Prevent fatal error when calling Command::getHelper without helperSet (chalasr)
+ * bug #18686 [console][table] adjust width of colspanned cell. (aitboudad)
+ * bug #18761 [Form] Modified iterator_to_array's 2nd parameter to false in ViolationMapper (issei-m)
+ * bug #18737 [Debug] Fix fatal error handlers on PHP 7 (nicolas-grekas)
+
* 2.7.13 (2016-05-09)
* security #18733 limited the maximum length of a submitted username (fabpot)
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 456aeba37aa74..5fc732e26ff90 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -23,8 +23,8 @@ Symfony is the result of the work of many people who made the code better
- Pascal Borreli (pborreli)
- Joseph Bielawski (stloyd)
- Wouter De Jong (wouterj)
- - Karma Dordrak (drak)
- Romain Neutron (romain)
+ - Karma Dordrak (drak)
- Lukas Kahwe Smith (lsmith)
- Martin Hasoň (hason)
- Jeremy Mikola (jmikola)
@@ -39,10 +39,10 @@ Symfony is the result of the work of many people who made the code better
- Maxime Steinhausser (ogizanagi)
- Alexandre Salomé (alexandresalome)
- William Durand (couac)
+ - Jules Pietri (heah)
- ornicar
- stealth35 (stealth35)
- Alexander Mols (asm89)
- - Jules Pietri (heah)
- Francis Besset (francisbesset)
- Bulat Shakirzyanov (avalanche123)
- Saša Stamenković (umpirsky)
@@ -53,11 +53,11 @@ Symfony is the result of the work of many people who made the code better
- Bilal Amarni (bamarni)
- Florin Patan (florinpatan)
- Kevin Bond (kbond)
+ - Peter Rehm (rpet)
- Gábor Egyed (1ed)
- Michel Weimerskirch (mweimerskirch)
- Eric Clemmons (ericclemmons)
- Andrej Hudec (pulzarraider)
- - Peter Rehm (rpet)
- Christian Raue
- Matthias Pigulla (mpdude)
- Deni
@@ -65,6 +65,7 @@ Symfony is the result of the work of many people who made the code better
- Dariusz Górecki (canni)
- Arnout Boks (aboks)
- Iltar van der Berg (kjarli)
+ - Charles Sarrazin (csarrazi)
- Ener-Getick (energetick)
- Douglas Greenshields (shieldo)
- Lee McDermott
@@ -74,7 +75,6 @@ Symfony is the result of the work of many people who made the code better
- Pierre du Plessis (pierredup)
- Bart van den Burg (burgov)
- Jordan Alliot (jalliot)
- - Charles Sarrazin (csarrazi)
- John Wards (johnwards)
- Toni Uebernickel (havvg)
- Fran Moreno (franmomu)
@@ -89,6 +89,7 @@ Symfony is the result of the work of many people who made the code better
- Alexander M. Turek (derrabus)
- Dariusz Ruminski
- marc.weistroff
+ - Issei Murasawa (issei_m)
- lenar
- Włodzimierz Gajda (gajdaw)
- Alexander Schwenn (xelaris)
@@ -97,13 +98,12 @@ Symfony is the result of the work of many people who made the code better
- Colin Frei
- Adrien Brault (adrienbrault)
- Joshua Thijssen
- - Issei Murasawa (issei_m)
+ - Baptiste Clavié (talus)
- Peter Kokot (maastermedia)
- excelwebzone
- Jacob Dreesen (jdreesen)
- Jérémy DERUSSÉ (jderusse)
- Vladimir Reznichenko (kalessil)
- - Baptiste Clavié (talus)
- Fabien Pennequin (fabienpennequin)
- Gordon Franke (gimler)
- David Buchmann (dbu)
@@ -121,6 +121,7 @@ Symfony is the result of the work of many people who made the code better
- Evgeniy (ewgraf)
- Guilherme Blanco (guilhermeblanco)
- Pablo Godel (pgodel)
+ - Titouan Galopin (tgalopin)
- Jérémie Augustin (jaugustin)
- Sebastiaan Stok (sstok)
- Tugdual Saunier (tucksaun)
@@ -132,6 +133,7 @@ Symfony is the result of the work of many people who made the code better
- Richard Shank (iampersistent)
- Thomas Rabaix (rande)
- Vincent AUBERT (vincent)
+ - Rouven Weßling (realityking)
- Mikael Pajunen
- Clemens Tolboom
- Helmer Aaviksoo
@@ -141,9 +143,7 @@ Symfony is the result of the work of many people who made the code better
- Michał Pipa (michal.pipa)
- Amal Raghav (kertz)
- Jonathan Ingram (jonathaningram)
- - Titouan Galopin (tgalopin)
- Artur Kotyrba
- - Rouven Weßling (realityking)
- Warnar Boekkooi (boekkooi)
- Dmitrii Chekaliuk (lazyhammer)
- Clément JOBEILI (dator)
@@ -187,6 +187,7 @@ Symfony is the result of the work of many people who made the code better
- Loïc Faugeron
- Jannik Zschiesche (apfelbox)
- Marco Pivetta (ocramius)
+ - Teoh Han Hui (teohhanhui)
- julien pauli (jpauli)
- Michael Lee (zerustech)
- Lorenz Schori
@@ -211,7 +212,9 @@ Symfony is the result of the work of many people who made the code better
- Kristen Gilden (kgilden)
- Dawid Nowak
- Pierre-Yves LEBECQ (pylebecq)
+ - Daniel Espendiller
- Jakub Kucharovic (jkucharovic)
+ - Robin Chalas (chalas_r)
- Eugene Leonovich (rybakit)
- Filippo Tessarotto
- Joseph Rouff (rouffj)
@@ -274,7 +277,6 @@ Symfony is the result of the work of many people who made the code better
- janschoenherr
- Thomas Schulz (king2500)
- Berny Cantos (xphere81)
- - Teoh Han Hui (teohhanhui)
- Ricard Clau (ricardclau)
- Mark Challoner (markchalloner)
- Gregor Harlan (gharlan)
@@ -292,6 +294,7 @@ Symfony is the result of the work of many people who made the code better
- Inal DJAFAR (inalgnu)
- Christian Gärtner (dagardner)
- Tomasz Kowalczyk (thunderer)
+ - Christian Schmidt
- François-Xavier de Guillebon (de-gui_f)
- Damien Alexandre (damienalexandre)
- Felix Labrecque
@@ -318,12 +321,14 @@ Symfony is the result of the work of many people who made the code better
- Pavel Volokitin (pvolok)
- Endre Fejes
- Tobias Naumann (tna)
+ - Daniel Beyer
- Shein Alexey
- Baptiste Lafontaine
- Joe Lencioni
- Daniel Tschinder
- Kai
- Lee Rowlands
+ - Krzysztof Piasecki (krzysztek)
- Maximilian Reichel (phramz)
- Loick Piera (pyrech)
- Karoly Negyesi (chx)
@@ -363,7 +368,6 @@ Symfony is the result of the work of many people who made the code better
- EdgarPE
- Florian Pfitzer (marmelatze)
- Asier Illarramendi (doup)
- - Christian Schmidt
- Chris Sedlmayr (catchamonkey)
- Seb Koelen
- Christoph Mewes (xrstf)
@@ -381,6 +385,7 @@ Symfony is the result of the work of many people who made the code better
- Mathieu Lemoine
- franek (franek)
- Christian Wahler
+ - Mathieu Lemoine
- Gintautas Miselis
- Zander Baldwin
- Adam Harvey
@@ -418,7 +423,6 @@ Symfony is the result of the work of many people who made the code better
- Anthony Ferrara
- Ioan Negulescu
- Jakub Škvára (jskvara)
- - Daniel Beyer
- Andrew Udvare (audvare)
- alexpods
- Tristan Darricau (nicofuma)
@@ -436,6 +440,7 @@ Symfony is the result of the work of many people who made the code better
- Benjamin Leveque (benji07)
- Nate (frickenate)
- jhonnyL
+ - Jhonny Lidfors (jhonne)
- sasezaki
- Dawid Pakuła (zulusx)
- Florian Rey (nervo)
@@ -446,6 +451,7 @@ Symfony is the result of the work of many people who made the code better
- Denis Gorbachev (starfall)
- Peter van Dommelen
- Tim van Densen
+ - Martin Morávek (keeo)
- Steven Surowiec
- Kevin Saliou (kbsali)
- NothingWeAre
@@ -460,7 +466,6 @@ Symfony is the result of the work of many people who made the code better
- Ziumin
- Jeremy Benoist
- Lenar Lõhmus
- - Krzysztof Piasecki (krzysztek)
- Benjamin Laugueux (yzalis)
- Zach Badgett (zachbadgett)
- Aurélien Fredouelle
@@ -499,6 +504,7 @@ Symfony is the result of the work of many people who made the code better
- Javier López (loalf)
- Reinier Kip
- Dustin Dobervich (dustin10)
+ - dantleech
- Anne-Sophie Bachelard (annesophie)
- Sebastian Marek (proofek)
- Erkhembayar Gantulga (erheme318)
@@ -561,6 +567,7 @@ Symfony is the result of the work of many people who made the code better
- Peter Ward
- Dominik Ritter (dritter)
- Sebastian Grodzicki (sgrodzicki)
+ - SpacePossum
- Martin Hujer (martinhujer)
- Pascal Helfenstein
- Baldur Rensch (brensch)
@@ -611,7 +618,7 @@ Symfony is the result of the work of many people who made the code better
- Adrien Lucas (adrienlucas)
- James Michael DuPont
- Tom Klingenberg
- - Jhonny Lidfors (jhonne)
+ - Filip Procházka (fprochazka)
- Christopher Hall (mythmakr)
- Paul Kamer (pkamer)
- Rafał Wrzeszcz (rafalwrzeszcz)
@@ -628,6 +635,7 @@ Symfony is the result of the work of many people who made the code better
- Alaattin Kahramanlar (alaattin)
- Maksim Kotlyar (makasim)
- Neil Ferreira
+ - Nathanael Noblet (gnat)
- Dmitry Parnas (parnas)
- Théo FIDRY (theofidry)
- Paul LE CORRE
@@ -744,7 +752,6 @@ Symfony is the result of the work of many people who made the code better
- Guillaume Royer
- Artem (digi)
- boite
- - dantleech
- Vadim Tyukov (vatson)
- Sortex
- chispita
@@ -850,6 +857,7 @@ Symfony is the result of the work of many people who made the code better
- Christian Sciberras
- Anton Bakai
- Clement Herreman (clemherreman)
+ - Dan Ionut Dumitriu (danionut90)
- Nyro (nyro)
- Marco
- Marc Torres
@@ -869,7 +877,6 @@ Symfony is the result of the work of many people who made the code better
- ConneXNL
- Aharon Perkel
- Abdul.Mohsen B. A. A
- - SpacePossum
- Benoît Burnichon
- Remi Collet
- pthompson
@@ -904,7 +911,6 @@ Symfony is the result of the work of many people who made the code better
- Albin Kerouaton
- Sébastien HOUZÉ
- Jingyu Wang
- - Daniel Espendiller
- steveYeah
- Samy Dindane (dinduks)
- Keri Henare (kerihenare)
@@ -945,6 +951,7 @@ Symfony is the result of the work of many people who made the code better
- Tadcka
- Beth Binkovitz
- Romain Geissler
+ - Oliver Hoff
- Tomaz Ahlin
- Benjamin Cremer (bcremer)
- Marcus Stöhr (dafish)
@@ -1058,6 +1065,7 @@ Symfony is the result of the work of many people who made the code better
- stloyd
- Chris Tickner
- Andrew Coulton
+ - Jeremy Benoist
- Michal Gebauer
- Gleb Sidora
- David Stone
@@ -1107,7 +1115,6 @@ Symfony is the result of the work of many people who made the code better
- Simon Sargeant
- efeen
- Michał Dąbrowski (defrag)
- - Nathanael Noblet (gnat)
- Simone Fumagalli (hpatoio)
- Brian Graham (incognito)
- Kevin Vergauwen (innocenzo)
@@ -1213,8 +1220,10 @@ Symfony is the result of the work of many people who made the code better
- Alan Chen
- Maerlyn
- Even André Fiskvik
+ - Erik van Wingerden
- Dane Powell
- Gerrit Drost
+ - Linnaea Von Lavia
- Lenar Lõhmus
- Cristian Gonzalez
- AlberT
@@ -1270,6 +1279,7 @@ Symfony is the result of the work of many people who made the code better
- Joseph Deray
- Damian Sromek
- Ben
+ - dasmfm
- Arnaud Buathier (arnapou)
- chesteroni (chesteroni)
- Mauricio Lopez (diaspar)
@@ -1302,6 +1312,7 @@ Symfony is the result of the work of many people who made the code better
- znerol
- Christian Eikermann
- Antonio Angelino
+ - Shawn Iwinski
- Vladimir Sazhin
- lol768
- jamogon
@@ -1356,7 +1367,6 @@ Symfony is the result of the work of many people who made the code better
- Norman Soetbeer
- zorn
- Benjamin Long
- - Robin Chalas
- Matt Janssen
- Peter Gribanov
- kwiateusz
@@ -1404,6 +1414,7 @@ Symfony is the result of the work of many people who made the code better
- Damon Jones (damon__jones)
- David Badura (davidbadura)
- Daniel Londero (dlondero)
+ - Sebastian Landwehr (dword123)
- Adel ELHAIBA (eadel)
- Damián Nohales (eagleoneraptor)
- Elliot Anderson (elliot)
@@ -1441,6 +1452,7 @@ Symfony is the result of the work of many people who made the code better
- ollie harridge (ollietb)
- Paul Andrieux (paulandrieux)
- Paweł Szczepanek (pauluz)
+ - Philippe Degeeter (pdegeeter)
- Christian López Espínola (penyaskito)
- Petr Jaroš (petajaros)
- Philipp Hoffmann (philipphoffmann)
diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md
index 475fcbbc80d56..467c13e6448ca 100644
--- a/UPGRADE-3.0.md
+++ b/UPGRADE-3.0.md
@@ -132,7 +132,10 @@ UPGRADE FROM 2.x to 3.0
### Form
- * The `ChoiceToBooleanArrayTransformer`, `ChoicesToBooleanArrayTransformer`,
+ * The `max_length` option was removed. Use the `attr` option instead by setting it to
+ an `array` with a `maxlength` key.
+
+ * The `ChoiceToBooleanArrayTransformer`, `ChoicesToBooleanArrayTransformer`,
`FixRadioInputListener`, and `FixCheckboxInputListener` classes were removed.
* The `choice_list` option of `ChoiceType` was removed.
diff --git a/appveyor.yml b/appveyor.yml
index 2de9fb45d92ad..5521a0a26b780 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -18,7 +18,7 @@ init:
install:
- IF EXIST c:\php (SET PHP=0) ELSE (mkdir c:\php)
- cd c:\php
- - IF %PHP%==1 appveyor DownloadFile https://curl.haxx.se/ca/cacert.pem
+ - IF %PHP%==1 appveyor DownloadFile https://raw.githubusercontent.com/symfony/binary-utils/master/cacert.pem
- IF %PHP%==1 appveyor DownloadFile http://windows.php.net/downloads/releases/archives/php-5.3.11-nts-Win32-VC9-x86.zip
- IF %PHP%==1 7z x php-5.3.11-nts-Win32-VC9-x86.zip -y >nul
- IF %PHP%==1 appveyor DownloadFile https://raw.githubusercontent.com/symfony/binary-utils/master/ICU-51.2-dlls.zip
@@ -49,12 +49,11 @@ install:
- IF %PHP%==1 echo extension=php_pdo_sqlite.dll >> php.ini-max
- IF %PHP%==1 echo extension=php_curl.dll >> php.ini-max
- IF %PHP%==1 echo curl.cainfo=c:\php\cacert.pem >> php.ini-max
- - IF %PHP%==1 appveyor DownloadFile https://getcomposer.org/download/1.0.2/composer.phar
+ - IF %PHP%==1 appveyor DownloadFile https://getcomposer.org/download/1.0.3/composer.phar
- copy /Y php.ini-max php.ini
- cd c:\projects\symfony
- mkdir %APPDATA%\Composer
- copy /Y .composer\* %APPDATA%\Composer\
- - composer global install --no-progress --ansi
- php phpunit install
- IF %APPVEYOR_REPO_BRANCH%==master (SET COMPOSER_ROOT_VERSION=dev-master) ELSE (SET COMPOSER_ROOT_VERSION=%APPVEYOR_REPO_BRANCH%.x-dev)
- composer update --no-progress --ansi
diff --git a/phpunit b/phpunit
index 6d66f7b2b252a..3ab3ca1686042 100755
--- a/phpunit
+++ b/phpunit
@@ -53,6 +53,9 @@ if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__
chdir("phpunit-$PHPUNIT_VERSION");
passthru("$COMPOSER remove --no-update phpspec/prophecy");
passthru("$COMPOSER remove --no-update symfony/yaml");
+ if (5.1 <= $PHPUNIT_VERSION && $PHPUNIT_VERSION < 5.4) {
+ passthru("$COMPOSER require --no-update phpunit/phpunit-mock-objects \"~3.1.0\"");
+ }
passthru("$COMPOSER require --dev --no-update symfony/phpunit-bridge \">=3.1@dev\"");
passthru("$COMPOSER install --prefer-dist --no-progress --ansi", $exit);
if ($exit) {
@@ -170,8 +173,11 @@ if (isset($argv[1]) && 'symfony' === $argv[1]) {
unlink($file);
}
- // Fail on any individual component failures but ignore STATUS_STACK_BUFFER_OVERRUN (-1073740791/0xC0000409) and STATUS_ACCESS_VIOLATION (-1073741819/0xC0000005) on Windows when APCu is enabled
- if ($procStatus && ('\\' !== DIRECTORY_SEPARATOR || !extension_loaded('apcu') || !ini_get('apc.enable_cli') || (-1073740791 !== $procStatus && -1073741819 !== $procStatus))) {
+ // Fail on any individual component failures but ignore some error codes on Windows when APCu is enabled:
+ // STATUS_STACK_BUFFER_OVERRUN (-1073740791/0xC0000409)
+ // STATUS_ACCESS_VIOLATION (-1073741819/0xC0000005)
+ // STATUS_HEAP_CORRUPTION (-1073740940/0xC0000374)
+ if ($procStatus && ('\\' !== DIRECTORY_SEPARATOR || !extension_loaded('apcu') || !ini_get('apc.enable_cli') || !in_array($procStatus, array(-1073740791, -1073741819, -1073740940)))) {
$exit = $procStatus;
echo "\033[41mKO\033[0m $component\n\n";
} else {
diff --git a/src/Symfony/Bridge/Twig/NodeVisitor/Scope.php b/src/Symfony/Bridge/Twig/NodeVisitor/Scope.php
index 1712bd5afee8e..f9333bf683d1a 100644
--- a/src/Symfony/Bridge/Twig/NodeVisitor/Scope.php
+++ b/src/Symfony/Bridge/Twig/NodeVisitor/Scope.php
@@ -67,9 +67,9 @@ public function leave()
* @param string $key
* @param mixed $value
*
- * @throws \LogicException
- *
* @return Scope Current scope
+ *
+ * @throws \LogicException
*/
public function set($key, $value)
{
diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig
index 0fb3f769b8391..ef2035ab43f04 100644
--- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig
+++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig
@@ -94,14 +94,12 @@
{% block choice_widget_expanded -%}
{% if '-inline' in label_attr.class|default('') -%}
-
- {%- for child in form %}
- {{- form_widget(child, {
- parent_label_class: label_attr.class|default(''),
- translation_domain: choice_translation_domain,
- }) -}}
- {% endfor -%}
-
+ {%- for child in form %}
+ {{- form_widget(child, {
+ parent_label_class: label_attr.class|default(''),
+ translation_domain: choice_translation_domain,
+ }) -}}
+ {% endfor -%}
{%- else -%}
{%- for child in form %}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ServerStatusCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ServerStatusCommand.php
index 2c6d2c49ff09c..fa5c537a0c97a 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/ServerStatusCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/ServerStatusCommand.php
@@ -13,6 +13,7 @@
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
@@ -31,6 +32,7 @@ protected function configure()
$this
->setDefinition(array(
new InputArgument('address', InputArgument::OPTIONAL, 'Address:port', '127.0.0.1:8000'),
+ new InputOption('port', 'p', InputOption::VALUE_REQUIRED, 'Address port number', '8000'),
))
->setName('server:status')
->setDescription('Outputs the status of the built-in web server for the given address')
@@ -44,6 +46,10 @@ protected function execute(InputInterface $input, OutputInterface $output)
{
$address = $input->getArgument('address');
+ if (false === strpos($address, ':')) {
+ $address = $address.':'.$input->getOption('port');
+ }
+
// remove an orphaned lock file
if (file_exists($this->getLockFile($address)) && !$this->isServerRunning($address)) {
unlink($this->getLockFile($address));
diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php
index 873c736841ba8..374d0eba10ff6 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php
@@ -142,6 +142,7 @@ private function findAlternative($nonExistentBundleName)
$lev = levenshtein($nonExistentBundleName, $bundleName);
if ($lev <= strlen($nonExistentBundleName) / 3 && ($alternative === null || $lev < $shortest)) {
$alternative = $bundleName;
+ $shortest = $lev;
}
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php b/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php
index b37bee83d401c..801149372af99 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php
@@ -77,6 +77,9 @@ public function load($resource, $type = null)
} catch (\Exception $e) {
$this->loading = false;
throw $e;
+ } catch (\Throwable $e) {
+ $this->loading = false;
+ throw $e;
}
$this->loading = false;
@@ -85,7 +88,7 @@ public function load($resource, $type = null)
if ($controller = $route->getDefault('_controller')) {
try {
$controller = $this->parser->parse($controller);
- } catch (\Exception $e) {
+ } catch (\InvalidArgumentException $e) {
// unable to optimize unknown notation
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php
index 4718c1eb0b238..0fe47b0908d83 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php
@@ -59,8 +59,8 @@ public function testBuild()
{
$parser = $this->createParser();
- $this->assertEquals('FooBundle:Default:index', $parser->build('TestBundle\FooBundle\Controller\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string');
- $this->assertEquals('FooBundle:Sub\Default:index', $parser->build('TestBundle\FooBundle\Controller\Sub\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string');
+ $this->assertEquals('FoooooBundle:Default:index', $parser->build('TestBundle\FooBundle\Controller\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string');
+ $this->assertEquals('FoooooBundle:Sub\Default:index', $parser->build('TestBundle\FooBundle\Controller\Sub\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string');
try {
$parser->build('TestBundle\FooBundle\Controller\DefaultController::index');
@@ -132,8 +132,9 @@ public function testInvalidBundleName($bundleName, $suggestedBundleName)
public function getInvalidBundleNameTests()
{
return array(
- array('FoodBundle:Default:index', 'FooBundle:Default:index'),
- array('CrazyBundle:Default:index', false),
+ 'Alternative will be found using levenshtein' => array('FoodBundle:Default:index', 'FooBundle:Default:index'),
+ 'Alternative will be found using partial match' => array('FabpotFooBund:Default:index', 'FabpotFooBundle:Default:index'),
+ 'Bundle does not exist at all' => array('CrazyBundle:Default:index', false),
);
}
@@ -162,6 +163,7 @@ private function createParser()
$bundles = array(
'SensioFooBundle' => $this->getBundle('TestBundle\Fabpot\FooBundle', 'FabpotFooBundle'),
'SensioCmsFooBundle' => $this->getBundle('TestBundle\Sensio\Cms\FooBundle', 'SensioCmsFooBundle'),
+ 'FoooooBundle' => $this->getBundle('TestBundle\FooBundle', 'FoooooBundle'),
'FooBundle' => $this->getBundle('TestBundle\FooBundle', 'FooBundle'),
'FabpotFooBundle' => $this->getBundle('TestBundle\Fabpot\FooBundle', 'FabpotFooBundle'),
);
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerResolverTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerResolverTest.php
index b4dc8ada555b6..00ffa4c1fd162 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerResolverTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerResolverTest.php
@@ -150,7 +150,7 @@ public function getUndefinedControllers()
{
return array(
array('foo', '\LogicException', 'Unable to parse the controller name "foo".'),
- array('foo::bar', '\InvalidArgumentException', 'Class "foo" does not exist.'),
+ array('oof::bar', '\InvalidArgumentException', 'Class "oof" does not exist.'),
array('stdClass', '\LogicException', 'Unable to parse the controller name "stdClass".'),
array(
'Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest::bar',
diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php b/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php
index ca9e7f994c090..cf7f3c5769bf2 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php
@@ -182,9 +182,9 @@ protected function parseTokens($tokens, MessageCatalogue $catalog)
/**
* @param string $file
*
- * @throws \InvalidArgumentException
- *
* @return bool
+ *
+ * @throws \InvalidArgumentException
*/
protected function canBeExtracted($file)
{
diff --git a/src/Symfony/Bundle/TwigBundle/Extension/AssetsExtension.php b/src/Symfony/Bundle/TwigBundle/Extension/AssetsExtension.php
index fc62ef059daaf..976086920e07b 100644
--- a/src/Symfony/Bundle/TwigBundle/Extension/AssetsExtension.php
+++ b/src/Symfony/Bundle/TwigBundle/Extension/AssetsExtension.php
@@ -95,9 +95,9 @@ public function getName()
*
* @param string $url The URL that has to be absolute
*
- * @throws \RuntimeException
- *
* @return string The absolute URL
+ *
+ * @throws \RuntimeException
*/
private function ensureUrlIsAbsolute($url)
{
diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig
index 8c10c95655317..23e05030c5862 100644
--- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig
+++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig
@@ -80,6 +80,20 @@
requestStack = [],
+ extractHeaders = function(xhr, stackElement) {
+ /* Here we avoid to call xhr.getResponseHeader in order to */
+ /* prevent polluting the console with CORS security errors */
+ var allHeaders = xhr.getAllResponseHeaders();
+ var ret;
+
+ if (ret = allHeaders.match(/^x-debug-token:\s+(.*)$/im)) {
+ stackElement.profile = ret[1];
+ }
+ if (ret = allHeaders.match(/^x-debug-token-link:\s+(.*)$/im)) {
+ stackElement.profilerUrl = ret[1];
+ }
+ },
+
renderAjaxRequests = function() {
var requestCounter = document.querySelectorAll('.sf-toolbar-ajax-requests');
if (!requestCounter.length) {
@@ -239,8 +253,8 @@
stackElement.duration = new Date() - stackElement.start;
stackElement.loading = false;
stackElement.error = self.status < 200 || self.status >= 400;
- stackElement.profile = self.getResponseHeader("X-Debug-Token");
- stackElement.profilerUrl = self.getResponseHeader("X-Debug-Token-Link");
+
+ extractHeaders(self, stackElement);
Sfjs.renderAjaxRequests();
}
diff --git a/src/Symfony/Component/Asset/Tests/VersionStrategy/StaticVersionStrategyTest.php b/src/Symfony/Component/Asset/Tests/VersionStrategy/StaticVersionStrategyTest.php
new file mode 100644
index 0000000000000..77958ce2ca0cc
--- /dev/null
+++ b/src/Symfony/Component/Asset/Tests/VersionStrategy/StaticVersionStrategyTest.php
@@ -0,0 +1,43 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Asset\Tests\VersionStrategy;
+
+use Symfony\Component\Asset\VersionStrategy\StaticVersionStrategy;
+
+class StaticVersionStrategyTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetVersion()
+ {
+ $version = 'v1';
+ $path = 'test-path';
+ $staticVersionStrategy = new StaticVersionStrategy($version);
+ $this->assertEquals($version, $staticVersionStrategy->getVersion($path));
+ }
+
+ /**
+ * @dataProvider getConfigs
+ */
+ public function testApplyVersion($path, $version, $format)
+ {
+ $staticVersionStrategy = new StaticVersionStrategy($version, $format);
+ $formatted = sprintf($format ?: '%s?%s', $path, $version);
+ $this->assertEquals($formatted, $staticVersionStrategy->applyVersion($path));
+ }
+
+ public function getConfigs()
+ {
+ return array(
+ array('test-path', 'v1', null),
+ array('test-path', 'v2', '%s?test%s'),
+ );
+ }
+}
diff --git a/src/Symfony/Component/BrowserKit/composer.json b/src/Symfony/Component/BrowserKit/composer.json
index 7c0234e1fed7b..344e3e81afed1 100644
--- a/src/Symfony/Component/BrowserKit/composer.json
+++ b/src/Symfony/Component/BrowserKit/composer.json
@@ -17,7 +17,7 @@
],
"require": {
"php": ">=5.3.9",
- "symfony/dom-crawler": "~2.0,>=2.0.5"
+ "symfony/dom-crawler": "~2.1"
},
"require-dev": {
"symfony/process": "~2.3.34|~2.7,>=2.7.6",
diff --git a/src/Symfony/Component/Config/Loader/FileLoader.php b/src/Symfony/Component/Config/Loader/FileLoader.php
index 88ec070f17a80..2b19b52584bdd 100644
--- a/src/Symfony/Component/Config/Loader/FileLoader.php
+++ b/src/Symfony/Component/Config/Loader/FileLoader.php
@@ -113,6 +113,9 @@ public function import($resource, $type = null, $ignoreErrors = false, $sourceRe
} catch (\Exception $e) {
unset(self::$loading[$resource]);
throw $e;
+ } catch (\Throwable $e) {
+ unset(self::$loading[$resource]);
+ throw $e;
}
unset(self::$loading[$resource]);
diff --git a/src/Symfony/Component/Console/Command/Command.php b/src/Symfony/Component/Console/Command/Command.php
index c8b049ce47208..e38002b6d8b39 100644
--- a/src/Symfony/Component/Console/Command/Command.php
+++ b/src/Symfony/Component/Console/Command/Command.php
@@ -297,14 +297,14 @@ public function mergeApplicationDefinition($mergeArgs = true)
return;
}
+ $this->definition->addOptions($this->application->getDefinition()->getOptions());
+
if ($mergeArgs) {
$currentArguments = $this->definition->getArguments();
$this->definition->setArguments($this->application->getDefinition()->getArguments());
$this->definition->addArguments($currentArguments);
}
- $this->definition->addOptions($this->application->getDefinition()->getOptions());
-
$this->applicationDefinitionMerged = true;
if ($mergeArgs) {
$this->applicationDefinitionMergedWithArgs = true;
@@ -598,10 +598,15 @@ public function getUsages()
*
* @return mixed The helper value
*
+ * @throws \LogicException if no HelperSet is defined
* @throws \InvalidArgumentException if the helper is not defined
*/
public function getHelper($name)
{
+ if (null === $this->helperSet) {
+ throw new \LogicException(sprintf('Cannot retrieve helper "%s" because there is no HelperSet defined. Did you forget to add your command to the application or to set the application on the command using the setApplication() method? You can also set the HelperSet directly using the setHelperSet() method.', $name));
+ }
+
return $this->helperSet->get($name);
}
diff --git a/src/Symfony/Component/Console/Helper/Table.php b/src/Symfony/Component/Console/Helper/Table.php
index 3823e9c4f61ca..c4e24a63d916d 100644
--- a/src/Symfony/Component/Console/Helper/Table.php
+++ b/src/Symfony/Component/Console/Helper/Table.php
@@ -257,7 +257,7 @@ private function renderRowSeparator()
*/
private function renderColumnSeparator()
{
- $this->output->write(sprintf($this->style->getBorderFormat(), $this->style->getVerticalBorderChar()));
+ return sprintf($this->style->getBorderFormat(), $this->style->getVerticalBorderChar());
}
/**
@@ -274,12 +274,12 @@ private function renderRow(array $row, $cellFormat)
return;
}
- $this->renderColumnSeparator();
+ $rowContent = $this->renderColumnSeparator();
foreach ($this->getRowColumns($row) as $column) {
- $this->renderCell($row, $column, $cellFormat);
- $this->renderColumnSeparator();
+ $rowContent .= $this->renderCell($row, $column, $cellFormat);
+ $rowContent .= $this->renderColumnSeparator();
}
- $this->output->writeln('');
+ $this->output->writeln($rowContent);
}
/**
@@ -306,12 +306,13 @@ private function renderCell(array $row, $column, $cellFormat)
}
if ($cell instanceof TableSeparator) {
- $this->output->write(sprintf($this->style->getBorderFormat(), str_repeat($this->style->getHorizontalBorderChar(), $width)));
- } else {
- $width += Helper::strlen($cell) - Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
- $content = sprintf($this->style->getCellRowContentFormat(), $cell);
- $this->output->write(sprintf($cellFormat, str_pad($content, $width, $this->style->getPaddingChar(), $this->style->getPadType())));
+ return sprintf($this->style->getBorderFormat(), str_repeat($this->style->getHorizontalBorderChar(), $width));
}
+
+ $width += Helper::strlen($cell) - Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
+ $content = sprintf($this->style->getCellRowContentFormat(), $cell);
+
+ return sprintf($cellFormat, str_pad($content, $width, $this->style->getPaddingChar(), $this->style->getPadType()));
}
/**
@@ -521,6 +522,18 @@ private function getColumnWidth($column)
continue;
}
+ foreach ($row as $i => $cell) {
+ if ($cell instanceof TableCell) {
+ $textLength = strlen($cell);
+ if ($textLength > 0) {
+ $contentColumns = str_split($cell, ceil($textLength / $cell->getColspan()));
+ foreach ($contentColumns as $position => $content) {
+ $row[$i + $position] = $content;
+ }
+ }
+ }
+ }
+
$lengths[] = $this->getCellWidth($row, $column);
}
@@ -550,10 +563,6 @@ private function getCellWidth(array $row, $column)
if (isset($row[$column])) {
$cell = $row[$column];
$cellWidth = Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
- if ($cell instanceof TableCell && $cell->getColspan() > 1) {
- // we assume that cell value will be across more than one column.
- $cellWidth = $cellWidth / $cell->getColspan();
- }
return $cellWidth;
}
diff --git a/src/Symfony/Component/Console/Output/StreamOutput.php b/src/Symfony/Component/Console/Output/StreamOutput.php
index 80c352a278671..f3708ecffe526 100644
--- a/src/Symfony/Component/Console/Output/StreamOutput.php
+++ b/src/Symfony/Component/Console/Output/StreamOutput.php
@@ -70,7 +70,7 @@ public function getStream()
*/
protected function doWrite($message, $newline)
{
- if (false === @fwrite($this->stream, $message.($newline ? PHP_EOL : ''))) {
+ if (false === @fwrite($this->stream, $message) || ($newline && (false === @fwrite($this->stream, PHP_EOL)))) {
// should never happen
throw new \RuntimeException('Unable to write output.');
}
diff --git a/src/Symfony/Component/Console/Style/SymfonyStyle.php b/src/Symfony/Component/Console/Style/SymfonyStyle.php
index 21fc3b92cfee0..03550836cfae8 100644
--- a/src/Symfony/Component/Console/Style/SymfonyStyle.php
+++ b/src/Symfony/Component/Console/Style/SymfonyStyle.php
@@ -67,23 +67,36 @@ public function block($messages, $type = null, $style = null, $prefix = ' ', $pa
{
$this->autoPrependBlock();
$messages = is_array($messages) ? array_values($messages) : array($messages);
+ $indentLength = 0;
$lines = array();
- // add type
if (null !== $type) {
- $messages[0] = sprintf('[%s] %s', $type, $messages[0]);
+ $typePrefix = sprintf('[%s] ', $type);
+ $indentLength = strlen($typePrefix);
+ $lineIndentation = str_repeat(' ', $indentLength);
}
// wrap and add newlines for each element
foreach ($messages as $key => $message) {
$message = OutputFormatter::escape($message);
- $lines = array_merge($lines, explode(PHP_EOL, wordwrap($message, $this->lineLength - Helper::strlen($prefix), PHP_EOL, true)));
+ $lines = array_merge($lines, explode(PHP_EOL, wordwrap($message, $this->lineLength - Helper::strlen($prefix) - $indentLength, PHP_EOL, true)));
+
+ // prefix each line with a number of spaces equivalent to the type length
+ if (null !== $type) {
+ foreach ($lines as &$line) {
+ $line = $lineIndentation === substr($line, 0, $indentLength) ? $line : $lineIndentation.$line;
+ }
+ }
if (count($messages) > 1 && $key < count($messages) - 1) {
$lines[] = '';
}
}
+ if (null !== $type) {
+ $lines[0] = substr_replace($lines[0], $typePrefix, 0, $indentLength);
+ }
+
if ($padding && $this->isDecorated()) {
array_unshift($lines, '');
$lines[] = '';
diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php
index a59601f600a0b..7a4079eddffaf 100644
--- a/src/Symfony/Component/Console/Tests/ApplicationTest.php
+++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php
@@ -730,6 +730,33 @@ public function testRunReturnsExitCodeOneForExceptionCodeZero()
$this->assertSame(1, $exitCode, '->run() returns exit code 1 when exception code is 0');
}
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage An option with shortcut "e" already exists.
+ */
+ public function testAddingOptionWithDuplicateShortcut()
+ {
+ $dispatcher = new EventDispatcher();
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+ $application->setDispatcher($dispatcher);
+
+ $application->getDefinition()->addOption(new InputOption('--env', '-e', InputOption::VALUE_REQUIRED, 'Environment'));
+
+ $application
+ ->register('foo')
+ ->setAliases(array('f'))
+ ->setDefinition(array(new InputOption('survey', 'e', InputOption::VALUE_REQUIRED, 'My option with a shortcut.')))
+ ->setCode(function (InputInterface $input, OutputInterface $output) {})
+ ;
+
+ $input = new ArrayInput(array('command' => 'foo'));
+ $output = new NullOutput();
+
+ $application->run($input, $output);
+ }
+
/**
* @expectedException \LogicException
* @dataProvider getAddingAlreadySetDefinitionElementData
diff --git a/src/Symfony/Component/Console/Tests/Command/CommandTest.php b/src/Symfony/Component/Console/Tests/Command/CommandTest.php
index 4c174e804a733..695759cb9d57c 100644
--- a/src/Symfony/Component/Console/Tests/Command/CommandTest.php
+++ b/src/Symfony/Component/Console/Tests/Command/CommandTest.php
@@ -173,6 +173,16 @@ public function testGetHelper()
$this->assertEquals($formatterHelper->getName(), $command->getHelper('formatter')->getName(), '->getHelper() returns the correct helper');
}
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage Cannot retrieve helper "formatter" because there is no HelperSet defined.
+ */
+ public function testGetHelperWithoutHelperSet()
+ {
+ $command = new \TestCommand();
+ $command->getHelper('formatter');
+ }
+
public function testMergeApplicationDefinition()
{
$application1 = new Application();
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/command_10.php b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/command_10.php
new file mode 100644
index 0000000000000..4120df9cb6b64
--- /dev/null
+++ b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/command_10.php
@@ -0,0 +1,17 @@
+block(
+ 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum',
+ 'CUSTOM',
+ 'fg=white;bg=green',
+ 'X ',
+ true
+ );
+};
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/command_9.php b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/command_9.php
new file mode 100644
index 0000000000000..6420730fd64ad
--- /dev/null
+++ b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/command/command_9.php
@@ -0,0 +1,11 @@
+block(array('Custom block', 'Second custom block line'), 'CUSTOM', 'fg=white;bg=green', 'X ', true);
+};
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_10.txt b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_10.txt
new file mode 100644
index 0000000000000..385c6a283c84d
--- /dev/null
+++ b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_10.txt
@@ -0,0 +1,7 @@
+
+X [CUSTOM] Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
+X dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
+X commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
+X nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit
+X anim id est laborum
+
diff --git a/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_9.txt b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_9.txt
new file mode 100644
index 0000000000000..069c0d5119f7b
--- /dev/null
+++ b/src/Symfony/Component/Console/Tests/Fixtures/Style/SymfonyStyle/output/output_9.txt
@@ -0,0 +1,5 @@
+
+X [CUSTOM] Custom block
+X
+X Second custom block line
+
diff --git a/src/Symfony/Component/Console/Tests/Helper/TableTest.php b/src/Symfony/Component/Console/Tests/Helper/TableTest.php
index ab562fdb57708..c933ff6a69760 100644
--- a/src/Symfony/Component/Console/Tests/Helper/TableTest.php
+++ b/src/Symfony/Component/Console/Tests/Helper/TableTest.php
@@ -269,21 +269,27 @@ public function testRenderProvider()
'9971-5-0210-0',
new TableCell("A Tale of \nTwo Cities", array('colspan' => 2)),
),
+ new TableSeparator(),
+ array(
+ new TableCell('Cupiditate dicta atque porro, tempora exercitationem modi animi nulla nemo vel nihil!', array('colspan' => 3)),
+ ),
),
'default',
<<
isRecursive = false;
+ throw $e;
+ } catch (\Throwable $e) {
+ $this->isRecursive = false;
+
throw $e;
}
}
@@ -469,7 +473,7 @@ public function handleException($exception, array $error = null)
}
$type = $exception instanceof FatalErrorException ? $exception->getSeverity() : E_ERROR;
- if ($this->loggedErrors & $type) {
+ if (($this->loggedErrors & $type) || $exception instanceof FatalThrowableError) {
$e = array(
'type' => $type,
'file' => $exception->getFile(),
@@ -496,9 +500,9 @@ public function handleException($exception, array $error = null)
} else {
$message = 'Uncaught Exception: '.$exception->getMessage();
}
- if ($this->loggedErrors & $e['type']) {
- $this->loggers[$e['type']][0]->log($this->loggers[$e['type']][1], $message, $e);
- }
+ }
+ if ($this->loggedErrors & $type) {
+ $this->loggers[$type][0]->log($this->loggers[$type][1], $message, $e);
}
if ($exception instanceof FatalErrorException && !$exception instanceof OutOfMemoryException && $error) {
foreach ($this->getFatalErrorHandlers() as $handler) {
@@ -555,6 +559,8 @@ public static function handleFatalError(array $error = null)
}
} catch (\Exception $exception) {
// Handled below
+ } catch (\Throwable $exception) {
+ // Handled below
}
if ($error && $error['type'] &= E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR) {
diff --git a/src/Symfony/Component/Debug/Exception/FatalThrowableError.php b/src/Symfony/Component/Debug/Exception/FatalThrowableError.php
index 6ff5ecdaffed0..34f43b17b13b4 100644
--- a/src/Symfony/Component/Debug/Exception/FatalThrowableError.php
+++ b/src/Symfony/Component/Debug/Exception/FatalThrowableError.php
@@ -27,7 +27,7 @@ public function __construct(\Throwable $e)
$message = 'Type error: '.$e->getMessage();
$severity = E_RECOVERABLE_ERROR;
} else {
- $message = 'Fatal error: '.$e->getMessage();
+ $message = $e->getMessage();
$severity = E_ERROR;
}
diff --git a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php
index c107c0c7cb56b..f3b7701c3f738 100644
--- a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php
+++ b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php
@@ -413,6 +413,24 @@ public function testHandleFatalError()
}
}
+ /**
+ * @requires PHP 7
+ */
+ public function testHandleErrorException()
+ {
+ $exception = new \Error("Class 'Foo' not found");
+
+ $handler = new ErrorHandler();
+ $handler->setExceptionHandler(function () use (&$args) {
+ $args = func_get_args();
+ });
+
+ $handler->handleException($exception);
+
+ $this->assertInstanceOf('Symfony\Component\Debug\Exception\ClassNotFoundException', $args[0]);
+ $this->assertStringStartsWith("Attempted to load class \"Foo\" from the global namespace.\nDid you forget a \"use\" statement", $args[0]->getMessage());
+ }
+
public function testHandleFatalErrorOnHHVM()
{
try {
diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php
index 553f9120e1385..3ecf81635a911 100644
--- a/src/Symfony/Component/DependencyInjection/Container.php
+++ b/src/Symfony/Component/DependencyInjection/Container.php
@@ -313,6 +313,11 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE
return;
}
+ throw $e;
+ } catch (\Throwable $e) {
+ unset($this->loading[$id]);
+ unset($this->services[$id]);
+
throw $e;
}
diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
index 15284a905033e..b2e97841819b4 100644
--- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
+++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
@@ -461,6 +461,10 @@ public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INV
return;
}
+ throw $e;
+ } catch (\Throwable $e) {
+ unset($this->loading[$id]);
+
throw $e;
}
diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
index 1c2efe587478f..aa1257d845c1f 100644
--- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
+++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
@@ -1268,7 +1268,7 @@ private function hasReference($id, array $arguments, $deep = false, array &$visi
return true;
}
- if ($deep && !isset($visited[$argumentId])) {
+ if ($deep && !isset($visited[$argumentId]) && 'service_container' !== $argumentId) {
$visited[$argumentId] = true;
$service = $this->container->getDefinition($argumentId);
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
index afe2f10ff50f0..562b94e21e94c 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
@@ -256,4 +256,15 @@ public function testCircularReference()
$dumper = new PhpDumper($container);
$dumper->dump();
}
+
+ public function testInlinedDefinitionReferencingServiceContainer()
+ {
+ $container = new ContainerBuilder();
+ $container->register('foo', 'stdClass')->addMethodCall('add', array(new Reference('service_container')))->setPublic(false);
+ $container->register('bar', 'stdClass')->addArgument(new Reference('foo'));
+ $container->compile();
+
+ $dumper = new PhpDumper($container);
+ $this->assertStringEqualsFile(self::$fixturesPath.'/php/services13.php', $dumper->dump(), '->dump() dumps inline definitions which reference service_container');
+ }
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services13.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services13.php
new file mode 100644
index 0000000000000..f6038f390367e
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services13.php
@@ -0,0 +1,62 @@
+services =
+ $this->scopedServices =
+ $this->scopeStacks = array();
+ $this->scopes = array();
+ $this->scopeChildren = array();
+ $this->methodMap = array(
+ 'bar' => 'getBarService',
+ );
+
+ $this->aliases = array();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function compile()
+ {
+ throw new LogicException('You cannot compile a dumped frozen container.');
+ }
+
+ /**
+ * Gets the 'bar' service.
+ *
+ * This service is shared.
+ * This method always returns the same instance of the service.
+ *
+ * @return \stdClass A stdClass instance.
+ */
+ protected function getBarService()
+ {
+ $a = new \stdClass();
+ $a->add($this);
+
+ return $this->services['bar'] = new \stdClass($a);
+ }
+}
diff --git a/src/Symfony/Component/EventDispatcher/GenericEvent.php b/src/Symfony/Component/EventDispatcher/GenericEvent.php
index 6458180a5aac3..03cbcfe33414e 100644
--- a/src/Symfony/Component/EventDispatcher/GenericEvent.php
+++ b/src/Symfony/Component/EventDispatcher/GenericEvent.php
@@ -61,9 +61,9 @@ public function getSubject()
*
* @param string $key Key.
*
- * @throws \InvalidArgumentException If key is not found.
- *
* @return mixed Contents of array key.
+ *
+ * @throws \InvalidArgumentException If key is not found.
*/
public function getArgument($key)
{
@@ -130,9 +130,9 @@ public function hasArgument($key)
*
* @param string $key Array key.
*
- * @throws \InvalidArgumentException If key does not exist in $this->args.
- *
* @return mixed
+ *
+ * @throws \InvalidArgumentException If key does not exist in $this->args.
*/
public function offsetGet($key)
{
diff --git a/src/Symfony/Component/Finder/Expression/Expression.php b/src/Symfony/Component/Finder/Expression/Expression.php
index 900260751ee4e..a4f1f219a8ec2 100644
--- a/src/Symfony/Component/Finder/Expression/Expression.php
+++ b/src/Symfony/Component/Finder/Expression/Expression.php
@@ -123,9 +123,9 @@ public function isGlob()
}
/**
- * @throws \LogicException
- *
* @return Glob
+ *
+ * @throws \LogicException
*/
public function getGlob()
{
diff --git a/src/Symfony/Component/Finder/Finder.php b/src/Symfony/Component/Finder/Finder.php
index ab9d08873dff7..c83a024eabfd3 100644
--- a/src/Symfony/Component/Finder/Finder.php
+++ b/src/Symfony/Component/Finder/Finder.php
@@ -128,9 +128,9 @@ public function useBestAdapter()
*
* @param string $name
*
- * @throws \InvalidArgumentException
- *
* @return Finder The current Finder instance
+ *
+ * @throws \InvalidArgumentException
*/
public function setAdapter($name)
{
@@ -171,7 +171,7 @@ public function getAdapters()
/**
* Restricts the matching to directories only.
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*/
public function directories()
{
@@ -183,7 +183,7 @@ public function directories()
/**
* Restricts the matching to files only.
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*/
public function files()
{
@@ -202,7 +202,7 @@ public function files()
*
* @param int $level The depth level expression
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @see DepthRangeFilterIterator
* @see NumberComparator
@@ -226,7 +226,7 @@ public function depth($level)
*
* @param string $date A date range string
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @see strtotime
* @see DateRangeFilterIterator
@@ -250,7 +250,7 @@ public function date($date)
*
* @param string $pattern A pattern (a regexp, a glob, or a string)
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @see FilenameFilterIterator
*/
@@ -266,7 +266,7 @@ public function name($pattern)
*
* @param string $pattern A pattern (a regexp, a glob, or a string)
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @see FilenameFilterIterator
*/
@@ -287,7 +287,7 @@ public function notName($pattern)
*
* @param string $pattern A pattern (string or regexp)
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @see FilecontentFilterIterator
*/
@@ -308,7 +308,7 @@ public function contains($pattern)
*
* @param string $pattern A pattern (string or regexp)
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @see FilecontentFilterIterator
*/
@@ -331,7 +331,7 @@ public function notContains($pattern)
*
* @param string $pattern A pattern (a regexp or a string)
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @see FilenameFilterIterator
*/
@@ -354,7 +354,7 @@ public function path($pattern)
*
* @param string $pattern A pattern (a regexp or a string)
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @see FilenameFilterIterator
*/
@@ -374,7 +374,7 @@ public function notPath($pattern)
*
* @param string $size A size range string
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @see SizeRangeFilterIterator
* @see NumberComparator
@@ -391,7 +391,7 @@ public function size($size)
*
* @param string|array $dirs A directory path or an array of directories
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @see ExcludeDirectoryFilterIterator
*/
@@ -407,7 +407,7 @@ public function exclude($dirs)
*
* @param bool $ignoreDotFiles Whether to exclude "hidden" files or not
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @see ExcludeDirectoryFilterIterator
*/
@@ -427,7 +427,7 @@ public function ignoreDotFiles($ignoreDotFiles)
*
* @param bool $ignoreVCS Whether to exclude VCS files or not
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @see ExcludeDirectoryFilterIterator
*/
@@ -467,7 +467,7 @@ public static function addVCSPattern($pattern)
*
* @param \Closure $closure An anonymous function
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @see SortableIterator
*/
@@ -483,7 +483,7 @@ public function sort(\Closure $closure)
*
* This can be slow as all the matching files and directories must be retrieved for comparison.
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @see SortableIterator
*/
@@ -499,7 +499,7 @@ public function sortByName()
*
* This can be slow as all the matching files and directories must be retrieved for comparison.
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @see SortableIterator
*/
@@ -517,7 +517,7 @@ public function sortByType()
*
* This can be slow as all the matching files and directories must be retrieved for comparison.
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @see SortableIterator
*/
@@ -537,7 +537,7 @@ public function sortByAccessedTime()
*
* This can be slow as all the matching files and directories must be retrieved for comparison.
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @see SortableIterator
*/
@@ -555,7 +555,7 @@ public function sortByChangedTime()
*
* This can be slow as all the matching files and directories must be retrieved for comparison.
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @see SortableIterator
*/
@@ -574,7 +574,7 @@ public function sortByModifiedTime()
*
* @param \Closure $closure An anonymous function
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @see CustomFilterIterator
*/
@@ -588,7 +588,7 @@ public function filter(\Closure $closure)
/**
* Forces the following of symlinks.
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*/
public function followLinks()
{
@@ -604,7 +604,7 @@ public function followLinks()
*
* @param bool $ignore
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*/
public function ignoreUnreadableDirs($ignore = true)
{
@@ -618,7 +618,7 @@ public function ignoreUnreadableDirs($ignore = true)
*
* @param string|array $dirs A directory path or an array of directories
*
- * @return Finder The current Finder instance
+ * @return Finder|SplFileInfo[] The current Finder instance
*
* @throws \InvalidArgumentException if one of the directories does not exist
*/
@@ -679,7 +679,7 @@ public function getIterator()
*
* @param mixed $iterator
*
- * @return Finder The finder
+ * @return Finder|SplFileInfo[] The finder
*
* @throws \InvalidArgumentException When the given argument is not iterable.
*/
diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php
index b38680a1bb6ec..5418f7feae919 100644
--- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php
+++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php
@@ -126,7 +126,7 @@ public function reverseTransform($value)
try {
// read timestamp into DateTime object - the formatter delivers in UTC
- $dateTime = new \DateTime(sprintf('@%s UTC', $timestamp));
+ $dateTime = new \DateTime(sprintf('@%s', $timestamp));
} catch (\Exception $e) {
throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
}
diff --git a/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php b/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php
index d3ba9cf7bf23b..304ec17e1a493 100644
--- a/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php
+++ b/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php
@@ -162,9 +162,7 @@ private function matchChild(FormInterface $form, PropertyPathIteratorInterface $
}
}
- $children = iterator_to_array(new \RecursiveIteratorIterator(
- new InheritDataAwareIterator($form)
- ));
+ $children = iterator_to_array(new \RecursiveIteratorIterator(new InheritDataAwareIterator($form)), false);
while ($it->valid()) {
if ($it->isIndex()) {
@@ -189,7 +187,7 @@ private function matchChild(FormInterface $form, PropertyPathIteratorInterface $
}
/** @var FormInterface $child */
- foreach ($children as $key => $child) {
+ foreach ($children as $i => $child) {
$childPath = (string) $child->getPropertyPath();
if ($childPath === $chunk) {
$target = $child;
@@ -198,7 +196,7 @@ private function matchChild(FormInterface $form, PropertyPathIteratorInterface $
continue;
}
- unset($children[$key]);
+ unset($children[$i]);
}
$it->next();
diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php
index 47c38c5718b06..a395f427087b2 100644
--- a/src/Symfony/Component/Form/Form.php
+++ b/src/Symfony/Component/Form/Form.php
@@ -1072,9 +1072,9 @@ public function createView(FormView $parent = null)
*
* @param mixed $value The value to transform
*
- * @throws TransformationFailedException If the value cannot be transformed to "normalized" format
- *
* @return mixed
+ *
+ * @throws TransformationFailedException If the value cannot be transformed to "normalized" format
*/
private function modelToNorm($value)
{
@@ -1098,9 +1098,9 @@ private function modelToNorm($value)
*
* @param string $value The value to reverse transform
*
- * @throws TransformationFailedException If the value cannot be transformed to "model" format
- *
* @return mixed
+ *
+ * @throws TransformationFailedException If the value cannot be transformed to "model" format
*/
private function normToModel($value)
{
@@ -1126,9 +1126,9 @@ private function normToModel($value)
*
* @param mixed $value The value to transform
*
- * @throws TransformationFailedException If the value cannot be transformed to "view" format
- *
* @return mixed
+ *
+ * @throws TransformationFailedException If the value cannot be transformed to "view" format
*/
private function normToView($value)
{
@@ -1161,9 +1161,9 @@ private function normToView($value)
*
* @param string $value The value to reverse transform
*
- * @throws TransformationFailedException If the value cannot be transformed to "normalized" format
- *
* @return mixed
+ *
+ * @throws TransformationFailedException If the value cannot be transformed to "normalized" format
*/
private function viewToNorm($value)
{
diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php
index a099e104595ff..74da4aee1c281 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php
@@ -1542,24 +1542,39 @@ public function testErrorMappingForFormInheritingParentData($target, $childName,
public function testBacktrackIfSeveralSubFormsWithSamePropertyPath()
{
- $violation = $this->getConstraintViolation('data.address[street]');
$parent = $this->getForm('parent');
$child1 = $this->getForm('subform1', 'address');
$child2 = $this->getForm('subform2', 'address');
- $grandChild = $this->getForm('street');
+ $child3 = $this->getForm('subform3', null, null, array(), true);
+ $child4 = $this->getForm('subform4', null, null, array(), true);
+ $grandChild1 = $this->getForm('street');
+ $grandChild2 = $this->getForm('street', '[sub_address1_street]');
+ $grandChild3 = $this->getForm('street', '[sub_address2_street]');
$parent->add($child1);
$parent->add($child2);
- $child2->add($grandChild);
+ $parent->add($child3);
+ $parent->add($child4);
+ $child2->add($grandChild1);
+ $child3->add($grandChild2);
+ $child4->add($grandChild3);
$parent->submit(array());
- $this->mapper->mapViolation($violation, $parent);
+ $violation1 = $this->getConstraintViolation('data.address[street]');
+ $violation2 = $this->getConstraintViolation('data[sub_address1_street]');
+ $violation3 = $this->getConstraintViolation('data[sub_address2_street]');
+ $this->mapper->mapViolation($violation1, $parent);
+ $this->mapper->mapViolation($violation2, $parent);
+ $this->mapper->mapViolation($violation3, $parent);
- // The error occurred on the child of the second form with the same path
$this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one');
$this->assertCount(0, $child1->getErrors(), $child1->getName().' should not have an error, but has one');
$this->assertCount(0, $child2->getErrors(), $child2->getName().' should not have an error, but has one');
- $this->assertEquals(array($this->getFormError($violation, $grandChild)), iterator_to_array($grandChild->getErrors()), $grandChild->getName().' should have an error, but has none');
+ $this->assertCount(0, $child3->getErrors(), $child3->getName().' should not have an error, but has one');
+ $this->assertCount(0, $child4->getErrors(), $child4->getName().' should not have an error, but has one');
+ $this->assertEquals(array($this->getFormError($violation1, $grandChild1)), iterator_to_array($grandChild1->getErrors()), $grandChild1->getName().' should have an error, but has none');
+ $this->assertEquals(array($this->getFormError($violation2, $grandChild2)), iterator_to_array($grandChild2->getErrors()), $grandChild2->getName().' should have an error, but has none');
+ $this->assertEquals(array($this->getFormError($violation3, $grandChild3)), iterator_to_array($grandChild3->getErrors()), $grandChild3->getName().' should have an error, but has none');
}
}
diff --git a/src/Symfony/Component/HttpFoundation/Response.php b/src/Symfony/Component/HttpFoundation/Response.php
index d4b8b2718aacc..62b67cce85744 100644
--- a/src/Symfony/Component/HttpFoundation/Response.php
+++ b/src/Symfony/Component/HttpFoundation/Response.php
@@ -59,6 +59,7 @@ class Response
const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
const HTTP_EXPECTATION_FAILED = 417;
const HTTP_I_AM_A_TEAPOT = 418; // RFC2324
+ const HTTP_MISDIRECTED_REQUEST = 421; // RFC7540
const HTTP_UNPROCESSABLE_ENTITY = 422; // RFC4918
const HTTP_LOCKED = 423; // RFC4918
const HTTP_FAILED_DEPENDENCY = 424; // RFC4918
@@ -115,7 +116,7 @@ class Response
*
* The list of codes is complete according to the
* {@link http://www.iana.org/assignments/http-status-codes/ Hypertext Transfer Protocol (HTTP) Status Code Registry}
- * (last updated 2012-02-13).
+ * (last updated 2016-03-01).
*
* Unless otherwise noted, the status code is defined in RFC2616.
*
@@ -163,6 +164,7 @@ class Response
416 => 'Requested Range Not Satisfiable',
417 => 'Expectation Failed',
418 => 'I\'m a teapot', // RFC2324
+ 421 => 'Misdirected Request', // RFC7540
422 => 'Unprocessable Entity', // RFC4918
423 => 'Locked', // RFC4918
424 => 'Failed Dependency', // RFC4918
diff --git a/src/Symfony/Component/HttpFoundation/ResponseHeaderBag.php b/src/Symfony/Component/HttpFoundation/ResponseHeaderBag.php
index 06534aa75bf39..1d26e86b9b17b 100644
--- a/src/Symfony/Component/HttpFoundation/ResponseHeaderBag.php
+++ b/src/Symfony/Component/HttpFoundation/ResponseHeaderBag.php
@@ -181,9 +181,9 @@ public function removeCookie($name, $path = '/', $domain = null)
*
* @param string $format
*
- * @throws \InvalidArgumentException When the $format is invalid
- *
* @return array
+ *
+ * @throws \InvalidArgumentException When the $format is invalid
*/
public function getCookies($format = self::COOKIES_FLAT)
{
diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/SessionStorageInterface.php b/src/Symfony/Component/HttpFoundation/Session/Storage/SessionStorageInterface.php
index 4b2f5d27aab41..206f18e77f8d9 100644
--- a/src/Symfony/Component/HttpFoundation/Session/Storage/SessionStorageInterface.php
+++ b/src/Symfony/Component/HttpFoundation/Session/Storage/SessionStorageInterface.php
@@ -24,9 +24,9 @@ interface SessionStorageInterface
/**
* Starts the session.
*
- * @throws \RuntimeException If something goes wrong starting the session.
- *
* @return bool True if started.
+ *
+ * @throws \RuntimeException If something goes wrong starting the session.
*/
public function start();
diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcacheSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcacheSessionHandlerTest.php
index e8795244b176e..0c579d7724846 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcacheSessionHandlerTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcacheSessionHandlerTest.php
@@ -30,6 +30,10 @@ class MemcacheSessionHandlerTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
+ if (defined('HHVM_VERSION')) {
+ $this->markTestSkipped('PHPUnit_MockObject cannot mock the Memcache class on HHVM. See https://github.com/sebastianbergmann/phpunit-mock-objects/pull/289');
+ }
+
parent::setUp();
$this->memcache = $this->getMock('Memcache');
$this->storage = new MemcacheSessionHandler(
diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php
index f51ec8ed63c86..75e4a20e2a8d5 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php
@@ -31,6 +31,10 @@ class MemcachedSessionHandlerTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
+ if (defined('HHVM_VERSION')) {
+ $this->markTestSkipped('PHPUnit_MockObject cannot mock the Memcached class on HHVM. See https://github.com/sebastianbergmann/phpunit-mock-objects/pull/289');
+ }
+
parent::setUp();
if (version_compare(phpversion('memcached'), '2.2.0', '>=')) {
diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php
index 1af321096ebad..9612320976944 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php
@@ -135,6 +135,10 @@ public function testReadWriteReadWithNullByte()
public function testReadConvertsStreamToString()
{
+ if (defined('HHVM_VERSION')) {
+ $this->markTestSkipped('PHPUnit_MockObject cannot mock the PDOStatement class on HHVM. See https://github.com/sebastianbergmann/phpunit-mock-objects/pull/289');
+ }
+
$pdo = new MockPdo('pgsql');
$pdo->prepareResult = $this->getMock('PDOStatement');
@@ -152,6 +156,10 @@ public function testReadConvertsStreamToString()
public function testReadLockedConvertsStreamToString()
{
+ if (defined('HHVM_VERSION')) {
+ $this->markTestSkipped('PHPUnit_MockObject cannot mock the PDOStatement class on HHVM. See https://github.com/sebastianbergmann/phpunit-mock-objects/pull/289');
+ }
+
$pdo = new MockPdo('pgsql');
$selectStmt = $this->getMock('PDOStatement');
$insertStmt = $this->getMock('PDOStatement');
diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php b/src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php
index 97aa740962665..4b3e218b85c58 100644
--- a/src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php
+++ b/src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php
@@ -71,6 +71,11 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ
$this->container->set('request', null, 'request');
$this->container->leaveScope('request');
+ throw $e;
+ } catch (\Throwable $e) {
+ $this->container->set('request', null, 'request');
+ $this->container->leaveScope('request');
+
throw $e;
}
diff --git a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php
index 6075d235b6d83..f794d94e29d45 100644
--- a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php
+++ b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php
@@ -153,9 +153,9 @@ public function getKernel()
/**
* Gets the Surrogate instance.
*
- * @throws \LogicException
- *
* @return SurrogateInterface A Surrogate instance
+ *
+ * @throws \LogicException
*/
public function getSurrogate()
{
@@ -169,10 +169,10 @@ public function getSurrogate()
/**
* Gets the Esi instance.
*
- * @throws \LogicException
- *
* @return Esi An Esi instance
*
+ * @throws \LogicException
+ *
* @deprecated since version 2.6, to be removed in 3.0. Use getSurrogate() instead
*/
public function getEsi()
diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php
index c348cac299911..47d3dc268683a 100644
--- a/src/Symfony/Component/HttpKernel/Kernel.php
+++ b/src/Symfony/Component/HttpKernel/Kernel.php
@@ -58,11 +58,11 @@ abstract class Kernel implements KernelInterface, TerminableInterface
protected $startTime;
protected $loadClassCache;
- const VERSION = '2.7.13';
- const VERSION_ID = 20713;
+ const VERSION = '2.7.14';
+ const VERSION_ID = 20714;
const MAJOR_VERSION = 2;
const MINOR_VERSION = 7;
- const RELEASE_VERSION = 13;
+ const RELEASE_VERSION = 14;
const EXTRA_VERSION = '';
const END_OF_MAINTENANCE = '05/2018';
diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php
index 7fc127e49b647..101782e49079e 100644
--- a/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php
@@ -127,7 +127,7 @@ public function getUndefinedControllers()
{
return array(
array('foo'),
- array('foo::bar'),
+ array('oof::bar'),
array('stdClass'),
array('Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest::bar'),
);
diff --git a/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php b/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php
index e9b8433c46ef5..8675622891c87 100644
--- a/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/DataCollector/DumpDataCollectorTest.php
@@ -128,7 +128,7 @@ public function testFlush()
$line = __LINE__ - 1;
ob_start();
- $collector = null;
+ $collector->__destruct();
if (PHP_VERSION_ID >= 50400) {
$this->assertSame("DumpDataCollectorTest.php on line {$line}:\n456\n", ob_get_clean());
} else {
diff --git a/src/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php b/src/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php
index faaa95973045b..86d8efee8537d 100644
--- a/src/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php
+++ b/src/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php
@@ -326,7 +326,7 @@ public static function create($locale = 'en', $style = null, $pattern = null)
* @return string The formatted currency value
*
* @see http://www.php.net/manual/en/numberformatter.formatcurrency.php
- * @see http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/currency_codes_list-1.htm
+ * @see https://en.wikipedia.org/wiki/ISO_4217#Active_codes
*/
public function formatCurrency($value, $currency)
{
diff --git a/src/Symfony/Component/OptionsResolver/OptionsResolver.php b/src/Symfony/Component/OptionsResolver/OptionsResolver.php
index e0578af71781d..bc763202f228a 100644
--- a/src/Symfony/Component/OptionsResolver/OptionsResolver.php
+++ b/src/Symfony/Component/OptionsResolver/OptionsResolver.php
@@ -861,6 +861,9 @@ public function offsetGet($option)
} catch (\Exception $e) {
unset($this->calling[$option]);
throw $e;
+ } catch (\Throwable $e) {
+ unset($this->calling[$option]);
+ throw $e;
}
unset($this->calling[$option]);
// END
@@ -963,6 +966,9 @@ public function offsetGet($option)
} catch (\Exception $e) {
unset($this->calling[$option]);
throw $e;
+ } catch (\Throwable $e) {
+ unset($this->calling[$option]);
+ throw $e;
}
unset($this->calling[$option]);
// END
diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php
index 08742df2d9c85..67ea6545891f6 100644
--- a/src/Symfony/Component/Process/Process.php
+++ b/src/Symfony/Component/Process/Process.php
@@ -477,10 +477,10 @@ public function getOutput()
* In comparison with the getOutput method which always return the whole
* output, this one returns the new output since the last call.
*
+ * @return string The process output since the last call
+ *
* @throws LogicException in case the output has been disabled
* @throws LogicException In case the process is not started
- *
- * @return string The process output since the last call
*/
public function getIncrementalOutput()
{
@@ -536,10 +536,10 @@ public function getErrorOutput()
* whole error output, this one returns the new error output since the last
* call.
*
+ * @return string The process error output since the last call
+ *
* @throws LogicException in case the output has been disabled
* @throws LogicException In case the process is not started
- *
- * @return string The process error output since the last call
*/
public function getIncrementalErrorOutput()
{
diff --git a/src/Symfony/Component/PropertyAccess/StringUtil.php b/src/Symfony/Component/PropertyAccess/StringUtil.php
index 248a6483d8b0a..caa8c3d7e1a0d 100644
--- a/src/Symfony/Component/PropertyAccess/StringUtil.php
+++ b/src/Symfony/Component/PropertyAccess/StringUtil.php
@@ -124,6 +124,9 @@ class StringUtil
// chateaux (chateau)
array('xuae', 4, false, true, 'eau'),
+
+ // people (person)
+ array('elpoep', 6, true, true, 'person'),
);
/**
diff --git a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php
index f3c7b405c1758..3f1ef1c040a6a 100644
--- a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php
+++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php
@@ -242,7 +242,9 @@ public function testSetValueThrowsNoExceptionIfIndexNotFoundAndIndexExceptionsEn
*/
public function testSetValueThrowsExceptionIfNotArrayAccess()
{
- $this->propertyAccessor->setValue(new \stdClass(), '[index]', 'Updated');
+ $object = new \stdClass();
+
+ $this->propertyAccessor->setValue($object, '[index]', 'Updated');
}
public function testSetValueUpdatesMagicSet()
@@ -259,7 +261,9 @@ public function testSetValueUpdatesMagicSet()
*/
public function testSetValueThrowsExceptionIfThereAreMissingParameters()
{
- $this->propertyAccessor->setValue(new TestClass('Bernhard'), 'publicAccessorWithMoreRequiredParameters', 'Updated');
+ $object = new TestClass('Bernhard');
+
+ $this->propertyAccessor->setValue($object, 'publicAccessorWithMoreRequiredParameters', 'Updated');
}
/**
@@ -527,7 +531,9 @@ public function testIsWritableForReferenceChainIssue($object, $path, $value)
*/
public function testThrowTypeError()
{
- $this->propertyAccessor->setValue(new TypeHinted(), 'date', 'This is a string, \DateTime expected.');
+ $object = new TypeHinted();
+
+ $this->propertyAccessor->setValue($object, 'date', 'This is a string, \DateTime expected.');
}
public function testSetTypeHint()
diff --git a/src/Symfony/Component/PropertyAccess/Tests/StringUtilTest.php b/src/Symfony/Component/PropertyAccess/Tests/StringUtilTest.php
index 0fd6bb69b2956..983e355cb9038 100644
--- a/src/Symfony/Component/PropertyAccess/Tests/StringUtilTest.php
+++ b/src/Symfony/Component/PropertyAccess/Tests/StringUtilTest.php
@@ -107,6 +107,8 @@ public function singularifyProvider()
array('objectives', 'objective'),
array('oxen', 'ox'),
array('parties', 'party'),
+ array('people', 'person'),
+ array('persons', 'person'),
array('phenomena', array('phenomenon', 'phenomenum')),
array('photos', 'photo'),
array('pianos', 'piano'),
diff --git a/src/Symfony/Component/Routing/Loader/AnnotationFileLoader.php b/src/Symfony/Component/Routing/Loader/AnnotationFileLoader.php
index a3a7e0e5ae50e..b8fc03615f968 100644
--- a/src/Symfony/Component/Routing/Loader/AnnotationFileLoader.php
+++ b/src/Symfony/Component/Routing/Loader/AnnotationFileLoader.php
@@ -112,7 +112,24 @@ protected function findClass($file)
}
if (T_CLASS === $token[0]) {
- $class = true;
+ // Skip usage of ::class constant
+ $isClassConstant = false;
+ for ($j = $i - 1; $j > 0; --$j) {
+ if (!isset($tokens[$j][1])) {
+ break;
+ }
+
+ if (T_DOUBLE_COLON === $tokens[$j][0]) {
+ $isClassConstant = true;
+ break;
+ } elseif (!in_array($tokens[$j][0], array(T_WHITESPACE, T_DOC_COMMENT, T_COMMENT))) {
+ break;
+ }
+ }
+
+ if (!$isClassConstant) {
+ $class = true;
+ }
}
if (T_NAMESPACE === $token[0]) {
diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/AnnotatedClasses/FooTrait.php b/src/Symfony/Component/Routing/Tests/Fixtures/AnnotatedClasses/FooTrait.php
new file mode 100644
index 0000000000000..ee8f4b071a368
--- /dev/null
+++ b/src/Symfony/Component/Routing/Tests/Fixtures/AnnotatedClasses/FooTrait.php
@@ -0,0 +1,13 @@
+loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/FooClass.php');
}
+ /**
+ * @requires PHP 5.4
+ */
+ public function testLoadTraitWithClassConstant()
+ {
+ $this->reader->expects($this->never())->method('getClassAnnotation');
+
+ $this->loader->load(__DIR__.'/../Fixtures/AnnotatedClasses/FooTrait.php');
+ }
+
/**
* @requires PHP 5.6
*/
diff --git a/src/Symfony/Component/Security/Acl/Dbal/MutableAclProvider.php b/src/Symfony/Component/Security/Acl/Dbal/MutableAclProvider.php
index 273625a48eb63..bd1976fa31851 100644
--- a/src/Symfony/Component/Security/Acl/Dbal/MutableAclProvider.php
+++ b/src/Symfony/Component/Security/Acl/Dbal/MutableAclProvider.php
@@ -554,9 +554,9 @@ protected function getInsertObjectIdentitySql($identifier, $classId, $entriesInh
*
* @param SecurityIdentityInterface $sid
*
- * @throws \InvalidArgumentException
- *
* @return string
+ *
+ * @throws \InvalidArgumentException
*/
protected function getInsertSecurityIdentitySql(SecurityIdentityInterface $sid)
{
@@ -626,9 +626,9 @@ protected function getSelectClassIdSql($classType)
*
* @param SecurityIdentityInterface $sid
*
- * @throws \InvalidArgumentException
- *
* @return string
+ *
+ * @throws \InvalidArgumentException
*/
protected function getSelectSecurityIdentityIdSql(SecurityIdentityInterface $sid)
{
@@ -655,9 +655,9 @@ protected function getSelectSecurityIdentityIdSql(SecurityIdentityInterface $sid
*
* @param SecurityIdentityInterface $sid
*
- * @throws \InvalidArgumentException
- *
* @return string
+ *
+ * @throws \InvalidArgumentException
*/
protected function getDeleteSecurityIdentityIdSql(SecurityIdentityInterface $sid)
{
@@ -673,9 +673,9 @@ protected function getDeleteSecurityIdentityIdSql(SecurityIdentityInterface $sid
* @param int $pk
* @param array $changes
*
- * @throws \InvalidArgumentException
- *
* @return string
+ *
+ * @throws \InvalidArgumentException
*/
protected function getUpdateObjectIdentitySql($pk, array $changes)
{
@@ -723,9 +723,9 @@ protected function getUpdateUserSecurityIdentitySql(UserSecurityIdentity $usid,
* @param int $pk
* @param array $sets
*
- * @throws \InvalidArgumentException
- *
* @return string
+ *
+ * @throws \InvalidArgumentException
*/
protected function getUpdateAccessControlEntrySql($pk, array $sets)
{
diff --git a/src/Symfony/Component/Security/Acl/Domain/ObjectIdentity.php b/src/Symfony/Component/Security/Acl/Domain/ObjectIdentity.php
index 871bda7b10970..ec817e2e87b74 100644
--- a/src/Symfony/Component/Security/Acl/Domain/ObjectIdentity.php
+++ b/src/Symfony/Component/Security/Acl/Domain/ObjectIdentity.php
@@ -52,9 +52,9 @@ public function __construct($identifier, $type)
*
* @param object $domainObject
*
- * @throws InvalidDomainObjectException
- *
* @return ObjectIdentity
+ *
+ * @throws InvalidDomainObjectException
*/
public static function fromDomainObject($domainObject)
{
diff --git a/src/Symfony/Component/Security/Acl/Model/AclInterface.php b/src/Symfony/Component/Security/Acl/Model/AclInterface.php
index 6a70a7c5943ac..13a6cf8394e34 100644
--- a/src/Symfony/Component/Security/Acl/Model/AclInterface.php
+++ b/src/Symfony/Component/Security/Acl/Model/AclInterface.php
@@ -97,9 +97,9 @@ public function isFieldGranted($field, array $masks, array $securityIdentities,
* @param array $securityIdentities
* @param bool $administrativeMode
*
- * @throws NoAceFoundException when no ACE was applicable for this request
- *
* @return bool
+ *
+ * @throws NoAceFoundException when no ACE was applicable for this request
*/
public function isGranted(array $masks, array $securityIdentities, $administrativeMode = false);
diff --git a/src/Symfony/Component/Security/Acl/Model/MutableAclProviderInterface.php b/src/Symfony/Component/Security/Acl/Model/MutableAclProviderInterface.php
index 95f531e09ba76..ee6d7c406ebd0 100644
--- a/src/Symfony/Component/Security/Acl/Model/MutableAclProviderInterface.php
+++ b/src/Symfony/Component/Security/Acl/Model/MutableAclProviderInterface.php
@@ -25,10 +25,10 @@ interface MutableAclProviderInterface extends AclProviderInterface
*
* @param ObjectIdentityInterface $oid
*
+ * @return MutableAclInterface
+ *
* @throws AclAlreadyExistsException when there already is an ACL for the given
* object identity
- *
- * @return MutableAclInterface
*/
public function createAcl(ObjectIdentityInterface $oid);
diff --git a/src/Symfony/Component/Security/Acl/Permission/MaskBuilder.php b/src/Symfony/Component/Security/Acl/Permission/MaskBuilder.php
index 0b5f388b48c69..ed13ecb8854f4 100644
--- a/src/Symfony/Component/Security/Acl/Permission/MaskBuilder.php
+++ b/src/Symfony/Component/Security/Acl/Permission/MaskBuilder.php
@@ -96,10 +96,10 @@ public function getPattern()
*
* @param int $mask
*
+ * @return string
+ *
* @throws \InvalidArgumentException
* @throws \RuntimeException
- *
- * @return string
*/
public static function getCode($mask)
{
diff --git a/src/Symfony/Component/Serializer/Encoder/ChainDecoder.php b/src/Symfony/Component/Serializer/Encoder/ChainDecoder.php
index f8f17b4f723e6..352ba584a7638 100644
--- a/src/Symfony/Component/Serializer/Encoder/ChainDecoder.php
+++ b/src/Symfony/Component/Serializer/Encoder/ChainDecoder.php
@@ -59,7 +59,7 @@ public function supportsDecoding($format)
*
* @return DecoderInterface
*
- * @throws RuntimeException if no decoder is found
+ * @throws RuntimeException If no decoder is found.
*/
private function getDecoder($format)
{
diff --git a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php
index d1f09f6eaf94e..4c17fb6b8d859 100644
--- a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php
+++ b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php
@@ -461,6 +461,8 @@ private function needsCdataWrapping($val)
* @param mixed $val
*
* @return bool
+ *
+ * @throws UnexpectedValueException
*/
private function selectNodeType(\DOMNode $node, $val)
{
diff --git a/src/Symfony/Component/Serializer/Normalizer/DenormalizableInterface.php b/src/Symfony/Component/Serializer/Normalizer/DenormalizableInterface.php
index 86c270299ee47..8ad1386a6cbd4 100644
--- a/src/Symfony/Component/Serializer/Normalizer/DenormalizableInterface.php
+++ b/src/Symfony/Component/Serializer/Normalizer/DenormalizableInterface.php
@@ -33,6 +33,8 @@ interface DenormalizableInterface
* @param string|null $format The format is optionally given to be able to denormalize differently
* based on different input formats
* @param array $context options for denormalizing
+ *
+ * @return object
*/
public function denormalize(DenormalizerInterface $denormalizer, $data, $format = null, array $context = array());
}
diff --git a/src/Symfony/Component/Serializer/Normalizer/NormalizableInterface.php b/src/Symfony/Component/Serializer/Normalizer/NormalizableInterface.php
index b9fefe887a44a..e19fe5ce58576 100644
--- a/src/Symfony/Component/Serializer/Normalizer/NormalizableInterface.php
+++ b/src/Symfony/Component/Serializer/Normalizer/NormalizableInterface.php
@@ -33,7 +33,7 @@ interface NormalizableInterface
* based on different output formats.
* @param array $context Options for normalizing this object
*
- * @return array|string|bool|int|float|null
+ * @return array|scalar
*/
public function normalize(NormalizerInterface $normalizer, $format = null, array $context = array());
}
diff --git a/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php b/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php
index 2a51d631b1624..f4bd355232b0b 100644
--- a/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php
+++ b/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php
@@ -25,7 +25,7 @@ interface NormalizerInterface
* @param string $format format the normalization result will be encoded as
* @param array $context Context options for the normalizer
*
- * @return array|string|bool|int|float|null
+ * @return array|scalar
*/
public function normalize($object, $format = null, array $context = array());
diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php
index c0602d7fa6b7d..398a579b9fa75 100644
--- a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php
+++ b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php
@@ -324,6 +324,19 @@ public function testIgnoredAttributes()
);
}
+ public function testIgnoredAttributesDenormalize()
+ {
+ $this->normalizer->setIgnoredAttributes(array('fooBar', 'bar', 'baz'));
+
+ $obj = new ObjectDummy();
+ $obj->setFoo('foo');
+
+ $this->assertEquals(
+ $obj,
+ $this->normalizer->denormalize(array('fooBar' => 'fooBar', 'foo' => 'foo', 'baz' => 'baz'), __NAMESPACE__.'\ObjectDummy')
+ );
+ }
+
public function provideCallbacks()
{
return array(
diff --git a/src/Symfony/Component/Stopwatch/StopwatchEvent.php b/src/Symfony/Component/Stopwatch/StopwatchEvent.php
index 930722d2f598c..957a5d0dae0a8 100644
--- a/src/Symfony/Component/Stopwatch/StopwatchEvent.php
+++ b/src/Symfony/Component/Stopwatch/StopwatchEvent.php
@@ -87,8 +87,6 @@ public function start()
/**
* Stops the last started event period.
*
- * @throws \LogicException When start wasn't called before stopping
- *
* @return StopwatchEvent The event
*
* @throws \LogicException When stop() is called without a matching call to start()
diff --git a/src/Symfony/Component/Translation/Extractor/AbstractFileExtractor.php b/src/Symfony/Component/Translation/Extractor/AbstractFileExtractor.php
index 196bc3341060a..57fd4938d22cf 100644
--- a/src/Symfony/Component/Translation/Extractor/AbstractFileExtractor.php
+++ b/src/Symfony/Component/Translation/Extractor/AbstractFileExtractor.php
@@ -54,9 +54,9 @@ private function toSplFileInfo($file)
/**
* @param string $file
*
- * @throws \InvalidArgumentException
- *
* @return bool
+ *
+ * @throws \InvalidArgumentException
*/
protected function isFile($file)
{
diff --git a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php
index 0e335db425cd3..0381a4ca4d8f7 100644
--- a/src/Symfony/Component/Translation/Loader/XliffFileLoader.php
+++ b/src/Symfony/Component/Translation/Loader/XliffFileLoader.php
@@ -112,10 +112,9 @@ private function utf8ToCharset($content, $encoding = null)
*
* @param string $file
*
- * @throws \RuntimeException
- *
* @return \SimpleXMLElement
*
+ * @throws \RuntimeException
* @throws InvalidResourceException
*/
private function parseFile($file)
diff --git a/src/Symfony/Component/Translation/TranslatorBagInterface.php b/src/Symfony/Component/Translation/TranslatorBagInterface.php
index 6f650b5ee0f88..14fbb17f5e46e 100644
--- a/src/Symfony/Component/Translation/TranslatorBagInterface.php
+++ b/src/Symfony/Component/Translation/TranslatorBagInterface.php
@@ -23,9 +23,9 @@ interface TranslatorBagInterface
*
* @param string|null $locale The locale or null to use the default
*
- * @throws \InvalidArgumentException If the locale contains invalid characters
- *
* @return MessageCatalogueInterface
+ *
+ * @throws \InvalidArgumentException If the locale contains invalid characters
*/
public function getCatalogue($locale = null);
}
diff --git a/src/Symfony/Component/Translation/TranslatorInterface.php b/src/Symfony/Component/Translation/TranslatorInterface.php
index 869e0b900442d..6916c335bd426 100644
--- a/src/Symfony/Component/Translation/TranslatorInterface.php
+++ b/src/Symfony/Component/Translation/TranslatorInterface.php
@@ -26,9 +26,9 @@ interface TranslatorInterface
* @param string|null $domain The domain for the message or null to use the default
* @param string|null $locale The locale or null to use the default
*
- * @throws \InvalidArgumentException If the locale contains invalid characters
- *
* @return string The translated string
+ *
+ * @throws \InvalidArgumentException If the locale contains invalid characters
*/
public function trans($id, array $parameters = array(), $domain = null, $locale = null);
@@ -41,9 +41,9 @@ public function trans($id, array $parameters = array(), $domain = null, $locale
* @param string|null $domain The domain for the message or null to use the default
* @param string|null $locale The locale or null to use the default
*
- * @throws \InvalidArgumentException If the locale contains invalid characters
- *
* @return string The translated string
+ *
+ * @throws \InvalidArgumentException If the locale contains invalid characters
*/
public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null);
diff --git a/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php b/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php
index cc4b2ef498974..1035bd70c292f 100644
--- a/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php
+++ b/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php
@@ -141,6 +141,8 @@ public function dump(Data $data, $output = null)
$this->dumpLine(-1);
} catch (\Exception $exception) {
// Re-thrown below
+ } catch (\Throwable $exception) {
+ // Re-thrown below
}
if ($output) {
$this->setOutput($prevOutput);
diff --git a/src/Symfony/Component/Yaml/Dumper.php b/src/Symfony/Component/Yaml/Dumper.php
index 21351a5c34fc9..9bd9389c07483 100644
--- a/src/Symfony/Component/Yaml/Dumper.php
+++ b/src/Symfony/Component/Yaml/Dumper.php
@@ -58,7 +58,7 @@ public function dump($input, $inline = 0, $indent = 0, $exceptionOnInvalidType =
if ($inline <= 0 || !is_array($input) || empty($input)) {
$output .= $prefix.Inline::dump($input, $exceptionOnInvalidType, $objectSupport);
} else {
- $isAHash = array_keys($input) !== range(0, count($input) - 1);
+ $isAHash = Inline::isHash($input);
foreach ($input as $key => $value) {
$willBeInlined = $inline - 1 <= 0 || !is_array($value) || empty($value);
diff --git a/src/Symfony/Component/Yaml/Inline.php b/src/Symfony/Component/Yaml/Inline.php
index fdd82d91f0e0e..125def97fb04b 100644
--- a/src/Symfony/Component/Yaml/Inline.php
+++ b/src/Symfony/Component/Yaml/Inline.php
@@ -157,6 +157,28 @@ public static function dump($value, $exceptionOnInvalidType = false, $objectSupp
}
}
+ /**
+ * Check if given array is hash or just normal indexed array.
+ *
+ * @internal
+ *
+ * @param array $value The PHP array to check
+ *
+ * @return bool true if value is hash array, false otherwise
+ */
+ public static function isHash(array $value)
+ {
+ $expectedKey = 0;
+
+ foreach ($value as $key => $val) {
+ if ($key !== $expectedKey++) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
/**
* Dumps a PHP array to a YAML string.
*
@@ -169,11 +191,7 @@ public static function dump($value, $exceptionOnInvalidType = false, $objectSupp
private static function dumpArray($value, $exceptionOnInvalidType, $objectSupport)
{
// array
- $keys = array_keys($value);
- $keysCount = count($keys);
- if ((1 === $keysCount && '0' == $keys[0])
- || ($keysCount > 1 && array_reduce($keys, function ($v, $w) { return (int) $v + $w; }, 0) === $keysCount * ($keysCount - 1) / 2)
- ) {
+ if ($value && !self::isHash($value)) {
$output = array();
foreach ($value as $val) {
$output[] = self::dump($val, $exceptionOnInvalidType, $objectSupport);
@@ -182,7 +200,7 @@ private static function dumpArray($value, $exceptionOnInvalidType, $objectSuppor
return sprintf('[%s]', implode(', ', $output));
}
- // mapping
+ // hash
$output = array();
foreach ($value as $key => $val) {
$output[] = sprintf('%s: %s', self::dump($key, $exceptionOnInvalidType, $objectSupport), self::dump($val, $exceptionOnInvalidType, $objectSupport));
diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php
index f1acae3a2daa5..4c6776b7f5b38 100644
--- a/src/Symfony/Component/Yaml/Parser.php
+++ b/src/Symfony/Component/Yaml/Parser.php
@@ -25,6 +25,7 @@ class Parser
const FOLDED_SCALAR_PATTERN = self::BLOCK_SCALAR_HEADER_PATTERN;
private $offset = 0;
+ private $totalNumberOfLines;
private $lines = array();
private $currentLineNb = -1;
private $currentLine = '';
@@ -33,11 +34,13 @@ class Parser
/**
* Constructor.
*
- * @param int $offset The offset of YAML document (used for line numbers in error messages)
+ * @param int $offset The offset of YAML document (used for line numbers in error messages)
+ * @param int|null $totalNumberOfLines The overall number of lines being parsed
*/
- public function __construct($offset = 0)
+ public function __construct($offset = 0, $totalNumberOfLines = null)
{
$this->offset = $offset;
+ $this->totalNumberOfLines = $totalNumberOfLines;
}
/**
@@ -62,6 +65,10 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
$value = $this->cleanup($value);
$this->lines = explode("\n", $value);
+ if (null === $this->totalNumberOfLines) {
+ $this->totalNumberOfLines = count($this->lines);
+ }
+
if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
$mbEncoding = mb_internal_encoding();
mb_internal_encoding('UTF-8');
@@ -83,7 +90,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
$isRef = $mergeNode = false;
if (preg_match('#^\-((?P\s+)(?P.+?))?\s*$#u', $this->currentLine, $values)) {
if ($context && 'mapping' == $context) {
- throw new ParseException('You cannot define a sequence item when in a mapping');
+ throw new ParseException('You cannot define a sequence item when in a mapping', $this->getRealCurrentLineNb() + 1, $this->currentLine);
}
$context = 'sequence';
@@ -95,7 +102,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
// array
if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
$c = $this->getRealCurrentLineNb() + 1;
- $parser = new self($c);
+ $parser = new self($c, $this->totalNumberOfLines);
$parser->refs = &$this->refs;
$data[] = $parser->parse($this->getNextEmbedBlock(null, true), $exceptionOnInvalidType, $objectSupport, $objectForMap);
} else {
@@ -104,7 +111,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
) {
// this is a compact notation element, add to next block and parse
$c = $this->getRealCurrentLineNb();
- $parser = new self($c);
+ $parser = new self($c, $this->totalNumberOfLines);
$parser->refs = &$this->refs;
$block = $values['value'];
@@ -122,7 +129,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
}
} elseif (preg_match('#^(?P'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P.+?))?\s*$#u', $this->currentLine, $values) && (false === strpos($values['key'], ' #') || in_array($values['key'][0], array('"', "'")))) {
if ($context && 'sequence' == $context) {
- throw new ParseException('You cannot define a mapping item when in a sequence');
+ throw new ParseException('You cannot define a mapping item when in a sequence', $this->currentLineNb + 1, $this->currentLine);
}
$context = 'mapping';
@@ -169,7 +176,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
$value = $this->getNextEmbedBlock();
}
$c = $this->getRealCurrentLineNb() + 1;
- $parser = new self($c);
+ $parser = new self($c, $this->totalNumberOfLines);
$parser->refs = &$this->refs;
$parsed = $parser->parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap);
@@ -220,7 +227,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
}
} else {
$c = $this->getRealCurrentLineNb() + 1;
- $parser = new self($c);
+ $parser = new self($c, $this->totalNumberOfLines);
$parser->refs = &$this->refs;
$value = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport, $objectForMap);
// Spec: Keys MUST be unique; first one wins.
@@ -247,7 +254,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
} else {
// multiple documents are not supported
if ('---' === $this->currentLine) {
- throw new ParseException('Multiple documents are not supported.');
+ throw new ParseException('Multiple documents are not supported.', $this->currentLineNb + 1, $this->currentLine);
}
// 1-liner optionally followed by newline(s)
@@ -483,7 +490,7 @@ private function parseValue($value, $exceptionOnInvalidType, $objectSupport, $ob
}
if (!array_key_exists($value, $this->refs)) {
- throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLine);
+ throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLineNb + 1, $this->currentLine);
}
return $this->refs[$value];
@@ -569,6 +576,8 @@ private function parseBlockScalar($style, $chomping = '', $indentation = 0)
if ($notEOF) {
$blockLines[] = '';
$this->moveToPreviousLine();
+ } elseif (!$notEOF && !$this->isCurrentLineLastLineInDocument()) {
+ $blockLines[] = '';
}
// folded style
@@ -675,6 +684,11 @@ private function isCurrentLineComment()
return '' !== $ltrimmedLine && $ltrimmedLine[0] === '#';
}
+ private function isCurrentLineLastLineInDocument()
+ {
+ return ($this->offset + $this->currentLineNb) >= ($this->totalNumberOfLines - 1);
+ }
+
/**
* Cleanups a YAML string to be parsed.
*
@@ -752,7 +766,7 @@ private function isNextLineUnIndentedCollection()
*/
private function isStringUnIndentedCollectionItem()
{
- return 0 === strpos($this->currentLine, '- ');
+ return '-' === rtrim($this->currentLine) || 0 === strpos($this->currentLine, '- ');
}
/**
diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php
index d368ab5f59d86..0e03e36a87a8a 100644
--- a/src/Symfony/Component/Yaml/Tests/InlineTest.php
+++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php
@@ -173,6 +173,24 @@ public function testParseUnquotedAsteriskFollowedByAComment()
Inline::parse('{ foo: * #foo }');
}
+ /**
+ * @dataProvider getDataForIsHash
+ */
+ public function testIsHash($array, $expected)
+ {
+ $this->assertSame($expected, Inline::isHash($array));
+ }
+
+ public function getDataForIsHash()
+ {
+ return array(
+ array(array(), false),
+ array(array(1, 2, 3), false),
+ array(array(2 => 1, 1 => 2, 0 => 3), true),
+ array(array('foo' => 1, 'bar' => 2), true),
+ );
+ }
+
public function getTestsForParse()
{
return array(
@@ -379,6 +397,8 @@ public function getTestsForDump()
array('[foo, { bar: foo, foo: [foo, { bar: foo }] }, [foo, { bar: foo }]]', array('foo', array('bar' => 'foo', 'foo' => array('foo', array('bar' => 'foo'))), array('foo', array('bar' => 'foo')))),
array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')),
+
+ array('{ foo: { bar: { 1: 2, baz: 3 } } }', array('foo' => array('bar' => array(1 => 2, 'baz' => 3)))),
);
}
}
diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php
index 7728267bc6fb7..6e508c1121111 100644
--- a/src/Symfony/Component/Yaml/Tests/ParserTest.php
+++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php
@@ -547,7 +547,7 @@ public function testShortcutKeyUnindentedCollectionException()
/**
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
- * @expectedExceptionMessage Multiple documents are not supported.
+ * @expectedExceptionMessageRegExp /^Multiple documents are not supported.+/
*/
public function testMultipleDocumentsNotSupportedException()
{
@@ -579,6 +579,34 @@ public function testSequenceInAMapping()
);
}
+ public function testSequenceInMappingStartedBySingleDashLine()
+ {
+ $yaml = << array(
+ array(
+ 'b' => array(
+ array(
+ 'bar' => 'baz',
+ ),
+ ),
+ ),
+ 'foo',
+ ),
+ 'd' => 'e',
+ );
+
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
/**
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
*/
@@ -905,6 +933,7 @@ public function getCommentLikeStringInScalarBlockData()
foo
# bar
baz
+
EOT
,
),
@@ -933,7 +962,7 @@ public function getCommentLikeStringInScalarBlockData()
$expected = array(
'foo' => array(
'bar' => array(
- 'scalar-block' => 'line1 line2>',
+ 'scalar-block' => "line1 line2>\n",
),
'baz' => array(
'foobar' => null,