diff --git a/.travis.yml b/.travis.yml
index 2cd44a1..0a95617 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -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
diff --git a/.upgrade.yml b/.upgrade.yml
new file mode 100644
index 0000000..6e73518
--- /dev/null
+++ b/.upgrade.yml
@@ -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
diff --git a/_config/config.yml b/_config/config.yml
index fe226a2..120f2eb 100644
--- a/_config/config.yml
+++ b/_config/config.yml
@@ -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
\ No newline at end of file
+ - SilverStripe\ContentReview\Extensions\ContentReviewDefaultSettings
diff --git a/_config/legacy.yml b/_config/legacy.yml
new file mode 100644
index 0000000..8db290e
--- /dev/null
+++ b/_config/legacy.yml
@@ -0,0 +1,6 @@
+---
+Name: contentreviewlegacy
+---
+SilverStripe\ORM\DatabaseAdmin:
+ classname_value_remapping:
+ ContentReviewLog: SilverStripe\ContentReview\Models\ContentReviewLog
diff --git a/codecov.yml b/codecov.yml
new file mode 100644
index 0000000..69cb760
--- /dev/null
+++ b/codecov.yml
@@ -0,0 +1 @@
+comment: false
diff --git a/composer.json b/composer.json
index e0e46c0..0966918 100644
--- a/composer.json
+++ b/composer.json
@@ -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
}
diff --git a/license.md b/license.md
index 9445c8e..8794670 100644
--- a/license.md
+++ b/license.md
@@ -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:
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 0000000..130037b
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,13 @@
+
+
+ tests/
+
+
+
+ src/
+
+ tests/
+
+
+
+
diff --git a/readme.md b/readme.md
index a797eda..dafc75b 100644
--- a/readme.md
+++ b/readme.md
@@ -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
diff --git a/code/compatability/ContentReviewCompatability.php b/src/Compatibility/ContentReviewCompatability.php
similarity index 78%
rename from code/compatability/ContentReviewCompatability.php
rename to src/Compatibility/ContentReviewCompatability.php
index 8c9cc92..7346995 100644
--- a/code/compatability/ContentReviewCompatability.php
+++ b/src/Compatibility/ContentReviewCompatability.php
@@ -1,5 +1,12 @@
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]);
}
}
diff --git a/code/extensions/ContentReviewCMSExtension.php b/src/Extensions/ContentReviewCMSExtension.php
similarity index 63%
rename from code/extensions/ContentReviewCMSExtension.php
rename to src/Extensions/ContentReviewCMSExtension.php
index c22b565..9b2095c 100644
--- a/code/extensions/ContentReviewCMSExtension.php
+++ b/src/Extensions/ContentReviewCMSExtension.php
@@ -1,5 +1,14 @@
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;
diff --git a/code/extensions/ContentReviewDefaultSettings.php b/src/Extensions/ContentReviewDefaultSettings.php
similarity index 86%
rename from code/extensions/ContentReviewDefaultSettings.php
rename to src/Extensions/ContentReviewDefaultSettings.php
index 969b229..b74063b 100644
--- a/code/extensions/ContentReviewDefaultSettings.php
+++ b/src/Extensions/ContentReviewDefaultSettings.php
@@ -1,5 +1,20 @@
'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];
}
diff --git a/code/extensions/ContentReviewOwner.php b/src/Extensions/ContentReviewOwner.php
similarity index 51%
rename from code/extensions/ContentReviewOwner.php
rename to src/Extensions/ContentReviewOwner.php
index bbf31ba..101dc65 100644
--- a/code/extensions/ContentReviewOwner.php
+++ b/src/Extensions/ContentReviewOwner.php
@@ -1,5 +1,10 @@
"SiteTree",
+ "SiteTreeContentReview" => SiteTree::class,
);
}
diff --git a/code/extensions/SiteTreeContentReview.php b/src/Extensions/SiteTreeContentReview.php
similarity index 81%
rename from code/extensions/SiteTreeContentReview.php
rename to src/Extensions/SiteTreeContentReview.php
index 621eae9..5876736 100644
--- a/code/extensions/SiteTreeContentReview.php
+++ b/src/Extensions/SiteTreeContentReview.php
@@ -1,5 +1,46 @@
"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
);
diff --git a/code/jobs/ContentReviewNotificationJob.php b/src/Jobs/ContentReviewNotificationJob.php
similarity index 82%
rename from code/jobs/ContentReviewNotificationJob.php
rename to src/Jobs/ContentReviewNotificationJob.php
index c884b0c..fae3a3b 100644
--- a/code/jobs/ContentReviewNotificationJob.php
+++ b/src/Jobs/ContentReviewNotificationJob.php
@@ -1,6 +1,15 @@
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)
);
diff --git a/code/models/ContentReviewLog.php b/src/Models/ContentReviewLog.php
similarity index 65%
rename from code/models/ContentReviewLog.php
rename to src/Models/ContentReviewLog.php
index 4c890c8..a3b7397 100644
--- a/code/models/ContentReviewLog.php
+++ b/src/Models/ContentReviewLog.php
@@ -1,5 +1,12 @@
"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();
}
}
diff --git a/code/reports/PagesDueForReviewReport.php b/src/Reports/PagesDueForReviewReport.php
similarity index 60%
rename from code/reports/PagesDueForReviewReport.php
rename to src/Reports/PagesDueForReviewReport.php
index acfdaef..52d109f 100644
--- a/code/reports/PagesDueForReviewReport.php
+++ b/src/Reports/PagesDueForReviewReport.php
@@ -1,11 +1,29 @@
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 %s",
+ return sprintf(
+ "%s %s",
$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();
diff --git a/code/reports/PagesWithoutReviewScheduleReport.php b/src/Reports/PagesWithoutReviewScheduleReport.php
similarity index 79%
rename from code/reports/PagesWithoutReviewScheduleReport.php
rename to src/Reports/PagesWithoutReviewScheduleReport.php
index 8dbae9b..36a9c57 100644
--- a/code/reports/PagesWithoutReviewScheduleReport.php
+++ b/src/Reports/PagesWithoutReviewScheduleReport.php
@@ -1,11 +1,24 @@
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 %s",
+ return sprintf(
+ "%s %s",
$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);
diff --git a/code/tasks/ContentReviewEmails.php b/src/Tasks/ContentReviewEmails.php
similarity index 71%
rename from code/tasks/ContentReviewEmails.php
rename to src/Tasks/ContentReviewEmails.php
index 11fb08f..9b82dd2 100644
--- a/code/tasks/ContentReviewEmails.php
+++ b/src/Tasks/ContentReviewEmails.php
@@ -1,12 +1,28 @@
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,
- );
+ ];
}
}
diff --git a/code/tasks/ContentReviewOwnerMigrationTask.php b/src/Tasks/ContentReviewOwnerMigrationTask.php
similarity index 80%
rename from code/tasks/ContentReviewOwnerMigrationTask.php
rename to src/Tasks/ContentReviewOwnerMigrationTask.php
index f0c8029..f3536b6 100644
--- a/code/tasks/ContentReviewOwnerMigrationTask.php
+++ b/src/Tasks/ContentReviewOwnerMigrationTask.php
@@ -1,12 +1,18 @@
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 "
Migrated 3 tables. Dropped obsolete OwnerID column
";
}
}
diff --git a/templates/ContentReviewAdminHelp.ss b/templates/SilverStripe/ContentReview/ContentReviewAdminHelp.ss
similarity index 100%
rename from templates/ContentReviewAdminHelp.ss
rename to templates/SilverStripe/ContentReview/ContentReviewAdminHelp.ss
diff --git a/templates/ContentReviewEmail.ss b/templates/SilverStripe/ContentReview/ContentReviewEmail.ss
similarity index 60%
rename from templates/ContentReviewEmail.ss
rename to templates/SilverStripe/ContentReview/ContentReviewEmail.ss
index 6b45554..bdfb389 100644
--- a/templates/ContentReviewEmail.ss
+++ b/templates/SilverStripe/ContentReview/ContentReviewEmail.ss
@@ -9,15 +9,15 @@
$EmailBody
- <% loop Pages %>
+ <% loop $Pages %>
$Title |
- <% _t('ContentReviewEmails.REVIEWPAGELINK','Review the page in the CMS') %>
- <% _t('ContentReviewEmails.VIEWPUBLISHEDLINK','View this page on the website') %>
+ | <%t ContentReviewEmails.REVIEWPAGELINK 'Review the page in the CMS' %>
+ <%t ContentReviewEmails.VIEWPUBLISHEDLINK 'View this page on the website' %>
|
<% end_loop %>