0 follower

Отображение записей

В нашем приложении запись может показываться как отдельно, так и среди других записей. Первое реализуется действием show, второе — list. В данном разделе мы изменим оба действия для достижения первоначальных требований.

1. Изменение действия show

Действие show реализовано в методе actionShow() контроллера PostController. Отдаваемый пользователю HTML генерируется из отображения show, находящегося в файле /wwwroot/blog/protected/views/post/show.php.

Ниже приведён код действия show контроллера PostController:

public function actionShow()
{
    $this->render('show',array(
        'post'=>$this->loadPost(),
    ));
}
 
private $_post;
 
protected function loadPost($id=null)
{
    if($this->_post===null)
    {
        if($id!==null || isset($_GET['id']))
            $this->_post=Post::model()->findbyPk($id!==null ? $id : $_GET['id']);
        if($this->_post===null || Yii::app()->user->isGuest &&
            $this->_post->status!=Post::STATUS_PUBLISHED)
            throw new CHttpException(404,'Кто здесь?!');
    }
    return $this->_post;
}

Наши изменения в основном коснулись метода loadPost(). В нём мы получаем запись из таблицы Post, используя параметр id из GET. Если запись не найдена или не опубликована (при этом пользователь является гостем) — показываем ошибку 404. Иначе возвращаем объект записи методу actionShow(), который передаёт объект отображению show.

Подсказка: Yii перехватывает исключения HTTP (экземпляры класса CHttpException) и отображает их на страницах ошибок с соответствующими предопределёнными шаблонами. Процесс изменения этих шаблонов в вашем приложении будет описан в конце данного руководства.

Изменения в отображении show в основном затрагивают форматирование и стили отображения записи, поэтому на нём мы останавливаться не будем.

2. Изменение действия list

Как и в действии show, мы будем изменять действие list в двух местах: метод actionList() контроллера PostController и отображение /wwwroot/blog/protected/views/post/list.php. Требуется добавить поддержку отображения записей с определённым тегом.

Ниже приведён изменённый метод actionList() контроллера PostController:

public function actionList()
{
    $criteria=new CDbCriteria;
    $criteria->condition='status='.Post::STATUS_PUBLISHED;
    $criteria->order='createTime DESC';
 
    $withOption=array('author');
    if(!empty($_GET['tag']))
    {
        $withOption['tagFilter']['params'][':tag']=$_GET['tag'];
        $postCount=Post::model()->with($withOption)->count($criteria);
    }
    else
        $postCount=Post::model()->count($criteria);
 
    $pages=new CPagination($postCount);
    $pages->applyLimit($criteria);
 
    $posts=Post::model()->with($withOption)->findAll($criteria);
 
    $this->render('list',array(
        'posts'=>$posts,
        'pages'=>$pages,
    ));
}

Мы создаём критерий запроса, ограничивающий отображаемые записи опубликованными и сортирующий их в обратном порядке в соответствии с временем их создания. После этого мы подсчитываем общее число записей, подходящих под критерий. Это количество используется в компоненте постраничной разбивки для определения общего количества страниц, необходимых для отображения записей. Далее мы получаем из БД сами данные и передаём их в отображение list.

Стоит отметить, что при заданном GET параметре tag мы делаем запрос используя tagFilter и передавая ему значение параметра. Включение tagFilter в запрос позволит нам сделать единственный JOIN запрос для получения записей с определённым тегом. Без этого Yii разобьёт запрос на два (для достижения большей эффективности) и вернёт неправильный результат.

Отображению list передаются два параметра: $posts и $pages. Первый является списком записей, которые необходимо отобразить. Второй содержит информацию для постраничной разбивки (такую, как общее кол-во страниц или текущая страница). Отображение list содержит виджет постраничной разметки, который автоматически делает разбивку на несколько страниц, если записей достаточно много.