Простенькая страница настроек для Yii-приложения

от автора

Привет.

Хочу поделиться небольшим модулем, предназначенным для создания страницы настроек в своём приложении. А заодно узнать у сообщества, что в нём можно было бы улучшить.

Задача по своей идее простая — сделать табличку в БД, хранящую параметры типа «ключ -> значение», а к ней сделать страничку редактирования, позволяющую изменять данные значения. ну и конечно же реализовать программный интерфейс для доступа к параметрам хранимым в БД.

Срок реализации — около получаса. В интернете почему-то готового решения было не найти. Исправим положение, авось кому пригодится.

Делать будем на конкретном примере. Допустим, нам необходимо хранить такие настройки: Имя приложения, Описание приложения, Пароль для Gii, Email администратора.

Пишем

Итак, для начала создадим структуру каталогов, в которой сложим наш модуль:

configpage     components         Econfig.php     conrollers         WtsController.php     models         WtsConfigForm.php     views         wts             config.php             configForm.php     ConfigpageModule.php 

Не будем ничего выдумывать и используем готовое расширения для хранения настроек в БД — EConfig. Его и сложим в каталог components. Данное расширение имеет два метода «get» и «set», а также само умеет создавать таблицу в БД, то есть париться по его настройке не придётся.

Шаблон для нашего модуля сгенерирован через Gii и основной файл модуля ConfigpageModule.php остаётся без изменений:

class ConfigpageModule extends CWebModule {  	public function init() 	{ 		$this->setImport(array( 			'configpage.models.*', 			'configpage.components.*', 		)); 	}  	public function beforeControllerAction($controller, $action) 	{ 		if(parent::beforeControllerAction($controller, $action)) 		{ 			return true; 		} 		else 			return false; 	} } 

Куда интереснее обстоят дела с самой формой. Для её создания мы можем воспользоваться конструктором форм, входящим в поставку Yii. Подробнее о нём можно почитать здесь.

Если вкратце, то нам понадобится создать модель формы, контроллер, описание формы и вьюшку. Начнём с модели.
WtsConfigForm.php:

class WtsConfigForm extends CFormModel {     public $applicationName;     public $applicationShortDesc;     public $giiPassword;     public $adminEmail;      public function rules()     {         return array(             array('applicationName, giiPassword, adminEmail, applicationShortDesc', 'required'),         );     }      public function attributeLabels()     {         return array(             'applicationName' => Yii::t('app', 'Наименование приложения'),             'applicationShortDesc' => Yii::t('app', 'Краткое описание приложения'),             'giiPassword' => Yii::t('app', 'Пароль для генератора кода Gii'),             'adminEmail' => Yii::t('app', 'Email администратора'),         );     } } 

Всё просто — описали 4 поля, описали их метки и указали правило, утверждающее, что поле является обязательным. Хинт: если не указать поле как обязательное, оно не появится на форме.

Окейно. Контроллер оставим на сладкое, а пока опишем форму и вьюшку. Описание формы — это простой массив, в котором хранится описание полей и элементов управления формы.
configForm.php:

return array(     'elements'=>array(          'mainSettings'=>array(             'type'=>'form',             'title'=>'Основные настройки',             'elements'=>array(                 'applicationName'=>array('type'=>'text',),                 'applicationShortDesc'=>array('type'=>'text',),             ),         ),          'systemSettings'=>array(             'type'=>'form',             'title'=>'Системные настройки',             'elements'=>array(                 'adminEmail'=>array('type'=>'text',),                 'giiPassword'=>array('type'=>'text', ),             ),         ),     ),      'buttons'=>array(         'configPage'=>array(             'type'=>'submit',             'label'=>'Сохранить',         ),     ), ); 

Просто? Вот и я думаю что да. Мы выделили две группы настроек — основные и системные, в каждой группе описали некие поля, присутствующие в модели и снизу расположили кнопку «Сохранить».

Выводить всё это мы будем простейшую вьюшку, имя которой config.php:

<?php $this->breadcrumbs = array(     'Администрирование',     'Настройки приложения', ); ?>  <div class="form">     <?php echo $form; ?> </div> 

Ну тут совсем всё тривиально. Разве что для красоты оставим breadcrumbs.

А вот теперь будет самое интересное. В контроллере мы свяжем нашу модель с произвольным количеством полей и спец. табличку БД, хранящую пары «ключ->значение». Связью как я и говорил будет сложить модуль EConfig. Файл WtsController.php:

class WtsController extends Controller {     public function actionIndex()     {         $model = new WtsConfigForm;          foreach ($model->attributes as $attr => $val) {             $model->$attr = Yii::app()->getModule('configpage')->config->get($attr);         }          $form = new CForm('configpage.views.wts.configForm', $model);         if ($form->submitted('configPage') && $form->validate()) {              foreach ($model->attributes as $attr => $val) {                 Yii::app()->getModule('configpage')->config->set($attr, $val);             }             $this->render('config', array('form' => $form));         } else {             $this->render('config', array('form' => $form));         }     } } 

Что здесь происходит. В actionIndex (чтобы не плодить лишнего) мы создаём экземпляр модели, заполняем её значениями из БД, причём если в БД отсутствует требуемое значение, то в поле проставляется значение null, затем мы создаём форму, используя наше описание и экземпляр модели.

А дальше проверяем — если есть данные из браузера — если таковые найдутся, то модель самостоятельно загрузит их, после чего эти данные будут записаны в БД и страница настроек будет вновь показана пользователю.

Кстати да, заметьте, что я за ненадобностью не описал правил фильтрации пользователей. Вы этого сделать не забудьте, а то все смогут поназаписывать настроек в базу.

Остаются мелочи. Подключить и начать использовать модуль.

Подключаем

Подключить модуль проще простого. Просто вписываем следующий код в раздел modules главного файла конфигурации приложения (main.php).

... 'modules' => array(         'configpage' => array(             'components' => array(                 'config' => array(                     'class' => 'EConfig',                     'strictMode' => false,                 ),             ),         ),      ), ... 

Вот и всё, модуль подключен.

Используем

Естественно сама по себе страничка нам нафиг не упала, нам нужен какой-то способ доступа к информации хранящейся в БД. Для данного конкретного примера мы можем реализовать загрузку данных в файле index.php нашего приложения:

$app = Yii::createWebApplication($config);  function loadSettings() {     Yii::app()->getModule('gii')->password = Yii::app()->getModule('configpage')->config->get('giiPassword');     Yii::app()->name = Yii::app()->getModule('configpage')->config->get('applicationName');     Yii::app()->params['adminEmail'] = Yii::app()->getModule('configpage')->config->get('adminEmail'); }  loadSettings();  $app->run(); 

То есть, мы создаём экземпляр приложения, оно подгружает модули и настройки, затем мы перезаписываем некоторые из настроек и только после этого выполняем приложение.
Как-то так. Единственное, что мне не нравится — это строка вызова метода get:

Yii::app()->getModule('configpage')->config->get('applicationName'); 

Уж слишком она длинная. К сожалению придумать как её укоротить я пока не могу. Может кто подскажет?

Ну и куда же без картинок. Вот что у нас примерно должно получиться в итоге:
image

За картинку кстати не ругайте, если найдёте сходство с данным проектом. OpenSource, все дела, можно использовать чужие наработки. В данном случае — понравилось расположение панельки слева. В остальном никакого сходства =). Ди а вообще, Twitter Bootstrap он везде одинаковый.

Из позитивного

Я по специализации вообще-то нифига не web-разработчик, но почему-то в последнее время всё больше приходится заниматься именно данным видом кодинга. И почему-то мне нравится, куда проще чем Qt и C++ =). Когда я открыл для себя такие вещи как генерация кода, фреймворк Yii, Twitter Bootstrap и множество других ништяков, я понял что проекты под web могут вылетать из под пера более-менее опытного разработчика как горячие пирожки — по три штуки в месяц.

Так что кипящие в соседних топиках дискуссии о постоянной нехватке квалифицированных кадров — какая-то глупость.

Современные средства разработки настолько просты, что 90% работы можно выполнить никогда так и не узнав разницы между MySql индексами типа BTree и hash. А оставшиеся 10% всегда можно где-то подглядеть.

Ну да ладно, всё это лирика.

Что ещё хотелось бы отметить

Расширить данный модуль очень легко — достаточно добавить ещё по одному экзепляру контроллера, модели, описания формы и вьюшки. А можно обойтись и меньшими усилиям — новый action, описалово формы и модель. Вьюшку можно юзать ту же самую. И тогда у вас будет уже две-три-десять независимых друг от друга страниц настроек.

Для меня кстати унификация и оптимизация — это вообще болезнь, так что хотелось бы конечно прикрутить ко всему этому интерфейс по редактированию полей формы настроек прямо в браузере, но это уже в каком-нибудь другом проекте.

Вообще после года работы с Yii у меня накопился целый ящик всяких примеров, архитектурных решений и извращений, всё собираюсь их по человечески описать, но как обычно время, время…

Вроде всё. Вопросы? Предложения?

Стоит ли мне дальше писать про Yii?

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Никто ещё не голосовал. Воздержавшихся нет.

ссылка на оригинал статьи http://habrahabr.ru/post/172737/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *