1 <?php
2
3 4 5 6 7 8
9 class WidgetAdmin extends LeftAndMain {
10
11 static $url_segment = 'widgets';
12 static $url_rule = '/$Action/$ID';
13 static = 'Widgets';
14 static $parent_tree_class = 'WebylonWidgetArea';
15 static $tree_class = 'WebylonWidget';
16
17 18 19
20 function IsTranslatableEnabled() {
21 return Object::has_extension('SiteConfig', 'Translatable');
22 }
23
24 25 26 27
28 function LangSelector() {
29 $member = Member::currentUser();
30 $dropdown = new LanguageDropdownField(
31 'LangSelector',
32 'Language',
33 array(),
34 'SiteTree',
35 'Locale-English',
36 singleton('SiteTree')
37 );
38 $dropdown->setValue(Translatable::get_current_locale());
39 return $dropdown;
40 }
41
42
43 public function init() {
44 parent::init();
45 Requirements::javascript("widgets/javascript/WidgetAdmin_left.js");
46 Requirements::javascript("widgets/javascript/WidgetAdmin_right.js");
47 }
48
49 function getObjList() {
50 $sc = SiteConfig::current_site_config();
51 return $sc->getActiveWidgetAreas();
52 }
53
54 55 56 57 58
59 public function SiteTreeAsUL() {
60 $this->generateDataTreeHints();
61 $siteTree = "";
62 $objList = $this->getObjList();
63 $currentAreaID = Session::get('CurrentWidgetArea');
64 $currentWidgetID = Session::get('CurrentWidget');
65
66 if ($objList) {
67 foreach ($objList as $area) {
68 $subObjList = $area->Widgets();
69
70 $siteTree .= '<li id="record-' . $area->ID
71 . '" class="Folder ' . $area->class
72 . ($area->Locked ? ' nodelete' : '')
73 . (SiteConfigWidgets::is_area_readonly($area->TechName) ? ' nochildren' : '')
74 . ($subObjList ? ' children' : '')
75 . ($area->ID == $currentAreaID ? ' current' : '')
76 . '" itemclass="' . $area->class
77 . '" areaclass="' . $area->TechName .
78 '" ' . (SiteConfigWidgets::is_area_readonly($area->TechName) ? 'readonly="true"' : '') . '>'
79 . '<a href="admin/' . $this->stat('url_segment').'/show/'. $area->ID . '" >' . _t('WebylonWidgetArea.Title_' . $area->TechName, $area->TechName) . '('.$area->class.')</a>';
80
81 if ($subObjList) {
82 $subSiteTree = '';
83 foreach ($subObjList as $widget) {
84
85 if (WebylonWidget::is_hidden_widget($widget->class)) {
86 continue;
87 }
88 $widgetID = $area->ID . '-' . $widget->ID;
89 $subSiteTree .= '<li id="record-' . $widgetID
90 . '" class="' . $widget->class
91 . ($widget->Locked ? ' nodelete' : '')
92 . ($widget->ID == $currentWidgetID ? ' current' : '')
93 . '" itemclass="' . $widget->class
94 . '" areaclass="' . $area->TechName
95 . '" ' . (SiteConfigWidgets::is_area_readonly($area->TechName) ? 'readonly="true"' : '').'>'
96 . '<a class="' . $widget->class . '" href="admin/' . $this->stat('url_segment').'/show/'. $widgetID . '" title="' . _t('WidgetAdmin.WIDGETTYPE','Widget type: ') . $widget->class.'">' . $widget->Title . '</a></li>';
97 }
98 $siteTree .= '<ul class="area_children'.(SiteConfigWidgets::is_area_readonly($area->TechName) ? ' nochildren' : '') . '" style="padding-left: 16px;" '.(SiteConfigWidgets::is_area_readonly($area->TechName) ? 'readonly="true"' : '').'>' . $subSiteTree . '</ul>';
99 }
100 $siteTree .= '</li>';
101
102 }
103 }
104 $siteTree = '<li id="record-0" class="Root nodelete" readonly="true"><a href="#">'. _t('Widgets.SiteTreeTitle', 'Виджеты') .'</a><ul class="" readonly="true">' . $siteTree . '</ul></li>';
105
106 if (!$this->isAjax()) {
107 return '<ul id="sitetree" class="tree">'
108
109
110 . $siteTree . '</ul>';
111 } else {
112 return $siteTree;
113 }
114 }
115
116 117 118 119 120
121
122 function getEditForm() {
123
124
125
126 $req = $this->getRequest();
127 if ($widgetID = $req->requestVar('WidgetID')) {
128 $id = "1-" . $widgetID;
129 }
130 else {
131
132 $id = $this->currentPageID();
133 }
134 if (!$id)
135 return false;
136
137 $widgetID = 0;
138 if (strpos($id, '-') !== false) {
139 $ids = explode('-', $id);
140 $widgetID = $ids[1];
141
142 $widget = DataObject::get_by_id($this->stat('tree_class'), $widgetID);
143 if ($widget) {
144 Session::set('CurrentWidgetArea', $widget->ParentID);
145 Session::set('CurrentWidget', $widget->ID);
146 $fields = $widget->getCMSFields();
147 $fields->replaceField('ParentID', new HiddenField('ParentID'));
148 $fields->push(new HiddenField('WidgetID', 'WidgetID', $widget->ID));
149 $fields->push(new HiddenField('ID', 'ID', $widget->ID));
150
151 $actions = $widget->getCMSActions();
152 $form = new Form($this, "EditForm", $fields, $actions);
153 $form->disableSecurityToken();
154 $form->loadDataFrom($widget);
155 if (SiteConfigWidgets::is_area_readonly($widget->Parent()->TechName)) {
156 $form->makeReadonly();
157 }
158 return $form;
159 }
160 }
161 elseif ($widgetArea = DataObject::get_by_id($this->stat('parent_tree_class'), $id)) {
162 Session::set('CurrentWidgetArea', $widgetArea->ID);
163
164 $fields = new FieldSet();
165 $fields->push(new HiddenField('ID', 'ID', $widgetArea->ID));
166 $actions = new FieldSet(
167 );
168 $form = new Form($this, "EditForm", $fields, $actions);
169 $form->disableSecurityToken();
170 return $form;
171 }
172 return false;
173 }
174
175
176 function save($data, $form) {
177 $id = (isset($data['WidgetID'])) ? (int)$data['WidgetID'] : 0;
178 $parentID = (isset($data['ParentID'])) ? (int)$data['ParentID'] : 0;
179
180 $record = DataObject::get_by_id($this->stat('tree_class'), $id);
181 if ($record) {
182 $form->saveInto($record, true);
183 }
184 if ($record->write()) {
185 FormResponse::status_message(_t('Widgets.SaveSuccess', 'Widget saved'), 'good');
186 FormResponse::set_node_title("{$parentID}-{$id}", $record->Title);
187
188
189 $response = <<<JS
190 var st = $('sitetree');
191 var node = st.getTreeNodeByIdx('{$parentID}-{$id}');
192 if( node ) node.getPageFromServer('{$parentID}-{$id}');
193 JS;
194 FormResponse::add($response);
195
196 } else {
197 FormResponse::status_message(_t('Widgets.SaveFail', 'Save Failed'), 'bad');
198 }
199 return FormResponse::respond();
200 }
201
202 function doDeleteWidget($data, $form) {
203
204 $id = (isset($data['WidgetID'])) ? (int)$data['WidgetID'] : 0;
205 $parentID = (isset($data['ParentID'])) ? (int)$data['ParentID'] : 0;
206
207 DataObject::delete_by_id($this->stat('tree_class'), $id);
208 FormResponse::status_message(_t('Widgets.DeleteSuccess', 'Widget deleted'), 'good');
209 $response = <<<JS
210 var st = $('sitetree');
211 var node = st.getTreeNodeByIdx('{$parentID}-{$id}');
212 if( node && node.parentTreeNode ) node.parentTreeNode.removeTreeNode( node );
213 $('Form_EditForm').close(); //IfSetTo('{$parentID}-{$id}');
214 JS;
215 FormResponse::add($response);
216
217 return FormResponse::respond();
218 }
219
220
221 function AddWidgetOptionsForm() {
222 $fields = new FieldSet(
223 new HiddenField("ParentID")
224 );
225
226 $pageTypes = array();
227 $currentWidgetArea = false;
228 if (Session::get('CurrentWidgetArea') && ($currentWidgetArea = DataObject::get_by_id($this->stat('parent_tree_class'), (int)Session::get('CurrentWidgetArea')))) {
229 $fields->push(new HiddenField("AreaID", "AreaID", $currentWidgetArea->ID));
230 }
231 $widgetClass = false;
232 if ($currentWidgetArea) {
233 $widgetClass = $currentWidgetArea::$widgetClass;
234 if (!SiteConfigWidgets::is_area_readonly($currentWidgetArea->TechName)) {
235 $allWidgets = SiteConfigWidgets::get_allowed_area_widgets($currentWidgetArea);
236 foreach ($allWidgets as $widget) {
237 $obj = singleton($widget);
238 if ($obj->canCreate($currentWidgetArea)) {
239 $pageTypes[$widget] = sprintf(_t('WidgetAdmin.CreateLine', 'Widget "%s"'), $obj->i18n_singular_name());
240 }
241 }
242 }
243 }
244 $fields->push(new DropdownField("WidgetType", "", $pageTypes));
245 $actions = new FieldSet(
246 new FormAction("addwidget", _t('CMSMain.GO',"Go"))
247 );
248
249 return new Form($this, "AddWidgetOptionsForm", $fields, $actions);
250 }
251
252 function addwidget($data, $form) {
253 if (isset($data['WidgetType']) && isset($data['AreaID'])) {
254 $widgetClass = $data['WidgetType'];
255 $widget = new $widgetClass();
256 $widget->ParentID = (int)$data['AreaID'];
257 if ($widget->write()) {
258 FormResponse::status_message(_t('Widgets.CreateSuccess', 'Widget created'), 'good');
259
260 $response = <<<JS
261 var newNode = $('sitetree').createTreeNode('{$widget->ParentID}-{$widget->ID}', '{$widget->Title}', '{$widgetClass}');
262 $('sitetree').appendTreeNode(newNode);
263 $('sitetree').setNodeParentID('{$widget->ParentID}-{$widget->ID}', '{$widget->ParentID}');
264 newNode.setAttribute("itemclass",'{$widgetClass}');
265 newNode.setAttribute("areaclass",'{$widget->Parent()->TechName}');
266 $('sitetree').changeCurrentTo(newNode);
267 $('Form_EditForm').getPageFromServer('{$widget->ParentID}-{$widget->ID}');
268 JS;
269
270 FormResponse::add($response);
271 }
272
273 } else {
274 FormResponse::status_message(_t('Widgets.BadWidgetArea', 'Bad widget area'), 'bad');
275
276 }
277 return FormResponse::respond();
278
279 }
280
281 public function EditForm() {
282
283 HtmlEditorField::include_js();
284 $form = $this->getEditForm();
285 if ($form) {
286 $form->disableDefaultAction();
287 return $form;
288 }
289 return false;
290 }
291
292
293 public function generateDataTreeHints() {
294 $def['Root'] = false;
295
296 $objList = $this->getObjList();
297 if ($objList) {
298 foreach ($objList as $area) {
299 $isHiddenArea = SiteConfigWidgets::is_area_readonly($area->TechName);
300 if (isset($def[$area->TechName]) || $isHiddenArea) {
301 continue;
302 }
303 $widgetClass = $area::$widgetClass;
304 $allWidgets = ClassInfo::subclassesFor($widgetClass);
305 unset($allWidgets[0]);
306 foreach($allWidgets as $widget) {
307 $obj = singleton($widget);
308 if ($obj->canCreate($area)) {
309 $line = array();
310 $line['class'] = $widget;
311 $line['title'] = sprintf(_t('WidgetAdmin.CreateLine', 'Widget "%s"'), $obj->i18n_singular_name());
312
313 $def[$area->TechName]['PossibleWidgets'][] = $line;
314 $def[$area->ClassName]['allowedChildren'][] = $widget;
315 $def[$area->TechName]['CanDrag'] = $isHiddenArea;
316 $def[$widget]['allowedChildren'][] = false;
317 }
318 }
319 }
320 }
321 $def['Root']['allowedChildren'][] = false;
322
323 Requirements::customScript("siteTreeHints = " . $this->jsDeclaration($def) . ";");
324 }
325
326 327 328
329 protected function jsDeclaration($array) {
330 if(is_array($array)) {
331 $object = false;
332 foreach(array_keys($array) as $key) {
333 if(!is_numeric($key)) {
334 $object = true;
335 break;
336 }
337 }
338
339 if($object) {
340 foreach($array as $k => $v) {
341 $parts[] = "$k : " . $this->jsDeclaration($v);
342 }
343 return " {\n " . implode(", \n", $parts) . " }\n";
344 } else {
345 foreach($array as $part) $parts[] = $this->jsDeclaration($part);
346 return " [ " . implode(", ", $parts) . " ]\n";
347 }
348 } else {
349 return "'" . addslashes($array) . "'";
350 }
351 }
352
353 public function ajaxupdatesort() {
354 $className = $this->stat('tree_class');
355 $counter = 0;
356 $js = '';
357 $_REQUEST['ajax'] = 1;
358
359 if (!Permission::check('SITETREE_REORGANISE') && !Permission::check('ADMIN')) {
360 FormResponse::status_message(_t('LeftAndMain.CANT_REORGANISE',"You do not have permission to rearange the site tree. Your change was not saved."),"bad");
361 return FormResponse::respond();
362 }
363
364 if(is_array($_REQUEST['ID'])) {
365 $movedNodeID = explode('-', $_REQUEST['MovedNodeID']);
366 $movedNodeID = $movedNodeID[1];
367 $movedNode = DataObject::get_by_id($className, $movedNodeID);
368 foreach($_REQUEST['ID'] as $id) {
369 $id = explode('-', $id);
370 $id = $id[1];
371 if($id == $movedNode->ID) {
372 $movedNode->Sort = ++$counter;
373 $movedNode->Status = "Saved (update)";
374 $movedNode->write();
375
376 $title = Convert::raw2js($movedNode->CMSTitle());
377 $js .="$('sitetree').setNodeTitle($movedNode->ID, \"$title\");\n";
378
379
380 } else if(is_numeric($id)) {
381 ++$counter;
382 DB::query("UPDATE Widget SET \"Sort\" = $counter WHERE \"ID\" = '$id'");
383 }
384 }
385 FormResponse::status_message(_t('LeftAndMain.SAVED'), 'good');
386 } else {
387 FormResponse::error(_t('LeftAndMain.REQUESTERROR',"Error in request"));
388 }
389
390 return FormResponse::respond();
391 }
392
393 public function ajaxupdateparent() {
394 $id = explode('-', $_REQUEST['ID']);
395 $id = $id[1];
396 $parentID = $_REQUEST['ParentID'];
397 if($parentID == 'root'){
398 $parentID = 0;
399 }
400 $_REQUEST['ajax'] = 1;
401
402 if (!Permission::check('SITETREE_REORGANISE') && !Permission::check('ADMIN')) {
403 FormResponse::status_message(_t('LeftAndMain.CANT_REORGANISE',"You do not have permission to rearange the site tree. Your change was not saved."),"bad");
404 return FormResponse::respond();
405 }
406
407 if(is_numeric($id) && is_numeric($parentID) && $id != $parentID) {
408 $node = DataObject::get_by_id($this->stat('tree_class'), $id);
409 if($node){
410 if(!$node->canEdit() || ($node->hasMethod('checkDevPermisson') && !$node->checkDevPermisson(null,'canReorder'))){
411 return Security::permissionFailure($this);
412 }
413 $node->ParentID = $parentID;
414 $node->write();
415 FormResponse::status_message(_t('LeftAndMain.SAVED','saved'), 'good');
416 }else{
417 FormResponse::status_message(_t('LeftAndMain.PLEASESAVE',"Please Save Page: This page could not be upated because it hasn't been saved yet."),"good");
418 }
419
420
421 return FormResponse::respond();
422 } else {
423 user_error("Error in ajaxupdateparent request; id=$id, parentID=$parentID", E_USER_ERROR);
424 }
425 }
426
427 }
428
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the
Silverstripe Forums to ask development related questions.
-