Merge pull request #1 from symfony/master

update symfony repo
This commit is contained in:
Tiago Brito 2013-01-10 13:37:17 -08:00
commit 87df0b7ee2
795 changed files with 14404 additions and 5048 deletions

View File

@ -4,6 +4,11 @@ php:
- 5.3.3
- 5.3
- 5.4
- 5.5
matrix:
allow_failures:
- php: 5.5
before_script:
- COMPOSER_ROOT_VERSION=dev-master composer --prefer-source --dev install

View File

@ -7,6 +7,22 @@ in 2.0 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.0.0...v2.0.1
* 2.0.21 (2012-12-21)
* b8e5689: [FrameworkBundle] fixed ESI calls
* 2.0.20 (2012-12-20)
* 532cc9a: [FrameworkBundle] added support for URIs as an argument to HttpKernel::render()
* 1f8c501: [FrameworkBundle] restricted the type of controllers that can be executed by InternalController
* 8b2c17f: fix double-decoding in the routing system
* 773d818: [FrameworkBundle] Added a check on file mime type for CodeHelper::fileExcerpt()
* a0e2391: [FrameworkBundle] used the new method for trusted proxies
* 8bb3208: [Config] Loader::import must return imported data
* 447ff91: [HttpFoundation] changed UploadedFile::move() to use move_uploaded_file() when possible
* 0489799: [HttpFoundation] added a check for the host header value
* ae3d531: [TwigBundle] Moved the registration of the app global to the environment
* 2.0.19 (2012-11-29)
* e5536f0: replaced magic strings by proper constants

View File

@ -7,6 +7,46 @@ in 2.1 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.1.0...v2.1.1
* 2.1.6 (2012-12-21)
* b8e5689: [FrameworkBundle] fixed ESI calls
* ce536cd: [FrameworkBundle] fixed ESI calls
* 2.1.5 (2012-12-20)
* 532cc9a: [FrameworkBundle] added support for URIs as an argument to HttpKernel::render()
* 1f8c501: [FrameworkBundle] restricted the type of controllers that can be executed by InternalController
* 2cd43da: [Process] Allow non-blocking start with PhpProcess
* 8b2c17f: fix double-decoding in the routing system
* 098b593: [Session] Added exception to save method
* ad29df5: [Form] Fixed DateTimeToStringTransformer parsing on PHP < 5.3.8
* 773d818: [FrameworkBundle] Added a check on file mime type for CodeHelper::fileExcerpt()
* f24e3d7: [HttpKernel] Revise MongoDbProfilerStorage::write() return value
* 78c5273: [Session] Document Mongo|MongoClient argument type instead of "object"
* de19a81: [HttpKernel] Support MongoClient and Mongo connection classes
* b28af77: [Session] Support MongoClient and Mongo connection classes
* 20e93bf: [Session] Utilize MongoDB::selectCollection()
* b20c5ca: [Form] Fixed reverse transformation of values in DateTimeToStringTransformer
* d2231d8: [Console] Add support for parsing terminal width/height on localized windows, fixes #5742
* 03b880f: [Form] Fixed treatment of countables and traversables in Form::isEmpty()
* 21a59ca: [Form] Fixed FileType not to throw an exception when bound empty
* eac14b5: Check if key # is defined in $value
* a0e2391: [FrameworkBundle] used the new method for trusted proxies
* d6a402a: [Security] fixed path info encoding (closes #6040, closes #5695)
* 47dfb9c: [HttpFoundation] added some tests for the previous merge and removed dead code (closes #6037)
* 1ab4923: Improved Cache-Control header when no-cache is sent
* 4e909bd: Fix to allow null values in labels array
* 9e46819: Fixed: HeaderBag::parseCacheControl() not parsing quoted zero correctly
* 8bb3208: [Config] Loader::import must return imported data
* ca5d9ac: [DoctrineBridge] Fixed caching in DoctrineType when "choices" or "preferred_choices" is passed
* 6e7e08f: [Form] Fixed the default value of "format" in DateType to DateType::DEFAULT_FORMAT if "widget" is not "single_text"
* 447ff91: [HttpFoundation] changed UploadedFile::move() to use move_uploaded_file() when possible (closes #5878, closes #6185)
* 0489799: [HttpFoundation] added a check for the host header value
* b604eb7: [DoctrineBridge] Improved performance of the EntityType when used with the "query_builder" option
* 99321cb: [DoctrineBridge] Fixed: Exception is thrown if the entity class is not known to Doctrine
* 2ed30e7: Fixed DefaultValue for session.auto_start in NodeDefinition
* ae3d531: [TwigBundle] Moved the registration of the app global to the environment
* 2.1.4 (2012-11-29)
* e5536f0: replaced magic strings by proper constants

View File

@ -3,7 +3,9 @@ Contributing
Symfony2 is an open source, community-driven project. If you'd like to contribute,
please read the [Contributing Code][1] part of the documentation. If you're submitting
a pull request, please follow the guidelines in the [Submitting a Patch][2] section.
a pull request, please follow the guidelines in the [Submitting a Patch][2] section
and use the [Pull Request Template][3].
[1]: http://symfony.com/doc/current/contributing/code/index.html
[2]: http://symfony.com/doc/current/contributing/code/patches.html#check-list
[3]: http://symfony.com/doc/current/contributing/code/patches.html#make-a-pull-request

View File

@ -11,116 +11,125 @@ Symfony2 is the result of the work of many people who made the code better
- Johannes S (johannes)
- Kris Wallsmith (kriswallsmith)
- Christophe Coevoet (stof)
- Tobias Schultze (tobion)
- Pascal Borreli (pborreli)
- Karma Dordrak (drak)
- Ryan Weaver
- Pascal Borreli (pborreli)
- Lukas Kahwe Smith (lsmith)
- Tobias Schultze (tobion)
- Jeremy Mikola (jmikola)
- Benjamin Eberlei (beberlei)
- Igor Wiedler (igorw)
- Joseph Bielawski (stloyd)
- Eriksen Costa (eriksencosta)
- Hugo Hamon (hhamon)
- Jonathan Wage (jwage)
- Martin Hasoň (hason)
- Jonathan Wage (jwage)
- William Durand (couac)
- Alexandre Salomé (alexandresalome)
- ornicar
- stealth35 (stealth35)
- Jean-François Simon (jfsimon)
- Bulat Shakirzyanov (avalanche123)
- Francis Besset (francisbesset)
- Miha Vrhovnik
- Henrik Bjørnskov (henrikbjorn)
- Konstantin Kudryashov (everzet)
- Jean-François Simon (jfsimon)
- Jakub Zalas (jakubzalas)
- Arnaud Le Blanc (arnaud-lb)
- Eric Clemmons (ericclemmons)
- Henrik Westphal (snc)
- Deni
- Dariusz Górecki (canni)
- Alexander Mols (asm89)
- Arnout Boks (aboks)
- Hidenori Goto (hidenorigoto)
- Jordan Alliot (jalliot)
- Deni
- Romain Neutron (romain)
- Dariusz Górecki (canni)
- Marc Weistroff (futurecat)
- Brandon Turner
- Jordan Alliot (jalliot)
- Arnout Boks (aboks)
- Саша Стаменковић (umpirsky)
- Hidenori Goto (hidenorigoto)
- Brandon Turner
- Andrej Hudec (pulzarraider)
- Brikou Carré (brikou)
- John Wards (johnwards)
- Daniel Holmes (dholmes)
- Antoine Hérault (herzult)
- Daniel Holmes (dholmes)
- Bilal Amarni (bamarni)
- Christian Raue
- Tim Nagel (merk)
- Michal Piotrowski (eventhorizon)
- Włodzimierz Gajda (gajdaw)
- Florin Patan (florinpatan)
- lenar
- Fabien Pennequin (fabienpennequin)
- Tim Nagel (merk)
- excelwebzone
- Bilal Amarni (bamarni)
- Romain Neutron (romain)
- Bart van den Burg (burgov)
- excelwebzone
- Kevin Bond (kbond)
- Włodzimierz Gajda (gajdaw)
- Toni Uebernickel (havvg)
- Douglas Greenshields (shieldo)
- Richard Miller (mr_r_miller)
- Grégoire Pineau (lyrixx)
- Toni Uebernickel (havvg)
- Jacob Dreesen (jdreesen)
- Douglas Greenshields (shieldo)
- Richard Shank (iampersistent)
- Sebastian Hörl (blogsh)
- Florin Patan (florinpatan)
- Michal Piotrowski (eventhorizon)
- Grégoire Pineau (lyrixx)
- Mario A. Alvarez Garcia (nomack84)
- Juti Noppornpitak
- Robert Schönthal (digitalkaoz)
- Michał Pipa (michal.pipa)
- woodspire
- Daniel Gomes (danielcsgomes)
- Michel Weimerskirch (mweimerskirch)
- Tigran Azatyan (tigranazatyan)
- Pierre Minnieur (pminnieur)
- Arnaud Kleinpeter (nanocom)
- Jonathan Ingram (jonathaningram)
- Javier Eguiluz (javier.eguiluz)
- Matthieu Ouellette-Vachon (maoueh)
- Larry Garfield (crell)
- Amal Raghav (kertz)
- Artur Kotyrba
- Pablo Godel (pgodel)
- Helmer Aaviksoo
- Clément JOBEILI (dator)
- Julien Brochet (mewt)
- Arnaud Kleinpeter (nanocom)
- Jonathan Ingram (jonathaningram)
- David Buchmann (dbu)
- Sebastiaan Stok (sstok)
- Benjamin Dulau (dbenjamin)
- Felix Labrecque
- Andreas Hucks (meandmymonkey)
- Noel Guilbert (noel)
- Jérémie Augustin (jaugustin)
- Martin Schuhfuß (usefulthink)
- Thomas Rabaix (rande)
- Dennis Benkert (denderello)
- Marcel Beerta (mazen)
- Rafael Dohms (rdohms)
- Matthieu Bontemps (mbontemps)
- fivestar
- Dominique Bongiraud
- Pablo Godel (pgodel)
- Arnaud Le Blanc (arnaud-lb)
- Leszek Prabucki (l3l0)
- Danny Berger (dpb587)
- Dustin Whittle (dustinwhittle)
- Fran Moreno (franmomu)
- jeff
- Justin Hileman (bobthecow)
- Sven Paulus (subsven)
- Xavier Perez
- Rui Marinho (ruimarinho)
- Ray
- Joseph Rouff (rouffj)
- Marcel Beerta (mazen)
- Albert Casademont (acasademont)
- Gordon Franke (gimler)
- Francois Zaninotto
- François Zaninotto (fzaninotto)
- Danny Berger (dpb587)
- Xavier Montaña Carreras (xmontana)
- Gábor Egyed (1ed)
- Katsuhiro OGAWA
- Clemens Tolboom
- Alif Rachmawadi
- Larry Garfield (crell)
- boombatower
- Florian Klein (docteurklein)
- jules boussekeyt (gordonslondon)
- Jan Sorgalla (jsor)
- Ray
- Lee McDermott
- Guilherme Blanco (guilhermeblanco)
- jdhoek
@ -128,40 +137,44 @@ Symfony2 is the result of the work of many people who made the code better
- Wodor Wodorski
- Matthew Lewinski (lewinski)
- Kim Hemsø Rasmussen
- Dirk Pahl (dirkaholic)
- Wouter Van Hecke
- Gyula Sallai (salla)
- Michael Holm (hollo)
- Peter Kokot (maastermedia)
- arjen
- Florian Klein (docteurklein)
- Adrien Brault (adrienbrault)
- David Buchmann (dbu)
- Manuel Kiessling (manuelkiessling)
- Sergey Linnik
- Bertrand Zuchuat (garfield-fr)
- Beau Simensen (simensen)
- Grégoire Paris (greg0ire)
- Tamas Szijarto
- Grégoire Passault (gregwar)
- Aurelijus Valeiša (aurelijus)
- Gustavo Piltcher
- Albert Casademont (acasademont)
- Stepan Tanasiychuk (stfalcon)
- Albert Jessurum (ajessu)
- Tiago Ribeiro (fixe)
- Adrian Rudnik (kreischweide)
- Francesc Rosàs (frosas)
- Julien Galenski (ruian)
- Bongiraud Dominique
- Michel Salib (michelsalib)
- Jeanmonod David (jeanmonod)
- Thomas Lallement (raziel057)
- Niklas Fiekas
- Brouznouf
- Andréia Bohner (andreia)
- Sebastiaan Stok (sstok)
- Sebastian Bergmann
- Fran Moreno (franmomu)
- Greg Thornton (xdissent)
- sun (sun)
- Yaroslav Kiliba
- Lars Strojny
- Beau Simensen (simensen)
- Terje Bråten
- Costin Bereveanu (schniper)
- Markus Lanthaler (lanthaler)
- realmfoo
- Tamas Szijarto
- Mario A. Alvarez Garcia (nomack84)
- Tobias Naumann
- Shein Alexey
- Joe Lencioni
@ -173,21 +186,18 @@ Symfony2 is the result of the work of many people who made the code better
- Oscar Cubo Medina (ocubom)
- Christophe L. (christophelau)
- Michael Ridgway
- Stepan Tanasiychuk (stfalcon)
- Pavel Campr (pcampr)
- Brian King
- Jeanmonod David (jeanmonod)
- Jan Schumann
- Niklas Fiekas
- Olivier Dolbeau (odolbeau)
- Michele Orselli (orso)
- Asier Illarramendi (doup)
- Christoph Mewes (xrstf)
- Dirk Pahl (dirkaholic)
- Jonas Flodén (flojon)
- Shigenibu Nishikawa
- Marcin Sikoń (marphi)
- Miquel Rodríguez Telep (mrtorrent)
- boombatower
- Filippo Tessarotto
- Laurent Bachelier (laurentb)
- Fabian Lange (codingfabian)
- Yoshio HANAWA
@ -196,9 +206,11 @@ Symfony2 is the result of the work of many people who made the code better
- Michael Piecko (michael.piecko)
- Manuel de Ruiter (manuel)
- ondrowan
- Roman Marintsenko (inori)
- mcben
- Yaroslav Kiliba
- Jérôme Vieilledent (lolautruche)
- Peter Kruithof (pkruithof)
- Eric GELOEN (gelo)
- Erik Trapman (eriktrapman)
- De Cock Xavier (xdecock)
- Manuel Reinhard (sprain)
@ -221,19 +233,33 @@ Symfony2 is the result of the work of many people who made the code better
- Zach Badgett (zachbadgett)
- Aurélien Fredouelle
- Francesco Levorato
- Thomas Tourlourat (armetiz)
- Geoffrey Tran (geoff)
- Florian Rey (nervo)
- Christian Schaefer (caefer)
- Julien Galenski (ruian)
- Elliot Anderson (elliot)
- Patrick Kaufmann
- Ben Ramsey (ramsey)
- Christian Jul Jensen
- Chris Jones (leek)
- Markus Bachmann (baachi)
- Colin Frei
- aubx
- Max Rath (drak3)
- DerManoMann
- Nahuel Cuesta (ncuesta)
- Chris Boden (cboden)
- Roumen Damianoff (roumen)
- Jeremy David (jeremy.david)
- Konstantin Myakshin (koc)
- Dustin Dobervich (dustin10)
- Sebastian Marek (proofek)
- Erkhembayar Gantulga (erheme318)
- Ken Marfilla (marfillaster)
- Rostyslav Kinash
- jfcixmedia
- Vincent Simonin
- Chris Heng
- yktd26
- Tom Van Looy (tvlooy)
- umpirski
@ -241,57 +267,70 @@ Symfony2 is the result of the work of many people who made the code better
- John Kary (johnkary)
- Hossein Bukhamsin
- Fabrice Bernhard (fabriceb)
- Mark Sonnabaum
- develop
- Filippo Tessarotto
- hossein zolfi (ocean)
- Atsuhiro KUBO (iteman)
- Samy Dindane (dinduks)
- yclian
- Jérémy Romey (jeremyfreeagent)
- Matt Daum (daum)
- Hiromi Hishida (77web)
- Yuen-Chi Lian
- Joshua Nye
- Sebastian Krebs
- avorobiev
- Mark Challoner
- Andrew Tchircoff (andrewtch)
- BilgeXA
- michaelwilliams
- Casper Valdemar Poulsen
- Josiah (josiah)
- John Bohn (jbohn)
- Nicolas Schwartz (nicoschwartz)
- Degory Valentine
- Krzysiek Łabuś
- Xavier Lacot (xavier)
- Markus Lanthaler (lanthaler)
- Olivier Maisonneuve
- Daniel F. Kudwien (sun)
- cgonzalez
- matt foster
- Evan S Kaufman (evanskaufman)
- Ismael Ambrosi (iambrosi)
- Jayson Xu (superjavason)
- Jan Prieser
- James Michael DuPont
- Tom Klingenberg
- Gunther Konig
- Christopher Hall (mythmakr)
- Paul Kamer (pkamer)
- Pierre Vanliefland (pvanliefland)
- Philipp Kräutli (pkraeutli)
- frost-nzcr4
- Loïc Chardonnet (gnusat)
- Michaël Perrin (michael.perrin)
- Abhoryo
- Fabian Vogler (fabian)
- Leevi Graham
- Maksim Kotlyar (makasim)
- Neil Ferreira
- Tony Malzhacker
- Cyril Quintin (cyqui)
- Gerard van Helden (drm)
- Johnny Peck (johnnypeck)
- Denis Gorbachev (starfall)
- Kirill chEbba Chebunin
- Benjamin Leveque (benji07)
- Gustavo Falco (gfalco)
- Matt Robinson (inanimatt)
- julien pauli (jpauli)
- mwsaz
- Benoît Bourgeois
- Filipe Guerra
- corphi
- grizlik
- Derek ROTH
- Shin Ohno (ganchiku)
- Jan Kramer (jankramer)
- Drew Butler (nodrew)
- Don Pinkster
- Emil Einarsson
@ -302,28 +341,27 @@ Symfony2 is the result of the work of many people who made the code better
- Arno Geurts
- Adán Lobato (adanlobato)
- Mikhail Yurasov
- jamogon
- Sam Williams
- Miha Vrhovnik
- Moritz Borgmann
- Daniel Cestari
- Thomas Tourlourat (armetiz)
- Eugene Leonovich
- Karoly Negyesi (chx)
- Javier López (loalf)
- Magnus Nordlander (magnusnordlander)
- Adam Monsen (meonkeys)
- Florian Rey (nervo)
- LOUARDI Abdeltif (ouardisoft)
- Robert Gruendler (pulse00)
- ragtek (ragtek)
- Benoît Merlet (trompette)
- Maks
- Jan Behrens
- Raul Fraile (raulfraile)
- sensio
- Patrick Kaufmann
- Théophile Helleboid - chtitux
- Ben Ramsey (ramsey)
- Christian Jul Jensen
- Chris Jones (leek)
- xaav
- Juti Noppornpitak
- Roumen Damianoff
- Sander Coolen
- Josip Kruslin
- Anton Babenko (antonbabenko)
@ -339,12 +377,9 @@ Symfony2 is the result of the work of many people who made the code better
- julien.galenski
- Sébastien Lavoie
- Per Sandström (per)
- Ken Marfilla (marfillaster)
- Robert Kiss (kepten)
- jfcixmedia
- Vitaliy Tverdokhlib (vitaliytv)
- Martijn Evers
- Chris Heng
- Nerijus Arlauskas
- DerManoMann
- Jochen Bayer (jocl)
@ -352,6 +387,7 @@ Symfony2 is the result of the work of many people who made the code better
- Evan Villemez
- Davide Borsatto (davide.borsatto)
- kaiwa
- Albert Ganiev (helios-ag)
- Neil Katin
- Gustavo Adrian
- Roger Webb
@ -365,8 +401,8 @@ Symfony2 is the result of the work of many people who made the code better
- modi
- Sergey Yuferev
- Richard van den Brand (ricbra)
- Mark Sonnabaum
- Aharon Perkel
- Malaney J. Hill
- Andy Cox (ringo)
- Balázs Benyó (duplabe)
- Sebastian Utz
@ -374,8 +410,6 @@ Symfony2 is the result of the work of many people who made the code better
- Cédric Lahouste (rapotor)
- Janusz Jablonski
- George Giannoulopoulos
- Thomas Lallement (raziel057)
- Matt Daum (daum)
- Alberto Pirovano (geezmo)
- Xavier Briand (xavierbriand)
- Evan Kaufman
@ -386,7 +420,6 @@ Symfony2 is the result of the work of many people who made the code better
- Stéphane PY (steph_py)
- Martin Eckhardt
- Michael Dowling (mtdowling)
- BilgeXA
- mlively
- Thomas Chmielowiec (chmielot)
- Sebastian Ionescu
@ -406,30 +439,28 @@ Symfony2 is the result of the work of many people who made the code better
- Paweł Wacławczyk (pwc)
- Thomas Bibb
- Josef Cech
- Andrey Esaulov (andremaha)
- hicham ELGUAROUANI (hiiimoo)
- Roman Marintsenko (inori)
- Ivan Kurnosov
- stloyd
- Martin Parsiegla (spea)
- Chris Tickner (tickner)
- Luis Muñoz
- Thomas Chmielowiec
- Gunther Konig
- Oleg Zinchenko
- Benjamin Grandfond (benjamin)
- Christoph Nissle (derstoffel)
- Stefano Sala (stefano.sala)
- Xavier HAUSHERR
- Benjamin Zikarsky
- Romain Dorgueil
- Grayson Koonce (breerly)
- Andy Stanberry
- alefranz
- Loïc Chardonnet (gnusat)
- Alessio Baglio (ioalessio)
- Jérôme Macias (jeromemacias)
- Cédric Dugat (ph3nol)
- Philip Dahlstrøm (phidah)
- Pierre Vanliefland (pvanliefland)
- Artem Lopata (bumz)
- Alexey Popkov
- Artyom Protaskin
@ -440,10 +471,12 @@ Symfony2 is the result of the work of many people who made the code better
- hirocaster
- Andrey Chernykh
- Alexander Miehe (engerim)
- Jörn Lang (j.lang)
- Jan Marek (janmarek)
- Dan Patrick (mdpatrick)
- Pierre-Yves LEBECQ (pylebecq)
- Rares Vlaseanu (raresvla)
- Tugdual Saunier (tucksaun)
- Alexander Zogheb
- Florian Pfitzer
- Linnik Sergey
@ -463,7 +496,6 @@ Symfony2 is the result of the work of many people who made the code better
- Grummfy
- Eduardo Gulias
- Rowan Manning
- Eric GELOEN
- David Windell
- Gabriel Birke
- Alan Chen
@ -517,7 +549,6 @@ Symfony2 is the result of the work of many people who made the code better
- Samuel Laulhau
- Oleg Stepura
- James Michael DuPont
- Miha Vrhovnik
- Ondrej Slinták
- vlechemin
- Skorney
@ -533,6 +564,7 @@ Symfony2 is the result of the work of many people who made the code better
- David Soria Parra
- Sergiy Sokolenko
- Penny Leach
- Philipp Rieber
- DanSync
- Peter Zwosta
- parhs
@ -552,7 +584,6 @@ Symfony2 is the result of the work of many people who made the code better
- Daniel Londero (dlondero)
- Adel ELHAIBA (eadel)
- Fabien Dosse (fabd)
- Jonas Flodén (flojon)
- Yohan Giarelli (frequence-web)
- Massimiliano Arione (garak)
- Vladislav Krupenkin (ideea)
@ -568,6 +599,7 @@ Symfony2 is the result of the work of many people who made the code better
- Daniel Perez Pinazo (pitiflautico)
- Ruud Kamphuis (ruudk)
- Sebastian Busch (sebu)
- Simon Terrien (sterrien)
- Markus Tacker (tacker)
- Tyler Stroud (tystr)
- Eugene Babushkin (warl)

View File

@ -1,4 +1,4 @@
Copyright (c) 2004-2012 Fabien Potencier
Copyright (c) 2004-2013 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -46,17 +46,19 @@ Contributing
Symfony2 is an open source, community-driven project. If you'd like to contribute,
please read the [Contributing Code][4] part of the documentation. If you're submitting
a pull request, please follow the guidelines in the [Submitting a Patch][5] section.
a pull request, please follow the guidelines in the [Submitting a Patch][5] section
and use [Pull Request Template][6].
Running Symfony2 Tests
----------------------
Information on how to run the Symfony2 test suite can be found in the
[Running Symfony2 Tests][6] section.
[Running Symfony2 Tests][7] section.
[1]: http://symfony.com/download
[2]: http://symfony.com/get_started
[3]: http://symfony.com/doc/current/
[4]: http://symfony.com/doc/current/contributing/code/index.html
[5]: http://symfony.com/doc/current/contributing/code/patches.html#check-list
[6]: http://symfony.com/doc/master/contributing/code/tests.html
[6]: http://symfony.com/doc/current/contributing/code/patches.html#make-a-pull-request
[7]: http://symfony.com/doc/master/contributing/code/tests.html

View File

@ -1,6 +1,24 @@
UPGRADE FROM 2.1 to 2.2
=======================
### TwigBridge
* The `render` tag signature and arguments changed.
Before:
```
{% render 'BlogBundle:Post:list' with { 'limit': 2 }, { 'alt': 'BlogBundle:Post:error' } %}
```
After:
```
{% render url('post_list', { 'limit': 2 }), { 'alt': 'BlogBundle:Post:error' } %}
```
where `post_list` is the route name for the `BlogBundle:Post:list` controller.
### HttpFoundation
* The MongoDbSessionHandler default field names and timestamp type have changed.
@ -37,7 +55,169 @@
### Form
* The PasswordType is now not trimmed by default.
* The PasswordType is now not trimmed by default.
* The class FormException is now an interface. The old class is still available
under the name Symfony\Component\Form\Exception\Exception, but will probably
be removed before 2.2. If you created FormException instances manually,
you are now advised to create any of the other exceptions in the
Symfony\Component\Form\Exception namespace or to create custom exception
classes for your purpose.
* Translating validation errors is now optional. You can still do so
manually if you like, or you can simplify your templates to simply output
the already translated message.
Before:
```
{{
error.messagePluralization is null
? error.messageTemplate|trans(error.messageParameters, 'validators')
: error.messageTemplate|transchoice(error.messagePluralization, error.messageParameters, 'validators')
}}
```
After:
```
{{ error.message }}
```
* FormType, ModelType and PropertyPathMapper now have constructors. If you
extended these classes, you should call the parent constructor now.
Note that you are not recommended to extend FormType nor ModelType. You should
extend AbstractType instead and use the Form component's own inheritance
mechanism (`AbstractType::getParent()`).
Before:
```
use Symfony\Component\Form\Extensions\Core\DataMapper\PropertyPathMapper;
class CustomMapper extends PropertyPathMapper
{
public function __construct()
{
// ...
}
// ...
}
```
After:
```
use Symfony\Component\Form\Extensions\Core\DataMapper\PropertyPathMapper;
class CustomMapper extends PropertyPathMapper
{
public function __construct()
{
parent::__construct();
// ...
}
// ...
}
```
#### Deprecations
* The methods `getParent()`, `setParent()` and `hasParent()` in
`FormBuilderInterface` were deprecated and will be removed in Symfony 2.3.
You should not rely on these methods in your form type because the parent
of a form can change after building it.
* The class PropertyPath and related classes were deprecated and moved to a
dedicated component PropertyAccess. If you used any of these classes or
interfaces, you should adapt the namespaces now. During the move,
InvalidPropertyException was renamed to NoSuchPropertyException.
Before:
```
use Symfony\Component\Form\Util\PropertyPath;
use Symfony\Component\Form\Util\PropertyPathBuilder;
use Symfony\Component\Form\Util\PropertyPathInterface;
use Symfony\Component\Form\Util\PropertyPathIterator;
use Symfony\Component\Form\Util\PropertyPathIteratorInterface;
use Symfony\Component\Form\Exception\InvalidPropertyException;
use Symfony\Component\Form\Exception\InvalidPropertyPathException;
use Symfony\Component\Form\Exception\PropertyAccessDeniedException;
```
After:
```
use Symfony\Component\PropertyAccess\PropertyPath;
use Symfony\Component\PropertyAccess\PropertyPathBuilder;
use Symfony\Component\PropertyAccess\PropertyPathInterface;
use Symfony\Component\PropertyAccess\PropertyPathIterator;
use Symfony\Component\PropertyAccess\PropertyPathIteratorInterface;
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
use Symfony\Component\PropertyAccess\Exception\InvalidPropertyPathException;
use Symfony\Component\PropertyAccess\Exception\PropertyAccessDeniedException;
```
Also, `FormUtil::singularify()` was split away into a class StringUtil
in the new component.
Before:
```
use Symfony\Component\Form\Util\FormUtil;
$singular = FormUtil::singularify($plural);
```
After:
```
use Symfony\Component\PropertyAccess\StringUtil;
$singular = StringUtil::singularify($plural);
```
The methods `getValue()` and `setValue()` were moved to a new class
PropertyAccessor.
Before:
```
use Symfony\Component\Form\Util\PropertyPath;
$propertyPath = new PropertyPath('some.path');
$value = $propertyPath->getValue($object);
$propertyPath->setValue($object, 'new value');
```
After (alternative 1):
```
use Symfony\Component\PropertyAccess\PropertyAccess;
$accessor = PropertyAccess::getPropertyAccessor();
$value = $propertyAccessor->getValue($object, 'some.path');
$accessor->setValue($object, 'some.path', 'new value');
```
After (alternative 2):
```
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyPath;
$accessor = PropertyAccess::getPropertyAccessor();
$propertyPath = new PropertyPath('some.path');
$value = $propertyAccessor->getValue($object, $propertyPath);
$accessor->setValue($object, $propertyPath, 'new value');
```
### Routing
@ -154,6 +334,27 @@
}
```
* The sources of the pluralized messages in translation files have changed
from the singular to the pluralized version. If you created custom
translation files for validator errors, you should adapt them.
Before:
<trans-unit id="6">
<source>You must select at least {{ limit }} choices.</source>
<target>Sie müssen mindestens {{ limit }} Möglichkeit wählen.|Sie müssen mindestens {{ limit }} Möglichkeiten wählen.</target>
</trans-unit>
After:
<trans-unit id="6">
<source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
<target>Sie müssen mindestens {{ limit }} Möglichkeit wählen.|Sie müssen mindestens {{ limit }} Möglichkeiten wählen.</target>
</trans-unit>
Check the file src/Symfony/Component/Validator/Resources/translations/validators.en.xlf
for the new message sources.
#### Deprecations
* The interface `ClassMetadataFactoryInterface` was deprecated and will be
@ -319,3 +520,42 @@
// ...
}
```
### FrameworkBundle
* The `render` method of the `actions` templating helper signature and arguments changed:
Before:
```
<?php echo $view['actions']->render('BlogBundle:Post:list', array('limit' => 2), array('alt' => 'BlogBundle:Post:error')) ?>
```
After:
```
<?php echo $view['actions']->render($view['router']->generate('post_list', array('limit' => 2)), array('alt' => 'BlogBundle:Post:error')) ?>
```
where `post_list` is the route name for the `BlogBundle:Post:list` controller.
#### Configuration
* The 2.2 version introduces a new parameter `trusted_proxies` that replaces
`trust_proxy_headers` in the framework configuration.
Before:
```
# app/config/config.yml
framework:
trust_proxy_headers: false
```
After:
```
# app/config/config.yml
framework:
trusted_proxies: ['127.0.0.1', '10.0.0.1'] # a list of proxy IPs you trust
```

View File

@ -18,7 +18,8 @@
"require": {
"php": ">=5.3.3",
"doctrine/common": ">2.2,<2.4-dev",
"twig/twig": ">=1.9.1,<2.0-dev"
"twig/twig": ">=1.11.0,<2.0-dev",
"psr/log": "~1.0"
},
"replace": {
"symfony/browser-kit": "self.version",
@ -59,7 +60,7 @@
"doctrine/data-fixtures": "1.0.*",
"doctrine/dbal": ">=2.2,<2.4-dev",
"doctrine/orm": ">=2.2.3,<2.4-dev",
"monolog/monolog": "1.*",
"monolog/monolog": "~1.3",
"propel/propel1": "dev-master"
},
"autoload": {

View File

@ -1,10 +1,11 @@
CHANGELOG
=========
2.1.5
2.2.0
-----
* fixed caching of choice lists when EntityType is used with the "query_builder" option
* added an optional PropertyAccessorInterface parameter to DoctrineType,
EntityType and EntityChoiceList
2.1.0
-----

View File

@ -93,6 +93,8 @@ class ContainerAwareEventManager extends EventManager
*
* @param string|array $events The event(s) to listen on.
* @param object|string $listener The listener object.
*
* @throws \RuntimeException
*/
public function addEventListener($events, $listener)
{

View File

@ -42,6 +42,8 @@ abstract class AbstractDoctrineExtension extends Extension
/**
* @param array $objectManager A configured object manager.
* @param ContainerBuilder $container A ContainerBuilder instance
*
* @throws \InvalidArgumentException
*/
protected function loadMappingInformation(array $objectManager, ContainerBuilder $container)
{
@ -119,6 +121,8 @@ abstract class AbstractDoctrineExtension extends Extension
*
* @param array $mappingConfig
* @param string $mappingName
*
* @throws \InvalidArgumentException
*/
protected function setMappingDriverConfig(array $mappingConfig, $mappingName)
{
@ -228,6 +232,8 @@ abstract class AbstractDoctrineExtension extends Extension
*
* @param array $mappingConfig
* @param string $objectManagerName
*
* @throws \InvalidArgumentException
*/
protected function assertValidMappingConfiguration(array $mappingConfig, $objectManagerName)
{
@ -309,7 +315,7 @@ abstract class AbstractDoctrineExtension extends Extension
$memcacheClass = !empty($cacheDriver['class']) ? $cacheDriver['class'] : '%'.$this->getObjectManagerElementName('cache.memcache.class').'%';
$memcacheInstanceClass = !empty($cacheDriver['instance_class']) ? $cacheDriver['instance_class'] : '%'.$this->getObjectManagerElementName('cache.memcache_instance.class').'%';
$memcacheHost = !empty($cacheDriver['host']) ? $cacheDriver['host'] : '%'.$this->getObjectManagerElementName('cache.memcache_host').'%';
$memcachePort = !empty($cacheDriver['port']) ? $cacheDriver['port'] : '%'.$this->getObjectManagerElementName('cache.memcache_port').'%';
$memcachePort = !empty($cacheDriver['port']) || (isset($cacheDriver['port']) && $cacheDriver['port'] === 0) ? $cacheDriver['port'] : '%'.$this->getObjectManagerElementName('cache.memcache_port').'%';
$cacheDef = new Definition($memcacheClass);
$memcacheInstance = new Definition($memcacheInstanceClass);
$memcacheInstance->addMethodCall('connect', array(

View File

@ -47,7 +47,7 @@ class DoctrineValidationPass implements CompilerPassInterface
*
* @param ContainerBuilder $container
* @param string $mapping
* @param type $extension
* @param string $extension
*/
private function updateValidatorMappingFiles(ContainerBuilder $container, $mapping, $extension)
{

View File

@ -11,10 +11,11 @@
namespace Symfony\Bridge\Doctrine\Form\ChoiceList;
use Symfony\Component\Form\Exception\FormException;
use Symfony\Component\Form\Exception\Exception;
use Symfony\Component\Form\Exception\StringCastException;
use Symfony\Component\Form\Extension\Core\ChoiceList\ObjectChoiceList;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
/**
* A choice list presenting a list of Doctrine entities as choices
@ -86,17 +87,18 @@ class EntityChoiceList extends ObjectChoiceList
/**
* Creates a new entity choice list.
*
* @param ObjectManager $manager An EntityManager instance
* @param string $class The class name
* @param string $labelPath The property path used for the label
* @param EntityLoaderInterface $entityLoader An optional query builder
* @param array $entities An array of choices
* @param array $preferredEntities An array of preferred choices
* @param string $groupPath A property path pointing to the property used
* to group the choices. Only allowed if
* the choices are given as flat array.
* @param ObjectManager $manager An EntityManager instance
* @param string $class The class name
* @param string $labelPath The property path used for the label
* @param EntityLoaderInterface $entityLoader An optional query builder
* @param array $entities An array of choices
* @param array $preferredEntities An array of preferred choices
* @param string $groupPath A property path pointing to the property used
* to group the choices. Only allowed if
* the choices are given as flat array.
* @param PropertyAccessorInterface $propertyAccessor The reflection graph for reading property paths.
*/
public function __construct(ObjectManager $manager, $class, $labelPath = null, EntityLoaderInterface $entityLoader = null, $entities = null, array $preferredEntities = array(), $groupPath = null)
public function __construct(ObjectManager $manager, $class, $labelPath = null, EntityLoaderInterface $entityLoader = null, $entities = null, array $preferredEntities = array(), $groupPath = null, PropertyAccessorInterface $propertyAccessor = null)
{
$this->em = $manager;
$this->entityLoader = $entityLoader;
@ -122,7 +124,7 @@ class EntityChoiceList extends ObjectChoiceList
$entities = array();
}
parent::__construct($entities, $labelPath, $preferredEntities, $groupPath);
parent::__construct($entities, $labelPath, $preferredEntities, $groupPath, null, $propertyAccessor);
}
/**
@ -329,7 +331,7 @@ class EntityChoiceList extends ObjectChoiceList
protected function createIndex($entity)
{
if ($this->idAsIndex) {
return current($this->getIdentifierValues($entity));
return $this->fixIndex(current($this->getIdentifierValues($entity)));
}
return parent::createIndex($entity);
@ -355,6 +357,23 @@ class EntityChoiceList extends ObjectChoiceList
return parent::createValue($entity);
}
/**
* {@inheritdoc}
*/
protected function fixIndex($index)
{
$index = parent::fixIndex($index);
// If the ID is a single-field integer identifier, it is used as
// index. Replace any leading minus by underscore to make it a valid
// form name.
if ($this->idAsIndex && $index < 0) {
$index = strtr($index, '-', '_');
}
return $index;
}
/**
* Loads the list with entities.
*/
@ -387,12 +406,12 @@ class EntityChoiceList extends ObjectChoiceList
*
* @return array The identifier values
*
* @throws FormException If the entity does not exist in Doctrine's identity map
* @throws Exception If the entity does not exist in Doctrine's identity map
*/
private function getIdentifierValues($entity)
{
if (!$this->em->contains($entity)) {
throw new FormException(
throw new Exception(
'Entities passed to the choice field must be managed. Maybe ' .
'persist them in the entity manager?'
);

View File

@ -26,7 +26,7 @@ class ORMQueryBuilderLoader implements EntityLoaderInterface
*
* This property should only be accessed through queryBuilder.
*
* @var Doctrine\ORM\QueryBuilder
* @var QueryBuilder
*/
private $queryBuilder;
@ -36,6 +36,8 @@ class ORMQueryBuilderLoader implements EntityLoaderInterface
* @param QueryBuilder|\Closure $queryBuilder
* @param EntityManager $manager
* @param string $class
*
* @throws UnexpectedTypeException
*/
public function __construct($queryBuilder, $manager = null, $class = null)
{

View File

@ -27,6 +27,8 @@ class CollectionToArrayTransformer implements DataTransformerInterface
* @param Collection $collection A collection of entities
*
* @return mixed An array of entities
*
* @throws UnexpectedTypeException
*/
public function transform($collection)
{

View File

@ -13,6 +13,7 @@ namespace Symfony\Bridge\Doctrine\Form;
use Doctrine\Common\Persistence\ManagerRegistry;
use Symfony\Component\Form\AbstractExtension;
use Symfony\Component\PropertyAccess\PropertyAccess;
class DoctrineOrmExtension extends AbstractExtension
{
@ -26,7 +27,7 @@ class DoctrineOrmExtension extends AbstractExtension
protected function loadTypes()
{
return array(
new Type\EntityType($this->registry),
new Type\EntityType($this->registry, PropertyAccess::getPropertyAccessor()),
);
}

View File

@ -143,6 +143,7 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface
*/
public function guessMinLength($class, $property)
{
trigger_error('guessMinLength() is deprecated since version 2.1 and will be removed in 2.3.', E_USER_DEPRECATED);
}
/**

View File

@ -12,7 +12,7 @@
namespace Symfony\Bridge\Doctrine\Form\Type;
use Doctrine\Common\Persistence\ManagerRegistry;
use Symfony\Component\Form\Exception\FormException;
use Symfony\Component\Form\Exception\Exception;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList;
@ -22,6 +22,8 @@ use Symfony\Bridge\Doctrine\Form\DataTransformer\CollectionToArrayTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
abstract class DoctrineType extends AbstractType
{
@ -35,9 +37,15 @@ abstract class DoctrineType extends AbstractType
*/
private $choiceListCache = array();
public function __construct(ManagerRegistry $registry)
/**
* @var PropertyAccessorInterface
*/
private $propertyAccessor;
public function __construct(ManagerRegistry $registry, PropertyAccessorInterface $propertyAccessor = null)
{
$this->registry = $registry;
$this->propertyAccessor = $propertyAccessor ?: PropertyAccess::getPropertyAccessor();
}
public function buildForm(FormBuilderInterface $builder, array $options)
@ -54,6 +62,7 @@ abstract class DoctrineType extends AbstractType
{
$choiceListCache =& $this->choiceListCache;
$registry = $this->registry;
$propertyAccessor = $this->propertyAccessor;
$type = $this;
$loader = function (Options $options) use ($type) {
@ -64,7 +73,7 @@ abstract class DoctrineType extends AbstractType
return null;
};
$choiceList = function (Options $options) use (&$choiceListCache, &$time) {
$choiceList = function (Options $options) use (&$choiceListCache, $propertyAccessor) {
// Support for closures
$propertyHash = is_object($options['property'])
? spl_object_hash($options['property'])
@ -118,7 +127,8 @@ abstract class DoctrineType extends AbstractType
$options['loader'],
$options['choices'],
$options['preferred_choices'],
$options['group_by']
$options['group_by'],
$propertyAccessor
);
}
@ -134,7 +144,7 @@ abstract class DoctrineType extends AbstractType
$em = $registry->getManagerForClass($options['class']);
if (null === $em) {
throw new FormException(sprintf(
throw new Exception(sprintf(
'Class "%s" seems not to be a managed Doctrine entity. ' .
'Did you forget to map it?',
$options['class']

View File

@ -11,53 +11,26 @@
namespace Symfony\Bridge\Doctrine\Form\Type;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Bridge\Doctrine\Form\ChoiceList\ORMQueryBuilderLoader;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\ChoiceList\ORMQueryBuilderLoader;
class EntityType extends DoctrineType
{
/**
* @var array
*/
private $loaderCache = array();
/**
* Return the default loader object.
*
* @param ObjectManager $manager
* @param QueryBuilder|\Closure $queryBuilder
* @param string $class
*
* @param ObjectManager $manager
* @param mixed $queryBuilder
* @param string $class
* @return ORMQueryBuilderLoader
*
* @throws UnexpectedTypeException If the passed $queryBuilder is no \Closure
* and no QueryBuilder or if the closure
* does not return a QueryBuilder.
*/
public function getLoader(ObjectManager $manager, $queryBuilder, $class)
{
if ($queryBuilder instanceof \Closure) {
$queryBuilder = $queryBuilder($manager->getRepository($class));
if (!$queryBuilder instanceof QueryBuilder) {
throw new UnexpectedTypeException($queryBuilder, 'Doctrine\ORM\QueryBuilder');
}
} elseif (!$queryBuilder instanceof QueryBuilder) {
throw new UnexpectedTypeException($queryBuilder, 'Doctrine\ORM\QueryBuilder or \Closure');
}
// It is important to return the same loader for identical queries,
// otherwise the caching mechanism in DoctrineType does not work
// (which expects identical loaders for the cache to work)
$hash = md5($queryBuilder->getQuery()->getDQL());
if (!isset($this->loaderCache[$hash])) {
$this->loaderCache[$hash] = new ORMQueryBuilderLoader($queryBuilder);
}
return $this->loaderCache[$hash];
return new ORMQueryBuilderLoader(
$queryBuilder,
$manager,
$class
);
}
public function getName()

View File

@ -157,6 +157,8 @@ class DbalSessionHandler implements \SessionHandlerInterface
*
* @param string $id
* @param string $data
*
* @return Boolean
*/
private function createNewSession($id, $data = '')
{

View File

@ -1,4 +1,4 @@
Copyright (c) 2004-2012 Fabien Potencier
Copyright (c) 2004-2013 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -11,7 +11,7 @@
namespace Symfony\Bridge\Doctrine\Logger;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Stopwatch\Stopwatch;
use Doctrine\DBAL\Logging\SQLLogger;

View File

@ -70,10 +70,10 @@ class EntityChoiceListTest extends DoctrineOrmTestCase
}
/**
* @expectedException Symfony\Component\Form\Exception\FormException
* @expectedException \Symfony\Component\Form\Exception\FormException
* @expectedMessage Entity "Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity" passed to the choice field must have a "__toString()" method defined (or you can also override the "property" option).
*/
public function testEntitesMustHaveAToStringMethod()
public function testEntitiesMustHaveAToStringMethod()
{
$entity1 = new NoToStringSingleIdentEntity(1, 'Foo');
$entity2 = new NoToStringSingleIdentEntity(2, 'Bar');
@ -97,7 +97,7 @@ class EntityChoiceListTest extends DoctrineOrmTestCase
}
/**
* @expectedException Symfony\Component\Form\Exception\FormException
* @expectedException \Symfony\Component\Form\Exception\FormException
*/
public function testChoicesMustBeManaged()
{
@ -312,4 +312,47 @@ class EntityChoiceListTest extends DoctrineOrmTestCase
$this->assertSame(array(0 => $entity1, 1 => $entity2), $choiceList->getChoices());
}
public function testMinusReplacedByUnderscoreInNegativeIntIds()
{
$entity1 = new SingleIdentEntity(-1, 'Foo');
$entity2 = new SingleIdentEntity(1, 'Bar');
// Persist for managed state
$this->em->persist($entity1);
$this->em->persist($entity2);
$this->em->flush();
$choiceList = new EntityChoiceList(
$this->em,
self::SINGLE_IDENT_CLASS,
'name'
);
$this->assertSame(array('_1' => $entity1, 1 => $entity2), $choiceList->getChoices());
$this->assertSame(array('_1', 1), $choiceList->getIndicesForChoices(array($entity1, $entity2)));
$this->assertSame(array('_1', 1), $choiceList->getIndicesForValues(array('-1', '1')));
}
public function testMinusReplacedByUnderscoreIfNotLoaded()
{
$entity1 = new SingleIdentEntity(-1, 'Foo');
$entity2 = new SingleIdentEntity(1, 'Bar');
// Persist for managed state
$this->em->persist($entity1);
$this->em->persist($entity2);
$this->em->flush();
$choiceList = new EntityChoiceList(
$this->em,
self::SINGLE_IDENT_CLASS,
'name'
);
// no getChoices()!
$this->assertSame(array('_1', 1), $choiceList->getIndicesForChoices(array($entity1, $entity2)));
$this->assertSame(array('_1', 1), $choiceList->getIndicesForValues(array('-1', '1')));
}
}

View File

@ -12,7 +12,6 @@
namespace Symfony\Bridge\Doctrine\Tests\Form\Type;
use Symfony\Component\Form\Tests\FormPerformanceTestCase;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity;
use Doctrine\ORM\Tools\SchemaTool;
use Symfony\Bridge\Doctrine\Tests\DoctrineOrmTestCase;
@ -37,9 +36,6 @@ class EntityTypePerformanceTest extends FormPerformanceTestCase
$manager->expects($this->any())
->method('getManager')
->will($this->returnValue($this->em));
$manager->expects($this->any())
->method('getManagerForClass')
->will($this->returnValue($this->em));
return array(
new CoreExtension(),
@ -114,26 +110,6 @@ class EntityTypePerformanceTest extends FormPerformanceTestCase
}
}
/**
* @group benchmark
*/
public function testCollapsedEntityFieldWithQueryBuilder()
{
$this->setMaxRunningTime(1);
for ($i = 0; $i < 40; ++$i) {
$form = $this->factory->create('entity', null, array(
'class' => self::ENTITY_CLASS,
'query_builder' => function (EntityRepository $repo) {
return $repo->createQueryBuilder('e')->addOrderBy('e.id', 'DESC');
}
));
// force loading of the choice list
$form->createView();
}
}
/**
* @group benchmark
*/

View File

@ -90,6 +90,7 @@ class EntityTypeTest extends TypeTestCase
parent::tearDown();
$this->em = null;
$this->emRegistry = null;
}
protected function getExtensions()
@ -111,7 +112,7 @@ class EntityTypeTest extends TypeTestCase
}
/**
* @expectedException Symfony\Component\OptionsResolver\Exception\MissingOptionsException
* @expectedException \Symfony\Component\OptionsResolver\Exception\MissingOptionsException
*/
public function testClassOptionIsRequired()
{
@ -171,7 +172,7 @@ class EntityTypeTest extends TypeTestCase
}
/**
* @expectedException Symfony\Component\Form\Exception\UnexpectedTypeException
* @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException
*/
public function testConfigureQueryBuilderWithNonQueryBuilderAndNonClosure()
{
@ -183,7 +184,7 @@ class EntityTypeTest extends TypeTestCase
}
/**
* @expectedException Symfony\Component\Form\Exception\UnexpectedTypeException
* @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException
*/
public function testConfigureQueryBuilderWithClosureReturningNonQueryBuilder()
{

View File

@ -12,6 +12,7 @@
namespace Symfony\Bridge\Doctrine\Tests\Validator\Constraints;
use Symfony\Bridge\Doctrine\Tests\DoctrineOrmTestCase;
use Symfony\Component\Validator\DefaultTranslator;
use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory;
use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity;
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleIdentEntity;
@ -132,7 +133,7 @@ class UniqueValidatorTest extends DoctrineOrmTestCase
$metadataFactory->addMetadata($metadata);
$validatorFactory = $this->createValidatorFactory($uniqueValidator);
return new Validator($metadataFactory, $validatorFactory);
return new Validator($metadataFactory, $validatorFactory, new DefaultTranslator());
}
private function createSchema($em)

View File

@ -40,6 +40,9 @@ class UniqueEntityValidator extends ConstraintValidator
/**
* @param object $entity
* @param Constraint $constraint
*
* @throws UnexpectedTypeException
* @throws ConstraintDefinitionException
*/
public function validate($entity, Constraint $constraint)
{
@ -63,7 +66,7 @@ class UniqueEntityValidator extends ConstraintValidator
$em = $this->registry->getManagerForClass(get_class($entity));
}
$className = $this->context->getCurrentClass();
$className = $this->context->getClassName();
$class = $em->getClassMetadata($className);
/* @var $class \Doctrine\Common\Persistence\Mapping\ClassMetadata */
@ -120,6 +123,6 @@ class UniqueEntityValidator extends ConstraintValidator
$errorPath = null !== $constraint->errorPath ? $constraint->errorPath : $fields[0];
$this->context->addViolationAtSubPath($errorPath, $constraint->message, array(), $criteria[$fields[0]]);
$this->context->addViolationAt($errorPath, $constraint->message, array(), $criteria[$fields[0]]);
}
}

View File

@ -47,10 +47,7 @@ class DebugHandler extends TestHandler implements DebugLoggerInterface
public function countErrors()
{
$cnt = 0;
$levels = array(Logger::ERROR, Logger::CRITICAL, Logger::ALERT);
if (defined('Monolog\Logger::EMERGENCY')) {
$levels[] = Logger::EMERGENCY;
}
$levels = array(Logger::ERROR, Logger::CRITICAL, Logger::ALERT, Logger::EMERGENCY);
foreach ($levels as $level) {
if (isset($this->recordsByLevel[$level])) {
$cnt += count($this->recordsByLevel[$level]);

View File

@ -1,4 +1,4 @@
Copyright (c) 2004-2012 Fabien Potencier
Copyright (c) 2004-2013 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -22,6 +22,38 @@ use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
*/
class Logger extends BaseLogger implements LoggerInterface, DebugLoggerInterface
{
/**
* @deprecated since 2.2, to be removed in 3.0. Use emergency() which is PSR-3 compatible.
*/
public function emerg($message, array $context = array())
{
return parent::addRecord(BaseLogger::EMERGENCY, $message, $context);
}
/**
* @deprecated since 2.2, to be removed in 3.0. Use critical() which is PSR-3 compatible.
*/
public function crit($message, array $context = array())
{
return parent::addRecord(BaseLogger::CRITICAL, $message, $context);
}
/**
* @deprecated since 2.2, to be removed in 3.0. Use error() which is PSR-3 compatible.
*/
public function err($message, array $context = array())
{
return parent::addRecord(BaseLogger::ERROR, $message, $context);
}
/**
* @deprecated since 2.2, to be removed in 3.0. Use warning() which is PSR-3 compatible.
*/
public function warn($message, array $context = array())
{
return parent::addRecord(BaseLogger::WARNING, $message, $context);
}
/**
* @see Symfony\Component\HttpKernel\Log\DebugLoggerInterface
*/

View File

@ -18,7 +18,7 @@
"require": {
"php": ">=5.3.3",
"symfony/http-kernel": "2.2.*",
"monolog/monolog": "1.*"
"monolog/monolog": "~1.3"
},
"autoload": {
"psr-0": { "Symfony\\Bridge\\Monolog\\": "" }

View File

@ -5,6 +5,9 @@ CHANGELOG
-----
* added a collection type for the I18n behavior
* added an optional PropertyAccessorInterface parameter to ModelType and
ModelChoiceList
* [BC BREAK] ModelType now has a constructor
2.1.0
-----

View File

@ -11,16 +11,20 @@
namespace Symfony\Bridge\Propel1\Form\ChoiceList;
use \ModelCriteria;
use \BaseObject;
use \Persistent;
use Symfony\Component\Form\Exception\FormException;
use Symfony\Component\Form\Exception\StringCastException;
use Symfony\Component\Form\Extension\Core\ChoiceList\ObjectChoiceList;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
/**
* Widely inspirated by the EntityChoiceList.
* Widely inspired by the EntityChoiceList.
*
* @author William Durand <william.durand1@gmail.com>
* @author Toni Uebernickel <tuebernickel@gmail.com>
*/
class ModelChoiceList extends ObjectChoiceList
{
@ -31,19 +35,28 @@ class ModelChoiceList extends ObjectChoiceList
*
* @var array
*/
private $identifier = array();
protected $identifier = array();
/**
* Query
* The query to retrieve the choices of this list.
*
* @var ModelCriteria
*/
private $query = null;
protected $query;
/**
* The query to retrieve the preferred choices for this list.
*
* @var ModelCriteria
*/
protected $preferredQuery;
/**
* Whether the model objects have already been loaded.
*
* @var Boolean
*/
private $loaded = false;
protected $loaded = false;
/**
* Whether to use the identifier for index generation
@ -53,13 +66,21 @@ class ModelChoiceList extends ObjectChoiceList
private $identifierAsIndex = false;
/**
* @param string $class
* @param string $labelPath
* @param array $choices
* @param \ModelCriteria $queryObject
* @param string $groupPath
* Constructor.
*
* @see Symfony\Bridge\Propel1\Form\Type\ModelType How to use the preferred choices.
*
* @param string $class The FQCN of the model class to be loaded.
* @param string $labelPath A property path pointing to the property used for the choice labels.
* @param array $choices An optional array to use, rather than fetching the models.
* @param ModelCriteria $queryObject The query to use retrieving model data from database.
* @param string $groupPath A property path pointing to the property used to group the choices.
* @param array|ModelCriteria $preferred The preferred items of this choice.
* Either an array if $choices is given,
* or a ModelCriteria to be merged with the $queryObject.
* @param PropertyAccessorInterface $propertyAccessor The reflection graph for reading property paths.
*/
public function __construct($class, $labelPath = null, $choices = null, $queryObject = null, $groupPath = null)
public function __construct($class, $labelPath = null, $choices = null, $queryObject = null, $groupPath = null, $preferred = array(), PropertyAccessorInterface $propertyAccessor = null)
{
$this->class = $class;
@ -70,17 +91,22 @@ class ModelChoiceList extends ObjectChoiceList
$this->query = $queryObject ?: $query;
$this->loaded = is_array($choices) || $choices instanceof \Traversable;
if ($preferred instanceof ModelCriteria) {
$this->preferredQuery = $preferred->mergeWith($this->query);
}
if (!$this->loaded) {
// Make sure the constraints of the parent constructor are
// fulfilled
$choices = array();
$preferred = array();
}
if (1 === count($this->identifier) && $this->isInteger(current($this->identifier))) {
$this->identifierAsIndex = true;
}
parent::__construct($choices, $labelPath, array(), $groupPath);
parent::__construct($choices, $labelPath, $preferred, $groupPath, null, $propertyAccessor);
}
/**
@ -328,10 +354,14 @@ class ModelChoiceList extends ObjectChoiceList
{
$models = (array) $this->query->find();
$preferred = array();
if ($this->preferredQuery instanceof ModelCriteria) {
$preferred = (array) $this->preferredQuery->find();
}
try {
// The second parameter $labels is ignored by ObjectChoiceList
// The third parameter $preferredChoices is currently not supported
parent::initialize($models, array(), array());
parent::initialize($models, array(), $preferred);
} catch (StringCastException $e) {
throw new StringCastException(str_replace('argument $labelPath', 'option "property"', $e->getMessage()), null, $e);
}
@ -348,6 +378,8 @@ class ModelChoiceList extends ObjectChoiceList
*
* @param object $model The model for which to get the identifier
*
* @return array
*
* @throws FormException If the model does not exist
*/
private function getIdentifierValues($model)
@ -357,7 +389,7 @@ class ModelChoiceList extends ObjectChoiceList
}
// readonly="true" models do not implement Persistent.
if ($model instanceof BaseObject and method_exists($model, 'getPrimaryKey')) {
if ($model instanceof BaseObject && method_exists($model, 'getPrimaryKey')) {
return array($model->getPrimaryKey());
}
@ -367,9 +399,9 @@ class ModelChoiceList extends ObjectChoiceList
/**
* Whether this column in an integer
*
* @param ColumnMap $column
* @param \ColumnMap $column
*
* @return boolean
* @return Boolean
*/
private function isInteger(\ColumnMap $column)
{

View File

@ -11,7 +11,6 @@
namespace Symfony\Bridge\Propel1\Form\EventListener;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
@ -24,13 +23,11 @@ class TranslationFormListener implements EventSubscriberInterface
{
private $columns;
private $dataClass;
private $formFactory;
public function __construct(FormFactoryInterface $formFactory, $columns, $dataClass)
public function __construct($columns, $dataClass)
{
$this->columns = $columns;
$this->dataClass = $dataClass;
$this->formFactory = $formFactory;
}
public static function getSubscribedEvents()
@ -78,7 +75,7 @@ class TranslationFormListener implements EventSubscriberInterface
$options = array_merge($options, $customOptions);
$form->add($this->formFactory->createNamed($column, $type, null, $options));
$form->add($column, $type, $options);
}
}
}

View File

@ -12,6 +12,7 @@
namespace Symfony\Bridge\Propel1\Form;
use Symfony\Component\Form\AbstractExtension;
use Symfony\Component\PropertyAccess\PropertyAccess;
/**
* Represents the Propel form extension, which loads the Propel functionality.
@ -23,7 +24,7 @@ class PropelExtension extends AbstractExtension
protected function loadTypes()
{
return array(
new Type\ModelType(),
new Type\ModelType(PropertyAccess::getPropertyAccessor()),
new Type\TranslationCollectionType(),
new Type\TranslationType()
);

View File

@ -126,6 +126,7 @@ class PropelTypeGuesser implements FormTypeGuesserInterface
*/
public function guessMinLength($class, $property)
{
trigger_error('guessMinLength() is deprecated since version 2.1 and will be removed in 2.3.', E_USER_DEPRECATED);
}
/**

View File

@ -17,14 +17,49 @@ use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
/**
* ModelType class.
*
* @author William Durand <william.durand1@gmail.com>
* @author Toni Uebernickel <tuebernickel@gmail.com>
*
* Example using the preferred_choices option.
*
* <code>
* public function buildForm(FormBuilderInterface $builder, array $options)
* {
* $builder
* ->add('product', 'model', array(
* 'class' => 'Model\Product',
* 'query' => ProductQuery::create()
* ->filterIsActive(true)
* ->useI18nQuery($options['locale'])
* ->orderByName()
* ->endUse()
* ,
* 'preferred_choices' => ProductQuery::create()
* ->filterByIsTopProduct(true)
* ,
* ))
* ;
* }
* </code>
*/
class ModelType extends AbstractType
{
/**
* @var PropertyAccessorInterface
*/
private $propertyAccessor;
public function __construct(PropertyAccessorInterface $propertyAccessor = null)
{
$this->propertyAccessor = $propertyAccessor ?: PropertyAccess::getPropertyAccessor();
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
if ($options['multiple']) {
@ -34,13 +69,17 @@ class ModelType extends AbstractType
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$choiceList = function (Options $options) {
$propertyAccessor = $this->propertyAccessor;
$choiceList = function (Options $options) use ($propertyAccessor) {
return new ModelChoiceList(
$options['class'],
$options['property'],
$options['choices'],
$options['query'],
$options['group_by']
$options['group_by'],
$options['preferred_choices'],
$propertyAccessor
);
};

View File

@ -28,8 +28,9 @@ class TranslationType extends AbstractType
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$listener = new TranslationFormListener($builder->getFormFactory(), $options['columns'], $options['data_class']);
$builder->addEventSubscriber($listener);
$builder->addEventSubscriber(
new TranslationFormListener($options['columns'], $options['data_class'])
);
}
/**

View File

@ -1,4 +1,4 @@
Copyright (c) 2004-2012 Fabien Potencier
Copyright (c) 2004-2013 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -12,7 +12,7 @@
namespace Symfony\Bridge\Propel1\Logger;
use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Psr\Log\LoggerInterface;
/**
* PropelLogger.
@ -73,7 +73,7 @@ class PropelLogger
public function crit($message)
{
if (null !== $this->logger) {
$this->logger->crit($message);
$this->logger->critical($message);
}
}
@ -85,7 +85,7 @@ class PropelLogger
public function err($message)
{
if (null !== $this->logger) {
$this->logger->err($message);
$this->logger->error($message);
}
}
@ -97,7 +97,7 @@ class PropelLogger
public function warning($message)
{
if (null !== $this->logger) {
$this->logger->warn($message);
$this->logger->warning($message);
}
}

View File

@ -26,6 +26,10 @@ class ModelChoiceListTest extends Propel1TestCase
if (!class_exists('Symfony\Component\Form\Form')) {
$this->markTestSkipped('The "Form" component is not available');
}
if (!class_exists('Symfony\Component\PropertyAccess\PropertyAccessor')) {
$this->markTestSkipped('The "PropertyAccessor" component is not available');
}
}
public function testEmptyChoicesReturnsEmpty()
@ -70,6 +74,29 @@ class ModelChoiceListTest extends Propel1TestCase
$this->assertSame(array(1 => $item1, 2 => $item2), $choiceList->getChoices());
}
public function testFlattenedPreferredChoices()
{
$item1 = new Item(1, 'Foo');
$item2 = new Item(2, 'Bar');
$choiceList = new ModelChoiceList(
self::ITEM_CLASS,
'value',
array(
$item1,
$item2,
),
null,
null,
array(
$item1
)
);
$this->assertSame(array(1 => $item1, 2 => $item2), $choiceList->getChoices());
$this->assertEquals(array(1 => new ChoiceView($item1, '1', 'Foo')), $choiceList->getPreferredViews());
}
public function testNestedChoices()
{
$item1 = new Item(1, 'Foo');

View File

@ -96,7 +96,7 @@ class TranslationCollectionTypeTest extends TypeTestCase
}
/**
* @expectedException Symfony\Component\Form\Exception\UnexpectedTypeException
* @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException
*/
public function testNoArrayGiven()
{
@ -118,7 +118,7 @@ class TranslationCollectionTypeTest extends TypeTestCase
}
/**
* @expectedException Symfony\Component\OptionsResolver\Exception\MissingOptionsException
* @expectedException \Symfony\Component\OptionsResolver\Exception\MissingOptionsException
*/
public function testNoDataClassAdded()
{
@ -131,7 +131,7 @@ class TranslationCollectionTypeTest extends TypeTestCase
}
/**
* @expectedException Symfony\Component\OptionsResolver\Exception\MissingOptionsException
* @expectedException \Symfony\Component\OptionsResolver\Exception\MissingOptionsException
*/
public function testNoLanguagesAdded()
{
@ -144,7 +144,7 @@ class TranslationCollectionTypeTest extends TypeTestCase
}
/**
* @expectedException Symfony\Component\OptionsResolver\Exception\MissingOptionsException
* @expectedException \Symfony\Component\OptionsResolver\Exception\MissingOptionsException
*/
public function testNoColumnsAdded()
{

View File

@ -1,4 +1,4 @@
Copyright (c) 2004-2012 Fabien Potencier
Copyright (c) 2004-2013 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -17,7 +17,7 @@
],
"require": {
"php": ">=5.3.3",
"swiftmailer/swiftmailer": ">=4.2.0,<4.3-dev"
"swiftmailer/swiftmailer": ">=4.2.0,<4.4-dev"
},
"suggest": {
"symfony/http-kernel": "2.2.*"

View File

@ -4,7 +4,11 @@ CHANGELOG
2.2.0
-----
* [BC BREAK] restricted the `render` tag to only accept URIs as reference (the signature changed)
* added a render function to render a request
* The `app` global variable is now injected even when using the twig service directly.
* Added an optional parameter to the `path` and `url` function which allows to generate
relative paths (e.g. "../parent-file") and scheme-relative URLs (e.g. "//example.com/dir/file").
2.1.0
-----

View File

@ -0,0 +1,97 @@
<?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\Bridge\Twig\Extension;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Provides integration with the HttpKernel component.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class HttpKernelExtension extends \Twig_Extension implements EventSubscriberInterface
{
private $kernel;
private $request;
/**
* Constructor.
*
* @param HttpKernelInterface $kernel A HttpKernelInterface install
*/
public function __construct(HttpKernelInterface $kernel)
{
$this->kernel = $kernel;
}
public function getFunctions()
{
return array(
'render' => new \Twig_Function_Method($this, 'render', array('needs_environment' => true, 'is_safe' => array('html'))),
);
}
/**
* Renders a URI.
*
* @param \Twig_Environment $twig A \Twig_Environment instance
* @param string $uri The URI to render
*
* @return string The Response content
*
* @throws \RuntimeException
*/
public function render(\Twig_Environment $twig, $uri)
{
if (null !== $this->request) {
$cookies = $this->request->cookies->all();
$server = $this->request->server->all();
} else {
$cookies = array();
$server = array();
}
$subRequest = Request::create($uri, 'get', array(), $cookies, array(), $server);
if (null !== $this->request && $this->request->getSession()) {
$subRequest->setSession($this->request->getSession());
}
$response = $this->kernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false);
if (!$response->isSuccessful()) {
throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $subRequest->getUri(), $response->getStatusCode()));
}
return $response->getContent();
}
public function onKernelRequest(GetResponseEvent $event)
{
$this->request = $event->getRequest();
}
public static function getSubscribedEvents()
{
return array(
KernelEvents::REQUEST => array('onKernelRequest'),
);
}
public function getName()
{
return 'http_kernel';
}
}

View File

@ -40,14 +40,14 @@ class RoutingExtension extends \Twig_Extension
);
}
public function getPath($name, $parameters = array())
public function getPath($name, $parameters = array(), $relative = false)
{
return $this->generator->generate($name, $parameters, false);
return $this->generator->generate($name, $parameters, $relative ? UrlGeneratorInterface::RELATIVE_PATH : UrlGeneratorInterface::ABSOLUTE_PATH);
}
public function getUrl($name, $parameters = array())
public function getUrl($name, $parameters = array(), $schemeRelative = false)
{
return $this->generator->generate($name, $parameters, true);
return $this->generator->generate($name, $parameters, $schemeRelative ? UrlGeneratorInterface::NETWORK_PATH : UrlGeneratorInterface::ABSOLUTE_URL);
}
/**

View File

@ -1,4 +1,4 @@
Copyright (c) 2004-2012 Fabien Potencier
Copyright (c) 2004-2013 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -69,7 +69,7 @@
{% spaceless %}
<select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
{% if empty_value is not none %}
<option value="">{{ empty_value|trans({}, translation_domain) }}</option>
<option value="" disabled="disabled"{% if value is empty %} selected="selected"{% endif %}>{{ empty_value|trans({}, translation_domain) }}</option>
{% endif %}
{% if preferred_choices|length > 0 %}
{% set options = preferred_choices %}
@ -148,7 +148,7 @@
{{ block('form_widget_simple') }}
{% else %}
<div {{ block('widget_container_attributes') }}>
{{ form_widget(form.hour, { 'attr': { 'size': '1' } }) }}:{{ form_widget(form.minute, { 'attr': { 'size': '1' } }) }}{% if with_seconds %}:{{ form_widget(form.second, { 'attr': { 'size': '1' } }) }}{% endif %}
{{ form_widget(form.hour, { 'attr': { 'size': '1' } }) }}{% if with_minutes %}:{{ form_widget(form.minute, { 'attr': { 'size': '1' } }) }}{% endif %}{% if with_seconds %}:{{ form_widget(form.second, { 'attr': { 'size': '1' } }) }}{% endif %}
</div>
{% endif %}
{% endspaceless %}
@ -275,11 +275,7 @@
{% if errors|length > 0 %}
<ul>
{% for error in errors %}
<li>{{
error.messagePluralization is null
? error.messageTemplate|trans(error.messageParameters, 'validators')
: error.messageTemplate|transchoice(error.messagePluralization, error.messageParameters, 'validators')
}}</li>
<li>{{ error.message }}</li>
{% endfor %}
</ul>
{% endif %}

View File

@ -0,0 +1,73 @@
<?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\Bridge\Twig\Tests\Extension;
use Symfony\Bridge\Twig\Extension\HttpKernelExtension;
use Symfony\Bridge\Twig\Tests\TestCase;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
class HttpKernelExtensionTest extends TestCase
{
protected function setUp()
{
if (!class_exists('Symfony\Component\HttpKernel\HttpKernel')) {
$this->markTestSkipped('The "HttpKernel" component is not available');
}
if (!class_exists('Twig_Environment')) {
$this->markTestSkipped('Twig is not available.');
}
}
public function testRenderWithoutMasterRequest()
{
$kernel = $this->getKernel($this->returnValue(new Response('foo')));
$this->assertEquals('foo', $this->renderTemplate($kernel));
}
/**
* @expectedException \Twig_Error_Runtime
*/
public function testRenderWithError()
{
$kernel = $this->getKernel($this->throwException(new \Exception('foo')));
$loader = new \Twig_Loader_Array(array('index' => '{{ render("foo") }}'));
$twig = new \Twig_Environment($loader, array('debug' => true, 'cache' => false));
$twig->addExtension(new HttpKernelExtension($kernel));
$this->renderTemplate($kernel);
}
protected function getKernel($return)
{
$kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface');
$kernel
->expects($this->once())
->method('handle')
->will($return)
;
return $kernel;
}
protected function renderTemplate(HttpKernelInterface $kernel, $template = '{{ render("foo") }}')
{
$loader = new \Twig_Loader_Array(array('index' => $template));
$twig = new \Twig_Environment($loader, array('debug' => true, 'cache' => false));
$twig->addExtension(new HttpKernelExtension($kernel));
return $twig->render('index');
}
}

View File

@ -26,6 +26,8 @@ class TransChoiceTokenParser extends TransTokenParser
* @param \Twig_Token $token A Twig_Token instance
*
* @return \Twig_NodeInterface A Twig_NodeInterface instance
*
* @throws \Twig_Error_Syntax
*/
public function parse(\Twig_Token $token)
{

View File

@ -26,6 +26,8 @@ class TransTokenParser extends \Twig_TokenParser
* @param \Twig_Token $token A Twig_Token instance
*
* @return \Twig_NodeInterface A Twig_NodeInterface instance
*
* @throws \Twig_Error_Syntax
*/
public function parse(\Twig_Token $token)
{

View File

@ -21,6 +21,7 @@
},
"require-dev": {
"symfony/form": "2.2.*",
"symfony/http-kernel": "2.2.*",
"symfony/routing": "2.2.*",
"symfony/templating": "2.2.*",
"symfony/translation": "2.2.*",
@ -29,6 +30,7 @@
},
"suggest": {
"symfony/form": "2.2.*",
"symfony/http-kernel": "2.2.*",
"symfony/routing": "2.2.*",
"symfony/templating": "2.2.*",
"symfony/translation": "2.2.*",

View File

@ -4,12 +4,18 @@ CHANGELOG
2.2.0
-----
* [BC BREAK] restricted the `Symfony\Bundle\FrameworkBundle\HttpKernel::render()` method to only accept URIs as reference
* `Symfony\Bundle\FrameworkBundle\HttpKernel::render()` method signature changed and the first argument
must now be a URI (the `generateInternalUri()` method was removed)
* The internal routes have been removed (`Resources/config/routing/internal.xml`)
* The `render` method of the `actions` templating helper signature and arguments changed:
* replaced Symfony\Bundle\FrameworkBundle\Controller\TraceableControllerResolver by Symfony\Component\HttpKernel\Controller\TraceableControllerResolver
* replaced Symfony\Component\HttpKernel\Debug\ContainerAwareTraceableEventDispatcher by Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher
* added Client::enableProfiler()
* A new parameter has been added to the DIC: `router.request_context.base_url`
You can customize it for your functional tests or for generating urls with
the right base url when your are in the cli context.
* Added support for default templates per render tag
2.1.0
-----

View File

@ -280,6 +280,8 @@ EOF
* Loads the ContainerBuilder from the cache.
*
* @return ContainerBuilder
*
* @throws \LogicException
*/
protected function getContainerBuilder()
{

View File

@ -11,6 +11,7 @@
namespace Symfony\Bundle\FrameworkBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\StreamedResponse;
@ -19,8 +20,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Form\FormTypeInterface;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Doctrine\Bundle\DoctrineBundle\Registry;
use Symfony\Component\HttpFoundation\Request;
/**
* Controller is a simple implementation of a Controller.
@ -34,15 +35,17 @@ class Controller extends ContainerAware
/**
* Generates a URL from the given parameters.
*
* @param string $route The name of the route
* @param mixed $parameters An array of parameters
* @param Boolean $absolute Whether to generate an absolute URL
* @param string $route The name of the route
* @param mixed $parameters An array of parameters
* @param Boolean|string $referenceType The type of reference (one of the constants in UrlGeneratorInterface)
*
* @return string The generated URL
*
* @see UrlGeneratorInterface
*/
public function generateUrl($route, $parameters = array(), $absolute = false)
public function generateUrl($route, $parameters = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH)
{
return $this->container->get('router')->generate($route, $parameters, $absolute);
return $this->container->get('router')->generate($route, $parameters, $referenceType);
}
/**

View File

@ -38,6 +38,11 @@ class ControllerNameParser
* Converts a short notation a:b:c to a class::method.
*
* @param string $controller A short notation controller (a:b:c)
*
* @return string A string with class::method
*
* @throws \InvalidArgumentException when the specified bundle is not enabled
* or the controller cannot be found
*/
public function parse($controller)
{
@ -47,40 +52,23 @@ class ControllerNameParser
list($bundle, $controller, $action) = $parts;
$controller = str_replace('/', '\\', $controller);
$class = null;
$logs = array();
$bundles = array();
// this throws an exception if there is no such bundle
foreach ($this->kernel->getBundle($bundle, false) as $b) {
$try = $b->getNamespace().'\\Controller\\'.$controller.'Controller';
if (!class_exists($try)) {
$logs[] = sprintf('Unable to find controller "%s:%s" - class "%s" does not exist.', $bundle, $controller, $try);
} else {
$class = $try;
break;
if (class_exists($try)) {
return $try.'::'.$action.'Action';
}
$bundles[] = $b->getName();
$msg = sprintf('Unable to find controller "%s:%s" - class "%s" does not exist.', $bundle, $controller, $try);
}
if (null === $class) {
$this->handleControllerNotFoundException($bundle, $controller, $logs);
if (count($bundles) > 1) {
$msg = sprintf('Unable to find controller "%s:%s" in bundles %s.', $bundle, $controller, implode(', ', $bundles));
}
return $class.'::'.$action.'Action';
}
private function handleControllerNotFoundException($bundle, $controller, array $logs)
{
// just one log, return it as the exception
if (1 == count($logs)) {
throw new \InvalidArgumentException($logs[0]);
}
// many logs, use a message that mentions each searched bundle
$names = array();
foreach ($this->kernel->getBundle($bundle, false) as $b) {
$names[] = $b->getName();
}
$msg = sprintf('Unable to find controller "%s:%s" in bundles %s.', $bundle, $controller, implode(', ', $names));
throw new \InvalidArgumentException($msg);
}
}

View File

@ -11,7 +11,7 @@
namespace Symfony\Bundle\FrameworkBundle\Controller;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Controller\ControllerResolver as BaseControllerResolver;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser;

View File

@ -1,46 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Controller;
use Symfony\Component\DependencyInjection\ContainerAware;
use Symfony\Component\HttpFoundation\Response;
/**
* InternalController.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class InternalController extends ContainerAware
{
/**
* Forwards to the given controller with the given path.
*
* @param string $path The path
* @param string $controller The controller name
*
* @return Response A Response instance
*/
public function indexAction($path, $controller)
{
$request = $this->container->get('request');
$attributes = $request->attributes;
$attributes->remove('path');
$attributes->remove('controller');
if ('none' !== $path) {
parse_str($path, $tmp);
$attributes->add($tmp);
}
return $this->container->get('http_kernel')->forward($controller, $attributes->all(), $request->query->all());
}
}

View File

@ -12,8 +12,9 @@
namespace Symfony\Bundle\FrameworkBundle\Controller;
use Symfony\Component\DependencyInjection\ContainerAware;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
/**
* Redirects a request to another URL.
@ -45,7 +46,7 @@ class RedirectController extends ContainerAware
$attributes = $this->container->get('request')->attributes->get('_route_params');
unset($attributes['route'], $attributes['permanent']);
return new RedirectResponse($this->container->get('router')->generate($route, $attributes, true), $permanent ? 301 : 302);
return new RedirectResponse($this->container->get('router')->generate($route, $attributes, UrlGeneratorInterface::ABSOLUTE_URL), $permanent ? 301 : 302);
}
/**

View File

@ -28,6 +28,6 @@ class AddValidatorInitializersPass implements CompilerPassInterface
$initializers[] = new Reference($id);
}
$container->getDefinition('validator')->replaceArgument(2, $initializers);
$container->getDefinition('validator')->replaceArgument(4, $initializers);
}
}

View File

@ -51,8 +51,20 @@ class Configuration implements ConfigurationInterface
})
->end()
->end()
->scalarNode('trust_proxy_headers')->defaultFalse()->end()
->scalarNode('secret')->end()
->scalarNode('trust_proxy_headers')->defaultFalse()->end() // @deprecated, to be removed in 2.3
->arrayNode('trusted_proxies')
->beforeNormalization()
->ifTrue(function($v) { return !is_array($v) && !is_null($v); })
->then(function($v) { return is_bool($v) ? array() : preg_split('/\s*,\s*/', $v); })
->end()
->prototype('scalar')
->validate()
->ifTrue(function($v) { return !empty($v) && !filter_var($v, FILTER_VALIDATE_IP); })
->thenInvalid('Invalid proxy IP "%s"')
->end()
->end()
->end()
->scalarNode('ide')->defaultNull()->end()
->booleanNode('test')->end()
->scalarNode('default_locale')->defaultValue('en')->end()
@ -358,6 +370,7 @@ class Configuration implements ConfigurationInterface
->children()
->scalarNode('cache')->end()
->booleanNode('enable_annotations')->defaultFalse()->end()
->scalarNode('translation_domain')->defaultValue('validators')->end()
->end()
->end()
->end()

View File

@ -65,6 +65,9 @@ class FrameworkExtension extends Extension
$container->setParameter('kernel.secret', $config['secret']);
}
$container->setParameter('kernel.trusted_proxies', $config['trusted_proxies']);
// @deprecated, to be removed in 2.3
$container->setParameter('kernel.trust_proxy_headers', $config['trust_proxy_headers']);
$container->setParameter('kernel.default_locale', $config['default_locale']);
@ -147,6 +150,8 @@ class FrameworkExtension extends Extension
* @param array $config A configuration array
* @param ContainerBuilder $container A ContainerBuilder instance
* @param XmlFileLoader $loader An XmlFileLoader instance
*
* @throws \LogicException
*/
private function registerFormConfiguration($config, ContainerBuilder $container, XmlFileLoader $loader)
{
@ -184,6 +189,8 @@ class FrameworkExtension extends Extension
* @param array $config A profiler configuration array
* @param ContainerBuilder $container A ContainerBuilder instance
* @param XmlFileLoader $loader An XmlFileLoader instance
*
* @throws \LogicException
*/
private function registerProfilerConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)
{
@ -520,6 +527,11 @@ class FrameworkExtension extends Extension
$dirs[] = dirname($r->getFilename()).'/Resources/translations';
}
if (class_exists('Symfony\Component\Security\Core\Exception\AuthenticationException')) {
$r = new \ReflectionClass('Symfony\Component\Security\Core\Exception\AuthenticationException');
$dirs[] = dirname($r->getFilename()).'/../../Resources/translations';
}
$overridePath = $container->getParameter('kernel.root_dir').'/Resources/%s/translations';
foreach ($container->getParameter('kernel.bundles') as $bundle => $class) {
$reflection = new \ReflectionClass($class);
@ -567,6 +579,7 @@ class FrameworkExtension extends Extension
{
$loader->load('validator.xml');
$container->setParameter('validator.translation_domain', $config['translation_domain']);
$container->setParameter('validator.mapping.loader.xml_files_loader.mapping_files', $this->getValidatorXmlMappingFiles($container));
$container->setParameter('validator.mapping.loader.yaml_files_loader.mapping_files', $this->getValidatorYamlMappingFiles($container));

View File

@ -19,7 +19,7 @@ use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Sets the session on the request.
* Sets the session in the request.
*
* This will also start the session if it was already started during a previous
* request.

View File

@ -67,11 +67,10 @@ class TestSessionListener implements EventSubscriberInterface
return;
}
if ($session = $event->getRequest()->getSession()) {
$session = $event->getRequest()->getSession();
if ($session && $session->isStarted()) {
$session->save();
$params = session_get_cookie_params();
$event->getResponse()->headers->setCookie(new Cookie($session->getName(), $session->getId(), 0 === $params['lifetime'] ? 0 : time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly']));
}
}

View File

@ -40,8 +40,10 @@ class FrameworkBundle extends Bundle
{
public function boot()
{
if ($this->container->getParameter('kernel.trust_proxy_headers')) {
Request::trustProxyData();
if ($trustedProxies = $this->container->getParameter('kernel.trusted_proxies')) {
Request::setTrustedProxies($trustedProxies);
} elseif ($this->container->getParameter('kernel.trust_proxy_headers')) {
Request::trustProxyData(); // @deprecated, to be removed in 2.3
}
}

View File

@ -84,77 +84,60 @@ class HttpKernel extends BaseHttpKernel
*
* Available options:
*
* * attributes: An array of request attributes (only when the first argument is a controller)
* * query: An array of request query parameters (only when the first argument is a controller)
* * ignore_errors: true to return an empty string in case of an error
* * alt: an alternative controller to execute in case of an error (can be a controller, a URI, or an array with the controller, the attributes, and the query arguments)
* * alt: an alternative URI to execute in case of an error
* * standalone: whether to generate an esi:include tag or not when ESI is supported
* * comment: a comment to add when returning an esi:include tag
*
* @param string $controller A controller name to execute (a string like BlogBundle:Post:index), or a relative URI
* @param array $options An array of options
* @param string $uri A URI
* @param array $options An array of options
*
* @return string The Response content
*
* @throws \RuntimeException
* @throws \Exception
*/
public function render($controller, array $options = array())
public function render($uri, array $options = array())
{
$request = $this->container->get('request');
$options = array_merge(array(
'attributes' => array(),
'query' => array(),
'ignore_errors' => !$this->container->getParameter('kernel.debug'),
'alt' => array(),
'alt' => null,
'standalone' => false,
'comment' => '',
'default' => null,
), $options);
if (!is_array($options['alt'])) {
$options['alt'] = array($options['alt']);
}
if (null === $this->esiSupport) {
$this->esiSupport = $this->container->has('esi') && $this->container->get('esi')->hasSurrogateEsiCapability($this->container->get('request'));
$this->esiSupport = $this->container->has('esi') && $this->container->get('esi')->hasSurrogateEsiCapability($request);
}
if ($this->esiSupport && (true === $options['standalone'] || 'esi' === $options['standalone'])) {
$uri = $this->generateInternalUri($controller, $options['attributes'], $options['query']);
$alt = '';
if ($options['alt']) {
$alt = $this->generateInternalUri($options['alt'][0], isset($options['alt'][1]) ? $options['alt'][1] : array(), isset($options['alt'][2]) ? $options['alt'][2] : array());
}
return $this->container->get('esi')->renderIncludeTag($uri, $alt, $options['ignore_errors'], $options['comment']);
return $this->container->get('esi')->renderIncludeTag($uri, $options['alt'], $options['ignore_errors'], $options['comment']);
}
if ('js' === $options['standalone']) {
$uri = $this->generateInternalUri($controller, $options['attributes'], $options['query'], false);
$defaultContent = null;
if ($template = $this->container->getParameter('templating.hinclude.default_template')) {
$defaultContent = $this->container->get('templating')->render($template);
$templating = $this->container->get('templating');
if ($options['default']) {
if ($templating->exists($options['default'])) {
$defaultContent = $templating->render($options['default']);
} else {
$defaultContent = $options['default'];
}
} elseif ($template = $this->container->getParameter('templating.hinclude.default_template')) {
$defaultContent = $templating->render($template);
}
return $this->renderHIncludeTag($uri, $defaultContent);
}
$request = $this->container->get('request');
// controller or URI?
if (0 === strpos($controller, '/')) {
$subRequest = Request::create($request->getUriForPath($controller), 'get', array(), $request->cookies->all(), array(), $request->server->all());
if ($session = $request->getSession()) {
$subRequest->setSession($session);
}
} else {
$options['attributes']['_controller'] = $controller;
if (!isset($options['attributes']['_format'])) {
$options['attributes']['_format'] = $request->getRequestFormat();
}
$options['attributes']['_route'] = '_internal';
$subRequest = $request->duplicate($options['query'], null, $options['attributes']);
$subRequest->setMethod('GET');
$subRequest = Request::create($uri, 'get', array(), $request->cookies->all(), array(), $request->server->all());
if ($session = $request->getSession()) {
$subRequest->setSession($session);
}
$level = ob_get_level();
@ -174,10 +157,8 @@ class HttpKernel extends BaseHttpKernel
if ($options['alt']) {
$alt = $options['alt'];
unset($options['alt']);
$options['attributes'] = isset($alt[1]) ? $alt[1] : array();
$options['query'] = isset($alt[2]) ? $alt[2] : array();
return $this->render($alt[0], $options);
return $this->render($alt, $options);
}
if (!$options['ignore_errors']) {
@ -191,43 +172,13 @@ class HttpKernel extends BaseHttpKernel
}
}
/**
* Generates an internal URI for a given controller.
*
* This method uses the "_internal" route, which should be available.
*
* @param string $controller A controller name to execute (a string like BlogBundle:Post:index), or a relative URI
* @param array $attributes An array of request attributes
* @param array $query An array of request query parameters
* @param boolean $secure
*
* @return string An internal URI
*/
public function generateInternalUri($controller, array $attributes = array(), array $query = array(), $secure = true)
{
if (0 === strpos($controller, '/')) {
return $controller;
}
$path = http_build_query($attributes, '', '&');
$uri = $this->container->get('router')->generate($secure ? '_internal' : '_internal_public', array(
'controller' => $controller,
'path' => $path ?: 'none',
'_format' => $this->container->get('request')->getRequestFormat(),
));
if ($queryString = http_build_query($query, '', '&')) {
$uri .= '?'.$queryString;
}
return $uri;
}
/**
* Renders an HInclude tag.
*
* @param string $uri A URI
* @param string $uri A URI
* @param string $defaultContent Default content
*
* @return string
*/
public function renderHIncludeTag($uri, $defaultContent = null)
{

View File

@ -1,4 +1,4 @@
Copyright (c) 2004-2012 Fabien Potencier
Copyright (c) 2004-2013 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -17,41 +17,41 @@
<services>
<service id="data_collector.config" class="%data_collector.config.class%" public="false">
<tag name="data_collector" template="WebProfilerBundle:Collector:config" id="config" priority="255" />
<call method="setKernel"><argument type="service" id="kernel" /></call>
<tag name="data_collector" template="@WebProfiler/Collector/config.html.twig" id="config" priority="255" />
<call method="setKernel"><argument type="service" id="kernel" on-invalid="ignore" /></call>
</service>
<service id="data_collector.request" class="%data_collector.request.class%">
<tag name="kernel.event_subscriber" />
<tag name="data_collector" template="WebProfilerBundle:Collector:request" id="request" priority="255" />
<tag name="data_collector" template="@WebProfiler/Collector/request.html.twig" id="request" priority="255" />
</service>
<service id="data_collector.exception" class="%data_collector.exception.class%" public="false">
<tag name="data_collector" template="WebProfilerBundle:Collector:exception" id="exception" priority="255" />
<tag name="data_collector" template="@WebProfiler/Collector/exception.html.twig" id="exception" priority="255" />
</service>
<service id="data_collector.events" class="%data_collector.events.class%" public="false">
<tag name="data_collector" template="WebProfilerBundle:Collector:events" id="events" priority="255" />
<tag name="data_collector" template="@WebProfiler/Collector/events.html.twig" id="events" priority="255" />
</service>
<service id="data_collector.logger" class="%data_collector.logger.class%" public="false">
<tag name="data_collector" template="WebProfilerBundle:Collector:logger" id="logger" priority="255" />
<tag name="data_collector" template="@WebProfiler/Collector/logger.html.twig" id="logger" priority="255" />
<tag name="monolog.logger" channel="profiler" />
<argument type="service" id="logger" on-invalid="ignore" />
</service>
<service id="data_collector.time" class="%data_collector.time.class%" public="false">
<tag name="data_collector" template="WebProfilerBundle:Collector:time" id="time" priority="255" />
<argument type="service" id="kernel" />
<tag name="data_collector" template="@WebProfiler/Collector/time.html.twig" id="time" priority="255" />
<argument type="service" id="kernel" on-invalid="ignore" />
</service>
<service id="data_collector.memory" class="%data_collector.memory.class%" public="false">
<tag name="data_collector" template="WebProfilerBundle:Collector:memory" id="memory" priority="255" />
<tag name="data_collector" template="@WebProfiler/Collector/memory.html.twig" id="memory" priority="255" />
</service>
<service id="data_collector.router" class="%data_collector.router.class%" >
<tag name="kernel.event_listener" event="kernel.controller" method="onKernelController"/>
<tag name="data_collector" template="WebProfilerBundle:Collector:router" id="router" priority="255" />
<tag name="data_collector" template="@WebProfiler/Collector/router.html.twig" id="router" priority="255" />
</service>
</services>
</container>

View File

@ -13,8 +13,8 @@
<service id="esi" class="%esi.class%" />
<service id="esi_listener" class="%esi_listener.class%">
<tag name="kernel.event_subscriber" />
<argument type="service" id="esi" on-invalid="ignore" />
<tag name="kernel.event_subscriber" />
<argument type="service" id="esi" on-invalid="ignore" />
</service>
</services>
</container>

View File

@ -10,6 +10,7 @@
<parameter key="form.factory.class">Symfony\Component\Form\FormFactory</parameter>
<parameter key="form.extension.class">Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension</parameter>
<parameter key="form.type_guesser.validator.class">Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser</parameter>
<parameter key="property_accessor.class">Symfony\Component\PropertyAccess\PropertyAccessor</parameter>
</parameters>
<services>
@ -53,11 +54,15 @@
<argument type="service" id="validator.mapping.class_metadata_factory" />
</service>
<!-- PropertyAccessor -->
<service id="property_accessor" class="%property_accessor.class%" />
<!-- CoreExtension -->
<service id="form.type.field" class="Symfony\Component\Form\Extension\Core\Type\FieldType">
<tag name="form.type" alias="field" />
</service>
<service id="form.type.form" class="Symfony\Component\Form\Extension\Core\Type\FormType">
<argument type="service" id="property_accessor"/>
<tag name="form.type" alias="form" />
</service>
<service id="form.type.birthday" class="Symfony\Component\Form\Extension\Core\Type\BirthdayType">

View File

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<route id="_internal" pattern="/secure/{controller}/{path}.{_format}">
<default key="_controller">FrameworkBundle:Internal:index</default>
<requirement key="path">.+</requirement>
<requirement key="_format">[^.]+</requirement>
</route>
<route id="_internal_public" pattern="/{controller}/{path}.{_format}">
<default key="_controller">FrameworkBundle:Internal:index</default>
<requirement key="path">.+</requirement>
<requirement key="_format">[^.]+</requirement>
</route>
</routes>

View File

@ -24,6 +24,7 @@
<!-- charset is deprecated and will be removed in 2.2 -->
<xsd:attribute name="charset" type="xsd:string" />
<xsd:attribute name="trust-proxy-headers" type="xsd:string" />
<xsd:attribute name="trusted-proxies" type="xsd:string" />
<xsd:attribute name="ide" type="xsd:string" />
<xsd:attribute name="secret" type="xsd:string" />
<xsd:attribute name="default-locale" type="xsd:string" />

View File

@ -13,7 +13,7 @@
<parameter key="translation.loader.xliff.class">Symfony\Component\Translation\Loader\XliffFileLoader</parameter>
<parameter key="translation.loader.po.class">Symfony\Component\Translation\Loader\PoFileLoader</parameter>
<parameter key="translation.loader.mo.class">Symfony\Component\Translation\Loader\MoFileLoader</parameter>
<parameter key="translation.loader.qt.class">Symfony\Component\Translation\Loader\QtTranslationsLoader</parameter>
<parameter key="translation.loader.qt.class">Symfony\Component\Translation\Loader\QtFileLoader</parameter>
<parameter key="translation.loader.csv.class">Symfony\Component\Translation\Loader\CsvFileLoader</parameter>
<parameter key="translation.loader.res.class">Symfony\Component\Translation\Loader\IcuResFileLoader</parameter>
<parameter key="translation.loader.dat.class">Symfony\Component\Translation\Loader\IcuDatFileLoader</parameter>

View File

@ -23,6 +23,8 @@
<service id="validator" class="%validator.class%">
<argument type="service" id="validator.mapping.class_metadata_factory" />
<argument type="service" id="validator.validator_factory" />
<argument type="service" id="translator.default" />
<argument>%validator.translation_domain%</argument>
<argument type="collection" />
</service>

View File

@ -2,7 +2,7 @@
<?php echo $view['form']->block($form, 'widget_attributes') ?>
<?php if ($multiple): ?> multiple="multiple"<?php endif ?>
>
<?php if (null !== $empty_value): ?><option value=""><?php echo $view->escape($view['translator']->trans($empty_value, array(), $translation_domain)) ?></option><?php endif; ?>
<?php if (null !== $empty_value): ?><option value="" disabled="disabled"<?php if (empty($value) && "0" !== $value): ?> selected="selected"<?php endif ?>><?php echo $view->escape($view['translator']->trans($empty_value, array(), $translation_domain)) ?></option><?php endif; ?>
<?php if (count($preferred_choices) > 0): ?>
<?php echo $view['form']->block($form, 'choice_widget_options', array('choices' => $preferred_choices)) ?>
<?php if (count($choices) > 0 && null !== $separator): ?>

View File

@ -1,21 +1,7 @@
<?php if ($errors): ?>
<ul>
<?php foreach ($errors as $error): ?>
<li><?php
if (null === $error->getMessagePluralization()) {
echo $view['translator']->trans(
$error->getMessageTemplate(),
$error->getMessageParameters(),
'validators'
);
} else {
echo $view['translator']->transChoice(
$error->getMessageTemplate(),
$error->getMessagePluralization(),
$error->getMessageParameters(),
'validators'
);
}?></li>
<li><?php echo $error->getMessage() ?></li>
<?php endforeach; ?>
</ul>
<?php endif ?>

View File

@ -6,8 +6,11 @@
// There should be no spaces between the colons and the widgets, that's why
// this block is written in a single PHP tag
echo $view['form']->widget($form['hour'], array('attr' => array('size' => 1)));
echo ':';
echo $view['form']->widget($form['minute'], array('attr' => array('size' => 1)));
if ($with_minutes) {
echo ':';
echo $view['form']->widget($form['minute'], array('attr' => array('size' => 1)));
}
if ($with_seconds) {
echo ':';

View File

@ -1,21 +0,0 @@
<?php if ($errors): ?>
<ul>
<?php foreach ($errors as $error): ?>
<li><?php
if (null === $error->getMessagePluralization()) {
echo $view['translator']->trans(
$error->getMessageTemplate(),
$error->getMessageParameters(),
'validators'
);
} else {
echo $view['translator']->transChoice(
$error->getMessageTemplate(),
$error->getMessagePluralization(),
$error->getMessageParameters(),
'validators'
);
}?></li>
<?php endforeach; ?>
</ul>
<?php endif ?>

View File

@ -14,7 +14,7 @@ namespace Symfony\Bundle\FrameworkBundle\Routing;
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser;
use Symfony\Component\Config\Loader\DelegatingLoader as BaseDelegatingLoader;
use Symfony\Component\Config\Loader\LoaderResolverInterface;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Psr\Log\LoggerInterface;
/**
* DelegatingLoader delegates route loading to other loaders using a loader resolver.

View File

@ -12,7 +12,7 @@
namespace Symfony\Bundle\FrameworkBundle\Templating;
use Symfony\Component\Templating\DebuggerInterface;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Psr\Log\LoggerInterface;
/**
* Binds the Symfony templating loader debugger to the Symfony logger.

View File

@ -12,6 +12,10 @@
namespace Symfony\Bundle\FrameworkBundle\Templating;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Request;
/**
* GlobalVariables is the entry point for Symfony global variables in Twig templates.
@ -30,7 +34,7 @@ class GlobalVariables
/**
* Returns the security context service.
*
* @return Symfony\Component\Security\Core\SecurityContext|void The security context
* @return SecurityContext|null The security context
*/
public function getSecurity()
{
@ -44,7 +48,7 @@ class GlobalVariables
*
* @return mixed|void
*
* @see Symfony\Component\Security\Core\Authentication\Token\TokenInterface::getUser()
* @see TokenInterface::getUser()
*/
public function getUser()
{
@ -67,7 +71,7 @@ class GlobalVariables
/**
* Returns the current request.
*
* @return Symfony\Component\HttpFoundation\Request|void The http request object
* @return Request|null The http request object
*/
public function getRequest()
{
@ -79,7 +83,7 @@ class GlobalVariables
/**
* Returns the current session.
*
* @return Symfony\Component\HttpFoundation\Session\Session|void The session
* @return Session|null The session
*/
public function getSession()
{

View File

@ -34,19 +34,18 @@ class ActionsHelper extends Helper
}
/**
* Returns the Response content for a given controller or URI.
* Returns the Response content for a given URI.
*
* @param string $controller A controller name to execute (a string like BlogBundle:Post:index), or a relative URI
* @param array $attributes An array of request attributes
* @param array $options An array of options
* @param string $uri A URI
* @param array $options An array of options
*
* @return string
*
* @see Symfony\Bundle\FrameworkBundle\HttpKernel::render()
*/
public function render($controller, array $attributes = array(), array $options = array())
public function render($uri, array $options = array())
{
$options['attributes'] = $attributes;
return $this->kernel->render($controller, $options);
return $this->kernel->render($uri, $options);
}
/**

View File

@ -122,6 +122,15 @@ class CodeHelper extends Helper
public function fileExcerpt($file, $line)
{
if (is_readable($file)) {
if (extension_loaded('fileinfo')) {
$finfo = new \Finfo();
// Check if the file is an application/octet-stream (eg. Phar file) because hightlight_file cannot parse these files
if ('application/octet-stream' === $finfo->file($file, FILEINFO_MIME_TYPE)) {
return;
}
}
$code = highlight_file($file, true);
// remove main code/span tags
$code = preg_replace('#^<code.*?>\s*<span.*?>(.*)</span>\s*</code>#s', '\\1', $code);

View File

@ -84,7 +84,7 @@ class FormHelper extends Helper
*
* <?php echo view['form']->widget(array('attr' => array('class' => 'foo'))) ?>
*
* <?php echo view['form']->widget(array('separator' => '+++++)) ?>
* <?php echo view['form']->widget(array('separator' => '+++++')) ?>
*
* @param FormView $view The view for which to render the widget
* @param array $variables Additional variables passed to the template

View File

@ -39,6 +39,8 @@ class RequestHelper extends Helper
* @param string $key The name of the parameter
* @param string $default A default value
*
* @return mixed
*
* @see Symfony\Component\HttpFoundation\Request::get()
*/
public function getParameter($key, $default = null)

View File

@ -36,15 +36,17 @@ class RouterHelper extends Helper
/**
* Generates a URL from the given parameters.
*
* @param string $name The name of the route
* @param mixed $parameters An array of parameters
* @param Boolean $absolute Whether to generate an absolute URL
* @param string $name The name of the route
* @param mixed $parameters An array of parameters
* @param Boolean|string $referenceType The type of reference (one of the constants in UrlGeneratorInterface)
*
* @return string The generated URL
*
* @see UrlGeneratorInterface
*/
public function generate($name, $parameters = array(), $absolute = false)
public function generate($name, $parameters = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH)
{
return $this->generator->generate($name, $parameters, $absolute);
return $this->generator->generate($name, $parameters, $referenceType);
}
/**

View File

@ -40,7 +40,7 @@ class FilesystemLoader implements LoaderInterface
*
* @param TemplateReferenceInterface $template A template
*
* @return Storage|Boolean false if the template cannot be loaded, a Storage instance otherwise
* @return FileStorage|Boolean false if the template cannot be loaded, a Storage instance otherwise
*/
public function load(TemplateReferenceInterface $template)
{
@ -58,6 +58,8 @@ class FilesystemLoader implements LoaderInterface
*
* @param TemplateReferenceInterface $template The template name as an array
* @param integer $time The last modification time of the cached template (timestamp)
*
* @return Boolean
*/
public function isFresh(TemplateReferenceInterface $template, $time)
{

View File

@ -55,6 +55,8 @@ abstract class WebTestCase extends \PHPUnit_Framework_TestCase
* If not, override this method in your test classes.
*
* @return string The directory where phpunit.xml(.dist) is stored
*
* @throws \RuntimeException
*/
protected static function getPhpUnitXmlDir()
{
@ -113,6 +115,8 @@ abstract class WebTestCase extends \PHPUnit_Framework_TestCase
* When the Kernel is located, the file is required.
*
* @return string The Kernel class name
*
* @throws \RuntimeException
*/
protected static function getKernelClass()
{

View File

@ -0,0 +1,81 @@
<?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\Bundle\FrameworkBundle\Tests\DependencyInjection;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Configuration;
use Symfony\Component\Config\Definition\Processor;
class ConfigurationTest extends \PHPUnit_Framework_TestCase
{
/**
* @dataProvider getTestConfigTreeData
*/
public function testConfigTree($options, $results)
{
$processor = new Processor();
$configuration = new Configuration(array());
$config = $processor->processConfiguration($configuration, array($options));
$this->assertEquals($results, $config);
}
public function getTestConfigTreeData()
{
return array(
array(array('secret' => 's3cr3t'), array('secret' => 's3cr3t', 'trusted_proxies' => array(), 'trust_proxy_headers' => false, 'ide' => NULL, 'annotations' => array('cache' => 'file', 'file_cache_dir' => '%kernel.cache_dir%/annotations', 'debug' => '%kernel.debug%'), 'default_locale' => 'en', 'charset' => null)),
);
}
/**
* @dataProvider getTestValidTrustedProxiesData
*/
public function testValidTrustedProxies($options, $results)
{
$processor = new Processor();
$configuration = new Configuration(array());
$config = $processor->processConfiguration($configuration, array($options));
$this->assertEquals($results, $config);
}
public function getTestValidTrustedProxiesData()
{
return array(
array(array('secret' => 's3cr3t', 'trusted_proxies' => array('127.0.0.1')), array('secret' => 's3cr3t', 'trusted_proxies' => array('127.0.0.1'), 'trust_proxy_headers' => false, 'ide' => NULL, 'annotations' => array('cache' => 'file', 'file_cache_dir' => '%kernel.cache_dir%/annotations', 'debug' => '%kernel.debug%'), 'default_locale' => 'en', 'charset' => null)),
array(array('secret' => 's3cr3t', 'trusted_proxies' => array('::1')), array('secret' => 's3cr3t', 'trusted_proxies' => array('::1'), 'trust_proxy_headers' => false, 'ide' => NULL, 'annotations' => array('cache' => 'file', 'file_cache_dir' => '%kernel.cache_dir%/annotations', 'debug' => '%kernel.debug%'), 'default_locale' => 'en', 'charset' => null)),
array(array('secret' => 's3cr3t', 'trusted_proxies' => array('127.0.0.1', '::1')), array('secret' => 's3cr3t', 'trusted_proxies' => array('127.0.0.1', '::1'), 'trust_proxy_headers' => false, 'ide' => NULL, 'annotations' => array('cache' => 'file', 'file_cache_dir' => '%kernel.cache_dir%/annotations', 'debug' => '%kernel.debug%'), 'default_locale' => 'en', 'charset' => null)),
array(array('secret' => 's3cr3t', 'trusted_proxies' => null), array('secret' => 's3cr3t', 'trusted_proxies' => array(), 'trust_proxy_headers' => false, 'ide' => NULL, 'annotations' => array('cache' => 'file', 'file_cache_dir' => '%kernel.cache_dir%/annotations', 'debug' => '%kernel.debug%'), 'default_locale' => 'en', 'charset' => null)),
array(array('secret' => 's3cr3t', 'trusted_proxies' => false), array('secret' => 's3cr3t', 'trusted_proxies' => array(), 'trust_proxy_headers' => false, 'ide' => NULL, 'annotations' => array('cache' => 'file', 'file_cache_dir' => '%kernel.cache_dir%/annotations', 'debug' => '%kernel.debug%'), 'default_locale' => 'en', 'charset' => null)),
array(array('secret' => 's3cr3t', 'trusted_proxies' => array()), array('secret' => 's3cr3t', 'trusted_proxies' => array(), 'trust_proxy_headers' => false, 'ide' => NULL, 'annotations' => array('cache' => 'file', 'file_cache_dir' => '%kernel.cache_dir%/annotations', 'debug' => '%kernel.debug%'), 'default_locale' => 'en', 'charset' => null)),
);
}
/**
* @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
*/
public function testInvalidTypeTrustedProxies()
{
$processor = new Processor();
$configuration = new Configuration(array());
$config = $processor->processConfiguration($configuration, array(array('secret' => 's3cr3t', 'trusted_proxies' => 'Not an IP address')));
}
/**
* @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
*/
public function testInvalidValueTrustedProxies()
{
$processor = new Processor();
$configuration = new Configuration(array());
$config = $processor->processConfiguration($configuration, array(array('secret' => 's3cr3t', 'trusted_proxies' => array('Not an IP address'))));
}
}

View File

@ -4,6 +4,8 @@ $container->loadFromExtension('framework', array(
'secret' => 's3cr3t',
'default_locale' => 'fr',
'form' => null,
'trust_proxy_headers' => true,
'trusted_proxies' => array('127.0.0.1', '10.0.0.1'),
'csrf_protection' => array(
'enabled' => true,
'field_name' => '_csrf',

View File

@ -6,7 +6,7 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
<framework:config secret="s3cr3t" ide="file%%link%%format" default-locale="fr">
<framework:config secret="s3cr3t" ide="file%%link%%format" default-locale="fr" trust-proxy-headers="true" trusted-proxies="127.0.0.1, 10.0.0.1">
<framework:csrf-protection enabled="true" field-name="_csrf" />
<framework:form />
<framework:esi enabled="true" />

View File

@ -2,6 +2,8 @@ framework:
secret: s3cr3t
default_locale: fr
form: ~
trust_proxy_headers: true
trusted_proxies: ['127.0.0.1', '10.0.0.1']
csrf_protection:
enabled: true
field_name: _csrf

View File

@ -33,6 +33,14 @@ abstract class FrameworkExtensionTest extends TestCase
$this->assertEquals('s3cr3t', $container->getParameterBag()->resolveValue($container->findDefinition('form.csrf_provider')->getArgument(1)));
}
public function testProxies()
{
$container = $this->createContainerFromFile('full');
$this->assertTrue($container->getParameter('kernel.trust_proxy_headers'));
$this->assertEquals(array('127.0.0.1', '10.0.0.1'), $container->getParameter('kernel.trusted_proxies'));
}
public function testEsi()
{
$container = $this->createContainerFromFile('full');
@ -65,7 +73,7 @@ abstract class FrameworkExtensionTest extends TestCase
}
/**
* @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
* @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
*/
public function testRouterRequiresResourceOption()
{
@ -197,13 +205,18 @@ abstract class FrameworkExtensionTest extends TestCase
$files,
'->registerTranslatorConfiguration() finds Form translation resources'
);
$this->assertContains(
'Symfony/Component/Security/Resources/translations/security.en.xlf',
$files,
'->registerTranslatorConfiguration() finds Security translation resources'
);
$calls = $container->getDefinition('translator.default')->getMethodCalls();
$this->assertEquals('fr', $calls[0][1][0]);
}
/**
* @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
* @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
*/
public function testTemplatingRequiresAtLeastOneEngine()
{

View File

@ -16,6 +16,7 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
/**
* SessionListenerTest.
@ -26,7 +27,14 @@ use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
*/
class TestSessionListenerTest extends \PHPUnit_Framework_TestCase
{
/**
* @var TestSessionListener
*/
private $listener;
/**
* @var SessionInterface
*/
private $session;
protected function setUp()
@ -43,6 +51,7 @@ class TestSessionListenerTest extends \PHPUnit_Framework_TestCase
public function testShouldSaveMasterRequestSession()
{
$this->sessionHasBeenStarted();
$this->sessionMustBeSaved();
$this->filterResponse(new Request());
@ -57,6 +66,8 @@ class TestSessionListenerTest extends \PHPUnit_Framework_TestCase
public function testDoesNotDeleteCookieIfUsingSessionLifetime()
{
$this->sessionHasBeenStarted();
$params = session_get_cookie_params();
session_set_cookie_params(0, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
@ -66,6 +77,14 @@ class TestSessionListenerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(0, reset($cookies)->getExpiresTime());
}
public function testUnstartedSessionIsNotSave()
{
$this->sessionHasNotBeenStarted();
$this->sessionMustNotBeSaved();
$this->filterResponse(new Request());
}
private function filterResponse(Request $request, $type = HttpKernelInterface::MASTER_REQUEST)
{
$request->setSession($this->session);
@ -92,6 +111,20 @@ class TestSessionListenerTest extends \PHPUnit_Framework_TestCase
->method('save');
}
private function sessionHasBeenStarted()
{
$this->session->expects($this->once())
->method('isStarted')
->will($this->returnValue(true));
}
private function sessionHasNotBeenStarted()
{
$this->session->expects($this->once())
->method('isStarted')
->will($this->returnValue(false));
}
private function getSession()
{
$mock = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\Session')

View File

@ -116,47 +116,6 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
}
}
public function testGenerateInternalUriHandlesNullValues()
{
$request = new Request();
$router = $this->getMock('Symfony\\Component\\Routing\\RouterInterface');
$container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerInterface');
$container
->expects($this->at(0))
->method('get')
->with($this->equalTo('router'))
->will($this->returnValue($router))
;
$container
->expects($this->at('1'))
->method('get')
->with($this->equalTo('request'))
->will($this->returnValue($request))
;
$controller = 'AController';
$attributes = array('anAttribute' => null);
$query = array('aQueryParam' => null);
$expectedPath = 'none';
$routeParameters = array('controller' => $controller, 'path' => $expectedPath, '_format' => 'html');
$router
->expects($this->once())
->method('generate')
->with($this->equalTo('_internal'), $this->equalTo($routeParameters))
->will($this->returnValue('GENERATED_URI'))
;
$dispatcher = new EventDispatcher();
$resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface');
$kernel = new HttpKernel($dispatcher, $container, $resolver);
$uri = $kernel->generateInternalUri($controller, $attributes, $query);
$this->assertEquals('GENERATED_URI', $uri);
}
public function getProviderTypes()
{
return array(
@ -172,22 +131,22 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
$container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerInterface');
$container
->expects($this->at(0))
->method('get')
->with($this->equalTo('request'))
->will($this->returnValue($request))
;
$container
->expects($this->at(1))
->method('getParameter')
->with($this->equalTo('kernel.debug'))
->will($this->returnValue(false))
;
$container
->expects($this->at(1))
->expects($this->at(2))
->method('has')
->with($this->equalTo('esi'))
->will($this->returnValue(false))
;
$container
->expects($this->at(2))
->method('get')
->with($this->equalTo('request'))
->will($this->returnValue($request))
;
$dispatcher = new EventDispatcher();
$resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface');

View File

@ -68,6 +68,8 @@ class FormHelperDivLayoutTest extends AbstractDivLayoutTest
protected function tearDown()
{
$this->engine = null;
parent::tearDown();
}
protected function renderEnctype(FormView $view)

View File

@ -69,6 +69,8 @@ class FormHelperTableLayoutTest extends AbstractTableLayoutTest
protected function tearDown()
{
$this->engine = null;
parent::tearDown();
}
protected function renderEnctype(FormView $view)

View File

@ -39,6 +39,8 @@ class Translator extends BaseTranslator
* @param MessageSelector $selector The message selector for pluralization
* @param array $loaderIds An array of loader Ids
* @param array $options An array of options
*
* @throws \InvalidArgumentException
*/
public function __construct(ContainerInterface $container, MessageSelector $selector, $loaderIds = array(), array $options = array())
{

Some files were not shown because too many files have changed in this diff Show More