PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.10.16
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.10.16
1.10.19 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 All 163 releases
woocommerce-pos / includes / Services / Settings / Visibility_Section.php

Visibility_Section.php in WCPOS – Point of Sale (POS) plugin for WooCommerce 1.10.16, at includes/Services/Settings/Visibility_Section.php

425 lines 12.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Visibility Settings Section.
4 *
5 * @package WCPOS\WooCommercePOS
6 */
7
8 namespace WCPOS\WooCommercePOS\Services\Settings;
9
10 use WP_Error;
11 use WCPOS\WooCommercePOS\Interfaces\Settings_Section_Interface;
12
13 /**
14 * The Visibility Settings Section: POS-only / online-only id lists for
15 * products and variations, per scope.
16 */
17 class Visibility_Section extends Abstract_Section {
18 /**
19 * Registered section providing the visibility storage surface.
20 *
21 * @var null|Settings_Section_Interface
22 */
23 private $storage;
24
25 /**
26 * Constructor.
27 *
28 * @param null|Settings_Section_Interface $storage Registered visibility section override.
29 */
30 public function __construct( ?Settings_Section_Interface $storage = null ) {
31 $this->storage = $storage;
32 }
33
34 /** {@inheritDoc} */
35 public function read(): array {
36 return $this->storage ? $this->storage->read() : parent::read();
37 }
38
39 /**
40 * {@inheritDoc}
41 *
42 * @param array $settings The full visibility settings array to persist.
43 */
44 public function write( array $settings ) {
45 return $this->storage ? $this->storage->write( $settings ) : parent::write( $settings );
46 }
47
48 /**
49 * Section id.
50 */
51 public function id(): string {
52 return 'visibility';
53 }
54
55 /**
56 * Section defaults.
57 */
58 public function defaults(): array {
59 return array(
60 'products' => array(
61 'default' => array(
62 'pos_only' => array(
63 'ids' => array(),
64 ),
65 'online_only' => array(
66 'ids' => array(),
67 ),
68 ),
69 ),
70 'variations' => array(
71 'default' => array(
72 'pos_only' => array(
73 'ids' => array(),
74 ),
75 'online_only' => array(
76 'ids' => array(),
77 ),
78 ),
79 ),
80 );
81 }
82
83 /**
84 * Merge visibility settings.
85 *
86 * @param array $existing Existing settings view.
87 * @param array $patch Incoming partial payload.
88 */
89 public function merge( array $existing, array $patch ): array {
90 $settings = parent::merge( $existing, $patch );
91 foreach ( $patch as $post_type => $scopes ) {
92 foreach ( (array) $scopes as $scope => $visibilities ) {
93 foreach ( (array) $visibilities as $visibility => $values ) {
94 $current = $settings[ $post_type ][ $scope ][ $visibility ] ?? array();
95 $settings[ $post_type ][ $scope ][ $visibility ] = array_replace( (array) $current, (array) $values );
96 }
97 }
98 }
99 return $settings;
100 }
101
102 /**
103 * POS Visibility settings.
104 *
105 * @return array
106 */
107 public function get_visibility_settings(): array {
108 return $this->read();
109 }
110
111 /**
112 * Update visibility settings.
113 *
114 * @param array $args The visibility settings to update.
115 *
116 * @return bool|WP_Error True on success, WP_Error on failure.
117 */
118 public function update_visibility_settings( array $args ) {
119 // Validate and normalize arguments.
120 $defaults = $this->defaults();
121 if (
122 empty( $args['post_type'] )
123 || ! \is_string( $args['post_type'] )
124 || ! isset( $defaults[ $args['post_type'] ] )
125 || ! isset( $args['ids'] )
126 ) {
127 return new WP_Error(
128 'woocommerce_pos_settings_error',
129 /* translators: Error message shown when invalid arguments are provided. */
130 __( 'Invalid arguments provided', 'woocommerce-pos' ),
131 array( 'status' => 400 )
132 );
133 }
134
135 // Define valid visibility options.
136 $valid_options = array( 'pos_only', 'online_only', '' );
137
138 // Check if visibility is set and valid.
139 if ( ! isset( $args['visibility'] ) || ! \in_array( $args['visibility'], $valid_options, true ) ) {
140 return new WP_Error(
141 'woocommerce_pos_settings_error',
142 __( 'Invalid visibility option provided', 'woocommerce-pos' ),
143 array( 'status' => 400 )
144 );
145 }
146
147 $post_type = $args['post_type'];
148 $scope = $args['scope'] ?? 'default';
149 $visibility = $args['visibility'];
150 $ids = \is_array( $args['ids'] ) ? $args['ids'] : array( $args['ids'] );
151 $ids = array_filter( array_map( 'intval', $ids ) ); // Force to array of integers.
152
153 // Get the current visibility settings.
154 $current_settings = $this->get_visibility_settings();
155 $current_settings[ $post_type ][ $scope ] = array_replace_recursive(
156 $defaults[ $post_type ]['default'],
157 $current_settings[ $post_type ][ $scope ] ?? array()
158 );
159
160 // Define the opposite visibility type.
161 $opposite_visibility = ( 'pos_only' === $visibility ) ? 'online_only' : 'pos_only';
162
163 // Add or remove IDs based on the visibility type.
164 foreach ( $ids as $id ) {
165 if ( '' === $visibility ) {
166 // Remove from both pos_only and online_only.
167 $current_settings[ $post_type ][ $scope ]['pos_only']['ids'] = $this->remove_id_from_visibility(
168 $current_settings[ $post_type ][ $scope ]['pos_only']['ids'],
169 $id
170 );
171 $current_settings[ $post_type ][ $scope ]['online_only']['ids'] = $this->remove_id_from_visibility(
172 $current_settings[ $post_type ][ $scope ]['online_only']['ids'],
173 $id
174 );
175 } else {
176 // Add to the specified visibility type.
177 $current_settings[ $post_type ][ $scope ][ $visibility ]['ids'] = $this->add_id_to_visibility(
178 $current_settings[ $post_type ][ $scope ][ $visibility ]['ids'],
179 $id
180 );
181 // Remove from the opposite visibility type.
182 $current_settings[ $post_type ][ $scope ][ $opposite_visibility ]['ids'] = $this->remove_id_from_visibility(
183 $current_settings[ $post_type ][ $scope ][ $opposite_visibility ]['ids'],
184 $id
185 );
186 }
187 }
188
189 return $this->write( $current_settings );
190 }
191
192 /**
193 * Get product visibility settings.
194 *
195 * @param string $scope The scope of the settings to get. 'default' or store ID.
196 *
197 * @return array $settings The product visibility settings, eg: { pos_only: { ids: [1, 2, 3] }, online_only: { ids: [4, 5, 6] }
198 */
199 public function get_product_visibility_settings( $scope = 'default' ) {
200 $settings = $this->get_visibility_settings();
201
202 /*
203 * Filters the product visibility settings.
204 *
205 * @param {array} $settings
206 * @returns {array} $settings
207 * @since 1.0.0
208 * @hook woocommerce_pos_product_visibility_settings
209 */
210 return apply_filters( 'woocommerce_pos_product_visibility_settings', $settings['products'][ $scope ], $scope );
211 }
212
213 /**
214 * Get product visibility settings.
215 *
216 * @param string $scope The scope of the settings to get. 'default' or store ID.
217 *
218 * @return array $settings The product visibility settings, eg: { ids: [1, 2, 3] }
219 */
220 public function get_pos_only_product_visibility_settings( $scope = 'default' ) {
221 $settings = $this->get_product_visibility_settings( $scope );
222
223 /*
224 * Filters the product visibility settings.
225 *
226 * @param {array} $settings
227 * @returns {array} $settings
228 * @since 1.0.0
229 * @hook woocommerce_pos_product_visibility_settings
230 */
231 return apply_filters( 'woocommerce_pos_pos_only_product_visibility_settings', $settings['pos_only'], $scope );
232 }
233
234 /**
235 * Get product visibility settings.
236 *
237 * @param string $scope The scope of the settings to get. 'default' or store ID.
238 *
239 * @return array $settings The product visibility settings, eg: { ids: [1, 2, 3] }
240 */
241 public function get_online_only_product_visibility_settings( $scope = 'default' ) {
242 $settings = $this->get_product_visibility_settings( $scope );
243
244 /*
245 * Filters the product visibility settings.
246 *
247 * @param {array} $settings
248 * @returns {array} $settings
249 * @since 1.0.0
250 * @hook woocommerce_pos_product_visibility_settings
251 */
252 return apply_filters( 'woocommerce_pos_online_only_product_visibility_settings', $settings['online_only'], $scope );
253 }
254
255 /**
256 * Get product visibility settings.
257 *
258 * @param string $scope The scope of the settings to get. 'default' or store ID.
259 *
260 * @return array $settings The product visibility settings, eg: { pos_only: { ids: [1, 2, 3] }, online_only: { ids: [4, 5, 6] }
261 */
262 public function get_variations_visibility_settings( $scope = 'default' ) {
263 $settings = $this->get_visibility_settings();
264
265 /*
266 * Filters the product visibility settings.
267 *
268 * @param {array} $settings
269 * @returns {array} $settings
270 * @since 1.0.0
271 * @hook woocommerce_pos_product_visibility_settings
272 */
273 return apply_filters( 'woocommerce_pos_variations_visibility_settings', $settings['variations'][ $scope ], $scope );
274 }
275
276 /**
277 * Get product visibility settings.
278 *
279 * @param string $scope The scope of the settings to get. 'default' or store ID.
280 *
281 * @return array $settings The product visibility settings, eg: { ids: [1, 2, 3] }
282 */
283 public function get_pos_only_variations_visibility_settings( $scope = 'default' ) {
284 $settings = $this->get_variations_visibility_settings( $scope );
285
286 /*
287 * Filters the product visibility settings.
288 *
289 * @param {array} $settings
290 * @returns {array} $settings
291 * @since 1.0.0
292 * @hook woocommerce_pos_product_visibility_settings
293 */
294 return apply_filters( 'woocommerce_pos_pos_only_variations_visibility_settings', $settings['pos_only'], $scope );
295 }
296
297 /**
298 * Get product visibility settings.
299 *
300 * @param string $scope The scope of the settings to get. 'default' or store ID.
301 *
302 * @return array $settings The product visibility settings, eg: { ids: [1, 2, 3] }
303 */
304 public function get_online_only_variations_visibility_settings( $scope = 'default' ) {
305 $settings = $this->get_variations_visibility_settings( $scope );
306
307 /*
308 * Filters the product visibility settings.
309 *
310 * @param {array} $settings
311 * @returns {array} $settings
312 * @since 1.0.0
313 * @hook woocommerce_pos_product_visibility_settings
314 */
315 return apply_filters( 'woocommerce_pos_online_only_variations_visibility_settings', $settings['online_only'], $scope );
316 }
317
318 /**
319 * Check if a product is POS only.
320 *
321 * @param int|string $product_id The product ID.
322 *
323 * @return bool
324 */
325 public function is_product_pos_only( $product_id ) {
326 $product_id = (int) $product_id;
327 $settings = $this->get_pos_only_product_visibility_settings();
328 $pos_only_ids = array_map( 'intval', (array) $settings['ids'] );
329
330 return \in_array( $product_id, $pos_only_ids, true );
331 }
332
333 /**
334 * Check if a product is Online only.
335 *
336 * @param int|string $product_id The product ID.
337 *
338 * @return bool
339 */
340 public function is_product_online_only( $product_id ) {
341 $product_id = (int) $product_id;
342 $settings = $this->get_online_only_product_visibility_settings();
343 $online_only_ids = array_map( 'intval', (array) $settings['ids'] );
344
345 return \in_array( $product_id, $online_only_ids, true );
346 }
347
348 /**
349 * Check if a variation is POS only.
350 *
351 * @param int|string $variation_id The variation ID.
352 *
353 * @return bool
354 */
355 public function is_variation_pos_only( $variation_id ) {
356 $variation_id = (int) $variation_id;
357 $settings = $this->get_pos_only_variations_visibility_settings();
358 $pos_only_ids = array_map( 'intval', (array) $settings['ids'] );
359
360 return \in_array( $variation_id, $pos_only_ids, true );
361 }
362
363 /**
364 * Check if a variation is Online only.
365 *
366 * @param int|string $variation_id The variation ID.
367 *
368 * @return bool
369 */
370 public function is_variation_online_only( $variation_id ) {
371 $variation_id = (int) $variation_id;
372 $settings = $this->get_online_only_variations_visibility_settings();
373 $online_only_ids = array_map( 'intval', (array) $settings['ids'] );
374
375 return \in_array( $variation_id, $online_only_ids, true );
376 }
377
378 /**
379 * Add an ID to a visibility type if it doesn't already exist.
380 *
381 * @param array $ids The current array of IDs.
382 * @param int $id The ID to add.
383 *
384 * @return array The updated array of IDs.
385 */
386 private function add_id_to_visibility( array $ids, int $id ): array {
387 if ( ! \in_array( $id, $ids, true ) ) {
388 $ids[] = $id;
389 }
390
391 return $ids;
392 }
393
394 /**
395 * Remove an ID from a visibility type if it exists.
396 *
397 * @param array $ids The current array of IDs.
398 * @param int $id The ID to remove.
399 *
400 * @return array The updated array of IDs.
401 */
402 private function remove_id_from_visibility( array $ids, int $id ): array {
403 return array_filter(
404 $ids,
405 function ( $existing_id ) use ( $id ) {
406 return $existing_id !== $id;
407 }
408 );
409 }
410
411 /** {@inheritDoc} */
412 public function endpoint_args(): array {
413 $validate = static function ( $param ): bool {
414 return is_array( $param ) && ! array_filter(
415 $param,
416 static fn( $scope ): bool => ! is_array( $scope ) || (bool) array_filter(
417 (array) $scope,
418 static fn( $visibility ): bool => ! is_array( $visibility ) || ! is_array( $visibility['ids'] ?? null )
419 )
420 );
421 };
422 return array_fill_keys( array( 'products', 'variations' ), array( 'validate_callback' => $validate ) );
423 }
424 }
425