PK œqhYî¶J‚ßFßF)nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/ $#$#$#

Dir : /home/trave494/tiktechtok.org/wp-content/plugins/woocommerce-store-toolkit/includes/
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64
IP: 209.182.202.254
Choose File :

Url:
Dir : //home/trave494/tiktechtok.org/wp-content/plugins/woocommerce-store-toolkit/includes/functions.php

<?php
if( is_admin() ) {

	/* Start of: WordPress Administration */

	include_once( WOO_ST_PATH . 'includes/admin.php' );

	// WordPress Administration menu
	function woo_st_admin_menu() {

		add_submenu_page( 'woocommerce', __( 'Store Toolkit', 'woocommerce-store-toolkit' ), __( 'Store Toolkit', 'woocommerce-store-toolkit' ), 'manage_woocommerce', 'woo_st', 'woo_st_html_page' );

	}
	add_action( 'admin_menu', 'woo_st_admin_menu', 11 );

	function woo_st_template_header( $title = '', $icon = 'woocommerce' ) {

		if( $title )
			$output = $title;
		else
			$output = __( 'Store Toolkit', 'woocommerce-store-toolkit' ); ?>
<div class="wrap">
	<div id="icon-<?php echo esc_attr( $icon ); ?>" class="icon32 icon32-woocommerce-settings"><br /></div>
	<h2><?php echo esc_html( $output ); ?></h2>
<?php
	}

	function woo_st_template_footer() { ?>
</div>
<!-- .wrap -->
<?php
	}

	function woo_st_support_donate() {

		$show = true;
		if( function_exists( 'woo_vl_we_love_your_plugins' ) ) {
			if( in_array( WOO_ST_DIRNAME, woo_vl_we_love_your_plugins() ) )
				$show = false;
		}
		if( $show ) {
			$donate_url = 'https://visser.com.au/donate/';
			$rate_url = 'https://wordpress.org/support/view/plugin-reviews/woocommerce-store-toolkit/';
			echo '<div id="support-donate_rate" class="support-donate_rate">';
			echo '<p>';
			echo sprintf( __( '<strong>Like this Plugin?</strong> %s and %s', 'woocommerce-store-toolkit' ), '<a href="' . esc_url( $donate_url ) . '" target="_blank">' . __( 'Donate to support this Plugin', 'woocommerce-store-toolkit' ) . '</a>', '<a href="' . esc_url( add_query_arg( array( 'rate' => '5' ), $rate_url ) ) . '#postform" target="_blank">rate / review us on WordPress.org</a>' );
			echo '</p>';
			echo '</div>';
		}

	}

	function woo_st_relink_rogue_simple_type() {

		$updated_products = 0;
		$ignored_products = 0;

		// Get the Term ID for the Simple Product Type
		$term_taxonomy = 'product_type';
		$term_id = term_exists( 'simple', $term_taxonomy );

		// Check if the Simple Product Type exists
		if( $term_id == null || is_wp_error( $term_id ) ) {
			$message = __( 'The Term ID for the Simple Product Type could not be found within the WordPress Terms table (wp_terms), please de-activate and re-activate WooCommerce to resolve this.', 'woocommerce-store-toolkit' );
			woo_st_admin_notice( $message, 'error' );
			return;
		}
		$term_id = $term_id['term_id'];

		// Get a list of all Product Types
		$args = array(
			'fields' => 'ids',
			'hide_empty' => false
		);
		$terms = get_terms( $term_taxonomy, $args );

		// Filter a list of Products that do not have a Product Type
		$post_type = 'product';
		$args = array(
			'post_type' => $post_type,
			'fields' => 'ids',
			'tax_query' => array(
				array(
					'taxonomy' => $term_taxonomy,
					'field' => 'term_id',
					'terms' => $terms,
					'operator' => 'NOT IN'
				)
			),
			'posts_per_page' => -1,
			'post_status' => 'any'
		);
		$product_ids = new WP_Query( $args );
		if( $product_ids->posts ) {
			foreach( $product_ids->posts as $product_id ) {
				// First strip any corrupt Terms assigned to that Product
				wp_set_object_terms( $product_id, null, $term_taxonomy );
				// Assign the new Simple Term to that Product
				$response = wp_set_object_terms( $product_id, (int)$term_id, $term_taxonomy, true );
				if( $response == null || is_wp_error( $response ) ) {
					$ignored_products ++;
					continue;
				}
				$updated_products++;
			}

			if( !empty( $ignored_products ) ) {
				$message = sprintf( __( 'Some Products would not take the Simple Product Type or WordPress returned an error, we managed to update %d of %d', 'woocommerce-store-toolkit' ), $ignored_products, $updated_products );
				woo_st_admin_notice( $message, 'error' );
			} else if( !empty( $updated_products ) ) {
				$message = sprintf( __( 'We managed to update %d Products with the Simple Product Type, happy days!', 'woocommerce-store-toolkit' ), $updated_products );
				woo_st_admin_notice( $message );
			} else {
				$message = __( 'No existing Products had the Simple Product Type assigned to them', 'woocommerce-store-toolkit' );
				woo_st_admin_notice( $message, 'error' );
			}
		} else {
			$message = __( 'No existing Products had the Simple Product Type assigned to them', 'woocommerce-store-toolkit' );
			woo_st_admin_notice( $message, 'error' );
		}

	}

	function woo_st_delete_corrupt_variations() {

		$post_type = 'product_variation';
		$args = array(
			'post_type' => $post_type,
			'fields' => 'ids',
			'posts_per_page' => -1,
			'post_status' => 'any'
		);
		$product_ids = new WP_Query( $args );
		if( $product_ids->posts ) {
			foreach( $product_ids->posts as $post_id ) {

				// Check if the Post Title is empty
				$post_title = get_the_title( $post_id );
				if( !empty( $post_title ) )
					continue;

				// Check if the Stock Status meta contains an invalid array
				$stock_status = get_post_meta( $post_id, '_stock_status', false );
				if( count( $stock_status ) == 1 )
					continue;

				wp_delete_post( $post_id, true );

			}
		}

	}

	function woo_st_refresh_product_transients() {

		$post_type = 'product';
		$args = array(
			'post_type' => $post_type,
			'fields' => 'ids',
			'posts_per_page' => -1,
			'post_status' => 'any'
		);
		$product_ids = new WP_Query( $args );
		if( $product_ids->posts ) {
			foreach( $product_ids->posts as $product_id ) {
				wc_delete_product_transients( $product_id );
				delete_post_meta( $product_id, '_wc_average_rating' );
				delete_post_meta( $product_id, '_wc_rating_count' );
				delete_post_meta( $product_id, '_wc_review_count' );
			}
		}

	}

	function woo_st_remove_filename_extension( $filename ) {

		$extension = strrchr( $filename, '.' );
		$filename = substr( $filename, 0, -strlen( $extension ) );

		return $filename;

	}
	
	function woo_st_get_product_statuses() {

/*
		$product_statuses = get_post_statuses();
		// $product_statuses = get_post_stati();
		if( !empty( $product_statuses ) ) {
			foreach( $product_statuses as $key => $product_status ) {
				$product_statuses[$key]->count = 
			}
		}
*/
		$post_type = 'product';
		$product_statuses = wp_count_posts( $post_type );
		// Trim off WooCommerce Order Statuses
		if( !empty( $product_statuses ) ) {
			$product_statuses = (array)$product_statuses;
			foreach( $product_statuses as $product_status => $product_count ) {
				if(
					strstr( $product_status, 'wc-' ) !== false || 
					strstr( $product_status, 'request-' ) !== false
				) {
				}
			}
		}
		return $product_statuses;

	}

	function woo_st_get_order_statuses() {

		$terms = false;
		// Check if this is a WooCommerce 2.2+ instance.
		$woocommerce_version = woo_get_woo_version();
		if ( version_compare( $woocommerce_version, '2.2' ) >= 0 ) {
			// Convert Order Status array into our magic sauce.
			$order_statuses = ( function_exists( 'wc_get_order_statuses' ) ? wc_get_order_statuses() : false );
			if ( ! empty( $order_statuses ) ) {
				$terms        = array();
				foreach ( $order_statuses as $key => $order_status ) {
					$terms[] = (object) array(
						'term_id' => $key,
						'name' => $order_status,
						'slug' => $key,
						'count' => wc_orders_count( $key ),
					);
				}
			}
		} else {
			$term_taxonomy = 'shop_order_status';
			$args = array(
				'hide_empty' => 0
			);
			$terms = get_terms( $term_taxonomy, $args );
		}
		return $terms;

	}

	function woo_st_convert_sale_status( $sale_status = '' ) {

		$output = $sale_status;
		if( $sale_status ) {
			switch( $sale_status ) {

				case 'cancelled':
					$output = __( 'Cancelled', 'woocommerce-store-toolkit' );
					break;

				case 'completed':
					$output = __( 'Completed', 'woocommerce-store-toolkit' );
					break;

				case 'on-hold':
					$output = __( 'On-Hold', 'woocommerce-store-toolkit' );
					break;

				case 'pending':
					$output = __( 'Pending', 'woocommerce-store-toolkit' );
					break;

				case 'processing':
					$output = __( 'Processing', 'woocommerce-store-toolkit' );
					break;

				case 'refunded':
					$output = __( 'Refunded', 'woocommerce-store-toolkit' );
					break;

				case 'failed':
					$output = __( 'Failed', 'woocommerce-store-toolkit' );
					break;

			}
		}
		return $output;

	}

	function woo_st_generate_sample_products( $args = array() ) {

		$defaults = array(
			'limit' => 100,
			'product_name' => 'Sample Product %count%',
			'short_description' => 'Short description for Sample Product %count%',
			'description' => 'Description for Sample Product %count%',
			'sku' => 'SAMPLE-%count%'
		);
		$args = wp_parse_args( $args, $defaults );

		if( empty( $args['limit'] ) )
			return false;

		for( $i = 0; $i < $args['limit']; $i++ ) {

			// @mod - WC only lets us use create_product via the WC_API

			$avatar_args = array(
				'default' => 'retro',
				'size' => 512
			);

			$post_excerpt = '';
			$post_content = '';
			$data = array(
				'title' => str_replace( '%count%', $i, $args['product_name'] ),
				'status' => 'publish',
				'short_description' => str_replace( '%count%', $i, $args['short_description'] ),
				'description' => str_replace( '%count%', $i, $args['description'] ),
				'menu_order' => 0,
				'virtual' => false,
				'featured' => false,
				'sku' => str_replace( '%count%', $i, $args['sku'] ),
				'image' => array( get_avatar_url( sprintf( 'email-%d@example.com', $i ), $args ) )
			);

			$new_product = array(
				'post_title'   => wc_clean( $data['title'] ),
				'post_status'  => isset( $data['status'] ) ? wc_clean( $data['status'] ) : 'publish',
				'post_type'    => 'product',
				'post_excerpt' => isset( $data['short_description'] ) ? $post_excerpt : '',
				'post_content' => isset( $data['description'] ) ? $post_content : '',
				'post_author'  => get_current_user_id(),
				'menu_order'   => isset( $data['menu_order'] ) ? intval( $data['menu_order'] ) : 0
			);

			$post_ID = wp_insert_post( $new_product, true );

			if( is_wp_error( $post_ID ) ) {
				error_log( 'create_sample_product: ' . $post_ID->get_error_message() );
			}

			// Set the Product Type
			$product_type = null;
			$_product_type = get_the_terms( $post_ID, 'product_type' );
			if( is_array( $_product_type ) ) {
				$_product_type = current( $_product_type );
				$product_type  = $_product_type->slug;
			}

			// Virtual.
			if ( isset( $data['virtual'] ) ) {
				update_post_meta( $post_ID, '_virtual', ( true === $data['virtual'] ) ? 'yes' : 'no' );
			}

			// Featured Product.
			if ( isset( $data['featured'] ) ) {
				update_post_meta( $post_ID, '_featured', ( true === $data['featured'] ) ? 'yes' : 'no' );
			}

			// SKU.
			if ( isset( $data['sku'] ) ) {
				$unique_sku = wc_product_has_unique_sku( $post_ID, $data['sku'] );
				if( $unique_sku )
					update_post_meta( $post_ID, '_sku', $data['sku'] );
			}

			// Clear cache/transients.
			wc_delete_product_transients( $post_ID );

		}
		return true;

	}

	function woo_st_generate_sample_orders( $args = array() ) {

		$defaults = array(
			'limit' => 100
		);
		$args = wp_parse_args( $args, $defaults );

		if( empty( $args['limit'] ) )
			return false;

		for( $i = 0; $i < $args['limit']; $i++ ) {

			$order    = new WC_Order();
			$customer = woo_st_get_random_customer();
			if ( !$customer instanceof \WC_Customer ) {
				return false;
			}
			/*
			$products = self::get_random_products( 1, 10 );
			foreach( $products as $product ) {
				$quantity = rand(1, 10);
				$order->add_product( $product, $quantity );
			}
			*/
			$order->set_customer_id( $customer->get_id() );
			$order->set_created_via( 'store-toolkit' );
			$order->set_currency( get_woocommerce_currency() );
			$order->set_billing_address_1( $customer->get_billing_address_1() );
			$order->set_billing_address_2( $customer->get_billing_address_2() );
			$order->set_billing_city( $customer->get_billing_city() );
			$order->set_billing_postcode( $customer->get_billing_postcode() );
			$order->set_billing_state( $customer->get_billing_state() );
			$order->set_billing_country( $customer->get_billing_country() );
			$order->set_shipping_address_1( $customer->get_shipping_address_1() );
			$order->set_shipping_address_2( $customer->get_shipping_address_2() );
			$order->set_shipping_city( $customer->get_shipping_city() );
			$order->set_shipping_postcode( $customer->get_shipping_postcode() );
			$order->set_shipping_state( $customer->get_shipping_state() );
			$order->set_shipping_country( $customer->get_shipping_country() );
			$order->set_status( woo_st_get_random_order_status() );
			$order->calculate_totals( true );
			$order->save();

		}

		return true;

	}

	function woo_st_get_random_customer() {

		$user_id = false;

		$orderbys = array(
			'ID',
			'login',
			'nicename',
			'email',
			'url',
			'registered'
		);
		$orders = array(
			'ASC',
			'DESC'
		);

		$guest = (bool)rand( 0, 1 );
		$existing = (bool)rand( 0, 1 );
		$orderby = rand( 0, ( count( $orderbys ) - 1 ) );
		$order = rand( 0, 1 );
		$limit = rand( 1, 100 );

		if( $existing ) {
			$args = array(
				'orderby' => $orderbys[$orderby],
				'number' => $limit,
				'fields' => 'ID'
			);
			$users = get_users( $args );
			if( !empty( $users ) )
				$user_id = $users[array_rand( $users )];
			if( !empty( $user_id ) ) {
				$customer = new WC_Customer( $user_id );
				return $customer;
			}
		}

		$customer = new WC_Customer( get_current_user_id() );
		return $customer;

	}

	function woo_st_get_random_order_status() {

		$order_statuses = array(
			'completed',
			'processing',
			'on-hold',
			'failed'
		);
		return $order_statuses[array_rand( $order_statuses )];

	}

	function woo_st_return_percentage( $after = 0, $before = 0, $display_html = true ) {

		$output = 0;
		if(
			absint( $after ) <> 0 && 
			absint( $before ) <> 0
		) {
			$output = absint( ( ( absint( $after ) / absint( $before ) ) * 100 ) - 100 );
			if( $display_html && absint( $output ) > 0 )
				$output = '+' . $output;
		}
		return $output;

	}

	function woo_st_percentage_symbol_class( $after = 0, $before = 0 ) {

		$output = '';
		$percentage = woo_st_return_percentage( $after, $before, false );
		if( $percentage < 0 ) {
			$output = 'down';
		} else if( $percentage > 0 ) {
			$output = 'up';
		} else {
			$output = 'line';
		}
		return $output;

	}

	function woo_st_settings_save() {

		// Permanently Delete Products bulk action
		woo_st_update_option( 'permanently_delete_products', ( isset( $_POST['permanently_delete_products'] ) ? absint( (int)$_POST['permanently_delete_products'] ) : 1 ) );

		// CRON settings
		$enable_cron = absint( $_POST['enable_cron'] );
		// Display additional notice if Enabled CRON is enabled/disabled
		if( woo_st_get_option( 'enable_cron', 0 ) <> $enable_cron ) {
			$message = sprintf( __( 'CRON support has been %s.', 'woocommerce-store-toolkit' ), ( ( $enable_cron == 1 ) ? __( 'enabled', 'woocommerce-store-toolkit' ) : __( 'disabled', 'woocommerce-store-toolkit' ) ) );
			woo_st_admin_notice( $message );
		}
		woo_st_update_option( 'enable_cron', $enable_cron );
		woo_st_update_option( 'secret_key', sanitize_text_field( $_POST['secret_key'] ) );

		$message = __( 'Changes have been saved.', 'woocommerce-store-toolkit' );
		woo_st_admin_notice( $message );

	}

	/* End of: WordPress Administration */

} else {

	/* Start of: Storefront */

	function woo_st_autocomplete_order_status( $order_id = 0, $posted = false ) {

		if( !empty( $order_id ) ) {
			if( class_exists( 'WC_Order' ) ) {
				$order = new WC_Order( $order_id );
				if( $order->get_total() == 0 )
					$order->update_status( 'completed', __( 'Auto-complete Order Status', 'woocommerce-store-toolkit' ) );
			}
		}
		return false;

	}

	/* End of: Storefront */

}

// So we can view the Edit Product screen for individual Variations
function woo_st_admin_unlock_variations_screen( $args ) {

	$args['show_ui'] = true;
	return $args;

}

// Returns date of first Order received, any status
function woo_st_get_order_first_date( $date_format = 'd/m/Y' ) {

	$output = date( $date_format, mktime( 0, 0, 0, date( 'n' ), 1 ) );

	$post_type = 'shop_order';
	$args = array(
		'post_type' => $post_type,
		'orderby' => 'post_date',
		'order' => 'ASC',
		'numberposts' => 1,
		'post_status' => 'any'
	);
	$orders = get_posts( $args );
	if( !empty( $orders ) ) {
		$output = date( $date_format, strtotime( $orders[0]->post_date ) );
	}
	return $output;

}

function woo_st_get_order_date_filter( $filter = '', $format = '' ) {

	$date_format = 'd-m-Y';
	$output = false;
	if( !empty( $filter ) && !empty( $format ) ) {
		switch( $filter ) {

			// Today
			case 'today':
				if( $format == 'from' )
					$output = date( $date_format, strtotime( 'today' ) );
				else
					$output = date( $date_format, strtotime( 'tomorrow' ) );
				break;

			// This month
			case 'current_month':
				if( $format == 'from' )
					$output = date( $date_format, mktime( 0, 0, 0, date( 'n' ), 1 ) );
				else
					$output = date( $date_format, mktime( 0, 0, 0, ( date( 'n' ) + 1 ), 0 ) );
				break;

		}
	}
	return $output;

}

function woo_st_clear_dataset( $export_type = '', $data = false ) {

	global $wpdb;

	if( empty( $export_type ) )
		return false;

	// Commence the drop
	woo_st_update_option( 'in_progress', $export_type );
	switch( $export_type ) {

		// WooCommerce

		case 'product':
			$post_type = array( 'product', 'product_variation' );
			$args = array(
				'post_type' => $post_type,
				'fields' => 'ids',
				'post_status' => woo_st_post_statuses(),
				'numberposts' => 100
			);

			// Check for Product Status filter
			if( !empty( $data['product_status'] ) ) {
				$args['post_status'] = $data['product_status'];
			}

			// Allow Plugin/Theme authors to add support for tactical nukes
			$args = apply_filters( 'woo_st_clear_dataset_product', $args );

			// Loop through every 100 records until 0 is returned, might take awhile
			while( $count = woo_st_return_count( 'product' ) ) {
				$products = get_posts( $args );
				if( !empty( $products ) ) {
					foreach( $products as $product ) {
						if( !WOO_ST_DEBUG ) {
							wp_delete_post( $product, true );
							// Product Category
							if( taxonomy_exists( 'product_cat' ) )
								wp_set_object_terms( $product, null, 'product_cat' );
							// Product Tag
							if( taxonomy_exists( 'product_tag' ) )
								wp_set_object_terms( $product, null, 'product_tag' );
							// Product Brand
							$term_taxonomy = apply_filters( 'woo_st_brand_term_taxonomy', 'product_brand' );
							if( taxonomy_exists( $term_taxonomy ) )
								wp_set_object_terms( $product, null, $term_taxonomy );
							// Product Vendor
							if( taxonomy_exists( 'shop_vendor' ) )
								wp_set_object_terms( $product, null, 'shop_vendor' );
							// Attributes
							$attributes_sql = "SELECT `attribute_id` as ID, `attribute_name` as name, `attribute_label` as label, `attribute_type` as type FROM `" . $wpdb->prefix . "woocommerce_attribute_taxonomies`";
							$attributes = $wpdb->get_results( $attributes_sql );
							if( !empty( $attributes ) ) {
								foreach( $attributes as $attribute ) {
									if( taxonomy_exists( 'pa_' . $attribute->name ) )
										wp_set_object_terms( $product, null, 'pa_' . $attribute->name );
								}
							}
							if( function_exists( 'wc_delete_product_transients' ) )
								wc_delete_product_transients( $product );
							if( class_exists( 'WC_Comments' ) ) {
								$comments = new WC_Comments;
								if( method_exists( $comments, 'clear_transients' ) ) {
									$comments->clear_transients( $product );
								}
							}
						} else {
							error_log( sprintf( '[store-toolkit] Delete Product #%d', $product ) );
						}
					}
				}

				// I don't get any pleasure out of doing this bit...
				$post_type = 'product';
				wp_cache_delete( $post_type );
				$post_type = 'product_variation';
				wp_cache_delete( $post_type );

				// Check if count hasn't budged and we're in a permanent loop
				if( $count == woo_st_return_count( 'product' ) ) {
					error_log( '[store-toolkit] Detected permanent loop nuking Products, bugging out...' );
					$output = false;
					break;
				}
			}
			if( !WOO_ST_DEBUG ) {
				delete_transient( 'wc_featured_products' );

				// Allow Plugin/Theme authors to perform their own tactical nukes when clearing this dataset
				do_action( 'woo_st_clear_dataset_product' );

			}
			if( !isset( $output ) )
				$output = true;
			break;

		case 'product_category':
			$term_taxonomy = 'product_cat';
			// Let's check if we're doing a filtered nuke...
			if( !empty( $data ) ) {
				foreach( $data as $single_category ) {
					$post_type = 'product';
					$args = array(
						'post_type' => $post_type,
						'fields' => 'ids',
						'tax_query' => array(
							array(
								'taxonomy' => $term_taxonomy,
								'field' => 'id',
								'terms' => $single_category
							)
						),
						'numberposts' => -1
					);

					// Allow Plugin/Theme authors to add support for tactical nukes
					$args = apply_filters( 'woo_st_clear_dataset_product_per_category', $args );

					$products = get_posts( $args );
					if( $products ) {
						foreach( $products as $product ) {
							if( !WOO_ST_DEBUG ) {
								wp_delete_post( $product, true );
							} else {
								error_log( sprintf( '[store-toolkit] Delete Product #%d by Product Category', $product ) );
							}
						}
					}
				}
			} else {
				$args = array(
					'hide_empty' => false,
					'number' => 100
				);

				// Allow Plugin/Theme authors to add support for tactical nukes
				$args = apply_filters( 'woo_st_clear_dataset_product_category', $args );

				// Loop through every 100 records until 0 is returned, might take awhile
				while( $count = woo_st_return_count( 'product_category' ) ) {
					$categories = get_terms( $term_taxonomy, $args );
					if( !empty( $categories ) ) {
						foreach( $categories as $category ) {
							if( !WOO_ST_DEBUG ) {
								wp_delete_term( $category->term_id, $term_taxonomy );
								$wpdb->query( $wpdb->prepare( "DELETE FROM `" . $wpdb->terms . "` WHERE `term_id` = %d", $category->term_id ) );
								$wpdb->query( $wpdb->prepare( "DELETE FROM `" . $wpdb->term_relationships . "` WHERE `term_taxonomy_id` = %d", $category->term_taxonomy_id ) );
								// Check if WooCommerce woocommerce_termmeta exists
								if( $wpdb->get_var( "SHOW TABLES LIKE '" . $wpdb->prefix . "woocommerce_termmeta'" ) )
									$wpdb->query( $wpdb->prepare( "DELETE FROM `" . $wpdb->prefix . "woocommerce_termmeta` WHERE `woocommerce_term_id` = %d", $category->term_id ) );
								delete_term_meta( $category->term_id, 'thumbnail_id' );
							} else {
								error_log( sprintf( '[store-toolkit] Delete Product Category #%d', $category->term_id ) );
							}
						}
					}

					// I don't get any pleasure out of doing this bit...
					wp_cache_delete( $term_taxonomy );

					// Check if count hasn't budged and we're in a permanent loop
					if( $count == woo_st_return_count( 'product_category' ) ) {
						error_log( '[store-toolkit] Detected permanent loop nuking Product Categories, bugging out...' );
						$output = false;
						break;
					}
				}
				if( !WOO_ST_DEBUG )
					$wpdb->query( $wpdb->prepare( "DELETE FROM `" . $wpdb->term_taxonomy . "` WHERE `taxonomy` = %s", $term_taxonomy ) );
			}
			if( !WOO_ST_DEBUG ) {
				// Allow Plugin/Theme authors to perform their own tactical nukes when clearing this dataset
				do_action( 'woo_st_clear_dataset_product_category' );
			}
			if( !isset( $output ) )
				$output = true;
			break;

		case 'product_tag':
			$term_taxonomy = 'product_tag';
			$args = array(
				'fields' => 'ids',
				'hide_empty' => false,
				'number' => 100
			);

			// Allow Plugin/Theme authors to add support for tactical nukes
			$args = apply_filters( 'woo_st_clear_dataset_product_tag', $args );

			// Loop through every 100 records until 0 is returned, might take awhile
			while( $count = woo_st_return_count( 'product_tag' ) ) {
				$tags = get_terms( $term_taxonomy, $args );
				if( !empty( $tags ) ) {
					foreach( $tags as $tag ) {
						if( !WOO_ST_DEBUG ) {
							wp_delete_term( $tag, $term_taxonomy );
							$wpdb->query( $wpdb->prepare( "DELETE FROM `" . $wpdb->terms . "` WHERE `term_id` = %d", $tag ) );
						} else {
							error_log( sprintf( '[store-toolkit] Delete Product Tag #%d', $tag ) );
						}
					}
				}

				// I don't get any pleasure out of doing this bit...
				wp_cache_delete( $term_taxonomy );

				// Check if count hasn't budged and we're in a permanent loop
				if( $count == woo_st_return_count( 'product_tag' ) ) {
					error_log( '[store-toolkit] Detected permanent loop nuking Product Tags, bugging out...' );
					$output = false;
					break;
				}
			}
			if( !WOO_ST_DEBUG ) {
				// Allow Plugin/Theme authors to perform their own tactical nukes when clearing this dataset
				do_action( 'woo_st_clear_dataset_product_tag' );
			}
			if( !isset( $output ) )
				$output = true;
			break;

		case 'product_brand':
			$term_taxonomy = apply_filters( 'woo_st_brand_term_taxonomy', 'product_brand' );
			$args = array(
				'fields' => 'ids',
				'hide_empty' => false,
				'number' => 100
			);

			// Allow Plugin/Theme authors to add support for tactical nukes
			$args = apply_filters( 'woo_st_clear_dataset_product_brand', $args );

			// Loop through every 100 records until 0 is returned, might take awhile
			while( $count = woo_st_return_count( 'product_brand' ) ) {
				$tags = get_terms( $term_taxonomy, $args );
				if( $tags ) {
					foreach( $tags as $tag ) {
						if( !WOO_ST_DEBUG ) {
							wp_delete_term( $tag, $term_taxonomy );
							$wpdb->query( $wpdb->prepare( "DELETE FROM `" . $wpdb->terms . "` WHERE `term_id` = %d", $tag ) );
						} else {
							error_log( sprintf( '[store-toolkit] Delete Product Brand #%d', $tag ) );
						}
					}
				}

				// I don't get any pleasure out of doing this bit...
				wp_cache_delete( $term_taxonomy );

				// Check if count hasn't budged and we're in a permanent loop
				if( $count == woo_st_return_count( 'product_brand' ) ) {
					error_log( '[store-toolkit] Detected permanent loop nuking Product Brands, bugging out...' );
					$output = false;
					break;
				}
			}
			if( !WOO_ST_DEBUG ) {
				// Allow Plugin/Theme authors to perform their own tactical nukes when clearing this dataset
				do_action( 'woo_st_clear_dataset_product_brand' );
			}
			if( !isset( $output ) )
				$output = true;
			break;

		case 'product_vendor':
			$term_taxonomy = 'shop_vendor';
			$args = array(
				'fields' => 'ids',
				'hide_empty' => false
			);

			// Allow Plugin/Theme authors to add support for tactical nukes
			$args = apply_filters( 'woo_st_clear_dataset_product_vendor', $args );

			// Loop through every 100 records until 0 is returned, might take awhile
			while( $count = woo_st_return_count( 'product_vendor' ) ) {
				$tags = get_terms( $term_taxonomy, $args );
				if( $tags ) {
					foreach( $tags as $tag ) {
						if( !WOO_ST_DEBUG ) {
							wp_delete_term( $tag, $term_taxonomy );
							$wpdb->query( $wpdb->prepare( "DELETE FROM `" . $wpdb->terms . "` WHERE `term_id` = %d", $tag ) );
						} else {
							error_log( sprintf( '[store-toolkit] Delete Product Vendor #%d', $tag ) );
						}
					}
				}

				// I don't get any pleasure out of doing this bit...
				wp_cache_delete( $term_taxonomy );

				// Check if count hasn't budged and we're in a permanent loop
				if( $count == woo_st_return_count( 'product_vendor' ) ) {
					error_log( '[store-toolkit] Detected permanent loop nuking Product Vendors, bugging out...' );
					$output = false;
					break;
				}
			}
			if( !WOO_ST_DEBUG ) {
				// Allow Plugin/Theme authors to perform their own tactical nukes when clearing this dataset
				do_action( 'woo_st_clear_dataset_product_vendor' );
			}
			if( !isset( $output ) )
				$output = true;
			break;

		case 'product_image':
			$post_type = array( 'product', 'product_variation' );
			$args = array(
				'post_type' => $post_type,
				'fields' => 'ids',
				'post_status' => 'any',
				'numberposts' => 100
			);

			// Allow Plugin/Theme authors to add support for tactical nukes
			$args = apply_filters( 'woo_st_clear_dataset_product_image', $args );

			// Loop through every 100 records until 0 is returned, might take awhile
			while( $count = woo_st_return_count( 'product_image' ) ) {
				$products = get_posts( $args );
				// Check each Product for images
				if( !empty( $products ) ) {
					$upload_dir = wp_upload_dir();
					foreach( $products as $product ) {
						$args = array(
							'post_type' => 'attachment',
							'post_parent' => $product,
							'post_status' => 'inherit',
							'post_mime_type' => 'image',
							'numberposts' => -1
						);
						$images = get_children( $args );
						if( !empty( $images ) ) {
							foreach( $images as $image ) {
								if( !WOO_ST_DEBUG ) {
									wp_delete_attachment( $image->ID, true );
								} else {
									error_log( sprintf( '[store-toolkit] Delete Product Image #%d', $image->ID ) );
								}
							}
						}
					}
				} else {
					// Check for WooCommerce-related images
					$images_sql = "SELECT `post_id` AS `ID` FROM `" . $wpdb->postmeta . "` WHERE `meta_key` = '_woocommerce_exclude_image' AND `meta_value` = 0";
					$images = $wpdb->get_col( $images_sql );
					if( !empty( $images ) ) {
						foreach( $images as $image ) {
							if( !WOO_ST_DEBUG ) {
								wp_delete_attachment( $image, true );
							} else {
								error_log( sprintf( '[store-toolkit] Delete Product Image #%d', $image ) );
							}
						}
					}
				}

				// I don't get any pleasure out of doing this bit...
				$post_type = 'product';
				wp_cache_delete( $post_type );
				$post_type = 'product_variation';
				wp_cache_delete( $post_type );

				// Check if count hasn't budged and we're in a permanent loop
				if( $count == woo_st_return_count( 'product_image' ) ) {
					error_log( '[store-toolkit] Detected permanent loop nuking Product Images, bugging out...' );
					$output = false;
					break;
				}
			}
			if( !WOO_ST_DEBUG ) {
				// Allow Plugin/Theme authors to perform their own tactical nukes when clearing this dataset
				do_action( 'woo_st_clear_dataset_product_image' );
			}
			if( !isset( $output ) )
				$output = true;
			break;

		case 'order':
			$post_type = 'shop_order';
			$term_taxonomy = 'shop_order_status';
			$woocommerce_version = woo_get_woo_version();

			// Let's check if we're doing a filtered nuke...
			$order_status = false;
			$order_date = false;
			$order_date_from = false;
			$order_date_to = false;
			if( !empty( $data ) ) {
				$order_status = ( isset( $data['status'] ) ? $data['status'] : false );
				$order_date = ( isset( $data['date'] ) ? $data['date'] : false );
			}
			
			if( !empty( $order_status ) ) {
				foreach( $order_status as $single_order => $value ) {
					$args = array(
						'limit' 	=> -1,
						'status' => $single_order,
					);

					// Allow Plugin/Theme authors to add support for tactical nukes
					$args = apply_filters( 'woo_st_clear_dataset_order_per_status', $args );

					$orders_query = new WC_Order_Query( $args );
					$orders 	  = $orders_query->get_orders();

					if ( ! empty( $orders ) ) {
						foreach ( $orders as $order ) {
							$order->delete( true );
						}
					}
				}
			} else {
				$args = array(
					'limit' => -1,
				);

				// Date
				if( !empty( $order_date ) ) {
					switch( $order_date ) {

						// Today
						case 'today':
							$order_date_from = woo_st_get_order_date_filter( 'today', 'from' );
							$order_date_to = woo_st_get_order_date_filter( 'today', 'to' );
							break;

						// Today
						case 'current_month':
							$order_date_from = woo_st_get_order_date_filter( 'current_month', 'from' );
							$order_date_to = woo_st_get_order_date_filter( 'current_month', 'to' );
							break;

						// Fixed date
						case 'manual':
							$order_date_from = ( isset( $data['date_from'] ) ? $data['date_from'] : false );
							$order_date_to = ( isset( $data['date_to'] ) ? $data['date_to'] : false );
							break;

					}
					$order_date_from = str_replace( '/', '-', $order_date_from );
					$order_date_to = str_replace( '/', '-', $order_date_to );

					$order_date_from = date( 'd-m-Y', strtotime( $order_date_from, current_time( 'timestamp', 0 ) ) );
					$order_date_to = date( 'd-m-Y', strtotime( $order_date_to, current_time( 'timestamp', 0 ) ) );

					$order_date_from = explode( '-', $order_date_from );
					$order_date_to = explode( '-', $order_date_to );

					$order_date_from = array(
						'year' => absint( $order_date_from[2] ),
						'month' => absint( $order_date_from[1] ),
						'day' => absint( $order_date_from[0] ),
						'hour' => 0,
						'minute' => 0,
						'second' => 0
					);

					$order_date_to = array(
						'year' => absint( $order_date_to[2] ),
						'month' => absint( $order_date_to[1] ),
						'day' => absint( $order_date_to[0] ),
						'hour' => 23,
						'minute' => 23,
						'second' => 59
					);

					$args['date_query'] = array(
						'column' => 'date_created_gmt',
						'before' => $order_date_to,
						'after' => $order_date_from,
						'inclusive' => true
					);
				}

				// Allow Plugin/Theme authors to add support for tactical nukes.
				$args = apply_filters( 'woo_st_clear_dataset_order', $args );

				$orders_query = new WC_Order_Query( $args );
				$orders 	  = $orders_query->get_orders();

				if ( ! empty( $orders ) ) {
					foreach ( $orders as $order ) {
						$order->delete( true );
					}
				}
				
			}
			if( !WOO_ST_DEBUG ) {
				// Allow Plugin/Theme authors to perform their own tactical nukes when clearing this dataset
				do_action( 'woo_st_clear_dataset_order' );
			}
			if( !isset( $output ) )
				$output = true;
			break;

		case 'tax_rate':
			if( !WOO_ST_DEBUG ) {
				$wpdb->query( "TRUNCATE TABLE `" . $wpdb->prefix . "woocommerce_tax_rates`" );
				$wpdb->query( "TRUNCATE TABLE `" . $wpdb->prefix . "woocommerce_tax_rate_locations`" );
			}
			if( !WOO_ST_DEBUG ) {
				// Allow Plugin/Theme authors to perform their own tactical nukes when clearing this dataset
				do_action( 'woo_st_clear_dataset_tax_rate' );
			}
			$output = true;
			break;

		case 'download_permission':
			if( !WOO_ST_DEBUG ) {
				$wpdb->query( "TRUNCATE TABLE `" . $wpdb->prefix . "woocommerce_downloadable_product_permissions`" );

				// Allow Plugin/Theme authors to perform their own tactical nukes when clearing this dataset
				do_action( 'woo_st_clear_dataset_download_permission' );
			}
			$output = true;
			break;

		case 'coupon':
			$post_type = 'shop_coupon';
			$args = array(
				'post_type' => $post_type,
				'fields' => 'ids',
				'post_status' => woo_st_post_statuses(),
				'numberposts' => 100
			);

			// Allow Plugin/Theme authors to add support for tactical nukes
			$args = apply_filters( 'woo_st_clear_dataset_coupon', $args );

			// Loop through every 100 records until 0 is returned, might take awhile
			while( $count = woo_st_return_count( 'coupon' ) ) {
				$coupons = get_posts( $args );
				if( !empty( $coupons ) ) {
					foreach( $coupons as $coupon ) {
						if( !WOO_ST_DEBUG ) {
							wp_delete_post( $coupon, true );
						} else {
							error_log( sprintf( '[store-toolkit] Delete Coupon #%d', $coupon ) );
						}
					}
				}

				// I don't get any pleasure out of doing this bit...
				wp_cache_delete( $post_type );

				// Check if count hasn't budged and we're in a permanent loop
				if( $count == woo_st_return_count( 'coupon' ) ) {
					error_log( '[store-toolkit] Detected permanent loop nuking Coupons, bugging out...' );
					$output = false;
					break;
				}
			}
			if( !WOO_ST_DEBUG ) {
				// Allow Plugin/Theme authors to perform their own tactical nukes when clearing this dataset
				do_action( 'woo_st_clear_dataset_coupon' );
			}
			if( !isset( $output ) )
				$output = true;
			break;

		case 'shipping_class':
			$term_taxonomy = 'product_shipping_class';
			$args = array(
				'fields' => 'ids',
				'hide_empty' => false,
				'number' => 100
			);

			// Allow Plugin/Theme authors to add support for tactical nukes
			$args = apply_filters( 'woo_st_clear_dataset_shipping_class', $args );

			// Loop through every 100 records until 0 is returned, might take awhile
			while( $count = woo_st_return_count( 'shipping_class' ) ) {
				$shipping_classes = get_terms( $term_taxonomy, $args );
				if( !empty( $shipping_classes ) ) {
					foreach( $shipping_classes as $shipping_class ) {
						if( !WOO_ST_DEBUG ) {
							wp_delete_term( $shipping_class, $term_taxonomy );
							$wpdb->query( $wpdb->prepare( "DELETE FROM `" . $wpdb->terms . "` WHERE `term_id` = %d", $shipping_class ) );
						} else {
							error_log( sprintf( '[store-toolkit] Delete Shipping Class #%d', $shipping_class ) );
						}
					}
				}

				// I don't get any pleasure out of doing this bit...
				wp_cache_delete( $post_type );

				// Check if count hasn't budged and we're in a permanent loop
				if( $count == woo_st_return_count( 'shipping_class' ) ) {
					error_log( '[store-toolkit] Detected permanent loop nuking Shipping Classes, bugging out...' );
					$output = false;
					break;
				}
			}
			if( !WOO_ST_DEBUG ) {
				// Allow Plugin/Theme authors to perform their own tactical nukes when clearing this dataset
				do_action( 'woo_st_clear_dataset_shipping_class' );
			}
			if( !isset( $output ) )
				$output = true;
			break;

		case 'woocommerce_log':
			if( class_exists( 'WC_REST_System_Status_Controller' ) ) {
				$system_status = new WC_REST_System_Status_Controller;
				if( method_exists( $system_status, 'get_environment_info' ) ) {
					$environment = $system_status->get_environment_info();
					$log_directory = $environment['log_directory'];
					if( !empty( $log_directory ) ) {
						if( file_exists( $log_directory ) ) {
							$files = glob( $log_directory . '*.log' );
							if( $files !== false ) {
								foreach( $files as $file ) {
									if( !WOO_ST_DEBUG ) {
										unlink( $file );
									} else {
										error_log( sprintf( '[store-toolkit] Delete WooCommerce Log #%d', $file ) );
									}
								}
							}
						}
					}
				}
			}
			if( !WOO_ST_DEBUG ) {
				// Allow Plugin/Theme authors to perform their own tactical nukes when clearing this dataset
				do_action( 'woo_st_clear_dataset_woocommerce_log' );
			}
			break;

		case 'attribute':
			if( isset( $_POST['woo_st_attributes'] ) ) {
				$attributes_sql = "SELECT `attribute_id` as ID, `attribute_name` as name, `attribute_label` as label, `attribute_type` as type FROM `" . $wpdb->prefix . "woocommerce_attribute_taxonomies`";
				$attributes = $wpdb->get_results( $attributes_sql );
				if( $attributes ) {
					foreach( $attributes as $attribute ) {
						$terms_sql = $wpdb->prepare( "SELECT `term_id` FROM `" . $wpdb->prefix . "term_taxonomy` WHERE `taxonomy` = %s", 'pa_' . $attribute->name );
						$terms = $wpdb->get_results( $terms_sql );
						if( !empty( $terms ) ) {
							foreach( $terms as $term ) {
								if( !WOO_ST_DEBUG )
									wp_delete_term( $term->term_id, 'pa_' . $attribute->name );
								else
									error_log( sprintf( '[store-toolkit] Delete Attribute #%d', $term->term_id ) );
							}
						}
						if( !WOO_ST_DEBUG ) {
							$wpdb->query( $wpdb->prepare( "DELETE FROM `" . $wpdb->term_relationships . "` WHERE `term_taxonomy_id` = %d", $attribute->ID ) );
							// Check if WooCommerce woocommerce_termmeta exists
							if( $wpdb->get_var( "SHOW TABLES LIKE '" . $wpdb->prefix . "woocommerce_termmeta'" ) )
								$wpdb->query( $wpdb->prepare( "DELETE FROM `" . $wpdb->prefix . "woocommerce_termmeta` WHERE `meta_key` = %s", 'order_pa_' . $attribute->name ) );
						}
					}
				}
				if( !WOO_ST_DEBUG ) {
					$wpdb->query( "DELETE FROM `" . $wpdb->prefix . "woocommerce_attribute_taxonomies`" );
					delete_transient( 'wc_attribute_taxonomies' );

					// Allow Plugin/Theme authors to perform their own tactical nukes when clearing this dataset
					do_action( 'woo_st_clear_dataset_attribute' );

				}
			}
			$output = true;
			break;

		// 3rd Party

		case 'credit_card':
			$post_type = 'offline_payment';
			$args = array( 
				'post_type' => $post_type,
				'fields' => 'ids',
				'post_status' => woo_st_post_statuses(),
				'numberposts' => 100
			);

			// Allow Plugin/Theme authors to add support for tactical nukes
			$args = apply_filters( 'woo_st_clear_dataset_credit_card', $args );

			// Loop through every 100 records until 0 is returned, might take awhile
			while( $count = woo_st_return_count( 'credit_card' ) ) {
				$credit_cards = get_posts( $args );
				if( !empty( $credit_cards ) ) {
					foreach( $credit_cards as $credit_card ) {
						if( !WOO_ST_DEBUG ) {
							wp_delete_post( $credit_card, true );
						} else {
							error_log( sprintf( '[store-toolkit] Delete Credit Card #%d', $credit_card ) );
						}
					}
				}

				// I don't get any pleasure out of doing this bit...
				wp_cache_delete( $post_type );

				// Check if count hasn't budged and we're in a permanent loop
				if( $count == woo_st_return_count( 'credit_card' ) ) {
					error_log( '[store-toolkit] Detected permanent loop nuking Credit Cards, bugging out...' );
					$output = false;
					break;
				}
			}
			if( !isset( $output ) )
				$output = true;
			break;

		case 'store_export_csv':
			$post_type = 'attachment';
			$post_mime_types = array( 'text/csv' );
			$args = array(
				'post_type' => $post_type,
				'fields' => 'ids',
				'post_mime_type' => $post_mime_types,
				'post_status' => woo_st_post_statuses(),
				'numberposts' => 100,
			);

			// Allow Plugin/Theme authors to add support for tactical nukes
			$args = apply_filters( 'woo_st_clear_dataset_store_export_csv', $args );

			// Loop through every 100 records until 0 is returned, might take awhile
			while( $count = woo_st_return_count( 'store_export_csv' ) ) {
				$images = get_posts( $args );
				if( !empty( $images ) ) {
					foreach( $images as $image ) {
						if( !WOO_ST_DEBUG ) {
							wp_delete_attachment( $image, true );
						} else {
							error_log( sprintf( '[store-toolkit] Delete Store Export (CSV) #%d', $image ) );
						}
					}
				}

				// I don't get any pleasure out of doing this bit...
				wp_cache_delete( $post_type );

				// Check if count hasn't budged and we're in a permanent loop
				if( $count == woo_st_return_count( 'store_export_csv' ) ) {
					error_log( '[store-toolkit] Detected permanent loop nuking Store Export (CSV), bugging out...' );
					$output = false;
					break;
				}
			}
			if( !isset( $output ) )
				$output = true;
			break;

		case 'store_export_tsv':
			$post_type = 'attachment';
			$post_mime_types = array( 'text/tab-separated-values' );
			$args = array(
				'post_type' => $post_type,
				'fields' => 'ids',
				'post_mime_type' => $post_mime_types,
				'post_status' => woo_st_post_statuses(),
				'numberposts' => 100,
			);

			// Allow Plugin/Theme authors to add support for tactical nukes
			$args = apply_filters( 'woo_st_clear_dataset_store_export_tsv', $args );

			// Loop through every 100 records until 0 is returned, might take awhile
			while( $count = woo_st_return_count( 'store_export_tsv' ) ) {
				$images = get_posts( $args );
				if( !empty( $images ) ) {
					foreach( $images as $image ) {
						if( !WOO_ST_DEBUG ) {
							wp_delete_attachment( $image, true );
						} else {
							error_log( sprintf( '[store-toolkit] Delete Store Export (TSV) #%d', $image ) );
						}
					}
				}

				// I don't get any pleasure out of doing this bit...
				wp_cache_delete( $post_type );

				// Check if count hasn't budged and we're in a permanent loop
				if( $count == woo_st_return_count( 'store_export_tsv' ) ) {
					error_log( '[store-toolkit] Detected permanent loop nuking Store Export (TSV), bugging out...' );
					$output = false;
					break;
				}
			}
			if( !isset( $output ) )
				$output = true;
			break;

		case 'store_export_xls':
			$post_type = 'attachment';
			$post_mime_types = array( 'application/vnd.ms-excel' );
			$args = array(
				'post_type' => $post_type,
				'fields' => 'ids',
				'post_mime_type' => $post_mime_types,
				'post_status' => woo_st_post_statuses(),
				'numberposts' => 100,
			);

			// Allow Plugin/Theme authors to add support for tactical nukes
			$args = apply_filters( 'woo_st_clear_dataset_store_export_xls', $args );

			// Loop through every 100 records until 0 is returned, might take awhile
			while( $count = woo_st_return_count( 'store_export_xls' ) ) {
				$images = get_posts( $args );
				if( !empty( $images ) ) {
					foreach( $images as $image ) {
						if( !WOO_ST_DEBUG ) {
							wp_delete_attachment( $image, true );
						} else {
							error_log( sprintf( '[store-toolkit] Delete Store Export (XLS) #%d', $image ) );
						}
					}
				}

				// I don't get any pleasure out of doing this bit...
				wp_cache_delete( $post_type );

				// Check if count hasn't budged and we're in a permanent loop
				if( $count == woo_st_return_count( 'store_export_xls' ) ) {
					error_log( '[store-toolkit] Detected permanent loop nuking Store Export (XLS), bugging out...' );
					$output = false;
					break;
				}
			}
			if( !isset( $output ) )
				$output = true;
			break;

		case 'store_export_xlsx':
			$post_type = 'attachment';
			$post_mime_types = array( 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' );
			$args = array(
				'post_type' => $post_type,
				'fields' => 'ids',
				'post_mime_type' => $post_mime_types,
				'post_status' => woo_st_post_statuses(),
				'numberposts' => 100,
			);

			// Allow Plugin/Theme authors to add support for tactical nukes
			$args = apply_filters( 'woo_st_clear_dataset_store_export_xlsx', $args );

			// Loop through every 100 records until 0 is returned, might take awhile
			while( $count = woo_st_return_count( 'store_export_xlsx' ) ) {
				$images = get_posts( $args );
				if( !empty( $images ) ) {
					foreach( $images as $image ) {
						if( !WOO_ST_DEBUG ) {
							wp_delete_attachment( $image, true );
						} else {
							error_log( sprintf( '[store-toolkit] Delete Store Export (XLSX) #%d', $image ) );
						}
					}
				}

				// I don't get any pleasure out of doing this bit...
				wp_cache_delete( $post_type );

				// Check if count hasn't budged and we're in a permanent loop
				if( $count == woo_st_return_count( 'store_export_xlsx' ) ) {
					error_log( '[store-toolkit] Detected permanent loop nuking Store Export (XLSX), bugging out...' );
					$output = false;
					break;
				}
			}
			if( !isset( $output ) )
				$output = true;
			break;

		case 'store_export_xml':
			$post_type = 'attachment';
			$post_mime_types = array( 'application/xml' );
			$args = array(
				'post_type' => $post_type,
				'fields' => 'ids',
				'post_mime_type' => $post_mime_types,
				'post_status' => woo_st_post_statuses(),
				'numberposts' => 100,
			);

			// Allow Plugin/Theme authors to add support for tactical nukes
			$args = apply_filters( 'woo_st_clear_dataset_store_export_xml', $args );

			// Loop through every 100 records until 0 is returned, might take awhile
			while( $count = woo_st_return_count( 'store_export_xml' ) ) {
				$images = get_posts( $args );
				if( !empty( $images ) ) {
					foreach( $images as $image ) {
						if( !WOO_ST_DEBUG ) {
							wp_delete_attachment( $image, true );
						} else {
							error_log( sprintf( '[store-toolkit] Delete Store Export (XML) #%d', $image ) );
						}
					}
				}

				// I don't get any pleasure out of doing this bit...
				wp_cache_delete( $post_type );

				// Check if count hasn't budged and we're in a permanent loop
				if( $count == woo_st_return_count( 'store_export_xml' ) ) {
					error_log( '[store-toolkit] Detected permanent loop nuking Store Export (XML), bugging out...' );
					$output = false;
					break;
				}
			}
			if( !isset( $output ) )
				$output = true;
			break;

		case 'store_export_rss':
			$post_type = 'attachment';
			$post_mime_types = array( 'application/rss+xml' );
			$args = array(
				'post_type' => $post_type,
				'fields' => 'ids',
				'post_mime_type' => $post_mime_types,
				'post_status' => woo_st_post_statuses(),
				'numberposts' => 100,
			);

			// Allow Plugin/Theme authors to add support for tactical nukes
			$args = apply_filters( 'woo_st_clear_dataset_store_export_rss', $args );

			// Loop through every 100 records until 0 is returned, might take awhile
			while( $count = woo_st_return_count( 'store_export_rss' ) ) {
				$images = get_posts( $args );
				if( !empty( $images ) ) {
					foreach( $images as $image ) {
						if( !WOO_ST_DEBUG ) {
							wp_delete_attachment( $image, true );
						} else {
							error_log( sprintf( '[store-toolkit] Delete Store Export (RSS) #%d', $image ) );
						}
					}
				}

				// I don't get any pleasure out of doing this bit...
				wp_cache_delete( $post_type );

				// Check if count hasn't budged and we're in a permanent loop
				if( $count == woo_st_return_count( 'store_export_rss' ) ) {
					error_log( '[store-toolkit] Detected permanent loop nuking Store Export (RSS), bugging out...' );
					$output = false;
					break;
				}
			}
			if( !isset( $output ) )
				$output = true;
			break;

		case 'google_product_feed':
			if( !WOO_ST_DEBUG ) {
				if( $wpdb->get_var( "SHOW TABLES LIKE '" . $wpdb->prefix . "woocommerce_gpf_google_taxonomy'" ) )
					$wpdb->query( "TRUNCATE TABLE `" . $wpdb->prefix . "woocommerce_gpf_google_taxonomy`" );
			}
			$output = true;
			break;

		// WordPress

		case 'post':
			$post_type = 'post';
			$args = array( 
				'post_type' => $post_type,
				'fields' => 'ids',
				'post_status' => woo_st_post_statuses(),
				'numberposts' => 100
			);

			// Allow Plugin/Theme authors to add support for tactical nukes
			$args = apply_filters( 'woo_st_clear_dataset_post', $args );

			// Loop through every 100 records until 0 is returned, might take awhile
			while( $count = woo_st_return_count( 'post' ) ) {
				$posts = get_posts( $args );
				if( $posts ) {
					foreach( $posts as $post ) {
						if( !WOO_ST_DEBUG ) {
							wp_delete_post( $post, true );
						} else {
							error_log( sprintf( '[store-toolkit] Delete Post #%d', $image ) );
						}
					}
				}

				// I don't get any pleasure out of doing this bit...
				wp_cache_delete( $post_type );

				// Check if count hasn't budged and we're in a permanent loop
				if( $count == woo_st_return_count( 'post' ) ) {
					error_log( '[store-toolkit] Detected permanent loop nuking Posts, bugging out...' );
					$output = false;
					break;
				}
			}
			if( !isset( $output ) )
				$output = true;
			break;

		case 'post_category':
			$term_taxonomy = 'category';
			$args = array(
				'hide_empty' => false,
				'number' => 100
			);

			// Allow Plugin/Theme authors to add support for tactical nukes
			$args = apply_filters( 'woo_st_clear_dataset_post_category', $args );

			// Loop through every 100 records until 0 is returned, might take awhile
			while( $count = woo_st_return_count( 'post_category' ) ) {
				$post_categories = get_terms( $term_taxonomy, $args );
				if( $post_categories ) {
					foreach( $post_categories as $post_category ) {
						if( !WOO_ST_DEBUG ) {
							wp_delete_term( $post_category->term_id, $term_taxonomy );
							$wpdb->query( "DELETE FROM `" . $wpdb->terms . "` WHERE `term_id` = " . $post_category->term_id );
							$wpdb->query( "DELETE FROM `" . $wpdb->term_relationships . "` WHERE `term_taxonomy_id` = " . $post_category->term_taxonomy_id );
						} else {
							error_log( sprintf( '[store-toolkit] Delete Post Category #%d', $post_category->term_id ) );
						}
					}
				}

				// I don't get any pleasure out of doing this bit...
				wp_cache_delete( $term_taxonomy );

				// Check if count hasn't budged and we're in a permanent loop
				if( $count == woo_st_return_count( 'post_category' ) ) {
					error_log( '[store-toolkit] Detected permanent loop nuking Post Categories, bugging out...' );
					$output = false;
					break;
				}
			}
			if( !WOO_ST_DEBUG )
				$wpdb->query( "DELETE FROM `" . $wpdb->term_taxonomy . "` WHERE `taxonomy` = '" . $term_taxonomy . "'" );
			if( !isset( $output ) )
			$output = true;
			break;

		case 'post_tag':
			$term_taxonomy = 'post_tag';
			$args = array(
				'hide_empty' => false,
				'number' => 100
			);

			// Allow Plugin/Theme authors to add support for tactical nukes
			$args = apply_filters( 'woo_st_clear_dataset_post_tag', $args );

			// Loop through every 100 records until 0 is returned, might take awhile
			while( $count = woo_st_return_count( 'post_tag' ) ) {
				$post_tags = get_terms( $term_taxonomy, $args );
				if( $post_tags ) {
					foreach( $post_tags as $post_tag ) {
						if( !WOO_ST_DEBUG ) {
							wp_delete_term( $post_tag->term_id, $term_taxonomy );
							$wpdb->query( "DELETE FROM `" . $wpdb->terms . "` WHERE `term_id` = " . $post_tag->term_id );
							$wpdb->query( "DELETE FROM `" . $wpdb->term_relationships . "` WHERE `term_taxonomy_id` = " . $post_tag->term_taxonomy_id );
						} else {
							error_log( sprintf( '[store-toolkit] Delete Post Tag #%d', $post_tag->term_id ) );
						}
					}
				}

				// I don't get any pleasure out of doing this bit...
				wp_cache_delete( $term_taxonomy );

				// Check if count hasn't budged and we're in a permanent loop
				if( $count == woo_st_return_count( 'post_tag' ) ) {
					error_log( '[store-toolkit] Detected permanent loop nuking Post Tags, bugging out...' );
					$output = false;
					break;
				}
			}
			if( !WOO_ST_DEBUG )
				$wpdb->query( "DELETE FROM `" . $wpdb->term_taxonomy . "` WHERE `taxonomy` = '" . $term_taxonomy . "'" );
			if( !isset( $output ) )
				$output = true;
			break;

		case 'link':
			if( !WOO_ST_DEBUG ) {
				$wpdb->query( "TRUNCATE TABLE `" . $wpdb->prefix . "links`" );
			}
			$output = true;
			break;

		case 'comment':
			$args = array(
				'number' => 100
			);

			// Allow Plugin/Theme authors to add support for tactical nukes
			$args = apply_filters( 'woo_st_clear_dataset_comment', $args );

			// Loop through every 100 records until 0 is returned, might take awhile
			while( $count = woo_st_return_count( 'comment' ) ) {
				$comments = get_comments( $args );
				if( !empty( $comments ) ) {
					foreach( $comments as $comment ) {
						if( !WOO_ST_DEBUG ) {
							wp_delete_comment( $comment->comment_ID, true );
						} else {
							error_log( sprintf( '[store-toolkit] Delete Comment #%d', $comment->comment_ID ) );
						}
					}
				}

				// I don't get any pleasure out of doing this bit...
				wp_cache_delete( 'comment' );

				// Check if count hasn't budged and we're in a permanent loop
				if( $count == woo_st_return_count( 'comment' ) ) {
					error_log( '[store-toolkit] Detected permanent loop nuking Comments, bugging out...' );
					$output = false;
					break;
				}
			}
			if( !isset( $output ) )
				$output = true;
			break;

		case 'media_image':
			$post_type = 'attachment';
			$post_mime_types = array( 'image/jpg', 'image/jpeg', 'image/jpe', 'image/gif', 'image/png' );
			$args = array(
				'post_type' => $post_type,
				'fields' => 'ids',
				'post_mime_type' => $post_mime_types,
				'post_status' => woo_st_post_statuses(),
				'numberposts' => 100,
			);

			// Allow Plugin/Theme authors to add support for tactical nukes
			$args = apply_filters( 'woo_st_clear_dataset_media_image', $args );

			// Loop through every 100 records until 0 is returned, might take awhile
			while( $count = woo_st_return_count( 'media_image' ) ) {
				$images = get_posts( $args );
				if( !empty( $images ) ) {
					foreach( $images as $image ) {
						if( !WOO_ST_DEBUG ) {
							wp_delete_attachment( $image, true );
						} else {
							error_log( sprintf( '[store-toolkit] Delete Image #%d', $image ) );
						}
					}
				}

				// I don't get any pleasure out of doing this bit...
				wp_cache_delete( $post_type );

				// Check if count hasn't budged and we're in a permanent loop
				if( $count == woo_st_return_count( 'media_image' ) ) {
					error_log( '[store-toolkit] Detected permanent loop nuking Media, bugging out...' );
					$output = false;
					break;
				}
			}
			if( !isset( $output ) )
				$output = true;
			break;

	}
	// Mission accomplished
	delete_option( WOO_ST_PREFIX . '_in_progress' );

	if( !isset( $output ) )
		$output = false;

	return $output;

}

// Returns a list of allowed Export type statuses
function woo_st_post_statuses() {

	$output = array(
		'publish',
		'pending',
		'draft',
		'auto-draft',
		'future',
		'private',
		'inherit',
		'trash'
	);
	return $output;

}

// Returns number of an Export type prior to nuke, used on Store Toolkit screen
function woo_st_return_count( $export_type = '' ) {

	global $wpdb;

	$count_sql = null;
	switch( $export_type ) {

		// WooCommerce

		case 'product':
			$post_type = array( 'product', 'product_variation' );
			$args = array(
				'post_type' => $post_type,
				'posts_per_page' => 1
			);
			$query = new WP_Query( $args );
			$count = $query->found_posts;
			break;

		case 'product_image':
			$meta_key = '_woocommerce_exclude_image';
			$count_sql = sprintf( "SELECT COUNT(`post_id`) FROM `" . $wpdb->postmeta . "` WHERE `meta_key` = '%s'", $meta_key );
			break;

		case 'product_category':
			$term_taxonomy = 'product_cat';
			if( taxonomy_exists( $term_taxonomy ) )
				$count = wp_count_terms( $term_taxonomy );
			break;

		case 'product_tag':
			$term_taxonomy = 'product_tag';
			if( taxonomy_exists( $term_taxonomy ) )
				$count = wp_count_terms( $term_taxonomy );
			break;

		case 'product_brand':
			$term_taxonomy = apply_filters( 'woo_st_brand_term_taxonomy', 'product_brand' );
			if( taxonomy_exists( $term_taxonomy ) )
				$count = wp_count_terms( $term_taxonomy );
			break;

		case 'product_vendor':
			$term_taxonomy = 'shop_vendor';
			if( taxonomy_exists( $term_taxonomy ) )
				$count = wp_count_terms( $term_taxonomy );
			break;

		case 'order':
			$count = woo_st_get_orders_count();
			break;

		case 'tax_rate':
			$count_sql = "SELECT COUNT(`tax_rate_id`) FROM `" . $wpdb->prefix . "woocommerce_tax_rates`";
			break;

		case 'download_permission':
			$count_sql = "SELECT COUNT(`download_id`) FROM `" . $wpdb->prefix . "woocommerce_downloadable_product_permissions`";
			break;

		case 'coupon':	
			$post_type = 'shop_coupon';
			if( post_type_exists( $post_type ) )
				$count = wp_count_posts( $post_type );
			break;

		case 'shipping_class':
			$term_taxonomy = apply_filters( 'woo_st_shipping_class_term_taxonomy', 'product_shipping_class' );
			if( taxonomy_exists( $term_taxonomy ) )
				$count = wp_count_terms( $term_taxonomy );
			break;

		case 'woocommerce_log':
			$count = 0;
			if( class_exists( 'WC_REST_System_Status_Controller' ) ) {
				$system_status = new WC_REST_System_Status_Controller;
				if( method_exists( $system_status, 'get_environment_info' ) ) {
					$environment = $system_status->get_environment_info();
					$log_directory = $environment['log_directory'];
					if( !empty( $log_directory ) ) {
						if( file_exists( $log_directory ) ) {
							$files = glob( $log_directory . '*.log' );
							if( $files !== false )
								$count = count( $files );
						}
					}
				}
			}
			break;

		case 'attribute':
			$count_sql = "SELECT COUNT(`attribute_id`) FROM `" . $wpdb->prefix . "woocommerce_attribute_taxonomies`";
			break;

		// 3rd Party

		case 'credit_card':
			$post_type = 'offline_payment';
			if( post_type_exists( $post_type ) )
				$count = wp_count_posts( $post_type );
			break;

		case 'store_export_csv':
			$count_sql = "SELECT COUNT(`ID`) FROM `" . $wpdb->posts . "` WHERE `post_mime_type` = 'text/csv'";
			break;

		case 'store_export_tsv':
			$count_sql = "SELECT COUNT(`ID`) FROM `" . $wpdb->posts . "` WHERE `post_mime_type` = 'text/tab-separated-values'";
			break;

		case 'store_export_xls':
			$count_sql = "SELECT COUNT(`ID`) FROM `" . $wpdb->posts . "` WHERE `post_mime_type` = 'application/vnd.ms-excel'";
			break;

		case 'store_export_xlsx':
			$count_sql = "SELECT COUNT(`ID`) FROM `" . $wpdb->posts . "` WHERE `post_mime_type` = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'";
			break;

		case 'store_export_xml':
			$count_sql = "SELECT COUNT(`ID`) FROM `" . $wpdb->posts . "` WHERE `post_mime_type` = 'application/xml'";
			break;

		case 'store_export_rss':
			$count_sql = "SELECT COUNT(`ID`) FROM `" . $wpdb->posts . "` WHERE `post_mime_type` = 'application/rss+xml'";
			break;

		case 'google_product_feed':
			if( $wpdb->get_var( "SHOW TABLES LIKE '" . $wpdb->prefix . "woocommerce_gpf_google_taxonomy'" ) )
				$count_sql = "SELECT COUNT(`taxonomy_term`) FROM `" . $wpdb->prefix . "woocommerce_gpf_google_taxonomy`";
			break;

		// WordPress

		case 'post':
			$post_type = 'post';
			if( post_type_exists( $post_type ) )
				$count = wp_count_posts( $post_type );
			break;

		case 'post_category':
			$term_taxonomy = 'category';
			if( taxonomy_exists( $term_taxonomy ) )
				$count = wp_count_terms( $term_taxonomy );
			break;

		case 'post_tag':
			$term_taxonomy = 'post_tag';
			if( taxonomy_exists( $term_taxonomy ) )
				$count = wp_count_terms( $term_taxonomy );
			break;

		case 'link':
			$count_sql = "SELECT COUNT(`link_id`) FROM `" . $wpdb->prefix . "links`";
			break;

		case 'comment':
			$count = wp_count_comments();
			break;

		case 'media_image':
			$count_sql = "SELECT COUNT(`ID`) FROM `" . $wpdb->posts . "` WHERE `post_mime_type` LIKE 'image%'";
			break;

	}
	if( isset( $count ) || $count_sql ) {
		if( isset( $count ) ) {
			if( is_object( $count ) ) {
				$count_object = $count;
				$count = 0;
				foreach( $count_object as $key => $item )
					$count = $item + $count;
			}
			return $count;
		} else if( !empty( $count_sql ) ) {
			$count = $wpdb->get_var( $count_sql );
		} else {
			$count = 0;
		}
		return $count;
	} else {
		return 0;
	}

}

// Provided by Pippin Williamson, mentioned on WP Beginner (http://www.wpbeginner.com/wp-tutorials/how-to-display-a-users-ip-address-in-wordpress/)
function woo_st_get_visitor_ip_address() {

	if( !empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
		//check ip from share internet
		$ip = sanitize_text_field( $_SERVER['HTTP_CLIENT_IP'] );
	} elseif( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
		//to check ip is passed from proxy
		$ip = sanitize_text_field( $_SERVER['HTTP_X_FORWARDED_FOR'] );
	} else {
		if( isset( $_SERVER['REMOTE_ADDR'] ) )
			$ip = sanitize_text_field( $_SERVER['REMOTE_ADDR'] );
	}
	return apply_filters( 'woo_st_get_visitor_ip_address', $ip );

}

function woo_st_cron_nuke() {

	$output = false;

	// Let's prepare the nuke data
	$datasets = apply_filters( 'woo_st_cron_allowed_dataset_types', array_keys( woo_st_get_dataset_types() ) );
	$type = ( isset( $_GET['type'] ) ? sanitize_text_field( $_GET['type'] ) : $type );
	if( empty( $type ) ) {
		woo_st_error_log( sprintf( 'Error: %s', __( 'No dataset type was provided', 'woocommerce-store-toolkit' ) ) );
		return;
	}
	// Check that the type is in the list of allowed datasets
	if( !in_array( $type, $datasets ) ) {
		woo_st_error_log( sprintf( 'Error: %s', __( 'An invalid export type was provided', 'woocommerce-store-toolkit' ) ) );
		return;
	}
	$output = woo_st_clear_dataset( $type );

	return $output;

}

function woo_st_get_dataset_types() {

	$types = array(
		'product',
		'product_category',
		'product_tag',
		'product_brand',
		'product_vendor',
		'product_image',
		'order',
		'tax_rate',
		'download_permission',
		'coupon',
		'shipping_class',
		'woocommerce_log',
		'attribute',
		'credit_card',
		'store_export_csv',
		'store_export_tsv',
		'store_export_xls',
		'store_export_xlsx',
		'store_export_xml',
		'store_export_rss',
		'google_product_feed',
		'post',
		'post_category',
		'post_tag',
		'link',
		'comment',
		'media_image'
	);
	return $types;

}

function woo_st_error_log( $message = '' ) {

	if( $message == '' )
		return;

	if( class_exists( 'WC_Logger' ) ) {
		$logger = new WC_Logger();
		$logger->add( WOO_ST_PREFIX, $message );
		return true;
	} else {
		// Fallback where the WooCommerce logging engine is unavailable
		error_log( sprintf( '[store-toolkit] %s', $message ) );
	}

}

function woo_st_get_option( $option = null, $default = false, $allow_empty = false ) {

	$output = false;
	if( $option !== null ) {
		$separator = '_';
		$option_name = sanitize_key( WOO_ST_PREFIX . $separator . $option );
		$output = get_option( $option_name, $default );
		if( $allow_empty == false && $output != 0 && ( $output == false || $output == '' ) )
			$output = $default;
	}
	return $output;

}

function woo_st_update_option( $option = null, $value = null ) {

	$output = false;
	if( $option !== null && $value !== null ) {
		$separator = '_';
		$option_name = sanitize_key( WOO_ST_PREFIX . $separator . $option );
		$output = update_option( $option_name, $value );
	}
	return $output;

}

function woo_st_get_orders_count() {
	$count = 0;
	foreach ( wc_get_order_statuses() as $status_slug => $status_name ) {
		$count += wc_orders_count( $status_slug );
	}
	return $count;
}