fix calendar css, take 2. (#213)
[openemr.git] / interface / modules / zend_modules / library / Zend / Http / PhpEnvironment / Request.php
blob10abf5980c3e20f427921e9a1cd42280cc42c93e
1 <?php
2 /**
3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
8 */
10 namespace Zend\Http\PhpEnvironment;
12 use Zend\Http\Header\Cookie;
13 use Zend\Http\Request as HttpRequest;
14 use Zend\Stdlib\Parameters;
15 use Zend\Stdlib\ParametersInterface;
16 use Zend\Uri\Http as HttpUri;
17 use Zend\Validator\Hostname as HostnameValidator;
19 /**
20 * HTTP Request for current PHP environment
22 class Request extends HttpRequest
24 /**
25 * Base URL of the application.
27 * @var string
29 protected $baseUrl;
31 /**
32 * Base Path of the application.
34 * @var string
36 protected $basePath;
38 /**
39 * Actual request URI, independent of the platform.
41 * @var string
43 protected $requestUri;
45 /**
46 * PHP server params ($_SERVER)
48 * @var ParametersInterface
50 protected $serverParams = null;
52 /**
53 * PHP environment params ($_ENV)
55 * @var ParametersInterface
57 protected $envParams = null;
59 /**
60 * Construct
61 * Instantiates request.
63 * @param bool $allowCustomMethods
65 public function __construct($allowCustomMethods = true)
67 $this->setAllowCustomMethods($allowCustomMethods);
69 $this->setEnv(new Parameters($_ENV));
71 if ($_GET) {
72 $this->setQuery(new Parameters($_GET));
74 if ($_POST) {
75 $this->setPost(new Parameters($_POST));
77 if ($_COOKIE) {
78 $this->setCookies(new Parameters($_COOKIE));
80 if ($_FILES) {
81 // convert PHP $_FILES superglobal
82 $files = $this->mapPhpFiles();
83 $this->setFiles(new Parameters($files));
86 $this->setServer(new Parameters($_SERVER));
89 /**
90 * Get raw request body
92 * @return string
94 public function getContent()
96 if (empty($this->content)) {
97 $requestBody = file_get_contents('php://input');
98 if (strlen($requestBody) > 0) {
99 $this->content = $requestBody;
103 return $this->content;
107 * Set cookies
109 * Instantiate and set cookies.
111 * @param $cookie
112 * @return Request
114 public function setCookies($cookie)
116 $this->getHeaders()->addHeader(new Cookie((array) $cookie));
117 return $this;
121 * Set the request URI.
123 * @param string $requestUri
124 * @return self
126 public function setRequestUri($requestUri)
128 $this->requestUri = $requestUri;
129 return $this;
133 * Get the request URI.
135 * @return string
137 public function getRequestUri()
139 if ($this->requestUri === null) {
140 $this->requestUri = $this->detectRequestUri();
142 return $this->requestUri;
146 * Set the base URL.
148 * @param string $baseUrl
149 * @return self
151 public function setBaseUrl($baseUrl)
153 $this->baseUrl = rtrim($baseUrl, '/');
154 return $this;
158 * Get the base URL.
160 * @return string
162 public function getBaseUrl()
164 if ($this->baseUrl === null) {
165 $this->setBaseUrl($this->detectBaseUrl());
167 return $this->baseUrl;
171 * Set the base path.
173 * @param string $basePath
174 * @return self
176 public function setBasePath($basePath)
178 $this->basePath = rtrim($basePath, '/');
179 return $this;
183 * Get the base path.
185 * @return string
187 public function getBasePath()
189 if ($this->basePath === null) {
190 $this->setBasePath($this->detectBasePath());
193 return $this->basePath;
197 * Provide an alternate Parameter Container implementation for server parameters in this object,
198 * (this is NOT the primary API for value setting, for that see getServer())
200 * @param ParametersInterface $server
201 * @return Request
203 public function setServer(ParametersInterface $server)
205 $this->serverParams = $server;
207 // This seems to be the only way to get the Authorization header on Apache
208 if (function_exists('apache_request_headers')) {
209 $apacheRequestHeaders = apache_request_headers();
210 if (!isset($this->serverParams['HTTP_AUTHORIZATION'])) {
211 if (isset($apacheRequestHeaders['Authorization'])) {
212 $this->serverParams->set('HTTP_AUTHORIZATION', $apacheRequestHeaders['Authorization']);
213 } elseif (isset($apacheRequestHeaders['authorization'])) {
214 $this->serverParams->set('HTTP_AUTHORIZATION', $apacheRequestHeaders['authorization']);
219 // set headers
220 $headers = array();
222 foreach ($server as $key => $value) {
223 if ($value || (!is_array($value) && strlen($value))) {
224 if (strpos($key, 'HTTP_') === 0) {
225 if (strpos($key, 'HTTP_COOKIE') === 0) {
226 // Cookies are handled using the $_COOKIE superglobal
227 continue;
230 $headers[strtr(ucwords(strtolower(strtr(substr($key, 5), '_', ' '))), ' ', '-')] = $value;
231 } elseif (strpos($key, 'CONTENT_') === 0) {
232 $name = substr($key, 8); // Remove "Content-"
233 $headers['Content-' . (($name == 'MD5') ? $name : ucfirst(strtolower($name)))] = $value;
238 $this->getHeaders()->addHeaders($headers);
240 // set method
241 if (isset($this->serverParams['REQUEST_METHOD'])) {
242 $this->setMethod($this->serverParams['REQUEST_METHOD']);
245 // set HTTP version
246 if (isset($this->serverParams['SERVER_PROTOCOL'])
247 && strpos($this->serverParams['SERVER_PROTOCOL'], self::VERSION_10) !== false
249 $this->setVersion(self::VERSION_10);
252 // set URI
253 $uri = new HttpUri();
255 // URI scheme
256 if ((!empty($this->serverParams['HTTPS']) && strtolower($this->serverParams['HTTPS']) !== 'off')
257 || (!empty($this->serverParams['HTTP_X_FORWARDED_PROTO'])
258 && $this->serverParams['HTTP_X_FORWARDED_PROTO'] == 'https')
260 $scheme = 'https';
261 } else {
262 $scheme = 'http';
264 $uri->setScheme($scheme);
266 // URI host & port
267 $host = null;
268 $port = null;
270 // Set the host
271 if ($this->getHeaders()->get('host')) {
272 $host = $this->getHeaders()->get('host')->getFieldValue();
274 // works for regname, IPv4 & IPv6
275 if (preg_match('|\:(\d+)$|', $host, $matches)) {
276 $host = substr($host, 0, -1 * (strlen($matches[1]) + 1));
277 $port = (int) $matches[1];
280 // set up a validator that check if the hostname is legal (not spoofed)
281 $hostnameValidator = new HostnameValidator(array(
282 'allow' => HostnameValidator::ALLOW_ALL,
283 'useIdnCheck' => false,
284 'useTldCheck' => false,
286 // If invalid. Reset the host & port
287 if (!$hostnameValidator->isValid($host)) {
288 $host = null;
289 $port = null;
293 if (!$host && isset($this->serverParams['SERVER_NAME'])) {
294 $host = $this->serverParams['SERVER_NAME'];
295 if (isset($this->serverParams['SERVER_PORT'])) {
296 $port = (int) $this->serverParams['SERVER_PORT'];
298 // Check for missinterpreted IPv6-Address
299 // Reported at least for Safari on Windows
300 if (isset($this->serverParams['SERVER_ADDR']) && preg_match('/^\[[0-9a-fA-F\:]+\]$/', $host)) {
301 $host = '[' . $this->serverParams['SERVER_ADDR'] . ']';
302 if ($port . ']' == substr($host, strrpos($host, ':')+1)) {
303 // The last digit of the IPv6-Address has been taken as port
304 // Unset the port so the default port can be used
305 $port = null;
309 $uri->setHost($host);
310 $uri->setPort($port);
312 // URI path
313 $requestUri = $this->getRequestUri();
314 if (($qpos = strpos($requestUri, '?')) !== false) {
315 $requestUri = substr($requestUri, 0, $qpos);
318 $uri->setPath($requestUri);
320 // URI query
321 if (isset($this->serverParams['QUERY_STRING'])) {
322 $uri->setQuery($this->serverParams['QUERY_STRING']);
325 $this->setUri($uri);
327 return $this;
331 * Return the parameter container responsible for server parameters or a single parameter value.
333 * @param string|null $name Parameter name to retrieve, or null to get the whole container.
334 * @param mixed|null $default Default value to use when the parameter is missing.
335 * @see http://www.faqs.org/rfcs/rfc3875.html
336 * @return \Zend\Stdlib\ParametersInterface|mixed
338 public function getServer($name = null, $default = null)
340 if ($this->serverParams === null) {
341 $this->serverParams = new Parameters();
344 if ($name === null) {
345 return $this->serverParams;
348 return $this->serverParams->get($name, $default);
352 * Provide an alternate Parameter Container implementation for env parameters in this object,
353 * (this is NOT the primary API for value setting, for that see env())
355 * @param ParametersInterface $env
356 * @return Request
358 public function setEnv(ParametersInterface $env)
360 $this->envParams = $env;
361 return $this;
365 * Return the parameter container responsible for env parameters or a single parameter value.
367 * @param string|null $name Parameter name to retrieve, or null to get the whole container.
368 * @param mixed|null $default Default value to use when the parameter is missing.
369 * @return \Zend\Stdlib\ParametersInterface|mixed
371 public function getEnv($name = null, $default = null)
373 if ($this->envParams === null) {
374 $this->envParams = new Parameters();
377 if ($name === null) {
378 return $this->envParams;
381 return $this->envParams->get($name, $default);
385 * Convert PHP superglobal $_FILES into more sane parameter=value structure
386 * This handles form file input with brackets (name=files[])
388 * @return array
390 protected function mapPhpFiles()
392 $files = array();
393 foreach ($_FILES as $fileName => $fileParams) {
394 $files[$fileName] = array();
395 foreach ($fileParams as $param => $data) {
396 if (!is_array($data)) {
397 $files[$fileName][$param] = $data;
398 } else {
399 foreach ($data as $i => $v) {
400 $this->mapPhpFileParam($files[$fileName], $param, $i, $v);
406 return $files;
410 * @param array $array
411 * @param string $paramName
412 * @param int|string $index
413 * @param string|array $value
415 protected function mapPhpFileParam(&$array, $paramName, $index, $value)
417 if (!is_array($value)) {
418 $array[$index][$paramName] = $value;
419 } else {
420 foreach ($value as $i => $v) {
421 $this->mapPhpFileParam($array[$index], $paramName, $i, $v);
427 * Detect the base URI for the request
429 * Looks at a variety of criteria in order to attempt to autodetect a base
430 * URI, including rewrite URIs, proxy URIs, etc.
432 * @return string
434 protected function detectRequestUri()
436 $requestUri = null;
437 $server = $this->getServer();
439 // Check this first so IIS will catch.
440 $httpXRewriteUrl = $server->get('HTTP_X_REWRITE_URL');
441 if ($httpXRewriteUrl !== null) {
442 $requestUri = $httpXRewriteUrl;
445 // Check for IIS 7.0 or later with ISAPI_Rewrite
446 $httpXOriginalUrl = $server->get('HTTP_X_ORIGINAL_URL');
447 if ($httpXOriginalUrl !== null) {
448 $requestUri = $httpXOriginalUrl;
451 // IIS7 with URL Rewrite: make sure we get the unencoded url
452 // (double slash problem).
453 $iisUrlRewritten = $server->get('IIS_WasUrlRewritten');
454 $unencodedUrl = $server->get('UNENCODED_URL', '');
455 if ('1' == $iisUrlRewritten && '' !== $unencodedUrl) {
456 return $unencodedUrl;
459 // HTTP proxy requests setup request URI with scheme and host [and port]
460 // + the URL path, only use URL path.
461 if (!$httpXRewriteUrl) {
462 $requestUri = $server->get('REQUEST_URI');
465 if ($requestUri !== null) {
466 return preg_replace('#^[^/:]+://[^/]+#', '', $requestUri);
469 // IIS 5.0, PHP as CGI.
470 $origPathInfo = $server->get('ORIG_PATH_INFO');
471 if ($origPathInfo !== null) {
472 $queryString = $server->get('QUERY_STRING', '');
473 if ($queryString !== '') {
474 $origPathInfo .= '?' . $queryString;
476 return $origPathInfo;
479 return '/';
483 * Auto-detect the base path from the request environment
485 * Uses a variety of criteria in order to detect the base URL of the request
486 * (i.e., anything additional to the document root).
489 * @return string
491 protected function detectBaseUrl()
493 $filename = $this->getServer()->get('SCRIPT_FILENAME', '');
494 $scriptName = $this->getServer()->get('SCRIPT_NAME');
495 $phpSelf = $this->getServer()->get('PHP_SELF');
496 $origScriptName = $this->getServer()->get('ORIG_SCRIPT_NAME');
498 if ($scriptName !== null && basename($scriptName) === $filename) {
499 $baseUrl = $scriptName;
500 } elseif ($phpSelf !== null && basename($phpSelf) === $filename) {
501 $baseUrl = $phpSelf;
502 } elseif ($origScriptName !== null && basename($origScriptName) === $filename) {
503 // 1and1 shared hosting compatibility.
504 $baseUrl = $origScriptName;
505 } else {
506 // Backtrack up the SCRIPT_FILENAME to find the portion
507 // matching PHP_SELF.
509 $baseUrl = '/';
510 $basename = basename($filename);
511 if ($basename) {
512 $path = ($phpSelf ? trim($phpSelf, '/') : '');
513 $basePos = strpos($path, $basename) ?: 0;
514 $baseUrl .= substr($path, 0, $basePos) . $basename;
518 // Does the base URL have anything in common with the request URI?
519 $requestUri = $this->getRequestUri();
521 // Full base URL matches.
522 if (0 === strpos($requestUri, $baseUrl)) {
523 return $baseUrl;
526 // Directory portion of base path matches.
527 $baseDir = str_replace('\\', '/', dirname($baseUrl));
528 if (0 === strpos($requestUri, $baseDir)) {
529 return $baseDir;
532 $truncatedRequestUri = $requestUri;
534 if (false !== ($pos = strpos($requestUri, '?'))) {
535 $truncatedRequestUri = substr($requestUri, 0, $pos);
538 $basename = basename($baseUrl);
540 // No match whatsoever
541 if (empty($basename) || false === strpos($truncatedRequestUri, $basename)) {
542 return '';
545 // If using mod_rewrite or ISAPI_Rewrite strip the script filename
546 // out of the base path. $pos !== 0 makes sure it is not matching a
547 // value from PATH_INFO or QUERY_STRING.
548 if (strlen($requestUri) >= strlen($baseUrl)
549 && (false !== ($pos = strpos($requestUri, $baseUrl)) && $pos !== 0)
551 $baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));
554 return $baseUrl;
558 * Autodetect the base path of the request
560 * Uses several criteria to determine the base path of the request.
562 * @return string
564 protected function detectBasePath()
566 $filename = basename($this->getServer()->get('SCRIPT_FILENAME', ''));
567 $baseUrl = $this->getBaseUrl();
569 // Empty base url detected
570 if ($baseUrl === '') {
571 return '';
574 // basename() matches the script filename; return the directory
575 if (basename($baseUrl) === $filename) {
576 return str_replace('\\', '/', dirname($baseUrl));
579 // Base path is identical to base URL
580 return $baseUrl;