This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | namespace samsonphp\router; |
||
3 | |||
4 | use samson\core\SamsonLocale; |
||
5 | use samsonframework\core\SystemInterface; |
||
6 | use samsonframework\routing\Core; |
||
7 | use samsonframework\routing\generator\Structure; |
||
8 | use samsonframework\routing\Route; |
||
9 | use samsonphp\event\Event; |
||
10 | |||
11 | /** |
||
12 | * SamsonPHP Routing module implementation. |
||
13 | * |
||
14 | * @package samsonphp\router |
||
15 | */ |
||
16 | class Module extends \samson\core\CompressableExternalModule |
||
0 ignored issues
–
show
|
|||
17 | { |
||
18 | const EVENT_ROUTE_FOUND = 'router.route.found'; |
||
19 | |||
20 | /** @var string Module identifier */ |
||
21 | public $id = 'router'; |
||
22 | |||
23 | /** @var string Default controller module identifier */ |
||
24 | public $defaultModule = 'main'; |
||
25 | |||
26 | /** @var bool Use automatic locale resolving with browser response headers */ |
||
27 | public $browserLocaleRedirect = false; |
||
28 | |||
29 | /** @var string Path to routing logic cache file */ |
||
30 | protected $cacheFile; |
||
31 | |||
32 | /** @var string Current URL path */ |
||
33 | protected $requestURI; |
||
34 | |||
35 | /** |
||
36 | * Old generic "main_page" route callback searcher to match old logic. |
||
37 | * |
||
38 | * @return Route Default application route "/" |
||
39 | */ |
||
40 | protected function findGenericDefaultAction() |
||
41 | { |
||
42 | $callback = null; |
||
43 | // Set pointer to module |
||
44 | $module = $this->system->getContainer()->get($this->defaultModule); |
||
45 | // If callback is passed - function name |
||
46 | if (is_callable($this->defaultModule)) { |
||
47 | // Use it as main controller callback |
||
48 | $callback = $this->defaultModule; |
||
49 | // Consider as module identifier is passed |
||
50 | } elseif ($module !== null) { |
||
51 | // Try to find module universal controller action |
||
52 | if (method_exists($module, self::CTR_BASE)) { |
||
53 | $callback = $module->id . '#' . self::CTR_BASE; |
||
54 | } else if (method_exists($module, self::CTR_CACHE_BASE)) { |
||
55 | $callback = $module->id . '#' . self::CTR_CACHE_BASE; |
||
56 | } elseif (method_exists($module, self::CTR_UNI)) { |
||
57 | $callback = $module->id . '#' . self::CTR_UNI; |
||
58 | } elseif (method_exists($module, self::CTR_CACHE_UNI)) { |
||
59 | $callback = $module->id . '#' . self::CTR_CACHE_UNI; |
||
60 | } |
||
61 | } |
||
62 | |||
63 | return new Route('/', $callback, 'main_page'); |
||
0 ignored issues
–
show
It seems like
$callback defined by null on line 42 can also be of type null ; however, samsonframework\routing\Route::__construct() does only seem to accept callable , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
64 | } |
||
65 | |||
66 | /** |
||
67 | * Module initialization. |
||
68 | * |
||
69 | * @param array $params Initialization parameters collection |
||
70 | * @return bool Initialization result |
||
71 | */ |
||
72 | public function init(array $params = array()) |
||
73 | { |
||
74 | //[PHPCOMPRESSOR(remove,start)] |
||
75 | $modules = $this->system->getContainer()->getServices('module'); |
||
76 | // Create SamsonPHP routing table from loaded modules |
||
77 | $rg = new GenericRouteGenerator($modules); |
||
78 | |||
79 | // Generate web-application routes |
||
80 | $routes = $rg->generate(); |
||
81 | $routes->add($this->findGenericDefaultAction()); |
||
82 | |||
83 | // Create cache marker |
||
84 | $this->cacheFile = $routes->hash().'.php'; |
||
85 | // If we need to refresh cache |
||
86 | if ($this->cache_refresh($this->cacheFile)) { |
||
87 | $generator = new Structure($routes, new \samsonphp\generator\Generator()); |
||
0 ignored issues
–
show
The class
samsonphp\generator\Generator has been deprecated with message: Use other separate generators.
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead. ![]() |
|||
88 | // Generate routing logic function |
||
89 | $routerLogic = $generator->generate(); |
||
90 | |||
91 | // Store router logic in cache |
||
92 | file_put_contents($this->cacheFile, '<?php '."\n".$routerLogic); |
||
93 | } |
||
94 | |||
95 | require($this->cacheFile); |
||
96 | //[PHPCOMPRESSOR(remove,end)] |
||
97 | |||
98 | // Set locale resolver mode |
||
99 | SamsonLocale::$leaveDefaultLocale = $this->browserLocaleRedirect; |
||
100 | |||
101 | // This should be change to receive path as a parameter on initialization |
||
102 | $pathParts = array_values(array_filter(explode(Route::DELIMITER, $_SERVER['REQUEST_URI']), function($v){ |
||
0 ignored issues
–
show
|
|||
103 | return ($v !== '' && null !== $v); |
||
104 | })); |
||
105 | |||
106 | // Parse URL and store locale found bug |
||
107 | $localeFound = SamsonLocale::parseURL($pathParts, $this->browserLocaleRedirect); |
||
108 | // Gather URL path parts with removed locale placeholder |
||
109 | $this->requestURI = implode(Route::DELIMITER, $pathParts); |
||
110 | |||
111 | // Get localization data |
||
112 | $current = SamsonLocale::current(); |
||
113 | $default = SamsonLocale::$defaultLocale; |
||
114 | |||
115 | // Browser agent language detection logic |
||
116 | if ($this->browserLocaleRedirect && !$localeFound) { |
||
117 | // Redirect to browser language |
||
118 | $lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2); |
||
119 | // Is browser language supported by application |
||
120 | $langSupport = in_array($lang, SamsonLocale::get(), true); |
||
121 | |||
122 | /** |
||
123 | * If browser language header is supported by our web-application and we are already not on that locale |
||
124 | * and current locale is not default. |
||
125 | */ |
||
126 | if ($current === $default && $current !== $lang && $langSupport) { |
||
127 | header('Location: http://'.$_SERVER['HTTP_HOST'].'/'.$lang.'/'.$this->requestURI);exit; |
||
0 ignored issues
–
show
|
|||
128 | } elseif (!$langSupport || $lang === $current) { |
||
129 | SamsonLocale::$leaveDefaultLocale = false; |
||
130 | } |
||
131 | } |
||
132 | |||
133 | // Subscribe to samsonphp\core routing event |
||
134 | \samsonphp\event\Event::subscribe('core.routing', array($this, 'router')); |
||
135 | |||
136 | // Continue initialization |
||
137 | return parent::init($params); |
||
138 | } |
||
139 | |||
140 | /** @see \samson\core\CompressableExternalModule::afterCompress() */ |
||
141 | public function afterCompress(&$obj = null, array &$code = null) |
||
142 | { |
||
143 | // Compress generated php code |
||
144 | $obj->compress_php($this->cacheFile, $this, $code, ''); |
||
145 | } |
||
146 | |||
147 | /** |
||
148 | * Define if HTTP request is asynchronous. |
||
149 | * |
||
150 | * @return bool True if request is asynchronous |
||
151 | */ |
||
152 | public function isAsynchronousRequest() |
||
153 | { |
||
154 | return isset($_SERVER['HTTP_SJSASYNC']) || isset($_POST['SJSASYNC']); |
||
155 | } |
||
156 | |||
157 | /** |
||
158 | * Parse route parameters received from router logic function. |
||
159 | * |
||
160 | * @param callable $callback Route instance |
||
161 | * @param array $receivedParameters Collection of parsed parameters |
||
162 | * @return array Collection of route callback needed parameters |
||
163 | */ |
||
164 | protected function parseParameters($callback, array $receivedParameters) |
||
165 | { |
||
166 | $parameters = array(); |
||
167 | // Parse callback signature and get parameters list |
||
168 | if (is_callable($callback)) { |
||
169 | $reflectionMethod = is_array($callback) |
||
170 | ? new \ReflectionMethod($callback[0], $callback[1]) |
||
171 | : new \ReflectionFunction($callback); |
||
172 | foreach ($reflectionMethod->getParameters() as $parameter) { |
||
173 | $parameters[] = $parameter->getName(); |
||
174 | } |
||
175 | } |
||
176 | |||
177 | // Gather parsed route parameters in correct order |
||
178 | $foundParameters = array(); |
||
179 | foreach ($parameters as $name) { |
||
180 | // Add to parameters collection |
||
181 | $parameterValue = &$receivedParameters[$name]; |
||
182 | if (isset($parameterValue) && isset($parameterValue{0})) { |
||
183 | $foundParameters[] = $parameterValue; |
||
184 | } |
||
185 | } |
||
186 | return $foundParameters; |
||
187 | } |
||
188 | |||
189 | /** |
||
190 | * SamsonPHP core.routing event handler |
||
191 | * |
||
192 | * @param SystemInterface $core Pointer to core object |
||
193 | * @param mixed $result Return value as routing result |
||
194 | * @return bool Routing result |
||
195 | */ |
||
196 | public function router(SystemInterface &$core, &$result) |
||
197 | { |
||
198 | //elapsed('Start routing'); |
||
199 | // Flag for matching SamsonPHP asynchronous requests |
||
200 | $async = $this->isAsynchronousRequest(); |
||
201 | // Get HTTP request path |
||
202 | $path = $this->requestURI;//$_SERVER['REQUEST_URI']; |
||
203 | // Get HTTP request method |
||
204 | $method = $_SERVER['REQUEST_METHOD']; |
||
205 | // Prepend HTTP request type, true - asynchronous |
||
206 | $method = ($async ? GenericRouteGenerator::ASYNC_PREFIX : '').$method; |
||
207 | |||
208 | $result = false; |
||
209 | |||
210 | // Remove first slash if present, add method to path, remove GET params, remove trailing slash |
||
211 | $path = rtrim(ltrim(strtok($path, '?'), '/'), '/'); |
||
212 | |||
213 | /** @var mixed $routeMetadata Dispatching result route metadata */ |
||
214 | if (is_array($routeMetadata = call_user_func(Core::ROUTING_LOGIC_FUNCTION, $path, $method))) { |
||
215 | // Check found route |
||
216 | if (count($routeMetadata) === 3) { |
||
217 | // Get callback info |
||
218 | list($module, $method) = explode("#", $routeMetadata[2]); |
||
219 | // Get module |
||
220 | $module = $core->module($module); |
||
221 | // Create callback |
||
222 | $callback = array($module, $method); |
||
223 | |||
224 | // Trigger found route event |
||
225 | Event::fire(self::EVENT_ROUTE_FOUND, array(&$module, $callback)); |
||
226 | |||
227 | // Check if we have vaild callback |
||
228 | if (is_callable($callback)) { |
||
229 | // Get object from callback and set it as current active core module |
||
230 | $core->active($module); |
||
231 | // Routing result |
||
232 | $result = call_user_func_array( |
||
233 | $callback, |
||
234 | $this->parseParameters($callback, $routeMetadata[1]) |
||
235 | ); |
||
236 | |||
237 | // If this is cached method |
||
238 | if (stripos($method, self::CACHE_PREFIX) !== false) { |
||
239 | // perform caching |
||
240 | $core->cached(); |
||
241 | } |
||
242 | |||
243 | // If this route is asynchronous |
||
244 | if ($async) { |
||
245 | // Set async response |
||
246 | $core->async(true); |
||
247 | |||
248 | // If controller action has failed |
||
249 | if (!isset($result['status']) || !$result['status']) { |
||
250 | $result['message'] = "\n" . 'Event failed: ' . $routeMetadata[0]; |
||
251 | $result['status'] = 0; |
||
252 | } |
||
253 | |||
254 | // Encode event result as json object |
||
255 | echo json_encode($result, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP); |
||
256 | |||
257 | // Mark as successful |
||
258 | $result = true; |
||
259 | } |
||
260 | } |
||
261 | |||
262 | // If no result is passed - consider success |
||
263 | $result = $result !== false ? true : $result; |
||
264 | } |
||
265 | } |
||
266 | |||
267 | //elapsed('Finished routing'); |
||
268 | // Return true or false depending on $result |
||
269 | return $result; |
||
270 | } |
||
271 | } |
||
272 |
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.