Adding content reviewed actions to a sitetree

This commit is contained in:
Stig Lindqvist 2014-02-14 14:49:43 +13:00
parent 131d643a8c
commit ae440666a0
7 changed files with 196 additions and 4 deletions

View File

@ -6,4 +6,7 @@ Group:
- ContentReviewOwner
Member:
extensions:
- ContentReviewOwner
- ContentReviewOwner
CMSPageEditController:
extensions:
- ContentReviewCMSPageEditController

View File

@ -52,6 +52,14 @@ class ContentReviewEmails extends BuildTask {
"LiveSiteLink" => Controller::join_links($page->Link(), "?stage=Live"),
));
$email->send();
$message = '<strong>'._t('ContentReviewEmails.EMAIL_HEADING','Page due for review').'</strong><br/>'.
'The page "'.$page->Title.'" is due for review today by you.<br/>
<a href="admin/pages/edit/show/'.$page->ID.'">'. _t('ContentReviewEmails.REVIEWPAGELINK','Review the page in the CMS') .'</a> &mdash;
<a href="#">'. _t('ContentReviewEmails.VIEWPUBLISHEDLINK','View this page on the website') .'</a>';
if(class_exists('Notification')) {
Notification::notify($recipient, $message);
}
}
}
}

View File

@ -49,7 +49,7 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
* @return string
*/
public function getEditorName() {
if( $member = Member::currentUser() ) {
if($member = Member::currentUser()) {
return $member->FirstName .' '. $member->Surname;
}
return NULL;
@ -163,15 +163,55 @@ class SiteTreeContentReview extends DataExtension implements PermissionProvider
)
)->setDescription(_t('ContentReview.REVIEWFREQUENCYDESCRIPTION', 'The review date will be set to this far in the future whenever the page is published'));
$notesField = TextareaField::create('ReviewNotes', 'Review Notes');
$fields->addFieldsToTab("Root.Review", array(
new HeaderField(_t('ContentReview.REVIEWHEADER', "Content review"), 2),
$userField,
$groupField,
$reviewDate,
$reviewFrequency,
new TextareaField('ReviewNotes', 'Review Notes')
$notesField
));
}
/**
*
* @param \FieldList $actions
*/
public function updateCMSActions(\FieldList $actions) {
if($this->canBeReviewedBy(Member::currentUser())) {
$reviewAction = FormAction::create('reviewed', _t('ContentReview.BUTTONREVIEWED', 'Content reviewed'))
->setAttribute('data-icon', 'pencil')
->setAttribute('data-text-alternate', _t('ContentReview.BUTTONREVIEWED', 'Content reviewed'));
$actions->push($reviewAction);
}
}
/**
* Check if a review is due by a member for this owner
*
* @param Member $member
* @return boolean
*/
public function canBeReviewedBy(Member $member) {
if(!$this->owner->obj('NextReviewDate')->exists()) {
return false;
}
if($this->owner->obj('NextReviewDate')->InFuture()) {
return false;
}
if($this->DirectGroups()->count() == 0 && $this->DirectUsers()->count() == 0) {
return false;
}
if($member->inGroups($this->DirectGroups())) {
return true;
}
if($this->DirectUsers()->find('ID', $member->ID)) {
return true;
}
return false;
}
/**
* Set the review data from the review period, if set.

View File

@ -0,0 +1,81 @@
<?php
/**
* CMSPageEditController extension to recieve the additonal action button from
* SiteTreeContentReview::updateCMSActions()
*
*/
class ContentReviewCMSPageEditController extends LeftAndMainExtension {
/**
*
* @var array
*/
private static $allowed_actions = array(
'reviewed',
'save_review',
);
/**
* Shows a form with review notes
*
* @param array $data
* @param Form $form
* @return SS_HTTPResponse
*/
public function reviewed($data, Form $form) {
if(!isset($data['ID'])) {
throw new SS_HTTPResponse_Exception("No record ID", 404);
}
$SQL_id = Convert::raw2sql($data['ID']);
$record = SiteTree::get()->byID($SQL_id);
if($record && !$record->canEdit()) {
return Security::permissionFailure($this);
}
if(!$record || !$record->ID) {
throw new SS_HTTPResponse_Exception("Bad record ID #$SQL_id", 404);
}
$fields = new FieldList();
$fields->push(HiddenField::create('ID', 'ID', $SQL_id));
$fields->push(TextareaField::create('ReviewNotes', 'Review notes'));
$actions = new FieldList(
FormAction::create('save_review', 'Save')
);
$form = CMSForm::create($this->owner, "EditForm", $fields, $actions)->setHTMLID('Form_EditForm');
$form->setResponseNegotiator($this->owner->getResponseNegotiator());
$form->loadDataFrom($record);
$form->disableDefaultAction();
// TODO Can't merge $FormAttributes in template at the moment
$form->setTemplate($this->owner->getTemplatesWithSuffix('LeftAndMain_EditForm'));
return $form->forTemplate();
}
/**
* Save the review notes and redirect back to the page edit form
*
* @param array $data
* @param Form $form
* @return string - html
*/
public function save_review($data, Form $form) {
if(!isset($data['ID'])) {
throw new SS_HTTPResponse_Exception("No record ID", 404);
}
$SQL_id = Convert::raw2sql($data['ID']);
$record = SiteTree::get()->byID($SQL_id);
if($record && !$record->canEdit()) {
return Security::permissionFailure($this);
}
if(!$record || !$record->ID) {
throw new SS_HTTPResponse_Exception("Bad record ID #$SQL_id", 404);
}
$record->ReviewNotes = $data['ReviewNotes'];
$record->write();
return $this->owner->redirect($this->owner->Link('show/'.$SQL_id));
}
}

View File

@ -0,0 +1,8 @@
/*jslint browser: true, nomen: true, white: true */ /*global $, jQuery*/
jQuery(function($) {
"use strict";
$.entwine('ss', function($) {
});
});

View File

@ -102,4 +102,52 @@ class ContentReviewTest extends FunctionalTest {
$this->assertTrue($page->doPublish());
$this->assertEquals('', $page->OwnerNames);
}
public function testCanNotBeReviewBecauseNoReviewDate() {
SS_Datetime::set_mock_now('2010-01-01 12:00:00');
$author = $this->objFromFixture('Member', 'author');
$page = $this->objFromFixture('Page', 'no-review');
// page 'no-review' is owned by author, but there is no review date
$this->assertFalse($page->canBeReviewedBy($author));
}
public function testCanNotBeReviewedBecauseInFuture() {
SS_Datetime::set_mock_now('2010-01-01 12:00:00');
$author = $this->objFromFixture('Member', 'author');
$page = $this->objFromFixture('Page', 'staff');
// page 'staff' is owned by author, but the review date is in the future
$this->assertFalse($page->canBeReviewedBy($author));
}
public function testCanNotBeReviewedByUser() {
SS_Datetime::set_mock_now('2010-03-01 12:00:00');
$author = $this->objFromFixture('Member', 'author');
$page = $this->objFromFixture('Page', 'home');
// page 'home' doesnt have any owners
$this->assertFalse($page->canBeReviewedBy($author));
}
public function testCanBeReviewedByUser() {
SS_Datetime::set_mock_now('2010-03-01 12:00:00');
$author = $this->objFromFixture('Member', 'author');
$page = $this->objFromFixture('Page', 'staff');
// page 'staff' is owned by author
$this->assertTrue($page->canBeReviewedBy($author));
}
public function testCanNotBeReviewedByGroup() {
SS_Datetime::set_mock_now('2010-03-01 12:00:00');
$author = $this->objFromFixture('Member', 'editor');
$page = $this->objFromFixture('Page', 'contact');
// page 'contact' is owned by the authorgroup
$this->assertFalse($page->canBeReviewedBy($author));
}
public function testCanBeReviewedByGroup() {
SS_Datetime::set_mock_now('2010-03-01 12:00:00');
$author = $this->objFromFixture('Member', 'author');
$page = $this->objFromFixture('Page', 'contact');
// page 'contact' is owned by the authorgroup
$this->assertTrue($page->canBeReviewedBy($author));
}
}

View File

@ -45,4 +45,8 @@ Page:
ContentReviewUsers: =>Member.author
contact:
Title: Contact Us
NextReviewDate: 2010-02-21
NextReviewDate: 2010-02-21
ContentReviewGroups: =>Group.authorgroup
no-review:
Title: Page without review date
ContentReviewUsers: =>Member.author