Test Failed
Push — master ( c2873c...a077d1 )
by Jeroen
01:35
created

Request::getElggPath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 0
dl 0
loc 8
ccs 4
cts 5
cp 0.8
crap 2.032
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace Elgg\Http;
3
4
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
5
use Elgg\Application;
6
7
/**
8
 * Elgg HTTP request.
9
 *
10
 * @access private
11
 */
12
class Request extends SymfonyRequest {
13
14
	const REWRITE_TEST_TOKEN = '__testing_rewrite';
15
	const REWRITE_TEST_OUTPUT = 'success';
16
17
	/**
18
	 * Get the Elgg URL segments
19
	 *
20
	 * @param bool $raw If true, the segments will not be HTML escaped
21 104
	 *
22 104
	 * @return string[]
23 104
	 */
24 95
	public function getUrlSegments($raw = false) {
25
		$path = trim($this->getElggPath(), '/');
26 104
		if (!$raw) {
27 9
			$path = htmlspecialchars($path, ENT_QUOTES, 'UTF-8');
28
		}
29
		if (!$path) {
30 100
			return [];
31
		}
32
33
		return explode('/', $path);
34
	}
35
36
	/**
37
	 * Get a cloned request with new Elgg URL segments
38
	 *
39
	 * @param string[] $segments URL segments
40 1
	 *
41 1
	 * @return Request
42 1
	 */
43 1
	public function setUrlSegments(array $segments) {
44
		$base_path = trim($this->getBasePath(), '/');
45 1
		$server = $this->server->all();
46
		$server['REQUEST_URI'] = "$base_path/" . implode('/', $segments);
47
48
		return $this->duplicate(null, null, null, null, null, $server);
49
	}
50
51
	/**
52
	 * Get first Elgg URL segment
53
	 *
54
	 * @see \Elgg\Http\Request::getUrlSegments()
55 7
	 *
56 7
	 * @return string
57 7
	 */
58 4
	public function getFirstUrlSegment() {
59
		$segments = $this->getUrlSegments();
60 3
		if ($segments) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $segments of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
61
			return array_shift($segments);
62
		} else {
63
			return '';
64
		}
65
	}
66
67 1
	/**
68 1
	 * Get the Request URI minus querystring
69
	 *
70 1
	 * @return string
71
	 */
72 1
	public function getElggPath() {
73 1
		if (php_sapi_name() === 'cli-server') {
74 1
			$path = $this->getRequestUri();
75 1
		} else {
76
			$path = $this->getPathInfo();
77
		}
78
		return preg_replace('~(\?.*)$~', '', $path);
79
	}
80
81
	/**
82
	 * {@inheritdoc}
83
	 */
84
	public function getClientIp() {
85 82
		$ip = parent::getClientIp();
86 82
87 30
		if ($ip == $this->server->get('REMOTE_ADDR')) {
88 82
			// try one more
89
			$ip_addresses = $this->server->get('HTTP_X_REAL_IP');
90
			if ($ip_addresses) {
91
				$ip_addresses = explode(',', $ip_addresses);
92
				return array_pop($ip_addresses);
93
			}
94
		}
95
96
		return $ip;
97
	}
98
99
	/**
100
	 * {@inheritdoc}
101
	 */
102
	public function isXmlHttpRequest() {
103
		return (strtolower($this->headers->get('X-Requested-With')) === 'xmlhttprequest'
104
			|| $this->query->get('X-Requested-With') === 'XMLHttpRequest'
105
			|| $this->request->get('X-Requested-With') === 'XMLHttpRequest');
106
		// GET/POST check is necessary for jQuery.form and other iframe-based "ajax". #8735
107
	}
108
109
	/**
110
	 * Sniff the Elgg site URL with trailing slash
111
	 *
112
	 * @return string
113
	 */
114
	public function sniffElggUrl() {
115
		$base_url = $this->getBaseUrl();
116
117
		// baseURL may end with the PHP script
118
		if ('.php' === substr($base_url, -4)) {
119
			$base_url = dirname($base_url);
120
		}
121
122
		return rtrim($this->getSchemeAndHttpHost() . $base_url, '/') . '/';
123
	}
124
125
	/**
126
	 * Is the request for checking URL rewriting?
127
	 *
128
	 * @return bool
129
	 */
130
	public function isRewriteCheck() {
131
		if ($this->getPathInfo() !== ('/' . self::REWRITE_TEST_TOKEN)) {
132
			return false;
133
		}
134
135
		if (!$this->get(self::REWRITE_TEST_TOKEN)) {
136
			return false;
137
		}
138
139
		return true;
140
	}
141
142
	/**
143
	 * Is PHP running the CLI server front controller
144
	 *
145
	 * @return bool
146
	 */
147
	public function isCliServer() {
148
		return php_sapi_name() === 'cli-server';
149
	}
150
151
	/**
152
	 * Is the request pointing to a file that the CLI server can handle?
153
	 *
154
	 * @param string $root Root directory
155
	 *
156
	 * @return bool
157
	 */
158
	public function isCliServable($root) {
159
		$file = rtrim($root, '\\/') . $this->getElggPath();
160
		if (!is_file($file)) {
161
			return false;
162
		}
163
164
		// http://php.net/manual/en/features.commandline.webserver.php
165
		$extensions = ".3gp, .apk, .avi, .bmp, .css, .csv, .doc, .docx, .flac, .gif, .gz, .gzip, .htm, .html, .ics, .jpe, .jpeg, .jpg, .js, .kml, .kmz, .m4a, .mov, .mp3, .mp4, .mpeg, .mpg, .odp, .ods, .odt, .oga, .ogg, .ogv, .pdf, .pdf, .png, .pps, .pptx, .qt, .svg, .swf, .tar, .text, .tif, .txt, .wav, .webm, .wmv, .xls, .xlsx, .xml, .xsl, .xsd, and .zip";
166
167
		// The CLI server routes ALL requests here (even existing files), so we have to check for these.
168
		$ext = pathinfo($file, PATHINFO_EXTENSION);
169
		if (!$ext) {
170
			return false;
171
		}
172
173
		$ext = preg_quote($ext, '~');
174
		return (bool) preg_match("~\\.{$ext}[,$]~", $extensions);
175
	}
176
}
177