Skip to content

Commit

Permalink
Nested comments proof of concept
Browse files Browse the repository at this point in the history
Update theme to new look and feel
Add jquery-validate 1.3.1 (w/ nz dst patch)
  • Loading branch information
Damian Mooyman committed Apr 20, 2015
1 parent 0c698a8 commit 468df23
Show file tree
Hide file tree
Showing 75 changed files with 5,103 additions and 208 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.sass-cache
3 changes: 2 additions & 1 deletion _config.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@

Deprecation::notification_version('2.0', 'comments');

define('COMMENTS_DIR', ltrim(Director::makeRelative(realpath(__DIR__)), DIRECTORY_SEPARATOR));
define('COMMENTS_DIR', basename(__DIR__));
define('COMMENTS_THIRDPARTY', COMMENTS_DIR . DIRECTORY_SEPARATOR . 'thirdparty');
114 changes: 92 additions & 22 deletions code/controllers/CommentingController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,27 @@ class CommentingController extends Controller {
'approve',
'rss',
'CommentsForm',
'reply',
'doPostComment',
'doPreviewComment'
);

private static $url_handlers = array(
'reply/$ParentCommentID//$ID/$OtherID' => 'reply',
);

/**
* Fields required for this form
*
* @var array
* @config
*/
private static $required_fields = array(
'Name',
'Email',
'Comment'
);

/**
* Base class this commenting form is for
*
Expand Down Expand Up @@ -289,6 +306,47 @@ public function getComment() {
return false;
}

/**
* Create a reply form for a specified comment
*
* @param Comment $comment
*/
public function ReplyForm($comment) {
// Enables multiple forms with different names to use the same handler
$form = $this->CommentsForm();
$form->setName('ReplyForm_'.$comment->ID);
$form->addExtraClass('reply-form');

// Load parent into reply form
$form->loadDataFrom(array(
'ParentCommentID' => $comment->ID
));

// Customise action
$form->setFormAction($this->Link('reply', $comment->ID));

$this->extend('updateReplyForm', $form);
return $form;
}


/**
* Request handler for reply form.
* This method will disambiguate multiple reply forms in the same method
*
* @param SS_HTTPRequest $request
*/
public function reply(SS_HTTPRequest $request) {
// Extract parent comment from reply and build this way
if($parentID = $request->param('ParentCommentID')) {
$comment = DataObject::get_by_id('Comment', $parentID, true);
if($comment) {
return $this->ReplyForm($comment);
}
}
return $this->httpError(404);
}

/**
* Post a comment form
*
Expand All @@ -297,26 +355,42 @@ public function getComment() {
public function CommentsForm() {
$usePreview = $this->getOption('use_preview');

$nameRequired = _t('CommentInterface.YOURNAME_MESSAGE_REQUIRED', 'Please enter your name');
$emailRequired = _t('CommentInterface.EMAILADDRESS_MESSAGE_REQUIRED', 'Please enter your email address');
$emailInvalid = _t('CommentInterface.EMAILADDRESS_MESSAGE_EMAIL', 'Please enter a valid email address');
$urlInvalid = _t('CommentInterface.COMMENT_MESSAGE_URL', 'Please enter a valid URL');
$commentRequired = _t('CommentInterface.COMMENT_MESSAGE_REQUIRED', 'Please enter your comment');

$fields = new FieldList(
$dataFields = new CompositeField(
TextField::create("Name", _t('CommentInterface.YOURNAME', 'Your name'))
->setCustomValidationMessage(_t('CommentInterface.YOURNAME_MESSAGE_REQUIRED', 'Please enter your name'))
->setAttribute('data-message-required', _t('CommentInterface.YOURNAME_MESSAGE_REQUIRED', 'Please enter your name')),

EmailField::create("Email", _t('CommentingController.EMAILADDRESS', "Your email address (will not be published)"))
->setCustomValidationMessage(_t('CommentInterface.EMAILADDRESS_MESSAGE_REQUIRED', 'Please enter your email address'))
->setAttribute('data-message-required', _t('CommentInterface.EMAILADDRESS_MESSAGE_REQUIRED', 'Please enter your email address'))
->setAttribute('data-message-email', _t('CommentInterface.EMAILADDRESS_MESSAGE_EMAIL', 'Please enter a valid email address')),

TextField::create("URL", _t('CommentingController.WEBSITEURL', "Your website URL"))
->setAttribute('data-message-url', _t('CommentInterface.COMMENT_MESSAGE_URL', 'Please enter a valid URL')),

TextareaField::create("Comment", _t('CommentingController.COMMENTS', "Comments"))
->setCustomValidationMessage(_t('CommentInterface.COMMENT_MESSAGE_REQUIRED', 'Please enter your comment'))
->setAttribute('data-message-required', _t('CommentInterface.COMMENT_MESSAGE_REQUIRED', 'Please enter your comment'))
// Name
TextField::create("Name", _t('CommentInterface.YOURNAME', 'Your name'))
->setCustomValidationMessage($nameRequired)
->setAttribute('data-msg-required', $nameRequired),

// Email
EmailField::create(
"Email",
_t('CommentingController.EMAILADDRESS', "Your email address (will not be published)")
)
->setCustomValidationMessage($emailRequired)
->setAttribute('data-msg-required', $emailRequired)
->setAttribute('data-msg-email', $emailInvalid)
->setAttribute('data-rule-email', true),

// Url
TextField::create("URL", _t('CommentingController.WEBSITEURL', "Your website URL"))
->setAttribute('data-msg-url', $urlInvalid)
->setAttribute('data-rule-url', true),

// Comment
TextareaField::create("Comment", _t('CommentingController.COMMENTS', "Comments"))
->setCustomValidationMessage($commentRequired)
->setAttribute('data-msg-required', $commentRequired)
),
HiddenField::create("ParentID"),
HiddenField::create("ReturnURL"),
HiddenField::create("ParentCommentID"),
HiddenField::create("BaseClass")
);

Expand Down Expand Up @@ -345,11 +419,7 @@ public function CommentsForm() {
}

// required fields for server side
$required = new RequiredFields(array(
'Name',
'Email',
'Comment'
));
$required = new RequiredFields($this->config()->required_fields);

// create the comment form
$form = new Form($this, 'CommentsForm', $fields, $actions, $required);
Expand Down Expand Up @@ -397,8 +467,8 @@ public function CommentsForm() {
}
}

if($member) {
$form->loadDataFrom($member);
if(!empty($member)) {
$form->loadDataFrom($member);
}

// hook to allow further extensions to alter the comments form
Expand Down
66 changes: 42 additions & 24 deletions code/extensions/CommentsExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class CommentsExtension extends DataExtension {
* gravatar_default: Theme for 'not found' gravatar {@see http://gravatar.com/site/implement/images}
* gravatar_rating: Gravatar rating (same as the standard default)
* show_comments_when_disabled: Show older comments when commenting has been disabled.
* order_comments_by: Default sort order.
* order_replies_by: Sort order for replies.
* comments_holder_id: ID for the comments holder
* comment_permalink_prefix: ID prefix for each comment
* require_moderation: Require moderation for all comments
Expand All @@ -27,6 +29,8 @@ class CommentsExtension extends DataExtension {
* frontend_spam: Display spam comments in the frontend, if the user can moderate them.
* html_allowed: Allow for sanitized HTML in comments
* use_preview: Preview formatted comment (when allowing HTML)
* nested_comments: Enable nested comments
* nested_depth: Max depth of nested comments in levels (where root is 1 depth) 0 means no limit.
*
* @var array
*
Expand All @@ -45,6 +49,7 @@ class CommentsExtension extends DataExtension {
'gravatar_rating' => 'g',
'show_comments_when_disabled' => false,
'order_comments_by' => '"Created" DESC',
'order_replies_by' => false,
'comments_per_page' => 10,
'comments_holder_id' => 'comments-holder',
'comment_permalink_prefix' => 'comment-',
Expand All @@ -56,6 +61,8 @@ class CommentsExtension extends DataExtension {
'html_allowed' => false,
'html_allowed_elements' => array('a', 'img', 'i', 'b'),
'use_preview' => false,
'nested_comments' => false,
'nested_depth' => 2,
);

/**
Expand Down Expand Up @@ -141,24 +148,6 @@ public function updateSettingsFields(FieldList $fields) {
}
}

/**
* Returns the RelationList of all comments against this object. Can be used as a data source
* for a gridfield with write access.
*
* @return CommentList
*/
public function AllComments() {
$comments = CommentList::create($this->ownerBaseClass)->forForeignID($this->owner->ID);
$this->owner->extend('updateAllComments', $comments);
return $comments;
}

public function getComments() {
// TODO: find out why this is being triggered when combined with blog
// Deprecation::notice('2.0', 'Use PagedComments to get paged comments');
return $this->PagedComments();
}

/**
* Get comment moderation rules for this parent
*
Expand Down Expand Up @@ -194,16 +183,27 @@ public function getCommentsRequireLogin() {
}

/**
* Returns the root level comments, with spam and unmoderated items excluded, for use in the frontend
* Returns the RelationList of all comments against this object. Can be used as a data source
* for a gridfield with write access.
*
* @return CommentList
*/
public function Comments() {
// Get all non-spam comments
public function AllComments() {
$order = $this->owner->getCommentsOption('order_comments_by');
$list = $this
->AllComments()
$comments = CommentList::create($this->ownerBaseClass)
->forForeignID($this->owner->ID)
->sort($order);
$this->owner->extend('updateAllComments', $comments);
return $comments;
}

/**
* Returns all comments against this object, with with spam and unmoderated items excluded, for use in the frontend
*
* @return CommentList
*/
public function AllVisibleComments() {
$list = $this->AllComments();

// Filter spam comments for non-administrators if configured
$showSpam = $this->owner->getCommentsOption('frontend_spam') && $this->owner->canModerateComments();
Expand All @@ -218,6 +218,23 @@ public function Comments() {
$list = $list->filter('Moderated', 1);
}

$this->owner->extend('updateAllVisibleComments', $list);
return $list;
}

/**
* Returns the root level comments, with spam and unmoderated items excluded, for use in the frontend
*
* @return CommentList
*/
public function Comments() {
$list = $this->AllVisibleComments();

// If nesting comments, only show root level
if($this->owner->getCommentsOption('nested_comments')) {
$list = $list->filter('ParentCommentID', 0);
}

$this->owner->extend('updateComments', $list);
return $list;
}
Expand Down Expand Up @@ -384,8 +401,9 @@ public function CommentsForm() {
$enabled = $this->getCommentsEnabled();
if($enabled && $this->owner->getCommentsOption('include_js')) {
Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
Requirements::javascript(THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js');
Requirements::javascript(THIRDPARTY_DIR . '/jquery-validate/lib/jquery.form.js');
Requirements::javascript(THIRDPARTY_DIR . '/jquery-validate/jquery.validate.pack.js');
Requirements::javascript(COMMENTS_THIRDPARTY . '/jquery-validate/jquery.validate.min.js');
Requirements::javascript('comments/javascript/CommentsInterface.js');
}

Expand Down
Loading

0 comments on commit 468df23

Please sign in to comment.