PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/system/helpers/request.php

http://github.com/ushahidi/Ushahidi_Web
PHP | 239 lines | 115 code | 36 blank | 88 comment | 14 complexity | 51efa889c191516daad35e775d1d83c1 MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php defined('SYSPATH') OR die('No direct access allowed.');
  2. /**
  3. * Request helper class.
  4. *
  5. * $Id: request.php 3917 2009-01-21 03:06:22Z zombor $
  6. *
  7. * @package Core
  8. * @author Kohana Team
  9. * @copyright (c) 2007-2008 Kohana Team
  10. * @license http://kohanaphp.com/license.html
  11. */
  12. class request_Core {
  13. // Possible HTTP methods
  14. protected static $http_methods = array('get', 'head', 'options', 'post', 'put', 'delete');
  15. // Content types from client's HTTP Accept request header (array)
  16. protected static $accept_types;
  17. /**
  18. * Returns the HTTP referrer, or the default if the referrer is not set.
  19. *
  20. * @param mixed default to return
  21. * @return string
  22. */
  23. public static function referrer($default = FALSE)
  24. {
  25. if ( ! empty($_SERVER['HTTP_REFERER']))
  26. {
  27. // Set referrer
  28. $ref = $_SERVER['HTTP_REFERER'];
  29. if (strpos($ref, url::base(FALSE)) === 0)
  30. {
  31. // Remove the base URL from the referrer
  32. $ref = substr($ref, strlen(url::base(TRUE)));
  33. }
  34. }
  35. return isset($ref) ? $ref : $default;
  36. }
  37. /**
  38. * Returns the current request protocol, based on $_SERVER['https']. In CLI
  39. * mode, NULL will be returned.
  40. *
  41. * @return string
  42. */
  43. public static function protocol()
  44. {
  45. if (PHP_SAPI === 'cli')
  46. {
  47. return NULL;
  48. }
  49. elseif ( ! empty($_SERVER['HTTPS']) AND $_SERVER['HTTPS'] === 'on')
  50. {
  51. return 'https';
  52. }
  53. else
  54. {
  55. return 'http';
  56. }
  57. }
  58. /**
  59. * Tests if the current request is an AJAX request by checking the X-Requested-With HTTP
  60. * request header that most popular JS frameworks now set for AJAX calls.
  61. *
  62. * @return boolean
  63. */
  64. public static function is_ajax()
  65. {
  66. return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
  67. }
  68. /**
  69. * Returns current request method.
  70. *
  71. * @throws Kohana_Exception in case of an unknown request method
  72. * @return string
  73. */
  74. public static function method()
  75. {
  76. $method = strtolower($_SERVER['REQUEST_METHOD']);
  77. if ( ! in_array($method, self::$http_methods))
  78. throw new Kohana_Exception('request.unknown_method', $method);
  79. return $method;
  80. }
  81. /**
  82. * Returns boolean of whether client accepts content type.
  83. *
  84. * @param string content type
  85. * @param boolean set to TRUE to disable wildcard checking
  86. * @return boolean
  87. */
  88. public static function accepts($type = NULL, $explicit_check = FALSE)
  89. {
  90. request::parse_accept_header();
  91. if ($type === NULL)
  92. return self::$accept_types;
  93. return (request::accepts_at_quality($type, $explicit_check) > 0);
  94. }
  95. /**
  96. * Compare the q values for given array of content types and return the one with the highest value.
  97. * If items are found to have the same q value, the first one encountered in the given array wins.
  98. * If all items in the given array have a q value of 0, FALSE is returned.
  99. *
  100. * @param array content types
  101. * @param boolean set to TRUE to disable wildcard checking
  102. * @return mixed string mime type with highest q value, FALSE if none of the given types are accepted
  103. */
  104. public static function preferred_accept($types, $explicit_check = FALSE)
  105. {
  106. // Initialize
  107. $mime_types = array();
  108. $max_q = 0;
  109. $preferred = FALSE;
  110. // Load q values for all given content types
  111. foreach (array_unique($types) as $type)
  112. {
  113. $mime_types[$type] = request::accepts_at_quality($type, $explicit_check);
  114. }
  115. // Look for the highest q value
  116. foreach ($mime_types as $type => $q)
  117. {
  118. if ($q > $max_q)
  119. {
  120. $max_q = $q;
  121. $preferred = $type;
  122. }
  123. }
  124. return $preferred;
  125. }
  126. /**
  127. * Returns quality factor at which the client accepts content type.
  128. *
  129. * @param string content type (e.g. "image/jpg", "jpg")
  130. * @param boolean set to TRUE to disable wildcard checking
  131. * @return integer|float
  132. */
  133. public static function accepts_at_quality($type = NULL, $explicit_check = FALSE)
  134. {
  135. request::parse_accept_header();
  136. // Normalize type
  137. $type = strtolower((string) $type);
  138. // General content type (e.g. "jpg")
  139. if (strpos($type, '/') === FALSE)
  140. {
  141. // Don't accept anything by default
  142. $q = 0;
  143. // Look up relevant mime types
  144. foreach ((array) Kohana::config('mimes.'.$type) as $type)
  145. {
  146. $q2 = request::accepts_at_quality($type, $explicit_check);
  147. $q = ($q2 > $q) ? $q2 : $q;
  148. }
  149. return $q;
  150. }
  151. // Content type with subtype given (e.g. "image/jpg")
  152. $type = explode('/', $type, 2);
  153. // Exact match
  154. if (isset(self::$accept_types[$type[0]][$type[1]]))
  155. return self::$accept_types[$type[0]][$type[1]];
  156. // Wildcard match (if not checking explicitly)
  157. if ($explicit_check === FALSE AND isset(self::$accept_types[$type[0]]['*']))
  158. return self::$accept_types[$type[0]]['*'];
  159. // Catch-all wildcard match (if not checking explicitly)
  160. if ($explicit_check === FALSE AND isset(self::$accept_types['*']['*']))
  161. return self::$accept_types['*']['*'];
  162. // Content type not accepted
  163. return 0;
  164. }
  165. /**
  166. * Parses client's HTTP Accept request header, and builds array structure representing it.
  167. *
  168. * @return void
  169. */
  170. protected static function parse_accept_header()
  171. {
  172. // Run this function just once
  173. if (self::$accept_types !== NULL)
  174. return;
  175. // Initialize accept_types array
  176. self::$accept_types = array();
  177. // No HTTP Accept header found
  178. if (empty($_SERVER['HTTP_ACCEPT']))
  179. {
  180. // Accept everything
  181. self::$accept_types['*']['*'] = 1;
  182. return;
  183. }
  184. // Remove linebreaks and parse the HTTP Accept header
  185. foreach (explode(',', str_replace(array("\r", "\n"), '', $_SERVER['HTTP_ACCEPT'])) as $accept_entry)
  186. {
  187. // Explode each entry in content type and possible quality factor
  188. $accept_entry = explode(';', trim($accept_entry), 2);
  189. // Explode each content type (e.g. "text/html")
  190. $type = explode('/', $accept_entry[0], 2);
  191. // Skip invalid content types
  192. if ( ! isset($type[1]))
  193. continue;
  194. // Assume a default quality factor of 1 if no custom q value found
  195. $q = (isset($accept_entry[1]) AND preg_match('~\bq\s*+=\s*+([.0-9]+)~', $accept_entry[1], $match)) ? (float) $match[1] : 1;
  196. // Populate accept_types array
  197. if ( ! isset(self::$accept_types[$type[0]][$type[1]]) OR $q > self::$accept_types[$type[0]][$type[1]])
  198. {
  199. self::$accept_types[$type[0]][$type[1]] = $q;
  200. }
  201. }
  202. }
  203. } // End request