Completed
Pull Request — master (#638)
by
unknown
12:52
created

RouteMatcher::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
namespace Mpociot\ApiDoc\Matching;
4
5
use Dingo\Api\Routing\RouteCollection;
6
use Illuminate\Routing\Route;
7
use Illuminate\Support\Facades\Route as RouteFacade;
8
use Illuminate\Support\Str;
9
10
class RouteMatcher
11
{
12
    /**
13
     * @var string
14
     */
15
    protected $router;
16
17
    /**
18
     * @var array
19
     */
20
    protected $routeRules;
21
22
    public function __construct(array $routeRules = [], string $router = 'laravel')
23
    {
24
        $this->router = $router;
25
        $this->routeRules = $routeRules;
26
    }
27
28
    public function getRoutes()
29
    {
30
        $usingDingoRouter = strtolower($this->router) == 'dingo';
31
32
        return $this->getRoutesToBeDocumented($this->routeRules, $usingDingoRouter);
33
    }
34
35
    protected function getRoutesToBeDocumented(array $routeRules, bool $usingDingoRouter = false)
36
    {
37
        $allRoutes = $this->getAllRoutes($usingDingoRouter);
38
        $matchedRoutes = [];
39
40
        foreach ($routeRules as $routeRule) {
41
            $includes = $routeRule['include'] ?? [];
42
43
            foreach ($allRoutes as $route) {
44
                if (is_array($route)) {
45
                    $route = new LumenRouteAdapter($route);
46
                }
47
48
                if ($this->shouldExcludeRoute($route, $routeRule)) {
49
                    continue;
50
                }
51
52
                if ($this->shouldIncludeRoute($route, $routeRule, $includes, $usingDingoRouter)) {
53
                    $matchedRoutes[] = [
54
                        'route' => $route,
55
                        'apply' => $routeRule['apply'] ?? [],
56
                    ];
57
                    continue;
58
                }
59
            }
60
        }
61
62
        return $matchedRoutes;
63
    }
64
65
    private function getAllRoutes(bool $usingDingoRouter)
66
    {
67
        if (! $usingDingoRouter) {
68
            return RouteFacade::getRoutes();
69
        }
70
71
        $allRouteCollections = app(\Dingo\Api\Routing\Router::class)->getRoutes();
72
73
        return collect($allRouteCollections)
74
            ->flatMap(function (RouteCollection $collection) {
75
                return $collection->getRoutes();
76
            })->toArray();
77
    }
78
79
    private function shouldIncludeRoute(Route $route, array $routeRule, array $mustIncludes, bool $usingDingoRouter)
80
    {
81
        $matchesVersion = $usingDingoRouter
82
            ? ! empty(array_intersect($route->versions(), $routeRule['match']['versions'] ?? []))
83
            : true;
84
85
        return Str::is($mustIncludes, $route->getName())
86
            || Str::is($mustIncludes, $route->uri())
87
            || (Str::is($routeRule['match']['domains'] ?? [], $route->getDomain())
88
            && Str::is($routeRule['match']['prefixes'] ?? [], $route->uri())
89
            && $matchesVersion);
90
    }
91
92
    private function shouldExcludeRoute(Route $route, array $routeRule)
93
    {
94
        $excludes = $routeRule['exclude'] ?? [];
95
96
        // Exclude this package's routes
97
        $excludes[] = 'apidoc';
98
99
        // Exclude Laravel Telescope routes
100
        if (class_exists("Laravel\Telescope\Telescope")) {
101
            $excludes[] = 'telescope/*';
102
        }
103
104
        return Str::is($excludes, $route->getName())
105
            || Str::is($excludes, $route->uri());
106
    }
107
}
108