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; |
|
|
|
|
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
|
|
|
|
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.