Exemplo n.º 1
0
 /**
  * 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);
 }
Exemplo n.º 5
0
 /**
  * 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;
 }
Exemplo n.º 6
0
/**
 * 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);
}
Exemplo n.º 7
0
 /**
  * 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);
 }
Exemplo n.º 8
0
 /**
  * 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);
 }
Exemplo n.º 13
0
 /**
  * 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()));
     }
 }
Exemplo n.º 14
0
 /**
  * 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', '');
                 }
             }
         }
     }
 }
Exemplo n.º 15
0
 /**
  * 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';
 }
Exemplo n.º 16
0
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();
}
Exemplo n.º 17
0
 /**
  * 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());
     }
 }
Exemplo n.º 18
0
 /**
  * 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()));
     }
 }
Exemplo n.º 19
0
 /**
  * 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);
             }
         }
     }
 }
Exemplo n.º 20
0
 /**
  * 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);
 }
Exemplo n.º 23
0
/**
 * 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 &ndash; %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);
}
Exemplo n.º 24
0
 /**
  * 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);
 }
Exemplo n.º 26
0
 /**
  * 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 &ndash; %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);
 }
Exemplo n.º 27
0
 /**
  * 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();
Exemplo n.º 30
0
 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);
         }
     }
 }