summaryrefslogtreecommitdiff
path: root/core/classes/Route.php
blob: ab0a0a74993bb2bb2a834bae43dc8f348a959ad7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<?php

/** Route
 * ---
 * Methods:
 * - add( expression , callback_function , method )
 * - notFound( callback_function )
 * - methodNotAllowed( callback_function )
 * - run()
 *
 * + matches static paths
 * + matches dynamic paths through regex expressions
 * + takes care of request-method
 */
class Route {

    private static $routes = Array();       // array to host routes
    private static $notFound = null;        // 404 error function
    private static $methodNotAllowed = null;    // 404 error function

    /** add (route)
     * ---
     * @param string $expression : static or regex matcher
     * @param callback $function : function to be executed if expression is matched
     * @param string $method : get / post / any
     */
    public static function add( $expression, $function, $method = 'get' )
    {
        array_push(self::$routes, Array(
            'expression' => $expression,
            'function' => $function,
            'method' => strtolower($method)
        ));
    }


    /** notFound($function)
     * ---
     * @param callback $function : callback function to be executed
     */
    public static function notFound($function)
    {
        self::$notFound = $function;
    }


    /** run()
     * ---
     * Parse request ; Find mathing route ;
     * then call route's function
     * usualy a Controller::method([poarametres])
     */
    public static function run(Request $request)
    {
        // $request = Registry::get('REQUEST');
        $path   = $request->PATH;       // request path
        $method = $request->METHOD;     // request method

        $path_match_found = false;
        $route_match_found = false;

        foreach(self::$routes as $route) {

            // If method matched check the path
            if ($route['method'] == $method || $method == 'any') {

                // Add 'find string start' automatically
                $route['expression'] = '^'.$route['expression'];

                // Add 'find string end' automatically
                $route['expression'] = $route['expression'].'$';

                // Check path match
                if (preg_match('#'. $route['expression'] .'#', $path, $matches)) {

                    $route_match_found = true;

                    array_shift($matches);  // Always remove first element. This contains the whole string

                    call_user_func_array($route['function'], $matches);
                    break;  // Do not check other routes

                }
            }
        }

        // No matching route was found
        if (!$route_match_found) {
            header("HTTP/1.0 404 Not Found");
            if (self::$notFound) {
                call_user_func_array(self::$notFound, []);
            }
        }

    }

}