Dialect::translateAll()   A
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 5
eloc 7
c 1
b 1
f 0
nc 4
nop 1
dl 0
loc 15
rs 9.6111
1
<?php
2
3
namespace Pmochine\LaravelTongue;
4
5
use Illuminate\Foundation\Application;
6
use Illuminate\Http\RedirectResponse;
7
use Pmochine\LaravelTongue\Accent\Accent;
8
use Pmochine\LaravelTongue\Localization\Localization;
9
use Pmochine\LaravelTongue\Misc\Config;
10
use Pmochine\LaravelTongue\Misc\Url;
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, string $locale = null)
51
    {
52
        $parsed_url = parse_url($url ?? request()->fullUrl());
53
54
        $domain = Url::domain();
55
56
        if (Config::beautify() && tongue()->current() === Config::fallbackLocale()) {
57
            $parsed_url['host'] = $domain;
58
        } else {
59
            $parsed_url['host'] = tongue()->current().'.'.$domain;
60
        }
61
62
        if ($locale) {
63
            $parsed_url['host'] = $locale.'.'.$domain;
64
        }
65
66
        return Accent::unparseUrl($parsed_url);
67
    }
68
69
    /**
70
     * Creates the redirect response.
71
     *
72
     * @param  string
73
     * @return \Illuminate\Http\RedirectResponse;
74
     */
75
    public function redirect(string $redirection)
76
    {
77
        // Save any flashed data for redirect
78
        app('session')->reflash();
79
80
        return new RedirectResponse($redirection, 302, ['Vary' => 'Accept-Language']);
81
    }
82
83
    /**
84
     * Translate the current route for the given locale.
85
     *
86
     * @param $locale
87
     * @return bool|string
88
     */
89
    public function current($locale)
90
    {
91
        return $this->translate($this->currentRouteName(), Accent::currentRouteAttributes(), $locale);
0 ignored issues
show
Bug introduced by
It seems like Pmochine\LaravelTongue\A...urrentRouteAttributes() can also be of type false; however, parameter $routeAttributes of Pmochine\LaravelTongue\Dialect::translate() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

91
        return $this->translate($this->currentRouteName(), /** @scrutinizer ignore-type */ Accent::currentRouteAttributes(), $locale);
Loading history...
92
    }
93
94
    /**
95
     * Get all Translations for the current URL.
96
     *
97
     * @param  bool  $excludeCurrentLocale
98
     * @return array
99
     */
100
    public function translateAll($excludeCurrentLocale = true)
101
    {
102
        $versions = [];
103
104
        foreach (tongue()->speaking()->keys()->all() as $locale) {
105
            if ($excludeCurrentLocale && $locale == tongue()->current()) {
106
                continue;
107
            }
108
109
            if ($url = $this->current($locale)) {
110
                $versions[$locale] = $url;
111
            }
112
        }
113
114
        return $versions;
115
    }
116
117
    /**
118
     * Return translated URL from route.
119
     *
120
     * @param  string  $routeName
121
     * @param array]null]bool $routeAttributes
122
     * @param  string|false  $locale
123
     * @return string|bool
124
     */
125
    public function translate($routeName, $routeAttributes = null, $locale = null)
126
    {
127
        // If no locale is given, we use the current locale
128
        if (! $locale) {
129
            $locale = tongue()->current();
130
        }
131
132
        if (empty($this->parsed_url)) {
133
            $this->parsed_url = Accent::parseCurrentUrl();
134
        }
135
136
        // Retrieve the current URL components
137
        $parsed_url = $this->parsed_url;
138
139
        $parsed_url['host'] = $this->addLocaleToHost($locale);
140
141
        // Resolve the translated route path for the given route name
142
        $translatedPath = Accent::findRoutePathByName($routeName, $locale);
143
144
        if ($translatedPath !== false) {
145
            $parsed_url['path'] = $translatedPath;
146
        }
147
148
        // If attributes are given, substitute them in the path
149
        if ($routeAttributes) {
150
            $parsed_url['path'] = Accent::substituteAttributesInRoute($routeAttributes, $parsed_url['path']);
151
        }
152
153
        return Accent::unparseUrl($parsed_url);
154
    }
155
156
    /**
157
     * If we have beautify on and the given $locale is the same
158
     * to the current locale and to the fallbackLocal.
159
     * We don't need to add a subdomain to the host.
160
     *
161
     * @param  string  $locale
162
     * @return string
163
     */
164
    protected function addLocaleToHost($locale)
165
    {
166
        if (Config::beautify() && $locale === tongue()->current() && $locale === Config::fallbackLocale()) {
167
            return Url::domain();
168
        }
169
170
        // Add locale to the host
171
        return $locale.'.'.Url::domain();
172
    }
173
174
    /**
175
     * Interprets a translated route path for the given route name.
176
     *
177
     * @param $routeName
178
     * @return string|false (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
     * @return bool|string
214
     */
215
    public function findRouteNameByPath($routePath)
216
    {
217
        foreach ($this->translatedRoutes as $name => $path) {
218
            if ($routePath == $path) {
219
                return $name;
220
            }
221
        }
222
223
        return false;
224
    }
225
226
    /**
227
     * Redirect back to the latest locale.
228
     * Used, when no language is found.
229
     *
230
     * @return \Illuminate\Http\RedirectResponse;
231
     */
232
    public function redirectBackToLatest()
233
    {
234
        tongue()->speaks(Localization::currentTongue());
235
236
        return dialect()->redirect(dialect()->redirectUrl());
237
    }
238
}
239