/** * Clear the product/shop transients cache. * * ## EXAMPLES * * wp wc tool clear_transients * * @since 2.5.0 */ public function clear_transients($args, $assoc_args) { wc_delete_product_transients(); wc_delete_shop_order_transients(); WC_Cache_Helper::get_transient_version('shipping', true); WP_CLI::success('Product transients and shop order transients were cleared.'); }
/** * Run on plugin activation */ static function plugin_registration_hook() { // TaxJar requires at least version 5.3 of PHP if (version_compare(PHP_VERSION, '5.3', '<')) { exit(sprintf('<strong>TaxJar requires PHP 5.3 or higher. You are currently using %s.</strong>', PHP_VERSION)); } // WooCommerce must be activated for TaxJar to activate if (!class_exists('Woocommerce')) { exit('<strong>Please activate WooCommerce before activating TaxJar.</strong>'); } global $wpdb; // Clear all transients wc_delete_product_transients(); wc_delete_shop_order_transients(); WC_Cache_Helper::get_transient_version('shipping', true); // Clear all expired transients /* * Deletes all expired transients. The multi-table delete syntax is used * to delete the transient record from table a, and the corresponding * transient_timeout record from table b. * * Based on code inside core's upgrade_network() function. */ $sql = "DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b\r\n \tWHERE a.option_name LIKE %s\r\n \tAND a.option_name NOT LIKE %s\r\n \tAND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )\r\n \tAND b.option_value < %d"; $rows = $wpdb->query($wpdb->prepare($sql, $wpdb->esc_like('_transient_') . '%', $wpdb->esc_like('_transient_timeout_') . '%', time())); $sql = "DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b\r\n \tWHERE a.option_name LIKE %s\r\n \tAND a.option_name NOT LIKE %s\r\n \tAND b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) )\r\n \tAND b.option_value < %d"; $rows2 = $wpdb->query($wpdb->prepare($sql, $wpdb->esc_like('_site_transient_') . '%', $wpdb->esc_like('_site_transient_timeout_') . '%', time())); // Export Tax Rates $current_class = ''; $rates = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}woocommerce_tax_rates\r\n ORDER BY tax_rate_order\r\n LIMIT %d, %d\r\n ", 0, 10000)); ob_start(); $header = __('Country Code', 'woocommerce') . ',' . __('State Code', 'woocommerce') . ',' . __('ZIP/Postcode', 'woocommerce') . ',' . __('City', 'woocommerce') . ',' . __('Rate %', 'woocommerce') . ',' . __('Tax Name', 'woocommerce') . ',' . __('Priority', 'woocommerce') . ',' . __('Compound', 'woocommerce') . ',' . __('Shipping', 'woocommerce') . ',' . __('Tax Class', 'woocommerce') . "\n"; echo $header; foreach ($rates as $rate) { if ($rate->tax_rate_country) { echo esc_attr($rate->tax_rate_country); } else { echo '*'; } echo ','; if ($rate->tax_rate_country) { echo esc_attr($rate->tax_rate_state); } else { echo '*'; } echo ','; $locations = $wpdb->get_col($wpdb->prepare("SELECT location_code FROM {$wpdb->prefix}woocommerce_tax_rate_locations WHERE location_type='postcode' AND tax_rate_id = %d ORDER BY location_code", $rate->tax_rate_id)); if ($locations) { echo esc_attr(implode('; ', $locations)); } else { echo '*'; } echo ','; $locations = $wpdb->get_col($wpdb->prepare("SELECT location_code FROM {$wpdb->prefix}woocommerce_tax_rate_locations WHERE location_type='city' AND tax_rate_id = %d ORDER BY location_code", $rate->tax_rate_id)); if ($locations) { echo esc_attr(implode('; ', $locations)); } else { echo '*'; } echo ','; if ($rate->tax_rate) { echo esc_attr($rate->tax_rate); } else { echo '0'; } echo ','; if ($rate->tax_rate_name) { echo esc_attr($rate->tax_rate_name); } else { echo '*'; } echo ','; if ($rate->tax_rate_priority) { echo esc_attr($rate->tax_rate_priority); } else { echo '1'; } echo ','; if ($rate->tax_rate_compound) { echo esc_attr($rate->tax_rate_compound); } else { echo '0'; } echo ','; if ($rate->tax_rate_shipping) { echo esc_attr($rate->tax_rate_shipping); } else { echo '0'; } echo ','; echo "\n"; } $csv = ob_get_contents(); ob_end_clean(); $upload_dir = wp_upload_dir(); file_put_contents($upload_dir['basedir'] . '/taxjar-wc_tax_rates-' . date('m-d-Y') . '-' . time() . '.csv', $csv); // Delete All tax rates $wpdb->query("TRUNCATE " . $wpdb->prefix . "woocommerce_tax_rates"); $wpdb->query("TRUNCATE " . $wpdb->prefix . "woocommerce_tax_rate_locations"); }
/** * Updates status of order * * @param string $new_status Status to change the order to. No internal wc- prefix is required. * @param string $note (default: '') Optional note to add * @param bool $manual is this a manual order status change? */ public function update_status($new_status, $note = '', $manual = false) { if (!$this->id) { return; } // Standardise status names. $new_status = 'wc-' === substr($new_status, 0, 3) ? substr($new_status, 3) : $new_status; $old_status = $this->get_status(); // Only update if they differ - and ensure post_status is a 'wc' status. if ($new_status !== $old_status || !in_array($this->post_status, array_keys(wc_get_order_statuses()))) { // Update the order wp_update_post(array('ID' => $this->id, 'post_status' => 'wc-' . $new_status)); $this->post_status = 'wc-' . $new_status; $this->add_order_note(trim($note . ' ' . sprintf(__('Order status changed from %s to %s.', 'woocommerce'), wc_get_order_status_name($old_status), wc_get_order_status_name($new_status))), 0, $manual); // Status was changed do_action('woocommerce_order_status_' . $new_status, $this->id); do_action('woocommerce_order_status_' . $old_status . '_to_' . $new_status, $this->id); do_action('woocommerce_order_status_changed', $this->id, $old_status, $new_status); switch ($new_status) { case 'completed': // Record the sales $this->record_product_sales(); // Increase coupon usage counts $this->increase_coupon_usage_counts(); // Record the completed date of the order update_post_meta($this->id, '_completed_date', current_time('mysql')); // Update reports wc_delete_shop_order_transients($this->id); break; case 'processing': case 'on-hold': // Record the sales $this->record_product_sales(); // Increase coupon usage counts $this->increase_coupon_usage_counts(); // Update reports wc_delete_shop_order_transients($this->id); break; case 'cancelled': // If the order is cancelled, restore used coupons $this->decrease_coupon_usage_counts(); // Update reports wc_delete_shop_order_transients($this->id); break; } } }
/** * Save meta box data */ public static function save($post_id, $post) { global $wpdb; self::init_address_fields(); // Add key add_post_meta($post_id, '_order_key', uniqid('order_'), true); // Update meta update_post_meta($post_id, '_customer_user', absint($_POST['customer_user'])); if (self::$billing_fields) { foreach (self::$billing_fields as $key => $field) { if (!isset($field['id'])) { $field['id'] = '_billing_' . $key; } update_post_meta($post_id, $field['id'], wc_clean($_POST[$field['id']])); } } if (self::$shipping_fields) { foreach (self::$shipping_fields as $key => $field) { if (!isset($field['id'])) { $field['id'] = '_shipping_' . $key; } update_post_meta($post_id, $field['id'], wc_clean($_POST[$field['id']])); } } if (isset($_POST['_transaction_id'])) { update_post_meta($post_id, '_transaction_id', wc_clean($_POST['_transaction_id'])); } // Payment method handling if (get_post_meta($post_id, '_payment_method', true) !== stripslashes($_POST['_payment_method'])) { $methods = WC()->payment_gateways->payment_gateways(); $payment_method = wc_clean($_POST['_payment_method']); $payment_method_title = $payment_method; if (isset($methods) && isset($methods[$payment_method])) { $payment_method_title = $methods[$payment_method]->get_title(); } update_post_meta($post_id, '_payment_method', $payment_method); update_post_meta($post_id, '_payment_method_title', $payment_method_title); } // Update date if (empty($_POST['order_date'])) { $date = current_time('timestamp'); } else { $date = strtotime($_POST['order_date'] . ' ' . (int) $_POST['order_date_hour'] . ':' . (int) $_POST['order_date_minute'] . ':00'); } $date = date_i18n('Y-m-d H:i:s', $date); $wpdb->query($wpdb->prepare("UPDATE {$wpdb->posts} SET post_date = %s, post_date_gmt = %s WHERE ID = %s", $date, get_gmt_from_date($date), $post_id)); // Order data saved, now get it so we can manipulate status $order = wc_get_order($post_id); // Order status $order->update_status($_POST['order_status']); wc_delete_shop_order_transients($post_id); }
/** * Delete a refund */ public static function delete_refund() { check_ajax_referer('order-item', 'security'); if (!current_user_can('edit_shop_orders')) { die(-1); } $refund_id = absint($_POST['refund_id']); if ($refund_id && 'shop_order_refund' === get_post_type($refund_id)) { $order_id = wp_get_post_parent_id($refund_id); wc_delete_shop_order_transients($order_id); wp_delete_post($refund_id); do_action('woocommerce_refund_deleted', $refund_id, $order_id); } die; }
/** * When refunding an order, create a refund line item if the partial refunds do not match order total. * * This is manual; no gateway refund will be performed. * * @since 2.4 * @param int $order_id */ function wc_order_fully_refunded($order_id) { $order = wc_get_order($order_id); $max_refund = wc_format_decimal($order->get_total() - $order->get_total_refunded()); if (!$max_refund) { return; } // Create the refund object $refund = wc_create_refund(array('amount' => $max_refund, 'reason' => __('Order Fully Refunded', 'woocommerce'), 'order_id' => $order_id, 'line_items' => array())); wc_delete_shop_order_transients($order_id); }
/** * Updates status of order * * @access public * @param string $new_status_slug Status to change the order to * @param string $note (default: '') Optional note to add * @return void */ public function update_status($new_status_slug, $note = '') { if ($note) { $note .= ' '; } $old_status = get_term_by('slug', sanitize_title($this->status), 'shop_order_status'); $new_status = get_term_by('slug', sanitize_title($new_status_slug), 'shop_order_status'); if ($new_status) { wp_set_object_terms($this->id, array($new_status->slug), 'shop_order_status', false); if ($this->id && $this->status != $new_status->slug) { // Status was changed do_action('woocommerce_order_status_' . $new_status->slug, $this->id); do_action('woocommerce_order_status_' . $this->status . '_to_' . $new_status->slug, $this->id); do_action('woocommerce_order_status_changed', $this->id, $this->status, $new_status->slug); if ($old_status) { $this->add_order_note($note . sprintf(__('Order status changed from %s to %s.', 'woocommerce'), __($old_status->name, 'woocommerce'), __($new_status->name, 'woocommerce'))); } // Record the completed date of the order if ('completed' == $new_status->slug) { update_post_meta($this->id, '_completed_date', current_time('mysql')); } if ('processing' == $new_status->slug || 'completed' == $new_status->slug || 'on-hold' == $new_status->slug) { // Record the sales $this->record_product_sales(); // Increase coupon usage counts $this->increase_coupon_usage_counts(); } // If the order is cancelled, restore used coupons if ('cancelled' == $new_status->slug) { $this->decrease_coupon_usage_counts(); } // Update last modified wp_update_post(array('ID' => $this->id)); $this->status = $new_status->slug; } } wc_delete_shop_order_transients($this->id); }
/** * woocommerce_untrash_post function. * * @param mixed $id */ public function untrash_post($id) { global $wpdb; if ($id > 0) { $post_type = get_post_type($id); if (in_array($post_type, wc_get_order_types('order-count'))) { // Delete count - meta doesn't work on trashed posts $user_id = get_post_meta($id, '_customer_user', true); if ($user_id > 0) { update_user_meta($user_id, '_order_count', ''); update_user_meta($user_id, '_money_spent', ''); } $refunds = $wpdb->get_results($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_type = 'shop_order_refund' AND post_parent = %d", $id)); foreach ($refunds as $refund) { $wpdb->update($wpdb->posts, array('post_status' => 'wc-completed'), array('ID' => $refund->ID)); } delete_transient('woocommerce_processing_order_count'); wc_delete_shop_order_transients($id); } } }
public function sync() { global $wp; global $wpdb; set_time_limit(0); @ini_set('display_errors', '1'); @ini_set('zlib.output_compression', 'Off'); @ini_set('output_buffering', 'Off'); @ini_set('output_handler', ''); while (ob_get_level() > 1) { @ob_end_clean(); } if (ob_get_level() > 0) { @ob_clean(); } if (!in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) { $this->sendHttpHeaders('500 Config Error', array('Content-Type' => 'application/json', 'Cache-Control' => 'no-cache, no-store', 'Expires' => 'Thu, 01 Jan 1970 00:00:00 GMT', 'Pragma' => 'no-cache')); echo $this->json_encode(array('ack' => 'failed', 'message' => 'WooCommerce Deactivated')); exit; } $type = $wp->query_vars['codisto-sync-route']; if (strtolower($_SERVER['REQUEST_METHOD']) == 'get') { if ($type == 'test' || $type == 'sync' && preg_match('/\\/sync\\/testHash\\?/', $_SERVER['REQUEST_URI'])) { if (!$this->check_hash()) { exit; } $this->sendHttpHeaders('200 OK', array('Content-Type' => 'application/json', 'Cache-Control' => 'no-cache, no-store', 'Expires' => 'Thu, 01 Jan 1970 00:00:00 GMT', 'Pragma' => 'no-cache')); echo $this->json_encode(array('ack' => 'ok')); } else { if ($type === 'settings') { if (!$this->check_hash()) { exit; } $logo_url = get_header_image(); if (function_exists('site_logo')) { $logo = site_logo()->logo; $logo_id = get_theme_mod('custom_logo'); $logo_id = $logo_id ? $logo_id : $logo['id']; if ($logo_id) { $logo_url = wp_get_attachment_image_src($logo_id, 'full'); $logo_url = $logo_url[0]; } } $currency = get_option('woocommerce_currency'); $dimension_unit = get_option('woocommerce_dimension_unit'); $weight_unit = get_option('woocommerce_weight_unit'); $default_location = explode(':', get_option('woocommerce_default_country')); $country_code = isset($default_location[0]) ? $default_location[0] : ''; $state_code = isset($default_location[1]) ? $default_location[1] : ''; $response = array('ack' => 'ok', 'logo' => $logo_url, 'currency' => $currency, 'dimension_unit' => $dimension_unit, 'weight_unit' => $weight_unit, 'country_code' => $country_code, 'state_code' => $state_code); $this->sendHttpHeaders('200 OK', array('Content-Type' => 'application/json', 'Cache-Control' => 'no-cache, no-store', 'Expires' => 'Thu, 01 Jan 1970 00:00:00 GMT', 'Pragma' => 'no-cache')); echo $this->json_encode($response); exit; } else { if ($type === 'tax') { if (!$this->check_hash()) { exit; } $tax_enabled = true; if (function_exists('wc_tax_enabled')) { $tax_enabled = wc_tax_enabled(); } else { $tax_enabled = get_option('woocommerce_calc_taxes') === 'yes'; } if ($tax_enabled) { $rates = $wpdb->get_results("SELECT tax_rate_country AS country, tax_rate_state AS state, tax_rate AS rate, tax_rate_name AS name, tax_rate_class AS class, tax_rate_order AS sequence, tax_rate_priority AS priority FROM `{$wpdb->prefix}woocommerce_tax_rates` ORDER BY tax_rate_order"); } else { $rates = array(); } $response = array('ack' => 'ok', 'tax_rates' => $rates); $this->sendHttpHeaders('200 OK', array('Content-Type' => 'application/json', 'Cache-Control' => 'no-cache, no-store', 'Expires' => 'Thu, 01 Jan 1970 00:00:00 GMT', 'Pragma' => 'no-cache')); echo $this->json_encode($response); exit; } else { if ($type === 'products') { if (!$this->check_hash()) { exit; } $page = isset($_GET['page']) ? (int) $_GET['page'] : 0; $count = isset($_GET['count']) ? (int) $_GET['count'] : 0; $product_ids = isset($_GET['product_ids']) ? json_decode(wp_unslash($_GET['product_ids'])) : null; if (!is_null($product_ids)) { if (!is_array($product_ids)) { $product_ids = array($product_ids); } $product_ids = array_filter($product_ids, create_function('$v', 'return is_numeric($v);')); if (!isset($_GET['count'])) { $count = count($product_ids); } } $products = $wpdb->get_results($wpdb->prepare("SELECT id AS id " . "FROM `{$wpdb->prefix}posts` AS P " . "WHERE post_type = 'product' " . "\t\tAND post_status IN ('publish', 'future', 'pending', 'private') " . "\t" . (is_array($product_ids) ? 'AND id IN (' . implode(',', $product_ids) . ')' : '') . "" . "ORDER BY ID LIMIT %d, %d", $page * $count, $count)); if (!is_array($product_ids) && $page === 0) { $total_count = $wpdb->get_var("SELECT COUNT(*) FROM `{$wpdb->prefix}posts` WHERE post_type = 'product' AND post_status IN ('publish', 'future', 'pending', 'private')"); } $acf_installed = function_exists('acf'); foreach ($products as $product) { $wc_product = $this->get_product($product->id); $categoryproduct = $wc_product->get_categories(); $product->sku = $wc_product->get_sku(); $product->name = html_entity_decode(apply_filters('woocommerce_product_title', $wc_product->post->post_title, $wc_product), ENT_COMPAT | ENT_HTML401, 'UTF-8'); $product->enabled = $wc_product->is_purchasable() && ($wc_product->managing_stock() || $wc_product->is_in_stock()); $product->price = $wc_product->get_price_excluding_tax(); $product->listprice = floatval($wc_product->get_regular_price()); $product->is_taxable = $wc_product->is_taxable(); $product->tax_class = $wc_product->get_tax_class(); $product->stock_control = $wc_product->managing_stock(); $product->stock_level = $wc_product->get_stock_quantity(); if (method_exists($wc_product, 'get_type')) { $product->type = $wc_product->get_type(); } else { $product->type = $wc_product->product_type; } $product->description = apply_filters('the_content', $wc_product->post->post_content); $product->short_description = apply_filters('the_content', $wc_product->post->post_excerpt); if (method_exists($wc_product, 'get_width')) { $product->width = $wc_product->get_width(); if (!is_numeric($product->width)) { unset($product->width); } $product->height = $wc_product->get_height(); if (!is_numeric($product->height)) { unset($product->height); } $product->length = $wc_product->get_length(); if (!is_numeric($product->length)) { unset($product->length); } } else { $product->length = $wc_product->length; $product->width = $wc_product->width; $product->height = $wc_product->height; } $product->weight = $wc_product->get_weight(); if (!is_numeric($product->weight)) { unset($product->weight); } if ($product->is_taxable && 'yes' === get_option('woocommerce_prices_include_tax')) { $tax_rates = WC_Tax::get_shop_base_rate($product->tax_class); $taxes = WC_Tax::calc_tax($product->listprice, $tax_rates, true); $product->listprice = $product->listprice - array_sum($taxes); } if ($product->type == 'variable') { $product->skus = array(); foreach ($wc_product->get_children() as $child_id) { $child_product = $wc_product->get_child($child_id); $img = wp_get_attachment_image_src($child_product->get_image_id(), 'full'); $img = $img[0]; $child_product_data = array('id' => $child_id, 'sku' => $child_product->get_sku(), 'enabled' => $wc_product->is_purchasable() && ($wc_product->managing_stock() || $wc_product->is_in_stock()), 'price' => $child_product->get_price_excluding_tax(), 'listprice' => $child_product->get_regular_price(), 'is_taxable' => $child_product->is_taxable(), 'tax_class' => $child_product->get_tax_class(), 'stock_control' => $child_product->managing_stock(), 'stock_level' => $child_product->get_stock_quantity(), 'images' => array(array('source' => $img, 'sequence' => 0))); $attributes = array(); $termsmap = array(); $names = array(); foreach ($child_product->get_variation_attributes() as $name => $value) { $name = preg_replace('/(pa_)?attribute_/', '', $name); if (!isset($names[$name])) { $names[$name] = true; $terms = get_terms(array('taxonomy' => $name)); if ($terms) { foreach ($terms as $term) { $termsmap[$term->slug] = $term->name; } } } if ($value && (gettype($value) == 'string' || gettype($value) == 'integer')) { if (array_key_exists($value, $termsmap)) { $newvalue = $termsmap[$value]; } else { $newvalue = $value; } } else { $newvalue = ''; } $name = wc_attribute_label($name, $child_product); $attributes[] = array('name' => $name, 'value' => $newvalue, 'slug' => $value); } foreach (get_post_custom_keys($child_product->variation_id) as $attribute) { if (!(in_array($attribute, array('_sku', '_weight', '_length', '_width', '_height', '_thumbnail_id', '_virtual', '_downloadable', '_regular_price', '_sale_price', '_sale_price_dates_from', '_sale_price_dates_to', '_price', '_download_limit', '_download_expiry', '_file_paths', '_manage_stock', '_stock_status', '_downloadable_files', '_variation_description', '_tax_class', '_tax_status', '_stock', '_default_attributes', '_product_attributes', '_file_path', '_backorders')) || substr($attribute, 0, 4) === '_wp_' || substr($attribute, 0, 13) === 'attribute_pa_')) { $value = get_post_meta($child_product->variation_id, $attribute, false); if (is_array($value)) { if (count($value) === 1) { $value = $value[0]; } else { $value = implode(',', $value); } } $attributes[] = array('name' => $attribute, 'value' => $value, 'custom' => true); } } $child_product_data['attributes'] = $attributes; $product->skus[] = $child_product_data; } $attrs = array(); foreach ($wc_product->get_variation_attributes() as $name => $value) { $name = preg_replace('/(pa_)?attribute_/', '', $name); if (!isset($names[$name])) { $names[$name] = true; $terms = get_terms(array('taxonomy' => $name)); if ($terms) { foreach ($terms as $term) { $termsmap[$term->slug] = $term->name; } } } if ($value && (gettype($value) == 'string' || gettype($value) == 'integer')) { if (array_key_exists($value, $termsmap)) { $newvalue = $termsmap[$value]; } else { $newvalue = $value; } } else { $newvalue = ''; } $name = wc_attribute_label($name, $child_product); $attrs[] = array('name' => $name, 'value' => $newvalue, 'slug' => $value); } $product->options = $attrs; } else { if ($product->type == 'grouped') { $product->skus = array(); foreach ($wc_product->get_children() as $child_id) { $child_product = $wc_product->get_child($child_id); $child_product_data = array('id' => $child_id, 'price' => $child_product->get_price_excluding_tax(), 'sku' => $child_product->get_sku(), 'name' => $child_product->get_title()); $product->skus[] = $child_product_data; } } } $product->categories = array(); $product_categories = get_the_terms($product->id, 'product_cat'); if (is_array($product_categories)) { $sequence = 0; foreach ($product_categories as $category) { $product->categories[] = array('category_id' => $category->term_id, 'sequence' => $sequence); $sequence++; } } $image_sequence = 1; $product->images = array(); $imagesUsed = array(); $primaryimage_path = wp_get_attachment_image_src($wc_product->get_image_id(), 'full'); $primaryimage_path = $primaryimage_path[0]; if ($primaryimage_path) { $product->images[] = array('source' => $primaryimage_path, 'sequence' => 0); $imagesUsed[$primaryimage_path] = true; foreach ($wc_product->get_gallery_attachment_ids() as $image_id) { $image_path = wp_get_attachment_image_src($image_id, 'full'); $image_path = $image_path[0]; if (!array_key_exists($image_path, $imagesUsed)) { $product->images[] = array('source' => $image_path, 'sequence' => $image_sequence); $imagesUsed[$image_path] = true; $image_sequence++; } } } $product->attributes = array(); $attributesUsed = array(); foreach ($wc_product->get_attributes() as $attribute) { if (!$attribute['is_variation']) { if (!array_key_exists($attribute['name'], $attributesUsed)) { $attributesUsed[$attribute['name']] = true; $attributeName = wc_attribute_label($attribute['name']); if (!$attribute['is_taxonomy']) { $product->attributes[] = array('name' => $attributeName, 'value' => $attribute['value']); } else { $attributeValue = implode(', ', wc_get_product_terms($product->id, $attribute['name'], array('fields' => 'names'))); $product->attributes[] = array('name' => $attributeName, 'value' => $attributeValue); } } } } foreach (get_post_custom_keys($product->id) as $attribute) { if (!(substr($attribute, 0, 1) === '_' || substr($attribute, 0, 3) === 'pa_')) { if (!array_key_exists($attribute, $attributesUsed)) { $attributesUsed[$attribute] = true; $value = get_post_meta($product->id, $attribute, false); if (is_array($value)) { if (count($value) === 1) { $value = $value[0]; } else { $value = implode(',', $value); } } $product->attributes[] = array('name' => $attribute, 'value' => $value); } } } // acf if ($acf_installed) { if (function_exists('get_field_objects')) { $fields = get_field_objects($product->id); if (is_array($fields)) { foreach ($fields as $field) { if ($field['type'] == 'image') { $image_path = $field['value']['url']; if (!array_key_exists($image_path, $imagesUsed)) { $product->images[] = array('source' => $image_path, 'sequence' => $image_sequence); $imagesUsed[$image_path] = true; $image_sequence++; } } else { if ($field['type'] == 'gallery') { $gallery = $field['value']; if (is_array($gallery)) { foreach ($gallery as $image) { $image_path = $image['url']; if (!array_key_exists($image_path, $imagesUsed)) { $product->images[] = array('source' => $image_path, 'sequence' => $image_sequence); $imagesUsed[$image_path] = true; $image_sequence++; } } } } else { if (in_array($field['type'], array('textarea', 'wysiwyg', 'text', 'number', 'select', 'radio', 'checkbox', 'true_false'))) { if (!array_key_exists($field['label'], $attributesUsed)) { $attributesUsed[$field['label']] = true; $value = $field['value']; if (is_array($value)) { if (count($value) === 1) { $value = $value[0]; } else { $value = implode(',', $value); } } $product->attributes[] = array('name' => $field['name'], 'value' => $value); } } } } if (!$product->description) { if (in_array($field['type'], array('textarea', 'wysiwyg')) && $field['name'] == 'description') { $product->description = $field['value']; } } } } } } } $response = array('ack' => 'ok', 'products' => $products); if (isset($total_count)) { $response['total_count'] = $total_count; } $this->sendHttpHeaders('200 OK', array('Content-Type' => 'application/json', 'Cache-Control' => 'no-cache, no-store', 'Expires' => 'Thu, 01 Jan 1970 00:00:00 GMT', 'Pragma' => 'no-cache')); echo $this->json_encode($response); exit; } else { if ($type === 'categories') { if (!$this->check_hash()) { exit; } $categories = get_categories(array('taxonomy' => 'product_cat', 'orderby' => 'term_order', 'hide_empty' => 0)); $result = array(); foreach ($categories as $category) { $result[] = array('category_id' => $category->term_id, 'name' => $category->name, 'parent_id' => $category->parent); } $response = array('ack' => 'ok', 'categories' => $result, 'total_count' => count($categories)); $this->sendHttpHeaders('200 OK', array('Content-Type' => 'application/json', 'Cache-Control' => 'no-cache, no-store', 'Expires' => 'Thu, 01 Jan 1970 00:00:00 GMT', 'Pragma' => 'no-cache')); echo $this->json_encode($response); exit; } else { if ($type === 'orders') { if (!$this->check_hash()) { exit; } $page = isset($_GET['page']) ? (int) $_GET['page'] : 0; $count = isset($_GET['count']) ? (int) $_GET['count'] : 0; $orders = $wpdb->get_results($wpdb->prepare("SELECT (SELECT meta_value FROM `{$wpdb->prefix}postmeta` WHERE post_id = P.id AND meta_key = '_codisto_orderid') AS id, ID AS post_id, post_status AS status FROM `{$wpdb->prefix}posts` AS P WHERE post_type = 'shop_order' AND ID IN (SELECT post_id FROM `{$wpdb->prefix}postmeta` WHERE meta_key = '_codisto_orderid') ORDER BY ID LIMIT %d, %d", $page * $count, $count)); if ($page == 0) { $total_count = $wpdb->get_var("SELECT COUNT(*) FROM `{$wpdb->prefix}posts` AS P WHERE post_type = 'shop_order' AND ID IN (SELECT post_id FROM `{$wpdb->prefix}postmeta` WHERE meta_key = '_codisto_orderid')"); } $order_data = array(); foreach ($orders as $order) { $ship_date = get_post_meta($order->post_id, '_date_shipped', true); if ($ship_date) { if (is_numeric($ship_date)) { $ship_date = date('Y-m-d H:i:s', $ship_date); } $order->ship_date = $ship_date; } $carrier = get_post_meta($order->post_id, '_tracking_provider', true); if ($carrier) { if ($carrier === 'custom') { $carrier = get_post_meta($order->post_id, '_custom_tracking_provider', true); } if ($carrier) { $order->carrier = $carrier; } } $tracking_number = get_post_meta($order->post_id, '_tracking_number', true); if ($tracking_number) { $order->track_number = $tracking_number; } unset($order->post_id); $order_data[] = $order; } $response = array('ack' => 'ok', 'orders' => $order_data); if (isset($total_count)) { $response['total_count'] = $total_count; } $this->sendHttpHeaders('200 OK', array('Content-Type' => 'application/json', 'Cache-Control' => 'no-cache, no-store', 'Expires' => 'Thu, 01 Jan 1970 00:00:00 GMT', 'Pragma' => 'no-cache')); echo $this->json_encode($response); exit; } else { if ($type == 'sync') { if ($_SERVER['HTTP_X_ACTION'] === 'TEMPLATE') { if (!$this->check_hash()) { exit; } $ebayDesignDir = WP_CONTENT_DIR . '/ebay/'; $merchantid = (int) $_GET['merchantid']; if (!$merchantid) { $merchantid = 0; } $templatedb = get_temp_dir() . '/ebay-template-' . $merchantid . '.db'; $db = new PDO('sqlite:' . $templatedb); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->setAttribute(PDO::ATTR_TIMEOUT, 60); $db->exec('PRAGMA synchronous=0'); $db->exec('PRAGMA temp_store=2'); $db->exec('PRAGMA page_size=65536'); $db->exec('PRAGMA encoding=\'UTF-8\''); $db->exec('PRAGMA cache_size=15000'); $db->exec('PRAGMA soft_heap_limit=67108864'); $db->exec('PRAGMA journal_mode=MEMORY'); $db->exec('BEGIN EXCLUSIVE TRANSACTION'); $db->exec('CREATE TABLE IF NOT EXISTS File(Name text NOT NULL PRIMARY KEY, Content blob NOT NULL, LastModified datetime NOT NULL, Changed bit NOT NULL DEFAULT -1)'); $db->exec('COMMIT TRANSACTION'); if (isset($_GET['markreceived'])) { $update = $db->prepare('UPDATE File SET LastModified = ? WHERE Name = ?'); $files = $db->query('SELECT Name FROM File WHERE Changed != 0'); $files->execute(); $db->exec('BEGIN EXCLUSIVE TRANSACTION'); while ($row = $files->fetch()) { $stat = stat(WP_CONTENT_DIR . '/ebay/' . $row['Name']); $lastModified = strftime('%Y-%m-%d %H:%M:%S', $stat['mtime']); $update->bindParam(1, $lastModified); $update->bindParam(2, $row['Name']); $update->execute(); } $db->exec('UPDATE File SET Changed = 0'); $db->exec('COMMIT TRANSACTION'); $db = null; $this->sendHttpHeaders('200 OK', array('Content-Type' => 'application/json', 'Cache-Control' => 'no-cache, must-revalidate', 'Expires' => 'Thu, 01 Jan 1970 00:00:00 GMT', 'Pragma' => 'no-cache')); echo $this->json_encode(array('ack' => 'ok')); exit; } else { $insert = $db->prepare('INSERT OR IGNORE INTO File(Name, Content, LastModified) VALUES (?, ?, ?)'); $update = $db->prepare('UPDATE File SET Content = ?, Changed = -1 WHERE Name = ? AND LastModified != ?'); $filelist = $this->files_in_dir($ebayDesignDir); $db->exec('BEGIN EXCLUSIVE TRANSACTION'); foreach ($filelist as $key => $name) { try { $fileName = $ebayDesignDir . $name; if (!in_array($name, array('README'))) { $content = @file_get_contents($fileName); if ($content !== false) { $stat = stat($fileName); $lastModified = strftime('%Y-%m-%d %H:%M:%S', $stat['mtime']); $update->bindParam(1, $content); $update->bindParam(2, $name); $update->bindParam(3, $lastModified); $update->execute(); if ($update->rowCount() == 0) { $insert->bindParam(1, $name); $insert->bindParam(2, $content); $insert->bindParam(3, $lastModified); $insert->execute(); } } } } catch (Exception $e) { } } $db->exec('COMMIT TRANSACTION'); $tmpDb = wp_tempnam(); $db = new PDO('sqlite:' . $tmpDb); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->exec('PRAGMA synchronous=0'); $db->exec('PRAGMA temp_store=2'); $db->exec('PRAGMA page_size=512'); $db->exec('PRAGMA encoding=\'UTF-8\''); $db->exec('PRAGMA cache_size=15000'); $db->exec('PRAGMA soft_heap_limit=67108864'); $db->exec('PRAGMA journal_mode=OFF'); $db->exec('ATTACH DATABASE \'' . $templatedb . '\' AS Source'); $db->exec('CREATE TABLE File AS SELECT * FROM Source.File WHERE Changed != 0'); $db->exec('DETACH DATABASE Source'); $db->exec('VACUUM'); $fileCountStmt = $db->query('SELECT COUNT(*) AS fileCount FROM File'); $fileCountStmt->execute(); $fileCountRow = $fileCountStmt->fetch(); $fileCount = $fileCountRow['fileCount']; $db = null; if ($fileCount == 0) { $this->sendHttpHeaders('204 No Content', array('Cache-Control' => 'no-cache, must-revalidate', 'Expires' => 'Thu, 01 Jan 1970 00:00:00 GMT', 'Pragma' => 'no-cache')); } else { $headers = array('Cache-Control' => 'no-cache, must-revalidate', 'Pragma' => 'no-cache', 'Expires' => 'Thu, 01 Jan 1970 00:00:00 GMT', 'Content-Type' => 'application/octet-stream', 'Content-Disposition' => 'attachment; filename=' . basename($tmpDb), 'Content-Length' => filesize($tmpDb)); $this->sendHttpHeaders('200 OK', $headers); while (ob_get_level() > 0) { if (!@ob_end_clean()) { break; } } flush(); readfile($tmpDb); } unlink($tmpDb); exit; } } } } } } } } } } else { if ($type === 'createorder') { if (!$this->check_hash()) { exit; } try { $xml = simplexml_load_string(file_get_contents('php://input')); $ordercontent = $xml->entry->content->children('http://api.codisto.com/schemas/2009/'); $wpdb->query('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE'); $wpdb->query('START TRANSACTION'); $billing_address = $ordercontent->orderaddresses->orderaddress[0]; $shipping_address = $ordercontent->orderaddresses->orderaddress[1]; $billing_first_name = $billing_last_name = ''; if (strpos($billing_address->name, ' ') !== false) { $billing_name = explode(' ', $billing_address->name, 2); $billing_first_name = $billing_name[0]; $billing_last_name = $billing_name[1]; } else { $billing_first_name = (string) $billing_address->name; } $billing_country_code = (string) $billing_address->countrycode; $billing_division = (string) $billing_address->division; $billing_states = WC()->countries->get_states($billing_country_code); if ($billing_states) { $billing_division_match = preg_replace('/\\s+/', '', strtolower($billing_division)); foreach ($billing_states as $state_code => $state_name) { if (preg_replace('/\\s+/', '', strtolower($state_name)) == $billing_division_match) { $billing_division = $state_code; break; } } } $shipping_first_name = $shipping_last_name = ''; if (strpos($shipping_address->name, ' ') !== false) { $shipping_name = explode(' ', $shipping_address->name, 2); $shipping_first_name = $shipping_name[0]; $shipping_last_name = $shipping_name[1]; } else { $shipping_first_name = (string) $shipping_address->name; } $shipping_country_code = (string) $shipping_address->countrycode; $shipping_division = (string) $shipping_address->division; if ($billing_country_code === $shipping_country_code) { $shipping_states = $billing_states; } else { $shipping_states = WC()->countries->get_states($shipping_country_code); } if ($shipping_states) { $shipping_division_match = preg_replace('/\\s+/', '', strtolower($shipping_division)); foreach ($shipping_states as $state_code => $state_name) { if (preg_replace('/\\s+/', '', strtolower($state_name)) == $shipping_division_match) { $shipping_division = $state_code; break; } } } $address_data = array('billing_first_name' => $billing_first_name, 'billing_last_name' => $billing_last_name, 'billing_company' => (string) $billing_address->companyname, 'billing_address_1' => (string) $billing_address->address1, 'billing_address_2' => (string) $billing_address->address2, 'billing_city' => (string) $billing_address->place, 'billing_postcode' => (string) $billing_address->postalcode, 'billing_state' => $billing_division, 'billing_country' => $billing_country_code, 'billing_email' => (string) $billing_address->email, 'billing_phone' => (string) $billing_address->phone, 'shipping_first_name' => $shipping_first_name, 'shipping_last_name' => $shipping_last_name, 'shipping_company' => (string) $shipping_address->companyname, 'shipping_address_1' => (string) $shipping_address->address1, 'shipping_address_2' => (string) $shipping_address->address2, 'shipping_city' => (string) $shipping_address->place, 'shipping_postcode' => (string) $shipping_address->postalcode, 'shipping_state' => $shipping_division, 'shipping_country' => $shipping_country_code, 'shipping_email' => (string) $shipping_address->email, 'shipping_phone' => (string) $shipping_address->phone); $email = (string) $billing_address->email; if (!$email) { $email = (string) $shipping_address->email; } if ($email) { $user = get_user_by('email', $email); if (!$user) { $username = (string) $ordercontent->ebayusername; if (!$username) { $username = current(explode('@', $email)); } if ($username) { $username = sanitize_user($username); } if (username_exists($username)) { $counter = 1; $newusername = $username . $counter; while (username_exists($newusername)) { $counter++; $newusername = $username . $counter; } $username = $newusername; } $password = wp_generate_password(); $customer_data = apply_filters('woocommerce_new_customer_data', array('user_login' => $username, 'user_pass' => $password, 'user_email' => $email, 'role' => 'customer')); $customer_id = wp_insert_user($customer_data); foreach ($address_data as $key => $value) { update_user_meta($customer_id, $key, $value); } do_action('woocommerce_created_customer', $customer_id, $customer_data, true); } else { $customer_id = $user->ID; } } else { $customer_id = 0; } $customer_note = @count($ordercontent->instructions) ? strval($ordercontent->instructions) : ''; $order_id = $wpdb->get_var($wpdb->prepare("SELECT ID FROM `{$wpdb->prefix}posts` AS P WHERE ID IN (SELECT post_id FROM `{$wpdb->prefix}postmeta` WHERE meta_key = '_codisto_orderid' AND meta_value = %d)", (int) $ordercontent->orderid)); $shipping = 0; $shipping_tax = 0; $cart_discount = 0; $cart_discount_tax = 0; $total = (double) $ordercontent->ordertotal; $tax = 0; if (!$order_id) { $new_order_data_callback = array($this, 'order_set_date'); add_filter('woocommerce_new_order_data', $new_order_data_callback, 1, 1); $order = wc_create_order(array('customer_id' => $customer_id, 'customer_note' => $customer_note, 'created_via' => 'eBay')); remove_filter('woocommerce_new_order_data', $new_order_data_callback); $order_id = $order->id; update_post_meta($order_id, '_codisto_orderid', (int) $ordercontent->orderid); update_post_meta($order_id, '_codisto_ebayuser', (string) $ordercontent->ebayusername); update_post_meta($order_id, '_order_currency', (string) $ordercontent->transactcurrency); update_post_meta($order_id, '_customer_ip_address', '-'); delete_post_meta($order_id, '_prices_include_tax'); do_action('woocommerce_new_order', $order_id); foreach ($ordercontent->orderlines->orderline as $orderline) { if ($orderline->productcode[0] != 'FREIGHT') { $productcode = (string) $orderline->productcode; if ($productcode == null) { $productcode = ''; } $productname = (string) $orderline->productname; if ($productname == null) { $productname = ''; } $product_id = $orderline->externalreference[0]; if ($product_id != null) { $product_id = intval($product_id); } $variation_id = 0; if (get_post_type($product_id) === 'product_variation') { $variation_id = $product_id; $product_id = wp_get_post_parent_id($variation_id); if (!is_numeric($product_id) || $product_id === 0) { $product_id = 0; $variation_id = 0; } } $qty = (int) $orderline->quantity[0]; $item_id = wc_add_order_item($order_id, array('order_item_name' => $productname, 'order_item_type' => 'line_item')); wc_add_order_item_meta($item_id, '_qty', $qty); if (!is_null($product_id) && $product_id !== 0) { wc_add_order_item_meta($item_id, '_product_id', $product_id); wc_add_order_item_meta($item_id, '_variation_id', $variation_id); wc_add_order_item_meta($item_id, '_tax_class', ''); } else { wc_add_order_item_meta($item_id, '_product_id', 0); wc_add_order_item_meta($item_id, '_variation_id', 0); wc_add_order_item_meta($item_id, '_tax_class', ''); } $line_total = wc_format_decimal((double) $orderline->linetotal); $line_total_tax = wc_format_decimal((double) $orderline->linetotalinctax - (double) $orderline->linetotal); wc_add_order_item_meta($item_id, '_line_subtotal', $line_total); wc_add_order_item_meta($item_id, '_line_total', $line_total); wc_add_order_item_meta($item_id, '_line_subtotal_tax', $line_total_tax); wc_add_order_item_meta($item_id, '_line_tax', $line_total_tax); wc_add_order_item_meta($item_id, '_line_tax_data', array('total' => array(1 => $line_total_tax), 'subtotal' => array(1 => $line_total_tax))); $tax += $line_total_tax; } else { $item_id = wc_add_order_item($order_id, array('order_item_name' => (string) $orderline->productname, 'order_item_type' => 'shipping')); wc_add_order_item_meta($item_id, 'cost', wc_format_decimal((double) $orderline->linetotal)); $shipping += (double) $orderline->linetotal; $shipping_tax += (double) $orderline->linetotalinctax - (double) $orderline->linetotal; } } if ($ordercontent->paymentstatus == 'complete') { $transaction_id = (string) $ordercontent->orderpayments[0]->orderpayment->transactionid; if ($transaction_id) { update_post_meta($order_id, '_payment_method', 'paypal'); update_post_meta($order_id, '_payment_method_title', __('PayPal', 'woocommerce')); update_post_meta($order_id, '_transaction_id', $transaction_id); } else { update_post_meta($order_id, '_payment_method', 'bacs'); update_post_meta($order_id, '_payment_method_title', __('BACS', 'woocommerce')); } // payment_complete add_post_meta($order_id, '_paid_date', current_time('mysql'), true); if (!get_post_meta($order_id, '_order_stock_reduced', true)) { $order->reduce_order_stock(); } } } else { $order = wc_get_order($order_id); foreach ($ordercontent->orderlines->orderline as $orderline) { if ($orderline->productcode[0] != 'FREIGHT') { $line_total = wc_format_decimal((double) $orderline->linetotal); $line_total_tax = wc_format_decimal((double) $orderline->linetotalinctax - (double) $orderline->linetotal); $tax += $line_total_tax; } else { $order->remove_order_items('shipping'); $item_id = wc_add_order_item($order_id, array('order_item_name' => (string) $orderline->productname, 'order_item_type' => 'shipping')); wc_add_order_item_meta($item_id, 'cost', wc_format_decimal((double) $orderline->linetotal)); $shipping += (double) $orderline->linetotal; $shipping_tax += (double) $orderline->linetotalinctax - (double) $orderline->linetotal; } } if ($ordercontent->paymentstatus == 'complete') { $transaction_id = (string) $ordercontent->orderpayments[0]->orderpayment->transactionid; if ($transaction_id) { update_post_meta($order_id, '_payment_method', 'paypal'); update_post_meta($order_id, '_payment_method_title', __('PayPal', 'woocommerce')); update_post_meta($order_id, '_transaction_id', $transaction_id); } else { update_post_meta($order_id, '_payment_method', 'bacs'); update_post_meta($order_id, '_payment_method_title', __('BACS', 'woocommerce')); } // payment_complete add_post_meta($order_id, '_paid_date', current_time('mysql'), true); if (!get_post_meta($order_id, '_order_stock_reduced', true)) { $order->reduce_order_stock(); } } } foreach ($address_data as $key => $value) { update_post_meta($order_id, '_' . $key, $value); } $order->remove_order_items('tax'); $order->add_tax(1, $tax, $shipping_tax); $order->set_total($shipping, 'shipping'); $order->set_total($shipping_tax, 'shipping_tax'); $order->set_total($cart_discount, 'cart_discount'); $order->set_total($cart_discount_tax, 'cart_discount_tax'); $order->set_total($tax, 'tax'); $order->set_total($total, 'total'); if ($ordercontent->orderstate == 'cancelled') { if (!$order->has_status('cancelled')) { // update_status $order->post_status = 'wc-cancelled'; $update_post_data = array('ID' => $order_id, 'post_status' => 'wc-cancelled', 'post_date' => current_time('mysql', 0), 'post_date_gmt' => current_time('mysql', 1)); wp_update_post($update_post_data); $order->decrease_coupon_usage_counts(); wc_delete_shop_order_transients($order_id); } } else { if ($ordercontent->orderstate == 'inprogress' || $ordercontent->orderstate == 'processing') { if ($ordercontent->paymentstatus == 'complete') { if (!$order->has_status('processing')) { // update_status $order->post_status = 'wc-processing'; $update_post_data = array('ID' => $order_id, 'post_status' => 'wc-processing', 'post_date' => current_time('mysql', 0), 'post_date_gmt' => current_time('mysql', 1)); wp_update_post($update_post_data); } } else { if (!$order->has_status('pending')) { // update_status $order->post_status = 'wc-pending'; $update_post_data = array('ID' => $order_id, 'post_status' => 'wc-pending', 'post_date' => current_time('mysql', 0), 'post_date_gmt' => current_time('mysql', 1)); wp_update_post($update_post_data); } } } else { if ($ordercontent->orderstate == 'complete') { if (!$order->has_status('completed')) { // update_status $order->post_status = 'wc-completed'; $update_post_data = array('ID' => $order_id, 'post_status' => 'wc-completed', 'post_date' => current_time('mysql', 0), 'post_date_gmt' => current_time('mysql', 1)); wp_update_post($update_post_data); $order->record_product_sales(); $order->increase_coupon_usage_counts(); update_post_meta($order_id, '_completed_date', current_time('mysql')); wc_delete_shop_order_transients($order_id); } } } } $wpdb->query('COMMIT'); $response = array('ack' => 'ok', 'orderid' => $order_id); $this->sendHttpHeaders('200 OK', array('Content-Type' => 'application/json', 'Cache-Control' => 'no-cache, no-store', 'Expires' => 'Thu, 01 Jan 1970 00:00:00 GMT', 'Pragma' => 'no-cache')); echo $this->json_encode($response); exit; } catch (Exception $e) { $wpdb->query('ROLLBACK'); $response = array('ack' => 'failed', 'message' => $e->getMessage() . ' ' . $e->getFile() . ' ' . $e->getLine()); $this->sendHttpHeaders('200 OK', array('Content-Type' => 'application/json', 'Cache-Control' => 'no-cache, no-store', 'Expires' => 'Thu, 01 Jan 1970 00:00:00 GMT', 'Pragma' => 'no-cache')); echo $this->json_encode($response); exit; } } else { if ($type == 'sync') { if ($_SERVER['HTTP_X_ACTION'] === 'TEMPLATE') { if (!$this->check_hash()) { exit; } $ebayDesignDir = WP_CONTENT_DIR . '/ebay/'; $tmpPath = wp_tempnam(); @file_put_contents($tmpPath, file_get_contents('php://input')); $db = new PDO('sqlite:' . $tmpPath); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->exec('PRAGMA synchronous=0'); $db->exec('PRAGMA temp_store=2'); $db->exec('PRAGMA page_size=65536'); $db->exec('PRAGMA encoding=\'UTF-8\''); $db->exec('PRAGMA cache_size=15000'); $db->exec('PRAGMA soft_heap_limit=67108864'); $db->exec('PRAGMA journal_mode=MEMORY'); $files = $db->prepare('SELECT Name, Content FROM File'); $files->execute(); $files->bindColumn(1, $name); $files->bindColumn(2, $content); while ($files->fetch()) { $fileName = $ebayDesignDir . $name; if (strpos($name, '..') === false) { if (!file_exists($fileName)) { $dir = dirname($fileName); if (!is_dir($dir)) { mkdir($dir . '/', 0755, true); } @file_put_contents($fileName, $content); } } } $db = null; unlink($tmpPath); $this->sendHttpHeaders('200 OK', array('Content-Type' => 'application/json', 'Cache-Control' => 'no-cache, no-store', 'Expires' => 'Thu, 01 Jan 1970 00:00:00 GMT', 'Pragma' => 'no-cache')); echo $this->json_encode(array('ack' => 'ok')); exit; } } else { if ($type == 'index/calc') { $product_ids = array(); $quantities = array(); for ($i = 0;; $i++) { if (!isset($_POST['PRODUCTCODE(' . $i . ')'])) { break; } $productid = (int) $_POST['PRODUCTID(' . $i . ')']; if (!$productid) { $productcode = $_POST['PRODUCTCODE(' . $i . ')']; $productid = wc_get_product_id_by_sku($productcode); } $productqty = $_POST['PRODUCTQUANTITY(' . $i . ')']; if (!$productqty && $productqty != 0) { $productqty = 1; } WC()->cart->add_to_cart($productid, $productqty); } WC()->customer->set_location($_POST['COUNTRYCODE'], $_POST['DIVISION'], $_POST['POSTALCODE'], $_POST['PLACE']); WC()->customer->set_shipping_location($_POST['COUNTRYCODE'], $_POST['DIVISION'], $_POST['POSTALCODE'], $_POST['PLACE']); WC()->cart->calculate_totals(); WC()->cart->calculate_shipping(); $response = ''; $idx = 0; $methods = WC()->shipping()->get_shipping_methods(); foreach ($methods as $method) { if (file_exists(plugin_dir_path(__FILE__) . 'shipping/' . $method->id)) { include plugin_dir_path(__FILE__) . 'shipping/' . $method->id; } else { foreach ($method->rates as $method => $rate) { $method_name = $rate->get_label(); if (!$method_name) { $method_name = 'Shipping'; } $method_cost = $rate->cost; if (is_numeric($method_cost)) { if (isset($rate->taxes) && is_array($rate->taxes)) { foreach ($rate->taxes as $tax) { if (is_numeric($tax)) { $method_cost += $tax; } } } $response .= ($idx > 0 ? '&' : '') . 'FREIGHTNAME(' . $idx . ')=' . rawurlencode($method_name) . '&FREIGHTCHARGEINCTAX(' . $idx . ')=' . number_format((double) $method_cost, 2, '.', ''); $idx++; } } } } $this->sendHttpHeaders('200 OK', array('Content-Type' => 'application/json', 'Cache-Control' => 'no-cache, no-store', 'Expires' => 'Thu, 01 Jan 1970 00:00:00 GMT', 'Pragma' => 'no-cache')); echo $response; exit; } } } } }
/** * Delete subscription * * @since 2.0 */ public function delete_subscription($subscription_id, $force = false) { $subscription_id = $this->validate_request($subscription_id, $this->post_type, 'delete'); if (is_wp_error($subscription_id)) { return $subscription_id; } wc_delete_shop_order_transients($subscription_id); do_action('woocommerce_api_delete_subscription', $subscription_id, $this); return $this->delete($subscription_id, 'subscription', 'true' === $force); }
/** * Save meta box data. * * @param int $post_id * @param WP_Post $post */ public static function save($post_id, $post) { global $wpdb; self::init_address_fields(); // Ensure gateways are loaded in case they need to insert data into the emails WC()->payment_gateways(); WC()->shipping(); $customer_changed = false; // Add key add_post_meta($post_id, '_order_key', uniqid('order_'), true); // Update meta if (update_post_meta($post_id, '_customer_user', absint($_POST['customer_user']))) { $customer_changed = true; } if (!empty(self::$billing_fields)) { foreach (self::$billing_fields as $key => $field) { if (!isset($field['id'])) { $field['id'] = '_billing_' . $key; } if (update_post_meta($post_id, $field['id'], wc_clean($_POST[$field['id']]))) { $customer_changed = true; } } } if (!empty(self::$shipping_fields)) { foreach (self::$shipping_fields as $key => $field) { if (!isset($field['id'])) { $field['id'] = '_shipping_' . $key; } if (update_post_meta($post_id, $field['id'], wc_clean($_POST[$field['id']]))) { $customer_changed = true; } } } if (isset($_POST['_transaction_id'])) { update_post_meta($post_id, '_transaction_id', wc_clean($_POST['_transaction_id'])); } // Payment method handling if (get_post_meta($post_id, '_payment_method', true) !== stripslashes($_POST['_payment_method'])) { $methods = WC()->payment_gateways->payment_gateways(); $payment_method = wc_clean($_POST['_payment_method']); $payment_method_title = $payment_method; if (isset($methods) && isset($methods[$payment_method])) { $payment_method_title = $methods[$payment_method]->get_title(); } update_post_meta($post_id, '_payment_method', $payment_method); update_post_meta($post_id, '_payment_method_title', $payment_method_title); } // Update date if (empty($_POST['order_date'])) { $date = current_time('timestamp'); } else { $date = strtotime($_POST['order_date'] . ' ' . (int) $_POST['order_date_hour'] . ':' . (int) $_POST['order_date_minute'] . ':00'); } $date = date_i18n('Y-m-d H:i:s', $date); $wpdb->query($wpdb->prepare("UPDATE {$wpdb->posts} SET post_date = %s, post_date_gmt = %s WHERE ID = %s", $date, get_gmt_from_date($date), $post_id)); clean_post_cache($post_id); // If customer changed, update any downloadable permissions if ($customer_changed) { $wpdb->update($wpdb->prefix . "woocommerce_downloadable_product_permissions", array('user_id' => absint(get_post_meta($post->ID, '_customer_user', true)), 'user_email' => wc_clean(get_post_meta($post->ID, '_billing_email', true))), array('order_id' => $post_id), array('%d', '%s'), array('%d')); } // Order data saved, now get it so we can manipulate status $order = wc_get_order($post_id); // Order status $order->update_status($_POST['order_status'], '', true); wc_delete_shop_order_transients($post_id); }
/** * Clear any caches. * * @param WC_Order * @since 2.7.0 */ protected function clear_caches(&$order) { clean_post_cache($order->get_id()); wc_delete_shop_order_transients($order); }
/** * Handle a refund via the edit order screen */ public static function refund_line_items() { ob_start(); check_ajax_referer('order-item', 'security'); $order_id = absint($_POST['order_id']); $refund_amount = wc_format_decimal(sanitize_text_field($_POST['refund_amount'])); $refund_reason = sanitize_text_field($_POST['refund_reason']); $line_item_qtys = json_decode(sanitize_text_field(stripslashes($_POST['line_item_qtys'])), true); $line_item_totals = json_decode(sanitize_text_field(stripslashes($_POST['line_item_totals'])), true); $line_item_tax_totals = json_decode(sanitize_text_field(stripslashes($_POST['line_item_tax_totals'])), true); $api_refund = $_POST['api_refund'] === 'true' ? true : false; $restock_refunded_items = $_POST['restock_refunded_items'] === 'true' ? true : false; $refund = false; try { // Validate that the refund can occur $order = wc_get_order($order_id); $order_items = $order->get_items(); $max_refund = $order->get_total() - $order->get_total_refunded(); if (!$refund_amount || $max_refund < $refund_amount) { throw new exception(__('Invalid refund amount', 'woocommerce')); } // Prepare line items which we are refunding $line_items = array(); $item_ids = array_unique(array_merge(array_keys($line_item_qtys, $line_item_totals))); foreach ($item_ids as $item_id) { $line_items[$item_id] = array('qty' => 0, 'refund_total' => 0, 'refund_tax' => array()); } foreach ($line_item_qtys as $item_id => $qty) { $line_items[$item_id]['qty'] = max($qty, 0); if ($restock_refunded_items && $qty && isset($order_items[$item_id])) { $order_item = $order_items[$item_id]; $_product = $order->get_product_from_item($order_item); if ($_product && $_product->exists() && $_product->managing_stock()) { $old_stock = $_product->stock; $new_quantity = $_product->increase_stock($qty); $order->add_order_note(sprintf(__('Item #%s stock increased from %s to %s.', 'woocommerce'), $order_item['product_id'], $old_stock, $new_quantity)); } } } foreach ($line_item_totals as $item_id => $total) { $line_items[$item_id]['refund_total'] = wc_format_decimal($total); } foreach ($line_item_tax_totals as $item_id => $tax_totals) { $line_items[$item_id]['refund_tax'] = array_map('wc_format_decimal', $tax_totals); } // Create the refund object $refund = wc_create_refund(array('amount' => $refund_amount, 'reason' => $refund_reason, 'order_id' => $order_id, 'line_items' => $line_items)); if (is_wp_error($refund)) { throw new Exception($refund->get_error_message()); } // Refund via API if ($api_refund) { if (WC()->payment_gateways()) { $payment_gateways = WC()->payment_gateways->payment_gateways(); } if (isset($payment_gateways[$order->payment_method]) && $payment_gateways[$order->payment_method]->supports('refunds')) { $result = $payment_gateways[$order->payment_method]->process_refund($order_id, $refund_amount, $refund_reason); if (is_wp_error($result)) { throw new Exception($result->get_error_message()); } elseif (!$result) { throw new Exception(__('Refund failed', 'woocommerce')); } } } // Clear transients wc_delete_shop_order_transients($order_id); wp_send_json(true); } catch (Exception $e) { if ($refund && is_a($refund, 'WC_Order_Refund')) { wp_delete_post($refund->id, true); } wp_send_json(array('error' => $e->getMessage())); } }
/** * woocommerce_untrash_post function. * * @param mixed $id */ public static function untrash_post($id) { global $wpdb; if ($id > 0) { $post_type = get_post_type($id); if (in_array($post_type, wc_get_order_types('order-count'))) { $refunds = $wpdb->get_results($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_type = 'shop_order_refund' AND post_parent = %d", $id)); foreach ($refunds as $refund) { $wpdb->update($wpdb->posts, array('post_status' => 'wc-completed'), array('ID' => $refund->ID)); } delete_transient('woocommerce_processing_order_count'); wc_delete_shop_order_transients($id); } elseif ('product' === $post_type) { // Check if SKU is valid before untrash the product. $sku = get_post_meta($id, '_sku', true); if (!empty($sku)) { if (!wc_product_has_unique_sku($id, $sku)) { update_post_meta($id, '_sku', ''); } } } } }
/** * Handles output of tools */ public static function status_tools() { global $wpdb; $tools = self::get_tools(); if (!empty($_GET['action']) && !empty($_REQUEST['_wpnonce']) && wp_verify_nonce($_REQUEST['_wpnonce'], 'debug_action')) { switch ($_GET['action']) { case 'clear_transients': wc_delete_product_transients(); wc_delete_shop_order_transients(); WC_Cache_Helper::get_transient_version('shipping', true); echo '<div class="updated"><p>' . __('Product Transients Cleared', 'woocommerce') . '</p></div>'; break; case 'clear_expired_transients': /* * Deletes all expired transients. The multi-table delete syntax is used * to delete the transient record from table a, and the corresponding * transient_timeout record from table b. * * Based on code inside core's upgrade_network() function. */ $sql = "DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b\r\n\t\t\t\t\t\tWHERE a.option_name LIKE %s\r\n\t\t\t\t\t\tAND a.option_name NOT LIKE %s\r\n\t\t\t\t\t\tAND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )\r\n\t\t\t\t\t\tAND b.option_value < %d"; $rows = $wpdb->query($wpdb->prepare($sql, $wpdb->esc_like('_transient_') . '%', $wpdb->esc_like('_transient_timeout_') . '%', time())); $sql = "DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b\r\n\t\t\t\t\t\tWHERE a.option_name LIKE %s\r\n\t\t\t\t\t\tAND a.option_name NOT LIKE %s\r\n\t\t\t\t\t\tAND b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) )\r\n\t\t\t\t\t\tAND b.option_value < %d"; $rows2 = $wpdb->query($wpdb->prepare($sql, $wpdb->esc_like('_site_transient_') . '%', $wpdb->esc_like('_site_transient_timeout_') . '%', time())); echo '<div class="updated"><p>' . sprintf(__('%d Transients Rows Cleared', 'woocommerce'), $rows + $rows2) . '</p></div>'; break; case 'reset_roles': // Remove then re-add caps and roles WC_Install::remove_roles(); WC_Install::create_roles(); echo '<div class="updated"><p>' . __('Roles successfully reset', 'woocommerce') . '</p></div>'; break; case 'recount_terms': $product_cats = get_terms('product_cat', array('hide_empty' => false, 'fields' => 'id=>parent')); _wc_term_recount($product_cats, get_taxonomy('product_cat'), true, false); $product_tags = get_terms('product_tag', array('hide_empty' => false, 'fields' => 'id=>parent')); _wc_term_recount($product_tags, get_taxonomy('product_tag'), true, false); echo '<div class="updated"><p>' . __('Terms successfully recounted', 'woocommerce') . '</p></div>'; break; case 'clear_sessions': $wpdb->query("\r\n\t\t\t\t\t\tDELETE FROM {$wpdb->options}\r\n\t\t\t\t\t\tWHERE option_name LIKE '_wc_session_%' OR option_name LIKE '_wc_session_expires_%'\r\n\t\t\t\t\t"); wp_cache_flush(); echo '<div class="updated"><p>' . __('Sessions successfully cleared', 'woocommerce') . '</p></div>'; break; case 'install_pages': WC_Install::create_pages(); echo '<div class="updated"><p>' . __('All missing WooCommerce pages was installed successfully.', 'woocommerce') . '</p></div>'; break; case 'delete_taxes': $wpdb->query("TRUNCATE " . $wpdb->prefix . "woocommerce_tax_rates"); $wpdb->query("TRUNCATE " . $wpdb->prefix . "woocommerce_tax_rate_locations"); echo '<div class="updated"><p>' . __('Tax rates successfully deleted', 'woocommerce') . '</p></div>'; break; case 'reset_tracking': delete_option('woocommerce_allow_tracking'); WC_Admin_Notices::add_notice('tracking'); echo '<div class="updated"><p>' . __('Usage tracking settings successfully reset.', 'woocommerce') . '</p></div>'; break; default: $action = esc_attr($_GET['action']); if (isset($tools[$action]['callback'])) { $callback = $tools[$action]['callback']; $return = call_user_func($callback); if ($return === false) { if (is_array($callback)) { echo '<div class="error"><p>' . sprintf(__('There was an error calling %s::%s', 'woocommerce'), get_class($callback[0]), $callback[1]) . '</p></div>'; } else { echo '<div class="error"><p>' . sprintf(__('There was an error calling %s', 'woocommerce'), $callback) . '</p></div>'; } } } break; } } // Manual translation update messages if (isset($_GET['translation_updated'])) { WC_Language_Pack_Upgrader::language_update_messages(); } // Display message if settings settings have been saved if (isset($_REQUEST['settings-updated'])) { echo '<div class="updated"><p>' . __('Your changes have been saved.', 'woocommerce') . '</p></div>'; } include_once 'views/html-admin-page-status-tools.php'; }
function wc_update_240_refunds() { global $wpdb; /** * Refunds for full refunded orders. * Update fully refunded orders to ensure they have a refund line item so reports add up. */ $refunded_orders = get_posts(array('posts_per_page' => -1, 'post_type' => 'shop_order', 'post_status' => array('wc-refunded'))); // Ensure emails are disabled during this update routine remove_all_actions('woocommerce_order_status_refunded_notification'); remove_all_actions('woocommerce_order_partially_refunded_notification'); remove_action('woocommerce_order_status_refunded', array('WC_Emails', 'send_transactional_email')); remove_action('woocommerce_order_partially_refunded', array('WC_Emails', 'send_transactional_email')); foreach ($refunded_orders as $refunded_order) { $order_total = get_post_meta($refunded_order->ID, '_order_total', true); $refunded_total = $wpdb->get_var($wpdb->prepare("\n\t\t\tSELECT SUM( postmeta.meta_value )\n\t\t\tFROM {$wpdb->postmeta} AS postmeta\n\t\t\tINNER JOIN {$wpdb->posts} AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d )\n\t\t\tWHERE postmeta.meta_key = '_refund_amount'\n\t\t\tAND postmeta.post_id = posts.ID\n\t\t", $refunded_order->ID)); if ($order_total > $refunded_total) { wc_create_refund(array('amount' => $order_total - $refunded_total, 'reason' => __('Order fully refunded', 'woocommerce'), 'order_id' => $refunded_order->ID, 'line_items' => array(), 'date' => $refunded_order->post_modified)); } } wc_delete_shop_order_transients(); }
/** * Update an order. * * ## OPTIONS * * <id> * : Product ID * * [--<field>=<value>] * : One or more fields to update. * * ## AVAILABLE FIELDS * * For available fields, see: wp wc order create --help * * ## EXAMPLES * * wp wc order update 123 --status=completed * * @todo gedex * @since 2.5.0 */ public function update($args, $assoc_args) { try { $id = $args[0]; $data = apply_filters('woocommerce_cli_update_order_data', $this->unflatten_array($assoc_args)); $update_totals = false; $order = wc_get_order($id); if (empty($order)) { throw new WC_CLI_Exception('woocommerce_cli_invalid_order_id', __('Order ID is invalid', 'woocommerce')); } $order_args = array('order_id' => $order->id); // customer note if (isset($data['note'])) { $order_args['customer_note'] = $data['note']; } // order status if (!empty($data['status'])) { $order->update_status($data['status'], isset($data['status_note']) ? $data['status_note'] : ''); } // customer ID if (isset($data['customer_id']) && $data['customer_id'] != $order->get_user_id()) { // make sure customer exists if (false === get_user_by('id', $data['customer_id'])) { throw new WC_CLI_Exception('woocommerce_cli_invalid_customer_id', __('Customer ID is invalid', 'woocommerce')); } update_post_meta($order->id, '_customer_user', $data['customer_id']); } // billing/shipping address $this->set_order_addresses($order, $data); $lines = array('line_item' => 'line_items', 'shipping' => 'shipping_lines', 'fee' => 'fee_lines', 'coupon' => 'coupon_lines'); foreach ($lines as $line_type => $line) { if (isset($data[$line]) && is_array($data[$line])) { $update_totals = true; foreach ($data[$line] as $item) { // item ID is always required if (!array_key_exists('id', $item)) { throw new WC_CLI_Exception('woocommerce_invalid_item_id', __('Order item ID is required', 'woocommerce')); } // create item if (is_null($item['id'])) { $this->set_item($order, $line_type, $item, 'create'); } elseif ($this->item_is_null($item)) { // delete item wc_delete_order_item($item['id']); } else { // update item $this->set_item($order, $line_type, $item, 'update'); } } } } // payment method (and payment_complete() if `paid` == true and order needs payment) if (isset($data['payment_details']) && is_array($data['payment_details'])) { // method ID if (isset($data['payment_details']['method_id'])) { update_post_meta($order->id, '_payment_method', $data['payment_details']['method_id']); } // method title if (isset($data['payment_details']['method_title'])) { update_post_meta($order->id, '_payment_method_title', $data['payment_details']['method_title']); } // mark as paid if set if ($order->needs_payment() && isset($data['payment_details']['paid']) && $this->is_true($data['payment_details']['paid'])) { $order->payment_complete(isset($data['payment_details']['transaction_id']) ? $data['payment_details']['transaction_id'] : ''); } } // set order currency if (isset($data['currency'])) { if (!array_key_exists($data['currency'], get_woocommerce_currencies())) { throw new WC_CLI_Exception('woocommerce_invalid_order_currency', __('Provided order currency is invalid', 'woocommerce')); } update_post_meta($order->id, '_order_currency', $data['currency']); } // set order number if (isset($data['order_number'])) { update_post_meta($order->id, '_order_number', $data['order_number']); } // if items have changed, recalculate order totals if ($update_totals) { $order->calculate_totals(); } // update order meta if (isset($data['order_meta']) && is_array($data['order_meta'])) { $this->set_order_meta($order->id, $data['order_meta']); } // update the order post to set customer note/modified date wc_update_order($order_args); wc_delete_shop_order_transients($order->id); do_action('woocommerce_cli_update_order', $order->id, $data); WP_CLI::success("Updated order {$order->id}."); } catch (WC_CLI_Exception $e) { WP_CLI::error($e->getMessage()); } }
/** * Handle a refund via the edit order screen. */ public static function refund_line_items() { ob_start(); check_ajax_referer('order-item', 'security'); if (!current_user_can('edit_shop_orders')) { die(-1); } $order_id = absint($_POST['order_id']); $refund_amount = wc_format_decimal(sanitize_text_field($_POST['refund_amount']), wc_get_price_decimals()); $refund_reason = sanitize_text_field($_POST['refund_reason']); $line_item_qtys = json_decode(sanitize_text_field(stripslashes($_POST['line_item_qtys'])), true); $line_item_totals = json_decode(sanitize_text_field(stripslashes($_POST['line_item_totals'])), true); $line_item_tax_totals = json_decode(sanitize_text_field(stripslashes($_POST['line_item_tax_totals'])), true); $api_refund = 'true' === $_POST['api_refund']; $restock_refunded_items = 'true' === $_POST['restock_refunded_items']; $refund = false; $response_data = array(); try { $order = wc_get_order($order_id); $order_items = $order->get_items(); $max_refund = wc_format_decimal($order->get_total() - $order->get_total_refunded(), wc_get_price_decimals()); if (!$refund_amount || $max_refund < $refund_amount || 0 > $refund_amount) { throw new exception(__('Invalid refund amount', 'woocommerce')); } // Prepare line items which we are refunding $line_items = array(); $item_ids = array_unique(array_merge(array_keys($line_item_qtys, $line_item_totals))); foreach ($item_ids as $item_id) { $line_items[$item_id] = array('qty' => 0, 'refund_total' => 0, 'refund_tax' => array()); } foreach ($line_item_qtys as $item_id => $qty) { $line_items[$item_id]['qty'] = max($qty, 0); } foreach ($line_item_totals as $item_id => $total) { $line_items[$item_id]['refund_total'] = wc_format_decimal($total); } foreach ($line_item_tax_totals as $item_id => $tax_totals) { $line_items[$item_id]['refund_tax'] = array_map('wc_format_decimal', $tax_totals); } // Create the refund object $refund = wc_create_refund(array('amount' => $refund_amount, 'reason' => $refund_reason, 'order_id' => $order_id, 'line_items' => $line_items)); if (is_wp_error($refund)) { throw new Exception($refund->get_error_message()); } // Refund via API if ($api_refund) { if (WC()->payment_gateways()) { $payment_gateways = WC()->payment_gateways->payment_gateways(); } if (isset($payment_gateways[$order->get_payment_method()]) && $payment_gateways[$order->get_payment_method()]->supports('refunds')) { $result = $payment_gateways[$order->get_payment_method()]->process_refund($order_id, $refund_amount, $refund_reason); do_action('woocommerce_refund_processed', $refund, $result); if (is_wp_error($result)) { throw new Exception($result->get_error_message()); } elseif (!$result) { throw new Exception(__('Refund failed', 'woocommerce')); } } } // restock items foreach ($line_item_qtys as $item_id => $qty) { if ($restock_refunded_items && $qty && isset($order_items[$item_id])) { $order_item = $order_items[$item_id]; $_product = $order_item->get_product(); if ($_product && $_product->exists() && $_product->managing_stock()) { $old_stock = wc_stock_amount($_product->stock); $new_quantity = $_product->increase_stock($qty); $order->add_order_note(sprintf(__('Item #%s stock increased from %1$s to %2$s.', 'woocommerce'), $order_item['product_id'], $old_stock, $new_quantity)); do_action('woocommerce_restock_refunded_item', $_product->get_id(), $old_stock, $new_quantity, $order, $_product); } } } // Trigger notifications and status changes if ($order->get_remaining_refund_amount() > 0 || $order->has_free_item() && $order->get_remaining_refund_items() > 0) { /** * woocommerce_order_partially_refunded. * * @since 2.4.0 * Note: 3rd arg was added in err. Kept for bw compat. 2.4.3. */ do_action('woocommerce_order_partially_refunded', $order_id, $refund->get_id(), $refund->get_id()); } else { do_action('woocommerce_order_fully_refunded', $order_id, $refund->get_id()); $order->update_status(apply_filters('woocommerce_order_fully_refunded_status', 'refunded', $order_id, $refund->get_id())); $response_data['status'] = 'fully_refunded'; } do_action('woocommerce_order_refunded', $order_id, $refund->get_id()); // Clear transients wc_delete_shop_order_transients($order_id); wp_send_json_success($response_data); } catch (Exception $e) { if ($refund && is_a($refund, 'WC_Order_Refund')) { wp_delete_post($refund->get_id(), true); } wp_send_json_error(array('error' => $e->getMessage())); } }
/** * Handle a refund via the edit order screen. * Called after wp_ajax_woocommerce_delete_refund action * * @use woocommerce_refund_deleted action * @see woocommerce\includes\class-wc-ajax.php:2328 */ public static function refund_deleted($refund_id, $parent_order_id) { check_ajax_referer('order-item', 'security'); if (!current_user_can('edit_shop_orders')) { die(-1); } if (!wp_get_post_parent_id($parent_order_id)) { global $wpdb; $child_refund_ids = $wpdb->get_col($wpdb->prepare("SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key=%s AND meta_value=%s", '_parent_refund_id', $refund_id)); foreach ($child_refund_ids as $child_refund_id) { if ($child_refund_id && 'shop_order_refund' === get_post_type($child_refund_id)) { $order_id = wp_get_post_parent_id($child_refund_id); wc_delete_shop_order_transients($order_id); wp_delete_post($child_refund_id); } } } }
/** * Delete a refund */ public static function delete_refund() { check_ajax_referer('order-item', 'security'); $refund_id = absint($_POST['refund_id']); if ($refund_id && 'shop_order_refund' === get_post_type($refund_id)) { wc_delete_shop_order_transients(wp_get_post_parent_id($refund_id)); wp_delete_post($refund_id); } die; }
/** * Delete order refund * * @since 2.2 * @param string $order_id order ID * @param string $id refund ID * @return WP_Error|array error or deleted message */ public function delete_order_refund($order_id, $id) { try { $order_id = $this->validate_request($order_id, $this->post_type, 'delete'); if (is_wp_error($order_id)) { return $order_id; } // Validate refund ID $id = absint($id); if (empty($id)) { throw new WC_API_Exception('woocommerce_api_invalid_order_refund_id', __('Invalid order refund ID', 'woocommerce'), 400); } // Ensure refund ID is valid $refund = get_post($id); if (!$refund) { throw new WC_API_Exception('woocommerce_api_invalid_order_refund_id', __('An order refund with the provided ID could not be found', 'woocommerce'), 404); } // Ensure refund ID is associated with given order if ($refund->post_parent != $order_id) { throw new WC_API_Exception('woocommerce_api_invalid_order_refund_id', __('The order refund ID provided is not associated with the order', 'woocommerce'), 400); } wc_delete_shop_order_transients($order_id); do_action('woocommerce_api_delete_order_refund', $refund->ID, $order_id, $this); return $this->delete($refund->ID, 'refund', true); } catch (WC_API_Exception $e) { return new WP_Error($e->getErrorCode(), $e->getMessage(), array('status' => $e->getCode())); } }
/** * Actually executes a a tool. * * @param string $tool * @return array */ public function execute_tool($tool) { global $wpdb; $ran = true; switch ($tool) { case 'clear_transients': wc_delete_product_transients(); wc_delete_shop_order_transients(); WC_Cache_Helper::get_transient_version('shipping', true); $message = __('Product Transients Cleared', 'woocommerce'); break; case 'clear_expired_transients': /* * Deletes all expired transients. The multi-table delete syntax is used. * to delete the transient record from table a, and the corresponding. * transient_timeout record from table b. * * Based on code inside core's upgrade_network() function. */ $sql = "DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b\n\t\t\t\t\tWHERE a.option_name LIKE %s\n\t\t\t\t\tAND a.option_name NOT LIKE %s\n\t\t\t\t\tAND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )\n\t\t\t\t\tAND b.option_value < %d"; $rows = $wpdb->query($wpdb->prepare($sql, $wpdb->esc_like('_transient_') . '%', $wpdb->esc_like('_transient_timeout_') . '%', time())); $sql = "DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b\n\t\t\t\t\tWHERE a.option_name LIKE %s\n\t\t\t\t\tAND a.option_name NOT LIKE %s\n\t\t\t\t\tAND b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) )\n\t\t\t\t\tAND b.option_value < %d"; $rows2 = $wpdb->query($wpdb->prepare($sql, $wpdb->esc_like('_site_transient_') . '%', $wpdb->esc_like('_site_transient_timeout_') . '%', time())); $message = sprintf(__('%d Transients Rows Cleared', 'woocommerce'), $rows + $rows2); break; case 'reset_roles': // Remove then re-add caps and roles WC_Install::remove_roles(); WC_Install::create_roles(); $message = __('Roles successfully reset', 'woocommerce'); break; case 'recount_terms': $product_cats = get_terms('product_cat', array('hide_empty' => false, 'fields' => 'id=>parent')); _wc_term_recount($product_cats, get_taxonomy('product_cat'), true, false); $product_tags = get_terms('product_tag', array('hide_empty' => false, 'fields' => 'id=>parent')); _wc_term_recount($product_tags, get_taxonomy('product_tag'), true, false); $message = __('Terms successfully recounted', 'woocommerce'); break; case 'clear_sessions': $wpdb->query("TRUNCATE {$wpdb->prefix}woocommerce_sessions"); wp_cache_flush(); $message = __('Sessions successfully cleared', 'woocommerce'); break; case 'install_pages': WC_Install::create_pages(); return __('All missing WooCommerce pages was installed successfully.', 'woocommerce'); break; case 'delete_taxes': $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rates;"); $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations;"); WC_Cache_Helper::incr_cache_prefix('taxes'); $message = __('Tax rates successfully deleted', 'woocommerce'); break; case 'reset_tracking': delete_option('woocommerce_allow_tracking'); WC_Admin_Notices::add_notice('tracking'); $message = __('Usage tracking settings successfully reset.', 'woocommerce'); break; default: $tools = $this->get_tools(); if (isset($tools[$tool]['callback'])) { $callback = $tools[$tool]['callback']; $return = call_user_func($callback); if ($return === false) { $callback_string = is_array($callback) ? get_class($callback[0]) . '::' . $callback[1] : $callback; $ran = false; $message = sprintf(__('There was an error calling %s', 'woocommerce'), $callback_string); } else { $message = __('Tool ran.', 'woocommerce'); } } else { $ran = false; $message = __('There was an error calling this tool. There is no callback present.', 'woocommerce'); } break; } return array('success' => $ran, 'message' => $message); }
/** * Create a new order refund programmatically * * Returns a new refund object on success which can then be used to add additional data. * * @since 2.2 * @param array $args * @return WC_Order_Refund|WP_Error */ function wc_create_refund($args = array()) { $default_args = array('amount' => '', 'reason' => null, 'order_id' => 0, 'refund_id' => 0, 'line_items' => array()); $args = wp_parse_args($args, $default_args); $refund_data = array(); if ($args['refund_id'] > 0) { $updating = true; $refund_data['ID'] = $args['refund_id']; } else { $updating = false; $refund_data['post_type'] = 'shop_order_refund'; $refund_data['post_status'] = 'wc-completed'; $refund_data['ping_status'] = 'closed'; $refund_data['post_author'] = get_current_user_id() ? get_current_user_id() : 1; $refund_data['post_password'] = uniqid('refund_'); $refund_data['post_parent'] = absint($args['order_id']); $refund_data['post_title'] = sprintf(__('Refund – %s', 'woocommerce'), strftime(_x('%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'woocommerce'))); } if (!is_null($args['reason'])) { $refund_data['post_excerpt'] = $args['reason']; } if ($updating) { $refund_id = wp_update_post($refund_data); } else { $refund_id = wp_insert_post(apply_filters('woocommerce_new_refund_data', $refund_data), true); } if (is_wp_error($refund_id)) { return $refund_id; } if (!$updating) { // Default refund meta data update_post_meta($refund_id, '_refund_amount', wc_format_decimal($args['amount'])); // Get refund object $refund = wc_get_order($refund_id); // Negative line items if (sizeof($args['line_items']) > 0) { $order = wc_get_order($args['order_id']); $order_items = $order->get_items(array('line_item', 'fee', 'shipping')); foreach ($args['line_items'] as $refund_item_id => $refund_item) { if (isset($order_items[$refund_item_id])) { if (empty($refund_item['qty']) && empty($refund_item['refund_total']) && empty($refund_item['refund_tax'])) { continue; } // Prevents errors when the order has no taxes if (!isset($refund_item['refund_tax'])) { $refund_item['refund_tax'] = array(); } switch ($order_items[$refund_item_id]['type']) { case 'line_item': $line_item_args = array('totals' => array('subtotal' => wc_format_refund_total($refund_item['refund_total']), 'total' => wc_format_refund_total($refund_item['refund_total']), 'subtotal_tax' => wc_format_refund_total(array_sum($refund_item['refund_tax'])), 'tax' => wc_format_refund_total(array_sum($refund_item['refund_tax'])), 'tax_data' => array('total' => array_map('wc_format_refund_total', $refund_item['refund_tax']), 'subtotal' => array_map('wc_format_refund_total', $refund_item['refund_tax'])))); $new_item_id = $refund->add_product($order->get_product_from_item($order_items[$refund_item_id]), isset($refund_item['qty']) ? $refund_item['qty'] : 0, $line_item_args); wc_add_order_item_meta($new_item_id, '_refunded_item_id', $refund_item_id); break; case 'shipping': $shipping = new stdClass(); $shipping->label = $order_items[$refund_item_id]['name']; $shipping->id = $order_items[$refund_item_id]['method_id']; $shipping->cost = wc_format_refund_total($refund_item['refund_total']); $shipping->taxes = array_map('wc_format_refund_total', $refund_item['refund_tax']); $new_item_id = $refund->add_shipping($shipping); wc_add_order_item_meta($new_item_id, '_refunded_item_id', $refund_item_id); break; case 'fee': $fee = new stdClass(); $fee->name = $order_items[$refund_item_id]['name']; $fee->tax_class = $order_items[$refund_item_id]['tax_class']; $fee->taxable = $fee->tax_class !== '0'; $fee->amount = wc_format_refund_total($refund_item['refund_total']); $fee->tax = wc_format_refund_total(array_sum($refund_item['refund_tax'])); $fee->tax_data = array_map('wc_format_refund_total', $refund_item['refund_tax']); $new_item_id = $refund->add_fee($fee); wc_add_order_item_meta($new_item_id, '_refunded_item_id', $refund_item_id); break; } } } $refund->update_taxes(); } $refund->calculate_totals(false); // Set total to total refunded which may vary from order items $refund->set_total(wc_format_decimal($args['amount']) * -1, 'total'); do_action('woocommerce_refund_created', $refund_id); } // Clear transients wc_delete_shop_order_transients($args['order_id']); return new WC_Order_Refund($refund_id); }
/** * Updates status of order. * * @param string $new_status Status to change the order to. No internal wc- prefix is required. * @param string $note (default: '') Optional note to add. * @param bool $manual is this a manual order status change? * @return bool Successful change or not */ public function update_status($new_status, $note = '', $manual = false) { if (!$this->id) { return false; } // Standardise status names. $new_status = 'wc-' === substr($new_status, 0, 3) ? substr($new_status, 3) : $new_status; $old_status = $this->get_status(); // If the statuses are the same there is no need to update, unless the post status is not a valid 'wc' status. if ($new_status === $old_status && in_array($this->post_status, array_keys(wc_get_order_statuses()))) { return false; } $this->post_status = 'wc-' . $new_status; $update_post_data = array('ID' => $this->id, 'post_status' => $this->post_status); if ('pending' === $old_status && !$manual) { $update_post_data['post_date'] = current_time('mysql', 0); $update_post_data['post_date_gmt'] = current_time('mysql', 1); } wp_update_post($update_post_data); $this->add_order_note(trim($note . ' ' . sprintf(__('Order status changed from %s to %s.', 'woocommerce'), wc_get_order_status_name($old_status), wc_get_order_status_name($new_status))), 0, $manual); // Status was changed. do_action('woocommerce_order_status_' . $new_status, $this->id); do_action('woocommerce_order_status_' . $old_status . '_to_' . $new_status, $this->id); do_action('woocommerce_order_status_changed', $this->id, $old_status, $new_status); switch ($new_status) { case 'completed': // Record the sales. $this->record_product_sales(); // Increase coupon usage counts. $this->increase_coupon_usage_counts(); // Record the completed date of the order. update_post_meta($this->id, '_completed_date', current_time('mysql')); // Update reports. wc_delete_shop_order_transients($this->id); break; case 'processing': case 'on-hold': // Record the sales. $this->record_product_sales(); // Increase coupon usage counts. $this->increase_coupon_usage_counts(); // Update reports. wc_delete_shop_order_transients($this->id); break; case 'cancelled': // If the order is cancelled, restore used coupons. $this->decrease_coupon_usage_counts(); // Update reports. wc_delete_shop_order_transients($this->id); break; } return true; }
/** * Update a single order. * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|WP_REST_Response */ public function update_item($request) { $id = (int) $request['id']; $post = get_post($id); if (empty($id) || empty($post->ID) || $this->post_type !== $post->post_type) { return new WP_Error("woocommerce_rest_{$this->post_type}_invalid_id", __('ID is invalid.', 'woocommerce'), array('status' => 400)); } $order_id = $this->update_order($request, $post); if (is_wp_error($order_id)) { return $order_id; } // Clear transients. wc_delete_shop_order_transients($order_id); $post = get_post($order_id); $this->update_additional_fields_for_object($post, $request); /** * Fires after a single item is created or updated via the REST API. * * @param object $post Inserted object (not a WP_Post object). * @param WP_REST_Request $request Request object. * @param boolean $creating True when creating item, false when updating. */ do_action("woocommerce_rest_insert_{$this->post_type}", $post, $request, false); $request->set_param('context', 'edit'); $response = $this->prepare_item_for_response($post, $request); return rest_ensure_response($response); }
/** * Create a new vendor order programmatically * * Returns a new vendor_order object on success which can then be used to add additional data. * * @since * @param array $args * @return WC_Order_Vendor|WP_Error */ public static function create_vendor_order($args = array()) { $default_args = array('vendor_id' => null, 'order_id' => 0, 'vendor_order_id' => 0, 'line_items' => array(), 'date' => current_time('mysql', 0)); $args = wp_parse_args($args, $default_args); $vendor_order_data = array(); if ($args['vendor_order_id'] > 0) { $updating = true; $vendor_order_data['ID'] = $args['vendor_order_id']; } else { $updating = false; $vendor_order_data['post_type'] = 'shop_order_vendor'; $vendor_order_data['post_status'] = 'wc-completed'; $vendor_order_data['ping_status'] = 'closed'; $vendor_order_data['post_author'] = get_current_user_id(); $vendor_order_data['post_password'] = uniqid('vendor_'); // password = 20 char max! (uniqid = 13) $vendor_order_data['post_parent'] = absint($args['order_id']); $vendor_order_data['post_title'] = sprintf(__('Vendor Order – %s', 'woocommerce'), strftime(_x('%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'woocommerce'))); $vendor_order_data['post_date'] = $args['date']; } if ($updating) { $vendor_order_id = wp_update_post($vendor_order_data); } else { $vendor_order_id = wp_insert_post(apply_filters('woocommerce_new_vendor_order_data', $vendor_order_data), true); } if (is_wp_error($vendor_order_id)) { return $vendor_order_id; } if (!$updating) { // Get vendor order object $vendor_order = wc_get_order($vendor_order_id); $order = wc_get_order($args['order_id']); // Order currency is the same used for the parent order update_post_meta($vendor_order_id, '_order_currency', $order->get_order_currency()); if (sizeof($args['line_items']) > 0) { $order_items = $order->get_items(array('line_item', 'fee', 'shipping')); foreach ($args['line_items'] as $vendor_order_item_id => $vendor_order_item) { if (isset($order_items[$vendor_order_item_id])) { if (empty($vendor_order_item['qty']) && empty($vendor_order_item['total']) && empty($vendor_order_item['tax'])) { continue; } // Prevents errors when the order has no taxes if (!isset($vendor_order_item['tax'])) { $vendor_order_item['tax'] = array(); } switch ($order_items[$vendor_order_item_id]['type']) { case 'line_item': $line_item_args = array('totals' => array('subtotal' => $vendor_order_item['subtotal'], 'total' => $vendor_order_item['total'], 'subtotal_tax' => $vendor_order_item['subtotal_tax'], 'tax' => $vendor_order_item['tax'], 'tax_data' => $vendor_order_item['tax_data'])); $new_item_id = $vendor_order->add_product($order->get_product_from_item($order_items[$vendor_order_item_id]), isset($vendor_order_item['qty']) ? $vendor_order_item['qty'] : 0, $line_item_args); wc_add_order_item_meta($new_item_id, '_vendor_order_item_id', $vendor_order_item_id); wc_add_order_item_meta($new_item_id, '_vendor_commission', $vendor_order_item['commission']); break; case 'shipping': $shipping = new stdClass(); $shipping->label = $order_items[$vendor_order_item_id]['name']; $shipping->id = $order_items[$vendor_order_item_id]['method_id']; $shipping->cost = $vendor_order_item['total']; $shipping->taxes = $vendor_order_item['tax']; $new_item_id = $vendor_order->add_shipping($shipping); wc_add_order_item_meta($new_item_id, '_vendor_order_item_id', $vendor_order_item_id); break; case 'fee': $fee = new stdClass(); $fee->name = $order_items[$vendor_order_item_id]['name']; $fee->tax_class = $order_items[$vendor_order_item_id]['tax_class']; $fee->taxable = $fee->tax_class !== '0'; $fee->amount = $vendor_order_item['total']; $fee->tax = array_sum($vendor_order_item['tax']); $fee->tax_data = $vendor_order_item['tax']; $new_item_id = $vendor_order->add_fee($fee); wc_add_order_item_meta($new_item_id, '_vendor_order_item_id', $vendor_order_item_id); break; } } } $vendor_order->update_taxes(); } $vendor_order->calculate_totals(false); do_action('woocommerce_vendor_order_created', $vendor_order_id, $args); } // Clear transients wc_delete_shop_order_transients($args['order_id']); return new WC_Order_Vendor($vendor_order_id); }
/** * Save data to the database. * @since 2.7.0 * @return int order ID */ public function save() { $this->set_version(WC_VERSION); if (!$this->get_id()) { $this->create(); } else { $this->update(); } $this->save_items(); clean_post_cache($this->get_id()); wc_delete_shop_order_transients($this->get_id()); return $this->get_id(); }
/** * Handles output of tools */ public static function status_tools() { global $wpdb; $tools = self::get_tools(); if (!empty($_GET['action']) && !empty($_REQUEST['_wpnonce']) && wp_verify_nonce($_REQUEST['_wpnonce'], 'debug_action')) { switch ($_GET['action']) { case 'clear_transients': wc_delete_product_transients(); wc_delete_shop_order_transients(); WC_Cache_Helper::get_transient_version('shipping', true); echo '<div class="updated"><p>' . __('Product Transients Cleared', 'woocommerce') . '</p></div>'; break; case 'clear_expired_transients': // http://w-shadow.com/blog/2012/04/17/delete-stale-transients/ $rows = $wpdb->query("\n\t\t\t\t\t\tDELETE\n\t\t\t\t\t\t\ta, b\n\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\t{$wpdb->options} a, {$wpdb->options} b\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\ta.option_name LIKE '_transient_%' AND\n\t\t\t\t\t\t\ta.option_name NOT LIKE '_transient_timeout_%' AND\n\t\t\t\t\t\t\tb.option_name = CONCAT(\n\t\t\t\t\t\t\t\t'_transient_timeout_',\n\t\t\t\t\t\t\t\tSUBSTRING(\n\t\t\t\t\t\t\t\t\ta.option_name,\n\t\t\t\t\t\t\t\t\tCHAR_LENGTH('_transient_') + 1\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tAND b.option_value < UNIX_TIMESTAMP()\n\t\t\t\t\t"); $rows2 = $wpdb->query("\n\t\t\t\t\t\tDELETE\n\t\t\t\t\t\t\ta, b\n\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\t{$wpdb->options} a, {$wpdb->options} b\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\ta.option_name LIKE '_site_transient_%' AND\n\t\t\t\t\t\t\ta.option_name NOT LIKE '_site_transient_timeout_%' AND\n\t\t\t\t\t\t\tb.option_name = CONCAT(\n\t\t\t\t\t\t\t\t'_site_transient_timeout_',\n\t\t\t\t\t\t\t\tSUBSTRING(\n\t\t\t\t\t\t\t\t\ta.option_name,\n\t\t\t\t\t\t\t\t\tCHAR_LENGTH('_site_transient_') + 1\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tAND b.option_value < UNIX_TIMESTAMP()\n\t\t\t\t\t"); echo '<div class="updated"><p>' . sprintf(__('%d Transients Rows Cleared', 'woocommerce'), $rows + $rows2) . '</p></div>'; break; case 'reset_roles': // Remove then re-add caps and roles WC_Install::remove_roles(); WC_Install::create_roles(); echo '<div class="updated"><p>' . __('Roles successfully reset', 'woocommerce') . '</p></div>'; break; case 'recount_terms': $product_cats = get_terms('product_cat', array('hide_empty' => false, 'fields' => 'id=>parent')); _wc_term_recount($product_cats, get_taxonomy('product_cat'), true, false); $product_tags = get_terms('product_tag', array('hide_empty' => false, 'fields' => 'id=>parent')); _wc_term_recount($product_tags, get_taxonomy('product_tag'), true, false); echo '<div class="updated"><p>' . __('Terms successfully recounted', 'woocommerce') . '</p></div>'; break; case 'clear_sessions': $wpdb->query("\n\t\t\t\t\t\tDELETE FROM {$wpdb->options}\n\t\t\t\t\t\tWHERE option_name LIKE '_wc_session_%' OR option_name LIKE '_wc_session_expires_%'\n\t\t\t\t\t"); wp_cache_flush(); echo '<div class="updated"><p>' . __('Sessions successfully cleared', 'woocommerce') . '</p></div>'; break; case 'install_pages': WC_Install::create_pages(); echo '<div class="updated"><p>' . __('All missing WooCommerce pages was installed successfully.', 'woocommerce') . '</p></div>'; break; case 'delete_taxes': $wpdb->query("TRUNCATE " . $wpdb->prefix . "woocommerce_tax_rates"); $wpdb->query("TRUNCATE " . $wpdb->prefix . "woocommerce_tax_rate_locations"); echo '<div class="updated"><p>' . __('Tax rates successfully deleted', 'woocommerce') . '</p></div>'; break; case 'reset_tracking': delete_option('woocommerce_allow_tracking'); WC_Admin_Notices::add_notice('tracking'); echo '<div class="updated"><p>' . __('Usage tracking settings successfully reset.', 'woocommerce') . '</p></div>'; break; default: $action = esc_attr($_GET['action']); if (isset($tools[$action]['callback'])) { $callback = $tools[$action]['callback']; $return = call_user_func($callback); if ($return === false) { if (is_array($callback)) { echo '<div class="error"><p>' . sprintf(__('There was an error calling %s::%s', 'woocommerce'), get_class($callback[0]), $callback[1]) . '</p></div>'; } else { echo '<div class="error"><p>' . sprintf(__('There was an error calling %s', 'woocommerce'), $callback) . '</p></div>'; } } } break; } } // Manual translation update messages if (isset($_GET['translation_updated'])) { switch ($_GET['translation_updated']) { case 2: echo '<div class="error"><p>' . __('Failed to install/update the translation:', 'woocommerce') . ' ' . __('Seems you don\'t have permission to do this!', 'woocommerce') . '</p></div>'; break; case 3: echo '<div class="error"><p>' . __('Failed to install/update the translation:', 'woocommerce') . ' ' . sprintf(__('An authentication error occurred while updating the translation. Please try again or configure your %sUpgrade Constants%s.', 'woocommerce'), '<a href="http://codex.wordpress.org/Editing_wp-config.php#WordPress_Upgrade_Constants">', '</a>') . '</p></div>'; break; case 4: echo '<div class="error"><p>' . __('Failed to install/update the translation:', 'woocommerce') . ' ' . __('Sorry but there is no translation available for your language =/', 'woocommerce') . '</p></div>'; break; default: // Force WordPress find for new updates and hide the WooCommerce translation update set_site_transient('update_plugins', null); echo '<div class="updated"><p>' . __('Translations installed/updated successfully!', 'woocommerce') . '</p></div>'; break; } } // Display message if settings settings have been saved if (isset($_REQUEST['settings-updated'])) { echo '<div class="updated"><p>' . __('Your changes have been saved.', 'woocommerce') . '</p></div>'; } include_once 'views/html-admin-page-status-tools.php'; }
// Delete old user keys from usermeta foreach ($api_users as $_user) { $user_id = intval($_user->user_id); delete_user_meta($user_id, 'woocommerce_api_consumer_key'); delete_user_meta($user_id, 'woocommerce_api_consumer_secret'); delete_user_meta($user_id, 'woocommerce_api_key_permissions'); } } /** * Webhooks * Make sure order.update webhooks get the woocommerce_order_edit_status hook */ $order_update_webhooks = get_posts(array('posts_per_page' => -1, 'post_type' => 'shop_webhook', 'meta_key' => '_topic', 'meta_value' => 'order.updated')); foreach ($order_update_webhooks as $order_update_webhook) { $webhook = new WC_Webhook($order_update_webhook->ID); $webhook->set_topic('order.updated'); } /** * Refunds for full refunded orders. * Update fully refunded orders to ensure they have a refund line item so reports add up. */ $refunded_orders = get_posts(array('posts_per_page' => -1, 'post_type' => 'shop_order', 'post_status' => array('wc-refunded'))); foreach ($refunded_orders as $refunded_order) { $order_total = get_post_meta($refunded_order->ID, '_order_total', true); $refunded_total = $wpdb->get_var($wpdb->prepare("\n\t\tSELECT SUM( postmeta.meta_value )\n\t\tFROM {$wpdb->postmeta} AS postmeta\n\t\tINNER JOIN {$wpdb->posts} AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d )\n\t\tWHERE postmeta.meta_key = '_refund_amount'\n\t\tAND postmeta.post_id = posts.ID\n\t", $refunded_order->ID)); if ($order_total > $refunded_total) { $refund = wc_create_refund(array('amount' => $order_total - $refunded_total, 'reason' => __('Order Fully Refunded', 'woocommerce'), 'order_id' => $refunded_order->ID, 'line_items' => array(), 'date' => $refunded_order->post_modified)); } } wc_delete_shop_order_transients();
public function check_awaiting_payment($posted) { // Insert or update the post data $order_id = absint(WC()->session->order_awaiting_payment); // Resume the unpaid order if its pending if ($order_id > 0 && ($order = wc_get_order($order_id)) && $order->has_status(array('pending', 'failed'))) { $suborder_ids = $this->get_suborder($order_id); YITH_Commissions()->bulk_action($suborder_ids, 'delete'); foreach ($suborder_ids as $suborder_id) { wc_delete_shop_order_transients($suborder_id); wp_delete_post($suborder_id, true); } } }