PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.10.18
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.10.18
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 / API / V2 / Writers / Variation_Writer.php

Variation_Writer.php in WCPOS – Point of Sale (POS) plugin for WooCommerce 1.10.18, at includes/API/V2/Writers/Variation_Writer.php

139 lines 5.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Variation collection writer.
4 *
5 * @package WCPOS\WooCommercePOS\API\V2\Writers
6 */
7
8 // phpcs:disable Squiz.Commenting, Generic.Commenting -- Lifecycle docblocks are intentionally concise.
9
10 namespace WCPOS\WooCommercePOS\API\V2\Writers;
11
12 use WC_Product;
13 use WC_Product_Variation;
14 use WCPOS\WooCommercePOS\Sync\Digest_Index;
15 use WCPOS\WooCommercePOS\Sync\Pos_Uuid;
16 use WCPOS\WooCommercePOS\Sync\Product_Serializer;
17 use WP_Error;
18 use WP_REST_Request;
19 use WP_REST_Response;
20
21 /** Enforces variation parents, nested routes, and wrapper documents. */
22 class Variation_Writer extends Null_Writer {
23 /** Prepare a nested variation create. */
24 public function prepare_create( array $meta, array $payload, callable $validate_tax_ids ) {
25 $parent_id = $this->required_parent_id( $payload );
26 if ( $parent_id instanceof WP_REST_Response ) {
27 return $parent_id;
28 }
29 return array(
30 'method' => 'POST',
31 'route' => $meta['route'] . '/' . $parent_id . '/variations',
32 'payload' => $payload,
33 'context' => array( 'parent_id' => $parent_id ),
34 );
35 }
36
37 /** Prepare a nested variation update. */
38 public function prepare_update( array $meta, int $id, array $payload, callable $validate_tax_ids ) {
39 $variation = $this->variation( $id );
40 if ( is_wp_error( $variation ) ) {
41 return $variation;
42 }
43 $parent_id = (int) $variation->get_parent_id();
44 if ( array_key_exists( 'parent_id', $payload ) && ( ! is_int( $payload['parent_id'] ) || $parent_id !== $payload['parent_id'] ) ) {
45 return $this->parent_mismatch();
46 }
47 return array(
48 'method' => 'PUT',
49 'route' => $meta['route'] . '/' . $parent_id . '/variations/' . $id,
50 'payload' => $payload,
51 'context' => array( 'parent_id' => $parent_id ),
52 );
53 }
54
55 /** Confirm a born-twice variation still belongs to the requested parent. */
56 public function validate_existing_create( int $id, array $payload, array $prepared ) {
57 $variation = $this->variation( $id );
58 if ( is_wp_error( $variation ) ) {
59 return $variation;
60 }
61 return (int) $variation->get_parent_id() === (int) $prepared['context']['parent_id'] ? null : $this->parent_mismatch();
62 }
63
64 /** Delete through the stored parent's nested route. */
65 public function delete( array $meta, int $id, array $mutation, callable $dispatch, callable $can_delete ) {
66 $variation = $this->variation( $id );
67 if ( is_wp_error( $variation ) ) {
68 return $variation;
69 }
70 $route = $meta['route'] . '/' . (int) $variation->get_parent_id() . '/variations/' . $id;
71 return $dispatch( $this->delete_request( $route, $id, true ) );
72 }
73
74 /** Build the targeted variation wrapper document. */
75 public function document( array $meta, int $id, callable $default_document ) {
76 $variation = $this->variation( $id );
77 if ( is_wp_error( $variation ) ) {
78 return $variation;
79 }
80 $payload = ( new Product_Serializer() )->serialize( $variation, new WP_REST_Request( 'GET', '/' ) );
81 $document = array(
82 'id' => $id,
83 'parent_id' => (int) $variation->get_parent_id(),
84 'payload' => $payload,
85 );
86 if ( class_exists( Digest_Index::class ) ) {
87 $digests = ( new Digest_Index() )->read_digests( 'products', array( $id ) );
88 if ( isset( $digests[ $id ] ) ) {
89 $document['_rxdb_digest'] = $digests[ $id ];
90 }
91 }
92 return new WP_REST_Response( $document, 200 );
93 }
94
95 /** Put the stable UUID inside the variation payload wrapper. */
96 public function build_response_document( array $bare, string $record_id, array $meta, int $id, callable $default_builder ): array {
97 $payload = isset( $bare['payload'] ) && is_array( $bare['payload'] ) ? $bare['payload'] : array();
98 $bare['payload'] = Pos_Uuid::ensure_in_payload( $payload, $record_id );
99 return $bare;
100 }
101
102 /** Require a live variable parent for create. */
103 private function required_parent_id( array $payload ) {
104 $parent_id = isset( $payload['parent_id'] ) && is_int( $payload['parent_id'] ) ? $payload['parent_id'] : 0;
105 $parent = $parent_id > 0 && function_exists( 'wc_get_product' ) ? wc_get_product( $parent_id ) : false;
106 if ( ! $parent instanceof WC_Product || $parent instanceof WC_Product_Variation
107 || ( method_exists( $parent, 'is_type' ) && ! $parent->is_type( 'variable' ) )
108 || ( method_exists( $parent, 'get_status' ) && 'trash' === $parent->get_status() ) ) {
109 return new WP_REST_Response(
110 array(
111 'code' => 'woo_rxdb_sync_parent_required',
112 'message' => 'Creating a variation requires a live parent product.',
113 ),
114 428
115 );
116 }
117 return $parent_id;
118 }
119
120 /** Build the stable parent mismatch response. */
121 private function parent_mismatch(): WP_REST_Response {
122 return new WP_REST_Response(
123 array(
124 'code' => 'woo_rxdb_sync_parent_mismatch',
125 'message' => 'payload parent_id does not match the stored variation parent.',
126 ),
127 409
128 );
129 }
130
131 /** Load only a real variation. */
132 private function variation( int $id ) {
133 $variation = function_exists( 'wc_get_product' ) ? wc_get_product( $id ) : false;
134 return $variation instanceof WC_Product_Variation
135 ? $variation
136 : new WP_Error( 'woo_rxdb_sync_record_not_found', 'No variation for recordId.', array( 'status' => 404 ) );
137 }
138 }
139