Elgg  Version 3.0
Request.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg\Http;
4 
6 use Elgg\Context;
10 use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
11 
17 class Request extends SymfonyRequest {
18 
19  const REWRITE_TEST_TOKEN = '__testing_rewrite';
20  const REWRITE_TEST_OUTPUT = 'success';
21 
25  protected $context_stack;
26 
30  protected $route;
31 
35  protected $request_overrides;
36 
40  public function __construct(
41  array $query = [],
42  array $request = [],
43  array $attributes = [],
44  array $cookies = [],
45  array $files = [],
46  array $server = [],
47  $content = null
48  ) {
49  parent::__construct($query, $request, $attributes, $cookies, $files, $server, $content);
50 
51  $this->initializeContext();
52 
53  $this->request_overrides = [];
54  }
55 
60  public function initializeContext() {
61  $context = new Context($this);
62  $this->context_stack = $context;
63 
64  return $this;
65  }
66 
71  public function getContextStack() {
72  return $this->context_stack;
73  }
74 
82  public function setRoute(Route $route) {
83  $this->route = $route;
84  foreach ($route->getMatchedParameters() as $key => $value) {
85  $this->setParam($key, $value);
86  }
87 
88  return $this;
89  }
90 
95  public function getRoute() {
96  return $this->route;
97  }
98 
110  public function setParam($key, $value, $override_request = false) {
111  if ((bool) $override_request) {
112  $this->request_overrides[$key] = $value;
113  } else {
114  $this->request->set($key, $value);
115  }
116 
117  return $this;
118  }
119 
137  public function getParam($key, $default = null, $filter_result = true) {
138  $result = $default;
139 
140  $values = $this->getParams($filter_result);
141 
142  $value = elgg_extract($key, $values, $default);
143  if ($value !== null) {
144  $result = $value;
145  }
146 
147  return $result;
148  }
149 
157  public function getParams($filter_result = true) {
159  $query = $this->query->all();
160  $attributes = $this->attributes->all();
161  $post = $this->request->all();
162 
163  $result = array_merge($post, $attributes, $query, $request_overrides);
164 
165  if ($filter_result) {
166  $this->getContextStack()->push('input');
167 
169 
170  $this->getContextStack()->pop();
171  }
172 
173  return $result;
174  }
175 
181  public function getCurrentURL() {
183 
184  $page = $url['scheme'] . "://" . $url['host'];
185 
186  if (isset($url['port']) && $url['port']) {
187  $page .= ":" . $url['port'];
188  }
189 
190  $page = trim($page, "/");
191 
192  $page .= $this->getRequestUri();
193 
194  return $page;
195  }
196 
204  public function getUrlSegments($raw = false) {
205  $path = trim($this->getElggPath(), '/');
206  if (!$raw) {
207  $path = htmlspecialchars($path, ENT_QUOTES, 'UTF-8');
208  }
209  if (!$path) {
210  return [];
211  }
212 
213  return explode('/', $path);
214  }
215 
223  public function setUrlSegments(array $segments) {
224  $base_path = trim($this->getBasePath(), '/');
225  $server = $this->server->all();
226  $server['REQUEST_URI'] = "$base_path/" . implode('/', $segments);
227 
228  return $this->duplicate(null, null, null, null, null, $server);
229  }
230 
238  public function getFirstUrlSegment() {
239  $segments = $this->getUrlSegments();
240  if (!empty($segments)) {
241  return array_shift($segments);
242  }
243 
244  return '';
245  }
246 
252  public function getElggPath() {
253  if (php_sapi_name() === 'cli-server') {
254  $path = $this->getRequestUri();
255  } else {
256  $path = $this->getPathInfo();
257  }
258 
259  return preg_replace('~(\?.*)$~', '', $path);
260  }
261 
265  public function getClientIp() {
266  $ip = parent::getClientIp();
267 
268  if ($ip == $this->server->get('REMOTE_ADDR')) {
269  // try one more
270  $ip_addresses = $this->server->get('HTTP_X_REAL_IP');
271  if ($ip_addresses) {
272  $ip_addresses = explode(',', $ip_addresses);
273 
274  return array_pop($ip_addresses);
275  }
276  }
277 
278  return $ip;
279  }
280 
284  public function isXmlHttpRequest() {
285  return (strtolower($this->headers->get('X-Requested-With')) === 'xmlhttprequest'
286  || $this->query->get('X-Requested-With') === 'XMLHttpRequest'
287  || $this->request->get('X-Requested-With') === 'XMLHttpRequest');
288  // GET/POST check is necessary for jQuery.form and other iframe-based "ajax". #8735
289  }
290 
296  public function sniffElggUrl() {
297  $base_url = $this->getBaseUrl();
298 
299  // baseURL may end with the PHP script
300  if ('.php' === substr($base_url, -4)) {
301  $base_url = dirname($base_url);
302  }
303 
304  $base_url = str_replace('\\', '/', $base_url);
305 
306  return rtrim($this->getSchemeAndHttpHost() . $base_url, '/') . '/';
307  }
308 
314  public function isRewriteCheck() {
315  if ($this->getPathInfo() !== ('/' . self::REWRITE_TEST_TOKEN)) {
316  return false;
317  }
318 
319  if (!$this->get(self::REWRITE_TEST_TOKEN)) {
320  return false;
321  }
322 
323  return true;
324  }
325 
331  public function isCliServer() {
332  return php_sapi_name() === 'cli-server';
333  }
334 
342  public function isCliServable($root) {
343  $file = rtrim($root, '\\/') . $this->getElggPath();
344  if (!is_file($file)) {
345  return false;
346  }
347 
348  // http://php.net/manual/en/features.commandline.webserver.php
349  $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";
350 
351  // The CLI server routes ALL requests here (even existing files), so we have to check for these.
352  $ext = pathinfo($file, PATHINFO_EXTENSION);
353  if (!$ext) {
354  return false;
355  }
356 
357  $ext = preg_quote($ext, '~');
358 
359  return (bool) preg_match("~\\.{$ext}[,$]~", $extensions);
360  }
361 
369  public function getFiles($input_name) {
370  $files = $this->files->get($input_name);
371  if (empty($files)) {
372  return [];
373  }
374 
375  if (!is_array($files)) {
376  $files = [$files];
377  }
378 
379  return $files;
380  }
381 
390  public function getFile($input_name, $check_for_validity = true) {
391  $files = $this->getFiles($input_name);
392  if (empty($files)) {
393  return false;
394  }
395 
396  $file = $files[0];
397  if (empty($file)) {
398  return false;
399  }
400 
401  if ($check_for_validity && !$file->isValid()) {
402  return false;
403  }
404 
405  return $file;
406  }
407 
414  public function validate() {
415 
416  $reported_bytes = $this->server->get('CONTENT_LENGTH');
417 
418  // Requests with multipart content type
419  $post_data_count = count($this->request->all());
420 
421  // Requests with other content types
422  $content = $this->getContent();
423  $post_body_length = is_string($content) ? strlen($content) : 0;
424 
425  $file_count = count($this->files->all());
426 
427  $is_valid = function() use ($reported_bytes, $post_data_count, $post_body_length, $file_count) {
428  if (empty($reported_bytes)) {
429  // Content length is set for POST requests only
430  return true;
431  }
432 
433  if (empty($post_data_count) && empty($post_body_length) && empty($file_count)) {
434  // The size of $_POST or uploaded files has exceed the size limit
435  // and the request body/query has been truncated
436  // thus the request reported bytes is set, but no postdata is found
437  return false;
438  }
439 
440  return true;
441  };
442 
443  if (!$is_valid()) {
444  $error_msg = elgg_trigger_plugin_hook('action_gatekeeper:upload_exceeded_msg', 'all', [
445  'post_size' => $reported_bytes,
446  'visible_errors' => true,
447  ], elgg_echo('actiongatekeeper:uploadexceeded'));
448 
449  throw new BadRequestException($error_msg);
450  }
451  }
452 }
validate()
Validate the request.
Definition: Request.php:414
getElggPath()
Get the Request URI minus querystring.
Definition: Request.php:252
$query
Definition: groups.php:8
Elgg HTTP request.
Definition: Request.php:17
$context
Definition: add.php:8
if(!array_key_exists($filename, $text_files)) $file
isCliServer()
Is PHP running the CLI server front controller.
Definition: Request.php:331
setRoute(Route $route)
Sets the route matched for this request by the router.
Definition: Request.php:82
setParam($key, $value, $override_request=false)
Sets an input value that may later be retrieved by get_input.
Definition: Request.php:110
$extensions
getFiles($input_name)
Returns an array of uploaded file objects regardless of upload status/errors.
Definition: Request.php:369
getFirstUrlSegment()
Get first Elgg URL segment.
Definition: Request.php:238
$request
Page handler for autocomplete endpoint.
Definition: livesearch.php:9
initializeContext()
Initialize context stack.
Definition: Request.php:60
$path
Definition: details.php:89
getUrlSegments($raw=false)
Get the Elgg URL segments.
Definition: Request.php:204
elgg parse_url
Parse a URL into its parts.
Definition: elgglib.js:442
filter_tags($var)
Filter tags from a given string based on registered hooks.
Definition: input.php:82
setUrlSegments(array $segments)
Get a cloned request with new Elgg URL segments.
Definition: Request.php:223
elgg_echo($message_key, array $args=[], $language="")
Given a message key, returns an appropriately translated full-text string.
Definition: languages.php:21
sniffElggUrl()
Sniff the Elgg site URL with trailing slash.
Definition: Request.php:296
isCliServable($root)
Is the request pointing to a file that the CLI server can handle?
Definition: Request.php:342
$page
Definition: admin.php:26
isXmlHttpRequest()
{}
Definition: Request.php:284
getParam($key, $default=null, $filter_result=true)
Get some input from variables passed submitted through GET or POST.
Definition: Request.php:137
Route Wrapper.
Definition: Route.php:8
c Accompany it with the information you received as to the offer to distribute corresponding source complete source code means all the source code for all modules it plus any associated interface definition files
Definition: LICENSE.txt:210
getCurrentURL()
Returns current page URL.
Definition: Request.php:181
if(!$entity instanceof ElggEntity) $input_name
Definition: default.php:14
getRoute()
Returns the route matched for this request by the router.
Definition: Request.php:95
$url
Definition: default.php:33
elgg_trigger_plugin_hook($hook, $type, $params=null, $returnvalue=null)
Definition: elgglib.php:720
elgg_get_site_url()
Get the URL for the current (or specified) site, ending with "/".
const REWRITE_TEST_TOKEN
Definition: Request.php:19
$default
Definition: checkbox.php:35
elgg_extract($key, $array, $default=null, $strict=true)
Checks for $array[$key] and returns its value if it exists, else returns $default.
Definition: elgglib.php:1131
if($container instanceof ElggGroup &&$container->guid!=elgg_get_page_owner_guid()) $key
Definition: summary.php:55
getContextStack()
Returns context stack.
Definition: Request.php:71
$value
Definition: debugging.php:7
isRewriteCheck()
Is the request for checking URL rewriting?
Definition: Request.php:314
getFile($input_name, $check_for_validity=true)
Returns the first file found based on the input name.
Definition: Request.php:390
$content
Set robots.txt action.
Definition: set_robots.php:6
$request_overrides
@ var array
Definition: Request.php:35
const REWRITE_TEST_OUTPUT
Definition: Request.php:20
Thrown when request is malformatted.
foreach($resources as $id=> $href) if(!empty($resources_html)) $files
Definition: details.php:142
$attributes
Definition: ajax_loader.php:13
getMatchedParameters()
Get matched parameters.
Definition: Route.php:34
Manages a global stack of strings for sharing information about the current execution context...
Definition: Context.php:27
__construct(array $query=[], array $request=[], array $attributes=[], array $cookies=[], array $files=[], array $server=[], $content=null)
{}
Definition: Request.php:40
getParams($filter_result=true)
Returns all values parsed from the request.
Definition: Request.php:157