Skip to content

Commit

Permalink
Merge pull request #8182 from cakephp/issue-8163
Browse files Browse the repository at this point in the history
Fix setting the template from the action of a Cell.
  • Loading branch information
markstory committed Feb 6, 2016
2 parents 91ab4d4 + 9f8f1f3 commit 5adff0b
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 16 deletions.
24 changes: 12 additions & 12 deletions src/View/Cell.php
Expand Up @@ -176,14 +176,25 @@ public function render($template = null)
}

$render = function () use ($template) {
try {
$reflect = new ReflectionMethod($this, $this->action);
$reflect->invokeArgs($this, $this->args);
} catch (ReflectionException $e) {
throw new BadMethodCallException(sprintf(
'Class %s does not have a "%s" method.',
get_class($this),
$this->action
));
}

if ($template !== null &&
strpos($template, '/') === false &&
strpos($template, '.') === false
) {
$template = Inflector::underscore($template);
}
if ($template === null) {
$template = $this->template;
$template = $this->viewBuilder()->template() ?: $this->template;
}

$builder = $this->viewBuilder();
Expand All @@ -194,17 +205,6 @@ public function render($template = null)
$name = substr($className, 0, -4);
$builder->templatePath('Cell' . DS . $name);

try {
$reflect = new ReflectionMethod($this, $this->action);
$reflect->invokeArgs($this, $this->args);
} catch (ReflectionException $e) {
throw new BadMethodCallException(sprintf(
'Class %s does not have a "%s" method.',
get_class($this),
$this->action
));
}

$this->View = $this->createView();
try {
return $this->View->render($template);
Expand Down
77 changes: 73 additions & 4 deletions tests/TestCase/View/CellTest.php
Expand Up @@ -15,13 +15,9 @@
namespace Cake\Test\TestCase\View;

use Cake\Cache\Cache;
use Cake\Controller\Controller;
use Cake\Core\Configure;
use Cake\Core\Plugin;
use Cake\Event\EventManager;
use Cake\TestSuite\TestCase;
use Cake\View\Cell;
use Cake\View\CellTrait;
use TestApp\View\CustomJsonView;

/**
Expand Down Expand Up @@ -132,6 +128,33 @@ public function testDefaultCellAction()
$this->assertEquals('display', $pluginCell->template);
}

/**
* Tests that cell action setting the template using the property renders the correct template
*
* @return void
*/
public function testSettingCellTemplateFromAction()
{
$appCell = $this->View->cell('Articles::customTemplate');

$this->assertContains('This is the alternate template', "{$appCell}");
$this->assertEquals('alternate_teaser_list', $appCell->template);
$this->assertEquals('alternate_teaser_list', $appCell->viewBuilder()->template());
}

/**
* Tests that cell action setting the template using the ViewBuilder renders the correct template
*
* @return void
*/
public function testSettingCellTemplateFromActionViewBuilder()
{
$appCell = $this->View->cell('Articles::customTemplateViewBuilder');

$this->assertContains('This is the alternate template', "{$appCell}");
$this->assertEquals('alternate_teaser_list', $appCell->viewBuilder()->template());
}

/**
* Tests manual render() invocation.
*
Expand Down Expand Up @@ -361,4 +384,50 @@ public function testCachedRenderArrayConfig()
$this->assertEquals("dummy\n", $result);
Cache::drop('cell');
}

/**
* Test cached render when using an action changing the template used
*
* @return void
*/
public function testCachedRenderSimpleCustomTemplate()
{
$mock = $this->getMock('Cake\Cache\CacheEngine');
$mock->method('init')
->will($this->returnValue(true));
$mock->method('read')
->will($this->returnValue(false));
$mock->expects($this->once())
->method('write')
->with('cell_test_app_view_cell_articles_cell_customTemplate', "<h1>This is the alternate template</h1>\n");
Cache::config('default', $mock);

$cell = $this->View->cell('Articles::customTemplate', [], ['cache' => true]);
$result = $cell->render();
$this->assertContains('This is the alternate template', $result);

Cache::drop('default');
}

/**
* Test that when the cell cache is enabled, the cell action is only invoke the first
* time the cell is rendered
*
* @return void
*/
public function testCachedRenderSimpleCustomTemplateViewBuilder()
{
Cache::config('default', [
'className' => 'File',
'path' => CACHE,
]);
$cell = $this->View->cell('Articles::customTemplateViewBuilder', [], ['cache' => ['key' => 'celltest']]);
$result = $cell->render();
$this->assertEquals(1, $cell->counter);
$cell->render();
$this->assertEquals(1, $cell->counter);
$this->assertContains('This is the alternate template', $result);
Cache::delete('celltest');
Cache::drop('default');
}
}
@@ -0,0 +1 @@
<h1>This is the alternate template</h1>
31 changes: 31 additions & 0 deletions tests/test_app/TestApp/View/Cell/ArticlesCell.php
Expand Up @@ -27,6 +27,13 @@ class ArticlesCell extends \Cake\View\Cell
*/
protected $_validCellOptions = ['limit', 'page'];

/**
* Counter used to test the cache cell feature
*
* @return void
*/
public $counter = 0;

/**
* Default cell action.
*
Expand All @@ -51,6 +58,30 @@ public function teaserList()
]);
}

/**
* Renders a view using a different template than the action name
* The template is set using the ``Cell::$template`` property
*
* @return void
*/
public function customTemplate()
{
$this->template = 'alternate_teaser_list';
}

/**
* Renders a view using a different template than the action name
* The template is set using the ViewBuilder bound to the Cell
*
* @return void
*/
public function customTemplateViewBuilder()
{
$this->template = 'derp';
$this->counter++;
$this->viewBuilder()->template('alternate_teaser_list');
}

/**
* Simple echo.
*
Expand Down

0 comments on commit 5adff0b

Please sign in to comment.