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 ( 3c14c6...dd6b89 )
by Marc
7s
created

getURLFromRouteNameTranslated()   C

Complexity

Conditions 8
Paths 17

Size

Total Lines 37
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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