Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Routing] Deprecate RouteCollection overriding its routes' properties #60343

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions UPGRADE-7.4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
UPGRADE FROM 7.3 to 7.4
=======================

Symfony 7.4 is a minor release. According to the Symfony release process, there should be no significant
backward compatibility breaks. Minor backward compatibility breaks are prefixed in this document with
`[BC BREAK]`, make sure your code is compatible with these entries before upgrading.
Read more about this in the [Symfony documentation](https://symfony.com/doc/7.4/setup/upgrade_minor.html).

If you're upgrading from a version below 7.3, follow the [7.3 upgrade guide](UPGRADE-7.3.md) first.

Routing
-------

* Deprecate `RouteCollection` overriding its routes' properties
2 changes: 1 addition & 1 deletion src/Symfony/Component/Console/Debug/CliRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function __construct(
public readonly TraceableCommand $command,
) {
parent::__construct(
attributes: ['_controller' => \get_class($command->command), '_virtual_type' => 'command'],
attributes: ['_controller' => $command->command::class, '_virtual_type' => 'command'],
server: $_SERVER,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public function testProcessValue()
$this->assertSame(CustomDefinition::class, $locator('bar')::class);
$this->assertSame(CustomDefinition::class, $locator('baz')::class);
$this->assertSame(CustomDefinition::class, $locator('some.service')::class);
$this->assertSame(CustomDefinition::class, \get_class($locator('inlines.service')));
$this->assertSame(CustomDefinition::class, $locator('inlines.service')::class);
}

public function testServiceWithKeyOverwritesPreviousInheritedKey()
Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Component/Routing/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
CHANGELOG
=========

7.4
---

* Deprecate `RouteCollection` overriding its routes' properties

7.3
---

Expand Down
63 changes: 52 additions & 11 deletions src/Symfony/Component/Routing/RouteCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -242,10 +242,15 @@ public function addNamePrefix(string $prefix): void
public function setHost(?string $pattern, array $defaults = [], array $requirements = []): void
{
foreach ($this->routes as $route) {
if ('' !== $route->getHost() && $route->getHost() !== $pattern) {
trigger_deprecation('symfony/routing', '7.3', 'Overriding a route\'s host with its group\'s is deprecated, you should remove it from the route.');
}

$route->setHost($pattern);
$route->addDefaults($defaults);
$route->addRequirements($requirements);
}

$this->addDefaults($defaults);
$this->addRequirements($requirements);
}

/**
Expand All @@ -256,6 +261,10 @@ public function setHost(?string $pattern, array $defaults = [], array $requireme
public function setCondition(?string $condition): void
{
foreach ($this->routes as $route) {
if ('' !== $route->getCondition() && $route->getCondition() !== $condition) {
trigger_deprecation('symfony/routing', '7.3', 'Overriding a route\'s condition with its group\'s is deprecated, you should remove it from the route.');
}

$route->setCondition($condition);
}
}
Expand All @@ -267,10 +276,18 @@ public function setCondition(?string $condition): void
*/
public function addDefaults(array $defaults): void
{
if ($defaults) {
foreach ($this->routes as $route) {
$route->addDefaults($defaults);
if (!$defaults) {
return;
}

foreach ($this->routes as $route) {
foreach ($defaults as $name => $value) {
if ($route->hasDefault($name) && $route->getDefault($name) !== $value) {
trigger_deprecation('symfony/routing', '7.3', 'Overriding a route\'s default with its group\'s is deprecated, you should remove it from the route.');
}
}

$route->addDefaults($defaults);
}
}

Expand All @@ -281,10 +298,18 @@ public function addDefaults(array $defaults): void
*/
public function addRequirements(array $requirements): void
{
if ($requirements) {
foreach ($this->routes as $route) {
$route->addRequirements($requirements);
if (!$requirements) {
return;
}

foreach ($this->routes as $route) {
foreach ($requirements as $key => $regex) {
if ($route->hasRequirement($key) && $route->getRequirement($key) !== $regex) {
trigger_deprecation('symfony/routing', '7.3', 'Overriding a route\'s requirement with its group\'s is deprecated, you should remove it from the route.');
}
}

$route->addRequirements($requirements);
}
}

Expand All @@ -295,10 +320,18 @@ public function addRequirements(array $requirements): void
*/
public function addOptions(array $options): void
{
if ($options) {
foreach ($this->routes as $route) {
$route->addOptions($options);
if (!$options) {
return;
}

foreach ($this->routes as $route) {
foreach ($options as $name => $value) {
if ($route->hasOption($name) && $route->getOption($name) !== $value) {
trigger_deprecation('symfony/routing', '7.3', 'Overriding a route\'s option with its group\'s is deprecated, you should remove it from the route.');
}
}

$route->addOptions($options);
}
}

Expand All @@ -310,6 +343,10 @@ public function addOptions(array $options): void
public function setSchemes(string|array $schemes): void
{
foreach ($this->routes as $route) {
if ($route->getSchemes() !== [] && $route->getSchemes() != (array) $schemes) {
trigger_deprecation('symfony/routing', '7.3', 'Overriding a route\'s schemes with its group\'s is deprecated, you should remove it from the route.');
}

$route->setSchemes($schemes);
}
}
Expand All @@ -322,6 +359,10 @@ public function setSchemes(string|array $schemes): void
public function setMethods(string|array $methods): void
{
foreach ($this->routes as $route) {
if ($route->getMethods() !== [] && $route->getMethods() != (array) $methods) {
trigger_deprecation('symfony/routing', '7.3', 'Overriding a route\'s methods with its group\'s is deprecated, you should remove it from the route.');
}

$route->setMethods($methods);
}
}
Expand Down
148 changes: 118 additions & 30 deletions src/Symfony/Component/Routing/Tests/RouteCollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@
namespace Symfony\Component\Routing\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Bridge\PhpUnit\ExpectUserDeprecationMessageTrait;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

class RouteCollectionTest extends TestCase
{
use ExpectUserDeprecationMessageTrait;

public function testRoute()
{
$collection = new RouteCollection();
Expand Down Expand Up @@ -115,27 +118,65 @@ public function testAddCollectionWithResources()
public function testAddDefaultsAndRequirementsAndOptions()
{
$collection = new RouteCollection();
$collection->add('foo', new Route('/{placeholder}'));
$collection1 = new RouteCollection();
$collection1->add('bar', new Route('/{placeholder}',
['_controller' => 'fixed', 'placeholder' => 'default'], ['placeholder' => '.+'], ['option' => 'value'])
);
$collection1->add('foo', new Route('/{placeholder}'));
$collection->addCollection($collection1);

$collection->addDefaults(['placeholder' => 'new-default']);
$this->assertEquals(['placeholder' => 'new-default'], $collection->get('foo')->getDefaults(), '->addDefaults() adds defaults to all routes');
$this->assertEquals(['_controller' => 'fixed', 'placeholder' => 'new-default'], $collection->get('bar')->getDefaults(),
'->addDefaults() adds defaults to all routes and overwrites existing ones');

$collection->addRequirements(['placeholder' => '\d+']);
$this->assertEquals(['placeholder' => '\d+'], $collection->get('foo')->getRequirements(), '->addRequirements() adds requirements to all routes');
$this->assertEquals(['placeholder' => '\d+'], $collection->get('bar')->getRequirements(),
'->addRequirements() adds requirements to all routes and overwrites existing ones');

$collection->addOptions(['option' => 'new-value']);
$this->assertEquals(
['option' => 'new-value', 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler'],
$collection->get('bar')->getOptions(), '->addOptions() adds options to all routes and overwrites existing ones'
$collection->get('foo')->getOptions(), '->addOptions() adds options to all routes'
);
}

/**
* @group legacy
*/
public function testCollectionOverridingDefaultsIsDeprecated()
{
$collection = new RouteCollection();
$collection->add('foo', new Route('/{placeholder}', ['placeholder' => 'default']));

$this->expectUserDeprecationMessage('Since symfony/routing 7.3: Overriding a route\'s default with its group\'s is deprecated, you should remove it from the route.');
$collection->addDefaults(['placeholder' => 'new-default']);

$this->assertEquals(['placeholder' => 'new-default'], $collection->get('foo')->getDefaults());
}

/**
* @group legacy
*/
public function testCollectionOverridingRequirementsIsDeprecated()
{
$collection = new RouteCollection();
$collection->add('foo', new Route('/{placeholder}', requirements: ['placeholder' => '.+']));

$this->expectUserDeprecationMessage('Since symfony/routing 7.3: Overriding a route\'s requirement with its group\'s is deprecated, you should remove it from the route.');
$collection->addRequirements(['placeholder' => '\d+']);

$this->assertEquals(['placeholder' => '\d+'], $collection->get('foo')->getRequirements());
}

/**
* @group legacy
*/
public function testCollectionOverridingOptionsIsDeprecated()
{
$collection = new RouteCollection();
$collection->add('foo', new Route('/{placeholder}', options: ['option' => 'value']));

$this->expectUserDeprecationMessage('Since symfony/routing 7.3: Overriding a route\'s option with its group\'s is deprecated, you should remove it from the route.');
$collection->addOptions(['option' => 'new-value']);

$this->assertEquals(
['option' => 'new-value', 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler'],
$collection->get('foo')->getOptions()
);
}

Expand Down Expand Up @@ -240,29 +281,52 @@ public function testRemove()
public function testSetHost()
{
$collection = new RouteCollection();
$routea = new Route('/a');
$routeb = new Route('/b', [], [], [], '{locale}.example.net');
$collection->add('a', $routea);
$collection->add('b', $routeb);
$route = new Route('/a');
$collection->add('a', $route);

$collection->setHost('{locale}.example.com');

$this->assertEquals('{locale}.example.com', $routea->getHost());
$this->assertEquals('{locale}.example.com', $routeb->getHost());
$this->assertEquals('{locale}.example.com', $route->getHost());
}

/**
* @group legacy
*/
public function testCollectionOverridingHostIsDeprecated()
{
$collection = new RouteCollection();
$route = new Route('/a', [], [], [], '{locale}.example.net');
$collection->add('a', $route);

$this->expectUserDeprecationMessage('Since symfony/routing 7.3: Overriding a route\'s host with its group\'s is deprecated, you should remove it from the route.');
$collection->setHost('{locale}.example.com');

$this->assertEquals('{locale}.example.com', $route->getHost());
}

public function testSetCondition()
{
$collection = new RouteCollection();
$routea = new Route('/a');
$routeb = new Route('/b', [], [], [], '{locale}.example.net', [], [], 'context.getMethod() == "GET"');
$collection->add('a', $routea);
$collection->add('b', $routeb);

$collection->setCondition('context.getMethod() == "POST"');

$this->assertEquals('context.getMethod() == "POST"', $routea->getCondition());
$this->assertEquals('context.getMethod() == "POST"', $routeb->getCondition());
}

/**
* @group legacy
*/
public function testCollectionOverridingConditionsIsDeprecated()
{
$collection = new RouteCollection();
$collection->add('foo', new Route('/{placeholder}', condition: 'condition'));

$this->expectUserDeprecationMessage('Since symfony/routing 7.3: Overriding a route\'s condition with its group\'s is deprecated, you should remove it from the route.');
$collection->setCondition(null);

$this->assertEquals('', $collection->get('foo')->getCondition());
}

public function testClone()
Expand All @@ -283,29 +347,53 @@ public function testClone()
public function testSetSchemes()
{
$collection = new RouteCollection();
$routea = new Route('/a', [], [], [], '', 'http');
$routeb = new Route('/b');
$collection->add('a', $routea);
$collection->add('b', $routeb);
$route = new Route('/a');
$collection->add('a', $route);

$collection->setSchemes(['http', 'https']);

$this->assertEquals(['http', 'https'], $route->getSchemes());
}

/**
* @group legacy
*/
public function testCollectionOverridingSchemesIsDeprecated()
{
$collection = new RouteCollection();
$route = new Route('/a', [], [], [], '', 'http');
$collection->add('a', $route);

$this->expectUserDeprecationMessage('Since symfony/routing 7.3: Overriding a route\'s schemes with its group\'s is deprecated, you should remove it from the route.');
$collection->setSchemes(['http', 'https']);

$this->assertEquals(['http', 'https'], $routea->getSchemes());
$this->assertEquals(['http', 'https'], $routeb->getSchemes());
$this->assertEquals(['http', 'https'], $route->getSchemes());
}

public function testSetMethods()
{
$collection = new RouteCollection();
$routea = new Route('/a', [], [], [], '', [], ['GET', 'POST']);
$routeb = new Route('/b');
$collection->add('a', $routea);
$collection->add('b', $routeb);
$route = new Route('/a');
$collection->add('a', $route);

$collection->setMethods('PUT');

$this->assertEquals(['PUT'], $route->getMethods());
}

/**
* @group legacy
*/
public function testCollectionOverridingMethodsIsDeprecated()
{
$collection = new RouteCollection();
$route = new Route('/a', [], [], [], '', [], ['GET', 'POST']);
$collection->add('a', $route);

$this->expectUserDeprecationMessage('Since symfony/routing 7.3: Overriding a route\'s methods with its group\'s is deprecated, you should remove it from the route.');
$collection->setMethods('PUT');

$this->assertEquals(['PUT'], $routea->getMethods());
$this->assertEquals(['PUT'], $routeb->getMethods());
$this->assertEquals(['PUT'], $route->getMethods());
}

public function testAddNamePrefix()
Expand Down
Loading