Completed
Push — master ( ab284c...4fdc7c )
by Justin
07:07
created

product-functions.php ➔ wpsc_admin_submit_product()   F

Complexity

Conditions 61
Paths > 20000

Size

Total Lines 257
Code Lines 142

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 61
eloc 142
nc 589234177
nop 2
dl 0
loc 257
rs 2

How to fix   Long Method    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
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
36
37
	if ( isset( $post_data['meta']['_wpsc_price'] ) )
38
		$post_data['meta']['_wpsc_price'] = wpsc_string_to_float( $post_data['meta']['_wpsc_price'] );
39
40
	if ( isset( $post_data['meta']['_wpsc_special_price'] ) )
41
		$post_data['meta']['_wpsc_special_price'] = wpsc_string_to_float( $post_data['meta']['_wpsc_special_price'] );
42
43
	if ( isset( $post_data['meta']['_wpsc_sku'] ) && $post_data['meta']['_wpsc_sku'] == __('N/A', 'wp-e-commerce') ) {
44
		$post_data['meta']['_wpsc_sku'] = '';
45
	}
46
47
	// Update donation setting
48
	if ( isset( $post_data['wpsc_product_pricing_nonce'] ) && wp_verify_nonce( $post_data['wpsc_product_pricing_nonce'], 'update' ) ) {
49
		$post_data['meta']['_wpsc_is_donation'] = isset( $post_data['meta']['_wpsc_is_donation'] ) ? 1 : 0;
50
	}
51
52
	if ( ! isset( $post_data['meta']['_wpsc_limited_stock'] ) ){
53
		$post_data['meta']['_wpsc_stock'] = false;
54
	} else {
55
		$post_data['meta']['_wpsc_stock'] = isset( $post_data['meta']['_wpsc_stock'] ) ? (int) $post_data['meta']['_wpsc_stock'] : 0;
56
	}
57
58
	unset($post_data['meta']['_wpsc_limited_stock']);
59
	if(!isset($post_data['quantity_limited'])) $post_data['quantity_limited'] = '';
60
    if(!isset($post_data['special'])) $post_data['special'] = '';
61
62
	$post_data['meta']['_wpsc_product_metadata']['quantity_limited'] = (int)(bool)$post_data['quantity_limited'];
63
	$post_data['meta']['_wpsc_product_metadata']['special'] = (int)(bool)$post_data['special'];
64
65
	// Update Stock Options
66
	if ( isset( $_POST['wpsc_product_stock_nonce'] ) && wp_verify_nonce( $_POST['wpsc_product_stock_nonce'], 'update' ) ) {
67
68
		$post_data['meta']['_wpsc_product_metadata'] = wp_parse_args( $post_data['meta']['_wpsc_product_metadata'], array(
69
			'notify_when_none_left'    => 0,
70
			'unpublish_when_none_left' => 0
71
		) );
72
		$post_data['meta']['_wpsc_product_metadata']['notify_when_none_left'] = absint( (bool) $post_data['meta']['_wpsc_product_metadata']['notify_when_none_left'] );
73
		$post_data['meta']['_wpsc_product_metadata']['unpublish_when_none_left'] = absint( (bool) $post_data['meta']['_wpsc_product_metadata']['unpublish_when_none_left'] );
74
75
	}
76
77
	// Update shipping setting
78
	if ( isset( $_POST['wpsc_product_shipping_nonce'] ) && wp_verify_nonce( $_POST['wpsc_product_shipping_nonce'], 'update' ) ) {
79
80
		$post_data['meta']['_wpsc_product_metadata'] = wp_parse_args( $post_data['meta']['_wpsc_product_metadata'], array(
81
			'no_shipping' => 0
82
		) );
83
		$post_data['meta']['_wpsc_product_metadata']['no_shipping'] = absint( (bool) $post_data['meta']['_wpsc_product_metadata']['no_shipping'] );
84
85
	}
86
87
	// Product Weight
88
	if(!isset($post_data['meta']['_wpsc_product_metadata']['display_weight_as'])) $post_data['meta']['_wpsc_product_metadata']['display_weight_as'] = '';
89
90
	if ( isset( $post_data['meta']['_wpsc_product_metadata']['weight'] ) ) {
91
		$weight = wpsc_string_to_float( $post_data['meta']['_wpsc_product_metadata']['weight'] );
92
		$weight = wpsc_convert_weight( $weight, $post_data['meta']['_wpsc_product_metadata']['weight_unit'], "pound", true);
93
		$post_data['meta']['_wpsc_product_metadata']['weight'] = $weight;
94
        $post_data['meta']['_wpsc_product_metadata']['display_weight_as'] = $post_data['meta']['_wpsc_product_metadata']['weight_unit'];
95
	}
96
97
	if ( isset( $post_data['meta']['_wpsc_product_metadata']['dimensions'] ) ) {
98
		$dimensions =& $post_data['meta']['_wpsc_product_metadata']['dimensions'];
99
		foreach ( $dimensions as $key => $value ) {
100
			if ( ! in_array( $key, array( 'height', 'width', 'length' ) ) )
101
				continue;
102
103
			$dimensions[$key] = wpsc_string_to_float( $value );
104
		}
105
	}
106
107
	// Update the table rate prices (quantity discounts)
108
	if ( isset( $post_data['wpsc-update-quantity-discounts'] ) && wp_verify_nonce( $post_data['wpsc-update-quantity-discounts'], 'update-options' ) ) {
109
		$post_data['meta']['_wpsc_product_metadata']['table_rate_price'] = isset( $post_data['table_rate_price'] ) ? $post_data['table_rate_price'] : array();
110
111
		// If table_rate_price is empty, set empty table rate price arrays
112
		if ( empty( $post_data['meta']['_wpsc_product_metadata']['table_rate_price'] ) ) {
113
			$post_data['meta']['_wpsc_product_metadata']['table_rate_price']['table_price'] = array();
114
			$post_data['meta']['_wpsc_product_metadata']['table_rate_price']['quantity'] = array();
115
		}
116
117
		// Remove any rates with no quantity or price
118
		if ( ! empty( $post_data['meta']['_wpsc_product_metadata']['table_rate_price']['table_price'] ) ) {
119
			foreach ( (array) $post_data['meta']['_wpsc_product_metadata']['table_rate_price']['quantity'] as $key => $value ) {
120
				if ( empty( $value ) ) {
121
					unset( $post_data['meta']['_wpsc_product_metadata']['table_rate_price']['table_price'][ $key ] );
122
					unset( $post_data['meta']['_wpsc_product_metadata']['table_rate_price']['quantity'][ $key ] );
123
				}
124
			}
125
			foreach ( (array) $post_data['meta']['_wpsc_product_metadata']['table_rate_price']['table_price'] as $key => $value ) {
126
				if ( empty( $value ) ) {
127
					unset( $post_data['meta']['_wpsc_product_metadata']['table_rate_price']['table_price'][ $key ] );
128
					unset( $post_data['meta']['_wpsc_product_metadata']['table_rate_price']['quantity'][ $key ] );
129
				}
130
			}
131
		}
132
	}
133
134
	if ( isset( $post_data['meta']['_wpsc_product_metadata']['shipping'] ) ) {
135
		$post_data['meta']['_wpsc_product_metadata']['shipping']['local'] = wpsc_string_to_float( $post_data['meta']['_wpsc_product_metadata']['shipping']['local'] );
136
		$post_data['meta']['_wpsc_product_metadata']['shipping']['international'] = wpsc_string_to_float( $post_data['meta']['_wpsc_product_metadata']['shipping']['international'] );
137
	}
138
139
	// Update product taxes
140
	if ( isset( $_POST['wpsc_product_tax_nonce'] ) && wp_verify_nonce( $_POST['wpsc_product_tax_nonce'], 'update' ) ) {
141
142
		$post_data['meta']['_wpsc_product_metadata'] = wp_parse_args( $post_data['meta']['_wpsc_product_metadata'], array(
143
			'wpec_taxes_taxable_amount' => '',
144
			'wpec_taxes_taxable'        => ''
145
		) );
146
		if ( ! empty( $post_data['meta']['_wpsc_product_metadata']['wpec_taxes_taxable_amount'] ) ) {
147
			$post_data['meta']['_wpsc_product_metadata']['wpec_taxes_taxable_amount'] = wpsc_string_to_float($post_data['meta']['_wpsc_product_metadata']['wpec_taxes_taxable_amount'] );
148
		}
149
		$post_data['meta']['_wpsc_product_metadata']['wpec_taxes_taxable'] = $post_data['meta']['_wpsc_product_metadata']['wpec_taxes_taxable'];
150
151
	}
152
153
	// External Link Options
154
	if ( isset( $_POST['wpsc_product_external_link_nonce'] ) && wp_verify_nonce( $_POST['wpsc_product_external_link_nonce'], 'update' ) ) {
155
156
		// Parse post meta to ensure default values
157
		$post_data['meta']['_wpsc_product_metadata'] = wp_parse_args( $post_data['meta']['_wpsc_product_metadata'], array(
158
			'external_link'        => '',
159
			'external_link_text'   => '',
160
			'external_link_target' => ''
161
		) );
162
163
	}
164
165
	// Advanced Options
166
	if ( isset( $_POST['wpsc_product_personalization_nonce'] ) && wp_verify_nonce( $_POST['wpsc_product_personalization_nonce'], 'update' ) ) {
167
168
		// Parse post meta to ensure default values (especially checkboxes)
169
		$post_data['meta']['_wpsc_product_metadata'] = wp_parse_args( $post_data['meta']['_wpsc_product_metadata'], array(
170
			'engraved'                => 0,
171
			'can_have_uploaded_image' => 0
172
		) );
173
174
		$post_data['meta']['_wpsc_product_metadata']['engraved'] = absint( (bool) $post_data['meta']['_wpsc_product_metadata']['engraved'] );
175
		$post_data['meta']['_wpsc_product_metadata']['can_have_uploaded_image'] = absint( (bool) $post_data['meta']['_wpsc_product_metadata']['can_have_uploaded_image'] );
176
177
	}
178
179
	if ( ! isset($post_data['meta']['_wpsc_product_metadata']['google_prohibited'])) $post_data['meta']['_wpsc_product_metadata']['google_prohibited'] = '';
180
	$post_data['meta']['_wpsc_product_metadata']['google_prohibited'] = (int)(bool)$post_data['meta']['_wpsc_product_metadata']['google_prohibited'];
181
182
	// Fill in any missing meta values with existing values.
183
	$post_data['meta'] = wp_parse_args( $post_data['meta'], array(
184
		'_wpsc_is_donation' => get_product_meta( $product_id, 'is_donation', true )
185
	) );
186
187
	// Fill in any missing product meta values with existing values.
188
	$default_meta_values = wp_parse_args( get_product_meta( $product_id, 'product_metadata', true ), array(
189
		'notify_when_none_left'    => 0,
190
		'unpublish_when_none_left' => 0,
191
		'no_shipping'              => 0,
192
		'external_link'            => '',
193
		'external_link_text'       => '',
194
		'external_link_target'     => '',
195
		'engraved'                 => 0,
196
		'can_have_uploaded_image'  => 0
197
	) );
198
199
	$post_data['meta']['_wpsc_product_metadata'] = wp_parse_args( $post_data['meta']['_wpsc_product_metadata'], $default_meta_values );
200
201
	$post_data['files'] = $_FILES;
202
203
	if(isset($post_data['post_title']) && $post_data['post_title'] != '') {
204
205
	$product_columns = array(
206
		'name' => '',
207
		'description' => '',
208
		'additional_description' => '',
209
		'price' => null,
210
		'weight' => null,
211
		'weight_unit' => '',
212
		'pnp' => null,
213
		'international_pnp' => null,
214
		'file' => null,
215
		'image' => '0',
216
		'quantity_limited' => '',
217
		'quantity' => null,
218
		'special' => null,
219
		'special_price' => null,
220
		'display_frontpage' => null,
221
		'notax' => null,
222
		'publish' => null,
223
		'active' => null,
224
		'donation' => null,
225
		'no_shipping' => null,
226
		'thumbnail_image' => null,
227
		'thumbnail_state' => null
228
	);
229
230
	foreach ( $product_columns as $column => $default ) {
231
		if ( ! isset( $post_data[ $column ] ) ) {
232
			$post_data[ $column ] = '';
233
		}
234
	}
235
236
	// if we succeed, we can do further editing (todo - if_wp_error)
237
238
	// if we have no categories selected, assign one.
239
	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){
240
		$post_data['tax_input']['wpsc_product_category'][1] = wpsc_add_product_category_default($product_id);
241
	}
242
243
	// and the meta
244
	wpsc_update_product_meta($product_id, $post_data['meta']);
245
246
	// and the custom meta
247
	wpsc_update_custom_meta($product_id, $post_data);
248
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
249
250
	// Update the alternative currencies
251
	if ( isset( $post_data['wpsc-update-currency-layers'] ) && wp_verify_nonce( $post_data['wpsc-update-currency-layers'], 'update-options' ) ) {
252
253
		// Clear currencies before re-saving to make sure deleted currencies are removed
254
		update_product_meta( $product_id, 'currency', array() );
255
256
		if ( ! empty( $post_data['newCurrency'] ) ) {
257
			foreach( (array) $post_data['newCurrency'] as $key =>$value ) {
258
				wpsc_update_alt_product_currency( $product_id, $value, $post_data['newCurrPrice'][ $key ] );
259
			}
260
		}
261
	}
262
263
	if ( isset( $post_data['files']['file'] ) && $post_data['files']['file']['tmp_name'] != '' ) {
264
		wpsc_item_process_file($product_id, $post_data['files']['file']);
265
	} else {
266
		if (!isset($post_data['select_product_file'])) $post_data['select_product_file'] = null;
267
	  	wpsc_item_reassign_file($product_id, $post_data['select_product_file']);
268
	}
269
270
	if(isset($post_data['files']['preview_file']['tmp_name']) && ($post_data['files']['preview_file']['tmp_name'] != '')) {
271
 		wpsc_item_add_preview_file($product_id, $post_data['files']['preview_file']);
272
	}
273
	do_action('wpsc_edit_product', $product_id);
274
	}
275
	return $product_id;
276
}
277
278
279
function wpsc_pre_update( $data , $postarr ) {
0 ignored issues
show
introduced by
Expected 0 spaces between argument "$data" and comma; 1 found
Loading history...
280
 	if ( (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || $postarr["post_type"] != 'wpsc-product' )
281
        return $data;
282
    if( isset( $postarr["additional_description"] ) )
283
        $data["post_excerpt"] = $postarr["additional_description"];
284
285
	 if( isset( $postarr["parent_post"] ) && !empty( $postarr["parent_post"] ) )
286
        $data["post_parent"] = $postarr["parent_post"];
287
288
	// Sanitize status for variations (see #324)
289
	if ( $data['post_parent'] && ( ! isset( $data['ID'] ) || $data['post_parent'] != $data['ID'] ) && $data['post_status'] == 'publish' ) {
290
		$data['post_status'] = 'inherit';
291
	}
292
293
	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'] ) ) ) {
294
		$data["comment_status"] = "closed";
295
	} else {
296
		$data["comment_status"] = "open";
297
	}
298
299
    //Can anyone explain to me why this is here?
300
    if ( isset( $sku ) && ( $sku != '' ) )
0 ignored issues
show
Bug introduced by
The variable $sku seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
301
        $data['guid'] = $sku;
302
303
    return $data;
304
}
305
add_filter( 'wp_insert_post_data','wpsc_pre_update', 99, 2 );
306
add_action( 'save_post', 'wpsc_admin_submit_product', 5, 2 );
307
add_action( 'admin_notices', 'wpsc_admin_submit_notices' );
308
309
/**
310
 * Remove category meta box from variation editor. This would disassociate variations
311
 * with the default category. See #431 (http://code.google.com/p/wp-e-commerce/issues/detail?id=431)
312
 *
313
 */
314
function wpsc_variation_remove_metaboxes() {
315
	global $post;
316
	if ( ! $post->post_parent )
317
		return;
318
319
	remove_meta_box( 'wpsc_product_categorydiv', 'wpsc-product', 'side' );
320
}
321
add_action( 'add_meta_boxes_wpsc-product', 'wpsc_variation_remove_metaboxes', 99 );
322
323
function wpsc_admin_submit_notices() {
324
    global $current_screen, $post;
325
326
    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...
327
            return;
328
    foreach ( $_SESSION['product_error_messages'] as $error )
0 ignored issues
show
introduced by
Usage of $_SESSION variable is prohibited.
Loading history...
329
        echo "<div id=\"message\" class=\"updated below-h2\"><p>".$error."</p></div>";
330
    unset( $_SESSION['product_error_messages'] );
0 ignored issues
show
introduced by
Usage of $_SESSION variable is prohibited.
Loading history...
331
}
332
333
/**
334
  * wpsc_add_product_category_default, if there is no category assigned assign first product category as default
335
  *
336
  * @since 3.8
337
  * @param $product_id (int) the Post ID
338
  * @return null
339
  */
340
function wpsc_add_product_category_default( $product_id ){
341
	$terms = get_terms( 'wpsc_product_category', array( 'orderby' => 'id', 'hide_empty' => 0 ) );
342
	if ( ! empty( $terms ) ) {
343
		$default = array_shift( $terms );
344
		wp_set_object_terms( $product_id , array( $default->slug ) , 'wpsc_product_category' );
345
	}
346
}
347
/**
348
* wpsc_sanitise_product_forms function
349
*
350
* @return array - Sanitised product details
351
*/
352
function wpsc_sanitise_product_forms($post_data = null) {
353
	if ( empty($post_data) ) {
354
		$post_data = &$_POST;
355
	}
356
357
	$post_data = stripslashes_deep( $post_data );
358
359
	$post_data['name'] = isset($post_data['post_title']) ? $post_data['post_title'] : '';
360
	$post_data['title'] = $post_data['name'];
361
	$post_data['description'] = isset($post_data['content']) ? $post_data['content'] : '';
362
	$post_data['additional_description'] = isset($post_data['additional_description']) ? $post_data['additional_description'] : '';
363
	$post_data['post_status'] = 'draft';
364
365
	if(isset($post_data['publish'])) {
366
		$post_data['post_status'] = 'publish';
367
	} else if(isset($post_data['unpublish'])) {
368
		$post_data['post_status'] = 'draft';
369
	}
370
371
	$post_data['meta']['_wpsc_price'] = wpsc_string_to_float( $post_data['meta']['_wpsc_price'] );
372
	$post_data['meta']['_wpsc_special_price'] = wpsc_string_to_float( $post_data['meta']['_wpsc_special_price'] );
373
	if (!isset($post_data['meta']['_wpsc_is_donation'])) $post_data['meta']['_wpsc_is_donation'] = '';
374
	$post_data['meta']['_wpsc_is_donation'] = (int)(bool)$post_data['meta']['_wpsc_is_donation'];
375
	$post_data['meta']['_wpsc_stock'] = (int)$post_data['meta']['_wpsc_stock'];
376
377
	if (!isset($post_data['meta']['_wpsc_limited_stock'])) $post_data['meta']['_wpsc_limited_stock'] = '';
378
	if((bool)$post_data['meta']['_wpsc_limited_stock'] != true) {
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...
379
	  $post_data['meta']['_wpsc_stock'] = false;
380
	}
381
	unset($post_data['meta']['_wpsc_limited_stock']);
382
	if(!isset($post_data['meta']['_wpsc_product_metadata']['notify_when_none_left'])) $post_data['meta']['_wpsc_product_metadata']['notify_when_none_left'] = 0;
383
	if(!isset($post_data['meta']['_wpsc_product_metadata']['unpublish_when_none_left'])) $post_data['meta']['_wpsc_product_metadata']['unpublish_when_none_left'] = '';
384
    if(!isset($post_data['quantity_limited'])) $post_data['quantity_limited'] = '';
385
    if(!isset($post_data['special'])) $post_data['special'] = '';
386
    if(!isset($post_data['meta']['_wpsc_product_metadata']['no_shipping'])) $post_data['meta']['_wpsc_product_metadata']['no_shipping'] = '';
387
388
	$post_data['meta']['_wpsc_product_metadata']['notify_when_none_left'] = (int)(bool)$post_data['meta']['_wpsc_product_metadata']['notify_when_none_left'];
389
	$post_data['meta']['_wpsc_product_metadata']['unpublish_when_none_left'] = (int)(bool)$post_data['meta']['_wpsc_product_metadata']['unpublish_when_none_left'];
390
	$post_data['meta']['_wpsc_product_metadata']['quantity_limited'] = (int)(bool)$post_data['quantity_limited'];
391
	$post_data['meta']['_wpsc_product_metadata']['special'] = (int)(bool)$post_data['special'];
392
	$post_data['meta']['_wpsc_product_metadata']['no_shipping'] = (int)(bool)$post_data['meta']['_wpsc_product_metadata']['no_shipping'];
393
394
	// Product Weight
395
	if(!isset($post_data['meta']['_wpsc_product_metadata']['display_weight_as'])) $post_data['meta']['_wpsc_product_metadata']['display_weight_as'] = '';
396
    if(!isset($post_data['meta']['_wpsc_product_metadata']['display_weight_as'])) $post_data['meta']['_wpsc_product_metadata']['display_weight_as'] = '';
397
398
    $weight = wpsc_string_to_float( $post_data['meta']['_wpsc_product_metadata']['weight'] );
399
	$weight = wpsc_convert_weight( $weight, $post_data['meta']['_wpsc_product_metadata']['weight_unit'], "pound", true);
400
	$post_data['meta']['_wpsc_product_metadata']['weight'] = $weight;
401
	$post_data['meta']['_wpsc_product_metadata']['display_weight_as'] = $post_data['meta']['_wpsc_product_metadata']['weight_unit'];
402
403
	$post_data['files'] = $_FILES;
404
	return $post_data;
405
}
406
407
 /**
408
	* wpsc_insert_product function
409
	*
410
	* @param unknown
411
	* @return unknown
412
*/
413
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...
414
	global $wpdb, $user_ID;
415
	$adding = false;
416
	$update = false;
417
418
	$product_columns = array(
419
		'name' => '',
420
		'description' => '',
421
		'additional_description' => '',
422
		'price' => null,
423
		'weight' => null,
424
		'weight_unit' => '',
425
		'pnp' => null,
426
		'international_pnp' => null,
427
		'file' => null,
428
		'image' => '0',
429
		'quantity_limited' => '',
430
		'quantity' => null,
431
		'special' => null,
432
		'special_price' => null,
433
		'display_frontpage' => null,
434
		'notax' => null,
435
		'publish' => null,
436
		'active' => null,
437
		'donation' => null,
438
		'no_shipping' => null,
439
		'thumbnail_image' => null,
440
		'thumbnail_state' => null
441
	);
442
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
443
444
	foreach ( $product_columns as $column => $default ) {
445
		if ( ! isset( $post_data[ $column ] ) ) {
446
			$post_data[ $column ] = '';
447
		}
448
	}
449
450
	$product_post_values = array(
451
		'post_author' => $user_ID,
452
		'post_content' => $post_data['description'],
453
		'post_excerpt' => $post_data['additional_description'],
454
		'post_title' => $post_data['name'],
455
		'post_status' => $post_data['post_status'],
456
		'post_type' => "wpsc-product",
457
		'post_name' => sanitize_title($post_data['name'])
458
	);
459
	$product_post_values["comment_status"] = "open";
460
461
	$product_id = wp_insert_post($product_post_values);
462
	if ( isset ( $post_data["sticky"] ) ) {
0 ignored issues
show
Coding Style introduced by
Space before opening parenthesis of function call prohibited
Loading history...
463
		stick_post($product_id);
464
	}else {
465
		unstick_post($product_id);
466
	}
467
468
	$adding = true;
469
470
	// if we succeed, we can do further editing
471
472
	// and the meta
473
	wpsc_update_product_meta($product_id, $post_data['meta']);
474
	do_action('wpsc_edit_product', $product_id);
475
	return $product_id;
476
}
477
478
/**
479
 * term_id_price function
480
 * Retreives associated price, if any, with term_id
481
 * @param integer term ID
482
 * @param integer parent product price
483
 * @return integer modified price for child product, based on term ID price and parent price
484
 */
485
486
function term_id_price($term_id, $parent_price) {
487
488
	$term_price_arr = get_option( 'term_prices' );
489
490
	if ( isset($term_price_arr[$term_id]) ) {
491
		$price = $term_price_arr[$term_id]["price"];
492
	} else {
493
		$price = 0;
494
	}
495
496
	//Check for flat, percentile or differential
497
		$var_price_type = '';
498
499
		if (flat_price($price)) {
500
			$var_price_type = 'flat';
501
			$price = floatval($price);
502
		} elseif ( differential_price($price) ) {
503
			$var_price_type = 'differential';
504
		} elseif (percentile_price($price)) {
505
			$var_price_type = 'percentile';
506
		}
507
508
		if (strchr($price, '-') ) {
509
			$positive = false;
510
		} else {
511
			$positive = true;
512
		}
513
514
		if ($positive) {
515
516
			if ( $var_price_type == 'differential' ) {
517
				$differential = (floatval($price));
518
				$price = $parent_price + $differential;
519
			} elseif ( $var_price_type == 'percentile' ) {
520
				$percentage = (floatval($price) / 100);
521
				$price = $parent_price + ($parent_price * $percentage);
522
			}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
523
524
		} else {
525
526
			if ( $var_price_type == 'differential' ) {
527
				$differential = (floatval($price));
528
				$price = $parent_price - $differential;
529
			} elseif ( $var_price_type == 'percentile' ) {
530
				$percentage = (floatval($price) / 100);
531
				$price = $parent_price - ($parent_price * $percentage);
532
			}
533
		}
534
	return $price;
535
}
536
537
/**
538
 * Determine the price of a variation product based on the variation it's assigned
539
 * to. Because each variation term can have its own price (eg. 10, +10, -5%), this
540
 * function also takes those into account.
541
 *
542
 * @since 3.8.6
543
 * @param int $variation_id ID of the variation product
544
 * @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...
545
 * the variation product. Pass this argument to save one SQL query.
546
 * @return float Calculated price of the variation
547
 */
548
function wpsc_determine_variation_price( $variation_id, $term_ids = false ) {
549
	$flat = array();
550
	$diff = 0;
551
552
	$variation = get_post( $variation_id );
553
	$price = (float) get_product_meta( $variation->post_parent, 'price', true );
554
555
	if ( ! $term_ids )
556
		$term_ids = wpsc_get_product_terms( $variation_id, 'wpsc-variation', 'term_id' );
557
558
	$term_price_arr = get_option( 'term_prices' );
559
	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...
560
		if ( isset( $term_price_arr[$term_id] ) )
561
			$term_price = trim( $term_price_arr[$term_id]['price'] );
562
		else
563
			continue;
564
		if ( flat_price( $term_price ) ) {
565
			$flat[] = $term_price;
566
		} elseif ( differential_price( $term_price ) ) {
567
			$diff += (float) $term_price;
568
		} elseif ( percentile_price( $term_price ) ) {
569
			$diff += (float) $term_price / 100 * $price;
570
		}
571
	}
572
	// Variation price should at least be the maximum of all flat prices
573
	if ( ! empty( $flat ) )
574
		$price = max( $flat );
575
	$price += $diff;
576
	return $price;
577
}
578
579
/**
580
 * wpsc_edit_product_variations function.
581
 * this is the function to make child products using variations
582
 *
583
 * @access public
584
 * @param mixed $product_id
585
 * @param mixed $post_data
586
 * @return void
587
 */
588
function wpsc_edit_product_variations($product_id, $post_data) {
589
	global $user_ID;
590
591
	$parent = get_post_field( 'post_parent', $product_id );
592
593
	if( ! empty( $parent ) )
594
		return;
595
596
	$variations = array();
597
	$product_children = array();
598
	if (!isset($post_data['edit_var_val']))
599
		$post_data['edit_var_val'] = '';
600
601
	$variations = (array) $post_data['edit_var_val'];
602
603
	// Generate the arrays for variation sets, values and combinations
604
    $wpsc_combinator = new wpsc_variation_combinator($variations);
605
606
	// Retrieve the array containing the variation set IDs
607
	$variation_sets = $wpsc_combinator->return_variation_sets();
608
609
	// Retrieve the array containing the combinations of each variation set to be associated with this product.
610
	$variation_values = $wpsc_combinator->return_variation_values();
611
612
	// Retrieve the array containing the combinations of each variation set to be associated with this product.
613
	$combinations = $wpsc_combinator->return_combinations();
614
615
	$product_terms = wpsc_get_product_terms( $product_id, 'wpsc-variation' );
616
617
	$variation_sets_and_values = array_merge($variation_sets, $variation_values);
618
	$variation_sets_and_values = apply_filters('wpsc_edit_product_variation_sets_and_values', $variation_sets_and_values, $product_id);
619
620
	wp_set_object_terms($product_id, $variation_sets_and_values, 'wpsc-variation');
621
622
	$parent_id = absint( $_REQUEST['product_id'] );
623
624
	$child_product_template = array(
625
		'post_author' 	=> $user_ID,
626
		'post_content' 	=> get_post_field( 'post_content', $parent_id, 'raw' ),
627
		'post_excerpt' 	=> get_post_field( 'post_excerpt', $parent_id, 'raw' ),
628
		'post_title' 	=> get_post_field( 'post_title', $parent_id, 'raw' ),
629
		'post_status' 	=> 'inherit',
630
		'post_type' 	=> "wpsc-product",
631
		'post_parent' 	=> $product_id
632
	);
633
634
	$child_product_meta = get_post_custom($product_id);
635
636
	// here we loop through the combinations, get the term data and generate custom product names
637
	foreach($combinations as $combination) {
638
		$term_names = array();
639
		$term_ids = array();
640
		$term_slugs = array();
641
		$product_values = $child_product_template;
642
643
		$combination_terms = get_terms('wpsc-variation', array(
644
			'hide_empty'	=> 0,
645
			'include' 		=> implode(",", $combination),
646
			'orderby' 		=> 'parent',
647
		));
648
649
		foreach($combination_terms as $term) {
650
			$term_ids[] = $term->term_id;
651
			$term_slugs[] = $term->slug;
652
			$term_names[] = $term->name;
653
		}
654
655
		$product_values['post_title'] .= " (".implode(", ", $term_names).")";
656
		$product_values['post_name'] = sanitize_title($product_values['post_title']);
657
658
		$selected_post = get_posts(array(
659
			'name' 				=> $product_values['post_name'],
660
			'post_parent' 		=> $product_id,
661
			'post_type' 		=> "wpsc-product",
662
			'post_status' 		=> 'all',
663
			'suppress_filters' 	=> true
664
		));
665
		$selected_post = array_shift($selected_post);
666
		$child_product_id = wpsc_get_child_object_in_terms($product_id, $term_ids, 'wpsc-variation');
667
		$already_a_variation = true;
668
		if($child_product_id == false) {
669
			$already_a_variation = false;
670
			if($selected_post != null) {
671
				$child_product_id = $selected_post->ID;
672
			} else {
673
				$child_product_id = wp_insert_post($product_values);
674
			}
675
		} else {
676
			// sometimes there have been problems saving the variations, this gets the correct product ID
677
			if(($selected_post != null) && ($selected_post->ID != $child_product_id)) {
678
				$child_product_id = $selected_post->ID;
679
			}
680
		}
681
		$product_children[] = $child_product_id;
682
		if($child_product_id > 0) {
683
			wp_set_object_terms($child_product_id, $term_slugs, 'wpsc-variation');
684
		}
685
		//JS - 7.9 - Adding loop to include meta data in child product.
686
		if(!$already_a_variation){
687
			$this_child_product_meta = apply_filters( 'insert_child_product_meta', $child_product_meta, $product_id, $combination_terms );
688
			foreach ($this_child_product_meta as $meta_key => $meta_value ) :
689
				if ($meta_key == "_wpsc_product_metadata") {
690
					update_post_meta($child_product_id, $meta_key, unserialize($meta_value[0]));
691
				} else {
692
					update_post_meta($child_product_id, $meta_key, $meta_value[0]);
693
				}
694
695
			endforeach;
696
697
			if ( is_array( $term_ids ) && $price = wpsc_determine_variation_price( $child_product_id, $term_ids ) )
698
				update_product_meta( $child_product_id, 'price', $price );
699
		}
700
	}
701
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
702
703
	//For reasons unknown, this code did not previously deal with variation deletions.
704
	//Basically, we'll just check if any existing term associations are missing from the posted variables, delete if they are.
705
	//Get posted terms (multi-dimensional array, first level = parent var, second level = child var)
706
	$posted_term = $variations;
707
	//Get currently associated terms
708
	$currently_associated_var = $product_terms;
709
710
	$currently_associated_vars = array();
711
	foreach ($currently_associated_var as $current) {
712
		$currently_associated_vars[] = $current->term_id;
713
	}
714
715
	$posted_terms = array();
716
717
	foreach ($posted_term as $term=>$val) {
718
		$posted_terms[] = $term;
719
		if(is_array($val)) {
720
			foreach($val as $term2=>$val2) {
721
				$posted_terms[] = $term2;
722
			}
723
		}
724
	}
725
726
	if(!empty($currently_associated_vars)){
727
		$term_ids_to_delete = array();
728
		$term_ids_to_delete = array_diff($currently_associated_vars, $posted_terms);
729
	}
730
731
	if(isset($_REQUEST["post_ID"])) {
732
		$post_id = $_REQUEST["post_ID"];
733
	} elseif(isset($_REQUEST["product_id"])) {
734
		$post_id = $_REQUEST["product_id"];
735
	} else {
736
		return;
737
	}
738
739
	if(!empty($term_ids_to_delete) && (isset($_REQUEST["product_id"]) || isset($post_id))) {
740
		$post_ids_to_delete = array();
741
742
		// Whatever remains, find child products of current product with that term, in the variation taxonomy, and delete
743
		$post_ids_to_delete = wpsc_get_child_object_in_terms_var($_REQUEST["product_id"], $term_ids_to_delete, 'wpsc-variation');
744
745
		if(is_array($post_ids_to_delete) && !empty($post_ids_to_delete)) {
746
			foreach($post_ids_to_delete as $object_ids) {
747
				foreach($object_ids as $object_id) {
748
					wp_delete_post($object_id);
749
				}
750
			}
751
		}
752
	}
753
	$current_children = get_posts(array(
754
		'post_parent'	=> $post_id,
755
		'post_type'		=> 'wpsc-product',
756
		'post_status'	=> 'all',
757
		'numberposts'   => -1
758
		));
759
760
	$children = array();
761
	foreach((array)$current_children as $child_prod){
762
		$children[] = $child_prod->ID;
763
	}
764
	if(!empty($children)){
765
		$old_ids_to_delete = array_diff($children, $product_children);
766
		$old_ids_to_delete = apply_filters('wpsc_edit_product_variations_deletion', $old_ids_to_delete);
767
		if(is_array($old_ids_to_delete) && !empty($old_ids_to_delete)) {
768
			foreach($old_ids_to_delete as $object_ids) {
769
				wp_delete_post($object_ids);
770
			}
771
		}
772
	}
773
	_wpsc_refresh_parent_product_terms( $parent_id );
774
775
}
776
777
function wpsc_update_alt_product_currency($product_id, $newCurrency, $newPrice){
778
	global $wpdb;
779
780
	$old_curr = get_product_meta($product_id, 'currency',true);
781
	$sql = $wpdb->prepare( "SELECT `isocode` FROM `".WPSC_TABLE_CURRENCY_LIST."` WHERE `id`= %d", $newCurrency );
782
	$isocode = $wpdb->get_var($sql);
783
784
	$newCurrency = 'currency';
785
	$old_curr[$isocode] = $newPrice;
786
	if(($newPrice != '') &&  ($newPrice > 0.00)){
787
		update_product_meta($product_id, $newCurrency, $old_curr);
788
	} else {
789
		if((empty($old_curr[$isocode]) || 0.00 == $old_curr[$isocode]) && is_array($old_curr))
790
			unset($old_curr[$isocode]);
791
		update_product_meta($product_id, $newCurrency, $old_curr);
792
793
	}
794
795
}
796
797
 /**
798
 * wpsc_update_product_meta function
799
 *
800
 * @param integer product ID
801
 * @param string comma separated tags
802
 */
803
function wpsc_update_product_meta($product_id, $product_meta) {
804
    if($product_meta != null) {
805
		foreach((array)$product_meta as $key => $value) {
806
			update_post_meta($product_id, $key, $value);
807
		}
808
	}
809
}
810
811
/**
812
 * Called from javascript within product page to toggle publish status - AJAX
813
 * @return bool	publish status
814
 */
815
function wpsc_ajax_toggle_publish() {
816
/**
817
 * @todo - Check Admin Referer
818
 * @todo - Check Permissions
819
 */
820
	$status = (wpsc_toggle_publish_status($_REQUEST['productid'])) ? ('true') : ('false');
821
	exit( $status );
822
}
823
/*
824
/*  END - Publish /No Publish functions
825
*/
826
827
function wpsc_update_custom_meta($product_id, $post_data) {
828
829
	if ( isset( $post_data['new_custom_meta'] ) && $post_data['new_custom_meta'] != null ) {
830
	foreach((array)$post_data['new_custom_meta']['name'] as $key => $name) {
831
	    $value = $post_data['new_custom_meta']['value'][(int)$key];
832
	    if(($name != '') && ($value != '')) {
833
		add_post_meta($product_id, $name, $value);
834
	    }
835
	}
836
	}
837
838
    if (!isset($post_data['custom_meta'])) $post_data['custom_meta'] = '';
839
    if($post_data['custom_meta'] != null) {
840
	    foreach((array)$post_data['custom_meta'] as $key => $values) {
841
		    if(($values['name'] != '') && ($values['value'] != '')) {
842
			    update_post_meta($product_id, $values['name'], $values['value']);
843
		    }
844
	    }
845
    }
846
}
847
848
 /**
849
 * wpsc_item_process_file function
850
 *
851
 * @param integer product ID
852
 * @param array the file array from $_FILES
853
 * @param array the preview file array from $_FILES
854
 */
855
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...
856
857
	add_filter( 'upload_dir', 'wpsc_modify_upload_directory' );
858
859
	$time = current_time( 'mysql' );
860
861
	if ( $post = get_post( $product_id ) ) {
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
862
		if ( substr( $post->post_date, 0, 4 ) > 0 )
863
			$time = $post->post_date;
864
	}
865
866
	$file = wp_handle_upload( $submitted_file, array( 'test_form' => false ), $time );
867
868
	if ( isset( $file['error'] ) ) {
869
		return new WP_Error( 'upload_error', $file['error'] );
870
	}
871
872
	$name_parts = pathinfo( $file['file'] );
873
874
	// Construct the attachment array
875
	$attachment = array(
876
		'post_mime_type' => $file['type'],
877
		'guid'           => $file['url'],
878
		'post_parent'    => $product_id,
879
		'post_title'     => $name_parts['basename'],
880
		'post_content'   => '',
881
		'post_type'      => 'wpsc-product-file',
882
		'post_status'    => 'inherit'
883
	);
884
885
	// Save the data
886
	wp_insert_post( $attachment );
887
888
	remove_filter( 'upload_dir', 'wpsc_modify_upload_directory' );
889
}
890
891
function wpsc_modify_upload_directory($input) {
892
	$previous_subdir = $input['subdir'];
893
	$download_subdir = str_replace($input['basedir'], '', WPSC_FILE_DIR);
894
	$input['path'] = substr_replace(str_replace($previous_subdir, $download_subdir, $input['path']),'',-1);
895
	$input['url'] = substr_replace(str_replace($previous_subdir, $download_subdir, $input['url']),'',-1);
896
	$input['subdir'] = substr_replace(str_replace($previous_subdir, $download_subdir, $input['subdir']),'',-1);
897
	return $input;
898
}
899
900
function wpsc_modify_preview_directory($input) {
901
	$previous_subdir = $input['subdir'];
902
	$download_subdir = str_replace($input['basedir'], '', WPSC_PREVIEW_DIR);
903
904
	$input['path'] = substr_replace(str_replace($previous_subdir, $download_subdir, $input['path']),'',-1);
905
	$input['url'] = substr_replace(str_replace($previous_subdir, $download_subdir, $input['url']),'',-1);
906
	$input['subdir'] = substr_replace(str_replace($previous_subdir, $download_subdir, $input['subdir']),'',-1);
907
908
	return $input;
909
}
910
911
 /**
912
 * wpsc_item_reassign_file function
913
 *
914
 * @param integer product ID
915
 * @param string the selected file name;
916
 */
917
function wpsc_item_reassign_file($product_id, $selected_files) {
918
	global $wpdb;
919
	$product_file_list = array();
920
	// initialise $idhash to null to prevent issues with undefined variables and error logs
921
	$idhash = null;
922
923
	$args = array(
924
		'post_type' => 'wpsc-product-file',
925
		'post_parent' => $product_id,
926
		'numberposts' => -1,
0 ignored issues
show
introduced by
Disabling pagination is prohibited in VIP context, do not set numberposts to -1 ever.
Loading history...
927
		'post_status' => 'any'
928
	);
929
930
	$attached_files = (array) get_posts( $args );
931
	$attached_files_by_file = array();
932
933
	foreach($attached_files as $key => $attached_file) {
934
		$attached_files_by_file[$attached_file->post_title] = $attached_files[$key];
935
	}
936
937
	/* if we are editing, grab the current file and ID hash */
938
	if(!$selected_files) {
939
		// unlikely that anyone will ever upload a file called .none., so its the value used to signify clearing the product association
940
		return null;
941
	}
942
943
	foreach($selected_files as $selected_file) {
944
		// if we already use this file, there is no point doing anything more.
945
		$file_is_attached = false;
946
		$selected_file_path = WPSC_FILE_DIR.basename($selected_file);
947
948
		if(isset($attached_files_by_file[$selected_file])) {
949
			$file_is_attached = true;
950
		}
951
952
		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...
953
			$type = wpsc_get_mimetype($selected_file_path);
954
			$attachment = array(
955
				'post_mime_type' => $type,
956
				'post_parent' => $product_id,
957
				'post_title' => $selected_file,
958
				'post_content' => '',
959
				'post_type' => "wpsc-product-file",
960
				'post_status' => 'inherit'
961
			);
962
			wp_insert_post($attachment);
963
		} else {
964
			$product_post_values = array(
965
				'ID' => $attached_files_by_file[$selected_file]->ID,
966
				'post_status' => 'inherit'
967
			);
968
			wp_update_post($product_post_values);
969
		}
970
	}
971
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
972
973
	foreach($attached_files as $attached_file) {
974
		if(!in_array($attached_file->post_title, $selected_files)) {
975
			$product_post_values = array(
976
				'ID' => $attached_file->ID,
977
				'post_status' => 'draft'
978
			);
979
			wp_update_post($product_post_values);
980
		}
981
	}
982
983
	return true;
984
}
985
986
 /**
987
 * wpsc_delete_preview_file
988
 *
989
 * @param integer product ID
990
 */
991
992
function wpsc_delete_preview_file($product_id) {
993
994
	$args = array(
995
	'post_type' => 'wpsc-preview-file',
996
	'post_parent' => $product_id,
997
	'numberposts' => -1,
0 ignored issues
show
introduced by
Disabling pagination is prohibited in VIP context, do not set numberposts to -1 ever.
Loading history...
998
	'post_status' => 'all'
999
	);
1000
1001
	$preview_files = (array)get_posts( $args );
1002
1003
	foreach( $preview_files as $preview ) {
1004
		$preview_id = $preview->ID;
1005
		wp_delete_post($preview_id);
1006
	}
1007
	return true;
1008
}
1009
1010
 /**
1011
 * wpsc_item_add_preview_file function
1012
 *
1013
 * @param integer product ID
1014
 * @param array the preview file array from $_FILES
1015
 */
1016
function wpsc_item_add_preview_file($product_id, $preview_file) {
1017
  global $wpdb;
1018
1019
  wpsc_delete_preview_file($product_id);
1020
1021
  add_filter('upload_dir', 'wpsc_modify_preview_directory');
1022
	$overrides = array('test_form'=>false);
1023
1024
	$time = current_time('mysql');
1025
	if ( $post = get_post($product_id) ) {
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
1026
		if ( substr( $post->post_date, 0, 4 ) > 0 )
1027
			$time = $post->post_date;
1028
	}
1029
1030
	$file = wp_handle_upload($preview_file, $overrides, $time);
1031
1032
	if ( isset($file['error']) )
1033
		return new WP_Error( 'upload_error', $file['error'] );
1034
1035
	$name_parts = pathinfo($file['file']);
1036
	$name = $name_parts['basename'];
1037
1038
	$url = $file['url'];
1039
	$type = $file['type'];
1040
	$file = $file['file'];
1041
	$title = $name;
1042
	$content = '';
1043
1044
	// Construct the attachment array
1045
	$attachment = array(
1046
		'post_mime_type' => $type,
1047
		'guid' => $url,
1048
		'post_parent' => $product_id,
1049
		'post_title' => $title,
1050
		'post_content' => $content,
1051
		'post_type' => "wpsc-preview-file",
1052
		'post_status' => 'inherit'
1053
	);
1054
1055
	// Save the data
1056
	$id = wp_insert_post($attachment, $file, $product_id);
1057
	remove_filter('upload_dir', 'wpsc_modify_preview_directory');
1058
  	return $id;
1059
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
1060
1061
}
1062
1063
/**
1064
 * wpsc_variation_combinator class.
1065
 * Produces all combinations of variations selected for this product
1066
 * this class is based off the example code from here:
1067
 * http://www.php.net/manual/en/ref.array.php#94910
1068
 * Thanks, phektus, you are awesome, whoever you are.
1069
 */
1070
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...
1071
	var $variation_sets = array();
1072
	var $variation_values = array();
1073
	var $reprocessed_array = array();
1074
	var $combinations= array();
1075
1076
public function __construct($variation_sets) {
1077
	if( $variation_sets ) {
1078
		foreach($variation_sets as $variation_set_id => $variation_set) {
1079
			$this->variation_sets[] = absint($variation_set_id);
1080
			$new_variation_set = array();
1081
			if( $variation_set ) {
1082
				foreach($variation_set as $variation => $active) {
1083
					if($active == 1) {
1084
						$new_variation_set[] = array(absint($variation));
1085
						$this->variation_values[] = $variation;
1086
					}
1087
				}
1088
			}
1089
			$this->reprocessed_array[] = $new_variation_set;
1090
		}
1091
		$this->get_combinations(array(), $this->reprocessed_array, 0);
1092
	}
1093
}
1094
1095
1096
	function get_combinations($batch, $elements, $i)  {
1097
        if ($i >= count($elements)) {
1098
            $this->combinations[] = $batch;
1099
        } else {
1100
            foreach ($elements[$i] as $element) {
1101
                $this->get_combinations(array_merge($batch, $element), $elements, $i + 1);
1102
            }
1103
        }
1104
	}
1105
1106
	function return_variation_sets() {
1107
		return $this->variation_sets;
1108
	}
1109
1110
	function return_variation_values() {
1111
		return $this->variation_values;
1112
	}
1113
1114
	function return_combinations() {
1115
		return $this->combinations;
1116
1117
	}
1118
}
1119
1120
function wpsc_variations_stock_remaining($product_id){
1121
	global $wpdb;
1122
	return $wpdb->get_var( $wpdb->prepare( '
1123
		SELECT
1124
			sum(`pm`.`meta_value`)
1125
		FROM
1126
			`' . $wpdb->postmeta . '` `pm`
1127
		JOIN
1128
			`' . $wpdb->posts . '` `p`
1129
			ON
1130
			`pm`.`post_id` = `p`.`id`
1131
		WHERE
1132
			`p`.`post_type`= "wpsc-product"
1133
			AND
1134
			`p`.`post_parent` = %d
1135
			AND
1136
			`pm`.`meta_key` = "_wpsc_stock"
1137
	', $product_id ) );
1138
}
1139
1140
function flat_price( $price ) {
1141
	if ( ! empty( $price ) && strchr( $price, '-' ) === false && strchr( $price, '+' ) === false && strchr( $price, '%' ) === false )
1142
		return true;
1143
}
1144
1145
function percentile_price( $price ) {
1146
	if ( ! empty( $price ) && ( strchr( $price, '-' ) || strchr( $price, '+' ) ) && strchr( $price, '%' ) )
1147
		return true;
1148
}
1149
1150
function differential_price( $price ) {
1151
	if ( ! empty( $price ) && ( strchr( $price, '-' ) || strchr( $price, '+' ) ) && strchr( $price, '%' ) === false )
1152
		return true;
1153
}
1154
1155
/**
1156
 * Refresh variation terms assigned to parent product based on the variations it has.
1157
 *
1158
 * @since 3.8.9
1159
 * @access private
1160
 * @param  int $parent_id Parent product ID
1161
 */
1162
function _wpsc_refresh_parent_product_terms( $parent_id ) {
1163
	$children = get_children( array(
1164
		'post_parent' => $parent_id,
1165
		'post_status' => array( 'publish', 'inherit' ),
1166
	) );
1167
1168
	$children_ids = wp_list_pluck( $children, 'ID' );
1169
1170
	$children_terms = wp_get_object_terms( $children_ids, 'wpsc-variation' );
1171
	$new_terms = array();
1172
	foreach ( $children_terms as $term ) {
1173
		if ( $term->parent )
1174
			$new_terms[] = $term->parent;
1175
	}
1176
1177
	$children_term_ids = wp_list_pluck( $children_terms, 'term_id' );
1178
	$new_terms = array_merge( $new_terms, $children_term_ids );
1179
	$new_terms = array_unique( $new_terms );
1180
	$new_terms = array_map( 'absint', $new_terms );
1181
	wp_set_object_terms( $parent_id, $new_terms, 'wpsc-variation' );
1182
}
1183
1184
/**
1185
 * Make sure parent product's assigned terms are refreshed when its variations are deleted or trashed
1186
 *
1187
 * @since 3.8.9
1188
 * @access private
1189
 * @param  int $post_id Parent product ID
1190
 */
1191
function _wpsc_action_refresh_variation_parent_terms( $post_id ) {
1192
	$post = get_post( $post_id );
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
1193
	if ( $post->post_type != 'wpsc-product' || ! $post->post_parent || in_array( $post->post_status, array( 'publish', 'inherit' ) ) )
1194
		return;
1195
1196
	_wpsc_refresh_parent_product_terms( $post->post_parent );
1197
}
1198
1199
/**
1200
 * Make sure parent product's assigned terms are refresh when its variations' statuses are changed
1201
 *
1202
 * @since 3.8.9
1203
 * @access private
1204
 * @param  string $new_status New status
1205
 * @param  string $old_status Old status
1206
 * @param  object $post       Variation object
1207
 */
1208
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...
1209
	if ( $post->post_type != 'wpsc-product' || ! $post->post_parent )
1210
		return;
1211
1212
	_wpsc_refresh_parent_product_terms( $post->post_parent );
1213
}
1214
1215
/**
1216
 * Prevent parent terms from being refreshed when its variations are updated. This is useful when
1217
 * the variations are being mass updated.
1218
 *
1219
 * @since  3.8.9
1220
 * @access private
1221
 */
1222
function _wpsc_remove_refresh_variation_parent_term_hooks() {
1223
	remove_action( 'transition_post_status', '_wpsc_action_transition_post_status', 10, 3 );
1224
	remove_action( 'deleted_post', '_wpsc_action_refresh_variation_parent_terms', 10, 1 );
1225
}
1226
1227
/**
1228
 * Add hooks so that parent product's assigned terms are refreshed when its variations are updated.
1229
 *
1230
 * @since  3.8.9
1231
 * @access private
1232
 */
1233
function _wpsc_add_refresh_variation_parent_term_hooks() {
1234
	add_action( 'transition_post_status', '_wpsc_action_transition_post_status', 10, 3 );
1235
	add_action( 'deleted_post', '_wpsc_action_refresh_variation_parent_terms', 10, 1 );
1236
}
1237
1238
_wpsc_add_refresh_variation_parent_term_hooks();