Merge paths and vars when calling widget handler

When an AJAX handler is called for a widget, the view paths and specified variables should be merged in to the controller. This sets the appropriate context:

1) Look at the widget first
2) Fall back to the controller

Fixes #2432
This commit is contained in:
Samuel Georges 2016-11-02 08:50:15 +11:00
parent ced920e5d2
commit 0aadcc6675
2 changed files with 40 additions and 9 deletions

View File

@ -512,7 +512,7 @@ class Controller extends Extendable
}
if (($widget = $this->widget->{$widgetName}) && $widget->methodExists($handlerName)) {
$result = call_user_func_array([$widget, $handlerName], $this->params);
$result = $this->runAjaxHandlerForWidget($widget, $handlerName);
return ($result) ?: true;
}
}
@ -543,7 +543,7 @@ class Controller extends Extendable
foreach ((array) $this->widget as $widget) {
if ($widget->methodExists($handler)) {
$result = call_user_func_array([$widget, $handler], $this->params);
$result = $this->runAjaxHandlerForWidget($widget, $handlerName);
return ($result) ?: true;
}
}
@ -552,6 +552,22 @@ class Controller extends Extendable
return false;
}
/**
* Specific code for executing an AJAX handler for a widget.
* This will append the widget view paths to the controller and merge the vars.
* @return mixed
*/
protected function runAjaxHandlerForWidget($widget, $handler)
{
$this->addViewPath($widget->getViewPaths());
$result = call_user_func_array([$widget, $handler], $this->params);
$this->vars = $widget->vars + $this->vars;
return $result;
}
/**
* Returns the controllers public actions.
*/

View File

@ -25,7 +25,7 @@ trait ViewMaker
public $vars = [];
/**
* @var string Specifies a path to the views directory.
* @var string|array Specifies a path to the views directory.
*/
protected $viewPath;
@ -45,14 +45,29 @@ trait ViewMaker
public $suppressLayout = false;
/**
* Prepends a path on the available view locations.
* @param string $path
* Prepends a path on the available view path locations.
* @param string|array $path
* @return void
*/
public function addViewPath($path)
{
$this->viewPath = (array) $this->viewPath;
array_unshift($this->viewPath, $path);
if (is_array($path)) {
$this->viewPath = array_merge($path, $this->viewPath);
}
else {
array_unshift($this->viewPath, $path);
}
}
/**
* Returns the active view path locations.
* @return array
*/
public function getViewPaths()
{
return (array) $this->viewPath;
}
/**
@ -160,9 +175,9 @@ trait ViewMaker
}
/**
* Locates a file based on it's definition. If the file starts with
* an "at symbol", it will be returned in context of the application base path,
* otherwise it will be returned in context of the view path.
* Locates a file based on its definition. The file name can be prefixed with a
* symbol (~|$) to return in context of the application or plugin base path,
* otherwise it will be returned in context of this object view path.
* @param string $fileName File to load.
* @param mixed $viewPath Explicitly define a view path.
* @return string Full path to the view file.