Created
April 22, 2011 01:38
-
-
Save eberfreitas/935858 to your computer and use it in GitHub Desktop.
Proposal for a new Request Object for the Alloy Framework
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Alloy; | |
class Request { | |
protected $schema = 'http'; | |
protected $host = 'localhost'; | |
protected $port = 80; | |
protected $method = 'GET'; | |
protected $webroot = '/'; | |
protected $path = '/'; | |
protected $uri = '/'; | |
protected $referrer; | |
protected $query = array(); | |
protected $body = array(); | |
protected $headers = array(); | |
protected $ip; | |
// Not complete but these are the most common methods I guess? | |
protected $_methods = array('HEAD', 'GET', 'POST', 'PUT', 'DELETE'); | |
protected $_isHttp = false; | |
protected $_isCli = false; | |
public function __construct() { | |
// We are dealing with a http request | |
if (isset($_SERVER['HTTP_HOST'])) { | |
$this->_isHttp = true; | |
// Defining the schema to https if this is a secure connection | |
if (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) === 'on') { | |
$this->schema = 'https'; | |
} | |
$this->host = $_SERVER['SERVER_NAME']; // Or should we use 'HTTP_HOST'? | |
$this->port = $_SERVER['SERVER_PORT']; | |
$this->method = $_SERVER['REQUEST_METHOD']; | |
// Emulating REST for browsers | |
if (!empty($_POST['_method']) && in_array($_POST['_method'], $this->_methods)) { | |
$this->method = strtoupper($_POST['_method']); | |
} | |
$this->webroot = $this->_getWebroot(); | |
if (!empty($_GET['url'])) { | |
$this->path = '/' . trim($_GET['url'], '/'); | |
unset($_GET['url']); | |
} | |
$this->uri = $_SERVER['REQUEST_URI']; | |
if (!empty($_SERVER['HTTP_REFERER'])) { | |
$this->referrer = $_SERVER['HTTP_REFERER']; | |
} | |
$this->query = $_GET; | |
$files = isset($_FILES) ? $_FILES : array(); | |
$this->body = array_merge($_POST, $files); | |
$this->headers = $this->_formatHeaders(); | |
$this->ip = $this->_getIp(); | |
} else { | |
// Here we are dealing with a cli request | |
$this->_isCli = true; | |
$this->schema = 'cli'; | |
$args = getopt('u:'); | |
if (!empty($args['u'])) { | |
$this->uri = $args['u']; | |
$query = parse_url($args['u'], PHP_URL_QUERY); | |
// If there are query parameters, let's take care of those... | |
if ($query) { | |
$this->path = str_replace('?' . $query, '', $args['u']); | |
parse_str($query, $this->query); | |
} else { | |
$this->path = $args['u']; | |
} | |
} | |
} | |
} | |
public function __get($attr) { | |
// Here we expose protected attributes from the objetc but not the ones | |
// preceded with ´_´ | |
if (strpos($attr, '_') !== 0 && isset($this->{$attr})) { | |
return $this->{$attr}; | |
} | |
return null; | |
} | |
public function isPost() { | |
return $this->method === 'POST'; | |
} | |
public function isGet() { | |
return $this->method === 'GET'; | |
} | |
public function isPut() { | |
return $this->method === 'PUT'; | |
} | |
public function isDelete() { | |
return $this->method === 'DELETE'; | |
} | |
public function isHead() { | |
return $this->method === 'HEAD'; | |
} | |
public function isSecure() { | |
return $this->scheme === 'https'; | |
} | |
public function isAjax() { | |
if (!empty($this->headers['X-Requested-With']) | |
&& strtolower($this->headers['X-Requested-With']) === 'xmlhttprequest') { | |
return true; | |
} | |
return false; | |
} | |
public function isMobile() { | |
if ($this->_isCli) { | |
return false; | |
} | |
$op = !empty($this->headers['X-Operamini-Phone']) | |
? strtolower($this->headers['X-Operamini-Phone']) | |
: ''; | |
$ua = strtolower($this->headers['User-Agent']); | |
$ac = strtolower($this->headers['Accept']); | |
return ( | |
false !== strpos($ac, 'application/vnd.wap.xhtml+xml') || | |
false !== strpos($ac, 'text/vnd.wap.wml') || | |
$op !== '' || | |
false !== strpos($ua, 'iphone') || | |
false !== strpos($ua, 'android') || | |
false !== strpos($ua, 'iemobile') || | |
false !== strpos($ua, 'kindle') || | |
false !== strpos($ua, 'sony') || | |
false !== strpos($ua, 'symbian') || | |
false !== strpos($ua, 'nokia') || | |
false !== strpos($ua, 'samsung') || | |
false !== strpos($ua, 'mobile') || | |
false !== strpos($ua, 'windows ce') || | |
false !== strpos($ua, 'epoc') || | |
false !== strpos($ua, 'opera mini') || | |
false !== strpos($ua, 'nitro') || | |
false !== strpos($ua, 'j2me') || | |
false !== strpos($ua, 'midp-') || | |
false !== strpos($ua, 'cldc-') || | |
false !== strpos($ua, 'netfront') || | |
false !== strpos($ua, 'mot') || | |
false !== strpos($ua, 'up.browser') || | |
false !== strpos($ua, 'up.link') || | |
false !== strpos($ua, 'audiovox') || | |
false !== strpos($ua, 'blackberry') || | |
false !== strpos($ua, 'ericsson,') || | |
false !== strpos($ua, 'panasonic') || | |
false !== strpos($ua, 'philips') || | |
false !== strpos($ua, 'sanyo') || | |
false !== strpos($ua, 'sharp') || | |
false !== strpos($ua, 'sie-') || | |
false !== strpos($ua, 'portalmmm') || | |
false !== strpos($ua, 'blazer') || | |
false !== strpos($ua, 'avantgo') || | |
false !== strpos($ua, 'danger') || | |
false !== strpos($ua, 'palm') || | |
false !== strpos($ua, 'series60') || | |
false !== strpos($ua, 'palmsource') || | |
false !== strpos($ua, 'pocketpc') || | |
false !== strpos($ua, 'smartphone') || | |
false !== strpos($ua, 'rover') || | |
false !== strpos($ua, 'ipaq') || | |
false !== strpos($ua, 'au-mic,') || | |
false !== strpos($ua, 'alcatel') || | |
false !== strpos($ua, 'ericy') || | |
false !== strpos($ua, 'up.link') || | |
false !== strpos($ua, 'vodafone/') || | |
false !== strpos($ua, 'wap1.') || | |
false !== strpos($ua, 'wap2.') | |
); | |
} | |
public function isBot() { | |
if ($this->_isCli) { | |
return false; | |
} | |
$ua = strtolower($this->headers['User-Agent']); | |
return ( | |
false !== strpos($ua, 'googlebot') || | |
false !== strpos($ua, 'msnbot') || | |
false !== strpos($ua, 'yahoo!') || | |
false !== strpos($ua, 'slurp') || | |
false !== strpos($ua, 'bot') || | |
false !== strpos($ua, 'spider') | |
); | |
} | |
public function isCli() { | |
return $this->_isCli; | |
} | |
public function isFlash() { | |
return ($this->header['User-Agent'] === 'Shockwave Flash'); | |
} | |
protected function _getWebroot() { | |
// Doing some calcs to get the webroot path relative to the host | |
$ru = explode('/', $_SERVER['REQUEST_URI']); | |
$sn = explode('/', $_SERVER['SCRIPT_NAME']); | |
$intersection = array_intersect($ru, $sn); | |
if ($intersection) { | |
return '/' . trim(str_replace('/index.php', '', implode('/', $intersection)), '/'); | |
} | |
return '/'; | |
} | |
protected function _formatHeaders() { | |
$headers = array(); | |
// If apache_request_headers is available, just use those | |
if (function_exists('apache_request_headers')) { | |
$headers = apache_request_headers(); | |
} else { | |
// Otherwise, we loop the $_SERVER variable to find out headers | |
// and try to format them the right way | |
foreach ($_SERVER as $key => $value) { | |
if (strpos($key, 'HTTP_') === 0) { | |
$key = strtolower(str_replace('HTTP_', '', $key)); | |
$key = str_replace('_', ' ', $key); | |
$key = ucwords($key); | |
$key = str_replace(' ', '-', $key); | |
$key = $key === 'Content-Md5' ? 'Content-MD5' : $key; | |
$headers[$key] = $value; | |
} | |
} | |
} | |
return $headers; | |
} | |
protected function _getIp() { | |
$ip = false; | |
if (!empty($_SERVER["HTTP_CLIENT_IP"])) { | |
$ip = $_SERVER["HTTP_CLIENT_IP"]; | |
} | |
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { | |
$ips = explode(', ', $_SERVER['HTTP_X_FORWARDED_FOR']); | |
if ($ip) { | |
array_unshift($ips, $ip); | |
$ip = false; | |
} | |
for ($i = 0; $i < count($ips); $i++) { | |
if (!eregi("^(10|172\.16|192\.168)\.", $ips[$i])) { | |
$ip = $ips[$i]; | |
break; | |
} | |
} | |
} | |
return $ip ? $ip : $_SERVER['REMOTE_ADDR']; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment