diff --git a/woocommerce-advanced-ordernumbers.php b/woocommerce-advanced-ordernumbers.php index 37d42f8254d09fafaee08df29e9d8333b09707f2..11cebcc3e8a4d081f1ecd33122133f8653f40f77 100644 --- a/woocommerce-advanced-ordernumbers.php +++ b/woocommerce-advanced-ordernumbers.php @@ -33,6 +33,8 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g if (!class_exists("OpenToolsOrdernumbers")) { class OpenToolsOrdernumbers { public $ordernumber_meta = "_order_number"; + public $ordernumber_new_placeholder = "[New Order]"; + public $ordernumber_counter_prefix = 'ordernumber-counter-'; /** * Construct the plugin object @@ -120,9 +122,10 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g // Sort the order list in the backend by order number rather than ID, make sure this is called LAST so we modify the defaults passed as arguments add_filter( 'manage_edit-shop_order_sortable_columns', array( $this, 'modify_order_column_sortkey' ), 9999 ); - - // register filters - add_filter("plugin_action_links_$plugin", array(&$this, 'plugin_settings_link')); + // When a new order is created, we immediately assign the order number: + add_action( 'wp_insert_post', array(&$this, 'check_create_ordernumber'), 10, 3); + add_action( 'save_post', array(&$this, 'check_create_ordernumber'), 10, 3); + // The filter to actually return the order number for the given order add_filter ('woocommerce_order_number', array(&$this, 'get_ordernumber'), 10, 2/*<= Also get the order object! */); } @@ -182,17 +185,35 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g // Use the passed columns as "default", so effectively, only the order_title will be changed: return wp_parse_args ($custom, $columns); } + + /** + * Handle new posts created in the frontend. This action will be called for all posts, + * not only for orders, so we need to check explicitly. Also, this function will be called + * for order updates, so we need to check the update argument, too. + */ + public function check_create_ordernumber($post_id, $post, $update) { + // Is the post really an order? + // Order numbers are only assigned to orders on creation, not when updating! + if ($post->post_type != 'shop_order') { + return; + } else { + // Handle new admin-created orders, where the address is entered later on! + // Assign an order number: + $number = $this->assign_new_ordernumber($post_id, $post, $update); + } + + } /** * Counter handling (simple loading/storing counters), storing them as options */ function _getCounter($type, $format, $start=1) { - $count = get_option ('ordernumber-counter-'.$type.'-'.$format, $start); + $count = get_option ($this->ordernumber_counter_prefix.$type.'-'.$format, $start); return $count; } // Insert new counter value into the db or update existing one function _setCounter($type, $format, $value) { - return update_option('ordernumber-counter-'.$type.'-'.$format, $value); + return update_option($this->ordernumber_counter_prefix.$type.'-'.$format, $value); } @@ -247,36 +268,36 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g "[minute]" => date("i"), "[second]" => date("s"), "[orderid]" => $order->id, - "[userid]" => $order->get_user_id(), ); + $reps["[userid]"] = $order->get_user_id(); $reps["[ipaddress]"] = $order->customer_ip_address; $reps["[orderstatus]"] = $order->get_status(); $reps["[email]"] = $order->billing_email; $reps["[firstname]"] = $order->billing_first_name; - $reps["[lastname]"] = $order->billing_last_name; + $reps["[lastname]"] = $order->billing_last_name; - $reps["[company]"] = $order->billing_company; - $reps["[zip]"] = $order->billing_postcode; - $reps["[postcode]"] = $order->billing_postcode; - $reps["[city]"] = $order->billing_city; + $reps["[company]"] = $order->billing_company; + $reps["[zip]"] = $order->billing_postcode; + $reps["[postcode]"] = $order->billing_postcode; + $reps["[city]"] = $order->billing_city; $country = $order->billing_country; $state = $order->billing_state; $allcountries = WC()->countries->get_countries(); $states = WC()->countries->get_states($country); - $reps["[country]"] = $country; + $reps["[country]"] = $country; $reps["[countryname]"] = ( isset( $allcountries[ $country ] ) ) ? $allcountries[ $country ] : $country; - $reps["[state]"] = $state; - $reps["[statename]"] = ( $country && $state && isset( $states[ $country ][ $state ] ) ) ? $states[ $country ][ $state ] : $state; + $reps["[state]"] = $state; + $reps["[statename]"] = ( $country && $state && isset( $states[ $country ][ $state ] ) ) ? $states[ $country ][ $state ] : $state; - $reps["[articles]"] = $order->get_item_count(); - $reps["[currency]"] = $order->get_order_currency(); - $reps["[downloadpermitted]"] = $order->is_download_permitted(); - $reps["[hasdownloads]"] = $order->has_downloadable_item(); + $reps["[articles]"] = $order->get_item_count(); + $reps["[currency]"] = $order->get_order_currency(); +// $reps["[downloadpermitted]"] = $order->is_download_permitted(); +// $reps["[hasdownloads]"] = $order->has_downloadable_item(); // $reps["[coupons]"] = $order->get_used_coupons(); if ($type != 'ordernumber') { @@ -288,6 +309,7 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g // $reps["[user]"] = print_r($user,1); // if (isset($order->username)) $reps["[username]"] = $order->username; } + // Allow customization via plugins: filter function($reps, $order, $type, $fmt) $reps = apply_filters( 'opentools_ordernumber_replacements', $reps, $order, $type, $fmt); return str_ireplace (array_keys($reps), array_values($reps), $fmt); @@ -321,21 +343,41 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g return $orderid; } } - + + /** + * The hook to assign a customized order number (unless the order already has one assigned) + */ + function assign_new_ordernumber($orderid, $order, $update=true) { + if ((!$update) && ($order->post_status == 'auto-draft')) { + // New order => assign placeholder, which will later be overwritten the real order number + update_post_meta( $orderid, $this->ordernumber_meta, $this->ordernumber_new_placeholder ); + } + // If we do not have an order (yet), we cannot proceed. But we probably have created the + // ordernumber placeholder for that post, so this function has done its job and we can return + if (!$order instanceof WC_Order) { + return; + } + $number = get_post_meta( $orderid, $this->ordernumber_meta, 'true'); + if ($number == $this->ordernumber_new_placeholder && $order->post_status != 'auto-draft') { + $number = $this->create_ordernumber($orderid, $order, 'ordernumber'); + // Assign a new number + } + return $number; + } + /** * The hook to customize order numbers (requests the order number from the database; creates a new ordernumber if no entry exists in the database) */ function get_ordernumber($orderid, $order) { $stored_number = get_post_meta( $orderid, $this->ordernumber_meta, 'true'); - if (!empty($stored_number)) { + if ($stored_number == $this->ordernumber_new_placeholder) { + // Check whether the order was now really created => create order number now + return $this->assign_new_ordernumber($orderid, $order); + } elseif (!empty($stored_number)) { + // Order number already exists => simply return it return $stored_number; - } elseif (get_option('customize_ordernumber', 'false')) { - // create a new one (if this is a new order, otherwise we don't have/generate a number!) - // TODO: Check whether this is a new number! Otherwise, do NOT create an order number - $number = $this->create_ordernumber($orderid, $order, 'ordernumber'); - return $number; } else { - print("<h1>Order number creation is DISABLED</h1>"); + // No order number was created for this order, so simply use the orderid as default. return $orderid; } }