Router::execute()   C
last analyzed

Complexity

Conditions 8
Paths 13

Size

Total Lines 27
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 27
rs 5.3846
cc 8
eloc 15
nc 13
nop 2
1
<?php
2
namespace PHPico;
3
4
class Router {
5
6
    /**
7
     * Get the base from any possible url
8
     * return string
9
     */
10
    public function base()
0 ignored issues
show
Coding Style introduced by
base uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
11
    {
12
        $b = strtr($_SERVER['SCRIPT_NAME'], ['index.php'=>'']);
13
        return strtr($_SERVER['REQUEST_URI'], [$b => '/']);
14
    }
15
    
16
    /**
17
     * Executes an array of routes. Should be properly formatted:
18
     * ['regex'=>'class@method']
19
     * ['regex'=> ['GET','class@method']]
20
     * By default index() method will be taken.
21
     * No need of /^...$/ inside of regex.
22
     * Returns false if route not found.
23
     * 
24
     * @var $routes array The routes array
25
     * @return string|false
26
     */
27
    public function dispatch($routes)
28
    {
29
        $result = null;
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
30
        foreach($routes as $regex => $callable){
31
            $result = $this->execute($regex, $callable);
32
            if($result !== false) return $result;
33
        }
34
        return false;
35
    }
36
    
37
    /**
38
     * Executes the request this regex and the route params. Could be a callable.
39
     * @var $regex string The regex
40
     * @var $route string|callable The route to be executed
41
     * return string|boolean The result
42
     */
43
    public function execute($regex, $callable)
0 ignored issues
show
Coding Style introduced by
execute uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
44
    {
45
        if(is_array($callable)){
46
            $callable = end($callable);
47
            foreach($callable as $conf){
48
                if($conf !== $_SERVER['REQUEST_METHOD']) return false;
49
            }
50
        }
51
        
52
        if(preg_match('/^'.$regex.'$/', $this->base(), $matches)){
53
            
54
            array_shift($matches);
55
            
56
            if(is_callable($callable)){
57
                return call_user_func_array($callable, $matches);
58
            }
59
            
60
            list($class, $method) = explode('@', $callable);
61
            
62
            $method = !preg_match('/\@/', $callable) ? 'index' : $method ;
63
            $class = class_exists($class) ? $class : $callable;
64
65
            $c = new $class();
66
            return call_user_func_array(array($c, $method), $matches);
67
        }
68
        return false;
69
    }
70
}
71