Router   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 65
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 26
c 3
b 0
f 0
dl 0
loc 65
rs 10
wmc 8

1 Method

Rating   Name   Duplication   Size   Complexity  
B relativePathFor() 0 51 8
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2016-2020
6
 * @package Slim
7
 */
8
9
10
namespace Aimeos\Slim;
11
12
use InvalidArgumentException;
13
14
15
/**
16
 * Router
17
 *
18
 * This class organizes Slim application route objects. It is responsible
19
 * for registering route objects, assigning names to route objects,
20
 * finding routes that match the current HTTP request, and creating
21
 * URLs for a named route.
22
 */
23
class Router extends \Slim\Router
24
{
25
	/**
26
	 * Build the path for a named route excluding the base path
27
	 *
28
	 * @param string $name		Route name
29
	 * @param array  $data		Named argument replacement data
30
	 * @param array  $queryParams Optional query string parameters
31
	 *
32
	 * @return string
33
	 *
34
	 * @throws RuntimeException		 If named route does not exist
35
	 * @throws InvalidArgumentException If required data not provided
36
	 */
37
	public function relativePathFor( $name, array $data = [], array $queryParams = [] )
38
	{
39
		$route = $this->getNamedRoute($name);
40
		$pattern = $route->getPattern();
41
42
		$routeDatas = $this->routeParser->parse($pattern);
43
		// $routeDatas is an array of all possible routes that can be made. There is
44
		// one routedata for each optional parameter plus one for no optional parameters.
45
		//
46
		// The most specific is last, so we look for that first.
47
		$routeDatas = array_reverse($routeDatas);
48
49
		$segments = $segmentKeys = [];
50
		foreach ( $routeDatas as $routeData ) {
51
			foreach ( $routeData as $item ) {
52
				if ( is_string($item) ) {
53
					// this segment is a static string
54
					$segments[] = $item;
55
					continue;
56
				}
57
58
				// This segment has a parameter: first element is the name
59
				if ( !array_key_exists($item[0], $data) ) {
60
					// we don't have a data element for this segment: cancel
61
					// testing this routeData item, so that we can try a less
62
					// specific routeData item.
63
					$segments = [];
64
					$segmentName = $item[0];
65
					break;
66
				}
67
				$segments[] = $data[$item[0]];
68
				$segmentKeys[$item[0]] = true;
69
			}
70
			if ( !empty($segments) ) {
71
				// we found all the parameters for this route data, no need to check
72
				// less specific ones
73
				break;
74
			}
75
		}
76
77
		if ( empty($segments) ) {
78
			throw new InvalidArgumentException('Missing data for URL segment: ' . $segmentName);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $segmentName does not seem to be defined for all execution paths leading up to this point.
Loading history...
79
		}
80
		$url = implode('', $segments);
81
82
		$params = array_merge(array_diff_key($data, $segmentKeys), $queryParams);
83
		if ( $params ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $params of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
84
			$url .= '?' . http_build_query($params);
85
		}
86
87
		return $url;
88
	}
89
}
90