1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Class WC_Product_Variation_Data_Store_CPT file. |
4
|
|
|
* |
5
|
|
|
* @package WooCommerce\DataStores |
6
|
|
|
*/ |
7
|
|
|
|
8
|
|
|
if ( ! defined( 'ABSPATH' ) ) { |
9
|
|
|
exit; |
10
|
|
|
} |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* WC Variation Product Data Store: Stored in CPT. |
14
|
|
|
* |
15
|
|
|
* @version 3.0.0 |
16
|
|
|
*/ |
17
|
|
|
class WC_Product_Variation_Data_Store_CPT extends WC_Product_Data_Store_CPT implements WC_Object_Data_Store_Interface { |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Callback to remove unwanted meta data. |
21
|
|
|
* |
22
|
|
|
* @param object $meta Meta object. |
23
|
|
|
* @return bool false if excluded. |
24
|
|
|
*/ |
25
|
15 |
|
protected function exclude_internal_meta_keys( $meta ) { |
26
|
15 |
|
return ! in_array( $meta->meta_key, $this->internal_meta_keys, true ) && 0 !== stripos( $meta->meta_key, 'attribute_' ) && 0 !== stripos( $meta->meta_key, 'wp_' ); |
27
|
|
|
} |
28
|
|
|
|
29
|
|
|
/* |
30
|
|
|
|-------------------------------------------------------------------------- |
31
|
|
|
| CRUD Methods |
32
|
|
|
|-------------------------------------------------------------------------- |
33
|
|
|
*/ |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* Reads a product from the database and sets its data to the class. |
37
|
|
|
* |
38
|
|
|
* @since 3.0.0 |
39
|
|
|
* @param WC_Product $product Product object. $product Product object. |
40
|
|
|
*/ |
41
|
60 |
|
public function read( &$product ) { |
42
|
60 |
|
$product->set_defaults(); |
43
|
|
|
|
44
|
60 |
|
if ( ! $product->get_id() ) { |
45
|
|
|
return; |
46
|
|
|
} |
47
|
|
|
|
48
|
60 |
|
$post_object = get_post( $product->get_id() ); |
49
|
|
|
|
50
|
60 |
View Code Duplication |
if ( ! $post_object || ! in_array( $post_object->post_type, array( 'product', 'product_variation' ), true ) ) { |
51
|
|
|
return; |
52
|
|
|
} |
53
|
|
|
|
54
|
60 |
|
$product->set_props( |
55
|
|
|
array( |
56
|
60 |
|
'name' => $post_object->post_title, |
57
|
60 |
|
'slug' => $post_object->post_name, |
58
|
60 |
|
'date_created' => 0 < $post_object->post_date_gmt ? wc_string_to_timestamp( $post_object->post_date_gmt ) : null, |
59
|
60 |
|
'date_modified' => 0 < $post_object->post_modified_gmt ? wc_string_to_timestamp( $post_object->post_modified_gmt ) : null, |
60
|
60 |
|
'status' => $post_object->post_status, |
61
|
60 |
|
'menu_order' => $post_object->menu_order, |
62
|
60 |
|
'reviews_allowed' => 'open' === $post_object->comment_status, |
63
|
60 |
|
'parent_id' => $post_object->post_parent, |
64
|
|
|
) |
65
|
|
|
); |
66
|
|
|
|
67
|
|
|
// The post parent is not a valid variable product so we should prevent this. |
68
|
60 |
|
if ( $product->get_parent_id( 'edit' ) && 'product' !== get_post_type( $product->get_parent_id( 'edit' ) ) ) { |
69
|
|
|
$product->set_parent_id( 0 ); |
70
|
|
|
} |
71
|
|
|
|
72
|
60 |
|
$this->read_downloads( $product ); |
73
|
60 |
|
$this->read_product_data( $product ); |
74
|
60 |
|
$this->read_extra_data( $product ); |
75
|
60 |
|
$product->set_attributes( wc_get_product_variation_attributes( $product->get_id() ) ); |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* If a variation title is not in sync with the parent e.g. saved prior to 3.0, or if the parent title has changed, detect here and update. |
79
|
|
|
*/ |
80
|
60 |
|
$new_title = $this->generate_product_title( $product ); |
81
|
|
|
|
82
|
60 |
|
if ( $post_object->post_title !== $new_title ) { |
83
|
51 |
|
$product->set_name( $new_title ); |
84
|
51 |
|
$GLOBALS['wpdb']->update( $GLOBALS['wpdb']->posts, array( 'post_title' => $new_title ), array( 'ID' => $product->get_id() ) ); |
85
|
51 |
|
clean_post_cache( $product->get_id() ); |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
// Set object_read true once all data is read. |
89
|
60 |
|
$product->set_object_read( true ); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* Create a new product. |
94
|
|
|
* |
95
|
|
|
* @since 3.0.0 |
96
|
|
|
* @param WC_Product $product Product object. |
97
|
|
|
*/ |
98
|
60 |
|
public function create( &$product ) { |
99
|
60 |
|
if ( ! $product->get_date_created() ) { |
100
|
60 |
|
$product->set_date_created( current_time( 'timestamp', true ) ); |
101
|
|
|
} |
102
|
|
|
|
103
|
60 |
|
$new_title = $this->generate_product_title( $product ); |
104
|
|
|
|
105
|
60 |
|
if ( $product->get_name( 'edit' ) !== $new_title ) { |
106
|
58 |
|
$product->set_name( $new_title ); |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
// The post parent is not a valid variable product so we should prevent this. |
110
|
60 |
|
if ( $product->get_parent_id( 'edit' ) && 'product' !== get_post_type( $product->get_parent_id( 'edit' ) ) ) { |
111
|
|
|
$product->set_parent_id( 0 ); |
112
|
|
|
} |
113
|
|
|
|
114
|
60 |
|
$id = wp_insert_post( |
115
|
60 |
|
apply_filters( |
116
|
60 |
|
'woocommerce_new_product_variation_data', |
117
|
60 |
|
array( |
118
|
60 |
|
'post_type' => 'product_variation', |
119
|
60 |
|
'post_status' => $product->get_status() ? $product->get_status() : 'publish', |
120
|
60 |
|
'post_author' => get_current_user_id(), |
121
|
60 |
|
'post_title' => $product->get_name( 'edit' ), |
122
|
60 |
|
'post_content' => '', |
123
|
60 |
|
'post_parent' => $product->get_parent_id(), |
124
|
60 |
|
'comment_status' => 'closed', |
125
|
60 |
|
'ping_status' => 'closed', |
126
|
60 |
|
'menu_order' => $product->get_menu_order(), |
127
|
60 |
|
'post_date' => gmdate( 'Y-m-d H:i:s', $product->get_date_created( 'edit' )->getOffsetTimestamp() ), |
128
|
60 |
|
'post_date_gmt' => gmdate( 'Y-m-d H:i:s', $product->get_date_created( 'edit' )->getTimestamp() ), |
129
|
|
|
'post_name' => $product->get_slug( 'edit' ), |
130
|
60 |
|
) |
131
|
|
|
), |
132
|
|
|
true |
133
|
60 |
|
); |
134
|
60 |
|
|
135
|
|
View Code Duplication |
if ( $id && ! is_wp_error( $id ) ) { |
136
|
60 |
|
$product->set_id( $id ); |
137
|
60 |
|
|
138
|
60 |
|
$this->update_post_meta( $product, true ); |
139
|
60 |
|
$this->update_terms( $product, true ); |
140
|
60 |
|
$this->update_visibility( $product, true ); |
141
|
|
|
$this->update_attributes( $product, true ); |
142
|
60 |
|
$this->handle_updated_props( $product ); |
143
|
60 |
|
|
144
|
|
|
$product->save_meta_data(); |
145
|
60 |
|
$product->apply_changes(); |
146
|
|
|
|
147
|
60 |
|
$this->update_version_and_type( $product ); |
148
|
|
|
$this->update_guid( $product ); |
149
|
60 |
|
|
150
|
|
|
$this->clear_caches( $product ); |
151
|
|
|
|
152
|
|
|
do_action( 'woocommerce_new_product_variation', $id ); |
153
|
|
|
} |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* Updates an existing product. |
158
|
|
|
* |
159
|
16 |
|
* @since 3.0.0 |
160
|
16 |
|
* @param WC_Product $product Product object. |
161
|
|
|
*/ |
162
|
16 |
|
public function update( &$product ) { |
163
|
|
|
$product->save_meta_data(); |
164
|
|
|
|
165
|
|
|
if ( ! $product->get_date_created() ) { |
166
|
16 |
|
$product->set_date_created( current_time( 'timestamp', true ) ); |
167
|
|
|
} |
168
|
16 |
|
|
169
|
2 |
|
$new_title = $this->generate_product_title( $product ); |
170
|
|
|
|
171
|
|
|
if ( $product->get_name( 'edit' ) !== $new_title ) { |
172
|
|
|
$product->set_name( $new_title ); |
173
|
16 |
|
} |
174
|
|
|
|
175
|
|
|
// The post parent is not a valid variable product so we should prevent this. |
176
|
|
|
if ( $product->get_parent_id( 'edit' ) && 'product' !== get_post_type( $product->get_parent_id( 'edit' ) ) ) { |
177
|
16 |
|
$product->set_parent_id( 0 ); |
178
|
|
|
} |
179
|
|
|
|
180
|
16 |
|
$changes = $product->get_changes(); |
181
|
|
|
|
182
|
3 |
|
// Only update the post when the post data changes. |
183
|
3 |
|
if ( array_intersect( array( 'name', 'parent_id', 'status', 'menu_order', 'date_created', 'date_modified' ), array_keys( $changes ) ) ) { |
184
|
3 |
|
$post_data = array( |
185
|
3 |
|
'post_title' => $product->get_name( 'edit' ), |
186
|
3 |
|
'post_parent' => $product->get_parent_id( 'edit' ), |
187
|
3 |
|
'comment_status' => 'closed', |
188
|
3 |
|
'post_status' => $product->get_status( 'edit' ) ? $product->get_status( 'edit' ) : 'publish', |
189
|
3 |
|
'menu_order' => $product->get_menu_order( 'edit' ), |
190
|
3 |
|
'post_date' => gmdate( 'Y-m-d H:i:s', $product->get_date_created( 'edit' )->getOffsetTimestamp() ), |
191
|
3 |
|
'post_date_gmt' => gmdate( 'Y-m-d H:i:s', $product->get_date_created( 'edit' )->getTimestamp() ), |
192
|
3 |
|
'post_modified' => isset( $changes['date_modified'] ) ? gmdate( 'Y-m-d H:i:s', $product->get_date_modified( 'edit' )->getOffsetTimestamp() ) : current_time( 'mysql' ), |
193
|
|
|
'post_modified_gmt' => isset( $changes['date_modified'] ) ? gmdate( 'Y-m-d H:i:s', $product->get_date_modified( 'edit' )->getTimestamp() ) : current_time( 'mysql', 1 ), |
194
|
|
|
'post_type' => 'product_variation', |
195
|
|
|
'post_name' => $product->get_slug( 'edit' ), |
196
|
|
|
); |
197
|
|
|
|
198
|
|
|
/** |
199
|
|
|
* When updating this object, to prevent infinite loops, use $wpdb |
200
|
|
|
* to update data, since wp_update_post spawns more calls to the |
201
|
|
|
* save_post action. |
202
|
|
|
* |
203
|
3 |
|
* This ensures hooks are fired by either WP itself (admin screen save), |
204
|
|
|
* or an update purely from CRUD. |
205
|
|
|
*/ |
206
|
|
View Code Duplication |
if ( doing_action( 'save_post' ) ) { |
207
|
3 |
|
$GLOBALS['wpdb']->update( $GLOBALS['wpdb']->posts, $post_data, array( 'ID' => $product->get_id() ) ); |
208
|
|
|
clean_post_cache( $product->get_id() ); |
209
|
3 |
|
} else { |
210
|
|
|
wp_update_post( array_merge( array( 'ID' => $product->get_id() ), $post_data ) ); |
211
|
|
|
} |
212
|
13 |
|
$product->read_meta_data( true ); // Refresh internal meta data, in case things were hooked into `save_post` or another WP hook. |
213
|
13 |
|
|
214
|
|
View Code Duplication |
} else { // Only update post modified time to record this save event. |
215
|
13 |
|
$GLOBALS['wpdb']->update( |
216
|
13 |
|
$GLOBALS['wpdb']->posts, |
217
|
|
|
array( |
218
|
|
|
'post_modified' => current_time( 'mysql' ), |
219
|
13 |
|
'post_modified_gmt' => current_time( 'mysql', 1 ), |
220
|
|
|
), |
221
|
|
|
array( |
222
|
13 |
|
'ID' => $product->get_id(), |
223
|
|
|
) |
224
|
|
|
); |
225
|
16 |
|
clean_post_cache( $product->get_id() ); |
226
|
16 |
|
} |
227
|
16 |
|
|
228
|
16 |
|
$this->update_post_meta( $product ); |
229
|
16 |
|
$this->update_terms( $product ); |
230
|
|
|
$this->update_visibility( $product, true ); |
231
|
16 |
|
$this->update_attributes( $product ); |
232
|
|
|
$this->handle_updated_props( $product ); |
233
|
16 |
|
|
234
|
|
|
$product->apply_changes(); |
235
|
16 |
|
|
236
|
|
|
$this->update_version_and_type( $product ); |
237
|
16 |
|
|
238
|
|
|
$this->clear_caches( $product ); |
239
|
|
|
|
240
|
|
|
do_action( 'woocommerce_update_product_variation', $product->get_id() ); |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
/* |
244
|
|
|
|-------------------------------------------------------------------------- |
245
|
|
|
| Additional Methods |
246
|
|
|
|-------------------------------------------------------------------------- |
247
|
|
|
*/ |
248
|
|
|
|
249
|
|
|
/** |
250
|
|
|
* Generates a title with attribute information for a variation. |
251
|
|
|
* Products will get a title of the form "Name - Value, Value" or just "Name". |
252
|
|
|
* |
253
|
|
|
* @since 3.0.0 |
254
|
60 |
|
* @param WC_Product $product Product object. |
255
|
60 |
|
* @return string |
256
|
|
|
*/ |
257
|
|
|
protected function generate_product_title( $product ) { |
258
|
60 |
|
$attributes = (array) $product->get_attributes(); |
259
|
|
|
|
260
|
|
|
// Do not include attributes if the product has 3+ attributes. |
261
|
|
|
$should_include_attributes = count( $attributes ) < 3; |
262
|
60 |
|
|
263
|
4 |
|
// Do not include attributes if an attribute name has 2+ words and the |
264
|
4 |
|
// product has multiple attributes. |
265
|
|
|
if ( $should_include_attributes && 1 < count( $attributes ) ) { |
266
|
4 |
|
foreach ( $attributes as $name => $value ) { |
267
|
|
|
if ( false !== strpos( $name, '-' ) ) { |
268
|
|
|
$should_include_attributes = false; |
269
|
|
|
break; |
270
|
|
|
} |
271
|
60 |
|
} |
272
|
60 |
|
} |
273
|
60 |
|
|
274
|
60 |
|
$should_include_attributes = apply_filters( 'woocommerce_product_variation_title_include_attributes', $should_include_attributes, $product ); |
275
|
|
|
$separator = apply_filters( 'woocommerce_product_variation_title_attributes_separator', ' - ', $product ); |
276
|
60 |
|
$title_base = get_post_field( 'post_title', $product->get_parent_id() ); |
277
|
|
|
$title_suffix = $should_include_attributes ? wc_get_formatted_variation( $product, true, false ) : ''; |
278
|
|
|
|
279
|
|
|
return apply_filters( 'woocommerce_product_variation_title', $title_suffix ? $title_base . $separator . $title_suffix : $title_base, $product, $title_base, $title_suffix ); |
280
|
|
|
} |
281
|
|
|
|
282
|
|
|
/** |
283
|
|
|
* Make sure we store the product version (to track data changes). |
284
|
|
|
* |
285
|
60 |
|
* @param WC_Product $product Product object. |
286
|
60 |
|
* @since 3.0.0 |
287
|
60 |
|
*/ |
288
|
|
|
protected function update_version_and_type( &$product ) { |
289
|
|
|
wp_set_object_terms( $product->get_id(), '', 'product_type' ); |
290
|
|
|
update_post_meta( $product->get_id(), '_product_version', WC_VERSION ); |
291
|
|
|
} |
292
|
|
|
|
293
|
|
|
/** |
294
|
|
|
* Read post data. |
295
|
|
|
* |
296
|
|
|
* @since 3.0.0 |
297
|
60 |
|
* @param WC_Product $product Product object. |
298
|
60 |
|
* @throws WC_Data_Exception If WC_Product::set_tax_status() is called with an invalid tax status. |
299
|
|
|
*/ |
300
|
60 |
|
protected function read_product_data( &$product ) { |
301
|
|
|
$id = $product->get_id(); |
302
|
60 |
|
|
303
|
60 |
|
$product->set_props( |
304
|
60 |
|
array( |
305
|
60 |
|
'description' => get_post_meta( $id, '_variation_description', true ), |
306
|
60 |
|
'regular_price' => get_post_meta( $id, '_regular_price', true ), |
307
|
60 |
|
'sale_price' => get_post_meta( $id, '_sale_price', true ), |
308
|
60 |
|
'date_on_sale_from' => get_post_meta( $id, '_sale_price_dates_from', true ), |
309
|
60 |
|
'date_on_sale_to' => get_post_meta( $id, '_sale_price_dates_to', true ), |
310
|
60 |
|
'manage_stock' => get_post_meta( $id, '_manage_stock', true ), |
311
|
60 |
|
'stock_status' => get_post_meta( $id, '_stock_status', true ), |
312
|
60 |
|
'shipping_class_id' => current( $this->get_term_ids( $id, 'product_shipping_class' ) ), |
313
|
60 |
|
'virtual' => get_post_meta( $id, '_virtual', true ), |
314
|
60 |
|
'downloadable' => get_post_meta( $id, '_downloadable', true ), |
315
|
60 |
|
'gallery_image_ids' => array_filter( explode( ',', get_post_meta( $id, '_product_image_gallery', true ) ) ), |
316
|
60 |
|
'download_limit' => get_post_meta( $id, '_download_limit', true ), |
317
|
60 |
|
'download_expiry' => get_post_meta( $id, '_download_expiry', true ), |
318
|
60 |
|
'image_id' => get_post_thumbnail_id( $id ), |
319
|
60 |
|
'backorders' => get_post_meta( $id, '_backorders', true ), |
320
|
60 |
|
'sku' => get_post_meta( $id, '_sku', true ), |
321
|
60 |
|
'stock_quantity' => get_post_meta( $id, '_stock', true ), |
322
|
60 |
|
'weight' => get_post_meta( $id, '_weight', true ), |
323
|
60 |
|
'length' => get_post_meta( $id, '_length', true ), |
324
|
|
|
'width' => get_post_meta( $id, '_width', true ), |
325
|
|
|
'height' => get_post_meta( $id, '_height', true ), |
326
|
|
|
'tax_class' => ! metadata_exists( 'post', $id, '_tax_class' ) ? 'parent' : get_post_meta( $id, '_tax_class', true ), |
327
|
60 |
|
) |
328
|
6 |
|
); |
329
|
|
|
|
330
|
60 |
|
if ( $product->is_on_sale( 'edit' ) ) { |
331
|
|
|
$product->set_price( $product->get_sale_price( 'edit' ) ); |
332
|
|
|
} else { |
333
|
60 |
|
$product->set_price( $product->get_regular_price( 'edit' ) ); |
334
|
60 |
|
} |
335
|
60 |
|
|
336
|
60 |
|
$parent_object = get_post( $product->get_parent_id() ); |
337
|
60 |
|
$terms = get_the_terms( $product->get_parent_id(), 'product_visibility' ); |
338
|
|
|
$term_names = is_array( $terms ) ? wp_list_pluck( $terms, 'name' ) : array(); |
339
|
60 |
|
$exclude_search = in_array( 'exclude-from-search', $term_names, true ); |
340
|
|
|
$exclude_catalog = in_array( 'exclude-from-catalog', $term_names, true ); |
341
|
60 |
|
|
342
|
|
View Code Duplication |
if ( $exclude_search && $exclude_catalog ) { |
343
|
60 |
|
$catalog_visibility = 'hidden'; |
344
|
|
|
} elseif ( $exclude_search ) { |
345
|
|
|
$catalog_visibility = 'catalog'; |
346
|
60 |
|
} elseif ( $exclude_catalog ) { |
347
|
|
|
$catalog_visibility = 'search'; |
348
|
|
|
} else { |
349
|
60 |
|
$catalog_visibility = 'visible'; |
350
|
|
|
} |
351
|
60 |
|
|
352
|
60 |
|
$product->set_parent_data( |
353
|
60 |
|
array( |
354
|
60 |
|
'title' => $parent_object ? $parent_object->post_title : '', |
355
|
60 |
|
'status' => $parent_object ? $parent_object->post_status : '', |
356
|
60 |
|
'sku' => get_post_meta( $product->get_parent_id(), '_sku', true ), |
357
|
60 |
|
'manage_stock' => get_post_meta( $product->get_parent_id(), '_manage_stock', true ), |
358
|
60 |
|
'backorders' => get_post_meta( $product->get_parent_id(), '_backorders', true ), |
359
|
60 |
|
'low_stock_amount' => get_post_meta( $product->get_parent_id(), '_low_stock_amount', true ), |
360
|
60 |
|
'stock_quantity' => wc_stock_amount( get_post_meta( $product->get_parent_id(), '_stock', true ) ), |
361
|
60 |
|
'weight' => get_post_meta( $product->get_parent_id(), '_weight', true ), |
362
|
60 |
|
'length' => get_post_meta( $product->get_parent_id(), '_length', true ), |
363
|
60 |
|
'width' => get_post_meta( $product->get_parent_id(), '_width', true ), |
364
|
60 |
|
'height' => get_post_meta( $product->get_parent_id(), '_height', true ), |
365
|
60 |
|
'tax_class' => get_post_meta( $product->get_parent_id(), '_tax_class', true ), |
366
|
60 |
|
'shipping_class_id' => absint( current( $this->get_term_ids( $product->get_parent_id(), 'product_shipping_class' ) ) ), |
367
|
|
|
'image_id' => get_post_thumbnail_id( $product->get_parent_id() ), |
368
|
|
|
'purchase_note' => get_post_meta( $product->get_parent_id(), '_purchase_note', true ), |
369
|
|
|
'catalog_visibility' => $catalog_visibility, |
370
|
|
|
) |
371
|
60 |
|
); |
372
|
60 |
|
|
373
|
60 |
|
// Pull data from the parent when there is no user-facing way to set props. |
374
|
|
|
$product->set_sold_individually( get_post_meta( $product->get_parent_id(), '_sold_individually', true ) ); |
375
|
|
|
$product->set_tax_status( get_post_meta( $product->get_parent_id(), '_tax_status', true ) ); |
376
|
|
|
$product->set_cross_sell_ids( get_post_meta( $product->get_parent_id(), '_crosssell_ids', true ) ); |
377
|
|
|
} |
378
|
|
|
|
379
|
|
|
/** |
380
|
|
|
* For all stored terms in all taxonomies, save them to the DB. |
381
|
|
|
* |
382
|
|
|
* @since 3.0.0 |
383
|
60 |
|
* @param WC_Product $product Product object. |
384
|
60 |
|
* @param bool $force Force update. Used during create. |
385
|
|
|
*/ |
386
|
60 |
|
protected function update_terms( &$product, $force = false ) { |
387
|
60 |
|
$changes = $product->get_changes(); |
388
|
|
|
|
389
|
|
View Code Duplication |
if ( $force || array_key_exists( 'shipping_class_id', $changes ) ) { |
390
|
|
|
wp_set_post_terms( $product->get_id(), array( $product->get_shipping_class_id( 'edit' ) ), 'product_shipping_class', false ); |
391
|
|
|
} |
392
|
|
|
} |
393
|
|
|
|
394
|
|
|
/** |
395
|
|
|
* Update visibility terms based on props. |
396
|
|
|
* |
397
|
|
|
* @since 3.0.0 |
398
|
|
|
* |
399
|
60 |
|
* @param WC_Product $product Product object. |
400
|
60 |
|
* @param bool $force Force update. Used during create. |
401
|
|
|
*/ |
402
|
60 |
|
protected function update_visibility( &$product, $force = false ) { |
403
|
60 |
|
$changes = $product->get_changes(); |
404
|
|
|
|
405
|
60 |
|
if ( $force || array_intersect( array( 'stock_status' ), array_keys( $changes ) ) ) { |
406
|
3 |
|
$terms = array(); |
407
|
|
|
|
408
|
|
|
if ( 'outofstock' === $product->get_stock_status() ) { |
409
|
60 |
|
$terms[] = 'outofstock'; |
410
|
|
|
} |
411
|
|
|
|
412
|
|
|
wp_set_post_terms( $product->get_id(), $terms, 'product_visibility', false ); |
413
|
|
|
} |
414
|
|
|
} |
415
|
|
|
|
416
|
|
|
/** |
417
|
|
|
* Update attribute meta values. |
418
|
|
|
* |
419
|
|
|
* @since 3.0.0 |
420
|
60 |
|
* @param WC_Product $product Product object. |
421
|
60 |
|
* @param bool $force Force update. Used during create. |
422
|
|
|
*/ |
423
|
60 |
|
protected function update_attributes( &$product, $force = false ) { |
424
|
|
|
$changes = $product->get_changes(); |
425
|
60 |
|
|
426
|
60 |
|
if ( $force || array_key_exists( 'attributes', $changes ) ) { |
427
|
60 |
|
global $wpdb; |
428
|
52 |
|
$attributes = $product->get_attributes(); |
429
|
52 |
|
$updated_attribute_keys = array(); |
430
|
|
|
foreach ( $attributes as $key => $value ) { |
431
|
|
|
update_post_meta( $product->get_id(), 'attribute_' . $key, $value ); |
432
|
|
|
$updated_attribute_keys[] = 'attribute_' . $key; |
433
|
60 |
|
} |
434
|
60 |
|
|
435
|
60 |
|
// Remove old taxonomies attributes so data is kept up to date - first get attribute key names. |
436
|
60 |
|
$delete_attribute_keys = $wpdb->get_col( |
|
|
|
|
437
|
60 |
|
$wpdb->prepare( |
438
|
|
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.QuotedDynamicPlaceholderGeneration |
439
|
|
|
"SELECT meta_key FROM {$wpdb->postmeta} WHERE meta_key LIKE %s AND meta_key NOT IN ( '" . implode( "','", array_map( 'esc_sql', $updated_attribute_keys ) ) . "' ) AND post_id = %d", |
440
|
|
|
$wpdb->esc_like( 'attribute_' ) . '%', |
441
|
60 |
|
$product->get_id() |
442
|
|
|
) |
443
|
|
|
); |
444
|
|
|
|
445
|
|
|
foreach ( $delete_attribute_keys as $key ) { |
446
|
|
|
delete_post_meta( $product->get_id(), $key ); |
447
|
|
|
} |
448
|
|
|
} |
449
|
|
|
} |
450
|
|
|
|
451
|
|
|
/** |
452
|
|
|
* Helper method that updates all the post meta for a product based on it's settings in the WC_Product class. |
453
|
|
|
* |
454
|
60 |
|
* @since 3.0.0 |
455
|
|
|
* @param WC_Product $product Product object. |
456
|
60 |
|
* @param bool $force Force update. Used during create. |
457
|
|
|
*/ |
458
|
|
View Code Duplication |
public function update_post_meta( &$product, $force = false ) { |
|
|
|
|
459
|
60 |
|
$meta_key_to_props = array( |
460
|
|
|
'_variation_description' => 'description', |
461
|
60 |
|
); |
462
|
60 |
|
|
463
|
60 |
|
$props_to_update = $force ? $meta_key_to_props : $this->get_props_to_update( $product, $meta_key_to_props ); |
464
|
60 |
|
|
465
|
60 |
|
foreach ( $props_to_update as $meta_key => $prop ) { |
466
|
|
|
$value = $product->{"get_$prop"}( 'edit' ); |
467
|
|
|
$updated = update_post_meta( $product->get_id(), $meta_key, $value ); |
468
|
|
|
if ( $updated ) { |
469
|
60 |
|
$this->updated_props[] = $prop; |
470
|
|
|
} |
471
|
|
|
} |
472
|
|
|
|
473
|
|
|
parent::update_post_meta( $product, $force ); |
474
|
|
|
} |
475
|
|
|
|
476
|
|
|
/** |
477
|
|
|
* Update product variation guid. |
478
|
|
|
* |
479
|
|
|
* @param WC_Product_Variation $product Product variation object. |
480
|
|
|
* |
481
|
|
|
* @since 3.6.0 |
482
|
|
|
*/ |
483
|
|
|
protected function update_guid( $product ) { |
484
|
|
|
global $wpdb; |
485
|
|
|
|
486
|
|
|
$guid = home_url( |
487
|
|
|
add_query_arg( |
488
|
|
|
array( |
489
|
|
|
'post_type' => 'product_variation', |
490
|
|
|
'p' => $product->get_id(), |
491
|
|
|
), |
492
|
|
|
'' |
493
|
|
|
) |
494
|
|
|
); |
495
|
|
|
$wpdb->update( $wpdb->posts, array( 'guid' => $guid ), array( 'ID' => $product->get_id() ) ); |
|
|
|
|
496
|
|
|
} |
497
|
|
|
} |
498
|
|
|
|