GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( b881e7...b8b07c )
by Marc
01:39
created

LaravelLocalization   D

Complexity

Total Complexity 130

Size/Duplication

Total Lines 880
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
wmc 130
lcom 1
cbo 8
dl 0
loc 880
rs 4.4444
c 0
b 0
f 0

35 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 19 2
B setLocale() 0 41 6
A setSupportedLocales() 0 4 1
A localizeURL() 0 4 1
A getNonLocalizedURL() 0 4 1
A getDefaultLocale() 0 4 1
A getSupportedLocales() 0 16 4
A getLocalesOrder() 0 14 1
A getCurrentLocaleName() 0 4 1
A getCurrentLocaleNative() 0 4 1
B getCurrentLocaleDirection() 0 18 7
A getCurrentLocaleScript() 0 4 1
A getCurrentLocaleNativeReading() 0 4 1
A getCurrentLocale() 0 15 3
A getCurrentLocaleRegional() 0 10 2
A getSupportedLanguagesKeys() 0 4 1
A checkLocaleInSupportedLocales() 0 9 3
A substituteAttributesInRoute() 0 12 2
A getTranslatedRoutes() 0 4 1
A setRouteName() 0 4 1
A transRoute() 0 8 2
A getRouteNameFromAPath() 0 19 4
A findTranslatedRouteByPath() 0 11 3
A findTranslatedRouteByUrl() 0 17 4
A checkUrl() 0 4 1
A getConfigRepository() 0 4 1
A useAcceptLanguageHeader() 0 4 1
A hideDefaultLocaleInURL() 0 4 1
A createUrlFromUri() 0 10 2
A setBaseUrl() 0 8 2
D extractAttributes() 0 86 21
F unparseUrl() 0 25 14
F getLocalizedURL() 0 79 20
D getURLFromRouteNameTranslated() 0 29 9
A normalizeAttributes() 0 8 4

How to fix   Complexity   

Complex Class

Complex classes like LaravelLocalization often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use LaravelLocalization, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Mcamara\LaravelLocalization;
4
5
use Illuminate\Config\Repository;
6
use Illuminate\Foundation\Application;
7
use Illuminate\Http\Request;
8
use Illuminate\Routing\Router;
9
use Illuminate\Support\Facades\URL;
10
use Illuminate\Translation\Translator;
11
use Illuminate\View\Factory;
12
use Mcamara\LaravelLocalization\Exceptions\SupportedLocalesNotDefined;
13
use Mcamara\LaravelLocalization\Exceptions\UnsupportedLocaleException;
14
15
class LaravelLocalization
16
{
17
    /**
18
     * Config repository.
19
     *
20
     * @var \Illuminate\Config\Repository
21
     */
22
    protected $configRepository;
23
24
    /**
25
     * Illuminate view Factory.
26
     *
27
     * @var \Illuminate\View\Factory
28
     */
29
    protected $view;
30
31
    /**
32
     * Illuminate translator class.
33
     *
34
     * @var \Illuminate\Translation\Translator
35
     */
36
    protected $translator;
37
38
    /**
39
     * Illuminate router class.
40
     *
41
     * @var \Illuminate\Routing\Router
42
     */
43
    protected $router;
44
45
    /**
46
     * Illuminate request class.
47
     *
48
     * @var \Illuminate\Routing\Request
49
     */
50
    protected $request;
51
52
    /**
53
     * Illuminate url class.
54
     *
55
     * @var \Illuminate\Routing\UrlGenerator
56
     */
57
    protected $url;
58
59
    /**
60
     * Illuminate request class.
61
     *
62
     * @var Illuminate\Foundation\Application
63
     */
64
    protected $app;
65
66
    /**
67
     * Illuminate request class.
68
     *
69
     * @var string
70
     */
71
    protected $baseUrl;
72
73
    /**
74
     * Default locale.
75
     *
76
     * @var string
77
     */
78
    protected $defaultLocale;
79
80
    /**
81
     * Supported Locales.
82
     *
83
     * @var array
84
     */
85
    protected $supportedLocales;
86
87
    /**
88
     * Current locale.
89
     *
90
     * @var string
91
     */
92
    protected $currentLocale = false;
93
94
    /**
95
     * An array that contains all routes that should be translated.
96
     *
97
     * @var array
98
     */
99
    protected $translatedRoutes = [];
100
101
    /**
102
     * Name of the translation key of the current route, it is used for url translations.
103
     *
104
     * @var string
105
     */
106
    protected $routeName;
107
108
    /**
109
     * Creates new instance.
110
     *
111
     * @throws UnsupportedLocaleException
112
     */
113
    public function __construct()
114
    {
115
        $this->app = app();
116
117
        $this->configRepository = $this->app['config'];
118
        $this->view = $this->app['view'];
119
        $this->translator = $this->app['translator'];
120
        $this->router = $this->app['router'];
121
        $this->request = $this->app['request'];
122
        $this->url = $this->app['url'];
123
124
        // set default locale
125
        $this->defaultLocale = $this->configRepository->get('app.locale');
126
        $supportedLocales = $this->getSupportedLocales();
127
128
        if (empty($supportedLocales[$this->defaultLocale])) {
129
            throw new UnsupportedLocaleException('Laravel default locale is not in the supportedLocales array.');
130
        }
131
    }
132
133
    /**
134
     * Set and return current locale.
135
     *
136
     * @param string $locale Locale to set the App to (optional)
137
     *
138
     * @return string Returns locale (if route has any) or null (if route does not have a locale)
139
     */
140
    public function setLocale($locale = null)
141
    {
142
        if (empty($locale) || !is_string($locale)) {
143
            // If the locale has not been passed through the function
144
            // it tries to get it from the first segment of the url
145
            $locale = $this->request->segment(1);
146
        }
147
148
        if (!empty($this->supportedLocales[$locale])) {
149
            $this->currentLocale = $locale;
150
        } else {
151
            // if the first segment/locale passed is not valid
152
            // the system would ask which locale have to take
153
            // it could be taken by the browser
154
            // depending on your configuration
155
156
            $locale = null;
157
158
            // if we reached this point and hideDefaultLocaleInURL is true
159
            // we have to assume we are routing to a defaultLocale route.
160
            if ($this->hideDefaultLocaleInURL()) {
161
                $this->currentLocale = $this->defaultLocale;
162
            }
163
            // but if hideDefaultLocaleInURL is false, we have
164
            // to retrieve it from the browser...
165
            else {
166
                $this->currentLocale = $this->getCurrentLocale();
167
            }
168
        }
169
170
        $this->app->setLocale($this->currentLocale);
171
172
        // Regional locale such as de_DE, so formatLocalized works in Carbon
173
        $regional = $this->getCurrentLocaleRegional();
174
        if ($regional) {
175
            setlocale(LC_TIME, $regional.'.UTF-8');
176
            setlocale(LC_MONETARY, $regional.'.UTF-8');
177
        }
178
179
        return $locale;
180
    }
181
182
    /**
183
     * Set and return supported locales.
184
     *
185
     * @param array $locales Locales that the App supports
186
     */
187
    public function setSupportedLocales($locales)
188
    {
189
        $this->supportedLocales = $locales;
190
    }
191
192
    /**
193
     * Returns an URL adapted to $locale or current locale.
194
     *
195
     * @param string      $url    URL to adapt. If not passed, the current url would be taken.
196
     * @param string|bool $locale Locale to adapt, false to remove locale
197
     *
198
     * @throws UnsupportedLocaleException
199
     *
200
     * @return string URL translated
201
     */
202
    public function localizeURL($url = null, $locale = null)
203
    {
204
        return $this->getLocalizedURL($locale, $url);
205
    }
206
207
    /**
208
     * Returns an URL adapted to $locale.
209
     *
210
     *
211
     * @param string|bool  $locale     Locale to adapt, false to remove locale
212
     * @param string|false $url        URL to adapt in the current language. If not passed, the current url would be taken.
213
     * @param array        $attributes Attributes to add to the route, if empty, the system would try to extract them from the url.
214
     * @param bool         $forceDefaultLocation Force to show default location even hideDefaultLocaleInURL set as TRUE
215
     *
216
     * @throws SupportedLocalesNotDefined
217
     * @throws UnsupportedLocaleException
218
     *
219
     * @return string|false URL translated, False if url does not exist
220
     */
221
    public function getLocalizedURL($locale = null, $url = null, $attributes = [], $forceDefaultLocation = false)
222
    {
223
        if ($locale === null) {
224
            $locale = $this->getCurrentLocale();
225
        }
226
227
        if (!$this->checkLocaleInSupportedLocales($locale)) {
228
            throw new UnsupportedLocaleException('Locale \''.$locale.'\' is not in the list of supported locales.');
229
        }
230
231
        if (empty($attributes)) {
232
            $attributes = $this->extractAttributes($url, $locale);
0 ignored issues
show
Bug introduced by
It seems like $locale defined by parameter $locale on line 221 can also be of type boolean; however, Mcamara\LaravelLocalizat...on::extractAttributes() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
233
        }
234
235
        if (empty($url)) {
236
            if (!empty($this->routeName)) {
237
                return $this->getURLFromRouteNameTranslated($locale, $this->routeName, $attributes, $forceDefaultLocation);
238
            }
239
240
            $url = $this->request->fullUrl();
241
        } else {
242
            $url = $this->url->to($url);
243
        }
244
245
        if ($locale && $translatedRoute = $this->findTranslatedRouteByUrl($url, $attributes, $this->currentLocale)) {
246
            return $this->getURLFromRouteNameTranslated($locale, $translatedRoute, $attributes, $forceDefaultLocation);
247
        }
248
249
        $base_path = $this->request->getBaseUrl();
250
        $parsed_url = parse_url($url);
251
        $url_locale = $this->getDefaultLocale();
252
253
        if (!$parsed_url || empty($parsed_url['path'])) {
254
            $path = $parsed_url['path'] = '';
255
        } else {
256
            $parsed_url['path'] = str_replace($base_path, '', '/'.ltrim($parsed_url['path'], '/'));
257
            $path = $parsed_url['path'];
258
            foreach ($this->getSupportedLocales() as $localeCode => $lang) {
259
                $parsed_url['path'] = preg_replace('%^/?'.$localeCode.'/%', '$1', $parsed_url['path']);
260
                if ($parsed_url['path'] !== $path) {
261
                    $url_locale = $localeCode;
262
                    break;
263
                }
264
265
                $parsed_url['path'] = preg_replace('%^/?'.$localeCode.'$%', '$1', $parsed_url['path']);
266
                if ($parsed_url['path'] !== $path) {
267
                    $url_locale = $localeCode;
268
                    break;
269
                }
270
            }
271
        }
272
273
        $parsed_url['path'] = ltrim($parsed_url['path'], '/');
274
275
        if ($translatedRoute = $this->findTranslatedRouteByPath($parsed_url['path'], $url_locale)) {
276
            return $this->getURLFromRouteNameTranslated($locale, $translatedRoute, $attributes, $forceDefaultLocation);
277
        }
278
279
	if (!empty($locale)) {
280
            if ($locale != $this->getDefaultLocale() || !$this->hideDefaultLocaleInURL() || $forceDefaultLocation) {
281
                $parsed_url['path'] = $locale.'/'.ltrim($parsed_url['path'], '/');
282
            }
283
        }
284
        $parsed_url['path'] = ltrim(ltrim($base_path, '/').'/'.$parsed_url['path'], '/');
285
286
        //Make sure that the pass path is returned with a leading slash only if it come in with one.
287
        if (starts_with($path, '/') === true) {
288
            $parsed_url['path'] = '/'.$parsed_url['path'];
289
        }
290
        $parsed_url['path'] = rtrim($parsed_url['path'], '/');
291
292
        $url = $this->unparseUrl($parsed_url);
293
294
        if ($this->checkUrl($url)) {
295
            return $url;
296
        }
297
298
        return $this->createUrlFromUri($url);
299
    }
300
301
    /**
302
     * Returns an URL adapted to the route name and the locale given.
303
     *
304
     *
305
     * @param string|bool $locale       Locale to adapt
306
     * @param string      $transKeyName Translation key name of the url to adapt
307
     * @param array       $attributes   Attributes for the route (only needed if transKeyName needs them)
308
     * @param bool        $forceDefaultLocation Force to show default location even hideDefaultLocaleInURL set as TRUE
309
     *
310
     * @throws SupportedLocalesNotDefined
311
     * @throws UnsupportedLocaleException
312
     *
313
     * @return string|false URL translated
314
     */
315
    public function getURLFromRouteNameTranslated($locale, $transKeyName, $attributes = [], $forceDefaultLocation = false)
316
    {
317
        if (!$this->checkLocaleInSupportedLocales($locale)) {
318
            throw new UnsupportedLocaleException('Locale \''.$locale.'\' is not in the list of supported locales.');
319
        }
320
321
        if (!is_string($locale)) {
322
            $locale = $this->getDefaultLocale();
323
        }
324
325
        $route = '';
326
327
        if ($forceDefaultLocation || !($locale === $this->defaultLocale && $this->hideDefaultLocaleInURL())) {
328
            $route = '/'.$locale;
329
        }
330
        if (is_string($locale) && $this->translator->has($transKeyName, $locale)) {
331
            $translation = $this->translator->trans($transKeyName, [], $locale);
332
            $route .= '/'.$translation;
333
334
            $route = $this->substituteAttributesInRoute($attributes, $route);
335
        }
336
337
        if (empty($route)) {
338
            // This locale does not have any key for this route name
339
            return false;
340
        }
341
342
        return rtrim($this->createUrlFromUri($route));
343
    }
344
345
    /**
346
     * It returns an URL without locale (if it has it)
347
     * Convenience function wrapping getLocalizedURL(false).
348
     *
349
     * @param string|false $url URL to clean, if false, current url would be taken
350
     *
351
     * @return string URL with no locale in path
352
     */
353
    public function getNonLocalizedURL($url = null)
354
    {
355
        return $this->getLocalizedURL(false, $url);
356
    }
357
358
    /**
359
     * Returns default locale.
360
     *
361
     * @return string
362
     */
363
    public function getDefaultLocale()
364
    {
365
        return $this->defaultLocale;
366
    }
367
368
    /**
369
     * Return an array of all supported Locales.
370
     *
371
     * @throws SupportedLocalesNotDefined
372
     *
373
     * @return array
374
     */
375
    public function getSupportedLocales()
376
    {
377
        if (!empty($this->supportedLocales)) {
378
            return $this->supportedLocales;
379
        }
380
381
        $locales = $this->configRepository->get('laravellocalization.supportedLocales');
382
383
        if (empty($locales) || !is_array($locales)) {
384
            throw new SupportedLocalesNotDefined();
385
        }
386
387
        $this->supportedLocales = $locales;
388
389
        return $locales;
390
    }
391
392
    /**
393
     * Return an array of all supported Locales but in the order the user
394
     * has specified in the config file. Useful for the language selector.
395
     *
396
     * @return array
397
     */
398
    public function getLocalesOrder()
399
    {
400
        $locales = $this->getSupportedLocales();
401
402
        $order = $this->configRepository->get('laravellocalization.localesOrder');
403
404
        uksort($locales, function ($a, $b) use ($order) {
405
            $pos_a = array_search($a, $order);
406
            $pos_b = array_search($b, $order);
407
            return $pos_a - $pos_b;
408
        });
409
410
        return $locales;
411
    }
412
413
    /**
414
     * Returns current locale name.
415
     *
416
     * @return string current locale name
417
     */
418
    public function getCurrentLocaleName()
419
    {
420
        return $this->supportedLocales[$this->getCurrentLocale()]['name'];
421
    }
422
423
    /**
424
     * Returns current locale native name.
425
     *
426
     * @return string current locale native name
427
     */
428
    public function getCurrentLocaleNative()
429
    {
430
        return $this->supportedLocales[$this->getCurrentLocale()]['native'];
431
    }
432
433
    /**
434
     * Returns current locale direction.
435
     *
436
     * @return string current locale direction
437
     */
438
    public function getCurrentLocaleDirection()
439
    {
440
        if (!empty($this->supportedLocales[$this->getCurrentLocale()]['dir'])) {
441
            return $this->supportedLocales[$this->getCurrentLocale()]['dir'];
442
        }
443
444
        switch ($this->getCurrentLocaleScript()) {
445
            // Other (historic) RTL scripts exist, but this list contains the only ones in current use.
446
            case 'Arab':
447
            case 'Hebr':
448
            case 'Mong':
449
            case 'Tfng':
450
            case 'Thaa':
451
            return 'rtl';
452
            default:
453
            return 'ltr';
454
        }
455
    }
456
457
    /**
458
     * Returns current locale script.
459
     *
460
     * @return string current locale script
461
     */
462
    public function getCurrentLocaleScript()
463
    {
464
        return $this->supportedLocales[$this->getCurrentLocale()]['script'];
465
    }
466
467
    /**
468
     * Returns current language's native reading.
469
     *
470
     * @return string current language's native reading
471
     */
472
    public function getCurrentLocaleNativeReading()
473
    {
474
        return $this->supportedLocales[$this->getCurrentLocale()]['native'];
475
    }
476
477
    /**
478
     * Returns current language.
479
     *
480
     * @return string current language
481
     */
482
    public function getCurrentLocale()
483
    {
484
        if ($this->currentLocale) {
485
            return $this->currentLocale;
486
        }
487
488
        if ($this->useAcceptLanguageHeader()) {
489
            $negotiator = new LanguageNegotiator($this->defaultLocale, $this->getSupportedLocales(), $this->request);
490
491
            return $negotiator->negotiateLanguage();
492
        }
493
494
        // or get application default language
495
        return $this->configRepository->get('app.locale');
496
    }
497
498
    /**
499
     * Returns current regional.
500
     *
501
     * @return string current regional
502
     */
503
    public function getCurrentLocaleRegional()
504
    {
505
        // need to check if it exists, since 'regional' has been added
506
        // after version 1.0.11 and existing users will not have it
507
        if (isset($this->supportedLocales[$this->getCurrentLocale()]['regional'])) {
508
            return $this->supportedLocales[$this->getCurrentLocale()]['regional'];
509
        } else {
510
            return;
511
        }
512
    }
513
514
    /**
515
     * Returns supported languages language key.
516
     *
517
     * @return array keys of supported languages
518
     */
519
    public function getSupportedLanguagesKeys()
520
    {
521
        return array_keys($this->supportedLocales);
522
    }
523
524
    /**
525
     * Check if Locale exists on the supported locales array.
526
     *
527
     * @param string|bool $locale string|bool Locale to be checked
528
     *
529
     * @throws SupportedLocalesNotDefined
530
     *
531
     * @return bool is the locale supported?
532
     */
533
    public function checkLocaleInSupportedLocales($locale)
534
    {
535
        $locales = $this->getSupportedLocales();
536
        if ($locale !== false && empty($locales[$locale])) {
537
            return false;
538
        }
539
540
        return true;
541
    }
542
543
    /**
544
     * Change route attributes for the ones in the $attributes array.
545
     *
546
     * @param $attributes array Array of attributes
547
     * @param string $route string route to substitute
548
     *
549
     * @return string route with attributes changed
550
     */
551
    protected function substituteAttributesInRoute($attributes, $route)
552
    {
553
        foreach ($attributes as $key => $value) {
554
            $route = str_replace('{'.$key.'}', $value, $route);
555
            $route = str_replace('{'.$key.'?}', $value, $route);
556
        }
557
558
        // delete empty optional arguments that are not in the $attributes array
559
        $route = preg_replace('/\/{[^)]+\?}/', '', $route);
560
561
        return $route;
562
    }
563
564
    /**
565
     * Returns translated routes.
566
     *
567
     * @return array translated routes
568
     */
569
    protected function getTranslatedRoutes()
570
    {
571
        return $this->translatedRoutes;
572
    }
573
574
    /**
575
     * Set current route name.
576
     *
577
     * @param string $routeName current route name
578
     */
579
    public function setRouteName($routeName)
580
    {
581
        $this->routeName = $routeName;
582
    }
583
584
    /**
585
     * Translate routes and save them to the translated routes array (used in the localize route filter).
586
     *
587
     * @param string $routeName Key of the translated string
588
     *
589
     * @return string Translated string
590
     */
591
    public function transRoute($routeName)
592
    {
593
        if (!in_array($routeName, $this->translatedRoutes)) {
594
            $this->translatedRoutes[] = $routeName;
595
        }
596
597
        return $this->translator->trans($routeName);
598
    }
599
600
    /**
601
     * Returns the translation key for a given path.
602
     *
603
     * @param string $path Path to get the key translated
604
     *
605
     * @return string|false Key for translation, false if not exist
606
     */
607
    public function getRouteNameFromAPath($path)
608
    {
609
        $attributes = $this->extractAttributes($path);
610
611
        $path = str_replace(url('/'), '', $path);
612
        if ($path[0] !== '/') {
613
            $path = '/'.$path;
614
        }
615
        $path = str_replace('/'.$this->currentLocale.'/', '', $path);
616
        $path = trim($path, '/');
617
618
        foreach ($this->translatedRoutes as $route) {
619
            if ($this->substituteAttributesInRoute($attributes, $this->translator->trans($route)) === $path) {
0 ignored issues
show
Bug introduced by
It seems like $this->translator->trans($route) targeting Illuminate\Translation\Translator::trans() can also be of type array; however, Mcamara\LaravelLocalizat...tuteAttributesInRoute() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
620
                return $route;
621
            }
622
        }
623
624
        return false;
625
    }
626
627
    /**
628
     * Returns the translated route for the path and the url given.
629
     *
630
     * @param string $path       Path to check if it is a translated route
631
     * @param string $url_locale Language to check if the path exists
632
     *
633
     * @return string|false Key for translation, false if not exist
634
     */
635
    protected function findTranslatedRouteByPath($path, $url_locale)
636
    {
637
        // check if this url is a translated url
638
        foreach ($this->translatedRoutes as $translatedRoute) {
639
            if ($this->translator->trans($translatedRoute, [], $url_locale) == rawurldecode($path)) {
640
                return $translatedRoute;
641
            }
642
        }
643
644
        return false;
645
    }
646
647
    /**
648
     * Returns the translated route for an url and the attributes given and a locale.
649
     *
650
     *
651
     * @param string|false|null $url        Url to check if it is a translated route
652
     * @param array             $attributes Attributes to check if the url exists in the translated routes array
653
     * @param string            $locale     Language to check if the url exists
654
     *
655
     * @throws SupportedLocalesNotDefined
656
     * @throws UnsupportedLocaleException
657
     *
658
     * @return string|false Key for translation, false if not exist
659
     */
660
    protected function findTranslatedRouteByUrl($url, $attributes, $locale)
661
    {
662
        if (empty($url)) {
663
            return false;
664
        }
665
666
        // check if this url is a translated url
667
        foreach ($this->translatedRoutes as $translatedRoute) {
668
            $routeName = $this->getURLFromRouteNameTranslated($locale, $translatedRoute, $attributes);
669
670
            if ($this->getNonLocalizedURL($routeName) == $this->getNonLocalizedURL($url)) {
671
                return $translatedRoute;
672
            }
673
        }
674
675
        return false;
676
    }
677
678
    /**
679
     * Returns true if the string given is a valid url.
680
     *
681
     * @param string $url String to check if it is a valid url
682
     *
683
     * @return bool Is the string given a valid url?
684
     */
685
    protected function checkUrl($url)
686
    {
687
        return filter_var($url, FILTER_VALIDATE_URL);
688
    }
689
690
    /**
691
     * Returns the config repository for this instance.
692
     *
693
     * @return Repository Configuration repository
694
     */
695
    public function getConfigRepository()
696
    {
697
        return $this->configRepository;
698
    }
699
700
    /**
701
     * Returns the translation key for a given path.
702
     *
703
     * @return bool Returns value of useAcceptLanguageHeader in config.
704
     */
705
    protected function useAcceptLanguageHeader()
706
    {
707
        return $this->configRepository->get('laravellocalization.useAcceptLanguageHeader');
708
    }
709
710
    /**
711
     * Returns the translation key for a given path.
712
     *
713
     * @return bool Returns value of hideDefaultLocaleInURL in config.
714
     */
715
    public function hideDefaultLocaleInURL()
716
    {
717
        return $this->configRepository->get('laravellocalization.hideDefaultLocaleInURL');
718
    }
719
720
    /**
721
     * Create an url from the uri.
722
     *
723
     * @param string $uri Uri
724
     *
725
     * @return string Url for the given uri
726
     */
727
    public function createUrlFromUri($uri)
728
    {
729
        $uri = ltrim($uri, '/');
730
731
        if (empty($this->baseUrl)) {
732
            return app('url')->to($uri);
733
        }
734
735
        return $this->baseUrl.$uri;
736
    }
737
738
    /**
739
     * Sets the base url for the site.
740
     *
741
     * @param string $url Base url for the site
742
     */
743
    public function setBaseUrl($url)
744
    {
745
        if (substr($url, -1) != '/') {
746
            $url .= '/';
747
        }
748
749
        $this->baseUrl = $url;
750
    }
751
752
    /**
753
     * Extract attributes for current url.
754
     *
755
     * @param bool|false|null|string $url    to extract attributes, if not present, the system will look for attributes in the current call
756
     * @param string                 $locale
757
     *
758
     * @return array Array with attributes
759
     */
760
    protected function extractAttributes($url = false, $locale = '')
761
    {
762
        if (!empty($url)) {
763
            $attributes = [];
764
            $parse = parse_url($url);
765
            if (isset($parse['path'])) {
766
                $parse = explode('/', $parse['path']);
767
            } else {
768
                $parse = [];
769
            }
770
            $url = [];
771
            foreach ($parse as $segment) {
772
                if (!empty($segment)) {
773
                    $url[] = $segment;
774
                }
775
            }
776
777
            foreach ($this->router->getRoutes() as $route) {
778
                $path = method_exists($route, 'uri') ? $route->uri() : $route->getUri();
779
780
                if (!preg_match("/{[\w]+}/", $path)) {
781
                    continue;
782
                }
783
784
                $path = explode('/', $path);
785
                $i = 0;
786
787
                $match = true;
788
                foreach ($path as $j => $segment) {
789
                    if (isset($url[$i])) {
790
                        if ($segment === $url[$i]) {
791
                            $i++;
792
                            continue;
793
                        }
794
                        if (preg_match("/{[\w]+}/", $segment)) {
795
                            // must-have parameters
796
                            $attribute_name = preg_replace(['/}/', '/{/', "/\?/"], '', $segment);
797
                            $attributes[$attribute_name] = $url[$i];
798
                            $i++;
799
                            continue;
800
                        }
801
                        if (preg_match("/{[\w]+\?}/", $segment)) {
802
                            // optional parameters
803
                            if (!isset($path[$j + 1]) || $path[$j + 1] !== $url[$i]) {
804
                                // optional parameter taken
805
                                $attribute_name = preg_replace(['/}/', '/{/', "/\?/"], '', $segment);
806
                                $attributes[$attribute_name] = $url[$i];
807
                                $i++;
808
                                continue;
809
                            }
810
                        }
811
                    } elseif (!preg_match("/{[\w]+\?}/", $segment)) {
812
                        // no optional parameters but no more $url given
813
                        // this route does not match the url
814
                        $match = false;
815
                        break;
816
                    }
817
                }
818
819
                if (isset($url[$i + 1])) {
820
                    $match = false;
821
                }
822
823
                if ($match) {
824
                    return $attributes;
825
                }
826
            }
827
        } else {
828
            if (!$this->router->current()) {
829
                return [];
830
            }
831
832
            $attributes = $this->normalizeAttributes($this->router->current()->parameters());
833
            $response = event('routes.translation', [$locale, $attributes]);
834
835
            if (!empty($response)) {
836
                $response = array_shift($response);
837
            }
838
839
            if (is_array($response)) {
840
                $attributes = array_merge($attributes, $response);
841
            }
842
        }
843
844
        return $attributes;
845
    }
846
847
    /**
848
     * Build URL using array data from parse_url.
849
     *
850
     * @param array|false $parsed_url Array of data from parse_url function
851
     *
852
     * @return string Returns URL as string.
853
     */
854
    protected function unparseUrl($parsed_url)
855
    {
856
        if (empty($parsed_url)) {
857
            return '';
858
        }
859
860
        $url = '';
861
        $url .= isset($parsed_url['scheme']) ? $parsed_url['scheme'].'://' : '';
862
        $url .= isset($parsed_url['host']) ? $parsed_url['host'] : '';
863
        $url .= isset($parsed_url['port']) ? ':'.$parsed_url['port'] : '';
864
        $user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
865
        $pass = isset($parsed_url['pass']) ? ':'.$parsed_url['pass'] : '';
866
        $url .= $user.(($user || $pass) ? "$pass@" : '');
867
868
        if (!empty($url)) {
869
            $url .= isset($parsed_url['path']) ? '/'.ltrim($parsed_url['path'], '/') : '';
870
        } else {
871
            $url .= isset($parsed_url['path']) ? $parsed_url['path'] : '';
872
        }
873
874
        $url .= isset($parsed_url['query']) ? '?'.$parsed_url['query'] : '';
875
        $url .= isset($parsed_url['fragment']) ? '#'.$parsed_url['fragment'] : '';
876
877
        return $url;
878
    }
879
880
    /**
881
    * Normalize attributes gotten from request parameters.
882
    *
883
    * @param      array  $attributes  The attributes
884
    * @return     array  The normalized attributes
885
    */
886
     protected function normalizeAttributes($attributes)
887
     {
888
         if (array_key_exists('data', $attributes) && is_array($attributes['data']) && ! count($attributes['data'])) {
889
             $attributes['data'] = null;
890
             return $attributes;
891
         }
892
         return $attributes;
893
     }
894
}
895