RouteManager   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 9
eloc 37
c 3
b 0
f 0
dl 0
loc 92
ccs 42
cts 42
cp 1
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A createRedirect() 0 6 1
A addRoutes() 0 13 2
A updateRoutes() 0 15 3
A deleteRoutes() 0 8 2
A createOrRestoreRoute() 0 16 1
1
<?php
2
3
namespace Oddvalue\DbRouter;
4
5
use Oddvalue\DbRouter\Route;
6
use Illuminate\Database\QueryException;
7
use Oddvalue\DbRouter\Contracts\Routable;
8
use Illuminate\Database\Eloquent\Relations\Relation;
9
use Oddvalue\DbRouter\Contracts\ChildRouteGenerator;
10
use Oddvalue\DbRouter\Exceptions\RouteCollisionException;
11
12
class RouteManager
13
{
14
    /**
15
     * If the slug has changed then softdelete current path for self and all
16
     * descendants and insert new path for self and all descendants
17
     *
18
     * @param \Oddvalue\DbRouter\Contracts\Routable $instance
19
     */
20 36
    public function updateRoutes(Routable $instance)
21
    {
22 36
        $this->deleteRoutes($instance);
23
24 36
        $generator = $instance->getRouteGenerator();
25
26 36
        if (! $generator->isRoutable($instance)) {
27 3
            return;
28
        }
29
30 36
        $this->addRoutes($instance);
31
32 36
        if ($generator instanceof ChildRouteGenerator) {
33
            $generator->getRouteChildren($instance)->map(function ($childInstance) {
34 3
                $this->updateRoutes($childInstance);
35 36
            });
36
        }
37 36
    }
38
39
    /**
40
     * Create new Route OR restore old path if already exists
41
     */
42 36
    public function addRoutes(Routable $instance)
43
    {
44
        try {
45 36
            $routes = collect($instance->getRouteGenerator()->getRoutes($instance));
46
47 36
            $canonicalRouteString = $routes->shift();
48 36
            $canonicalId = $this->createOrRestoreRoute($canonicalRouteString, $instance)->id;
49
50
            $routes->each(function ($route) use ($instance, $canonicalId) {
51 9
                $this->createOrRestoreRoute($route, $instance, $canonicalId);
52 36
            });
53 3
        } catch (QueryException $e) {
54 3
            throw RouteCollisionException::fromQueryException($e);
55
        }
56 36
    }
57
58 36
    public function createOrRestoreRoute(string $routeString, Routable $instance, int $canonicalId = null)
59
    {
60 36
        $type = get_class($instance);
61 36
        $type = Relation::getMorphedModel($type) ?? $type;
62
        Route::onlyTrashed()->whereHasMorph('routable', $type, function ($query) use ($instance) {
63 36
            $keyName = $instance->/** @scrutinizer ignore-call */getKeyName();
64 36
            $query->where($keyName, $instance->{$keyName});
65 36
        })->whereUrl($routeString)->forceDelete();
66
67 36
        $path = $instance->routes()->withTrashed()->firstOrCreate([
68 36
            'url' => $routeString,
69 36
            'canonical_id' => $canonicalId,
70
        ]);
71 36
        $path->restore();
72
73 36
        return $path;
74
    }
75
76
    /**
77
     * Delete existing Route instances for an entity
78
     */
79 36
    public function deleteRoutes(Routable $instance)
80
    {
81 36
        $instance->routes()->delete();
82
83 36
        $generator = $instance->getRouteGenerator();
84 36
        if ($generator instanceof ChildRouteGenerator) {
85
            $generator->getRouteChildren($instance)->map(function ($childInstance) {
86 3
                $this->deleteRoutes($childInstance);
87 36
            });
88
        }
89 36
    }
90
91
    /**
92
     * Create a redirect route
93
     *
94
     * @param string $url
95
     * @param self $route
96
     * @return Route
97
     */
98 6
    public static function createRedirect(string $url, Route $route) : Route
99
    {
100 6
        $redirect = new Route(['url' => $url]);
101 6
        $redirect->redirect()->associate($route);
102 6
        $redirect->save();
103 6
        return $redirect;
104
    }
105
}
106