I’ve been coding along with the book without any issues until I got to page 14, where it demonstrates how to send an email notification upon a comment being added to a blog post.
Following the book, I have the following in [font="Palatino Linotype"]protected/components/NewCommentEvent.php[/font]
<?php
class NewCommentEvent extends CModelEvent {
public $comment;
public $post;
}
After that, I added the following to the Post model in [font="Palatino Linotype"]protected/models/Post.php[/font]. This model was created via Gii, and I left the auto-generated methods intact:
function addComment(Comment $comment)
{
$comment->post_id = $this->id;
// creating event class instance
$event = new NewCommentEvent($this);
$event->post = $this;
$event->comment = $comment;
// triggering event
$this->onNewComment($event);
return $event->isValid;
}
// defining onNewComment event
public function onNewComment($event)
{
// Event is actually triggered here. This way we can use
// onNewComment method instead of raiseEvent.
$this->raiseEvent('onNewComment', $event);
}
Still following the book, I created [font="Palatino Linotype"]protected/components/Notifier.php[/font] with the following contents:
<?php
class Notifier
{
function comment($event)
{
$text = "There was a new comment from
{$event->comment->author} on post {$event->post->title}";
mail('idontknowwhattopu@live.com', 'New Comment', $text);
}
}
Finally, I created the controller [font="Palatino Linotype"]protected/controllers/PostController.php[/font] with the following:
<?php
class PostController extends CController
{
function actionAddComment()
{
$post = Post::model()->findByPk(10);
$notifier = new Notifier();
var_dump($post);
//adding the event handler
$post->onNewComment = array($notifier, 'comment');
//in production, this should come from $_POST
$comment = new Comment();
$comment->author = 'Sam Dark';
$comment->text = 'Yii events are awesome!';
//adding the comment
$post->addComment($comment);
}
}
When trying to run this via %siteName%/index.php/Post/AddComment, I get the following error along with a giant stack trace:
Before the stack trace, it points to line 421 of YiiBase.php:
[spoiler]
409 {
410 include($classFile);
411 if(YII_DEBUG && basename(realpath($classFile))!==$className.'.php')
412 throw new CException(Yii::t('yii','Class name "{class}" does not match class file "{file}".', array(
413 '{class}'=>$className,
414 '{file}'=>$classFile,
415 )));
416 break;
417 }
418 }
419 }
420 else
[color="#FF0000"]421 include($className.'.php');[[/color]
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;
[/spoiler]
From the looks if it, I think Yii is trying to find the file Commment.php because of line 13 in PostController.php, which was not defined in the book. Was the class definition of Comment accidentally omitted in the book, or am I just missing something?
Some additional information about the variables used in PostController.php:
var_dump($post) yields:
[spoiler]
object(Post)[30]
private '_md' (CActiveRecord) =>
object(CActiveRecordMetaData)[17]
public 'tableSchema' =>
object(CMysqlTableSchema)[21]
public 'schemaName' => null
public 'name' => string 'post' (length=4)
public 'rawName' => string '`post`' (length=6)
public 'primaryKey' => string 'id' (length=2)
public 'sequenceName' => string '' (length=0)
public 'foreignKeys' =>
array (size=0)
...
public 'columns' =>
array (size=4)
...
private '_e' (CComponent) => null
private '_m' (CComponent) => null
public 'columns' =>
array (size=4)
'id' =>
object(CMysqlColumnSchema)[22]
...
'text' =>
object(CMysqlColumnSchema)[23]
...
'title' =>
object(CMysqlColumnSchema)[24]
...
'is_deleted' =>
object(CMysqlColumnSchema)[25]
...
public 'relations' =>
array (size=0)
empty
public 'attributeDefaults' =>
array (size=1)
'is_deleted' => int 0
private '_model' =>
object(Post)[16]
private '_md' (CActiveRecord) =>
&object(CActiveRecordMetaData)[17]
private '_new' (CActiveRecord) => boolean false
private '_attributes' (CActiveRecord) =>
array (size=0)
...
private '_related' (CActiveRecord) =>
array (size=0)
...
private '_c' (CActiveRecord) => null
private '_pk' (CActiveRecord) => null
private '_alias' (CActiveRecord) => string 't' (length=1)
private '_errors' (CModel) =>
array (size=0)
...
private '_validators' (CModel) => null
private '_scenario' (CModel) => string '' (length=0)
private '_e' (CComponent) => null
private '_m' (CComponent) => null
private '_new' (CActiveRecord) => boolean false
private '_attributes' (CActiveRecord) =>
array (size=4)
'id' => string '10' (length=2)
'text' => string 'slk1111dfjsdlkfjl' (length=17)
'title' => string 'sd1kfjdskf' (length=10)
'is_deleted' => string '0' (length=1)
private '_related' (CActiveRecord) =>
array (size=0)
empty
private '_c' (CActiveRecord) => null
private '_pk' (CActiveRecord) => string '10' (length=2)
private '_alias' (CActiveRecord) => string 't' (length=1)
private '_errors' (CModel) =>
array (size=0)
empty
private '_validators' (CModel) => null
private '_scenario' (CModel) => string 'update' (length=6)
private '_e' (CComponent) => null
private '_m' (CComponent) => null
[/spoiler]
var_dump($notifier) yields:
[spoiler]
object(Notifier)[27]
[/spoiler]
Thanks in advance.