PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 1.91.6
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v1.91.6
2.1.0 2.0.15 2.0.12 2.0.10 2.0.4 2.0.1 2.0.0 1.95.3 1.95.2 1.95 1.91.6 trunk 1.11 1.12 1.13 1.20 1.21 1.22 1.23 1.30 1.31 1.32 1.35 1.40 1.41 All 42 releases
fluent-boards / vendor / wpfluent / framework / src / WPFluent / Http / Response / Response.php

Response.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 1.91.6, at vendor/wpfluent/framework/src/WPFluent/Http/Response/Response.php

379 lines 8.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBoards\Framework\Http\Response;
4
5 use DateTime;
6 use WP_Error;
7 use DateTimeInterface;
8 use WP_REST_Response;
9 use FluentBoards\Framework\App\App;
10 use InvalidArgumentException;
11 use FluentBoards\Framework\Http\Request\File;
12
13 class Response
14 {
15 /**
16 * Response Data
17 * @var mixed
18 */
19 protected $data = null;
20
21 /**
22 * Response Status Code
23 * @var integer
24 */
25 protected $code = 200;
26
27 /**
28 * Response Headers
29 * @var array
30 */
31 protected $headers = [];
32
33 /**
34 * Response Cookies
35 * @var array
36 */
37 protected $cookies = [];
38
39 /**
40 * Construct the response instance.
41 *
42 * @param array $data
43 * @param integer $code
44 * @param array $headers
45 */
46 public function __construct($data = null, $code = 200, $headers = [])
47 {
48 $this->data = $data;
49 $this->code = $code;
50 $this->headers = $headers;
51 }
52
53 /**
54 * Creates an instance of self.
55 *
56 * @param mixed $data
57 * @param integer $code
58 * @param array $headers
59 * @return self
60 */
61 public static function make($data = null, $code = 200, $headers = [])
62 {
63 return new static($data, $code, $headers);
64 }
65
66 /**
67 * Send json response.
68 *
69 * @param array $data
70 * @param integer $code
71 * @return string|false JSON encoded string, or false if fails to encode.
72 */
73 public function json($data = null, $code = 200)
74 {
75 return wp_send_json($data, $code);
76 }
77
78 /**
79 * Send rest response.
80 *
81 * @param mixed $data
82 * @param integer $code
83 * @param array $headers
84 * @return \WP_REST_Response
85 */
86 public function send($data = null, $code = 200, $headers = [])
87 {
88 // disable litespeed cache
89 do_action( 'litespeed_control_set_nocache', 'fluent plugin api request' );
90
91 $response = new WP_REST_Response($data, $code, $headers);
92
93 return $this->maybeMergeHeaders(
94 $this->MaybeMergeCookies($response)
95 );
96 }
97
98 /**
99 * Send a success rest response.
100 *
101 * @param mixed $data
102 * @param integer $code
103 * @return \WP_REST_Response
104 */
105 public function sendSuccess($data = null, $code = 200, $headers = [])
106 {
107 return $this->send($data, $code, $headers);
108 }
109
110 /**
111 * Send an error json response
112 * @param array $data
113 * @param integer $code
114 * @return \WP_REST_Response
115 */
116 public function sendError($data = null, $code = 422, $headers = [])
117 {
118 if (!$code || $code < 400 ) {
119 $code = 422;
120 }
121
122 return $this->send($data, $code, $headers);
123 }
124
125 /**
126 * Convert the WP_Error to WP_REST_Response
127 *
128 * @param \WP_Error $wpError
129 * @return \WP_REST_Response
130 */
131 public function wpErrorToResponse(WP_Error $wpError)
132 {
133 return rest_convert_error_to_response($wpError);
134 }
135
136 /**
137 * Set response headers
138 * @param string|array $key
139 * @param string|null $value
140 * @return self
141 */
142 public function withHeader($key, $value = null)
143 {
144 if (is_array($key) && !$value) {
145 $this->headers = $key;
146 } else {
147 $this->headers = [$key => $value];
148 }
149
150 return $this;
151 }
152
153 /**
154 * Set response cookie
155 *
156 * @param string $name
157 * @param mixed $value
158 * @param int $minutes
159 * @param string $path
160 * @param string|null $domain
161 * @param bool $secure
162 * @param bool $httpOnly
163 * @return self
164 */
165 public function withCookie(
166 $name,
167 $value,
168 $minutes,
169 $path = '/',
170 $domain = null,
171 $secure = false,
172 $httpOnly = true
173 )
174 {
175 $cookie = $this->buildCookie(
176 $name, $value, $minutes, $path, $domain, $secure, $httpOnly
177 );
178
179 $this->cookies[] = $cookie;
180
181 return $this;
182 }
183
184 /**
185 * Build cookie header for response
186 *
187 * @param string $name
188 * @param mixed $value
189 * @param int $minutes
190 * @param string $path
191 * @param string|null $domain
192 * @param bool $secure
193 * @param bool $httpOnly
194 * @return string
195 */
196 protected function buildCookie(
197 $name,
198 $value,
199 $minutes,
200 $path,
201 $domain,
202 $secure,
203 $httpOnly
204 ) {
205 $expiration = static::expiresAt($minutes);
206
207 $cookieHeader = "{$name}=" . rawurlencode($value);
208
209 $cookieHeader .= "; Expires=" . gmdate('D, d-M-Y H:i:s T', $expiration);
210
211 $cookieHeader .= "; Path=" . $path;
212
213 if ($domain) {
214 $cookieHeader .= "; Domain=" . $domain;
215 }
216
217 if ($secure) {
218 $cookieHeader .= "; Secure";
219 }
220
221 if ($httpOnly) {
222 $cookieHeader .= "; HttpOnly";
223 }
224
225 return $cookieHeader;
226 }
227
228 /**
229 * Merge additional headers if exist.
230 *
231 * @param \WP_REST_Response $response
232 */
233 protected function maybeMergeHeaders(WP_REST_Response $response)
234 {
235 if ($this->headers) {
236 foreach ($this->headers as $key => $value) {
237 $response->header($key, $value);
238 }
239 }
240
241 $this->headers = [];
242
243 return $response;
244 }
245
246 /**
247 * Merge cookies if exist.
248 *
249 * @param \WP_REST_Response $response
250 */
251 protected function MaybeMergeCookies(WP_REST_Response $response)
252 {
253 if ($this->cookies) {
254 foreach ($this->cookies as $cookie) {
255 $response->header('Set-Cookie', $cookie);
256 }
257 }
258
259 $this->cookies = [];
260
261 return $response;
262 }
263
264 /**
265 * Prepares expiration time in minutes.
266 *
267 * @param int|DateTimeInterface $minutes
268 * @return int
269 */
270 protected static function expiresAt($minutes = 0)
271 {
272 if (is_int($minutes)) {
273 if ($minutes === 0) {
274 return $minutes;
275 }
276
277 $minutes = new DateTime('+' . $minutes . ' minutes');
278 }
279
280 if (!($minutes instanceof DateTimeInterface)) {
281 throw new InvalidArgumentException(
282 'Invalid expiration time provided.'
283 );
284 }
285
286 return $minutes->getTimestamp();
287 }
288
289 /**
290 * Send the response
291 *
292 * @return \WP_REST_Response
293 */
294 public function toArray()
295 {
296 $response = new WP_REST_Response(
297 $this->data, $this->code
298 );
299
300 return $this->MaybeMergeCookies(
301 $this->maybeMergeHeaders($response)
302 );
303 }
304
305 /**
306 * Send a file download response.
307 *
308 * @param string $filePath
309 * @param string|null $fileName
310 * @return void
311 */
312 public static function download($filePath, $fileName = null)
313 {
314 if ($filePath instanceof File) {
315 $array = $filePath->toArray();
316 $filePath = $array['tmp_name'];
317 $fileName ??= $fileName ?? $array['name'];
318 }
319
320 if (!file_exists($filePath) || !is_readable($filePath)) {
321 wp_die('File does not exist or unreadable.', '404 Not Found');
322 }
323
324 $mimeType = mime_content_type($filePath) ?: 'application/octet-stream';
325
326 $fileName = sanitize_file_name($fileName ?? basename($filePath));
327
328 header('Content-Description: File Transfer');
329 header('Content-Type: ' . $mimeType);
330 header('Content-Disposition: attachment; filename="' . $fileName . '"');
331 header('Content-Transfer-Encoding: binary');
332 header('Expires: 0');
333 header('Cache-Control: must-revalidate');
334 header('Pragma: public');
335 header('Content-Length: ' . filesize($filePath));
336
337 if (php_sapi_name() === 'cli') {
338 ob_start();
339 readfile($filePath);
340 $content = ob_get_clean();
341 add_action('shutdown', function() { exit; });
342 return $content;
343 } else {
344 ob_get_level() && ob_end_clean() && flush();
345 readfile($filePath);
346 exit;
347 }
348 }
349
350 /**
351 * Send a redirect response.
352 *
353 * @param string $route
354 * @param integer $status
355 * @return \WP_REST_Response
356 */
357 public static function redirect($route, $status = 303)
358 {
359 [$ns, $ver] = App::config()->only('rest_namespace', 'rest_version');
360
361 $baseUrl = rest_url("{$ns}/{$ver}");
362
363 $parsedUrl = parse_url($route);
364
365 $path = trim($parsedUrl['path'] ?? '', '/');
366
367 parse_str($parsedUrl['query'] ?? '', $queryParams);
368
369 $queryParams['x_redirect_to'] = $path;
370 $queryParams['x_redirected_from'] = App::request()->url();
371
372 $location = "{$baseUrl}/{$path}?" . http_build_query($queryParams);
373
374 return new WP_REST_Response(null, $status, [
375 'Location' => $location
376 ]);
377 }
378 }
379