Compare commits

...

66 Commits
4.4.0 ... 4

Author SHA1 Message Date
github-actions 9b79699dcc Merge branch '4.7' into 4 2024-02-11 11:32:58 +00:00
Guy Sartorelli bb3eec1160
TLN Update translations (#223) 2024-02-07 16:03:34 +13:00
github-actions 5f04e466d2 Merge branch '4.7' into 4 2023-08-27 11:32:16 +00:00
Guy Sartorelli 20d61d7d87
ENH Update translations (#208) 2023-08-21 12:13:52 +12:00
Michal Kleiner b6ce505e12 Merge branch '4.7' into 4 2023-06-16 12:09:26 +12:00
Michal Kleiner 9fe83e948d
Merge pull request #201 from silverstripe/pulls/200-use-injector-for-task
MNT Use ::create to allow Injector to replace content review emails sending task
2023-06-16 12:02:44 +12:00
Michal Kleiner 2e22bd4900 MNT Use ::create to allow Injector to replace content review emails sending task 2023-06-16 11:46:30 +12:00
Michal Kleiner 32e7929f01 Merge branch '4.7' into 4 2023-06-16 11:10:50 +12:00
Michal Kleiner 27e0f8f517
Merge pull request #183 from sunnysideup/patch-1
MNT Add additional keywords to composer.json
2023-06-16 10:48:01 +12:00
Guy Sartorelli 72e4321696
Merge pull request #199 from creative-commoners/pulls/4.7/tx-1686724607
ENH Update translations
2023-06-15 10:06:32 +12:00
Steve Boyd b6e00e9528 ENH Update translations 2023-06-14 18:36:47 +12:00
Guy Sartorelli d13bebf999
Merge branch '4.7' into 4 2023-04-26 12:46:27 +12:00
Guy Sartorelli ad33d32066
Merge pull request #195 from creative-commoners/pulls/4.7/fix-broken-job-on-wrong-email
FIX Notification job marked as broken
2023-04-14 12:30:53 +12:00
Sabina Talipova c39e588306 FIX Notification job marked as broken 2023-04-14 12:22:23 +12:00
Guy Sartorelli f9dc2e537d
Merge pull request #192 from creative-commoners/pulls/4/fix-broken-job-on-wrong-email
FIX Notification job marked as broken
2023-04-14 09:40:47 +12:00
Sabina Talipova 36d3718581 ENH Add Exception with list of invilid emails 2023-04-13 10:13:08 +12:00
Sabina Talipova 24766e4e5a FIX Notification job marked as broken 2023-04-12 08:56:49 +12:00
Guy Sartorelli 77bb69f74c
MNT Revert erroneous dependency changes (#191) 2023-03-28 17:06:01 +13:00
Maxime Rainville b5e468a266
Merge pull request #190 from creative-commoners/pulls/4/dispatch-ci
MNT Use gha-dispatch-ci
2023-03-23 14:10:27 +13:00
Steve Boyd f1f6abca67 MNT Use gha-dispatch-ci 2023-03-21 12:23:51 +13:00
Nicolaas / Sunny Side Up 4324836cb7 MNT Add additional keywords to composer.json 2023-03-20 23:21:46 +13:00
Guy Sartorelli 47769763db
MNT Update development dependencies 2023-03-10 16:33:34 +13:00
Guy Sartorelli 884a846167
MNT Update release dependencies 2023-03-10 16:33:31 +13:00
Guy Sartorelli ff723b58ef
MNT Update development dependencies 2023-03-10 12:21:29 +13:00
Guy Sartorelli 18828ed094
Merge pull request #187 from creative-commoners/pulls/4/tx-1678079773
ENH Update translations
2023-03-08 10:25:08 +13:00
Steve Boyd e8a41d96e5 ENH Update translations 2023-03-06 18:16:13 +13:00
dependabot[bot] 179e9d0cf2
Merge pull request #180 from silverstripe/dependabot/npm_and_yarn/debug-2.6.9 2023-01-12 10:25:21 +00:00
dependabot[bot] 48c40a542e
Bump debug from 2.6.8 to 2.6.9
Bumps [debug](https://github.com/debug-js/debug) from 2.6.8 to 2.6.9.
- [Release notes](https://github.com/debug-js/debug/releases)
- [Changelog](https://github.com/debug-js/debug/blob/2.6.9/CHANGELOG.md)
- [Commits](https://github.com/debug-js/debug/compare/2.6.8...2.6.9)

---
updated-dependencies:
- dependency-name: debug
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-12 10:00:53 +00:00
dependabot[bot] 0b32166a1a
Merge pull request #177 from silverstripe/dependabot/npm_and_yarn/minimatch-3.0.8 2022-12-09 09:50:49 +00:00
dependabot[bot] 013a5c34e7
Bump minimatch from 3.0.4 to 3.0.8
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.0.8.
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.0.8)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-09 08:13:31 +00:00
dependabot[bot] fad0c2b4b4
Merge pull request #176 from silverstripe/dependabot/npm_and_yarn/qs-6.5.3 2022-12-09 08:12:59 +00:00
dependabot[bot] 63024cb902
Bump qs from 6.5.2 to 6.5.3
Bumps [qs](https://github.com/ljharb/qs) from 6.5.2 to 6.5.3.
- [Release notes](https://github.com/ljharb/qs/releases)
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.5.2...v6.5.3)

---
updated-dependencies:
- dependency-name: qs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-09 08:01:04 +00:00
Sabina Talipova a6c7030274
Merge pull request #174 from creative-commoners/pulls/4/stop-using-depr
API Stop using deprecated API
2022-12-05 16:34:50 +13:00
Steve Boyd 6f18e92169 API Stop using deprecated API 2022-11-24 13:04:34 +13:00
Guy Sartorelli 7eb81fd449
Merge pull request #172 from creative-commoners/pulls/4/review-behat-tests
ENH Replace ADMIN permissions with less permissions in Behat test
2022-09-16 10:46:30 +12:00
Sabina Talipova 495e7460db ENH Replace ADMIN permissions with less permissions in Behat test 2022-09-15 15:32:06 +12:00
Sabina Talipova 55d52cb7dc
Merge pull request #155 from creative-commoners/pulls/4.3/all-sections
FIX Allow users with the CMS_ACCESS_LeftAndMain permission to be added
2022-09-15 15:14:52 +12:00
Maxime Rainville dbd9099d3d
Merge pull request #170 from creative-commoners/pulls/4/fix-userdoc-deploy
MNT Fix github action for deploying userdocs
2022-08-24 11:29:09 +12:00
Guy Sartorelli 6f5edab1ad
MNT Fix github action for deploying userdocs 2022-08-23 15:24:27 +12:00
Guy Sartorelli 1123d26477
Merge pull request #169 from creative-commoners/pulls/4/userhelp-fix
DOC Correct title for userhelp
2022-08-22 11:04:27 +12:00
Maxime Rainville 566a9e7d0e DOC Correct title for userhelp 2022-08-20 20:58:19 +12:00
Steve Boyd 422647b724 Merge branch '4.5' into 4 2022-08-02 18:48:08 +12:00
Steve Boyd 774c8343c7 Merge branch '4.4' into 4.5 2022-08-02 18:48:04 +12:00
Guy Sartorelli 562e882072
Merge pull request #168 from creative-commoners/pulls/4.4/standardise-modules
MNT Standardise modules
2022-08-02 15:12:34 +12:00
Steve Boyd 9d4381554a MNT Standardise modules 2022-08-01 16:21:34 +12:00
Guy Sartorelli c5cd5c5ff3
Merge pull request #167 from creative-commoners/pulls/4/update-js
MNT Use up­date-js action
2022-07-29 17:03:59 +12:00
Steve Boyd 31c81bf093 MNT Use update-js action 2022-07-29 13:04:47 +12:00
Steve Boyd 675d094731 Merge branch '4.5' into 4 2022-07-25 11:23:19 +12:00
Steve Boyd 03ee0d0559 Merge branch '4.4' into 4.5 2022-07-25 11:23:06 +12:00
Guy Sartorelli e2bf86414e
Merge pull request #166 from creative-commoners/pulls/4.4/ci
MNT Use node 10
2022-07-20 09:39:30 +12:00
Steve Boyd 0dd255303d MNT Use node 10 2022-07-19 17:20:05 +12:00
Guy Sartorelli f93687a53d
Merge pull request #165 from creative-commoners/pulls/4.4/module-standards
MNT Use GitHub Actions CI
2022-07-15 11:31:29 +12:00
Steve Boyd 4cafa687ae MNT Use GitHub Actions CI 2022-07-08 12:00:12 +12:00
Mo Alsharaf 1cf0f01a35
NEW Allow for optional can permission method for content review (#152)
* Allow for optional can permission method for content review

* Content Review permission logic

With the new `canReviewContent()` permission checker we only need to check the permission is set for the user and `canBeReviewedBy()` will always check if the page object is due for review by its owner.

Thus removed redundant logic in `canUseReviewContent()` and accordingly renamed the class filename for additional context.

Co-authored-by: Jared Dreyer <jared.dreyer@silverstripe.com>
2022-06-22 12:25:59 +12:00
Steve Boyd c1c47583b1 Merge branch '4.5' into 4 2022-05-10 21:58:53 +12:00
Steve Boyd 3359ab477e Update translations 2022-05-04 13:29:41 +12:00
dependabot[bot] 917c63467e
Merge pull request #164 from silverstripe/dependabot/npm_and_yarn/async-2.6.4 2022-05-03 09:27:01 +00:00
dependabot[bot] 69cf355d9f
Bump async from 2.5.0 to 2.6.4
Bumps [async](https://github.com/caolan/async) from 2.5.0 to 2.6.4.
- [Release notes](https://github.com/caolan/async/releases)
- [Changelog](https://github.com/caolan/async/blob/v2.6.4/CHANGELOG.md)
- [Commits](https://github.com/caolan/async/compare/v2.5.0...v2.6.4)

---
updated-dependencies:
- dependency-name: async
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-28 21:09:32 +00:00
Guy Sartorelli 9f7b0e2169
Merge pull request #163 from creative-commoners/pulls/4/php81
ENH PHP 8.1 compatibility
2022-04-26 17:58:20 +12:00
Steve Boyd 856660192b ENH PHP 8.1 compatibility 2022-04-13 10:23:56 +12:00
Maxime Rainville 5e313dd7fc
Merge pull request #161 from creative-commoners/pulls/4/update-js-deps
MNT Add update JS deps workflow
2022-03-23 15:43:06 +13:00
Steve Boyd 3447883c3c MNT Add update JS deps workflow 2022-03-22 12:07:10 +13:00
Guy Sartorelli 141e8d0bf3
ENH: Respect sort and limit arguments (#158)
These parameters are defined in the PHPDocs for `Report` and are technically part of the method signature. They should be respected and in the case of the new default limit in silverstripe/silverstripe-reports#139 this could have performance ramifications for large datasets.
2022-03-11 09:14:06 +13:00
Maxime Rainville 46a637a6a8
Merge pull request #157 from creative-commoners/pulls/4/php74
DEP Set PHP 7.4 as the minimum version
2022-02-18 21:46:29 +13:00
Steve Boyd 7def6f8c2a DEP Set PHP 7.4 as the minimum version 2022-02-11 16:30:49 +13:00
Steve Boyd a821edf8d7 FIX Allow users with the CMS_ACCESS_LeftAndMain permission to be added 2021-09-14 13:53:32 +12:00
40 changed files with 422 additions and 121 deletions

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

View File

@ -1,13 +1,14 @@
name: Build Docs
name: Deploy Userhelp Docs
on:
push:
branches:
- 'master'
- '5'
- '4'
paths:
- 'docs/en/userguide/**'
jobs:
build:
name: build-docs
deploy:
name: deploy-userhelp-docs
runs-on: ubuntu-latest
steps:
- name: Run build hook

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

@ -0,0 +1,16 @@
name: Dispatch CI
on:
# At 11:30 AM UTC, only on Wednesday and Thursday
schedule:
- cron: '30 11 * * 3,4'
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,11 +0,0 @@
name: Module CI
on:
push:
pull_request:
jobs:
ci:
uses: silverstripe/github-actions-ci-cd/.github/workflows/ci.yml@0.1.11
with:
run_endtoend: true

17
.github/workflows/update-js.yml vendored Normal file
View File

@ -0,0 +1,17 @@
name: Update JS
on:
workflow_dispatch:
# Run on a schedule of once per quarter
schedule:
- cron: '0 0 1 */3 *'
jobs:
update-js:
name: Update JS
# 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: Update JS
uses: silverstripe/gha-update-js@v1

1
.nvmrc Normal file
View File

@ -0,0 +1 @@
10

View File

@ -1,10 +1,7 @@
# sass-lint config to match the AirBNB style guide
# See silverstripe-admin
files:
include: '**/client/src/**/*.scss'
ignore:
- 'client/src/styles/legacy/*'
- 'src/**/*'
include: client/src/**/*.scss'
options:
formatter: stylish
merge-default-rules: false

View File

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

View File

@ -1,9 +0,0 @@
version: ~> 1.0
import:
- silverstripe/silverstripe-travis-shared:config/provision/standard-jobs-range-behat.yml
env:
global:
- BEHAT_SUITE="contentreview"
- REQUIRE_EXTRA="symbiote/silverstripe-queuedjobs:^4"

View File

@ -1,14 +1,15 @@
[main]
host = https://www.transifex.com
[silverstripe-contentreview.master]
[o:silverstripe:p:silverstripe-contentreview:r:master]
file_filter = lang/<lang>.yml
source_file = lang/en.yml
source_lang = en
type = YML
type = YML
[silverstripe-contentreview.master-js]
[o:silverstripe:p:silverstripe-contentreview:r:master-js]
file_filter = client/lang/src/<lang>.json
source_file = client/lang/src/en.json
source_lang = en
type = KEYVALUEJSON
type = KEYVALUEJSON

View File

@ -1,9 +1,7 @@
# Content Review module
[![Build Status](https://api.travis-ci.com/silverstripe/silverstripe-contentreview.svg?branch=4)](https://travis-ci.com/silverstripe/silverstripe-contentreview)
[![SilverStripe supported module](https://img.shields.io/badge/silverstripe-supported-0071C4.svg)](https://www.silverstripe.org/software/addons/silverstripe-commercially-supported-module-list/)
[![Code quality](https://scrutinizer-ci.com/g/silverstripe/silverstripe-contentreview/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/silverstripe/silverstripe-contentreview/?branch=master)
[![Code coverage](https://codecov.io/gh/silverstripe/silverstripe-contentreview/branch/master/graph/badge.svg)](https://codecov.io/gh/silverstripe/silverstripe-contentreview)
[![CI](https://github.com/silverstripe/silverstripe-contentreview/actions/workflows/ci.yml/badge.svg)](https://github.com/silverstripe/silverstripe-contentreview/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/)
This module helps keep your website content accurate and up-to-date, which keeps your users happy.
@ -17,9 +15,9 @@ There are two types of roles with this module.
## Requirements
* SilverStripe ^4.0
* Silverstripe ^4.0
**Note:** For SilverStripe 3.x, please use the [3.x release line](https://github.com/silverstripe/silverstripe-contentreview/tree/3).
**Note:** For Silverstripe 3.x, please use the [3.x release line](https://github.com/silverstripe/silverstripe-contentreview/tree/3).
## Features

View File

@ -1 +0,0 @@
{"version":3,"sources":["webpack:///./client/src/styles/ContentReviewForm.scss?a3bd","webpack:///./bundle.scss?6663"],"names":[],"mappings":"AAEA,wBACE,uDACA,wBACA,qBACA,YACA,sBACA,UACA,oBACA,WCDD,4DDKG,4BCAH","file":"styles/contentreview.css","sourcesContent":["// The bell button, shows up next to the major actions (save, publish, etc) when\n// viewing a page in the CMS\n.content-review__button {\n background: url(\"images/icon-bell.png\") center center no-repeat;\n background-position: 0 0;\n display: inline-block;\n height: 20px;\n margin: 6px 4px 0 12px;\n padding: 0;\n text-indent: -9999px;\n width: 20px;\n\n &:hover,\n &:focus {\n background-position: 0 -20px;\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./client/src/styles/ContentReviewForm.scss",".content-review__button {\n background: url(\"../images/icon-bell.png\") center center no-repeat;\n background-position: 0 0;\n display: inline-block;\n height: 20px;\n margin: 6px 4px 0 12px;\n padding: 0;\n text-indent: -9999px;\n width: 20px;\n}\n\n.content-review__button:hover,\n.content-review__button:focus {\n background-position: 0 -20px;\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./bundle.scss"],"sourceRoot":""}

View File

@ -1,5 +1,5 @@
// This file was generated by silverstripe/cow from client/lang/src/en.json.
// See https://github.com/tractorcow/cow for details
// This file was generated by silverstripe/tx-translator from client/lang/src/en.json.
// See https://github.com/silverstripe/silverstripe-tx-translator for details
if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') {
if (typeof(console) !== 'undefined') { // eslint-disable-line no-console
console.error('Class ss.i18n not defined'); // eslint-disable-line no-console

11
client/lang/sk.js Normal file
View File

@ -0,0 +1,11 @@
// This file was generated by silverstripe/tx-translator from client/lang/src/sk.json.
// See https://github.com/silverstripe/silverstripe-tx-translator for details
if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') {
if (typeof(console) !== 'undefined') { // eslint-disable-line no-console
console.error('Class ss.i18n not defined'); // eslint-disable-line no-console
}
} else {
ss.i18n.addDictionary('sk', {
"ContentReview.CONTENT_DUE_FOR_REVIEW": "Obsah určený na kontrolu"
});
}

View File

@ -1,3 +1,3 @@
{
"ContentReview.CONTENT_DUE_FOR_REVIEW": "Content due for review"
}
}

3
client/lang/src/sk.json Normal file
View File

@ -0,0 +1,3 @@
{
"ContentReview.CONTENT_DUE_FOR_REVIEW": "Obsah určený na kontrolu"
}

View File

@ -7,7 +7,10 @@
"keywords": [
"silverstripe",
"cms",
"workflow"
"workflow",
"content review",
"review",
"permissions"
],
"authors": [
{
@ -20,7 +23,7 @@
}
],
"require": {
"php": "^7.3 || ^8.0",
"php": "^7.4 || ^8.0",
"silverstripe/vendor-plugin": "^1",
"silverstripe/framework": "^4.10",
"silverstripe/cms": "^4.2",
@ -29,7 +32,8 @@
},
"require-dev": {
"silverstripe/recipe-testing": "^2",
"squizlabs/php_codesniffer": "^3"
"squizlabs/php_codesniffer": "^3",
"symbiote/silverstripe-queuedjobs": "^4.9"
},
"suggest": {
"symbiote/silverstripe-queuedjobs": "Automatically schedules content review emails to be sent, only requiring one crontask to be created"
@ -48,4 +52,4 @@
},
"minimum-stability": "dev",
"prefer-stable": true
}
}

View File

@ -1,5 +1,7 @@
---
title: Content review
summary: Mark pages in the CMS with a date and an owner for future reviews.
---
## Content review

View File

@ -15,6 +15,14 @@ en:
PAGEOWNERUSERS: Users
REVIEWFREQUENCY: 'Review frequency'
REVIEWFREQUENCYDESCRIPTION: 'The review date will be set to this far in the future, whenever the page is published.'
db_ReviewBody: 'Review body'
db_ReviewFrom: 'Review from'
db_ReviewPeriodDays: 'Review period days'
db_ReviewSubject: 'Review subject'
many_many_ContentReviewGroups: 'Content review groups'
many_many_ContentReviewUsers: 'Content review users'
SilverStripe\ContentReview\Extensions\ContentReviewOwner:
many_many_SiteTreeContentReview: 'Site tree content review'
SilverStripe\ContentReview\Extensions\SiteTreeContentReview:
ADDGROUP: 'Add groups'
ADDUSERS: 'Add users'
@ -34,6 +42,14 @@ en:
REVIEWFREQUENCYDESCRIPTION: 'The review date will be set to this far in the future whenever the page is published'
REVIEWHEADER: 'Content review'
SETTINGSFROM: 'Options are'
belongs_many_many_ContentReviewGroups: 'Content review groups'
belongs_many_many_ContentReviewUsers: 'Content review users'
db_ContentReviewType: 'Content review type'
db_LastEditedByName: 'Last edited by name'
db_NextReviewDate: 'Next review date'
db_OwnerNames: 'Owner names'
db_ReviewPeriodDays: 'Review period days'
has_many_ReviewLogs: 'Review logs'
SilverStripe\ContentReview\Forms\ReviewContentHandler:
ErrorReviewPermissionDenied: 'It seems you don''t have the necessary permissions to submit a content review'
MarkAsReviewedAction: 'Mark as reviewed'
@ -46,6 +62,9 @@ en:
one: 'A Content Review Log'
other: '{count} Content Review Logs'
SINGULARNAME: 'Content Review Log'
db_Note: Note
has_one_Reviewer: Reviewer
has_one_SiteTree: 'Site tree'
SilverStripe\ContentReview\Reports\PagesDueForReviewReport:
ONLYMYPAGES: 'Only Show pages assigned to me'
REVIEWDATEAFTER: 'Review date after or on'

80
lang/sk.yml Normal file
View File

@ -0,0 +1,80 @@
sk:
SilverStripe\ContentReview\Extensions\ContentReviewCMSExtension:
ErrorItemPermissionDenied: 'Zdá sa, že nemáte potrebné oprávnenia na kontrolu tohto obsahu'
SilverStripe\ContentReview\Extensions\ContentReviewDefaultSettings:
ADDGROUP: 'Pridať skupiny'
ADDUSERS: 'Pridať používateľov'
DEFAULTSETTINGSHELP: 'Tieto nastavenia sa použijú na všetky stránky, ktoré nemajú špecifický plán kontroly obsahu.'
EMAILFROM: 'Z e-mailovej adresy'
EMAILFROM_RIGHTTITLE: 'napr.: do-not-reply@site.com'
EMAILSUBJECT: Predmet
EMAILTEMPLATE: 'Šablóna e-mailu'
OWNERGROUPSDESCRIPTION: 'Vlastníci stránok, ktorí sú zodpovední za kontrolu'
OWNERUSERSDESCRIPTION: 'Vlastníci stránok, ktorí sú zodpovední za kontrolu'
PAGEOWNERGROUPS: Skupiny
PAGEOWNERUSERS: Používatelia
REVIEWFREQUENCY: 'Frekvencia kontroly'
REVIEWFREQUENCYDESCRIPTION: 'Dátum kontroly bude nastavený na tento dátum v budúcnosti, bez ohľadu na to, kedy bude stránka zverejnená.'
db_ReviewBody: 'Revízny orgán'
db_ReviewFrom: 'Kontrola od'
db_ReviewPeriodDays: 'Dni periódy kontroly'
db_ReviewSubject: 'Predmet kontroly'
many_many_ContentReviewGroups: 'Skupiny kontroly obsahu'
many_many_ContentReviewUsers: 'Používatelia kontroly obsahu'
SilverStripe\ContentReview\Extensions\ContentReviewOwner:
many_many_SiteTreeContentReview: 'Kontrola obsahu stromu stránok'
SilverStripe\ContentReview\Extensions\SiteTreeContentReview:
ADDGROUP: 'Pridať skupiny'
ADDUSERS: 'Pridať používateľov'
CONTENTOWNERS: 'Vlastníci obsahu'
CONTENTREVIEW: 'Obsah určený na kontrolu'
CUSTOM: 'Vlastné nastavenia'
DISABLE: 'Zakázať kontrolu obsahu'
INHERIT: 'Zdediť z nadradenej stránky'
NEXTREVIEWDATADESCRIPTION: 'Ak nechcete vyplniť kontrolu, ponechajte pole prázdne'
NEXTREVIEWDATE: 'Dátum ďalšej kontroly'
OPTIONS: Možnosti
OWNERGROUPSDESCRIPTION: 'Vlastníci stránok, ktorí sú zodpovední za kontrolu'
OWNERUSERSDESCRIPTION: 'Vlastníci stránok, ktorí sú zodpovední za kontrolu'
PAGEOWNERGROUPS: Skupiny
PAGEOWNERUSERS: Používatelia
REVIEWFREQUENCY: 'Frekvencia kontroly'
REVIEWFREQUENCYDESCRIPTION: 'Dátum kontroly bude nastavený na tento dátum v budúcnosti, bez ohľadu na to, kedy bude stránka zverejnená.'
REVIEWHEADER: 'Kontrola obsahu'
SETTINGSFROM: 'Možnosti sú'
belongs_many_many_ContentReviewGroups: 'Skupiny kontroly obsahu'
belongs_many_many_ContentReviewUsers: 'Používatelia kontroly obsahu'
db_ContentReviewType: 'Typ kontroly obsahu'
db_LastEditedByName: 'Naposledy upravené podľa mena'
db_NextReviewDate: 'Dátum ďalšej kontroly'
db_OwnerNames: 'Mená vlastníkov'
db_ReviewPeriodDays: 'Dni periódy kontroly'
has_many_ReviewLogs: 'Záznamy z kontroly'
SilverStripe\ContentReview\Forms\ReviewContentHandler:
ErrorReviewPermissionDenied: 'Zdá sa, že nemáte potrebné oprávnenia na odoslanie kontroly obsahu'
MarkAsReviewedAction: 'Označiť ako skontrolované'
NoComments: '(bez komentára)'
Placeholder: 'Pridať komentáre (voliteľné)'
Success: 'Kontrola bola úspešne pridaná'
SilverStripe\ContentReview\Models\ContentReviewLog:
PLURALNAME: 'Záznamy z kontroly obsahu'
PLURALS:
few: '{count} záznamy z kontroly obsahu'
many: '{count} záznamov z kontroly obsahu'
one: 'Záznam z kontroly obsahu'
other: '{count} záznamov z kontroly obsahu'
SINGULARNAME: 'Záznam z kontroly obsahu'
db_Note: Poznámka
has_one_Reviewer: Kontrolór
has_one_SiteTree: 'Strom stránok'
SilverStripe\ContentReview\Reports\PagesDueForReviewReport:
ONLYMYPAGES: 'Zobraziť iba mne priradené stránky'
REVIEWDATEAFTER: 'Dátum kontroly po'
REVIEWDATEBEFORE: 'Dátum kontroly pred'
SHOWVIRTUALPAGES: 'Zobraziť virtuálne stránky'
TITLE: 'Stránky určené na kontrolu'
SilverStripe\ContentReview\Reports\PagesWithoutReviewScheduleReport:
TITLE: 'Stránky bez naplánovanej kontroly.'
SilverStripe\ContentReview\Tasks\ContentReviewEmails:
REVIEWPAGELINK: 'Skontrolujte stránku v CMS'
VIEWPUBLISHEDLINK: 'Pozrite si túto stránku na webe'

View File

@ -39,6 +39,6 @@
"eslint-config-airbnb": "^6.2.0"
},
"engines": {
"node": "^6.x"
"node": "^10.x"
}
}

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/silverstripe/cms/tests/bootstrap.php" colors="true">
<testsuites>
<testsuite name="Default">

View File

@ -6,10 +6,10 @@ use SilverStripe\Admin\LeftAndMain;
use SilverStripe\Admin\LeftAndMainExtension;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\ContentReview\Forms\ReviewContentHandler;
use SilverStripe\ContentReview\Traits\PermissionChecker;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\HTTPResponse;
use SilverStripe\Control\HTTPResponse_Exception;
use SilverStripe\Core\Convert;
use SilverStripe\Forms\Form;
use SilverStripe\ORM\ValidationResult;
use SilverStripe\Security\Security;
@ -20,6 +20,8 @@ use SilverStripe\Security\Security;
*/
class ContentReviewCMSExtension extends LeftAndMainExtension
{
use PermissionChecker;
private static $allowed_actions = [
'ReviewContentForm',
'savereview',
@ -48,7 +50,7 @@ class ContentReviewCMSExtension extends LeftAndMainExtension
{
$page = $this->findRecord(['ID' => $id]);
$user = Security::getCurrentUser();
if (!$page->canEdit() || ($page->hasMethod('canBeReviewedBy') && !$page->canBeReviewedBy($user))) {
if (!$this->isContentReviewable($page, $user)) {
$this->owner->httpError(403, _t(
__CLASS__.'.ErrorItemPermissionDenied',
'It seems you don\'t have the necessary permissions to review this content'

View File

@ -130,6 +130,7 @@ class ContentReviewDefaultSettings extends DataExtension
$users = Permission::get_members_by_permission([
'CMS_ACCESS_CMSMain',
'CMS_ACCESS_LeftAndMain',
'ADMIN',
]);

View File

@ -132,13 +132,13 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
$familyIDs = $group->collateFamilyIDs();
if (is_array($familyIDs)) {
$groupIDs = array_merge($groupIDs, array_values($familyIDs));
$groupIDs = array_merge($groupIDs, array_values($familyIDs ?? []));
}
}
array_unique($groupIDs);
array_unique($groupIDs ?? []);
if (count($groupIDs)) {
if (count($groupIDs ?? [])) {
$groupMembers = DataObject::get(Member::class)
->where("\"Group\".\"ID\" IN (" . implode(",", $groupIDs) . ")")
->leftJoin("Group_Members", "\"Member\".\"ID\" = \"Group_Members\".\"MemberID\"")
@ -397,7 +397,7 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
$options
);
$users = Permission::get_members_by_permission(["CMS_ACCESS_CMSMain", "ADMIN"]);
$users = Permission::get_members_by_permission(['CMS_ACCESS_CMSMain', 'CMS_ACCESS_LeftAndMain', 'ADMIN']);
$usersMap = $users->map("ID", "Title")->toArray();
@ -512,11 +512,11 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
*/
public function canBeReviewedBy(Member $member = null)
{
if (!$this->owner->obj("NextReviewDate")->exists()) {
if (!$this->owner->obj('NextReviewDate')->exists()) {
return false;
}
if ($this->owner->obj("NextReviewDate")->InFuture()) {
if ($this->owner->obj('NextReviewDate')->InFuture()) {
return false;
}
@ -542,6 +542,11 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
return true;
}
// Check whether this user is allowed to review the content of the page.
if ($this->owner->hasMethod("canReviewContent") && !$this->owner->canReviewContent($member)) {
return false;
}
if ($member->inGroups($options->OwnerGroups())) {
return true;
}
@ -676,7 +681,7 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
$runHour = Config::inst()->get(ContentReviewNotificationJob::class, "first_run_hour");
$firstRunTime = date(
"Y-m-d H:i:s",
mktime($runHour, 0, 0, date("m"), date("d") + 1, date("y"))
mktime($runHour ?? 0, 0, 0, date("m"), date("d") + 1, date("y"))
);
singleton(QueuedJobService::class)->queueJob(

View File

@ -3,6 +3,7 @@
namespace SilverStripe\ContentReview\Forms;
use SilverStripe\ContentReview\Extensions\SiteTreeContentReview;
use SilverStripe\ContentReview\Traits\PermissionChecker;
use SilverStripe\Control\Controller;
use SilverStripe\Control\Director;
use SilverStripe\Control\HTTPResponse;
@ -19,6 +20,7 @@ use SilverStripe\Security\Security;
class ReviewContentHandler
{
use Injectable;
use PermissionChecker;
/**
* Parent controller for this form
@ -120,12 +122,11 @@ class ReviewContentHandler
*/
public function canSubmitReview($record)
{
if (!$record->canEdit()
|| !$record->hasMethod('canBeReviewedBy')
|| !$record->canBeReviewedBy(Security::getCurrentUser())
) {
// Ensure the parameter of correct data type
if (!$record instanceof DataObject) {
return false;
}
return true;
return $this->isContentReviewable($record, Security::getCurrentUser());
}
}

View File

@ -93,7 +93,7 @@ class ContentReviewNotificationJob extends AbstractQueuedJob implements QueuedJo
{
$this->queueNextRun();
$task = new ContentReviewEmails();
$task = ContentReviewEmails::create();
$task->run(new HTTPRequest("GET", "/dev/tasks/ContentReviewEmails"));
$this->currentStep = 1;
@ -108,7 +108,7 @@ class ContentReviewNotificationJob extends AbstractQueuedJob implements QueuedJo
$nextRun = new ContentReviewNotificationJob();
$nextRunTime = mktime(
Config::inst()->get(__CLASS__, 'next_run_hour'),
Config::inst()->get(__CLASS__, 'next_run_hour') ?? 0,
Config::inst()->get(__CLASS__, 'next_run_minute'),
0,
date("m"),

View File

@ -77,8 +77,8 @@ class PagesDueForReviewReport extends Report
public function columns()
{
$linkBase = singleton(CMSPageEditController::class)->Link("show");
$linkPath = parse_url($linkBase, PHP_URL_PATH);
$linkQuery = parse_url($linkBase, PHP_URL_QUERY);
$linkPath = parse_url($linkBase ?? '', PHP_URL_PATH);
$linkQuery = parse_url($linkBase ?? '', PHP_URL_QUERY);
$fields = [
"Title" => [
@ -148,16 +148,26 @@ class PagesDueForReviewReport extends Report
/**
* @param array $params
* @param array|string|null $sort
* @param int|null $limit
*
* @return SS_List
*/
public function sourceRecords($params = [])
public function sourceRecords($params = [], $sort = null, $limit = null)
{
Versioned::set_stage(Versioned::DRAFT);
$records = SiteTree::get();
$compatibility = ContentReviewCompatability::start();
// Apply sort and limit if appropriate.
if ($sort !== null) {
$records = $records->sort($sort);
}
if ($limit !== null) {
$records = $records->limit($limit);
}
if (empty($params['ReviewDateBefore']) && empty($params['ReviewDateAfter'])) {
// If there's no review dates set, default to all pages due for review now
$records = $records->where(
@ -172,7 +182,7 @@ class PagesDueForReviewReport extends Report
// TODO Get value from DateField->dataValue() once we have access to form elements here
$nextReviewUnixSec = strtotime(
' + 1 day',
strtotime($params['ReviewDateBefore'])
strtotime($params['ReviewDateBefore'] ?? '')
);
$records = $records->where(
sprintf(
@ -199,7 +209,7 @@ class PagesDueForReviewReport extends Report
$virtualPageClasses = ClassInfo::subclassesFor(VirtualPage::class);
$records = $records->where(sprintf(
"\"SiteTree\".\"ClassName\" NOT IN ('%s')",
implode("','", array_values($virtualPageClasses))
implode("','", array_values($virtualPageClasses ?? []))
));
}

View File

@ -46,8 +46,8 @@ class PagesWithoutReviewScheduleReport extends Report
public function columns()
{
$linkBase = singleton(CMSPageEditController::class)->Link("show");
$linkPath = parse_url($linkBase, PHP_URL_PATH);
$linkQuery = parse_url($linkBase, PHP_URL_QUERY);
$linkPath = parse_url($linkBase ?? '', PHP_URL_PATH);
$linkQuery = parse_url($linkBase ?? '', PHP_URL_QUERY);
$fields = [
"Title" => [
@ -104,10 +104,12 @@ class PagesWithoutReviewScheduleReport extends Report
/**
* @param array $params
* @param array|string|null $sort
* @param int|null $limit
*
* @return SS_List
*/
public function sourceRecords($params = [])
public function sourceRecords($params = [], $sort = null, $limit = null)
{
Versioned::set_stage(Versioned::DRAFT);
@ -121,20 +123,22 @@ class PagesWithoutReviewScheduleReport extends Report
$virtualPageClasses = ClassInfo::subclassesFor(VirtualPage::class);
$records = $records->where(sprintf(
"\"SiteTree\".\"ClassName\" NOT IN ('%s')",
implode("','", array_values($virtualPageClasses))
implode("','", array_values($virtualPageClasses ?? []))
));
}
$records->sort("ParentID");
$records = $records->toArray();
// Apply sort and limit if appropriate.
if ($sort !== null) {
$records = $records->sort($sort);
}
if ($limit !== null) {
$records = $records->limit($limit);
}
// Trim out calculated values
$list = ArrayList::create();
foreach ($records as $record) {
if (!$this->hasReviewSchedule($record)) {
$list->push($record);
}
}
$list = $records->filterByCallback(function ($record) {
return !$this->hasReviewSchedule($record);
});
ContentReviewCompatability::done($compatibility);

View File

@ -3,6 +3,7 @@
namespace SilverStripe\ContentReview\Tasks;
use Page;
use RuntimeException;
use SilverStripe\ContentReview\Compatibility\ContentReviewCompatability;
use SilverStripe\Control\Email\Email;
use SilverStripe\Control\HTTPRequest;
@ -15,18 +16,29 @@ use SilverStripe\Security\Member;
use SilverStripe\SiteConfig\SiteConfig;
use SilverStripe\View\ArrayData;
use SilverStripe\View\SSViewer;
use SilverStripe\ContentReview\Models\ContentReviewLog;
/**
* Daily task to send emails to the owners of content items when the review date rolls around.
*/
class ContentReviewEmails extends BuildTask
{
private array $invalid_emails = [];
/**
* @param HTTPRequest $request
* @throws RuntimeException
*/
public function run($request)
{
if (!$this->isValidEmail($senderEmail = SiteConfig::current_site_config()->ReviewFrom)) {
throw new RuntimeException(
sprintf(
'Provided sender email address is invalid: "%s".',
$senderEmail
)
);
}
$compatibility = ContentReviewCompatability::start();
// First grab all the pages with a custom setting
@ -42,6 +54,16 @@ class ContentReviewEmails extends BuildTask
}
ContentReviewCompatability::done($compatibility);
if (is_array($this->invalid_emails) && count($this->invalid_emails) > 0) {
$plural = count($this->invalid_emails) > 1 ? 's are' : ' is';
throw new RuntimeException(
sprintf(
'Provided email' . $plural . ' invalid: "%s".',
implode(', ', $this->invalid_emails)
)
);
}
}
/**
@ -93,6 +115,13 @@ class ContentReviewEmails extends BuildTask
// Prepare variables
$siteConfig = SiteConfig::current_site_config();
$owner = Member::get()->byID($ownerID);
if (!$this->isValidEmail($owner->Email)) {
$this->invalid_emails[] = $owner->Name . ': ' . $owner->Email;
return;
}
$templateVariables = $this->getTemplateVariables($owner, $siteConfig, $pages);
// Build email
@ -159,4 +188,12 @@ class ContentReviewEmails extends BuildTask
'ToEmail' => $recipient->Email,
];
}
/**
* Check validity of email
*/
protected function isValidEmail(?string $email): bool
{
return (bool) filter_var($email, FILTER_VALIDATE_EMAIL);
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace SilverStripe\ContentReview\Traits;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;
use SilverStripe\Security\Security;
trait PermissionChecker
{
/**
* Checks the user has been granted special permission to review the content of the page
* if not fallback to canEdit() permission.
*/
protected function isContentReviewable(DataObject $record, ?Member $user = null): bool
{
return $record->hasMethod('canReviewContent')
? $record->canReviewContent($user)
: $record->canEdit();
}
}

View File

@ -6,14 +6,17 @@ Feature: Set up reviews
Background:
# Note: the review date is deliberately in the past
Given a "page" "My page" with "Content"="<p>Welcome</p>", "NextReviewDate"="01/01/2017", "ReviewPeriodDays"="1"
And the "group" "EDITOR group" has permissions "CMS_ACCESS_LeftAndMain" and "FILE_EDIT_ALL"
And the "group" "FILEONLY group" has permissions "FILE_EDIT_ALL"
And a "member" "Ed" belonging to "EDITOR group" with "Email"="ed@example.com"
And a "member" "Phil" belonging to "FILEONLY group" with "Email"="phil@example.com"
# Login in as EDITOR once https://github.com/silverstripe/silverstripe-contentreview/pull/155 is merged
# And I am logged in with "EDITOR" permissions
And I am logged in with "ADMIN" permissions
And the "group" "ADMIN group" has permissions "Full administrative rights"
And the "group" "EDITOR" has permissions "CMS_ACCESS_CMSMain" and "EDIT_CONTENT_REVIEW_FIELDS"
And the "group" "AUTHOR" has permissions and "CMS_ACCESS_LeftAndMain"
And the "group" "FILEONLY" has permissions "FILE_EDIT_ALL"
And the "group" "CMS_MAIN" has permissions "CMS_ACCESS_CMSMain"
And a "member" "Ed" belonging to "AUTHOR" with "Email"="ed@example.com"
And a "member" "Phil" belonging to "FILEONLY" with "Email"="phil@example.com"
And a "member" "Anna" belonging to "CMS_MAIN" with "Email"="anna@example.com"
And I am logged in as a member of "EDITOR" group
And I go to "admin/pages"
And I wait for 1 second
And I click on "My page" in the tree
And I click the "Settings" CMS tab
And I click the "Content review" CMS tab
@ -24,10 +27,11 @@ Feature: Set up reviews
# Test adding individual member based on them having access to the Pages section fo the CMS
Then the "#Form_EditForm_OwnerUsers" select element should have an option with an "Ed" label
And the "#Form_EditForm_OwnerUsers" select element should have an option with an "Anna" label
And the "#Form_EditForm_OwnerUsers" select element should not have an option with a "Phil" label
# Test adding groups
Then the "#Form_EditForm_OwnerGroups" select element should have an option with an "EDITOR group" label
Then the "#Form_EditForm_OwnerGroups" select element should have an option with an "EDITOR" label
# Required to avoid "unsaved changed" browser dialog
Then I press the "Save" button
@ -37,7 +41,7 @@ Feature: Set up reviews
And I wait for 1 second
Then I should not see the ".content-review__button" element
When I press the "Save" button
And I select "ADMIN group" from "Groups"
And I select "EDITOR" from "Groups"
And I press the "Save" button
Then I should see the ".content-review__button" element
When I click on the ".content-review__button" element

View File

@ -6,7 +6,8 @@ Feature: Set up reviews
Background:
# Note: the review date is deliberately in the past
Given a "page" "Home" with "Content"="<p>Welcome</p>", "NextReviewDate"="01/01/2017", "ReviewPeriodDays"="1"
And I am logged in with "ADMIN" permissions
And the "group" "EDITOR" has permissions "CMS_ACCESS_CMSMain" and "EDIT_CONTENT_REVIEW_FIELDS"
And I am logged in as a member of "EDITOR" group
And I go to "admin/pages"
@javascript
@ -18,7 +19,7 @@ Feature: Set up reviews
When I click the "Content review" CMS tab
And I select "Custom settings" from "Options" input group
And I wait for 1 second
And I select "ADMIN group" from "Groups"
And I select "EDITOR" from "Groups"
And I press "Save"
Then I should see a "Content due for review" button
@ -29,7 +30,7 @@ Feature: Set up reviews
And I click the "Content review" CMS tab
And I select "Custom settings" from "Options" input group
And I wait for 1 seconds
And I select "ADMIN group" from "Groups"
And I select "EDITOR" from "Groups"
And I press "Save"
And I follow "Content due for review"
And I wait for 3 seconds

View File

@ -3,6 +3,7 @@
namespace SilverStripe\ContentReview\Tests;
use Page;
use ReflectionClass;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\CMS\Controllers\CMSPageEditController;
use SilverStripe\ContentReview\Extensions\ContentReviewCMSExtension;
@ -132,6 +133,26 @@ class ContentReviewNotificationTest extends SapphireTest
DBDatetime::clear_mock_now();
}
/**
* Test that provided email is valid
*/
public function testIsValidEmail()
{
$class = new ReflectionClass(ContentReviewEmails::class);
$method = $class->getMethod('isValidEmail');
$method->setAccessible(true);
$member = $this->objFromFixture(Member::class, 'author');
$task = new ContentReviewEmails();
$this->assertTrue($method->invokeArgs($task, [$member->Email]));
$this->assertTrue($method->invokeArgs($task, ['correct.email@example.com']));
$this->assertFalse($method->invokeArgs($task, [null]));
$this->assertFalse($method->invokeArgs($task, ['broken.email']));
$this->assertFalse($method->invokeArgs($task, ['broken@email']));
}
/**
* Deletes all pages except those passes in to the $ids parameter
*

View File

@ -87,11 +87,11 @@ class ContentReviewReportTest extends FunctionalTest
$results = $report->sourceRecords();
$this->assertEquals([
"Home",
"About Us",
"Page without review date",
"Page owned by group",
], $results->column("Title"));
$this->assertListEquals([
['Title' => 'Home'],
['Title' => 'About Us'],
['Title' => 'Page without review date'],
['Title' => 'Page owned by group'],
], $results);
}
}

View File

@ -2,6 +2,7 @@
namespace SilverStripe\ContentReview\Tests\Extensions;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\ContentReview\Extensions\ContentReviewCMSExtension;
use SilverStripe\ContentReview\Forms\ReviewContentHandler;
use SilverStripe\Control\Controller;
@ -50,7 +51,7 @@ class ContentReviewCMSExtensionTest extends SapphireTest
$mock->setOwner(new Controller);
// Return a DataObject without the content review extension applied
$mock->expects($this->once())->method('findRecord')->with(['ID' => 123])->willReturn(new Member);
$mock->expects($this->once())->method('findRecord')->with(['ID' => 123])->willReturn(new SiteTree);
$mock->getReviewContentForm(123);
}

View File

@ -45,6 +45,13 @@ class ReviewContentHandlerTest extends SapphireTest
ReviewContentHandler::create()->submitReview(new Member, ['foo' => 'bar']);
}
public function testExceptionThrownWhenSubmittingReviewForInvalidDataObject()
{
$this->expectException(ValidationException::class);
$this->expectExceptionMessage('It seems you don\'t have the necessary permissions to submit a content review');
ReviewContentHandler::create()->submitReview(new Controller, ['foo' => 'bar']);
}
public function testAddReviewNoteCalledWhenSubmittingReview()
{
$this->logInWithPermission('ADMIN');

View File

@ -9,6 +9,7 @@ use SilverStripe\ContentReview\Extensions\ContentReviewCMSExtension;
use SilverStripe\ContentReview\Extensions\ContentReviewDefaultSettings;
use SilverStripe\ContentReview\Extensions\ContentReviewOwner;
use SilverStripe\ContentReview\Extensions\SiteTreeContentReview;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Forms\LiteralField;
use SilverStripe\ORM\FieldType\DBDate;
use SilverStripe\ORM\FieldType\DBDatetime;
@ -16,6 +17,7 @@ use SilverStripe\Security\Group;
use SilverStripe\Security\Member;
use SilverStripe\SiteConfig\SiteConfig;
use SilverStripe\Versioned\Versioned;
use SilverStripe\ORM\ArrayList;
class SiteTreeContentReviewTest extends ContentReviewBaseTest
{
@ -53,7 +55,7 @@ class SiteTreeContentReviewTest extends ContentReviewBaseTest
$page->write();
$this->assertTrue($page->canPublish());
$this->assertTrue($page->doPublish());
$this->assertTrue($page->publishRecursive());
$this->assertEquals($page->OwnerNames, "Test Editor", "Test Editor should be the owner");
/** @var Page|SiteTreeContentReview $page */
@ -117,7 +119,7 @@ class SiteTreeContentReviewTest extends ContentReviewBaseTest
$page->ReviewPeriodDays = 10;
$page->write();
$this->assertTrue($page->doPublish());
$this->assertTrue($page->publishRecursive());
$this->assertEquals(null, $page->NextReviewDate);
}
@ -365,4 +367,38 @@ class SiteTreeContentReviewTest extends ContentReviewBaseTest
DBDatetime::clear_mock_now();
}
public function testPermissionCheckByOnDataObject()
{
$reviewer = $this->objFromFixture(Member::class, 'editor');
// Mock Page class with canReviewContent method to return true on first call and false on second call
$mock = $this->getMockBuilder(Page::class)
->setMethods(['canReviewContent', 'NextReviewDate', 'OwnerUsers'])
->getMock();
$mock->expects($this->exactly(2))->method('canReviewContent')->willReturnOnConsecutiveCalls(false, true);
$mock->method('NextReviewDate')->willReturn('2020-02-20 12:00:00');
$mock->method('OwnerUsers')->willReturn(ArrayList::create([$reviewer]));
$mock->ContentReviewType = 'Custom';
/** @var SiteTreeContentReview $extension */
$extension = Injector::inst()->get(SiteTreeContentReview::class);
$extension->setOwner($mock);
// Assert that the user is not allowed to review content
$author = $this->objFromFixture(Member::class, 'author');
$this->assertFalse($extension->canBeReviewedBy($author));
DBDatetime::set_mock_now("2020-03-01 12:00:00");
// Assert that the user is allowed to review content
$this->assertTrue($extension->canBeReviewedBy($reviewer));
// Assert tht canBeReviewedBy return true if no user logged in
// This is for CLI execution for ContentReviewEmails task
$this->logOut();
$this->assertTrue($extension->canBeReviewedBy());
DBDatetime::clear_mock_now();
}
}

View File

@ -253,10 +253,10 @@ async-foreach@^0.1.3:
resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542"
async@^2.1.2, async@^2.1.5:
version "2.5.0"
resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d"
version "2.6.4"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221"
dependencies:
lodash "^4.14.0"
lodash "^4.17.14"
asynckit@^0.4.0:
version "0.4.0"
@ -1392,8 +1392,8 @@ date-now@^0.1.4:
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
debug@^2.1.1, debug@^2.2.0, debug@^2.6.8:
version "2.6.8"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
dependencies:
ms "2.0.0"
@ -2733,7 +2733,7 @@ lodash@4.17.4:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
lodash@^4.0.0, lodash@^4.14.0, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0, lodash@~4.17.10:
lodash@^4.0.0, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0, lodash@~4.17.10:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
@ -2860,8 +2860,8 @@ minimalistic-crypto-utils@^1.0.1:
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.2:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
version "3.0.8"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.8.tgz#5e6a59bd11e2ab0de1cfb843eb2d82e546c321c1"
dependencies:
brace-expansion "^1.1.7"
@ -3650,8 +3650,8 @@ q@^1.1.2:
resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1"
qs@~6.5.2:
version "6.5.2"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
version "6.5.3"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
query-string@^4.1.0:
version "4.3.4"