Completed
Push — master ( 34b351...9f2396 )
by Aimeos
01:49
created

Router::process()   B

Complexity

Conditions 6
Paths 12

Size

Total Lines 27
Code Lines 14

Duplication

Lines 3
Ratio 11.11 %

Importance

Changes 0
Metric Value
dl 3
loc 27
rs 8.439
c 0
b 0
f 0
cc 6
eloc 14
nc 12
nop 2
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2016
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);
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