Completed
Push — master ( cf61ee...1444c2 )
by Philipp
02:57
created

Localization::extractDomain()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Pmochine\LaravelTongue\Localization;
4
5
use Illuminate\Support\Arr;
6
use Pmochine\LaravelTongue\Misc\Config;
7
use Illuminate\Contracts\Encryption\DecryptException;
8
9
class Localization
10
{
11
    /** Name of the cookie */
12
    const COOKIE = 'tongue-locale';
13
14
    /**
15
     * The goal is to find the language (the locale).
16
     * We look at the subdomain or in the cookies or browser language.
17
     *
18
     * @return stirng [Finds the locale of the url]
0 ignored issues
show
Bug introduced by
The type Pmochine\LaravelTongue\Localization\stirng 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...
19
     */
20
    public static function decipherTongue()
21
    {
22
        $locale = self::fromUrl();
23
24
        // there is no subdomain found
25
        if ($locale === false) {
26
            // this could be a future bug
27
            // when no middleware is active the language is not set right
28
            // domain.com could be in german etc...
29
            if (! Config::beautify()) {
30
                // if the middleware is active we should be redirected to en.domain.com
31
                // if not the fallback language is going to be used
32
                return Config::fallbackLocale();
33
            }
34
            // we are checking if we have languages set in cookies or in the browser
35
            return self::currentTongue();
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::currentTongue() returns the type string which is incompatible with the documented return type Pmochine\LaravelTongue\Localization\stirng.
Loading history...
36
        }
37
38
        // could be a custom subdomain
39
        if (! tongue()->isSpeaking($locale)) {
40
            // check if it is a white listed domain
41
            if (tongue()->speaking('subdomains', $locale)) {
42
                return self::currentTongue();
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::currentTongue() returns the type string which is incompatible with the documented return type Pmochine\LaravelTongue\Localization\stirng.
Loading history...
43
            }
44
            // check if we have a custom locale subdomain, if not it returns a null
45
            $locale = tongue()->speaking('custom-subdomains', $locale);
46
        }
47
48
        return $locale;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $locale returns the type array|string which is incompatible with the documented return type Pmochine\LaravelTongue\Localization\stirng.
Loading history...
49
    }
50
51
    /**
52
     * Gets the locale from the url.
53
     * @return string|bool false [when hostname===locale]
54
     */
55
    public static function fromUrl()
56
    {
57
        $hostname = explode('.', self::domain())[0];
58
        $locale = explode('.', request()->getHost())[0];
59
60
        return  $hostname === $locale ? false : $locale;
61
    }
62
63
    /**
64
     * Gets the registrable Domain of the website from the config.
65
     * If not set we are going to get it with TLDExtract
66
     * @return string
67
     */
68
    public static function domain(): string
69
    {
70
        if ($domain = Config::domain()) return $domain;
71
72
        return self::extractDomain();
73
    }
74
75
    /**
76
     * 
77
     * Gets the registrable Domain of the website.
78
     *
79
     * https://github.com/layershifter/TLDExtract
80
     *
81
     * @return  string  
82
     */
83
    protected static function extractDomain(): string
84
    {
85
        $extract = new \LayerShifter\TLDExtract\Extract();
86
87
        $result = $extract->parse(request()->getHost());
88
89
        return $result->getRegistrableDomain();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result->getRegistrableDomain() could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
90
    }
91
92
    /**
93
     * Tries to get the current locale of the user.
94
     * Via the Browser or the fallback language.
95
     *
96
     * @return string
97
     */
98
    protected static function currentTongue()
99
    {
100
        if (Config::cookieLocalization() && $locale = self::cookie()) {
101
            return $locale;
102
        }
103
104
        if (Config::acceptLanguage() && self::languageIsSet()) {
105
            $detector = new TongueDetector(Config::fallbackLocale(), Config::supportedLocales(), request());
106
107
            return $detector->negotiateLanguage();
108
        }
109
110
        return Config::fallbackLocale();
111
    }
112
113
    /**
114
     * Only for testing the TongueDetector.
115
     *
116
     * @return bool
117
     */
118
    protected static function languageIsSet()
119
    {
120
        return ! app()->runningInConsole() || Arr::has(request()->server(), 'HTTP_ACCEPT_LANGUAGE');
0 ignored issues
show
introduced by
The method runningInConsole() does not exist on Illuminate\Container\Container. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

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

120
        return ! app()->/** @scrutinizer ignore-call */ runningInConsole() || Arr::has(request()->server(), 'HTTP_ACCEPT_LANGUAGE');
Loading history...
Bug introduced by
It seems like request()->server() can also be of type string; however, parameter $array of Illuminate\Support\Arr::has() does only seem to accept ArrayAccess|array, maybe add an additional type check? ( Ignorable by Annotation )

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

120
        return ! app()->runningInConsole() || Arr::has(/** @scrutinizer ignore-type */ request()->server(), 'HTTP_ACCEPT_LANGUAGE');
Loading history...
121
    }
122
123
    /**
124
     * Sets or gets the cookie of the locale.
125
     * Important to set config/session domain to .exmaple.com
126
     * https://gistlog.co/JacobBennett/15558410de2a394373ac.
127
     *
128
     * @param  string $locale
129
     * @return string|null
130
     */
131
    public static function cookie($locale = null)
132
    {
133
        if ($locale != null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $locale of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
134
            return cookie()->queue(cookie()->forever(self::COOKIE, $locale));
0 ignored issues
show
Bug Best Practice introduced by
The expression return cookie()->queue(c...self::COOKIE, $locale)) returns the type void which is incompatible with the documented return type null|string.
Loading history...
Bug introduced by
Are you sure the usage of cookie()->queue(cookie()...self::COOKIE, $locale)) targeting Illuminate\Cookie\CookieJar::queue() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
135
        }
136
137
        if (! request()->hasCookie(self::COOKIE)) {
138
            return;
139
        }
140
141
        try {
142
            //Somehow I got this error: unserialize(): Error at offset 0 of 2 bytes
143
            //I needed to change decrypt(value, unserialize = false);
144
            return app('encrypter')->decrypt(request()->cookie(self::COOKIE), false);
145
        } catch (DecryptException $e) {
146
            //Somehow the middleware for decrypting does not kick in here...
147
            //but it even fails if we use php artisan <something> (weird)
148
            //if it happes we can simply give it normally back
149
            return request()->cookie(self::COOKIE);
0 ignored issues
show
Bug Best Practice introduced by
The expression return request()->cookie(self::COOKIE) also could return the type array which is incompatible with the documented return type null|string.
Loading history...
150
        } catch (Exception $e) {
0 ignored issues
show
Bug introduced by
The type Pmochine\LaravelTongue\Localization\Exception was not found. Did you mean Exception? If so, make sure to prefix the type with \.
Loading history...
151
            //So I don't return a cookie in that case
152
            return;
153
        }
154
    }
155
}
156