2010-12-06 11:08:38 +01:00
< ? php
/**
* @ package comments
*/
class CommentingController extends Controller {
2012-07-22 03:30:33 +02:00
public static $allowed_actions = array (
2010-12-11 06:01:19 +01:00
'delete' ,
2012-07-22 03:30:33 +02:00
'spam' ,
'ham' ,
'approve' ,
'rss' ,
2010-12-11 06:01:19 +01:00
'CommentsForm' ,
2011-02-05 23:48:48 +01:00
'doPostComment'
2010-12-11 06:01:19 +01:00
);
2012-07-31 10:45:29 +02:00
2010-12-06 11:08:38 +01:00
private $baseClass = " " ;
private $ownerRecord = " " ;
private $ownerController = " " ;
public function setBaseClass ( $class ) {
$this -> baseClass = $class ;
}
public function getBaseClass () {
return $this -> baseClass ;
}
public function setOwnerRecord ( $record ) {
$this -> ownerRecord = $record ;
}
public function getOwnerRecord () {
return $this -> ownerRecord ;
}
public function setOwnerController ( $controller ) {
$this -> ownerController = $controller ;
}
public function getOwnerController () {
return $this -> ownerController ;
}
/**
* Workaround for generating the link to this controller
2012-07-22 03:30:33 +02:00
*
* @ return string
2010-12-06 11:08:38 +01:00
*/
2012-07-22 03:30:33 +02:00
public function Link ( $action = " " , $id = '' , $other = '' ) {
return Controller :: join_links ( __CLASS__ , $action , $id , $other );
2010-12-06 11:08:38 +01:00
}
/**
2012-07-31 10:45:29 +02:00
* Outputs the RSS feed of comments
*
* @ return XML
*/
public function rss () {
return $this -> getFeed ( $this -> request ) -> outputToBrowser ();
}
/**
* Return an RSSFeed of comments for a given set of comments or all
2012-07-22 03:30:33 +02:00
* comments on the website .
*
* To maintain backwards compatibility with 2.4 this supports mapping
* of PageComment / rss ? pageid = as well as the new RSS format for comments
* of CommentingController / rss / { classname } / { id }
2010-12-11 06:01:19 +01:00
*
2012-07-31 10:45:29 +02:00
* @ param SS_HTTPRequest
*
* @ return RSSFeed
2010-12-11 06:01:19 +01:00
*/
2012-07-31 10:45:29 +02:00
public function getFeed ( SS_HTTPRequest $request ) {
2012-07-22 03:30:33 +02:00
$link = $this -> Link ( 'rss' );
2012-07-31 10:45:29 +02:00
$class = $request -> param ( 'ID' );
$id = $request -> param ( 'OtherID' );
2012-07-22 03:30:33 +02:00
if ( isset ( $_GET [ 'pageid' ])) {
$id = Convert :: raw2sql ( $_GET [ 'pageid' ]);
$comments = Comment :: get () -> where ( sprintf (
2012-07-22 03:43:42 +02:00
" BaseClass = 'SiteTree' AND ParentID = '%s' AND Moderated = 1 AND IsSpam = 0 " , $id
2012-07-22 03:30:33 +02:00
));
$link = $this -> Link ( 'rss' , 'SiteTree' , $id );
} else if ( $class && $id ) {
if ( Commenting :: has_commenting ( $class )) {
$comments = Comment :: get () -> where ( sprintf (
2012-07-22 03:43:42 +02:00
" BaseClass = '%s' AND ParentID = '%s' AND Moderated = 1 AND IsSpam = 0 " ,
2012-07-22 03:30:33 +02:00
Convert :: raw2sql ( $class ),
Convert :: raw2sql ( $id )
));
$link = $this -> Link ( 'rss' , Convert :: raw2xml ( $class ), ( int ) $id );
} else {
return $this -> httpError ( 404 );
}
} else if ( $class ) {
if ( Commenting :: has_commenting ( $class )) {
$comments = Comment :: get () -> where ( sprintf (
2012-07-22 03:43:42 +02:00
" BaseClass = '%s' AND Moderated = 1 AND IsSpam = 0 " ,
Convert :: raw2sql ( $class )
2012-07-22 03:30:33 +02:00
));
} else {
return $this -> httpError ( 404 );
}
} else {
2012-07-31 10:45:29 +02:00
$comments = Comment :: get () -> where ( " Moderated = 1 AND IsSpam = 0 " );
2012-07-22 03:30:33 +02:00
}
$title = _t ( 'CommentingController.RSSTITLE' , " Comments RSS Feed " );
2012-07-31 10:45:29 +02:00
$comments = new PaginatedList ( $comments , $request );
$comments -> setPageLength ( Commenting :: get_config_value ( null , 'comments_per_page' ));
return new RSSFeed ( $comments , $link , $title , $link , 'Title' , 'Comment' , 'AuthorName' );
2012-07-22 03:30:33 +02:00
}
/**
* Deletes a given { @ link Comment } via the URL .
*/
2012-07-31 10:45:29 +02:00
public function delete () {
if ( ! $this -> checkSecurityToken ( $this -> request )) {
2012-07-22 03:30:33 +02:00
return $this -> httpError ( 400 );
}
if (( $comment = $this -> getComment ()) && $comment -> canDelete ()) {
$comment -> delete ();
return ( $this -> request -> isAjax ()) ? true : $this -> redirectBack ();
}
return $this -> httpError ( 404 );
}
/**
* Marks a given { @ link Comment } as spam . Removes the comment from display
*/
public function spam () {
2012-07-31 10:45:29 +02:00
if ( ! $this -> checkSecurityToken ( $this -> request )) {
2012-07-22 03:30:33 +02:00
return $this -> httpError ( 400 );
}
$comment = $this -> getComment ();
if (( $comment = $this -> getComment ()) && $comment -> canEdit ()) {
$comment -> IsSpam = true ;
$comment -> Moderated = true ;
$comment -> write ();
return ( $this -> request -> isAjax ()) ? true : $this -> redirectBack ();
}
return $this -> httpError ( 404 );
}
/**
* Marks a given { @ link Comment } as ham ( not spam ) .
*/
2012-07-31 10:45:29 +02:00
public function ham () {
if ( ! $this -> checkSecurityToken ( $this -> request )) {
2012-07-22 03:30:33 +02:00
return $this -> httpError ( 400 );
}
$comment = $this -> getComment ();
if (( $comment = $this -> getComment ()) && $comment -> canEdit ()) {
$comment -> IsSpam = false ;
$comment -> Moderated = true ;
$comment -> write ();
return ( $this -> request -> isAjax ()) ? true : $this -> redirectBack ();
}
return $this -> httpError ( 404 );
}
/**
* Marks a given { @ link Comment } as approved .
*/
2012-07-31 10:45:29 +02:00
public function approve () {
if ( ! $this -> checkSecurityToken ( $this -> request )) {
2012-07-22 03:30:33 +02:00
return $this -> httpError ( 400 );
}
$comment = $this -> getComment ();
if (( $comment = $this -> getComment ()) && $comment -> canEdit ()) {
$comment -> IsSpam = false ;
$comment -> Moderated = true ;
$comment -> write ();
return ( $this -> request -> isAjax ()) ? true : $this -> redirectBack ();
}
return $this -> httpError ( 404 );
}
/**
2012-07-31 10:45:29 +02:00
* Returns the comment referenced in the URL ( by ID ) . Permission checking
* should be done in the callee .
2012-07-22 03:30:33 +02:00
*
* @ return Comment | false
*/
public function getComment () {
2010-12-11 06:01:19 +01:00
$id = isset ( $this -> urlParams [ 'ID' ]) ? $this -> urlParams [ 'ID' ] : false ;
if ( $id ) {
$comment = DataObject :: get_by_id ( 'Comment' , $id );
2012-07-22 03:30:33 +02:00
if ( $comment ) {
return $comment ;
2010-12-11 06:01:19 +01:00
}
}
2012-07-22 03:30:33 +02:00
return false ;
2010-12-11 06:01:19 +01:00
}
2012-07-22 03:30:33 +02:00
/**
* Checks the security token given with the URL to prevent CSRF attacks
* against administrators allowing users to hijack comment moderation .
*
* @ param SS_HTTPRequest
*
* @ return boolean
*/
public function checkSecurityToken ( $req ) {
$token = SecurityToken :: inst ();
return $token -> checkRequest ( $req );
}
2010-12-11 06:01:19 +01:00
/**
* Post a comment form
*
2010-12-06 11:08:38 +01:00
* @ return Form
*/
2012-07-22 03:30:33 +02:00
public function CommentsForm () {
2010-12-06 11:08:38 +01:00
$member = Member :: currentUser ();
2012-06-01 08:34:31 +02:00
$fields = new FieldList (
2010-12-06 11:08:38 +01:00
new TextField ( " Name " , _t ( 'CommentInterface.YOURNAME' , 'Your name' )),
new EmailField ( " Email " , _t ( 'CommentingController.EMAILADDRESS' , " Your email address (will not be published) " )),
new TextField ( " URL " , _t ( 'CommentingController.WEBSITEURL' , " Your website URL " )),
new TextareaField ( " Comment " , _t ( 'CommentingController.COMMENTS' , " Comments " )),
new HiddenField ( " ParentID " ),
new HiddenField ( " ReturnURL " ),
new HiddenField ( " BaseClass " )
);
// save actions
2012-06-01 08:34:31 +02:00
$actions = new FieldList (
2010-12-06 11:08:38 +01:00
new FormAction ( " doPostComment " , _t ( 'CommentInterface.POST' , 'Post' ))
);
// required fields for server side
$required = new RequiredFields ( array (
'Name' ,
'Email' ,
'Comment'
));
// create the comment form
$form = new Form ( $this , 'CommentsForm' , $fields , $actions , $required );
// if the record exists load the extra required data
if ( $record = $this -> getOwnerRecord ()) {
$require_login = Commenting :: get_config_value ( $this -> getBaseClass (), 'require_login' );
$permission = Commenting :: get_config_value ( $this -> getBaseClass (), 'required_permission' );
if (( $require_login || $permission ) && $member ) {
$fields = $form -> Fields ();
$fields -> removeByName ( 'Name' );
$fields -> removeByName ( 'Email' );
$fields -> insertBefore ( new ReadonlyField ( " NameView " , _t ( 'CommentInterface.YOURNAME' , 'Your name' ), $member -> getName ()), 'URL' );
$fields -> push ( new HiddenField ( " Name " , " " , $member -> getName ()));
2012-07-26 09:12:05 +02:00
$fields -> push ( new HiddenField ( " Email " , " " , $member -> Email ));
2010-12-06 11:08:38 +01:00
$form -> setFields ( $fields );
}
// we do not want to read a new URL when the form has already been submitted
// which in here, it hasn't been.
$url = ( isset ( $_SERVER [ 'REQUEST_URI' ])) ? Director :: protocolAndHost () . '' . $_SERVER [ 'REQUEST_URI' ] : false ;
$form -> loadDataFrom ( array (
'ParentID' => $record -> ID ,
'ReturnURL' => $url ,
'BaseClass' => $this -> getBaseClass ()
));
}
// Set it so the user gets redirected back down to the form upon form fail
$form -> setRedirectToFormOnValidationError ( true );
// load any data from the cookies
if ( $data = Cookie :: get ( 'CommentsForm_UserData' )) {
2011-09-15 16:37:10 +02:00
$data = Convert :: json2array ( $data );
2010-12-06 11:08:38 +01:00
$form -> loadDataFrom ( array (
" Name " => isset ( $data [ 'Name' ]) ? $data [ 'Name' ] : '' ,
" URL " => isset ( $data [ 'URL' ]) ? $data [ 'URL' ] : '' ,
" Email " => isset ( $data [ 'Email' ]) ? $data [ 'Email' ] : '' ,
" Comment " => Cookie :: get ( 'CommentsForm_Comment' )
));
}
2012-07-22 03:30:33 +02:00
if ( $member ) {
$form -> loadDataFrom ( $member );
}
2010-12-06 11:08:38 +01:00
// hook to allow further extensions to alter the comments form
$this -> extend ( 'alterCommentForm' , $form );
return $form ;
}
/**
* Process which creates a { @ link Comment } once a user submits a comment from this form .
*
* @ param array $data
* @ param Form $form
*/
2012-07-22 03:30:33 +02:00
public function doPostComment ( $data , $form ) {
2010-12-06 11:08:38 +01:00
$class = ( isset ( $data [ 'BaseClass' ])) ? $data [ 'BaseClass' ] : $this -> getBaseClass ();
// if no class then we cannot work out what controller or model they
// are on so throw an error
if ( ! $class ) user_error ( " No OwnerClass set on CommentingController. " , E_USER_ERROR );
// cache users data
2011-09-15 16:37:10 +02:00
Cookie :: set ( " CommentsForm_UserData " , Convert :: raw2json ( $data ));
2010-12-06 11:08:38 +01:00
Cookie :: set ( " CommentsForm_Comment " , $data [ 'Comment' ]);
// extend hook to allow extensions. Also see onAfterPostComment
$this -> extend ( 'onBeforePostComment' , $form );
// If commenting can only be done by logged in users, make sure the user is logged in
$member = Member :: currentUser ();
if ( Commenting :: can_member_post ( $class ) && $member ) {
$form -> Fields () -> push ( new HiddenField ( " AuthorID " , " Author ID " , $member -> ID ));
}
if ( ! Commenting :: can_member_post ( $class )) {
echo _t ( 'CommentingController.PERMISSIONFAILURE' , " You're not able to post comments to this page. Please ensure you are logged in and have an appropriate permission level. " );
return ;
}
// is moderation turned on
$moderated = Commenting :: get_config_value ( $class , 'require_moderation' );
2012-08-08 02:51:14 +02:00
// we want to show a notification if comments are moderated
if ( $moderated ) {
Session :: set ( 'CommentsModerated' , 1 );
}
2010-12-06 11:08:38 +01:00
$comment = new Comment ();
$form -> saveInto ( $comment );
$comment -> Moderated = ( $moderated ) ? false : true ;
$comment -> write ();
2012-11-27 13:56:21 +01:00
// extend hook to allow extensions. Also see onBeforePostComment
$this -> extend ( 'onAfterPostComment' , $comment );
2010-12-06 11:08:38 +01:00
// clear the users comment since it passed validation
Cookie :: set ( 'CommentsForm_Comment' , false );
if ( Director :: is_ajax ()) {
2012-07-22 03:50:17 +02:00
if ( ! $comment -> Moderated ) {
echo $comment -> renderWith ( 'CommentInterface_pendingcomment' );
} else {
2010-12-06 11:08:38 +01:00
echo $comment -> renderWith ( 'CommentInterface_singlecomment' );
}
2012-07-22 03:50:17 +02:00
return true ;
2010-12-06 11:08:38 +01:00
}
2012-07-31 10:45:29 +02:00
2010-12-07 01:34:17 +01:00
$holder = Commenting :: get_config_value ( $comment -> BaseClass , 'comments_holder_id' );
2012-07-31 10:45:29 +02:00
$hash = ( $moderated ) ? $comment -> Permalink () : $holder ;
2010-12-06 11:08:38 +01:00
$url = ( isset ( $data [ 'ReturnURL' ])) ? $data [ 'ReturnURL' ] : false ;
2010-12-07 01:34:17 +01:00
return ( $url ) ? $this -> redirect ( $url . '#' . $hash ) : $this -> redirectBack ();
2010-12-06 11:08:38 +01:00
}
2012-08-08 02:51:14 +02:00
}