Source of file DashboardController.php
Size: 17,275 Bytes - Last Modified: 2021-12-23T10:31:31+00:00
/var/www/docs.ssmods.com/process/src/code/controllers/DashboardController.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535 | <?php /** * @author Marcus Nyeholt <marcus@silverstripe.com.au> * @license BSD http://silverstripe.org/BSD-license */ class DashboardController extends FrontendModelController { private static $model_class = 'DashboardPage'; private static $include_default_requirements = true; private static $url_handlers = array( 'widget/$ID' => 'handleDashlet', 'dashlet/$ID' => 'handleDashlet', // what it should be 'board/$URLSegment/$MemberID' => 'handleBoard', 'user/$Identifier/$Segment' => 'handleUser', ); private static $allowed_actions = array( 'index', 'board', 'handleDashlet', 'handleBoard', 'adddashlet', 'AddDashletForm', 'updateDashboard', 'DashboardForm', 'editorfor', 'EditDashletForm', 'loaddashlet', 'deletedashlet' ); private static $allowed_dashlets = array(); private static $dependencies = array( 'injector' => '%$Injector', 'securityContext' => '%$SecurityContext', 'dataService' => '%$DataService', ); public $injector; public $securityContext; /** * @var DataService */ public $dataService; /** * @var DashboardPage */ protected $currentDashboard; public function __construct($page=null, $dashboard=null) { if ($dashboard && $dashboard instanceof DashboardPage) { $this->currentDashboard = $dashboard; } $dashlets = Config::inst()->get('DashboardController', 'allowed_dashlets'); if (!count($dashlets)) { $widgets = ClassInfo::subclassesFor('Dashlet'); array_shift($widgets); Config::inst()->update('DashboardController', 'allowed_dashlets', array_values($widgets)); } parent::__construct($page); } /** * Get the currnet dashboard that the user is viewing */ public function getCurrentDashboard() { return $this->currentDashboard; } public function init() { if (!$this->currentDashboard) { Restrictable::set_enabled(false); if (Member::currentUserID()) { Restrictable::set_enabled(true); $this->currentDashboard = $this->getDashboard(); } Restrictable::set_enabled(true); } parent::init(); if ($this->currentDashboard && !$this->currentDashboard->checkPerm('View')) { if (!Member::currentUserID() && !$this->redirectedTo()) { Security::permissionFailure($this, "You must be logged in"); return; } } if ($this->config()->include_default_requirements) { Requirements::block(THIRDPARTY_DIR . '/jquery/jquery.js'); Requirements::javascript('frontend-dashboards/javascript/jquery-1.10.2.min.js'); Requirements::javascript(THIRDPARTY_DIR . '/jquery-ui/jquery-ui.js'); Requirements::javascript(THIRDPARTY_DIR.'/jquery-form/jquery.form.js'); Requirements::javascript(THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js'); Requirements::javascript('frontend-dashboards/thirdparty/jquery-cookie/jquery.cookie.js'); Requirements::javascript(FRAMEWORK_DIR . '/javascript/jquery-ondemand/jquery.ondemand.js'); Requirements::javascript('frontend-dashboards/javascript/dashboards.js'); Requirements::javascript('frontend-dashboards/javascript/dashboard-dialogs.js'); Requirements::css('frontend-dashboards/css/dashboards.css'); Requirements::javascript('frontend-dashboards/javascript/jquery.gridster.min.js'); Requirements::css('frontend-dashboards/css/jquery.gridster.min.css'); } // Requirements::javascript('frontend-dashboards/javascript/jquery.gridly.js'); // Requirements::css('frontend-dashboards/css/jquery.gridly.css'); } public static function set_allowed_dashlets($dashlets) { Config::inst()->update('DashboardController', 'allowed_dashlets', $dashlets); self::$allowed_dashlets = $dashlets; } protected $allowedDashlets = null; public static function get_allowed_dashlets() { return Config::inst()->get('DashboardController', 'allowed_dashlets'); } public function handleUser($request) { $segment = $this->request->param('Segment'); $identifier = $this->request->param('Identifier'); try { $userId = (int) $identifier; if (!$userId) { $field = Member::get_unique_identifier_field(); $member = DataList::create('Member')->filter(array($field => $identifier))->first(); if ($member) { $userId = $member->ID; } } if (!$segment) { $segment = 'main'; } $board = $this->getDashboard($segment, $userId); } catch (PermissionDeniedException $pde) { return Security::permissionFailure($this, 'You do not have permission to view that'); } if ($board) { // need this call to make sure the params are properly processed $this->request->allParams(); $cls = get_class($this); $controller = $this->injector->create($cls, $this->dataRecord, $board); return $controller; } return $this->httpError(404, "Board $segment does not exist"); } public function handleBoard($request) { $segment = $this->request->param('URLSegment'); $userId = $this->request->param('MemberID'); try { $board = $this->getDashboard($segment, $userId); } catch (PermissionDeniedException $pde) { return Security::permissionFailure($this, 'You do not have permission to view that'); } if ($board) { // need this call to make sure the params are properly processed $this->request->allParams(); $cls = get_class($this); $controller = $this->injector->create($cls, $this->dataRecord, $board); return $controller; } return $this->httpError(404, "Board $segment does not exist"); } /** * Handles widgets attached to a page through one or more {@link WidgetArea} elements. * Iterated through each $has_one relation with a {@link WidgetArea} * and looks for connected widgets by their database identifier. * Assumes URLs in the following format: <URLSegment>/widget/<Widget-ID>. * * @return RequestHandler */ public function handleDashlet() { $SQL_id = $this->request->param('ID'); if (!$SQL_id) { return false; } // find widget $dataService = $this->dataService; $widget = $dataService->dashletById($SQL_id); if (!$widget) { throw new Exception("Invalid widget #$SQL_id"); } // find controller $controllerClass = ''; foreach (array_reverse(ClassInfo::ancestry($widget->class)) as $widgetClass) { $controllerClass = "{$widgetClass}_Controller"; if (class_exists($controllerClass)) { break; } } if (!$controllerClass) { user_error( sprintf('No controller available for %s', $widget->class), E_USER_ERROR ); } return $this->injector->create($controllerClass, $widget, $this); } public function getDashletsList() { if ($this->allowedDashlets) { return $this->allowedDashlets; } $dashlets = self::get_allowed_dashlets(); // prune any that have specific requirements foreach ($dashlets as $cls => $title) { $clazz = is_int($cls) ? $title : $cls; $dummy = singleton($clazz); if (!$dummy->canCreate()) { unset($dashlets[$cls]); } } $keys = array_keys($dashlets); if (count($keys) && is_int($keys[0])) { foreach (array_values($dashlets) as $dashletClass) { $title = Config::inst()->get($dashletClass, 'title'); if (!$title) { FormField::name_to_label($dashletClass); } $this->allowedDashlets[$dashletClass] = $title; } } else { $this->allowedDashlets = $dashlets; } return $this->allowedDashlets; } public function index() { $page = $this->currentDashboard ? $this->currentDashboard : $this->getDashboard(); if (!$page || !$page->exists()) { if (!$this->securityContext->getMember()) { return Security::permissionFailure($this, _t('DashboardController.USER_REQUIRED', 'You must be logged in to do that')); } $page = $this->securityContext->getMember()->getAnyDashboard(); $this->currentDashboard = $page; } return $this->customise(array('Dashboard' => $page))->renderWith(array('Dashboard', 'Page')); } /** * Handler for when the board action is triggered by a nested controller */ public function board() { return $this->index(); } public function user() { return $this->index(); } protected function getDashboard($name='main', $memberId = null) { if (is_int($memberId)) { // try and get the page from that user, if there's read access // we're deliberately loading the member without permission checks $member = Member::get()->byID($memberId); // $member = $this->dataService->memberById($memberId); if (!$member) { throw new PermissionDeniedException('View'); } } else { $member = $this->securityContext->getMember(); } if ($member) { $page = $member->getNamedDashboard($name); if ($page) { $page->setController($this); } return $page; } } /** * Called to update a dashboard structure */ public function updateDashboard() { $dashboardId = (int) $this->request->postVar('dashboard'); $items = (array) $this->request->postVar('order'); if ($dashboardId) { $dashboard = $this->dataService->memberDashboardById($dashboardId); if ($dashboard && $dashboard->exists()) { $dashboard->Widgets()->removeAll(); if (is_array($items)) { foreach ($items as $i => $widgetId) { $widget = $this->dataService->dashletById($widgetId); if ($widget) { $widget->ParentID = $dashboard->ID; $widget->Sort = $i+1; // need +1 here so there's no 0 sort val, otherwise onbeforewrite sets it automatically. $widget->write(); } } } } } } public function DashboardForm() { $fields = new FieldList( new TextField('Title', _t('Dashboard.TITLE', 'Title')) ); $actions = new FieldList(new FormAction('adddashboard', _t('Dashboard.ADD_NEW', 'Add Dashboard'))); $form = new Form($this, 'DashboardForm', $fields, $actions); return $form; } public function adddashboard($data, Form $form) { $title = isset($data['Title']) ? $data['Title'] : ''; if ($title) { $page = $this->securityContext->getMember()->createDashboard($title); $this->redirect($page->Link()); return; } else { $form->sessionMessage("Failed creating new dashboard", "bad"); } $this->redirect($this->Link()); } public function adddashlet() { return $this->AddDashletForm()->forAjaxTemplate(); } public function AddDashletForm() { $dashlets = array(); $dashlets = $this->getDashletsList(); asort($dashlets); $fields = new FieldList( DropdownField::create('DashletClass', 'Dashlet', $dashlets)->setEmptyString('Add dashlet...') ); return new Form($this, 'AddDashletForm', $fields, new FieldList( new FormAction('doAddDashlet', _t('Dashboards.ADD_DASHLET', 'Add Dashlet')) )); } public function doAddDashlet($data, $form) { $classes = $this->getDashletsList(); $type = $data['DashletClass']; if (isset($classes[$type])) { $stage = Versioned::current_stage(); Versioned::reading_stage('Stage'); $dashlet = $this->injector->create($type); if (!$dashlet->canCreate()) { throw new PermissionDeniedException('CreateChildren'); } $dashboard = $this->currentDashboard->getDashboard(0); $dashboard->addDashlet($dashlet); Versioned::reading_stage($stage); } if ($this->getRequest()->isAjax()) { $this->response->addHeader('Content-Type', 'application/json'); return '{"success": 1}'; } //return $this->redirect($this->currentDashboard->Link()); return $this->redirectBack(); } /** * Gets an editing form for the particular widget */ public function editorfor() { return $this->EditDashletForm()->forTemplate(); } public function EditDashletForm() { $dashlet = $this->getRequestedDashlet(); $fields = $dashlet->getDashletFields(); $fields->push(new HiddenField('DashletID', '', $dashlet->ID)); /* @var $fields FieldList */ // there's some that we KNOW we don't want $actions = new FieldList( new FormAction('savedashlet', 'Save'), new FormAction('deletedashlet', 'Delete') ); $form = new Form($this, 'EditDashletForm', $fields, $actions); $form->loadDataFrom($dashlet); return $form; } public function savedashlet($data, Form $form) { $dashlet = $this->getRequestedDashlet(); if ($dashlet->checkPerm('Write')) { $form->saveInto($dashlet); $dashlet->write(); return $this->editorfor(); } } public function deletedashlet($data, $form = null) { $dashlet = $this->getRequestedDashlet(); if ($dashlet->checkPerm('Delete')) { $dashlet->delete(); $this->response->addHeader('Content-Type', 'application/json'); $this->response->setBody('{ "success": true }'); return $this->response; } throw new PermissionDeniedException('Delete'); } public function loaddashlet() { $dashlet = $this->getRequestedDashlet(); $controller = $dashlet->class.'_Controller'; $renderObj = $dashlet; if (class_exists($controller)) { $renderObj = $this->injector->create($controller, $dashlet, $this); $renderObj->init(); } return $renderObj->renderWith('DashletLayout'); } protected function getRequestedDashlet() { $dashletId = (int) $this->request->requestVar('DashletID'); if (!$dashletId) { throw new Exception("Invalid $dashletId in request"); } $dashlet = $this->dataService->dashletById($dashletId); if (!$dashlet) { throw new Exception("Invalid dashlet #$dashletId"); } return $dashlet; } /** * Overridden to make sure the dashboard page is attached to the correct controller * @return type */ protected function getRecord() { $id = (int) $this->request->param('ID'); if (!$id) { $id = (int) $this->request->requestVar('ID'); } if ($id) { $type = $this->stat('model_class'); $action = $this->request->param('Action'); if ($action == 'dashlet' || $action == 'widget') { $type = 'Dashlet'; } $item = $this->dataService->byId($type, $id); if ($item instanceof DashboardPage) { $item->setController($this); } return $item; } } public function Link($action='') { if ($this->currentDashboard && $this->currentDashboard->URLSegment != 'main') { return $this->currentDashboard->Link($action); } return $this->dataRecord->Link($action); } public function Footer() { return $this->renderWith('DashboardFooter'); } } |