php - Yii: ID getting overwritten on load

700

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);
}
148

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:

if(isset($_POST['Comment']) && isset($_POST['Comment']['id'])) {
    $comment = Comment::model()->findByPk($_POST['Comment']['id']);
    $comment->attributes=$_POST['Comment'];
    $post->addComment($comment);
}

People are also looking for solutions to the problem: javascript - How to not allow values that are not in the database in an Autocomplete form with PHP & JS

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.