RouteBuilder::getUrlGenerator()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
namespace TomHart\Routing;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Routing\Router;
7
use Illuminate\Routing\UrlGenerator;
8
use Symfony\Component\Routing\Exception\RouteNotFoundException;
9
use TomHart\Utilities\ArrayUtil;
10
11
class RouteBuilder
12
{
13
    public function __construct()
14
    {
15
    }
16
17
    /**
18
     * Get the router instance.
19
     *
20
     * @return Router
21
     */
22
    private function getRouter(): Router
23
    {
24
        return app('router');
25
    }
26
27
    /**
28
     * Get the UrlGenerator.
29
     *
30
     * @return UrlGenerator
31
     */
32
    private function getUrlGenerator(): UrlGenerator
33
    {
34
        return app('url');
35
    }
36
37
    /**
38
     * This allows a route to be dynamically built just from a Model instance.
39
     * Imagine a route called "test":
40
     *      '/test/{name}/{id}'
41
     * Calling:
42
     *      routeFromModel('test', Site::find(8));
43
     * will successfully build the route, as "name" and "id" are both attributes on the Site model.
44
     *
45
     * Further more, once using routeFromModel, the route can be changed. Without changing the call:
46
     *      routeFromModel('test', Site::find(8));
47
     * You can change the route to be:
48
     *      '/test/{name}/{id}/{parent->relationship->value}/{slug}/{otherParent->value}'
49
     * And the route will successfully change, as all the extra parts can be extracted from the Model.
50
     * Relationships can be called and/or chained with "->" (Imagine Model is a Order):
51
     *      {customer->address->postcode}
52
     * Would get the postcode of the customer who owns the order.
53
     *
54
     * @param string  $routeName The route you want to build
55
     * @param Model   $model     The model to pull the data from
56
     * @param mixed[] $data      Data to build into the route when it doesn't exist on the model
57
     *
58
     * @return string The built URL.
59
     */
60
    public function routeFromModel(string $routeName, Model $model, array $data = [])
61
    {
62
        $router = $this->getRouter();
63
        $urlGen = $this->getUrlGenerator();
64
        $route = $router->getRoutes()->getByName($routeName);
65
66
        if (!$route) {
67
            throw new RouteNotFoundException("Route $routeName not found");
68
        }
69
70
        $params = $route->parameterNames();
71
72
        $data = ArrayUtil::populateArrayFromObject($params, $model, $data);
73
74
        return rtrim($urlGen->route($routeName, $data), '?');
75
    }
76
}
77