From ee220bbccec4c40258c74288ba30c383b5ed6868 Mon Sep 17 00:00:00 2001 From: Julian Seidenberg Date: Tue, 3 Apr 2012 18:06:35 +1200 Subject: [PATCH] API-CHANGE: SSF-168 initial rearranging the SS_Report class for use in SS3. Deprecating unnecessary methods, moving code around, rewriting get_reports method and writing unit tests --- code/reports/Report.php | 187 +++++++++++++++-------------------- tests/reports/ReportTest.php | 36 +++++-- 2 files changed, 108 insertions(+), 115 deletions(-) diff --git a/code/reports/Report.php b/code/reports/Report.php index 3592869f..5c7862d0 100644 --- a/code/reports/Report.php +++ b/code/reports/Report.php @@ -35,19 +35,13 @@ * Showing reports to the user * =========================== * - * Right now, all subclasses of SS_Report will be shown in the ReportAdmin. However, we are planning - * on adding an explicit registration mechanism, so that you can decide which reports go in the - * report admin, and which go elsewhere (such as the side panel in the CMS). + * Right now, all subclasses of SS_Report will be shown in the ReportAdmin. In SS3 there is only + * one place where reports can go, so this class is greatly simplifed from from its version in SS2. * * @package cms * @subpackage reports */ class SS_Report extends ViewableData { - /** - * Report registry populated by {@link SS_Report::register()} - */ - private static $registered_reports = array(); - /** * This is the title of the report, * used by the ReportAdmin templates. @@ -70,6 +64,22 @@ class SS_Report extends ViewableData { * Set by overriding in your subclass. */ protected $dataClass = 'SiteTree'; + + /** + * A field that specifies the sort order of this report + * @var int + */ + protected $sort = 0; + + /** + * Reports which should not be collected and returned in get_reports + * @var array + */ + public static $excluded_reports = array( + 'SS_Report', + 'SS_ReportWrapper', + 'SideReportWrapper' + ); /** * Return the title of this report. @@ -93,22 +103,12 @@ class SS_Report extends ViewableData { return $this->description; } - /** - * Return a FieldList specifying the search criteria for this report. - * - * Override this method to define search criteria. - */ - function parameterFields() { - return null; - } - /** * Return the {@link SQLQuery} that provides your report data. */ function sourceQuery($params) { if($this->hasMethod('sourceRecords')) { $query = new SS_Report_FakeQuery($this, 'sourceRecords', $params); - $query->setSortColumnMethod('sortColumns'); return $query; } else { user_error("Please override sourceQuery()/sourceRecords() and columns() or, if necessary, override getReportField()", E_USER_ERROR); @@ -126,29 +126,7 @@ class SS_Report extends ViewableData { } } - /** - * Return an map of columns for your report. - * - The map keys will be the source columns for your report (in TableListField dot syntax) - * - The values can either be a string (the column title), or a map containing the following - * column parameters: - * - title: The column title - * - formatting: A formatting string passed to {@link TableListField::setFieldFormatting()} - */ - function columns() { - user_error("Please override sourceQuery() and columns() or, if necessary, override getReportField()", E_USER_ERROR); - } - - function sortColumns() { - return array_keys($this->columns()); - } - - /** - * Return the number of records in this report with no filters applied. - */ - function count() { - return (int)$this->sourceQuery(array())->unlimitedRowCount(); - } - + /** * Return the data class for this report */ @@ -157,6 +135,67 @@ class SS_Report extends ViewableData { } + + /** + * @deprecated 3.0 + * All subclasses of SS_Report now appear in the report admin, no need to register or unregister. + * + * Register a report. + * @param $list The list to add the report to: "ReportAdmin" or "SideReports" + * @param $reportClass The class of the report to add. + * @param $priority The priority. Higher numbers will appear furhter up in the reports list. + * The default value is zero. + */ + static function register($list, $reportClass, $priority = 0) { + } + + /** + * @deprecated 3.0 + * All subclasses of SS_Report now appear in the report admin, no need to register or unregister. + */ + static function unregister($list, $reportClass) { + self::excludeReport($reportClass); + } + + /** + * Exclude a certain report class from the list of Reports in the CMS + * @static + * @param $reportClass + */ + static function excludeReport($reportClass) { + self::$excluded_reports[] = $reportClass; //add to the excluded reports, so this report doesn't get used + } + + /** + * Return the SS_Report objects making up the given list. + * @return An array of SS_Report objects + */ + static function get_reports() { + $reports = ClassInfo::subclassesFor(get_called_class()); + + $reportsArray = array(); + if ($reports && count($reports) > 0) { + //collect reports into array with an attribute for 'sort' + foreach($reports as $report) { + if (in_array($report, self::$excluded_reports)) continue; //don't use the SS_Report superclass + $reportObj = new $report; + if (method_exists($reportObj,'sort')) $reportObj->sort = $reportObj->sort(); //use the sort method to specify the sort field + $reportsArray[] = $reportObj; + } + } + + //convert array into ArrayList + $list = ArrayList::create($reportsArray); + + //sort + $list->sort('sort'); + + return $list; + } + + /////////////////////// UI METHODS /////////////////////// + + /** * Returns a FieldList with which to create the CMS editing form. * You can use the extend() method of FieldList to create customised forms for your other @@ -273,72 +312,10 @@ class SS_Report extends ViewableData { * @return string */ function TreeTitle() { - return $this->title();/* . ' (' . $this->count() . ')'; - this is too slow atm */ + return $this->title(); } - /** - * Return the ID of this Report class. - * Because it doesn't have a number, we - * use the class name as the ID. - * - * @return string - */ - function ID() { - return $this->class; - } - - ///////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Register a report. - * @param $list The list to add the report to: "ReportAdmin" or "SideReports" - * @param $reportClass The class of the report to add. - * @param $priority The priority. Higher numbers will appear furhter up in the reports list. - * The default value is zero. - */ - static function register($list, $reportClass, $priority = 0) { - if(strpos($reportClass, '(') === false && (!class_exists($reportClass) || !is_subclass_of($reportClass,'SS_Report'))) { - user_error("SS_Report::register(): '$reportClass' is not a subclass of SS_Report", E_USER_WARNING); - return; - } - - self::$registered_reports[$list][$reportClass] = $priority; - } - - /** - * Unregister a report, removing it from the list - */ - static function unregister($list, $reportClass) { - unset(self::$registered_reports[$list][$reportClass]); - } - - /** - * Return the SS_Report objects making up the given list. - * @return An array of SS_Report objects - */ - static function get_reports($list) { - $output = array(); - if(isset(self::$registered_reports[$list])) { - $listItems = self::$registered_reports[$list]; - // Sort by priority, preserving internal order of items with the same priority - $groupedItems = array(); - foreach($listItems as $k => $v) { - $groupedItems[$v][] = $k; - } - krsort($groupedItems); - $sortedListItems = call_user_func_array('array_merge', $groupedItems); - - foreach($sortedListItems as $report) { - if(strpos($report,'(') === false) $reportObj = new $report; - else $reportObj = eval("return new $report;"); - - $output[$reportObj->ID()] = $reportObj; - } - } - - return $output; - } } @@ -370,7 +347,7 @@ class SS_Report_FakeQuery extends SQLQuery { $this->method = $method; $this->params = $params; } - + /** * Provide a method that will return a list of columns that can be used to sort. */ diff --git a/tests/reports/ReportTest.php b/tests/reports/ReportTest.php index a5c74d2e..16bc3bed 100644 --- a/tests/reports/ReportTest.php +++ b/tests/reports/ReportTest.php @@ -1,18 +1,34 @@ assertTrue($report->sourceQuery(array())->canSortBy('Title ASC')); - $this->assertTrue($report->sourceQuery(array())->canSortBy('Title DESC')); - $this->assertTrue($report->sourceQuery(array())->canSortBy('Title')); - } function testGetReports() { $reports = SS_Report::get_reports(); $this->assertNotNull($reports, "Reports returned"); - Debug::Show($reports); + $previousSort = 0; + foreach($reports as $report) { + $this->assertGreaterThanOrEqual($previousSort, $report->sort, "Reports are in correct sort order"); + $previousSort = $report->sort; + } + } + + function testExcludeReport() { + $reports = SS_Report::get_reports(); + $reportNames = array(); + foreach($reports as $report) { + $reportNames[] = $report->class; + } + $this->assertContains('ReportTest_FakeTest',$reportNames,'ReportTest_FakeTest is in reports list'); + + //excluse one report + SS_Report::excludeReport('ReportTest_FakeTest'); + + $reports = SS_Report::get_reports(); + $reportNames = array(); + foreach($reports as $report) { + $reportNames[] = $report->class; + } + $this->assertNotContains('ReportTest_FakeTest',$reportNames,'ReportTest_FakeTest is NOT in reports list'); } } @@ -39,12 +55,12 @@ class ReportTest_FakeTest extends SS_Report implements TestOnly { class ReportTest_FakeTest2 extends SS_Report implements TestOnly { function title() { - return 'Report title'; + return 'Report title 2'; } function columns() { return array( "Title" => array( - "title" => "Page Title" + "title" => "Page Title 2" ) ); }