1 <?php
2 3 4 5 6 7 8 9 10 11
12 class LeftAndMain extends Controller {
13
14 15 16 17 18 19 20
21 static $url_base = "admin";
22
23 static $url_segment;
24
25 static $url_rule = '/$Action/$ID/$OtherID';
26
27 static ;
28
29 static = 0;
30
31 static $url_priority = 50;
32
33 static $tree_class = null;
34
35 static $ForceReload;
36
37 static $allowed_actions = array(
38 'index',
39 'ajaxupdateparent',
40 'ajaxupdatesort',
41 'callPageMethod',
42 'deleteitems',
43 'getitem',
44 'getsubtree',
45 'myprofile',
46 'printable',
47 'save',
48 'show',
49 'Member_ProfileForm',
50 'EditorToolbar',
51 'EditForm',
52 );
53
54 55 56 57 58 59 60
61 protected static = array(
62 'javascript' => array(),
63 'css' => array(),
64 'themedcss' => array(),
65 );
66
67 68 69 70
71 function canView($member = null) {
72 if(!$member && $member !== FALSE) {
73 $member = Member::currentUser();
74 }
75
76
77 if(!$member) return false;
78
79
80 if($this->hasMethod('alternateAccessCheck')) {
81 $alternateAllowed = $this->alternateAccessCheck();
82 if($alternateAllowed === FALSE) return false;
83 }
84
85
86 if(!Permission::checkMember($member, "CMS_ACCESS_$this->class") &&
87 !Permission::checkMember($member, "CMS_ACCESS_LeftAndMain")) {
88 return false;
89 }
90
91 return true;
92 }
93
94 95 96 97 98
99 function init() {
100 parent::init();
101
102
103 $member = Member::currentUser();
104 if(!empty($member->Locale)) {
105 i18n::set_locale($member->Locale);
106 }
107
108
109
110 CMSMenu::add_link(
111 'Help',
112 _t('LeftAndMain.HELP', 'Help', PR_HIGH, 'Menu title'),
113 'http://support.mediaweb.ru/faq31/',
114 -100
115 );
116
117
118
119 if(Object::has_extension('SiteTree', 'Translatable') && !Director::is_ajax()) {
120 Translatable::choose_site_locale(array_keys(Translatable::get_existing_content_languages('SiteTree')));
121 }
122
123
124
125 if(!$this->canView() && !$this->response->isFinished()) {
126
127 $menu = $this->MainMenu();
128 foreach($menu as $candidate) {
129 if(
130 $candidate->Link &&
131 $candidate->Link != $this->Link()
132 && $candidate->MenuItem->controller
133 && singleton($candidate->MenuItem->controller)->canView()
134 ) {
135 return Director::redirect($candidate->Link);
136 }
137 }
138
139 if(Member::currentUser()) {
140 Session::set("BackURL", null);
141 }
142
143
144 $messageSet = array(
145 'default' => _t('LeftAndMain.PERMDEFAULT',"Please choose an authentication method and enter your credentials to access the CMS."),
146 'alreadyLoggedIn' => _t('LeftAndMain.PERMALREADY',"I'm sorry, but you can't access that part of the CMS. If you want to log in as someone else, do so below"),
147 'logInAgain' => _t('LeftAndMain.PERMAGAIN',"You have been logged out of the CMS. If you would like to log in again, enter a username and password below."),
148 );
149
150 return Security::permissionFailure($this, $messageSet);
151 }
152
153
154 if(Director::redirected_to()) return;
155
156
157 if(empty($_REQUEST['executeForm']) && !Director::is_ajax()) $this->extend('accessedCMS');
158
159
160 HtmlEditorConfig::set_active(Member::currentUser()->getHtmlEditorConfigForCMS());
161
162
163
164
165 $htmlEditorConfig = HtmlEditorConfig::get_active();
166 if(!$htmlEditorConfig->getOption('content_css')) {
167 $cssFiles = 'cms/css/editor.css';
168
169
170 if(($config = SiteConfig::current_site_config()) && $config->Theme) {
171 $theme = $config->Theme;
172 } elseif(SSViewer::current_theme()) {
173 $theme = SSViewer::current_theme();
174 } else {
175 $theme = false;
176 }
177 if ($theme && file_exists(THEMES_PATH . "/{$theme}/css/editor.css")) {
178 $cssFiles .= ', ' . THEMES_DIR . "/{$theme}/css/editor.css?m=" . filemtime(THEMES_PATH . "/{$theme}/css/editor.css");
179 }
180 else if(project()) {
181 $cssFiles .= ', ' . project() . '/css/editor.css?m=' . filemtime(Director::baseFolder() . '/' . project() . "/css/editor.css");
182 }
183 $htmlEditorConfig->setOption('content_css', $cssFiles);
184 }
185
186
187 Requirements::css(CMS_DIR . '/css/typography.css');
188 Requirements::css(CMS_DIR . '/css/layout.css');
189 Requirements::css(CMS_DIR . '/css/cms_left.css');
190 Requirements::css(CMS_DIR . '/css/cms_right.css');
191 Requirements::css(SAPPHIRE_DIR . '/css/Form.css');
192
193 if(isset($_REQUEST['debug_firebug'])) {
194
195
196
197 Requirements::javascript(THIRDPARTY_DIR . '/firebug-lite/firebug.js');
198 } else {
199
200
201 Requirements::javascript(THIRDPARTY_DIR . '/firebug-lite/firebugx.js');
202 }
203
204 Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/prototype/prototype.js');
205 Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
206 Requirements::javascript(SAPPHIRE_DIR . '/javascript/jquery_improvements.js');
207 Requirements::javascript(THIRDPARTY_DIR . '/behaviour/behaviour.js');
208 Requirements::javascript(THIRDPARTY_DIR . '/jquery-livequery/jquery.livequery.js');
209 Requirements::javascript(SAPPHIRE_DIR . '/javascript/core/jquery.ondemand.js');
210 Requirements::javascript(SAPPHIRE_DIR . '/javascript/prototype_improvements.js');
211 Requirements::javascript(SAPPHIRE_DIR . '/javascript/loader.js');
212 Requirements::javascript(CMS_DIR . '/javascript/hover.js');
213 Requirements::javascript(SAPPHIRE_DIR . '/javascript/layout_helpers.js');
214 Requirements::add_i18n_javascript(SAPPHIRE_DIR . '/javascript/lang');
215 Requirements::add_i18n_javascript(CMS_DIR . '/javascript/lang');
216
217 Requirements::javascript(THIRDPARTY_DIR . '/scriptaculous/effects.js');
218 Requirements::javascript(THIRDPARTY_DIR . '/scriptaculous/dragdrop.js');
219 Requirements::javascript(THIRDPARTY_DIR . '/scriptaculous/controls.js');
220
221 Requirements::css(THIRDPARTY_DIR . '/greybox/greybox.css');
222 Requirements::javascript(THIRDPARTY_DIR . '/greybox/AmiJS.js');
223 Requirements::javascript(THIRDPARTY_DIR . '/greybox/greybox.js');
224
225 Requirements::javascript(SAPPHIRE_DIR . '/javascript/tree/tree.js');
226 Requirements::css(THIRDPARTY_DIR . '/tree/tree.css');
227
228 Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain.js');
229 Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain_left.js');
230 Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain_right.js');
231
232 Requirements::javascript(CMS_DIR . '/javascript/SideTabs.js');
233 Requirements::javascript(CMS_DIR . '/javascript/SideReports.js');
234 Requirements::javascript(CMS_DIR . '/javascript/LangSelector.js');
235 Requirements::javascript(CMS_DIR . '/javascript/TranslationTab.js');
236
237
238 Requirements::css(SAPPHIRE_DIR . '/css/SilverStripeNavigator.css');
239 Requirements::javascript(SAPPHIRE_DIR . '/javascript/SilverStripeNavigator.js');
240
241
242
243 foreach (self::$extra_requirements['javascript'] as $file) {
244 Requirements::javascript($file[0]);
245 }
246
247 foreach (self::$extra_requirements['css'] as $file) {
248 Requirements::css($file[0], $file[1]);
249 }
250
251 foreach (self::$extra_requirements['themedcss'] as $file) {
252 Requirements::themedCSS($file[0], $file[1]);
253 }
254
255 Requirements::customScript('Behaviour.addLoader(hideLoading);');
256
257
258 Requirements::combine_files(
259 'assets/_tmp/base.js',
260 array(
261 THIRDPARTY_DIR . '/prototype/prototype.js',
262 THIRDPARTY_DIR . '/behaviour/behaviour.js',
263 SAPPHIRE_DIR . '/javascript/prototype_improvements.js',
264 THIRDPARTY_DIR .'/jquery/jquery.js',
265 THIRDPARTY_DIR .'/jquery-livequery/jquery.livequery.js',
266 THIRDPARTY_DIR . '/jquery-effen/jquery.fn.js',
267 SAPPHIRE_DIR . '/javascript/core/jquery.ondemand.js',
268 SAPPHIRE_DIR . '/javascript/jquery_improvements.js',
269 THIRDPARTY_DIR . '/firebug-lite/firebugx.js',
270 SAPPHIRE_DIR . '/javascript/i18n.js',
271 )
272 );
273
274 Requirements::combine_files(
275 'assets/_tmp/leftandmain.js',
276 array(
277 SAPPHIRE_DIR . '/javascript/loader.js',
278 CMS_DIR . '/javascript/hover.js',
279 SAPPHIRE_DIR . '/javascript/layout_helpers.js',
280 THIRDPARTY_DIR . '/scriptaculous/effects.js',
281 THIRDPARTY_DIR . '/scriptaculous/dragdrop.js',
282 THIRDPARTY_DIR . '/scriptaculous/controls.js',
283 THIRDPARTY_DIR . '/greybox/AmiJS.js',
284 THIRDPARTY_DIR . '/greybox/greybox.js',
285 CMS_DIR . '/javascript/LeftAndMain.js',
286 CMS_DIR . '/javascript/LeftAndMain_left.js',
287 CMS_DIR . '/javascript/LeftAndMain_right.js',
288 SAPPHIRE_DIR . '/javascript/tree/tree.js',
289 THIRDPARTY_DIR . '/tabstrip/tabstrip.js',
290 SAPPHIRE_DIR . '/javascript/TreeSelectorField.js',
291 CMS_DIR . '/javascript/ThumbnailStripField.js',
292 )
293 );
294
295 Requirements::combine_files(
296 'assets/_tmp/cmsmain.js',
297 array(
298 CMS_DIR . '/javascript/CMSMain.js',
299 CMS_DIR . '/javascript/CMSMain_left.js',
300 CMS_DIR . '/javascript/CMSMain_right.js',
301 CMS_DIR . '/javascript/SideTabs.js',
302 CMS_DIR . '/javascript/SideReports.js',
303 CMS_DIR . '/javascript/LangSelector.js',
304 CMS_DIR . '/javascript/TranslationTab.js',
305 THIRDPARTY_DIR . '/calendar/calendar.js',
306 THIRDPARTY_DIR . '/calendar/lang/calendar-'.substr(i18n::get_locale(),0,2).'.js',
307 THIRDPARTY_DIR . '/calendar/calendar-setup.js',
308 )
309 );
310
311 $dummy = null;
312 $this->extend('init', $dummy);
313
314
315 if (property_exists('FormField', 'use_html5')) {
316 FormField::allow_html5(false);
317 }
318
319
320
321
322 SSViewer::set_theme(null);
323 }
324
325
326 327 328 329 330 331
332 function ShowSwitchView() {
333 return false;
334 }
335
336
337
338
339 340 341 342 343 344
345 public function Link($action = null) {
346
347 if(!$this->stat('url_segment', true))
348 self::$url_segment = $this->class;
349 return Controller::join_links(
350 $this->stat('url_base', true),
351 $this->stat('url_segment', true),
352 '/',
353 "$action"
354 );
355 }
356
357
358 359 360 361 362
363 static function ($class) {
364 $title = eval("return $class::\$menu_title;");
365 if(!$title) $title = preg_replace('/Admin$/', '', $class);
366 return $title;
367 }
368
369 public function show() {
370 $params = $this->getURLParams();
371 if($params['ID']) $this->setCurrentPageID($params['ID']);
372 if(isset($params['OtherID'])) {
373 Session::set('currentMember', $params['OtherID']);
374 }
375
376 if(Director::is_ajax()) {
377 SSViewer::setOption('rewriteHashlinks', false);
378 return $this->EditForm()->formHtmlContent();
379
380 } else {
381 return array();
382 }
383 }
384
385
386 public function getitem() {
387 $this->setCurrentPageID($_REQUEST['ID']);
388 SSViewer::setOption('rewriteHashlinks', false);
389
390 if(isset($_REQUEST['ID']) && is_numeric($_REQUEST['ID'])) {
391 $record = DataObject::get_by_id($this->stat('tree_class'), $_REQUEST['ID']);
392 if($record && !$record->canView()) return Security::permissionFailure($this);
393 }
394
395 $form = $this->EditForm();
396 if ($form) {
397 $content = $form->formHtmlContent();
398 if($this->ShowSwitchView()) {
399 $content .= '<div id="AjaxSwitchView">' . $this->SwitchView() . '</div>';
400 }
401
402 return $content;
403 }
404 else return "";
405 }
406 public function getLastFormIn($html) {
407 $parts = split('</?form[^>]*>', $html);
408 return $parts[sizeof($parts)-2];
409 }
410
411
412
413
414 415 416 417 418 419
420 public function MainMenu() {
421
422 if(!Member::currentUser()) return new DataObjectSet();
423
424
425 $menu = new DataObjectSet();
426 $menuItems = CMSMenu::get_viewable_menu_items();
427 if($menuItems) foreach($menuItems as $code => $menuItem) {
428
429 if(
430 isset($menuItem->controller)
431 && $this->hasMethod('alternateMenuDisplayCheck')
432 && !$this->alternateMenuDisplayCheck($menuItem->controller)
433 ) {
434 continue;
435 }
436
437 $linkingmode = "";
438
439 if(strpos($this->Link(), $menuItem->url) !== false) {
440 if($this->Link() == $menuItem->url) {
441 $linkingmode = "current";
442
443
444 } else if(singleton($menuItem->controller)->stat('url_segment') == '') {
445 if($this->Link() == $this->stat('url_base').'/') $linkingmode = "current";
446
447 } else {
448 $linkingmode = "current";
449 }
450 }
451
452
453
454
455 if($menuItem->controller) {
456 $defaultTitle = LeftAndMain::menu_title_for_class($menuItem->controller);
457 $title = _t("{$menuItem->controller}.MENUTITLE", $defaultTitle);
458 } else {
459 $title = $menuItem->title;
460 }
461
462 $menu->push(new ArrayData(array(
463 "MenuItem" => $menuItem,
464 "Title" => Convert::raw2xml($title),
465 "Code" => $code,
466 "Link" => $menuItem->url,
467 "LinkingMode" => $linkingmode
468 )));
469 }
470
471
472
473 return $menu;
474 }
475
476
477 public function () {
478 return $this->renderWith(array('CMSTopMenu_alternative','CMSTopMenu'));
479 }
480
481 482 483
484 protected function getTemplatesWithSuffix($suffix) {
485 $classes = array_reverse(ClassInfo::ancestry($this->class));
486 foreach($classes as $class) {
487 $templates[] = $class . $suffix;
488 if($class == 'LeftAndMain') break;
489 }
490 return $templates;
491 }
492
493 public function Left() {
494 return $this->renderWith($this->getTemplatesWithSuffix('_left'));
495 }
496
497 public function Right() {
498 return $this->renderWith($this->getTemplatesWithSuffix('_right'));
499 }
500
501 public function getRecord($id, $className = null) {
502 if($id && is_numeric($id)) {
503 if(!$className) $className = $this->stat('tree_class');
504 return DataObject::get_by_id($className, $id);
505 }
506 }
507
508 509 510 511 512 513 514 515
516 function getSiteTreeFor($className, $rootID = null, $childrenMethod = null, $numChildrenMethod = null, $filterFunction = null, $minNodeCount = 30) {
517
518 if (!$childrenMethod) $childrenMethod = 'AllChildrenIncludingDeleted';
519 if (!$numChildrenMethod) $numChildrenMethod = 'numChildren';
520
521
522 $obj = $rootID ? $this->getRecord($rootID) : singleton($className);
523
524
525 if ($filterFunction) $obj->setMarkingFilterFunction($filterFunction);
526
527 $obj->markPartialTree($minNodeCount, $this, $childrenMethod, $numChildrenMethod);
528
529
530 if($p = $this->currentPage()) $obj->markToExpose($p);
531
532
533 SiteTree::prepopuplate_permission_cache('CanEditType', $obj->markedNodeIDs(), 'SiteTree::can_edit_multiple');
534
535
536 $titleEval = '
537 "<li id=\"record-$child->ID\" class=\"" . $child->CMSTreeClasses($extraArg) . "\">" .
538 "<a href=\"" . Controller::join_links(substr($extraArg->Link(),0,-1), "show", $child->ID) . "\" class=\"" . $child->CMSTreeClasses($extraArg) . "\" title=\"' . _t('LeftAndMain.PAGETYPE','Page type: ') . '".$child->class."\" >" .
539 ($child->TreeTitle()) .
540 "</a>"
541 ';
542 $siteTree = $obj->getChildrenAsUL(
543 "",
544 $titleEval,
545 $this,
546 true,
547 $childrenMethod,
548 $numChildrenMethod,
549 $minNodeCount
550 );
551
552
553
554 if(!$rootID) {
555 $rootLink = $this->Link('show') . '/root';
556
557
558 if($this->hasMethod('getCMSTreeTitle') && $customTreeTitle = $this->getCMSTreeTitle()) {
559 $treeTitle = $customTreeTitle;
560 } else {
561 $siteConfig = SiteConfig::current_site_config();
562 $treeTitle = $siteConfig->Title;
563 }
564
565 $siteTree = "<ul id=\"sitetree\" class=\"tree unformatted\"><li id=\"record-0\" class=\"Root nodelete\"><a href=\"$rootLink\"><strong>$treeTitle</strong></a>"
566 . $siteTree . "</li></ul>";
567 }
568
569 return $siteTree;
570 }
571
572 573 574 575
576 public function getsubtree($request) {
577
578 $minNodeCount = (is_numeric($request->getVar('minNodeCount'))) ? $request->getVar('minNodeCount') : NULL;
579 $tree = $this->getSiteTreeFor(
580 $this->stat('tree_class'),
581 $request->getVar('ID'),
582 null,
583 null,
584 null,
585 $minNodeCount
586 );
587
588
589 $tree = ereg_replace('^[ \t\r\n]*<ul[^>]*>','', $tree);
590 $tree = ereg_replace('</ul[^>]*>[ \t\r\n]*$','', $tree);
591
592 return $tree;
593 }
594
595 596 597 598
599 public function returnItemToUser($p) {
600 if(Director::is_ajax()) {
601
602 $parentID = (int) $p->ParentID;
603 $id = $p->ID ? $p->ID : "new-$p->class-$p->ParentID";
604 $treeTitle = Convert::raw2js($p->TreeTitle());
605 $hasChildren = (is_numeric($id) && $p->AllChildren() && $p->AllChildren()->Count()) ? ' unexpanded' : '';
606
607
608 $response = <<<JS
609 var tree = $('sitetree');
610 var newNode = tree.createTreeNode("$id", "$treeTitle", "{$p->class}{$hasChildren}");
611 node = tree.getTreeNodeByIdx($parentID);
612 if(!node) {
613 node = tree.getTreeNodeByIdx(0);
614 }
615 node.open();
616 node.appendTreeNode(newNode);
617 newNode.selectTreeNode();
618 JS;
619 FormResponse::add($response);
620
621 return FormResponse::respond();
622 } else {
623 Director::redirect('admin/' . self::$url_segment . '/show/' . $p->ID);
624 }
625 }
626
627 628 629
630 public function save($urlParams, $form) {
631 $className = $this->stat('tree_class');
632
633 $SQL_id = Convert::raw2sql($_REQUEST['ID']);
634 if(substr($SQL_id,0,3) != 'new') {
635 $record = DataObject::get_one($className, "\"$className\".\"ID\" = {$SQL_id}");
636 if($record && !$record->canEdit()) return Security::permissionFailure($this);
637 } else {
638 if(!singleton($this->stat('tree_class'))->canCreate()) return Security::permissionFailure($this);
639 $record = $this->getNewItem($SQL_id, false);
640 }
641
642
643 $dataFields_new = $form->Fields()->dataFields();
644 $dataFields_old = $record->getAllFields();
645 $changed = false;
646 $hasNonRecordFields = false;
647 foreach($dataFields_new as $datafield) {
648
649 if(!isset($dataFields_old[$datafield->Name()])) {
650 $hasNonRecordFields = true;
651 }
652
653 if(!isset($dataFields_old[$datafield->Name()]) || $dataFields_old[$datafield->Name()] != $datafield->dataValue()) {
654 $changed = true;
655 }
656 }
657
658 if(!$changed && !$hasNonRecordFields) {
659
660 if(is_a($record, "Page")) {
661 $record->Status = "Saved (update)";
662 }
663 FormResponse::status_message(_t('LeftAndMain.SAVEDUP',"Saved"), "good");
664 FormResponse::update_status($record->Status);
665 return FormResponse::respond();
666 }
667
668 $form->dataFieldByName('ID')->Value = 0;
669
670 if(isset($urlParams['Sort']) && is_numeric($urlParams['Sort'])) {
671 $record->Sort = $urlParams['Sort'];
672 }
673
674
675 $originalClass = $record->ClassName;
676 $originalStatus = $record->Status;
677 $originalParentID = $record->ParentID;
678
679 $originalBrokenLinkValues = $record->HasBrokenLink.$record->HasBrokenFile;
680
681 $record->HasBrokenLink = 0;
682 $record->HasBrokenFile = 0;
683
684 $record->writeWithoutVersion();
685
686
687 $originalURLSegment = $record->URLSegment;
688
689 $form->saveInto($record, true);
690
691 if(is_a($record, "Page")) {
692 $record->Status = ($record->Status == "New page" || $record->Status == "Saved (new)") ? "Saved (new)" : "Saved (update)";
693 }
694
695 if(Director::is_ajax()) {
696 if($SQL_id != $record->ID) {
697 FormResponse::add("$('sitetree').setNodeIdx(\"{$SQL_id}\", \"$record->ID\");");
698 FormResponse::add("$('Form_EditForm').elements.ID.value = \"$record->ID\";");
699 }
700
701 if($added = DataObjectLog::getAdded('SiteTree')) {
702 foreach($added as $page) {
703 if($page->ID != $record->ID) FormResponse::add($this->addTreeNodeJS($page));
704 }
705 }
706 if($deleted = DataObjectLog::getDeleted('SiteTree')) {
707 foreach($deleted as $page) {
708 if($page->ID != $record->ID) FormResponse::add($this->deleteTreeNodeJS($page));
709 }
710 }
711 if($changed = DataObjectLog::getChanged('SiteTree')) {
712 foreach($changed as $page) {
713 if($page->ID != $record->ID) {
714 $title = Convert::raw2js($page->TreeTitle());
715 FormResponse::add("$('sitetree').setNodeTitle($page->ID, \"$title\");");
716 }
717 }
718 }
719
720 $message = _t('LeftAndMain.SAVEDUP');
721
722
723 if($originalClass != $record->ClassName) {
724 $newClassName = $record->ClassName;
725
726
727
728 $record->setClassName($originalClass);
729
730 $record = $record->newClassInstance($newClassName);
731
732
733 FormResponse::add("if(\$('sitetree').setNodeIcon) \$('sitetree').setNodeIcon($record->ID, '$originalClass', '$record->ClassName');");
734 }
735
736
737
738 if( ( $originalURLSegment != $record->URLSegment) ||
739 ($originalClass != $record->ClassName) || self::$ForceReload == true) {
740
741 FormResponse::add($str = "$('Form_EditForm').getPageFromServer($record->ID);", $str);
742 }
743
744
745
746
747
748
749 if($originalParentID != $record->ParentID) {
750 FormResponse::add("if(\$('sitetree').setNodeParentID) \$('sitetree').setNodeParentID($record->ID, $record->ParentID);");
751 }
752
753
754
755 $record->write();
756
757 if( ($record->class != 'VirtualPage') && $originalURLSegment != $record->URLSegment) {
758 $message .= sprintf(_t('LeftAndMain.CHANGEDURL'," Changed URL to '%s'"),$record->URLSegment);
759 FormResponse::add("\$('Form_EditForm').elements.URLSegment.value = \"$record->URLSegment\";");
760 FormResponse::add("\$('Form_EditForm_StageURLSegment').value = \"" . $record->AbsoluteLink() . "\";");
761 }
762
763 if($virtualPages = DataObject::get("VirtualPage", "\"CopyContentFromID\" = $record->ID")) {
764 foreach($virtualPages as $page) {
765 if($page->ID != $record->ID) {
766 $title = Convert::raw2js($page->TreeTitle());
767 FormResponse::add("$('sitetree').setNodeTitle($page->ID, \"$title\");");
768 }
769 }
770 }
771
772
773 if ($originalBrokenLinkValues != $record->HasBrokenLink.$record->HasBrokenFile) {
774
775 FormResponse::add($str = "$('Form_EditForm').getPageFromServer($record->ID);", $str);
776 }
777
778
779 if (isset($urlParams['publish']) && $urlParams['publish'] == 1) {
780 $this->extend('onAfterSave', $record);
781
782 $record->doPublish();
783
784
785 $record->setClassName($originalClass);
786 $publishedRecord = $record->newClassInstance($record->ClassName);
787
788 return $this->tellBrowserAboutPublicationChange(
789 $publishedRecord,
790 sprintf(
791 _t(
792 'LeftAndMain.STATUSPUBLISHEDSUCCESS',
793 "Published '%s' successfully",
794 PR_MEDIUM,
795 'Status message after publishing a page, showing the page title'
796 ),
797 $record->Title
798 )
799 );
800 } else {
801
802 $title = Convert::raw2js($record->TreeTitle());
803 FormResponse::add("$('sitetree').setNodeTitle(\"$record->ID\", \"$title\");");
804 FormResponse::add($this->getActionUpdateJS($record));
805 FormResponse::status_message($message, "good");
806 FormResponse::update_status($record->Status);
807
808 $this->extend('onAfterSave', $record);
809
810 return FormResponse::respond();
811 }
812 }
813 }
814
815 816 817 818 819
820 public function getActionUpdateJS($record) {
821
822
823 $tempForm = $this->getEditForm($record->ID);
824 $actionList = '';
825 foreach($tempForm->Actions() as $action) {
826 $actionList .= $action->Field() . ' ';
827 }
828
829 return "$('Form_EditForm').loadActionsFromString('" . Convert::raw2js($actionList) . "');";
830 }
831
832 833 834 835 836
837 public function addTreeNodeJS($page, $select = false) {
838 $parentID = (int)$page->ParentID;
839 $title = Convert::raw2js($page->TreeTitle());
840 $response = <<<JS
841 var newNode = $('sitetree').createTreeNode($page->ID, "$title", "$page->class");
842 var parentNode = $('sitetree').getTreeNodeByIdx($parentID);
843 if(parentNode) parentNode.appendTreeNode(newNode);
844 JS;
845 $response .= ($select ? "newNode.selectTreeNode();\n" : "") ;
846 return $response;
847 }
848 849 850 851 852
853 public function deleteTreeNodeJS($page) {
854 $id = $page->ID ? $page->ID : $page->OldID;
855 $response = <<<JS
856 var node = $('sitetree').getTreeNodeByIdx($id);
857 if(node && node.parentTreeNode) node.parentTreeNode.removeTreeNode(node);
858 $('Form_EditForm').closeIfSetTo($id);
859 JS;
860
861
862 if(Session::get("{$this->class}.currentPage") == $id) {
863 $this->setCurrentPageID(null);
864 }
865
866 return $response;
867 }
868
869 870 871
872 static function ForceReload(){
873 self::$ForceReload = true;
874 }
875
876 877 878
879 public function ajaxupdateparent() {
880 $id = $_REQUEST['ID'];
881 $parentID = $_REQUEST['ParentID'];
882 if($parentID == 'root'){
883 $parentID = 0;
884 }
885 $_REQUEST['ajax'] = 1;
886 $cleanupJS = '';
887
888 if (!Permission::check('SITETREE_REORGANISE') && !Permission::check('ADMIN')) {
889 FormResponse::status_message(_t('LeftAndMain.CANT_REORGANISE',"You do not have permission to rearange the site tree. Your change was not saved."),"bad");
890 return FormResponse::respond();
891 }
892
893 if(is_numeric($id) && is_numeric($parentID) && $id != $parentID) {
894 $node = DataObject::get_by_id($this->stat('tree_class'), $id);
895 if($node){
896 if(!$node->canEdit() || ($node->hasMethod('checkDevPermisson') && !$node->checkDevPermisson(null,'canReorder'))){
897 return Security::permissionFailure($this);
898 }
899
900 $node->ParentID = $parentID;
901 $node->Status = "Saved (update)";
902 $node->write();
903
904 if(is_numeric($_REQUEST['CurrentlyOpenPageID'])) {
905 $currentPage = DataObject::get_by_id($this->stat('tree_class'), $_REQUEST['CurrentlyOpenPageID']);
906 if($currentPage) {
907 $cleanupJS = $currentPage->cmsCleanup_parentChanged();
908 }
909 }
910
911 FormResponse::status_message(_t('LeftAndMain.SAVED','saved'), 'good');
912 if($cleanupJS) FormResponse::add($cleanupJS);
913
914 }else{
915 FormResponse::status_message(_t('LeftAndMain.PLEASESAVE',"Please Save Page: This page could not be upated because it hasn't been saved yet."),"good");
916 }
917
918
919 return FormResponse::respond();
920 } else {
921 user_error("Error in ajaxupdateparent request; id=$id, parentID=$parentID", E_USER_ERROR);
922 }
923 }
924
925 926 927 928 929
930 public function ajaxupdatesort() {
931 $className = $this->stat('tree_class');
932 $counter = 0;
933 $js = '';
934 $_REQUEST['ajax'] = 1;
935
936 if (!Permission::check('SITETREE_REORGANISE') && !Permission::check('ADMIN')) {
937 FormResponse::status_message(_t('LeftAndMain.CANT_REORGANISE',"You do not have permission to rearange the site tree. Your change was not saved."),"bad");
938 return FormResponse::respond();
939 }
940
941 if(is_array($_REQUEST['ID'])) {
942 if($_REQUEST['MovedNodeID']==0){
943 $movedNode = DataObject::get($className, "\"ParentID\"=0");
944 }else{
945 $movedNode = DataObject::get_by_id($className, $_REQUEST['MovedNodeID']);
946 }
947 foreach($_REQUEST['ID'] as $id) {
948 if($id == $movedNode->ID) {
949 $movedNode->Sort = ++$counter;
950 $movedNode->Status = "Saved (update)";
951 $movedNode->write();
952
953 $title = Convert::raw2js($movedNode->TreeTitle());
954 $js .="$('sitetree').setNodeTitle($movedNode->ID, \"$title\");\n";
955
956
957 } else if(is_numeric($id)) {
958 ++$counter;
959 DB::query("UPDATE \"$className\" SET \"Sort\" = $counter WHERE \"ID\" = '$id'");
960 }
961 }
962 FormResponse::status_message(_t('LeftAndMain.SAVED'), 'good');
963 } else {
964 FormResponse::error(_t('LeftAndMain.REQUESTERROR',"Error in request"));
965 }
966
967 return FormResponse::respond();
968 }
969
970 public function CanOrganiseSitetree() {
971 return !Permission::check('SITETREE_REORGANISE') && !Permission::check('ADMIN') ? false : true;
972 }
973
974 975 976
977 public function deleteitems() {
978 $ids = split(' *, *', $_REQUEST['csvIDs']);
979
980 $script = "st = \$('sitetree'); \n";
981 foreach($ids as $id) {
982 if(is_numeric($id)) {
983 $record = DataObject::get_by_id($this->stat('tree_class'), $id);
984 if($record && !$record->canDelete()) return Security::permissionFailure($this);
985
986 DataObject::delete_by_id($this->stat('tree_class'), $id);
987 $script .= "node = st.getTreeNodeByIdx($id); if(node) node.parentTreeNode.removeTreeNode(node); $('Form_EditForm').closeIfSetTo($id); \n";
988
989 }
990 }
991
992 FormResponse::add($script);
993
994 return FormResponse::respond();
995 }
996
997 998 999 1000 1001 1002
1003 function EmptyForm() {
1004 $form = new Form(
1005 $this,
1006 "EditForm",
1007 new FieldSet(
1008 new HeaderField(
1009 'WelcomeHeader',
1010 $this->getApplicationName()
1011 ),
1012 new LiteralField(
1013 'WelcomeText',
1014 sprintf('<p id="WelcomeMessage">%s %s. %s</p>',
1015 _t('LeftAndMain_right.ss.WELCOMETO','Welcome to'),
1016 $this->getApplicationName(),
1017 _t('CHOOSEPAGE','Please choose an item from the left.')
1018 )
1019 )
1020 ),
1021 new FieldSet()
1022 );
1023 $form->unsetValidator();
1024
1025 return $form;
1026 }
1027
1028 public function EditForm() {
1029
1030 HtmlEditorField::include_js();
1031
1032 if ($this->currentPageID() != 0) {
1033 $record = $this->currentPage();
1034 if(!$record) return false;
1035 if($record && !$record->canView()) return Security::permissionFailure($this);
1036 }
1037 if ($this->hasMethod('getEditForm')) {
1038 return $this->getEditForm($this->currentPageID());
1039 }
1040
1041 return false;
1042 }
1043
1044 public function myprofile() {
1045 $form = $this->Member_ProfileForm();
1046 return $this->customise(array(
1047 'Form' => $form
1048 ))->renderWith('BlankPage');
1049 }
1050
1051 public function Member_ProfileForm() {
1052 return new Member_ProfileForm($this, 'Member_ProfileForm', Member::currentUser());
1053 }
1054
1055 public function printable() {
1056 $id = $_REQUEST['ID'] ? $_REQUEST['ID'] : $this->currentPageID();
1057
1058 if($id) $form = $this->getEditForm($id);
1059 $form->transform(new PrintableTransformation());
1060 $form->actions = null;
1061
1062 Requirements::clear();
1063 Requirements::css(CMS_DIR . '/css/LeftAndMain_printable.css');
1064 return array(
1065 "PrintForm" => $form
1066 );
1067 }
1068
1069 public function currentPageID() {
1070 if(isset($_REQUEST['ID']) && is_numeric($_REQUEST['ID'])) {
1071 return $_REQUEST['ID'];
1072 } elseif (isset($this->urlParams['ID']) && is_numeric($this->urlParams['ID'])) {
1073 return $this->urlParams['ID'];
1074 } elseif(Session::get("{$this->class}.currentPage")) {
1075 return Session::get("{$this->class}.currentPage");
1076 } else {
1077 return null;
1078 }
1079 }
1080
1081 public function setCurrentPageID($id) {
1082 Session::set("{$this->class}.currentPage", $id);
1083 }
1084
1085 public function currentPage() {
1086 return $this->getRecord($this->currentPageID());
1087 }
1088
1089 public function isCurrentPage(DataObject $page) {
1090 return $page->ID == Session::get("{$this->class}.currentPage");
1091 }
1092
1093 1094 1095 1096 1097 1098 1099
1100
1101 1102 1103
1104 public function EditorToolbar() {
1105 return Object::create('HtmlEditorField_Toolbar', $this, "EditorToolbar");
1106 }
1107
1108 1109 1110 1111 1112 1113 1114
1115 public function CMSVersion() {
1116 if (file_exists(BASE_PATH . '/webylon/.version'))
1117 return file_get_contents(BASE_PATH . '/webylon/.version');
1118
1119 $sapphireVersionFile = file_get_contents(BASE_PATH . '/sapphire/silverstripe_version');
1120 $cmsVersionFile = file_get_contents(BASE_PATH . '/cms/silverstripe_version');
1121
1122 $sapphireVersion = $this->versionFromVersionFile($sapphireVersionFile);
1123 $cmsVersion = $this->versionFromVersionFile($cmsVersionFile);
1124
1125 if($sapphireVersion == $cmsVersion) {
1126 return $sapphireVersion;
1127 } else {
1128 return "cms: $cmsVersion, sapphire: $sapphireVersion";
1129 }
1130 }
1131
1132 1133 1134
1135 public function versionFromVersionFile($fileContent) {
1136 if(preg_match('/\/trunk\/silverstripe_version/', $fileContent)) {
1137 return "trunk";
1138 } else {
1139 preg_match("/\/(?:branches|tags\/rc|tags\/beta|tags\/alpha|tags)\/([A-Za-z0-9._-]+)\/silverstripe_version/", $fileContent, $matches);
1140 return ($matches) ? $matches[1] : null;
1141 }
1142 }
1143
1144 1145 1146
1147 function SwitchView() {
1148 if($page = $this->currentPage()) {
1149 $nav = SilverStripeNavigator::get_for_record($page);
1150 return $nav['items'];
1151 }
1152 }
1153
1154 1155 1156 1157 1158 1159
1160 static $application_name = 'SilverStripe CMS';
1161
1162 1163 1164 1165 1166 1167
1168 static $application_logo_text = 'SilverStripe';
1169
1170 1171 1172 1173 1174 1175
1176 static $application_link = "http://www.silverstripe.org/";
1177 static function setApplicationName($name, $logoText = null, $link = null) {
1178 self::$application_name = $name;
1179 self::$application_logo_text = $logoText ? $logoText : $name;
1180 if($link) self::$application_link = $link;
1181 }
1182
1183 1184 1185 1186
1187 function getApplicationName() {
1188 return self::$application_name;
1189 }
1190
1191 1192 1193 1194
1195 function getApplicationLogoText() {
1196 return self::$application_logo_text;
1197 }
1198 function ApplicationLink() {
1199 return self::$application_link;
1200 }
1201
1202 1203 1204
1205 function SectionTitle() {
1206
1207 $menu = $this->obj('MainMenu');
1208
1209 foreach($menu as $menuItem) {
1210 if($menuItem->LinkingMode == 'current') return $menuItem->Title;
1211 }
1212 }
1213
1214 1215 1216 1217 1218 1219
1220 static $application_logo = 'cms/images/mainmenu/logo.gif';
1221
1222 1223 1224 1225 1226 1227
1228 static $application_logo_style = '';
1229
1230 1231 1232 1233 1234 1235 1236
1237 static function setLogo($logo, $logoStyle) {
1238 self::$application_logo = $logo;
1239 self::$application_logo_style = $logoStyle;
1240 self::$application_logo_text = '';
1241 }
1242
1243 protected static $loading_image = 'cms/images/loading.gif';
1244
1245 1246 1247
1248 static function set_loading_image($loadingImage) {
1249 self::$loading_image = $loadingImage;
1250 }
1251
1252 function LoadingImage() {
1253 return self::$loading_image;
1254 }
1255
1256 function LogoStyle() {
1257 return "background: url(" . self::$application_logo . ") no-repeat; " . self::$application_logo_style;
1258 }
1259
1260 1261 1262
1263 function MceRoot() {
1264 return MCE_ROOT;
1265 }
1266
1267 1268 1269
1270 function callPageMethod($data, $form) {
1271 $methodName = $form->buttonClicked()->extraData();
1272 $record = $this->currentPage();
1273 if(!$record) return false;
1274
1275 return $record->$methodName($data, $form);
1276 }
1277
1278 1279 1280 1281
1282 public static function require_javascript($file) {
1283 self::$extra_requirements['javascript'][] = array($file);
1284 }
1285
1286 1287 1288 1289 1290 1291 1292
1293 public static function require_css($file, $media = null) {
1294 self::$extra_requirements['css'][] = array($file, $media);
1295 }
1296
1297 1298 1299 1300 1301 1302 1303 1304
1305 static function require_themed_css($name, $media = null) {
1306 self::$extra_requirements['themedcss'][] = array($name, $media);
1307 }
1308 }
1309
1310
[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.
-