PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.10.17
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.10.17
1.10.18 1.10.17 1.10.16 1.10.15 1.10.13 1.10.14 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 untagged-3d9b7ccddc54df87c672 1.10.7 1.10.6 1.10.5 1.10.3 1.10.4 1.10.2 1.10.1 1.10.0 1.9.17 1.9.15 1.9.16 1.9.14 1.9.13 All 162 releases
woocommerce-pos / includes / API / V1 / Raw_Response.php

Raw_Response.php in WCPOS – Point of Sale (POS) plugin for WooCommerce 1.10.17, at includes/API/V1/Raw_Response.php

88 lines 2.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Raw REST response helper.
4 *
5 * @package WCPOS\WooCommercePOS\API\V1
6 */
7
8 namespace WCPOS\WooCommercePOS\API\V1;
9
10 use WP_REST_Response;
11
12 /**
13 * Raw_Response class.
14 */
15 class Raw_Response extends WP_REST_Response {
16 /**
17 * Raw response body.
18 *
19 * @var string
20 */
21 private $raw_body;
22
23 /**
24 * Constructor.
25 *
26 * @param string $body Raw response body.
27 */
28 private function __construct( string $body ) {
29 parent::__construct( null, 200 );
30 $this->raw_body = $body;
31 }
32
33 /**
34 * Serve raw bytes from a REST callback.
35 *
36 * @param string $body Response body.
37 * @param string $content_type Content type.
38 * @param array $headers Extra headers.
39 *
40 * @return self
41 */
42 public static function serve( string $body, string $content_type, array $headers = array() ): self {
43 $response = new self( $body );
44 $response->header( 'Content-Type', $content_type );
45
46 foreach ( $headers as $name => $value ) {
47 $response->header( (string) $name, (string) $value );
48 }
49
50 $served = false;
51 add_filter(
52 'rest_pre_serve_request',
53 static function ( $served_result, $result ) use ( $response, &$served ) {
54 // `true === $served_result` means an earlier handler already wrote
55 // the body. Echoing again would append to it and corrupt the file —
56 // a receipt PDF the browser then refuses to open. The own-flag check
57 // below cannot see that: it only knows about THIS closure. Moving to
58 // priority 30 widened the window by putting more handlers ahead of
59 // us, so the guard has to look at what WordPress reports, not just
60 // at what we remember doing.
61 if ( true === $served_result || $served || $result !== $response ) {
62 return $served_result;
63 }
64 $served = true;
65 echo $response->get_raw_body(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Raw response bytes.
66
67 return true;
68 },
69 // AFTER the wire contract at 20 ({@see \WCPOS\WooCommercePOS\Rest_Cors}):
70 // echoing the body sends the headers, and CORS headers written after
71 // that are dropped — a receipt PDF the browser then refuses to read.
72 30,
73 2
74 );
75
76 return $response;
77 }
78
79 /**
80 * Get the raw response body for tests and direct consumers.
81 *
82 * @return string
83 */
84 public function get_raw_body(): string {
85 return $this->raw_body;
86 }
87 }
88