Browse Source

Invoke cell action just before rendering.

This is a step towards avoiding running the cell action when cached cell
is available.
ADmad 10 years ago
parent
commit
9e50e93861
3 changed files with 34 additions and 13 deletions
  1. 29 0
      src/View/Cell.php
  2. 3 12
      src/View/CellTrait.php
  3. 2 1
      tests/TestCase/View/CellTest.php

+ 29 - 0
src/View/Cell.php

@@ -14,6 +14,7 @@
  */
 namespace Cake\View;
 
+use BadMethodCallException;
 use Cake\Datasource\ModelAwareTrait;
 use Cake\Event\EventDispatcherTrait;
 use Cake\Event\EventManager;
@@ -24,6 +25,8 @@ use Cake\Utility\Inflector;
 use Cake\View\Exception\MissingCellViewException;
 use Cake\View\Exception\MissingTemplateException;
 use Exception;
+use ReflectionException;
+use ReflectionMethod;
 
 /**
  * Cell base.
@@ -87,6 +90,20 @@ abstract class Cell
     public $helpers = [];
 
     /**
+     * The cell's action to invoke.
+     *
+     * @var string
+     */
+    public $action;
+
+    /**
+     * Arguments to pass to cell's action.
+     *
+     * @var array
+     */
+    public $args = [];
+
+    /**
      * These properties can be set directly on Cell and passed to the View as options.
      *
      * @var array
@@ -131,6 +148,7 @@ abstract class Cell
         $this->response = $response;
         $this->modelFactory('Table', [$this->tableLocator(), 'get']);
 
+        $this->_validCellOptions = array_merge(['action', 'args'], $this->_validCellOptions);
         foreach ($this->_validCellOptions as $var) {
             if (isset($cellOptions[$var])) {
                 $this->{$var} = $cellOptions[$var];
@@ -151,6 +169,17 @@ abstract class Cell
      */
     public function render($template = null)
     {
+        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

+ 3 - 12
src/View/CellTrait.php

@@ -75,22 +75,13 @@ trait CellTrait
             throw new Exception\MissingCellException(['className' => $pluginAndCell . 'Cell']);
         }
 
-        $cell = $this->_createCell($className, $action, $plugin, $options);
         if (!empty($data)) {
             $data = array_values($data);
         }
+        $options = ['action' => $action, 'args' => $data] + $options;
+        $cell = $this->_createCell($className, $action, $plugin, $options);
 
-        try {
-            $reflect = new ReflectionMethod($cell, $action);
-            $reflect->invokeArgs($cell, $data);
-            return $cell;
-        } catch (ReflectionException $e) {
-            throw new BadMethodCallException(sprintf(
-                'Class %s does not have a "%s" method.',
-                $className,
-                $action
-            ));
-        }
+        return $cell;
     }
 
     /**

+ 2 - 1
tests/TestCase/View/CellTest.php

@@ -250,7 +250,8 @@ class CellTest extends TestCase
      */
     public function testCellMissingMethod()
     {
-        $this->View->cell('Articles::nope');
+        $cell = $this->View->cell('Articles::nope');
+        $cell->render();
     }
 
     /**