Like the Post
model, we need to customize the rules()
, relations()
and safeAttributes()
methods of the Comment
model. In addition, we also need to modify the attributeLabels()
to declare the customized labels for some attributes.
rules()
Method ¶We first customize the validation rules generated by the yiic
tool. The following rules are used for comments:
public function rules()
{
return array(
array('author,email,content', 'required'),
array('author,email,url','length','max'=>128),
array('email','email'),
array('url','url'),
array('verifyCode', 'captcha', 'on'=>'insert',
'allowEmpty'=>!Yii::app()->user->isGuest),
);
}
In the above, we specify that the author
, email
and content
attributes are required; the length of author
, email
and url
cannot exceed 128; the email
attribute must be a valid email address; the url
attribute must be a valid URL; and the verifyCode
attribute should be validated as a CAPTCHA code.
The verifyCode
attribute in the above is mainly used to store the verification code that a user enters in order to leave a comment. Because it is not present in the Comment
table, we need to explicitly declare it as a public member variable. Its validation is using a special validator named captcha
which refers to the CCaptchaValidator class. Moreover, the validation will only be performed when a new comment is being inserted (see the on
option). And for authenticated users, this is not needed (see the allowEmpty
option).
safeAttributes()
Method ¶We then customize the safeAttributes()
method to specify which attributes can be massively assigned.
public function safeAttributes()
{
return array('author', 'email', 'url', 'content', 'verifyCode');
}
This also indicates that the comment form would consist of fields to collect the information about author, email, URL, content and verification code.
relations()
Method ¶When we develop the "recent comments" portlet, we need to list the most recent comments together with their corresponding post information. Therefore, we need to customize the relations()
method to declare the relation about post.
public function relations()
{
return array(
'post'=>array(self::BELONGS_TO, 'Post', 'postId',
'joinType'=>'INNER JOIN'),
);
}
Notice that the join type for the post
relation is INNER JOIN
. This is because a comment has to belong to a post.
attributeLabels()
Method ¶Finally, we need to customize the attributeLabels()
method to declare the customized labels for the attributes. The method returns an array consisting of name-label pairs. When we call CHtml::activeLabel() to display an attribute label, it will first check if a customized label is declared. If not, it will use an algorithm to generate the default label.
public function attributeLabels()
{
return array(
'author'=>'Name',
'url'=>'Website',
'content'=>'Comment',
'verifyCode'=>'Verification Code',
);
}
Tip: The algorithm for generating the default label is based on the attribute name. It first breaks the name into words according to capitalization. It then changes the first character in each word into upper case. For example, the name
verifyCode
would have the default labelVerify Code
.
Because we want to keep the comment count in each post, when we add or delete a comment, we need to adjust the corresponding comment count for the post. We achieve this by overriding the afterSave()
method and the afterDelete()
method of the Comment
model. We also override its beforeValidate()
method so that we can convert the content from the Markdown format to HTML format and record the creation time.
protected function beforeValidate($on)
{
$parser=new CMarkdownParser;
$this->contentDisplay=$parser->safeTransform($this->content);
if($this->isNewRecord)
$this->createTime=time();
return true;
}
protected function afterSave()
{
if($this->isNewRecord && $this->status==Comment::STATUS_APPROVED)
Post::model()->updateCounters(array('commentCount'=>1), "id={$this->postId}");
}
protected function afterDelete()
{
if($this->status==Comment::STATUS_APPROVED)
Post::model()->updateCounters(array('commentCount'=>-1), "id={$this->postId}");
}
Signup or Login in order to comment.