Compare commits

...

64 Commits
4.6.0 ... 4

Author SHA1 Message Date
github-actions 6942278b41 Merge branch '4.13' into 4 2024-02-09 11:04:20 +00:00
Guy Sartorelli c9c6c3ff1e
TLN Update translations (#176) 2024-02-08 13:29:26 +13:00
Guy Sartorelli f5b5daa711
TLN Update translations (#175) 2024-02-07 16:10:59 +13:00
github-actions aa3d0a3b6a Merge branch '4.13' into 4 2023-09-29 11:04:25 +00:00
Guy Sartorelli aa085022a1
Merge pull request #169 from heyday/4
FIX broken URL builder when using MultiSelectFields as parameters
2023-09-26 10:35:41 +13:00
Will Rossiter a25d0432c4
FIX broken URL builder when using MultiSelectFields as parameters 2023-09-21 13:21:46 +12:00
github-actions 030c56777c Merge branch '4.13' into 4 2023-08-25 11:04:27 +00:00
Guy Sartorelli 03869a7535
ENH Update translations (#167) 2023-08-21 12:56:04 +12:00
Steve Boyd 2c3f2ca64d Merge branch '4.13' into 4 2023-06-16 10:39:53 +12:00
Guy Sartorelli 92b5d968da
Merge pull request #164 from creative-commoners/pulls/4.13/tx-1686724792
ENH Update translations
2023-06-15 10:06:10 +12:00
Steve Boyd f6aee12f07 ENH Update translations 2023-06-14 18:39:52 +12:00
Guy Sartorelli 2db20aba1a
Merge branch '4.13' into 4 2023-04-26 12:44:49 +12:00
Guy Sartorelli cea17947ea
MNT Revert erroneous dependency changes (#161) 2023-03-28 16:43:12 +13:00
Maxime Rainville 48b103bf97
Merge pull request #160 from creative-commoners/pulls/4/dispatch-ci
MNT Use gha-dispatch-ci
2023-03-23 12:09:00 +13:00
Steve Boyd 454a3df1e7 MNT Use gha-dispatch-ci 2023-03-21 12:16:32 +13:00
Guy Sartorelli 4cb8e8f880
MNT Update development dependencies 2023-03-10 16:30:57 +13:00
Guy Sartorelli f23076b4cf
MNT Update release dependencies 2023-03-10 16:30:53 +13:00
Guy Sartorelli 2bf6bc1a9c
MNT Update development dependencies 2023-03-10 12:21:27 +13:00
Guy Sartorelli e88a56243d
Merge pull request #159 from creative-commoners/pulls/4/tx-1678080021
ENH Update translations
2023-03-08 10:32:08 +13:00
Steve Boyd a75e054b99 ENH Update translations 2023-03-06 18:20:21 +13:00
Steve Boyd bd74939c14
Merge pull request #154 from creative-commoners/pulls/4/rescue-master-psr12
Rescue Master Branch PR: PSR12 compliance
2022-08-29 18:15:29 +12:00
Robbie Averill 01f2663179
Use Injector to instantiate new base report instances 2022-08-26 13:53:16 +12:00
Robbie Averill 213f7167a6
ENH Fix phpcs violations 2022-08-26 13:53:08 +12:00
Robbie Averill c5f42d99a3
MNT Update phpcs ruleset to use PSR-12 as a base 2022-08-26 13:48:51 +12:00
Steve Boyd d21503c88c Merge branch '4.11' into 4 2022-08-02 18:38:12 +12:00
Steve Boyd eacecdbb56 Merge branch '4.10' into 4.11 2022-08-02 18:38:08 +12:00
Guy Sartorelli c0bdbc3d3b
Merge pull request #150 from creative-commoners/pulls/4.10/standardise-modules
MNT Standardise modules
2022-08-02 14:29:45 +12:00
Steve Boyd 567124b34a MNT Standardise modules 2022-08-01 15:36:42 +12:00
Guy Sartorelli bd7fb5a45d Merge branch '4.11' into 4 2022-07-11 11:24:14 +12:00
Guy Sartorelli f18dd784e5 Merge branch '4.10' into 4.11 2022-07-11 11:24:02 +12:00
Guy Sartorelli 86d338680a
Merge pull request #149 from creative-commoners/pulls/4.10/module-standards
MNT Use GitHub Actions CI
2022-07-05 16:31:12 +12:00
Steve Boyd fca925673f MNT Use GitHub Actions CI 2022-07-05 16:04:25 +12:00
Guy Sartorelli 8e3d6cb3eb
Merge pull request #148 from creative-commoners/pulls/4/php81
ENH PHP 8.1 compatibility
2022-04-22 16:18:26 +12:00
Steve Boyd 0bceb0903c ENH PHP 8.1 compatibility 2022-04-13 17:39:46 +12:00
Guy Sartorelli 6d565028c8
ENH Prefer dependency injection for GridFieldComponents. (#147)
GridFieldComponents packaged with silverstripe/framework are injectable as of 4.11.0
2022-03-04 10:13:45 +13:00
Maxime Rainville ede88ee491
Merge pull request #146 from creative-commoners/pulls/4/php74
DEP Set PHP 7.4 as the minimum version
2022-02-18 22:05:50 +13:00
Steve Boyd 013c5d74cf DEP Set PHP 7.4 as the minimum version 2022-02-10 17:31:38 +13:00
GuySartorelli 375c31904f
ENH Add configuration to cap report counts for large datasets. (#139)
Opted not to return the result from `getCount()` directly since the PHPDoc says this returns an int (even though it technically already returns a string if the report isn't set up correctly...)
2022-01-31 17:20:11 +13:00
Steve Boyd 0cb265434a Merge branch '4.10' into 4 2021-12-22 10:12:27 +13:00
Maxime Rainville 411a98e45b
Merge pull request #143 from creative-commoners/pulls/4.10/dynamic
MNT Rely on dynamic REQUIRE_RECIPE
2021-12-14 10:30:03 +13:00
Steve Boyd cb71f6b7f2 MNT Rely on dynamic REQUIRE_RECIPE 2021-12-13 11:47:20 +13:00
Maxime Rainville 6dd0627678
Merge pull request #142 from creative-commoners/pulls/4/dms
MNT Remove polyfill
2021-11-09 10:57:04 +13:00
Steve Boyd 1b2a9a8926 MNT Remove polyfill 2021-11-05 13:23:15 +13:00
Maxime Rainville 3ab86f3d0a
Merge pull request #141 from creative-commoners/pulls/4/sapphire-test-nine
API phpunit9 support
2021-10-28 00:00:38 +13:00
Steve Boyd 9f76ec2a43 API phpunit9 support 2021-10-27 17:52:11 +13:00
Steve Boyd 908dc49dca Merge branch '4.9' into 4 2021-09-06 16:08:45 +12:00
Steve Boyd 22839ec8c2
MNT Update REQUIRE_RECIPE 2021-09-06 16:06:23 +12:00
Steve Boyd 8098a7c61f Merge branch '4.8' into 4 2021-05-17 16:34:51 +12:00
Steve Boyd 1d9940aab0 MNT Remove COMPOSER_ROOT_VERSION 2021-05-17 16:34:21 +12:00
Steve Boyd 27288dc508 Update translations 2021-05-17 10:53:21 +12:00
Steve Boyd e101f1e034
Update build status badge 2021-01-21 16:07:28 +13:00
Steve Boyd 90bdc6f3ce Merge branch '4.7' into 4 2020-11-11 17:02:56 +13:00
Steve Boyd 82b5059265
Merge pull request #132 from creative-commoners/pulls/4.7/phpcs
MNT Update how phpcs is called
2020-11-11 13:02:46 +13:00
Serge Latyntcev da8bc5c240 MNT Travis shared config 2020-11-11 11:35:21 +13:00
Steve Boyd ee4c391682 MNT Update how phpcs is called 2020-11-06 17:11:09 +13:00
Maxime Rainville b62a6c66d1 Merge branch '4.6' into 4 2020-11-02 13:33:44 +13:00
Andre Kiste 466ec19b60
Merge pull request #131 from creative-commoners/pulls/4/php8
MNT PHP8 support
2020-10-13 12:58:20 +13:00
Serge Latyntcev 3314f95da6 MNT PHP8 support 2020-10-13 08:55:47 +13:00
Guy Marriott 8f40ddb5eb
Merge pull request #130 from robbieaverill/pulls/4.7/exceptions
ENH Replace E_USER_ERROR errors with exceptions
2020-10-04 16:58:15 -07:00
Robbie Averill 6ed13f7e07
Merge pull request #128 from creative-commoners/pulls/4.6/travis
Update travis 4.6
2020-09-24 17:12:23 -07:00
Robbie Averill 9b9e673e4b ENH Replace E_USER_ERROR errors with exceptions 2020-09-24 17:11:47 -07:00
Steve Boyd b0cb0b695e Update travis 2020-06-23 15:39:47 +12:00
Robbie Averill 275a1bc7f4
Merge pull request #127 from open-sausages/pulls/4/set-up-47-dev
Merge up 1.6 branch + update travis to target x-dev branches
2020-06-04 09:09:45 -07:00
Maxime Rainville f931dc37df Update travis config to target x-dev branches 2020-06-04 15:17:53 +12:00
27 changed files with 265 additions and 166 deletions

View File

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

11
.github/workflows/ci.yml vendored Normal file
View File

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

16
.github/workflows/dispatch-ci.yml vendored Normal file
View File

@ -0,0 +1,16 @@
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

17
.github/workflows/keepalive.yml vendored Normal file
View File

@ -0,0 +1,17 @@
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

View File

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

View File

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

View File

@ -1,17 +1,17 @@
# Reports
[![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/)
[![CI](https://github.com/silverstripe/silverstripe-reports/actions/workflows/ci.yml/badge.svg)](https://github.com/silverstripe/silverstripe-reports/actions/workflows/ci.yml)
[![Silverstripe supported module](https://img.shields.io/badge/silverstripe-supported-0071C4.svg)](https://www.silverstripe.org/software/addons/silverstripe-commercially-supported-module-list/)
## Introduction
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
versions of SilverStripe (2.4 and 3.0).
Silverstripe backend. This module replaces the built-in reports API from earlier
versions of Silverstripe (2.4 and 3.0).
## Requirements
* SilverStripe 4.0
* Silverstripe 4.0
## Troubleshooting
@ -20,6 +20,16 @@ The reports section will not show up in the CMS if:
* There are no reports to show
* 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 ##
* [License](./LICENSE)

View File

@ -25,6 +25,7 @@ use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\CMSPreviewable;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DataQuery;
use SilverStripe\ORM\Limitable;
use SilverStripe\ORM\SS_List;
use SilverStripe\Security\Member;
use SilverStripe\Security\Permission;
@ -60,7 +61,8 @@ use SilverStripe\View\ViewableData;
* 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.
*
* @method SS_List|DataList sourceRecords($params = [], $sort = null, $limit = null) List of records to show for this report
* @method SS_List|DataList sourceRecords($params = [], $sort = null, $limit = null)
* List of records to show for this report
*/
class Report extends ViewableData
{
@ -105,6 +107,14 @@ class Report extends ViewableData
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.
*
@ -147,11 +157,14 @@ class Report extends ViewableData
*/
public function sourceQuery($params)
{
if ($this->hasMethod('sourceRecords')) {
return $this->sourceRecords($params, null, null)->dataQuery();
} else {
user_error("Please override sourceQuery()/sourceRecords() and columns() or, if necessary, override getReportField()", E_USER_ERROR);
if (!$this->hasMethod('sourceRecords')) {
throw new \RuntimeException(
'Please override sourceQuery()/sourceRecords() and columns() or, '
. 'if necessary, override getReportField()'
);
}
return $this->sourceRecords($params, null, null)->dataQuery();
}
/**
@ -207,25 +220,53 @@ class Report extends ViewableData
*/
protected function sanitiseClassName($class)
{
return str_replace('\\', '-', $class);
return str_replace('\\', '-', $class ?? '');
}
/**
* counts the number of objects returned
* @param array $params - any parameters for the sourceRecords
* @param int|null $limit - the maximum number of records to count
* @return int
*/
public function getCount($params = array())
public function getCount($params = array(), $limit = null)
{
$sourceRecords = $this->sourceRecords($params, null, null);
$sourceRecords = $this->sourceRecords($params, null, $limit);
if (!$sourceRecords instanceof SS_List) {
user_error(static::class . "::sourceRecords does not return an SS_List", E_USER_NOTICE);
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();
}
/**
* 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
* the list of reports in report admin in the CMS.
@ -247,12 +288,12 @@ class Report extends ViewableData
$reports = ClassInfo::subclassesFor(get_called_class());
$reportsArray = [];
if ($reports && count($reports) > 0) {
if ($reports && count($reports ?? []) > 0) {
$excludedReports = static::get_excluded_reports();
// Collect reports into array with an attribute for 'sort'
foreach ($reports as $report) {
// Don't use the Report superclass, or any excluded report classes
if (in_array($report, $excludedReports)) {
if (in_array($report, $excludedReports ?? [])) {
continue;
}
$reflectionClass = new ReflectionClass($report);
@ -314,7 +355,10 @@ class Report extends ViewableData
}
// Add a search button
$formAction = FormAction::create('updatereport', _t('SilverStripe\\Forms\\GridField\\GridField.Filter', 'Filter'));
$formAction = FormAction::create(
'updatereport',
_t('SilverStripe\\Forms\\GridField\\GridField.Filter', 'Filter')
);
$formAction->addExtraClass('btn-primary mb-4');
$fields->push($formAction);
@ -350,12 +394,12 @@ class Report extends ViewableData
$items = $this->sourceRecords($params, null, null);
$gridFieldConfig = GridFieldConfig::create()->addComponents(
new GridFieldButtonRow('before'),
new GridFieldPrintButton('buttons-before-left'),
new GridFieldExportButton('buttons-before-left'),
new GridFieldSortableHeader(),
new GridFieldDataColumns(),
new GridFieldPaginator()
GridFieldButtonRow::create('before'),
GridFieldPrintButton::create('buttons-before-left'),
GridFieldExportButton::create('buttons-before-left'),
GridFieldSortableHeader::create(),
GridFieldDataColumns::create(),
GridFieldPaginator::create()
);
/** @var GridField $gridField */
$gridField = GridField::create('Report', null, $items, $gridFieldConfig);
@ -445,7 +489,7 @@ class Report extends ViewableData
$results = $this->extend($methodName, $member);
if ($results && is_array($results)) {
// Remove NULLs
$results = array_filter($results, function ($v) {
$results = array_filter($results ?? [], function ($v) {
return !is_null($v);
});
// 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)
{
return str_replace('-', '\\', $class);
return str_replace('-', '\\', $class ?? '');
}
/**
@ -155,7 +155,7 @@ class ReportAdmin extends LeftAndMain implements PermissionProvider
*/
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
$items->push(new ArrayData(array(
$items->push(ArrayData::create([
'Title' => $report->title(),
'Link' => Controller::join_links(
$this->Link(),
'?' . http_build_query(array('q' => $this->request->requestVar('q')))
'?' . http_build_query(['q' => $this->request->requestVar('q')])
)
)));
]));
}
return $items;
@ -230,19 +230,20 @@ class ReportAdmin extends LeftAndMain implements PermissionProvider
// List all reports
$fields = new FieldList();
$gridFieldConfig = GridFieldConfig::create()->addComponents(
new GridFieldSortableHeader(),
new GridFieldDataColumns(),
new GridFieldFooter()
GridFieldSortableHeader::create(),
GridFieldDataColumns::create(),
GridFieldFooter::create()
);
$gridField = new GridField('Reports', false, $this->Reports(), $gridFieldConfig);
$gridField = GridField::create('Reports', false, $this->Reports(), $gridFieldConfig);
/** @var GridFieldDataColumns $columns */
$columns = $gridField->getConfig()->getComponentByType('SilverStripe\\Forms\\GridField\\GridFieldDataColumns');
$columns = $gridField->getConfig()
->getComponentByType('SilverStripe\\Forms\\GridField\\GridFieldDataColumns');
$columns->setDisplayFields(array(
'title' => _t('SilverStripe\\Reports\\ReportAdmin.ReportTitle', 'Title'),
));
$columns->setFieldFormatting(array(
'title' => '<a href=\"$Link\" class=\"grid-field__link-block\">$value ($Count)</a>'
'title' => '<a href=\"$Link\" class=\"grid-field__link-block\">$value ($CountForOverview)</a>'
));
$gridField->addExtraClass('all-reports-gridfield');
$fields->push($gridField);
@ -250,7 +251,9 @@ class ReportAdmin extends LeftAndMain implements PermissionProvider
$actions = new FieldList();
$form = new Form($this, "EditForm", $fields, $actions);
$form->addExtraClass('panel panel--padded panel--scrollable cms-edit-form cms-panel-padded' . $this->BaseCSSClasses());
$form->addExtraClass(
'panel panel--padded panel--scrollable cms-edit-form cms-panel-padded' . $this->BaseCSSClasses()
);
$form->loadDataFrom($this->request->getVars());
$this->extend('updateEditForm', $form);

View File

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

View File

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

View File

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

View File

@ -2,17 +2,32 @@
* File: ReportAdmin.js
*/
(function($) {
$.entwine('ss', function($){
$('.ReportAdmin .cms-edit-form').entwine({
onsubmit: function(e) {
var url = $.path.parseUrl(document.location.href).hrefNoSearch,
params = this.find(':input[name^=filters]').serializeArray();
params = $.grep(params, function(param) {return (param.value);}); // filter out empty
if(params) url = $.path.addSearchParams(url, $.param(params));
$('.cms-container').loadPanel(url);
return false;
}
});
});
(function ($) {
$.entwine("ss", function ($) {
$(".ReportAdmin .cms-edit-form").entwine({
onsubmit: function (e) {
let url = $.path.parseUrl(document.location.href).hrefNoSearch;
let params = this.find(":input[name^=filters]").serializeArray();
try {
params = $.grep(params, function (param) {
// filter out empty
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);

View File

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

View File

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

View File

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

7
lang/sl.yml Normal file
View File

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

View File

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

View File

@ -2,21 +2,12 @@
<ruleset name="SilverStripe">
<description>CodeSniffer ruleset for SilverStripe coding conventions.</description>
<!-- base rules are PSR-2 -->
<rule ref="PSR2" >
<file>code</file>
<file>tests</file>
<!-- base rules are PSR-12 -->
<rule ref="PSR12" >
<!-- Current exclusions -->
<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" />
<exclude name="PSR1.Methods.CamelCapsMethodName.NotCamelCaps" />
</rule>
</ruleset>

View File

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

View File

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

View File

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

View File

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

View File

@ -114,4 +114,20 @@ class ReportTest extends SapphireTest
$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

@ -0,0 +1,15 @@
<?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,7 +8,6 @@ use SilverStripe\Reports\Report;
abstract class FakeTestAbstract extends Report implements TestOnly
{
public function title()
{
return 'Report title Abstract';