Passed
Push — master ( 3c754e...e72f0b )
by Kanto
03:33
created

Application::parseController()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 20
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 14
c 1
b 0
f 0
nc 5
nop 1
dl 0
loc 20
rs 9.7998
1
<?php
2
namespace Kore;
3
4
class Application
5
{
6
    /**
7
     * @var string
8
     */
9
    protected $basePath = '';
10
    /**
11
     * @var string
12
     */
13
    protected $defaultController = 'index';
14
    /**
15
     * @var callable
16
     */
17
    protected $notFound;
18
19
    /**
20
     * @param string $basePath ex. 'mybasepath'
21
     * @return void
22
     */
23
    public function setBasePath($basePath)
24
    {
25
        $this->basePath = $basePath;
26
    }
27
28
    /**
29
     * @param string $defaultController
30
     * @return void
31
     */
32
    public function setDefaultController($defaultController)
33
    {
34
        $this->defaultController = $defaultController;
35
    }
36
37
    /**
38
     * @param callable $notFound
39
     * @return void
40
     */
41
    public function setNotFound($notFound)
42
    {
43
        if (is_callable($notFound)) {
44
            $this->notFound = $notFound;
45
        }
46
    }
47
    
48
    /**
49
     * @param string|null $path
50
     * @return void
51
     */
52
    public function run($path = null)
53
    {
54
        if ($path === null) {
55
            $path = $_SERVER['REQUEST_URI'];
56
        }
57
        if (!empty($this->basePath) && strpos($path, $this->basePath) === 0) {
58
            $path = substr($path, strlen($this->basePath));
59
        }
60
        if (false !== $pos = strpos($path, '?')) {
61
            $path = substr($path, 0, $pos);
62
        }
63
        $path = rawurldecode($path);
64
        $path = trim($path, '/');
65
66
        list($class, $controller, $args) = $this->parseController($path);
67
68
        if ($class === null) {
69
            if (is_callable($this->notFound)) {
70
                call_user_func($this->notFound);
71
            }
72
            http_response_code(404);
73
            return;
74
        }
75
    
76
        $class->main($controller, $args);
77
    }
78
79
    /**
80
     * @param string $path
81
     * @return array<mixed>
82
     */
83
    protected function parseController($path)
84
    {
85
        $parray = explode('/', $path);
86
    
87
        $class = null;
88
        $controller = $this->defaultController;
89
        $args = [];
90
        foreach ($parray as $i => $p) {
91
            $tmpController = implode('\\', array_slice($parray, 0, $i+1));
92
            if ($tmpController !== '') {
93
                $controller = $tmpController;
94
            }
95
            $controller = CONTROLLERS_NS.'\\'.$controller;
96
            if (class_exists($controller)) {
97
                $class = new $controller();
98
                $args = array_slice($parray, $i+1);
99
                break;
100
            }
101
        }
102
        return [$class, $controller, $args];
103
    }
104
105
    /**
106
     * @param array<string> $argv
107
     * @return void
108
     */
109
    public function runCmd($argv)
110
    {
111
        if (!isset($argv[1])) {
112
            throw new \Exception('Unable to find command name');
113
        }
114
115
        list($class, $command, $args, $opts) = $this->parseCommand($argv);
116
117
        if ($class === null) {
118
            throw new \Exception('Unable to load command class ->' . $command);
119
        }
120
121
        $class->main($command, $args, $opts);
122
    }
123
124
    /**
125
     * @param array<string> $argv
126
     * @return array<mixed>
127
     */
128
    protected function parseCommand($argv)
129
    {
130
        $class = null;
131
        $command = COMMANDS_NS.'\\'.str_replace('/', '\\', $argv[1]);
132
        $args = [];
133
        $opts = [];
134
135
        if (!class_exists($command)) {
136
            return [$class, $command, $args, $opts];
137
        }
138
139
        $class = new $command();
140
        foreach ($argv as $key => $value) {
141
            if ($key > 1) {
142
                if (preg_match('/^--[a-zA-Z0-9]+=[a-zA-Z0-9]+$/', $value)) {
143
                    $params = explode('=', $value);
144
                    $name = str_replace('--', '', $params[0]);
145
                    $opts[$name] = $params[1];
146
                } else {
147
                    $args[] = $value;
148
                }
149
            }
150
        }
151
        return [$class, $command, $args, $opts];
152
    }
153
}
154