Completed
Push — master ( b4d6a5...352f6d )
by Basil
02:42
created

Bootstrap::beforeRun()   B

Complexity

Conditions 8
Paths 50

Size

Total Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 33
rs 8.1475
c 0
b 0
f 0
cc 8
nc 50
nop 1
1
<?php
2
3
namespace luya\web;
4
5
use Yii;
6
use yii\base\InvalidConfigException;
7
use yii\helpers\ArrayHelper;
8
use luya\base\AdminModuleInterface;
9
use luya\TagParser;
10
use luya\base\BaseBootstrap;
11
12
/**
13
 * LUYA base bootstrap class which will be called during the bootstraping process.
14
 *
15
 * @author Basil Suter <[email protected]>
16
 * @since 1.0.0
17
 */
18
class Bootstrap extends BaseBootstrap
19
{
20
    private $_apis = [];
21
22
    private $_urlRules = [];
23
    
24
    private $_apiRules = [];
25
26
    private $_adminAssets = [];
27
28
    private $_adminMenus = [];
29
    
30
    private $_jsTranslations = [];
31
    
32
    /**
33
     * Before bootstrap run process.
34
     *
35
     * @param Application $app
36
     * @see \luya\base\BaseBootstrap::beforeRun()
37
     */
38
    public function beforeRun($app)
39
    {
40
        foreach ($app->tags as $name => $config) {
41
            TagParser::inject($name, $config);
42
        }
43
        
44
        foreach ($this->getModules() as $id => $module) {
45
            foreach ($module->urlRules as $key => $rule) {
46
                if (is_string($key)) {
47
                    $this->_urlRules[$key] = $rule;
48
                } else {
49
                    $this->_urlRules[] = $rule;
50
                }
51
            }
52
            
53
            // get all api rules (since 1.0.10)
54
            foreach ($module->apiRules as $endpoint => $rule) {
55
                $this->_apiRules[$endpoint] = $rule;
56
            }
57
            
58
            /**
59
             * 'api-admin-user' => 'admin\apis\UserController',
60
             * 'api-cms-navcontainer' => 'admin\apis\NavContainerController'
61
             */
62
            foreach ($module->apis as $alias => $class) {
63
                $this->_apis[$alias] = ['class' => $class, 'module' => $module];
64
            }
65
            
66
            foreach ($module->tags as $name => $config) {
67
                TagParser::inject($name, $config);
68
            }
69
        }
70
    }
71
72
    /**
73
     * Generate the rest rule defintions for {{luya\admin\Module::$apiDefintions}}.
74
     *
75
     * @param array $apis The array of apis where key is the api name `['api-admin-user' => 'admin\apis\UserController', ...]`.
76
     * @param array $rules The new {{luya\base\Module::$apiRules}} defintion `['api-admin-user' => [...], 'api-admin-group' => []]`.
77
     * @return array
78
     */
79
    protected function generateApiRuleDefintions(array $apis, array $rules)
80
    {
81
        // generate the url rules which are collected as ONE with an array of controllers:
82
        $collection = [];
83
        foreach ($apis as $alias => $array) {
84
            if (!isset($rules[$alias])) {
85
                $collection[] = 'admin/'.$alias;
86
            }
87
        }
88
        
89
        $result = [];
90
        $result[] = ['controller' => $collection];
91
        
92
        // generate the rules from apiRules defintions as they are own entries:
93
        foreach ($rules as $api => $rule) {
94
            $rule['controller'] = 'admin/' . $api;
95
            $result[] = $rule;
96
        }
97
        
98
        return $result;
99
    }
100
101
    /**
102
     * Invokes the bootstraping process.
103
     *
104
     * @param Application $app
105
     * @see \luya\base\BaseBootstrap::run()
106
     */
107
    public function run($app)
108
    {
109
        if (!$app->request->getIsConsoleRequest()) {
110
            if ($this->hasModule('admin') && $app->request->isAdmin) {
111
                // When admin context, change csrf token, this will not terminate the frontend csrf token:
112
                // @see https://github.com/luyadev/luya/issues/1778
113
                $app->request->csrfParam = '_csrf_admin';
114
                
115
                foreach ($this->getModules() as $id => $module) {
116
                    if ($module instanceof AdminModuleInterface) {
117
                        $this->_adminAssets = ArrayHelper::merge($module->getAdminAssets(), $this->_adminAssets);
118
                        if ($module->getMenu()) {
119
                            $this->_adminMenus[$module->id] = $module->getMenu();
120
                        }
121
                        $this->_jsTranslations[$id] = $module->getJsTranslationMessages();
122
                    }
123
                }
124
                
125
                $app->getModule('admin')->assets = $this->_adminAssets;
126
                $app->getModule('admin')->controllerMap = $this->_apis;
127
                $app->getModule('admin')->moduleMenus = $this->_adminMenus;
0 ignored issues
show
Bug introduced by
The property moduleMenus does not seem to exist. Did you mean module?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
128
                $app->getModule('admin')->setJsTranslations($this->_jsTranslations);
129
                
130
                // calculate api defintions
131
                if ($app->getModule('admin')->hasProperty('apiDefintions')) { // ensure backwards compatibility
132
                    $app->getModule('admin')->apiDefintions = $this->generateApiRuleDefintions($this->_apis, $this->_apiRules);
133
                }
134
                // as the admin module needs to listen for $apiDefintions we have to get the urlRules from the admin and merge with the existing rules:
135
                // in admin context, admin url rules have always precedence over frontend rules.
136
                $this->_urlRules = array_merge($app->getModule('admin')->urlRules, $this->_urlRules);
137
            } else {
138
                // Frontend context
139
                $app->themeManager->setup();
140
                
141
                if ($app->themeManager->hasActiveTheme) {
142
                    $app->layout = $app->themeManager->activeTheme->layout;
143
                }
144
            }
145
        }
146
        
147
        $app->getUrlManager()->addRules($this->_urlRules);
148
    }
149
}
150