Closed cv65kr closed 6 years ago
Hi! I'm just trying to separate modules from each other. The idea is to be able to reuse modules without editing their relations.
Main problem is to make communication via modules thin and clear, so I decided to try the Mediator pattern + Observer pattern (with Yii2 global events) Mediator pattern is well illustrated here:
Mediator knows about all modules (colleagues) and able to receive, process and send events. Modules have to communicate only with Mediator, not with each other. The problem is that some business logic leaks to the Mediator. So we need to find the balance between the module responsibility and Mediator. Mediator should not turn into the "god" object... as described in the article above…
Technically modules can subscribe to each other and send events with Yii without mediator. Maybe this part has to be strict and we should use only strongly typed messages to restrict such type of communication. On the other hand it is very flexible and Yii-styled… Developers should decide who can communicate and how at the logical level. Time will tell.
Sorry if Im not clear enough… As usual it is not enough free time...
This is another attempt to develop a perfect app though we know that it is impossible… But it is interesting :)
"Modules should not know about each other" Let's assume that i have module "modules/menu", to manage i must create MenuController in "modules/admin/controllers".
If not a better solution is "modules/menu/controllers" have a structure IndexController - Frontend controller AdminController - Backend controller
Maybe we can make Admin module will recognize whether AdminController isset in controllers of module and create dynamicly nav with all modules.
What You think?
Do You want separate login frontend and backend. Whether it will one login panel checking database column role?
About menu I think modules has to register their menu items during bootstrap. Application should save them somewhere in global namespace (eg Yii::$app->params['menu']['backend'] or even Yii::$app->menu['backend']). Every module can use unique abstract key for storing menu (backend, frontend, etc).
Admin, Email and Log modules can register menu with 'backend' key index.
Smth like this:
Module::registerMenu('backend', 'items')
Then we can show menu in admin layout.
Disadvantages of this approach is we should use a common layout for all backend modules
So result array might look like this
'backend' => [
'users' => [
'label' => '<span class="icon icon-users"></span> Users',
'url' => ['/admin/users'], // in terms of Url::to() method
'items' => [
'create' => ['/admin/users/create'],
'stats' => [
'label' => 'Statistics',
'url' => ['/admin/users/statistics']
]
]
],
'logs' => ['/admin/logs'] // or just /log
],
'frontend' => [
'item' => 'itemUrl',
'item2' => 'item2Url'
]
Do You want separate login frontend and backend. Whether it will one login panel checking database column role?
It depends on tasks of Your app. This skeleton is just concept for building big web application with modules. I think we should think in terms of independent module. I will try to leave ActiveRecord class UserRecord to handle database operations. But domain models (or FormModels) should be described in every module. Including LoginModel.
I'll try to finish menu and user managment this weekend)
I tried to write a simple test app on Your modular skeleton. I got stuck on change UrlManager class in site module. config/web.php supports only routes so I tried to change it in site/Module.php: I used default function setCompontent but rules from config/web.php are ignored:
namespace modules\site;
class Module extends \common\base\Module
{
public function init()
{
\Yii::$app->setComponents([
'urlManager' => [
'class' => 'modules\site\components\UrlManager'
]
]);
parent::init();
}
}
If I understood you correctly there is no need to change urlManager in the module. It is global feature for whole app. You can define rules ("routes" is the same thing) for concrete module in config routes section.
See users module for example https://github.com/gigi/yii2-modular/blob/master/modules/users/config/web.php (\yii\web\GroupUrlRule class used) or site module config https://github.com/gigi/yii2-modular/blob/master/modules/site/config/web.php Module loader takes these rules and adds to global urlManager https://github.com/gigi/yii2-modular/blob/master/common/components/Loader.php#L122
or You can add rules to \common\base\Module::bootstrap() function:
namespace modules\site;
class Module extends \common\base\Module
{
public static function bootstrap($app)
{
$app->getUrlManager()->addRules([
'' => 'site/index'
]);
}
}
\common\base\Module::bootstrap() will be called before app starts.
What remains to be done in your plans ? Your idea is brilliant.