2009-11-02 05:02:57 +01:00
< ? php
/**
* Set dates at which content needs to be reviewed and provide
* a report and emails to alert to content needing review
*
* @ package contentreview
*/
2012-07-10 18:36:05 +02:00
class SiteTreeContentReview extends DataExtension implements PermissionProvider {
2010-07-20 05:51:15 +02:00
2014-02-13 02:07:39 +01:00
/**
*
* @ var array
*/
2013-09-23 07:56:29 +02:00
private static $db = array (
2012-07-10 18:36:05 +02:00
" ReviewPeriodDays " => " Int " ,
" NextReviewDate " => " Date " ,
'LastEditedByName' => 'Varchar(255)' ,
'OwnerNames' => 'Varchar(255)'
);
2014-02-18 03:39:13 +01:00
/**
*
* @ var array
*/
private static $has_many = array (
'ReviewLogs' => 'ContentReviewLog'
);
2012-07-10 18:36:05 +02:00
2014-02-13 02:07:39 +01:00
/**
*
* @ var array
*/
2014-02-13 04:35:13 +01:00
private static $belongs_many_many = array (
'ContentReviewGroups' => 'Group' ,
'ContentReviewUsers' => 'Member'
2012-07-10 18:36:05 +02:00
);
2014-02-13 04:35:13 +01:00
2014-02-19 02:31:47 +01:00
/**
*
* @ var array
*/
private $daysToString = array (
0 => " No automatic review date " ,
1 => " 1 day " ,
7 => " 1 week " ,
30 => " 1 month " ,
60 => " 2 months " ,
91 => " 3 months " ,
121 => " 4 months " ,
152 => " 5 months " ,
183 => " 6 months " ,
365 => " 12 months " ,
);
2014-02-13 02:07:39 +01:00
/**
*
* @ return string
*/
2014-02-13 04:35:13 +01:00
public function getOwnerNames () {
$names = array ();
2014-02-18 03:39:13 +01:00
foreach ( $this -> OwnerGroups () as $group ) {
2014-02-19 02:31:47 +01:00
$names [] = $group -> getBreadcrumbs ( ' > ' );
2014-02-13 04:35:13 +01:00
}
2014-02-18 03:39:13 +01:00
foreach ( $this -> OwnerUsers () as $group ) {
2014-02-13 04:35:13 +01:00
$names [] = $group -> getName ();
2014-02-13 02:07:39 +01:00
}
2014-02-13 04:35:13 +01:00
return implode ( ', ' , $names );
2009-11-02 05:02:57 +01:00
}
2010-07-20 05:51:15 +02:00
2014-02-13 02:07:39 +01:00
/**
*
* @ return string
*/
public function getEditorName () {
2014-02-14 02:49:43 +01:00
if ( $member = Member :: currentUser ()) {
2010-07-20 05:51:15 +02:00
return $member -> FirstName . ' ' . $member -> Surname ;
}
return NULL ;
}
2014-02-13 04:35:13 +01:00
/**
* Get all Members that are Content Owners to this page
*
* This includes checking group hierarchy and adding any direct users
*
* @ return \ArrayList
*/
public function ContentReviewOwners () {
$contentReviewOwners = new ArrayList ();
2014-02-18 03:39:13 +01:00
$toplevelGroups = $this -> OwnerGroups ();
if ( $toplevelGroups -> count ()) {
2014-02-13 04:35:13 +01:00
$groupIDs = array ();
foreach ( $toplevelGroups as $group ) {
$familyIDs = $group -> collateFamilyIDs ();
if ( is_array ( $familyIDs )) {
$groupIDs = array_merge ( $groupIDs , array_values ( $familyIDs ));
}
}
2014-02-18 03:39:13 +01:00
array_unique ( $groupIDs );
2014-02-13 04:35:13 +01:00
if ( count ( $groupIDs )) {
$groupMembers = DataObject :: get ( 'Member' ) -> where ( " \" Group \" . \" ID \" IN ( " . implode ( " , " , $groupIDs ) . " ) " )
-> leftJoin ( " Group_Members " , " \" Member \" . \" ID \" = \" Group_Members \" . \" MemberID \" " )
-> leftJoin ( " Group " , " \" Group_Members \" . \" GroupID \" = \" Group \" . \" ID \" " );
$contentReviewOwners -> merge ( $groupMembers );
}
}
2014-02-18 03:39:13 +01:00
$contentReviewOwners -> merge ( $this -> OwnerUsers ());
2014-02-13 04:35:13 +01:00
$contentReviewOwners -> removeDuplicates ();
return $contentReviewOwners ;
}
/**
* @ return ManyManyList
*/
2014-02-18 03:39:13 +01:00
public function OwnerGroups () {
2014-02-13 04:35:13 +01:00
return $this -> owner -> getManyManyComponents ( 'ContentReviewGroups' );
}
/**
* @ return ManyManyList
*/
2014-02-18 03:39:13 +01:00
public function OwnerUsers () {
2014-02-13 04:35:13 +01:00
return $this -> owner -> getManyManyComponents ( 'ContentReviewUsers' );
}
2010-07-20 05:51:15 +02:00
2014-02-13 02:07:39 +01:00
/**
*
* @ param FieldList $fields
* @ return void
*/
2014-02-19 02:31:47 +01:00
public function updateSettingsFields ( FieldList $fields ) {
$crFields = new FieldList ();
// Display read-only version only
2014-02-13 04:35:13 +01:00
if ( ! Permission :: check ( " EDIT_CONTENT_REVIEW_FIELDS " )) {
2014-02-19 02:31:47 +01:00
$contentOwners = ReadonlyField :: create ( 'ROContentOwners' , _t ( 'ContentReview.CONTENTOWNERS' , 'Content Owners' ), $this -> getOwnerNames ());
$nextReviewAt = DateField :: create ( 'RONextReviewDate' , _t ( " ContentReview.NEXTREVIEWDATE " , " Next review date " ), $this -> owner -> NextReviewDate );
if ( ! isset ( $this -> daysToString [ $this -> owner -> ReviewPeriodDays ])) {
$reviewFreq = ReadonlyField :: create ( " ROReviewPeriodDays " , _t ( " ContentReview.REVIEWFREQUENCY " , " Review frequency " ), $this -> daysToString [ 0 ]);
} else {
$reviewFreq = ReadonlyField :: create ( " ROReviewPeriodDays " , _t ( " ContentReview.REVIEWFREQUENCY " , " Review frequency " ), $this -> daysToString [ $this -> owner -> ReviewPeriodDays ]);
}
$logConfig = GridFieldConfig :: create ()
-> addComponent ( new GridFieldSortableHeader ())
-> addComponent ( $logColumns = new GridFieldDataColumns ());
// Cast the value to the users prefered date format
$logColumns -> setFieldCasting ( array (
'Created' => 'DateTimeField->value'
));
$logs = GridField :: create ( 'ROReviewNotes' , 'Review Notes' , $this -> owner -> ReviewLogs (), $logConfig );
$fields -> addFieldsToTab ( " Root.ContentReview " , array (
$contentOwners ,
$nextReviewAt -> performReadonlyTransformation (),
$reviewFreq ,
$logs
));
// Done!
2014-02-13 02:07:39 +01:00
return ;
2009-11-02 05:02:57 +01:00
}
2014-02-19 02:31:47 +01:00
2014-02-13 04:35:13 +01:00
$users = Permission :: get_members_by_permission ( array ( " CMS_ACCESS_CMSMain " , " ADMIN " ));
2014-02-19 02:31:47 +01:00
$usersMap = $users -> map ( 'ID' , 'Title' ) -> toArray ();
2014-02-13 04:35:13 +01:00
asort ( $usersMap );
2014-02-19 02:31:47 +01:00
$userField = ListboxField :: create ( 'OwnerUsers' , _t ( " ContentReview.PAGEOWNERUSERS " , " Users " ), $usersMap )
2014-02-13 04:35:13 +01:00
-> setMultiple ( true )
-> setAttribute ( 'data-placeholder' , _t ( 'ContentReview.ADDUSERS' , 'Add users' ))
-> setDescription ( _t ( 'ContentReview.OWNERUSERSDESCRIPTION' , 'Page owners that are responsible for reviews' ));
2014-02-13 02:07:39 +01:00
2014-02-13 04:35:13 +01:00
$groupsMap = array ();
foreach ( Group :: get () as $group ) {
// Listboxfield values are escaped, use ASCII char instead of »
$groupsMap [ $group -> ID ] = $group -> getBreadcrumbs ( ' > ' );
}
asort ( $groupsMap );
2014-02-19 02:31:47 +01:00
$groupField = ListboxField :: create ( 'OwnerGroups' , _t ( " ContentReview.PAGEOWNERGROUPS " , " Groups " ), $groupsMap )
2014-02-13 04:35:13 +01:00
-> setMultiple ( true )
-> setAttribute ( 'data-placeholder' , _t ( 'ContentReview.ADDGROUP' , 'Add groups' ))
-> setDescription ( _t ( 'ContentReview.OWNERGROUPSDESCRIPTION' , 'Page owners that are responsible for reviews' ));
2014-02-19 02:31:47 +01:00
$reviewDate = DateField :: create ( " NextReviewDate " , _t ( " ContentReview.NEXTREVIEWDATE " , " Next review date " ))
-> setConfig ( 'showcalendar' , true )
2014-02-13 04:35:13 +01:00
-> setConfig ( 'dateformat' , 'yyyy-MM-dd' )
-> setConfig ( 'datavalueformat' , 'yyyy-MM-dd' )
-> setDescription ( _t ( 'ContentReview.NEXTREVIEWDATADESCRIPTION' , 'Leave blank for no review' ));
2014-02-19 02:31:47 +01:00
$reviewFrequency = DropdownField :: create ( " ReviewPeriodDays " , _t ( " ContentReview.REVIEWFREQUENCY " , " Review frequency " ), $this -> daysToString )
-> setDescription ( _t ( 'ContentReview.REVIEWFREQUENCYDESCRIPTION' , 'The review date will be set to this far in the future whenever the page is published' ));
$notesField = GridField :: create ( 'ReviewNotes' , 'Review Notes' , $this -> owner -> ReviewLogs (), GridFieldConfig_RecordEditor :: create ());
2014-02-13 04:35:13 +01:00
2014-02-19 02:31:47 +01:00
$crFields -> add ( new HeaderField ( _t ( 'ContentReview.REVIEWHEADER' , " Content review " ), 2 ));
$crFields -> add ( $userField );
$crFields -> add ( $groupField );
$crFields -> add ( $reviewDate );
$crFields -> add ( $reviewFrequency );
$crFields -> add ( $notesField );
2014-02-14 02:49:43 +01:00
2014-02-19 02:31:47 +01:00
$fields -> addFieldsToTab ( " Root.ContentReview " , $crFields );
2009-11-02 05:02:57 +01:00
}
2014-02-14 02:49:43 +01:00
2014-02-18 03:39:13 +01:00
/**
* Creates a ContentReviewLog and connects it to this Page
*
* @ param Member $reviewer
* @ param string $message
*/
public function addReviewNote ( Member $reviewer , $message ) {
$reviewLog = ContentReviewLog :: create ();
$reviewLog -> Note = $message ;
2014-02-19 02:31:47 +01:00
$reviewLog -> ReviewerID = $reviewer -> ID ;
2014-02-18 03:39:13 +01:00
$this -> owner -> ReviewLogs () -> add ( $reviewLog );
}
/**
* Advance review date to the next date based on review period or set it to null
* if there is no schedule
*
* @ return bool - returns true if date was set and false is content review is 'off'
*/
public function advanceReviewDate () {
$hasNextReview = true ;
if ( $this -> owner -> ReviewPeriodDays ) {
$this -> owner -> NextReviewDate = date ( 'Y-m-d' , strtotime ( '+' . $this -> owner -> ReviewPeriodDays . ' days' ));
} else {
$hasNextReview = false ;
$this -> owner -> NextReviewDate = null ;
}
$this -> owner -> write ();
return $hasNextReview ;
}
2014-02-14 02:49:43 +01:00
/**
*
* @ 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 ;
}
2014-02-18 03:39:13 +01:00
if ( $this -> OwnerGroups () -> count () == 0 && $this -> OwnerUsers () -> count () == 0 ) {
2014-02-14 02:49:43 +01:00
return false ;
}
2014-02-18 03:39:13 +01:00
if ( $member -> inGroups ( $this -> OwnerGroups ())) {
2014-02-14 02:49:43 +01:00
return true ;
}
2014-02-18 03:39:13 +01:00
if ( $this -> OwnerUsers () -> find ( 'ID' , $member -> ID )) {
2014-02-14 02:49:43 +01:00
return true ;
}
return false ;
}
2010-07-20 05:51:15 +02:00
2014-02-13 02:07:39 +01:00
/**
* Set the review data from the review period , if set .
*/
public function onBeforeWrite () {
2010-07-20 05:51:15 +02:00
$this -> owner -> LastEditedByName = $this -> owner -> getEditorName ();
2014-02-13 04:35:13 +01:00
$this -> owner -> OwnerNames = $this -> owner -> getOwnerNames ();
2009-11-02 05:02:57 +01:00
}
2010-07-20 05:51:15 +02:00
2014-02-13 02:07:39 +01:00
/**
* Provide permissions to the CMS
*
* @ return array
*/
public function providePermissions () {
2009-11-02 05:02:57 +01:00
return array (
" EDIT_CONTENT_REVIEW_FIELDS " => array (
'name' => " Set content owners and review dates " ,
'category' => _t ( 'Permissions.CONTENT_CATEGORY' , 'Content permissions' ),
'sort' => 50
)
);
}
}