diff --git a/src/FuzeWorks/Event/RouterCallViewEvent.php b/src/FuzeWorks/Event/RouterCallViewEvent.php index 47c1159..8cb6679 100644 --- a/src/FuzeWorks/Event/RouterCallViewEvent.php +++ b/src/FuzeWorks/Event/RouterCallViewEvent.php @@ -38,6 +38,7 @@ namespace FuzeWorks\Event; use FuzeWorks\Controller; use FuzeWorks\Event; +use FuzeWorks\Priority; use FuzeWorks\View; /** @@ -58,9 +59,9 @@ class RouterCallViewEvent extends Event /** * The function that will be loaded in the view * - * @var string + * @var array */ - public $viewMethod; + public $viewMethods; /** * The parameters that will be provided to the function in the view @@ -90,12 +91,27 @@ class RouterCallViewEvent extends Event */ public $controller; - public function init(View $view, Controller $controller, string $viewMethod, string $viewParameters, string $route) + public function init(View $view, Controller $controller, array $viewMethods, string $viewParameters, string $route) { $this->view = $view; $this->controller = $controller; - $this->viewMethod = $viewMethod; + $this->viewMethods = $viewMethods; $this->viewParameters = $viewParameters; $this->route = $route; } + + /** + * Add a method which should be tried upon calling the view + * + * @param string $method + * @param int $priority + */ + public function addMethod(string $method, int $priority = Priority::NORMAL) + { + if (!isset($this->viewMethods[$priority])) + $this->viewMethods[$priority] = []; + + if (!isset($this->viewMethods[$priority][$method])) + $this->viewMethods[$priority][] = $method; + } } \ No newline at end of file diff --git a/src/FuzeWorks/Event/RouterLoadViewAndControllerEvent.php b/src/FuzeWorks/Event/RouterLoadViewAndControllerEvent.php index d072c33..dcb9c82 100644 --- a/src/FuzeWorks/Event/RouterLoadViewAndControllerEvent.php +++ b/src/FuzeWorks/Event/RouterLoadViewAndControllerEvent.php @@ -37,6 +37,7 @@ namespace FuzeWorks\Event; use FuzeWorks\Controller; use FuzeWorks\Event; +use FuzeWorks\Priority; /** * Event that gets fired when a view and controller are loaded. @@ -67,9 +68,9 @@ class RouterLoadViewAndControllerEvent extends Event /** * The function that will be loaded in the view * - * @var string + * @var array */ - public $viewMethod; + public $viewMethods; /** * The parameters that will be provided to the function in the view @@ -92,15 +93,30 @@ class RouterLoadViewAndControllerEvent extends Event */ public $controller; - public function init(string $viewName, string $viewType, string $viewMethod, string $viewParameters, string $route) + public function init(string $viewName, string $viewType, array $viewMethods, string $viewParameters, string $route) { $this->viewName = $viewName; $this->viewType = $viewType; - $this->viewMethod = $viewMethod; + $this->viewMethods = $viewMethods; $this->viewParameters = $viewParameters; $this->route = $route; } + /** + * Add a method which should be tried upon calling the view + * + * @param string $method + * @param int $priority + */ + public function addMethod(string $method, int $priority = Priority::NORMAL) + { + if (!isset($this->viewMethods[$priority])) + $this->viewMethods[$priority] = []; + + if (!isset($this->viewMethods[$priority][$method])) + $this->viewMethods[$priority][] = $method; + } + /** * Override the controller to be provided to the view. * diff --git a/src/FuzeWorks/Router.php b/src/FuzeWorks/Router.php index ff6d77f..cc32824 100644 --- a/src/FuzeWorks/Router.php +++ b/src/FuzeWorks/Router.php @@ -325,7 +325,8 @@ class Router $event = Events::fireEvent('routerLoadViewAndControllerEvent', $viewName, $viewType, - $viewMethod, + // ViewMethod is provided as a Priority::NORMAL method + [3 => [$viewMethod]], $viewParameters, $route ); @@ -363,7 +364,7 @@ class Router $event = Events::fireEvent('routerCallViewEvent', $this->view, $this->controller, - $event->viewMethod, + $event->viewMethods, $event->viewParameters, $event->route ); @@ -383,21 +384,27 @@ class Router if (isset($this->view->halt)) throw new HaltException("Will not load view. Cancelled by 'halt' attribute in view."); - // Check if requested function or magic method exists in view - if (method_exists($this->view, $event->viewMethod) || method_exists($this->view, '__call')) - { - // Execute the function on the view - Logger::newLevel("Calling method '{$event->viewMethod}' on " . get_class($this->view) . ' with ' . get_class($this->controller)); - $output = $this->view->{$event->viewMethod}($event->viewParameters); - Logger::stopLevel(); - return $output; - } - else - { - Logger::logError("Could not load view. View does not have method '".$event->viewMethod."'"); + // Cycle over every viewMethod until a valid one is found + for ($i=Priority::getHighestPriority(); $i<=Priority::getLowestPriority(); $i++) { + if (!isset($event->viewMethods[$i])) + continue; + + foreach ($event->viewMethods[$i] as $method) { + if (method_exists($this->view, $method)) + { + // Execute this method on the view + Logger::newLevel("Calling method '{$method}' on " . get_class($this->view) . ' with ' . get_class($this->controller)); + $output = $this->view->{$method}($event->viewParameters); + Logger::stopLevel(); + return $output; + } + } } - // View could not be found + // Otherwise log an error + Logger::logError("Could not load view. View does not have any of the provided methods."); + + // View could not be found. return false; } diff --git a/test/mcr/RouterTest.php b/test/mcr/RouterTest.php index a57f5ea..de9fe7a 100644 --- a/test/mcr/RouterTest.php +++ b/test/mcr/RouterTest.php @@ -331,7 +331,7 @@ class RouterTest extends MVCRTestAbstract $this->assertInstanceOf('\FuzeWorks\Event\RouterLoadViewAndControllerEvent', $event); $this->assertEquals('TestDefaultCallable', $event->viewName); $this->assertEquals('test', $event->viewType); - $this->assertEquals('missing', $event->viewMethod); + $this->assertEquals([3=>['missing']], $event->viewMethods); $event->setCancelled(true); }, 'routerLoadViewAndControllerEvent'); @@ -365,6 +365,32 @@ class RouterTest extends MVCRTestAbstract $this->assertEquals($mockController, $this->router->getCurrentController()); } + /** + * @depends testDefaultCallableReplaceController + * @covers ::defaultCallable + * @covers \FuzeWorks\Event\RouterLoadViewAndControllerEvent::addMethod + */ + public function testDefaultCallableAddMethod() + { + $matches = [ + 'viewName' => 'TestDefaultCallableChangeMethod', + 'viewType' => 'test', + 'viewMethod' => 'index' + ]; + + $this->assertNull($this->router->getCurrentController()); + $this->assertNull($this->router->getCurrentView()); + + $mockController = $this->getMockBuilder('\FuzeWorks\Controller')->getMock(); + // Create listener + Events::addListener(function($event, $mockController){ + $event->overrideController($mockController); + $event->addMethod('altered', Priority::HIGH); + }, 'routerLoadViewAndControllerEvent', Priority::NORMAL, $mockController); + + $this->assertEquals('Altered!', $this->router->defaultCallable($matches, '.*$')); + } + /* route() ------------------------------------------------------------ */ /** diff --git a/test/views/view.test.testdefaultcallablechangemethod.php b/test/views/view.test.testdefaultcallablechangemethod.php new file mode 100644 index 0000000..3533d0e --- /dev/null +++ b/test/views/view.test.testdefaultcallablechangemethod.php @@ -0,0 +1,52 @@ +