Completed
Pull Request — master (#149)
by
unknown
05:28
created

UrlGenerator::getHttpProtocol()   C

Complexity

Conditions 9
Paths 5

Size

Total Lines 24
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 9

Importance

Changes 0
Metric Value
dl 0
loc 24
ccs 12
cts 12
cp 1
rs 5.3563
c 0
b 0
f 0
cc 9
eloc 12
nc 5
nop 0
crap 9
1
<?php
2
3
namespace Happyr\LinkedIn\Http;
4
5
/**
6
 * @author Tobias Nyholm <[email protected]>
7
 */
8
class UrlGenerator implements UrlGeneratorInterface
9
{
10
    /**
11
     * @var array knownLinkedInParams
12
     *
13
     * A list of params that might be in the query string
14
     */
15
    public static $knownLinkedInParams = ['state', 'code', 'access_token', 'user'];
16
17
    /**
18
     * @var array domainMap
19
     *
20
     * Maps aliases to LinkedIn domains.
21
     */
22
    public static $domainMap = [
23
        'api' => 'https://api.linkedin.com/',
24
        'www' => 'https://www.linkedin.com/',
25
    ];
26
27
    /**
28
     * @var bool
29
     *
30
     * Indicates if we trust HTTP_X_FORWARDED_* headers.
31
     */
32
    protected $trustForwarded = false;
33
34
    /**
35
     * {@inheritdoc}
36
     */
37 2
    public function getUrl($name, $path = '', $params = [])
38
    {
39
        /* handle the user passing in a full URL as the path */
40 2
        $urlComponents = parse_url($path);
41 2
        if (isset($urlComponents['path'])) {
42 2
            if (!empty($urlComponents['host'])) {
43
                $path = $urlComponents['path'];
44
                if (!empty($urlComponents['query'])) {
45
                    $path .= '?' . http_build_query($urlComponents['query']);
46
                }
47
            }
48 2
        }
49
50 2
        $url = self::$domainMap[$name];
51 2
        if ($path) {
52 2
            if ($path[0] === '/') {
53 1
                $path = substr($path, 1);
54 1
            }
55 2
            $url .= $path;
56 2
        }
57
58 2
        if (!empty($params)) {
59
            // does it exist a query string?
60 2
            $queryString = parse_url($url, PHP_URL_QUERY);
61 2
            if (empty($queryString)) {
62 1
                $url .= '?';
63 1
            } else {
64 1
                $url .= '&';
65
            }
66
67
            // it needs to be PHP_QUERY_RFC3986. We want to have %20 between scopes
68 2
            $url .= http_build_query($params, null, '&', PHP_QUERY_RFC3986);
69 2
        }
70
71 2
        return $url;
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77 3
    public function getCurrentUrl()
78
    {
79 3
        $protocol = $this->getHttpProtocol().'://';
80 3
        $host = $this->getHttpHost();
81 3
        $currentUrl = $protocol.$host.$_SERVER['REQUEST_URI'];
82 3
        $parts = parse_url($currentUrl);
83
84 3
        $query = '';
85 3
        if (!empty($parts['query'])) {
86
            // drop known linkedin params
87 1
            $query = $this->dropLinkedInParams($parts['query']);
88 1
        }
89
90
        // use port if non default
91
        $port =
92 3
            isset($parts['port']) &&
93 2
            (($protocol === 'http://' && $parts['port'] !== 80) ||
94 1
                ($protocol === 'https://' && $parts['port'] !== 443))
95 3
                ? ':'.$parts['port'] : '';
96
97
        // rebuild
98 3
        return $protocol.$parts['host'].$port.$parts['path'].$query;
99
    }
100
101
    /**
102
     * Drop known LinkedIn params. Ie those in self::$knownLinkeInParams.
103
     *
104
     * @param string $query
105
     *
106
     * @return string query without LinkedIn params. This string is prepended with a question mark '?'
107
     */
108 1
    protected function dropLinkedInParams($query)
109
    {
110 1
        if ($query == '') {
111 1
            return '';
112
        }
113
114 1
        $params = explode('&', $query);
115 1
        foreach ($params as $i => $param) {
116
            /*
117
             * A key or key/value pair might me 'foo=bar', 'foo=', or 'foo'.
118
             */
119
            //get the first value of the array you will get when you explode()
120 1
            list($key) = explode('=', $param, 2);
121 1
            if (in_array($key, self::$knownLinkedInParams)) {
122 1
                unset($params[$i]);
123 1
            }
124 1
        }
125
126
        //assert: params is an array. It might be empty
127 1
        if (!empty($params)) {
128 1
            return '?'.implode($params, '&');
129
        }
130
131 1
        return '';
132
    }
133
134
    /**
135
     * Get the host.
136
     *
137
     *
138
     * @return mixed
139
     */
140 2
    protected function getHttpHost()
141
    {
142 2
        if ($this->trustForwarded && isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
143 1
            return $_SERVER['HTTP_X_FORWARDED_HOST'];
144
        }
145
146 1
        return $_SERVER['HTTP_HOST'];
147
    }
148
149
    /**
150
     * Get the protocol.
151
     *
152
     *
153
     * @return string
154
     */
155 4
    protected function getHttpProtocol()
156
    {
157 4
        if ($this->trustForwarded && isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
158 2
            if ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
159 1
                return 'https';
160
            }
161
162 1
            return 'http';
163
        }
164
165
        /*apache + variants specific way of checking for https*/
166 3
        if (isset($_SERVER['HTTPS']) &&
167 3
            ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] == 1)) {
168 1
            return 'https';
169
        }
170
171
        /*nginx way of checking for https*/
172 2
        if (isset($_SERVER['SERVER_PORT']) &&
173 2
            ($_SERVER['SERVER_PORT'] === '443')) {
174 1
            return 'https';
175
        }
176
177 1
        return 'http';
178
    }
179
180
    /**
181
     * {@inheritdoc}
182
     */
183 3
    public function setTrustForwarded($trustForwarded)
184
    {
185 3
        $this->trustForwarded = $trustForwarded;
186
187 3
        return $this;
188
    }
189
}
190