These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace mdm\admin\components; |
||
4 | |||
5 | use mdm\admin\models\Route; |
||
6 | use Yii; |
||
7 | use yii\caching\TagDependency; |
||
8 | use yii\helpers\ArrayHelper; |
||
9 | use yii\web\User; |
||
10 | |||
11 | /** |
||
12 | * Description of Helper |
||
13 | * |
||
14 | * @author Misbahul D Munir <[email protected]> |
||
15 | * @since 2.3 |
||
16 | */ |
||
17 | class Helper |
||
18 | { |
||
19 | private static $_userRoutes = []; |
||
20 | private static $_defaultRoutes; |
||
21 | private static $_routes; |
||
22 | |||
23 | public static function getRegisteredRoutes() |
||
24 | { |
||
25 | if (self::$_routes === null) { |
||
26 | self::$_routes = []; |
||
27 | $manager = Configs::authManager(); |
||
28 | foreach ($manager->getPermissions() as $item) { |
||
29 | if ($item->name[0] === '/') { |
||
30 | self::$_routes[$item->name] = $item->name; |
||
31 | } |
||
32 | } |
||
33 | } |
||
34 | return self::$_routes; |
||
35 | } |
||
36 | |||
37 | /** |
||
38 | * Get assigned routes by default roles |
||
39 | * @return array |
||
40 | */ |
||
41 | protected static function getDefaultRoutes() |
||
42 | { |
||
43 | if (self::$_defaultRoutes === null) { |
||
44 | $manager = Configs::authManager(); |
||
45 | $roles = $manager->defaultRoles; |
||
46 | $cache = Configs::cache(); |
||
47 | if ($cache && ($routes = $cache->get($roles)) !== false) { |
||
48 | self::$_defaultRoutes = $routes; |
||
49 | } else { |
||
50 | $permissions = self::$_defaultRoutes = []; |
||
51 | foreach ($roles as $role) { |
||
52 | $permissions = array_merge($permissions, $manager->getPermissionsByRole($role)); |
||
53 | } |
||
54 | foreach ($permissions as $item) { |
||
55 | if ($item->name[0] === '/') { |
||
56 | self::$_defaultRoutes[$item->name] = true; |
||
57 | } |
||
58 | } |
||
59 | if ($cache) { |
||
60 | $cache->set($roles, self::$_defaultRoutes, Configs::cacheDuration(), new TagDependency([ |
||
61 | 'tags' => Configs::CACHE_TAG, |
||
62 | ])); |
||
63 | } |
||
64 | } |
||
65 | } |
||
66 | return self::$_defaultRoutes; |
||
67 | } |
||
68 | |||
69 | /** |
||
70 | * Get assigned routes of user. |
||
71 | * @param integer $userId |
||
72 | * @return array |
||
73 | */ |
||
74 | public static function getRoutesByUser($userId) |
||
75 | { |
||
76 | if (!isset(self::$_userRoutes[$userId])) { |
||
77 | $cache = Configs::cache(); |
||
78 | if ($cache && ($routes = $cache->get([__METHOD__, $userId])) !== false) { |
||
79 | self::$_userRoutes[$userId] = $routes; |
||
80 | } else { |
||
81 | $routes = static::getDefaultRoutes(); |
||
82 | $manager = Configs::authManager(); |
||
83 | foreach ($manager->getPermissionsByUser($userId) as $item) { |
||
84 | if ($item->name[0] === '/') { |
||
85 | $routes[$item->name] = true; |
||
86 | } |
||
87 | } |
||
88 | self::$_userRoutes[$userId] = $routes; |
||
89 | if ($cache) { |
||
90 | $cache->set([__METHOD__, $userId], $routes, Configs::cacheDuration(), new TagDependency([ |
||
91 | 'tags' => Configs::CACHE_TAG, |
||
92 | ])); |
||
93 | } |
||
94 | } |
||
95 | } |
||
96 | return self::$_userRoutes[$userId]; |
||
97 | } |
||
98 | |||
99 | /** |
||
100 | * Check access route for user. |
||
101 | * @param string|array $route |
||
102 | * @param integer|User $user |
||
103 | * @return boolean |
||
104 | */ |
||
105 | public static function checkRoute($route, $params = [], $user = null) |
||
106 | { |
||
107 | $config = Configs::instance(); |
||
108 | $r = static::normalizeRoute($route, $config->advanced); |
||
0 ignored issues
–
show
|
|||
109 | if ($config->onlyRegisteredRoute && !isset(static::getRegisteredRoutes()[$r])) { |
||
110 | return true; |
||
111 | } |
||
112 | |||
113 | if ($user === null) { |
||
114 | $user = Yii::$app->getUser(); |
||
115 | } |
||
116 | $userId = $user instanceof User ? $user->getId() : $user; |
||
117 | |||
118 | if ($config->strict) { |
||
119 | if ($user->can($r, $params)) { |
||
120 | return true; |
||
121 | } |
||
122 | View Code Duplication | while (($pos = strrpos($r, '/')) > 0) { |
|
123 | $r = substr($r, 0, $pos); |
||
124 | if ($user->can($r . '/*', $params)) { |
||
125 | return true; |
||
126 | } |
||
127 | } |
||
128 | return $user->can('/*', $params); |
||
129 | } else { |
||
130 | $routes = static::getRoutesByUser($userId); |
||
131 | if (isset($routes[$r])) { |
||
132 | return true; |
||
133 | } |
||
134 | View Code Duplication | while (($pos = strrpos($r, '/')) > 0) { |
|
135 | $r = substr($r, 0, $pos); |
||
136 | if (isset($routes[$r . '/*'])) { |
||
137 | return true; |
||
138 | } |
||
139 | } |
||
140 | return isset($routes['/*']); |
||
141 | } |
||
142 | } |
||
143 | |||
144 | /** |
||
145 | * Normalize route |
||
146 | * @param string $route Plain route string |
||
147 | * @param boolean|array $advanced Array containing the advanced configuration. Defaults to false. |
||
148 | * @return string Normalized route string |
||
149 | */ |
||
150 | protected static function normalizeRoute($route, $advanced = false) |
||
151 | { |
||
152 | if ($route === '') { |
||
153 | $normalized = '/' . Yii::$app->controller->getRoute(); |
||
154 | } elseif (strncmp($route, '/', 1) === 0) { |
||
155 | $normalized = $route; |
||
156 | } elseif (strpos($route, '/') === false) { |
||
157 | $normalized = '/' . Yii::$app->controller->getUniqueId() . '/' . $route; |
||
158 | } elseif (($mid = Yii::$app->controller->module->getUniqueId()) !== '') { |
||
159 | $normalized = '/' . $mid . '/' . $route; |
||
160 | } else { |
||
161 | $normalized = '/' . $route; |
||
162 | } |
||
163 | // Prefix @app-id to route. |
||
164 | if ($advanced) { |
||
165 | $normalized = Route::PREFIX_ADVANCED . Yii::$app->id . $normalized; |
||
166 | } |
||
167 | return $normalized; |
||
168 | } |
||
169 | |||
170 | /** |
||
171 | * Filter menu items |
||
172 | * @param array $items |
||
173 | * @param integer|User $user |
||
174 | */ |
||
175 | public static function filter($items, $user = null) |
||
176 | { |
||
177 | if ($user === null) { |
||
178 | $user = Yii::$app->getUser(); |
||
179 | } |
||
180 | return static::filterRecursive($items, $user); |
||
181 | } |
||
182 | |||
183 | /** |
||
184 | * Filter menu recursive |
||
185 | * @param array $items |
||
186 | * @param integer|User $user |
||
187 | * @return array |
||
188 | */ |
||
189 | protected static function filterRecursive($items, $user) |
||
190 | { |
||
191 | $result = []; |
||
192 | foreach ($items as $i => $item) { |
||
193 | $url = ArrayHelper::getValue($item, 'url', '#'); |
||
194 | $allow = is_array($url) ? static::checkRoute($url[0], array_slice($url, 1), $user) : true; |
||
195 | |||
196 | if (isset($item['items']) && is_array($item['items'])) { |
||
197 | $subItems = self::filterRecursive($item['items'], $user); |
||
198 | if (count($subItems)) { |
||
199 | $allow = true; |
||
200 | } |
||
201 | $item['items'] = $subItems; |
||
202 | } |
||
203 | if ($allow && !($url == '#' && empty($item['items']))) { |
||
204 | $result[$i] = $item; |
||
205 | } |
||
206 | } |
||
207 | return $result; |
||
208 | } |
||
209 | |||
210 | /** |
||
211 | * Filter action column button. Use with [[yii\grid\GridView]] |
||
212 | * ```php |
||
213 | * 'columns' => [ |
||
214 | * ... |
||
215 | * [ |
||
216 | * 'class' => 'yii\grid\ActionColumn', |
||
217 | * 'template' => Helper::filterActionColumn(['view','update','activate']) |
||
218 | * ] |
||
219 | * ], |
||
220 | * ``` |
||
221 | * @param array|string $buttons |
||
222 | * @param integer|User $user |
||
223 | * @return string |
||
224 | */ |
||
225 | public static function filterActionColumn($buttons = [], $user = null) |
||
226 | { |
||
227 | if (is_array($buttons)) { |
||
228 | $result = []; |
||
229 | foreach ($buttons as $button) { |
||
230 | if (static::checkRoute($button, [], $user)) { |
||
231 | $result[] = "{{$button}}"; |
||
232 | } |
||
233 | } |
||
234 | return implode(' ', $result); |
||
235 | } |
||
236 | return preg_replace_callback('/\\{([\w\-\/]+)\\}/', function ($matches) use ($user) { |
||
237 | return static::checkRoute($matches[1], [], $user) ? "{{$matches[1]}}" : ''; |
||
238 | }, $buttons); |
||
239 | } |
||
240 | |||
241 | /** |
||
242 | * Use to invalidate cache. |
||
243 | */ |
||
244 | public static function invalidate() |
||
245 | { |
||
246 | if (Configs::cache() !== null) { |
||
247 | TagDependency::invalidate(Configs::cache(), Configs::CACHE_TAG); |
||
248 | } |
||
249 | } |
||
250 | } |
||
251 |
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.