Получить список всех родительских модулей дочернего модуля и наоборот в Yii2 - PullRequest
0 голосов
/ 08 сентября 2018

У меня есть иерархия модулей, как показано ниже

yii/web/Application -> frontend\modules\mangomod\MangomodModule -> frontend\modules\mangomod\modules\lemonmod\Lemonmod -> frontend\modules\mangomod\modules\lemonmod\modules\grapemod\Grapemod

Самозагруженные модули:

yii\debug\Module и yii\gii\Module

Теперь в DefaultController из Grapemod модуля мне нужно знать все его родительские модули. Как?

и

Теперь в DefaultController из Lemonmod модуля мне нужно знать все его дочерние модули. Как?

Я пробовал yii\base\Application::$loadedModules, но он также предоставляет загрузочные модули, такие как gii и debug, которые мне не нужны в списке.

Вот результат yii\base\Application::$loadedModules:

[0] => yii\web\Application
[1] => frontend\modules\mangomod\MangomodModule
[2] => yii\debug\Module
[3] => yii\gii\Module
[4] => frontend\modules\mangomod\modules\lemonmod\Lemonmod
[5] => frontend\modules\mangomod\modules\lemonmod\modules\grapemod\Grapemod

UPDATE lemonmod получил свой родной модуль

frontend\modules\mangomod\modules\lemonmod2\Lemonmod2Module

Греймод получил свой родственный модуль

frontend\modules\mangomod\modules\lemonmod\modules\grapemod2\Grapemod2Module

1 Ответ

0 голосов
/ 08 сентября 2018

Для получения всех модулей-предков контроллера вы можете использовать метод Controller::getModules():

$modules = $controller->getModules();

Возвращает все модули-предки этого контроллера.

Первый модуль в массиве является самым внешним (т.е. экземпляр приложения), в то время как последний является самым внутренним.

https://www.yiiframework.com/doc/api/2.0/yii-base-controller#getModules()-detail


Для получения списка дочерних модулей вы можете использовать Module::getModules(). Однако он вернет конфигурацию модуля вместо экземпляра модуля для не загруженных модулей - это задокументировано в $loadedOnly параметре этого метода:

Возвращать ли загруженные субмодули только. Если установлено false, то будут возвращены все зарегистрированные в этом модуле подмодули, независимо от того, загружены они или нет. Загруженные модули будут возвращены как объекты, а выгруженные модули - как массивы конфигурации .

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

$modules = [];
foreach ($module->getModules() as $id => $child) {
    if (!$child instanceof Module) {
        $child = $module->getModule($id);
    }
    $modules[] = $child;
}

Также это вернет только прямые дочерние модули - чтобы получить всех потомков, вам нужно пройти по дереву модулей:

/**
 * Return all descendants of given module.
 * 
 * @param Module $module
 * @return Module[]
 */
$traverse = function (Module $module) use (&$traverse) {
    $modules = [];
    foreach ($module->getModules() as $id => $child) {
        if (!$child instanceof Module) {
            $child = $module->getModule($id);
        }
        $modules[] = $child;
        $modules = array_merge($modules, $traverse($child));
    }

    return $modules;
};
$modules = $traverse($module);
...