response.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. <?php namespace Laravel;
  2. class Response_Factory {
  3. /**
  4. * The view factory instance.
  5. *
  6. * @var View_Factory
  7. */
  8. protected $view;
  9. /**
  10. * The file manager instance.
  11. *
  12. * @var File
  13. */
  14. protected $file;
  15. /**
  16. * Create a new response factory instance.
  17. *
  18. * @param View_Factory $view
  19. * @param File $file
  20. * @return void
  21. */
  22. public function __construct(View_Factory $view, File $file)
  23. {
  24. $this->view = $view;
  25. $this->file = $file;
  26. }
  27. /**
  28. * Create a new response instance.
  29. *
  30. * <code>
  31. * // Create a response instance
  32. * return Response::make('Hello World');
  33. *
  34. * // Create a response instance with a given status code
  35. * return Response::make('Hello World', 200);
  36. * </code>
  37. *
  38. * @param mixed $content
  39. * @param int $status
  40. * @param array $headers
  41. * @return Response
  42. */
  43. public function make($content, $status = 200, $headers = array())
  44. {
  45. return new Response($content, $status, $headers);
  46. }
  47. /**
  48. * Create a new response instance containing a view.
  49. *
  50. * <code>
  51. * // Create a new response instance with view content
  52. * return Response::view('home.index');
  53. *
  54. * // Create a new response instance with a view and bound data
  55. * return Response::view('home.index', array('name' => 'Fred'));
  56. * </code>
  57. *
  58. * @param string $view
  59. * @param array $data
  60. * @return Response
  61. */
  62. public function view($view, $data = array())
  63. {
  64. return new Response($this->view->make($view, $data));
  65. }
  66. /**
  67. * Create a new response instance containing a named view.
  68. *
  69. * <code>
  70. * // Create a new response instance with a named view
  71. * return Response::with('layout');
  72. *
  73. * // Create a new response instance with a named view and bound data
  74. * return Response::with('layout', array('name' => 'Fred'));
  75. * </code>
  76. *
  77. * @param string $name
  78. * @param array $data
  79. * @return Response
  80. */
  81. public function with($name, $data = array())
  82. {
  83. return new Response($this->view->of($name, $data));
  84. }
  85. /**
  86. * Create a new error response instance.
  87. *
  88. * The response status code will be set using the specified code.
  89. *
  90. * Note: The specified error code should correspond to a view in your views/error directory.
  91. *
  92. * <code>
  93. * // Create an error response for status 500
  94. * return Response::error('500');
  95. * </code>
  96. *
  97. * @param int $code
  98. * @param array $data
  99. * @return Response
  100. */
  101. public function error($code, $data = array())
  102. {
  103. return new Response($this->view->make('error/'.$code, $data), $code);
  104. }
  105. /**
  106. * Create a new download response instance.
  107. *
  108. * @param string $path
  109. * @param string $name
  110. * @param array $headers
  111. * @return Response
  112. */
  113. public function download($path, $name = null, $headers = array())
  114. {
  115. if (is_null($name)) $name = basename($path);
  116. $headers = array_merge(array(
  117. 'Content-Description' => 'File Transfer',
  118. 'Content-Type' => $this->file->mime($this->file->extension($path)),
  119. 'Content-Disposition' => 'attachment; filename="'.$name.'"',
  120. 'Content-Transfer-Encoding' => 'binary',
  121. 'Expires' => 0,
  122. 'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
  123. 'Pragma' => 'public',
  124. 'Content-Length' => $this->file-size($path),
  125. ), $headers);
  126. return new Response($this->file->get($path), 200, $headers);
  127. }
  128. /**
  129. * Magic Method for handling the dynamic creation of Responses containing named views.
  130. *
  131. * <code>
  132. * // Create a Response instance with the "layout" named view
  133. * $response = Response::with_layout();
  134. *
  135. * // Create a Response instance with the "layout" named view and bound data
  136. * $response = Response::with_layout(array('name' => 'Fred'));
  137. * </code>
  138. */
  139. public function __call($method, $parameters)
  140. {
  141. if (strpos($method, 'with_') === 0)
  142. {
  143. return $this->with(substr($method, 5), Arr::get($parameters, 0, array()));
  144. }
  145. }
  146. }
  147. class Response {
  148. /**
  149. * The content of the response.
  150. *
  151. * @var mixed
  152. */
  153. public $content;
  154. /**
  155. * The HTTP status code of the response.
  156. *
  157. * @var int
  158. */
  159. public $status;
  160. /**
  161. * The response headers.
  162. *
  163. * @var array
  164. */
  165. public $headers = array();
  166. /**
  167. * HTTP status codes.
  168. *
  169. * @var array
  170. */
  171. private $statuses = array(
  172. 100 => 'Continue',
  173. 101 => 'Switching Protocols',
  174. 200 => 'OK',
  175. 201 => 'Created',
  176. 202 => 'Accepted',
  177. 203 => 'Non-Authoritative Information',
  178. 204 => 'No Content',
  179. 205 => 'Reset Content',
  180. 206 => 'Partial Content',
  181. 207 => 'Multi-Status',
  182. 300 => 'Multiple Choices',
  183. 301 => 'Moved Permanently',
  184. 302 => 'Found',
  185. 303 => 'See Other',
  186. 304 => 'Not Modified',
  187. 305 => 'Use Proxy',
  188. 307 => 'Temporary Redirect',
  189. 400 => 'Bad Request',
  190. 401 => 'Unauthorized',
  191. 402 => 'Payment Required',
  192. 403 => 'Forbidden',
  193. 404 => 'Not Found',
  194. 405 => 'Method Not Allowed',
  195. 406 => 'Not Acceptable',
  196. 407 => 'Proxy Authentication Required',
  197. 408 => 'Request Timeout',
  198. 409 => 'Conflict',
  199. 410 => 'Gone',
  200. 411 => 'Length Required',
  201. 412 => 'Precondition Failed',
  202. 413 => 'Request Entity Too Large',
  203. 414 => 'Request-URI Too Long',
  204. 415 => 'Unsupported Media Type',
  205. 416 => 'Requested Range Not Satisfiable',
  206. 417 => 'Expectation Failed',
  207. 422 => 'Unprocessable Entity',
  208. 423 => 'Locked',
  209. 424 => 'Failed Dependency',
  210. 500 => 'Internal Server Error',
  211. 501 => 'Not Implemented',
  212. 502 => 'Bad Gateway',
  213. 503 => 'Service Unavailable',
  214. 504 => 'Gateway Timeout',
  215. 505 => 'HTTP Version Not Supported',
  216. 507 => 'Insufficient Storage',
  217. 509 => 'Bandwidth Limit Exceeded'
  218. );
  219. /**
  220. * Create a new response instance.
  221. *
  222. * @param mixed $content
  223. * @param int $status
  224. * @param array $headers
  225. * @return void
  226. */
  227. public function __construct($content, $status = 200, $headers = array())
  228. {
  229. $this->content = $content;
  230. $this->headers = $headers;
  231. $this->status = $status;
  232. }
  233. /**
  234. * Get the evaluated string contents of the response.
  235. *
  236. * @return string
  237. */
  238. public function render()
  239. {
  240. return ($this->content instanceof View) ? $this->content->render() : (string) $this->content;
  241. }
  242. /**
  243. * Send the response to the browser.
  244. *
  245. * All of the response header will be sent to the browser first, followed by
  246. * the content of the response instance, which will be evaluated and rendered
  247. * by the render method.
  248. *
  249. * @return void
  250. */
  251. public function send()
  252. {
  253. if ( ! isset($this->headers['Content-Type'])) $this->header('Content-Type', 'text/html; charset=utf-8');
  254. if ( ! headers_sent()) $this->send_headers();
  255. echo $this->render();
  256. }
  257. /**
  258. * Send the response headers to the browser.
  259. *
  260. * @return void
  261. */
  262. public function send_headers()
  263. {
  264. $protocol = (isset($_SERVER['SERVER_PROTOCOL'])) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1';
  265. header($protocol.' '.$this->status.' '.$this->statuses[$this->status]);
  266. foreach ($this->headers as $name => $value)
  267. {
  268. header($name.': '.$value, true);
  269. }
  270. }
  271. /**
  272. * Add a header to the response.
  273. *
  274. * @param string $name
  275. * @param string $value
  276. * @return Response
  277. */
  278. public function header($name, $value)
  279. {
  280. $this->headers[$name] = $value;
  281. return $this;
  282. }
  283. /**
  284. * Set the response status code.
  285. *
  286. * @param int $status
  287. * @return Response
  288. */
  289. public function status($status)
  290. {
  291. $this->status = $status;
  292. return $this;
  293. }
  294. }