diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 82e580d..ec37189 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -32,6 +32,7 @@ Yii Framework 2 Change Log - Bug #9046: Fixed problem with endless error loop when an error occurred after sending a stream or file download response to the user (cebe) - Bug #9059: Fixed PHP Notice in error handler view (dynasource, andrewnester, samdark) - Bug #9063: Workaround for MySQL losing table case when adding index (sebathi) +- Bug #9091: `UrlManager::createUrl()` did not create correct url when defaults were used, internal cache is now skipped in certain situations (cebe) - Bug #9127, #9128: Fixed MSSQL `QueryBuilder::renameColumn()` and `QueryBuilder::renameTable()` escaping (sitawit) - Bug #9161: Fixed `yii\web\Request` ignore `queryParams` when resolve request (zetamen) - Bug: Fixed string comparison in `BaseActiveRecord::unlink()` which may result in wrong comparison result for hash valued primary keys starting with `0e` (cebe) diff --git a/framework/web/UrlManager.php b/framework/web/UrlManager.php index 49ccce0..3149efe 100644 --- a/framework/web/UrlManager.php +++ b/framework/web/UrlManager.php @@ -325,9 +325,16 @@ class UrlManager extends Component } if ($url === false) { + $cacheable = true; foreach ($this->rules as $rule) { + if (!empty($rule->defaults) && $rule->mode !== UrlRule::PARSING_ONLY) { + // if there is a rule with default values involved, the matching result may not be cached + $cacheable = false; + } if (($url = $rule->createUrl($this, $route, $params)) !== false) { - $this->_ruleCache[$cacheKey][] = $rule; + if ($cacheable) { + $this->_ruleCache[$cacheKey][] = $rule; + } break; } } diff --git a/tests/framework/web/UrlManagerTest.php b/tests/framework/web/UrlManagerTest.php index 4a2097d..d4bb5a1 100644 --- a/tests/framework/web/UrlManagerTest.php +++ b/tests/framework/web/UrlManagerTest.php @@ -125,6 +125,26 @@ class UrlManagerTest extends TestCase $this->assertEquals('http://en.example.com/test/post/1/sample+post', $url); $url = $manager->createUrl(['post/index', 'page' => 1]); $this->assertEquals('/test/post/index?page=1', $url); + + // create url with the same route but different params/defaults + $manager = new UrlManager([ + 'enablePrettyUrl' => true, + 'cache' => null, + 'rules' => [ + [ + 'pattern' => '', + 'route' => 'frontend/page/view', + 'defaults' => ['slug' => 'index'], + ], + 'page/' => 'frontend/page/view', + ], + 'baseUrl' => '/test', + 'scriptUrl' => '/test', + ]); + $url = $manager->createUrl(['frontend/page/view', 'slug' => 'services']); + $this->assertEquals('/test/page/services', $url); + $url = $manager->createUrl(['frontend/page/view', 'slug' => 'index']); + $this->assertEquals('/test/', $url); } /**