Completed
Push — master ( 854a10...1fcf15 )
by Philipp
02:12
created

Dialect::findRouteNameByPath()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
c 0
b 0
f 0
nc 3
nop 1
dl 0
loc 9
rs 10
1
<?php
2
3
namespace Pmochine\LaravelTongue;
4
5
use Pmochine\LaravelTongue\Misc\Url;
6
use Illuminate\Http\RedirectResponse;
7
use Illuminate\Foundation\Application;
8
use Pmochine\LaravelTongue\Misc\Config;
9
use Pmochine\LaravelTongue\Accent\Accent;
10
use Pmochine\LaravelTongue\Localization\Localization;
11
12
/**
13
 * This class was written by
14
 * https://github.com/hoyvoy/laravel-subdomain-localization
15
 * Now is the time to have my own dialect with it :P.
16
 */
17
class Dialect
18
{
19
    /**
20
     * Our instance of the Laravel app.
21
     *
22
     * @var \Illuminate\Foundation\Application
23
     */
24
    protected $app = '';
25
26
    /**
27
     * An array that contains information about the current request.
28
     *
29
     * @var array
30
     */
31
    protected $parsed_url;
32
33
    /**
34
     * An array that contains all routes that should be translated.
35
     *
36
     * @var array
37
     */
38
    protected $translatedRoutes = [];
39
40
    public function __construct(Application $app)
41
    {
42
        $this->app = $app;
43
    }
44
45
    /**
46
     * Adds the detected locale to the current unlocalized URL.
47
     *
48
     * @return string
49
     */
50
    public function redirectUrl($url = null)
51
    {
52
        $parsed_url = parse_url($url ?? request()->fullUrl());
53
54
        $domain = Url::domain();
55
56
        if (Config::beautify() && Localization::fromUrl() === Config::fallbackLocale()) {
57
            $parsed_url['host'] = $domain;
58
        } else {
59
            $parsed_url['host'] = tongue()->current() . '.' . $domain;
60
        }
61
62
        return Accent::unparseUrl($parsed_url);
63
    }
64
65
    /**
66
     * Creates the redirect response.
67
     *
68
     * @param  string
69
     * @return \Illuminate\Http\RedirectResponse;
70
     */
71
    public function redirect(string $redirection)
72
    {
73
        // Save any flashed data for redirect
74
        app('session')->reflash();
75
76
        return new RedirectResponse($redirection, 302, ['Vary' => 'Accept-Language']);
77
    }
78
79
    /**
80
     * Translate the current route for the given locale.
81
     *
82
     * @param $locale
83
     *
84
     * @return bool|string
85
     */
86
    public function current($locale)
87
    {
88
        return $this->translate($this->currentRouteName(), Accent::currentRouteAttributes(), $locale);
89
    }
90
91
    /**
92
     * Get all Translations for the current URL.
93
     *
94
     * @param bool $excludeCurrentLocale
95
     *
96
     * @return array
97
     */
98
    public function translateAll($excludeCurrentLocale = true)
99
    {
100
        $versions = [];
101
102
        foreach (tongue()->speaking()->keys()->all() as $locale) {
103
            if ($excludeCurrentLocale && $locale == tongue()->current()) {
104
                continue;
105
            }
106
107
            if ($url = $this->current($locale)) {
108
                $versions[$locale] = $url;
109
            }
110
        }
111
112
        return $versions;
113
    }
114
115
    /**
116
     * Return translated URL from route.
117
     *
118
     * @param string       $routeName
119
     * @param string|false $routeAttributes
120
     * @param string|false $locale
121
     *
122
     * @return string|bool
123
     */
124
    public function translate($routeName, $routeAttributes = null, $locale = null)
125
    {
126
        // If no locale is given, we use the current locale
127
        if (!$locale) {
128
            $locale = tongue()->current();
129
        }
130
131
        if (empty($this->parsed_url)) {
132
            $this->parsed_url = Accent::parseCurrentUrl();
133
        }
134
135
        // Retrieve the current URL components
136
        $parsed_url = $this->parsed_url;
137
138
        $parsed_url['host'] = $this->addLocaleToHost($locale);
139
140
        // Resolve the translated route path for the given route name
141
        $translatedPath = Accent::findRoutePathByName($routeName, $locale);
142
143
        if ($translatedPath !== false) {
144
            $parsed_url['path'] = $translatedPath;
145
        }
146
147
        // If attributes are given, substitute them in the path
148
        if ($routeAttributes) {
149
            $parsed_url['path'] = Accent::substituteAttributesInRoute($routeAttributes, $parsed_url['path']);
150
        }
151
152
        return Accent::unparseUrl($parsed_url);
153
    }
154
155
    /**
156
     * If we have beautify on and the given $locale is the same
157
     * to the current locale and to the fallbackLocal.
158
     * We don't need to add a subdomain to the host.
159
     *
160
     * @param string $locale
161
     * @return string
162
     */
163
    protected function addLocaleToHost($locale)
164
    {
165
        if (Config::beautify() && $locale === tongue()->current() && $locale === Config::fallbackLocale()) {
166
            return Url::domain();
167
        }
168
169
        // Add locale to the host
170
        return $locale . '.' . Url::domain();
171
    }
172
173
    /**
174
     * Interprets a translated route path for the given route name.
175
     *
176
     * @param $routeName
177
     *
178
     * @return mixed (but should be string if it exists!)
179
     */
180
    public function interpret($routeName)
181
    {
182
        $routePath = Accent::findRoutePathByName($routeName);
183
184
        if (!isset($this->translatedRoutes[$routeName])) {
185
            $this->translatedRoutes[$routeName] = $routePath;
186
        }
187
188
        return $routePath;
189
    }
190
191
    /**
192
     * Get the current route name.
193
     *
194
     * @return bool|string
195
     */
196
    protected function currentRouteName()
197
    {
198
        if (app('router')->currentRouteName()) {
199
            return app('router')->currentRouteName();
200
        }
201
202
        if (app('router')->current()) {
203
            return $this->findRouteNameByPath(app('router')->current()->uri());
204
        }
205
206
        return false;
207
    }
208
209
    /**
210
     * Find the route name matching the given route path.
211
     *
212
     * @param string $routePath
213
     *
214
     * @return bool|string
215
     */
216
    public function findRouteNameByPath($routePath)
217
    {
218
        foreach ($this->translatedRoutes as $name => $path) {
219
            if ($routePath == $path) {
220
                return $name;
221
            }
222
        }
223
224
        return false;
225
    }
226
227
    /**
228
     * Redirect back to the latest locale.
229
     * Used, when no language is found.
230
     */
231
    public function redirectBackToLatest()
232
    {
233
        tongue()->speaks(Localization::currentTongue());
234
235
        return dialect()->redirect(dialect()->redirectUrl());
236
    }
237
}
238