- Цель
- Установка
- Суть идеи
- Использование
- Наследование модулей
- Настройка модуля
- Пример подключения на Basic шаблоне
- Рецепты
Данное расширение предоставляет структуру модуля, который:
-
Будет полностью самодостаточным и переносимым, т.к. в одной папке содержит весь свой функционал
-
Логически разделен на backend и frontend части
-
Легко подключается как на Advanced так и на Basic шаблоны приложений
-
На Basic шаблоне приложения:
- Подключается в секцию модулей один раз
- Имеется возможность защиты всех backend контроллеров (для админок)
-
Легко наследовать такие модуля один от другого, для переопределения функционала, без дублирования контроллеров
Установка через 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'
, т.е. когда оба типа контроллеров доступны
- В frontend приложении Advanced шаблона, мы подключаем модуль в режиме
- Модуль, получая запрос, создает контроллер из их карты, при этом по его пространству имен зная
backend или frontend это контроллер, для дополнительной настройки - Модуль ожидает следующую структуру папок:
Папка_с_модулем/
ui/ // User Interface данного модуля
controllers/
backend/ // Backend контроллеры, например следующий:
AdminDefaultController.php
...
frontend/ // Frontend контроллеры, например следующий:
DefaultController.php
...
views/ // Views для соответствующих контроллеров
backend/
admin-default/
frontend/
default/
Module.php // класс модуля
-
Сгенерируйте, или создайте сами, класс своего модуля
-
Отнаследуйтесь вашим модулем от универсального модуля
use mgrechanik\yiiuniversalmodule\UniversalModule;
class YourModule extends UniversalModule
{
- Теперь создадим (или сгенерируем) 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'
.
Всегда, создавая свои контроллеры, не забывайте прописать их в соответствующую карту контроллеров модуля.
Классы контроллеров не требуется наследовать от какого то общего типа.
- Теперь создадим (или сгенерируем) backend контроллер
- Логика по аналогии с пунктом 3), но его
namespace
должен бытьyourModuleNamespace\ui\controllers\backend
- Указывать в модуле в:
class YourModule extends UniversalModule
{
public $backendControllers = [
'admin-default',
];
- Именовать backend контроллеры удобно с помощью префикса Admin, чтобы всем таким адресам потом единообразно настроить урлы на начинающиеся не с имени модуля, а с admin/
- Все, ваш модуль готов, можно подключить его в приложение:
config/main.php:
// ...
'modules' => [
'yourModule' => [
'class' => 'yourModuleNamespace\YourModule',
'mode' => 'frontend',
],
, не забывая выставить его mode - режим
Все такие модули удобно подключать на первом уровне модулей, без всяких вложенных структур, а как список модулей, который мы привыкли видеть в админках популярных CMS-ок, что к тому же дает короткие урлы.
Когда вы наследуете класс вашего модуля от другого существующего, без переопределения $frontendControllers
и $backendControllers
, происходят следующие вещи:
- Вот эти два свойства естественно возьмутся у модуля родителя
- Но базовое пространство имен для этих контроллеров по умолчанию будет устанавливаться в пространство имен вашего модуля. У вас этих контроллеров нет и вы не хотите создавать себе их копии
- Имеются следующие возможности как указать модулю взять контроллеры от родителя:
- Если контроллеры располагаются у непосредственного родителя вашего модуля, то установите вашему модулю
свойство
$takeControllersFromParentModule = true
- Если же контроллеры в каком то другом модуле, например
'Omega'
, то установите вашему модулю свойство$baseControllerNamespace
в namespace этого модуля'Omega'
Views
-ы будут по умолчанию искаться в зависимости от настроек выше
- Если контроллеры располагаются у непосредственного родителя вашего модуля, то установите вашему модулю
свойство
Подключяя модуль в приложение мы можем воспользоваться следующими его свойствами:
Обязательное свойство для установки. Подробнее
Указывается layout
, устанавливаемый модулю, когда обращение идет к backend контроллеру.
Полезно для Basic шаблона приложения.
После того как карта контроллеров модуля сгенерирована, ее можно тонко настроить этой функцией,
ее сигнатура: function($map) { ...; return $map; }
Когда модуль создает backend контроллер он перед работой может настроить его данными свойствами.
Удобно, например, чтобы через поведение закрыть доступ к таким контроллерам через фильтры доступа.
По аналогии с $backendControllerConfig
По умолчанию не используется, контроллеры будут браться из пространства имен вашего модуля.
Но этим свойством можно изменить на пространство имен любого другого модуля, контроллеры будут браться оттуда
По умолчанию false
- не брать.
Но этим свойством можно изменить и взять контроллеры от непосредственного модуля родителя
По умолчанию не используется.
Устанавливается или к папке текущего модуля или если два свойства выше изменены, то относительно них.
Но этим свойством можно финально изменить откуда брать views
-ы. Пример значения: '@mgrechanik/yii2catalog'
Предположим что у нас имеется два таких наших модуля - 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'],
],
],
Рассмотрим 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>',
],
],
Вы легко можете сгенерировать функционал 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/
, то формы и виджеты следует располагать там