239 lines
6.2 KiB
PHP
239 lines
6.2 KiB
PHP
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
|
/**
|
|
* Request helper class.
|
|
*
|
|
* $Id: request.php 4355 2009-05-15 17:18:28Z kiall $
|
|
*
|
|
* @package Core
|
|
* @author Kohana Team
|
|
* @copyright (c) 2007-2008 Kohana Team
|
|
* @license http://kohanaphp.com/license.html
|
|
*/
|
|
class request_Core {
|
|
|
|
// Possible HTTP methods
|
|
protected static $http_methods = array('get', 'head', 'options', 'post', 'put', 'delete');
|
|
|
|
// Content types from client's HTTP Accept request header (array)
|
|
protected static $accept_types;
|
|
|
|
/**
|
|
* Returns the HTTP referrer, or the default if the referrer is not set.
|
|
*
|
|
* @param mixed default to return
|
|
* @return string
|
|
*/
|
|
public static function referrer($default = FALSE)
|
|
{
|
|
if ( ! empty($_SERVER['HTTP_REFERER']))
|
|
{
|
|
// Set referrer
|
|
$ref = $_SERVER['HTTP_REFERER'];
|
|
|
|
if (strpos($ref, url::base(FALSE)) === 0)
|
|
{
|
|
// Remove the base URL from the referrer
|
|
$ref = substr($ref, strlen(url::base(FALSE)));
|
|
}
|
|
}
|
|
|
|
return isset($ref) ? $ref : $default;
|
|
}
|
|
|
|
/**
|
|
* Returns the current request protocol, based on $_SERVER['https']. In CLI
|
|
* mode, NULL will be returned.
|
|
*
|
|
* @return string
|
|
*/
|
|
public static function protocol()
|
|
{
|
|
if (PHP_SAPI === 'cli')
|
|
{
|
|
return NULL;
|
|
}
|
|
elseif ( ! empty($_SERVER['HTTPS']) AND $_SERVER['HTTPS'] === 'on')
|
|
{
|
|
return 'https';
|
|
}
|
|
else
|
|
{
|
|
return 'http';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Tests if the current request is an AJAX request by checking the X-Requested-With HTTP
|
|
* request header that most popular JS frameworks now set for AJAX calls.
|
|
*
|
|
* @return boolean
|
|
*/
|
|
public static function is_ajax()
|
|
{
|
|
return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
|
|
}
|
|
|
|
/**
|
|
* Returns current request method.
|
|
*
|
|
* @throws Kohana_Exception in case of an unknown request method
|
|
* @return string
|
|
*/
|
|
public static function method()
|
|
{
|
|
$method = strtolower($_SERVER['REQUEST_METHOD']);
|
|
|
|
if ( ! in_array($method, request::$http_methods))
|
|
throw new Kohana_Exception('request.unknown_method', $method);
|
|
|
|
return $method;
|
|
}
|
|
|
|
/**
|
|
* Returns boolean of whether client accepts content type.
|
|
*
|
|
* @param string content type
|
|
* @param boolean set to TRUE to disable wildcard checking
|
|
* @return boolean
|
|
*/
|
|
public static function accepts($type = NULL, $explicit_check = FALSE)
|
|
{
|
|
request::parse_accept_header();
|
|
|
|
if ($type === NULL)
|
|
return request::$accept_types;
|
|
|
|
return (request::accepts_at_quality($type, $explicit_check) > 0);
|
|
}
|
|
|
|
/**
|
|
* Compare the q values for given array of content types and return the one with the highest value.
|
|
* If items are found to have the same q value, the first one encountered in the given array wins.
|
|
* If all items in the given array have a q value of 0, FALSE is returned.
|
|
*
|
|
* @param array content types
|
|
* @param boolean set to TRUE to disable wildcard checking
|
|
* @return mixed string mime type with highest q value, FALSE if none of the given types are accepted
|
|
*/
|
|
public static function preferred_accept($types, $explicit_check = FALSE)
|
|
{
|
|
// Initialize
|
|
$mime_types = array();
|
|
$max_q = 0;
|
|
$preferred = FALSE;
|
|
|
|
// Load q values for all given content types
|
|
foreach (array_unique($types) as $type)
|
|
{
|
|
$mime_types[$type] = request::accepts_at_quality($type, $explicit_check);
|
|
}
|
|
|
|
// Look for the highest q value
|
|
foreach ($mime_types as $type => $q)
|
|
{
|
|
if ($q > $max_q)
|
|
{
|
|
$max_q = $q;
|
|
$preferred = $type;
|
|
}
|
|
}
|
|
|
|
return $preferred;
|
|
}
|
|
|
|
/**
|
|
* Returns quality factor at which the client accepts content type.
|
|
*
|
|
* @param string content type (e.g. "image/jpg", "jpg")
|
|
* @param boolean set to TRUE to disable wildcard checking
|
|
* @return integer|float
|
|
*/
|
|
public static function accepts_at_quality($type = NULL, $explicit_check = FALSE)
|
|
{
|
|
request::parse_accept_header();
|
|
|
|
// Normalize type
|
|
$type = strtolower((string) $type);
|
|
|
|
// General content type (e.g. "jpg")
|
|
if (strpos($type, '/') === FALSE)
|
|
{
|
|
// Don't accept anything by default
|
|
$q = 0;
|
|
|
|
// Look up relevant mime types
|
|
foreach ((array) Kohana::config('mimes.'.$type) as $type)
|
|
{
|
|
$q2 = request::accepts_at_quality($type, $explicit_check);
|
|
$q = ($q2 > $q) ? $q2 : $q;
|
|
}
|
|
|
|
return $q;
|
|
}
|
|
|
|
// Content type with subtype given (e.g. "image/jpg")
|
|
$type = explode('/', $type, 2);
|
|
|
|
// Exact match
|
|
if (isset(request::$accept_types[$type[0]][$type[1]]))
|
|
return request::$accept_types[$type[0]][$type[1]];
|
|
|
|
// Wildcard match (if not checking explicitly)
|
|
if ($explicit_check === FALSE AND isset(request::$accept_types[$type[0]]['*']))
|
|
return request::$accept_types[$type[0]]['*'];
|
|
|
|
// Catch-all wildcard match (if not checking explicitly)
|
|
if ($explicit_check === FALSE AND isset(request::$accept_types['*']['*']))
|
|
return request::$accept_types['*']['*'];
|
|
|
|
// Content type not accepted
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Parses client's HTTP Accept request header, and builds array structure representing it.
|
|
*
|
|
* @return void
|
|
*/
|
|
protected static function parse_accept_header()
|
|
{
|
|
// Run this function just once
|
|
if (request::$accept_types !== NULL)
|
|
return;
|
|
|
|
// Initialize accept_types array
|
|
request::$accept_types = array();
|
|
|
|
// No HTTP Accept header found
|
|
if (empty($_SERVER['HTTP_ACCEPT']))
|
|
{
|
|
// Accept everything
|
|
request::$accept_types['*']['*'] = 1;
|
|
return;
|
|
}
|
|
|
|
// Remove linebreaks and parse the HTTP Accept header
|
|
foreach (explode(',', str_replace(array("\r", "\n"), '', $_SERVER['HTTP_ACCEPT'])) as $accept_entry)
|
|
{
|
|
// Explode each entry in content type and possible quality factor
|
|
$accept_entry = explode(';', trim($accept_entry), 2);
|
|
|
|
// Explode each content type (e.g. "text/html")
|
|
$type = explode('/', $accept_entry[0], 2);
|
|
|
|
// Skip invalid content types
|
|
if ( ! isset($type[1]))
|
|
continue;
|
|
|
|
// Assume a default quality factor of 1 if no custom q value found
|
|
$q = (isset($accept_entry[1]) AND preg_match('~\bq\s*+=\s*+([.0-9]+)~', $accept_entry[1], $match)) ? (float) $match[1] : 1;
|
|
|
|
// Populate accept_types array
|
|
if ( ! isset(request::$accept_types[$type[0]][$type[1]]) OR $q > request::$accept_types[$type[0]][$type[1]])
|
|
{
|
|
request::$accept_types[$type[0]][$type[1]] = $q;
|
|
}
|
|
}
|
|
}
|
|
|
|
} // End request
|