Fix #18590: Fix yii\web\UrlManager to instantiate cache only when it's actually needed

This commit is contained in:
Bizley
2021-04-10 12:02:23 +02:00
committed by GitHub
parent 5ad809e815
commit a6dba47963
3 changed files with 49 additions and 15 deletions

View File

@ -21,6 +21,7 @@ Yii Framework 2 Change Log
- Bug #18325: Fix `yii\db\pgsql\Schema` to respect non-default PgSQL schema name for data types (theonedemon, silverfire) - Bug #18325: Fix `yii\db\pgsql\Schema` to respect non-default PgSQL schema name for data types (theonedemon, silverfire)
- Bug #18593: Fix setting the `maxlength` attribute for `Html::activeInput()` and `Html::activeTextArea()` based on `length` parameter of validator (BSCheshir) - Bug #18593: Fix setting the `maxlength` attribute for `Html::activeInput()` and `Html::activeTextArea()` based on `length` parameter of validator (BSCheshir)
- Bug #18592: Fix `yii\db\Command::getRawSql()` to not replace query params in invalid places (sartor) - Bug #18592: Fix `yii\db\Command::getRawSql()` to not replace query params in invalid places (sartor)
- Bug #18590: Fix `yii\web\UrlManager` to instantiate cache only when it's actually needed (bizley)
2.0.41.1 March 04, 2021 2.0.41.1 March 04, 2021
----------------------- -----------------------

View File

@ -119,7 +119,7 @@ class UrlManager extends Component
*/ */
public $routeParam = 'r'; public $routeParam = 'r';
/** /**
* @var CacheInterface|array|string the cache object or the application component ID of the cache object. * @var CacheInterface|array|string|bool the cache object or the application component ID of the cache object.
* This can also be an array that is used to create a [[CacheInterface]] instance in case you do not want to use * This can also be an array that is used to create a [[CacheInterface]] instance in case you do not want to use
* an application component. * an application component.
* Compiled URL rules will be cached through this cache object, if it is available. * Compiled URL rules will be cached through this cache object, if it is available.
@ -185,17 +185,10 @@ class UrlManager extends Component
if (!$this->enablePrettyUrl) { if (!$this->enablePrettyUrl) {
return; return;
} }
if ($this->cache !== false && $this->cache !== null) {
try { if (!empty($this->rules)) {
$this->cache = Instance::ensure($this->cache, 'yii\caching\CacheInterface'); $this->rules = $this->buildRules($this->rules);
} catch (InvalidConfigException $e) {
Yii::warning('Unable to use cache for URL manager: ' . $e->getMessage());
}
} }
if (empty($this->rules)) {
return;
}
$this->rules = $this->buildRules($this->rules);
} }
/** /**
@ -263,6 +256,23 @@ class UrlManager extends Component
return $builtRules; return $builtRules;
} }
/**
* @return CacheInterface|null|bool
*/
private function ensureCache()
{
if (!$this->cache instanceof CacheInterface && $this->cache !== false && $this->cache !== null) {
try {
$this->cache = Instance::ensure($this->cache, 'yii\caching\CacheInterface');
} catch (InvalidConfigException $e) {
Yii::warning('Unable to use cache for URL manager: ' . $e->getMessage());
$this->cache = null;
}
}
return $this->cache;
}
/** /**
* Stores $builtRules to cache, using $rulesDeclaration as a part of cache key. * Stores $builtRules to cache, using $rulesDeclaration as a part of cache key.
* *
@ -274,11 +284,12 @@ class UrlManager extends Component
*/ */
protected function setBuiltRulesCache($ruleDeclarations, $builtRules) protected function setBuiltRulesCache($ruleDeclarations, $builtRules)
{ {
if (!$this->cache instanceof CacheInterface) { $cache = $this->ensureCache();
if (!$cache) {
return false; return false;
} }
return $this->cache->set([$this->cacheKey, $this->ruleConfig, $ruleDeclarations], $builtRules); return $cache->set([$this->cacheKey, $this->ruleConfig, $ruleDeclarations], $builtRules);
} }
/** /**
@ -292,11 +303,12 @@ class UrlManager extends Component
*/ */
protected function getBuiltRulesFromCache($ruleDeclarations) protected function getBuiltRulesFromCache($ruleDeclarations)
{ {
if (!$this->cache instanceof CacheInterface) { $cache = $this->ensureCache();
if (!$cache) {
return false; return false;
} }
return $this->cache->get([$this->cacheKey, $this->ruleConfig, $ruleDeclarations]); return $cache->get([$this->cacheKey, $this->ruleConfig, $ruleDeclarations]);
} }
/** /**

View File

@ -837,4 +837,25 @@ class UrlManagerCreateUrlTest extends TestCase
$this->assertInstanceOf(UrlRule::className(), $urlManager->rules[0]); $this->assertInstanceOf(UrlRule::className(), $urlManager->rules[0]);
$this->assertInstanceOf(CachedUrlRule::className(), $cachedUrlManager->rules[0]); $this->assertInstanceOf(CachedUrlRule::className(), $cachedUrlManager->rules[0]);
} }
public function testNotEnsuringCacheForEmptyRuleset()
{
$this->mockWebApplication([
'components' => [
'cache' => ArrayCache::className(),
],
]);
// no rules - don't ensure cache
$urlManager = $this->getUrlManager([
'cache' => 'cache',
'rules' => [],
]);
$this->assertSame('cache', $urlManager->cache);
// with rules - ensure cache
$urlManager = $this->getUrlManager([
'cache' => 'cache',
'rules' => ['/' => 'site/index'],
]);
$this->assertInstanceOf(ArrayCache::className(), $urlManager->cache);
}
} }