response.class.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <?php
  2. namespace Juju\Http;
  3. require_once(realpath(dirname(__DIR__).'/events.trait.php'));
  4. require_once(realpath(dirname(__DIR__).'/App/router.class.php'));
  5. use \Juju\{App\Router, Events};
  6. class Response {
  7. use Events;
  8. public $output = '';
  9. public $body = '';
  10. private $code = 200;
  11. public $headers = [];
  12. protected $open = true;
  13. protected $shutdown = false;
  14. public function __construct(){}
  15. public function __toString(){
  16. return $this->body;
  17. }
  18. public function clear(){
  19. if($this->open){
  20. $this->fire('clear');
  21. $this->body = '';
  22. }
  23. return $this;
  24. }
  25. public function clear_headers(){
  26. if($this->open){
  27. $this->fire('clear_headers');
  28. $this->headers = [];
  29. }
  30. return $this;
  31. }
  32. public function clear_header(string $name){
  33. foreach($this->headers as $key => $header){
  34. if($header[0] == $name){
  35. $this->fire('clear_header', $name);
  36. array_splice($this->headers, $key, 1);
  37. }
  38. }
  39. return $this;
  40. }
  41. public function write(string $chunk){
  42. $this->fire('write', $chunk);
  43. if($this->open){
  44. $this->body .= $chunk;
  45. }
  46. return $this;
  47. }
  48. public function json($json){
  49. if(is_array($json)){
  50. array_walk_recursive($json, function(&$item, $key){
  51. if(!mb_detect_encoding($item, 'utf-8', true)){
  52. $item = utf8_encode($item);
  53. }
  54. });
  55. }
  56. $this->fire('json', $json);
  57. $this->write(json_encode($json));
  58. if(json_last_error() != JSON_ERROR_NONE){
  59. throw new \Exception(json_last_error_msg());
  60. }
  61. return $this;
  62. }
  63. public function header(string $name, string $value = null){
  64. if(is_null($value)){
  65. $headers = array_filter($this->headers,function($header) use($name){
  66. return $header[0] == $name;
  67. });
  68. return end($headers)[1];
  69. }else{
  70. if($this->open){
  71. if($this->fire('header', $name, $value) !== false){
  72. $this->headers[] = [
  73. $name,
  74. $value
  75. ];
  76. }
  77. }
  78. }
  79. return $this;
  80. }
  81. public function redirect(string $url){
  82. $this->fire('redirect', $url);
  83. $this->header('Location', Router::url($url));
  84. return $this;
  85. }
  86. public function end(string $chunk=''){
  87. if($this->open){
  88. $this->write($chunk);
  89. $this->fire('end');
  90. $this->open = false;
  91. }
  92. return $this;
  93. }
  94. public function img(Image $img, string $type = null){
  95. if(!$type){
  96. $type = $img->type;
  97. }
  98. $this->fire('image', $img, $type);
  99. $this->clear_header('Content-Type')
  100. ->header('Content-Type', 'image/'.$type);
  101. if(!is_a($img, 'Image')){
  102. $img = new Image(100, 20);
  103. $img->text('Invalid Image',0,0,'black',12);
  104. }
  105. ob_start();
  106. $img();
  107. $this->write(ob_get_contents());
  108. ob_end_clean();
  109. return $this;
  110. }
  111. public function code(int $code=null){
  112. if(is_null($code)){
  113. return $this->code;
  114. }
  115. $this->fire('code', $code);
  116. $this->code = $code;
  117. return $this;
  118. }
  119. public function shutdown(){
  120. if(!$this->shutdown){
  121. $this->shutdown = true;
  122. $this->fire('beforeshutdown');
  123. if($this->open){
  124. $this->end();
  125. }
  126. $this->fire('shutdown');
  127. http_response_code($this->code);
  128. foreach($this->headers as $k => $header){
  129. header("{$header[0]}: $header[1]");
  130. }
  131. echo $this->body;
  132. flush();
  133. $this->fire('aftershutdown');
  134. }
  135. return $this;
  136. }
  137. public function open(){
  138. if(!$this->shutdown){
  139. $this->open = true;
  140. }
  141. return $this;
  142. }
  143. public static function locale(string $locale, string $domain, string $folder, string $codeset = 'UTF-8'){
  144. $path = realpath($folder);
  145. if($path !== false){
  146. bindtextdomain($domain, $path);
  147. textdomain($domain);
  148. bind_textdomain_codeset($domain, $codeset);
  149. $orig_locale = $locale;
  150. if(!file_exists("{$path}/$locale/LC_MESSAGES/{$domain}.mo")){
  151. $locale = \Locale::getPrimaryLanguage($locale);
  152. if(!file_exists("{$path}/$locale/LC_MESSAGES/{$domain}.mo")){
  153. $locale = \Locale::getDefault();
  154. if(!file_exists("{$path}/$locale/LC_MESSAGES/{$domain}.mo")){
  155. $dir = dir("{$path}/");
  156. do{
  157. $locale = $dir->read();
  158. if($locale === false){
  159. trigger_error("Unable to find fallback locale for {$orig_locale}", E_USER_WARNING);
  160. break;
  161. }
  162. }while(!file_exists("{$path}/$locale/LC_MESSAGES/{$domain}.mo"));
  163. }
  164. }
  165. }
  166. }else{
  167. trigger_error("Locale folder {$folder} missing", E_USER_WARNING);
  168. }
  169. \Locale::setDefault($locale);
  170. }
  171. }
  172. ?>