horros /
agavi2
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 Agavi\Routing; |
||
| 3 | |||
| 4 | // +---------------------------------------------------------------------------+ |
||
| 5 | // | This file is part of the Agavi package. | |
||
| 6 | // | Copyright (c) 2005-2011 the Agavi Project. | |
||
| 7 | // | | |
||
| 8 | // | For the full copyright and license information, please view the LICENSE | |
||
| 9 | // | file that was distributed with this source code. You can also view the | |
||
| 10 | // | LICENSE file online at http://www.agavi.org/LICENSE.txt | |
||
| 11 | // | vi: set noexpandtab: | |
||
| 12 | // | Local Variables: | |
||
| 13 | // | indent-tabs-mode: t | |
||
| 14 | // | End: | |
||
| 15 | // +---------------------------------------------------------------------------+ |
||
| 16 | use Agavi\Core\Context; |
||
| 17 | use Agavi\Request\RequestDataHolder; |
||
| 18 | use Agavi\Request\WebRequest; |
||
| 19 | use Agavi\Util\Toolkit; |
||
| 20 | |||
| 21 | /** |
||
| 22 | * WebRouting sets the prefix and input with some magic from the request |
||
| 23 | * uri and path_info |
||
| 24 | * |
||
| 25 | * @package agavi |
||
| 26 | * @subpackage routing |
||
| 27 | * |
||
| 28 | * @author Dominik del Bondio <[email protected]> |
||
| 29 | * @copyright Authors |
||
| 30 | * @copyright The Agavi Project |
||
| 31 | * |
||
| 32 | * @since 0.11.0 |
||
| 33 | * |
||
| 34 | * @version $Id$ |
||
| 35 | */ |
||
| 36 | class WebRouting extends Routing |
||
| 37 | { |
||
| 38 | /** |
||
| 39 | * @var string The path to the application's root with trailing slash. |
||
| 40 | */ |
||
| 41 | protected $basePath = ''; |
||
| 42 | |||
| 43 | /** |
||
| 44 | * @var string The URL to the application's root with trailing slash. |
||
| 45 | */ |
||
| 46 | protected $baseHref = ''; |
||
| 47 | |||
| 48 | /** |
||
| 49 | * @var array The GET parameters that were passed in the URL. |
||
| 50 | */ |
||
| 51 | protected $inputParameters = array(); |
||
| 52 | |||
| 53 | /** |
||
| 54 | * @var array arg_separator.input as defined in php.ini, exploded |
||
| 55 | */ |
||
| 56 | protected $argSeparatorInput = array('&'); |
||
| 57 | |||
| 58 | /** |
||
| 59 | * @var string arg_separator.output as defined in php.ini |
||
| 60 | */ |
||
| 61 | protected $argSeparatorOutput = '&'; |
||
| 62 | |||
| 63 | /** |
||
| 64 | * Constructor. |
||
| 65 | * |
||
| 66 | * @author David Zülke <[email protected]> |
||
| 67 | * @since 0.11.0 |
||
| 68 | */ |
||
| 69 | public function __construct() |
||
| 70 | { |
||
| 71 | parent::__construct(); |
||
| 72 | |||
| 73 | $this->defaultGenOptions = array_merge($this->defaultGenOptions, array( |
||
| 74 | // separator, typically & for HTML, & otherwise |
||
| 75 | 'separator' => '&', |
||
| 76 | // whether or not to append the SID if necessary |
||
| 77 | 'use_trans_sid' => false, |
||
| 78 | // scheme, or true to include, or false to block |
||
| 79 | 'scheme' => null, |
||
| 80 | // authority, or true to include, or false to block |
||
| 81 | 'authority' => null, |
||
| 82 | // host, or true to include, or false to block |
||
| 83 | 'host' => null, |
||
| 84 | // port, or true to include, or false to block |
||
| 85 | 'port' => null, |
||
| 86 | // fragment identifier (#foo) |
||
| 87 | 'fragment' => null, |
||
| 88 | )); |
||
| 89 | |||
| 90 | $this->argSeparatorInput = str_split(ini_get('arg_separator.input')); |
||
| 91 | $this->argSeparatorOutput = ini_get('arg_separator.output'); |
||
| 92 | } |
||
| 93 | |||
| 94 | /** |
||
| 95 | * Initialize the routing instance. |
||
| 96 | * |
||
| 97 | * @param Context $context The Context. |
||
| 98 | * @param array $parameters An array of initialization parameters. |
||
| 99 | * |
||
| 100 | * @author David Zülke <[email protected]> |
||
| 101 | * @author Veikko Mäkinen <[email protected]> |
||
| 102 | * @author Dominik del Bondio <[email protected]> |
||
| 103 | * @since 0.11.0 |
||
| 104 | */ |
||
| 105 | public function initialize(Context $context, array $parameters = array()) |
||
|
0 ignored issues
–
show
initialize uses the super-global variable $_GET which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
Loading history...
initialize uses the super-global variable $GLOBALS which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
Loading history...
initialize uses the super-global variable $_POST which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
Loading history...
initialize uses the super-global variable $_REQUEST which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
Loading history...
|
|||
| 106 | { |
||
| 107 | parent::initialize($context, $parameters); |
||
| 108 | |||
| 109 | /** @var WebRequest $rq */ |
||
| 110 | $rq = $this->context->getRequest(); |
||
| 111 | |||
| 112 | /** @var RequestDataHolder $rd */ |
||
| 113 | $rd = $rq->getRequestData(); |
||
| 114 | |||
| 115 | // 'scheme://authority' is necessary so parse_url doesn't stumble over '://' in the request URI |
||
| 116 | $ru = array_merge(array('path' => '', 'query' => ''), parse_url('scheme://authority' . $rq->getRequestUri())); |
||
| 117 | |||
| 118 | if (isset($_SERVER['QUERY_STRING'])) { |
||
| 119 | $qs = $_SERVER['QUERY_STRING']; |
||
| 120 | } else { |
||
| 121 | $qs = ''; |
||
| 122 | } |
||
| 123 | |||
| 124 | // when rewriting, apache strips one (not all) trailing ampersand from the end of QUERY_STRING... normalize: |
||
| 125 | $rewritten = (preg_replace('/&+$/D', '', $qs) !== preg_replace('/&+$/D', '', $ru['query'])); |
||
| 126 | |||
| 127 | if ($this->isEnabled() && $rewritten) { |
||
| 128 | // strip the one trailing ampersand, see above |
||
| 129 | $queryWasEmptied = false; |
||
| 130 | if ($ru['query'] !== '' && isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false) { |
||
| 131 | $ru['query'] = preg_replace('/&$/D', '', $ru['query']); |
||
| 132 | if ($ru['query'] == '') { |
||
| 133 | $queryWasEmptied = true; |
||
| 134 | } |
||
| 135 | } |
||
| 136 | |||
| 137 | $stripFromQuery = '&' . $ru['query']; |
||
| 138 | if ($ru['query'] == '' && !$queryWasEmptied && isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false) { |
||
| 139 | // if the query is empty, simply give apache2 nothing instead of an "&", since that could kill a real trailing ampersand in the path, as Apache strips those from the query string (which has the rewritten path), but not the request uri |
||
| 140 | $stripFromQuery = ''; |
||
| 141 | } |
||
| 142 | $this->input = preg_replace('/' . preg_quote($stripFromQuery, '/') . '$/D', '', $qs); |
||
| 143 | |||
| 144 | if (isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache/2') !== false) { |
||
| 145 | $sru = $_SERVER['REQUEST_URI']; |
||
| 146 | |||
| 147 | if (($fqmp = strpos($sru, '?')) !== false && ($fqmp == strlen($sru)-1)) { |
||
| 148 | // strip a trailing question mark, but only if it really is the query string separator (i.e. the only question mark in the URI) |
||
| 149 | $sru = substr($sru, 0, -1); |
||
| 150 | } elseif ($ru['query'] !== '' || $queryWasEmptied) { |
||
| 151 | // if there is a trailing ampersand (in query string or path, whatever ends the URL), strip it (but just one) |
||
| 152 | $sru = preg_replace('/&$/D', '', $sru); |
||
| 153 | } |
||
| 154 | |||
| 155 | // multiple consecutive slashes got lost in our input thanks to an apache bug |
||
| 156 | // let's fix that |
||
| 157 | $cqs = preg_replace('#/{2,}#', '/', rawurldecode($ru['query'])); |
||
| 158 | $cru = preg_replace('#/{2,}#', '/', rawurldecode($sru)); |
||
| 159 | $tmp = preg_replace('/' . preg_quote($this->input . (($cqs != '' || $queryWasEmptied) ? '?' . $cqs : ''), '/') . '$/D', '', $cru); |
||
| 160 | $input = preg_replace('/^' . preg_quote($tmp, '/') . '/', '', $sru); |
||
| 161 | if ($ru['query'] !== '' || $queryWasEmptied) { |
||
| 162 | $input = preg_replace('/' . preg_quote('?' . $ru['query'], '/') . '$/D', '', $input); |
||
| 163 | } |
||
| 164 | $this->input = $input; |
||
| 165 | } |
||
| 166 | |||
| 167 | if (!(isset($_SERVER['SERVER_SOFTWARE']) && (strpos($_SERVER['SERVER_SOFTWARE'], 'Apache/1') !== false || (strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false && isset($_SERVER['UNENCODED_URL']))))) { |
||
| 168 | // don't do that for Apache 1 or IIS 7 with URL Rewrite Module, it's already rawurldecode()d there |
||
| 169 | $this->input = rawurldecode($this->input); |
||
| 170 | } |
||
| 171 | |||
| 172 | $this->basePath = $this->prefix = preg_replace('/' . preg_quote($this->input, '/') . '$/D', '', rawurldecode($ru['path'])); |
||
| 173 | |||
| 174 | // that was easy. now clean up $_GET and the Request |
||
| 175 | $parsedRuQuery = $parsedInput = ''; |
||
| 176 | parse_str($ru['query'], $parsedRuQuery); |
||
| 177 | parse_str($this->input, $parsedInput); |
||
| 178 | if (get_magic_quotes_gpc()) { |
||
| 179 | $parsedRuQuery = WebRequest::clearMagicQuotes($parsedRuQuery); |
||
|
0 ignored issues
–
show
It seems like
$parsedRuQuery can also be of type null; however, Agavi\Request\WebRequest::clearMagicQuotes() does only seem to accept array, 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. Loading history...
|
|||
| 180 | $parsedInput = WebRequest::clearMagicQuotes($parsedInput, false /* start on the first level */); |
||
|
0 ignored issues
–
show
It seems like
$parsedInput can also be of type null; however, Agavi\Request\WebRequest::clearMagicQuotes() does only seem to accept array, 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. Loading history...
The call to
WebRequest::clearMagicQuotes() has too many arguments starting with false.
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. In this case you can add the Loading history...
|
|||
| 181 | } |
||
| 182 | foreach (array_diff(array_keys($parsedInput), array_keys($parsedRuQuery)) as $unset) { |
||
| 183 | // our element is in $_GET |
||
| 184 | unset($_GET[$unset]); |
||
| 185 | unset($GLOBALS['HTTP_GET_VARS'][$unset]); |
||
| 186 | // if it is not also in $_POST, then we need to remove it from the request params |
||
| 187 | if (!isset($_POST[$unset])) { |
||
| 188 | $rd->removeParameter($unset); |
||
| 189 | // and from $_REQUEST, too! |
||
|
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
40% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. Loading history...
|
|||
| 190 | unset($_REQUEST[$unset]); |
||
| 191 | } |
||
| 192 | } |
||
| 193 | } else { |
||
| 194 | $sn = $_SERVER['SCRIPT_NAME']; |
||
| 195 | $path = rawurldecode($ru['path']); |
||
| 196 | |||
| 197 | $appendFrom = 0; |
||
| 198 | $this->prefix = Toolkit::stringBase($sn, $path, $appendFrom); |
||
| 199 | $this->prefix .= substr($sn, $appendFrom); |
||
| 200 | |||
| 201 | $this->input = substr($path, $appendFrom); |
||
| 202 | if (!isset($_SERVER['SERVER_SOFTWARE']) || strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') === false || isset($_SERVER['HTTP_X_REWRITE_URL']) || !isset($_SERVER['GATEWAY_INTERFACE']) || strpos($_SERVER['GATEWAY_INTERFACE'], 'CGI') === false) { |
||
| 203 | // don't do that for IIS-CGI, it's already rawurldecode()d there |
||
| 204 | $this->input = rawurldecode($this->input); |
||
| 205 | } |
||
| 206 | |||
| 207 | $this->basePath = str_replace('\\', '/', dirname($this->prefix)); |
||
| 208 | } |
||
| 209 | |||
| 210 | $this->inputParameters = $_GET; |
||
| 211 | |||
| 212 | if (!$this->input) { |
||
| 213 | $this->input = "/"; |
||
| 214 | } |
||
| 215 | |||
| 216 | if (substr($this->basePath, -1, 1) != '/') { |
||
| 217 | $this->basePath .= '/'; |
||
| 218 | } |
||
| 219 | |||
| 220 | $this->baseHref = $rq->getUrlScheme() . '://' . $rq->getUrlAuthority() . $this->basePath; |
||
| 221 | } |
||
| 222 | |||
| 223 | /** |
||
| 224 | * Retrieve the base path where the application's root sits |
||
| 225 | * |
||
| 226 | * @return string A path string, including a trailing slash. |
||
| 227 | * |
||
| 228 | * @author David Zülke <[email protected]> |
||
| 229 | * @since 0.11.0 |
||
| 230 | */ |
||
| 231 | public function getBasePath() |
||
| 232 | { |
||
| 233 | return $this->basePath; |
||
| 234 | } |
||
| 235 | |||
| 236 | /** |
||
| 237 | * Retrieve the full URL to the application's root. |
||
| 238 | * |
||
| 239 | * @return string A URL string, including the protocol, the server port |
||
| 240 | * (if necessary) and the path including a trailing slash. |
||
| 241 | * |
||
| 242 | * @author David Zülke <[email protected]> |
||
| 243 | * @since 0.11.0 |
||
| 244 | */ |
||
| 245 | public function getBaseHref() |
||
| 246 | { |
||
| 247 | return $this->baseHref; |
||
| 248 | } |
||
| 249 | |||
| 250 | /** |
||
| 251 | * Generate a formatted Agavi URL. |
||
| 252 | * |
||
| 253 | * @param string $route A route name. |
||
| 254 | * @param array $params An associative array of parameters. |
||
| 255 | * @param mixed $options An array of options, or the name of an options preset. |
||
| 256 | * |
||
| 257 | * @return string The generated URL. |
||
| 258 | * |
||
| 259 | * @author David Zülke <[email protected]> |
||
| 260 | * @since 0.11.0 |
||
| 261 | */ |
||
| 262 | public function gen($route, array $params = array(), $options = array()) |
||
|
0 ignored issues
–
show
gen uses the super-global variable $_SERVER which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
Loading history...
|
|||
| 263 | { |
||
| 264 | /** @var WebRequest $req */ |
||
| 265 | $req = $this->context->getRequest(); |
||
| 266 | |||
| 267 | if (substr($route, -1) == '*') { |
||
| 268 | $options['refill_all_parameters'] = true; |
||
| 269 | $route = substr($route, 0, -1); |
||
| 270 | } |
||
| 271 | |||
| 272 | $options = $this->resolveGenOptions($options); |
||
| 273 | |||
| 274 | $aso = $this->argSeparatorOutput; |
||
| 275 | if ($options['separator'] != $aso) { |
||
| 276 | $aso = $options['separator']; |
||
| 277 | } |
||
| 278 | |||
| 279 | if ($options['use_trans_sid'] === true && defined('SID') && SID !== '') { |
||
| 280 | $params = array_merge($params, array(session_name() => session_id())); |
||
| 281 | } |
||
| 282 | |||
| 283 | if ($route === null && empty($params)) { |
||
| 284 | $retval = $req->getRequestUri(); |
||
| 285 | $retval = str_replace(array('[', ']', '\''), array('%5B', '%5D', '%27'), $retval); |
||
| 286 | // much quicker than str_replace($this->argSeparatorInput, array_fill(0, count($this->argSeparatorInput), $aso), $retval) |
||
|
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
52% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. Loading history...
|
|||
| 287 | foreach ($this->argSeparatorInput as $char) { |
||
| 288 | $retval = str_replace($char, $aso, $retval); |
||
| 289 | } |
||
| 290 | } else { |
||
| 291 | if ($this->isEnabled()) { |
||
| 292 | // the route exists and routing is enabled, the parent method handles it |
||
| 293 | |||
| 294 | $append = ''; |
||
| 295 | |||
| 296 | list($path, $usedParams, $options, $extraParams, $isNullRoute) = parent::gen($route, $params, $options); |
||
|
0 ignored issues
–
show
The assignment to
$usedParams is unused. Consider omitting it like so list($first,,$third).
This checks looks for assignemnts to variables using the Consider the following code example. <?php
function returnThreeValues() {
return array('a', 'b', 'c');
}
list($a, $b, $c) = returnThreeValues();
print $a . " - " . $c;
Only the variables Instead, the list call could have been. list($a,, $c) = returnThreeValues();
Loading history...
|
|||
| 297 | |||
| 298 | if ($isNullRoute) { |
||
| 299 | // add the incoming parameters from the request uri for gen(null) and friends |
||
| 300 | $extraParams = array_merge($this->inputParameters, $extraParams); |
||
| 301 | } |
||
| 302 | if (count($extraParams) > 0) { |
||
| 303 | $append = http_build_query($extraParams, '', $aso); |
||
| 304 | if ($append !== '') { |
||
| 305 | $append = '?' . $append; |
||
| 306 | } |
||
| 307 | } |
||
| 308 | } else { |
||
| 309 | // the route exists, but we must create a normal index.php?foo=bar URL. |
||
| 310 | |||
| 311 | $isNullRoute = false; |
||
| 312 | $routes = $this->getAffectedRoutes($route, $isNullRoute); |
||
| 313 | if ($isNullRoute) { |
||
| 314 | $params = array_merge($this->inputParameters, $params); |
||
| 315 | } |
||
| 316 | if (count($routes) == 0) { |
||
| 317 | $path = $route; |
||
| 318 | } |
||
| 319 | |||
| 320 | // we collect the default parameters from the route and make sure |
||
| 321 | // new parameters don't overwrite already defined parameters |
||
| 322 | $defaults = array(); |
||
| 323 | |||
| 324 | $ma = $req->getParameter('module_accessor'); |
||
| 325 | $aa = $req->getParameter('controller_accessor'); |
||
| 326 | |||
| 327 | foreach ($routes as $route) { |
||
| 328 | if (isset($this->routes[$route])) { |
||
| 329 | $r = $this->routes[$route]; |
||
| 330 | $myDefaults = array(); |
||
| 331 | |||
| 332 | foreach ($r['opt']['defaults'] as $key => $default) { |
||
| 333 | $myDefaults[$key] = $default->getValue(); |
||
| 334 | } |
||
| 335 | if ($r['opt']['module']) { |
||
| 336 | $myDefaults[$ma] = $r['opt']['module']; |
||
| 337 | } |
||
| 338 | if ($r['opt']['controller']) { |
||
| 339 | $myDefaults[$aa] = $r['opt']['controller']; |
||
| 340 | } |
||
| 341 | |||
| 342 | $defaults = array_merge($myDefaults, $defaults); |
||
| 343 | } |
||
| 344 | } |
||
| 345 | |||
| 346 | $params = array_merge($defaults, $params); |
||
| 347 | } |
||
| 348 | |||
| 349 | if (!isset($path)) { |
||
| 350 | // the route does not exist. we generate a normal index.php?foo=bar URL. |
||
| 351 | $path = $_SERVER['SCRIPT_NAME']; |
||
| 352 | } |
||
| 353 | |||
| 354 | if (!isset($path)) { |
||
|
0 ignored issues
–
show
This
if statement is empty and can be removed.
This check looks for the bodies of These if (rand(1, 6) > 3) {
//print "Check failed";
} else {
print "Check succeeded";
}
could be turned into if (rand(1, 6) <= 3) {
print "Check succeeded";
}
This is much more concise to read. Loading history...
|
|||
| 355 | // routing was off; the name of the route is the input |
||
| 356 | } |
||
| 357 | if (!isset($append)) { |
||
| 358 | $append = '?' . http_build_query($params, '', $aso); |
||
| 359 | } |
||
| 360 | |||
| 361 | $retval = $path . $append; |
||
| 362 | } |
||
| 363 | |||
| 364 | if (!$options['relative'] || |
||
| 365 | ($options['relative'] && ( |
||
| 366 | $options['scheme'] !== null || |
||
| 367 | $options['authority'] !== null || |
||
| 368 | $options['host'] !== null || |
||
| 369 | $options['port'] !== null |
||
| 370 | )) |
||
| 371 | ) { |
||
| 372 | $scheme = false; |
||
| 373 | if ($options['scheme'] !== false) { |
||
| 374 | $scheme = ($options['scheme'] === null ? $req->getUrlScheme() : $options['scheme']); |
||
| 375 | } |
||
| 376 | |||
| 377 | $authority = ''; |
||
| 378 | |||
| 379 | if ($options['authority'] === null) { |
||
| 380 | if ($options['host'] !== null && $options['host'] !== false) { |
||
| 381 | $authority = $options['host']; |
||
| 382 | } elseif ($options['host'] === false) { |
||
| 383 | $authority = ''; |
||
| 384 | } else { |
||
| 385 | $authority = $req->getUrlHost(); |
||
| 386 | } |
||
| 387 | $port = null; |
||
| 388 | if ($options['port'] !== null && $options['port'] !== false) { |
||
| 389 | if (Toolkit::isPortNecessary($options['scheme'] !== null && $options['scheme'] !== false ? $options['scheme'] : $req->getUrlScheme(), $options['port'])) { |
||
| 390 | $port = $options['port']; |
||
| 391 | } else { |
||
| 392 | $port = null; |
||
| 393 | } |
||
| 394 | } elseif ($options['port'] === false) { |
||
| 395 | $port = null; |
||
| 396 | } elseif ($options['scheme'] === null) { |
||
| 397 | if (!Toolkit::isPortNecessary($req->getUrlScheme(), $port = $req->getUrlPort())) { |
||
| 398 | $port = null; |
||
| 399 | } |
||
| 400 | } |
||
| 401 | if ($port !== null) { |
||
| 402 | $authority .= ':' . $port; |
||
| 403 | } |
||
| 404 | } elseif ($options['authority'] !== false) { |
||
| 405 | $authority = $options['authority']; |
||
| 406 | } |
||
| 407 | |||
| 408 | if ($scheme === false) { |
||
| 409 | // nothing at all, e.g. when displaying a URL without the "http://" prefix |
||
| 410 | $scheme = ''; |
||
| 411 | } elseif (trim($scheme) === '') { |
||
| 412 | // a protocol-relative URL (see #1224) |
||
| 413 | $scheme = '//'; |
||
| 414 | } else { |
||
| 415 | // given scheme plus "://" |
||
| 416 | $scheme = $scheme . '://'; |
||
| 417 | } |
||
| 418 | |||
| 419 | $retval = $scheme . $authority . $retval; |
||
| 420 | } |
||
| 421 | |||
| 422 | if ($options['fragment'] !== null) { |
||
| 423 | $retval .= '#' . $options['fragment']; |
||
| 424 | } |
||
| 425 | |||
| 426 | return $retval; |
||
|
0 ignored issues
–
show
The return type of
return $retval; (string) is incompatible with the return type of the parent method Agavi\Routing\Routing::gen of type array.
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function Loading history...
|
|||
| 427 | } |
||
| 428 | |||
| 429 | /** |
||
| 430 | * Escapes an argument to be used in an generated route. |
||
| 431 | * |
||
| 432 | * @param string $string The argument to be escaped. |
||
| 433 | * |
||
| 434 | * @return string The escaped argument. |
||
| 435 | * |
||
| 436 | * @author Dominik del Bondio <[email protected]> |
||
| 437 | * @since 0.11.0 |
||
| 438 | */ |
||
| 439 | public function escapeOutputParameter($string) |
||
| 440 | { |
||
| 441 | return rawurlencode($string); |
||
| 442 | } |
||
| 443 | } |
||
| 444 |
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: