Compare commits

..

No commits in common. "4" and "4.6.0" have entirely different histories.
4 ... 4.6.0

27 changed files with 166 additions and 265 deletions

1
.codecov.yml Normal file
View File

@ -0,0 +1 @@
comment: false

View File

@ -1,11 +0,0 @@
name: CI
on:
push:
pull_request:
workflow_dispatch:
jobs:
ci:
name: CI
uses: silverstripe/gha-ci/.github/workflows/ci.yml@v1

View File

@ -1,16 +0,0 @@
name: Dispatch CI
on:
# At 11:00 AM UTC, only on Monday and Tuesday
schedule:
- cron: '0 11 * * 1,2'
jobs:
dispatch-ci:
name: Dispatch CI
# Only run cron on the silverstripe account
if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule')
runs-on: ubuntu-latest
steps:
- name: Dispatch CI
uses: silverstripe/gha-dispatch-ci@v1

View File

@ -1,17 +0,0 @@
name: Keepalive
on:
workflow_dispatch:
# The 4th of every month at 10:50am UTC
schedule:
- cron: '50 10 4 * *'
jobs:
keepalive:
name: Keepalive
# Only run cron on the silverstripe account
if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule')
runs-on: ubuntu-latest
steps:
- name: Keepalive
uses: silverstripe/gha-keepalive@v1

9
.scrutinizer.yml Normal file
View File

@ -0,0 +1,9 @@
inherit: true
checks:
php:
code_rating: true
duplication: true
filter:
paths: [code/*, tests/*]

50
.travis.yml Normal file
View File

@ -0,0 +1,50 @@
language: php
dist: xenial
services:
- mysql
- postgresql
- xvfb
cache:
directories:
- $HOME/.composer/cache/files
env:
global:
- COMPOSER_ROOT_VERSION=4.6.x-dev
matrix:
fast_finish: true
include:
- php: 7.1
env: DB=MYSQL PHPUNIT_TEST=1 PHPCS_TEST=1
- php: 7.2
env: DB=MYSQL PHPUNIT_TEST=1
- php: 7.3
env: DB=MYSQL PDO=1 PHPUNIT_COVERAGE_TEST=1
- php: 7.4
env: DB=MYSQL PHPUNIT_TEST=1
before_script:
# Init PHP
- phpenv rehash
- phpenv config-rm xdebug.ini || true
# Install composer dependencies
- export PATH=~/.composer/vendor/bin:$PATH
- composer validate
- if [[ $DB == PGSQL ]]; then composer require silverstripe/postgresql:2.x-dev --no-update; fi
- if [[ $DB == SQLITE ]]; then composer require silverstripe/sqlite3:2.x-dev --no-update; fi
- composer require silverstripe/recipe-core:4.6.x-dev silverstripe/admin:1.6.x-dev silverstripe/versioned:1.6.x-dev --no-update
- if [[ $PHPCS_TEST ]]; then composer global require squizlabs/php_codesniffer:^3 --prefer-dist --no-interaction --no-progress --no-suggest -o; fi
- composer install --prefer-dist --no-interaction --no-progress --no-suggest --optimize-autoloader --verbose --profile
script:
- if [[ $PHPUNIT_TEST ]]; then vendor/bin/phpunit tests; fi
- if [[ $PHPUNIT_COVERAGE_TEST ]]; then phpdbg -qrr vendor/bin/phpunit --coverage-clover=coverage.xml tests; fi
- if [[ $PHPCS_TEST ]]; then composer run-script lint; fi
after_success:
- if [[ $PHPUNIT_COVERAGE_TEST ]]; then bash <(curl -s https://codecov.io/bash) -f coverage.xml; fi

View File

@ -1,9 +1,8 @@
[main] [main]
host = https://www.transifex.com host = https://www.transifex.com
[o:silverstripe:p:silverstripe-reports:r:master] [silverstripe-reports.master]
file_filter = lang/<lang>.yml file_filter = lang/<lang>.yml
source_file = lang/en.yml source_file = lang/en.yml
source_lang = en source_lang = en
type = YML type = YML

View File

@ -1,17 +1,17 @@
# Reports # Reports
[![CI](https://github.com/silverstripe/silverstripe-reports/actions/workflows/ci.yml/badge.svg)](https://github.com/silverstripe/silverstripe-reports/actions/workflows/ci.yml) [![Build Status](https://secure.travis-ci.org/silverstripe/silverstripe-reports.png?branch=master)](http://travis-ci.org/silverstripe/silverstripe-reports)
[![Silverstripe supported module](https://img.shields.io/badge/silverstripe-supported-0071C4.svg)](https://www.silverstripe.org/software/addons/silverstripe-commercially-supported-module-list/) [![SilverStripe supported module](https://img.shields.io/badge/silverstripe-supported-0071C4.svg)](https://www.silverstripe.org/software/addons/silverstripe-commercially-supported-module-list/)
## Introduction ## Introduction
This module contains the API's for building Reports that are displayed in the This module contains the API's for building Reports that are displayed in the
Silverstripe backend. This module replaces the built-in reports API from earlier SilverStripe backend. This module replaces the built-in reports API from earlier
versions of Silverstripe (2.4 and 3.0). versions of SilverStripe (2.4 and 3.0).
## Requirements ## Requirements
* Silverstripe 4.0 * SilverStripe 4.0
## Troubleshooting ## Troubleshooting
@ -20,16 +20,6 @@ The reports section will not show up in the CMS if:
* There are no reports to show * There are no reports to show
* The logged in user does not have permission to view any reports * The logged in user does not have permission to view any reports
For large datasets, the reports section may take a long time to load, since each report is getting a count of the items it contains to display next to the title.
To mitigate this issue, there is a cap on the number of items that will be counted per report. This is set at 10,000 items by default, but can be configured using the `limit_count_in_overview` configuration variable. Setting this to `null` will result in showing the actual count regardless of how many items there are.
```yml
SilverStripe\Reports\Report:
limit_count_in_overview: 500
```
Note that some reports may have overridden the `getCount` method, and for those reports this may not apply.
## Links ## ## Links ##
* [License](./LICENSE) * [License](./LICENSE)

View File

@ -25,7 +25,6 @@ use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\CMSPreviewable; use SilverStripe\ORM\CMSPreviewable;
use SilverStripe\ORM\DataList; use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DataQuery; use SilverStripe\ORM\DataQuery;
use SilverStripe\ORM\Limitable;
use SilverStripe\ORM\SS_List; use SilverStripe\ORM\SS_List;
use SilverStripe\Security\Member; use SilverStripe\Security\Member;
use SilverStripe\Security\Permission; use SilverStripe\Security\Permission;
@ -61,8 +60,7 @@ use SilverStripe\View\ViewableData;
* Right now, all subclasses of SS_Report will be shown in the ReportAdmin. In SS3 there is only * 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 its version in SS2. * one place where reports can go, so this class is greatly simplifed from its version in SS2.
* *
* @method SS_List|DataList sourceRecords($params = [], $sort = null, $limit = null) * @method SS_List|DataList sourceRecords($params = [], $sort = null, $limit = null) List of records to show for this report
* List of records to show for this report
*/ */
class Report extends ViewableData class Report extends ViewableData
{ {
@ -107,14 +105,6 @@ class Report extends ViewableData
SideReportWrapper::class, SideReportWrapper::class,
]; ];
/**
* The maximum number of items to include in the count in the reports overview
*
* @config
* @var int|null
*/
private static $limit_count_in_overview = 10000;
/** /**
* Return the title of this report. * Return the title of this report.
* *
@ -157,14 +147,11 @@ class Report extends ViewableData
*/ */
public function sourceQuery($params) public function sourceQuery($params)
{ {
if (!$this->hasMethod('sourceRecords')) { if ($this->hasMethod('sourceRecords')) {
throw new \RuntimeException( return $this->sourceRecords($params, null, null)->dataQuery();
'Please override sourceQuery()/sourceRecords() and columns() or, ' } else {
. 'if necessary, override getReportField()' user_error("Please override sourceQuery()/sourceRecords() and columns() or, if necessary, override getReportField()", E_USER_ERROR);
);
} }
return $this->sourceRecords($params, null, null)->dataQuery();
} }
/** /**
@ -220,53 +207,25 @@ class Report extends ViewableData
*/ */
protected function sanitiseClassName($class) protected function sanitiseClassName($class)
{ {
return str_replace('\\', '-', $class ?? ''); return str_replace('\\', '-', $class);
} }
/** /**
* counts the number of objects returned * counts the number of objects returned
* @param array $params - any parameters for the sourceRecords * @param array $params - any parameters for the sourceRecords
* @param int|null $limit - the maximum number of records to count
* @return int * @return int
*/ */
public function getCount($params = array(), $limit = null) public function getCount($params = array())
{ {
$sourceRecords = $this->sourceRecords($params, null, $limit); $sourceRecords = $this->sourceRecords($params, null, null);
if (!$sourceRecords instanceof SS_List) { if (!$sourceRecords instanceof SS_List) {
user_error(static::class . "::sourceRecords does not return an SS_List", E_USER_NOTICE); user_error(static::class . "::sourceRecords does not return an SS_List", E_USER_NOTICE);
return "-1"; return "-1";
} }
// Some reports may not use the $limit parameter in sourceRecords since it isn't actually
// used anywhere else - so make sure we limit record counts if possible.
if ($sourceRecords instanceof Limitable) {
$sourceRecords = $sourceRecords->limit($limit);
}
return $sourceRecords->count(); return $sourceRecords->count();
} }
/**
* Counts the number of objects returned up to a configurable limit.
*
* Large datasets can cause performance issues for some reports if allowed to count all records.
* To mitigate this, you can set the limit_count_in_overview config variable to the maximum number
* of items you wish to count to. Counts will be limited to this value, and any counts that hit
* this limit will be displayed with a plus, e.g. "500+"
*
* The default is to have no limit.
*
* @return string
*/
public function getCountForOverview(): string
{
$limit = $this->config()->get('limit_count_in_overview');
$count = $this->getCount([], $limit);
if ($limit && $count == $limit) {
$count = "$count+";
}
return "$count";
}
/** /**
* Return an array of excluded reports. That is, reports that will not be included in * Return an array of excluded reports. That is, reports that will not be included in
* the list of reports in report admin in the CMS. * the list of reports in report admin in the CMS.
@ -288,12 +247,12 @@ class Report extends ViewableData
$reports = ClassInfo::subclassesFor(get_called_class()); $reports = ClassInfo::subclassesFor(get_called_class());
$reportsArray = []; $reportsArray = [];
if ($reports && count($reports ?? []) > 0) { if ($reports && count($reports) > 0) {
$excludedReports = static::get_excluded_reports(); $excludedReports = static::get_excluded_reports();
// Collect reports into array with an attribute for 'sort' // Collect reports into array with an attribute for 'sort'
foreach ($reports as $report) { foreach ($reports as $report) {
// Don't use the Report superclass, or any excluded report classes // Don't use the Report superclass, or any excluded report classes
if (in_array($report, $excludedReports ?? [])) { if (in_array($report, $excludedReports)) {
continue; continue;
} }
$reflectionClass = new ReflectionClass($report); $reflectionClass = new ReflectionClass($report);
@ -355,10 +314,7 @@ class Report extends ViewableData
} }
// Add a search button // Add a search button
$formAction = FormAction::create( $formAction = FormAction::create('updatereport', _t('SilverStripe\\Forms\\GridField\\GridField.Filter', 'Filter'));
'updatereport',
_t('SilverStripe\\Forms\\GridField\\GridField.Filter', 'Filter')
);
$formAction->addExtraClass('btn-primary mb-4'); $formAction->addExtraClass('btn-primary mb-4');
$fields->push($formAction); $fields->push($formAction);
@ -394,12 +350,12 @@ class Report extends ViewableData
$items = $this->sourceRecords($params, null, null); $items = $this->sourceRecords($params, null, null);
$gridFieldConfig = GridFieldConfig::create()->addComponents( $gridFieldConfig = GridFieldConfig::create()->addComponents(
GridFieldButtonRow::create('before'), new GridFieldButtonRow('before'),
GridFieldPrintButton::create('buttons-before-left'), new GridFieldPrintButton('buttons-before-left'),
GridFieldExportButton::create('buttons-before-left'), new GridFieldExportButton('buttons-before-left'),
GridFieldSortableHeader::create(), new GridFieldSortableHeader(),
GridFieldDataColumns::create(), new GridFieldDataColumns(),
GridFieldPaginator::create() new GridFieldPaginator()
); );
/** @var GridField $gridField */ /** @var GridField $gridField */
$gridField = GridField::create('Report', null, $items, $gridFieldConfig); $gridField = GridField::create('Report', null, $items, $gridFieldConfig);
@ -489,7 +445,7 @@ class Report extends ViewableData
$results = $this->extend($methodName, $member); $results = $this->extend($methodName, $member);
if ($results && is_array($results)) { if ($results && is_array($results)) {
// Remove NULLs // Remove NULLs
$results = array_filter($results ?? [], function ($v) { $results = array_filter($results, function ($v) {
return !is_null($v); return !is_null($v);
}); });
// If there are any non-NULL responses, then return the lowest one of them. // If there are any non-NULL responses, then return the lowest one of them.

View File

@ -139,7 +139,7 @@ class ReportAdmin extends LeftAndMain implements PermissionProvider
*/ */
protected function unsanitiseClassName($class) protected function unsanitiseClassName($class)
{ {
return str_replace('-', '\\', $class ?? ''); return str_replace('-', '\\', $class);
} }
/** /**
@ -155,7 +155,7 @@ class ReportAdmin extends LeftAndMain implements PermissionProvider
*/ */
public static function has_reports() public static function has_reports()
{ {
return sizeof(Report::get_reports() ?? []) > 0; return sizeof(Report::get_reports()) > 0;
} }
/** /**
@ -181,13 +181,13 @@ class ReportAdmin extends LeftAndMain implements PermissionProvider
} }
//build breadcrumb trail to the current report //build breadcrumb trail to the current report
$items->push(ArrayData::create([ $items->push(new ArrayData(array(
'Title' => $report->title(), 'Title' => $report->title(),
'Link' => Controller::join_links( 'Link' => Controller::join_links(
$this->Link(), $this->Link(),
'?' . http_build_query(['q' => $this->request->requestVar('q')]) '?' . http_build_query(array('q' => $this->request->requestVar('q')))
) )
])); )));
} }
return $items; return $items;
@ -230,20 +230,19 @@ class ReportAdmin extends LeftAndMain implements PermissionProvider
// List all reports // List all reports
$fields = new FieldList(); $fields = new FieldList();
$gridFieldConfig = GridFieldConfig::create()->addComponents( $gridFieldConfig = GridFieldConfig::create()->addComponents(
GridFieldSortableHeader::create(), new GridFieldSortableHeader(),
GridFieldDataColumns::create(), new GridFieldDataColumns(),
GridFieldFooter::create() new GridFieldFooter()
); );
$gridField = GridField::create('Reports', false, $this->Reports(), $gridFieldConfig); $gridField = new GridField('Reports', false, $this->Reports(), $gridFieldConfig);
/** @var GridFieldDataColumns $columns */ /** @var GridFieldDataColumns $columns */
$columns = $gridField->getConfig() $columns = $gridField->getConfig()->getComponentByType('SilverStripe\\Forms\\GridField\\GridFieldDataColumns');
->getComponentByType('SilverStripe\\Forms\\GridField\\GridFieldDataColumns');
$columns->setDisplayFields(array( $columns->setDisplayFields(array(
'title' => _t('SilverStripe\\Reports\\ReportAdmin.ReportTitle', 'Title'), 'title' => _t('SilverStripe\\Reports\\ReportAdmin.ReportTitle', 'Title'),
)); ));
$columns->setFieldFormatting(array( $columns->setFieldFormatting(array(
'title' => '<a href=\"$Link\" class=\"grid-field__link-block\">$value ($CountForOverview)</a>' 'title' => '<a href=\"$Link\" class=\"grid-field__link-block\">$value ($Count)</a>'
)); ));
$gridField->addExtraClass('all-reports-gridfield'); $gridField->addExtraClass('all-reports-gridfield');
$fields->push($gridField); $fields->push($gridField);
@ -251,9 +250,7 @@ class ReportAdmin extends LeftAndMain implements PermissionProvider
$actions = new FieldList(); $actions = new FieldList();
$form = new Form($this, "EditForm", $fields, $actions); $form = new Form($this, "EditForm", $fields, $actions);
$form->addExtraClass( $form->addExtraClass('panel panel--padded panel--scrollable cms-edit-form cms-panel-padded' . $this->BaseCSSClasses());
'panel panel--padded panel--scrollable cms-edit-form cms-panel-padded' . $this->BaseCSSClasses()
);
$form->loadDataFrom($this->request->getVars()); $form->loadDataFrom($this->request->getVars());
$this->extend('updateEditForm', $form); $this->extend('updateEditForm', $form);

View File

@ -2,8 +2,6 @@
namespace SilverStripe\Reports; namespace SilverStripe\Reports;
use SilverStripe\Core\Injector\Injector;
/** /**
* SS_ReportWrapper is a base class for creating report wappers. * SS_ReportWrapper is a base class for creating report wappers.
* *
@ -23,7 +21,7 @@ abstract class ReportWrapper extends Report
public function __construct($baseReport) public function __construct($baseReport)
{ {
$this->baseReport = is_string($baseReport) ? Injector::inst()->create($baseReport) : $baseReport; $this->baseReport = is_string($baseReport) ? new $baseReport : $baseReport;
$this->dataClass = $this->baseReport->dataClass(); $this->dataClass = $this->baseReport->dataClass();
parent::__construct(); parent::__construct();
} }
@ -77,9 +75,7 @@ abstract class ReportWrapper extends Report
$this->afterQuery(); $this->afterQuery();
return $query; return $query;
} else { } else {
throw new \RuntimeException( user_error("Please override sourceQuery()/sourceRecords() and columns() in your base report", E_USER_ERROR);
"Please override sourceQuery()/sourceRecords() and columns() in your base report"
);
} }
} }

View File

@ -11,8 +11,8 @@ use SilverStripe\View\ViewableData;
*/ */
class SideReportView extends ViewableData class SideReportView extends ViewableData
{ {
protected $controller;
protected $report; protected $controller, $report;
protected $parameters; protected $parameters;
public function __construct($controller, $report) public function __construct($controller, $report)
@ -79,9 +79,9 @@ class SideReportView extends ViewableData
// Formatting, a la TableListField // Formatting, a la TableListField
if (!empty($info['formatting'])) { if (!empty($info['formatting'])) {
$format = str_replace('$value', "__VAL__", $info['formatting'] ?? ''); $format = str_replace('$value', "__VAL__", $info['formatting']);
$format = preg_replace('/\$([A-Za-z0-9-_]+)/', '$record->$1', $format ?? ''); $format = preg_replace('/\$([A-Za-z0-9-_]+)/', '$record->$1', $format);
$format = str_replace('__VAL__', '$val', $format ?? ''); $format = str_replace('__VAL__', '$val', $format);
$val = eval('return "' . $format . '";'); $val = eval('return "' . $format . '";');
} }
@ -90,7 +90,7 @@ class SideReportView extends ViewableData
$classClause = ""; $classClause = "";
if (isset($info['title'])) { if (isset($info['title'])) {
$cssClass = preg_replace('/[^A-Za-z0-9]+/', '', $info['title'] ?? ''); $cssClass = preg_replace('/[^A-Za-z0-9]+/', '', $info['title']);
$classClause = "class=\"$cssClass\""; $classClause = "class=\"$cssClass\"";
} }

View File

@ -20,8 +20,7 @@
} }
], ],
"require": { "require": {
"php": "^7.4 || ^8.0", "silverstripe/framework": "^4.6@dev",
"silverstripe/framework": "^4.11",
"silverstripe/admin": "^1.6@dev", "silverstripe/admin": "^1.6@dev",
"silverstripe/versioned": "^1.6@dev", "silverstripe/versioned": "^1.6@dev",
"silverstripe/config": "^1.0@dev", "silverstripe/config": "^1.0@dev",
@ -29,8 +28,7 @@
"silverstripe/vendor-plugin": "^1" "silverstripe/vendor-plugin": "^1"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.5", "phpunit/phpunit": "^5.7"
"squizlabs/php_codesniffer": "^3.0"
}, },
"extra": { "extra": {
"expose": [ "expose": [
@ -43,6 +41,10 @@
"SilverStripe\\Reports\\Tests\\": "tests/" "SilverStripe\\Reports\\Tests\\": "tests/"
} }
}, },
"scripts": {
"lint": "phpcs code/ tests/",
"lint-clean": "phpcbf code/ tests/"
},
"minimum-stability": "dev", "minimum-stability": "dev",
"prefer-stable": true "prefer-stable": true
} }

View File

@ -2,32 +2,17 @@
* File: ReportAdmin.js * File: ReportAdmin.js
*/ */
(function ($) { (function($) {
$.entwine("ss", function ($) { $.entwine('ss', function($){
$(".ReportAdmin .cms-edit-form").entwine({ $('.ReportAdmin .cms-edit-form').entwine({
onsubmit: function (e) { onsubmit: function(e) {
let url = $.path.parseUrl(document.location.href).hrefNoSearch; var url = $.path.parseUrl(document.location.href).hrefNoSearch,
let params = this.find(":input[name^=filters]").serializeArray(); params = this.find(':input[name^=filters]').serializeArray();
params = $.grep(params, function(param) {return (param.value);}); // filter out empty
try { if(params) url = $.path.addSearchParams(url, $.param(params));
params = $.grep(params, function (param) { $('.cms-container').loadPanel(url);
// filter out empty return false;
return param.value; }
}); });
});
// convert params to a query string
params = $.param(params);
// append query string to url
url += "?" + params;
$(".cms-container").loadPanel(url);
} catch (err) {
console.error(err);
}
return false;
},
});
});
})(jQuery); })(jQuery);

View File

@ -1,8 +1,4 @@
en: en:
SilverStripe\CMS\Controllers\CMSPageHistoryController:
PREVIEW: 'Website preview'
SilverStripe\Forms\GridField\GridField:
Filter: Filter
SilverStripe\Reports\ReportAdmin: SilverStripe\Reports\ReportAdmin:
MENUTITLE: Reports MENUTITLE: Reports
ReportTitle: Title ReportTitle: Title

View File

@ -1,8 +1,4 @@
eo: eo:
SilverStripe\CMS\Controllers\CMSPageHistoryController:
PREVIEW: 'Retejon antaŭvidi'
SilverStripe\Forms\GridField\GridField:
Filter: Filtrilo
SilverStripe\Reports\ReportAdmin: SilverStripe\Reports\ReportAdmin:
MENUTITLE: Raportoj MENUTITLE: Raportoj
ReportTitle: Titoloj ReportTitle: Titoloj

View File

@ -1,9 +1,7 @@
sk: sk:
SilverStripe\CMS\Controllers\CMSPageHistoryController:
PREVIEW: 'Náhľad webovej stránky'
SilverStripe\Reports\ReportAdmin: SilverStripe\Reports\ReportAdmin:
MENUTITLE: Správy MENUTITLE: Výkazy
ReportTitle: Názov ReportTitle: Titulok
SilverStripe\Reports\SideReport: SilverStripe\Reports\SideReport:
OtherGroupTitle: Iné OtherGroupTitle: Iné
REPEMPTY: 'Správa {title} je prázdna.' REPEMPTY: 'Výkaz {title} je prázdny.'

View File

@ -1,7 +0,0 @@
sl:
SilverStripe\Reports\ReportAdmin:
MENUTITLE: Poročila
ReportTitle: Naslov
SilverStripe\Reports\SideReport:
OtherGroupTitle: Drugo
REPEMPTY: 'Poročilo ''{title}'' je prazno.'

View File

@ -1,6 +1,4 @@
sv: sv:
SilverStripe\CMS\Controllers\CMSPageHistoryController:
PREVIEW: 'Webbplats förhandsvisning'
SilverStripe\Reports\ReportAdmin: SilverStripe\Reports\ReportAdmin:
MENUTITLE: Rapporter MENUTITLE: Rapporter
ReportTitle: Titel ReportTitle: Titel

View File

@ -2,12 +2,21 @@
<ruleset name="SilverStripe"> <ruleset name="SilverStripe">
<description>CodeSniffer ruleset for SilverStripe coding conventions.</description> <description>CodeSniffer ruleset for SilverStripe coding conventions.</description>
<file>code</file> <!-- base rules are PSR-2 -->
<file>tests</file> <rule ref="PSR2" >
<!-- base rules are PSR-12 -->
<rule ref="PSR12" >
<!-- Current exclusions --> <!-- Current exclusions -->
<exclude name="PSR1.Methods.CamelCapsMethodName.NotCamelCaps" /> <exclude name="PSR1.Methods.CamelCapsMethodName" />
<exclude name="PSR1.Files.SideEffects.FoundWithSymbols" />
<exclude name="PSR2.Classes.PropertyDeclaration" />
<exclude name="PSR2.ControlStructures.SwitchDeclaration" /> <!-- causes php notice while linting -->
<exclude name="PSR2.ControlStructures.SwitchDeclaration.WrongOpenercase" />
<exclude name="PSR2.ControlStructures.SwitchDeclaration.WrongOpenerdefault" />
<exclude name="PSR2.ControlStructures.SwitchDeclaration.TerminatingComment" />
<exclude name="PSR2.Methods.MethodDeclaration.Underscore" />
<exclude name="Squiz.Scope.MethodScope" />
<exclude name="Squiz.Classes.ValidClassName.NotCamelCaps" />
<exclude name="Generic.Files.LineLength.TooLong" />
<exclude name="PEAR.Functions.ValidDefaultValue.NotAtEnd" />
</rule> </rule>
</ruleset> </ruleset>

View File

@ -1,11 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/silverstripe/framework/tests/bootstrap.php" colors="true"> <phpunit bootstrap="vendor/silverstripe/framework/tests/bootstrap.php" colors="true">
<testsuites> <testsuite name="Default">
<testsuite name="Default"> <directory>tests</directory>
<directory>tests</directory> </testsuite>
</testsuite>
</testsuites>
<filter> <filter>
<whitelist addUncoveredFilesFromWhitelist="true"> <whitelist addUncoveredFilesFromWhitelist="true">

View File

@ -1,5 +1,4 @@
<?php <?php
namespace SilverStripe\Reports\Tests; namespace SilverStripe\Reports\Tests;
use ReflectionClass; use ReflectionClass;
@ -21,12 +20,15 @@ class ReportAdminTest extends SapphireTest
$breadcrumbs = $controller->BreadCrumbs(); $breadcrumbs = $controller->BreadCrumbs();
$this->assertCount(2, $breadcrumbs); $this->assertCount(2, $breadcrumbs);
$map = $breadcrumbs[0]->toMap();
$this->assertSame('Reports', $map['Title']);
$this->assertSame('admin/reports/', $map['Link']);
$map = $breadcrumbs[1]->toMap(); $this->assertArraySubset([
$this->assertSame('Fake report', $map['Title']); 'Title' => 'Reports',
'Link' => 'admin/reports/',
], $breadcrumbs[0]->toMap(), true, 'Link to top level reports is within breadcrumbs');
$this->assertArraySubset([
'Title' => 'Fake report'
], $breadcrumbs[1]->toMap(), true, 'Current report is within breadcrumbs');
$extraCrumbs = FakeReport2::create(); $extraCrumbs = FakeReport2::create();
$controller = $this->mockController($extraCrumbs); $controller = $this->mockController($extraCrumbs);
@ -34,16 +36,19 @@ class ReportAdminTest extends SapphireTest
$this->assertCount(3, $breadcrumbs); $this->assertCount(3, $breadcrumbs);
$map = $breadcrumbs[0]->toMap(); $this->assertArraySubset([
$this->assertSame('Reports', $map['Title']); 'Title' => 'Reports',
$this->assertSame('admin/reports/', $map['Link']); 'Link' => 'admin/reports/',
], $breadcrumbs[0]->toMap(), true, 'Link to top level reports is within breadcrumbs (again)');
$map = $breadcrumbs[1]->toMap(); $this->assertArraySubset([
$this->assertSame('Fake report title', $map['Title']); 'Title' => 'Fake report title',
$this->assertSame('admin/reports/show/SilverStripe-Reports-Tests-ReportAdminTest-FakeReport', $map['Link']); 'Link' => 'admin/reports/show/SilverStripe-Reports-Tests-ReportAdminTest-FakeReport',
], $breadcrumbs[1]->toMap(), true, 'Custom breadcrumb appears');
$map = $breadcrumbs[2]->toMap(); $this->assertArraySubset([
$this->assertSame('Fake report two', $map['Title']); 'Title' => 'Fake report two'
], $breadcrumbs[2]->toMap(), true, 'Current report is still within breadcrumbs');
} }
/** /**

View File

@ -1,5 +1,4 @@
<?php <?php
namespace SilverStripe\Reports\Tests\ReportAdminTest; namespace SilverStripe\Reports\Tests\ReportAdminTest;
use SilverStripe\Dev\TestOnly; use SilverStripe\Dev\TestOnly;

View File

@ -1,5 +1,4 @@
<?php <?php
namespace SilverStripe\Reports\Tests\ReportAdminTest; namespace SilverStripe\Reports\Tests\ReportAdminTest;
use SilverStripe\Control\Controller; use SilverStripe\Control\Controller;

View File

@ -114,20 +114,4 @@ class ReportTest extends SapphireTest
$titleContent $titleContent
); );
} }
public function testCountForOverview()
{
$report = new ReportTest\FakeTest3();
// Count is limited to 10000 by default
$this->assertEquals('10000+', $report->getCountForOverview());
// Count is limited as per configuration
Config::modify()->set(ReportTest\FakeTest3::class, 'limit_count_in_overview', 15);
$this->assertEquals('15+', $report->getCountForOverview());
// A null limit displays the full count
Config::modify()->set(ReportTest\FakeTest3::class, 'limit_count_in_overview', null);
$this->assertEquals('15000', $report->getCountForOverview());
}
} }

View File

@ -1,15 +0,0 @@
<?php
namespace SilverStripe\Reports\Tests\ReportTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\ArrayList;
use SilverStripe\Reports\Report;
class FakeTest3 extends Report implements TestOnly
{
public function sourceRecords($params, $sort, $limit)
{
return new ArrayList(range(1, 15000));
}
}

View File

@ -8,6 +8,7 @@ use SilverStripe\Reports\Report;
abstract class FakeTestAbstract extends Report implements TestOnly abstract class FakeTestAbstract extends Report implements TestOnly
{ {
public function title() public function title()
{ {
return 'Report title Abstract'; return 'Report title Abstract';