Completed
Push — master ( c19901...1c66fc )
by Basil
06:57 queued 03:52
created

Bootstrap::generateApiRuleDefintions()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

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