Skip to content
seregagl edited this page Feb 27, 2013 · 11 revisions

Исходники

Что для нас "простой модуль"

В backend модуль представляет собой набор из хотя бы 1 контроллера, 1 модели, index-view и _form-view, расположенными в соответствующих поддиректориях модуля. Сам модуль должен иметь путь backend/protected/modules/moduleName.

Структура директории модуля

  • components (не обязательно)
  • controllers
  • BModelController.php
  • exceptions (не обязательно)
  • models
  • BModel.php
  • views
  • index.php
  • _form.php
  • ModuleNameModule.php

Модуль "гарантия"

Что там будет?

Модуль будет представлять собой набор статей по обслуживанию чего-нибудь с возможностью комментирования статьи и отправкой запроса на обслуживание.

Статьи - backend

Структура

  • controllers
    • BWarrantyArticleController.php
  • models
    • BWarrantyArticle.php
  • views
    • warrantyArticle
      • index.php
      • _form.php
  • WarrantyModule.php

После создания директорий и файлов можно приступить к созданию класса модуля.

Module

class WarrantyModule extends BModule
{
    public $name = 'Гарантия'; // Имя модуля в меню
    public $defaultController = 'BWarrantyArticle'; // стандартный контроллер модуля
}

Controller

class BWarrantyArticleController extends BController
{
    public $name = 'Статьи'; // Название пункта в меню модуля
    public $modelClass = 'BWarrantyArticle'; // Название класса, с которым будет работать контроллер
}

Model

Для начала необходимо создать таблицу в БД (используется mysql)

CREATE TABLE IF NOT EXISTS `warranty_article` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8 NOT NULL,
  `notice` text CHARACTER SET utf8,
  `content` text CHARACTER SET utf8,
  `visible` int(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

После этого можно приступать к созданию самой модели

class BWarrantyArticle extends BActiveRecord
{
    /**
     * @return array
     */
    public function rules()
    {
        return [
            ['name', 'required'],
            ['name', 'length', 'max' => 255],
            ['visible', 'numerical', 'integerOnly' => true],
            ['notice, content', 'safe'],
        ];
    }
}

В данном случае название модели соответствует названию таблицы в БД (warranty_article => BWarrantyArticle), в противном случае наша модель выглядела бы следующим образом

class BWarrantyArticle extends BActiveRecord
{
    /**
     * @return string
     */
    public function tableName()
    {
        return '{{tbl_name}}'; // Название таблицы используется внутри "{{}}" для подстановки префикса таблиц в БД
    }
    
    /**
     * @return array
     */
    public function rules()
    {
        return [
            ['name', 'required'],
            ['name', 'length', 'max' => 255],
            ['visible', 'numerical', 'integerOnly' => true],
            ['notice', 'content', 'safe']
        ];
    }
}

С моделью закончили, можем переходить к представлениям.

Views

Для корректной работы нам необходимо index.php и _form.php. Создаем их в директории warrantyArticle.

index.php будет выглядеть следующем образом:

<?php
Yii::app()->breadcrumbs->show(); // используется для отображения хлебных крошек

$this->widget('BGridView', [
    'dataProvider' => $dataProvider,
    'columns' => [
        ['name' => 'name', 'filter' => false],
        ['name' => 'notice', 'filter' => false],
        ['name' => 'content', 'filter' => false],

        ['class' => 'JToggleColumn', 'name' => 'visible', 'filter' => false], // Переключение свойства visible
        ['class' => 'BButtonColumn'], // Колонка с кнопками редактирования и удаления записи
    ],
]);

В index.php доступны несколько переменных:

  • $model - объект модели, указанной в BWarrantyArticleController::$modelClass
  • $dataPovider - BActiveDataProvider

Теперь можно перейти к _form.php

<?php
Yii::app()->breadcrumbs->show(); // испорльзуется для отображения хлебных крошек

$form = $this->beginWidget('BActiveForm', array('id' => $model->getFormId()));
$this->renderPartial('//_form_buttons', array('model' => $model));
echo $form->errorSummary($model);
echo $form->renderRequire();
?>

<table class="detail-view table table-striped table-bordered">
  <tbody>
      <?php echo $form->textFieldRow($model, 'name');?>

      <?php echo $form->textAreaRow($model, 'notice');?>
      <?php echo $form->textAreaRow($model, 'content');?>

      <?php echo $form->checkBoxRow($model, 'visible');?>
  </tbody>

</table>

<?php
$this->renderPartial('//_form_buttons', array('model' => $model));
$this->endWidget();

В _form.php также уже доступнен объект модели, указанной в BWarrantyArticleController::$modelClass

Добавление фильтров в index.php

Для того, чтобы добавить строковый фильтр на разводную страницу в backend необходимо просто не передавать 'filter' в список для вывода и определить метод поиска для модели. После всех изменений наша модель будет выглядеть следующим образом

class BWarrantyArticle extends BActiveRecord
{
    /**
     * @return array
     */
    public function rules()
    {
        return [
            ['name', 'required'],
            ['name', 'length', 'max' => 255],
            ['visible', 'numerical', 'integerOnly' => true],
            ['notice, content', 'safe']
        ];
    }
    
    public function search()
    {
        $criteria = new CDbCriteria();
        
        $criteria->compare('name', $this->name, true);
        $criteria->compare('visible', $this->visible);
        
        return new BActiveDataProvider($this, [
            'criteria' => $criteria,
        ]);
    }
}

И index.php

<?php
Yii::app()->breadcrumbs->show(); // испорльзуется для отображения хлебных крошек

$this->widget('BGridView', [
    'dataProvider' => $model->search(),
    'filter' => $model,
    'columns' => [
        ['name' => 'name'], // Будем использовать только фильтр по имени
        ['name' => 'notice', 'filter' => false],
        ['name' => 'content', 'filter' => false],

        ['class' => 'JToggleColumn', 'name' => 'visible', 'filter' => CHtml::listData($model->yesNoList(), 'id', 'name')], // Фильтр по свойству видимости
        ['class' => 'BButtonColumn'],
    ],
]);

Статьи - frontend

Model

Создаем директорию protected/models/warranty и в ней WarrantyArticle.php

class WarrantyArticle extends FActiveRecord
{
}

В данном случае у нас опять же совпадают названия модели и таблицы (warranty_article => WarrantyArticle), иначе необходимо было бы дописать соответствующий метод tableName(). Правила валидация также не нужны, если модель не используется в формах.

В случае использования свойства видимости, желательно использователь defaultScope()

class WarrantyArticle extends FActiveRecord
{
    /**
     * @return array
     */
    public function defaultScope()
    {
        return [
            'condition' => '`visible` = 1',
        ];
    }
}

Controller

По необходимости, но для примера можно использовать собственный контроллер для создания страницы со статьями

Yii::import('frontend.models.warranty.*'); // импорт моделей

class WarrantyController extends FController
{
    public function actionIndex()
    {
        $articles = WarrantyArticle::model()->findAll();

        return $this->render('index', ['articles' => $articles]);
    }

    public function actionArticle($id)
    {
        $article = WarrantyArticle::model()->findByPk($id);

        if( $article === null )
            throw new CHttpException(404);

        $this->render('article', ['article' => $article]);
    }
}

Routes

Для добавления / составление роутов используется protected/config/routes.php. Добавляем туда следующие правила роутов для контроллера

'warrantyArticles' => ['warranty/index', 'pattern' => 'warranty'],
'warrantyArticle'  => ['warranty/article', 'pattern' => 'warranty/<id:\d+>'],

Теперь если перейти по /warranty (при наличии доступных статей) будет отображен их список

Views

Все представления на frontend хранятся в директории protected/views/controllerId, где controllerId в данном случае warranty. Вывод уже оставлю уже на твою фантазию, %username% :)