Merge pull request #61 from creative-commoners/pulls/4.0/ss4-compat

API Upgrade for SS4 compatibility
This commit is contained in:
Franco Springveldt 2017-09-07 16:20:03 +12:00 committed by GitHub
commit 521c8c9128
30 changed files with 750 additions and 387 deletions

View File

@ -1,36 +1,35 @@
# See https://github.com/silverstripe/silverstripe-travis-support for setup details
sudo: false
language: php
dist: precise
php:
- 5.3
- 5.4
- 5.5
dist: trusty
env:
- DB=MYSQL CORE_RELEASE=3.5
global:
- COMPOSER_ROOT_VERSION=4.0.x-dev
matrix:
include:
- php: 5.6
env: DB=MYSQL CORE_RELEASE=3
- php: 5.6
env: DB=MYSQL CORE_RELEASE=3.1
- php: 5.6
env: DB=PGSQL CORE_RELEASE=3.2
env: DB=MYSQL PHPCS_TEST=1 PHPUNIT_TEST=1
- php: 7.0
env: DB=PGSQL PHPUNIT_TEST=1
- php: 7.1
env: DB=MYSQL CORE_RELEASE=3.6
env: DB=MYSQL PHPUNIT_COVERAGE_TEST=1
before_script:
- composer self-update || true
- git clone git://github.com/silverstripe/silverstripe-travis-support.git ~/travis-support
- php ~/travis-support/travis_setup.php --source `pwd` --target ~/builds/ss
- cd ~/builds/ss
- composer install
# Init PHP
- phpenv rehash
- phpenv config-rm xdebug.ini
# Install composer dependencies
- composer install --prefer-dist
- composer require --prefer-dist --no-update silverstripe/recipe-cms:1.0.x-dev
- if [[ $DB == PGSQL ]]; then composer require --prefer-dist --no-update silverstripe/postgresql:2.0.x-dev; fi
- composer update
script:
- vendor/bin/phpunit contentreview/tests
- if [[ $PHPUNIT_TEST ]]; then vendor/bin/phpunit; fi
- if [[ $PHPUNIT_COVERAGE_TEST ]]; then phpdbg -qrr vendor/bin/phpunit --coverage-clover=coverage.xml; fi
- if [[ $PHPCS_TEST ]]; then vendor/bin/phpcs --standard=framework/phpcs.xml.dist src/ tests/; fi
after_success:
- if [[ $PHPUNIT_COVERAGE_TEST ]]; then bash <(curl -s https://codecov.io/bash) -f coverage.xml; fi

18
.upgrade.yml Normal file
View File

@ -0,0 +1,18 @@
mappings:
ContentReviewCompatability: SilverStripe\ContentReview\Compatibility\ContentReviewCompatability
ContentReviewCMSExtension: SilverStripe\ContentReview\Extensions\ContentReviewCMSExtension
ContentReviewDefaultSettings: SilverStripe\ContentReview\Extensions\ContentReviewDefaultSettings
ContentReviewOwner: SilverStripe\ContentReview\Extensions\ContentReviewOwner
SiteTreeContentReview: SilverStripe\ContentReview\Extensions\SiteTreeContentReview
ContentReviewNotificationJob: SilverStripe\ContentReview\Jobs\ContentReviewNotificationJob
ContentReviewLog: SilverStripe\ContentReview\Models\ContentReviewLog
PagesDueForReviewReport: SilverStripe\ContentReview\Reports\PagesDueForReviewReport
PagesWithoutReviewScheduleReport: SilverStripe\ContentReview\Reports\PagesWithoutReviewScheduleReport
ContentReviewEmails: SilverStripe\ContentReview\Tasks\ContentReviewEmails
ContentReviewOwnerMigrationTask: SilverStripe\ContentReview\Tasks\ContentReviewOwnerMigrationTask
ContentReviewBaseTest: SilverStripe\ContentReview\Tests\ContentReviewBaseTest
ContentReviewCMSPageEditControllerTest: SilverStripe\ContentReview\Tests\ContentReviewCMSPageEditControllerTest
ContentReviewNotificationTest: SilverStripe\ContentReview\Tests\ContentReviewNotificationTest
ContentReviewReportTest: SilverStripe\ContentReview\Tests\ContentReviewReportTest
ContentReviewSettingsTest: SilverStripe\ContentReview\Tests\ContentReviewSettingsTest
SiteTreeContentReviewTest: SilverStripe\ContentReview\Tests\SiteTreeContentReviewTest

View File

@ -1,18 +1,21 @@
SiteTree:
---
Name: contentreviewextensions
---
SilverStripe\CMS\Model\SiteTree:
extensions:
- SiteTreeContentReview
Group:
- SilverStripe\ContentReview\Extensions\SiteTreeContentReview
SilverStripe\Security\Group:
extensions:
- ContentReviewOwner
Member:
- SilverStripe\ContentReview\Extensions\ContentReviewOwner
SilverStripe\Security\Member:
extensions:
- ContentReviewOwner
CMSPageEditController:
- SilverStripe\ContentReview\Extensions\ContentReviewOwner
SilverStripe\CMS\Controllers\CMSPageEditController:
extensions:
- ContentReviewCMSExtension
CMSPageSettingsController:
- SilverStripe\ContentReview\Extensions\ContentReviewCMSExtension
SilverStripe\CMS\Controllers\CMSPageSettingsController:
extensions:
- ContentReviewCMSExtension
SiteConfig:
- SilverStripe\ContentReview\Extensions\ContentReviewCMSExtension
SilverStripe\SiteConfig\SiteConfig:
extensions:
- ContentReviewDefaultSettings
- SilverStripe\ContentReview\Extensions\ContentReviewDefaultSettings

6
_config/legacy.yml Normal file
View File

@ -0,0 +1,6 @@
---
Name: contentreviewlegacy
---
SilverStripe\ORM\DatabaseAdmin:
classname_value_remapping:
ContentReviewLog: SilverStripe\ContentReview\Models\ContentReviewLog

1
codecov.yml Normal file
View File

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

View File

@ -20,16 +20,29 @@
}
],
"require": {
"composer/installers": "*",
"silverstripe/framework": "~3.1",
"silverstripe/cms": "~3.1"
"silverstripe/framework": "^4@dev",
"silverstripe/cms": "^4@dev",
"silverstripe/reports": "^4@dev",
"silverstripe/siteconfig": "^4@dev"
},
"require-dev": {
"phpunit/phpunit": "^5.7",
"squizlabs/php_codesniffer": "^3.0"
},
"suggest": {
"silverstripe/queuedjobs": "Automatically schedules content review emails to be sent, only requiring one crontask to be created"
"symbiote/silverstripe-queuedjobs": "Automatically schedules content review emails to be sent, only requiring one crontask to be created"
},
"extra": {
"branch-alias": {
"dev-master": "4.0.x-dev"
}
}
},
"autoload": {
"psr-4": {
"SilverStripe\\ContentReview\\": "src/",
"SilverStripe\\ContentReview\\Tests\\": "tests/"
}
},
"minimum-stability": "dev",
"prefer-stable": true
}

View File

@ -1,4 +1,4 @@
Copyright (c) 2016, SilverStripe Limited
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:

13
phpunit.xml.dist Normal file
View File

@ -0,0 +1,13 @@
<phpunit bootstrap="cms/tests/bootstrap.php" colors="true">
<testsuite name="Default">
<directory>tests/</directory>
</testsuite>
<filter>
<whitelist addUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src/</directory>
<exclude>
<directory suffix=".php">tests/</directory>
</exclude>
</whitelist>
</filter>
</phpunit>

View File

@ -1,33 +1,33 @@
# Content Review module
[![Build Status](http://img.shields.io/travis/silverstripe/silverstripe-contentreview.svg?style=flat-square)](https://travis-ci.org/silverstripe/silverstripe-contentreview)
[![Code Quality](http://img.shields.io/scrutinizer/g/silverstripe/silverstripe-contentreview.svg?style=flat-square)](https://scrutinizer-ci.com/g/silverstripe/silverstripe-contentreview)
[![Version](http://img.shields.io/packagist/v/silverstripe/contentreview.svg?style=flat-square)](https://packagist.org/packages/silverstripe/contentreview)
[![License](http://img.shields.io/packagist/l/silverstripe/contentreview.svg?style=flat-square)](license.md)
![helpfulrobot](https://helpfulrobot.io/silverstripe/contentreview/badge)
[![Build status](https://travis-ci.org/silverstripe/silverstripe-contentreview.png?branch=master)](https://travis-ci.org/silverstripe/silverstripe-contentreview)
[![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)
[![Version](http://img.shields.io/packagist/v/silverstripe/contentreview.svg)](https://packagist.org/packages/silverstripe/contentreview)
[![License](http://img.shields.io/packagist/l/silverstripe/contentreview.svg)](license.md)
This module helps keep your website content accurate and up-to-date, which keeps your users happy.
This module helps keep your website content accurate and up-to-date, which keeps your users happy.
It does so by sending reviewers reminder emails to go in and check the content. For a reviewer this
It does so by sending reviewers reminder emails to go in and check the content. For a reviewer this
often includes checking links, grammar, factual information and look and feel.
There are two types of roles with this module.
There are two types of roles with this module.
* Website owner; (typically assigned to the Administrator group) ensures that a website is accurate and up-to-date, by delegating responsibility to content reviewers.
* Content reviewer; responsible for keeping a website or part of a website accurate and up-to-date.
## Requirements
* SilverStripe ^3.1
* SilverStripe ^4.0
## Features
* Content reviewer will receive an email notification when a page is due for review.
* Content reviewer will receive an email notification when a page is due for review.
* Content reviewer can mark a page as 'reviewed', and provide review notes.
* Website owner can assign content reviewers to a page and set when the content should be reviewed.
* Website owner can see a report of pages and their reviewed status.
* Content reviewers can be assigned to a page, a page and all sub-pages, or globally.
* The content review schedule can be automatic, e.g. every month, and/or a specific date.
* The content review schedule can be automatic, e.g. every month, and/or a specific date.
## Wishlist features

View File

@ -1,5 +1,12 @@
<?php
namespace SilverStripe\ContentReview\Compatibility;
use SilverStripe\Core\ClassInfo;
use SilverStripe\Subsites\Model\Subsite;
// @todo add translatable namespace
use Translatable;
/**
* This is a helper class which lets us do things with content review data without subsites
* and translatable messing our SQL queries up.
@ -25,12 +32,12 @@ class ContentReviewCompatability
self::TRANSLATABLE => null,
);
if (ClassInfo::exists("Subsite")) {
if (ClassInfo::exists(Subsite::class)) {
$compatibility[self::SUBSITES] = Subsite::$disable_subsite_filter;
Subsite::disable_subsite_filter(true);
}
if (ClassInfo::exists("Translatable")) {
if (ClassInfo::exists(Translatable::class)) {
$compatibility[self::TRANSLATABLE] = Translatable::locale_filter_enabled();
Translatable::disable_locale_filter();
}
@ -43,11 +50,11 @@ class ContentReviewCompatability
*/
public static function done(array $compatibility)
{
if (class_exists("Subsite")) {
if (class_exists(Subsite::class)) {
Subsite::$disable_subsite_filter = $compatibility[self::SUBSITES];
}
if (class_exists("Translatable")) {
if (class_exists(Translatable::class)) {
Translatable::enable_locale_filter($compatibility[self::TRANSLATABLE]);
}
}

View File

@ -1,5 +1,14 @@
<?php
namespace SilverStripe\ContentReview\Extensions;
use SilverStripe\Admin\LeftAndMainExtension;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Control\HTTPResponse_Exception;
use SilverStripe\Forms\Form;
use SilverStripe\Security\Member;
use SilverStripe\Security\Security;
/**
* CMSPageEditController extension to receive the additional action button from
* SiteTreeContentReview::updateCMSActions()
@ -21,7 +30,7 @@ class ContentReviewCMSExtension extends LeftAndMainExtension
*
* @return string
*
* @throws SS_HTTPResponse_Exception
* @throws HTTPResponse_Exception
*/
public function savereview($data, Form $form)
{
@ -30,14 +39,17 @@ class ContentReviewCMSExtension extends LeftAndMainExtension
return Security::permissionFailure($this->owner);
}
$notes = (!empty($data["ReviewNotes"]) ? $data["ReviewNotes"] : _t("ContentReview.NOCOMMENTS", "(no comments)"));
$notes = (!empty($data["ReviewNotes"])
? $data["ReviewNotes"]
: _t("ContentReview.NOCOMMENTS", "(no comments)"));
$page->addReviewNote(Member::currentUser(), $notes);
$page->advanceReviewDate();
$this->owner->getResponse()->addHeader("X-Status", _t("ContentReview.REVIEWSUCCESSFUL", "Content reviewed successfully"));
$this->owner->getResponse()
->addHeader("X-Status", _t("ContentReview.REVIEWSUCCESSFUL", "Content reviewed successfully"));
return $this->owner->redirectBack();
}
/**
* Find the page this form is updating
*
@ -48,7 +60,7 @@ class ContentReviewCMSExtension extends LeftAndMainExtension
protected function findRecord($data)
{
if (empty($data["ID"])) {
throw new SS_HTTPResponse_Exception("No record ID", 404);
throw new HTTPResponse_Exception("No record ID", 404);
}
$page = null;
@ -58,7 +70,7 @@ class ContentReviewCMSExtension extends LeftAndMainExtension
}
if (!$page || !$page->ID) {
throw new SS_HTTPResponse_Exception("Bad record ID #{$id}", 404);
throw new HTTPResponse_Exception("Bad record ID #{$id}", 404);
}
return $page;

View File

@ -1,5 +1,20 @@
<?php
namespace SilverStripe\ContentReview\Extensions;
use SilverStripe\Core\Config\Config;
use SilverStripe\Control\Email\Email;
use SilverStripe\Forms\DropdownField;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\ListboxField;
use SilverStripe\Forms\LiteralField;
use SilverStripe\Forms\TextareaField;
use SilverStripe\Forms\TextField;
use SilverStripe\ORM\DataExtension;
use SilverStripe\Security\Group;
use SilverStripe\Security\Member;
use SilverStripe\Security\Permission;
/**
* This extensions add a default schema for new pages and pages without a content
* review setting.
@ -36,8 +51,8 @@ class ContentReviewDefaultSettings extends DataExtension
* @var array
*/
private static $many_many = array(
'ContentReviewGroups' => 'Group',
'ContentReviewUsers' => 'Member',
'ContentReviewGroups' => Group::class,
'ContentReviewUsers' => Member::class,
);
/**
@ -49,7 +64,7 @@ class ContentReviewDefaultSettings extends DataExtension
*
* @var string
*/
private static $content_review_template = 'ContentReviewEmail';
private static $content_review_template = 'SilverStripe\\ContentReview\\ContentReviewEmail';
/**
* @return string
@ -121,7 +136,6 @@ class ContentReviewDefaultSettings extends DataExtension
asort($usersMap);
$userField = ListboxField::create('OwnerUsers', _t('ContentReview.PAGEOWNERUSERS', 'Users'), $usersMap)
->setMultiple(true)
->setAttribute('data-placeholder', _t('ContentReview.ADDUSERS', 'Add users'))
->setDescription(_t('ContentReview.OWNERUSERSDESCRIPTION', 'Page owners that are responsible for reviews'));
@ -137,7 +151,6 @@ class ContentReviewDefaultSettings extends DataExtension
asort($groupsMap);
$groupField = ListboxField::create('OwnerGroups', _t('ContentReview.PAGEOWNERGROUPS', 'Groups'), $groupsMap)
->setMultiple(true)
->setAttribute('data-placeholder', _t('ContentReview.ADDGROUP', 'Add groups'))
->setDescription(_t('ContentReview.OWNERGROUPSDESCRIPTION', 'Page owners that are responsible for reviews'));
@ -151,7 +164,10 @@ class ContentReviewDefaultSettings extends DataExtension
->setRightTitle(_t('Review.EMAILFROM_RIGHTTITLE', 'e.g: do-not-reply@site.com')),
TextField::create('ReviewSubject', _t('ContentReview.EMAILSUBJECT', 'Subject line')),
TextAreaField::create('ReviewBody', _t('ContentReview.EMAILTEMPLATE', 'Email template')),
LiteralField::create('TemplateHelp', $this->owner->renderWith('ContentReviewAdminHelp')),
LiteralField::create(
'TemplateHelp',
$this->owner->renderWith('SilverStripe\\ContentReview\\ContentReviewAdminHelp')
),
)
);
}
@ -200,7 +216,7 @@ class ContentReviewDefaultSettings extends DataExtension
}
// Fall back to admin email
return Config::inst()->get('Email', 'admin_email');
return Config::inst()->get(Email::class, 'admin_email');
}
/**
@ -217,7 +233,7 @@ class ContentReviewDefaultSettings extends DataExtension
return $value;
}
// fallback to default value
$defaults = $this->owner->config()->defaults;
$defaults = $this->owner->config()->get('defaults');
if (isset($defaults[$field])) {
return $defaults[$field];
}

View File

@ -1,5 +1,10 @@
<?php
namespace SilverStripe\ContentReview\Extensions;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\ORM\DataExtension;
/**
* Description of GroupContentReview.
*/
@ -9,6 +14,6 @@ class ContentReviewOwner extends DataExtension
* @var array
*/
private static $many_many = array(
"SiteTreeContentReview" => "SiteTree",
"SiteTreeContentReview" => SiteTree::class,
);
}

View File

@ -1,5 +1,46 @@
<?php
namespace SilverStripe\ContentReview\Extensions;
use Exception;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\ContentReview\Jobs\ContentReviewNotificationJob;
use SilverStripe\ContentReview\Models\ContentReviewLog;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\LiteralField;
use SilverStripe\Forms\FormAction;
use SilverStripe\Forms\CompositeField;
use SilverStripe\Forms\Tab;
use SilverStripe\Forms\DateField;
use SilverStripe\Forms\DropdownField;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldConfig;
use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor;
use SilverStripe\Forms\GridField\GridFieldDataColumns;
use SilverStripe\Forms\GridField\GridFieldSortableHeader;
use SilverStripe\Forms\ListboxField;
use SilverStripe\Forms\OptionsetField;
use SilverStripe\Forms\ReadonlyField;
use SilverStripe\Forms\HeaderField;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataExtension;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DB;
use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\ORM\FieldType\DBDate;
use SilverStripe\ORM\SS_List;
use SilverStripe\Security\Group;
use SilverStripe\Security\Member;
use SilverStripe\Security\Permission;
use SilverStripe\Security\PermissionProvider;
use SilverStripe\Security\Security;
use SilverStripe\SiteConfig\SiteConfig;
use SilverStripe\View\Requirements;
use Symbiote\QueuedJobs\DataObjects\QueuedJobDescriptor;
use Symbiote\QueuedJobs\Services\QueuedJobService;
/**
* Set dates at which content needs to be reviewed and provide a report and emails to alert
* to content needing review.
@ -38,15 +79,15 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
* @var array
*/
private static $has_many = array(
"ReviewLogs" => "ContentReviewLog",
"ReviewLogs" => ContentReviewLog::class,
);
/**
* @var array
*/
private static $belongs_many_many = array(
"ContentReviewGroups" => "Group",
"ContentReviewUsers" => "Member",
"ContentReviewGroups" => Group::class,
"ContentReviewUsers" => Member::class,
);
/**
@ -70,7 +111,7 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
*/
public static function get_schedule()
{
return self::$schedule;
return Config::inst()->get(static::class, 'schedule');
}
/**
@ -99,9 +140,10 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
array_unique($groupIDs);
if (count($groupIDs)) {
$groupMembers = DataObject::get("Member")->where("\"Group\".\"ID\" IN (" . implode(",", $groupIDs) . ")")
$groupMembers = DataObject::get(Member::class)->where("\"Group\".\"ID\" IN (" . implode(",", $groupIDs) . ")")
->leftJoin("Group_Members", "\"Member\".\"ID\" = \"Group_Members\".\"MemberID\"")
->leftJoin("Group", "\"Group_Members\".\"GroupID\" = \"Group\".\"ID\"");
/** @skipUpgrade */
->leftJoin('Group', "\"Group_Members\".\"GroupID\" = \"Group\".\"ID\"");
$contentReviewOwners->merge($groupMembers);
}
@ -118,8 +160,8 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
*/
public function updateCMSActions(FieldList $actions)
{
if ($this->canBeReviewedBy(Member::currentUser())) {
Requirements::css("contentreview/css/contentreview.css");
if ($this->canBeReviewedBy(Security::getCurrentUser())) {
Requirements::css("silverstripe/contentreview:css/contentreview.css");
$reviewTitle = LiteralField::create(
"ReviewContentNotesLabel",
@ -155,8 +197,8 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
$page = $this->owner;
}
if ($page->obj("NextReviewDate")->exists()) {
return $page->obj("NextReviewDate");
if ($page->obj('NextReviewDate')->exists()) {
return $page->obj('NextReviewDate');
}
$options = $this->owner->getOptions();
@ -170,9 +212,9 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
}
// Failover to check on ReviewPeriodDays + LastEdited
$nextReviewUnixSec = strtotime(" + " . $options->ReviewPeriodDays . " days", SS_Datetime::now()->format("U"));
$date = Date::create("NextReviewDate");
$date->setValue(date("Y-m-d H:i:s", $nextReviewUnixSec));
$nextReviewUnixSec = strtotime(' + ' . $options->ReviewPeriodDays . ' days', DBDatetime::now()->getTimestamp());
$date = DBDate::create('NextReviewDate');
$date->setValue($nextReviewUnixSec);
return $date;
}
@ -205,7 +247,6 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
// $page is inheriting it's settings from it's parent, find
// the first valid parent with a valid setting
while ($parent = $page->Parent()) {
// Root page, use site config
if (!$parent->exists()) {
return SiteConfig::current_site_config();
@ -254,7 +295,7 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
*/
public function getEditorName()
{
$member = Member::currentUser();
$member = Security::getCurrentUser();
if ($member) {
return $member->getTitle();
@ -298,7 +339,7 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
*/
public function updateSettingsFields(FieldList $fields)
{
Requirements::javascript("contentreview/javascript/contentreview.js");
Requirements::javascript("silverstripe/contentreview:javascript/contentreview.js");
// Display read-only version only
if (!Permission::check("EDIT_CONTENT_REVIEW_FIELDS")) {
@ -313,8 +354,8 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
}
$logConfig = GridFieldConfig::create()
->addComponent(new GridFieldSortableHeader())
->addComponent($logColumns = new GridFieldDataColumns());
->addComponent(Injector::inst()->create(GridFieldSortableHeader::class))
->addComponent($logColumns = Injector::inst()->create(GridFieldDataColumns::class));
// Cast the value to the users preferred date format
$logColumns->setFieldCasting(array(
@ -351,7 +392,6 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
asort($usersMap);
$userField = ListboxField::create("OwnerUsers", _t("ContentReview.PAGEOWNERUSERS", "Users"), $usersMap)
->setMultiple(true)
->addExtraClass('custom-setting')
->setAttribute("data-placeholder", _t("ContentReview.ADDUSERS", "Add users"))
->setDescription(_t('ContentReview.OWNERUSERSDESCRIPTION', 'Page owners that are responsible for reviews'));
@ -364,15 +404,11 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
asort($groupsMap);
$groupField = ListboxField::create("OwnerGroups", _t("ContentReview.PAGEOWNERGROUPS", "Groups"), $groupsMap)
->setMultiple(true)
->addExtraClass('custom-setting')
->setAttribute("data-placeholder", _t("ContentReview.ADDGROUP", "Add groups"))
->setDescription(_t("ContentReview.OWNERGROUPSDESCRIPTION", "Page owners that are responsible for reviews"));
$reviewDate = DateField::create("NextReviewDate", _t("ContentReview.NEXTREVIEWDATE", "Next review date"))
->setConfig("showcalendar", true)
->setConfig("dateformat", "yyyy-MM-dd")
->setConfig("datavalueformat", "yyyy-MM-dd")
->setDescription(_t("ContentReview.NEXTREVIEWDATADESCRIPTION", "Leave blank for no review"));
$reviewFrequency = DropdownField::create(
@ -386,7 +422,7 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
$notesField = GridField::create("ReviewNotes", "Review Notes", $this->owner->ReviewLogs(), GridFieldConfig_RecordEditor::create());
$fields->addFieldsToTab("Root.ContentReview", array(
new HeaderField(_t("ContentReview.REVIEWHEADER", "Content review"), 2),
HeaderField::create('ContentReviewHeader', _t("ContentReview.REVIEWHEADER", "Content review"), 2),
$viewersOptionsField,
CompositeField::create(
$userField,
@ -422,17 +458,20 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
*/
public function advanceReviewDate()
{
$nextDate = false;
$nextDateTimestamp = false;
$options = $this->getOptions();
if ($options && $options->ReviewPeriodDays) {
$nextDate = date('Y-m-d', strtotime('+ ' . $options->ReviewPeriodDays . ' days', SS_Datetime::now()->format('U')));
$nextDateTimestamp = strtotime(
' + ' . $options->ReviewPeriodDays . ' days',
DBDatetime::now()->getTimestamp()
);
$this->owner->NextReviewDate = $nextDate;
$this->owner->NextReviewDate = DBDate::create()->setValue($nextDateTimestamp)->Format('y-MM-dd');
$this->owner->write();
}
return (bool) $nextDate;
return (bool) $nextDateTimestamp;
}
/**
@ -453,12 +492,12 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
}
$options = $this->getOptions();
if (!$options) {
return false;
}
if (!$options || !$options->hasExtension($this->class)) {
if (!$options || !$options->hasExtension(__CLASS__)) {
return false;
}
@ -488,7 +527,7 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
{
// Only update if DB fields have been changed
$changedFields = $this->owner->getChangedFields(true, 2);
if($changedFields) {
if ($changedFields) {
$this->owner->LastEditedByName = $this->owner->getEditorName();
$this->owner->OwnerNames = $this->owner->getOwnerNames();
}
@ -518,9 +557,12 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
// parent page change its review period
// && !$this->owner->isChanged('ContentReviewType', 2)
if ($this->owner->isChanged("ReviewPeriodDays", 2)) {
$nextReviewUnixSec = strtotime(" + " . $this->owner->ReviewPeriodDays . " days", SS_Datetime::now()->format("U"));
$this->owner->NextReviewDate = date("Y-m-d", $nextReviewUnixSec);
if ($this->owner->isChanged('ReviewPeriodDays', 2)) {
$nextReviewUnixSec = strtotime(
' + ' . $this->owner->ReviewPeriodDays . ' days',
DBDatetime::now()->getTimestamp()
);
$this->owner->NextReviewDate = DBDate::create()->setValue($nextReviewUnixSec)->Format('y-MM-dd');
}
}
@ -591,17 +633,17 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
*/
public function requireDefaultRecords()
{
if (class_exists("ContentReviewNotificationJob")) {
if (class_exists(ContentReviewNotificationJob::class)) {
// Ensure there is not already a job queued
if (QueuedJobDescriptor::get()->filter("Implementation", "ContentReviewNotificationJob")->first()) {
if (QueuedJobDescriptor::get()->filter("Implementation", ContentReviewNotificationJob::class)->first()) {
return;
}
$nextRun = new ContentReviewNotificationJob();
$runHour = Config::inst()->get("ContentReviewNotificationJob", "first_run_hour");
$nextRun = Injector::inst()->create(ContentReviewNotificationJob::class);
$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")));
singleton("QueuedJobService")->queueJob(
singleton(QueuedJobService::class)->queueJob(
$nextRun,
$firstRunTime
);

View File

@ -1,6 +1,15 @@
<?php
if (!class_exists("AbstractQueuedJob")) {
namespace SilverStripe\ContentReview\Jobs;
use SilverStripe\ContentReview\Tasks\ContentReviewEmails;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Core\Config\Config;
use Symbiote\QueuedJobs\Services\AbstractQueuedJob;
use Symbiote\QueuedJobs\Services\QueuedJob;
use Symbiote\QueuedJobs\Services\QueuedJobService;
if (!class_exists(AbstractQueuedJob::class)) {
return;
}
@ -76,7 +85,7 @@ class ContentReviewNotificationJob extends AbstractQueuedJob implements QueuedJo
$this->queueNextRun();
$task = new ContentReviewEmails();
$task->run(new SS_HTTPRequest("GET", "/dev/tasks/ContentReviewEmails"));
$task->run(new HTTPRequest("GET", "/dev/tasks/ContentReviewEmails"));
$this->currentStep = 1;
$this->isComplete = true;
@ -98,7 +107,7 @@ class ContentReviewNotificationJob extends AbstractQueuedJob implements QueuedJo
date("Y")
);
singleton("QueuedJobService")->queueJob(
singleton(QueuedJobService::class)->queueJob(
$nextRun,
date("Y-m-d H:i:s", $nextRunTime)
);

View File

@ -1,5 +1,12 @@
<?php
namespace SilverStripe\ContentReview\Models;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;
use SilverStripe\Security\Security;
class ContentReviewLog extends DataObject
{
/**
@ -13,8 +20,8 @@ class ContentReviewLog extends DataObject
* @var array
*/
private static $has_one = array(
"Reviewer" => "Member",
"SiteTree" => "SiteTree",
"Reviewer" => Member::class,
"SiteTree" => SiteTree::class,
);
/**
@ -31,6 +38,8 @@ class ContentReviewLog extends DataObject
*/
private static $default_sort = "Created DESC";
private static $table_name = 'ContentReviewLog';
/**
* @param mixed $member
*
@ -38,6 +47,6 @@ class ContentReviewLog extends DataObject
*/
public function canView($member = null)
{
return (bool) Member::currentUser();
return (bool) Security::getCurrentUser();
}
}

View File

@ -1,11 +1,29 @@
<?php
require_once "Zend/Date.php";
namespace SilverStripe\ContentReview\Reports;
use SilverStripe\CMS\Controllers\CMSPageEditController;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\CMS\Model\VirtualPage;
use SilverStripe\ContentReview\Compatibility\ContentReviewCompatability;
use SilverStripe\ContentReview\Extensions\ContentReviewOwner;
use SilverStripe\Core\ClassInfo;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Convert;
use SilverStripe\Forms\CheckboxField;
use SilverStripe\Forms\DateField;
use SilverStripe\Forms\FieldList;
use SilverStripe\i18n\i18n;
use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\Reports\Report;
use SilverStripe\Security\Security;
use SilverStripe\SiteConfig\SiteConfig;
use SilverStripe\Versioned\Versioned;
/**
* Show all pages that need to be reviewed.
*/
class PagesDueForReviewReport extends SS_Report
class PagesDueForReviewReport extends Report
{
/**
* @return string
@ -20,21 +38,36 @@ class PagesDueForReviewReport extends SS_Report
*/
public function parameterFields()
{
$filtersList = new FieldList();
$filtersList = FieldList::create();
$filtersList->push(
DateField::create("ReviewDateAfter", _t("PagesDueForReviewReport.REVIEWDATEAFTER", "Review date after or on"))
->setConfig("showcalendar", true)
DateField::create(
"ReviewDateAfter",
_t("PagesDueForReviewReport.REVIEWDATEAFTER", "Review date after or on")
)
);
$filtersList->push(
DateField::create("ReviewDateBefore", _t("PagesDueForReviewReport.REVIEWDATEBEFORE", "Review date before or on"), date("d/m/Y", strtotime("midnight")))
->setConfig("showcalendar", true)
DateField::create(
"ReviewDateBefore",
_t("PagesDueForReviewReport.REVIEWDATEBEFORE", "Review date before or on"),
date("d/m/Y", strtotime("midnight"))
)
);
$filtersList->push(new CheckboxField("ShowVirtualPages", _t("PagesDueForReviewReport.SHOWVIRTUALPAGES", "Show Virtual Pages")));
$filtersList->push(
CheckboxField::create(
"ShowVirtualPages",
_t("PagesDueForReviewReport.SHOWVIRTUALPAGES", "Show Virtual Pages")
)
);
$filtersList->push(new CheckboxField("OnlyMyPages", _t("PagesDueForReviewReport.ONLYMYPAGES", "Only Show pages assigned to me")));
$filtersList->push(
CheckboxField::create(
"OnlyMyPages",
_t("PagesDueForReviewReport.ONLYMYPAGES", "Only Show pages assigned to me")
)
);
return $filtersList;
}
@ -44,7 +77,7 @@ class PagesDueForReviewReport extends SS_Report
*/
public function columns()
{
$linkBase = singleton("CMSPageEditController")->Link("show");
$linkBase = singleton(CMSPageEditController::class)->Link("show");
$linkPath = parse_url($linkBase, PHP_URL_PATH);
$linkQuery = parse_url($linkBase, PHP_URL_QUERY);
@ -80,7 +113,8 @@ class PagesDueForReviewReport extends SS_Report
$liveLink = $item->AbsoluteLiveLink;
$stageLink = $item->AbsoluteLink();
return sprintf("%s <a href='%s'>%s</a>",
return sprintf(
"%s <a href='%s'>%s</a>",
$stageLink,
$liveLink ? $liveLink : $stageLink . "?stage=Stage",
$liveLink ? "(live)" : "(draft)"
@ -120,36 +154,50 @@ class PagesDueForReviewReport extends SS_Report
*/
public function sourceRecords($params = array())
{
Versioned::reading_stage("Stage");
Versioned::set_stage(Versioned::DRAFT);
$records = SiteTree::get();
$compatibility = ContentReviewCompatability::start();
if (empty($params["ReviewDateBefore"]) && empty($params["ReviewDateAfter"])) {
if (empty($params['ReviewDateBefore']) && empty($params['ReviewDateAfter'])) {
// If there's no review dates set, default to all pages due for review now
$reviewDate = new Zend_Date(SS_Datetime::now()->Format("U"));
$reviewDate->add(1, Zend_Date::DAY);
$records = $records->where(sprintf('"NextReviewDate" < \'%s\'', $reviewDate->toString("YYYY-MM-dd")));
$records = $records->where(
sprintf(
'"NextReviewDate" < \'%s\'',
DBDatetime::now()->Format('y-MM-dd')
)
);
} else {
// Review date before
if (!empty($params['ReviewDateBefore'])) {
// TODO Get value from DateField->dataValue() once we have access to form elements here
$reviewDate = new Zend_Date($params["ReviewDateBefore"], Config::inst()->get("i18n", "date_format"));
$reviewDate->add(1, Zend_Date::DAY);
$records = $records->where(sprintf("\"NextReviewDate\" < '%s'", $reviewDate->toString("YYYY-MM-dd")));
$nextReviewUnixSec = strtotime(
' + 1 day',
strtotime($params['ReviewDateBefore'])
);
$records = $records->where(
sprintf(
"\"NextReviewDate\" < '%s'",
DBDatetime::create()->setValue($nextReviewUnixSec)->Format('y-MM-dd')
)
);
}
// Review date after
if (!empty($params["ReviewDateAfter"])) {
if (!empty($params['ReviewDateAfter'])) {
// TODO Get value from DateField->dataValue() once we have access to form elements here
$reviewDate = new Zend_Date($params["ReviewDateAfter"], Config::inst()->get("i18n", "date_format"));
$records = $records->where(sprintf("\"NextReviewDate\" >= '%s'", $reviewDate->toString("YYYY-MM-dd")));
$records = $records->where(
sprintf(
"\"NextReviewDate\" >= '%s'",
DBDatetime::create()->setValue(strtotime($params['ReviewDateAfter']))->Format('y-MM-dd')
)
);
}
}
// Show virtual pages?
if (empty($params["ShowVirtualPages"])) {
$virtualPageClasses = ClassInfo::subclassesFor("VirtualPage");
$virtualPageClasses = ClassInfo::subclassesFor(VirtualPage::class);
$records = $records->where(sprintf(
"\"SiteTree\".\"ClassName\" NOT IN ('%s')",
implode("','", array_values($virtualPageClasses))
@ -157,15 +205,15 @@ class PagesDueForReviewReport extends SS_Report
}
// Owner dropdown
if (!empty($params["ContentReviewOwner"])) {
$ownerNames = Convert::raw2sql($params["ContentReviewOwner"]);
if (!empty($params[ContentReviewOwner::class])) {
$ownerNames = Convert::raw2sql($params[ContentReviewOwner::class]);
$records = $records->filter("OwnerNames:PartialMatch", $ownerNames);
}
// Only show pages assigned to the current user?
// This come last because it transforms $records to an ArrayList.
if (!empty($params["OnlyMyPages"])) {
$currentUser = Member::currentUser();
$currentUser = Security::getCurrentUser();
$records = $records->filterByCallback(function ($page) use ($currentUser) {
$options = $page->getOptions();

View File

@ -1,11 +1,24 @@
<?php
require_once "Zend/Date.php";
namespace SilverStripe\ContentReview\Reports;
use SilverStripe\Forms\CheckboxField;
use SilverStripe\Forms\FieldList;
use SilverStripe\CMS\Controllers\CMSPageEditController;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\CMS\Model\VirtualPage;
use SilverStripe\ContentReview\Compatibility\ContentReviewCompatability;
use SilverStripe\Core\ClassInfo;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataObject;
use SilverStripe\Reports\Report;
use SilverStripe\SiteConfig\SiteConfig;
use SilverStripe\Versioned\Versioned;
/**
* Show all pages that need to be reviewed.
*/
class PagesWithoutReviewScheduleReport extends SS_Report
class PagesWithoutReviewScheduleReport extends Report
{
/**
* @return string
@ -20,8 +33,8 @@ class PagesWithoutReviewScheduleReport extends SS_Report
*/
public function parameterFields()
{
$params = new FieldList();
$params->push(new CheckboxField("ShowVirtualPages", "Show Virtual Pages"));
$params = FieldList::create();
$params->push(CheckboxField::create("ShowVirtualPages", "Show Virtual Pages"));
return $params;
}
@ -31,7 +44,7 @@ class PagesWithoutReviewScheduleReport extends SS_Report
*/
public function columns()
{
$linkBase = singleton("CMSPageEditController")->Link("show");
$linkBase = singleton(CMSPageEditController::class)->Link("show");
$linkPath = parse_url($linkBase, PHP_URL_PATH);
$linkQuery = parse_url($linkBase, PHP_URL_QUERY);
@ -54,7 +67,8 @@ class PagesWithoutReviewScheduleReport extends SS_Report
$liveLink = $item->AbsoluteLiveLink;
$stageLink = $item->AbsoluteLink();
return sprintf("%s <a href='%s'>%s</a>",
return sprintf(
"%s <a href='%s'>%s</a>",
$stageLink,
$liveLink ? $liveLink : $stageLink . "?stage=Stage",
$liveLink ? "(live)" : "(draft)"
@ -94,7 +108,7 @@ class PagesWithoutReviewScheduleReport extends SS_Report
*/
public function sourceRecords($params = array())
{
Versioned::reading_stage("Stage");
Versioned::set_stage(Versioned::DRAFT);
$records = SiteTree::get();
$compatibility = ContentReviewCompatability::start();
@ -103,7 +117,7 @@ class PagesWithoutReviewScheduleReport extends SS_Report
// Show virtual pages?
if (empty($params["ShowVirtualPages"])) {
$virtualPageClasses = ClassInfo::subclassesFor("VirtualPage");
$virtualPageClasses = ClassInfo::subclassesFor(VirtualPage::class);
$records = $records->where(sprintf(
"\"SiteTree\".\"ClassName\" NOT IN ('%s')",
implode("','", array_values($virtualPageClasses))
@ -114,7 +128,7 @@ class PagesWithoutReviewScheduleReport extends SS_Report
$records = $records->toArray();
// Trim out calculated values
$list = new ArrayList();
$list = ArrayList::create();
foreach ($records as $record) {
if (!$this->hasReviewSchedule($record)) {
$list->push($record);

View File

@ -1,12 +1,28 @@
<?php
namespace SilverStripe\ContentReview\Tasks;
use Page;
use SilverStripe\ContentReview\Compatibility\ContentReviewCompatability;
use SilverStripe\Control\Email\Email;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Dev\BuildTask;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\ORM\SS_List;
use SilverStripe\Security\Member;
use SilverStripe\SiteConfig\SiteConfig;
use SilverStripe\View\ArrayData;
use SilverStripe\View\SSViewer;
/**
* Daily task to send emails to the owners of content items when the review date rolls around.
*/
class ContentReviewEmails extends BuildTask
{
/**
* @param SS_HTTPRequest $request
* @param HTTPRequest $request
*/
public function run($request)
{
@ -14,7 +30,7 @@ class ContentReviewEmails extends BuildTask
// First grab all the pages with a custom setting
$pages = Page::get()
->filter('NextReviewDate:LessThanOrEqual', SS_Datetime::now()->URLDate());
->filter('NextReviewDate:LessThanOrEqual', DBDatetime::now()->URLDate());
$overduePages = $this->getOverduePagesForOwners($pages);
@ -28,11 +44,11 @@ class ContentReviewEmails extends BuildTask
}
/**
* @param SS_list $pages
* @param SS_List $pages
*
* @return array
*/
protected function getOverduePagesForOwners(SS_list $pages)
protected function getOverduePagesForOwners(SS_List $pages)
{
$overduePages = array();
@ -45,7 +61,7 @@ class ContentReviewEmails extends BuildTask
foreach ($option->ContentReviewOwners() as $owner) {
if (!isset($overduePages[$owner->ID])) {
$overduePages[$owner->ID] = new ArrayList();
$overduePages[$owner->ID] = ArrayList::create();
}
$overduePages[$owner->ID]->push($page);
@ -67,7 +83,7 @@ class ContentReviewEmails extends BuildTask
$templateVariables = $this->getTemplateVariables($owner, $siteConfig, $pages);
// Build email
$email = new Email();
$email = Email::create();
$email->setTo($owner->Email);
$email->setFrom($siteConfig->ReviewFrom);
$email->setSubject($siteConfig->ReviewSubject);
@ -76,13 +92,17 @@ class ContentReviewEmails extends BuildTask
$body = $this->getEmailBody($siteConfig, $templateVariables);
// Populate mail body with fixed template
$email->setTemplate($siteConfig->config()->content_review_template);
$email->populateTemplate($templateVariables);
$email->populateTemplate(array(
'EmailBody' => $body,
'Recipient' => $owner,
'Pages' => $pages,
));
$email->setHTMLTemplate($siteConfig->config()->get('content_review_template'));
$email->setData(
array_merge(
$templateVariables,
[
'EmailBody' => $body,
'Recipient' => $owner,
'Pages' => $pages,
]
)
);
$email->send();
}
@ -97,7 +117,7 @@ class ContentReviewEmails extends BuildTask
protected function getEmailBody($config, $variables)
{
$template = SSViewer::fromString($config->ReviewBody);
$value = $template->process(new ArrayData($variables));
$value = $template->process(ArrayData::create($variables));
// Cast to HTML
return DBField::create_field('HTMLText', (string) $value);
@ -117,13 +137,13 @@ class ContentReviewEmails extends BuildTask
*/
protected function getTemplateVariables($recipient, $config, $pages)
{
return array(
return [
'Subject' => $config->ReviewSubject,
'PagesCount' => $pages->count(),
'FromEmail' => $config->ReviewFrom,
'ToFirstName' => $recipient->FirstName,
'ToSurname' => $recipient->Surname,
'ToEmail' => $recipient->Email,
);
];
}
}

View File

@ -1,12 +1,18 @@
<?php
namespace SilverStripe\ContentReview\Tasks;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Dev\BuildTask;
use SilverStripe\ORM\DB;
/**
* Task which migrates the ContentReview Module's SiteTree->OwnerID column to a new column name.
*/
class ContentReviewOwnerMigrationTask extends BuildTask
{
/**
* @param SS_HTTPRequest $request
* @param HTTPRequest $request
*/
public function run($request)
{
@ -20,7 +26,7 @@ class ContentReviewOwnerMigrationTask extends BuildTask
DB::query("UPDATE \"SiteTree_versions\" SET \"ContentReviewOwnerID\" = \"OwnerID\"");
DB::query("ALTER TABLE \"SiteTree\" DROP COLUMN \"OwnerID\"");
DB::query("ALTER TABLE \"SiteTree_Live\" DROP COLUMN \"OwnerID\"");
DB::query("ALTER TABLE \"SiteTree_versions\" DROP COLUMN \"OwnerID\"");
DB::query("ALTER TABLE \"SiteTree_Versions\" DROP COLUMN \"OwnerID\"");
echo "<h1>Migrated 3 tables. Dropped obsolete OwnerID column</h1>";
}
}

View File

@ -9,15 +9,15 @@
$EmailBody
</td>
</tr>
<% loop Pages %>
<% loop $Pages %>
<tr>
<td valign="top">$Title</td>
<td><a href="{$BaseURL}admin/pages/edit/show/$ID"><% _t('ContentReviewEmails.REVIEWPAGELINK','Review the page in the CMS') %></a><br />
<a href="$AbsoluteLink"><% _t('ContentReviewEmails.VIEWPUBLISHEDLINK','View this page on the website') %></a>
<td><a href="{$BaseURL}admin/pages/edit/show/$ID"><%t ContentReviewEmails.REVIEWPAGELINK 'Review the page in the CMS' %></a><br />
<a href="$AbsoluteLink"><%t ContentReviewEmails.VIEWPUBLISHEDLINK 'View this page on the website' %></a>
</td>
</tr>
<% end_loop %>
</tbody>
</table>
</body>
</html>
</html>

View File

@ -1,5 +1,12 @@
<?php
namespace SilverStripe\ContentReview\Tests;
use SilverStripe\Dev\FunctionalTest;
use SilverStripe\CMS\Model\SiteTree;
// @todo add translatable namespace
use Translatable;
/**
* Extend this class when writing unit tests which are compatible with other modules.
* All compatibility code goes here.
@ -11,7 +18,7 @@ abstract class ContentReviewBaseTest extends FunctionalTest
*/
protected $translatableEnabledBefore;
public function setUp()
protected function setUp()
{
parent::setUp();
@ -21,21 +28,21 @@ abstract class ContentReviewBaseTest extends FunctionalTest
* (e.g. $this->post()) do not seem to get passed the tester's locale, but instead fallback to the default locale.
*
* So we set the pages locale to be the default locale, which will then match any subsequent requests.
*
*
* If creating pages in your unit tests (rather than reading from the fixtures file), you must explicitly call
* self::compat() on the page, for the same reasons as above.
*/
if (class_exists("Translatable")) {
$this->translatableEnabledBefore = SiteTree::has_extension("Translatable");
SiteTree::remove_extension("Translatable");
if (class_exists(Translatable::class)) {
$this->translatableEnabledBefore = SiteTree::has_extension(Translatable::class);
SiteTree::remove_extension(Translatable::class);
}
}
public function tearDown()
protected function tearDown()
{
if (class_exists("Translatable")) {
if (class_exists(Translatable::class)) {
if ($this->translatableEnabledBefore) {
SiteTree::add_extension("Translatable");
SiteTree::add_extension(Translatable::class);
}
}

View File

@ -1,5 +1,22 @@
<?php
namespace SilverStripe\ContentReview\Tests;
use Page;
use SilverStripe\CMS\Controllers\CMSPageEditController;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\ContentReview\Extensions\SiteTreeContentReview;
use SilverStripe\ContentReview\Extensions\ContentReviewOwner;
use SilverStripe\ContentReview\Extensions\ContentReviewCMSExtension;
use SilverStripe\ContentReview\Extensions\ContentReviewDefaultSettings;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\HTTPResponse_Exception;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Security\Group;
use SilverStripe\Security\Member;
use SilverStripe\SiteConfig\SiteConfig;
/**
* @mixin PHPUnit_Framework_TestCase
*/
@ -8,27 +25,27 @@ class ContentReviewCMSPageEditControllerTest extends ContentReviewBaseTest
/**
* @var string
*/
public static $fixture_file = "contentreview/tests/ContentReviewTest.yml";
protected static $fixture_file = 'ContentReviewTest.yml';
/**
* @var array
*/
protected $requiredExtensions = array(
"SiteTree" => array("SiteTreeContentReview"),
"Group" => array("ContentReviewOwner"),
"Member" => array("ContentReviewOwner"),
"CMSPageEditController" => array("ContentReviewCMSExtension"),
"SiteConfig" => array("ContentReviewDefaultSettings"),
);
protected static $required_extensions = [
SiteTree::class => [SiteTreeContentReview::class],
Group::class => [ContentReviewOwner::class],
Member::class => [ContentReviewOwner::class],
CMSPageEditController::class => [ContentReviewCMSExtension::class],
SiteConfig::class => [ContentReviewDefaultSettings::class],
];
public function testReviewedThrowsExceptionWithNoRecordID()
{
$this->setExpectedException("SS_HTTPResponse_Exception");
$this->setExpectedException(HTTPResponse_Exception::class);
/** @var CMSPageEditController|ContentReviewCMSExtension $controller */
$controller = new CMSPageEditController();
$dummyForm = new CMSForm($controller, "EditForm", new FieldList(), new FieldList());
$dummyForm = new Form($controller, "EditForm", new FieldList(), new FieldList());
$controller->savereview(array(
"ID" => null,
@ -38,12 +55,12 @@ class ContentReviewCMSPageEditControllerTest extends ContentReviewBaseTest
public function testReviewedThrowsExceptionWithWrongRecordID()
{
$this->setExpectedException("SS_HTTPResponse_Exception");
$this->setExpectedException(HTTPResponse_Exception::class);
/** @var CMSPageEditController|ContentReviewCMSExtension $controller */
$controller = new CMSPageEditController();
$dummyForm = new CMSForm($controller, "EditForm", new FieldList(), new FieldList());
$dummyForm = new Form($controller, "EditForm", new FieldList(), new FieldList());
$controller->savereview(array(
"ID" => "FAIL",
@ -54,20 +71,20 @@ class ContentReviewCMSPageEditControllerTest extends ContentReviewBaseTest
public function testReviewedWithAuthor()
{
/** @var Member $author */
$author = $this->objFromFixture("Member", "author");
$author = $this->objFromFixture(Member::class, "author");
$this->loginAs($author);
$this->logInAs($author);
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "home");
$page = $this->objFromFixture(Page::class, "home");
$data = array(
"action_savereview" => 1,
"ID" => $page->ID,
"ID" => $page->ID,
);
$this->get('admin/pages/edit/show/' . $page->ID);
$response = $this->post(singleton('CMSPageEditController')->getEditForm($page->ID)->FormAction(), $data);
$response = $this->post($this->getFormAction($page), $data);
$this->assertEquals("OK", $response->getStatusDescription());
$this->assertEquals(200, $response->getStatusCode());
@ -76,21 +93,21 @@ class ContentReviewCMSPageEditControllerTest extends ContentReviewBaseTest
public function testSaveReview()
{
/** @var Member $author */
$author = $this->objFromFixture("Member", "author");
$author = $this->objFromFixture(Member::class, "author");
$this->loginAs($author);
$this->logInAs($author);
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "home");
$page = $this->objFromFixture(Page::class, "home");
$data = array(
"action_savereview" => 1,
"ID" => $page->ID,
"ReviewNotes" => "This is the best page ever",
"ID" => $page->ID,
"ReviewNotes" => "This is the best page ever",
);
$this->get('admin/pages/edit/show/' . $page->ID);
$response = $this->post(singleton('CMSPageEditController')->getEditForm($page->ID)->FormAction(), $data);
$response = $this->post($this->getFormAction($page), $data);
$this->assertEquals("OK", $response->getStatusDescription());
$this->assertEquals(200, $response->getStatusCode());
@ -100,4 +117,19 @@ class ContentReviewCMSPageEditControllerTest extends ContentReviewBaseTest
$this->assertEquals($data["ReviewNotes"], $reviewLog->Note);
}
/**
* Return a CMS page edit form action via using a dummy request and session
*
* @param Page $page
* @return string
*/
protected function getFormAction(Page $page)
{
$controller = singleton(CMSPageEditController::class);
$controller->setRequest(new HTTPRequest('GET', '/'));
$controller->getRequest()->setSession($this->session());
return $controller->getEditForm($page->ID)->FormAction();
}
}

View File

@ -1,5 +1,22 @@
<?php
namespace SilverStripe\ContentReview\Tests;
use Page;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\CMS\Controllers\CMSPageEditController;
use SilverStripe\ContentReview\Extensions\ContentReviewCMSExtension;
use SilverStripe\ContentReview\Extensions\ContentReviewDefaultSettings;
use SilverStripe\ContentReview\Extensions\ContentReviewOwner;
use SilverStripe\ContentReview\Extensions\SiteTreeContentReview;
use SilverStripe\ContentReview\Tasks\ContentReviewEmails;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\Security\Group;
use SilverStripe\Security\Member;
use SilverStripe\SiteConfig\SiteConfig;
/**
* @mixin PHPUnit_Framework_TestCase
*/
@ -8,14 +25,14 @@ class ContentReviewNotificationTest extends SapphireTest
/**
* @var string
*/
public static $fixture_file = 'contentreview/tests/ContentReviewTest.yml';
protected static $fixture_file = 'ContentReviewTest.yml';
public function setUp()
protected function setUp()
{
parent::setUp();
// Hack to ensure only desired siteconfig is scaffolded
$desiredID = $this->idFromFixture('SiteConfig', 'mysiteconfig');
$desiredID = $this->idFromFixture(SiteConfig::class, 'mysiteconfig');
foreach (SiteConfig::get()->exclude('ID', $desiredID) as $config) {
$config->delete();
}
@ -24,25 +41,25 @@ class ContentReviewNotificationTest extends SapphireTest
/**
* @var array
*/
protected $requiredExtensions = array(
'SiteTree' => array('SiteTreeContentReview'),
'Group' => array('ContentReviewOwner'),
'Member' => array('ContentReviewOwner'),
'CMSPageEditController' => array('ContentReviewCMSExtension'),
'SiteConfig' => array('ContentReviewDefaultSettings'),
);
protected static $required_extensions = [
SiteTree::class => [SiteTreeContentReview::class],
Group::class => [ContentReviewOwner::class],
Member::class => [ContentReviewOwner::class],
CMSPageEditController::class => [ContentReviewCMSExtension::class],
SiteConfig::class => [ContentReviewDefaultSettings::class],
];
public function testContentReviewEmails()
{
SS_Datetime::set_mock_now('2010-02-24 12:00:00');
DBDatetime::set_mock_now('2010-02-24 12:00:00');
/** @var Page|SiteTreeContentReview $childParentPage */
$childParentPage = $this->objFromFixture('Page', 'contact');
$childParentPage = $this->objFromFixture(Page::class, 'contact');
$childParentPage->NextReviewDate = '2010-02-23';
$childParentPage->write();
$task = new ContentReviewEmails();
$task->run(new SS_HTTPRequest('GET', '/dev/tasks/ContentReviewEmails'));
$task->run(new HTTPRequest('GET', '/dev/tasks/ContentReviewEmails'));
// Set template variables (as per variable case)
$ToEmail = 'author@example.com';
@ -54,12 +71,12 @@ class ContentReviewNotificationTest extends SapphireTest
$this->assertNotNull($email, "Email haven't been sent.");
$this->assertContains(
"<h1>$Subject</h1><p>There are $PagesCount pages that are due for review today by you, $ToFirstName.</p><p>This email was sent to $ToEmail</p>",
$email['htmlContent']
$email['HtmlContent']
);
$this->assertContains('Staff', $email['htmlContent']);
$this->assertContains('Contact Us', $email['htmlContent']);
$this->assertContains('Contact Us Child', $email['htmlContent']);
$this->assertContains('Staff', $email['HtmlContent']);
$this->assertContains('Contact Us', $email['HtmlContent']);
$this->assertContains('Contact Us Child', $email['HtmlContent']);
SS_Datetime::clear_mock_now();
DBDatetime::clear_mock_now();
}
}

View File

@ -1,27 +1,43 @@
<?php
namespace SilverStripe\ContentReview\Tests;
use SilverStripe\CMS\Controllers\CMSPageEditController;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\ContentReview\Extensions\ContentReviewCMSExtension;
use SilverStripe\ContentReview\Extensions\ContentReviewDefaultSettings;
use SilverStripe\ContentReview\Extensions\ContentReviewOwner;
use SilverStripe\ContentReview\Extensions\SiteTreeContentReview;
use SilverStripe\ContentReview\Reports\PagesDueForReviewReport;
use SilverStripe\ContentReview\Reports\PagesWithoutReviewScheduleReport;
use SilverStripe\Dev\FunctionalTest;
use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\Security\Group;
use SilverStripe\Security\Member;
use SilverStripe\SiteConfig\SiteConfig;
class ContentReviewReportTest extends FunctionalTest
{
/**
* @var string
*/
public static $fixture_file = "contentreview/tests/ContentReviewTest.yml";
protected static $fixture_file = 'ContentReviewTest.yml';
/**
* @var array
*/
protected $requiredExtensions = array(
"SiteTree" => array("SiteTreeContentReview"),
"Group" => array("ContentReviewOwner"),
"Member" => array("ContentReviewOwner"),
"CMSPageEditController" => array("ContentReviewCMSExtension"),
"SiteConfig" => array("ContentReviewDefaultSettings"),
);
protected static $required_extensions = [
SiteTree::class => [SiteTreeContentReview::class],
Group::class => [ContentReviewOwner::class],
Member::class => [ContentReviewOwner::class],
CMSPageEditController::class => [ContentReviewCMSExtension::class],
SiteConfig::class => [ContentReviewDefaultSettings::class],
];
public function testPagesDueForReviewReport()
{
/** @var Member $editor */
$editor = $this->objFromFixture("Member", "editor");
$editor = $this->objFromFixture(Member::class, "editor");
$this->logInAs($editor);
@ -32,8 +48,8 @@ class ContentReviewReportTest extends FunctionalTest
$report->title();
$results = $report->sourceRecords(array(
"ReviewDateAfter" => "01/01/2010",
"ReviewDateBefore" => "12/12/2010",
"ReviewDateAfter" => "2010-01-01",
"ReviewDateBefore" => "2010-12-12",
));
$this->assertEquals(array(
@ -44,7 +60,7 @@ class ContentReviewReportTest extends FunctionalTest
"Contact Us",
), $results->column("Title"));
SS_Datetime::set_mock_now("2010-02-13 00:00:00");
DBDatetime::set_mock_now("2010-02-13 00:00:00");
$results = $report->sourceRecords(array());
@ -53,13 +69,13 @@ class ContentReviewReportTest extends FunctionalTest
"About Us",
), $results->column("Title"));
SS_Datetime::clear_mock_now();
DBDatetime::clear_mock_now();
}
public function testPagesWithoutReviewScheduleReport()
{
/** @var Member $editor */
$editor = $this->objFromFixture("Member", "editor");
$editor = $this->objFromFixture(Member::class, "editor");
$this->logInAs($editor);

View File

@ -1,5 +1,22 @@
<?php
namespace SilverStripe\ContentReview\Tests;
use Page;
use SilverStripe\CMS\Controllers\CMSPageEditController;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\ContentReview\Extensions\ContentReviewCMSExtension;
use SilverStripe\ContentReview\Extensions\ContentReviewDefaultSettings;
use SilverStripe\ContentReview\Extensions\ContentReviewOwner;
use SilverStripe\ContentReview\Extensions\SiteTreeContentReview;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\FieldType\DBDate;
use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\Security\Group;
use SilverStripe\Security\Member;
use SilverStripe\SiteConfig\SiteConfig;
/**
* This class tests that settings are inherited correctly based on the inherited,
* custom or disabled settings.
@ -11,18 +28,18 @@ class ContentReviewSettingsTest extends SapphireTest
/**
* @var string
*/
public static $fixture_file = "contentreview/tests/ContentReviewSettingsTest.yml";
protected static $fixture_file = 'ContentReviewSettingsTest.yml';
/**
* @var array
*/
protected $requiredExtensions = array(
"SiteTree" => array("SiteTreeContentReview"),
"Group" => array("ContentReviewOwner"),
"Member" => array("ContentReviewOwner"),
"CMSPageEditController" => array("ContentReviewCMSExtension"),
"SiteConfig" => array("ContentReviewDefaultSettings"),
);
protected static $required_extensions = [
SiteTree::class => [SiteTreeContentReview::class],
Group::class => [ContentReviewOwner::class],
Member::class => [ContentReviewOwner::class],
CMSPageEditController::class => [ContentReviewCMSExtension::class],
SiteConfig::class => [ContentReviewDefaultSettings::class],
];
public function testAdvanceReviewDate10Days()
{
@ -36,7 +53,7 @@ class ContentReviewSettingsTest extends SapphireTest
$page->write();
$this->assertEquals(date("Y-m-d", strtotime("now + 10 days")), $page->NextReviewDate);
$this->assertEquals(date('Y-m-d', strtotime("now + 10 days")), $page->NextReviewDate);
}
public function testAdvanceReviewDateNull()
@ -57,51 +74,51 @@ class ContentReviewSettingsTest extends SapphireTest
public function testAdvanceReviewFromCustomSettings()
{
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "custom");
$page = $this->objFromFixture(Page::class, "custom");
$this->assertTrue($page->advanceReviewDate());
$page->write();
$this->assertEquals(date("Y-m-d", strtotime("now + " . $page->ReviewPeriodDays . " days")), $page->NextReviewDate);
$this->assertEquals(date('Y-m-d', strtotime("now + " . $page->ReviewPeriodDays . " days")), $page->NextReviewDate);
}
public function testAdvanceReviewFromInheritedSettings()
{
// When a parent page is advanced, the next review date of the child is not automatically advanced
$parentPage = $this->objFromFixture("Page", "page-1");
$parentPage = $this->objFromFixture(Page::class, "page-1");
$this->assertTrue($parentPage->advanceReviewDate());
$parentPage->write();
$page = $this->objFromFixture("Page", "page-1-1");
$this->assertEquals(date("Y-m-d", strtotime("now + 5 days")), $parentPage->NextReviewDate);
$page = $this->objFromFixture(Page::class, "page-1-1");
$this->assertEquals(date('Y-m-d', strtotime("now + 5 days")), $parentPage->NextReviewDate);
$this->assertEquals('2011-04-12', $page->NextReviewDate);
// When a sub page is advanced, the next review date is advanced by the number of days in the parent
$this->assertTrue($page->advanceReviewDate());
$page->write();
$this->assertEquals(date("Y-m-d", strtotime("now + 5 days")), $page->NextReviewDate);
$this->assertEquals(date('Y-m-d', strtotime("now + 5 days")), $page->NextReviewDate);
}
public function testAdvanceReviewFromInheritedSiteConfigSettings()
{
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "inherit");
$page = $this->objFromFixture(Page::class, "inherit");
/** @var SiteConfig|ContentReviewDefaultSettings $siteConfig */
$siteConfig = $this->objFromFixture("SiteConfig", "default");
$siteConfig = $this->objFromFixture(SiteConfig::class, "default");
$this->assertTrue($page->advanceReviewDate());
$page->write();
$this->assertEquals(date("Y-m-d", strtotime("now + " . $siteConfig->ReviewPeriodDays . " days")), $page->NextReviewDate);
$this->assertEquals(date('Y-m-d', strtotime("now + " . $siteConfig->ReviewPeriodDays . " days")), $page->NextReviewDate);
}
public function testGetSettingsObjectFromCustom()
{
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "custom");
$page = $this->objFromFixture(Page::class, "custom");
$this->assertEquals("Custom", $page->ContentReviewType);
$this->assertEquals($page, $page->getOptions());
@ -110,7 +127,7 @@ class ContentReviewSettingsTest extends SapphireTest
public function testGetSettingsObjectFromDisabled()
{
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "disabled");
$page = $this->objFromFixture(Page::class, "disabled");
$this->assertEquals("Disabled", $page->ContentReviewType);
$this->assertFalse($page->getOptions());
@ -119,7 +136,7 @@ class ContentReviewSettingsTest extends SapphireTest
public function testGetOptionObjectFromInheritedDisabled()
{
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "page-2-1-1");
$page = $this->objFromFixture(Page::class, "page-2-1-1");
$this->assertEquals("Inherit", $page->ContentReviewType);
$this->assertFalse($page->getOptions());
@ -128,19 +145,19 @@ class ContentReviewSettingsTest extends SapphireTest
public function testGetOptionObjectFromDeeplyInheritedPage()
{
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "page-3-1-1-1");
$page = $this->objFromFixture(Page::class, "page-3-1-1-1");
$this->assertEquals("Inherit", $page->ContentReviewType);
$this->assertInstanceOf("SiteConfig", $page->getOptions());
$this->assertInstanceOf(SiteConfig::class, $page->getOptions());
}
public function testGetSettingsObjectFromInheritPage()
{
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "page-1-1");
$page = $this->objFromFixture(Page::class, "page-1-1");
/** @var Page|SiteTreeContentReview $parentPage */
$parentPage = $this->objFromFixture("Page", "page-1");
$parentPage = $this->objFromFixture(Page::class, "page-1");
$this->assertEquals("Inherit", $page->ContentReviewType);
$this->assertEquals(get_class($parentPage), get_class($page->getOptions()));
@ -150,52 +167,52 @@ class ContentReviewSettingsTest extends SapphireTest
public function testGetSettingsObjectFromInheritedRootPage()
{
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "inherit");
$page = $this->objFromFixture(Page::class, "inherit");
$this->assertEquals("Inherit", $page->ContentReviewType);
$this->assertEquals($this->objFromFixture("SiteConfig", "default"), $page->getOptions());
$this->assertEquals($this->objFromFixture(SiteConfig::class, "default")->ID, $page->getOptions()->ID);
}
public function testGetNextReviewDateFromCustomSettings()
{
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture('Page', 'custom');
$page = $this->objFromFixture(Page::class, 'custom');
$date = $page->getReviewDate();
$this->assertEquals('2010-02-01', $date->format('Y-m-d'));
$this->assertEquals('2010-02-01', $date->format('Y-MM-dd'));
}
public function testGetNextReviewDateFromSiteConfigInheritedSetting()
{
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "inherit");
$page = $this->objFromFixture(Page::class, "inherit");
$nextReviewDate = $page->getReviewDate();
$this->assertInstanceOf("Date", $nextReviewDate);
$this->assertInstanceOf(DBDate::class, $nextReviewDate);
/** @var SiteConfig|ContentReviewDefaultSettings $siteConfig */
$siteConfig = $this->objFromFixture("SiteConfig", "default");
$siteConfig = $this->objFromFixture(SiteConfig::class, "default");
$expected = $this->addDaysToDate(SS_Datetime::now(), $siteConfig->ReviewPeriodDays);
$expected = $this->addDaysToDate(DBDatetime::now(), $siteConfig->ReviewPeriodDays);
$this->assertEquals($expected, $nextReviewDate->format("Y-m-d"));
$this->assertEquals($expected, $nextReviewDate->format('Y-MM-dd'));
}
public function testGetNextReviewDateFromPageInheritedSetting()
{
// Although page-1-1 inherits from page-1, it has an independent review date
$page = $this->objFromFixture("Page", "page-1-1");
$page = $this->objFromFixture(Page::class, "page-1-1");
$nextReviewDate = $page->getReviewDate();
$this->assertInstanceOf("Date", $nextReviewDate);
$this->assertEquals('2011-04-12', $nextReviewDate->format("Y-m-d"));
$this->assertInstanceOf(DBDate::class, $nextReviewDate);
$this->assertEquals('2011-04-12', $nextReviewDate->format('Y-MM-dd'));
}
public function testUpdateNextReviewDateFromCustomToDisabled()
{
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "custom");
$page = $this->objFromFixture(Page::class, "custom");
// before write()
$this->assertEquals("2010-02-01", $page->NextReviewDate);
@ -207,7 +224,7 @@ class ContentReviewSettingsTest extends SapphireTest
unset($page);
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "custom");
$page = $this->objFromFixture(Page::class, "custom");
$this->assertNull($page->NextReviewDate);
}
@ -215,7 +232,7 @@ class ContentReviewSettingsTest extends SapphireTest
public function testUpdateNextReviewDateFromDisabledToCustom()
{
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "disabled");
$page = $this->objFromFixture(Page::class, "disabled");
$this->assertNull($page->NextReviewDate);
@ -227,9 +244,9 @@ class ContentReviewSettingsTest extends SapphireTest
unset($page);
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "disabled");
$page = $this->objFromFixture(Page::class, "disabled");
$expected = date("Y-m-d", strtotime("+ " . $page->ReviewPeriodDays . " days"));
$expected = date('Y-m-d', strtotime("+ " . $page->ReviewPeriodDays . " days"));
$this->assertEquals($expected, $page->NextReviewDate);
}
@ -237,10 +254,10 @@ class ContentReviewSettingsTest extends SapphireTest
public function testParentChangedOptionsAndChildShouldToo()
{
/** @var Page|SiteTreeContentReview $parentPage */
$parentPage = $this->objFromFixture("Page", "page-1");
$parentPage = $this->objFromFixture(Page::class, "page-1");
/** @var Page|SiteTreeContentReview $childPage */
$childPage = $this->objFromFixture("Page", "page-1-1");
$childPage = $this->objFromFixture(Page::class, "page-1-1");
// Parent and child pages have different review dates
$this->assertNotEquals($parentPage->NextReviewDate, $childPage->NextReviewDate);
@ -253,36 +270,38 @@ class ContentReviewSettingsTest extends SapphireTest
DataObject::flush_and_destroy_cache();
/** @var Page|SiteTreeContentReview $page */
$parentPage = $this->objFromFixture("Page", "page-1");
$parentPage = $this->objFromFixture(Page::class, "page-1");
/** @var Page|SiteTreeContentReview $page */
$childPage = $this->objFromFixture("Page", "page-1-1");
$childPage = $this->objFromFixture(Page::class, "page-1-1");
// The parent page's date advances, but not the child's
$this->assertEquals('2011-04-12', $childPage->NextReviewDate);
$this->assertEquals($this->addDaysToDate(date("Y-m-d"), 10), $parentPage->NextReviewDate);
$this->assertEquals($this->addDaysToDate(date('Y-m-d'), 10), $parentPage->NextReviewDate);
// Reviewing the child page should, however, advance its review by 10 days
$childPage->advanceReviewDate();
$childPage->write();
$this->assertEquals($this->addDaysToDate(date("Y-m-d"), 10), $childPage->NextReviewDate);
$this->assertEquals($this->addDaysToDate(date('Y-m-d'), 10), $childPage->NextReviewDate);
}
/**
* @param string|SS_DateTime|DateTime $date
* @param int $days
* @param string $format
* Note: all input dates should be DBDatetime or strings in CLDR date format. See {@link DBDate} for information
*
* @param string|DBDatetime $date
* @param int $days
* @param string $format
*
* @return bool|string
*/
private function addDaysToDate($date, $days, $format = "Y-m-d")
private function addDaysToDate($date, $days, $format = 'Y-MM-dd')
{
if (is_object($date)) {
$sec = strtotime("+ " . $days . " days", $date->format("U"));
$sec = strtotime("+ " . $days . " days", $date->getTimestamp());
} else {
$sec = strtotime("+ " . $days . " days", strtotime($date));
$sec = strtotime("+ " . $days . " days", DBDate::create()->setValue($date)->getTimestamp());
}
return date($format, $sec);
return DBDate::create()->setValue($sec)->format($format);
}
}

View File

@ -1,4 +1,4 @@
Permission:
SilverStripe\Security\Permission:
cmsmain1:
Code: CMS_ACCESS_CMSMain
cmsmain2:
@ -10,46 +10,56 @@ Permission:
workflowadmin2:
Code: IS_WORKFLOW_ADMIN
Group:
SilverStripe\Security\Group:
webmastergroup:
Title: Edit existing pages
Code: editorgroup
Permissions: =>Permission.cmsmain1,=>Permission.workflowadmin1,=>Permission.setreviewdates
Permissions:
- =>SilverStripe\Security\Permission.cmsmain1
- =>SilverStripe\Security\Permission.workflowadmin1
- =>SilverStripe\Security\Permission.setreviewdates
editorgroup:
Title: Edit existing pages
Code: editorgroup
Permissions: =>Permission.cmsmain1,=>Permission.workflowadmin1,=>Permission.setreviewdates
Permissions:
- =>SilverStripe\Security\Permission.cmsmain1
- =>SilverStripe\Security\Permission.workflowadmin1
- =>SilverStripe\Security\Permission.setreviewdates
authorgroup:
Title: Author existing pages
Code: authorgroup
Permissions: =>Permission.cmsmain2,=>Permission.workflowadmin2
Permissions:
- =>SilverStripe\Security\Permission.cmsmain2
- =>SilverStripe\Security\Permission.workflowadmin2
Member:
SilverStripe\Security\Member:
webmaster:
FirstName: Web
Surname: Master
Email: webmaster@example.com
Groups: =>Group.webmastergroup
Groups: =>SilverStripe\Security\Group.webmastergroup
author:
FirstName: Test
Surname: Author
Email: author@example.com
Groups: =>Group.authorgroup
Groups: =>SilverStripe\Security\Group.authorgroup
editor:
FirstName: Test
Surname: Editor
Groups: =>Group.editorgroup
SiteConfig:
Groups: =>SilverStripe\Security\Group.editorgroup
SilverStripe\SiteConfig\SiteConfig:
default:
ContentReviewUsers: =>Member.webmaster
ContentReviewGroups: =>Group.webmastergroup
ContentReviewUsers: =>SilverStripe\Security\Member.webmaster
ContentReviewGroups: =>SilverStripe\Security\Group.webmastergroup
ReviewPeriodDays: 30
Page:
custom:
Title: custom
ContentReviewType: Custom
NextReviewDate: 2010-02-01
ContentReviewUsers: =>Member.editor
ContentReviewUsers: =>SilverStripe\Security\Member.editor
ReviewPeriodDays: 10
disabled:
Title: disabled
@ -89,7 +99,7 @@ Page:
page-3-1-1:
Title: page 3 1 1
ContentReviewType: Inherit
ParentID: =>Page.page-3-1
ParentID: =>Page.page-3-1
page-3-1-1-1:
Title: page 3 1 1 1
ContentReviewType: Inherit

View File

@ -1,10 +1,10 @@
SiteConfig:
SilverStripe\SiteConfig\SiteConfig:
mysiteconfig:
ReviewFrom: sender@silverstripe.com
ReviewSubject: 'Please log in to review some content!'
ReviewBody: '<h1>$Subject</h1><p>There are $PagesCount pages that are due for review today by you, $ToFirstName.</p><p>This email was sent to $ToEmail</p>'
Permission:
SilverStripe\Security\Permission:
cmsmain1:
Code: CMS_ACCESS_CMSMain
cmsmain2:
@ -16,39 +16,44 @@ Permission:
workflowadmin2:
Code: IS_WORKFLOW_ADMIN
Group:
SilverStripe\Security\Group:
editorgroup:
Title: Edit existing pages
Code: editorgroup
Permissions: =>Permission.cmsmain1,=>Permission.workflowadmin1,=>Permission.setreviewdates
Permissions:
- =>SilverStripe\Security\Permission.cmsmain1
- =>SilverStripe\Security\Permission.workflowadmin1
- =>SilverStripe\Security\Permission.setreviewdates
authorgroup:
Title: Author existing pages
Code: authorgroup
Permissions: =>Permission.cmsmain2,=>Permission.workflowadmin2
Permissions:
- =>SilverStripe\Security\Permission.cmsmain2
- =>SilverStripe\Security\Permission.workflowadmin2
Member:
SilverStripe\Security\Member:
author:
FirstName: Test
Surname: Author
Email: author@example.com
Groups: =>Group.authorgroup
Groups: =>SilverStripe\Security\Group.authorgroup
editor:
FirstName: Test
Surname: Editor
Groups: =>Group.editorgroup
Groups: =>SilverStripe\Security\Group.editorgroup
visitor:
FirstName: Kari
Surname: Visitor
Email: visitor@example.com
Page:
# Cant be reviewed, no owners
# Cant be reviewed, no owners
home:
Title: Home
ContentReviewType: Custom
NextReviewDate: 2010-02-01
ReviewPeriodDays: 10
# Cant be reviewed, no owners
# Cant be reviewed, no owners
about:
Title: About Us
ContentReviewType: Custom
@ -59,24 +64,24 @@ Page:
ContentReviewType: Custom
NextReviewDate: 2010-02-14
ReviewPeriodDays: 10
ContentReviewUsers: =>Member.author
ContentReviewUsers: =>SilverStripe\Security\Member.author
contact:
Title: Contact Us
ContentReviewType: Custom
ReviewPeriodDays: 10
NextReviewDate: 2010-02-21
ContentReviewGroups: =>Group.authorgroup
ContentReviewGroups: =>SilverStripe\Security\Group.authorgroup
contact-child:
Title: Contact Us Child
ContentReviewType: Inherit
ParentID: =>Page.contact
# Cant be reviewed, no NextReviewDate
# Cant be reviewed, no NextReviewDate
no-review:
Title: Page without review date
ContentReviewType: Custom
ContentReviewUsers: =>Member.author
# Cant be reviewed, no NextReviewDate
ContentReviewUsers: =>SilverStripe\Security\Member.author
# Cant be reviewed, no NextReviewDate
group-owned:
Title: Page owned by group
ContentReviewType: Custom
ContentReviewGroups: =>Group.authorgroup
ContentReviewGroups: =>SilverStripe\Security\Group.authorgroup

View File

@ -1,5 +1,20 @@
<?php
namespace SilverStripe\ContentReview\Tests;
use Page;
use SilverStripe\CMS\Controllers\CMSPageEditController;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\ContentReview\Extensions\SiteTreeContentReview;
use SilverStripe\ContentReview\Extensions\ContentReviewOwner;
use SilverStripe\ContentReview\Extensions\ContentReviewCMSExtension;
use SilverStripe\ContentReview\Extensions\ContentReviewDefaultSettings;
use SilverStripe\Security\Group;
use SilverStripe\Security\Member;
use SilverStripe\SiteConfig\SiteConfig;
use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\Versioned\Versioned;
/**
* @mixin PHPUnit_Framework_TestCase
*/
@ -8,23 +23,23 @@ class SiteTreeContentReviewTest extends ContentReviewBaseTest
/**
* @var string
*/
public static $fixture_file = "contentreview/tests/ContentReviewTest.yml";
protected static $fixture_file = 'ContentReviewTest.yml';
/**
* @var array
*/
protected $requiredExtensions = array(
"SiteTree" => array("SiteTreeContentReview"),
"Group" => array("ContentReviewOwner"),
"Member" => array("ContentReviewOwner"),
"CMSPageEditController" => array("ContentReviewCMSExtension"),
"SiteConfig" => array("ContentReviewDefaultSettings"),
);
protected static $required_extensions = [
SiteTree::class => [SiteTreeContentReview::class],
Group::class => [ContentReviewOwner::class],
Member::class => [ContentReviewOwner::class],
CMSPageEditController::class => [ContentReviewCMSExtension::class],
SiteConfig::class => [ContentReviewDefaultSettings::class],
];
public function testOwnerNames()
{
/** @var Member $editor */
$editor = $this->objFromFixture("Member", "editor");
$editor = $this->objFromFixture(Member::class, "editor");
$this->logInAs($editor);
@ -41,7 +56,7 @@ class SiteTreeContentReviewTest extends ContentReviewBaseTest
$this->assertEquals($page->OwnerNames, "Test Editor", "Test Editor should be the owner");
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "about");
$page = $this->objFromFixture(Page::class, "about");
$page->OwnerUsers()->removeAll();
$page->write();
@ -53,7 +68,7 @@ class SiteTreeContentReviewTest extends ContentReviewBaseTest
public function testPermissionsExists()
{
$perms = singleton("SiteTreeContentReview")->providePermissions();
$perms = singleton(SiteTreeContentReview::class)->providePermissions();
$this->assertTrue(isset($perms["EDIT_CONTENT_REVIEW_FIELDS"]));
}
@ -61,7 +76,7 @@ class SiteTreeContentReviewTest extends ContentReviewBaseTest
public function testUserWithPermissionCanEdit()
{
/** @var Member $editor */
$editor = $this->objFromFixture("Member", "editor");
$editor = $this->objFromFixture(Member::class, "editor");
$this->logInAs($editor);
@ -76,7 +91,7 @@ class SiteTreeContentReviewTest extends ContentReviewBaseTest
public function testUserWithoutPermissionCannotEdit()
{
/** @var Member $author */
$author = $this->objFromFixture("Member", "author");
$author = $this->objFromFixture(Member::class, "author");
$this->logInAs($author);
@ -91,7 +106,7 @@ class SiteTreeContentReviewTest extends ContentReviewBaseTest
public function testAutomaticallyToNotSetReviewDate()
{
/** @var Member $editor */
$editor = $this->objFromFixture("Member", "editor");
$editor = $this->objFromFixture(Member::class, "editor");
$this->logInAs($editor);
@ -108,15 +123,15 @@ class SiteTreeContentReviewTest extends ContentReviewBaseTest
public function testAddReviewNote()
{
/** @var Member $author */
$author = $this->objFromFixture("Member", "author");
$author = $this->objFromFixture(Member::class, "author");
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "home");
$page = $this->objFromFixture(Page::class, "home");
$page->addReviewNote($author, "This is a message");
/** @var Page|SiteTreeContentReview $page */
$homepage = $this->objFromFixture("Page", "home");
$homepage = $this->objFromFixture(Page::class, "home");
$this->assertEquals(1, $homepage->ReviewLogs()->count());
$this->assertEquals("This is a message", $homepage->ReviewLogs()->first()->Note);
@ -125,7 +140,7 @@ class SiteTreeContentReviewTest extends ContentReviewBaseTest
public function testGetContentReviewOwners()
{
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "group-owned");
$page = $this->objFromFixture(Page::class, "group-owned");
$owners = $page->ContentReviewOwners();
@ -135,134 +150,135 @@ class SiteTreeContentReviewTest extends ContentReviewBaseTest
public function testCanNotBeReviewBecauseNoReviewDate()
{
SS_Datetime::set_mock_now("2010-01-01 12:00:00");
DBDatetime::set_mock_now("2010-01-01 12:00:00");
/** @var Member $author */
$author = $this->objFromFixture("Member", "author");
$author = $this->objFromFixture(Member::class, "author");
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "no-review");
$page = $this->objFromFixture(Page::class, "no-review");
$this->assertFalse($page->canBeReviewedBy($author));
SS_Datetime::clear_mock_now();
DBDatetime::clear_mock_now();
}
public function testCanNotBeReviewedBecauseInFuture()
{
SS_Datetime::set_mock_now("2010-01-01 12:00:00");
DBDatetime::set_mock_now("2010-01-01 12:00:00");
/** @var Member $author */
$author = $this->objFromFixture("Member", "author");
$author = $this->objFromFixture(Member::class, "author");
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "staff");
$page = $this->objFromFixture(Page::class, "staff");
$this->assertFalse($page->canBeReviewedBy($author));
SS_Datetime::clear_mock_now();
DBDatetime::clear_mock_now();
}
public function testCanNotBeReviewedByUser()
{
SS_Datetime::set_mock_now("2010-03-01 12:00:00");
DBDatetime::set_mock_now("2010-03-01 12:00:00");
/** @var Member $author */
$author = $this->objFromFixture("Member", "author");
$author = $this->objFromFixture(Member::class, "author");
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "home");
$page = $this->objFromFixture(Page::class, "home");
$this->assertFalse($page->canBeReviewedBy($author));
SS_Datetime::clear_mock_now();
DBDatetime::clear_mock_now();
}
public function testCanBeReviewedByUser()
{
SS_Datetime::set_mock_now("2010-03-01 12:00:00");
DBDatetime::set_mock_now("2010-03-01 12:00:00");
/** @var Member $author */
$author = $this->objFromFixture("Member", "author");
$author = $this->objFromFixture(Member::class, "author");
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "staff");
$page = $this->objFromFixture(Page::class, "staff");
$this->assertTrue($page->canBeReviewedBy($author));
SS_Datetime::clear_mock_now();
DBDatetime::clear_mock_now();
}
public function testCanNotBeReviewedByGroup()
{
SS_Datetime::set_mock_now("2010-03-01 12:00:00");
DBDatetime::set_mock_now("2010-03-01 12:00:00");
/** @var Member $author */
$author = $this->objFromFixture("Member", "editor");
$author = $this->objFromFixture(Member::class, "editor");
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "contact");
$page = $this->objFromFixture(Page::class, "contact");
$this->assertFalse($page->canBeReviewedBy($author));
SS_Datetime::clear_mock_now();
DBDatetime::clear_mock_now();
}
public function testCanBeReviewedByGroup()
{
SS_Datetime::set_mock_now("2010-03-01 12:00:00");
DBDatetime::set_mock_now("2010-03-01 12:00:00");
/** @var Member $author */
$author = $this->objFromFixture("Member", "author");
$author = $this->objFromFixture(Member::class, "author");
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "contact");
$page = $this->objFromFixture(Page::class, "contact");
$this->assertTrue($page->canBeReviewedBy($author));
SS_Datetime::clear_mock_now();
DBDatetime::clear_mock_now();
}
public function testCanBeReviewedFromInheritedSetting()
{
SS_Datetime::set_mock_now("2013-03-01 12:00:00");
DBDatetime::set_mock_now("2013-03-01 12:00:00");
/** @var Member $author */
$author = $this->objFromFixture("Member", "author");
$author = $this->objFromFixture(Member::class, "author");
/** @var Page|SiteTreeContentReview $parentPage */
$parentPage = $this->objFromFixture("Page", "contact");
$parentPage = $this->objFromFixture(Page::class, "contact");
$parentPage->NextReviewDate = "2013-01-01";
$parentPage->write();
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "contact-child");
$page = $this->objFromFixture(Page::class, "contact-child");
$this->assertTrue($page->canBeReviewedBy($author));
SS_Datetime::clear_mock_now();
DBDatetime::clear_mock_now();
}
public function testUnModifiedPagesDontChangeEditor() {
SS_Datetime::set_mock_now("2013-03-01 12:00:00");
public function testUnModifiedPagesDontChangeEditor()
{
DBDatetime::set_mock_now("2013-03-01 12:00:00");
/** @var Member $author */
$author = $this->objFromFixture("Member", "author");
$author = $this->objFromFixture(Member::class, "author");
$this->logInAs($author);
// Page which is un-modified doesn't advance version of have an editor assigned
$contactPage = $this->objFromFixture("Page", "contact");
$contactPage = $this->objFromFixture(Page::class, "contact");
$contactPageVersion = $contactPage->Version;
$contactPage->write();
$this->assertEmpty($contactPage->LastEditedByName);
$this->assertEquals(
$contactPageVersion,
Versioned::get_versionnumber_by_stage('SiteTree', 'Stage', $contactPage->ID, false)
Versioned::get_versionnumber_by_stage(SiteTree::class, 'Stage', $contactPage->ID, false)
);
// Page with modifications gets marked
$homePage = $this->objFromFixture("Page", "home");
$homePage = $this->objFromFixture(Page::class, "home");
$homePageVersion = $homePage->Version;
$homePage->Content = '<p>Welcome!</p>';
$homePage->write();
@ -270,21 +286,21 @@ class SiteTreeContentReviewTest extends ContentReviewBaseTest
$this->assertEquals($author->getTitle(), $homePage->LastEditedByName);
$this->assertGreaterThan(
$homePageVersion,
Versioned::get_versionnumber_by_stage('SiteTree', 'Stage', $homePage->ID, false)
Versioned::get_versionnumber_by_stage(SiteTree::class, 'Stage', $homePage->ID, false)
);
SS_Datetime::clear_mock_now();
DBDatetime::clear_mock_now();
}
public function testReviewActionVisibleForAuthor()
{
SS_Datetime::set_mock_now("2020-03-01 12:00:00");
DBDatetime::set_mock_now("2020-03-01 12:00:00");
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "contact");
$page = $this->objFromFixture(Page::class, "contact");
/** @var Member $author */
$author = $this->objFromFixture("Member", "author");
$author = $this->objFromFixture(Member::class, "author");
$this->logInAs($author);
@ -292,18 +308,18 @@ class SiteTreeContentReviewTest extends ContentReviewBaseTest
$this->assertNotNull($fields->fieldByName("ActionMenus.ReviewContent"));
SS_Datetime::clear_mock_now();
DBDatetime::clear_mock_now();
}
public function testReviewActionNotVisibleForEditor()
{
SS_Datetime::set_mock_now("2020-03-01 12:00:00");
DBDatetime::set_mock_now("2020-03-01 12:00:00");
/** @var Page|SiteTreeContentReview $page */
$page = $this->objFromFixture("Page", "contact");
$page = $this->objFromFixture(Page::class, "contact");
/** @var Member $author */
$author = $this->objFromFixture("Member", "editor");
$author = $this->objFromFixture(Member::class, "editor");
$this->logInAs($author);
@ -311,6 +327,6 @@ class SiteTreeContentReviewTest extends ContentReviewBaseTest
$this->assertNull($fields->fieldByName("ActionMenus.ReviewContent"));
SS_Datetime::clear_mock_now();
DBDatetime::clear_mock_now();
}
}