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
Pull Request — master (#370)
by
unknown
02:13
created

LaravelLocalization::getTranslatedRoutes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php namespace Mcamara\LaravelLocalization;
2
3
use Mcamara\LaravelLocalization\Exceptions\SupportedLocalesNotDefined;
4
use Mcamara\LaravelLocalization\Exceptions\UnsupportedLocaleException;
5
use Illuminate\Config\Repository;
6
use Illuminate\View\Factory;
7
use Illuminate\Translation\Translator;
8
use Illuminate\Routing\Router;
9
use Illuminate\Http\Request;
10
use Illuminate\Foundation\Application;
11
use Illuminate\Support\Facades\URL;
12
13
class LaravelLocalization {
14
15
    /**
16
     * Config repository.
17
     *
18
     * @var \Illuminate\Config\Repository
19
     */
20
    protected $configRepository;
21
22
    /**
23
     * Illuminate view Factory.
24
     *
25
     * @var \Illuminate\View\Factory
26
     */
27
    protected $view;
28
29
    /**
30
     * Illuminate translator class.
31
     *
32
     * @var \Illuminate\Translation\Translator
33
     */
34
    protected $translator;
35
36
    /**
37
     * Illuminate router class.
38
     *
39
     * @var \Illuminate\Routing\Router
40
     */
41
    protected $router;
42
43
    /**
44
     * Illuminate request class.
45
     *
46
     * @var \Illuminate\Routing\Request
47
     */
48
    protected $request;
49
50
    /**
51
     * Illuminate request class.
52
     *
53
     * @var Illuminate\Foundation\Application
54
     */
55
    protected $app;
56
57
    /**
58
     * Illuminate request class.
59
     *
60
     * @var string
61
     */
62
    protected $baseUrl;
63
64
    /**
65
     * Default locale
66
     *
67
     * @var string
68
     */
69
    protected $defaultLocale;
70
71
    /**
72
     * Supported Locales
73
     *
74
     * @var array
75
     */
76
    protected $supportedLocales;
77
78
    /**
79
     * Current locale
80
     *
81
     * @var string
82
     */
83
    protected $currentLocale = false;
84
85
    /**
86
     * An array that contains all routes that should be translated
87
     *
88
     * @var array
89
     */
90
    protected $translatedRoutes = array();
91
92
    /**
93
     * Name of the translation key of the current route, it is used for url translations
94
     *
95
     * @var string
96
     */
97
    protected $routeName;
98
99
    /**
100
     * Creates new instance.
101
     * @throws UnsupportedLocaleException
102
     */
103
    public function __construct()
104
    {
105
        $this->app = app();
106
107
        $this->configRepository = $this->app[ 'config' ];
108
        $this->view = $this->app[ 'view' ];
109
        $this->translator = $this->app[ 'translator' ];
110
        $this->router = $this->app[ 'router' ];
111
        $this->request = $this->app[ 'request' ];
112
113
        // set default locale
114
        $this->defaultLocale = $this->configRepository->get('app.locale');
115
        $supportedLocales = $this->getSupportedLocales();
116
117
        if ( empty( $supportedLocales[ $this->defaultLocale ] ) )
118
        {
119
            throw new UnsupportedLocaleException("Laravel default locale is not in the supportedLocales array.");
120
        }
121
    }
122
123
    /**
124
     * Set and return current locale
125
     *
126
     * @param  string $locale Locale to set the App to (optional)
127
     *
128
     * @return string                    Returns locale (if route has any) or null (if route does not have a locale)
129
     */
130
    public function setLocale( $locale = null )
131
    {
132
        if ( empty( $locale ) || !is_string($locale) )
133
        {
134
            // If the locale has not been passed through the function
135
            // it tries to get it from the first segment of the url
136
            $locale = $this->request->segment(1);
137
        }
138
139
        if ( !empty( $this->supportedLocales[ $locale ] ) )
140
        {
141
            $this->currentLocale = $locale;
142
        } else
143
        {
144
            // if the first segment/locale passed is not valid
145
            // the system would ask which locale have to take
146
            // it could be taken by the browser
147
            // depending on your configuration
148
149
            $locale = null;
150
151
            // if we reached this point and hideDefaultLocaleInURL is true
152
            // we have to assume we are routing to a defaultLocale route.
153
            if ( $this->hideDefaultLocaleInURL() )
154
            {
155
                $this->currentLocale = $this->defaultLocale;
156
            }
157
            // but if hideDefaultLocaleInURL is false, we have
158
            // to retrieve it from the browser...
159
            else
160
            {
161
                $this->currentLocale = $this->getCurrentLocale();
162
            }
163
        }
164
165
        $this->app->setLocale($this->currentLocale);
166
167
        // Regional locale such as de_DE, so formatLocalized works in Carbon
168
        $regional = $this->getCurrentLocaleRegional();
169
        if($regional)
170
        {
171
            setlocale(LC_TIME, $regional.'.UTF-8');
172
            setlocale(LC_MONETARY, $regional.'.UTF-8');
173
        }
174
175
        return $locale;
176
    }
177
178
    /**
179
     * Set and return supported locales
180
     *
181
     * @param  array $locales Locales that the App supports
182
     */
183
    public function setSupportedLocales( $locales )
184
    {
185
        $this->supportedLocales = $locales;
186
    }
187
188
    /**
189
     * Returns an URL adapted to $locale or current locale
190
     *
191
     * @param  string $url URL to adapt. If not passed, the current url would be taken.
192
     * @param  string|boolean $locale Locale to adapt, false to remove locale
193
     *
194
     * @throws UnsupportedLocaleException
195
     *
196
     * @return string                       URL translated
197
     */
198
    public function localizeURL( $url = null, $locale = null )
199
    {
200
        return $this->getLocalizedURL($locale, $url);
201
    }
202
203
204
    /**
205
     * Returns an URL adapted to $locale
206
     *
207
     * @throws SupportedLocalesNotDefined
208
     * @throws UnsupportedLocaleException
209
     *
210
     * @param  string|boolean $locale Locale to adapt, false to remove locale
211
     * @param  string|false $url URL to adapt in the current language. If not passed, the current url would be taken.
212
     * @param  array $attributes Attributes to add to the route, if empty, the system would try to extract them from the url.
213
     *
214
     *
215
     * @return string|false                URL translated, False if url does not exist
216
     */
217
    public function getLocalizedURL( $locale = null, $url = null, $attributes = array() )
218
    {
219
        if ( $locale === null )
220
        {
221
            $locale = $this->getCurrentLocale();
222
        }
223
224
        if ( !$this->checkLocaleInSupportedLocales($locale) )
225
        {
226
            throw new UnsupportedLocaleException('Locale \'' . $locale . '\' is not in the list of supported locales.');
227
        }
228
229
        if ( empty( $attributes ) )
230
        {
231
            $attributes = $this->extractAttributes($url, $locale);
0 ignored issues
show
Bug introduced by
It seems like $locale defined by parameter $locale on line 217 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...
232
        }
233
234
        if ( empty( $url ) )
235
        {
236
            if ( !empty( $this->routeName ) )
237
            {
238
                return $this->getURLFromRouteNameTranslated($locale, $this->routeName, $attributes);
239
            }
240
241
            $url = $this->request->fullUrl();
242
243
        }
244
245
        if ( $locale && $translatedRoute = $this->findTranslatedRouteByUrl($url, $attributes, $this->currentLocale) )
246
        {
247
            return $this->getURLFromRouteNameTranslated($locale, $translatedRoute, $attributes);
248
        }
249
250
        $base_path = $this->request->getBaseUrl();
251
        $parsed_url = parse_url($url);
252
        $url_locale = $this->getDefaultLocale();
253
254
        if ( !$parsed_url || empty( $parsed_url[ 'path' ] ) )
255
        {
256
            $path = $parsed_url[ 'path' ] = "";
257
        } else
258
        {
259
            $parsed_url[ 'path' ] = str_replace($base_path, '', '/' . ltrim($parsed_url[ 'path' ], '/'));
260
            $path = $parsed_url[ 'path' ];
261
            foreach ( $this->getSupportedLocales() as $localeCode => $lang )
262
            {
263
                $parsed_url[ 'path' ] = preg_replace('%^/?' . $localeCode . '/%', '$1', $parsed_url[ 'path' ]);
264
                if ( $parsed_url[ 'path' ] !== $path )
265
                {
266
                    $url_locale = $localeCode;
267
                    break;
268
                }
269
270
                $parsed_url[ 'path' ] = preg_replace('%^/?' . $localeCode . '$%', '$1', $parsed_url[ 'path' ]);
271
                if ( $parsed_url[ 'path' ] !== $path )
272
                {
273
                    $url_locale = $localeCode;
274
                    break;
275
                }
276
            }
277
        }
278
279
        $parsed_url[ 'path' ] = ltrim($parsed_url[ 'path' ], '/');
280
281
        if ( $translatedRoute = $this->findTranslatedRouteByPath($parsed_url[ 'path' ], $url_locale) )
282
        {
283
            return $this->getURLFromRouteNameTranslated($locale, $translatedRoute, $attributes);
284
        }
285
286
        if ( !empty( $locale ) && ( $locale != $this->defaultLocale || !$this->hideDefaultLocaleInURL() ) )
287
        {
288
            $parsed_url[ 'path' ] = $locale . '/' . ltrim($parsed_url[ 'path' ], '/');
289
        }
290
        $parsed_url[ 'path' ] = ltrim(ltrim($base_path, '/') . '/' . $parsed_url[ 'path' ], '/');
291
292
        //Make sure that the pass path is returned with a leading slash only if it come in with one.
293
        if ( starts_with($path, '/') === true )
294
        {
295
            $parsed_url[ 'path' ] = '/' . $parsed_url[ 'path' ];
296
        }
297
        $parsed_url[ 'path' ] = rtrim($parsed_url[ 'path' ], '/');
298
299
        $url = $this->unparseUrl($parsed_url);
300
301
        if ( $this->checkUrl($url) )
302
        {
303
            return $url;
304
        }
305
306
        return $this->createUrlFromUri($url);
307
    }
308
309
310
    /**
311
     * Returns an URL adapted to the route name and the locale given
312
     *
313
     * @throws SupportedLocalesNotDefined
314
     * @throws UnsupportedLocaleException
315
     *
316
     * @param  string|boolean $locale Locale to adapt
317
     * @param  string $transKeyName Translation key name of the url to adapt
318
     * @param  array $attributes Attributes for the route (only needed if transKeyName needs them)
319
     *
320
     * @return string|false    URL translated
321
     */
322
    public function getURLFromRouteNameTranslated( $locale, $transKeyName, $attributes = array() )
323
    {
324
        if ( !$this->checkLocaleInSupportedLocales($locale) )
325
        {
326
            throw new UnsupportedLocaleException('Locale \'' . $locale . '\' is not in the list of supported locales.');
327
        }
328
329
        if ( !is_string($locale) )
330
        {
331
            $locale = $this->getDefaultLocale();
332
        }
333
334
        $route = "";
335
336
        if ( !( $locale === $this->defaultLocale && $this->hideDefaultLocaleInURL() ) )
337
        {
338
            $route = '/' . $locale;
339
        }
340
        if ( is_string($locale) && $this->translator->has($transKeyName, $locale) )
341
        {
342
            $translation = $this->translator->trans($transKeyName, [ ], "", $locale);
343
            $route .= "/" . $translation;
344
345
            $route = $this->substituteAttributesInRoute($attributes, $route);
346
347
        }
348
349
        if ( empty( $route ) )
350
        {
351
            // This locale does not have any key for this route name
352
            return false;
353
        }
354
355
        return rtrim($this->createUrlFromUri($route));
356
357
358
    }
359
360
    /**
361
     * It returns an URL without locale (if it has it)
362
     * Convenience function wrapping getLocalizedURL(false)
363
     *
364
     * @param  string|false $url URL to clean, if false, current url would be taken
365
     *
366
     * @return string           URL with no locale in path
367
     */
368
    public function getNonLocalizedURL( $url = null )
369
    {
370
        return $this->getLocalizedURL(false, $url);
371
    }
372
373
    /**
374
     * Returns default locale
375
     *
376
     * @return string
377
     */
378
    public function getDefaultLocale()
379
    {
380
        return $this->defaultLocale;
381
    }
382
383
    /**
384
     * Return an array of all supported Locales
385
     *
386
     * @throws SupportedLocalesNotDefined
387
     * @return array
388
     */
389
    public function getSupportedLocales()
390
    {
391
        if ( !empty( $this->supportedLocales ) )
392
        {
393
            return $this->supportedLocales;
394
        }
395
396
        $locales = $this->configRepository->get('laravellocalization.supportedLocales');
397
398
        if ( empty( $locales ) || !is_array($locales) )
399
        {
400
            throw new SupportedLocalesNotDefined();
401
        }
402
403
        $this->supportedLocales = $locales;
404
405
        return $locales;
406
    }
407
408
    /**
409
     * Returns current locale name
410
     *
411
     * @return string current locale name
412
     */
413
    public function getCurrentLocaleName()
414
    {
415
        return $this->supportedLocales[ $this->getCurrentLocale() ][ 'name' ];
416
    }
417
    
418
    /**
419
     * Returns current locale Flag image
420
     *
421
     * @return string current locale image
422
     */
423
    public function getCurrentLocaleImage()
424
    {
425
        return $this->supportedLocales[ $this->getCurrentLocale() ][ 'img' ];
426
    }
427
428
    /**
429
     * Returns current locale native name
430
     *
431
     * @return string current locale native name
432
     */
433
    public function getCurrentLocaleNative()
434
    {
435
        return $this->supportedLocales[ $this->getCurrentLocale() ][ 'native' ];
436
    }
437
438
    /**
439
     * Returns current locale direction
440
     *
441
     * @return string current locale direction
442
     */
443
    public function getCurrentLocaleDirection()
444
    {
445
446
        if ( !empty( $this->supportedLocales[ $this->getCurrentLocale() ][ 'dir' ] ) )
447
        {
448
            return $this->supportedLocales[ $this->getCurrentLocale() ][ 'dir' ];
449
        }
450
451
        switch ( $this->getCurrentLocaleScript() )
452
        {
453
            // Other (historic) RTL scripts exist, but this list contains the only ones in current use.
454
            case 'Arab':
455
            case 'Hebr':
456
            case 'Mong':
457
            case 'Tfng':
458
            case 'Thaa':
459
                return 'rtl';
460
            default:
461
                return 'ltr';
462
        }
463
464
    }
465
466
    /**
467
     * Returns current locale script
468
     *
469
     * @return string current locale script
470
     */
471
    public function getCurrentLocaleScript()
472
    {
473
        return $this->supportedLocales[ $this->getCurrentLocale() ][ 'script' ];
474
    }
475
476
    /**
477
     * Returns current language's native reading
478
     *
479
     * @return string current language's native reading
480
     */
481
    public function getCurrentLocaleNativeReading()
482
    {
483
        return $this->supportedLocales[ $this->getCurrentLocale() ][ 'native' ];
484
    }
485
486
    /**
487
     * Returns current language
488
     *
489
     * @return string current language
490
     */
491
    public function getCurrentLocale()
492
    {
493
        if ( $this->currentLocale )
494
        {
495
            return $this->currentLocale;
496
        }
497
498
        if ( $this->useAcceptLanguageHeader() )
499
        {
500
            $negotiator = new LanguageNegotiator($this->defaultLocale, $this->getSupportedLocales(), $this->request);
501
502
            return $negotiator->negotiateLanguage();
503
        }
504
505
        // or get application default language
506
        return $this->configRepository->get('app.locale');
507
    }
508
509
    /**
510
     * Returns current regional
511
     * @return string current regional
512
     */
513
    public function getCurrentLocaleRegional()
514
    {
515
        // need to check if it exists, since 'regional' has been added
516
        // after version 1.0.11 and existing users will not have it
517
        if(isset($this->supportedLocales[ $this->getCurrentLocale() ][ 'regional' ]) )
518
            return $this->supportedLocales[ $this->getCurrentLocale() ][ 'regional' ];
519
        else
520
            return null;
521
    }
522
523
    /**
524
     * Returns supported languages language key
525
     *
526
     * @return array    keys of supported languages
527
     */
528
    public function getSupportedLanguagesKeys()
529
    {
530
        return array_keys($this->supportedLocales);
531
    }
532
533
534
    /**
535
     * Check if Locale exists on the supported locales array
536
     *
537
     * @param string|boolean $locale string|bool Locale to be checked
538
     * @throws SupportedLocalesNotDefined
539
     * @return boolean is the locale supported?
540
     */
541
    public function checkLocaleInSupportedLocales( $locale )
542
    {
543
        $locales = $this->getSupportedLocales();
544
        if ( $locale !== false && empty( $locales[ $locale ] ) )
545
        {
546
            return false;
547
        }
548
549
        return true;
550
    }
551
552
    /**
553
     * Change route attributes for the ones in the $attributes array
554
     *
555
     * @param $attributes array Array of attributes
556
     * @param string $route string route to substitute
557
     * @return string route with attributes changed
558
     */
559
    protected function substituteAttributesInRoute( $attributes, $route )
560
    {
561
        foreach ( $attributes as $key => $value )
562
        {
563
            $route = str_replace("{" . $key . "}", $value, $route);
564
            $route = str_replace("{" . $key . "?}", $value, $route);
565
        }
566
567
        // delete empty optional arguments that are not in the $attributes array
568
        $route = preg_replace('/\/{[^)]+\?}/', '', $route);
569
570
        return $route;
571
    }
572
573
    /**
574
     * Returns translated routes
575
     *
576
     * @return array translated routes
577
     */
578
    protected function getTranslatedRoutes()
579
    {
580
        return $this->translatedRoutes;
581
    }
582
583
    /**
584
     * Set current route name
585
     * @param string $routeName current route name
586
     */
587
    public function setRouteName( $routeName )
588
    {
589
        $this->routeName = $routeName;
590
    }
591
592
    /**
593
     * Translate routes and save them to the translated routes array (used in the localize route filter)
594
     *
595
     * @param  string $routeName Key of the translated string
596
     *
597
     * @return string                Translated string
598
     */
599
    public function transRoute( $routeName )
600
    {
601
        if ( !in_array($routeName, $this->translatedRoutes) )
602
        {
603
            $this->translatedRoutes[ ] = $routeName;
604
        }
605
606
        return $this->translator->trans($routeName);
607
    }
608
609
    /**
610
     * Returns the translation key for a given path
611
     *
612
     * @param  string $path Path to get the key translated
613
     *
614
     * @return string|false            Key for translation, false if not exist
615
     */
616
    public function getRouteNameFromAPath( $path )
617
    {
618
        $attributes = $this->extractAttributes($path);
619
620
        $path = str_replace(url('/'), "", $path);
621
        if ( $path[ 0 ] !== '/' )
622
        {
623
            $path = '/' . $path;
624
        }
625
        $path = str_replace('/' . $this->currentLocale . '/', '', $path);
626
        $path = trim($path, "/");
627
628
        foreach ( $this->translatedRoutes as $route )
629
        {
630
            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...
631
            {
632
                return $route;
633
            }
634
        }
635
636
        return false;
637
    }
638
639
    /**
640
     * Returns the translated route for the path and the url given
641
     *
642
     * @param  string $path Path to check if it is a translated route
643
     * @param  string $url_locale Language to check if the path exists
644
     *
645
     * @return string|false            Key for translation, false if not exist
646
     */
647
    protected function findTranslatedRouteByPath( $path, $url_locale )
648
    {
649
        // check if this url is a translated url
650
        foreach ( $this->translatedRoutes as $translatedRoute )
651
        {
652
            if ( $this->translator->trans($translatedRoute, [ ], "", $url_locale) == rawurldecode($path) )
653
            {
654
                return $translatedRoute;
655
            }
656
        }
657
658
        return false;
659
    }
660
661
    /**
662
     * Returns the translated route for an url and the attributes given and a locale
663
     *
664
     * @throws SupportedLocalesNotDefined
665
     * @throws UnsupportedLocaleException
666
     *
667
     * @param  string|false|null $url Url to check if it is a translated route
668
     * @param  array $attributes Attributes to check if the url exists in the translated routes array
669
     * @param  string $locale Language to check if the url exists
670
     *
671
     * @return string|false                Key for translation, false if not exist
672
     */
673
    protected function findTranslatedRouteByUrl( $url, $attributes, $locale )
674
    {
675
        if ( empty( $url ) )
676
        {
677
            return false;
678
        }
679
680
        // check if this url is a translated url
681
        foreach ( $this->translatedRoutes as $translatedRoute )
682
        {
683
            $routeName = $this->getURLFromRouteNameTranslated($locale, $translatedRoute, $attributes);
684
685
            if ( $this->getNonLocalizedURL($routeName) == $this->getNonLocalizedURL($url) )
686
            {
687
                return $translatedRoute;
688
            }
689
690
        }
691
692
        return false;
693
    }
694
695
    /**
696
     * Returns true if the string given is a valid url
697
     *
698
     * @param  string $url String to check if it is a valid url
699
     *
700
     * @return boolean        Is the string given a valid url?
701
     */
702
    protected function checkUrl( $url )
703
    {
704
        return filter_var($url, FILTER_VALIDATE_URL);
705
    }
706
707
708
    /**
709
     * Returns the config repository for this instance
710
     *
711
     * @return Repository    Configuration repository
712
     *
713
     */
714
    public function getConfigRepository()
715
    {
716
        return $this->configRepository;
717
    }
718
719
720
    /**
721
     * Returns the translation key for a given path
722
     *
723
     * @return boolean       Returns value of useAcceptLanguageHeader in config.
724
     */
725
    protected function useAcceptLanguageHeader()
726
    {
727
        return $this->configRepository->get('laravellocalization.useAcceptLanguageHeader');
728
    }
729
730
    /**
731
     * Returns the translation key for a given path
732
     *
733
     * @return boolean       Returns value of hideDefaultLocaleInURL in config.
734
     */
735
    public function hideDefaultLocaleInURL()
736
    {
737
        return $this->configRepository->get('laravellocalization.hideDefaultLocaleInURL');
738
    }
739
740
    /**
741
     * Create an url from the uri
742
     * @param    string $uri Uri
743
     *
744
     * @return  string  Url for the given uri
745
     */
746
    public function createUrlFromUri( $uri )
747
    {
748
        $uri = ltrim($uri, "/");
749
750
        if ( empty( $this->baseUrl ) )
751
        {
752
            return app('url')->to($uri);
753
        }
754
755
        return $this->baseUrl . $uri;
756
    }
757
758
    /**
759
     * Sets the base url for the site
760
     * @param string $url Base url for the site
761
     *
762
     */
763
    public function setBaseUrl( $url )
764
    {
765
        if ( substr($url, -1) != "/" )
766
            $url .= "/";
767
768
        $this->baseUrl = $url;
769
    }
770
771
    /**
772
     * Extract attributes for current url
773
     *
774
     * @param bool|false|null|string $url to extract attributes, if not present, the system will look for attributes in the current call
775
     *
776
     * @param string $locale
777
     * @return array Array with attributes
778
     *
779
     */
780
    protected function extractAttributes( $url = false, $locale='' )
781
    {
782
        if ( !empty( $url ) )
783
        {
784
            $attributes = [ ];
785
            $parse = parse_url($url);
786
            if ( isset( $parse[ 'path' ] ) ) {
787
                $parse = explode("/", $parse[ 'path' ]);
788
            }
789
            else {
790
                $parse = [];
791
            }
792
            $url = [ ];
793
            foreach ( $parse as $segment )
794
            {
795
                if ( !empty( $segment ) )
796
                    $url[ ] = $segment;
797
            }
798
799
            foreach ( $this->router->getRoutes() as $route )
800
            {
801
                $path = $route->getUri();
802
                if ( !preg_match("/{[\w]+}/", $path) )
803
                {
804
                    continue;
805
                }
806
807
                $path = explode("/", $path);
808
                $i = 0;
809
810
                $match = true;
811
                foreach ( $path as $j => $segment )
812
                {
813
                    if ( isset( $url[ $i ] ) )
814
                    {
815
                        if ( $segment === $url[ $i ] )
816
                        {
817
                            $i++;
818
                            continue;
819
                        }
820
                        if ( preg_match("/{[\w]+}/", $segment) )
821
                        {
822
                            // must-have parameters
823
                            $attribute_name = preg_replace([ "/}/", "/{/", "/\?/" ], "", $segment);
824
                            $attributes[ $attribute_name ] = $url[ $i ];
825
                            $i++;
826
                            continue;
827
                        }
828
                        if ( preg_match("/{[\w]+\?}/", $segment) )
829
                        {
830
                            // optional parameters
831
                            if ( !isset( $path[ $j + 1 ] ) || $path[ $j + 1 ] !== $url[ $i ] )
832
                            {
833
                                // optional parameter taken
834
                                $attribute_name = preg_replace([ "/}/", "/{/", "/\?/" ], "", $segment);
835
                                $attributes[ $attribute_name ] = $url[ $i ];
836
                                $i++;
837
                                continue;
838
                            }
839
840
                        }
841
                    } else if ( !preg_match("/{[\w]+\?}/", $segment) )
842
                    {
843
                        // no optional parameters but no more $url given
844
                        // this route does not match the url
845
                        $match = false;
846
                        break;
847
                    }
848
                }
849
850
                if ( isset( $url[ $i + 1 ] ) )
851
                {
852
                    $match = false;
853
                }
854
855
                if ( $match )
856
                {
857
                    return $attributes;
858
                }
859
            }
860
861
        } else
862
        {
863
            if ( !$this->router->current() )
864
            {
865
                return [ ];
866
            }
867
868
            $attributes = $this->router->current()->parameters();
869
            $response = event('routes.translation', [ $locale, $attributes ]);
870
871
            if ( !empty( $response ) )
872
            {
873
                $response = array_shift($response);
874
            }
875
876
            if ( is_array($response) )
877
            {
878
                $attributes = array_merge($attributes, $response);
879
            }
880
        }
881
882
883
        return $attributes;
884
    }
885
886
    /**
887
     * Build URL using array data from parse_url
888
     *
889
     * @param array|false $parsed_url Array of data from parse_url function
890
     *
891
     * @return string               Returns URL as string.
892
     */
893
    protected function unparseUrl( $parsed_url )
894
    {
895
        if ( empty( $parsed_url ) )
896
        {
897
            return "";
898
        }
899
900
        $url = "";
901
        $url .= isset( $parsed_url[ 'scheme' ] ) ? $parsed_url[ 'scheme' ] . '://' : '';
902
        $url .= isset( $parsed_url[ 'host' ] ) ? $parsed_url[ 'host' ] : '';
903
        $url .= isset( $parsed_url[ 'port' ] ) ? ':' . $parsed_url[ 'port' ] : '';
904
        $user = isset( $parsed_url[ 'user' ] ) ? $parsed_url[ 'user' ] : '';
905
        $pass = isset( $parsed_url[ 'pass' ] ) ? ':' . $parsed_url[ 'pass' ] : '';
906
        $url .= $user . ( ( $user || $pass ) ? "$pass@" : '' );
907
908
        if ( !empty( $url ) )
909
        {
910
            $url .= isset( $parsed_url[ 'path' ] ) ? '/' . ltrim($parsed_url[ 'path' ], '/') : '';
911
        } else
912
        {
913
            $url .= isset( $parsed_url[ 'path' ] ) ? $parsed_url[ 'path' ] : '';
914
        }
915
916
        $url .= isset( $parsed_url[ 'query' ] ) ? '?' . $parsed_url[ 'query' ] : '';
917
        $url .= isset( $parsed_url[ 'fragment' ] ) ? '#' . $parsed_url[ 'fragment' ] : '';
918
919
        return $url;
920
    }
921
}
922