Issues (238)

src/Services/UriLocalizer.php (3 issues)

1
<?php
2
3
namespace Translation\Services;
4
5
use Illuminate\Http\Request;
0 ignored issues
show
The type Illuminate\Http\Request was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use Translation\Repositories\LanguageRepository;
7
8
class UriLocalizer
9
{
10
    /**
11
     * @param LanguageRepository $languageRepository
12
     * @param Request            $request
13
     */
14
    public function __construct(LanguageRepository $languageRepository, Request $request)
15
    {
16
        $this->request          = $request;
0 ignored issues
show
Bug Best Practice introduced by
The property request does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
17
        $this->availableLocales = $languageRepository->availableLocales();
0 ignored issues
show
Bug Best Practice introduced by
The property availableLocales does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
18
    }
19
20
    /**
21
     *  Returns the locale present in the current url, if any.
22
     *
23
     * @param  integer $segment Index of the segment containing locale info
24
     * @return string
25
     */
26
    public function localeFromRequest($segment = 0)
27
    {
28
        $url = $this->request->getUri();
29
        return $this->getLocaleFromUrl($url, $segment);
30
    }
31
32
    /**
33
     *  Localizes the given url to the given locale. Removes domain if present.
34
     *  Ex: /home => /es/home, /en/home => /es/home, http://www.domain.com/en/home => /en/home, https:://domain.com/ => /en
35
     *  If a non zero segment index is given, and the url doesn't have enought segments, the url is unchanged.
36
     *
37
     * @param  string  $url
38
     * @param  string  $locale
39
     * @param  integer $segment Index of the segment containing locale info
40
     * @return string
41
     */
42
    public function localize($url, $locale, $segment = 0)
43
    {
44
        $cleanUrl  = $this->cleanUrl($url, $segment);
45
        $parsedUrl = $this->parseUrl($cleanUrl, $segment);
46
47
        // Check if there are enough segments, if not return url unchanged:
48
        if (count($parsedUrl['segments']) >= $segment) {
49
            array_splice($parsedUrl['segments'], $segment, 0, $locale);
50
        }
51
        return $this->pathFromParsedUrl($parsedUrl);
52
    }
53
54
    /**
55
     *  Extract the first valid locale from a url
56
     *
57
     * @param  string  $url
58
     * @param  integer $segment Index of the segment containing locale info
59
     * @return string|null $locale
60
     */
61
    public function getLocaleFromUrl($url, $segment = 0)
62
    {
63
        return $this->parseUrl($url, $segment)['locale'];
64
    }
65
66
    /**
67
     *  Removes the domain and locale (if present) of a given url.
68
     *  Ex: http://www.domain.com/locale/random => /random, https://www.domain.com/random => /random, http://domain.com/random?param=value => /random?param=value
69
     *
70
     * @param  string  $url
71
     * @param  integer $segment Index of the segment containing locale info
72
     * @return string
73
     */
74
    public function cleanUrl($url, $segment = 0)
75
    {
76
        $parsedUrl = $this->parseUrl($url, $segment);
77
        // Remove locale from segments:
78
        if ($parsedUrl['locale']) {
79
            unset($parsedUrl['segments'][$segment]);
80
            $parsedUrl['locale'] = false;
81
        }
82
        return $this->pathFromParsedUrl($parsedUrl);
83
    }
84
85
    /**
86
     *  Parses the given url in a similar way to PHP's parse_url, with the following differences:
87
     *      Forward and trailling slashed are removed from the path value.
88
     *      A new "segments" key replaces 'path', with the uri segments in array form ('/es/random/thing' => ['es', 'random', 'thing'])
89
     *      A 'locale' key is added, with the value of the locale found in the current url
90
     *
91
     * @param  string  $url
92
     * @param  integer $segment Index of the segment containing locale info
93
     * @return mixed
94
     */
95
    protected function parseUrl($url, $segment = 0)
96
    {
97
        $parsedUrl             = parse_url($url);
98
        $parsedUrl['segments'] = array_values(array_filter(explode('/', $parsedUrl['path']), 'strlen'));
99
        $localeCandidate       = array_get($parsedUrl['segments'], $segment, false);
100
        $parsedUrl['locale']   = in_array($localeCandidate, $this->availableLocales) ? $localeCandidate : null;
101
        $parsedUrl['query']    = array_get($parsedUrl, 'query', false);
102
        $parsedUrl['fragment'] = array_get($parsedUrl, 'fragment', false);
103
        unset($parsedUrl['path']);
104
        return $parsedUrl;
105
    }
106
107
    /**
108
     *  Returns the uri for the given parsed url based on its segments, query and fragment
109
     *
110
     * @return string
111
     */
112
    protected function pathFromParsedUrl($parsedUrl)
113
    {
114
        $path = '/' . implode('/', $parsedUrl['segments']);
115
        if ($parsedUrl['query']) {
116
            $path .= "?{$parsedUrl['query']}";
117
        }
118
        if ($parsedUrl['fragment']) {
119
            $path .= "#{$parsedUrl['fragment']}";
120
        }
121
        return $path;
122
    }
123
124
    /**
125
     *  Remove the front slash from a string
126
     *
127
     * @param  string $path
128
     * @return string
129
     */
130
    protected function removeFrontSlash($path)
131
    {
132
        return strlen($path) > 0 && substr($path, 0, 1) === '/' ? substr($path, 1) : $path;
133
    }
134
135
    /**
136
     *  Remove the trailing slash from a string
137
     *
138
     * @param  string $path
139
     * @return string
140
     */
141
    protected function removeTrailingSlash($path)
142
    {
143
        return strlen($path) > 0 && substr($path, -1) === '/' ? substr($path, 0, -1) : $path;
144
    }
145
}
146