php - Yii: ID getting overwritten on load
I need help with tracing this web application. I'm very new to Yii, and I'm trying to dissect an existing app to understand it better. I'm trying to create an edit function, which video tutorials lead me to believe has the exact same process as an add function [save()
], except you specify the ID to be overwritten (and I very well could be wrong about this).
Near as I can tell, the following files are in play:
- views/forum/view.php
- views/forum/_commentform.php
- views/forum/_comments.php
- controllers/ForumController.php
- models/Forum.php
- models/Comment.php
I can't really change much of the existing, though I can add my own. It starts withview.php
, where much of the stuff is displayed. At the bottom of it is this:
<?php
$this->widget('zii.widgets.CListView',
array('dataProvider'=>$dataProvider, 'itemView'=>'_comments', 'summaryText'=>'',));
?>
_comments.php
displays all the usual elements of a comment, like say, from Facebook. There's an edit button there that I made, code here:
<?php echo CHtml::link(CHtml::encode('Edit'),array('forum/editcomment','reply'=>$data->id,'topic'=>$data->content_id)); ?>
That edit button gets the ID of the current comment from the database. Near as the application logs can tell me, this does work.
That calls this particular function inForumController.php
:
public function actionEditComment() {
if(isset($_GET['reply'])) {
$comment=Comment::model()->findByAttributes(array('id'=>$_GET['reply']));
$topic=Forum::model()->findByAttributes(array('id'=>$comment->content_id));
$this->renderPartial('_commentform', array('forum'=>$topic, 'model'=>$comment, 'view'=>'view',));
}
}
Next is the_commentform.php
. Nothing much, just a textbox, though it does check if an ID is present; if it is, it is editing an existing comment, otherwise, it is creating a new one. A submit button also changes fromReply
toUpdate
, depending on the value ofisNewRecord
.
EDIT: There's also a CActiveForm, in case that of any help. Might have something to do with routing?
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'comment-form',
'action'=>Yii::app()->createUrl('forum/view/id/'.$forum->id),
'enableAjaxValidation'=>false,
)); ?>
<?php
if ($view == 'view') {
echo CHtml::submitButton($model->isNewRecord ? 'Reply' : 'Update', array('id'=>'comment'.$model->id));
}?>
Again, confirmed via application logs, the ID of the comment is being passed through, albeit asid => comment<commentID>
. Then this is where things get hazy. I assume the flow goes back toForumController.php
, where, per my logging, the ID is lost.
Here's the parts of theForumController.php
that I deem responsible:
public function actionView() {
$post=$this->loadModel();
$comment=$this->newComment($post);
$viewcount=$post->view_count+1;
$post->view_count=$viewcount;
$post->save();
$this->render('view',array('model'=>$post, 'dataProvider'=>$dataProvider,));
}
private $_model;
public function loadModel() {
if($this->_model===null) {
if(isset($_GET['id'])) {
$this->_model=Forum::model()->findByPk($_GET['id'], $condition);
}
if($this->_model===null)
throw new CHttpException(404,'The requested page does not exist.');
}
return $this->_model;
}
protected function newComment($post) {
$comment=new Comment;
if(isset($_POST['Comment'])) {
$comment->attributes=$_POST['Comment'];
$post->addComment($comment);
}
return $comment;
}
Interestingly, if I write out$comment
fromnewComment()
out to the log, it does print out the edited comment (i.e., it prints out "john cena" if I edited the existing comment "who is champ?"), but$comment->id
yields a null, which I assume is why instead of updating, the edited comment is saved as a new one.
As for the models,Forum.php
andComment.php
strangely point to the same database table, because for some reason they decided to put Forums and Comments into one table.Forum.php
also contains the actualaddComment
function (a placement I find weird), though by the time the flow gets there, the Comment ID is of course null, though the edited comment itself is there.
Where did I go wrong? Did I miss anything?
EDIT: Here's the attributes and rules for the Comment model:
public function attributeLabels() {
return array(
'id' => 'ID',
'node_type' => 'Node Type',
'party_id' => 'Party',
'category' => 'Category',
'title' => 'Title',
'content' => 'Content',
'date_created' => 'Create Time',
'date_modified' => 'Update Time',
'status' => 'Status',);
}
public function rules()
{
/* combine parent and own rules */
$parentRules = parent::rules();
$myRules = array(
array('node_type_id', 'default', 'value'=>'7'), /* set type to Person */
array('node_type_id', 'in', 'range'=>array('7')), /* allow only Person type */
array('party_id, date_created, date_modified, status', 'numerical', 'integerOnly'=>true),
array('category, title, content', 'safe'),
);
/* you want to apply parent rules last, delete them here if necessary */
return array_merge($myRules);
}
Answer
Solution:
Could you post Comment class defenition here?
I think you don't have rule for "id" in Comment::rules(), When rule for attribute is not defined attribute will be unsafe and you can't set it value by $comment->attributes, or you can change you code to something like: