Skip to content

Latest commit

 

History

History
346 lines (282 loc) · 18.6 KB

README_ru.md

File metadata and controls

346 lines (282 loc) · 18.6 KB

Универсальный модуль под Yii2

English version

Содержание


Цель

Данное расширение предоставляет структуру модуля, который:

  1. Будет полностью самодостаточным и переносимым, т.к. в одной папке содержит весь свой функционал

  2. Логически разделен на backend и frontend части

  3. Легко подключается как на Advanced так и на Basic шаблоны приложений

  4. На Basic шаблоне приложения:

    • Подключается в секцию модулей один раз
    • Имеется возможность защиты всех backend контроллеров (для админок)
  5. Легко наследовать такие модуля один от другого, для переопределения функционала, без дублирования контроллеров


Установка

Установка через composer:

Выполните

composer require --prefer-dist mgrechanik/yii2-universal-module-sceleton

или добавьте

"mgrechanik/yii2-universal-module-sceleton" : "~1.0.0"

в require секцию вашего composer.json файла.


Суть идеи

  • По умолчанию в Yii2 модулях контроллеры ищутся автоматически в $controllerNamespace
  • Мы намеренно не используем эту функцию, а задаем все контроллеры через $controllerMap модуля
  • Но делаем это не через $controllerMap свойство напрямую, а отдельно указываем какие контроллеры для backend, а какие для frontend
  • У модуля есть режим работы , выставляемый в конфиге, в соответствии с которым в карту контроллеров попадут только соответствующие данному режиму контроллеры:
    • В frontend приложении Advanced шаблона, мы подключаем модуль в режиме 'frontend'
    • В backend приложении Advanced шаблона, мы подключаем модуль в режиме 'backend'
    • В Basic шаблоне, мы можем подключить модуль как в вышеописанных режимах так и в режиме 'backend and frontend', т.е. когда оба типа контроллеров доступны
  • Модуль, получая запрос, создает контроллер из их карты, при этом по его пространству имен зная
    backend или frontend это контроллер, для дополнительной настройки
  • Модуль ожидает следующую структуру папок:
Папка_с_модулем/
   ui/                                  // User Interface данного модуля
      controllers/
          backend/                      // Backend контроллеры, например следующий:
            AdminDefaultController.php  
            ...
          frontend/                     // Frontend контроллеры, например следующий: 
            DefaultController.php       
            ...
      views/                            // Views для соответствующих контроллеров  
          backend/
            admin-default/
          frontend/        
            default/
   Module.php                           // класс модуля

Использование

  1. Сгенерируйте, или создайте сами, класс своего модуля

  2. Отнаследуйтесь вашим модулем от универсального модуля

use mgrechanik\yiiuniversalmodule\UniversalModule;

class YourModule extends UniversalModule
{
  1. Теперь создадим (или сгенерируем) frontend контроллер
  • Учитываем что его namespace должен быть yourModuleNamespace\ui\controllers\frontend
  • Создайте предварительно все упоминаемые подпапки
  • Соответственно контроллеру views складываются в @yourModuleNamespace/ui/views/frontend/YourControllerName/
  • Мы должны указать этот контроллер в карте frontend контроллеров модуля:
class YourModule extends UniversalModule
{
    public $frontendControllers = [
        'default',
    ];

, где 'default' обозначает соответственно yourModuleNamespace\ui\controllers\frontend\DefaultController.
Если ваши имена контроллера и класса не совпадают, задайте в форме 'default2' => 'SomeDefaultController'.

Всегда, создавая свои контроллеры, не забывайте прописать их в соответствующую карту контроллеров модуля.

Классы контроллеров не требуется наследовать от какого то общего типа.

  1. Теперь создадим (или сгенерируем) backend контроллер
  • Логика по аналогии с пунктом 3), но его namespace должен быть yourModuleNamespace\ui\controllers\backend
  • Указывать в модуле в:
class YourModule extends UniversalModule
{
    public $backendControllers = [
        'admin-default',
    ];
  • Именовать backend контроллеры удобно с помощью префикса Admin, чтобы всем таким адресам потом единообразно настроить урлы на начинающиеся не с имени модуля, а с admin/
  1. Все, ваш модуль готов, можно подключить его в приложение:

config/main.php:

    // ...
    'modules' => [
        'yourModule' => [
            'class' => 'yourModuleNamespace\YourModule',
            'mode' => 'frontend',
        ],

, не забывая выставить его mode - режим

Все такие модули удобно подключать на первом уровне модулей, без всяких вложенных структур, а как список модулей, который мы привыкли видеть в админках популярных CMS-ок, что к тому же дает короткие урлы.


Наследование модулей

Когда вы наследуете класс вашего модуля от другого существующего, без переопределения $frontendControllers и $backendControllers, происходят следующие вещи:

  1. Вот эти два свойства естественно возьмутся у модуля родителя
  2. Но базовое пространство имен для этих контроллеров по умолчанию будет устанавливаться в пространство имен вашего модуля. У вас этих контроллеров нет и вы не хотите создавать себе их копии
  3. Имеются следующие возможности как указать модулю взять контроллеры от родителя:
    • Если контроллеры располагаются у непосредственного родителя вашего модуля, то установите вашему модулю свойство $takeControllersFromParentModule = true
    • Если же контроллеры в каком то другом модуле, например 'Omega', то установите вашему модулю свойство $baseControllerNamespace в namespace этого модуля 'Omega'
    • Views-ы будут по умолчанию искаться в зависимости от настроек выше

Настройка модуля

Подключяя модуль в приложение мы можем воспользоваться следующими его свойствами:

$mode - режим работы модуля

Обязательное свойство для установки. Подробнее

$backendLayout - layout для backend контроллеров

Указывается layout, устанавливаемый модулю, когда обращение идет к backend контроллеру.
Полезно для Basic шаблона приложения.

$frontendControllers - карта frontend контроллеров

Подробнее

$backendControllers - карта backend контроллеров

Подробнее

$controllerMapAdjustCallback - callback для финальной настройки карты контроллеров

После того как карта контроллеров модуля сгенерирована, ее можно тонко настроить этой функцией, ее сигнатура: function($map) { ...; return $map; }

$backendControllerConfig - настройки backend контроллеров

Когда модуль создает backend контроллер он перед работой может настроить его данными свойствами.

Удобно, например, чтобы через поведение закрыть доступ к таким контроллерам через фильтры доступа.

Пример использования.

$frontendControllerConfig - настройки frontend контроллеров

По аналогии с $backendControllerConfig

$baseControllerNamespace - базовое пространство имен для используемых модулем контроллеров

По умолчанию не используется, контроллеры будут браться из пространства имен вашего модуля.
Но этим свойством можно изменить на пространство имен любого другого модуля, контроллеры будут браться оттуда

$takeControllersFromParentModule - брать ли контроллеры от родителя

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

$baseViewsPath - базовый путь для views-ов модуля

По умолчанию не используется.
Устанавливается или к папке текущего модуля или если два свойства выше изменены, то относительно них.
Но этим свойством можно финально изменить откуда брать views-ы. Пример значения: '@mgrechanik/yii2catalog'


Пример подключения на Basic шаблоне

Предположим что у нас имеется два таких наших модуля - example и omega.
Для их подключения вот пример рабочих конфигов:

config/params.php:

return [
    'backendLayout' => '//lte/main',
    'backendControllerConfig' => [
        'as backendaccess' => [
            'class' => \yii\filters\AccessControl::class,
            'rules' => [
                [
                    'allow' => true,
                    'ips' => ['54.54.22.44'],
                    'matchCallback' => function ($rule, $action){
                        $user = \Yii::$app->user;
                        return !$user->isGuest &&
                            ($user->id == 1);
                },
                ]
            ],
        ],
    ],	
  
];

В данном примере мы разрешили доступ "в админку" только одному указанному пользователю (id==1), плюс ограничиваем по ip.

config/web.php:

    'components' => [
	//...
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
                'admin/<module:(example|omega)>-<controllersuffix>/<action:\w*>' =>
                    '<module>/admin-<controllersuffix>/<action>',
                'admin/<module:(example|omega)>-<controllersuffix>' =>
                    '<module>/admin-<controllersuffix>',
            ],
        ],	
    ],
    'modules' => [
        'example' => [
            'class' => 'modules\example\Module',
            'mode' => 'backend and frontend',
            'backendLayout' => $params['backendLayout'],
            'backendControllerConfig' => $params['backendControllerConfig'],
        ],
        'omega' => [
            'class' => 'modules\username1\omega\Module',
            'mode' => 'backend and frontend',
            'backendLayout' => $params['backendLayout'],
            'backendControllerConfig' => $params['backendControllerConfig'],
        ],        
    ], 

Рецепты

Делаем чтобы все админские адреса начинались с /admin

Рассмотрим Basic приложение, к которому мы подключили два наших модуля:

    'modules' => [
        'example' => [
            ...
        ],
        'omega' => [
            ...
        ],  

Если мы следовали совету насчет админских контроллеров, то все они именуются по шаблону Admin...Controller.
Соответственно адреса к ним будут вида example/admin-default и omega/admin-default.
Мы же хотим чтобы все админские адреса начинались с admin/.

Это легко достигается следующими двумя правилами вашего urlManager:

	'urlManager' => [
		'enablePrettyUrl' => true,
		'showScriptName' => false,
		'rules' => [
			'admin/<module:(example|omega)>-<controllersuffix>/<action:\w*>' =>
				'<module>/admin-<controllersuffix>/<action>',
			'admin/<module:(example|omega)>-<controllersuffix>' =>
				'<module>/admin-<controllersuffix>',
		],
	],

Генерация функционала backend-а с помощью Gii CRUD generator

Вы легко можете сгенерировать функционал CRUD-а как обычно, учитывая:

  • Имя контроллера и его пространство имен выбирайте соответственно документации
  • View Path указывайте соответственно структуре папок требуемой модулем

Как подключать модуль в консольное приложение?

Если в вашем модуле предусмотрены консольные команды, которые располагаются например тут:

Папка_с_модулем/
  console/
    commands/                // Папка для консольных комманд
      HelloController.php
  Module.php

, то в конфиге консольного приложения данный модуль подключается:

    'modules' => [
        'example' => [
            'class' => 'modules\example\Module',
            'controllerNamespace' => 'yourModuleNamespace\console\commands',
        ],
    ],

Куда располагать остальной функционал модуля?

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

  • Если компонент четко относится только к одному типу - backend или frontend, то и помещайте его в соответствующую подпапку
  • Если же такого разделения нет, то располагайте его в корне его папки.
    Например для моделей
  models/
    backend/
      SomeBackendModel.php
    frontend/
      SomeFrontendModel.php	  
    SomeCommonModel.php  
  • Т.к. для пользовательского интерфейса мы в модуле уже создали подпапку ui/, то формы и виджеты следует располагать там