Chapter 9 loadModel method

Looking at the book, the loadModel method doesn’t have a variable being passed into the function however my version of Yii 1.1.8 does create a loadModel method that gets a $id variable rather than looking for it in a get request. Here is what I have




public function loadModel($id)

        {

                $model=Issue::model()->findByPk((int)$id);

                if($model===null)

                        throw new CHttpException(404,'The requested page does not exist.');

                return $model;

        }



and here is what the book wants me to have




public function loadModel($withComments=false)

	{

		if($this->_model===null)

		{

			if(isset($_GET['id']))

			{

			     if($withComments)

			     {

				      $this->_model=Issue::model()->with(array(

					                     'comments'=>array('with'=>'author')))->findbyPk($_GET['id']);

				 }

			     else

			     {

				      $this->_model=Issue::model()->findbyPk($_GET['id']);

			     }

			}

			if($this->_model===null)

				throw new CHttpException(404,'The requested page does not exist.');

		}

		return $this->_model;

	}



My concern is how do I alter either the method to fit my version of yii’s way of passing an id or alter the yii defaults to fit the method’s way of doing things? I tried downloading the source code for the book and opened the IssueController.php for chapter 9. If I try a straight swap of files so my IssueController is the books version of the same it still errors out when I get to pg 234.

Here is the stack trace of the error I get when I reach pg 234




include(RecentComments.php) [<a href='function.include'>function.include</a>]: failed to open stream: No such file or directory


C:\yii\framework\YiiBase.php(421)


409                 {

410                     foreach(self::$_includePaths as $path)

411                     {

412                         $classFile=$path.DIRECTORY_SEPARATOR.$className.'.php';

413                         if(is_file($classFile))

414                         {

415                             include($classFile);

416                             break;

417                         }

418                     }

419                 }

420                 else

421                     include($className.'.php');

422             }

423             else  // class name with namespace in PHP 5.3

424             {

425                 $namespace=str_replace('\\','.',ltrim($className,'\\'));

426                 if(($path=self::getPathOfAlias($namespace))!==false)

427                     include($path.'.php');

428                 else

429                     return false;

430             }

431             return class_exists($className,false) || interface_exists($className,false);

432         }

433         return true;

Stack Trace

#0	

+  C:\yii\framework\YiiBase.php(421): YiiBase::autoload()

#1	

+  C:\yii\framework\YiiBase.php(301): YiiBase::autoload("RecentComments")

#2	

+  C:\yii\framework\web\CWidgetFactory.php(147): YiiBase::import("RecentComments", true)

#3	

+  C:\yii\framework\web\CBaseController.php(139): CWidgetFactory->createWidget(ProjectController, "RecentComments", array())

#4	

+  C:\yii\framework\web\CBaseController.php(165): CBaseController->createWidget("RecentComments", array())

#5	

–  C:\Users\nick\workspace\trackstar\protected\views\project\index.php(19): CBaseController->widget("RecentComments")

14 <?php $this->widget('zii.widgets.CListView', array(

15     'dataProvider'=>$dataProvider,

16     'itemView'=>'_view',

17 )); ?>

18 

19 <?php $this->widget('RecentComments'); ?>

#6	

+  C:\yii\framework\web\CBaseController.php(119): require("C:\Users\nick\workspace\trackstar\protected\views\project\index....")

#7	

+  C:\yii\framework\web\CBaseController.php(88): CBaseController->renderInternal("C:\Users\nick\workspace\trackstar\protected\views\project\index....", array("dataProvider" => CActiveDataProvider), true)

#8	

+  C:\yii\framework\web\CController.php(866): CBaseController->renderFile("C:\Users\nick\workspace\trackstar\protected\views\project\index....", array("dataProvider" => CActiveDataProvider), true)

#9	

+  C:\yii\framework\web\CController.php(779): CController->renderPartial("index", array("dataProvider" => CActiveDataProvider), true)

#10	

–  C:\Users\nick\workspace\trackstar\protected\controllers\ProjectController.php(145): CController->render("index", array("dataProvider" => CActiveDataProvider))

140     public function actionIndex()

141     {

142         $dataProvider=new CActiveDataProvider('Project');

143         $this->render('index',array(

144             'dataProvider'=>$dataProvider,

145         ));

146     }

147 

148     /**

149      * Manages all models.

150      */

#11	

+  C:\yii\framework\web\actions\CInlineAction.php(50): ProjectController->actionIndex()

#12	

+  C:\yii\framework\web\CController.php(300): CInlineAction->runWithParams(array("r" => "project/index"))

#13	

+  C:\yii\framework\web\filters\CFilterChain.php(134): CController->runAction(CInlineAction)

#14	

+  C:\yii\framework\web\filters\CFilter.php(41): CFilterChain->run()

#15	

+  C:\yii\framework\web\CController.php(1144): CFilter->filter(CFilterChain)

#16	

+  C:\yii\framework\web\filters\CInlineFilter.php(59): CController->filterAccessControl(CFilterChain)

#17	

+  C:\yii\framework\web\filters\CFilterChain.php(131): CInlineFilter->filter(CFilterChain)

#18	

+  C:\yii\framework\web\CController.php(283): CFilterChain->run()

#19	

+  C:\yii\framework\web\CController.php(257): CController->runActionWithFilters(CInlineAction, array("accessControl"))

#20	

+  C:\yii\framework\web\CWebApplication.php(277): CController->run("index")

#21	

+  C:\yii\framework\web\CWebApplication.php(136): CWebApplication->runController("project/index")

#22	

+  C:\yii\framework\base\CApplication.php(158): CWebApplication->processRequest()

#23	

–  C:\Users\nick\workspace\trackstar\index.php(13): CApplication->run()

08 defined('YII_DEBUG') or define('YII_DEBUG',true);

09 // specify how many levels of call stack should be shown in each log message

10 defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3);

11 

12 require_once($yii);

13 Yii::createWebApplication($config)->run();



protected\components\RecentComment.php





<?php

/**

 * RecentComments is a Yii widget used to display a list of recent comments 

 */

class RecentComments extends CWidget

{

	private $_comments;  

	public $displayLimit = 5;

	public $projectId = null;

	

	public function init()

    {

        $this->_comments = Comment::model()->findRecentComments($this->displayLimit, $this->projectId);

    }  


    public function getRecentComments()

	{

		return $this->_comments;

	}


    public function run()

    {

        // this method is called by CController::endWidget()    

        $this->render('recentComments');

    }

}



protected\components\view\renderComments.php




<ul>

<?php foreach($this->getRecentComments() as $comment): ?>

		<div class="author">

			<?php echo $comment->author->username; ?> added a comment.

		</div>

		<div class="issue">      

		   <?php echo CHtml::link(CHtml::encode($comment->issue->name), array('issue/view', 'id'=>$comment->issue->id)); ?>

	    </div>

	

	<?php endforeach; ?>

</ul>



protected\views\project\index.php




<?php

$this->breadcrumbs=array(

	'Projects',

);


$this->menu=array(

	array('label'=>'Create Project', 'url'=>array('create')),

	array('label'=>'Manage Project', 'url'=>array('admin')),

);

?>


<h1>Projects</h1>


<?php $this->widget('zii.widgets.CListView', array(

	'dataProvider'=>$dataProvider,

	'itemView'=>'_view',

)); ?>


<?php $this->widget('RecentComments'); ?>



Have a look config file.

It seems that you have not registered components folder to autoload.

It should be like that:




 'import' => array(

                            'application.components.*',

                            'application.models.*',

),



no dice. my config has




'import'=>array(

		'application.models.*',

		'application.components.*',

	),



which was part of the auto generated code

then Have a look your RecentComment.php file

the file name is RecentComment.php and class name is RecentComments

It is not correct for YII.

In Yii spec it is required the names should be same. change it.

That changes my error to




CException


RecentComments cannot find the view "recentComments".


C:\yii\framework\web\widgets\CWidget.php(244)


232      * about how the view script is resolved.

233      * @param array $data data to be extracted into PHP variables and made available to the view script

234      * @param boolean $return whether the rendering result should be returned instead of being displayed to end users

235      * @return string the rendering result. Null if the rendering result is not required.

236      * @throws CException if the view does not exist

237      * @see getViewFile

238      */

239     public function render($view,$data=null,$return=false)

240     {

241         if(($viewFile=$this->getViewFile($view))!==false)

242             return $this->renderFile($viewFile,$data,$return);

243         else

244             throw new CException(Yii::t('yii','{widget} cannot find the view "{view}".',

245                 array('{widget}'=>get_class($this), '{view}'=>$view)));

246     }

247 }

Stack Trace

#0	

–  C:\Users\nick\workspace\trackstar\protected\components\RecentComments.php(24): CWidget->render("recentComments")

19     }

20 

21     public function run()

22     {

23         // this method is called by CController::endWidget()    

24         $this->render('recentComments');

25     }

26 }

#1	

+  C:\yii\framework\web\CBaseController.php(166): RecentComments->run()

#2	

–  C:\Users\nick\workspace\trackstar\protected\views\project\index.php(19): CBaseController->widget("RecentComments")

14 <?php $this->widget('zii.widgets.CListView', array(

15     'dataProvider'=>$dataProvider,

16     'itemView'=>'_view',

17 )); ?>

18 

19 <?php $this->widget('RecentComments'); ?>

#3	

+  C:\yii\framework\web\CBaseController.php(119): require("C:\Users\nick\workspace\trackstar\protected\views\project\index....")

#4	

+  C:\yii\framework\web\CBaseController.php(88): CBaseController->renderInternal("C:\Users\nick\workspace\trackstar\protected\views\project\index....", array("dataProvider" => CActiveDataProvider), true)

#5	

+  C:\yii\framework\web\CController.php(866): CBaseController->renderFile("C:\Users\nick\workspace\trackstar\protected\views\project\index....", array("dataProvider" => CActiveDataProvider), true)

#6	

+  C:\yii\framework\web\CController.php(779): CController->renderPartial("index", array("dataProvider" => CActiveDataProvider), true)

#7	

–  C:\Users\nick\workspace\trackstar\protected\controllers\ProjectController.php(145): CController->render("index", array("dataProvider" => CActiveDataProvider))

140     public function actionIndex()

141     {

142         $dataProvider=new CActiveDataProvider('Project');

143         $this->render('index',array(

144             'dataProvider'=>$dataProvider,

145         ));

146     }

147 

148     /**

149      * Manages all models.

150      */

#8	

+  C:\yii\framework\web\actions\CInlineAction.php(50): ProjectController->actionIndex()

#9	

+  C:\yii\framework\web\CController.php(300): CInlineAction->runWithParams(array("r" => "project/index"))

#10	

+  C:\yii\framework\web\filters\CFilterChain.php(134): CController->runAction(CInlineAction)

#11	

+  C:\yii\framework\web\filters\CFilter.php(41): CFilterChain->run()

#12	

+  C:\yii\framework\web\CController.php(1144): CFilter->filter(CFilterChain)

#13	

+  C:\yii\framework\web\filters\CInlineFilter.php(59): CController->filterAccessControl(CFilterChain)

#14	

+  C:\yii\framework\web\filters\CFilterChain.php(131): CInlineFilter->filter(CFilterChain)

#15	

+  C:\yii\framework\web\CController.php(283): CFilterChain->run()

#16	

+  C:\yii\framework\web\CController.php(257): CController->runActionWithFilters(CInlineAction, array("accessControl"))

#17	

+  C:\yii\framework\web\CWebApplication.php(277): CController->run("index")

#18	

+  C:\yii\framework\web\CWebApplication.php(136): CWebApplication->runController("project/index")

#19	

+  C:\yii\framework\base\CApplication.php(158): CWebApplication->processRequest()

#20	

+  C:\Users\nick\workspace\trackstar\index.php(13): CApplication->run()



I’m pretty sure my problem is centered around the IssueController::loadModel. As of right now it is un-altered but it is expecting an input variable other than the id I am passing it. I tried using the books code and it throws the same error as the one without it.

Looking at the downloadable source code I found the following errors in the books text.

On pg 232 it calls for a file to be created called protected/components/RecentComment.php This must be protected/components/Recent[color="#FF0000"]Comments[/color].php

On pg 233 it calls for a file to be created called protected/components/views/renderComments.php This must be protected/components/views/[color="#FF0000"]recent[/color]Comments.php

Also the changes to be made to the urlManager in protected/config/main.php in the book are completely wrong if your going off of Yii 1.1.8. I just copy and pasted the source code urlManager for chapter 10 and it worked.

We have the same code error my friend…

Anyone fixed this ? I have the same problem following the book.

in 1.1.8 you should pass the $id to the loadModel() method.




public function loadModel($id, $withComments=false)

	{

            if ($withComments) 

            {

                $model = Issue::model()->with(array('comments' => array('with' => 'author')))->findByPk($id);

            } 

            else 

            {

                $model = Issue::model()->findByPk((int) $id);

            }

            if ($model === null)

                throw new CHttpException(404, 'The requested page does not exists.');

            return $model;

	}



good solution

Does anyone have the same result as image from page 237?

My Project view is different.

you save me

The book instructs to name the component file RecentComments.php. However, it should be named RecentCommentsWidget.php. This is how the file is named in the downloadable source code.