UrlGenerator   A
last analyzed

Complexity

Total Complexity 30

Size/Duplication

Total Lines 171
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 0

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 30
lcom 2
cbo 0
dl 0
loc 171
ccs 63
cts 63
cp 1
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
B getUrl() 0 25 5
C getCurrentUrl() 0 23 7
B dropLinkedInParams() 0 25 5
A getHttpHost() 0 8 3
C getHttpProtocol() 0 24 9
A setTrustForwarded() 0 6 1
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 2
        $url = self::$domainMap[$name];
40 2
        if ($path) {
41 2
            if ($path[0] === '/') {
42 1
                $path = substr($path, 1);
43 1
            }
44 2
            $url .= $path;
45 2
        }
46
47 2
        if (!empty($params)) {
48
            // does it exist a query string?
49 2
            $queryString = parse_url($url, PHP_URL_QUERY);
50 2
            if (empty($queryString)) {
51 1
                $url .= '?';
52 1
            } else {
53 1
                $url .= '&';
54
            }
55
56
            // it needs to be PHP_QUERY_RFC3986. We want to have %20 between scopes
57 2
            $url .= http_build_query($params, null, '&', PHP_QUERY_RFC3986);
58 2
        }
59
60 2
        return $url;
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66 3
    public function getCurrentUrl()
67
    {
68 3
        $protocol = $this->getHttpProtocol().'://';
69 3
        $host = $this->getHttpHost();
70 3
        $currentUrl = $protocol.$host.$_SERVER['REQUEST_URI'];
71 3
        $parts = parse_url($currentUrl);
72
73 3
        $query = '';
74 3
        if (!empty($parts['query'])) {
75
            // drop known linkedin params
76 1
            $query = $this->dropLinkedInParams($parts['query']);
77 1
        }
78
79
        // use port if non default
80
        $port =
81 3
            isset($parts['port']) &&
82 2
            (($protocol === 'http://' && $parts['port'] !== 80) ||
83 1
                ($protocol === 'https://' && $parts['port'] !== 443))
84 3
                ? ':'.$parts['port'] : '';
85
86
        // rebuild
87 3
        return $protocol.$parts['host'].$port.$parts['path'].$query;
88
    }
89
90
    /**
91
     * Drop known LinkedIn params. Ie those in self::$knownLinkeInParams.
92
     *
93
     * @param string $query
94
     *
95
     * @return string query without LinkedIn params. This string is prepended with a question mark '?'
96
     */
97 1
    protected function dropLinkedInParams($query)
98
    {
99 1
        if ($query == '') {
100 1
            return '';
101
        }
102
103 1
        $params = explode('&', $query);
104 1
        foreach ($params as $i => $param) {
105
            /*
106
             * A key or key/value pair might me 'foo=bar', 'foo=', or 'foo'.
107
             */
108
            //get the first value of the array you will get when you explode()
109 1
            list($key) = explode('=', $param, 2);
110 1
            if (in_array($key, self::$knownLinkedInParams)) {
111 1
                unset($params[$i]);
112 1
            }
113 1
        }
114
115
        //assert: params is an array. It might be empty
116 1
        if (!empty($params)) {
117 1
            return '?'.implode($params, '&');
118
        }
119
120 1
        return '';
121
    }
122
123
    /**
124
     * Get the host.
125
     *
126
     *
127
     * @return mixed
128
     */
129 2
    protected function getHttpHost()
130
    {
131 2
        if ($this->trustForwarded && isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
132 1
            return $_SERVER['HTTP_X_FORWARDED_HOST'];
133
        }
134
135 1
        return $_SERVER['HTTP_HOST'];
136
    }
137
138
    /**
139
     * Get the protocol.
140
     *
141
     *
142
     * @return string
143
     */
144 4
    protected function getHttpProtocol()
145
    {
146 4
        if ($this->trustForwarded && isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
147 2
            if ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
148 1
                return 'https';
149
            }
150
151 1
            return 'http';
152
        }
153
154
        /*apache + variants specific way of checking for https*/
155 3
        if (isset($_SERVER['HTTPS']) &&
156 3
            ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] == 1)) {
157 1
            return 'https';
158
        }
159
160
        /*nginx way of checking for https*/
161 2
        if (isset($_SERVER['SERVER_PORT']) &&
162 2
            ($_SERVER['SERVER_PORT'] === '443')) {
163 1
            return 'https';
164
        }
165
166 1
        return 'http';
167
    }
168
169
    /**
170
     * {@inheritdoc}
171
     */
172 3
    public function setTrustForwarded($trustForwarded)
173
    {
174 3
        $this->trustForwarded = $trustForwarded;
175
176 3
        return $this;
177
    }
178
}
179