Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
 
3
/**
4
 * Slim Framework (https://slimframework.com)
5
 *
6
 * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
7
 */
8
 
9
declare(strict_types=1);
10
 
11
namespace Slim\Routing;
12
 
13
use FastRoute\RouteParser\Std;
14
use InvalidArgumentException;
15
use Psr\Http\Message\UriInterface;
16
use Slim\Interfaces\RouteCollectorInterface;
17
use Slim\Interfaces\RouteParserInterface;
18
 
19
use function array_key_exists;
20
use function array_reverse;
21
use function http_build_query;
22
use function implode;
23
use function is_string;
24
 
25
class RouteParser implements RouteParserInterface
26
{
27
    private RouteCollectorInterface $routeCollector;
28
 
29
    private Std $routeParser;
30
 
31
    public function __construct(RouteCollectorInterface $routeCollector)
32
    {
33
        $this->routeCollector = $routeCollector;
34
        $this->routeParser = new Std();
35
    }
36
 
37
    /**
38
     * {@inheritdoc}
39
     */
40
    public function relativeUrlFor(string $routeName, array $data = [], array $queryParams = []): string
41
    {
42
        $route = $this->routeCollector->getNamedRoute($routeName);
43
        $pattern = $route->getPattern();
44
 
45
        $segments = [];
46
        $segmentName = '';
47
 
48
        /*
49
         * $routes is an associative array of expressions representing a route as multiple segments
50
         * There is an expression for each optional parameter plus one without the optional parameters
51
         * The most specific is last, hence why we reverse the array before iterating over it
52
         */
53
        $expressions = array_reverse($this->routeParser->parse($pattern));
54
        foreach ($expressions as $expression) {
55
            foreach ($expression as $segment) {
56
                /*
57
                 * Each $segment is either a string or an array of strings
58
                 * containing optional parameters of an expression
59
                 */
60
                if (is_string($segment)) {
61
                    $segments[] = $segment;
62
                    continue;
63
                }
64
 
65
                /** @var string[] $segment */
66
                /*
67
                 * If we don't have a data element for this segment in the provided $data
68
                 * we cancel testing to move onto the next expression with a less specific item
69
                 */
70
                if (!array_key_exists($segment[0], $data)) {
71
                    $segments = [];
72
                    $segmentName = $segment[0];
73
                    break;
74
                }
75
 
76
                $segments[] = $data[$segment[0]];
77
            }
78
 
79
            /*
80
             * If we get to this logic block we have found all the parameters
81
             * for the provided $data which means we don't need to continue testing
82
             * less specific expressions
83
             */
84
            if (!empty($segments)) {
85
                break;
86
            }
87
        }
88
 
89
        if (empty($segments)) {
90
            throw new InvalidArgumentException('Missing data for URL segment: ' . $segmentName);
91
        }
92
 
93
        $url = implode('', $segments);
94
        if ($queryParams) {
95
            $url .= '?' . http_build_query($queryParams);
96
        }
97
 
98
        return $url;
99
    }
100
 
101
    /**
102
     * {@inheritdoc}
103
     */
104
    public function urlFor(string $routeName, array $data = [], array $queryParams = []): string
105
    {
106
        $basePath = $this->routeCollector->getBasePath();
107
        $url = $this->relativeUrlFor($routeName, $data, $queryParams);
108
 
109
        if ($basePath) {
110
            $url = $basePath . $url;
111
        }
112
 
113
        return $url;
114
    }
115
 
116
    /**
117
     * {@inheritdoc}
118
     */
119
    public function fullUrlFor(UriInterface $uri, string $routeName, array $data = [], array $queryParams = []): string
120
    {
121
        $path = $this->urlFor($routeName, $data, $queryParams);
122
        $scheme = $uri->getScheme();
123
        $authority = $uri->getAuthority();
124
        $protocol = ($scheme ? $scheme . ':' : '') . ($authority ? '//' . $authority : '');
125
        return $protocol . $path;
126
    }
127
}