Compare commits

...

359 Commits
3.2.1-rc2 ... 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
Robbie Averill cb55795013
Merge pull request #126 from open-sausages/pulls/4.6/update-travis
Target 4.6 minor branches in build
2020-05-28 09:17:45 -07:00
Maxime Rainville 0499717d7c Target 4.6 minor branches in build 2020-05-28 18:17:07 +12:00
Garion Herman f681448dbb Merge branch '4.5' into 4 2020-02-28 15:06:41 +13:00
Robbie Averill 2a77c2454f
Merge pull request #124 from creative-commoners/pulls/4.5/php-7.4-builds
Update Travis config to include PHP 7.4 build, upgrade to Xenial
2020-02-26 12:01:04 +11:00
Garion Herman f2deee8fa0 Update Travis config to include PHP 7.4 build, upgrade to Xenial 2020-02-26 13:32:02 +13:00
Steve Boyd 5677d2d61d
Merge pull request #123 from creative-commoners/pulls/4.5/update-core-requirement
FIX Update core requirements to 4.5 series
2020-02-17 11:11:07 +13:00
Garion Herman 7436e11d4f FIX Update core requirements to 4.5 series 2020-02-11 12:49:55 +13:00
Robbie Averill 34474804a2
Merge pull request #122 from creative-commoners/pulls/4/rfc-9344
RFC-9344 Remove branch aliases
2019-12-09 09:57:51 -08:00
Serge Latyntcev 476f7b06f3 RFC-9344 Remove branch aliases 2019-12-09 14:47:28 +13:00
Garion Herman 7f34088211
Merge pull request #121 from creative-commoners/pulls/4/fix-codestyle
Fix codestyle
2019-11-21 16:35:16 +13:00
Serge Latyntcev f3db5f72aa Fix codestyle 2019-11-21 16:04:17 +13:00
Serge Latyntcev d020ed86a1 Update branch alias and travis 2019-11-21 13:58:55 +13:00
Serge Latyntsev 9e95803970
Merge pull request #120 from creative-commoners/pulls/4.5/linting-fix
FIX Linting failure
2019-11-18 14:36:56 +13:00
Garion Herman 8be3660409 FIX Linting failure 2019-11-18 14:30:42 +13:00
Serge Latyntcev 0bb704decf Remove obsolete branch-alias 2019-11-14 01:24:48 +00:00
Ingo Schommer b5232aa7ab
Merge pull request #117 from creative-commoners/pulls/4.5/php71
Update minimum PHP version to 7.1 in Travis
2019-06-07 14:24:24 +12:00
Robbie Averill 250813f79c Update minimum PHP version to 7.1 in Travis 2019-05-23 14:14:40 +12:00
Robbie Averill 1f1278b820 Merge branch '4.4' into 4 2019-04-21 11:28:07 +12:00
Robbie Averill 9b89812058 Remove obsolete branch alias 2019-04-21 11:27:08 +12:00
Aaron Carlino c3c38aa976 Merge branch '4.3' into 4 2019-01-10 13:58:04 +13:00
Robbie Averill ed3ffee31e
Merge pull request #114 from intwebg/patch-1
Create fr.yml
2019-01-06 21:01:39 +00:00
Stéphane Guevremont 9d94712c04
Create fr.yml
Missing french translation
2019-01-04 21:30:42 -05:00
Aaron Carlino c797d128a2 Merge branch '4.2' into 4.3 2018-12-11 12:05:41 +13:00
Aaron Carlino 423cc180cd Merge branch '4.1' into 4.2 2018-12-11 12:05:18 +13:00
Maxime Rainville bc70b87721 FIX Apply missing class to report header. 2018-12-11 12:05:14 +13:00
Robbie Averill 9270206c3b NEW Use Injector to create new class instances and pass $params
Also adds a couple of missing PHPDoc annotations for IDE hints
2018-12-11 12:05:14 +13:00
Maxime Rainville ebe98f487a Increment travis root version to 4.3.x-dev 2018-12-11 12:05:14 +13:00
Dylan Wagstaff a344110a10 Add supported module badge to readme 2018-12-11 12:05:14 +13:00
Aaron Carlino 5a3bd39609 Merge branch '4.0' into 4.1 2018-12-11 12:04:59 +13:00
Maxime Rainville f074256a16
Merge pull request #113 from creative-commoners/pulls/4.4/make-a-breadcrumb-trail
NEW Allow reports to specify breadcrumbs for child reports
2018-11-23 09:12:59 +13:00
Guy Marriott 52a234410d
NEW Extracting out the method to determine parameters (filters) for update the report sourceRecords 2018-11-20 17:52:48 +13:00
Guy Marriott d6b1c071b6
NEW Adding tests for new report breadcrumbs feature 2018-11-19 11:48:23 +13:00
Guy Marriott edecbabe61
NEW Allow reports to specify breadcrumbs for child reports 2018-11-16 15:09:45 +13:00
Aaron Carlino dea66bc037 Update translations 2018-11-08 16:25:42 +13:00
Vagrant Default User c48cb248dc Update translations 2018-11-07 21:37:37 +13:00
Aaron Carlino 9ec437d033 Update translations 2018-11-07 17:57:46 +13:00
Aaron Carlino 6e3f8ff982 Update translations 2018-11-07 16:31:28 +13:00
Robbie Averill 7d4d7c05e6 Bump branch alias and Travis version for 4.4.x-dev 2018-10-15 14:32:23 +02:00
Robbie Averill 9dd2cb35ac Merge remote-tracking branch 'origin/4.3' into 4 2018-10-15 14:31:26 +02:00
Aaron Carlino f1f0f521b5 Remove obsolete branch-alias 2018-10-15 16:31:42 +13:00
Aaron Carlino 057dc90ebc Merge branch '4.2' into 4 2018-10-15 13:56:30 +13:00
Maxime Rainville 67254da185 FIX Apply missing class to report header. 2018-10-15 13:56:17 +13:00
Robbie Averill 786446fb67 NEW Use Injector to create new class instances and pass $params
Also adds a couple of missing PHPDoc annotations for IDE hints
2018-10-15 13:56:17 +13:00
Maxime Rainville ee1c77fa7d Increment travis root version to 4.3.x-dev 2018-10-15 13:56:17 +13:00
Dylan Wagstaff eb7be779f2 Add supported module badge to readme 2018-10-15 13:56:17 +13:00
Robbie Averill 62b3f0c74d
Merge pull request #111 from creative-commoners/pulls/4.2/allow-post-vars
FIX Use requestVar() to include post vars as well as get vars
2018-08-27 14:59:42 +12:00
Robbie Averill f3230c78d4 FIX Use requestVar() to include post vars as well as get vars 2018-08-27 13:59:23 +12:00
Aaron Carlino 9e4be5b4f6
Merge pull request #107 from creative-commoners/pulls/4.2/fix-getvar
FIX Filter var can be returned correctly from get variables as a fallback
2018-08-20 12:21:47 +12:00
Daniel Hensby c316c6bb7e
Merge pull request #110 from open-sausages/pulls/4/display-report-title-full-width
FIX Apply missing class to report header.
2018-07-30 16:58:55 +01:00
Daniel Hensby e9e5cdcc22
Merge branch '4.2' into 4 2018-07-30 11:11:39 +01:00
Maxime Rainville 3bbcfdde85 FIX Apply missing class to report header. 2018-07-27 17:06:38 +12:00
Daniel Hensby e9c73e9332
Merge tag '4.2.0' into 4.2
Release 4.2.0
2018-07-24 23:57:44 +01:00
root 8c7acb3d24 Update translations 2018-07-24 19:07:49 +00:00
Daniel Hensby 46de3d8f19
Merge branch '4.2' into 4 2018-07-23 17:15:27 +01:00
Daniel Hensby a3768f5f60
Merge branch '4.1' into 4.2 2018-07-23 17:15:05 +01:00
Daniel Hensby c90f1ed47c
Merge pull request #106 from creative-commoners/pulls/4.3/injection
NEW Use Injector to create new class instances and pass $params
2018-07-16 10:06:02 +01:00
Robbie Averill e1296d4813 FIX Filter var can be returned correctly from get variables as a fallback 2018-07-16 17:15:30 +12:00
Robbie Averill 693889cb3e NEW Use Injector to create new class instances and pass $params
Also adds a couple of missing PHPDoc annotations for IDE hints
2018-07-16 17:07:00 +12:00
Robbie Averill dce7df600b
Merge pull request #103 from open-sausages/pulls/4.3/increment-travis-to-4.3.x-dev
Increment travis root version to 4.3.x-dev
2018-06-27 09:45:15 +12:00
Maxime Rainville 650e17b3fd Increment travis root version to 4.3.x-dev 2018-06-26 17:39:51 +12:00
Damian Mooyman 745fdf87cf Update translations 2018-06-19 16:50:07 +12:00
Damian Mooyman fd62136c8f
Merge pull request #102 from creative-commoners/pulls/master/add-supported-module-badge
Add supported module badge to readme
2018-06-18 10:12:51 +12:00
Dylan Wagstaff 326e19ac8e Add supported module badge to readme 2018-06-15 17:46:23 +12:00
Damian Mooyman 9b239fd9a3
Merge remote-tracking branch 'origin/4.2' into 4 2018-06-15 16:32:48 +12:00
Damian Mooyman 75dfeb2b47 Update translations 2018-06-15 15:39:16 +12:00
Damian Mooyman 2a36be9bed Remove obsolete branch-alias 2018-06-15 15:29:59 +12:00
Ingo Schommer 86850eefb7
Merge pull request #101 from open-sausages/pulls/4/update-recipe-branch
Update recipe branching
2018-06-14 16:44:39 +12:00
Damian Mooyman 7eacd8a3c3
Update recipe branching 2018-06-14 13:55:46 +12:00
Damian Mooyman cb14e856ff
Update travis.yml 2018-02-07 18:04:32 +13:00
Damian Mooyman dee598eb0e
Update travis.yml 2018-02-07 18:01:05 +13:00
Damian Mooyman ac23686777
Update alias 2018-02-07 17:59:11 +13:00
Damian Mooyman 00cff693a6
Merge remote-tracking branch 'origin/4.0' into 4 2018-02-05 18:07:25 +13:00
Daniel Hensby 4c549d653a
Merge pull request #98 from open-sausages/pulls/4.0/update-ci
Update CI to use recipe
2018-01-25 13:19:39 +00:00
Damian Mooyman 7c0795eb68
Update CI to use recipe 2018-01-25 11:57:16 +13:00
Daniel Hensby 7e927aed74
Merge branch '3' into 4 2018-01-16 12:18:34 +00:00
Daniel Hensby b7b1b4d024
Merge branch '4.0' into 4 2018-01-16 12:18:32 +00:00
Daniel Hensby 2f59965515
Merge branch '3.6' into 4.0 2018-01-16 12:17:40 +00:00
Daniel Hensby 01fd709d74
Merge branch '3.6' into 3 2018-01-16 12:13:58 +00:00
Daniel Hensby 5ddb796d15
Merge branch '3.5' into 3.6 2018-01-16 12:01:55 +00:00
Damian Mooyman 8443529646
Merge pull request #97 from creative-commoners/pulls/4.1/remove-report-heading
NEW Remove duplicated report heading
2017-12-18 14:14:46 +13:00
Robbie Averill 8a29918ac5 NEW Remove duplicated report heading 2017-12-17 21:25:19 +13:00
Damian Mooyman 4d3ad97a69
Merge pull request #95 from open-sausages/pulls/4.1/composer-does-prefer-dist
Feature Set .gitattributes to ignore docs and tests folder, and …
2017-12-14 17:54:35 +13:00
Damian Mooyman a9db6dee3a
Merge pull request #88 from creative-commoners/pulls/dynamic-link
NEW Add support for callable link formatting
2017-12-14 13:44:58 +13:00
Damian Mooyman b006a9968a Linting, phpdoc and code style fixes 2017-12-14 13:38:15 +13:00
Robbie Averill b4a3529339 FIX Minor linting violation in Report 2017-12-14 13:32:50 +13:00
Christopher Joe 4d8053611d Feature Set .gitattributes to ignore docs and tests folder, and some source asset files which are not needed 2017-12-13 12:32:55 +13:00
Damian Mooyman ed16d96842 Update translations 2017-12-07 11:08:26 +13:00
Christopher Joe 86f845972f BUG Actioned feedback 2017-11-27 14:46:05 +13:00
Will Rossiter 5b335ad511 NEW Add support for callable link formatting 2017-11-27 14:46:05 +13:00
Damian Mooyman 6ac1dea913
Merge pull request #93 from dhensby/pulls/3.5/phpunit-loosen-constraint
Loosen PHPUnit constraints
2017-11-20 13:57:13 +13:00
Damian Mooyman e575bff1af
Merge pull request #94 from dhensby/pulls/3.5/remove-php7-test
Remove php7 test suite as its pointless
2017-11-20 13:56:54 +13:00
Daniel Hensby 14eeb10d31
Remove php7 test suite as its pointless 2017-11-17 12:07:34 +00:00
Daniel Hensby b406d8724f
Loosen PHPUnit constraints 2017-11-17 11:41:43 +00:00
Damian Mooyman cd94e99d89
Merge remote-tracking branch 'origin/4.0' into 4 2017-11-16 10:28:01 +13:00
Daniel Hensby ece79fd2b2
Merge pull request #90 from creative-commoners/pulls/4.0/filter-button-class
FIX Add primary button class to 'Filter' button
2017-11-07 15:59:47 +00:00
Damian Mooyman ec40ffb2cf
Merge pull request #89 from dhensby/pulls/3.5/composer-autoload
Add composer autoloading support to 3.x
2017-11-02 11:42:04 +13:00
Robbie Averill 26dc7373ba FIX Add primary button class to 'Filter' button 2017-10-30 11:51:00 +13:00
Daniel Hensby a548f0290e
Add composer autoloading support to 3.x 2017-10-25 18:44:03 +01:00
Damian Mooyman f7815b52e5
Merge remote-tracking branch 'origin/4.0' into 4 2017-10-25 17:15:18 +13:00
Daniel Hensby 0f387ad6a1 Merge pull request #87 from open-sausages/pulls/4.0/i-smith-thee-with-my-css-hammer
BUG align heading properly
2017-10-12 08:33:14 +01:00
Christopher Joe 6fe1e2c5b2 BUG align heading properly 2017-10-12 16:48:08 +13:00
Damian Mooyman 8020e36409
Merge remote-tracking branch 'origin/4.0' into 4 2017-10-12 12:58:30 +13:00
Damian Mooyman c5ca89a173
Update editorconfig 2017-10-12 12:57:05 +13:00
Damian Mooyman 7a2344117e Remove obsolete branch-alias 2017-10-11 17:31:46 +13:00
Chris Joe 4a80bd9166 Merge pull request #85 from open-sausages/pulls/4.0/vendor-phpunit
BUG Fix vendor bootstrap path
2017-10-05 10:06:15 +13:00
Damian Mooyman ca60b94f2e
BUG Fix vendor bootstrap path 2017-10-05 09:50:04 +13:00
Damian Mooyman 418ac59e90 Merge pull request #84 from open-sausages/pulls/4/vendorise-me-baby
Expose as vendor module
2017-10-03 16:22:47 +13:00
Ingo Schommer 9ce1eedf2f Expose as vendor module 2017-09-27 18:09:56 +13:00
Chris Joe 04e4c7d1a4 Merge pull request #82 from open-sausages/pulls/1.0/toolbar-style-layout
FIX toolbar title layout
2017-09-21 16:47:51 +12:00
Damian Mooyman 9afcf7780a Merge pull request #83 from dhensby/pulls/4/travis-composer-updates
Make composer installs on travis more efficient
2017-09-21 00:23:47 +12:00
Daniel Hensby 448955d82f
Make composer installs on travis more efficient 2017-09-19 11:56:55 +01:00
Saophalkun Ponlu cda78e2d88 FIX add space below report filter form 2017-09-19 10:15:08 +12:00
Saophalkun Ponlu 5351ba670f FIX toolbar title layout 2017-09-15 15:44:31 +12:00
Damian Mooyman e9c7273bb4 Update translations 2017-08-07 14:34:14 +12:00
Daniel Hensby d0f65850fa
Merge branch '3' into 4 2017-07-26 10:45:44 +01:00
Daniel Hensby 6025de29cc
Merge branch '3.6' into 3 2017-07-26 10:45:27 +01:00
Daniel Hensby e8fef7ebdd
Merge branch '3.5' into 3.6 2017-07-26 10:45:00 +01:00
Daniel Hensby 28b79c88ff
Stay on travis precise for now 2017-07-26 10:43:43 +01:00
Marco Hermo 09bd6fc231 Adds missing PreviewPanel template file to the main reports folder (#75)
See Issue 1841 - BUG Navigating to a page from reports section loads broken CMSMain view
2017-07-21 09:16:28 +12:00
Daniel Hensby 879ce3086c Merge pull request #80 from robbieaverill/pulls/4.0/make-excluded-reports-configurable
API Remove Report::add_excluded_report() and make excluded_reports configurable
2017-07-17 14:06:12 +01:00
Daniel Hensby 36d745ab24 Add .codecov.yml file 2017-07-17 14:04:44 +01:00
Daniel Hensby 92ffc87e97 Merge pull request #81 from robbieaverill/pulls/4.0/enable-code-coverage
FIX Re-enable code coverage runs with phpdbg
2017-07-17 14:04:05 +01:00
Robbie Averill 85c79d4e66 FIX Re-enable code coverage runs with phpdbg 2017-07-16 16:42:16 +12:00
Robbie Averill 4aefa50087 Remove unused test report stubs 2017-07-16 16:37:08 +12:00
Robbie Averill c3d2ba06c6 Update SilverStripe version requirement in readme 2017-07-16 16:36:22 +12:00
Robbie Averill f4af1fab77 API Remove Report::add_excluded_report() and make excluded_reports configurable 2017-07-16 16:36:12 +12:00
Christopher Joe bf4e7224e0 Update composer alias 2017-07-06 09:20:17 +12:00
Damian Mooyman fdbd6015d8
Fix dependencies 2017-07-04 09:18:21 +12:00
Damian Mooyman 62419d748d Update translations 2017-07-03 17:17:41 +12:00
Damian Mooyman 614ebcfcd9 Remove obsolete branch-alias 2017-07-03 16:53:55 +12:00
Chris Joe e532d01821 Merge pull request #79 from open-sausages/pulls/4.0/upgrader-tweaks
Add extra upgrade rules
2017-07-03 15:59:12 +12:00
Damian Mooyman b1ec225246
Add extra upgrade rules 2017-07-03 14:32:26 +12:00
Daniel Hensby 84fb64bf8f
Merge branch '3' 2017-06-28 11:18:15 +01:00
Ingo Schommer 9e7108420b Merge pull request #78 from sminnee/resource-loading
API: Remove REPORTS_DIR and its use.
2017-06-28 21:00:19 +12:00
Sam Minnee cf5115624d API : Remove REPORTS_DIR and its use.
Relies on
https://github.com/silverstripe/silverstripe-framework/pull/7065
2017-06-28 16:39:18 +12:00
Daniel Hensby 76b59e7464
Merge branch '3.6' into 3 2017-06-27 13:17:31 +01:00
Daniel Hensby 108869841c Merge pull request #77 from open-sausages/pulls/4.0/namespace-in-docs
FIX namespaces in docs
2017-06-27 12:47:32 +01:00
Saophalkun Ponlu ab0b3d8a2f FIX namespaces in docs 2017-06-27 15:52:13 +12:00
Damian Mooyman 1e386c83f6 Merge remote-tracking branch 'origin/3'
# Conflicts:
#	composer.json
2017-06-27 13:41:28 +12:00
Ingo Schommer a58416b6f6 New style travis tests
- Removed PHP 5.5. build (no longer supported)
- Removed PG and SQLite tests (tested through installer nightly)
- Added code coverage and linting tests
- Fixed linting errors
2017-06-26 21:45:56 +12:00
Ingo Schommer 19fa5355ce Merge pull request #76 from creative-commoners/pulls/3.6/add-php7-build
Add PHP 7.1 and SS 3.6 build to Travis configuration
2017-06-26 15:16:01 +12:00
Robbie Averill 83dae0fbac Add PHP 7.1 and SS 3.6 build to Travis configuration 2017-06-23 16:01:58 +12:00
Ingo Schommer 179310e457 Merge pull request #74 from open-sausages/pulls/4.0/app-object
[WIP] Upgrade module for app object refactor
2017-06-22 23:00:52 +12:00
Damian Mooyman 7bab717c8d Update phpunit 2017-06-21 21:05:12 +12:00
Damian Mooyman 8dbdc98cc2
Upgrade module for app object refactor 2017-06-21 16:30:14 +12:00
Simon Erkelens 03125b8c6c API Changes for Authenticator refactor 2017-06-09 16:48:30 +12:00
Daniel Hensby 2aa6433357
Merge branch '3.6' into 3 2017-05-31 00:06:39 +01:00
Daniel Hensby 2e29bf27fe
Merge branch '3.5' into 3.6 2017-05-31 00:06:19 +01:00
Daniel Hensby c249173e48
Merge tag '3.6.0' into 3.6
Release 3.6.0
2017-05-31 00:06:19 +01:00
Daniel Hensby be44c5e7df
Merge branch '3.4' into 3.5 2017-05-31 00:05:59 +01:00
Daniel Hensby 63bbc0bae4
Merge tag '3.5.4' into 3.5
Release 3.5.4
2017-05-31 00:05:59 +01:00
Daniel Hensby d1764ffc08
Merge tag '3.4.6' into 3.4
Release 3.4.6
2017-05-31 00:05:32 +01:00
Daniel Hensby a0fc3aa86f
Merge remote-tracking branch 'security/3.5.4' into 3.6.0 2017-05-29 01:30:58 +01:00
Daniel Hensby c2e804ad72
Merge remote-tracking branch 'security/3.4.6' into 3.5.4 2017-05-29 01:04:35 +01:00
Daniel Hensby c927870432
Merge branch '3.3' into 3.4 2017-05-28 21:37:05 +00:00
Daniel Hensby 3f112ecfcd Merge pull request #71 from open-sausages/pulls/4.0/remove-toolbar-header
Remove empty toolbar header from reports list
2017-05-18 11:18:05 +01:00
Ingo Schommer c37c69097d Remove empty toolbar header from reports list
See https://github.com/silverstripe/silverstripe-cms/issues/981
2017-05-18 22:06:02 +12:00
Garion Herman 19974fe1f2 Fix PHPDoc for Report::add_excluded_reports method. 2017-05-11 09:30:15 +12:00
Aaron Carlino 664fa75a02 Reorganise i18n keys 2017-05-08 17:56:43 +12:00
Ingo Schommer 24afd61131 Merge pull request #70 from sminnee/drop-php55
FIX: Drop php5.5, add php7.1, simplify build
2017-05-04 16:13:54 +12:00
Sam Minnee 4332d2fa8e FIX: Drop php5.5, add php7.1, simplify build
SS4 no longer supports PHP 5.5 so I’ve dropped it. In addition I’ve
reduced the double-up of builds as we don’t need so many. And I’ve
added PHP 7.1
2017-05-04 15:25:14 +12:00
Daniel Hensby 7172eecd08
Aliasing 3 as 3.7.x-dev 2017-04-21 16:13:40 +01:00
Loz Calver c1d2696514 Merge pull request #65 from sminnee/fix-php-req
FIX: Relax PHP version requirement.
2017-04-04 00:03:05 +01:00
Sam Minnee e5f51b14a3 FIX: Relax PHP version requirement.
PHP7 support for SS3 is currently under development and the safest 
approach is to fix this module first.
2017-04-04 10:58:52 +12:00
Damian Mooyman 27b2037c68 Merge pull request #64 from sminnee/license-file
FIX: Rename license file to match module standard.
2017-03-29 17:34:30 +13:00
Sam Minnee 59a9ff8459 FIX: Rename license file to match module standard. 2017-03-29 12:58:41 +13:00
Damian Mooyman 5dace88830 Merge pull request #63 from open-sausages/pulls/add-admin-dep
Add silverstripe/admin dep
2017-03-15 14:24:46 +13:00
Ingo Schommer 02446a47a5 Add silverstripe/admin dep 2017-03-15 14:09:09 +13:00
Ingo Schommer 376d2bfbc1 Merge pull request #62 from open-sausages/pulls/4.0/admin-module-split
API move CMSPreviewable to ORM
2017-03-15 12:02:05 +13:00
Damian Mooyman 4599b2b52c
API move CMSPreviewable to ORM 2017-03-15 10:38:36 +13:00
Damian Mooyman 240723b378 Merge pull request #60 from silverstripe/fix-composer
FIX: Allow pre-release versions of SS4.
2017-02-27 14:39:07 +13:00
Sam Minnee c9e2c249c2 FIX: Allow pre-release versions of SS4.
Since SS4 has not yet been released, and this module is used to test
pre-release versions of SS4, we need to have @dev on the requirement
to make it as flexible as possible.

As a general rule, modules that plug *into* SS4 rather than making *use*
of it should have @dev on the end of their dependencies.
2017-02-27 09:19:43 +11:00
Ingo Schommer 015b400fb7 Merge pull request #59 from open-sausages/pulls/4.0/i18n-locale
Remove unnecessary tinymce config
2017-02-16 10:56:51 +13:00
Damian Mooyman b4e047b39f
Remove unnecessary tinymce config 2017-01-26 17:22:54 +13:00
Daniel Hensby 37a7e68f2d Merge pull request #58 from open-sausages/pulls/4.0/i18n-symfony
BUG Fix missing default on _t(‘GridField.Filter’)
2017-01-24 12:19:07 +00:00
Damian Mooyman 3c8a56f904
BUG Fix missing default on _t(‘GridField.Filter’) 2017-01-24 12:30:06 +13:00
Damian Mooyman 3cadebf595 Merge pull request #57 from open-sausages/features/4.0/ui-button-refresh
Refresh CMS UI buttons to new flat style and bootstrap classes
2017-01-11 14:27:02 +13:00
Paul Clarke d67aee56fe Update icon 2016-12-20 16:13:46 +13:00
Paul Clarke 417fb81ae4 add font-icon to menu 2016-12-20 13:30:50 +13:00
Daniel Hensby cb06593a65
Merge branch '3' 2016-11-30 11:22:46 +00:00
Daniel Hensby b10955d985
Merge branch '3.5' into 3 2016-11-28 14:14:09 +00:00
Daniel Hensby dcb8024158
Merge tag '3.5.0' into 3.5
Release 3.5.0
2016-11-28 14:13:29 +00:00
Daniel Hensby 9c5974a13b
Merge branch '3.4' into 3.5.0 2016-11-15 12:09:14 +00:00
Daniel Hensby da4aeda90e
Merge branch '3.3' into 3.4 2016-11-15 12:08:32 +00:00
Daniel Hensby 65e0b6ef35
Merge branch '3.2' into 3.3 2016-11-15 12:08:05 +00:00
Daniel Hensby 8e5462794d
Merge pull request #1 from silverstripe-security/patch/3.2/SS-2016-012 2016-11-15 12:07:00 +00:00
Damian Mooyman a0eda1edd1 Increment 3 alias to 3.6 2016-11-14 10:04:09 +13:00
Daniel Hensby 804ff7c247
FIX Fixing test errors 2016-11-10 13:01:37 +00:00
Daniel Hensby 537f4da88f
Merge branch '3' 2016-11-10 12:19:27 +00:00
Damian Mooyman 43462f1afa Merge pull request #55 from open-sausages/features/4.0/jlayout-to-flexbox
Replace Layout CSS classes for flexbox classes
2016-10-11 17:36:26 +13:00
Damian Mooyman 8dd40b3c26 Merge pull request #50 from open-sausages/pulls/4.0/reports-filter-spacing
Add spacing below filter action
2016-10-05 19:42:45 +13:00
Paul Clarke 97eac2eb09 Replace Layout CSS classes for flexbox classes 2016-10-05 17:48:03 +13:00
Loz Calver fa7e0825c5 Merge pull request #54 from sminnee/the-chrisening
MINOR: Make use of static::class
2016-09-28 09:22:40 +01:00
Sam Minnee c813488412 MINOR: Make use of static::class 2016-09-28 11:36:52 +13:00
Daniel Hensby 2c7846cb72 Merge pull request #53 from sminnee/no-class-property
FIX: Remove referencies to Object::$class
2016-09-27 22:15:51 +01:00
Sam Minnee fe0ca63c7a FIX: Remove referencies to Object::$class
This property is being deprecated in SS4 and so this removes references
to it.
2016-09-28 10:00:51 +13:00
Paul Clarke 3d144b3afc Add spacing below filter action 2016-09-20 17:28:05 +12:00
Will Rossiter 0008f474b8 Update Travis build URL 2016-09-19 19:17:07 +12:00
Will Rossiter 3b32047f28 Merge pull request #49 from open-sausages/pulls/4.0/alignment-and-spacing
Alignment and spacing of main CMS panels
2016-09-19 19:05:45 +12:00
Loz Calver c4ba67c1fb Merge pull request #48 from open-sausages/webpack
Remove HTMLEditorField.js include
2016-09-15 09:45:36 +01:00
Paul Clarke 9cee3c25fb Remove custom reportAdmin css overrides 2016-09-15 18:23:43 +12:00
Ingo Schommer 1e8d94afe1 Remove HTMLEditorField.js include
This should already be handled by the CMS bundle.
2016-09-15 15:25:14 +12:00
Damian Mooyman b2f3902996 Rename SS_ prefixed classes (#46) 2016-09-09 18:11:38 +12:00
Ingo Schommer c6b6c5fb2a Merge pull request #45 from open-sausages/pulls/4.0/namespace-everything
Upgrade code for namespaces
2016-09-08 17:57:19 +12:00
Damian Mooyman bd17cca223
Upgrade code for namespaces
Apply SilverStripe\Reports namespace
2016-09-08 15:37:35 +12:00
Daniel Hensby f759a7c6db Merge pull request #44 from open-sausages/pulls/4.0/namespace-admin
Namespace Admin module
2016-08-17 11:45:37 +01:00
Damian Mooyman a96ab15af3 API Fix issue with namespaced reports
Add permission code to reports
Fix include paths
2016-08-16 11:43:45 +12:00
Damian Mooyman 8f14b94433 Merge 3.4 into 3 2016-08-15 19:05:25 +12:00
Damian Mooyman 20f929ba8b Merge 3.3 into 3.4 2016-08-15 19:01:57 +12:00
Damian Mooyman 8395a55442 Merge 3.2 into 3.3 2016-08-15 18:47:45 +12:00
Damian Mooyman ac0d621d6f Merge 3.4.1 into 3.4 2016-08-15 18:37:56 +12:00
Damian Mooyman f92b83fc45 Merge 3.3.3 into 3.3 2016-08-15 18:36:18 +12:00
Damian Mooyman eb096e869f Merge 3.2.5 into 3.2 2016-08-15 18:35:03 +12:00
Daniel Hensby c1525c8ba6 [SS-2016-012] FIX Missing ACL check on ReportAdmin
This issue exposed reports to users able to guess the URL of a Report that they were not allowed to view the report
2016-08-15 15:54:47 +12:00
Daniel Hensby efa20d2da0 [SS-2016-012] FIX Missing ACL check on ReportAdmin
This issue exposed reports to users able to guess the URL of a Report that they were not allowed to view the report
2016-08-15 15:05:41 +12:00
Daniel Hensby cff2ea9a98 [SS-2016-012] FIX Missing ACL check on ReportAdmin
This issue exposed reports to users able to guess the URL of a Report that they were not allowed to view the report
2016-08-15 14:17:02 +12:00
Damian Mooyman a325bfb222 Apply SilverStripe\Admin namespace 2016-08-12 10:38:40 +12:00
Hamish Friedlander 83c7e9955b Merge pull request #42 from open-sausages/pulls/4.0/namespace-cms
API Update for SilverStripe\CMS namespace
2016-08-11 20:44:13 +07:00
Damian Mooyman 5953957881 API Update for SilverStripe\CMS namespace
Remove unused reports
2016-08-08 18:14:06 +12:00
Damian Mooyman a446714e5e Merge 3.4 into 3
# Conflicts:
#	composer.json
2016-08-05 19:15:26 +12:00
Damian Mooyman f17fad179f Merge 3.3 into 3.4
# Conflicts:
#	code/Report.php
2016-08-05 16:48:52 +12:00
Hamish Friedlander 77a696ecdd Merge pull request #36 from open-sausages/features/4.0/gridfield-styles
Class change for new gridfield styles, moved report actions to appear above gridfield
2016-08-04 11:54:19 +12:00
Damian Mooyman c54b8b5a6c Fix link formatting 2016-08-01 16:51:21 +12:00
Damian Mooyman d2142f252e Fix psr-2 formatting 2016-08-01 16:51:21 +12:00
Paul Clarke f04975c64e Remove additional title and move actions to top 2016-08-01 16:47:38 +12:00
Paul Clarke 9fdf236611 Add new styling for links in gridfield 2016-08-01 16:47:08 +12:00
Hamish Friedlander 2502118a21 Merge pull request #40 from open-sausages/pulls/4.0/fix-form-actions
BUG Fix broken form actions on parent and nested gridfields
2016-08-01 16:40:20 +12:00
Damian Mooyman 9d31bb0542 BUG Fix broken form actions on parent and nested gridfields 2016-08-01 16:35:37 +12:00
Damian Mooyman 6c1f17da91 Remove obsolete alias 2016-07-28 14:34:38 +12:00
Daniel Hensby c6fdf440a6 Merge pull request #37 from tractorcow/pulls/3.3/fix-broken-links
BUG Fix incorrect url manipulation
2016-07-21 13:37:40 +01:00
Damian Mooyman 87477a1e01
BUG Fix incorrect url manipulation
Fixes https://github.com/silverstripe/silverstripe-cms/issues/1183
2016-07-21 18:06:19 +12:00
Daniel Hensby 8a5741aa00 Merge pull request #39 from dhensby/pulls/4/admin-url-fix
FIX Use new admin_url
2016-07-19 14:48:22 +01:00
Daniel Hensby 761cbf0dc2
FIX Use new admin_url 2016-07-18 13:06:49 +01:00
Daniel Hensby c876a21669
Merge branch '3' 2016-07-18 13:02:20 +01:00
Daniel Hensby ca526b08c3
[SS-2016-012] FIX Missing ACL check on ReportAdmin
This issue exposed reports to users able to guess the URL of a Report that they were not allowed to view the report
2016-07-14 16:57:16 +01:00
Damian Mooyman 2d47fed75d Fix ReportAdmin::Link() not returning correct home url (#38) 2016-07-14 17:51:20 +12:00
Damian Mooyman 39b6d12969 API Apply SilverStripe\Security namespace (#35) 2016-07-07 13:43:27 +12:00
Ingo Schommer c4cdeda7dc Merge pull request #33 from open-sausages/pulls/4.0/namespace-orm
API Apply SilverStripe\ORM namespace
2016-07-01 15:09:24 +12:00
Will Rossiter 6c31b23b2d Merge pull request #34 from mikenz/patch-1
ReportTest needs the database
2016-06-24 19:36:37 +12:00
Mike Cochrane 0a2c248e6b ReportTest needs the database
ReportTest needs the database, if run in isolation these tests will fail.
2016-06-24 18:43:35 +12:00
Damian Mooyman ab81961115
API Apply SilverStripe\ORM namespace 2016-06-23 17:32:58 +12:00
Will Rossiter 9c124f1d53 Merge pull request #32 from dhensby/pulls/3.4/fix-hardcoded-admin-url
FIX No longer hardcoding admin links
2016-06-10 08:40:05 +12:00
Daniel Hensby 3bb32eb013
FIX Tests need the DB 2016-06-09 14:25:01 +01:00
Daniel Hensby 68c4040299
FIX No longer hardcoding admin links 2016-06-09 13:40:29 +01:00
Daniel Hensby 1890c208e3 Merge pull request #31 from silverstripe-labs/copyright-in-contributingmd
Create CONTRIBUTING.md
2016-05-31 13:58:33 +01:00
Sam Minnée 36298ee8c1 Create CONTRIBUTING.md
New contribution guide to mathc https://github.com/silverstripe/silverstripe-framework/pull/5610
2016-05-30 14:37:53 +12:00
Damian Mooyman 68d9533542
Alias 3 as 3.5 2016-05-19 16:14:08 +12:00
Daniel Hensby 1d8f3b0c7c Merge pull request #30 from chillu/pulls/remove-triple-title
Remove triple report titles
2016-05-11 10:02:52 +01:00
Ingo Schommer b63600c392 Remove triple report titles 2016-05-10 22:24:40 +12:00
Daniel Hensby a39515357d
Merge branch '3' 2016-04-26 02:32:15 +01:00
Daniel Hensby fe17073355
Merge branch '3.3' into 3 2016-04-26 02:30:18 +01:00
Daniel Hensby b985ce0eba
Merge branch '3.2' into 3.3 2016-04-26 02:29:59 +01:00
Damian Mooyman 7eb6b21494 Merge pull request #29 from dhensby/pulls/3.2/fix-deps
Decouple from CMS module
2016-03-22 17:41:09 +13:00
Daniel Hensby b1566f3e79 Decoupling from CMS module 2016-03-21 12:15:27 +00:00
Damian Mooyman dfb7b4d29f Merge pull request #28 from dhensby/pulls/3.2/join-links-fix
FIX Bad joining of links in reports
2016-03-21 14:34:50 +13:00
Daniel Hensby 57cfe3c66a FIX Bad joining of links in reports 2016-03-18 11:03:26 +00:00
Damian Mooyman 94faf34266 Merge pull request #27 from chillu/pulls/fix-phpunit-dependency
Require-dev for PHPUnit
2016-03-07 20:46:20 +13:00
Ingo Schommer 3c6c4b33db Require-dev for PHPUnit
If not set, it breaks the root composer.json generation in travis-support, since it falls back to PHPUnit 3.7.
See https://github.com/silverstripe-labs/silverstripe-travis-support/blob/master/src/ComposerGenerator.php

See d9e292ba28
for same fix on cms module.
2016-03-07 20:41:05 +13:00
Damian Mooyman d031f53e73 Fix incorrect version dependency 2016-01-25 16:59:20 +13:00
Damian Mooyman f777f36c68 Merge remote-tracking branch 'origin/3'
# Conflicts:
#	code/Report.php
#	composer.json
#	tests/ReportTest.php
2016-01-25 16:20:10 +13:00
Damian Mooyman e7ed9b2a77 Merge pull request #26 from helpfulrobot/update-license-year
Updated license year
2016-01-05 09:50:15 +13:00
helpfulrobot 32b39916d2 Updated license year 2016-01-01 06:36:21 +13:00
Damian Mooyman 59cff00bb7 Alias 3 branch as 3.4 2015-12-23 14:24:14 +13:00
Damian Mooyman fb3083688e Merge remote-tracking branch 'origin/3.2' into 3
# Conflicts:
#	.travis.yml
#	composer.json
2015-12-22 14:21:03 +13:00
Daniel Hensby ccb72a10c5 Merge pull request #25 from tractorcow/pulls/3/fix-tests
BUG Fix regressions is SS_Report::canView
2015-12-18 13:54:46 +00:00
Damian Mooyman 36241d52a0 BUG Fix regressions is SS_Report::canView 2015-12-18 11:41:34 +13:00
Damian Mooyman fc81b1f582 Merge pull request #14 from christopherdarling/patch-2
FIX: SS_Report canView should check permissions
2015-12-18 10:21:07 +13:00
Christopher Darling 5d0f833a39 FIX: SS_Report canView should check permissions
... checks for ADMIN / CMS_ACCESS_ReportAdmin (from ReportAdmin)

fixes #13
2015-12-17 12:27:54 +00:00
Damian Mooyman af2d51125c Merge pull request #23 from dhensby/pulls/travis-3.2
fixing travis config
2015-12-17 10:00:39 +13:00
Damian Mooyman 7b245c6df9 Merge pull request #22 from dhensby/pulls/travis-fix
Added standard Travis config
2015-12-17 09:59:57 +13:00
helpfulrobot 648b6bac40 Added standard Travis config 2015-12-16 11:54:58 +00:00
helpfulrobot 9f780b3eeb fixing travis config 2015-12-16 11:50:55 +00:00
Damian Mooyman 49e1631066 Merge pull request #21 from helpfulrobot/convert-to-psr-2
Converted to PSR-2
2015-12-16 12:26:16 +13:00
Damian Mooyman ff0598f827 Merge pull request #20 from helpfulrobot/add-standard-scrutinizer-config
Added standard Scrutinizer config
2015-12-16 12:25:09 +13:00
Damian Mooyman 8691a7d9b6 Merge pull request #18 from helpfulrobot/add-standard-editor-config
Added standard editor config
2015-12-16 12:22:35 +13:00
Damian Mooyman c6ce02bd33 Merge pull request #17 from helpfulrobot/add-standard-license
Added standard license
2015-12-16 12:22:18 +13:00
Damian Mooyman 1024c16ffe Merge pull request #16 from helpfulrobot/add-standard-git-attributes
Added standard git attributes
2015-12-16 12:21:52 +13:00
Damian Mooyman 891cb40654 Merge pull request #15 from helpfulrobot/add-standard-code-of-conduct
Added standard code of conduct
2015-12-16 12:21:04 +13:00
helpfulrobot b16e1c6788 Added standard code of conduct 2015-12-16 11:07:23 +13:00
helpfulrobot 75ece1710c Added standard git attributes 2015-12-16 11:07:17 +13:00
helpfulrobot 3014b3dbe3 Added standard license 2015-12-16 11:07:11 +13:00
helpfulrobot 26fb8d965a Added standard editor config 2015-12-16 11:07:05 +13:00
helpfulrobot 1e2e65d279 Added standard Scrutinizer config 2015-12-16 11:06:51 +13:00
helpfulrobot 93fced94f1 Converted to PSR-2 2015-12-16 11:06:45 +13:00
Damian Mooyman a09795b3a2 Merge remote-tracking branch 'origin/3' 2015-11-03 13:18:09 +13:00
Damian Mooyman 1e665a59b1 Merge remote-tracking branch 'origin/3.2' into 3 2015-11-03 13:11:11 +13:00
Daniel Hensby 0759392980 Merge pull request #2 from sunnysideup/master
adding counts to report links
2015-07-22 13:23:52 +01:00
Daniel Hensby 324da5fff4 Merge pull request #4 from jedateach/patch-1
Added note about visibility of reports
2015-07-22 13:22:39 +01:00
Daniel Hensby 740dbbfb99 Merge branch '3'
Conflicts:
	composer.json
2015-07-20 15:39:40 +01:00
Daniel Hensby c56b92a4c3 Merge branch '3.2' into 3 2015-07-20 15:37:49 +01:00
Damian Mooyman bcc7f358a8 Alias master as 4.0 2015-06-18 11:31:48 +12:00
Damian Mooyman 46281d7d33 Alias 3 as 3.3 2015-06-18 11:30:08 +12:00
Jeremy Shipman 6b17c8fb42 Added note about visibility of reports
I assumed the module wasn't working, but it turns out I just had no report to show.
2013-11-06 10:55:48 +13:00
Nicolaas 78cebe8723 adding count to reports
adds a count for each report.
2013-02-21 09:04:21 +13:00
Nicolaas c736906016 adding getCount method
the getCount method works out the number of "entries" for each report. E.g. if the report is "missing pages" and the method returns 3 then there are three "missing pages".
2013-02-21 09:01:26 +13:00
55 changed files with 1774 additions and 942 deletions

21
.editorconfig Normal file
View File

@ -0,0 +1,21 @@
# For more information about the properties used in this file,
# please see the EditorConfig documentation:
# http://editorconfig.org
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.{yml,js,json,css,scss,eslintrc}]
indent_size = 2
indent_style = space
[composer.json]
indent_size = 4
# The indent size used in the package.json file cannot be changed:
# https://github.com/npm/npm/pull/3180#issuecomment-16336516

7
.gitattributes vendored Normal file
View File

@ -0,0 +1,7 @@
/tests export-ignore
/.tx export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/.travis.yml export-ignore
/.scrutinizer.yml export-ignore
/*.dist export-ignore

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,27 +0,0 @@
# See https://github.com/silverstripe-labs/silverstripe-travis-support for setup details
language: php
php:
- 5.6
sudo: false
env:
- DB=MYSQL CORE_RELEASE=3.2
matrix:
include:
- php: 5.4
env: DB=PGSQL CORE_RELEASE=3.2
- php: 5.3
env: DB=MYSQL CORE_RELEASE=3.2
- php: 5.5
env: DB=MYSQL CORE_RELEASE=3
before_script:
- git clone git://github.com/silverstripe-labs/silverstripe-travis-support.git ~/travis-support
- php ~/travis-support/travis_setup.php --source `pwd` --target ~/builds/ss
- cd ~/builds/ss
script:
- vendor/bin/phpunit reports/tests/

9
.tx/config Normal file
View File

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

9
.upgrade.yml Normal file
View File

@ -0,0 +1,9 @@
mappings:
SS_Report: SilverStripe\Reports\Report
SilverStripe\Reports\SS_Report: SilverStripe\Reports\Report
SS_ReportWrapper: SilverStripe\Reports\ReportWrapper
SilverStripe\Reports\SS_ReportWrapper: SilverStripe\Reports\ReportWrapper
ReportAdmin: SilverStripe\Reports\ReportAdmin
SideReportView: SilverStripe\Reports\SideReportView
SideReportWrapper: SilverStripe\Reports\SideReportWrapper
SideReport: SilverStripe\Reports\SideReportView

15
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,15 @@
# Contributing
Any open source product is only as good as the community behind it. You can participate by sharing code, ideas, or simply helping others. No matter what your skill level is, every contribution counts.
See our [high level overview](http://silverstripe.org/contributing-to-silverstripe) on silverstripe.org on how you can help out.
## Copyright
**IMPORTANT: By supplying code to the SilverStripe core team in patches, tickets and pull requests, you agree to assign copyright of that code to SilverStripe Limited, on the condition that SilverStripe Limited releases that code under the BSD license.**
We ask for this so that the ownership in the license is clear and unambiguous, and so that community involvement doesn't stop us from being able to continue supporting these projects. By releasing this code under a permissive license, this copyright assignment won't prevent you from using the code in any way you see fit.
## Contributing code
See [contributing code](docs/en/05_Contributing/01_Code.md)

19
LICENSE
View File

@ -1,17 +1,12 @@
Copyright (c) 2007-2013, SilverStripe Limited - silverstripe.com
Copyright (c) 2017, SilverStripe Limited
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of SilverStripe nor the names of its contributors may be used to endorse or promote products derived from this software
without specific prior written permission.
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,13 +1,35 @@
# Reports
[![Build Status](https://secure.travis-ci.org/silverstripe-labs/silverstripe-reports.png?branch=master)](http://travis-ci.org/silverstripe-labs/silverstripe-reports)
[![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 3.2
* Silverstripe 4.0
## Troubleshooting
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

@ -1,6 +0,0 @@
<?php
$path = explode(DIRECTORY_SEPARATOR, dirname(__FILE__));
$dir = $path[count($path) - 1];
define('REPORTS_DIR', $dir);

1
code-of-conduct.md Normal file
View File

@ -0,0 +1 @@
When having discussions about this module in issues or pull request please adhere to the [SilverStripe Community Code of Conduct](https://docs.silverstripe.org/en/contributing/code_of_conduct).

View File

@ -1,439 +1,544 @@
<?php
namespace SilverStripe\Reports;
use ReflectionClass;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Core\ClassInfo;
use SilverStripe\Core\Convert;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\FormAction;
use SilverStripe\Forms\FormField;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldButtonRow;
use SilverStripe\Forms\GridField\GridFieldConfig;
use SilverStripe\Forms\GridField\GridFieldDataColumns;
use SilverStripe\Forms\GridField\GridFieldExportButton;
use SilverStripe\Forms\GridField\GridFieldPaginator;
use SilverStripe\Forms\GridField\GridFieldPrintButton;
use SilverStripe\Forms\GridField\GridFieldSortableHeader;
use SilverStripe\Forms\LiteralField;
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;
use SilverStripe\Security\Security;
use SilverStripe\View\ArrayData;
use SilverStripe\View\ViewableData;
/**
* Base "abstract" class creating reports on your data.
*
*
* Creating reports
* ================
*
*
* Creating a new report is a matter overloading a few key methods
*
*
* {@link title()}: Return the title - i18n is your responsibility
* {@link description()}: Return the description - i18n is your responsibility
* {@link sourceQuery()}: Return a SS_List of the search results
* {@link columns()}: Return information about the columns in this report.
* {@link parameterFields()}: Return a FieldList of the fields that can be used to filter this
* report.
*
*
* If you wish to modify the report in more extreme ways, you could overload these methods instead.
*
*
* {@link getReportField()}: Return a FormField in the place where your report's TableListField
* usually appears.
* {@link getCMSFields()}: Return the FieldList representing the complete right-hand area of the
* {@link getCMSFields()}: Return the FieldList representing the complete right-hand area of the
* report, including the title, description, parameter fields, and results.
*
*
* Showing reports to the user
* ===========================
*
*
* 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.
*
* @package reports
*
* @method SS_List|DataList sourceRecords($params = [], $sort = null, $limit = null)
* List of records to show for this report
*/
class SS_Report extends ViewableData {
/**
* This is the title of the report,
* used by the ReportAdmin templates.
*
* @var string
*/
protected $title = '';
class Report extends ViewableData
{
/**
* This is the title of the report,
* used by the ReportAdmin templates.
*
* @var string
*/
protected $title = '';
/**
* This is a description about what this
* report does. Used by the ReportAdmin
* templates.
*
* @var string
*/
protected $description = '';
/**
* The class of object being managed by this report.
* Set by overriding in your subclass.
*/
protected $dataClass = 'SiteTree';
/**
* This is a description about what this
* report does. Used by the ReportAdmin
* templates.
*
* @var string
*/
protected $description = '';
/**
* A field that specifies the sort order of this report
* @var int
*/
protected $sort = 0;
/**
* The class of object being managed by this report.
* Set by overriding in your subclass.
*/
protected $dataClass = SiteTree::class;
/**
* Reports which should not be collected and returned in get_reports
* @var array
*/
public static $excluded_reports = array(
'SS_Report',
'SS_ReportWrapper',
'SideReportWrapper',
'SideReport_RecentlyEdited', // @deprecated 3.2..4.0
'SideReport_EmptyPages', // @deprecated 3.2..4.0
'SideReport_BrokenVirtualPages', // @deprecated 3.2..4.0
'SideReport_BrokenRedirectorPages', // @deprecated 3.2..4.0
'SideReport_BrokenLinks', // @deprecated 3.2..4.0
'SideReport_BrokenFiles' // @deprecated 3.2..4.0
);
/**
* A field that specifies the sort order of this report
* @var int
*/
protected $sort = 0;
/**
* Return the title of this report.
*
* You have two ways of specifying the description:
* - overriding description(), which lets you support i18n
* - defining the $description property
*/
public function title() {
return $this->title;
}
/**
* Allows access to title as a property
*
* @return string
*/
public function getTitle() {
return $this->title();
}
/**
* Return the description of this report.
*
* You have two ways of specifying the description:
* - overriding description(), which lets you support i18n
* - defining the $description property
*/
public function description() {
return $this->description;
}
/**
* Return the {@link SQLQuery} that provides your report data.
*/
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);
}
}
/**
* Return a SS_List records for this report.
*/
public function records($params) {
if($this->hasMethod('sourceRecords')) {
return $this->sourceRecords($params, null, null);
} else {
$query = $this->sourceQuery();
$results = new ArrayList();
foreach($query->execute() as $data) {
$class = $this->dataClass();
$result = new $class($data);
$results->push($result);
}
return $results;
}
}
/**
* Reports which should not be collected and returned in get_reports
*
* @config
* @var array
*/
private static $excluded_reports = [
self::class,
ReportWrapper::class,
SideReportWrapper::class,
];
/**
* Return the data class for this report
*/
public function dataClass() {
return $this->dataClass;
}
/**
* 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;
public function getLink($action = null) {
return Controller::join_links(
'admin/reports/',
"$this->class",
'/', // trailing slash needed if $action is null!
"$action"
);
}
/**
* Return the title of this report.
*
* You have two ways of specifying the description:
* - overriding description(), which lets you support i18n
* - defining the $description property
*/
public function title()
{
return $this->title;
}
/**
* Exclude certain reports classes from the list of Reports in the CMS
* @param $reportClass Can be either a string with the report classname or an array of reports classnames
*/
static public function add_excluded_reports($reportClass) {
if (is_array($reportClass)) {
self::$excluded_reports = array_merge(self::$excluded_reports, $reportClass);
} else {
if (is_string($reportClass)) {
//add to the excluded reports, so this report doesn't get used
self::$excluded_reports[] = $reportClass;
}
}
}
/**
* Allows access to title as a property
*
* @return string
*/
public function getTitle()
{
return $this->title();
}
/**
* 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.
* @return array
*/
static public function get_excluded_reports() {
return self::$excluded_reports;
}
/**
* Return the description of this report.
*
* You have two ways of specifying the description:
* - overriding description(), which lets you support i18n
* - defining the $description property
*/
public function description()
{
return $this->description;
}
/**
* Return the SS_Report objects making up the given list.
* @return Array of SS_Report objects
*/
static public function get_reports() {
$reports = ClassInfo::subclassesFor(get_called_class());
/**
* Return the {@link DataQuery} that provides your report data.
*
* @param array $params
* @return DataQuery
*/
public function sourceQuery($params)
{
if (!$this->hasMethod('sourceRecords')) {
throw new \RuntimeException(
'Please override sourceQuery()/sourceRecords() and columns() or, '
. 'if necessary, override getReportField()'
);
}
$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
$reflectionClass = new ReflectionClass($report);
if ($reflectionClass->isAbstract()) continue; //don't use abstract classes
return $this->sourceRecords($params, null, null)->dataQuery();
}
$reportObj = new $report;
if (method_exists($reportObj,'sort')) $reportObj->sort = $reportObj->sort(); //use the sort method to specify the sort field
$reportsArray[$report] = $reportObj;
}
}
/**
* Return a SS_List records for this report.
*
* @param array $params
* @return SS_List
*/
public function records($params)
{
if ($this->hasMethod('sourceRecords')) {
return $this->sourceRecords($params, null, null);
} else {
$query = $this->sourceQuery($params);
$results = ArrayList::create();
foreach ($query->execute() as $data) {
$class = $this->dataClass();
$result = Injector::inst()->create($class, $data);
$results->push($result);
}
return $results;
}
}
uasort($reportsArray, function($a, $b) {
if($a->sort == $b->sort) return 0;
else return ($a->sort < $b->sort) ? -1 : 1;
});
public function columns()
{
return [];
}
return $reportsArray;
}
/////////////////////// UI METHODS ///////////////////////
/**
* Return the data class for this report
*/
public function dataClass()
{
return $this->dataClass;
}
/**
* 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
* data objects.
*
* @uses getReportField() to render a table, or similar field for the report. This
* method should be defined on the SS_Report subclasses.
*
* @return FieldList
*/
public function getCMSFields() {
$fields = new FieldList();
public function getLink($action = null)
{
return Controller::join_links(
ReportAdmin::singleton()->Link('show'),
$this->sanitiseClassName(static::class),
$action
);
}
if($title = $this->title()) {
$fields->push(new LiteralField('ReportTitle', "<h3>{$title}</h3>"));
}
if($description = $this->description()) {
$fields->push(new LiteralField('ReportDescription', "<p>" . $description . "</p>"));
}
// Add search fields is available
if($this->hasMethod('parameterFields') && $parameterFields = $this->parameterFields()) {
foreach($parameterFields as $field) {
// Namespace fields for easier handling in form submissions
$field->setName(sprintf('filters[%s]', $field->getName()));
$field->addExtraClass('no-change-track'); // ignore in changetracker
$fields->push($field);
}
/**
* Sanitise a model class' name for inclusion in a link
*
* @param string $class
* @return string
*/
protected function sanitiseClassName($class)
{
return str_replace('\\', '-', $class ?? '');
}
// Add a search button
$fields->push(new FormAction('updatereport', _t('GridField.Filter')));
}
$fields->push($this->getReportField());
$this->extend('updateCMSFields', $fields);
return $fields;
}
public function getCMSActions() {
// getCMSActions() can be extended with updateCMSActions() on a extension
$actions = new FieldList();
$this->extend('updateCMSActions', $actions);
return $actions;
}
/**
* Return a field, such as a {@link GridField} that is
* used to show and manipulate data relating to this report.
*
* Generally, you should override {@link columns()} and {@link records()} to make your report,
* but if they aren't sufficiently flexible, then you can override this method.
*
* @return FormField subclass
*/
public function getReportField() {
// TODO Remove coupling with global state
$params = isset($_REQUEST['filters']) ? $_REQUEST['filters'] : array();
$items = $this->sourceRecords($params, null, null);
/**
* 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(), $limit = 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();
}
$gridFieldConfig = GridFieldConfig::create()->addComponents(
new GridFieldToolbarHeader(),
new GridFieldSortableHeader(),
new GridFieldDataColumns(),
new GridFieldPaginator(),
new GridFieldButtonRow('after'),
new GridFieldPrintButton('buttons-after-left'),
new GridFieldExportButton('buttons-after-left')
);
$gridField = new GridField('Report',$this->title(), $items, $gridFieldConfig);
$columns = $gridField->getConfig()->getComponentByType('GridFieldDataColumns');
$displayFields = array();
$fieldCasting = array();
$fieldFormatting = array();
/**
* 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";
}
// Parse the column information
foreach($this->columns() as $source => $info) {
if(is_string($info)) $info = array('title' => $info);
if(isset($info['formatting'])) $fieldFormatting[$source] = $info['formatting'];
if(isset($info['csvFormatting'])) $csvFieldFormatting[$source] = $info['csvFormatting'];
if(isset($info['casting'])) $fieldCasting[$source] = $info['casting'];
/**
* 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.
*
* @return array
*/
public static function get_excluded_reports()
{
return (array) self::config()->get('excluded_reports');
}
if(isset($info['link']) && $info['link']) {
$link = singleton('CMSPageEditController')->Link('show');
$fieldFormatting[$source] = '<a href=\"' . $link . '/$ID\">$value</a>';
}
/**
* Return the SS_Report objects making up the given list.
*
* @return Report[] Array of Report objects
*/
public static function get_reports()
{
$reports = ClassInfo::subclassesFor(get_called_class());
$displayFields[$source] = isset($info['title']) ? $info['title'] : $source;
}
$columns->setDisplayFields($displayFields);
$columns->setFieldCasting($fieldCasting);
$columns->setFieldFormatting($fieldFormatting);
$reportsArray = [];
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 ?? [])) {
continue;
}
$reflectionClass = new ReflectionClass($report);
// Don't use abstract classes
if ($reflectionClass->isAbstract()) {
continue;
}
return $gridField;
}
/**
* @param Member $member
* @return boolean
*/
public function canView($member = null) {
if(!$member && $member !== FALSE) {
$member = Member::currentUser();
}
return true;
}
/** @var Report $reportObj */
$reportObj = $report::create();
if ($reportObj->hasMethod('sort')) {
// Use the sort method to specify the sort field
$reportObj->sort = $reportObj->sort();
}
$reportsArray[$report] = $reportObj;
}
}
/**
* Return the name of this report, which
* is used by the templates to render the
* name of the report in the report tree,
* the left hand pane inside ReportAdmin.
*
* @return string
*/
public function TreeTitle() {
return $this->title();
}
uasort($reportsArray, function ($a, $b) {
if ($a->sort == $b->sort) {
return 0;
} else {
return ($a->sort < $b->sort) ? -1 : 1;
}
});
}
/**
* SS_ReportWrapper is a base class for creating report wappers.
*
* Wrappers encapsulate an existing report to alter their behaviour - they are implementations of
* the standard GoF decorator pattern.
*
* This base class ensure that, by default, wrappers behave in the same way as the report that is
* being wrapped. You should override any methods that need to behave differently in your subclass
* of SS_ReportWrapper.
*
* It also makes calls to 2 empty methods that you can override {@link beforeQuery()} and
* {@link afterQuery()}
*
* @package reports
*/
abstract class SS_ReportWrapper extends SS_Report {
protected $baseReport;
public function __construct($baseReport) {
$this->baseReport = is_string($baseReport) ? new $baseReport : $baseReport;
$this->dataClass = $this->baseReport->dataClass();
parent::__construct();
}
public function ID() {
return get_class($this->baseReport) . '_' . get_class($this);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Filtering
public function parameterFields() {
return $this->baseReport->parameterFields();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Columns
public function columns() {
return $this->baseReport->columns();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Querying
/**
* Override this method to perform some actions prior to querying.
*/
public function beforeQuery($params) {
}
/**
* Override this method to perform some actions after querying.
*/
public function afterQuery() {}
public function sourceQuery($params) {
if($this->baseReport->hasMethod('sourceRecords')) {
// The default implementation will create a fake query from our sourceRecords() method
return parent::sourceQuery($params);
} else if($this->baseReport->hasMethod('sourceQuery')) {
$this->beforeQuery($params);
$query = $this->baseReport->sourceQuery($params);
$this->afterQuery();
return $query;
} else {
user_error("Please override sourceQuery()/sourceRecords() and columns() in your base report", E_USER_ERROR);
}
}
public function sourceRecords($params = array(), $sort = null, $limit = null) {
$this->beforeQuery($params);
$records = $this->baseReport->sourceRecords($params, $sort, $limit);
$this->afterQuery();
return $records;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Pass-through
public function title() {
return $this->baseReport->title();
}
public function group() {
return $this->baseReport->hasMethod('group') ? $this->baseReport->group() : 'Group';
}
public function sort() {
return $this->baseReport->hasMethod('sort') ? $this->baseReport->sort() : 0;
}
public function description() {
return $this->baseReport->description();
}
public function canView($member = null) {
return $this->baseReport->canView($member);
}
return $reportsArray;
}
/////////////////////// 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
* data objects.
*
* @uses getReportField() to render a table, or similar field for the report. This
* method should be defined on the SS_Report subclasses.
*
* @return FieldList
*/
public function getCMSFields()
{
$fields = new FieldList();
if ($description = $this->description()) {
$fields->push(new LiteralField('ReportDescription', "<p>" . $description . "</p>"));
}
// Add search fields is available
if ($this->hasMethod('parameterFields') && $parameterFields = $this->parameterFields()) {
/** @var FormField $field */
foreach ($parameterFields as $field) {
// Namespace fields for easier handling in form submissions
$field->setName(sprintf('filters[%s]', $field->getName()));
$field->addExtraClass('no-change-track'); // ignore in changetracker
$fields->push($field);
}
// Add a search button
$formAction = FormAction::create(
'updatereport',
_t('SilverStripe\\Forms\\GridField\\GridField.Filter', 'Filter')
);
$formAction->addExtraClass('btn-primary mb-4');
$fields->push($formAction);
}
$fields->push($this->getReportField());
$this->extend('updateCMSFields', $fields);
return $fields;
}
public function getCMSActions()
{
// getCMSActions() can be extended with updateCMSActions() on a extension
$actions = new FieldList();
$this->extend('updateCMSActions', $actions);
return $actions;
}
/**
* Return a field, such as a {@link GridField} that is
* used to show and manipulate data relating to this report.
*
* Generally, you should override {@link columns()} and {@link records()} to make your report,
* but if they aren't sufficiently flexible, then you can override this method.
*
* @return \SilverStripe\Forms\FormField subclass
*/
public function getReportField()
{
$params = $this->getSourceParams();
$items = $this->sourceRecords($params, null, null);
$gridFieldConfig = GridFieldConfig::create()->addComponents(
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);
/** @var GridFieldDataColumns $columns */
$columns = $gridField->getConfig()->getComponentByType(GridFieldDataColumns::class);
$displayFields = [];
$fieldCasting = [];
$fieldFormatting = [];
// Parse the column information
foreach ($this->columns() as $source => $info) {
if (is_string($info)) {
$info = ['title' => $info];
}
if (isset($info['formatting'])) {
$fieldFormatting[$source] = $info['formatting'];
}
if (isset($info['csvFormatting'])) {
$csvFieldFormatting[$source] = $info['csvFormatting'];
}
if (isset($info['casting'])) {
$fieldCasting[$source] = $info['casting'];
}
if (isset($info['link']) && $info['link']) {
if (is_callable($info['link'])) {
$fieldFormatting[$source] = $info['link'];
} else {
$fieldFormatting[$source] = function ($value, $item) {
if ($item instanceof CMSPreviewable) {
/** @var CMSPreviewable $item */
return sprintf(
'<a class="grid-field__link-block" href="%s" title="%s">%s</a>',
Convert::raw2att($item->CMSEditLink()),
Convert::raw2att($value),
Convert::raw2xml($value)
);
}
return $value;
};
}
}
$displayFields[$source] = isset($info['title']) ? $info['title'] : $source;
}
$columns->setDisplayFields($displayFields);
$columns->setFieldCasting($fieldCasting);
$columns->setFieldFormatting($fieldFormatting);
return $gridField;
}
/**
* @param Member $member
* @return boolean
*/
public function canView($member = null)
{
if (!$member && $member !== false) {
$member = Security::getCurrentUser();
}
$extended = $this->extendedCan('canView', $member);
if ($extended !== null) {
return $extended;
}
if ($member && Permission::checkMember($member, array('CMS_ACCESS_LeftAndMain', 'CMS_ACCESS_ReportAdmin'))) {
return true;
}
return false;
}
/**
* Helper to assist with permission extension
*
* {@see DataObject::extendedCan()}
*
* @param string $methodName Method on the same object, e.g. {@link canEdit()}
* @param Member|int $member
* @return boolean|null
*/
public function extendedCan($methodName, $member)
{
$results = $this->extend($methodName, $member);
if ($results && is_array($results)) {
// Remove NULLs
$results = array_filter($results ?? [], function ($v) {
return !is_null($v);
});
// If there are any non-NULL responses, then return the lowest one of them.
// If any explicitly deny the permission, then we don't get access
if ($results) {
return min($results);
}
}
return null;
}
/**
* Return the name of this report, which is used by the templates to render the name of the report in the report
* tree, the left hand pane inside ReportAdmin.
*
* @return string
*/
public function TreeTitle()
{
return $this->title();
}
/**
* Return additional breadcrumbs for this report. Useful when this report is a child of another.
*
* @return ArrayData[]
*/
public function getBreadcrumbs()
{
return [];
}
/**
* Get source params for the report to filter by
*
* @return array
*/
protected function getSourceParams()
{
$params = [];
if (Injector::inst()->has(HTTPRequest::class)) {
/** @var HTTPRequest $request */
$request = Injector::inst()->get(HTTPRequest::class);
$params = $request->param('filters') ?: $request->requestVar('filters') ?: [];
}
$this->extend('updateSourceParams', $params);
return $params;
}
}

View File

@ -1,189 +1,263 @@
<?php
namespace SilverStripe\Reports;
use SilverStripe\Admin\LeftAndMain;
use SilverStripe\Control\Controller;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldConfig;
use SilverStripe\Forms\GridField\GridFieldDataColumns;
use SilverStripe\Forms\GridField\GridFieldFooter;
use SilverStripe\Forms\GridField\GridFieldSortableHeader;
use SilverStripe\Forms\HTMLEditor\HTMLEditorConfig;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\SS_List;
use SilverStripe\Security\Member;
use SilverStripe\Security\PermissionProvider;
use SilverStripe\Security\Security;
use SilverStripe\View\ArrayData;
use SilverStripe\View\Requirements;
/**
* Reports section of the CMS.
*
*
* All reports that should show in the ReportAdmin section
* of the CMS need to subclass {@link SS_Report}, and implement
* of the CMS need to subclass {@link SilverStripe\Reports\Report}, and implement
* the appropriate methods and variables that are required.
*
* @see SS_Report
*
* @package reports
*/
class ReportAdmin extends LeftAndMain implements PermissionProvider {
private static $url_segment = 'reports';
private static $url_rule = '/$ReportClass/$Action';
private static $menu_title = 'Reports';
private static $template_path = null; // defaults to (project)/templates/email
private static $tree_class = 'SS_Report';
class ReportAdmin extends LeftAndMain implements PermissionProvider
{
private static $url_segment = 'reports';
private static $url_handlers = array(
'$ReportClass/$Action' => 'handleAction'
);
private static $menu_title = 'Reports';
/**
* Variable that describes which report we are currently viewing based on
* the URL (gets set in init method).
*
* @var string
*/
protected $reportClass;
private static $menu_icon_class = 'font-icon-chart-line';
protected $reportObject;
public function init() {
parent::init();
private static $template_path = null; // defaults to (project)/templates/email
//set the report we are currently viewing from the URL
$this->reportClass = (isset($this->urlParams['ReportClass']) && $this->urlParams['ReportClass'] !== 'index')
? $this->urlParams['ReportClass']
: null;
$allReports = SS_Report::get_reports();
$this->reportObject = (isset($allReports[$this->reportClass])) ? $allReports[$this->reportClass] : null;
private static $tree_class = Report::class;
// Set custom options for TinyMCE specific to ReportAdmin
HtmlEditorConfig::get('cms')->setOption('content_css', project() . '/css/editor.css');
HtmlEditorConfig::get('cms')->setOption('Lang', i18n::get_tinymce_lang());
private static $url_handlers = array(
'show/$ReportClass/$Action' => 'handleAction'
);
// Always block the HtmlEditorField.js otherwise it will be sent with an ajax request
Requirements::block(FRAMEWORK_DIR . '/javascript/HtmlEditorField.js');
Requirements::javascript(REPORTS_DIR . '/javascript/ReportAdmin.js');
}
/**
* Variable that describes which report we are currently viewing based on
* the URL (gets set in init method).
*
* @var string
*/
protected $reportClass;
/**
* Does the parent permission checks, but also
* makes sure that instantiatable subclasses of
* {@link 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 = Member::currentUser();
/**
* @var Report
*/
protected $reportObject;
if(!parent::canView($member)) return false;
private static $required_permission_codes = 'CMS_ACCESS_ReportAdmin';
$hasViewableSubclasses = false;
foreach($this->Reports() as $report) {
if($report->canView($member)) return true;
}
public function init()
{
parent::init();
return false;
}
// Set custom options for TinyMCE specific to ReportAdmin
HTMLEditorConfig::get('cms')->setOption('content_css', project() . '/css/editor.css');
/**
* Return a SS_List of SS_Report subclasses
* that are available for use.
*
* @return SS_List
*/
public function Reports() {
$output = new ArrayList();
foreach(SS_Report::get_reports() as $report) {
if($report->canView()) $output->push($report);
}
return $output;
}
Requirements::javascript('silverstripe/reports: javascript/ReportAdmin.js');
}
/**
* 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(SS_Report::get_reports()) > 0;
}
/**
* 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();
}
/**
* Returns the Breadcrumbs for the ReportAdmin
* @return ArrayList
*/
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('ReportAdmin')->Link();
if (!parent::canView($member)) {
return false;
}
if ($this->reportObject) {
//build breadcrumb trail to the current report
$items->push(new ArrayData(array(
'Title' => $this->reportObject->title(),
'Link' => Controller::join_links($this->Link(), '?' . http_build_query(array('q' => $this->request->requestVar('q'))))
)));
}
foreach ($this->Reports() as $report) {
if ($report->canView($member)) {
return true;
}
}
return $items;
}
return false;
}
/**
* Returns the link to the report admin section, or the specific report that is currently displayed
* @return String
*/
public function Link($action = null) {
if ($this->reportObject) {
$link = $this->reportObject->getLink($action);
} else {
$link = self::join_links(parent::Link('index'), $action);
}
return $link;
}
/**
* Return a SS_List of SS_Report subclasses
* that are available for use.
*
* @return SS_List
*/
public function Reports()
{
$output = new ArrayList();
/** @var Report $report */
foreach (Report::get_reports() as $report) {
if ($report->canView()) {
$output->push($report);
}
}
return $output;
}
public function providePermissions() {
$title = _t("ReportAdmin.MENUTITLE", LeftAndMain::menu_title_for_class($this->class));
return array(
"CMS_ACCESS_ReportAdmin" => array(
'name' => _t('CMSMain.ACCESS', "Access to '{title}' section", array('title' => $title)),
'category' => _t('Permission.CMS_ACCESS_CATEGORY', 'CMS Access')
)
);
}
public function handleAction($request, $action)
{
$this->reportClass = $this->unsanitiseClassName($request->param('ReportClass'));
public function getEditForm($id = null, $fields = null) {
$report = $this->reportObject;
if($report) {
$fields = $report->getCMSFields();
} else {
// List all reports
$fields = new FieldList();
$gridFieldConfig = GridFieldConfig::create()->addComponents(
new GridFieldToolbarHeader(),
new GridFieldSortableHeader(),
new GridFieldDataColumns(),
new GridFieldFooter()
);
$gridField = new GridField('Reports',false, $this->Reports(), $gridFieldConfig);
$columns = $gridField->getConfig()->getComponentByType('GridFieldDataColumns');
$columns->setDisplayFields(array(
'title' => _t('ReportAdmin.ReportTitle', 'Title'),
));
// Check report
if ($this->reportClass) {
$allReports = Report::get_reports();
if (empty($allReports[$this->reportClass])) {
return $this->httpError(404);
}
$this->reportObject = $allReports[$this->reportClass];
}
$columns->setFieldFormatting(array(
'title' => '<a href=\"$Link\" class=\"cms-panel-link\">$value</a>'
));
$gridField->addExtraClass('all-reports-gridfield');
$fields->push($gridField);
}
// Delegate to sub-form
return parent::handleAction($request, $action);
}
$actions = new FieldList();
$form = new Form($this, "EditForm", $fields, $actions);
$form->addExtraClass('cms-edit-form cms-panel-padded center ' . $this->BaseCSSClasses());
$form->loadDataFrom($this->request->getVars());
/**
* Unsanitise a model class' name from a URL param
*
* @param string $class
* @return string
*/
protected function unsanitiseClassName($class)
{
return str_replace('-', '\\', $class ?? '');
}
$this->extend('updateEditForm', $form);
/**
* 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;
}
return $form;
}
/**
* Returns the Breadcrumbs for the ReportAdmin
*
* @param bool $unlinked
* @return ArrayList
*/
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 = new FieldList();
$gridFieldConfig = GridFieldConfig::create()->addComponents(
GridFieldSortableHeader::create(),
GridFieldDataColumns::create(),
GridFieldFooter::create()
);
$gridField = GridField::create('Reports', false, $this->Reports(), $gridFieldConfig);
/** @var GridFieldDataColumns $columns */
$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 ($CountForOverview)</a>'
));
$gridField->addExtraClass('all-reports-gridfield');
$fields->push($gridField);
}
$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->loadDataFrom($this->request->getVars());
$this->extend('updateEditForm', $form);
return $form;
}
}

123
code/ReportWrapper.php Normal file
View File

@ -0,0 +1,123 @@
<?php
namespace SilverStripe\Reports;
use SilverStripe\Core\Injector\Injector;
/**
* SS_ReportWrapper is a base class for creating report wappers.
*
* Wrappers encapsulate an existing report to alter their behaviour - they are implementations of
* the standard GoF decorator pattern.
*
* This base class ensure that, by default, wrappers behave in the same way as the report that is
* being wrapped. You should override any methods that need to behave differently in your subclass
* of SS_ReportWrapper.
*
* It also makes calls to 2 empty methods that you can override {@link beforeQuery()} and
* {@link afterQuery()}
*/
abstract class ReportWrapper extends Report
{
protected $baseReport;
public function __construct($baseReport)
{
$this->baseReport = is_string($baseReport) ? Injector::inst()->create($baseReport) : $baseReport;
$this->dataClass = $this->baseReport->dataClass();
parent::__construct();
}
public function ID()
{
return get_class($this->baseReport) . '_' . static::class;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Filtering
public function parameterFields()
{
return $this->baseReport->parameterFields();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Columns
public function columns()
{
return $this->baseReport->columns();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Querying
/**
* Override this method to perform some actions prior to querying.
*/
public function beforeQuery($params)
{
}
/**
* Override this method to perform some actions after querying.
*/
public function afterQuery()
{
}
public function sourceQuery($params)
{
if ($this->baseReport->hasMethod('sourceRecords')) {
// The default implementation will create a fake query from our sourceRecords() method
return parent::sourceQuery($params);
} elseif ($this->baseReport->hasMethod('sourceQuery')) {
$this->beforeQuery($params);
$query = $this->baseReport->sourceQuery($params);
$this->afterQuery();
return $query;
} else {
throw new \RuntimeException(
"Please override sourceQuery()/sourceRecords() and columns() in your base report"
);
}
}
public function sourceRecords($params = array(), $sort = null, $limit = null)
{
$this->beforeQuery($params);
$records = $this->baseReport->sourceRecords($params, $sort, $limit);
$this->afterQuery();
return $records;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Pass-through
public function title()
{
return $this->baseReport->title();
}
public function group()
{
/** @skipUpgrade */
return $this->baseReport->hasMethod('group') ? $this->baseReport->group() : 'Group';
}
public function sort()
{
return $this->baseReport->hasMethod('sort') ? $this->baseReport->sort() : 0;
}
public function description()
{
return $this->baseReport->description();
}
public function canView($member = null)
{
return $this->baseReport->canView($member);
}
}

View File

@ -1,115 +0,0 @@
<?php
/**
* Renderer for showing SideReports in CMSMain
*
* @package reports
*/
class SideReportView extends ViewableData {
protected $controller, $report;
protected $parameters;
public function __construct($controller, $report) {
$this->controller = $controller;
$this->report = $report;
parent::__construct();
}
public function group() {
return _t('SideReport.OtherGroupTitle', "Other");
}
public function sort() {
return 0;
}
public function setParameters($parameters) {
$this->parameters = $parameters;
}
public function forTemplate() {
$records = $this->report->records($this->parameters);
$columns = $this->report->columns();
if($records && $records->Count()) {
$result = "<ul class=\"$this->class\">\n";
foreach($records as $record) {
$result .= "<li>\n";
foreach($columns as $source => $info) {
if(is_string($info)) $info = array('title' => $info);
$result .= $this->formatValue($record, $source, $info);
}
$result .= "\n</li>\n";
}
$result .= "</ul>\n";
} else {
$result = "<p class=\"message notice\">" .
_t(
'SideReport.REPEMPTY',
'The {title} report is empty.',
array('title' => $this->report->title())
)
. "</p>";
}
return $result;
}
protected function formatValue($record, $source, $info) {
// Field sources
//if(is_string($source)) {
$val = Convert::raw2xml($record->$source);
//} else {
// $val = $record->val($source[0], $source[1]);
//}
// Casting, a la TableListField. We're deep-calling a helper method on TableListField that
// should probably be pushed elsewhere...
if(!empty($info['casting'])) {
$val = TableListField::getCastedValue($val, $info['casting']);
}
// 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);
$val = eval('return "' . $format . '";');
}
$prefix = empty($info['newline']) ? "" : "<br>";
$classClause = "";
if(isset($info['title'])) {
$cssClass = preg_replace('/[^A-Za-z0-9]+/', '', $info['title']);
$classClause = "class=\"$cssClass\"";
}
if(isset($info['link']) && $info['link']) {
$linkBase = singleton('CMSPageEditController')->Link('show') . '/';
$link = ($info['link'] === true) ? $linkBase . $record->ID : $info['link'];
return $prefix . "<a $classClause href=\"$link\">$val</a>";
} else {
return $prefix . "<span $classClause>$val</span>";
}
}
}
/**
* A report wrapper that makes it easier to define slightly different behaviour for side-reports.
*
* This report wrapper will use sideReportColumns() for the report columns, instead of columns().
*
* @package reports
*/
class SideReportWrapper extends SS_ReportWrapper {
public function columns() {
if($this->baseReport->hasMethod('sideReportColumns')) {
return $this->baseReport->sideReportColumns();
} else {
return parent::columns();
}
}
}

106
code/SideReportView.php Normal file
View File

@ -0,0 +1,106 @@
<?php
namespace SilverStripe\Reports;
use SilverStripe\Core\Convert;
use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\View\ViewableData;
/**
* Renderer for showing SideReports in CMSMain
*/
class SideReportView extends ViewableData
{
protected $controller;
protected $report;
protected $parameters;
public function __construct($controller, $report)
{
$this->controller = $controller;
$this->report = $report;
parent::__construct();
}
public function group()
{
return _t('SilverStripe\\Reports\\SideReport.OtherGroupTitle', "Other");
}
public function sort()
{
return 0;
}
public function setParameters($parameters)
{
$this->parameters = $parameters;
}
public function forTemplate()
{
$records = $this->report->records($this->parameters);
$columns = $this->report->columns();
if ($records && $records->Count()) {
$result = "<ul class=\"" . static::class . "\">\n";
foreach ($records as $record) {
$result .= "<li>\n";
foreach ($columns as $source => $info) {
if (is_string($info)) {
$info = array('title' => $info);
}
$result .= $this->formatValue($record, $source, $info);
}
$result .= "\n</li>\n";
}
$result .= "</ul>\n";
} else {
$result = "<p class=\"message notice\">" .
_t(
'SilverStripe\\Reports\\SideReport.REPEMPTY',
'The {title} report is empty.',
array('title' => $this->report->title())
)
. "</p>";
}
return $result;
}
protected function formatValue($record, $source, $info)
{
// Cast value
if (!empty($info['casting'])) {
$val = DBField::create_field($info['casting'], $record->source)->forTemplate();
} else {
$val = Convert::raw2xml($record->$source);
}
// 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 ?? '');
$val = eval('return "' . $format . '";');
}
$prefix = empty($info['newline']) ? "" : "<br>";
$classClause = "";
if (isset($info['title'])) {
$cssClass = preg_replace('/[^A-Za-z0-9]+/', '', $info['title'] ?? '');
$classClause = "class=\"$cssClass\"";
}
if (isset($info['link']) && $info['link']) {
$link = ($info['link'] === true && $record->hasMethod('CMSEditLink'))
? $record->CMSEditLink()
: $info['link'];
return $prefix . "<a $classClause href=\"$link\">$val</a>";
} else {
return $prefix . "<span $classClause>$val</span>";
}
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace SilverStripe\Reports;
/**
* A report wrapper that makes it easier to define slightly different behaviour for side-reports.
*
* This report wrapper will use sideReportColumns() for the report columns, instead of columns().
*/
class SideReportWrapper extends ReportWrapper
{
public function columns()
{
if ($this->baseReport->hasMethod('sideReportColumns')) {
return $this->baseReport->sideReportColumns();
} else {
return parent::columns();
}
}
}

View File

@ -1,24 +1,48 @@
{
"name": "silverstripe/reports",
"type": "silverstripe-module",
"homepage": "http://silverstripe.org",
"license": "BSD-3-Clause",
"keywords": ["silverstripe", "cms", "reports"],
"authors": [
{
"name": "SilverStripe",
"homepage": "http://silverstripe.com"
},
{
"name": "The SilverStripe Community",
"homepage": "http://silverstripe.org"
}
],
"require": {
"php": ">=5.3.3",
"silverstripe/framework": "~3.2"
},
"require-dev": {
"phpunit/PHPUnit": "~3.7"
}
}
"name": "silverstripe/reports",
"type": "silverstripe-vendormodule",
"description": "Reports module for SilverStripe CMS",
"homepage": "http://silverstripe.org",
"license": "BSD-3-Clause",
"keywords": [
"silverstripe",
"cms",
"reports"
],
"authors": [
{
"name": "SilverStripe",
"homepage": "http://silverstripe.com"
},
{
"name": "The SilverStripe Community",
"homepage": "http://silverstripe.org"
}
],
"require": {
"php": "^7.4 || ^8.0",
"silverstripe/framework": "^4.11",
"silverstripe/admin": "^1.6@dev",
"silverstripe/versioned": "^1.6@dev",
"silverstripe/config": "^1.0@dev",
"silverstripe/assets": "^1.6@dev",
"silverstripe/vendor-plugin": "^1"
},
"require-dev": {
"phpunit/phpunit": "^9.5",
"squizlabs/php_codesniffer": "^3.0"
},
"extra": {
"expose": [
"javascript"
]
},
"autoload": {
"psr-4": {
"SilverStripe\\Reports\\": "code/",
"SilverStripe\\Reports\\Tests\\": "tests/"
}
},
"minimum-stability": "dev",
"prefer-stable": true
}

View File

@ -2,22 +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;
}
});
$('.ReportAdmin').css({
'overflow-y': 'scroll',
'padding-top': 0
});
});
(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);

0
lang/_manifest_exclude Normal file
View File

7
lang/bg.yml Normal file
View File

@ -0,0 +1,7 @@
bg:
SilverStripe\Reports\ReportAdmin:
MENUTITLE: Отчети
ReportTitle: Заглавие
SilverStripe\Reports\SideReport:
OtherGroupTitle: Други
REPEMPTY: 'Отчетът за {title} е празен.'

7
lang/cs.yml Normal file
View File

@ -0,0 +1,7 @@
cs:
SilverStripe\Reports\ReportAdmin:
MENUTITLE: Výkazy
ReportTitle: Titulek
SilverStripe\Reports\SideReport:
OtherGroupTitle: Jiné
REPEMPTY: 'Výkaz {title} je prázdný.'

7
lang/da.yml Normal file
View File

@ -0,0 +1,7 @@
da:
SilverStripe\Reports\ReportAdmin:
MENUTITLE: Rapporter
ReportTitle: Titel
SilverStripe\Reports\SideReport:
OtherGroupTitle: Andre
REPEMPTY: 'Rapporten {title} er tom.'

7
lang/de.yml Normal file
View File

@ -0,0 +1,7 @@
de:
SilverStripe\Reports\ReportAdmin:
MENUTITLE: Berichte
ReportTitle: Titel
SilverStripe\Reports\SideReport:
OtherGroupTitle: Andere
REPEMPTY: 'Der Bericht {title} ist leer.'

11
lang/en.yml Normal file
View File

@ -0,0 +1,11 @@
en:
SilverStripe\CMS\Controllers\CMSPageHistoryController:
PREVIEW: 'Website preview'
SilverStripe\Forms\GridField\GridField:
Filter: Filter
SilverStripe\Reports\ReportAdmin:
MENUTITLE: Reports
ReportTitle: Title
SilverStripe\Reports\SideReport:
OtherGroupTitle: Other
REPEMPTY: 'The {title} report is empty.'

11
lang/eo.yml Normal file
View File

@ -0,0 +1,11 @@
eo:
SilverStripe\CMS\Controllers\CMSPageHistoryController:
PREVIEW: 'Retejon antaŭvidi'
SilverStripe\Forms\GridField\GridField:
Filter: Filtrilo
SilverStripe\Reports\ReportAdmin:
MENUTITLE: Raportoj
ReportTitle: Titoloj
SilverStripe\Reports\SideReport:
OtherGroupTitle: Aliaj
REPEMPTY: 'La raporto {title} estas malplena.'

7
lang/fi.yml Normal file
View File

@ -0,0 +1,7 @@
fi:
SilverStripe\Reports\ReportAdmin:
MENUTITLE: Raportit
ReportTitle: Otsikko
SilverStripe\Reports\SideReport:
OtherGroupTitle: Muu
REPEMPTY: '{title} raportti on tyhjä.'

7
lang/fr.yml Normal file
View File

@ -0,0 +1,7 @@
fr:
SilverStripe\Reports\ReportAdmin:
MENUTITLE: Rapports
ReportTitle: Titre
SilverStripe\Reports\SideReport:
OtherGroupTitle: Autre
REPEMPTY: 'Le rapport {title} est vide.'

6
lang/hr.yml Normal file
View File

@ -0,0 +1,6 @@
hr:
SilverStripe\Reports\ReportAdmin:
MENUTITLE: Izvještaji
ReportTitle: Naslov
SilverStripe\Reports\SideReport:
OtherGroupTitle: Drugi

7
lang/it.yml Normal file
View File

@ -0,0 +1,7 @@
it:
SilverStripe\Reports\ReportAdmin:
MENUTITLE: Rapporti
ReportTitle: Titolo
SilverStripe\Reports\SideReport:
OtherGroupTitle: Altro
REPEMPTY: 'Il rapporto {title} è vuoto.'

7
lang/nl.yml Normal file
View File

@ -0,0 +1,7 @@
nl:
SilverStripe\Reports\ReportAdmin:
MENUTITLE: Rapporten
ReportTitle: Naam
SilverStripe\Reports\SideReport:
OtherGroupTitle: Overig
REPEMPTY: 'Het {title} rapport is leeg.'

7
lang/pl.yml Normal file
View File

@ -0,0 +1,7 @@
pl:
SilverStripe\Reports\ReportAdmin:
MENUTITLE: Raporty
ReportTitle: Tytuł
SilverStripe\Reports\SideReport:
OtherGroupTitle: Inne
REPEMPTY: 'Raport {title} jest pusty'

7
lang/ru.yml Normal file
View File

@ -0,0 +1,7 @@
ru:
SilverStripe\Reports\ReportAdmin:
MENUTITLE: Отчёты
ReportTitle: Заголовок
SilverStripe\Reports\SideReport:
OtherGroupTitle: Другое
REPEMPTY: 'Отчёт {title} пустой.'

9
lang/sk.yml Normal file
View File

@ -0,0 +1,9 @@
sk:
SilverStripe\CMS\Controllers\CMSPageHistoryController:
PREVIEW: 'Náhľad webovej stránky'
SilverStripe\Reports\ReportAdmin:
MENUTITLE: Správy
ReportTitle: Názov
SilverStripe\Reports\SideReport:
OtherGroupTitle: Iné
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.'

9
lang/sv.yml Normal file
View File

@ -0,0 +1,9 @@
sv:
SilverStripe\CMS\Controllers\CMSPageHistoryController:
PREVIEW: 'Webbplats förhandsvisning'
SilverStripe\Reports\ReportAdmin:
MENUTITLE: Rapporter
ReportTitle: Titel
SilverStripe\Reports\SideReport:
OtherGroupTitle: Annat
REPEMPTY: 'Rapporten {title} är tom.'

13
phpcs.xml.dist Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<ruleset name="SilverStripe">
<description>CodeSniffer ruleset for SilverStripe coding conventions.</description>
<file>code</file>
<file>tests</file>
<!-- base rules are PSR-12 -->
<rule ref="PSR12" >
<!-- Current exclusions -->
<exclude name="PSR1.Methods.CamelCapsMethodName.NotCamelCaps" />
</rule>
</ruleset>

19
phpunit.xml.dist Normal file
View File

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

View File

@ -1,20 +0,0 @@
<div id="reportadmin-cms-content" class="cms-content center cms-tabset $BaseCSSClasses" data-layout-type="border" data-pjax-fragment="Content">
<div class="cms-content-header north">
<% with $EditForm %>
<div class="cms-content-header-info">
<% include BackLink_Button %>
<% with $Controller %>
<% include CMSBreadcrumbs %>
<% end_with %>
</div>
<% end_with %>
</div>
<div class="cms-content-fields center ui-widget-content" data-layout-type="border">
$EditForm
</div>
</div>

View File

@ -1,41 +0,0 @@
<form $FormAttributes>
<p style="display: none;" class="message " id="Form_EditForm_error"/>
<div id="ScrollPanel">
<fieldset>
$FieldMap.ReportTitle.FieldHolder
$FieldMap.ReportDescription.FieldHolder
<% if $FieldMap.Filters.Children %>
<h4><% _t('ReportAdminForm.FILTERBY', 'Filter by') %></h4>
<div class="filters">
<% loop $FieldMap.Filters %>
<% loop $Children %>
$FieldHolder
<% end_loop %>
<% end_loop %>
</div>
<div id="action_updatereport">
<% if $FieldMap.action_updatereport %>
$FieldMap.action_updatereport.Field
<% end_if %>
</div>
<div style="clear: both">&nbsp;</div>
<% end_if %>
$FieldMap.ReportContent.FieldHolder
<% loop $HiddenFields %>$Field<% end_loop %>
</fieldset>
</div>
<div class="clear"><!-- --></div>
</form>

View File

@ -0,0 +1,20 @@
<div id="reportadmin-cms-content" class="flexbox-area-grow fill-height cms-content cms-tabset $BaseCSSClasses" data-layout-type="border" data-pjax-fragment="Content">
<div class="cms-content-header vertical-align-items">
<% with $EditForm %>
<div class="cms-content-header-info flexbox-area-grow vertical-align-items">
<% include SilverStripe\\Admin\\BackLink_Button %>
<% with $Controller %>
<% include SilverStripe\\Admin\\CMSBreadcrumbs %>
<% end_with %>
</div>
<% end_with %>
</div>
<div class="flexbox-area-grow cms-content-fields ui-widget-content" data-layout-type="border">
$EditForm
</div>
</div>

View File

@ -0,0 +1,14 @@
<div class="cms-preview fill-height flexbox-area-grow" data-layout-type="border">
<div class="panel flexbox-area-grow fill-height">
<div class="preview-note"><span><!-- --></span><%t SilverStripe\CMS\Controllers\CMSPageHistoryController.PREVIEW 'Website preview' %></div>
<div class="preview__device">
<div class="preview-device-outer">
<div class="preview-device-inner">
<iframe src="about:blank" class="center" name="cms-preview-iframe"></iframe>
</div>
</div>
</div>
</div>
<div class="toolbar toolbar--south cms-content-controls cms-preview-controls"></div>
<div class="cms-preview-overlay ui-widget-overlay-light"></div>
</div>

70
tests/ReportAdminTest.php Normal file
View File

@ -0,0 +1,70 @@
<?php
namespace SilverStripe\Reports\Tests;
use ReflectionClass;
use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Reports\Report;
use SilverStripe\Reports\ReportAdmin;
use SilverStripe\Reports\Tests\ReportAdminTest\FakeReport;
use SilverStripe\Reports\Tests\ReportAdminTest\FakeReport2;
class ReportAdminTest extends SapphireTest
{
public function testBreadcrumbsAreGenerated()
{
$noExtraCrumbs = FakeReport::create();
$controller = $this->mockController($noExtraCrumbs);
$breadcrumbs = $controller->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->assertSame('Fake report', $map['Title']);
$extraCrumbs = FakeReport2::create();
$controller = $this->mockController($extraCrumbs);
$breadcrumbs = $controller->Breadcrumbs();
$this->assertCount(3, $breadcrumbs);
$map = $breadcrumbs[0]->toMap();
$this->assertSame('Reports', $map['Title']);
$this->assertSame('admin/reports/', $map['Link']);
$map = $breadcrumbs[1]->toMap();
$this->assertSame('Fake report title', $map['Title']);
$this->assertSame('admin/reports/show/SilverStripe-Reports-Tests-ReportAdminTest-FakeReport', $map['Link']);
$map = $breadcrumbs[2]->toMap();
$this->assertSame('Fake report two', $map['Title']);
}
/**
* @param Report $report
* @return ReportAdmin
* @throws \ReflectionException
*/
protected function mockController(Report $report)
{
$reflector = new ReflectionClass($controller = ReportAdmin::create());
$reportClass = $reflector->getProperty('reportClass');
$reportClass->setAccessible(true);
$reportClass->setValue($controller, get_class($report));
$reportObject = $reflector->getProperty('reportObject');
$reportObject->setAccessible(true);
$reportObject->setValue($controller, $report);
$controller->setRequest(Controller::curr()->getRequest());
return $controller;
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace SilverStripe\Reports\Tests\ReportAdminTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\Reports\Report;
class FakeReport extends Report implements TestOnly
{
public function title()
{
return 'Fake report';
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace SilverStripe\Reports\Tests\ReportAdminTest;
use SilverStripe\Control\Controller;
use SilverStripe\Dev\TestOnly;
use SilverStripe\Reports\Report;
use SilverStripe\Reports\ReportAdmin;
use SilverStripe\View\ArrayData;
class FakeReport2 extends Report implements TestOnly
{
public function title()
{
return 'Fake report two';
}
public function getBreadcrumbs()
{
return [ArrayData::create([
'Title' => 'Fake report title',
'Link' => FakeReport::singleton()->getLink()
])];
}
}

View File

@ -1,134 +1,133 @@
<?php
/**
* @package reports
* @subpackage tests
*/
class ReportTest extends SapphireTest {
namespace SilverStripe\Reports\Tests;
public function testGetReports() {
$reports = SS_Report::get_reports();
$this->assertNotNull($reports, "Reports returned");
$previousSort = 0;
foreach($reports as $report) {
$this->assertGreaterThanOrEqual($previousSort, $report->sort, "Reports are in correct sort order");
$previousSort = $report->sort;
}
}
use SilverStripe\Core\Config\Config;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Forms\GridField\GridFieldDataColumns;
use SilverStripe\Reports\Tests\ReportTest\FakeObject;
use SilverStripe\Reports\Tests\ReportTest\FakeTest;
use SilverStripe\Reports\Tests\ReportTest\FakeTest2;
use SilverStripe\Reports\Report;
public 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');
class ReportTest extends SapphireTest
{
protected static $extra_dataobjects = [
FakeObject::class,
];
//exclude one report
SS_Report::add_excluded_reports('ReportTest_FakeTest');
public function testGetReports()
{
$reports = Report::get_reports();
$this->assertNotNull($reports, "Reports returned");
$previousSort = 0;
foreach ($reports as $report) {
$this->assertGreaterThanOrEqual($previousSort, $report->sort, "Reports are in correct sort order");
$previousSort = $report->sort;
}
}
$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');
public function testExcludeReport()
{
$reports = Report::get_reports();
$reportNames = [];
foreach ($reports as $report) {
$reportNames[] = get_class($report);
}
$this->assertContains(FakeTest::class, $reportNames, 'ReportTest_FakeTest is in reports list');
//exclude two reports
SS_Report::add_excluded_reports(array('ReportTest_FakeTest','ReportTest_FakeTest2'));
// Exclude one report
Config::modify()->merge(Report::class, 'excluded_reports', [FakeTest::class]);
$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');
$this->assertNotContains('ReportTest_FakeTest2',$reportNames,'ReportTest_FakeTest2 is NOT in reports list');
}
$reports = Report::get_reports();
$reportNames = array();
foreach ($reports as $report) {
$reportNames[] = get_class($report);
}
$this->assertNotContains(FakeTest::class, $reportNames, 'ReportTest_FakeTest is NOT in reports list');
public function testAbstractClassesAreExcluded() {
$reports = SS_Report::get_reports();
$reportNames = array();
foreach($reports as $report) {
$reportNames[] = $report->class;
}
$this->assertNotContains('ReportTest_FakeTest_Abstract',
$reportNames,
'ReportTest_FakeTest_Abstract is NOT in reports list as it is abstract');
}
// Exclude two reports
Config::modify()->merge(Report::class, 'excluded_reports', [
FakeTest::class,
FakeTest2::class
]);
$reports = Report::get_reports();
$reportNames = [];
foreach ($reports as $report) {
$reportNames[] = get_class($report);
}
$this->assertNotContains(FakeTest::class, $reportNames, 'ReportTest_FakeTest is NOT in reports list');
$this->assertNotContains(FakeTest2::class, $reportNames, 'ReportTest_FakeTest2 is NOT in reports list');
}
public function testAbstractClassesAreExcluded()
{
$reports = Report::get_reports();
$reportNames = array();
foreach ($reports as $report) {
$reportNames[] = get_class($report);
}
$this->assertNotContains(
'ReportTest_FakeTest_Abstract',
$reportNames,
'ReportTest_FakeTest_Abstract is NOT in reports list as it is abstract'
);
}
public function testPermissions()
{
$report = new ReportTest\FakeTest2();
// Visitor cannot view
$this->logOut();
$this->assertFalse($report->canView());
// Logged in user that cannot view reports
$this->logInWithPermission('SITETREE_REORGANISE');
$this->assertFalse($report->canView());
// Logged in with report permissions
$this->logInWithPermission('CMS_ACCESS_ReportAdmin');
$this->assertTrue($report->canView());
// Admin can view
$this->logInWithPermission('ADMIN');
$this->assertTrue($report->canView());
}
public function testColumnLink()
{
$report = new ReportTest\FakeTest();
/** @var GridField $gridField */
$gridField = $report->getReportField();
/** @var GridFieldDataColumns $columns */
$columns = $gridField->getConfig()->getComponentByType(GridFieldDataColumns::class);
$page = new ReportTest\FakeObject();
$page->Title = 'My Object';
$page->ID = 959547;
$titleContent = $columns->getColumnContent($gridField, $page, 'Title');
$this->assertEquals(
'<a class="grid-field__link-block" href="dummy-edit-link/959547" title="My Object">My Object</a>',
$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());
}
}
/**
* @package reports
* @subpackage tests
*/
class ReportTest_FakeTest extends SS_Report implements TestOnly {
public function title() {
return 'Report title';
}
public function columns() {
return array(
"Title" => array(
"title" => "Page Title"
)
);
}
public function sourceRecords($params, $sort, $limit) {
return new ArrayList();
}
public function sort() {
return 100;
}
}
/**
* @package reports
* @subpackage tests
*/
class ReportTest_FakeTest2 extends SS_Report implements TestOnly {
public function title() {
return 'Report title 2';
}
public function columns() {
return array(
"Title" => array(
"title" => "Page Title 2"
)
);
}
public function sourceRecords($params, $sort, $limit) {
return new ArrayList();
}
public function sort() {
return 98;
}
}
/**
* @package reports
* @subpackage tests
*/
abstract class ReportTest_FakeTest_Abstract extends SS_Report implements TestOnly {
public function title() {
return 'Report title Abstract';
}
public function columns() {
return array(
"Title" => array(
"title" => "Page Title Abstract"
)
);
}
public function sourceRecords($params, $sort, $limit) {
return new ArrayList();
}
public function sort() {
return 5;
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace SilverStripe\Reports\Tests\ReportTest;
use SilverStripe\Control\Controller;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\CMSPreviewable;
use SilverStripe\ORM\DataObject;
class FakeObject extends DataObject implements CMSPreviewable, TestOnly
{
private static $table_name = 'ReportTest_FakeObject';
private static $db = array(
'Title' => 'Varchar'
);
/**
* @return String Absolute URL to the end-user view for this record.
* Example: http://mysite.com/my-record
*/
public function Link()
{
return Controller::join_links('dummy-link', $this->ID);
}
public function CMSEditLink()
{
return Controller::join_links('dummy-edit-link', $this->ID);
}
public function PreviewLink($action = null)
{
return false;
}
public function getMimeType()
{
return 'text/html';
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace SilverStripe\Reports\Tests\ReportTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\ArrayList;
use SilverStripe\Reports\Report;
class FakeTest extends Report implements TestOnly
{
public function title()
{
return 'Report title';
}
public function columns()
{
return array(
"Title" => array(
"title" => "Page Title",
"link" => true,
)
);
}
public function sourceRecords($params, $sort, $limit)
{
return new ArrayList();
}
public function sort()
{
return 100;
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace SilverStripe\Reports\Tests\ReportTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\ArrayList;
use SilverStripe\Reports\Report;
class FakeTest2 extends Report implements TestOnly
{
public function title()
{
return 'Report title 2';
}
public function columns()
{
return array(
"Title" => array(
"title" => "Page Title 2"
)
);
}
public function sourceRecords($params, $sort, $limit)
{
return new ArrayList();
}
public function sort()
{
return 98;
}
}

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

@ -0,0 +1,34 @@
<?php
namespace SilverStripe\Reports\Tests\ReportTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\ArrayList;
use SilverStripe\Reports\Report;
abstract class FakeTestAbstract extends Report implements TestOnly
{
public function title()
{
return 'Report title Abstract';
}
public function columns()
{
return array(
"Title" => array(
"title" => "Page Title Abstract"
)
);
}
public function sourceRecords($params, $sort, $limit)
{
return new ArrayList();
}
public function sort()
{
return 5;
}
}