I got error when I follow these steps in book
Armed with the knowledge of the benefits of Lazy Loading versus Eager Loading
in Yii, we should make an adjustment to how the Issue model is loaded within the
IssueController::actionView() method. Since we have altered the issues detail
view to display our comments, including the author of the comment, we know it will
be more efficient to use the Eager Loading approach to load our comments along with
their respective authors when we make the call to loadModel() in this method. To do
this, we can add a simple input flag to this loadModel() method to indicate whether
or not we want to load the comments as well.
Alter the IssueController::loadModel() method as shown below:
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
Iteration 6: Adding User Comments
[ 232 ]
{
$this->_model=Issue::model()->findbyPk($_GET[‘id’]);
}
}
if($this->_model===null)
throw new CHttpException(404,'The requested page does not
exist.’);
}
return $this->_model;
}
Now we can change the call to this method in IssueController::actionView(),
as such:
public function actionView()
{
$issue=$this->loadModel(true);
With this in place, we will load all of our comments, along with their respective
author information, with just one database call.
Creating the widget
Now we are ready to create our new widget to use our new method to display our
recent comments.
As we previously mentioned a widget in Yii is a class that extend from the
framework class CWidget or one of its child classes. We’ll add our new widget to the
protected/components/ directly, as the contents of this folder are already specified
in the main configuration file to be auto-loaded within the application. This way we
won’t have to explicitly import the class every time we wish to use it. We’ll name
our widget RecentComments, so we need to add a php file of the same name to this
directly. Add the following class definition to this newly created RecentComment.
php file:
<?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()
Chapter 9
[ 233 ]
{
$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’);
}
}
The primary work involved when creating a new widget is to override the init()
and run() methods of the base class. The init() method initializes the widget and
is called after its properties have been initialized. The run() method executes the
widget. In this case, we simply initialize the widget by requesting recent comments
based on the $displayLimit and $projectId properties. The execution of the widget
itself simply renders its associated view file, which we have yet to create. view files,
by convention, are placed in views/ directly within the same folder where the widget
resides, and have the same name as the widget, but start with a lowercase letter.
Sticking with convention, create a new file whose fully qualified path is protected/
components/views/renderComments.php. Once created, add the following markup
to that file:
<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>
This calls the RenderComments widget’s getRecentComments() method, which
returns an array of comments. It then iterates over each of them displaying who
added the comment and the associated issue on which the comment was left.
Iteration 6: Adding User Comments
[ 234 ]
In order to see the results, we need to embed this widget into an existing controller
view file. As previously mentioned, we want to use this widget on the projects listing
page, to display all recent comments across all projects, and also on a specific project
details page, to display the recent comments for just that specific project.
Let’s start with the project listing page. The view file responsible for displaying that
content is protected/views/project/index.php. Open up that file and add the
following at the bottom:
<?php $this->widget(‘RecentComments’); ?>
Now if we view the projects listing page http://localhost/trackstar/index.
php?r=project, we see something similar to the following screenshot: