Merge branch '2.7'

* 2.7: (24 commits)
  bumped Symfony version to 2.6.4
  updated VERSION for 2.6.3
  updated CHANGELOG for 2.6.3
  bumped Symfony version to 2.6.3
  updated VERSION for 2.6.2
  updated CHANGELOG for 2.6.2
  bumped Symfony version to 2.5.10
  updated VERSION for 2.5.9
  updated CHANGELOG for 2.5.9
  [FrameworkBundle] Use security.token_storage service in Controller::getUser()
  bumped Symfony version to 2.3.25
  updated VERSION for 2.3.24
  update CONTRIBUTORS for 2.3.24
  added missing E_USER_DEPRECATED argument to trigger_error() calls
  Removed unneeded version requirements
  updated CHANGELOG for 2.3.24
  fixed tests
  [Security] Don't destroy the session on buggy php releases.
  Enhance deprecation summary at end of tests
  [2.7] silence deprecations for getFactory*() BC layer
  ...

Conflicts:
	CHANGELOG-2.3.md
	CHANGELOG-2.5.md
	CHANGELOG-2.6.md
	src/Symfony/Component/Form/Tests/ResolvedFormTypeTest.php
This commit is contained in:
Fabien Potencier 2015-01-07 16:59:06 +01:00
commit b33b1dc00c
32 changed files with 762 additions and 284 deletions

View File

@ -12,10 +12,12 @@ Symfony is the result of the work of many people who made the code better
- Johannes S (johannes)
- Kris Wallsmith (kriswallsmith)
- Christophe Coevoet (stof)
- Nicolas Grekas (nicolas-grekas)
- Pascal Borreli (pborreli)
- Jakub Zalas (jakubzalas)
- Karma Dordrak (drak)
- Joseph Bielawski (stloyd)
- Hugo Hamon (hhamon)
- Ryan Weaver (weaverryan)
- Lukas Kahwe Smith (lsmith)
- Romain Neutron (romain)
@ -23,11 +25,9 @@ Symfony is the result of the work of many people who made the code better
- Jean-François Simon (jfsimon)
- Benjamin Eberlei (beberlei)
- Igor Wiedler (igorw)
- Hugo Hamon (hhamon)
- Nicolas Grekas (nicolas-grekas)
- Christian Flothmann (xabbuh)
- Martin Hasoň (hason)
- Eriksen Costa (eriksencosta)
- Christian Flothmann (xabbuh)
- Jonathan Wage (jwage)
- Grégoire Pineau (lyrixx)
- Alexandre Salomé (alexandresalome)
@ -35,12 +35,12 @@ Symfony is the result of the work of many people who made the code better
- ornicar
- stealth35 (stealth35)
- Alexander Mols (asm89)
- Wouter De Jong (wouterj)
- Bulat Shakirzyanov (avalanche123)
- Francis Besset (francisbesset)
- Saša Stamenković (umpirsky)
- Wouter De Jong (wouterj)
- Miha Vrhovnik
- Henrik Bjørnskov (henrikbjorn)
- Miha Vrhovnik
- Konstantin Kudryashov (everzet)
- Bilal Amarni (bamarni)
- Florin Patan (florinpatan)
@ -49,8 +49,10 @@ Symfony is the result of the work of many people who made the code better
- Deni
- Henrik Westphal (snc)
- Dariusz Górecki (canni)
- Christian Raue
- Arnout Boks (aboks)
- Christian Raue
- Sarah Khalil (saro0h)
- Ait Boudad Abdellatif (aitboudad)
- Michel Weimerskirch (mweimerskirch)
- Lee McDermott
- Brandon Turner
@ -62,7 +64,6 @@ Symfony is the result of the work of many people who made the code better
- Fran Moreno (franmomu)
- Antoine Hérault (herzult)
- Toni Uebernickel (havvg)
- Ait Boudad Abdellatif (aitboudad)
- Luis Cordova (cordoval)
- Arnaud Le Blanc (arnaud-lb)
- Kevin Bond (kbond)
@ -70,15 +71,17 @@ Symfony is the result of the work of many people who made the code better
- Brice BERNARD (brikou)
- marc.weistroff
- lenar
- Graham Campbell (graham)
- Włodzimierz Gajda (gajdaw)
- Colin Frei
- Gábor Egyed (1ed)
- excelwebzone
- Jacob Dreesen (jdreesen)
- Florian Voutzinos (florianv)
- Jérôme Tamarelle (gromnan)
- Adrien Brault (adrienbrault)
- Gábor Egyed (1ed)
- Fabien Pennequin (fabienpennequin)
- Kévin Dunglas (dunglas)
- Michal Piotrowski (eventhorizon)
- Gordon Franke (gimler)
- Robert Schönthal (digitalkaoz)
@ -93,11 +96,10 @@ Symfony is the result of the work of many people who made the code better
- Jérémie Augustin (jaugustin)
- Rafael Dohms (rdohms)
- Jérémy DERUSSÉ (jderusse)
- Stefano Sala (stefano.sala)
- Tigran Azatyan (tigranazatyan)
- Javier Eguiluz (javier.eguiluz)
- Richard Shank (iampersistent)
- Kévin Dunglas (dunglas)
- Stefano Sala (stefano.sala)
- Clemens Tolboom
- Helmer Aaviksoo
- Sebastiaan Stok (sstok)
@ -111,9 +113,11 @@ Symfony is the result of the work of many people who made the code better
- Rouven Weßling (realityking)
- Dmitrii Chekaliuk (lazyhammer)
- Clément JOBEILI (dator)
- Peter Rehm (rpet)
- Dorian Villet (gnutix)
- Richard Miller (mr_r_miller)
- Arnaud Kleinpeter (nanocom)
- hacfi (hifi)
- Mario A. Alvarez Garcia (nomack84)
- Dennis Benkert (denderello)
- Benjamin Dulau (dbenjamin)
@ -121,7 +125,7 @@ Symfony is the result of the work of many people who made the code better
- Andreas Hucks (meandmymonkey)
- Andréia Bohner (andreia)
- Noel Guilbert (noel)
- Peter Rehm (rpet)
- Joel Wurtz (brouznouf)
- Charles Sarrazin (csarrazi)
- bronze1man
- sun (sun)
@ -139,14 +143,12 @@ Symfony is the result of the work of many people who made the code better
- Justin Hileman (bobthecow)
- Sven Paulus (subsven)
- Lars Strojny (lstrojny)
- Joel Wurtz (brouznouf)
- Rui Marinho (ruimarinho)
- Julien Brochet (mewt)
- Tugdual Saunier (tucksaun)
- Graham Campbell (graham)
- Sergey Linnik (linniksa)
- Marcel Beerta (mazen)
- hacfi (hifi)
- Iltar van der Berg
- Francois Zaninotto
- Alexander Kotynia (olden)
- Daniel Tschinder
@ -172,9 +174,9 @@ Symfony is the result of the work of many people who made the code better
- Thomas Adam
- Albert Casademont (acasademont)
- jdhoek
- Jeremy Livingston (jeremylivingston)
- Nikita Konstantinov
- Wodor Wodorski
- Iltar van der Berg
- julien pauli (jpauli)
- Beau Simensen (simensen)
- Robert Kiss (kepten)
@ -193,6 +195,7 @@ Symfony is the result of the work of many people who made the code better
- Bertrand Zuchuat (garfield-fr)
- Gabor Toth (tgabi333)
- realmfoo
- Chris Wilkinson (thewilkybarkid)
- Thomas Tourlourat (armetiz)
- Andrey Esaulov (andremaha)
- Grégoire Passault (gregwar)
@ -216,6 +219,7 @@ Symfony is the result of the work of many people who made the code better
- alquerci
- Francesco Levorato
- Vitaliy Zakharov (zakharovvi)
- Florian Lonqueu-Brochard (florianlb)
- Gyula Sallai (salla)
- Inal DJAFAR (inalgnu)
- Christian Gärtner (dagardner)
@ -223,8 +227,10 @@ Symfony is the result of the work of many people who made the code better
- Yaroslav Kiliba
- Sébastien Lavoie (lavoiesl)
- Terje Bråten
- Joshua Thijssen
- Kristen Gilden (kgilden)
- Robbert Klarenbeek (robbertkl)
- Blanchon Vincent (blanchonvincent)
- hossein zolfi (ocean)
- Clément Gautier (clementgautier)
- Eduardo Gulias (egulias)
@ -234,13 +240,13 @@ Symfony is the result of the work of many people who made the code better
- Kirill chEbba Chebunin (chebba)
- Greg Thornton (xdissent)
- Grégoire Paris (greg0ire)
- Chris Wilkinson (thewilkybarkid)
- Costin Bereveanu (schniper)
- Loïc Chardonnet (gnusat)
- Marek Kalnik (marekkalnik)
- Vyacheslav Salakhutdinov (megazoll)
- Alex Pott
- Tamas Szijarto
- Mikael Pajunen
- Pavel Volokitin (pvolok)
- Endre Fejes
- Tobias Naumann (tna)
@ -248,6 +254,7 @@ Symfony is the result of the work of many people who made the code better
- Shein Alexey
- Joe Lencioni
- Kai
- Maximilian Reichel (phramz)
- Karoly Negyesi (chx)
- Xavier HAUSHERR
- Albert Jessurum (ajessu)
@ -255,6 +262,7 @@ Symfony is the result of the work of many people who made the code better
- Miha Vrhovnik
- Alessandro Desantis
- hubert lecorche (hlecorche)
- Marc Morales Valldepérez (kuert)
- Oscar Cubo Medina (ocubom)
- Karel Souffriau
- Christophe L. (christophelau)
@ -262,6 +270,7 @@ Symfony is the result of the work of many people who made the code better
- Jáchym Toušek
- Jannik Zschiesche (apfelbox)
- Emanuele Gaspari (inmarelibero)
- Dariusz Rumiński
- Brian King
- Michel Salib (michelsalib)
- geoffrey
@ -275,6 +284,7 @@ Symfony is the result of the work of many people who made the code better
- Olivier Dolbeau (odolbeau)
- Roumen Damianoff (roumen)
- Tobias Sjösten (tobiassjosten)
- Konstantin Myakshin (koc)
- vagrant
- Asier Illarramendi (doup)
- Chris Sedlmayr (catchamonkey)
@ -307,6 +317,7 @@ Symfony is the result of the work of many people who made the code better
- Iker Ibarguren (ikerib)
- Ricardo Oliveira (ricardolotr)
- ondrowan
- Jerzy Zawadzki (jzawadzki)
- Evan S Kaufman (evanskaufman)
- mcben
- Maks Slesarenko
@ -316,7 +327,6 @@ Symfony is the result of the work of many people who made the code better
- Ioan Negulescu
- Jakub Škvára (jskvara)
- Andrew Udvare (audvare)
- Sarah Khalil (saro0h)
- alexpods
- Erik Trapman (eriktrapman)
- De Cock Xavier (xdecock)
@ -327,8 +337,8 @@ Symfony is the result of the work of many people who made the code better
- Nils Adermann (naderman)
- Gábor Fási
- Benjamin Leveque (benji07)
- Maximilian Reichel (phramz)
- sasezaki
- Dawid Pakuła (zulusx)
- Florian Rey (nervo)
- Rodrigo Borrego Bernabé (rodrigobb)
- Denis Gorbachev (starfall)
@ -346,8 +356,8 @@ Symfony is the result of the work of many people who made the code better
- Zach Badgett (zachbadgett)
- Aurélien Fredouelle
- Pavel Campr (pcampr)
- Alexander Schwenn (xelaris)
- Disquedur
- Marc Morales Valldepérez (kuert)
- Geoffrey Tran (geoff)
- Jan Behrens
- Sebastian Krebs
@ -364,7 +374,6 @@ Symfony is the result of the work of many people who made the code better
- Max Rath (drak3)
- Stéphane Escandell (sescandell)
- Sinan Eldem
- Konstantin Myakshin (koc)
- Nahuel Cuesta (ncuesta)
- Chris Boden (cboden)
- Asmir Mustafic (goetas)
@ -383,7 +392,6 @@ Symfony is the result of the work of many people who made the code better
- Erkhembayar Gantulga (erheme318)
- David Fuhr
- Kamil Kokot (pamil)
- Florian Lonqueu-Brochard (florianlb)
- Rostyslav Kinash
- Daisuke Ohata
- Vincent Simonin
@ -433,7 +441,6 @@ Symfony is the result of the work of many people who made the code better
- Alex Xandra Albert Sim
- Yuen-Chi Lian
- Besnik Br
- Jerzy Zawadzki (jzawadzki)
- Joshua Nye
- avorobiev
- Venu
@ -445,9 +452,11 @@ Symfony is the result of the work of many people who made the code better
- 1emming
- Leevi Graham (leevigraham)
- Casper Valdemar Poulsen
- Daniel Wehner
- Josiah (josiah)
- Marek Štípek (maryo)
- John Bohn (jbohn)
- Marc Morera (mmoreram)
- Andrew Hilobok (hilobok)
- Christian Soronellas (theunic)
- Yosmany Garcia (yosmanyga)
@ -459,7 +468,6 @@ Symfony is the result of the work of many people who made the code better
- Krzysiek Łabuś
- Xavier Lacot (xavier)
- Olivier Maisonneuve (olineuve)
- Blanchon Vincent (blanchonvincent)
- Francis Turmel (fturmel)
- Loick Piera (pyrech)
- cgonzalez
@ -482,6 +490,7 @@ Symfony is the result of the work of many people who made the code better
- frost-nzcr4
- Abhoryo
- Fabian Vogler (fabian)
- Javier Spagnoletti (phansys)
- Korvin Szanto
- Maksim Kotlyar (makasim)
- Neil Ferreira
@ -529,6 +538,7 @@ Symfony is the result of the work of many people who made the code better
- Maks
- Gábor Tóth
- Daniel Cestari
- Massimiliano Arione (garak)
- Brunet Laurent (lbrunet)
- Magnus Nordlander (magnusnordlander)
- Mikhail Yurasov (mym)
@ -601,12 +611,14 @@ Symfony is the result of the work of many people who made the code better
- Dan Finnie
- Ken Marfilla (marfillaster)
- benatespina (benatespina)
- Denis Kop
- jfcixmedia
- Martijn Evers
- Benjamin Paap (benjaminpaap)
- Christian
- Sergii Smertin (nfx)
- Artur Eshenbrener
- Bailey Parker
- Eddie Jaoude
- Haritz Iturbe (hizai)
- Nerijus Arlauskas (nercury)
@ -638,6 +650,7 @@ Symfony is the result of the work of many people who made the code better
- Albert Ganiev (helios-ag)
- Neil Katin
- David Otton
- Will Donohoe
- peter
- Jérémy Jourdin (jjk801)
- Artem Kolesnikov (tyomo4ka)
@ -645,6 +658,7 @@ Symfony is the result of the work of many people who made the code better
- Yannick
- Luc Vieillescazes (iamluc)
- Eduardo García Sanz (coma)
- Szijarto Tamas
- Roy Van Ginneken
- David de Boer (ddeboer)
- Gilles Doge (gido)
@ -666,6 +680,7 @@ Symfony is the result of the work of many people who made the code better
- Philipp Strube
- Christian Sciberras
- Clement Herreman (clemherreman)
- Nyro (nyro)
- Trent Steel (trsteel88)
- Marco
- Marc Torres
@ -678,6 +693,7 @@ Symfony is the result of the work of many people who made the code better
- Jakub Kulhan
- Mo Di (modi)
- Jeroen van den Enden (stoefke)
- origaminal
- Quique Porta (quiqueporta)
- Tomasz Szymczyk (karion)
- ConneXNL
@ -685,6 +701,7 @@ Symfony is the result of the work of many people who made the code better
- Abdul.Mohsen B. A. A
- Benoît Burnichon
- Malaney J. Hill
- Christian Flach (cmfcmf)
- Cédric Girard (enk_)
- Oriol Mangas Abellan (oriolman)
- Sebastian Göttschkes (sgoettschkes)
@ -697,7 +714,6 @@ Symfony is the result of the work of many people who made the code better
- Erika Heidi Reinaldo (erikaheidi)
- Pierre Tachoire (krichprollsch)
- Marc J. Schmidt (marcjs)
- Marc Morera (mmoreram)
- Marco Jantke
- Saem Ghani
- Sebastian Utz
@ -708,6 +724,7 @@ Symfony is the result of the work of many people who made the code better
- steveYeah
- Samy Dindane (dinduks)
- Keri Henare (kerihenare)
- Mickaël Andrieu (mickaelandrieu)
- Cédric Lahouste (rapotor)
- Samuel Vogel (samuelvogel)
- Berat Doğan
@ -736,6 +753,7 @@ Symfony is the result of the work of many people who made the code better
- Felds Liscia
- James Halsall (jaitsu)
- Maxime Veber (nek-)
- Sullivan SENECHAL
- Tadcka
- Beth Binkovitz
- Romain Geissler
@ -754,6 +772,7 @@ Symfony is the result of the work of many people who made the code better
- Timothy Anido (xanido)
- Rick Prent
- Martin Eckhardt
- Pieter Jordaan
- Damien Tournoud
- Jon Gotlin (jongotlin)
- Michael Dowling (mtdowling)
@ -777,7 +796,6 @@ Symfony is the result of the work of many people who made the code better
- Simon Neidhold
- Kevin Dew
- James Cowgill
- Jeremy Livingston (jeremylivingston)
- Nicolas Schwartz (nicoschwartz)
- Patrik Gmitter (patie)
- Jonathan Gough
@ -798,12 +816,14 @@ Symfony is the result of the work of many people who made the code better
- César Suárez (csuarez)
- Nicolas Badey (nico-b)
- Shane Preece (shane)
- wusuopu
- povilas
- Diego Agulló
- Alexander Obuhovich
- Alessandro Tagliapietra (alex88)
- Gunnar Lium (gunnarlium)
- Tiago Garcia (tiagojsag)
- Artiom
- Bouke Haarsma
- Martin Eckhardt
- Denis Zunke
@ -836,7 +856,6 @@ Symfony is the result of the work of many people who made the code better
- Michal Gebauer
- Gleb Sidora
- David Stone
- Javier Spagnoletti (phansys)
- Pablo Maria Martelletti (pmartelletti)
- Yassine Guedidi (yguedidi)
- Luis Muñoz
@ -852,6 +871,7 @@ Symfony is the result of the work of many people who made the code better
- Ionel Scutelnicu (ionelscutelnicu)
- Johnny Peck (johnnypeck)
- Nicolas Tallefourtané (nicolab)
- Botond Dani (picur)
- Thierry Marianne (thierrymarianne)
- Nick Stemerdink
- jjanvier
@ -871,7 +891,6 @@ Symfony is the result of the work of many people who made the code better
- Mike Meier
- Warwick
- Chris
- Daniel Wehner
- efeen
- Michał Dąbrowski (defrag)
- Dominik Zogg (dominik.zogg)
@ -897,6 +916,7 @@ Symfony is the result of the work of many people who made the code better
- Kevin Decherf
- Jason Woods
- dened
- Dmitry Korotovsky
- Sam Ward
- Walther Lalk
- Adam
@ -905,16 +925,19 @@ Symfony is the result of the work of many people who made the code better
- gedrox
- dropfen
- Andrey Chernykh
- Edvinas Klovas
- Drew Butler
- J Bruni
- Alexey Prilipko
- bertillon
- Luca Genuzio (genuzio)
- Hans Nilsson (hansnilsson)
- Ioana Hazsda (ioana-hazsda)
- Jan Marek (janmarek)
- Mark de Haan (markdehaan)
- Dan Patrick (mdpatrick)
- Rares Vlaseanu (raresvla)
- Sofiane HADDAG (sofhad)
- tante kinast (tante)
- Vincent LEFORT (vlefort)
- Alexander Zogheb
@ -941,6 +964,7 @@ Symfony is the result of the work of many people who made the code better
- Hein Zaw Htet™
- Ruben Kruiswijk
- Michael J
- Berny Cantos
- Alex Pods
- timaschew
- Ian Phillips
@ -964,10 +988,12 @@ Symfony is the result of the work of many people who made the code better
- ddebree
- Alex
- Klaas Naaijkens
- Daniel González Cerviño
- Rafał
- Adria Lopez (adlpz)
- Rosio (ben-rosio)
- Simon Paarlberg (blamh)
- Jeroen Thora (bolle)
- Masao Maeda (brtriver)
- Darius Leskauskas (darles)
- Dave Hulbert (dave1010)
@ -989,6 +1015,7 @@ Symfony is the result of the work of many people who made the code better
- Muriel (metalmumu)
- Michaël Perrin (michael.perrin)
- Michael Pohlers (mick_the_big)
- Mantas Var (mvar)
- Cayetano Soriano Gallego (neoshadybeat)
- Pablo Monterde Perez (plebs)
- Jimmy Leger (redpanda)
@ -1093,6 +1120,7 @@ Symfony is the result of the work of many people who made the code better
- tirnanog06
- phc
- ilyes kooli
- Matthias Althaus
- Michaël VEROUX
- sualko
- Nicolas Roudaire
@ -1117,7 +1145,6 @@ Symfony is the result of the work of many people who made the code better
- Fabien D. (fabd)
- Sorin Gitlan (forapathy)
- Yohan Giarelli (frequence-web)
- Massimiliano Arione (garak)
- Gerry Vandermaesen (gerryvdm)
- Ghazy Ben Ahmed (ghazy)
- Arash Tabriziyan (ghost098)
@ -1141,6 +1168,7 @@ Symfony is the result of the work of many people who made the code better
- Matt Drollette (mdrollette)
- Adam Monsen (meonkeys)
- Ala Eddine Khefifi (nayzo)
- emilienbouard (neime)
- ollie harridge (ollietb)
- Paweł Szczepanek (pauluz)
- Christian López Espínola (penyaskito)
@ -1153,7 +1181,9 @@ Symfony is the result of the work of many people who made the code better
- scourgen hung (scourgen)
- Sebastian Busch (sebu)
- André Filipe Gonçalves Neves (seven)
- Bruno Ziegler (sfcoder)
- Andrea Giuliano (shark)
- Schuyler Jager (sjager)
- Volker (skydiablo)
- Julien Sanchez (sumbobyboys)
- Guillermo Gisinger (t3chn0r)
@ -1163,8 +1193,6 @@ Symfony is the result of the work of many people who made the code better
- Vincent (vincent1870)
- Eugene Babushkin (warl)
- Xavier Amado (xamado)
- Alexander Schwenn (xelaris)
- Dawid Pakuła (zulusx)
- Florent Cailhol
- szymek
- craigmarvelley
@ -1181,6 +1209,7 @@ Symfony is the result of the work of many people who made the code better
- Philipp Scheit
- max
- Mohamed Karnichi (amiral)
- Daniel Kolvik (dkvk)
- Jeroen De Dauw (jeroendedauw)
- Muharrem Demirci (mdemirci)
- Evgeny Z (meze)

View File

@ -20,13 +20,19 @@ class DeprecationErrorHandler
if (self::$isRegistered) {
return;
}
$deprecations = array(0);
$oldErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context) use (&$deprecations) {
$deprecations = array(
'remainingCount' => 0,
'legacyCount' => 0,
'otherCount' => 0,
'remaining' => array(),
'legacy' => array(),
'other' => array(),
);
$deprecationHandler = function ($type, $msg, $file, $line, $context) use (&$deprecations) {
if (E_USER_DEPRECATED !== $type) {
return PHPUnit_Util_ErrorHandler::handleError($type, $msg, $file, $line, $context);
}
++$deprecations[0];
$trace = debug_backtrace(PHP_VERSION_ID >= 50400 ? DEBUG_BACKTRACE_IGNORE_ARGS : false);
$i = count($trace);
@ -35,13 +41,24 @@ class DeprecationErrorHandler
}
if (isset($trace[$i]['class'])) {
if (isset($deprecations[$trace[$i]['class']][$trace[$i]['function']][$msg])) {
++$deprecations[$trace[$i]['class']][$trace[$i]['function']][$msg];
$class = $trace[$i]['class'];
$method = $trace[$i]['function'];
$type = 0 === strpos($method, 'testLegacy') || 0 === strpos($method, 'provideLegacy') || strpos($class, '\Legacy') ? 'legacy' : 'remaining';
if ('legacy' === $type && 0 === (error_reporting() & E_USER_DEPRECATED)) {
@++$deprecations[$type]['Silenced']['count'];
} else {
$deprecations[$trace[$i]['class']][$trace[$i]['function']][$msg] = 1;
@++$deprecations[$type][$msg]['count'];
@++$deprecations[$type][$msg][$class.'::'.$method];
}
} else {
$type = 'other';
@++$deprecations[$type][$msg]['count'];
}
});
++$deprecations[$type.'Count'];
};
$oldErrorHandler = set_error_handler($deprecationHandler);
if (null !== $oldErrorHandler) {
restore_error_handler();
@ -51,31 +68,52 @@ class DeprecationErrorHandler
}
} else {
self::$isRegistered = true;
register_shutdown_function(function () use (&$deprecations) {
if ($deprecations[0]) {
if (function_exists('posix_isatty') && @posix_isatty(STDOUT)) {
echo "\n\x1B[43;30mDeprecation notices ($deprecations[0]):\x1B[0m\n";
} else {
echo "\nDeprecation notices ($deprecations[0]):\n";
}
register_shutdown_function(function () use (&$deprecations, $deprecationHandler) {
foreach ($deprecations as $class => $notices) {
if (0 !== $class) {
echo "\n{$class}\n";
foreach ($notices as $method => $notices) {
echo " ->{$method}()\n";
foreach ($notices as $msg => $freq) {
echo " {$msg}: $freq\n";
$colorize = new \SebastianBergmann\Environment\Console();
if ($colorize->hasColorSupport()) {
$colorize = function ($str, $red) {
$color = $red ? '41;37' : '43;30';
return "\x1B[{$color}m{$str}\x1B[0m";
};
} else {
$colorize = function ($str) {return $str;};
}
$currErrorHandler = set_error_handler('var_dump');
restore_error_handler();
if ($currErrorHandler !== $deprecationHandler) {
echo "\n", $colorize('THE ERROR HANDLER HAS CHANGED!', true), "\n";
}
$cmp = function ($a, $b) {
return $b['count'] - $a['count'];
};
foreach (array('remaining', 'legacy', 'other') as $type) {
if ($deprecations[$type]) {
echo "\n", $colorize(sprintf('%s deprecation notices (%d)', ucfirst($type), $deprecations[$type.'Count']), 'legacy' !== $type), "\n";
uasort($deprecations[$type], $cmp);
foreach ($deprecations[$type] as $msg => $notices) {
echo "\n", $msg, ': ', $notices['count'], "x\n";
arsort($notices);
foreach ($notices as $method => $count) {
if ('count' !== $method) {
echo ' ', $count, 'x in ', preg_replace('/(.*)\\\\(.*?::.*?)$/', '$2 from $1', $method), "\n";
}
}
}
}
} else {
if (function_exists('posix_isatty') && @posix_isatty(STDOUT)) {
echo "\n\x1B[42;30mNo deprecation notice\x1B[0m\n";
} else {
echo "\nNo deprecation notice\n";
}
}
if (!empty($notices)) {
echo "\n";
}
});
}

View File

@ -331,16 +331,18 @@ class XmlDescriptor extends Descriptor
$serviceXML->setAttribute('class', $definition->getClass());
if ($definition->getFactoryClass()) {
$serviceXML->setAttribute('factory-class', $definition->getFactoryClass());
}
if (method_exists($definition, 'getFactoryMethod')) {
if ($definition->getFactoryClass(false)) {
$serviceXML->setAttribute('factory-class', $definition->getFactoryClass(false));
}
if ($definition->getFactoryService()) {
$serviceXML->setAttribute('factory-service', $definition->getFactoryService());
}
if ($definition->getFactoryService(false)) {
$serviceXML->setAttribute('factory-service', $definition->getFactoryService(false));
}
if ($definition->getFactoryMethod()) {
$serviceXML->setAttribute('factory-method', $definition->getFactoryMethod());
if ($definition->getFactoryMethod(false)) {
$serviceXML->setAttribute('factory-method', $definition->getFactoryMethod(false));
}
}
if ($factory = $definition->getFactory()) {

View File

@ -279,7 +279,7 @@ abstract class Controller extends ContainerAware
}
/**
* Get a user from the Security Context.
* Get a user from the Security Token Storage.
*
* @return mixed
*
@ -289,15 +289,16 @@ abstract class Controller extends ContainerAware
*/
protected function getUser()
{
if (!$this->container->has('security.context')) {
if (!$this->container->has('security.token_storage')) {
throw new \LogicException('The SecurityBundle is not registered in your application.');
}
if (null === $token = $this->container->get('security.context')->getToken()) {
if (null === $token = $this->container->get('security.token_storage')->getToken()) {
return;
}
if (!is_object($user = $token->getUser())) {
// e.g. anonymous authentication
return;
}

View File

@ -13,9 +13,13 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\User\User;
class ControllerTest extends TestCase
{
@ -43,6 +47,95 @@ class ControllerTest extends TestCase
$response = $controller->forward('a_controller');
$this->assertEquals('xml--fr', $response->getContent());
}
public function testGetUser()
{
$user = new User('user', 'pass');
$token = new UsernamePasswordToken($user, 'pass', 'default', array('ROLE_USER'));
$controller = new TestController();
$controller->setContainer($this->getContainerWithTokenStorage($token));
$this->assertSame($controller->getUser(), $user);
}
public function testGetUserAnonymousUserConvertedToNull()
{
$token = new AnonymousToken('default', 'anon.');
$controller = new TestController();
$controller->setContainer($this->getContainerWithTokenStorage($token));
$this->assertNull($controller->getUser());
}
public function testGetUserWithEmptyTokenStorage()
{
$controller = new TestController();
$controller->setContainer($this->getContainerWithTokenStorage(null));
$this->assertNull($controller->getUser());
}
/**
* @expectedException \LogicException
* @expectedExceptionMessage The SecurityBundle is not registered in your application.
*/
public function testGetUserWithEmptyContainer()
{
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
$container
->expects($this->once())
->method('has')
->with('security.token_storage')
->will($this->returnValue(false));
$controller = new TestController();
$controller->setContainer($container);
$controller->getUser();
}
/**
* @param $token
* @return ContainerInterface
*/
private function getContainerWithTokenStorage($token = null)
{
$tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage');
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue($token));
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
$container
->expects($this->once())
->method('has')
->with('security.token_storage')
->will($this->returnValue(true));
$container
->expects($this->once())
->method('get')
->with('security.token_storage')
->will($this->returnValue($tokenStorage));
return $container;
}
}
class TestController extends Controller
{
public function forward($controller, array $path = array(), array $query = array())
{
return parent::forward($controller, $path, $query);
}
public function getUser()
{
return parent::getUser();
}
}
class TestController extends Controller

View File

@ -71,8 +71,8 @@ class AnalyzeServiceReferencesPass implements RepeatablePassInterface
$this->currentDefinition = $definition;
$this->processArguments($definition->getArguments());
if ($definition->getFactoryService()) {
$this->processArguments(array(new Reference($definition->getFactoryService())));
if ($definition->getFactoryService(false)) {
$this->processArguments(array(new Reference($definition->getFactoryService(false))));
}
if (is_array($definition->getFactory())) {
$this->processArguments($definition->getFactory());
@ -118,8 +118,8 @@ class AnalyzeServiceReferencesPass implements RepeatablePassInterface
if (is_array($argument->getFactory())) {
$this->processArguments($argument->getFactory());
}
if ($argument->getFactoryService()) {
$this->processArguments(array(new Reference($argument->getFactoryService())));
if ($argument->getFactoryService(false)) {
$this->processArguments(array(new Reference($argument->getFactoryService(false))));
}
}
}

View File

@ -50,13 +50,13 @@ class CheckDefinitionValidityPass implements CompilerPassInterface
throw new RuntimeException(sprintf('A synthetic service ("%s") cannot be of scope "prototype".', $id));
}
if ($definition->getFactory() && ($definition->getFactoryClass() || $definition->getFactoryService() || $definition->getFactoryMethod())) {
if ($definition->getFactory() && ($definition->getFactoryClass(false) || $definition->getFactoryService(false) || $definition->getFactoryMethod(false))) {
throw new RuntimeException(sprintf('A service ("%s") can use either the old or the new factory syntax, not both.', $id));
}
// non-synthetic, non-abstract service has class
if (!$definition->isAbstract() && !$definition->isSynthetic() && !$definition->getClass()) {
if ($definition->getFactory() || $definition->getFactoryClass() || $definition->getFactoryService()) {
if ($definition->getFactory() || $definition->getFactoryClass(false) || $definition->getFactoryService(false)) {
throw new RuntimeException(sprintf('Please add the class to service "%s" even if it is constructed by a factory since we might need to add method calls based on compile-time checks.', $id));
}

View File

@ -148,7 +148,7 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
return false;
}
if (count($ids) > 1 && $definition->getFactoryService()) {
if (count($ids) > 1 && $definition->getFactoryService(false)) {
return false;
}

View File

@ -81,9 +81,15 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
$def->setArguments($parentDef->getArguments());
$def->setMethodCalls($parentDef->getMethodCalls());
$def->setProperties($parentDef->getProperties());
$def->setFactoryClass($parentDef->getFactoryClass());
$def->setFactoryMethod($parentDef->getFactoryMethod());
$def->setFactoryService($parentDef->getFactoryService());
if ($parentDef->getFactoryClass(false)) {
$def->setFactoryClass($parentDef->getFactoryClass(false));
}
if ($parentDef->getFactoryMethod(false)) {
$def->setFactoryMethod($parentDef->getFactoryMethod(false));
}
if ($parentDef->getFactoryService(false)) {
$def->setFactoryService($parentDef->getFactoryService(false));
}
$def->setFactory($parentDef->getFactory());
$def->setConfigurator($parentDef->getConfigurator());
$def->setFile($parentDef->getFile());
@ -96,13 +102,13 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
$def->setClass($definition->getClass());
}
if (isset($changes['factory_class'])) {
$def->setFactoryClass($definition->getFactoryClass());
$def->setFactoryClass($definition->getFactoryClass(false));
}
if (isset($changes['factory_method'])) {
$def->setFactoryMethod($definition->getFactoryMethod());
$def->setFactoryMethod($definition->getFactoryMethod(false));
}
if (isset($changes['factory_service'])) {
$def->setFactoryService($definition->getFactoryService());
$def->setFactoryService($definition->getFactoryService(false));
}
if (isset($changes['factory'])) {
$def->setFactory($definition->getFactory());

View File

@ -944,16 +944,16 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
}
$service = call_user_func_array($factory, $arguments);
} elseif (null !== $definition->getFactoryMethod()) {
if (null !== $definition->getFactoryClass()) {
$factory = $parameterBag->resolveValue($definition->getFactoryClass());
} elseif (null !== $definition->getFactoryService()) {
$factory = $this->get($parameterBag->resolveValue($definition->getFactoryService()));
} elseif (null !== $definition->getFactoryMethod(false)) {
if (null !== $definition->getFactoryClass(false)) {
$factory = $parameterBag->resolveValue($definition->getFactoryClass(false));
} elseif (null !== $definition->getFactoryService(false)) {
$factory = $this->get($parameterBag->resolveValue($definition->getFactoryService(false)));
} else {
throw new RuntimeException(sprintf('Cannot create service "%s" from factory method without a factory service or factory class.', $id));
}
$service = call_user_func_array(array($factory, $definition->getFactoryMethod()), $arguments);
$service = call_user_func_array(array($factory, $definition->getFactoryMethod(false)), $arguments);
} else {
$r = new \ReflectionClass($parameterBag->resolveValue($definition->getClass()));

View File

@ -113,9 +113,11 @@ class Definition
* @api
* @deprecated since version 2.6, to be removed in 3.0.
*/
public function getFactoryClass()
public function getFactoryClass($triggerDeprecationError = true)
{
trigger_error('The '.__METHOD__.' is deprecated since version 2.6 and will be removed in 3.0.', E_USER_DEPRECATED);
if ($triggerDeprecationError) {
trigger_error('The '.__METHOD__.' is deprecated since version 2.6 and will be removed in 3.0.', E_USER_DEPRECATED);
}
return $this->factoryClass;
}
@ -182,9 +184,11 @@ class Definition
* @api
* @deprecated since version 2.6, to be removed in 3.0.
*/
public function getFactoryMethod()
public function getFactoryMethod($triggerDeprecationError = true)
{
trigger_error('The '.__METHOD__.' is deprecated since version 2.6 and will be removed in 3.0.', E_USER_DEPRECATED);
if ($triggerDeprecationError) {
trigger_error('The '.__METHOD__.' is deprecated since version 2.6 and will be removed in 3.0.', E_USER_DEPRECATED);
}
return $this->factoryMethod;
}
@ -216,9 +220,11 @@ class Definition
* @api
* @deprecated since version 2.6, to be removed in 3.0.
*/
public function getFactoryService()
public function getFactoryService($triggerDeprecationError = true)
{
trigger_error('The '.__METHOD__.' is deprecated since version 2.6 and will be removed in 3.0.', E_USER_DEPRECATED);
if ($triggerDeprecationError) {
trigger_error('The '.__METHOD__.' is deprecated since version 2.6 and will be removed in 3.0.', E_USER_DEPRECATED);
}
return $this->factoryService;
}

View File

@ -572,10 +572,10 @@ class PhpDumper extends Dumper
$return[] = sprintf('@return object An instance returned by %s::%s().', $factory[0]->getClass(), $factory[1]);
}
}
} elseif ($definition->getFactoryClass()) {
$return[] = sprintf('@return object An instance returned by %s::%s().', $definition->getFactoryClass(), $definition->getFactoryMethod());
} elseif ($definition->getFactoryService()) {
$return[] = sprintf('@return object An instance returned by %s::%s().', $definition->getFactoryService(), $definition->getFactoryMethod());
} elseif ($definition->getFactoryClass(false)) {
$return[] = sprintf('@return object An instance returned by %s::%s().', $definition->getFactoryClass(false), $definition->getFactoryMethod(false));
} elseif ($definition->getFactoryService(false)) {
$return[] = sprintf('@return object An instance returned by %s::%s().', $definition->getFactoryService(false), $definition->getFactoryMethod(false));
}
$scope = $definition->getScope();
@ -768,20 +768,20 @@ EOF;
}
return sprintf(" $return{$instantiation}\\%s(%s);\n", $callable, $arguments ? implode(', ', $arguments) : '');
} elseif (null !== $definition->getFactoryMethod()) {
if (null !== $definition->getFactoryClass()) {
$class = $this->dumpValue($definition->getFactoryClass());
} elseif (null !== $definition->getFactoryMethod(false)) {
if (null !== $definition->getFactoryClass(false)) {
$class = $this->dumpValue($definition->getFactoryClass(false));
// If the class is a string we can optimize call_user_func away
if (strpos($class, "'") === 0) {
return sprintf(" $return{$instantiation}%s::%s(%s);\n", $this->dumpLiteralClass($class), $definition->getFactoryMethod(), $arguments ? implode(', ', $arguments) : '');
return sprintf(" $return{$instantiation}%s::%s(%s);\n", $this->dumpLiteralClass($class), $definition->getFactoryMethod(false), $arguments ? implode(', ', $arguments) : '');
}
return sprintf(" $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($definition->getFactoryClass()), $definition->getFactoryMethod(), $arguments ? ', '.implode(', ', $arguments) : '');
return sprintf(" $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($definition->getFactoryClass(false)), $definition->getFactoryMethod(false), $arguments ? ', '.implode(', ', $arguments) : '');
}
if (null !== $definition->getFactoryService()) {
return sprintf(" $return{$instantiation}%s->%s(%s);\n", $this->getServiceCall($definition->getFactoryService()), $definition->getFactoryMethod(), implode(', ', $arguments));
if (null !== $definition->getFactoryService(false)) {
return sprintf(" $return{$instantiation}%s->%s(%s);\n", $this->getServiceCall($definition->getFactoryService(false)), $definition->getFactoryMethod(false), implode(', ', $arguments));
}
throw new RuntimeException(sprintf('Factory method requires a factory service or factory class in service definition for %s', $id));
@ -1328,11 +1328,11 @@ EOF;
throw new RuntimeException('Cannot dump definition because of invalid factory');
}
if (null !== $value->getFactoryMethod()) {
if (null !== $value->getFactoryClass()) {
return sprintf("call_user_func(array(%s, '%s')%s)", $this->dumpValue($value->getFactoryClass()), $value->getFactoryMethod(), count($arguments) > 0 ? ', '.implode(', ', $arguments) : '');
} elseif (null !== $value->getFactoryService()) {
return sprintf("%s->%s(%s)", $this->getServiceCall($value->getFactoryService()), $value->getFactoryMethod(), implode(', ', $arguments));
if (null !== $value->getFactoryMethod(false)) {
if (null !== $value->getFactoryClass(false)) {
return sprintf("call_user_func(array(%s, '%s')%s)", $this->dumpValue($value->getFactoryClass(false)), $value->getFactoryMethod(false), count($arguments) > 0 ? ', '.implode(', ', $arguments) : '');
} elseif (null !== $value->getFactoryService(false)) {
return sprintf("%s->%s(%s)", $this->getServiceCall($value->getFactoryService(false)), $value->getFactoryMethod(false), implode(', ', $arguments));
} else {
throw new RuntimeException('Cannot dump definitions which have factory method without factory service or factory class.');
}

View File

@ -117,14 +117,14 @@ class XmlDumper extends Dumper
if ($definition->getClass()) {
$service->setAttribute('class', $definition->getClass());
}
if ($definition->getFactoryMethod()) {
$service->setAttribute('factory-method', $definition->getFactoryMethod());
if ($definition->getFactoryMethod(false)) {
$service->setAttribute('factory-method', $definition->getFactoryMethod(false));
}
if ($definition->getFactoryClass()) {
$service->setAttribute('factory-class', $definition->getFactoryClass());
if ($definition->getFactoryClass(false)) {
$service->setAttribute('factory-class', $definition->getFactoryClass(false));
}
if ($definition->getFactoryService()) {
$service->setAttribute('factory-service', $definition->getFactoryService());
if ($definition->getFactoryService(false)) {
$service->setAttribute('factory-service', $definition->getFactoryService(false));
}
if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope()) {
$service->setAttribute('scope', $scope);

View File

@ -107,20 +107,20 @@ class YamlDumper extends Dumper
$code .= sprintf(" synchronized: true\n");
}
if ($definition->getFactoryClass()) {
$code .= sprintf(" factory_class: %s\n", $definition->getFactoryClass());
if ($definition->getFactoryClass(false)) {
$code .= sprintf(" factory_class: %s\n", $definition->getFactoryClass(false));
}
if ($definition->isLazy()) {
$code .= sprintf(" lazy: true\n");
}
if ($definition->getFactoryMethod()) {
$code .= sprintf(" factory_method: %s\n", $definition->getFactoryMethod());
if ($definition->getFactoryMethod(false)) {
$code .= sprintf(" factory_method: %s\n", $definition->getFactoryMethod(false));
}
if ($definition->getFactoryService()) {
$code .= sprintf(" factory_service: %s\n", $definition->getFactoryService());
if ($definition->getFactoryService(false)) {
$code .= sprintf(" factory_service: %s\n", $definition->getFactoryService(false));
}
if ($definition->getArguments()) {

View File

@ -1,13 +1,20 @@
CHANGELOG
=========
2.6.2
-----
* Added back the `model_timezone` and `view_timezone` options for `TimeType`, `DateType`
and `BirthdayType`
2.6.0
-----
* added "html5" option to Date, Time and DateTimeFormType to be able to
enable/disable HTML5 input date when widget option is "single_text"
* added "label_format" option with possible placeholders "%name%" and "%id%"
* [BC BREAK] drop support for model_timezone and view_timezone options in TimeType, DateType and BirthdayType
* [BC BREAK] drop support for model_timezone and view_timezone options in TimeType, DateType and BirthdayType,
update to 2.6.2 to get back support for these options
2.5.0
------

View File

@ -197,6 +197,8 @@ class TimeType extends AbstractType
'input' => 'datetime',
'with_minutes' => true,
'with_seconds' => false,
'model_timezone' => null,
'view_timezone' => null,
'empty_value' => $emptyValue, // deprecated
'placeholder' => $placeholder,
'html5' => true,

View File

@ -60,6 +60,8 @@ class DateTypeTest extends TestCase
public function testSubmitFromSingleTextDateTimeWithDefaultFormat()
{
$form = $this->factory->create('date', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'widget' => 'single_text',
'input' => 'datetime',
));
@ -74,6 +76,8 @@ class DateTypeTest extends TestCase
{
$form = $this->factory->create('date', null, array(
'format' => \IntlDateFormatter::MEDIUM,
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'widget' => 'single_text',
'input' => 'datetime',
));
@ -88,6 +92,8 @@ class DateTypeTest extends TestCase
{
$form = $this->factory->create('date', null, array(
'format' => \IntlDateFormatter::MEDIUM,
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'widget' => 'single_text',
'input' => 'string',
));
@ -102,6 +108,8 @@ class DateTypeTest extends TestCase
{
$form = $this->factory->create('date', null, array(
'format' => \IntlDateFormatter::MEDIUM,
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'widget' => 'single_text',
'input' => 'timestamp',
));
@ -118,6 +126,8 @@ class DateTypeTest extends TestCase
{
$form = $this->factory->create('date', null, array(
'format' => \IntlDateFormatter::MEDIUM,
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'widget' => 'single_text',
'input' => 'array',
));
@ -137,6 +147,8 @@ class DateTypeTest extends TestCase
public function testSubmitFromText()
{
$form = $this->factory->create('date', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'widget' => 'text',
));
@ -157,6 +169,8 @@ class DateTypeTest extends TestCase
public function testSubmitFromChoice()
{
$form = $this->factory->create('date', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'widget' => 'choice',
));
@ -177,6 +191,8 @@ class DateTypeTest extends TestCase
public function testSubmitFromChoiceEmpty()
{
$form = $this->factory->create('date', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'widget' => 'choice',
'required' => false,
));
@ -196,6 +212,8 @@ class DateTypeTest extends TestCase
public function testSubmitFromInputDateTimeDifferentPattern()
{
$form = $this->factory->create('date', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'format' => 'MM*yyyy*dd',
'widget' => 'single_text',
'input' => 'datetime',
@ -210,6 +228,8 @@ class DateTypeTest extends TestCase
public function testSubmitFromInputStringDifferentPattern()
{
$form = $this->factory->create('date', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'format' => 'MM*yyyy*dd',
'widget' => 'single_text',
'input' => 'string',
@ -224,6 +244,8 @@ class DateTypeTest extends TestCase
public function testSubmitFromInputTimestampDifferentPattern()
{
$form = $this->factory->create('date', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'format' => 'MM*yyyy*dd',
'widget' => 'single_text',
'input' => 'timestamp',
@ -240,6 +262,8 @@ class DateTypeTest extends TestCase
public function testSubmitFromInputRawDifferentPattern()
{
$form = $this->factory->create('date', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'format' => 'MM*yyyy*dd',
'widget' => 'single_text',
'input' => 'array',
@ -358,10 +382,25 @@ class DateTypeTest extends TestCase
public function testSetDataWithDifferentNegativeUTCTimezoneDateTime()
{
date_default_timezone_set('Pacific/Tahiti');
$form = $this->factory->create('date', null, array(
'format' => \IntlDateFormatter::MEDIUM,
'model_timezone' => 'America/New_York',
'view_timezone' => 'Pacific/Tahiti',
'input' => 'string',
'widget' => 'single_text',
));
$form->setData('2010-06-02');
$this->assertEquals('01.06.2010', $form->getViewData());
}
public function testSetDataWithDifferentTimezonesDateTime()
{
$form = $this->factory->create('date', null, array(
'format' => \IntlDateFormatter::MEDIUM,
'model_timezone' => 'America/New_York',
'view_timezone' => 'Pacific/Tahiti',
'input' => 'datetime',
'widget' => 'single_text',
));
@ -371,7 +410,7 @@ class DateTypeTest extends TestCase
$form->setData($dateTime);
$this->assertDateTimeEquals($dateTime, $form->getData());
$this->assertEquals('02.06.2010', $form->getViewData());
$this->assertEquals('01.06.2010', $form->getViewData());
}
public function testSetDataWithDifferentPositiveUTCTimezoneDateTime()
@ -520,6 +559,8 @@ class DateTypeTest extends TestCase
$this->markTestIncomplete('Needs to be reimplemented using validators');
$form = $this->factory->create('date', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'widget' => 'single_text',
));
@ -533,6 +574,8 @@ class DateTypeTest extends TestCase
$this->markTestIncomplete('Needs to be reimplemented using validators');
$form = $this->factory->create('date', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'widget' => 'choice',
));
@ -550,6 +593,8 @@ class DateTypeTest extends TestCase
$this->markTestIncomplete('Needs to be reimplemented using validators');
$form = $this->factory->create('date', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'widget' => 'choice',
));
@ -567,6 +612,8 @@ class DateTypeTest extends TestCase
$this->markTestIncomplete('Needs to be reimplemented using validators');
$form = $this->factory->create('date', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'widget' => 'choice',
));

View File

@ -18,25 +18,18 @@ use Symfony\Component\Intl\Util\IntlTestHelper;
class TimeTypeTest extends TestCase
{
private $defaultTimezone;
protected function setUp()
{
IntlTestHelper::requireIntl($this);
parent::setUp();
$this->defaultTimezone = date_default_timezone_get();
}
protected function tearDown()
{
date_default_timezone_set($this->defaultTimezone);
}
public function testSubmitDateTime()
{
$form = $this->factory->create('time', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'input' => 'datetime',
));
@ -56,6 +49,8 @@ class TimeTypeTest extends TestCase
public function testSubmitString()
{
$form = $this->factory->create('time', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'input' => 'string',
));
@ -73,6 +68,8 @@ class TimeTypeTest extends TestCase
public function testSubmitTimestamp()
{
$form = $this->factory->create('time', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'input' => 'timestamp',
));
@ -92,6 +89,8 @@ class TimeTypeTest extends TestCase
public function testSubmitArray()
{
$form = $this->factory->create('time', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'input' => 'array',
));
@ -109,6 +108,8 @@ class TimeTypeTest extends TestCase
public function testSubmitDatetimeSingleText()
{
$form = $this->factory->create('time', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'input' => 'datetime',
'widget' => 'single_text',
));
@ -122,6 +123,8 @@ class TimeTypeTest extends TestCase
public function testSubmitDatetimeSingleTextWithoutMinutes()
{
$form = $this->factory->create('time', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'input' => 'datetime',
'widget' => 'single_text',
'with_minutes' => false,
@ -136,6 +139,8 @@ class TimeTypeTest extends TestCase
public function testSubmitArraySingleText()
{
$form = $this->factory->create('time', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'input' => 'array',
'widget' => 'single_text',
));
@ -154,6 +159,8 @@ class TimeTypeTest extends TestCase
public function testSubmitArraySingleTextWithoutMinutes()
{
$form = $this->factory->create('time', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'input' => 'array',
'widget' => 'single_text',
'with_minutes' => false,
@ -172,6 +179,8 @@ class TimeTypeTest extends TestCase
public function testSubmitArraySingleTextWithSeconds()
{
$form = $this->factory->create('time', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'input' => 'array',
'widget' => 'single_text',
'with_seconds' => true,
@ -192,6 +201,8 @@ class TimeTypeTest extends TestCase
public function testSubmitStringSingleText()
{
$form = $this->factory->create('time', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'input' => 'string',
'widget' => 'single_text',
));
@ -205,6 +216,8 @@ class TimeTypeTest extends TestCase
public function testSubmitStringSingleTextWithoutMinutes()
{
$form = $this->factory->create('time', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'input' => 'string',
'widget' => 'single_text',
'with_minutes' => false,
@ -219,6 +232,8 @@ class TimeTypeTest extends TestCase
public function testSetDataWithoutMinutes()
{
$form = $this->factory->create('time', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'input' => 'datetime',
'with_minutes' => false,
));
@ -231,6 +246,8 @@ class TimeTypeTest extends TestCase
public function testSetDataWithSeconds()
{
$form = $this->factory->create('time', null, array(
'model_timezone' => 'UTC',
'view_timezone' => 'UTC',
'input' => 'datetime',
'with_seconds' => true,
));
@ -240,23 +257,53 @@ class TimeTypeTest extends TestCase
$this->assertEquals(array('hour' => 3, 'minute' => 4, 'second' => 5), $form->getViewData());
}
public function testSetDataWithTimezoneDateTime()
public function testSetDataDifferentTimezones()
{
date_default_timezone_set('Asia/Hong_Kong');
$form = $this->factory->create('time', null, array(
'model_timezone' => 'America/New_York',
'view_timezone' => 'Asia/Hong_Kong',
'input' => 'string',
'with_seconds' => true,
));
$dateTime = new \DateTime('2013-01-01 12:04:05');
$dateTime->setTimezone(new \DateTimeZone('America/New_York'));
$form->setData($dateTime->format('H:i:s'));
$outputTime = clone $dateTime;
$outputTime->setTimezone(new \DateTimeZone('Asia/Hong_Kong'));
$displayedData = array(
'hour' => (int) $outputTime->format('H'),
'minute' => (int) $outputTime->format('i'),
'second' => (int) $outputTime->format('s'),
);
$this->assertEquals($displayedData, $form->getViewData());
}
public function testSetDataDifferentTimezonesDateTime()
{
$form = $this->factory->create('time', null, array(
'model_timezone' => 'America/New_York',
'view_timezone' => 'Asia/Hong_Kong',
'input' => 'datetime',
'with_seconds' => true,
));
$dateTime = new \DateTime('12:04:05', new \DateTimeZone('America/New_York'));
$dateTime = new \DateTime('12:04:05');
$dateTime->setTimezone(new \DateTimeZone('America/New_York'));
$form->setData($dateTime);
$outputTime = clone $dateTime;
$outputTime->setTimezone(new \DateTimeZone('Asia/Hong_Kong'));
$displayedData = array(
'hour' => 12,
'minute' => 4,
'second' => 5,
'hour' => (int) $outputTime->format('H'),
'minute' => (int) $outputTime->format('i'),
'second' => (int) $outputTime->format('s'),
);
$this->assertDateTimeEquals($dateTime, $form->getData());

View File

@ -98,10 +98,6 @@ class ResolvedFormTypeTest extends \PHPUnit_Framework_TestCase
public function testCreateBuilder()
{
if (version_compare(\PHPUnit_Runner_Version::id(), '3.7', '<')) {
$this->markTestSkipped('This test requires PHPUnit 3.7.');
}
$givenOptions = array('a' => 'a_custom', 'c' => 'c_custom');
$resolvedOptions = array('a' => 'a_custom', 'b' => 'b_default', 'c' => 'c_custom', 'd' => 'd_default');
$optionsResolver = $this->getMock('Symfony\Component\OptionsResolver\OptionsResolverInterface');
@ -130,10 +126,6 @@ class ResolvedFormTypeTest extends \PHPUnit_Framework_TestCase
public function testCreateBuilderWithDataClassOption()
{
if (version_compare(\PHPUnit_Runner_Version::id(), '3.7', '<')) {
$this->markTestSkipped('This test requires PHPUnit 3.7.');
}
$givenOptions = array('data_class' => 'Foo');
$resolvedOptions = array('data_class' => '\stdClass');
$optionsResolver = $this->getMock('Symfony\Component\OptionsResolver\OptionsResolverInterface');
@ -162,10 +154,6 @@ class ResolvedFormTypeTest extends \PHPUnit_Framework_TestCase
public function testBuildForm()
{
if (version_compare(\PHPUnit_Runner_Version::id(), '3.7', '<')) {
$this->markTestSkipped('This test requires PHPUnit 3.7.');
}
$i = 0;
$assertIndex = function ($index) use (&$i) {
@ -278,7 +266,6 @@ class ResolvedFormTypeTest extends \PHPUnit_Framework_TestCase
$assertIndex = function ($index) use (&$i) {
return function () use (&$i, $index) {
/* @var \PHPUnit_Framework_TestCase $test */
$this->assertEquals($index, $i, 'Executed at index '.$index);
++$i;

View File

@ -68,7 +68,7 @@ class RouterListener implements EventSubscriberInterface
}
if (!$requestStack instanceof RequestStack) {
trigger_error('The '.__METHOD__.' method now requires a RequestStack instance as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.');
trigger_error('The '.__METHOD__.' method now requires a RequestStack instance as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED);
}
$this->matcher = $matcher;

View File

@ -11,7 +11,7 @@
namespace Symfony\Component\HttpKernel\Log;
trigger_error('The '.__NAMESPACE__.'\NullLogger class is deprecated since version 2.2 and will be removed in 3.0. Use the Psr\Log\NullLogger class instead from the psr/log Composer package.');
trigger_error('The '.__NAMESPACE__.'\NullLogger class is deprecated since version 2.2 and will be removed in 3.0. Use the Psr\Log\NullLogger class instead from the psr/log Composer package.', E_USER_DEPRECATED);
use Psr\Log\NullLogger as PsrNullLogger;

View File

@ -230,7 +230,7 @@ class WindowsPipes extends AbstractPipes
if (false === $data || (true === $close && feof($r['input']) && '' === $data)) {
// no more data to read on input resource
// use an empty buffer in the next reads
unset($this->input);
$this->input = null;
}
}

View File

@ -47,7 +47,10 @@ class SessionAuthenticationStrategy implements SessionAuthenticationStrategyInte
return;
case self::MIGRATE:
$request->getSession()->migrate(true);
// Destroying the old session is broken in php 5.4.0 - 5.4.10
// See php bug #63379
$destroy = PHP_VERSION_ID < 50400 || PHP_VERSION_ID >= 50411;
$request->getSession()->migrate($destroy);
return;

View File

@ -39,6 +39,10 @@ class SessionAuthenticationStrategyTest extends \PHPUnit_Framework_TestCase
public function testSessionIsMigrated()
{
if (PHP_VERSION_ID >= 50400 && PHP_VERSION_ID < 50411) {
$this->markTestSkipped('We cannot destroy the old session on PHP 5.4.0 - 5.4.10.');
}
$session = $this->getMock('Symfony\Component\HttpFoundation\Session\SessionInterface');
$session->expects($this->once())->method('migrate')->with($this->equalTo(true));
@ -46,6 +50,19 @@ class SessionAuthenticationStrategyTest extends \PHPUnit_Framework_TestCase
$strategy->onAuthentication($this->getRequest($session), $this->getToken());
}
public function testSessionIsMigratedWithPhp54Workaround()
{
if (PHP_VERSION_ID < 50400 || PHP_VERSION_ID >= 50411) {
$this->markTestSkipped('This PHP version is not affected.');
}
$session = $this->getMock('Symfony\Component\HttpFoundation\Session\SessionInterface');
$session->expects($this->once())->method('migrate')->with($this->equalTo(false));
$strategy = new SessionAuthenticationStrategy(SessionAuthenticationStrategy::MIGRATE);
$strategy->onAuthentication($this->getRequest($session), $this->getToken());
}
public function testSessionIsInvalidated()
{
$session = $this->getMock('Symfony\Component\HttpFoundation\Session\SessionInterface');

View File

@ -11,6 +11,7 @@
namespace Symfony\Component\Serializer\Normalizer;
use Symfony\Component\Serializer\Exception\CircularReferenceException;
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
@ -21,6 +22,8 @@ use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
*/
abstract class AbstractNormalizer extends SerializerAwareNormalizer implements NormalizerInterface, DenormalizerInterface
{
protected $circularReferenceLimit = 1;
protected $circularReferenceHandler;
protected $classMetadataFactory;
protected $callbacks = array();
protected $ignoredAttributes = array();
@ -36,6 +39,40 @@ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements N
$this->classMetadataFactory = $classMetadataFactory;
}
/**
* Set circular reference limit.
*
* @param $circularReferenceLimit limit of iterations for the same object
*
* @return self
*/
public function setCircularReferenceLimit($circularReferenceLimit)
{
$this->circularReferenceLimit = $circularReferenceLimit;
return $this;
}
/**
* Set circular reference handler.
*
* @param callable $circularReferenceHandler
*
* @return self
*
* @throws InvalidArgumentException
*/
public function setCircularReferenceHandler($circularReferenceHandler)
{
if (!is_callable($circularReferenceHandler)) {
throw new InvalidArgumentException('The given circular reference handler is not callable.');
}
$this->circularReferenceHandler = $circularReferenceHandler;
return $this;
}
/**
* Set normalization callbacks.
*
@ -88,6 +125,56 @@ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements N
return $this;
}
/**
* Detects if the configured circular reference limit is reached.
*
* @param object $object
* @param array $context
*
* @return bool
*
* @throws CircularReferenceException
*/
protected function isCircularReference($object, &$context)
{
$objectHash = spl_object_hash($object);
if (isset($context['circular_reference_limit'][$objectHash])) {
if ($context['circular_reference_limit'][$objectHash] >= $this->circularReferenceLimit) {
unset($context['circular_reference_limit'][$objectHash]);
return true;
}
$context['circular_reference_limit'][$objectHash]++;
} else {
$context['circular_reference_limit'][$objectHash] = 1;
}
return false;
}
/**
* Handles a circular reference.
*
* If a circular reference handler is set, it will be called. Otherwise, a
* {@class CircularReferenceException} will be thrown.
*
* @param object $object
*
* @return mixed
*
* @throws CircularReferenceException
*/
protected function handleCircularReference($object)
{
if ($this->circularReferenceHandler) {
return call_user_func($this->circularReferenceHandler, $object);
}
throw new CircularReferenceException(sprintf('A circular reference has been detected (configured limit: %d).', $this->circularReferenceLimit));
}
/**
* Format an attribute name, for example to convert a snake_case name to camelCase.
*
@ -127,4 +214,88 @@ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements N
return array_unique($allowedAttributes);
}
/**
* Normalizes the given data to an array. It's particularly useful during
* the denormalization process.
*
* @param object|array $data
*
* @return array
*/
protected function prepareForDenormalization($data)
{
if (is_array($data) || is_object($data) && $data instanceof \ArrayAccess) {
$normalizedData = $data;
} elseif (is_object($data)) {
$normalizedData = array();
foreach ($data as $attribute => $value) {
$normalizedData[$attribute] = $value;
}
} else {
$normalizedData = array();
}
return $normalizedData;
}
/**
* Instantiates an object using contructor parameters when needed.
*
* This method also allows to denormalize data into an existing object if
* it is present in the context with the object_to_populate key.
*
* @param array $data
* @param string $class
* @param array $context
* @param \ReflectionClass $reflectionClass
* @param array|bool $allowedAttributes
*
* @return object
*
* @throws RuntimeException
*/
protected function instantiateObject(array $data, $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes)
{
if (
isset($context['object_to_populate']) &&
is_object($context['object_to_populate']) &&
$class === get_class($context['object_to_populate'])
) {
return $context['object_to_populate'];
}
$constructor = $reflectionClass->getConstructor();
if ($constructor) {
$constructorParameters = $constructor->getParameters();
$params = array();
foreach ($constructorParameters as $constructorParameter) {
$paramName = lcfirst($this->formatAttribute($constructorParameter->name));
$allowed = $allowedAttributes === false || in_array($paramName, $allowedAttributes);
$ignored = in_array($paramName, $this->ignoredAttributes);
if ($allowed && !$ignored && isset($data[$paramName])) {
$params[] = $data[$paramName];
// don't run set for a parameter passed to the constructor
unset($data[$paramName]);
} elseif ($constructorParameter->isOptional()) {
$params[] = $constructorParameter->getDefaultValue();
} else {
throw new RuntimeException(
sprintf(
'Cannot create an instance of %s from serialized data because its constructor requires parameter "%s" to be present.',
$class,
$constructorParameter->name
)
);
}
}
return $reflectionClass->newInstanceArgs($params);
}
return new $class();
}
}

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Serializer\Normalizer;
use Symfony\Component\Serializer\Exception\CircularReferenceException;
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Exception\RuntimeException;
/**
@ -38,64 +37,15 @@ use Symfony\Component\Serializer\Exception\RuntimeException;
*/
class GetSetMethodNormalizer extends AbstractNormalizer
{
protected $circularReferenceLimit = 1;
protected $circularReferenceHandler;
/**
* Set circular reference limit.
*
* @param $circularReferenceLimit limit of iterations for the same object
*
* @return self
*/
public function setCircularReferenceLimit($circularReferenceLimit)
{
$this->circularReferenceLimit = $circularReferenceLimit;
return $this;
}
/**
* Set circular reference handler.
*
* @param callable $circularReferenceHandler
*
* @return self
*
* @throws InvalidArgumentException
*/
public function setCircularReferenceHandler($circularReferenceHandler)
{
if (!is_callable($circularReferenceHandler)) {
throw new InvalidArgumentException('The given circular reference handler is not callable.');
}
$this->circularReferenceHandler = $circularReferenceHandler;
return $this;
}
/**
* {@inheritdoc}
*
* @throws CircularReferenceException
*/
public function normalize($object, $format = null, array $context = array())
{
$objectHash = spl_object_hash($object);
if (isset($context['circular_reference_limit'][$objectHash])) {
if ($context['circular_reference_limit'][$objectHash] >= $this->circularReferenceLimit) {
unset($context['circular_reference_limit'][$objectHash]);
if ($this->circularReferenceHandler) {
return call_user_func($this->circularReferenceHandler, $object);
}
throw new CircularReferenceException(sprintf('A circular reference has been detected (configured limit: %d).', $this->circularReferenceLimit));
}
$context['circular_reference_limit'][$objectHash]++;
} else {
$context['circular_reference_limit'][$objectHash] = 1;
if ($this->isCircularReference($object, $context)) {
return $this->handleCircularReference($object);
}
$reflectionObject = new \ReflectionObject($object);
@ -136,54 +86,16 @@ class GetSetMethodNormalizer extends AbstractNormalizer
/**
* {@inheritdoc}
*
* @throws RuntimeException
*/
public function denormalize($data, $class, $format = null, array $context = array())
{
$allowedAttributes = $this->getAllowedAttributes($class, $context);
if (is_array($data) || is_object($data) && $data instanceof \ArrayAccess) {
$normalizedData = $data;
} elseif (is_object($data)) {
$normalizedData = array();
foreach ($data as $attribute => $value) {
$normalizedData[$attribute] = $value;
}
} else {
$normalizedData = array();
}
$normalizedData = $this->prepareForDenormalization($data);
$reflectionClass = new \ReflectionClass($class);
$constructor = $reflectionClass->getConstructor();
if ($constructor) {
$constructorParameters = $constructor->getParameters();
$params = array();
foreach ($constructorParameters as $constructorParameter) {
$paramName = lcfirst($this->formatAttribute($constructorParameter->name));
$allowed = $allowedAttributes === false || in_array($paramName, $allowedAttributes);
$ignored = in_array($paramName, $this->ignoredAttributes);
if ($allowed && !$ignored && isset($normalizedData[$paramName])) {
$params[] = $normalizedData[$paramName];
// don't run set for a parameter passed to the constructor
unset($normalizedData[$paramName]);
} elseif ($constructorParameter->isOptional()) {
$params[] = $constructorParameter->getDefaultValue();
} else {
throw new RuntimeException(
'Cannot create an instance of '.$class.
' from serialized data because its constructor requires '.
'parameter "'.$constructorParameter->name.
'" to be present.');
}
}
$object = $reflectionClass->newInstanceArgs($params);
} else {
$object = new $class();
}
$object = $this->instantiateObject($normalizedData, $class, $context, $reflectionClass, $allowedAttributes);
foreach ($normalizedData as $attribute => $value) {
$allowed = $allowedAttributes === false || in_array($attribute, $allowedAttributes);

View File

@ -11,6 +11,7 @@
namespace Symfony\Component\Serializer\Normalizer;
use Symfony\Component\Serializer\Exception\CircularReferenceException;
use Symfony\Component\Serializer\Exception\RuntimeException;
/**
@ -34,9 +35,15 @@ class PropertyNormalizer extends AbstractNormalizer
{
/**
* {@inheritdoc}
*
* @throws CircularReferenceException
*/
public function normalize($object, $format = null, array $context = array())
{
if ($this->isCircularReference($object, $context)) {
return $this->handleCircularReference($object);
}
$reflectionObject = new \ReflectionObject($object);
$attributes = array();
$allowedAttributes = $this->getAllowedAttributes($object, $context);
@ -61,7 +68,7 @@ class PropertyNormalizer extends AbstractNormalizer
$attributeValue = call_user_func($this->callbacks[$property->name], $attributeValue);
}
if (null !== $attributeValue && !is_scalar($attributeValue)) {
$attributeValue = $this->serializer->normalize($attributeValue, $format);
$attributeValue = $this->serializer->normalize($attributeValue, $format, $context);
}
$attributes[$property->name] = $attributeValue;
@ -72,41 +79,16 @@ class PropertyNormalizer extends AbstractNormalizer
/**
* {@inheritdoc}
*
* @throws RuntimeException
*/
public function denormalize($data, $class, $format = null, array $context = array())
{
$allowedAttributes = $this->getAllowedAttributes($class, $context);
$data = $this->prepareForDenormalization($data);
$reflectionClass = new \ReflectionClass($class);
$constructor = $reflectionClass->getConstructor();
if ($constructor) {
$constructorParameters = $constructor->getParameters();
$params = array();
foreach ($constructorParameters as $constructorParameter) {
$paramName = lcfirst($this->formatAttribute($constructorParameter->name));
$allowed = $allowedAttributes === false || in_array($paramName, $allowedAttributes);
$ignored = in_array($paramName, $this->ignoredAttributes);
if ($allowed && !$ignored && isset($data[$paramName])) {
$params[] = $data[$paramName];
// don't run set for a parameter passed to the constructor
unset($data[$paramName]);
} elseif (!$constructorParameter->isOptional()) {
throw new RuntimeException(sprintf(
'Cannot create an instance of %s from serialized data because '.
'its constructor requires parameter "%s" to be present.',
$class,
$constructorParameter->name
));
}
}
$object = $reflectionClass->newInstanceArgs($params);
} else {
$object = new $class();
}
$object = $this->instantiateObject($data, $class, $context, $reflectionClass, $allowedAttributes);
foreach ($data as $propertyName => $value) {
$propertyName = lcfirst($this->formatAttribute($propertyName));

View File

@ -0,0 +1,25 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Serializer\Tests\Fixtures;
/**
* @author Kévin Dunglas <dunglas@gmail.com>
*/
class PropertyCircularReferenceDummy
{
public $me;
public function __construct()
{
$this->me = $this;
}
}

View File

@ -0,0 +1,39 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Serializer\Tests\Fixtures;
/**
* @author Kévin Dunglas <dunglas@gmail.com>
*/
class PropertySiblingHolder
{
public $sibling0;
public $sibling1;
public $sibling2;
public function __construct()
{
$sibling = new PropertySibling();
$this->sibling0 = $sibling;
$this->sibling1 = $sibling;
$this->sibling2 = $sibling;
}
}
/**
* @author Kévin Dunglas <dunglas@gmail.com>
*/
class PropertySibling
{
public $coopTilleuls = 'Les-Tilleuls.coop';
}

View File

@ -23,6 +23,7 @@ class SiblingHolder
public function __construct()
{
$sibling = new Sibling();
$this->sibling0 = $sibling;
$this->sibling1 = $sibling;
$this->sibling2 = $sibling;

View File

@ -385,6 +385,23 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase
$expected = array('me' => 'Symfony\Component\Serializer\Tests\Fixtures\CircularReferenceDummy');
$this->assertEquals($expected, $this->normalizer->normalize($obj));
}
public function testObjectToPopulate()
{
$dummy = new GetSetDummy();
$dummy->setFoo('foo');
$obj = $this->normalizer->denormalize(
array('bar' => 'bar'),
__NAMESPACE__.'\GetSetDummy',
null,
array('object_to_populate' => $dummy)
);
$this->assertEquals($dummy, $obj);
$this->assertEquals('foo', $obj->getFoo());
$this->assertEquals('bar', $obj->getBar());
}
}
class GetSetDummy

View File

@ -15,8 +15,11 @@ use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Serializer\Tests\Fixtures\GroupDummy;
use Symfony\Component\Serializer\Tests\Fixtures\PropertyCircularReferenceDummy;
use Symfony\Component\Serializer\Tests\Fixtures\PropertySiblingHolder;
require_once __DIR__.'/../../Annotation/Groups.php';
@ -264,6 +267,49 @@ class PropertyNormalizerTest extends \PHPUnit_Framework_TestCase
),
);
}
/**
* @expectedException \Symfony\Component\Serializer\Exception\CircularReferenceException
*/
public function testUnableToNormalizeCircularReference()
{
$serializer = new Serializer(array($this->normalizer));
$this->normalizer->setSerializer($serializer);
$this->normalizer->setCircularReferenceLimit(2);
$obj = new PropertyCircularReferenceDummy();
$this->normalizer->normalize($obj);
}
public function testSiblingReference()
{
$serializer = new Serializer(array($this->normalizer));
$this->normalizer->setSerializer($serializer);
$siblingHolder = new PropertySiblingHolder();
$expected = array(
'sibling0' => array('coopTilleuls' => 'Les-Tilleuls.coop'),
'sibling1' => array('coopTilleuls' => 'Les-Tilleuls.coop'),
'sibling2' => array('coopTilleuls' => 'Les-Tilleuls.coop'),
);
$this->assertEquals($expected, $this->normalizer->normalize($siblingHolder));
}
public function testCircularReferenceHandler()
{
$serializer = new Serializer(array($this->normalizer));
$this->normalizer->setSerializer($serializer);
$this->normalizer->setCircularReferenceHandler(function ($obj) {
return get_class($obj);
});
$obj = new PropertyCircularReferenceDummy();
$expected = array('me' => 'Symfony\Component\Serializer\Tests\Fixtures\PropertyCircularReferenceDummy');
$this->assertEquals($expected, $this->normalizer->normalize($obj));
}
}
class PropertyDummy