Localize   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 17
eloc 38
dl 0
loc 96
c 0
b 0
f 0
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A isValidLocale() 0 3 1
A prefixFromRequest() 0 5 1
A __construct() 0 4 1
A url() 0 11 3
A pathFromParsedUrl() 0 11 3
A parseUrl() 0 13 3
A cleanUrl() 0 10 2
A getSupportedLocales() 0 5 2
A getLocaleFromUrl() 0 3 1
1
<?php
2
3
namespace Presspack\Framework\Support\Localization;
4
5
use Illuminate\Support\Arr;
6
use Illuminate\Support\Facades\DB;
7
use Illuminate\Support\Facades\App;
8
9
class Localize
10
{
11
    protected $request;
12
    public $supportedLocales;
13
14
    public function __construct()
15
    {
16
        $this->request = app()['request'];
0 ignored issues
show
Bug introduced by
The function app was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

16
        $this->request = /** @scrutinizer ignore-call */ app()['request'];
Loading history...
17
        $this->supportedLocales = $this->getSupportedLocales();
18
    }
19
20
    public function getSupportedLocales()
21
    {
22
        return null === config('presspack.supported_locales')
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

22
        return null === /** @scrutinizer ignore-call */ config('presspack.supported_locales')
Loading history...
23
            ? DB::table('icl_languages')->where('active', '1')->pluck('code')->all()
24
            : config('presspack.supported_locales');
25
    }
26
27
    public function prefixFromRequest(int $segment = 0): ?string
28
    {
29
        $url = $this->request->getUri();
30
31
        return $this->getLocaleFromUrl($url, $segment);
32
    }
33
34
    public function getLocaleFromUrl(string $url, int $segment = 0): ?string
35
    {
36
        return $this->parseUrl($url, $segment)['locale'];
37
    }
38
39
    protected function parseUrl(string $url, int $segment = 0)
40
    {
41
        $parsedUrl = parse_url($url);
42
        if ($parsedUrl) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $parsedUrl of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
43
            $parsedUrl['segments'] = array_values(array_filter(explode('/', $parsedUrl['path']), 'strlen'));
44
            $localeCandidate = Arr::get($parsedUrl['segments'], $segment, false);
45
            $parsedUrl['locale'] = \in_array($localeCandidate, $this->supportedLocales, true) ? $localeCandidate : null;
46
            $parsedUrl['query'] = Arr::get($parsedUrl, 'query', false);
47
            $parsedUrl['fragment'] = Arr::get($parsedUrl, 'fragment', false);
48
            unset($parsedUrl['path']);
49
        }
50
51
        return $parsedUrl;
52
    }
53
54
    public function isValidLocale(string $locale): bool
55
    {
56
        return \in_array($locale, $this->supportedLocales, true);
57
    }
58
59
    public function url(string $url, string $locale = null, int $segment = 0): string
60
    {
61
        $locale = $locale ?: App::getLocale();
62
        $cleanUrl = $this->cleanUrl($url, $segment);
63
        $parsedUrl = $this->parseUrl($cleanUrl, $segment);
64
        // Check if there are enough segments, if not return url unchanged:
65
        if (\count($parsedUrl['segments']) >= $segment) {
66
            array_splice($parsedUrl['segments'], $segment, 0, $locale);
67
        }
68
69
        return url($this->pathFromParsedUrl($parsedUrl));
0 ignored issues
show
Bug introduced by
The function url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

69
        return /** @scrutinizer ignore-call */ url($this->pathFromParsedUrl($parsedUrl));
Loading history...
70
    }
71
72
    /**
73
     * Removes the domain and locale (if present) of a given url.
74
     *
75
     * Ex:
76
     * http://www.domain.com/locale/random => /random,
77
     * https://www.domain.com/random => /random, http://domain.com/random?param=value => /random?param=value.
78
     */
79
    public function cleanUrl(string $url, int $segment = 0): string
80
    {
81
        $parsedUrl = $this->parseUrl($url, $segment);
82
        // Remove locale from segments:
83
        if ($parsedUrl['locale']) {
84
            unset($parsedUrl['segments'][$segment]);
85
            $parsedUrl['locale'] = false;
86
        }
87
88
        return $this->pathFromParsedUrl($parsedUrl);
89
    }
90
91
    /**
92
     * Returns the uri for the given parsed url based on its segments, query and fragment.
93
     */
94
    protected function pathFromParsedUrl($parsedUrl): string
95
    {
96
        $path = '/'.implode('/', $parsedUrl['segments']);
97
        if ($parsedUrl['query']) {
98
            $path .= "?{$parsedUrl['query']}";
99
        }
100
        if ($parsedUrl['fragment']) {
101
            $path .= "#{$parsedUrl['fragment']}";
102
        }
103
104
        return $path;
105
    }
106
}
107