/
WidgetController.php
145 lines (131 loc) · 3.69 KB
/
WidgetController.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<?php
/**
* Optional controller for every widget which has its own logic, e.g. in forms.
*
* It always handles a single widget, usually passed in as a database
* identifier through the controller URL. Needs to be constructed as a nested
* controller within a {@link ContentController}.
*
* ## Forms
* You can add forms like in any other SilverStripe controller. If you need
* access to the widget from within a form, you can use
* `$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.
*
* @package widgets
*/
class WidgetController extends Controller
{
/**
* @var Widget
*/
protected $widget;
/**
* @var array
*/
private static $allowed_actions = array(
'editablesegment'
);
/**
* @param Widget $widget
*/
public function __construct($widget = null)
{
if ($widget) {
$this->widget = $widget;
$this->failover = $widget;
}
parent::__construct();
}
/**
* @param string $action
* @return string
*/
public function Link($action = null)
{
$id = ($this->widget) ? $this->widget->ID : null;
$segment = Controller::join_links('widget', $id, $action);
$page = Director::get_current_page();
if($page && !($page instanceof WidgetController)) {return $page->Link($segment);
}
if ($controller = $this->getParentController()) {return $controller->Link($segment);
}
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()
{
foreach(Controller::$controller_stack as $controller) {
if (!($controller instanceof WidgetController)) {
return $controller;
}
}
return false;
}
/**
* @return Widget
*/
public function getWidget()
{return $this->widget;
}
/**
* Overloaded from {@link Widget->Content()} to allow for controller / form
* linking.
*
* @return string HTML
*/
public function Content()
{return $this->renderWith(array_reverse(ClassInfo::ancestry($this->widget->class)));
}
/**
* Overloaded from {@link Widget->WidgetHolder()} to allow for controller/
* form linking.
*
* @return string HTML
*/
public function WidgetHolder()
{return $this->renderWith("WidgetHolder");
}
/**
* 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() {
// use left and main to set the html config
$leftandmain = LeftAndMain::create();
$leftandmain->init();
$className = $this->urlParams['ID'];
if (class_exists('Translatable') && Member::currentUserID()) {
// set current locale based on logged in user's locale
$locale = Member::currentUser()->Locale;
i18n::set_locale($locale);
}
if(class_exists($className) && is_subclass_of($className, 'Widget')) {
$obj = new $className();
return $obj->EditableSegment();
} else {
user_error("Bad widget class: $className", E_USER_WARNING);
return "Bad widget class name given";
}
}
}
/**
* @deprecated Use WidgetController
* @package widgets
*/
class Widget_Controller extends WidgetController
{
}