Merge branch '4.1' into 4.2

* 4.1:
  [Routing] fix trailing slash redirection
  calculate cache keys for property setters depending on the value
  updated VERSION for 2.8.48
  update CONTRIBUTORS for 2.8.48
  updated CHANGELOG for 2.8.48
This commit is contained in:
Nicolas Grekas 2018-11-29 15:48:32 +01:00
commit cfc54b481a
8 changed files with 159 additions and 35 deletions

View File

@ -14,9 +14,9 @@ Symfony is the result of the work of many people who made the code better
- Victor Berchet (victor) - Victor Berchet (victor)
- Robin Chalas (chalas_r) - Robin Chalas (chalas_r)
- Kévin Dunglas (dunglas) - Kévin Dunglas (dunglas)
- Maxime Steinhausser (ogizanagi)
- Jakub Zalas (jakubzalas) - Jakub Zalas (jakubzalas)
- Johannes S (johannes) - Johannes S (johannes)
- Maxime Steinhausser (ogizanagi)
- Kris Wallsmith (kriswallsmith) - Kris Wallsmith (kriswallsmith)
- Ryan Weaver (weaverryan) - Ryan Weaver (weaverryan)
- Javier Eguiluz (javier.eguiluz) - Javier Eguiluz (javier.eguiluz)
@ -37,8 +37,8 @@ Symfony is the result of the work of many people who made the code better
- Benjamin Eberlei (beberlei) - Benjamin Eberlei (beberlei)
- Igor Wiedler (igorw) - Igor Wiedler (igorw)
- Jules Pietri (heah) - Jules Pietri (heah)
- Eriksen Costa (eriksencosta)
- Yonel Ceruto (yonelceruto) - Yonel Ceruto (yonelceruto)
- Eriksen Costa (eriksencosta)
- Guilhem Niot (energetick) - Guilhem Niot (energetick)
- Sarah Khalil (saro0h) - Sarah Khalil (saro0h)
- Jonathan Wage (jwage) - Jonathan Wage (jwage)
@ -70,6 +70,7 @@ Symfony is the result of the work of many people who made the code better
- Gábor Egyed (1ed) - Gábor Egyed (1ed)
- Mathieu Piot (mpiot) - Mathieu Piot (mpiot)
- Titouan Galopin (tgalopin) - Titouan Galopin (tgalopin)
- Vladimir Reznichenko (kalessil)
- Michel Weimerskirch (mweimerskirch) - Michel Weimerskirch (mweimerskirch)
- Andrej Hudec (pulzarraider) - Andrej Hudec (pulzarraider)
- Konstantin Myakshin (koc) - Konstantin Myakshin (koc)
@ -77,7 +78,6 @@ Symfony is the result of the work of many people who made the code better
- Jáchym Toušek (enumag) - Jáchym Toušek (enumag)
- Charles Sarrazin (csarrazi) - Charles Sarrazin (csarrazi)
- David Maicher (dmaicher) - David Maicher (dmaicher)
- Vladimir Reznichenko (kalessil)
- Christian Raue - Christian Raue
- Issei Murasawa (issei_m) - Issei Murasawa (issei_m)
- Arnout Boks (aboks) - Arnout Boks (aboks)
@ -86,13 +86,13 @@ Symfony is the result of the work of many people who made the code better
- Dariusz Górecki (canni) - Dariusz Górecki (canni)
- Douglas Greenshields (shieldo) - Douglas Greenshields (shieldo)
- Dariusz Ruminski - Dariusz Ruminski
- Grégoire Paris (greg0ire)
- Lee McDermott - Lee McDermott
- Brandon Turner - Brandon Turner
- Luis Cordova (cordoval) - Luis Cordova (cordoval)
- Graham Campbell (graham) - Graham Campbell (graham)
- Daniel Holmes (dholmes) - Daniel Holmes (dholmes)
- Toni Uebernickel (havvg) - Toni Uebernickel (havvg)
- Grégoire Paris (greg0ire)
- Bart van den Burg (burgov) - Bart van den Burg (burgov)
- Jordan Alliot (jalliot) - Jordan Alliot (jalliot)
- Jérôme Tamarelle (gromnan) - Jérôme Tamarelle (gromnan)
@ -113,12 +113,12 @@ Symfony is the result of the work of many people who made the code better
- lenar - lenar
- Alexander Schwenn (xelaris) - Alexander Schwenn (xelaris)
- Włodzimierz Gajda (gajdaw) - Włodzimierz Gajda (gajdaw)
- Tomáš Votruba (tomas_votruba)
- Peter Kokot (maastermedia) - Peter Kokot (maastermedia)
- Jacob Dreesen (jdreesen) - Jacob Dreesen (jdreesen)
- Florian Voutzinos (florianv) - Florian Voutzinos (florianv)
- Colin Frei - Colin Frei
- Adrien Brault (adrienbrault) - Adrien Brault (adrienbrault)
- Tomáš Votruba (tomas_votruba)
- Joshua Thijssen - Joshua Thijssen
- excelwebzone - excelwebzone
- Gordon Franke (gimler) - Gordon Franke (gimler)
@ -179,6 +179,7 @@ Symfony is the result of the work of many people who made the code better
- jeremyFreeAgent (Jérémy Romey) (jeremyfreeagent) - jeremyFreeAgent (Jérémy Romey) (jeremyfreeagent)
- James Halsall (jaitsu) - James Halsall (jaitsu)
- Matthieu Napoli (mnapoli) - Matthieu Napoli (mnapoli)
- Florent Mata (fmata)
- Warnar Boekkooi (boekkooi) - Warnar Boekkooi (boekkooi)
- Alessandro Chitolina (alekitto) - Alessandro Chitolina (alekitto)
- Dmitrii Chekaliuk (lazyhammer) - Dmitrii Chekaliuk (lazyhammer)
@ -193,7 +194,6 @@ Symfony is the result of the work of many people who made the code better
- Dennis Benkert (denderello) - Dennis Benkert (denderello)
- DQNEO - DQNEO
- Benjamin Dulau (dbenjamin) - Benjamin Dulau (dbenjamin)
- Florent Mata (fmata)
- Mathieu Lemoine (lemoinem) - Mathieu Lemoine (lemoinem)
- Thomas Calvet (fancyweb) - Thomas Calvet (fancyweb)
- Christian Schmidt - Christian Schmidt
@ -258,6 +258,7 @@ Symfony is the result of the work of many people who made the code better
- Benoît Burnichon (bburnichon) - Benoît Burnichon (bburnichon)
- Roman Marintšenko (inori) - Roman Marintšenko (inori)
- Xavier Montaña Carreras (xmontana) - Xavier Montaña Carreras (xmontana)
- François-Xavier de Guillebon (de-gui_f)
- Mickaël Andrieu (mickaelandrieu) - Mickaël Andrieu (mickaelandrieu)
- Maxime Veber (nek-) - Maxime Veber (nek-)
- Xavier Perez - Xavier Perez
@ -294,7 +295,9 @@ Symfony is the result of the work of many people who made the code better
- Thomas Lallement (raziel057) - Thomas Lallement (raziel057)
- mcfedr (mcfedr) - mcfedr (mcfedr)
- Colin O'Dell (colinodell) - Colin O'Dell (colinodell)
- Fabien Bourigault (fbourigault)
- Giorgio Premi - Giorgio Premi
- Jan Schädlich (jschaedl)
- Beau Simensen (simensen) - Beau Simensen (simensen)
- Michael Hirschler (mvhirsch) - Michael Hirschler (mvhirsch)
- Robert Kiss (kepten) - Robert Kiss (kepten)
@ -305,8 +308,8 @@ Symfony is the result of the work of many people who made the code better
- Jérôme Parmentier (lctrs) - Jérôme Parmentier (lctrs)
- Michael Babker (mbabker) - Michael Babker (mbabker)
- Peter Kruithof (pkruithof) - Peter Kruithof (pkruithof)
- François-Xavier de Guillebon (de-gui_f)
- Michael Holm (hollo) - Michael Holm (hollo)
- Remon van de Kamp (rpkamp)
- Marc Weistroff (futurecat) - Marc Weistroff (futurecat)
- Christian Schmidt - Christian Schmidt
- MatTheCat - MatTheCat
@ -350,8 +353,6 @@ Symfony is the result of the work of many people who made the code better
- Ricard Clau (ricardclau) - Ricard Clau (ricardclau)
- Mark Challoner (markchalloner) - Mark Challoner (markchalloner)
- Gennady Telegin (gtelegin) - Gennady Telegin (gtelegin)
- Jan Schädlich (jschaedl)
- Fabien Bourigault (fbourigault)
- Ben Davies (bendavies) - Ben Davies (bendavies)
- Erin Millard - Erin Millard
- Artur Melo (restless) - Artur Melo (restless)
@ -445,6 +446,7 @@ Symfony is the result of the work of many people who made the code better
- lancergr - lancergr
- Zan Baldwin - Zan Baldwin
- Mihai Stancu - Mihai Stancu
- Ivan Nikolaev (destillat)
- Olivier Dolbeau (odolbeau) - Olivier Dolbeau (odolbeau)
- Jan Rosier (rosier) - Jan Rosier (rosier)
- Alessandro Lai (jean85) - Alessandro Lai (jean85)
@ -461,7 +463,6 @@ Symfony is the result of the work of many people who made the code better
- Boris Vujicic (boris.vujicic) - Boris Vujicic (boris.vujicic)
- Chris Sedlmayr (catchamonkey) - Chris Sedlmayr (catchamonkey)
- Mateusz Sip (mateusz_sip) - Mateusz Sip (mateusz_sip)
- Remon van de Kamp
- Kamil Kokot (pamil) - Kamil Kokot (pamil)
- Seb Koelen - Seb Koelen
- Christoph Mewes (xrstf) - Christoph Mewes (xrstf)
@ -470,6 +471,7 @@ Symfony is the result of the work of many people who made the code better
- Dirk Pahl (dirkaholic) - Dirk Pahl (dirkaholic)
- cedric lombardot (cedriclombardot) - cedric lombardot (cedriclombardot)
- Jonas Flodén (flojon) - Jonas Flodén (flojon)
- Gonzalo Vilaseca (gonzalovilaseca)
- Marcin Sikoń (marphi) - Marcin Sikoń (marphi)
- Dominik Zogg (dominik.zogg) - Dominik Zogg (dominik.zogg)
- Marek Pietrzak - Marek Pietrzak
@ -643,7 +645,6 @@ Symfony is the result of the work of many people who made the code better
- adev - adev
- Stefan Warman - Stefan Warman
- Arkadius Stefanski (arkadius) - Arkadius Stefanski (arkadius)
- Gonzalo Vilaseca (gonzalovilaseca)
- Tristan Maindron (tmaindron) - Tristan Maindron (tmaindron)
- Wesley Lancel - Wesley Lancel
- Ke WANG (yktd26) - Ke WANG (yktd26)
@ -665,6 +666,7 @@ Symfony is the result of the work of many people who made the code better
- Sergey (upyx) - Sergey (upyx)
- Michael Devery (mickadoo) - Michael Devery (mickadoo)
- Antoine Corcy - Antoine Corcy
- Dmitrii Poddubnyi (karser)
- Sascha Grossenbacher - Sascha Grossenbacher
- Szijarto Tamas - Szijarto Tamas
- Robin Lehrmann (robinlehrmann) - Robin Lehrmann (robinlehrmann)
@ -804,7 +806,6 @@ Symfony is the result of the work of many people who made the code better
- Sofiane HADDAG (sofhad) - Sofiane HADDAG (sofhad)
- frost-nzcr4 - frost-nzcr4
- Bozhidar Hristov - Bozhidar Hristov
- Ivan Nikolaev (destillat)
- Laurent Bassin (lbassin) - Laurent Bassin (lbassin)
- andrey1s - andrey1s
- Abhoryo - Abhoryo
@ -989,6 +990,7 @@ Symfony is the result of the work of many people who made the code better
- Mathieu Santostefano - Mathieu Santostefano
- Arjan Keeman - Arjan Keeman
- Máximo Cuadros (mcuadros) - Máximo Cuadros (mcuadros)
- Lukas Mencl
- tamirvs - tamirvs
- julien.galenski - julien.galenski
- Christian Neff - Christian Neff
@ -1290,6 +1292,7 @@ Symfony is the result of the work of many people who made the code better
- Adrien Samson (adriensamson) - Adrien Samson (adriensamson)
- Samuel Gordalina (gordalina) - Samuel Gordalina (gordalina)
- Max Romanovsky (maxromanovsky) - Max Romanovsky (maxromanovsky)
- Nicolas Eeckeloo (neeckeloo)
- Mathieu Morlon - Mathieu Morlon
- Daniel Tschinder - Daniel Tschinder
- Arnaud CHASSEUX - Arnaud CHASSEUX
@ -1351,6 +1354,7 @@ Symfony is the result of the work of many people who made the code better
- Andrew (drew) - Andrew (drew)
- kor3k kor3k (kor3k) - kor3k kor3k (kor3k)
- Stelian Mocanita (stelian) - Stelian Mocanita (stelian)
- Thomas Bisignani (toma)
- Justin (wackymole) - Justin (wackymole)
- Flavian (2much) - Flavian (2much)
- Gautier Deuette - Gautier Deuette
@ -1448,6 +1452,7 @@ Symfony is the result of the work of many people who made the code better
- Phobetor - Phobetor
- Andreas - Andreas
- Markus - Markus
- Daniel Gorgan
- Thomas Chmielowiec - Thomas Chmielowiec
- shdev - shdev
- Andrey Ryaguzov - Andrey Ryaguzov
@ -1499,6 +1504,7 @@ Symfony is the result of the work of many people who made the code better
- David Barratt - David Barratt
- Pavel.Batanov - Pavel.Batanov
- avi123 - avi123
- Pavel Prischepa
- alsar - alsar
- downace - downace
- Aarón Nieves Fernández - Aarón Nieves Fernández
@ -1613,6 +1619,7 @@ Symfony is the result of the work of many people who made the code better
- David Zuelke - David Zuelke
- Adrian - Adrian
- Oleg Andreyev - Oleg Andreyev
- neFAST
- Pierre Rineau - Pierre Rineau
- Maxim Lovchikov - Maxim Lovchikov
- adenkejawen - adenkejawen
@ -1710,7 +1717,6 @@ Symfony is the result of the work of many people who made the code better
- Giovanni Albero (johntree) - Giovanni Albero (johntree)
- Jorge Martin (jorgemartind) - Jorge Martin (jorgemartind)
- Joeri Verdeyen (jverdeyen) - Joeri Verdeyen (jverdeyen)
- Dmitrii Poddubnyi (karser)
- Kevin Verschaeve (keversc) - Kevin Verschaeve (keversc)
- Kevin Herrera (kherge) - Kevin Herrera (kherge)
- Luis Ramón López López (lrlopez) - Luis Ramón López López (lrlopez)
@ -1872,6 +1878,7 @@ Symfony is the result of the work of many people who made the code better
- zorn - zorn
- Yuriy Potemkin - Yuriy Potemkin
- Emilie Lorenzo - Emilie Lorenzo
- Edvin Hultberg
- Benjamin Long - Benjamin Long
- Matt Janssen - Matt Janssen
- Ben Miller - Ben Miller
@ -1992,6 +1999,7 @@ Symfony is the result of the work of many people who made the code better
- Alex Carol (picard89) - Alex Carol (picard89)
- Daniel Perez Pinazo (pitiflautico) - Daniel Perez Pinazo (pitiflautico)
- Phil Taylor (prazgod) - Phil Taylor (prazgod)
- Maxim Pustynnikov (pustynnikov)
- Brayden Williams (redstar504) - Brayden Williams (redstar504)
- Rich Sage (richsage) - Rich Sage (richsage)
- Rokas Mikalkėnas (rokasm) - Rokas Mikalkėnas (rokasm)

View File

@ -587,7 +587,8 @@ class PropertyAccessor implements PropertyAccessorInterface
*/ */
private function getWriteAccessInfo(string $class, string $property, $value): array private function getWriteAccessInfo(string $class, string $property, $value): array
{ {
$key = str_replace('\\', '.', $class).'..'.$property; $useAdderAndRemover = \is_array($value) || $value instanceof \Traversable;
$key = str_replace('\\', '.', $class).'..'.$property.'..'.(int) $useAdderAndRemover;
if (isset($this->writePropertyCache[$key])) { if (isset($this->writePropertyCache[$key])) {
return $this->writePropertyCache[$key]; return $this->writePropertyCache[$key];
@ -607,6 +608,16 @@ class PropertyAccessor implements PropertyAccessorInterface
$camelized = $this->camelize($property); $camelized = $this->camelize($property);
$singulars = (array) Inflector::singularize($camelized); $singulars = (array) Inflector::singularize($camelized);
if ($useAdderAndRemover) {
$methods = $this->findAdderAndRemover($reflClass, $singulars);
if (null !== $methods) {
$access[self::ACCESS_TYPE] = self::ACCESS_TYPE_ADDER_AND_REMOVER;
$access[self::ACCESS_ADDER] = $methods[0];
$access[self::ACCESS_REMOVER] = $methods[1];
}
}
if (!isset($access[self::ACCESS_TYPE])) { if (!isset($access[self::ACCESS_TYPE])) {
$setter = 'set'.$camelized; $setter = 'set'.$camelized;
$getsetter = lcfirst($camelized); // jQuery style, e.g. read: last(), write: last($item) $getsetter = lcfirst($camelized); // jQuery style, e.g. read: last(), write: last($item)
@ -628,22 +639,16 @@ class PropertyAccessor implements PropertyAccessorInterface
$access[self::ACCESS_TYPE] = self::ACCESS_TYPE_MAGIC; $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_MAGIC;
$access[self::ACCESS_NAME] = $setter; $access[self::ACCESS_NAME] = $setter;
} elseif (null !== $methods = $this->findAdderAndRemover($reflClass, $singulars)) { } elseif (null !== $methods = $this->findAdderAndRemover($reflClass, $singulars)) {
if (\is_array($value) || $value instanceof \Traversable) { $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_NOT_FOUND;
$access[self::ACCESS_TYPE] = self::ACCESS_TYPE_ADDER_AND_REMOVER; $access[self::ACCESS_NAME] = sprintf(
$access[self::ACCESS_ADDER] = $methods[0]; 'The property "%s" in class "%s" can be defined with the methods "%s()" but '.
$access[self::ACCESS_REMOVER] = $methods[1]; 'the new value must be an array or an instance of \Traversable, '.
} else { '"%s" given.',
$access[self::ACCESS_TYPE] = self::ACCESS_TYPE_NOT_FOUND; $property,
$access[self::ACCESS_NAME] = sprintf( $reflClass->name,
'The property "%s" in class "%s" can be defined with the methods "%s()" but '. implode('()", "', $methods),
'the new value must be an array or an instance of \Traversable, '. \is_object($value) ? \get_class($value) : \gettype($value)
'"%s" given.', );
$property,
$reflClass->name,
implode('()", "', $methods),
\is_object($value) ? \get_class($value) : \gettype($value)
);
}
} else { } else {
$access[self::ACCESS_TYPE] = self::ACCESS_TYPE_NOT_FOUND; $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_NOT_FOUND;
$access[self::ACCESS_NAME] = sprintf( $access[self::ACCESS_NAME] = sprintf(
@ -680,6 +685,18 @@ class PropertyAccessor implements PropertyAccessorInterface
$access = $this->getWriteAccessInfo(\get_class($object), $property, array()); $access = $this->getWriteAccessInfo(\get_class($object), $property, array());
$isWritable = self::ACCESS_TYPE_METHOD === $access[self::ACCESS_TYPE]
|| self::ACCESS_TYPE_PROPERTY === $access[self::ACCESS_TYPE]
|| self::ACCESS_TYPE_ADDER_AND_REMOVER === $access[self::ACCESS_TYPE]
|| (!$access[self::ACCESS_HAS_PROPERTY] && property_exists($object, $property))
|| self::ACCESS_TYPE_MAGIC === $access[self::ACCESS_TYPE];
if ($isWritable) {
return true;
}
$access = $this->getWriteAccessInfo(\get_class($object), $property, '');
return self::ACCESS_TYPE_METHOD === $access[self::ACCESS_TYPE] return self::ACCESS_TYPE_METHOD === $access[self::ACCESS_TYPE]
|| self::ACCESS_TYPE_PROPERTY === $access[self::ACCESS_TYPE] || self::ACCESS_TYPE_PROPERTY === $access[self::ACCESS_TYPE]
|| self::ACCESS_TYPE_ADDER_AND_REMOVER === $access[self::ACCESS_TYPE] || self::ACCESS_TYPE_ADDER_AND_REMOVER === $access[self::ACCESS_TYPE]

View File

@ -708,7 +708,27 @@ class PropertyAccessorTest extends TestCase
$this->propertyAccessor->isWritable($object, 'emails'); //cache access info $this->propertyAccessor->isWritable($object, 'emails'); //cache access info
$this->propertyAccessor->setValue($object, 'emails', array('test@email.com')); $this->propertyAccessor->setValue($object, 'emails', array('test@email.com'));
self::assertEquals(array('test@email.com'), $object->getEmails()); $this->assertEquals(array('test@email.com'), $object->getEmails());
self::assertNull($object->getEmail()); $this->assertNull($object->getEmail());
}
public function testAdderAndRemoverArePreferredOverSetter()
{
$object = new TestPluralAdderRemoverAndSetter();
$this->propertyAccessor->isWritable($object, 'emails'); //cache access info
$this->propertyAccessor->setValue($object, 'emails', array('test@email.com'));
$this->assertEquals(array('test@email.com'), $object->getEmails());
}
public function testAdderAndRemoverArePreferredOverSetterForSameSingularAndPlural()
{
$object = new TestPluralAdderRemoverAndSetterSameSingularAndPlural();
$this->propertyAccessor->isWritable($object, 'aircraft'); //cache access info
$this->propertyAccessor->setValue($object, 'aircraft', array('aeroplane'));
$this->assertEquals(array('aeroplane'), $object->getAircraft());
} }
} }

View File

@ -0,0 +1,37 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\PropertyAccess\Tests;
class TestPluralAdderRemoverAndSetter
{
private $emails = array();
public function getEmails()
{
return $this->emails;
}
public function setEmails(array $emails)
{
$this->emails = array('foo@email.com');
}
public function addEmail($email)
{
$this->emails[] = $email;
}
public function removeEmail($email)
{
$this->emails = array_diff($this->emails, array($email));
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace Symfony\Component\PropertyAccess\Tests;
class TestPluralAdderRemoverAndSetterSameSingularAndPlural
{
private $aircraft = array();
public function getAircraft()
{
return $this->aircraft;
}
public function setAircraft(array $aircraft)
{
$this->aircraft = array('plane');
}
public function addAircraft($aircraft)
{
$this->aircraft[] = $aircraft;
}
public function removeAircraft($aircraft)
{
$this->aircraft = array_diff($this->aircraft, array($aircraft));
}
}

View File

@ -130,7 +130,7 @@ trait PhpMatcherTrait
continue; continue;
} }
if ('/' === $pathinfo || $hasTrailingSlash === ('/' === $pathinfo[-1])) { if ('/' === $pathinfo || (!$hasTrailingSlash ? '/' !== $pathinfo[-1] || !preg_match($regex, substr($pathinfo, 0, -1), $n) || $m !== (int) $n['MARK'] : '/' === $pathinfo[-1])) {
// no-op // no-op
} elseif ($this instanceof RedirectableUrlMatcherInterface) { } elseif ($this instanceof RedirectableUrlMatcherInterface) {
return null; return null;

View File

@ -160,8 +160,13 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
continue; continue;
} }
if ($supportsTrailingSlash && $hasTrailingSlash !== ('/' === $pathinfo[-1])) { if ($supportsTrailingSlash) {
return; if (!$hasTrailingSlash && '/' === $pathinfo[-1] && preg_match($regex, substr($pathinfo, 0, -1))) {
return;
}
if ($hasTrailingSlash && '/' !== $pathinfo[-1]) {
return;
}
} }
$hostMatches = array(); $hostMatches = array();

View File

@ -683,6 +683,15 @@ class UrlMatcherTest extends TestCase
$this->assertEquals('b', $matcher->match('/bar/abc.123')['_route']); $this->assertEquals('b', $matcher->match('/bar/abc.123')['_route']);
} }
public function testSlashVariant()
{
$coll = new RouteCollection();
$coll->add('a', new Route('/foo/{bar}', array(), array('bar' => '.*')));
$matcher = $this->getUrlMatcher($coll);
$this->assertEquals('a', $matcher->match('/foo/')['_route']);
}
protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null) protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
{ {
return new UrlMatcher($routes, $context ?: new RequestContext()); return new UrlMatcher($routes, $context ?: new RequestContext());