我正在使用cakephp,我有一个带有两个字段的模型“comment”:“model_type”和“model_id”,以便评论我的应用程序的每个项目(例如图片,新闻,文章......)单一评论模型。
我想知道如何做到这一点。 (可以评论的控制器的组件“注释”?)
最后,我想在一个帮助器中列出评论: $ comment-> show('model_name','item_id'); 这将显示正确的分页注释和用于向项添加新注释的表单。
感谢。
答案 0 :(得分:5)
修改:也请看这个:http://bakery.cakephp.org/articles/AD7six/2008/03/13/polymorphic-behavior
多模型评论系统和分页只需:
<?php echo $this->element('comments',
array(
'model_type' => "model_name",
'model_id' => $data['model']['id'],
'order_field' => 'created',
'order' => 'asc')); ?>
计划:
- id - model_type - model_id - content (optional:) - user_id - created - updated - rating - ...
评论模型:
// {app}/models/comment.php
class Comment extends AppModel{
public $name = 'Comment';
// List of model that could be commented
protected $model_list = array(
'news' => array(
'name' => 'News', // here it's the model's name
'field' => 'validated'), // A field for validation ( allow comments only on validaded items)
'articles' => array(
'name' => 'Article',
'field' => 'validated')
);
// This is an example
public $belongsTo = array(
'User' => array(
'conditions' => 'User.validated = true'
)
);
public $validate = array(
'model_type' => array(
'rule' => 'checkModelType',
'message' => "Something goes wrong !"
),
'model_id' => array(
'rule' => 'checkModelId',
'message' => "Something goes wrong !"
),
'content' => array(
'rule' => 'notEmpty',
'message' => "Empty content !"
)
);
// Check if the model is commentable
public function checkModelType($data){
$model_type = $data['model_type'];
return in_array($model_type, array_keys($this->model_list));
}
// Check if the item exists and is validated
public function checkModelId($data){
$model_id = intval($data['model_id']);
$model = $this->model_list[$this->data['Comment']['model_type']];
$params = array(
'fields' => array('id', $model['field']),
'conditions' => array(
$model['name'].'.'.$model['field'] => 1, // Validated item
$model['name'].'.id' => $model_id
)
);
// Binding model to Comment Model since there is no $belongsTo
return (bool) ClassRegistry::init($model['name'])->find('first', $params);
}
}
// {app}/controllers/comments_controller.php
class CommentsController extends AppController
{
public $name = 'Comments';
// Pagination works fine !
public $paginate = array(
'limit' => 15,
'order' => array(
'Comment.created' => 'asc')
);
// The action that lists comments for a specific item (plus pagination and order !)
public function view($model_type, $model_id, $order_field = 'created', $order = 'DESC'){
$conditions = array(
'Comment.model_type' => $model_type,
'Comment.model_id' => $model_id
);
// (optional)
if($order_field != 'created') {
$this->paginate['order'] = array(
'Comment.'.$order_field => $order,
'Comment.created' => 'asc');
}
// Paginate comments
$comments = $this->paginate($conditions);
// This allow to use paginator with requestAction
$paginator = ClassRegistry::getObject('view')->loaded['paginator'];
$paginator->params = $this->params;
return compact('comments', 'paginator');
}
public function add(){
// What you want !
}
}
/* {app}/views/elements/comments.ctp
@params : $model_type
* : $model_id
*
* */
$result = $this->requestAction("/comments/view/$model_type/$model_id/$order_field/$order/", $this->passedArgs);
$paginator = $result['paginator'];
$comments = $result['comments'];
$paginator->options(array('url' => $this->passedArgs));
?>
<h2>Comments</h2>
<fieldset class="commentform">
<legend>Add un commentaire</legend>
<?php
// Form
echo $form->create('Comment', array('action' => 'add'));
echo $form->hidden('model_type', array('value' => $model_type));
echo $form->hidden('model_id', array('value' => $model_id));
echo $form->input('content');
<?php
echo $form->end('Send');
?>
</fieldset>
<div class="paginationBar">
<?php
echo $paginator->prev('<< ', null, null, array('class' => 'disabled'));
echo '<span class="pagination">',$paginator->numbers(),'</span>';
echo $paginator->next(' >>', null, null, array('class' => 'disabled'));
?>
</div>
<?php
foreach($comments as $comment){
echo $this->element('comment', array('comment' => $comment));
}
?>
<div class="paginationBar">
<?php
echo $paginator->prev('<< ', null, null, array('class' => 'disabled'));
echo '<span class="pagination">',$paginator->numbers(),'</span>';
echo $paginator->next(' >>', null, null, array('class' => 'disabled'));
?>
<p><br />
<?php
echo $paginator->counter(array('format' => 'Page %page% on %pages%, displayi %current% items of %count%'));
?>
</p>
</div>
//{app}/views/elements/comment.ctp
// A single comment view
$id = $comment['Comment']['id'];
?>
<div class="comment">
<p class="com-author">
<span class="com-authorname"><?=$comment['User']['name']?> </span>
<span class="com-date">(<?=$comment['Comment']['created']?>)</span>
</p>
<p class="com-content"><?=$comment['Comment']['content']?></p>
</div>
答案 1 :(得分:1)
嗯......如果你想显示那样的分页评论会很复杂。你应该使用延迟加载:在用户点击之前不要加载评论。
你应该做一个元素。您可以将model_name和model_id传递给它。在元素中,您可以创建一个注释“小部件”,可以使用ajax直接将注释发送到您的注释控制器;并使用ajax加载分页注释。
答案 2 :(得分:1)
查看CakeDC开发的this插件(它实际上是一个组件)。
您可以实现该功能,也可以使用它来创建自己的解决方案。