Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
 
3
namespace FastRoute\RouteParser;
4
 
5
use FastRoute\BadRouteException;
6
use FastRoute\RouteParser;
7
 
8
/**
9
 * Parses route strings of the following form:
10
 *
11
 * "/user/{name}[/{id:[0-9]+}]"
12
 */
13
class Std implements RouteParser
14
{
15
    const VARIABLE_REGEX = <<<'REGEX'
16
\{
17
    \s* ([a-zA-Z_][a-zA-Z0-9_-]*) \s*
18
    (?:
19
        : \s* ([^{}]*(?:\{(?-1)\}[^{}]*)*)
20
    )?
21
\}
22
REGEX;
23
    const DEFAULT_DISPATCH_REGEX = '[^/]+';
24
 
25
    public function parse($route)
26
    {
27
        $routeWithoutClosingOptionals = rtrim($route, ']');
28
        $numOptionals = strlen($route) - strlen($routeWithoutClosingOptionals);
29
 
30
        // Split on [ while skipping placeholders
31
        $segments = preg_split('~' . self::VARIABLE_REGEX . '(*SKIP)(*F) | \[~x', $routeWithoutClosingOptionals);
32
        if ($numOptionals !== count($segments) - 1) {
33
            // If there are any ] in the middle of the route, throw a more specific error message
34
            if (preg_match('~' . self::VARIABLE_REGEX . '(*SKIP)(*F) | \]~x', $routeWithoutClosingOptionals)) {
35
                throw new BadRouteException('Optional segments can only occur at the end of a route');
36
            }
37
            throw new BadRouteException("Number of opening '[' and closing ']' does not match");
38
        }
39
 
40
        $currentRoute = '';
41
        $routeDatas = [];
42
        foreach ($segments as $n => $segment) {
43
            if ($segment === '' && $n !== 0) {
44
                throw new BadRouteException('Empty optional part');
45
            }
46
 
47
            $currentRoute .= $segment;
48
            $routeDatas[] = $this->parsePlaceholders($currentRoute);
49
        }
50
        return $routeDatas;
51
    }
52
 
53
    /**
54
     * Parses a route string that does not contain optional segments.
55
     *
56
     * @param string
57
     * @return mixed[]
58
     */
59
    private function parsePlaceholders($route)
60
    {
61
        if (!preg_match_all(
62
            '~' . self::VARIABLE_REGEX . '~x', $route, $matches,
63
            PREG_OFFSET_CAPTURE | PREG_SET_ORDER
64
        )) {
65
            return [$route];
66
        }
67
 
68
        $offset = 0;
69
        $routeData = [];
70
        foreach ($matches as $set) {
71
            if ($set[0][1] > $offset) {
72
                $routeData[] = substr($route, $offset, $set[0][1] - $offset);
73
            }
74
            $routeData[] = [
75
                $set[1][0],
76
                isset($set[2]) ? trim($set[2][0]) : self::DEFAULT_DISPATCH_REGEX
77
            ];
78
            $offset = $set[0][1] + strlen($set[0][0]);
79
        }
80
 
81
        if ($offset !== strlen($route)) {
82
            $routeData[] = substr($route, $offset);
83
        }
84
 
85
        return $routeData;
86
    }
87
}