Completed
Push — master ( 976d79...2f341b )
by Chin
06:27 queued 10s
created

MultilingualRegistrar   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 194
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 0
loc 194
rs 10
c 0
b 0
f 0
wmc 21
lcom 1
cbo 4

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A register() 0 14 2
A registerRoute() 0 10 2
A generateRoute() 0 20 3
A getRequestMethodFromOptions() 0 10 2
A generateNameForLocaleFromOptions() 0 12 2
A generatePrefixForLocale() 0 14 4
A generateUriFromKey() 0 8 3
A applyUniqueRegistrationKey() 0 4 1
A cleanUniqueRegistrationKey() 0 4 1
1
<?php
2
3
namespace ChinLeung\LaravelMultilingualRoutes;
4
5
use Illuminate\Routing\Route;
6
use Illuminate\Routing\RouteCollection;
7
use Illuminate\Routing\Router;
8
use Illuminate\Support\Arr;
9
10
class MultilingualRegistrar
11
{
12
    /**
13
     * The router instance.
14
     *
15
     * @var \Illuminate\Routing\Router
16
     */
17
    protected $router;
18
19
    /**
20
     * Constructor of the class.
21
     *
22
     * @param  \Illuminate\Routing\Router  $router
23
     */
24
    public function __construct(Router $router)
25
    {
26
        $this->router = $router;
27
    }
28
29
    /**
30
     * Register the routes.
31
     *
32
     * @param  string  $key
33
     * @param  mixed  $handle
34
     * @param  array  $locales
35
     * @param  array  $options
36
     * @return \Illuminate\Routing\RouteCollection
37
     */
38
    public function register(string $key, $handle, array $locales, array $options) : RouteCollection
39
    {
40
        $collection = new RouteCollection;
41
42
        foreach ($locales as $locale) {
43
            $collection->add(
44
                $this
45
                    ->registerRoute($key, $handle, $locale, $options)
46
                    ->name($this->generateNameForLocaleFromOptions($locale, $key, $options))
47
            );
48
        }
49
50
        return $collection;
51
    }
52
53
    /**
54
     * Register a single route.
55
     *
56
     * @param  string  $key
57
     * @param  mixed  $handle
58
     * @param  string  $locale
59
     * @param  array  $options
60
     * @return \Illuminate\Routing\Route
61
     */
62
    protected function registerRoute(string $key, $handle, string $locale, array $options) : Route
63
    {
64
        $route = $this->generateRoute($key, $handle, $locale, $options);
65
66
        if ($prefix = $this->generatePrefixForLocale($key, $locale)) {
67
            $route->setUri("{$prefix}/{$route->uri}");
68
        }
69
70
        return $this->cleanUniqueRegistrationKey($route, $locale);
71
    }
72
73
    /**
74
     * Generate a route.
75
     *
76
     * @param  string  $key
77
     * @param  mixed  $handle
78
     * @param  string  $locale
79
     * @param  array  $options
80
     * @return \Illuminate\Routing\Route
81
     */
82
    protected function generateRoute(string $key, $handle, string $locale, array $options) : Route
83
    {
84
        $route = $this->router->addRoute(
85
            $this->getRequestMethodFromOptions($options),
86
            $this->applyUniqueRegistrationKey(
87
                $this->generateUriFromKey($key, $locale),
88
                $locale
89
            ),
90
            $handle ?: '\Illuminate\Routing\ViewController'
91
        );
92
93
        if (is_null($handle)) {
94
            return $route
95
                ->defaults('view', Arr::get($options, 'view', $key))
96
                ->defaults('data', Arr::get($options, 'data', []))
97
            ;
98
        }
99
100
        return $route;
101
    }
102
103
    /**
104
     * Retrieve the request method from the options.
105
     *
106
     * @param  array  $options
107
     * @return array
108
     */
109
    protected function getRequestMethodFromOptions(array $options) : array
110
    {
111
        $method = $options['method'] ?? 'get';
112
113
        if ($method == 'get') {
114
            return ['GET', 'HEAD'];
115
        }
116
117
        return [strtoupper($method)];
118
    }
119
120
    /**
121
     * Generate the name of the route based on the options.
122
     *
123
     * @param  string  $locale
124
     * @param  string  $key
125
     * @param  array  $options
126
     * @return string
127
     */
128
    protected function generateNameForLocaleFromOptions(string $locale, string $key, array $options) : string
129
    {
130
        if ($name = Arr::get($options, "names.$locale")) {
131
            return "$locale.$name";
132
        }
133
134
        return sprintf(
135
            '%s.%s',
136
            $locale,
137
            Arr::get($options, 'name', $key)
138
        );
139
    }
140
141
    /**
142
     * Generate the prefix of the route based on the options.
143
     *
144
     * @param  string  $key
145
     * @param  string  $locale
146
     * @return string|null
147
     */
148
    protected function generatePrefixForLocale(string $key, string $locale) : ?string
149
    {
150
        if ($key == '/') {
151
            return null;
152
        }
153
154
        if ($locale != config('app.fallback_locale')) {
155
            return $locale;
156
        }
157
158
        return config('laravel-multilingual-routes.prefix_fallback')
159
            ? $locale
160
            : null;
161
    }
162
163
    /**
164
     * Generate the route uri from the translation key and locale.
165
     *
166
     * @param  string  $key
167
     * @param  string  $locale
168
     * @return string
169
     */
170
    protected function generateUriFromKey(string $key, string $locale) : string
171
    {
172
        if ($key == '/') {
173
            return $locale == config('app.fallback_locale') ? '/' : "/$locale";
174
        }
175
176
        return trans("routes.$key", [], $locale);
177
    }
178
179
    /**
180
     * Apply the unique registration key to make sure the route is registered.
181
     *
182
     * @param  string  $uri
183
     * @param  string  $locale
184
     * @return string
185
     */
186
    protected function applyUniqueRegistrationKey(string $uri, string $locale) : string
187
    {
188
        return "__{$locale}__".$uri;
189
    }
190
191
    /**
192
     * Clean the unique registration key from the route uri after it has been
193
     * registered in the router.
194
     *
195
     * @param  \Illuminate\Routing\Route  $route
196
     * @param  string  $locale
197
     * @return \Illuminate\Routing\Route
198
     */
199
    protected function cleanUniqueRegistrationKey(Route $route, string $locale) : Route
200
    {
201
        return $route->setUri(str_replace("__{$locale}__", '', $route->uri));
202
    }
203
}
204