Completed
Push — master ( f538af...fba328 )
by Justin
07:10
created

product-functions.php ➔ wpsc_pre_update()   C

Complexity

Conditions 15
Paths 17

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 15
eloc 14
c 0
b 0
f 0
nc 17
nop 2
dl 0
loc 22
rs 5.8335

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * WPSC Product modifying functions
4
 *
5
 * @package wp-e-commerce
6
 * @since 3.7
7
 */
8
9
function wpsc_get_max_upload_size(){
10
	return size_format( wp_max_upload_size() );
11
}
12
13
/**
14
* wpsc_admin_submit_product function
15
* @internal Was going to completely refactor sanitise forms and wpsc_insert_product, but they are also used by the import system
16
 * which I'm not really familiar with...so I'm not touching them :)  Erring on the side of redundancy and caution I'll just
17
 * refactor this to do the job.
18
* @return nothing
19
*/
20
function wpsc_admin_submit_product( $post_ID, $post ) {
21
22
	if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || $post->post_type != 'wpsc-product' ) {
23
		return;
24
	}
25
26
    //Type-casting ( not so much sanitization, which would be good to do )
27
    $post_data  = stripslashes_deep( $_POST );
28
    $product_id = $post_ID;
29
30
	$post_data['additional_description'] = isset( $post_data['additional_description'] ) ? $post_data['additional_description'] : '';
31
32
	if ( ! isset( $post_data['meta'] ) && isset( $_POST['meta'] ) ) {
33
		$post_data['meta'] = (array) $_POST['meta'];
34
	}
35
36
	if ( isset( $post_data['meta']['_wpsc_price'] ) )
37
		$post_data['meta']['_wpsc_price'] = wpsc_string_to_float( $post_data['meta']['_wpsc_price'] );
38
39
	if ( isset( $post_data['meta']['_wpsc_special_price'] ) )
40
		$post_data['meta']['_wpsc_special_price'] = wpsc_string_to_float( $post_data['meta']['_wpsc_special_price'] );
41
42
	if ( isset( $post_data['meta']['_wpsc_sku'] ) && $post_data['meta']['_wpsc_sku'] == __('N/A', 'wp-e-commerce') ) {
43
		$post_data['meta']['_wpsc_sku'] = '';
44
	}
45
46
	// Update donation setting
47
	if ( isset( $post_data['wpsc_product_pricing_nonce'] ) && wp_verify_nonce( $post_data['wpsc_product_pricing_nonce'], 'update' ) ) {
48
		$post_data['meta']['_wpsc_is_donation'] = isset( $post_data['meta']['_wpsc_is_donation'] ) ? 1 : 0;
49
	}
50
51
	if ( ! isset( $post_data['meta']['_wpsc_limited_stock'] ) ){
52
		$post_data['meta']['_wpsc_stock'] = false;
53
	} else {
54
		$post_data['meta']['_wpsc_stock'] = isset( $post_data['meta']['_wpsc_stock'] ) ? (int) $post_data['meta']['_wpsc_stock'] : 0;
55
	}
56
57
	unset($post_data['meta']['_wpsc_limited_stock']);
58
	if(!isset($post_data['quantity_limited'])) $post_data['quantity_limited'] = '';
59
    if(!isset($post_data['special'])) $post_data['special'] = '';
60
61
	$post_data['meta']['_wpsc_product_metadata']['quantity_limited'] = (int)(bool)$post_data['quantity_limited'];
62
	$post_data['meta']['_wpsc_product_metadata']['special'] = (int)(bool)$post_data['special'];
63
64
	// Update Stock Options
65
	if ( isset( $_POST['wpsc_product_stock_nonce'] ) && wp_verify_nonce( $_POST['wpsc_product_stock_nonce'], 'update' ) ) {
66
67
		$post_data['meta']['_wpsc_product_metadata'] = wp_parse_args( $post_data['meta']['_wpsc_product_metadata'], array(
68
			'notify_when_none_left'    => 0,
69
			'unpublish_when_none_left' => 0
70
		) );
71
		$post_data['meta']['_wpsc_product_metadata']['notify_when_none_left'] = absint( (bool) $post_data['meta']['_wpsc_product_metadata']['notify_when_none_left'] );
72
		$post_data['meta']['_wpsc_product_metadata']['unpublish_when_none_left'] = absint( (bool) $post_data['meta']['_wpsc_product_metadata']['unpublish_when_none_left'] );
73
74
	}
75
76
	// Update shipping setting
77
	if ( isset( $_POST['wpsc_product_shipping_nonce'] ) && wp_verify_nonce( $_POST['wpsc_product_shipping_nonce'], 'update' ) ) {
78
79
		$post_data['meta']['_wpsc_product_metadata'] = wp_parse_args( $post_data['meta']['_wpsc_product_metadata'], array(
80
			'no_shipping' => 0
81
		) );
82
		$post_data['meta']['_wpsc_product_metadata']['no_shipping'] = absint( (bool) $post_data['meta']['_wpsc_product_metadata']['no_shipping'] );
83
84
	}
85
86
	// Product Weight
87
	if(!isset($post_data['meta']['_wpsc_product_metadata']['display_weight_as'])) $post_data['meta']['_wpsc_product_metadata']['display_weight_as'] = '';
88
89
	if ( isset( $post_data['meta']['_wpsc_product_metadata']['weight'] ) ) {
90
		$weight = wpsc_string_to_float( $post_data['meta']['_wpsc_product_metadata']['weight'] );
91
		$weight = wpsc_convert_weight( $weight, $post_data['meta']['_wpsc_product_metadata']['weight_unit'], "pound", true);
92
		$post_data['meta']['_wpsc_product_metadata']['weight'] = $weight;
93
        $post_data['meta']['_wpsc_product_metadata']['display_weight_as'] = $post_data['meta']['_wpsc_product_metadata']['weight_unit'];
94
	}
95
96
	if ( isset( $post_data['meta']['_wpsc_product_metadata']['dimensions'] ) ) {
97
		$dimensions =& $post_data['meta']['_wpsc_product_metadata']['dimensions'];
98
		foreach ( $dimensions as $key => $value ) {
99
			if ( ! in_array( $key, array( 'height', 'width', 'length' ) ) )
100
				continue;
101
102
			$dimensions[$key] = wpsc_string_to_float( $value );
103
		}
104
	}
105
106
	// Update the table rate prices (quantity discounts)
107
	if ( isset( $post_data['wpsc-update-quantity-discounts'] ) && wp_verify_nonce( $post_data['wpsc-update-quantity-discounts'], 'update-options' ) ) {
108
		$post_data['meta']['_wpsc_product_metadata']['table_rate_price'] = isset( $post_data['table_rate_price'] ) ? $post_data['table_rate_price'] : array();
109
110
		// If table_rate_price is empty, set empty table rate price arrays
111
		if ( empty( $post_data['meta']['_wpsc_product_metadata']['table_rate_price'] ) ) {
112
			$post_data['meta']['_wpsc_product_metadata']['table_rate_price']['table_price'] = array();
113
			$post_data['meta']['_wpsc_product_metadata']['table_rate_price']['quantity'] = array();
114
		}
115
116
		// Remove any rates with no quantity or price
117
		if ( ! empty( $post_data['meta']['_wpsc_product_metadata']['table_rate_price']['table_price'] ) ) {
118
			foreach ( (array) $post_data['meta']['_wpsc_product_metadata']['table_rate_price']['quantity'] as $key => $value ) {
119
				if ( empty( $value ) ) {
120
					unset( $post_data['meta']['_wpsc_product_metadata']['table_rate_price']['table_price'][ $key ] );
121
					unset( $post_data['meta']['_wpsc_product_metadata']['table_rate_price']['quantity'][ $key ] );
122
				}
123
			}
124
			foreach ( (array) $post_data['meta']['_wpsc_product_metadata']['table_rate_price']['table_price'] as $key => $value ) {
125
				if ( empty( $value ) ) {
126
					unset( $post_data['meta']['_wpsc_product_metadata']['table_rate_price']['table_price'][ $key ] );
127
					unset( $post_data['meta']['_wpsc_product_metadata']['table_rate_price']['quantity'][ $key ] );
128
				}
129
			}
130
		}
131
	}
132
133
	if ( isset( $post_data['meta']['_wpsc_product_metadata']['shipping'] ) ) {
134
		$post_data['meta']['_wpsc_product_metadata']['shipping']['local'] = wpsc_string_to_float( $post_data['meta']['_wpsc_product_metadata']['shipping']['local'] );
135
		$post_data['meta']['_wpsc_product_metadata']['shipping']['international'] = wpsc_string_to_float( $post_data['meta']['_wpsc_product_metadata']['shipping']['international'] );
136
	}
137
138
	// Update product taxes
139
	if ( isset( $_POST['wpsc_product_tax_nonce'] ) && wp_verify_nonce( $_POST['wpsc_product_tax_nonce'], 'update' ) ) {
140
141
		$post_data['meta']['_wpsc_product_metadata'] = wp_parse_args( $post_data['meta']['_wpsc_product_metadata'], array(
142
			'wpec_taxes_taxable_amount' => '',
143
			'wpec_taxes_taxable'        => ''
144
		) );
145
		if ( ! empty( $post_data['meta']['_wpsc_product_metadata']['wpec_taxes_taxable_amount'] ) ) {
146
			$post_data['meta']['_wpsc_product_metadata']['wpec_taxes_taxable_amount'] = wpsc_string_to_float($post_data['meta']['_wpsc_product_metadata']['wpec_taxes_taxable_amount'] );
147
		}
148
		$post_data['meta']['_wpsc_product_metadata']['wpec_taxes_taxable'] = $post_data['meta']['_wpsc_product_metadata']['wpec_taxes_taxable'];
149
150
	}
151
152
	// External Link Options
153
	if ( isset( $_POST['wpsc_product_external_link_nonce'] ) && wp_verify_nonce( $_POST['wpsc_product_external_link_nonce'], 'update' ) ) {
154
155
		// Parse post meta to ensure default values
156
		$post_data['meta']['_wpsc_product_metadata'] = wp_parse_args( $post_data['meta']['_wpsc_product_metadata'], array(
157
			'external_link'        => '',
158
			'external_link_text'   => '',
159
			'external_link_target' => ''
160
		) );
161
162
	}
163
164
	// Advanced Options
165
	if ( isset( $_POST['wpsc_product_personalization_nonce'] ) && wp_verify_nonce( $_POST['wpsc_product_personalization_nonce'], 'update' ) ) {
166
167
		// Parse post meta to ensure default values (especially checkboxes)
168
		$post_data['meta']['_wpsc_product_metadata'] = wp_parse_args( $post_data['meta']['_wpsc_product_metadata'], array(
169
			'engraved'                => 0,
170
			'can_have_uploaded_image' => 0
171
		) );
172
173
		$post_data['meta']['_wpsc_product_metadata']['engraved'] = absint( (bool) $post_data['meta']['_wpsc_product_metadata']['engraved'] );
174
		$post_data['meta']['_wpsc_product_metadata']['can_have_uploaded_image'] = absint( (bool) $post_data['meta']['_wpsc_product_metadata']['can_have_uploaded_image'] );
175
176
	}
177
178
	if ( ! isset($post_data['meta']['_wpsc_product_metadata']['google_prohibited'])) $post_data['meta']['_wpsc_product_metadata']['google_prohibited'] = '';
179
	$post_data['meta']['_wpsc_product_metadata']['google_prohibited'] = (int)(bool)$post_data['meta']['_wpsc_product_metadata']['google_prohibited'];
180
181
	// Fill in any missing meta values with existing values.
182
	$post_data['meta'] = wp_parse_args( $post_data['meta'], array(
183
		'_wpsc_is_donation' => get_product_meta( $product_id, 'is_donation', true )
184
	) );
185
186
	// Fill in any missing product meta values with existing values.
187
	$default_meta_values = wp_parse_args( get_product_meta( $product_id, 'product_metadata', true ), array(
188
		'notify_when_none_left'    => 0,
189
		'unpublish_when_none_left' => 0,
190
		'no_shipping'              => 0,
191
		'external_link'            => '',
192
		'external_link_text'       => '',
193
		'external_link_target'     => '',
194
		'engraved'                 => 0,
195
		'can_have_uploaded_image'  => 0
196
	) );
197
198
	$post_data['meta']['_wpsc_product_metadata'] = wp_parse_args( $post_data['meta']['_wpsc_product_metadata'], $default_meta_values );
199
200
	$post_data['files'] = $_FILES;
201
202
	if(isset($post_data['post_title']) && $post_data['post_title'] != '') {
203
204
	$product_columns = array(
205
		'name' => '',
206
		'description' => '',
207
		'additional_description' => '',
208
		'price' => null,
209
		'weight' => null,
210
		'weight_unit' => '',
211
		'pnp' => null,
212
		'international_pnp' => null,
213
		'file' => null,
214
		'image' => '0',
215
		'quantity_limited' => '',
216
		'quantity' => null,
217
		'special' => null,
218
		'special_price' => null,
219
		'display_frontpage' => null,
220
		'notax' => null,
221
		'publish' => null,
222
		'active' => null,
223
		'donation' => null,
224
		'no_shipping' => null,
225
		'thumbnail_image' => null,
226
		'thumbnail_state' => null
227
	);
228
229
	foreach ( $product_columns as $column => $default ) {
230
		if ( ! isset( $post_data[ $column ] ) ) {
231
			$post_data[ $column ] = '';
232
		}
233
	}
234
235
	// if we succeed, we can do further editing (todo - if_wp_error)
236
237
	// if we have no categories selected, assign one.
238
	if ( isset( $post_data['tax_input']['wpsc_product_category'] ) && count( $post_data['tax_input']['wpsc_product_category'] ) == 1 && $post_data['tax_input']['wpsc_product_category'][0] == 0){
239
		$post_data['tax_input']['wpsc_product_category'][1] = wpsc_add_product_category_default($product_id);
240
	}
241
242
	// and the meta
243
	wpsc_update_product_meta($product_id, $post_data['meta']);
244
245
	// and the custom meta
246
	wpsc_update_custom_meta($product_id, $post_data);
247
248
	// Update the alternative currencies
249
	if ( isset( $post_data['wpsc-update-currency-layers'] ) && wp_verify_nonce( $post_data['wpsc-update-currency-layers'], 'update-options' ) ) {
250
251
		// Clear currencies before re-saving to make sure deleted currencies are removed
252
		update_product_meta( $product_id, 'currency', array() );
253
254
		if ( ! empty( $post_data['newCurrency'] ) ) {
255
			foreach( (array) $post_data['newCurrency'] as $key =>$value ) {
256
				wpsc_update_alt_product_currency( $product_id, $value, $post_data['newCurrPrice'][ $key ] );
257
			}
258
		}
259
	}
260
261
	if ( isset( $post_data['files']['file'] ) && $post_data['files']['file']['tmp_name'] != '' ) {
262
		wpsc_item_process_file($product_id, $post_data['files']['file']);
263
	} else {
264
		if (!isset($post_data['select_product_file'])) $post_data['select_product_file'] = null;
265
	  	wpsc_item_reassign_file($product_id, $post_data['select_product_file']);
266
	}
267
268
	if(isset($post_data['files']['preview_file']['tmp_name']) && ($post_data['files']['preview_file']['tmp_name'] != '')) {
269
 		wpsc_item_add_preview_file($product_id, $post_data['files']['preview_file']);
270
	}
271
	do_action('wpsc_edit_product', $product_id);
272
	}
273
	return $product_id;
274
}
275
276
277
function wpsc_pre_update( $data, $postarr ) {
278
 	if ( (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || $postarr["post_type"] != 'wpsc-product' )
279
        return $data;
280
    if( isset( $postarr["additional_description"] ) )
281
        $data["post_excerpt"] = $postarr["additional_description"];
282
283
	 if( isset( $postarr["parent_post"] ) && !empty( $postarr["parent_post"] ) )
284
        $data["post_parent"] = $postarr["parent_post"];
285
286
	// Sanitize status for variations (see #324)
287
	if ( $data['post_parent'] && ( ! isset( $data['ID'] ) || $data['post_parent'] != $data['ID'] ) && $data['post_status'] == 'publish' ) {
288
		$data['post_status'] = 'inherit';
289
	}
290
291
	if ( ! empty( $postarr['meta'] ) && ( ! isset( $postarr['meta']['_wpsc_product_metadata']['enable_comments'] ) || $postarr['meta']['_wpsc_product_metadata']['enable_comments'] == 0 || empty( $postarr['meta']['_wpsc_product_metadata']['enable_comments'] ) ) ) {
292
		$data["comment_status"] = "closed";
293
	} else {
294
		$data["comment_status"] = "open";
295
	}
296
297
    return $data;
298
}
299
add_filter( 'wp_insert_post_data','wpsc_pre_update', 99, 2 );
300
add_action( 'save_post', 'wpsc_admin_submit_product', 5, 2 );
301
add_action( 'admin_notices', 'wpsc_admin_submit_notices' );
302
303
/**
304
 * Remove category meta box from variation editor. This would disassociate variations
305
 * with the default category. See #431 (http://code.google.com/p/wp-e-commerce/issues/detail?id=431)
306
 *
307
 */
308
function wpsc_variation_remove_metaboxes() {
309
	global $post;
310
	if ( ! $post->post_parent )
311
		return;
312
313
	remove_meta_box( 'wpsc_product_categorydiv', 'wpsc-product', 'side' );
314
}
315
add_action( 'add_meta_boxes_wpsc-product', 'wpsc_variation_remove_metaboxes', 99 );
316
317
function wpsc_admin_submit_notices() {
318
    global $current_screen, $post;
319
320
    if( $current_screen->id != 'wpsc-product' || !isset( $_SESSION['product_error_messages'] ) )
0 ignored issues
show
introduced by
Usage of $_SESSION variable is prohibited.
Loading history...
321
            return;
322
    foreach ( $_SESSION['product_error_messages'] as $error )
0 ignored issues
show
introduced by
Usage of $_SESSION variable is prohibited.
Loading history...
323
        echo "<div id=\"message\" class=\"updated below-h2\"><p>".$error."</p></div>";
324
    unset( $_SESSION['product_error_messages'] );
0 ignored issues
show
introduced by
Usage of $_SESSION variable is prohibited.
Loading history...
325
}
326
327
/**
328
  * wpsc_add_product_category_default, if there is no category assigned assign first product category as default
329
  *
330
  * @since 3.8
331
  * @param $product_id (int) the Post ID
332
  * @return null
333
  */
334
function wpsc_add_product_category_default( $product_id ){
335
	$terms = get_terms( 'wpsc_product_category', array( 'orderby' => 'id', 'hide_empty' => 0 ) );
336
	if ( ! empty( $terms ) ) {
337
		$default = array_shift( $terms );
338
		wp_set_object_terms( $product_id , array( $default->slug ) , 'wpsc_product_category' );
339
	}
340
}
341
/**
342
* wpsc_sanitise_product_forms function
343
*
344
* @return array - Sanitised product details
345
*/
346
function wpsc_sanitise_product_forms($post_data = null) {
347
	if ( empty($post_data) ) {
348
		$post_data = &$_POST;
349
	}
350
351
	$post_data = stripslashes_deep( $post_data );
352
353
	$post_data['name'] = isset($post_data['post_title']) ? $post_data['post_title'] : '';
354
	$post_data['title'] = $post_data['name'];
355
	$post_data['description'] = isset($post_data['content']) ? $post_data['content'] : '';
356
	$post_data['additional_description'] = isset($post_data['additional_description']) ? $post_data['additional_description'] : '';
357
	$post_data['post_status'] = 'draft';
358
359
	if(isset($post_data['publish'])) {
360
		$post_data['post_status'] = 'publish';
361
	} else if(isset($post_data['unpublish'])) {
362
		$post_data['post_status'] = 'draft';
363
	}
364
365
	$post_data['meta']['_wpsc_price'] = wpsc_string_to_float( $post_data['meta']['_wpsc_price'] );
366
	$post_data['meta']['_wpsc_special_price'] = wpsc_string_to_float( $post_data['meta']['_wpsc_special_price'] );
367
	if (!isset($post_data['meta']['_wpsc_is_donation'])) $post_data['meta']['_wpsc_is_donation'] = '';
368
	$post_data['meta']['_wpsc_is_donation'] = (int)(bool)$post_data['meta']['_wpsc_is_donation'];
369
	$post_data['meta']['_wpsc_stock'] = (int)$post_data['meta']['_wpsc_stock'];
370
371
	if (!isset($post_data['meta']['_wpsc_limited_stock'])) $post_data['meta']['_wpsc_limited_stock'] = '';
372
	if((bool)$post_data['meta']['_wpsc_limited_stock'] !== true) {
373
	  $post_data['meta']['_wpsc_stock'] = false;
374
	}
375
	unset($post_data['meta']['_wpsc_limited_stock']);
376
	if(!isset($post_data['meta']['_wpsc_product_metadata']['notify_when_none_left'])) $post_data['meta']['_wpsc_product_metadata']['notify_when_none_left'] = 0;
377
	if(!isset($post_data['meta']['_wpsc_product_metadata']['unpublish_when_none_left'])) $post_data['meta']['_wpsc_product_metadata']['unpublish_when_none_left'] = '';
378
    if(!isset($post_data['quantity_limited'])) $post_data['quantity_limited'] = '';
379
    if(!isset($post_data['special'])) $post_data['special'] = '';
380
    if(!isset($post_data['meta']['_wpsc_product_metadata']['no_shipping'])) $post_data['meta']['_wpsc_product_metadata']['no_shipping'] = '';
381
382
	$post_data['meta']['_wpsc_product_metadata']['notify_when_none_left'] = (int)(bool)$post_data['meta']['_wpsc_product_metadata']['notify_when_none_left'];
383
	$post_data['meta']['_wpsc_product_metadata']['unpublish_when_none_left'] = (int)(bool)$post_data['meta']['_wpsc_product_metadata']['unpublish_when_none_left'];
384
	$post_data['meta']['_wpsc_product_metadata']['quantity_limited'] = (int)(bool)$post_data['quantity_limited'];
385
	$post_data['meta']['_wpsc_product_metadata']['special'] = (int)(bool)$post_data['special'];
386
	$post_data['meta']['_wpsc_product_metadata']['no_shipping'] = (int)(bool)$post_data['meta']['_wpsc_product_metadata']['no_shipping'];
387
388
	// Product Weight
389
	if(!isset($post_data['meta']['_wpsc_product_metadata']['display_weight_as'])) $post_data['meta']['_wpsc_product_metadata']['display_weight_as'] = '';
390
    if(!isset($post_data['meta']['_wpsc_product_metadata']['display_weight_as'])) $post_data['meta']['_wpsc_product_metadata']['display_weight_as'] = '';
391
392
    $weight = wpsc_string_to_float( $post_data['meta']['_wpsc_product_metadata']['weight'] );
393
	$weight = wpsc_convert_weight( $weight, $post_data['meta']['_wpsc_product_metadata']['weight_unit'], "pound", true);
394
	$post_data['meta']['_wpsc_product_metadata']['weight'] = $weight;
395
	$post_data['meta']['_wpsc_product_metadata']['display_weight_as'] = $post_data['meta']['_wpsc_product_metadata']['weight_unit'];
396
397
	$post_data['files'] = $_FILES;
398
	return $post_data;
399
}
400
401
 /**
402
	* wpsc_insert_product function
403
	*
404
	* @param unknown
405
	* @return unknown
406
*/
407
function wpsc_insert_product($post_data, $wpsc_error = false) {
0 ignored issues
show
Unused Code introduced by
The parameter $wpsc_error is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
408
	global $wpdb, $user_ID;
409
	$adding = false;
410
	$update = false;
411
412
	$product_columns = array(
413
		'name' => '',
414
		'description' => '',
415
		'additional_description' => '',
416
		'price' => null,
417
		'weight' => null,
418
		'weight_unit' => '',
419
		'pnp' => null,
420
		'international_pnp' => null,
421
		'file' => null,
422
		'image' => '0',
423
		'quantity_limited' => '',
424
		'quantity' => null,
425
		'special' => null,
426
		'special_price' => null,
427
		'display_frontpage' => null,
428
		'notax' => null,
429
		'publish' => null,
430
		'active' => null,
431
		'donation' => null,
432
		'no_shipping' => null,
433
		'thumbnail_image' => null,
434
		'thumbnail_state' => null
435
	);
436
437
	foreach ( $product_columns as $column => $default ) {
438
		if ( ! isset( $post_data[ $column ] ) ) {
439
			$post_data[ $column ] = '';
440
		}
441
	}
442
443
	$product_post_values = array(
444
		'post_author' => $user_ID,
445
		'post_content' => $post_data['description'],
446
		'post_excerpt' => $post_data['additional_description'],
447
		'post_title' => $post_data['name'],
448
		'post_status' => $post_data['post_status'],
449
		'post_type' => "wpsc-product",
450
		'post_name' => sanitize_title($post_data['name'])
451
	);
452
	$product_post_values["comment_status"] = "open";
453
454
	$product_id = wp_insert_post($product_post_values);
455
	if ( isset ( $post_data["sticky"] ) ) {
0 ignored issues
show
Coding Style introduced by
Space before opening parenthesis of function call prohibited
Loading history...
456
		stick_post($product_id);
457
	}else {
458
		unstick_post($product_id);
459
	}
460
461
	$adding = true;
462
463
	// if we succeed, we can do further editing
464
465
	// and the meta
466
	wpsc_update_product_meta($product_id, $post_data['meta']);
467
	do_action('wpsc_edit_product', $product_id);
468
	return $product_id;
469
}
470
471
/**
472
 * term_id_price function
473
 * Retreives associated price, if any, with term_id
474
 * @param integer term ID
475
 * @param integer parent product price
476
 * @return integer modified price for child product, based on term ID price and parent price
477
 */
478
479
function term_id_price($term_id, $parent_price) {
480
481
	$term_price_arr = get_option( 'term_prices' );
482
483
	if ( isset($term_price_arr[$term_id]) ) {
484
		$price = $term_price_arr[$term_id]["price"];
485
	} else {
486
		$price = 0;
487
	}
488
489
	//Check for flat, percentile or differential
490
		$var_price_type = '';
491
492
		if (flat_price($price)) {
493
			$var_price_type = 'flat';
494
			$price = floatval($price);
495
		} elseif ( differential_price($price) ) {
496
			$var_price_type = 'differential';
497
		} elseif (percentile_price($price)) {
498
			$var_price_type = 'percentile';
499
		}
500
501
		if (strchr($price, '-') ) {
502
			$positive = false;
503
		} else {
504
			$positive = true;
505
		}
506
507
		if ($positive) {
508
509
			if ( $var_price_type == 'differential' ) {
510
				$differential = (floatval($price));
511
				$price = $parent_price + $differential;
512
			} elseif ( $var_price_type == 'percentile' ) {
513
				$percentage = (floatval($price) / 100);
514
				$price = $parent_price + ($parent_price * $percentage);
515
			}
516
		} else {
517
518
			if ( $var_price_type == 'differential' ) {
519
				$differential = (floatval($price));
520
				$price = $parent_price - $differential;
521
			} elseif ( $var_price_type == 'percentile' ) {
522
				$percentage = (floatval($price) / 100);
523
				$price = $parent_price - ($parent_price * $percentage);
524
			}
525
		}
526
	return $price;
527
}
528
529
/**
530
 * Determine the price of a variation product based on the variation it's assigned
531
 * to. Because each variation term can have its own price (eg. 10, +10, -5%), this
532
 * function also takes those into account.
533
 *
534
 * @since 3.8.6
535
 * @param int $variation_id ID of the variation product
536
 * @param string $terms Optional. Defaults to false. Variation terms assigned to
0 ignored issues
show
Bug introduced by
There is no parameter named $terms. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
537
 * the variation product. Pass this argument to save one SQL query.
538
 * @return float Calculated price of the variation
539
 */
540
function wpsc_determine_variation_price( $variation_id, $term_ids = false ) {
541
	$flat = array();
542
	$diff = 0;
543
544
	$variation = get_post( $variation_id );
545
	$price = (float) get_product_meta( $variation->post_parent, 'price', true );
546
547
	if ( ! $term_ids )
548
		$term_ids = wpsc_get_product_terms( $variation_id, 'wpsc-variation', 'term_id' );
549
550
	$term_price_arr = get_option( 'term_prices' );
551
	foreach ( $term_ids as $term_id ) {
0 ignored issues
show
Bug introduced by
The expression $term_ids of type array<integer,object<stdObject>>|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
552
		if ( isset( $term_price_arr[$term_id] ) )
553
			$term_price = trim( $term_price_arr[$term_id]['price'] );
554
		else
555
			continue;
556
		if ( flat_price( $term_price ) ) {
557
			$flat[] = $term_price;
558
		} elseif ( differential_price( $term_price ) ) {
559
			$diff += (float) $term_price;
560
		} elseif ( percentile_price( $term_price ) ) {
561
			$diff += (float) $term_price / 100 * $price;
562
		}
563
	}
564
	// Variation price should at least be the maximum of all flat prices
565
	if ( ! empty( $flat ) )
566
		$price = max( $flat );
567
	$price += $diff;
568
	return $price;
569
}
570
571
/**
572
 * wpsc_edit_product_variations function.
573
 * this is the function to make child products using variations
574
 *
575
 * @access public
576
 * @param mixed $product_id
577
 * @param mixed $post_data
578
 * @return void
579
 */
580
function wpsc_edit_product_variations($product_id, $post_data) {
581
	global $user_ID;
582
583
	$parent = get_post_field( 'post_parent', $product_id );
584
585
	if( ! empty( $parent ) )
586
		return;
587
588
	$variations = array();
589
	$product_children = array();
590
	if (!isset($post_data['edit_var_val']))
591
		$post_data['edit_var_val'] = '';
592
593
	$variations = (array) $post_data['edit_var_val'];
594
595
	// Generate the arrays for variation sets, values and combinations
596
    $wpsc_combinator = new wpsc_variation_combinator($variations);
597
598
	// Retrieve the array containing the variation set IDs
599
	$variation_sets = $wpsc_combinator->return_variation_sets();
600
601
	// Retrieve the array containing the combinations of each variation set to be associated with this product.
602
	$variation_values = $wpsc_combinator->return_variation_values();
603
604
	// Retrieve the array containing the combinations of each variation set to be associated with this product.
605
	$combinations = $wpsc_combinator->return_combinations();
606
607
	$product_terms = wpsc_get_product_terms( $product_id, 'wpsc-variation' );
608
609
	$variation_sets_and_values = array_merge($variation_sets, $variation_values);
610
	$variation_sets_and_values = apply_filters('wpsc_edit_product_variation_sets_and_values', $variation_sets_and_values, $product_id);
611
612
	wp_set_object_terms($product_id, $variation_sets_and_values, 'wpsc-variation');
613
614
	$parent_id = absint( $_REQUEST['product_id'] );
615
616
	$child_product_template = array(
617
		'post_author' 	=> $user_ID,
618
		'post_content' 	=> get_post_field( 'post_content', $parent_id, 'raw' ),
619
		'post_excerpt' 	=> get_post_field( 'post_excerpt', $parent_id, 'raw' ),
620
		'post_title' 	=> get_post_field( 'post_title', $parent_id, 'raw' ),
621
		'post_status' 	=> 'inherit',
622
		'post_type' 	=> "wpsc-product",
623
		'post_parent' 	=> $product_id
624
	);
625
626
	$child_product_meta = get_post_custom($product_id);
627
628
	// here we loop through the combinations, get the term data and generate custom product names
629
	foreach($combinations as $combination) {
630
		$term_names = array();
631
		$term_ids = array();
632
		$term_slugs = array();
633
		$product_values = $child_product_template;
634
635
		$combination_terms = get_terms('wpsc-variation', array(
636
			'hide_empty'	=> 0,
637
			'include' 		=> implode(",", $combination),
638
			'orderby' 		=> 'parent',
639
		));
640
641
		foreach($combination_terms as $term) {
642
			$term_ids[] = $term->term_id;
643
			$term_slugs[] = $term->slug;
644
			$term_names[] = $term->name;
645
		}
646
647
		$product_values['post_title'] .= " (".implode(", ", $term_names).")";
648
		$product_values['post_name'] = sanitize_title($product_values['post_title']);
649
650
		$selected_post = get_posts(array(
651
			'name' 				=> $product_values['post_name'],
652
			'post_parent' 		=> $product_id,
653
			'post_type' 		=> "wpsc-product",
654
			'post_status' 		=> 'all',
655
			'suppress_filters' 	=> true
656
		));
657
		$selected_post = array_shift($selected_post);
658
		$child_product_id = wpsc_get_child_object_in_terms($product_id, $term_ids, 'wpsc-variation');
659
		$already_a_variation = true;
660
		if($child_product_id == false) {
661
			$already_a_variation = false;
662
			if($selected_post != null) {
663
				$child_product_id = $selected_post->ID;
664
			} else {
665
				$child_product_id = wp_insert_post($product_values);
666
			}
667
		} else {
668
			// sometimes there have been problems saving the variations, this gets the correct product ID
669
			if(($selected_post != null) && ($selected_post->ID != $child_product_id)) {
670
				$child_product_id = $selected_post->ID;
671
			}
672
		}
673
		$product_children[] = $child_product_id;
674
		if($child_product_id > 0) {
675
			wp_set_object_terms($child_product_id, $term_slugs, 'wpsc-variation');
676
		}
677
		//JS - 7.9 - Adding loop to include meta data in child product.
678
		if(!$already_a_variation){
679
			$this_child_product_meta = apply_filters( 'insert_child_product_meta', $child_product_meta, $product_id, $combination_terms );
680
			foreach ($this_child_product_meta as $meta_key => $meta_value ) :
681
				if ($meta_key == "_wpsc_product_metadata") {
682
					update_post_meta($child_product_id, $meta_key, unserialize($meta_value[0]));
683
				} else {
684
					update_post_meta($child_product_id, $meta_key, $meta_value[0]);
685
				}
686
687
			endforeach;
688
689
			if ( is_array( $term_ids ) && $price = wpsc_determine_variation_price( $child_product_id, $term_ids ) )
690
				update_product_meta( $child_product_id, 'price', $price );
691
		}
692
	}
693
694
	//For reasons unknown, this code did not previously deal with variation deletions.
695
	//Basically, we'll just check if any existing term associations are missing from the posted variables, delete if they are.
696
	//Get posted terms (multi-dimensional array, first level = parent var, second level = child var)
697
	$posted_term = $variations;
698
	//Get currently associated terms
699
	$currently_associated_var = $product_terms;
700
701
	$currently_associated_vars = array();
702
	foreach ($currently_associated_var as $current) {
703
		$currently_associated_vars[] = $current->term_id;
704
	}
705
706
	$posted_terms = array();
707
708
	foreach ($posted_term as $term=>$val) {
709
		$posted_terms[] = $term;
710
		if(is_array($val)) {
711
			foreach($val as $term2=>$val2) {
712
				$posted_terms[] = $term2;
713
			}
714
		}
715
	}
716
717
	if(!empty($currently_associated_vars)){
718
		$term_ids_to_delete = array();
719
		$term_ids_to_delete = array_diff($currently_associated_vars, $posted_terms);
720
	}
721
722
	if(isset($_REQUEST["post_ID"])) {
723
		$post_id = $_REQUEST["post_ID"];
724
	} elseif(isset($_REQUEST["product_id"])) {
725
		$post_id = $_REQUEST["product_id"];
726
	} else {
727
		return;
728
	}
729
730
	if(!empty($term_ids_to_delete) && (isset($_REQUEST["product_id"]) || isset($post_id))) {
731
		$post_ids_to_delete = array();
732
733
		// Whatever remains, find child products of current product with that term, in the variation taxonomy, and delete
734
		$post_ids_to_delete = wpsc_get_child_object_in_terms_var($_REQUEST["product_id"], $term_ids_to_delete, 'wpsc-variation');
735
736
		if(is_array($post_ids_to_delete) && !empty($post_ids_to_delete)) {
737
			foreach($post_ids_to_delete as $object_ids) {
738
				foreach($object_ids as $object_id) {
739
					wp_delete_post($object_id);
740
				}
741
			}
742
		}
743
	}
744
	$current_children = get_posts(array(
745
		'post_parent'	=> $post_id,
746
		'post_type'		=> 'wpsc-product',
747
		'post_status'	=> 'all',
748
		'numberposts'   => -1
749
		));
750
751
	$children = array();
752
	foreach((array)$current_children as $child_prod){
753
		$children[] = $child_prod->ID;
754
	}
755
	if(!empty($children)){
756
		$old_ids_to_delete = array_diff($children, $product_children);
757
		$old_ids_to_delete = apply_filters('wpsc_edit_product_variations_deletion', $old_ids_to_delete);
758
		if(is_array($old_ids_to_delete) && !empty($old_ids_to_delete)) {
759
			foreach($old_ids_to_delete as $object_ids) {
760
				wp_delete_post($object_ids);
761
			}
762
		}
763
	}
764
	_wpsc_refresh_parent_product_terms( $parent_id );
765
766
}
767
768
function wpsc_update_alt_product_currency($product_id, $newCurrency, $newPrice){
769
	global $wpdb;
770
771
	$old_curr = get_product_meta($product_id, 'currency',true);
772
	$sql = $wpdb->prepare( "SELECT `isocode` FROM `".WPSC_TABLE_CURRENCY_LIST."` WHERE `id`= %d", $newCurrency );
773
	$isocode = $wpdb->get_var($sql);
774
775
	$newCurrency = 'currency';
776
	$old_curr[$isocode] = $newPrice;
777
	if(($newPrice != '') &&  ($newPrice > 0.00)){
778
		update_product_meta($product_id, $newCurrency, $old_curr);
779
	} else {
780
		if((empty($old_curr[$isocode]) || 0.00 == $old_curr[$isocode]) && is_array($old_curr))
781
			unset($old_curr[$isocode]);
782
		update_product_meta($product_id, $newCurrency, $old_curr);
783
784
	}
785
786
}
787
788
 /**
789
 * wpsc_update_product_meta function
790
 *
791
 * @param integer product ID
792
 * @param string comma separated tags
793
 */
794
function wpsc_update_product_meta($product_id, $product_meta) {
795
    if($product_meta != null) {
796
		foreach((array)$product_meta as $key => $value) {
797
			update_post_meta($product_id, $key, $value);
798
		}
799
	}
800
}
801
802
/**
803
 * Called from javascript within product page to toggle publish status - AJAX
804
 * @return bool	publish status
805
 */
806
function wpsc_ajax_toggle_publish() {
807
/**
808
 * @todo - Check Admin Referer
809
 * @todo - Check Permissions
810
 */
811
	$status = (wpsc_toggle_publish_status($_REQUEST['productid'])) ? ('true') : ('false');
812
	exit( $status );
813
}
814
/*
815
/*  END - Publish /No Publish functions
816
*/
817
818
function wpsc_update_custom_meta($product_id, $post_data) {
819
820
	if ( isset( $post_data['new_custom_meta'] ) && $post_data['new_custom_meta'] != null ) {
821
	foreach((array)$post_data['new_custom_meta']['name'] as $key => $name) {
822
	    $value = $post_data['new_custom_meta']['value'][(int)$key];
823
	    if(($name != '') && ($value != '')) {
824
		add_post_meta($product_id, $name, $value);
825
	    }
826
	}
827
	}
828
829
    if (!isset($post_data['custom_meta'])) $post_data['custom_meta'] = '';
830
    if($post_data['custom_meta'] != null) {
831
	    foreach((array)$post_data['custom_meta'] as $key => $values) {
832
		    if(($values['name'] != '') && ($values['value'] != '')) {
833
			    update_post_meta($product_id, $values['name'], $values['value']);
834
		    }
835
	    }
836
    }
837
}
838
839
 /**
840
 * wpsc_item_process_file function
841
 *
842
 * @param integer product ID
843
 * @param array the file array from $_FILES
844
 * @param array the preview file array from $_FILES
845
 */
846
function wpsc_item_process_file( $product_id, $submitted_file, $preview_file = null ) {
0 ignored issues
show
Unused Code introduced by
The parameter $preview_file is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
847
848
	add_filter( 'upload_dir', 'wpsc_modify_upload_directory' );
849
850
	$time = current_time( 'mysql' );
851
852
	if ( $post = get_post( $product_id ) ) {
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
853
		if ( substr( $post->post_date, 0, 4 ) > 0 )
854
			$time = $post->post_date;
855
	}
856
857
	$file = wp_handle_upload( $submitted_file, array( 'test_form' => false ), $time );
858
859
	if ( isset( $file['error'] ) ) {
860
		return new WP_Error( 'upload_error', $file['error'] );
861
	}
862
863
	$name_parts = pathinfo( $file['file'] );
864
865
	// Construct the attachment array
866
	$attachment = array(
867
		'post_mime_type' => $file['type'],
868
		'guid'           => $file['url'],
869
		'post_parent'    => $product_id,
870
		'post_title'     => $name_parts['basename'],
871
		'post_content'   => '',
872
		'post_type'      => 'wpsc-product-file',
873
		'post_status'    => 'inherit'
874
	);
875
876
	// Save the data
877
	wp_insert_post( $attachment );
878
879
	remove_filter( 'upload_dir', 'wpsc_modify_upload_directory' );
880
}
881
882
function wpsc_modify_upload_directory($input) {
883
	$previous_subdir = $input['subdir'];
884
	$download_subdir = str_replace($input['basedir'], '', WPSC_FILE_DIR);
885
	$input['path'] = substr_replace(str_replace($previous_subdir, $download_subdir, $input['path']),'',-1);
886
	$input['url'] = substr_replace(str_replace($previous_subdir, $download_subdir, $input['url']),'',-1);
887
	$input['subdir'] = substr_replace(str_replace($previous_subdir, $download_subdir, $input['subdir']),'',-1);
888
	return $input;
889
}
890
891
function wpsc_modify_preview_directory($input) {
892
	$previous_subdir = $input['subdir'];
893
	$download_subdir = str_replace($input['basedir'], '', WPSC_PREVIEW_DIR);
894
895
	$input['path'] = substr_replace(str_replace($previous_subdir, $download_subdir, $input['path']),'',-1);
896
	$input['url'] = substr_replace(str_replace($previous_subdir, $download_subdir, $input['url']),'',-1);
897
	$input['subdir'] = substr_replace(str_replace($previous_subdir, $download_subdir, $input['subdir']),'',-1);
898
899
	return $input;
900
}
901
902
 /**
903
 * wpsc_item_reassign_file function
904
 *
905
 * @param integer product ID
906
 * @param string the selected file name;
907
 */
908
function wpsc_item_reassign_file($product_id, $selected_files) {
909
	global $wpdb;
910
	$product_file_list = array();
911
	// initialise $idhash to null to prevent issues with undefined variables and error logs
912
	$idhash = null;
913
914
	$args = array(
915
		'post_type' => 'wpsc-product-file',
916
		'post_parent' => $product_id,
917
		'numberposts' => -1,
0 ignored issues
show
introduced by
Disabling pagination is prohibited in VIP context, do not set numberposts to -1 ever.
Loading history...
918
		'post_status' => 'any'
919
	);
920
921
	$attached_files = (array) get_posts( $args );
922
	$attached_files_by_file = array();
923
924
	foreach($attached_files as $key => $attached_file) {
925
		$attached_files_by_file[$attached_file->post_title] = $attached_files[$key];
926
	}
927
928
	/* if we are editing, grab the current file and ID hash */
929
	if(!$selected_files) {
930
		// unlikely that anyone will ever upload a file called .none., so its the value used to signify clearing the product association
931
		return null;
932
	}
933
934
	foreach($selected_files as $selected_file) {
935
		// if we already use this file, there is no point doing anything more.
936
		$file_is_attached = false;
937
		$selected_file_path = WPSC_FILE_DIR.basename($selected_file);
938
939
		if(isset($attached_files_by_file[$selected_file])) {
940
			$file_is_attached = true;
941
		}
942
943
		if($file_is_attached == false ) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
944
			$type = wpsc_get_mimetype($selected_file_path);
945
			$attachment = array(
946
				'post_mime_type' => $type,
947
				'post_parent' => $product_id,
948
				'post_title' => $selected_file,
949
				'post_content' => '',
950
				'post_type' => "wpsc-product-file",
951
				'post_status' => 'inherit'
952
			);
953
			wp_insert_post($attachment);
954
		} else {
955
			$product_post_values = array(
956
				'ID' => $attached_files_by_file[$selected_file]->ID,
957
				'post_status' => 'inherit'
958
			);
959
			wp_update_post($product_post_values);
960
		}
961
	}
962
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
963
964
	foreach($attached_files as $attached_file) {
965
		if(!in_array($attached_file->post_title, $selected_files)) {
966
			$product_post_values = array(
967
				'ID' => $attached_file->ID,
968
				'post_status' => 'draft'
969
			);
970
			wp_update_post($product_post_values);
971
		}
972
	}
973
974
	return true;
975
}
976
977
 /**
978
 * wpsc_delete_preview_file
979
 *
980
 * @param integer product ID
981
 */
982
983
function wpsc_delete_preview_file($product_id) {
984
985
	$args = array(
986
	'post_type' => 'wpsc-preview-file',
987
	'post_parent' => $product_id,
988
	'numberposts' => -1,
0 ignored issues
show
introduced by
Disabling pagination is prohibited in VIP context, do not set numberposts to -1 ever.
Loading history...
989
	'post_status' => 'all'
990
	);
991
992
	$preview_files = (array)get_posts( $args );
993
994
	foreach( $preview_files as $preview ) {
995
		$preview_id = $preview->ID;
996
		wp_delete_post($preview_id);
997
	}
998
	return true;
999
}
1000
1001
 /**
1002
 * wpsc_item_add_preview_file function
1003
 *
1004
 * @param integer product ID
1005
 * @param array the preview file array from $_FILES
1006
 */
1007
function wpsc_item_add_preview_file($product_id, $preview_file) {
1008
  global $wpdb;
1009
1010
  wpsc_delete_preview_file($product_id);
1011
1012
  add_filter('upload_dir', 'wpsc_modify_preview_directory');
1013
	$overrides = array('test_form'=>false);
1014
1015
	$time = current_time('mysql');
1016
	if ( $post = get_post($product_id) ) {
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
1017
		if ( substr( $post->post_date, 0, 4 ) > 0 )
1018
			$time = $post->post_date;
1019
	}
1020
1021
	$file = wp_handle_upload($preview_file, $overrides, $time);
1022
1023
	if ( isset($file['error']) )
1024
		return new WP_Error( 'upload_error', $file['error'] );
1025
1026
	$name_parts = pathinfo($file['file']);
1027
	$name = $name_parts['basename'];
1028
1029
	$url = $file['url'];
1030
	$type = $file['type'];
1031
	$file = $file['file'];
1032
	$title = $name;
1033
	$content = '';
1034
1035
	// Construct the attachment array
1036
	$attachment = array(
1037
		'post_mime_type' => $type,
1038
		'guid' => $url,
1039
		'post_parent' => $product_id,
1040
		'post_title' => $title,
1041
		'post_content' => $content,
1042
		'post_type' => "wpsc-preview-file",
1043
		'post_status' => 'inherit'
1044
	);
1045
1046
	// Save the data
1047
	$id = wp_insert_post($attachment, $file, $product_id);
1048
	remove_filter('upload_dir', 'wpsc_modify_preview_directory');
1049
  	return $id;
1050
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
1051
1052
}
1053
1054
/**
1055
 * wpsc_variation_combinator class.
1056
 * Produces all combinations of variations selected for this product
1057
 * this class is based off the example code from here:
1058
 * http://www.php.net/manual/en/ref.array.php#94910
1059
 * Thanks, phektus, you are awesome, whoever you are.
1060
 */
1061
class wpsc_variation_combinator {
0 ignored issues
show
Coding Style introduced by
Class name "wpsc_variation_combinator" is not in camel caps format
Loading history...
1062
	var $variation_sets = array();
1063
	var $variation_values = array();
1064
	var $reprocessed_array = array();
1065
	var $combinations= array();
1066
1067
public function __construct($variation_sets) {
1068
	if( $variation_sets ) {
1069
		foreach($variation_sets as $variation_set_id => $variation_set) {
1070
			$this->variation_sets[] = absint($variation_set_id);
1071
			$new_variation_set = array();
1072
			if( $variation_set ) {
1073
				foreach($variation_set as $variation => $active) {
1074
					if($active == 1) {
1075
						$new_variation_set[] = array(absint($variation));
1076
						$this->variation_values[] = $variation;
1077
					}
1078
				}
1079
			}
1080
			$this->reprocessed_array[] = $new_variation_set;
1081
		}
1082
		$this->get_combinations(array(), $this->reprocessed_array, 0);
1083
	}
1084
}
1085
1086
1087
	function get_combinations($batch, $elements, $i)  {
1088
        if ($i >= count($elements)) {
1089
            $this->combinations[] = $batch;
1090
        } else {
1091
            foreach ($elements[$i] as $element) {
1092
                $this->get_combinations(array_merge($batch, $element), $elements, $i + 1);
1093
            }
1094
        }
1095
	}
1096
1097
	function return_variation_sets() {
1098
		return $this->variation_sets;
1099
	}
1100
1101
	function return_variation_values() {
1102
		return $this->variation_values;
1103
	}
1104
1105
	function return_combinations() {
1106
		return $this->combinations;
1107
1108
	}
1109
}
1110
1111
function wpsc_variations_stock_remaining($product_id){
1112
	global $wpdb;
1113
	return $wpdb->get_var( $wpdb->prepare( '
1114
		SELECT
1115
			sum(`pm`.`meta_value`)
1116
		FROM
1117
			`' . $wpdb->postmeta . '` `pm`
1118
		JOIN
1119
			`' . $wpdb->posts . '` `p`
1120
			ON
1121
			`pm`.`post_id` = `p`.`id`
1122
		WHERE
1123
			`p`.`post_type`= "wpsc-product"
1124
			AND
1125
			`p`.`post_parent` = %d
1126
			AND
1127
			`pm`.`meta_key` = "_wpsc_stock"
1128
	', $product_id ) );
1129
}
1130
1131
function flat_price( $price ) {
1132
	if ( ! empty( $price ) && strchr( $price, '-' ) === false && strchr( $price, '+' ) === false && strchr( $price, '%' ) === false )
1133
		return true;
1134
}
1135
1136
function percentile_price( $price ) {
1137
	if ( ! empty( $price ) && ( strchr( $price, '-' ) || strchr( $price, '+' ) ) && strchr( $price, '%' ) )
1138
		return true;
1139
}
1140
1141
function differential_price( $price ) {
1142
	if ( ! empty( $price ) && ( strchr( $price, '-' ) || strchr( $price, '+' ) ) && strchr( $price, '%' ) === false )
1143
		return true;
1144
}
1145
1146
/**
1147
 * Refresh variation terms assigned to parent product based on the variations it has.
1148
 *
1149
 * @since 3.8.9
1150
 * @access private
1151
 * @param  int $parent_id Parent product ID
1152
 */
1153
function _wpsc_refresh_parent_product_terms( $parent_id ) {
1154
	$children = get_children( array(
1155
		'post_parent' => $parent_id,
1156
		'post_status' => array( 'publish', 'inherit' ),
1157
	) );
1158
1159
	$children_ids = wp_list_pluck( $children, 'ID' );
1160
1161
	$children_terms = wp_get_object_terms( $children_ids, 'wpsc-variation' );
1162
	$new_terms = array();
1163
	foreach ( $children_terms as $term ) {
1164
		if ( $term->parent )
1165
			$new_terms[] = $term->parent;
1166
	}
1167
1168
	$children_term_ids = wp_list_pluck( $children_terms, 'term_id' );
1169
	$new_terms = array_merge( $new_terms, $children_term_ids );
1170
	$new_terms = array_unique( $new_terms );
1171
	$new_terms = array_map( 'absint', $new_terms );
1172
	wp_set_object_terms( $parent_id, $new_terms, 'wpsc-variation' );
1173
}
1174
1175
/**
1176
 * Make sure parent product's assigned terms are refreshed when its variations are deleted or trashed
1177
 *
1178
 * @since 3.8.9
1179
 * @access private
1180
 * @param  int $post_id Parent product ID
1181
 */
1182
function _wpsc_action_refresh_variation_parent_terms( $post_id ) {
1183
	$post = get_post( $post_id );
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
1184
	if ( $post->post_type != 'wpsc-product' || ! $post->post_parent || in_array( $post->post_status, array( 'publish', 'inherit' ) ) )
1185
		return;
1186
1187
	_wpsc_refresh_parent_product_terms( $post->post_parent );
1188
}
1189
1190
/**
1191
 * Make sure parent product's assigned terms are refresh when its variations' statuses are changed
1192
 *
1193
 * @since 3.8.9
1194
 * @access private
1195
 * @param  string $new_status New status
1196
 * @param  string $old_status Old status
1197
 * @param  object $post       Variation object
1198
 */
1199
function _wpsc_action_transition_post_status( $new_status, $old_status, $post ) {
0 ignored issues
show
Unused Code introduced by
The parameter $new_status is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $old_status is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1200
	if ( $post->post_type != 'wpsc-product' || ! $post->post_parent )
1201
		return;
1202
1203
	_wpsc_refresh_parent_product_terms( $post->post_parent );
1204
}
1205
1206
/**
1207
 * Prevent parent terms from being refreshed when its variations are updated. This is useful when
1208
 * the variations are being mass updated.
1209
 *
1210
 * @since  3.8.9
1211
 * @access private
1212
 */
1213
function _wpsc_remove_refresh_variation_parent_term_hooks() {
1214
	remove_action( 'transition_post_status', '_wpsc_action_transition_post_status', 10, 3 );
1215
	remove_action( 'deleted_post', '_wpsc_action_refresh_variation_parent_terms', 10, 1 );
1216
}
1217
1218
/**
1219
 * Add hooks so that parent product's assigned terms are refreshed when its variations are updated.
1220
 *
1221
 * @since  3.8.9
1222
 * @access private
1223
 */
1224
function _wpsc_add_refresh_variation_parent_term_hooks() {
1225
	add_action( 'transition_post_status', '_wpsc_action_transition_post_status', 10, 3 );
1226
	add_action( 'deleted_post', '_wpsc_action_refresh_variation_parent_terms', 10, 1 );
1227
}
1228
1229
_wpsc_add_refresh_variation_parent_term_hooks();
1230