'handleAction' ); /** * Variable that describes which report we are currently viewing based on * the URL (gets set in init method). * * @var string */ protected $reportClass; /** * @var Report */ protected $reportObject; private static $required_permission_codes = 'CMS_ACCESS_ReportAdmin'; public function init() { parent::init(); // Set custom options for TinyMCE specific to ReportAdmin HTMLEditorConfig::get('cms')->setOption('content_css', project() . '/css/editor.css'); Requirements::javascript('silverstripe/reports: javascript/ReportAdmin.js'); } /** * Does the parent permission checks, but also * makes sure that instantiatable subclasses of * {@link SilverStripe\Reports\Report} exist. By default, the CMS doesn't * include any Reports, so there's no point in showing * * @param Member $member * @return boolean */ public function canView($member = null) { if (!$member && $member !== false) { $member = Security::getCurrentUser(); } if (!parent::canView($member)) { return false; } foreach ($this->Reports() as $report) { if ($report->canView($member)) { return true; } } return false; } /** * Return a SS_List of SS_Report subclasses * that are available for use. * * @return SS_List */ public function Reports() { $output = ArrayList::create(); foreach (Report::get_reports() as $report) { if ($report->canView()) { $output->push($report); } } return $output ->sort('Title', 'ASC') ->setDataClass(Report::class); } public function handleAction($request, $action) { $this->reportClass = $this->unsanitiseClassName($request->param('ReportClass')); // Check report if ($this->reportClass) { $allReports = Report::get_reports(); if (empty($allReports[$this->reportClass])) { return $this->httpError(404); } $this->reportObject = $allReports[$this->reportClass]; if (!$this->reportObject->canView()) { return Security::permissionFailure($this); } } // Delegate to sub-form return parent::handleAction($request, $action); } /** * Unsanitise a model class' name from a URL param * * @param string $class * @return string */ protected function unsanitiseClassName($class) { return str_replace('-', '\\', $class ?? ''); } /** * Determine if we have reports and need * to display the "Reports" main menu item * in the CMS. * * The test for an existance of a report * is done by checking for a subclass of * "SS_Report" that exists. * * @return boolean */ public static function has_reports() { return sizeof(Report::get_reports() ?? []) > 0; } /** * Returns the Breadcrumbs for the ReportAdmin */ public function Breadcrumbs($unlinked = false) { $items = parent::Breadcrumbs($unlinked); // The root element should explicitly point to the root node. // Uses session state for current record otherwise. $items[0]->Link = singleton('SilverStripe\\Reports\\ReportAdmin')->Link(); if ($report = $this->reportObject) { $breadcrumbs = $report->getBreadcrumbs(); if (!empty($breadcrumbs)) { foreach ($breadcrumbs as $crumb) { $items->push($crumb); } } //build breadcrumb trail to the current report $items->push(ArrayData::create([ 'Title' => $report->title(), 'Link' => Controller::join_links( $this->Link(), '?' . http_build_query(['q' => $this->request->requestVar('q')]) ) ])); } return $items; } /** * Returns the link to the report admin section, or the specific report that is currently displayed * * @param string $action * @return string */ public function Link($action = null) { if ($this->reportObject) { return $this->reportObject->getLink($action); } // Basic link to this cms section return parent::Link($action); } public function providePermissions() { return array( "CMS_ACCESS_ReportAdmin" => array( 'name' => _t('SilverStripe\\CMS\\Controllers\\CMSMain.ACCESS', "Access to '{title}' section", array( 'title' => static::menu_title() )), 'category' => _t('SilverStripe\\Security\\Permission.CMS_ACCESS_CATEGORY', 'CMS Access') ) ); } public function getEditForm($id = null, $fields = null) { $report = $this->reportObject; if ($report) { $fields = $report->getCMSFields(); } else { // List all reports $fields = FieldList::create(); $gridFieldConfig = GridFieldConfig::create()->addComponents( // This is a container component that is required by filter header component GridFieldButtonRow::create('before'), $filterHeader = GridFieldFilterHeader::create(), GridFieldSortableHeader::create(), $columns = GridFieldDataColumns::create(), GridFieldPageCount::create(), GridFieldPaginator::create() ); $titleLabel = _t('SilverStripe\\Reports\\ReportAdmin.ReportTitle', 'Title'); $descriptionLabel = _t('SilverStripe\\Reports\\ReportAdmin.ReportDescription', 'Description'); // Configure the filter header filter search form $generalField = BasicSearchContext::config()->get('general_search_field_name'); $searchFieldList = FieldList::create([ HiddenField::create($generalField), TextField::create('Title', $titleLabel), TextField::create('Description', $descriptionLabel), ]); $searchContext = BasicSearchContext::create(Report::class); $searchContext->setFields($searchFieldList); // Setup filter configuration - partial match with case-insensitive modifier $filters = [ 'Title', 'Description', ]; foreach ($filters as $fieldName) { $fieldFilter = PartialMatchFilter::create($fieldName); $searchContext->addFilter($fieldFilter); } $filterHeader->setSearchContext($searchContext); $gridField = GridField::create('Reports', false, $this->Reports(), $gridFieldConfig); $columns->setDisplayFields(array( 'title' => $titleLabel, 'description' => $descriptionLabel, )); $columns->setFieldFormatting([ 'title' => '$value ($CountForOverview)' ]); $gridField->addExtraClass('all-reports-gridfield'); $fields->push($gridField); } $actions = FieldList::create(); $form = Form::create($this, "EditForm", $fields, $actions); $form->addExtraClass( 'panel panel--padded panel--scrollable cms-edit-form cms-panel-padded' . $this->BaseCSSClasses() ); $form->loadDataFrom($this->request->getVars()); $this->extend('updateEditForm', $form); return $form; } }