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

getMatchesFromAcceptedLanguages()   C

Complexity

Conditions 10
Paths 2

Size

Total Lines 58
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 58
rs 6.6515
cc 10
eloc 29
nc 2
nop 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php namespace Mcamara\LaravelLocalization;
2
3
use Locale;
4
use Illuminate\Http\Request;
5
6
class LanguageNegotiator {
7
8
    /**
9
     * @var String
10
     */
11
    private $defaultLocale;
12
13
    /**
14
     * @var Array
15
     */
16
    private $supportedLanguages;
17
18
    /**
19
     * @var Request
20
     */
21
    private $request;
22
23
24
    /**
25
     * @param string $defaultLocale
26
     * @param array $supportedLanguages
27
     * @param Request $request
28
     */
29
    function __construct( $defaultLocale, $supportedLanguages, Request $request )
0 ignored issues
show
Bug introduced by
You have injected the Request via parameter $request. This is generally not recommended as there might be multiple instances during a request cycle (f.e. when using sub-requests). Instead, it is recommended to inject the RequestStack and retrieve the current request each time you need it via getCurrentRequest().
Loading history...
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
30
    {
31
        $this->defaultLocale = $defaultLocale;
32
        $this->supportedLanguages = $supportedLanguages;
33
        $this->request = $request;
34
    }
35
36
37
    /**
38
     * Negotiates language with the user's browser through the Accept-Language
39
     * HTTP header or the user's host address.  Language codes are generally in
40
     * the form "ll" for a language spoken in only one country, or "ll-CC" for a
41
     * language spoken in a particular country.  For example, U.S. English is
42
     * "en-US", while British English is "en-UK".  Portuguese as spoken in
43
     * Portugal is "pt-PT", while Brazilian Portuguese is "pt-BR".
44
     *
45
     * This function is based on negotiateLanguage from Pear HTTP2
46
     * http://pear.php.net/package/HTTP2/
47
     *
48
     * Quality factors in the Accept-Language: header are supported, e.g.:
49
     *      Accept-Language: en-UK;q=0.7, en-US;q=0.6, no, dk;q=0.8
50
     *
51
     * @return string  The negotiated language result or app.locale.
52
     */
53
    public function negotiateLanguage()
0 ignored issues
show
Coding Style introduced by
negotiateLanguage uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
54
    {
55
        $matches = $this->getMatchesFromAcceptedLanguages();
56
        foreach ( $matches as $key => $q )
57
        {
58
            if ( !empty( $this->supportedLanguages[ $key ] ) )
59
            {
60
                return $key;
61
            }
62
        }
63
        // If any (i.e. "*") is acceptable, return the first supported format
64
        if ( isset( $matches[ '*' ] ) )
65
        {
66
            reset($this->supportedLanguages);
67
68
            return key($this->supportedLanguages);
69
        }
70
71
        if ( class_exists('Locale') && !empty( $_SERVER[ 'HTTP_ACCEPT_LANGUAGE' ] ) )
72
        {
73
            $http_accept_language = Locale::acceptFromHttp($_SERVER[ 'HTTP_ACCEPT_LANGUAGE' ]);
74
75
            if ( !empty( $this->supportedLanguages[ $http_accept_language ] ) )
76
            {
77
                return $http_accept_language;
78
            }
79
        }
80
81
        if ( $this->request->server('REMOTE_HOST') )
82
        {
83
            $remote_host = explode('.', $this->request->server('REMOTE_HOST'));
84
            $lang = strtolower(end($remote_host));
85
86
            if ( !empty( $this->supportedLanguages[ $lang ] ) )
87
            {
88
                return $lang;
89
            }
90
        }
91
92
        return $this->defaultLocale;
93
    }
94
95
    /**
96
     * Return all the accepted languages from the browser
97
     * @return array Matches from the header field Accept-Languages
98
     */
99
    private function getMatchesFromAcceptedLanguages()
100
    {
101
        $matches = [ ];
102
103
        if ( $acceptLanguages = $this->request->header('Accept-Language') )
104
        {
105
            $acceptLanguages = explode(',', $acceptLanguages);
106
107
            $generic_matches = [ ];
108
            foreach ( $acceptLanguages as $option )
109
            {
110
                $option = array_map('trim', explode(';', $option));
111
                $l = $option[ 0 ];
112
                if ( isset( $option[ 1 ] ) )
113
                {
114
                    $q = (float)str_replace('q=', '', $option[ 1 ]);
115
                } else
116
                {
117
                    $q = null;
118
                    // Assign default low weight for generic values
119
                    if ( $l == '*/*' )
120
                    {
121
                        $q = 0.01;
122
                    } elseif ( substr($l, -1) == '*' )
123
                    {
124
                        $q = 0.02;
125
                    }
126
                }
127
                // Unweighted values, get high weight by their position in the
128
                // list
129
                $q = isset( $q ) ? $q : 1000 - count($matches);
130
                $matches[ $l ] = $q;
131
132
                //If for some reason the Accept-Language header only sends language with country
133
                //we should make the language without country an accepted option, with a value
134
                //less than it's parent.
135
                $l_ops = explode('-', $l);
136
                array_pop($l_ops);
137
                while ( !empty( $l_ops ) )
138
                {
139
                    //The new generic option needs to be slightly less important than it's base
140
                    $q -= 0.001;
141
                    $op = implode('-', $l_ops);
142
                    if ( empty( $generic_matches[ $op ] ) || $generic_matches[ $op ] > $q )
143
                    {
144
                        $generic_matches[ $op ] = $q;
145
                    }
146
                    array_pop($l_ops);
147
                }
148
            }
149
            $matches = array_merge($generic_matches, $matches);
150
151
            arsort($matches, SORT_NUMERIC);
152
153
        }
154
155
        return $matches;
156
    }
157
}
158