Проблема с каптчей

Приветствую.

С недавних пор боты стали постить спам в комменты.

Решил закрыться о них каптчей.

Однако, что-то не заработало у меня, вот и прошу помощи.

Формочка добавления комментов показыватся во views/posts/show.php

или другими словами, когда показывается конкретный пост (posts/show) ниже рисуется формочка.

Рисуется так:




<?php $this->renderPartial('/comments/_form',array(

    'model'=>$newComment,

    'update'=>false,

)); ?>



В comments/_form.php такое:




<?php $this->widget('CCaptcha', array('buttonLabel' => '<br>[new code]')); ?>

<?php echo CHtml::activeTextField($model,'verifyCode'); ?>



в Comments Model добавил




  public function rules()

  {

    return array(

//..

      array('verifyCode', 'captcha', 'allowEmpty' => false, 'on' => 'create'),

     );

  }



В Comments Controller добавил:




    public function actions()

    {

        return array(

            // Создаем экшин captcha.

             'captcha'=>array(

                'class'=>'CCaptchaAction',

                'backColor'=> 0x003300,

                'maxLength'=> 3,

                'minLength'=> 3,

                 'foreColor'=> 0x66FF66,

            ),

        );

    }

  public function accessRules()

  {

    return array(

      array('allow',  

        'actions'=>array('list','show', 'create', 'captcha'),

        'users'=>array('*'),

      ),

//....



В итоге, при просмотре поста каптча даже не отображается.

Потому что сгенерированный путь к картинке ведет как: posts/captcha

Это логично, потому что мы же внутри экшена posts/show.

А как все-таки реализовать задуманное, комменты к посту с каптчей?

Текс. Каптчу стало показывать.

Указал просто




<?php $this->widget('CCaptcha', array('captchaAction' => 'comments/captcha',

                                      'buttonLabel' => '<br>[new code]')); ?>



Однако, форма не реагирует на неё.

Видать по тому, что у неё прописано:




array('verifyCode', 'captcha', 'allowEmpty' => false, 'on' => 'create'),



А используется она в PostsController при экшене Show:




  public function actionShow()

  {

    $post = $this->loadPosts();

    $this->pageTitle = $post->Title;

    $comment = $this->newComment($post);

...



и newComment выглядит так:




  protected function newComment($post)

  {

      $comment = new Comments;

      if(isset($_POST['Comments']))

      {

          $comment->attributes=$_POST['Comments'];

          $comment->PID=$post->PID;

          $comment->DateOf = date("Y-m-d H:i:s");

          $comment->IP = $_SERVER["REMOTE_ADDR"];


              if(isset($_POST['saveComment']) && $comment->save())

              {

                  $this->redirect(array('posts/show',

                                             'id'=>$comment->PID,

                                             '#'=>'c'.$comment->CID));

              }

          }

      }

      return $comment;

  }




Естественно тут нет никакого ‘on’ => ‘create’.

А как тут указать что именно тут надо проверить еще и каптчу?

Укажите в модели Comments следующее:




  public function rules()

  {

    return array(

//..

      array('verifyCode', 'captcha', 'allowEmpty' => false, 'on' => 'create', 'captchaAction' => 'comments/captcha'),

     );

  }



Ага. Еще убрал ‘on’ => ‘create’ и в Posts::newComment

добавил:




          $comment->verifyCode = $_POST["Comments"]["verifyCode"];



Без этого не работало.

Я так понимаю safeAttributes теперь как-то по-другому обрабываются чем раньше?

Использую версию 1.10

Да и еще. Теперь и в админке, например в Comments/Update тоже требует каптчу.

Она конечно же там не нужна, а нужна только если коммент вводят на странице Posts/show.

Как это правило задать?

Для этого и нужен ‘on’ => ‘create’

Ок. Тогда как код в Posts::newComment поймет что это как раз ‘on’=>‘create’?

Принцип добавления комментария к посту взят тут http://www.yiiframework.com/doc/blog/comment.create

Т.е. код одинаковый практически.

А, всё понял.

В newComment надо использовать




$model->validate('create')



вместо




$model->validate()



Всем спасибо. :)