Динамическое подключение модулей в Yii2

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

При разработке я использовал базовый шаблон приложения.

В папке components создадим файл ModuleManager.php для управления подключаемыми модулями.

Листинг файла ModuleManager.php:

<?php

namespace app\components;

use Yii;
use yii\base\Component;
use yii\base\BootstrapInterface;

class ModuleManager extends Component implements BootstrapInterface
{
  public function bootstrap($app)
  {
    Yii::$app->setModule('admin', [
      'class' => 'app\modules\admin\Admin'
    ]);

    Yii::$app->getModule('admin')->bootstrap(Yii::$app);

    Yii::$app->setModule('welcome', [
      'class' => 'app\modules\welcome\Welcome'
    ]);

    Yii::$app->getModule('welcome')->bootstrap(Yii::$app);
  }
}

В выше указанном файле я подключаю модули вручную. Можно сделать подключение с использованием базы данных (оставляю на вашу фантазию).

Теперь приведу пример модуля admin. Он располагается в папке modules/admin.

Структура модуля admin

Листинг файла Admin.php:

<?php

namespace app\modules\admin;

use app\components\ModuleInterface;

/**
 * Class Admin Module
 * @package app\modules\admin
 */
class Admin extends \yii\base\Module implements ModuleInterface
{
    /**
     * @var string the namespace that controller classes are in.
     */
    public $controllerNamespace = 'app\modules\admin\controllers';

    /**
     * Initializes the module.
     */
    public function init()
    {
    	parent::init();
    }

  /**
   * Bootstrap method to be called during application bootstrap stage.
   * @param \app\components\Application $app
   */
  public function bootstrap($app)
  {
    $app->getUrlManager()->addRules([
      'admin/test' => 'admin/default/test',
    ]);
  }
}

Листинг файла ModuleInterface.php:

<?php

namespace app\components;

/**
 * Interface ModuleInterface
 * @package app\components
 */
interface ModuleInterface
{
  /**
   * Initializes the module.
   */
  public function init();

  /**
   * Bootstrap method to be called during application bootstrap stage.
   * @param Application $app the application currently running
   */
  public function bootstrap($app);

}

Данный интерфейс будет использоваться во всех модулях. В функции bootstrap() мы описываем все правила для маршрутизации, если они нужны.

Теперь необходимо подключить класс ModuleManager в конфигурационном файле приложения (web.php).

$db = require(__DIR__ . '/db.php');

$config = [
    ...
    'bootstrap' => [
    	'log',
        'app\components\ModuleManager'
    ],
    ...
];

return $config;

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

Еще можно было бы хранить маршруты, например в файле Bootstrap, наследующего интерфейс BootstrapInterface. Однако, подключение все равно пришлось бы делать в конфиге приложения.

Теперь вы можете сделать любую реализацию подключения модулей в файле ModuleManager.php.

Будут вопросы, пишите.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

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

Сообщить об опечатке

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