wc-admin-functions.php ➔ wc_save_order_items()   F
last analyzed

Complexity

Conditions 33
Paths > 20000

Size

Total Lines 199
Code Lines 110

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 33
dl 0
loc 199
rs 2
c 0
b 0
f 0
eloc 110
nc 23040
nop 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
 * WooCommerce Admin Functions
4
 *
5
 * @author   WooThemes
6
 * @category Core
7
 * @package  WooCommerce/Admin/Functions
8
 * @version  2.4.0
9
 */
10
11
if ( ! defined( 'ABSPATH' ) ) {
12
	exit; // Exit if accessed directly
13
}
14
15
/**
16
 * Get all WooCommerce screen ids.
17
 *
18
 * @return array
19
 */
20
function wc_get_screen_ids() {
21
22
	$wc_screen_id = sanitize_title( __( 'WooCommerce', 'woocommerce' ) );
23
	$screen_ids   = array(
24
		'toplevel_page_' . $wc_screen_id,
25
		$wc_screen_id . '_page_wc-reports',
26
		$wc_screen_id . '_page_wc-shipping',
27
		$wc_screen_id . '_page_wc-settings',
28
		$wc_screen_id . '_page_wc-status',
29
		$wc_screen_id . '_page_wc-addons',
30
		'toplevel_page_wc-reports',
31
		'product_page_product_attributes',
32
		'edit-product',
33
		'product',
34
		'edit-shop_coupon',
35
		'shop_coupon',
36
		'edit-product_cat',
37
		'edit-product_tag',
38
		'profile',
39
		'user-edit'
40
	);
41
42
	foreach ( wc_get_order_types() as $type ) {
43
		$screen_ids[] = $type;
44
		$screen_ids[] = 'edit-' . $type;
45
	}
46
47
	return apply_filters( 'woocommerce_screen_ids', $screen_ids );
48
}
49
50
/**
51
 * Create a page and store the ID in an option.
52
 *
53
 * @param mixed $slug Slug for the new page
54
 * @param string $option Option name to store the page's ID
55
 * @param string $page_title (default: '') Title for the new page
56
 * @param string $page_content (default: '') Content for the new page
57
 * @param int $post_parent (default: 0) Parent for the new page
58
 * @return int page ID
59
 */
60
function wc_create_page( $slug, $option = '', $page_title = '', $page_content = '', $post_parent = 0 ) {
61
	global $wpdb;
62
63
	$option_value     = get_option( $option );
64
65
	if ( $option_value > 0 ) {
66
		$page_object = get_post( $option_value );
67
68
		if ( 'page' === $page_object->post_type && ! in_array( $page_object->post_status, array( 'pending', 'trash', 'future', 'auto-draft' ) ) ) {
69
			// Valid page is already in place
70
			return $page_object->ID;
71
		}
72
	}
73
74 View Code Duplication
	if ( strlen( $page_content ) > 0 ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
75
		// Search for an existing page with the specified page content (typically a shortcode)
76
		$valid_page_found = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_type='page' AND post_status NOT IN ( 'pending', 'trash', 'future', 'auto-draft' ) AND post_content LIKE %s LIMIT 1;", "%{$page_content}%" ) );
77
	} else {
78
		// Search for an existing page with the specified page slug
79
		$valid_page_found = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_type='page' AND post_status NOT IN ( 'pending', 'trash', 'future', 'auto-draft' )  AND post_name = %s LIMIT 1;", $slug ) );
80
	}
81
82
	$valid_page_found = apply_filters( 'woocommerce_create_page_id', $valid_page_found, $slug, $page_content );
83
84
	if ( $valid_page_found ) {
85
		if ( $option ) {
86
			update_option( $option, $valid_page_found );
87
		}
88
		return $valid_page_found;
89
	}
90
91
	// Search for a matching valid trashed page
92 View Code Duplication
	if ( strlen( $page_content ) > 0 ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
93
		// Search for an existing page with the specified page content (typically a shortcode)
94
		$trashed_page_found = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_type='page' AND post_status = 'trash' AND post_content LIKE %s LIMIT 1;", "%{$page_content}%" ) );
95
	} else {
96
		// Search for an existing page with the specified page slug
97
		$trashed_page_found = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_type='page' AND post_status = 'trash' AND post_name = %s LIMIT 1;", $slug ) );
98
	}
99
100
	if ( $trashed_page_found ) {
101
		$page_id   = $trashed_page_found;
102
		$page_data = array(
103
			'ID'             => $page_id,
104
			'post_status'    => 'publish',
105
		);
106
	 	wp_update_post( $page_data );
107
	} else {
108
		$page_data = array(
109
			'post_status'    => 'publish',
110
			'post_type'      => 'page',
111
			'post_author'    => 1,
112
			'post_name'      => $slug,
113
			'post_title'     => $page_title,
114
			'post_content'   => $page_content,
115
			'post_parent'    => $post_parent,
116
			'comment_status' => 'closed'
117
		);
118
		$page_id = wp_insert_post( $page_data );
119
	}
120
121
	if ( $option ) {
122
		update_option( $option, $page_id );
123
	}
124
125
	return $page_id;
126
}
127
128
/**
129
 * Output admin fields.
130
 *
131
 * Loops though the woocommerce options array and outputs each field.
132
 *
133
 * @param array $options Opens array to output
134
 */
135
function woocommerce_admin_fields( $options ) {
136
137
	if ( ! class_exists( 'WC_Admin_Settings' ) ) {
138
		include 'class-wc-admin-settings.php';
139
	}
140
141
	WC_Admin_Settings::output_fields( $options );
142
}
143
144
/**
145
 * Update all settings which are passed.
146
 *
147
 * @param array $options
148
 */
149
function woocommerce_update_options( $options ) {
150
151
	if ( ! class_exists( 'WC_Admin_Settings' ) ) {
152
		include 'class-wc-admin-settings.php';
153
	}
154
155
	WC_Admin_Settings::save_fields( $options );
156
}
157
158
/**
159
 * Get a setting from the settings API.
160
 *
161
 * @param mixed $option_name
162
 * @param mixed $default
163
 * @return string
164
 */
165
function woocommerce_settings_get_option( $option_name, $default = '' ) {
166
167
	if ( ! class_exists( 'WC_Admin_Settings' ) ) {
168
		include 'class-wc-admin-settings.php';
169
	}
170
171
	return WC_Admin_Settings::get_option( $option_name, $default );
172
}
173
174
/**
175
 * Save order items.
176
 *
177
 * @since 2.2
178
 * @param int $order_id Order ID
179
 * @param array $items Order items to save
180
 */
181
function wc_save_order_items( $order_id, $items ) {
182
	global $wpdb;
183
184
	// Order items + fees
185
	$subtotal     = 0;
186
	$total        = 0;
187
	$subtotal_tax = 0;
188
	$total_tax    = 0;
189
	$taxes        = array( 'items' => array(), 'shipping' => array() );
190
191
	if ( isset( $items['order_item_id'] ) ) {
192
		$line_total = $line_subtotal = $line_tax = $line_subtotal_tax = array();
193
194
		foreach ( $items['order_item_id'] as $item_id ) {
195
196
			$item_id = absint( $item_id );
197
198
			if ( isset( $items['order_item_name'][ $item_id ] ) ) {
199
				$wpdb->update(
200
					$wpdb->prefix . 'woocommerce_order_items',
201
					array( 'order_item_name' => wc_clean( wp_unslash( $items['order_item_name'][ $item_id ] ) ) ),
202
					array( 'order_item_id' => $item_id ),
203
					array( '%s' ),
204
					array( '%d' )
205
				);
206
			}
207
208
			if ( isset( $items['order_item_qty'][ $item_id ] ) ) {
209
				wc_update_order_item_meta( $item_id, '_qty', wc_stock_amount( $items['order_item_qty'][ $item_id ] ) );
210
			}
211
212
			if ( isset( $items['order_item_tax_class'][ $item_id ] ) ) {
213
				wc_update_order_item_meta( $item_id, '_tax_class', wc_clean( $items['order_item_tax_class'][ $item_id ] ) );
214
			}
215
216
			// Get values. Subtotals might not exist, in which case copy value from total field
217
			$line_total[ $item_id ]        = isset( $items['line_total'][ $item_id ] ) ? $items['line_total'][ $item_id ] : 0;
218
			$line_subtotal[ $item_id ]     = isset( $items['line_subtotal'][ $item_id ] ) ? $items['line_subtotal'][ $item_id ] : $line_total[ $item_id ];
219
			$line_tax[ $item_id ]          = isset( $items['line_tax'][ $item_id ] ) ? $items['line_tax'][ $item_id ] : array();
220
			$line_subtotal_tax[ $item_id ] = isset( $items['line_subtotal_tax'][ $item_id ] ) ? $items['line_subtotal_tax'][ $item_id ] : $line_tax[ $item_id ];
221
222
			// Format taxes
223
			$line_taxes          = array_map( 'wc_format_decimal', $line_tax[ $item_id ] );
224
			$line_subtotal_taxes = array_map( 'wc_format_decimal', $line_subtotal_tax[ $item_id ] );
225
226
			// Update values
227
			wc_update_order_item_meta( $item_id, '_line_subtotal', wc_format_decimal( $line_subtotal[ $item_id ] ) );
228
			wc_update_order_item_meta( $item_id, '_line_total', wc_format_decimal( $line_total[ $item_id ] ) );
229
			wc_update_order_item_meta( $item_id, '_line_subtotal_tax', array_sum( $line_subtotal_taxes ) );
230
			wc_update_order_item_meta( $item_id, '_line_tax', array_sum( $line_taxes ) );
231
232
			// Save line tax data - Since 2.2
233
			wc_update_order_item_meta( $item_id, '_line_tax_data', array( 'total' => $line_taxes, 'subtotal' => $line_subtotal_taxes ) );
234
			$taxes['items'][] = $line_taxes;
235
236
			// Total up
237
			$subtotal     += wc_format_decimal( $line_subtotal[ $item_id ] );
238
			$total        += wc_format_decimal( $line_total[ $item_id ] );
239
			$subtotal_tax += array_sum( $line_subtotal_taxes );
240
			$total_tax    += array_sum( $line_taxes );
241
242
			// Clear meta cache
243
			wp_cache_delete( $item_id, 'order_item_meta' );
244
		}
245
	}
246
247
	// Save meta
248
	$meta_keys   = isset( $items['meta_key'] ) ? $items['meta_key'] : array();
249
	$meta_values = isset( $items['meta_value'] ) ? $items['meta_value'] : array();
250
251
	foreach ( $meta_keys as $id => $meta_key ) {
252
		$meta_value = ( empty( $meta_values[ $id ] ) && ! is_numeric( $meta_values[ $id ] ) ) ? '' : $meta_values[ $id ];
253
254
		// Delele blank item meta entries
255
		if ( $meta_key === '' && $meta_value === '' ) {
256
			$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_id = %d", $id ) );
257
		} else {
258
259
			$wpdb->update(
260
				$wpdb->prefix . 'woocommerce_order_itemmeta',
261
				array(
262
					'meta_key'   => wp_unslash( $meta_key ),
263
					'meta_value' => wp_unslash( $meta_value )
264
				),
265
				array( 'meta_id' => $id ),
266
				array( '%s', '%s' ),
267
				array( '%d' )
268
			);
269
		}
270
	}
271
272
	// Shipping Rows
273
	$order_shipping = 0;
274
275
	if ( isset( $items['shipping_method_id'] ) ) {
276
277
		foreach ( $items['shipping_method_id'] as $item_id ) {
278
			$item_id      = absint( $item_id );
279
			$method_id    = isset( $items['shipping_method'][ $item_id ] ) ? wc_clean( $items['shipping_method'][ $item_id ] ) : '';
280
			$method_title = isset( $items['shipping_method_title'][ $item_id ] ) ? wc_clean( wp_unslash( $items['shipping_method_title'][ $item_id ] ) ) : '';
281
			$cost         = isset( $items['shipping_cost'][ $item_id ] ) ? wc_format_decimal( $items['shipping_cost'][ $item_id ] ) : '';
282
			$ship_taxes   = isset( $items['shipping_taxes'][ $item_id ] ) ? array_map( 'wc_format_decimal', $items['shipping_taxes'][ $item_id ] ) : array();
283
284
			$wpdb->update(
285
				$wpdb->prefix . 'woocommerce_order_items',
286
				array( 'order_item_name' => $method_title ),
287
				array( 'order_item_id' => $item_id ),
288
				array( '%s' ),
289
				array( '%d' )
290
			);
291
292
			wc_update_order_item_meta( $item_id, 'method_id', $method_id );
293
			wc_update_order_item_meta( $item_id, 'cost', $cost );
294
			wc_update_order_item_meta( $item_id, 'taxes', $ship_taxes );
295
296
			$taxes['shipping'][] = $ship_taxes;
297
298
			$order_shipping += $cost;
299
		}
300
	}
301
302
	// Taxes
303
	$order_taxes        = isset( $items['order_taxes'] ) ? $items['order_taxes'] : array();
304
	$taxes_items        = array();
305
	$taxes_shipping     = array();
306
	$total_tax          = 0;
307
	$total_shipping_tax = 0;
308
309
	// Sum items taxes
310
	foreach ( $taxes['items'] as $rates ) {
311
312
		foreach ( $rates as $id => $value ) {
313
314
			if ( isset( $taxes_items[ $id ] ) ) {
315
				$taxes_items[ $id ] += $value;
316
			} else {
317
				$taxes_items[ $id ] = $value;
318
			}
319
		}
320
	}
321
322
	// Sum shipping taxes
323
	foreach ( $taxes['shipping'] as $rates ) {
324
325
		foreach ( $rates as $id => $value ) {
326
327
			if ( isset( $taxes_shipping[ $id ] ) ) {
328
				$taxes_shipping[ $id ] += $value;
329
			} else {
330
				$taxes_shipping[ $id ] = $value;
331
			}
332
		}
333
	}
334
335
	// Update order taxes
336
	foreach ( $order_taxes as $item_id => $rate_id ) {
337
338
		if ( isset( $taxes_items[ $rate_id ] ) ) {
339
			$_total = wc_format_decimal( $taxes_items[ $rate_id ] );
340
			wc_update_order_item_meta( $item_id, 'tax_amount', $_total );
341
342
			$total_tax += $_total;
343
		}
344
345
		if ( isset( $taxes_shipping[ $rate_id ] ) ) {
346
			$_total = wc_format_decimal( $taxes_shipping[ $rate_id ] );
347
			wc_update_order_item_meta( $item_id, 'shipping_tax_amount', $_total );
348
349
			$total_shipping_tax += $_total;
350
		}
351
	}
352
353
	// Update order shipping total
354
	update_post_meta( $order_id, '_order_shipping', $order_shipping );
355
356
	// Update cart discount from item totals
357
	update_post_meta( $order_id, '_cart_discount', $subtotal - $total );
358
	update_post_meta( $order_id, '_cart_discount_tax', $subtotal_tax - $total_tax );
359
360
	// Update totals
361
	update_post_meta( $order_id, '_order_total', wc_format_decimal( $items['_order_total'] ) );
362
363
	// Update tax
364
	update_post_meta( $order_id, '_order_tax', wc_format_decimal( $total_tax ) );
365
	update_post_meta( $order_id, '_order_shipping_tax', wc_format_decimal( $total_shipping_tax ) );
366
367
	// Remove old values
368
	delete_post_meta( $order_id, '_shipping_method' );
369
	delete_post_meta( $order_id, '_shipping_method_title' );
370
371
	// Set the currency
372
	add_post_meta( $order_id, '_order_currency', get_woocommerce_currency(), true );
373
374
	// Update version after saving
375
	update_post_meta( $order_id, '_order_version', WC_VERSION );
376
377
	// inform other plugins that the items have been saved
378
	do_action( 'woocommerce_saved_order_items', $order_id, $items );
379
}
380