'dispatcher' => [ 'class' => 'app\modules\dispatcher\Module', ],
<?php namespace app\modules\dispatcher; use app\modules\dispatcher\components\Controller; use app\modules\dispatcher\models\LayoutModule; /** * * Class Module * @package app\modules\dispatcher\components * */ class BasicModule extends \yii\base\Module { const POSITION_HEADER = 'header'; const POSITION_FOOTER = 'footer'; const POSITION_LEFT = 'left'; const POSITION_RIGHT = 'right'; /** * @var array of positions */ static protected $positions = [ self::POSITION_HEADER, self::POSITION_FOOTER, self::POSITION_LEFT, self::POSITION_RIGHT, ]; /** * @var string controller name */ public $defaultControllerName = 'DefaultController'; /** * @var string dir of modules catalog */ public $modulesDir = 'catalog'; /** * @var string modules namespace */ private $_modulesNamespace; /** * @var string absolute path to modules dir */ public $modulePath; /** * * @throws \yii\base\InvalidParamException */ public function init() { parent::init(); $this->_setModuleVariables(); $this->loadModules(); } /** * Load modules from directory by path * @throws \yii\base\InvalidParamException */ protected function loadModules() { $handle = opendir($this->modulePath); while (($dir = readdir($handle)) !== false) { if ($dir === '.' || $dir === '..') { continue; } $class = $this->_modulesNamespace . '\\' . $dir . '\\Module'; if (class_exists($class)) { $this->modules = [ $dir => [ 'class' => $class, ], ]; } } closedir($handle); } /** * @param $layout * @param array $positions * @return array * @throws \yii\base\InvalidConfigException */ public function run($layout, array $positions = []) { $model = $this->findModel($layout, $positions); $data = []; foreach ($model as $item) { if ($controller = $this->findModuleController($item['module'])) { $data[$item['position']][] = \Yii::createObject($controller, [$item['module'], $this])->index(); } } return $data; } /** * @param $layout_id * @param array $positions * @return array|\yii\db\ActiveRecord[] * @internal param $layout */ public function findModel($layout_id, array $positions = []) { if (empty($positions)) { $positions = self::$positions; } return LayoutModule::find() ->where([ 'layout_id' => $layout_id, 'position' => $positions, 'status' => LayoutModule::STATUS_ACTIVE, ])->orderBy([ 'sort_order' => SORT_ASC ])->asArray()->all(); } /** * @param $name * @return null|string */ public function findModuleController($name) { $className = $this->_modulesNamespace . '\\' . $name . '\controllers\\' . $this->defaultControllerName; return is_subclass_of($className, Controller::class) ? $className : null; } /** * Set modules namespace and path */ private function _setModuleVariables() { $class = new \ReflectionClass($this); $this->_modulesNamespace = $class->getNamespaceName() . '\\' . $this->modulesDir; $this->modulePath = dirname($class->getFileName()) . DIRECTORY_SEPARATOR . $this->modulesDir; } }
<?php namespace app\modules\dispatcher; /** * dispatcher module definition class */ class Module extends BasicModule { /** * @inheritdoc */ public function init() { parent::init(); } }
public $table = '{{%layout_module}}'; public function safeUp() { $tableOptions = null; if ($this->db->driverName === 'mysql') { $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; } $this->createTable($this->table, [ 'id' => $this->primaryKey(), 'layout_id' => $this->integer()->notNull(), // id 'module' => $this->string(150)->notNull(), // 'status' => $this->boolean()->defaultValue(true), 'position' => $this->string(30)->notNull(), 'sort_order' => $this->integer()->defaultValue(1), ], $tableOptions); } public function safeDown() { $this->dropTable($this->table); }
INSERT INTO `layout_module` VALUES ('1', '1', 'test', '1', 'header', '1'); INSERT INTO `layout_module` VALUES ('2', '1', 'test', '1', 'footer', '1'); INSERT INTO `layout_module` VALUES ('3', '1', 'test', '1', 'left', '1');
<?php namespace app\modules\dispatcher\components; /** * * Class Controller * @package app\modules\dispatcher\components */ class Controller extends \yii\web\Controller { /** * @param string $view * @param array $params * @return string * @throws \yii\base\InvalidParamException * @throws \yii\base\ViewNotFoundException * @throws \yii\base\InvalidCallException */ public function render($view, $params = []) { $controller = str_replace('Controller', '', $this->module->defaultControllerName); $path = '@app/modules/dispatcher/' . $this->module->modulesDir . '/' . $this->id . '/views/' . $controller; return $this->getView()->render($path . '/' . 'index', $params, $this); } }
<?php namespace app\modules\dispatcher\catalog\test; /** * test module definition class */ class Module extends \yii\base\Module { /** * @inheritdoc */ public $controllerNamespace = 'app\modules\dispatcher\catalog\test\controllers'; }
<?php namespace app\modules\dispatcher\catalog\test\controllers; use app\modules\dispatcher\components\Controller; /** * Default controller for the `test` module */ class DefaultController extends Controller { /** * Renders the index view for the module * @return string * @throws \yii\base\InvalidParamException * @throws \yii\base\ViewNotFoundException * @throws \yii\base\InvalidCallException */ public function index() { return $this->render('index'); } }
<div class="dispatcher-default-index"> <p> You may customize this page by editing the following file:<br> <code><?= __FILE__ ?></code> </p> </div>
<?php namespace app\modules\dispatcher\components; use yii\base\Object; class Dispatcher extends Object { /** * @var \app\modules\dispatcher\Module */ private $_module; public $module = 'dispatcher'; /** * Dispatcher constructor. * @param array $config */ public function __construct(array $config = []) { parent::__construct($config); $this->_module = \Yii::$app->getModule($this->module); } /** * Get modules by layout * * @param $layout * @param array $positions * @return array * @throws \yii\base\InvalidConfigException */ public function modules($layout, array $positions = []) { return $this->_module->run($layout, $positions); } }
'dispatcher' => [ 'class' => 'app\modules\dispatcher\components\Dispatcher', ],
/* @var $modules Dispatcher */ $modules = \Yii::$app->dispatcher->modules(1); return $this->render('index', compact('modules'));
<?php /* @var $this yii\web\View */ $this->title = 'My Yii Application'; use app\modules\dispatcher\Module; ?> <div class="site-index"> <?php if (isset($modules[Module::POSITION_HEADER])) { ?> <div class="row"> <?php foreach ($modules[Module::POSITION_HEADER] as $module) { echo $module; } ?> </div> <?php } ?> <div class="jumbotron"> <h1>Congratulations!</h1> <p class="lead">You have successfully created your Yii-powered application.</p> <p><a class="btn btn-lg btn-success" href="http://www.yiiframework.com">Get started with Yii</a></p> </div> <div class="body-content"> <div class="row"> <div class="col-lg-4"> <h2>Heading</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p> <p><a class="btn btn-default" href="http://www.yiiframework.com/doc/">Yii Documentation »</a></p> </div> <div class="col-lg-4"> <h2>Heading</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p> <p><a class="btn btn-default" href="http://www.yiiframework.com/forum/">Yii Forum »</a> </p> </div> <div class="col-lg-4"> <h2>Heading</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p> <p><a class="btn btn-default" href="http://www.yiiframework.com/extensions/">Yii Extensions »</a></p> </div> </div> </div> <?php if (isset($modules[Module::POSITION_FOOTER])) { ?> <div class="row"> <?php foreach ($modules[Module::POSITION_FOOTER] as $module) { echo $module; } ?> </div> <?php } ?> </div>
Source: https://habr.com/ru/post/317950/
All Articles