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.

Path::getTotalSegments()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
/**
3
 * This file is part of the O2System Framework package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @author         Steeve Andrian Salim
9
 * @copyright      Copyright (c) Steeve Andrian Salim
10
 */
11
12
// ------------------------------------------------------------------------
13
14
namespace O2System\Kernel\Http\Message\Uri;
15
16
// ------------------------------------------------------------------------
17
18
use O2System\Spl\DataStructures\SplArrayObject;
19
use O2System\Spl\Exceptions\RuntimeException;
20
21
/**
22
 * Class Path
23
 *
24
 * @package O2System\Kernel\Http\Message\Uri
25
 */
26
class Path
27
{
28
    /**
29
     * Path::$string
30
     *
31
     * @var string
32
     */
33
    private $string;
34
35
    /**
36
     * Path::__construct
37
     *
38
     * @var array
39
     */
40
    private $segments;
41
42
    // ------------------------------------------------------------------------
43
44
    /**
45
     * Path::__construct
46
     *
47
     * @throws \O2System\Spl\Exceptions\RuntimeException
48
     */
49
    public function __construct()
50
    {
51
        if (function_exists('config')) {
52
            $protocol = strtoupper(config('uri')->offsetGet('protocol'));
53
        }
54
55
        empty($protocol) && $protocol = 'REQUEST_URI';
56
57
        switch ($protocol) {
58
            case 'AUTO':
59
            case 'REQUEST_URI':
60
                $this->string = $this->parseRequestUri();
61
                break;
62
            case 'QUERY_STRING':
63
                $this->string = $this->parseQueryString();
64
                break;
65
            case 'PATH_INFO':
66
            default:
67
                $this->string = isset($_SERVER[ $protocol ])
68
                    ? $_SERVER[ $protocol ]
69
                    : $this->parseRequestUri();
70
                break;
71
        }
72
73
        // Filter out control characters and trim slashes
74
        $this->string = trim(remove_invisible_characters($this->string, false), '/');
75
        $this->setSegments(explode('/', $this->string));
76
    }
77
78
    // ------------------------------------------------------------------------
79
80
    /**
81
     * Path::parseRequestUri
82
     *
83
     * Parse REQUEST_URI
84
     *
85
     * Will parse REQUEST_URI and automatically detect the URI from it,
86
     * while fixing the query string if necessary.
87
     *
88
     * @access  protected
89
     * @return  string
90
     */
91
    protected function parseRequestUri()
92
    {
93
        if ( ! isset($_SERVER[ 'REQUEST_URI' ], $_SERVER[ 'SCRIPT_NAME' ])) {
94
            return '';
95
        }
96
97
        $uri = parse_url($_SERVER[ 'REQUEST_URI' ]);
98
        $query = isset($uri[ 'query' ])
99
            ? $uri[ 'query' ]
100
            : '';
101
        $uri = isset($uri[ 'path' ])
102
            ? $uri[ 'path' ]
103
            : '';
104
105
        if (isset($_SERVER[ 'SCRIPT_NAME' ][ 0 ])) {
106
            if (strpos($uri, $_SERVER[ 'SCRIPT_NAME' ]) === 0) {
107
                $uri = (string)substr($uri, strlen($_SERVER[ 'SCRIPT_NAME' ]));
108
            } elseif (strpos($uri, dirname($_SERVER[ 'SCRIPT_NAME' ])) === 0) {
109
                $uri = (string)substr($uri, strlen(dirname($_SERVER[ 'SCRIPT_NAME' ])));
110
            }
111
        }
112
113
        // This section ensures that even on servers that require the URI to be in the query string (Nginx) a correct
114
        // URI is found, and also fixes the QUERY_STRING server var and $_GET array.
115
        if (trim($uri, '/') === '' AND strncmp($query, '/', 1) === 0) {
116
            $query = explode('?', $query, 2);
117
            $uri = $query[ 0 ];
118
119
            $_SERVER[ 'QUERY_STRING' ] = isset($query[ 1 ])
120
                ? $query[ 1 ]
121
                : '';
122
        } else {
123
            $_SERVER[ 'QUERY_STRING' ] = $query;
124
        }
125
126
        parse_str($_SERVER[ 'QUERY_STRING' ], $_GET);
127
128
        if ($uri === '/' || $uri === '') {
129
            return '/';
130
        }
131
132
        // Do some final cleaning of the URI and return it
133
        return $this->removeRelativeDirectory($uri);
134
    }
135
136
    // ------------------------------------------------------------------------
137
138
    /**
139
     * Path::removeRelativeDirectory
140
     *
141
     * Remove relative directory (../) and multi slashes (///)
142
     *
143
     * Do some final cleaning of the URI and return it, currently only used in self::parseRequestURI()
144
     *
145
     * @param   string $uri URI String
146
     *
147
     * @access  protected
148
     * @return  string
149
     */
150
    protected function removeRelativeDirectory($uri)
151
    {
152
        $segments = [];
153
        $segment = strtok($uri, '/');
154
155
        $base_dirs = explode('/', str_replace('\\', '/', PATH_ROOT));
0 ignored issues
show
Bug introduced by
The constant O2System\Kernel\Http\Message\Uri\PATH_ROOT was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
156
157
        while ($segment !== false) {
158
            if (( ! empty($segment) || $segment === '0') AND
159
                $segment !== '..' AND
160
                ! in_array(
161
                    $segment,
162
                    $base_dirs
163
                )
164
            ) {
165
                $segments[] = $segment;
166
            }
167
            $segment = strtok('/');
168
        }
169
170
        return implode('/', $segments);
171
    }
172
173
    // ------------------------------------------------------------------------
174
175
    /**
176
     * Path::parseQueryString
177
     *
178
     * Parse QUERY_STRING
179
     *
180
     * Will parse QUERY_STRING and automatically detect the URI from it.
181
     *
182
     * @access  protected
183
     * @return  string
184
     */
185
    protected function parseQueryString()
186
    {
187
        $uri = isset($_SERVER[ 'QUERY_STRING' ])
188
            ? $_SERVER[ 'QUERY_STRING' ]
189
            : @getenv('QUERY_STRING');
190
191
        if (trim($uri, '/') === '') {
192
            return '';
193
        } elseif (strncmp($uri, '/', 1) === 0) {
194
            $uri = explode('?', $uri, 2);
195
            $_SERVER[ 'QUERY_STRING' ] = isset($uri[ 1 ])
196
                ? $uri[ 1 ]
197
                : '';
198
            $uri = rawurldecode($uri[ 0 ]);
199
        }
200
201
        parse_str($_SERVER[ 'QUERY_STRING' ], $_GET);
202
203
        return $this->removeRelativeDirectory($uri);
204
    }
205
206
    // --------------------------------------------------------------------
207
208
    /**
209
     * Path::setSegments
210
     *
211
     * @param array $segments
212
     *
213
     * @throws \O2System\Spl\Exceptions\RuntimeException
214
     */
215
    public function setSegments(array $segments)
216
    {
217
        $validSegments = [];
218
219
        if (count($segments)) {
220
            foreach ($segments as $key => $segment) {
221
                // Filter segments for security
222
                if ($segment = trim($this->filterSegment($segment))) {
223
                    if (false !== ($language = language()->registered($segment))) {
0 ignored issues
show
Unused Code introduced by
The assignment to $language is dead and can be removed.
Loading history...
Bug introduced by
The method registered() does not exist on O2System\Kernel\Services\Language. ( Ignorable by Annotation )

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

223
                    if (false !== ($language = language()->/** @scrutinizer ignore-call */ registered($segment))) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
224
                        language()->setDefault($segment);
225
226
                        continue;
227
                    } else {
228
                        $validSegments[] = $segment;
229
                    }
230
                }
231
            }
232
        }
233
234
        $validSegments = array_filter($validSegments);
235
        array_unshift($validSegments, null);
236
237
        unset($validSegments[ 0 ]);
238
239
        $this->segments = $validSegments;
240
        $this->string = implode('/', $this->segments);
241
    }
242
243
    // ------------------------------------------------------------------------
244
245
    /**
246
     * Path::filterSegment
247
     *
248
     * Filters segments for malicious characters.
249
     *
250
     * @param string $segment URI String
251
     *
252
     * @return mixed
253
     * @throws RuntimeException
254
     */
255
    protected function filterSegment($segment)
256
    {
257
        if (function_exists('config')) {
258
            $config = config('uri');
259
        } else {
260
            $config = new SplArrayObject([
261
                'permittedChars' => 'a-z 0-9~%.:_\-@#',
262
                'suffix'         => null,
263
            ]);
264
        }
265
266
        if ( ! empty($segment) AND
267
            ! empty($config->offsetGet('permittedChars')) AND
268
            ! preg_match('/^[' . $config->offsetGet('permittedChars') . ']+$/i', $segment) AND
269
            ! is_cli()
270
        ) {
271
            throw new RuntimeException('E_URI_HAS_DISALLOWED_CHARACTERS', 105);
272
        }
273
274
        // Convert programatic characters to entities and return
275
        return str_replace(
276
            ['$', '(', ')', '%28', '%29', $config->offsetGet('suffix')],    // Bad
277
            ['&#36;', '&#40;', '&#41;', '&#40;', '&#41;', ''],    // Good
278
            $segment
279
        );
280
    }
281
282
    // ------------------------------------------------------------------------
283
284
    /**
285
     * Path::getTotalSegments
286
     *
287
     * @return int
288
     */
289
    public function getTotalSegments()
290
    {
291
        return count($this->segments);
292
    }
293
}