* @author Dennis Eichhorn * @copyright 2013 Dennis Eichhorn * @license OMS License 1.0 * @version 1.0.0 * @link http://orange-management.com */ namespace phpOMS\Message\Http; use phpOMS\Localization\Localization; use phpOMS\Message\RequestAbstract; use phpOMS\Message\RequestMethod; use phpOMS\Uri\Http; use phpOMS\Uri\UriFactory; /** * Request class. * * @category Framework * @package phpOMS\Request * @author OMS Development Team * @author Dennis Eichhorn * @license OMS License 1.0 * @link http://orange-management.com * @since 1.0.0 */ class Request extends RequestAbstract { /** * Browser type. * * @var BrowserType * @since 1.0.0 */ private $browser = null; /** * OS type. * * @var OSType * @since 1.0.0 */ private $os = null; /** * Path. * * @var array * @since 1.0.0 */ protected $path = null; /** * Uploaded files. * * @var array * @since 1.0.0 */ protected $files = []; /** * Request information. * * @var \string[] * @since 1.0.0 */ private $info = null; /** * Constructor. * * @param \string $rootPath relative installation path * * @since 1.0.0 * @author Dennis Eichhorn */ public function __construct(\string $rootPath) { $this->uri = new Http($rootPath); $this->l11n = new Localization(); UriFactory::setQuery('/root', $rootPath); } /** * Init request. * * This is used in order to either initialize the current http request or a batch of GET requests * * @param \string $uri URL * * @return void * * @throws * * @since 1.0.0 * @author Dennis Eichhorn */ public function init(\string $uri = null) { if ($uri === null) { $this->data = $_GET ?? []; if (isset($_SERVER['CONTENT_TYPE'])) { if (strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== false) { if (($json = json_decode(($input = file_get_contents('php://input')), true)) === false || $json === null) { throw new \Exception('Is not valid json ' . $input); } $this->data += $json; } elseif (strpos($_SERVER['CONTENT_TYPE'], 'application/x-www-form-urlencoded') !== false) { parse_str(file_get_contents('php://input'), $temp); $this->data += $temp; } elseif (strpos($_SERVER['CONTENT_TYPE'], 'multipart/form-data') !== false) { $this->files = $_FILES; } } $this->uri->set(Http::getCurrent()); } else { $this->setMethod($uri['type']); // TODO: is this correct? $this->uri->set($uri['uri']); } unset($_FILES); unset($_GET); unset($_POST); unset($_PUT); unset($_HEAD); $this->path = explode('/', $this->uri->getPath()); $this->l11n->setLanguage($this->path[0]); $this->hash = []; UriFactory::setQuery('/scheme', $this->uri->getScheme()); UriFactory::setQuery('/host', $this->uri->getHost()); UriFactory::setQuery('/lang', $this->l11n->getLanguage()); foreach ($this->path as $key => $path) { $paths = []; for ($i = 1; $i < $key + 1; $i++) { $paths[] = $this->path[$i]; } $this->hash[] = $this->hashRequest($paths); } } /** * Is Mobile * * @return bool * * @since 1.0.0 * @author Dennis Eichhorn */ public function isMobile() : \bool { // TODO: maybe replace this with smart media queries... checked gets handled in reverse!!! $useragent = $_SERVER['HTTP_USER_AGENT']; if (preg_match('/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i', $useragent) || preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i', $useragent)) { return true; } return false; } /** * Set request type. * * @param RequestMethod $type Request type * * @return void * * @since 1.0.0 * @author Dennis Eichhorn */ public function setMethod(RequestMethod $type) { $this->type = $type; } /** * Generate request hash. * * @param array $request Request array * * @return \string * * @since 1.0.0 * @author Dennis Eichhorn */ private function hashRequest(array $request) : \string { return sha1(implode('', $request)); } /** * {@inheritdoc} */ public function getRequestInfo() : array { if (!isset($this->info)) { $this->info['browser'] = $this->getBrowser(); $this->info['os'] = $this->getOS(); } return $this->info; } /** * Determine request browser. * * @return BrowserType * * @since 1.0.0 * @author Dennis Eichhorn */ public function getBrowser() : BrowserType { if (!isset($this->browser)) { $arr = BrowserType::getConstants(); $http_request_type = strtolower($_SERVER['HTTP_USER_AGENT']); foreach ($arr as $key => $val) { if (stripos($http_request_type, $val)) { $this->browser = $val; break; } } } return $this->browser; } /** * Determine request OS. * * @return OSType * * @since 1.0.0 * @author Dennis Eichhorn */ public function getOS() : OSType { if (!isset($this->os)) { $arr = OSType::getConstants(); $http_request_type = strtolower($_SERVER['HTTP_USER_AGENT']); foreach ($arr as $key => $val) { if (stripos($http_request_type, $val)) { $this->os = $val; break; } } } return $this->os; } /** * Get request hashes. * * @return array Request hashes * * @since 1.0.0 * @author Dennis Eichhorn */ public function getHash() : array { return $this->hash; } /** * {@inheritdoc} */ public function getOrigin() : \string { return $_SERVER['REMOTE_ADDR']; } /** * Is request made via https. * * @param \int $port Secure port * * @return \bool * * @since 1.0.0 * @author Dennis Eichhorn */ public function isHttps(\int $port = 443) : \bool { if ($port < 1 || $port > 65535) { throw new \OutOfRangeException('Value "' . $port . '" is out of range.'); } return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') || (!empty($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on') || $_SERVER['SERVER_PORT'] == $port; } /** * Stringify request. * * @return \string * * @since 1.0.0 * @author Dennis Eichhorn */ public function __toString() { $lastElement = end($this->hash); reset($this->hash); return $lastElement; } /** * Get request type. * * @return \string * * @since 1.0.0 * @author Dennis Eichhorn */ public function getMethod() : \string { if (!isset($this->type)) { $this->type = $_SERVER['REQUEST_METHOD']; } return $this->type; } /** * {@inheritdoc} */ public function getProtocolVersion() : \string { return $_SERVER['SERVER_PROTOCOL']; } /** * {@inheritdoc} */ public function getHeaders() : array { return getallheaders(); } /** * {@inheritdoc} */ public function hasHeader(\string $name) : \bool { return array_key_exists($name, getallheaders()); } /** * {@inheritdoc} */ public function getHeader(\string $name) : \string { return getallheaders()[$name]; } /** * {@inheritdoc} */ public function getBody() : \string { return file_get_contents('php://input'); } /** * {@inheritdoc} */ public function getRequestTarget() : \string { return '/'; } /** * Get files passed in request. * * @return array * * @since 1.0.0 * @author Dennis Eichhorn */ public function getFiles() : array { return $this->files; } public function setHeader($key, \string $header, \bool $overwrite = true) { // NOT Required for Http request } /** * Get request route. * * @return string * * @since 1.0.0 * @author Dennis Eichhorn */ public function getRoutify() : \string { return $this->uri->__toString(); } }