Введение
Я давно работаю с yii framework. И пока это единственный framework в мире php. Из минусов для меня то, что он слишком низкоуровневый, отсутствует много плюшек, которые я с успехом возмещаю разумным использованием Zend компонент. Как набор компонент Zend хорош, чего не скажешь о его framework'е.
Ну так вот, возвращаясь к низкоуровневому yii. Его CRUD хорош, хорош для прототипирования, но плодит кучу файлов. Многие из которых со временем вырезаются и сильно модифицируются. Моим кошмаром была работа на небольшим по объему backend проектом. Где вся работа сводилась к администрированию кучи таблиц с текстовыми и буленовскими полями. При помощи CRUD все было сделано быстро, но большую часть времени я потратил на украшение админки, checkboxes вместо input, фильтры вида true|false вместо 0,1 и тому подобной ерунды. Таблиц было много, view еще больше. Я с нежностью вспоминал django и жалел что проект на PHP.
Прошло время, и вот во время работы над очередным проектом выдалась несколько часов, в результате которых было рождено небольшое расширение над CRUD.
Краткая суть. CRUD очень похожи, и их можно объединить. Второй задачей является способ указания системе типов данных в моделях, для того чтобы CRUD мог на основе этих типов создавать фильтры, приводить к строковому виду автоматически.
Что получилось? Получился модуль который позволяет не запуская CRUD получить CRUD странички над любой моделью при условии что она отнаследована от особого ActiveRecord + в ней определен один единственный метод. В качестве небольшого бонуса есть простая возможность слегка менять список полей и их порядок на полученных страницах.
Ниже небольшой туториал как заставить это работать. Текста много, но он расчитан на новичка в yii. Если вы накоротке с yii можете сразу читать с установки модуля.
Инициализация yii проекта
Можно пропустить, если хотите воспользоваться существующим.
Описание как создать yii проект с нуля. Для того чтобы потом использовать модуль.
Установка модуля.
Переходим в директорию расширений. (Если пропустили первый шаг, замените /var/www/AdminTest/ на путь до папки вашего проекта, содержащей protected)
claymore:$ cd /var/www/AdminTest/protected/extensions/
Скачиваем расширение.
claymore:$ hg clone -q https://yii-rextensions.googlecode.com/hg/ YiisyCrudAdmin -r YiisyCrudAdmin
[Опционально] удаляем информацию о репозитории, особенно ваш проект уже под системой контроля версий.
claymore:$ rm -rf YiisyCrudAdmin/.hg
Среда 2011-03-30 11:03 box:/var/www/AdminTest/protected/extensions
Модуль установлен.
Пример создания crud административной страницы.
Для примера нам понадобится любая модель.
Создаем таблицу в созданной базе данных.
mysql> create table example(id int primary key auto_increment, name char(20), is_good_record tinyint(1) default 0 , long_description text);
Query OK, 0 rows affected (0.08 sec)
Переходим в папку protected
claymore:$ cd /var/www/AdminTest/protected
Создаем модель.
claymore:$ ./yiic shell config/main.php
Yii Interactive Tool v1.1 (based on Yii v1.1.7)
Please type 'help' for help. Type 'exit' to quit.
>> model Example example
generate models/Example.php
generate fixtures/example.php
generate unit/ExampleTest.php
The following model classes are successfully generated:
Example
If you have a 'db' database connection, you can test these models now with:
$model=Example::model()->find();
print_r($model);
>>
Модифицируем модель.
Цель. Отнаследоваться от расширения CActiveRecord объявленному в YiisyCrudAdmin.RActiveRecord. И реализовать абстрактный метод getFieldsDescription
Открываем /var/www/AdminTest/protected/models/Example.php в любимом редакторе
Yii::import("ext.YiisyCrudAdmin.RActiveRecord"); //Добавляем эту строчку импорта в верх файла.
В модель Example добавляем новый метод
Yii::import("ext.YiisyCrudAdmin.RActiveRecord");
class Example extends RActiveRecord
{
//...
// в последней версии данный метод не требуется в модели, может создаваться по желанию в классе ExampleAdmin
public function getFieldsDescription()
{
return array(
'is_good_record' => 'RDbBoolean',
'long_description' => 'RDbText',
);
}
//...
}
Этот метод предоствляет расширенную информацию о полях модели. На данный момент реализованы пока Bool и Text.
Т.к. метод абстрактный ( чтобы про него не забывали), реализация обязательна, метод может возвращать пустой массив если нет желания заморачиваться.
Создаем в вашем любимом редакторе controllers/ExampleController.php
Yii::import('ext.YiisyCrudAdmin.RController');
class ExampleController extends RController
{
protected $_modelName = 'Example';
}
Тестируем
Открываем в браузере http://127.0.0.1/AdminTest/index.php?r=example/admin
Получаем типичный yii crud с небольшими улучшениями.
- Поля, отмеченные как boolean, отображаются в виде чекбоксов при редактировании. Также в наличии встроенный фильтр для этих полей на странице actionAdmin.
- Текстовые поля при редактировании редактируются в textarea. При просмотре в griidview обрезаются. (Пока и в view обрезаются, но это уже решаемый вопрос :) )
Из плюсов такого подхода, все сделано стандартными средствами yii. Т.е. после этапа прототипирования, вы уже можете использовать существующую базу кода, достаточно заглянуть в RController
Гибкость, например в методе getFieldsDescription модели, элеметом массива может быть массив, формирующий CGridColumn, в этом случае все обрабатывается в обычном для yii ключе.
Улучшаем внешний вид
Как поменять порядок полей в actionAdmin ?
Прямо в файле модели создаем класс
Yii::import('ext.YiisyCrudAdmin.RModelAdmin');
class ExampleAdmin extends RModelAdmin
{
public function getAdminFields()
{
return array(
'name', 'long_description', 'is_good_record', 'id'
);
}
}
После этого в actionAdmin наблюдаем поля в указанном порядке
.
Как исключить поле из отображения в actionAdmin ?
Yii::import('ext.YiisyCrudAdmin.RModelAdmin');
class ExampleAdmin extends RModelAdmin
{
public function getAdminExcludedFields()
{
return array(
'id',
);
}
}
И это все. Оба метода можно комбинировать.
Ну и вот интерфейс RModelAdmin, отвечающий за порядок и отображаемые поля
public function getViewExcludedFields();// список полей для исключения в actionView
public function getAdminExcludedFields();//список полей для исключения в actionAdmin
public function getViewFields();// список полей для отображения в actionView
public function getSearchFields();//список полей для отображения в расширенной форме поиска actionAdmin
public function getAdminFields();// список полей для отображения в actionAdmin
public function getFormFields();// список полей для создания/редактирования.
Почему методы а не массивы? Например для динамической генерации в зависимости от условий.
UPDATED:
В последней версии метод getFieldsDescription перенесен из модели в ModelAdmin класс.
Создание директории проекта.
Я буду использовать локальный вебсервер, с дефолтными настройками. Проект создам в папке AdminTest внутри моего document root /var/www/
Папка создана, скачиваем yii-framework
Распаковываем
Переименовываем, или делаем символическую ссылку( кому как удобнее), я переименовываю, т.к. работаю в рамках демонстрации
Удаляю скаченный архив
Проверяем что у нас есть распаковааная папка с yii framework
Переходим в папку со скриптами yii framework
Запускаем скрипт создания проекта
Проверяем
Создаем базу данных admintest. При помощи вашего любимого средства.
Прописываем настройки базы данных в protected/config/main.php
Теперь у нас есть болванка для веб сайта на основе шаблона yii.