Skip to content

Commit

Permalink
Fixes yiisoft#13560: Refactored `\yii\widgets\FragmentCache::getCache…
Browse files Browse the repository at this point in the history
…dContent()`, added tests
  • Loading branch information
Kolyunya authored and samdark committed Apr 1, 2017
1 parent 43edf24 commit 892512f
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 20 deletions.
1 change: 1 addition & 0 deletions framework/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ Yii Framework 2 Change Log
- Enh #13376: Data provider now automatically sets an ID so there is no need to set it manually in case multiple data providers are used with pagination (SamMousa)
- Enh #13369: Added ability to render current `yii\widgets\LinkPager` page disabled (aquy)
- Enh #13837: Refactored masking of CSRF tokens (sammousa)
- Enh #13560: Refactored `\yii\widgets\FragmentCache::getCachedContent()`, added tests (Kolyunya)

2.0.11.2 February 08, 2017
--------------------------
Expand Down
46 changes: 27 additions & 19 deletions framework/widgets/FragmentCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,25 +134,33 @@ public function run()
*/
public function getCachedContent()
{
if ($this->_content === null) {
$this->_content = false;
if ($this->cache instanceof Cache) {
$key = $this->calculateKey();
$data = $this->cache->get($key);
if (is_array($data) && count($data) === 2) {
list ($content, $placeholders) = $data;
if (is_array($placeholders) && count($placeholders) > 0) {
if (empty($this->getView()->cacheStack)) {
// outermost cache: replace placeholder with dynamic content
$content = $this->updateDynamicContent($content, $placeholders);
}
foreach ($placeholders as $name => $statements) {
$this->getView()->addDynamicPlaceholder($name, $statements);
}
}
$this->_content = $content;
}
}
if ($this->_content !== null) {
return $this->_content;
}

$this->_content = false;

if (!($this->cache instanceof Cache)) {
return $this->_content;
}

$key = $this->calculateKey();
$data = $this->cache->get($key);
if (!is_array($data) || count($data) !== 2) {
return $this->_content;
}

list ($this->_content, $placeholders) = $data;
if (!is_array($placeholders) || count($placeholders) === 0) {
return $this->_content;
}

if (empty($this->getView()->cacheStack)) {
// outermost cache: replace placeholder with dynamic content
$this->_content = $this->updateDynamicContent($this->_content, $placeholders);
}
foreach ($placeholders as $name => $statements) {
$this->getView()->addDynamicPlaceholder($name, $statements);
}

return $this->_content;
Expand Down
104 changes: 103 additions & 1 deletion tests/framework/widgets/FragmentCacheTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use Yii;
use yii\caching\ArrayCache;
use yii\base\View;
use yii\widgets\Breadcrumbs;

/**
* @group widgets
Expand Down Expand Up @@ -86,6 +85,109 @@ public function testCacheDisabled2()
$this->assertEquals($expectedLevel, ob_get_level(), 'Output buffer not closed correctly.');
}

public function testSingleDynamicFragment()
{
Yii::$app->params['counter'] = 0;

$view = new View();

for ($counter = 0; $counter < 42; $counter++) {
ob_start();
ob_implicit_flush(false);

$cacheUnavailable = $view->beginCache('test');

if ($counter === 0) {
$this->assertTrue($cacheUnavailable);
} else {
$this->assertFalse($cacheUnavailable);
}

if ($cacheUnavailable) {
echo 'single dynamic cached fragment: ';
echo $view->renderDynamic('return \Yii::$app->params["counter"]++;');
$view->endCache();
}

$expectedContent = vsprintf('single dynamic cached fragment: %d', [
$counter,
]);
$this->assertEquals($expectedContent, ob_get_clean());
}
}

public function testMultipleDynamicFragments()
{
Yii::$app->params['counter'] = 0;

$view = new View();

for ($counter = 0; $counter < 42; $counter++) {
ob_start();
ob_implicit_flush(false);

$cacheUnavailable = $view->beginCache('test');

if ($counter === 0) {
$this->assertTrue($cacheUnavailable);
} else {
$this->assertFalse($cacheUnavailable);
}

if ($cacheUnavailable) {
echo 'multiple dynamic cached fragments: ';
echo $view->renderDynamic('return md5(\Yii::$app->params["counter"]);');
echo $view->renderDynamic('return \Yii::$app->params["counter"]++;');
$view->endCache();
}

$expectedContent = vsprintf('multiple dynamic cached fragments: %s%d', [
md5($counter),
$counter,
]);
$this->assertEquals($expectedContent, ob_get_clean());
}
}

public function testNestedDynamicFragments()
{
Yii::$app->params['counter'] = 0;

$view = new View();

for ($counter = 0; $counter < 42; $counter++) {
ob_start();
ob_implicit_flush(false);

$cacheUnavailable = $view->beginCache('test');

if ($counter === 0) {
$this->assertTrue($cacheUnavailable);
} else {
$this->assertFalse($cacheUnavailable);
}

if ($cacheUnavailable) {
echo 'nested dynamic cached fragments: ';
echo $view->renderDynamic('return md5(\Yii::$app->params["counter"]);');

if ($view->beginCache('test-nested')) {
echo $view->renderDynamic('return sha1(\Yii::$app->params["counter"]);');
$view->endCache();
}

echo $view->renderDynamic('return \Yii::$app->params["counter"]++;');
$view->endCache();
}

$expectedContent = vsprintf('nested dynamic cached fragments: %s%s%d', [
md5($counter),
sha1($counter),
$counter,
]);
$this->assertEquals($expectedContent, ob_get_clean());
}
}

// TODO test dynamic replacements
}

0 comments on commit 892512f

Please sign in to comment.