Passed
Pull Request — master (#196)
by Sergei
02:31
created

FileRoutesProvider::isRoutesAreValid()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 5
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 10
rs 10
ccs 5
cts 5
cp 1
crap 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Router\Provider;
6
7
use Yiisoft\Router\Group;
8
use Yiisoft\Router\Route;
9
10
/**
11
 * A file provider provides routes from a file or directory of files.
12
 */
13
final class FileRoutesProvider implements RoutesProviderInterface
14
{
15 4
    public function __construct(private string $file, private array $scope = [])
16
    {
17 4
    }
18
19 4
    public function getRoutes(): array
20
    {
21 4
        $scopeRequire = static function (string $file, array $scope): mixed {
22 3
            extract($scope, EXTR_SKIP);
23
            /**
24
             * @psalm-suppress UnresolvableInclude
25
             */
26 3
            return require $file;
27 4
        };
28 4
        if (!file_exists($this->file)) {
29 1
            throw new \RuntimeException(
30 1
                'Failed to provide routes from "' . $this->file . '". File or directory not found.'
31 1
            );
32
        }
33 3
        if (is_dir($this->file) && !is_file($this->file)) {
34 1
            $directoryRoutes = [];
35 1
            $files = new \CallbackFilterIterator(
36 1
                new \FilesystemIterator(
37 1
                    $this->file,
38 1
                    \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS
39 1
                ),
40 1
                fn (\SplFileInfo $fileInfo) => $fileInfo->isFile() && $fileInfo->getExtension() === 'php'
41 1
            );
42
            /** @var \SplFileInfo[] $files */
43 1
            foreach ($files as $file) {
44
                /** @var mixed $fileRoutes */
45 1
                $fileRoutes = $scopeRequire($file->getRealPath(), $this->scope);
46 1
                if (is_array($fileRoutes) && $this->isRoutesAreValid($fileRoutes)) {
47 1
                    array_push(
48 1
                        $directoryRoutes,
49 1
                        ...$fileRoutes
50 1
                    );
51
                }
52
            }
53 1
            return $directoryRoutes;
54
        }
55
56
        /** @var mixed $routes */
57 2
        $routes = $scopeRequire($this->file, $this->scope);
58 2
        if (is_array($routes) && $this->isRoutesAreValid($routes)) {
59 1
            return $routes;
60
        }
61
62 1
        return [];
63
    }
64
65
    /**
66
     * @psalm-assert-if-true Route[]|Group[] $routes
67
     */
68 3
    private function isRoutesAreValid(array $routes): bool
69
    {
70 3
        foreach ($routes as $route) {
71
            if (
72 3
                !is_a($route, Route::class, true) && !is_a($route, Group::class, true)
73
            ) {
74 2
                return false;
75
            }
76
        }
77 2
        return true;
78
    }
79
}
80