Сегодня мы продолжим разработку игрового сайта и напишем код необходимый для создания, удаления и изменения жанров.
Но вначале два небольших объявления.
1) Я как-то упустил, что есть русский перевод документации Yii, причём очень качественный.
2) Я решил выложить весь исходный код этого сайта, думаю так будет проще экспериментировать. Все-таки копировать куски кода из блога неудобно.
SourceИнструкция по установке.
1) В архиве находятся: папка public_html
(в ней только исходные файлы сайта, без самого фреймворка), файл dump.sql
(с дампом базы) и файл с инструкциями.
2) Распакуйте папку public_html
так, чтобы DOCUMENT_ROOT
вашего сервера указывал на ее содержимое (при желании, саму папку можно переименовать).
3) Откройте файл index.php
и укажите путь к фреймворку Yii (строка 4).
4) Откройте файл \protected\config\main.php
и укажите параметры подключения к базе данных (строки 45-47).
5) Импортируйте базу данных (файл dump.sql
), например, с помощью phpMyAdmin.
6) Можно работать 🙂
7) Адрес входа в админку http://sitename.local/index.php?r=dashboard
Сразу хочу обратить ваше внимание, что это не окончательная версия сайта и, скорее всего, в ней есть баги и недоработки. Поэтому буду рад, если вы о них мне сообщите 😉
Возвращаемся к жанрам.
Открываем окно консоли и выполняем команды
>> yiic shell
>> model Types ygs_types
>> crud Types
В результате будут созданы:
1) Класс модели \protected\models\Types.php
2) Класс контроллера \protected\controllers\TypesController.php
3) Папка с представлениями \protected\views\types\
По-умолчанию, контроллер содержит 6 методов, которые предназначены для формирования страниц. Это:
actionShow
(адрес types/show) – страница с выбранным жанром;
actionCreate
(адрес types/create) – форма создания нового жанра;
actionUpdate
(адрес types/update) – форма изменения жанра;
actionDelete
(адрес types/delete) – удаление жанра;
actionList
(адрес types/list) – список жанров;
actionAdmin
(адрес types/admin) – список жанров с кнопками «Изменить» и «Удалить».
Тут я хочу обратить ваше внимание на один момент. Этот контроллер ничего не знает об играх. Поэтому на страницах show
и list
будут просто выведены отдельные жанры и их список, без игр.
Этот список мы оформим в виде виджета и поместим в сайдбаре, а для вывода игр, которые относятся к выбранному жанру, по-моему, будет логичнее использовать контроллер GamesController
, который мы рассмотрим в следующий раз.
Я начинаю с жанров только потому, что они должны быть созданы до того как будет выполнен импорт игр из фида партнерки.
Т.е. методы actionShow
и actionList
нам не нужны, поэтому закроем к ним доступ. Чтобы не удалять эти методы из контроллера, я просто закомментировал первый элемент массива в методе accessRules
. В результате при попытке доступа к ним посетитель увидит страницу с 403-ей ошибкой «У вас недостаточно прав для доступа к запрошенной странице».
Вносим небольшие изменения в методы actionCreate
и actionUpdate
. Нам нужно только изменить редирект. Посмотрите, например, на actionUpdate
.
public function actionUpdate() { $model=$this->loadTypes(); //если запрос отправлен через форму изменения жанра if(isset($_POST['Types'])) { $model->attributes=$_POST['Types']; //если жанр сохранен, переходим на страницу управления жанрами if($model->save()) $this->redirect(array('admin')); } $this->render('update',array('model'=>$model)); }
Прежде всего, мы создаём модель. Для этого метод loadTypes
читает $_GET['id']
и выполняет запрос к базе.
Затем проверяем, заполнял ли пользователь форму. Если нет – показываем страницу с формой (используется представление \protected\views\types\update.php
), и в этом представлении мы можем получить данные из базы, используя переменную $model
(об этом чуть позже).
Если пользователь заполнил и отправил форму, сохраняем модель и отправляем редирект на страницу types/admin
.
Тут есть несколько интересных моментов.
Взгляните на строку
$model->attributes=$_POST['Types'];
При её выполнении используется метод setAttributes
, который при присваивании элементов $_POST['Types']
будет использовать только безопасные атрибуты (safe attributes).
Определить список безопасных атрибутов можно с помощью метода модели safeAttributes
public function safeAttributes() { return array('t_id', 't_name'); }
Таким образом, фреймворк автоматически фильтрует все данные, которые не относятся к форме.
UPD. В версии 1.1 метод safeAttributes можно не использовать. Атрибуты считаются безопасными, если они упоминаются в правилах, которые возвращает метод rules()
. При этом, правила должны относиться к данному сценарию (подробнее здесь). Спасибо, SAM!
При вызове $model->save()
перед сохранением выполняется валидация данных. Правила валидации возвращает метод rules
модели
public function rules() { return array( array('t_name','length','max'=>45), array('t_id', 'required'), array('t_id', 'numerical', 'integerOnly'=>true), ); }
Как видите, по-умолчанию, для создания правил используются данные таблиц БД.
Переходим к работе с представлениями.
Как видите, для отображения представления используется метод render
. В его первом параметре нужно указать имя файла представления (без расширения), а во втором – массив со всеми переменными к которым мы хотим получить доступ в представлении.
При этом если мы будем использовать встроенные библиотеки фреймворка, то в большинстве случаев будет достаточно передать экземпляр модели. Прежде всего, это касается класса CHtml.
Он содержит методы для создания различных элементов, причем для многих элементов есть по два метода. Например, CHtml::activeLabel()
и CHtml::label()
. Оба используются для создания тега label
, но первый в качестве параметра получает экземпляр модели и использует её в качестве источника данных, а для второго метода нужно передать все данные явно.
Кстати, обратите внимание на метод attributeLabels
модели
public function attributeLabels() { return array( 't_id' => 'Id жанра', 't_name' => 'Жанр', ); }
Он возвращает массив с названиями полей, которые используются методами с приставкой active
.
В качестве примера рассмотрим представление update.php
<?php //страница "Изменить жанр" //используется шаблон dashboard $this->layout = 'dashboard'; ?> <h2>Изменить жанр: <?php echo $model->t_name; ?></h2> <div class="actionBar"> [<?php echo CHtml::link('Управление жанрами',array('admin')); ?>] [<?php echo CHtml::link('Создать жанр',array('create')); ?>] </div> <?php echo $this->renderPartial('_form', array( 'model'=>$model, 'update'=>true, )); ?>
Начнем со строки 4. В ней мы указываем, какой макет страницы нужно использовать. Дело в том, что Yii при создании страницы использует так называемый Two-Step View Pattern.
При этом для создания страницы используются минимум два файла. Первый – макет (layout) (может, есть более удачный перевод?), находится в папке \views\layuots\
. Второй – файл представления, который указан в методе render
.
Макет – это обычный php файл, содержащий строку
<?php echo $content; ?>
При обработке этого файла переменная $content
будет содержать всю разметку представления.
В данном случае мы указываем, что нужно использовать макет dashboard
, который я сделал для панели управления. Для остальных страниц сайта будет использоваться макет main
.
В представлении для отображения формы используется метод renderPartial
. Разница между render
и renderPartial
в том, что при вызове первого будет использован макет, а при вызове второго – нет. Т.е. мы просто вставляем форму (она находится в файле \views\types\_form.php
).
Теперь давайте рассмотрим метод actionAdmin
контроллера.
public function actionAdmin() { //обработка команды удаления $this->processAdminCommand(); //формируем запрос $criteria=new CDbCriteria; $pages=new CPagination(Types::model()->count($criteria)); $pages->pageSize=self::PAGE_SIZE; $pages->applyLimit($criteria); //настраиваем сортировку $sort=new CSort('Types'); $sort->applyOrder($criteria); //выполняем запрос $models=Types::model()->findAll($criteria); //показываем страницу $this->render('admin',array( 'models'=>$models, 'pages'=>$pages, 'sort'=>$sort, )); }
Он создаёт таблицу с перечнем жанров. Напротив каждого жанра есть ссылки «Изменить» и «Удалить», а клик по заголовку столбца таблицы выполняет её сортировку.
Посмотрим, как работает этот метод.
Прежде всего, вызывается метод processAdminCommand
. Он проверяет, был ли клик по ссылке «Удалить» и если был, удаляет соответствующую запись из базы.
Затем создаётся объект CDbCriteria
. С его помощью можно изменять параметры запросов к БД. Например, можно указать список полей, которые должен вернуть запрос или ограничить количество строк.
Создаём объект CPagination
, который используется для пагинации (разбивки записей на страницы). Обратите внимание, в качестве параметра конструктор получает общее количество записей. А это количество мы определяем с помощью метода count модели.
После этого, создаём объект CSort
– сортировка записей. Этот объект использует параметр $_GET['sort']
, который будет установлен при клике по заголовку столбца. С помощью метода applyOrder
мы передаём параметры сортировки в объект CDbCriteria
.
Таким образом, вызов Types::model()->findAll($criteria)
возвращает записи таблицы, отсортированные в нужном порядке.
Заключительным этапом мы вызываем метод render
. Ему передаём массив с найденными записями и объектами CPagination
и CSort
. CPagination
используется для создания виджета с перечнем страниц, а CSort
– для создания ссылок в заголовке таблицы.
На этом можно остановиться. Теперь вы можете зайти в админку и создать жанры.
Как видите, я не пытаюсь объяснить каждую строчку кода, да это и не реально 🙂 . Вместо этого, я попытался объяснить общий принцип. Поэтому, если что-то непонятно, спрашивайте в комментариях.
В следующий раз я планирую рассказать о работе с играми. Это самая объемная часть. И в ней мы подробнее рассмотрим работу с моделями и библиотекой для работы с БД.
Удачи!
Все разделы цикла.
- Yii PHP framework: создаём игровой сайт. Часть 1. Постановка задачи.
- Yii PHP framework: создаём игровой сайт. Часть 2. База данных и установка фреймворка.
- Yii PHP framework: создаём игровой сайт. Часть 3. Аутентификация.
- Yii PHP framework: создаём игровой сайт. Часть 4. Работа с жанрами игр.
- Yii PHP framework: создаём игровой сайт. Часть 5. Импорт игр.
- Yii PHP framework: создаём игровой сайт. Часть 6. Формируем страницы игр и жанров.
- Yii PHP framework: создаём игровой сайт. Часть 7. Работа с JavaScript и страницы игр.
- Yii PHP framework: создаём игровой сайт. Часть 8. Создаём виджеты.
- Yii PHP framework: создаём игровой сайт. Часть 9. Поиск ошибок.
- Yii PHP framework: создаём игровой сайт. Часть 10. Панель управления.
- Yii PHP framework: создаём игровой сайт. Часть 11. Человекопонятные URL.
- Архив с исходниками