response.php 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. <?php namespace Laravel;
  2. use Symfony\Component\HttpFoundation\ResponseHeaderBag;
  3. use Symfony\Component\HttpFoundation\LaravelResponse as FoundationResponse;
  4. class Response {
  5. /**
  6. * The content of the response.
  7. *
  8. * @var mixed
  9. */
  10. public $content;
  11. /**
  12. * The Symfony HttpFoundation Response instance.
  13. *
  14. * @var HttpFoundation\Response
  15. */
  16. public $foundation;
  17. /**
  18. * Create a new response instance.
  19. *
  20. * @param mixed $content
  21. * @param int $status
  22. * @param array $headers
  23. * @return void
  24. */
  25. public function __construct($content, $status = 200, $headers = array())
  26. {
  27. $this->content = $content;
  28. $this->foundation = new FoundationResponse('', $status, $headers);
  29. }
  30. /**
  31. * Create a new response instance.
  32. *
  33. * <code>
  34. * // Create a response instance with string content
  35. * return Response::make(json_encode($user));
  36. *
  37. * // Create a response instance with a given status
  38. * return Response::make('Not Found', 404);
  39. *
  40. * // Create a response with some custom headers
  41. * return Response::make(json_encode($user), 200, array('header' => 'value'));
  42. * </code>
  43. *
  44. * @param mixed $content
  45. * @param int $status
  46. * @param array $headers
  47. * @return Response
  48. */
  49. public static function make($content, $status = 200, $headers = array())
  50. {
  51. return new static($content, $status, $headers);
  52. }
  53. /**
  54. * Create a new response instance containing a view.
  55. *
  56. * <code>
  57. * // Create a response instance with a view
  58. * return Response::view('home.index');
  59. *
  60. * // Create a response instance with a view and data
  61. * return Response::view('home.index', array('name' => 'Taylor'));
  62. * </code>
  63. *
  64. * @param string $view
  65. * @param array $data
  66. * @return Response
  67. */
  68. public static function view($view, $data = array())
  69. {
  70. return new static(View::make($view, $data));
  71. }
  72. /**
  73. * Create a new JSON response.
  74. *
  75. * <code>
  76. * // Create a response instance with JSON
  77. * return Response::json($data, 200, array('header' => 'value'));
  78. * </code>
  79. *
  80. * @param mixed $data
  81. * @param int $status
  82. * @param array $headers
  83. * @return Response
  84. */
  85. public static function json($data, $status = 200, $headers = array())
  86. {
  87. $headers['Content-Type'] = 'application/json; charset=utf-8';
  88. return new static(json_encode($data), $status, $headers);
  89. }
  90. /**
  91. * Create a new JSONP response.
  92. *
  93. * <code>
  94. * // Create a response instance with JSONP
  95. * return Response::jsonp('myFunctionCall', $data, 200, array('header' => 'value'));
  96. * </code>
  97. *
  98. * @param mixed $data
  99. * @param int $status
  100. * @param array $headers
  101. * @return Response
  102. */
  103. public static function jsonp($callback, $data, $status = 200, $headers = array())
  104. {
  105. $headers['Content-Type'] = 'application/javascript; charset=utf-8';
  106. return new static($callback.'('.json_encode($data).');', $status, $headers);
  107. }
  108. /**
  109. * Create a new response of JSON'd Eloquent models.
  110. *
  111. * <code>
  112. * // Create a new response instance with Eloquent models
  113. * return Response::eloquent($data, 200, array('header' => 'value'));
  114. * </code>
  115. *
  116. * @param Eloquent|array $data
  117. * @param int $status
  118. * @param array $headers
  119. * @return Response
  120. */
  121. public static function eloquent($data, $status = 200, $headers = array())
  122. {
  123. $headers['Content-Type'] = 'application/json; charset=utf-8';
  124. return new static(eloquent_to_json($data), $status, $headers);
  125. }
  126. /**
  127. * Create a new error response instance.
  128. *
  129. * The response status code will be set using the specified code.
  130. *
  131. * The specified error should match a view in your views/error directory.
  132. *
  133. * <code>
  134. * // Create a 404 response
  135. * return Response::error('404');
  136. *
  137. * // Create a 404 response with data
  138. * return Response::error('404', array('message' => 'Not Found'));
  139. * </code>
  140. *
  141. * @param int $code
  142. * @param array $data
  143. * @return Response
  144. */
  145. public static function error($code, $data = array())
  146. {
  147. return new static(View::make('error.'.$code, $data), $code);
  148. }
  149. /**
  150. * Create a new download response instance.
  151. *
  152. * <code>
  153. * // Create a download response to a given file
  154. * return Response::download('path/to/file.jpg');
  155. *
  156. * // Create a download response with a given file name
  157. * return Response::download('path/to/file.jpg', 'your_file.jpg');
  158. * </code>
  159. *
  160. * @param string $path
  161. * @param string $name
  162. * @param array $headers
  163. * @return Response
  164. */
  165. public static function download($path, $name = null, $headers = array())
  166. {
  167. if (is_null($name)) $name = basename($path);
  168. // We'll set some sensible default headers, but merge the array given to
  169. // us so that the developer has the chance to override any of these
  170. // default headers with header values of their own liking.
  171. $headers = array_merge(array(
  172. 'Content-Description' => 'File Transfer',
  173. 'Content-Type' => File::mime(File::extension($path)),
  174. 'Content-Transfer-Encoding' => 'binary',
  175. 'Expires' => 0,
  176. 'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
  177. 'Pragma' => 'public',
  178. 'Content-Length' => File::size($path),
  179. ), $headers);
  180. // Once we create the response, we need to set the content disposition
  181. // header on the response based on the file's name. We'll pass this
  182. // off to the HttpFoundation and let it create the header text.
  183. $response = new static(File::get($path), 200, $headers);
  184. $d = $response->disposition($name);
  185. return $response->header('Content-Disposition', $d);
  186. }
  187. /**
  188. * Create the proper Content-Disposition header.
  189. *
  190. * @param string $file
  191. * @return string
  192. */
  193. public function disposition($file)
  194. {
  195. $type = ResponseHeaderBag::DISPOSITION_ATTACHMENT;
  196. return $this->foundation->headers->makeDisposition($type, $file);
  197. }
  198. /**
  199. * Prepare a response from the given value.
  200. *
  201. * @param mixed $response
  202. * @return Response
  203. */
  204. public static function prepare($response)
  205. {
  206. // We will need to force the response to be a string before closing
  207. // the session since the developer may be utilizing the session
  208. // within the view, and we can't age it until rendering.
  209. if ( ! $response instanceof Response)
  210. {
  211. $response = new static($response);
  212. }
  213. return $response;
  214. }
  215. /**
  216. * Send the headers and content of the response to the browser.
  217. *
  218. * @return void
  219. */
  220. public function send()
  221. {
  222. $this->cookies();
  223. $this->foundation->prepare(Request::foundation());
  224. $this->foundation->send();
  225. }
  226. /**
  227. * Convert the content of the Response to a string and return it.
  228. *
  229. * @return string
  230. */
  231. public function render()
  232. {
  233. // If the content is a stringable object, we'll go ahead and call
  234. // the toString method so that we can get the string content of
  235. // the content object. Otherwise we'll just cast to string.
  236. if (str_object($this->content))
  237. {
  238. $this->content = $this->content->__toString();
  239. }
  240. else
  241. {
  242. $this->content = (string) $this->content;
  243. }
  244. // Once we obtain the string content, we can set the content on
  245. // the HttpFoundation's Response instance in preparation for
  246. // sending it back to client browser when all is finished.
  247. $this->foundation->setContent($this->content);
  248. return $this->content;
  249. }
  250. /**
  251. * Send all of the response headers to the browser.
  252. *
  253. * @return void
  254. */
  255. public function send_headers()
  256. {
  257. $this->foundation->prepare(Request::foundation());
  258. $this->foundation->sendHeaders();
  259. }
  260. /**
  261. * Set the cookies on the HttpFoundation Response.
  262. *
  263. * @return void
  264. */
  265. protected function cookies()
  266. {
  267. $ref = new \ReflectionClass('Symfony\Component\HttpFoundation\Cookie');
  268. // All of the cookies for the response are actually stored on the
  269. // Cookie class until we're ready to send the response back to
  270. // the browser. This allows our cookies to be set easily.
  271. foreach (Cookie::$jar as $name => $cookie)
  272. {
  273. $config = array_values($cookie);
  274. $this->headers()->setCookie($ref->newInstanceArgs($config));
  275. }
  276. }
  277. /**
  278. * Add a header to the array of response headers.
  279. *
  280. * @param string $name
  281. * @param string $value
  282. * @return Response
  283. */
  284. public function header($name, $value)
  285. {
  286. $this->foundation->headers->set($name, $value);
  287. return $this;
  288. }
  289. /**
  290. * Get the HttpFoundation Response headers.
  291. *
  292. * @return ResponseParameterBag
  293. */
  294. public function headers()
  295. {
  296. return $this->foundation->headers;
  297. }
  298. /**
  299. * Get / set the response status code.
  300. *
  301. * @param int $status
  302. * @return mixed
  303. */
  304. public function status($status = null)
  305. {
  306. if (is_null($status))
  307. {
  308. return $this->foundation->getStatusCode();
  309. }
  310. else
  311. {
  312. $this->foundation->setStatusCode($status);
  313. return $this;
  314. }
  315. }
  316. /**
  317. * Render the response when cast to string
  318. *
  319. * @return string
  320. */
  321. public function __toString()
  322. {
  323. return $this->render();
  324. }
  325. }