FactoryRouter   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 177
Duplicated Lines 0 %

Importance

Changes 5
Bugs 1 Features 0
Metric Value
wmc 17
eloc 50
c 5
b 1
f 0
dl 0
loc 177
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A build() 0 12 2
A __construct() 0 8 1
A getFileName() 0 5 1
A addFile() 0 21 3
A addDir() 0 18 6
A checkClass() 0 15 3
A pathToNamespace() 0 4 1
1
<?php
2
3
namespace ThallesDella\FactoryRouter;
4
5
use ArrayObject;
6
use CoffeeCode\Router\Router;
7
use ThallesDella\FactoryRouter\Exceptions\ClassNotFoundException;
8
use ThallesDella\FactoryRouter\Exceptions\DirectoryNotFoundException;
9
use ThallesDella\FactoryRouter\Exceptions\FileNotFoundException;
10
use ThallesDella\FactoryRouter\Exceptions\UpdateRouterMissingMethodException;
11
12
/**
13
 * Factory Router | Class FactoryRouter
14
 *
15
 * @category FactoryRouter
16
 * @package  ThallesDella\FactoryRouter
17
 * @author   Thalles D. koester <[email protected]>
18
 * @license  https://choosealicense.com/licenses/mit/ MIT
19
 * @link     https://github.com/thallesdella/factory-router
20
 */
21
class FactoryRouter
22
{
23
    /**
24
     * Router object
25
     *
26
     * @var Router
27
     */
28
    private $router;
29
    
30
    /**
31
     * Target ArrayObject
32
     *
33
     * @var ArrayObject
34
     */
35
    private $target;
36
    
37
    /**
38
     * Project root folder
39
     *
40
     * @var string
41
     */
42
    private $project_root;
43
    
44
    /**
45
     * FactoryRouter constructor.
46
     *
47
     * @param string $projectUrl  Base url of project
48
     * @param string $projectRoot Path to the project root folder
49
     * @param string $namespace   Default namespace of the controllers
50
     */
51
    public function __construct(string $projectUrl, string $projectRoot, string $namespace)
52
    {
53
        $this->router = new Router($projectUrl);
54
        $this->router->namespace($namespace);
55
    
56
        $this->project_root = $projectRoot;
57
    
58
        $this->target = new ArrayObject();
59
    }
60
    
61
    /**
62
     * Scan directory for targets
63
     *
64
     * @param string $dir Relative path of directory
65
     *
66
     * @return FactoryRouter
67
     *
68
     * @throws ClassNotFoundException
69
     * @throws DirectoryNotFoundException
70
     * @throws FileNotFoundException
71
     * @throws UpdateRouterMissingMethodException
72
     */
73
    public function addDir(string $dir): FactoryRouter
74
    {
75
        $path = "{$this->project_root}/{$dir}";
76
        if (!file_exists($dir) || !is_dir($dir)) {
77
            $error = new DirectoryNotFoundException('Directory not found');
78
            $error->file = $dir;
79
            throw $error;
80
        }
81
        
82
        $dirFiles = scandir($path);
83
        
84
        foreach ($dirFiles as $file) {
85
            if ($file == '.' || $file == '..') {
86
                continue;
87
            }
88
            $this->addFile("{$dir}/{$file}");
89
        }
90
        return $this;
91
    }
92
    
93
    /**
94
     * Add file as target
95
     *
96
     * @param string $file Relative path of file
97
     *
98
     * @return FactoryRouter
99
     *
100
     * @throws ClassNotFoundException
101
     * @throws FileNotFoundException
102
     * @throws UpdateRouterMissingMethodException
103
     */
104
    public function addFile(string $file): FactoryRouter
105
    {
106
        $fileInfo = new ArrayObject(
107
            [
108
                "filename" => $this->getFileName($file),
109
                "handler" => $this->pathToNamespace($file),
110
                "path" => "{$this->project_root}/{$file}"
111
            ],
112
            ArrayObject::ARRAY_AS_PROPS
113
        );
114
        
115
        if (!file_exists($fileInfo->path) || !is_file($fileInfo->path)) {
0 ignored issues
show
Bug introduced by
The property path does not seem to exist on ArrayObject.
Loading history...
116
            $error = new FileNotFoundException('File not found');
117
            $error->file = $fileInfo->filename;
0 ignored issues
show
Bug introduced by
The property filename does not seem to exist on ArrayObject.
Loading history...
118
            throw $error;
119
        }
120
        include_once $fileInfo->path;
121
    
122
        $this->checkClass($fileInfo);
123
        $this->target->append($fileInfo);
124
        return $this;
125
    }
126
    
127
    /**
128
     * Build router
129
     *
130
     * @return Router
131
     */
132
    public function build(): Router
133
    {
134
        foreach ($this->target->getIterator() as $fileInfo) {
135
            /**
136
             * Instance of the router manager
137
             *
138
             * @var Routes $routes
139
             */
140
            $routes = new $fileInfo->handler($this->router);
141
            $routes->updateRouter();
142
        }
143
        return $this->router;
144
    }
145
    
146
    /**
147
     * Check if is a valid class
148
     *
149
     * @param ArrayObject $fileInfo ArrayObject containing file's information
150
     *
151
     * @return void
152
     *
153
     * @throws ClassNotFoundException
154
     * @throws UpdateRouterMissingMethodException
155
     */
156
    private function checkClass(ArrayObject $fileInfo): void
157
    {
158
        if (!class_exists($fileInfo->handler)) {
0 ignored issues
show
Bug introduced by
The property handler does not seem to exist on ArrayObject.
Loading history...
159
            $error = new ClassNotFoundException("Class not found");
160
            $error->file = $fileInfo->filename;
0 ignored issues
show
Bug introduced by
The property filename does not seem to exist on ArrayObject.
Loading history...
161
            throw $error;
162
        }
163
        
164
        if (!method_exists($fileInfo->handler, 'updateRouter')) {
165
            $error = new UpdateRouterMissingMethodException("Method updateRouter not found");
166
            $error->file = $fileInfo->filename;
167
            throw $error;
168
        }
169
        
170
        return;
171
    }
172
    
173
    /**
174
     * Converts a path to a file into the file's namespace
175
     *
176
     * @param string $path Path to be transform
177
     *
178
     * @return string
179
     */
180
    private function pathToNamespace(string $path): string
181
    {
182
        $buffer = str_replace('/', '\\', ucwords($path, '/'));
183
        return explode('.', $buffer)[0];
184
    }
185
    
186
    /**
187
     * Get the file name, without extension
188
     *
189
     * @param string $path Path of file
190
     *
191
     * @return string
192
     */
193
    private function getFileName(string $path): string
194
    {
195
        $array = explode('/', $path);
196
        $file = end($array);
197
        return explode('.', $file)[0];
198
    }
199
    
200
}
201