2013-05-07 10:56:38 +02:00
|
|
|
<?php
|
|
|
|
|
2017-12-19 02:20:20 +01:00
|
|
|
namespace SilverStripe\Widgets\Model;
|
2017-01-17 23:43:11 +01:00
|
|
|
|
|
|
|
use SilverStripe\Admin\LeftAndMain;
|
|
|
|
use SilverStripe\Control\Controller;
|
|
|
|
use SilverStripe\Control\Director;
|
|
|
|
use SilverStripe\Core\ClassInfo;
|
|
|
|
|
2013-05-07 10:56:38 +02:00
|
|
|
/**
|
2017-01-25 14:29:00 +01:00
|
|
|
* Optional controller for every widget which has its own logic, e.g. in forms.
|
2013-05-07 10:56:38 +02:00
|
|
|
*
|
2017-01-25 14:29:00 +01:00
|
|
|
* It always handles a single widget, usually passed in as a database
|
|
|
|
* identifier through the controller URL. Needs to be constructed as a nested
|
2013-05-07 10:56:38 +02:00
|
|
|
* controller within a {@link ContentController}.
|
2017-01-25 14:29:00 +01:00
|
|
|
*
|
2013-05-07 10:56:38 +02:00
|
|
|
* ## Forms
|
2017-01-25 14:29:00 +01:00
|
|
|
* You can add forms like in any other SilverStripe controller. If you need
|
|
|
|
* access to the widget from within a form, you can use
|
2013-05-07 10:56:38 +02:00
|
|
|
* `$this->controller->getWidget()` inside the form logic.
|
|
|
|
*
|
|
|
|
* Note: Widget controllers currently only work on {@link Page} objects,
|
|
|
|
* because the logic is implemented in {@link ContentController->handleWidget()}.
|
|
|
|
* Copy this logic and the URL rules to enable it for other controllers.
|
2017-01-25 14:29:00 +01:00
|
|
|
*
|
2013-05-07 10:56:38 +02:00
|
|
|
* @package widgets
|
|
|
|
*/
|
2015-11-18 05:08:21 +01:00
|
|
|
class WidgetController extends Controller
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @var Widget
|
|
|
|
*/
|
|
|
|
protected $widget;
|
2013-05-07 10:56:38 +02:00
|
|
|
|
2015-11-18 05:08:21 +01:00
|
|
|
/**
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
private static $allowed_actions = array(
|
|
|
|
'editablesegment'
|
|
|
|
);
|
2013-05-07 10:56:38 +02:00
|
|
|
|
2015-11-18 05:08:21 +01:00
|
|
|
/**
|
|
|
|
* @param Widget $widget
|
|
|
|
*/
|
|
|
|
public function __construct($widget = null)
|
|
|
|
{
|
|
|
|
if ($widget) {
|
|
|
|
$this->widget = $widget;
|
|
|
|
$this->failover = $widget;
|
|
|
|
}
|
2017-01-25 14:29:00 +01:00
|
|
|
|
2015-11-18 05:08:21 +01:00
|
|
|
parent::__construct();
|
|
|
|
}
|
2013-05-07 10:56:38 +02:00
|
|
|
|
2017-01-25 20:25:53 +01:00
|
|
|
/**
|
|
|
|
* @param string $action
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function Link($action = null)
|
2015-11-18 05:08:21 +01:00
|
|
|
{
|
|
|
|
$id = ($this->widget) ? $this->widget->ID : null;
|
2017-01-17 23:43:11 +01:00
|
|
|
$segment = Controller::join_links('widget', $id, $action);
|
2015-11-11 03:01:03 +01:00
|
|
|
|
2017-01-17 23:43:11 +01:00
|
|
|
$page = Director::get_current_page();
|
2017-01-25 20:25:53 +01:00
|
|
|
if ($page && !($page instanceof WidgetController)) {
|
2017-01-17 23:43:11 +01:00
|
|
|
return $page->Link($segment);
|
|
|
|
}
|
2015-11-11 03:01:03 +01:00
|
|
|
|
2017-01-25 20:25:53 +01:00
|
|
|
if ($controller = $this->getParentController()) {
|
2017-01-17 23:43:11 +01:00
|
|
|
return $controller->Link($segment);
|
2017-01-25 20:25:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return $segment;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Cycles up the controller stack until it finds a non-widget controller
|
|
|
|
* This is needed becauseController::currreturns the widget controller,
|
|
|
|
* which means anyLinkfunction turns into endless loop.
|
|
|
|
*
|
|
|
|
* @return Controller
|
|
|
|
*/
|
|
|
|
public function getParentController()
|
2015-11-18 05:08:21 +01:00
|
|
|
{
|
2017-01-17 23:43:11 +01:00
|
|
|
foreach (Controller::$controller_stack as $controller) {
|
|
|
|
if (!($controller instanceof WidgetController)) {
|
|
|
|
return $controller;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-01-25 20:25:53 +01:00
|
|
|
/**
|
|
|
|
* @return Widget
|
|
|
|
*/
|
|
|
|
public function getWidget()
|
|
|
|
{
|
2017-01-17 23:43:11 +01:00
|
|
|
return $this->widget;
|
2017-01-25 20:25:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Overloaded from {@link Widget->Content()} to allow for controller / form
|
|
|
|
* linking.
|
|
|
|
*
|
|
|
|
* @return string HTML
|
|
|
|
*/
|
|
|
|
public function Content()
|
|
|
|
{
|
2022-04-13 03:54:56 +02:00
|
|
|
return $this->renderWith(array_reverse(ClassInfo::ancestry(get_class($this->widget)) ?? []));
|
2017-01-25 20:25:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Overloaded from {@link Widget->WidgetHolder()} to allow for controller/
|
|
|
|
* form linking.
|
|
|
|
*
|
|
|
|
* @return string HTML
|
|
|
|
*/
|
|
|
|
public function WidgetHolder()
|
|
|
|
{
|
2017-01-17 23:43:11 +01:00
|
|
|
return $this->renderWith("WidgetHolder");
|
2017-01-25 20:25:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Uses the `WidgetEditor.ss` template and {@link Widget->editablesegment()}
|
|
|
|
* to render a administrator-view of the widget. It is assumed that this
|
|
|
|
* view contains form elements which are submitted and saved through
|
|
|
|
* {@link WidgetAreaEditor} within the CMS interface.
|
|
|
|
*
|
|
|
|
* @return string HTML
|
|
|
|
*/
|
|
|
|
public function editablesegment()
|
2017-01-17 23:43:11 +01:00
|
|
|
{
|
2016-06-21 05:44:37 +02:00
|
|
|
// use left and main to set the html config
|
|
|
|
$leftandmain = LeftAndMain::create();
|
2017-12-13 11:03:12 +01:00
|
|
|
$leftandmain->setRequest($this->getRequest());
|
2017-01-17 23:43:11 +01:00
|
|
|
$leftandmain->doInit();
|
2013-05-07 10:56:38 +02:00
|
|
|
|
2017-01-18 02:49:15 +01:00
|
|
|
// Decode if fully qualified - @see Widget::ClassName
|
2022-04-13 03:54:56 +02:00
|
|
|
$className = str_replace('_', '\\', $this->urlParams['ID'] ?? '');
|
|
|
|
if (class_exists($className ?? '') && is_subclass_of($className, Widget::class)) {
|
2017-01-17 23:43:11 +01:00
|
|
|
$obj = new $className();
|
|
|
|
return $obj->EditableSegment();
|
|
|
|
} else {
|
|
|
|
user_error("Bad widget class: $className", E_USER_WARNING);
|
|
|
|
return "Bad widget class name given";
|
|
|
|
}
|
|
|
|
}
|
2013-05-07 10:56:38 +02:00
|
|
|
}
|