PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / trunk
WCPOS – Point of Sale (POS) plugin for WooCommerce vtrunk
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 1.9.12 1.9.11 1.9.10 1.9.9 All 158 releases
woocommerce-pos / includes / Services / Provider.php

Provider.php in WCPOS – Point of Sale (POS) plugin for WooCommerce trunk, at includes/Services/Provider.php

273 lines 8.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Cloud-print provider capabilities value object.
4 *
5 * Single source of truth for per-provider knowledge: validity, the default for
6 * rows without a provider, polling, content types, poll endpoints, server
7 * diagnostics, thermal wire formats and renderable template engines.
8 *
9 * @package WCPOS\WooCommercePOS\Services
10 */
11
12 namespace WCPOS\WooCommercePOS\Services;
13
14 use WCPOS\WooCommercePOS\Interfaces\Provider_Adapter_Interface;
15 use WCPOS\WooCommercePOS\Services\Providers\Epson_Sdp_Adapter;
16 use WCPOS\WooCommercePOS\Services\Providers\Printnode_Adapter;
17 use WCPOS\WooCommercePOS\Services\Providers\Star_Cloudprnt_Adapter;
18 use WCPOS\WooCommercePOS\Services\Providers\Star_Online_Adapter;
19
20 /**
21 * Provider class.
22 */
23 class Provider {
24 /**
25 * Provider assumed for printer rows that predate the provider field.
26 *
27 * Star CloudPRNT was the only provider before the field existed, so a row
28 * without one is a Star CloudPRNT printer.
29 */
30 public const DEFAULT_PROVIDER = 'star-cloudprnt';
31
32 /**
33 * Per-provider capability map.
34 *
35 * @var array<string, array<string, mixed>>
36 */
37 private const CAPABILITIES = array(
38 // StarPRNT-native printers (the whole TSP100 line) cannot decode
39 // ESC/POS; Star's docs advise against octet-stream for command data,
40 // so jobs are emitted as native StarPRNT under the vnd.star type.
41 'star-cloudprnt' => array(
42 'polling' => true,
43 'content_type' => 'application/vnd.star.starprnt',
44 'poll_endpoint' => 'cloudprnt',
45 'supports_server_diagnostic' => true,
46 'thermal_wire_format' => 'starprnt',
47 'template_engines' => 'thermal',
48 'stores_job_kind' => false,
49 // The StarPRNT emitter emits a native drawer pulse (and inserts one
50 // before the trailing cut when a job asks for it), so drawer metadata
51 // has to survive to render time.
52 'supports_drawer' => true,
53 ),
54 'epson-sdp' => array(
55 'polling' => true,
56 'content_type' => 'application/xml',
57 'poll_endpoint' => 'epson-sdp',
58 'supports_server_diagnostic' => true,
59 'thermal_wire_format' => 'epos-xml',
60 'template_engines' => 'thermal',
61 'stores_job_kind' => false,
62 'supports_drawer' => true,
63 ),
64 'printnode' => array(
65 'polling' => false,
66 'content_type' => 'application/pdf',
67 'poll_endpoint' => null,
68 'supports_server_diagnostic' => false,
69 'thermal_wire_format' => null,
70 'template_engines' => 'all',
71 'stores_job_kind' => true,
72 'supports_drawer' => true,
73 ),
74 'star-online' => array(
75 'polling' => false,
76 'content_type' => 'text/vnd.star.markup',
77 'poll_endpoint' => null,
78 'supports_server_diagnostic' => false,
79 'thermal_wire_format' => 'star-markup',
80 'template_engines' => 'thermal',
81 'stores_job_kind' => false,
82 'supports_drawer' => false,
83 ),
84 );
85
86 /**
87 * List of valid provider keys.
88 *
89 * @return array<int, string>
90 */
91 public static function valid(): array {
92 return array_keys( self::CAPABILITIES );
93 }
94
95 /**
96 * Resolve a stored printer row's provider to a known provider key.
97 *
98 * Callers read `$printer['provider']` from an option that predates the
99 * field, so the value can be missing, empty, or (for hand-edited options)
100 * a key this build does not know. All three resolve to the default rather
101 * than to a silent no-provider state.
102 *
103 * @param string|null $provider Raw provider value from a printer row.
104 *
105 * @return string A key from self::valid().
106 */
107 public static function normalize( ?string $provider ): string {
108 return \in_array( $provider, self::valid(), true ) ? (string) $provider : self::DEFAULT_PROVIDER;
109 }
110
111 /**
112 * Resolve a provider adapter.
113 *
114 * An empty legacy-row value uses normalize()'s Star CloudPRNT default;
115 * non-empty unknown keys remain unknown and return null.
116 *
117 * @param string $provider Provider key or empty legacy-row value.
118 *
119 * @return Provider_Adapter_Interface|null
120 */
121 public static function adapter( string $provider ): ?Provider_Adapter_Interface {
122 $provider = '' === $provider ? self::normalize( $provider ) : $provider;
123
124 switch ( $provider ) {
125 case 'star-cloudprnt':
126 return new Star_Cloudprnt_Adapter();
127 case 'epson-sdp':
128 return new Epson_Sdp_Adapter();
129 case 'printnode':
130 return new Printnode_Adapter();
131 case 'star-online':
132 return new Star_Online_Adapter();
133 default:
134 return null;
135 }
136 }
137
138 /**
139 * Whether the provider polls the server for jobs.
140 *
141 * @param string $provider Provider key.
142 *
143 * @return bool
144 */
145 public static function is_polling( string $provider ): bool {
146 return (bool) ( self::CAPABILITIES[ $provider ]['polling'] ?? false );
147 }
148
149 /**
150 * Whether the provider needs an out-of-band submit (we push jobs to it),
151 * as opposed to a polling provider that fetches jobs itself.
152 *
153 * @param string $provider Provider key.
154 *
155 * @return bool
156 */
157 public static function requires_submit( string $provider ): bool {
158 return \in_array( $provider, self::valid(), true ) && ! self::is_polling( $provider );
159 }
160
161 /**
162 * HTTP content type for the provider's job payloads.
163 *
164 * @param string $provider Provider key.
165 *
166 * @return string
167 */
168 public static function content_type( string $provider ): string {
169 return (string) ( self::CAPABILITIES[ $provider ]['content_type'] ?? 'application/octet-stream' );
170 }
171
172 /**
173 * REST poll-endpoint slug for the provider.
174 *
175 * @param string $provider Provider key.
176 *
177 * @return string|null
178 */
179 public static function poll_endpoint( string $provider ): ?string {
180 return self::CAPABILITIES[ $provider ]['poll_endpoint'] ?? null;
181 }
182
183 /**
184 * Whether the provider supports a server-built diagnostic payload.
185 *
186 * @param string $provider Provider key.
187 *
188 * @return bool
189 */
190 public static function supports_server_diagnostic( string $provider ): bool {
191 return (bool) ( self::CAPABILITIES[ $provider ]['supports_server_diagnostic'] ?? false );
192 }
193
194 /**
195 * Thermal wire format for the given provider/engine pair.
196 *
197 * Only the 'thermal' engine on a direct printer yields a wire format;
198 * any other engine, or an unknown provider, returns null.
199 *
200 * @param string $provider Provider key.
201 * @param string $engine Render engine (e.g. 'thermal', 'logicless').
202 *
203 * @return string|null
204 */
205 public static function wire_format( string $provider, string $engine ): ?string {
206 if ( 'thermal' !== $engine ) {
207 return null;
208 }
209
210 return self::CAPABILITIES[ $provider ]['thermal_wire_format'] ?? null;
211 }
212
213 /**
214 * Receipt-template engines the provider can render for automatic jobs.
215 *
216 * 'all' means every active template; 'thermal' means thermal templates
217 * only. Unknown providers are treated as thermal-only, the conservative
218 * answer for a printer we cannot render a PDF for.
219 *
220 * @param string $provider Provider key.
221 *
222 * @return string 'all' or 'thermal'.
223 */
224 public static function template_engines( string $provider ): string {
225 return (string) ( self::CAPABILITIES[ $provider ]['template_engines'] ?? 'thermal' );
226 }
227
228 /**
229 * Whether jobs for the provider persist their resolved kind separately.
230 *
231 * @param string $provider Provider key.
232 *
233 * @return bool
234 */
235 public static function stores_job_kind( string $provider ): bool {
236 return (bool) ( self::CAPABILITIES[ $provider ]['stores_job_kind'] ?? false );
237 }
238
239 /**
240 * Whether the provider supports the generic drawer metadata contract.
241 *
242 * @param string $provider Provider key.
243 *
244 * @return bool
245 */
246 public static function supports_drawer( string $provider ): bool {
247 return (bool) ( self::CAPABILITIES[ $provider ]['supports_drawer'] ?? false );
248 }
249
250 /**
251 * Per-provider facts the settings screen cannot derive, keyed by provider.
252 *
253 * Projected onto the cloud-print settings response (cf.
254 * Cloud_Print_Relay_Service::public_state()) so the admin app can read the
255 * provider table from the server instead of re-declaring it. Deliberately
256 * narrow: presentation (labels, badges) stays in the client, and facts the
257 * client already renders from its own table are not duplicated here until
258 * something reads them.
259 *
260 * @return array<string, array<string, string>>
261 */
262 public static function public_capabilities(): array {
263 $capabilities = array();
264 foreach ( self::valid() as $provider ) {
265 $capabilities[ $provider ] = array(
266 'template_engines' => self::template_engines( $provider ),
267 );
268 }
269
270 return $capabilities;
271 }
272 }
273