Issues (1182)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

includes/admin/wc-admin-functions.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
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
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