Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00%
0 / 1
85.71%
30 / 35
CRAP
90.48%
190 / 210
Request
0.00%
0 / 1
85.71%
30 / 35
103.96
90.48%
190 / 210
 makeFromGlobals()
100.00%
1 / 1
1
100.00%
1 / 1
 __construct(array $query = array()
100.00%
1 / 1
1
100.00%
2 / 2
 __toString()
100.00%
1 / 1
1
100.00%
1 / 1
 init(array $query = array()
100.00%
1 / 1
1
100.00%
12 / 12
 applyChanges()
100.00%
1 / 1
1
100.00%
5 / 5
 mock($uri, $method = 'GET', array $request = array()
100.00%
1 / 1
8
100.00%
41 / 41
 normalizeQuery($query)
100.00%
1 / 1
6
100.00%
16 / 16
 getMethod()
100.00%
1 / 1
2
100.00%
4 / 4
 setMethod($method)
100.00%
1 / 1
1
100.00%
3 / 3
 getScheme()
100.00%
1 / 1
2
100.00%
1 / 1
 getHttpHost()
100.00%
1 / 1
5
100.00%
5 / 5
 getHost()
100.00%
1 / 1
3
100.00%
7 / 7
 setHost($host)
100.00%
1 / 1
1
100.00%
2 / 2
 getPort()
100.00%
1 / 1
1
100.00%
1 / 1
 getAcceptedEncodings()
100.00%
1 / 1
1
100.00%
1 / 1
 getBaseUri()
100.00%
1 / 1
2
100.00%
4 / 4
 getBaseUrl()
100.00%
1 / 1
2
100.00%
4 / 4
 getPath()
100.00%
1 / 1
2
100.00%
4 / 4
 getBasePath()
100.00%
1 / 1
2
100.00%
4 / 4
 root()
100.00%
1 / 1
1
100.00%
1 / 1
 url()
100.00%
1 / 1
1
100.00%
1 / 1
 segments()
100.00%
1 / 1
2
100.00%
5 / 5
 anonymous function($val)
100.00%
1 / 1
1
100.00%
3 / 3
 segment($index, $default = null)
100.00%
1 / 1
3
100.00%
3 / 3
 isMethod($method)
100.00%
1 / 1
1
100.00%
1 / 1
 isAjax()
100.00%
1 / 1
1
100.00%
1 / 1
 isXmlHttpRequest()
100.00%
1 / 1
1
100.00%
1 / 1
 isSecure()
100.00%
1 / 1
2
100.00%
1 / 1
 getClientIp()
100.00%
1 / 1
1
100.00%
1 / 1
 getScript()
100.00%
1 / 1
1
100.00%
1 / 1
 generateBaseUri()
0.00%
0 / 1
18.25
60.87%
14 / 23
 generateBaseUrl()
0.00%
0 / 1
14.57
85.71%
24 / 28
 generateBasePath()
0.00%
0 / 1
7.91
37.50%
3 / 8
 generatePath()
0.00%
0 / 1
6.05
88.89%
8 / 9
 getPrefixUrlEncoded($str, $pre)
0.00%
0 / 1
3.14
75.00%
3 / 4
<?php namespace Modulework\Modules\Http;
/*
* (c) Christian Gärtner <christiangaertner.film@googlemail.com>
* This file is part of the Modulework Framework
* License: View distributed LICENSE file
*/
use Modulework\Modules\Http\Utilities\FileCase;
use Modulework\Modules\Http\Utilities\ArrayCase;
use Modulework\Modules\Http\Utilities\HeaderCase;
use Modulework\Modules\Http\Utilities\ServerCase;
/**
* Request
* This class represents the current HTTP request.
* It exposes 6 public vars (objects) for getting information
* For some there are methods for convience.
*/
class Request
{
/**
* The ArrayCase for the QueryString (_GET)
* @var \Modulework\Modules\Http\ArrayCase
*/
public $query;
/**
* The ArrayCase for the POST request (_POST)
* @var \Modulework\Modules\Http\ArrayCase
*/
public $request;
/**
* The ArrayCase for the server varibales (_SERVER)
* @var \Modulework\Modules\Http\ServerCase
*/
public $server;
/**
* The ArrayCase for the files attached to the request (_FILES)
* @var \Modulework\Modules\Http\FileCase
*/
public $files;
/**
* The ArrayCase for the cookies (_COOKIE)
* @var \Modulework\Modules\Http\ArrayCase
*/
public $cookies;
/**
* The ArrayCase for the HTTP headers
* @var \Modulework\Modules\Http\HeaderCase
*/
public $headers;
/**
* The URI of this request
* @var string
*/
protected $uri;
/**
* The path information of this request
* @var string
*/
protected $path;
/**
* The base URL of this request
* @var string
*/
protected $baseUrl;
/**
* The base path of this request
* @var string
*/
protected $basePath;
/**
* The HTTP verb (GET/POST/PUT/DELETE)
* @var string
*/
protected $method;
/**
* Create the Request object from PHP _ENV (or superglobals)
* @return \Modulework\Modules\Http\Request The new Request object
*/
public static function makeFromGlobals()
{
return new static($_GET, $_POST, $_COOKIE, $_FILES, $_SERVER);
}
/**
* Constructor
* @param array $query GET
* @param array $request POST
* @param array $cookies COOKIE
* @param array $files FILES
* @param array $server SERVER
*/
public function __construct(array $query = array(), array $request = array(), array $cookies = array(), array $files = array(), array $server = array())
{
$this->init($query, $request, $cookies, $files, $server);
}
/**
* Displays the Request in the following format:
* PROTOCOLL VERB >> BASEURI
* @return string [description]
*/
public function __toString()
{
return sprintf('%s %s >> %s', $this->server->get('SERVER_PROTOCOL'), $this->getMethod(), $this->getBaseUri());
}
/**
* Initialize all parameters
* @param array $query GET
* @param array $request POST
* @param array $cookies COOKIE
* @param array $files FILES
* @param array $server SERVER
*/
public function init(array $query = array(), array $request = array(), array $cookies = array(), array $files = array(), array $server = array())
{
$this->query = new ArrayCase($query);
$this->request = new ArrayCase($request);
$this->cookies = new ArrayCase($cookies);
$this->files = new FileCase($files);
$this->server = new ServerCase($server);
$this->headers = new HeaderCase($this->server->getHeaders());
// Reset propertys
$this->uri = null;
$this->path = null;
$this->baseUrl = null;
$this->basePath = null;
$this->method = null;
}
/**
* Write changes to the Request to the globals
*/
public function applyChanges()
{
$_GET = $this->query->all();
$_POST = $this->request->all();
$_SERVER = $this->server->all();
$_COOKIE = $this->cookies->all();
}
/**
* Mock an request by providing a URI only, to feed more info is still possible
* @param string $uri The URI
* @param string $method The HTTP request method
* @param array $request The _POST values
* @param array $cookies The _COOKIES
* @param array $files The _FILES
* @param array $server The _SERVER values
*
* @return \Modulework\Modules\Http\Request A new instance based on the info provided
*/
public static function mock($uri, $method = 'GET', array $request = array(), array $cookies = array(), array $files = array(), array $server = array())
{
$server = array_replace(array(
'SERVER_PROTOCOL' => 'HTTP/1.1',
'SERVER_NAME' => 'localhost',
'SERVER_PORT' => 80,
'SCRIPT_NAME' => '',
'SCRIPT_FILENAME' => '',
'HTTP_HOST' => 'localhost',
'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'HTTP_USER_AGENT' => 'Modulework/Release',
'HTTP_ACCEPT_LANGUAGE' => 'en-us,en;q=0.5',
'REQUEST_TIME' => time(),
), $server);
$server['REQUEST_METHOD'] = strtoupper($method);
$parsed = parse_url($uri);
if (isset($parsed['host'])) {
$server['SERVER_NAME'] = $parsed['host'];
$server['HTTP_HOST'] = $parsed['host'];
}
if (isset($parsed['scheme'])) {
if ($parsed['scheme'] === 'https') {
$server['SERVER_PORT'] = 443;
$server['HTTPS'] = 'on';
} else {
$server['SERVER_PORT'] = 80;
unset($server['HTTPS']);
}
}
if (isset($parsed['port'])) {
$server['SERVER_PORT'] = $parsed['port'];
$server['HTTP_HOST'] .= ':' . $parsed['port'];
}
if (!isset($parsed['path'])) {
$parsed['path'] = '/';
}
$query = array();
if (isset($parsed['query'])) {
parse_str(html_entity_decode($parsed['query']), $query);
}
$queryString = http_build_query($query, '', '&');
$server['QUERY_STRING'] = $queryString;
$server['REQUEST_URI'] = $parsed['path'] . ('' == $queryString ? '' : '?' . $queryString);
return new static($query, $request, $cookies, $files, $server);
}
/**
* Normalize a query string
* @param string $query Query String
* @return string The normalized version of $query
*/
public static function normalizeQuery($query)
{
if ('' == $query) {
return '';
}
$parts = array();
$sort = array();
$split = explode('&', $query);
foreach ($split as $value) {
if ('' == $value || '=' === $value[0]) continue;
$pair = explode('=', $value, 2);
if (isset($pair[1])) {
$parts[] = rawurlencode(urldecode($pair[0])) . '=' . rawurlencode(urldecode($pair[1]));
} else {
$parts[] = rawurlencode(urldecode($pair[0]));
}
$sort[] = urldecode($pair[0]);
}
array_multisort($sort, SORT_ASC, $parts);
return implode('&', $parts);
}
/**
* Returns the request method
* @return string The request method
*/
public function getMethod()
{
if ($this->method === null) {
$this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
}
return $this->method;
}
/**
* Mock the request method
* @param string $method The request method
*/
public function setMethod($method)
{
$this->$method = null; //Reset, so it' s getting regenerated properly.
$this->server->set('REQUEST_METHOD', strtoupper($method), true);
}
/**
* Returns either http or https
* calls isSecure()
* @return string The scheme (http | https)
*/
public function getScheme()
{
return $this->isSecure() ? 'https' : 'http';
}
/**
* Returns the HTTP Host (with port if not default)
*
* For example:
* localhost
* or
* localhost:4000
*
* @return string The host
*/
public function getHttpHost()
{
$port = $this->getPort();
$scheme = $this->getScheme();
if (('https' == $scheme && $port == 443) || ('http' == $scheme && $port == 80)) {
// if standard ports then don' t add em
return $this->getHost();
}
return $this->getHost() . ':' . $port;
}
/**
* Returns the host of the server
* @return string The host of this server
*/
public function getHost()
{
if (!$host = $this->headers->get('HOST')) {
if (!$host = $this->server->get('SERVER_ADDR')) {
$host = $this->server->get('SERVER_NAME', '');
}
}
$host = strtolower(preg_replace('/:\d+$/', '', trim($host)));
return $host;
}
/**
* Set the host in the header
* @param string $host The new host
*/
public function setHost($host)
{
$this->headers->set('HOST', $host, true);
}
/**
* Port for the Request
* @return string the port
*/
public function getPort()
{
return $this->server->get('SERVER_PORT');
}
/**
* Retrieve the accepted encoding types from the HTTP headers
* @return array The accepted encodings
*/
public function getAcceptedEncodings()
{
return explode(',', $this->headers->get('ACCEPT_ENCODING'));
}
/**
* Get the BaseUri
* Calls once: generateBaseUri()
* @return string The base uri for the request
*/
public function getBaseUri()
{
if ($this->uri === null) {
$this->uri = $this->generateBaseUri();
}
return $this->uri;
}
/**
* The base URL
* @return string The base URL
*/
public function getBaseUrl()
{
if ($this->baseUrl === null) {
$this->baseUrl = $this->generateBaseUrl();
}
return $this->baseUrl;
}
/**
* Returns the path.
* Examples (this class was initalized at /dev on localhost):
*
* * http://localhost/dev -> ''
* * http://localhost/dev/more -> '/more'
* * http://localhost/dev/more?foo -> '/more'
* @return string The path
*/
public function getPath()
{
if ($this->path === null) {
$this->path = $this->generatePath();
}
return $this->path;
}
/**
* Returns the base path from the root,
* for example if this class was constructed in the subfolder
* 'foo' this method would return 'foo' for this uri:
* http://localhost/foo/index.php
* @return string The raw path
*/
public function getBasePath()
{
if ($this->basePath === null) {
$this->basePath = $this->generateBasePath();
}
return $this->basePath;
}
/**
* Returns the root URL
* @return string The root URL
*/
public function root()
{
return rtrim($this->getScheme() . '://' . $this->getHost() . $this->getPath(), '/');
}
/**
* Returns the URL (without query string)
* @return string The URL
*/
public function url()
{
return rtrim(preg_replace('/\?.*/', '', $this->getBaseUri()), '/');
}
/**
* Returns all URI segments
* (or empty array if path = '/')
* @return array The URI segments
*/
public function segments()
{
$path = $this->getPath();
$array = $path == '/' ? array() : explode('/', $path);
return array_filter($array, function($val) {
return $val != '';
});
}
/**
* Get a URI segment
* 1 based index
* @param int $index The index
* @param mixed $default If the segement does not exists this will get returned
* @return mixed The URI segment | $default
*/
public function segment($index, $default = null)
{
if ('/' === $path = $this->getPath()) {
return '/';
}
$segments = explode('/', rtrim($path, '/'));
$segments = array_filter($segments, function($val) {
return $val != '';
});
return (isset($segments[$index])) ? $segments[$index] : $default;
}
/**
* Check if the request method equals the given
* @param string $method The method to test
* @return boolean TRUE if match
*/
public function isMethod($method)
{
return ($this->getMethod() === strtoupper($method));
}
/**
* Wrapper for isXmlHttpRequest
* @return boolean TRUE if it is a XMLHttpRequest
*/
public function isAjax()
{
return $this->isXmlHttpRequest();
}
/**
* Is the request of type XMLHttpRequest
* @return boolean TRUE if it is a XMLHttpRequest
*/
public function isXmlHttpRequest()
{
return ('XMLHttpRequest' == $this->headers->get('X-Requested-With'));
}
/**
* Check for HTTPS connection
* @return boolean TRUE if it is a HTTPS connection
*/
public function isSecure()
{
return (1 == $this->server->get('HTTPS') || strtolower($this->server->get('HTTPS') == 'on'));
}
/**
* Returns the client' s IP address
* @return string The IP
*/
public function getClientIp()
{
return $this->server->get('REMOTE_ADDR');
}
/**
* Returns the current script name
* @return string The script name
*/
public function getScript()
{
return $this->server->get('SCRIPT_NAME');
}
/**
* Generate the BaseUri
* @return string The base uri
*/
protected function generateBaseUri()
{
$uri = '';
/*
* The first check is obvious, all these headers after REQUEST_URI are taken from the Zend Framework,
* they are for IIS and the like setups.
*/
if ($this->server->has('REQUEST_URI')) {
$uri = $this->server->get('REQUEST_URI');
// this will be with scheme and host maybe....
// We' ll need to cut these out
$schemeHost = $this->getScheme() . '://' . $this->getHttpHost();
if (strpos($uri, $schemeHost) === 0) {
$uri = substr($uri, strlen($schemeHost));
}
} elseif ($this->server->has('ORIG_PATH_INFO')) {
$uri = $this->server->get('ORIG_PATH_INFO');
if ('' == $this->server->get('QUERY_STRING')) {
$uri .= '?' . $this->server->get('QUERY_STRING');
}
} elseif ($this->headers->has('X_ORIGINAL_URL')) {
$uri = $this->headers->get('X_ORIGINAL_URL');
} elseif ($this->headers->has('X_REWRITE_URL')) {
$this->headers->has('X_REWRITE_URL');
} elseif ($this->server->has('IIS_WasUrlRewritten') == '1' && ('' !== $this->server->get('UNENCODED_URL'))) {
$uri = $this->server->get('UNENCODED_URL');
} elseif ($this->server->has('IIS_WasUrlRewritten') == '1' && ('' !== $this->server->get('UNENCODED_URL'))) {
$uri = $this->server->get('UNENCODED_URL');
}
$this->server->set('REQUEST_URI', $uri);
return $uri;
}
/**
* Generate the BaseUrl
* @return string The base url
*/
protected function generateBaseUrl()
{
$filename = basename($this->server->get('SCRIPT_FILENAME'));
if (basename($this->server->get('SCRIPT_NAME')) === $filename) {
$baseUrl = $this->server->get('SCRIPT_NAME');
} elseif (basename($this->server->get('PHP_SELF')) === $filename) {
$baseUrl = $this->server->get('PHP_SELF');
} elseif (basename($this->server->get('ORIG_SCRIPT_NAME')) === $filename) {
$baseUrl = $this->server->get('ORIG_SCRIPT_NAME');
} else {
$path = $this->server->get('PHP_SELF', '');
$file = $this->server->get('SCRIPT_FILENAME', '');
$parts = array_reverse(explode('/', trim($file, '/')));
$i = 0;
$prev = count($parts);
$baseUrl = '';
do {
$part = $parts[$i];
$baseUrl = '/' . $part . $baseUrl;
$i++;
} while (($prev > $i) && (($pos = strpos($path, $baseUrl)) !== false) && (0 !== $pos));
}
$uri = $this->getBaseUri();
if ($baseUrl && false !== $pre = self::getPrefixUrlEncoded($uri, $baseUrl)) return $pre;
if ($baseUrl && false !== $pre = self::getPrefixUrlEncoded($uri, dirname($baseUrl))) return rtrim($prefix, '/');
if (($pos = strpos($uri, '?')) !== false) {
$queryLessUri = substr($uri, 0, $pos);
} else {
$queryLessUri = $uri;
}
$base = basename($baseUrl);
if (empty($base) || !strpos(rawurldecode($queryLessUri), $base)) return '';
return rtrim($baseUrl, '/');
}
protected function generateBasePath()
{
$filename = basename($this->server->get('SCRIPT_FILENAME'));
$baseUrl = $this->getBaseUrl();
if (empty($baseUrl)) return '';
$basePath = (basename($baseUrl) === $filename) ? dirname($baseUrl) : $baseUrl;
if ('\\' === DIRECTORY_SEPARATOR) { // We are on Windows
$basePath = str_replace('\\', '/', $basePath);
}
return rtrim($basePath, '/');
}
protected function generatePath()
{
$baseUrl = $this->getBaseUrl();
if (($baseUri = $this->getBaseUri()) === null) return '/';
$path = '/';
if ($pos = strpos($baseUri, '?')) $baseUri = substr($baseUri, 0, $pos);
if ((null !== $baseUrl) && (false === ($path = substr($baseUri, strlen($baseUrl))))) {
return '/';
} elseif ($baseUrl === null) {
return $baseUri;
}
return $path;
}
/**
* Returns the string prefix if it' s the string' s prefix (URL Encoded)
* false otherwise
* @param string $str The urlencoded string
* @param string $pre The NOT encoeded prefix
* @return string|false The prefix as it is encoded in $str or false
*/
protected static function getPrefixUrlEncoded($str, $pre)
{
if (strpos(rawurldecode($str), $pre) !== 0) return false;
$length = strlen($pre);
/*
NOTE! THIS REGEX is COPIED from the ZEND Framework (BSD License)
*/
if (preg_match("#^(%[[:xdigit:]]{2}|.){{$length}}#", $str, $match)) return $match[0];
return false;
}