Response.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <?php
  2. /**
  3. * Pimf
  4. *
  5. * @copyright Copyright (c) Gjero Krsteski (http://krsteski.de)
  6. * @license http://krsteski.de/new-bsd-license New BSD License
  7. */
  8. namespace Pimf;
  9. use \Pimf\Util\Header, Pimf\Util\Json as UtilJson;
  10. /**
  11. * Provides a simple interface around the HTTP an HTTPCache-friendly response generating.
  12. * Use this class to build and the current HTTP response before it is returned to the client.
  13. *
  14. * @package Pimf
  15. * @author Gjero Krsteski <[email protected]>
  16. */
  17. class Response
  18. {
  19. /**
  20. * The request method send by the client-browser.
  21. *
  22. * @var string
  23. */
  24. protected $method = null;
  25. /**
  26. * If the response attempts to send any cached headers.
  27. *
  28. * @var bool
  29. */
  30. protected static $cached = false;
  31. /**
  32. * Type of the data will be send to the client-browser.
  33. *
  34. * @var string
  35. */
  36. protected static $typed = null;
  37. /**
  38. * @param string $requestMethod
  39. *
  40. * @throws \RuntimeException
  41. */
  42. public function __construct($requestMethod)
  43. {
  44. $this->method = '' . strtoupper($requestMethod);
  45. // it is PIMF framework restriction
  46. if (!in_array($this->method, array('POST', 'GET', null))) {
  47. throw new \RuntimeException('unsupported request-method given');
  48. }
  49. Header::clear();
  50. }
  51. /**
  52. * @return string
  53. */
  54. public function getMethod()
  55. {
  56. return $this->method;
  57. }
  58. public function asJSON()
  59. {
  60. $this->preventMultipleTypes();
  61. self::$typed = __FUNCTION__;
  62. Header::asJSON();
  63. return $this;
  64. }
  65. public function asHTML()
  66. {
  67. $this->preventMultipleTypes();
  68. self::$typed = __FUNCTION__;
  69. Header::asTextHTML();
  70. return $this;
  71. }
  72. public function asPDF()
  73. {
  74. $this->preventMultipleTypes();
  75. self::$typed = __FUNCTION__;
  76. Header::asPDF();
  77. return $this;
  78. }
  79. public function asCSV()
  80. {
  81. $this->preventMultipleTypes();
  82. self::$typed = __FUNCTION__;
  83. Header::asCSV();
  84. return $this;
  85. }
  86. public function asTEXT()
  87. {
  88. $this->preventMultipleTypes();
  89. self::$typed = __FUNCTION__;
  90. Header::asTextPlain();
  91. return $this;
  92. }
  93. public function asZIP()
  94. {
  95. $this->preventMultipleTypes();
  96. self::$typed = __FUNCTION__;
  97. Header::asZIP();
  98. return $this;
  99. }
  100. public function asXZIP()
  101. {
  102. $this->preventMultipleTypes();
  103. self::$typed = __FUNCTION__;
  104. Header::asXZIP();
  105. return $this;
  106. }
  107. public function asMSWord()
  108. {
  109. $this->preventMultipleTypes();
  110. self::$typed = __FUNCTION__;
  111. Header::asMSWord();
  112. return $this;
  113. }
  114. /**
  115. * Sends a download dialog to the browser.
  116. *
  117. * @param string $stream Can be a file-path or a string.
  118. * @param string $name Name of the stream/file should be shown.
  119. */
  120. public function sendStream($stream, $name)
  121. {
  122. Header::clear();
  123. Header::sendDownloadDialog($stream, $name);
  124. }
  125. /**
  126. * @param mixed $data
  127. * @param bool $exit
  128. */
  129. public function send($data, $exit = true)
  130. {
  131. $body = $data;
  132. if (self::$typed === 'asJSON') {
  133. $body = UtilJson::encode($data);
  134. } elseif ($data instanceof \Pimf\View) {
  135. $body = $data->render();
  136. }
  137. echo '' . $body;
  138. if ($exit) {
  139. exit(0);
  140. }
  141. }
  142. /**
  143. * If instead you have a page that has personalization on it
  144. * (say, for example, the splash page contains local news as well),
  145. * you can set a copy to be cached only by the browser.
  146. *
  147. * @param int $seconds Interval in seconds
  148. *
  149. * @return $this
  150. */
  151. public function cacheBrowser($seconds)
  152. {
  153. self::preventMultipleCaching();
  154. self::$cached = true;
  155. Header::cacheBrowser($seconds);
  156. return $this;
  157. }
  158. /**
  159. * If you want to try as hard as possible to keep a page from being cached anywhere.
  160. *
  161. * @return $this
  162. */
  163. public function cacheNone()
  164. {
  165. self::preventMultipleCaching();
  166. self::$cached = true;
  167. Header::cacheNone();
  168. return $this;
  169. }
  170. /**
  171. * If you want to allow a page to be cached by shared proxies for one minute.
  172. *
  173. * @param int $seconds Interval in seconds
  174. *
  175. * @return $this
  176. */
  177. public function cacheNoValidate($seconds = 60)
  178. {
  179. self::preventMultipleCaching();
  180. self::$cached = true;
  181. Header::cacheNoValidate($seconds);
  182. return $this;
  183. }
  184. /**
  185. * Handles setting pages that are always to be revalidated for freshness by any cache.
  186. *
  187. * @param int $last_modified Timestamp in seconds
  188. *
  189. * @return $this
  190. */
  191. public function exitIfNotModifiedSince($last_modified)
  192. {
  193. self::preventMultipleCaching();
  194. self::$cached = true;
  195. Header::exitIfNotModifiedSince($last_modified);
  196. return $this;
  197. }
  198. /**
  199. * @throws \RuntimeException
  200. */
  201. private function preventMultipleTypes()
  202. {
  203. if (!is_empty(self::$typed)) {
  204. Header::clear();
  205. throw new \RuntimeException('only one HTTP content-type can be sent!');
  206. }
  207. }
  208. /**
  209. * @throws \RuntimeException
  210. */
  211. private function preventMultipleCaching()
  212. {
  213. if ($this->method != 'GET') {
  214. Header::clear();
  215. throw new \RuntimeException('HTTP cache headers can only take effect if request was sent via GET method!');
  216. }
  217. if (self::$cached === true) {
  218. Header::clear();
  219. throw new \RuntimeException('only one HTTP cache-control can be sent!');
  220. }
  221. }
  222. }