WooCommerce Sequential Order Numbers - Version 1.0.0

Version Description

  • Initial Release
Download this release

Release Info

Developer FoxRunSoftware
Plugin Icon WooCommerce Sequential Order Numbers
Version 1.0.0
Comparing to
See all releases

Version 1.0.0

readme.txt ADDED
@@ -0,0 +1,30 @@
1
+ === WooCommerce Sequential Order Numbers ===
2
+ Contributors: FoxRunSoftware
3
+ Tags: woocommerce, order number
4
+ Requires at least: 3.3
5
+ Tested up to: 3.3
6
+ Stable tag: 1.0.0
7
+
8
+ This plugin extends the WooCommerce e-commerce plugin by setting sequential order numbers for new orders.
9
+
10
+ == Description ==
11
+
12
+ This plugin extends the WooCommerce e-commerce plugin by setting sequential order numbers for new orders. If there are existing orders at the time of installation, the sequential order numbers will start with the highest current order number.
13
+
14
+ = Feedback =
15
+ * I am open to your suggestions and feedback - Thank you for using or trying out one of my plugins!
16
+ * Drop me a line at [www.foxrunsoftware.com](http://www.foxrunsoftware.com)
17
+
18
+ = More =
19
+ * Vist the [WooCommerce Sequential Order Number plugin page](http://www.foxrunsoftware.net/articles/wordpress/woocommerce-sequential-order-numbers/) for further details and a discussion of the implementation. [Also see my other plugins](http://www.foxrunsoftware.com) or see [my WordPress.org profile page](http://profiles.wordpress.org/foxrunsoftware/)
20
+
21
+ == Installation ==
22
+
23
+ 1. Upload the entire 'woocommerce-seq-order-number' folder to the '/wp-content/plugins/' directory
24
+ 2. Activate the plugin through the 'Plugins' menu in WordPress
25
+ 3. Order numbers will continue sequentially from the current highest order number, or from 1 if no orders have been placed yet
26
+
27
+ == Changelog ==
28
+
29
+ = 1.0.0 =
30
+ * Initial Release
woo-includes/class-wc-dependencies.php ADDED
@@ -0,0 +1,30 @@
1
+ <?php
2
+ /**
3
+ * WC Dependency Checker
4
+ *
5
+ * Checks if WooCommerce is enabled
6
+ */
7
+ class WC_Dependencies {
8
+
9
+ private static $active_plugins;
10
+
11
+ function init() {
12
+
13
+ self::$active_plugins = (array) get_option( 'active_plugins', array() );
14
+
15
+ if ( is_multisite() )
16
+ self::$active_plugins = array_merge( self::$active_plugins, get_site_option( 'active_sitewide_plugins', array() ) );
17
+
18
+ }
19
+
20
+ function woocommerce_active_check() {
21
+
22
+ if ( ! self::$active_plugins ) self::init();
23
+
24
+ return in_array('woocommerce/woocommerce.php', self::$active_plugins) || array_key_exists('woocommerce/woocommerce.php', self::$active_plugins);
25
+
26
+ }
27
+
28
+ }
29
+
30
+
woo-includes/woo-functions.php ADDED
@@ -0,0 +1,15 @@
1
+ <?php
2
+ /**
3
+ * Functions used by plugins
4
+ */
5
+
6
+ if ( ! class_exists( 'WC_Dependencies' ) ) require_once( 'class-wc-dependencies.php' );
7
+
8
+ /**
9
+ * WC Detection
10
+ **/
11
+ function is_woocommerce_active() {
12
+
13
+ return WC_Dependencies::woocommerce_active_check();
14
+
15
+ }
woocommerce-sequential-order-numbers.php ADDED
@@ -0,0 +1,525 @@
1
+ <?php
2
+ /*
3
+ Plugin Name: WooCommerce Sequential Order Numbers
4
+ Plugin URI: http://www.foxrunsoftware.net/articles/wordpress/woocommerce-sequential-order-numbers/
5
+ Description: Provides sequential order numbers for WooCommerce orders
6
+ Author: Justin Stern
7
+ Author URI: http://www.foxrunsoftware.net
8
+ Version: 1.0.0
9
+
10
+ Copyright: © 2012 Justin Stern (email : justin@foxrunsoftware.net)
11
+ License: GNU General Public License v3.0
12
+ License URI: http://www.gnu.org/licenses/gpl-3.0.html
13
+ */
14
+
15
+ /**
16
+ * Required functions
17
+ **/
18
+ if ( ! function_exists( 'is_woocommerce_active' ) ) require_once( 'woo-includes/woo-functions.php' );
19
+
20
+
21
+ if (is_woocommerce_active()) {
22
+ if (!class_exists('WC_Seq_Order_Number')) {
23
+
24
+ class WC_Seq_Order_Number {
25
+ const VERSION = "1.0.0";
26
+ const VERSION_OPTION_NAME = "woocommerce_seq_order_number_db_version";
27
+
28
+ public function __construct() {
29
+
30
+ // actions/filters
31
+ add_action('woocommerce_init', array(&$this, 'woocommerce_loaded' ));
32
+ add_action('wp_insert_post', array(&$this, 'set_sequential_order_number'), 10, 2);
33
+ add_filter('woocommerce_order_number', array(&$this, 'get_order_number'), 10, 2);
34
+
35
+ // Installation
36
+ if (is_admin() && !defined('DOING_AJAX')) $this->install();
37
+ }
38
+
39
+
40
+ /**
41
+ * Called after WooCommerce is initialized, so put anything in here that
42
+ * needs to be run after WooCommerce has had a chance to initialize.
43
+ */
44
+ function woocommerce_loaded() {
45
+ global $woocommerce;
46
+
47
+ if (is_admin()) {
48
+ // Override a bunch of admin functionality to support the sequential order numbers on the backend, unfortunately...
49
+ remove_action('manage_shop_order_posts_custom_column', 'woocommerce_custom_order_columns', 2);
50
+ add_action('manage_shop_order_posts_custom_column', array(&$this,'woocommerce_custom_order_columns'), 2);
51
+
52
+ remove_filter( 'request', 'woocommerce_custom_shop_order_orderby' );
53
+ add_filter( 'request', array(&$this, 'woocommerce_custom_shop_order_orderby' ));
54
+
55
+ add_action( 'add_meta_boxes', array(&$this, 'woocommerce_meta_boxes'), 20 );
56
+ }
57
+ }
58
+
59
+
60
+ /**
61
+ * Largely unchanged from the WooCommerce original, just one point
62
+ * change identified below
63
+ */
64
+ function woocommerce_custom_order_columns($column) {
65
+
66
+ global $post, $woocommerce;
67
+ $order = new WC_Order( $post->ID );
68
+
69
+ switch ($column) {
70
+ case "order_status" :
71
+
72
+ echo sprintf( '<mark class="%s">%s</mark>', sanitize_title($order->status), __($order->status, 'woocommerce') );
73
+
74
+ break;
75
+ case "order_title" :
76
+
77
+ if ($order->user_id) $user_info = get_userdata($order->user_id);
78
+
79
+ if (isset($user_info) && $user_info) :
80
+
81
+ $user = '<a href="user-edit.php?user_id=' . esc_attr( $user_info->ID ) . '">';
82
+
83
+ if ($user_info->first_name || $user_info->last_name) $user .= $user_info->first_name.' '.$user_info->last_name;
84
+ else $user .= esc_html( $user_info->display_name );
85
+
86
+ $user .= '</a>';
87
+
88
+ else :
89
+ $user = __('Guest', 'woocommerce');
90
+ endif;
91
+
92
+ // JES - changed $post->ID to $order->get_order_number()
93
+ echo '<a href="'.admin_url('post.php?post='.$post->ID.'&action=edit').'"><strong>'.sprintf( __('Order %s', 'woocommerce'), $order->get_order_number() ).'</strong></a> ' . __('made by', 'woocommerce') . ' ' . $user;
94
+
95
+ if ($order->billing_email) :
96
+ echo '<small class="meta">'.__('Email:', 'woocommerce') . ' ' . '<a href="' . esc_url( 'mailto:'.$order->billing_email ).'">'.esc_html( $order->billing_email ).'</a></small>';
97
+ endif;
98
+ if ($order->billing_phone) :
99
+ echo '<small class="meta">'.__('Tel:', 'woocommerce') . ' ' . esc_html( $order->billing_phone ) . '</small>';
100
+ endif;
101
+
102
+ break;
103
+ case "billing_address" :
104
+ if ($order->get_formatted_billing_address()) :
105
+
106
+ echo '<a target="_blank" href="' . esc_url( 'http://maps.google.com/maps?&q='.urlencode( $order->get_billing_address() ).'&z=16' ) . '">'. preg_replace('#<br\s*/?>#i', ', ', $order->get_formatted_billing_address()) .'</a>';
107
+ else :
108
+ echo '&ndash;';
109
+ endif;
110
+
111
+ if ($order->payment_method_title) :
112
+ echo '<small class="meta">' . __('Via', 'woocommerce') . ' ' . esc_html( $order->payment_method_title ) . '</small>';
113
+ endif;
114
+
115
+ break;
116
+ case "shipping_address" :
117
+ if ($order->get_formatted_shipping_address()) :
118
+
119
+ echo '<a target="_blank" href="' . esc_url( 'http://maps.google.com/maps?&q='.urlencode( $order->get_shipping_address() ).'&z=16' ) .'">'. preg_replace('#<br\s*/?>#i', ', ', $order->get_formatted_shipping_address()) .'</a>';
120
+ else :
121
+ echo '&ndash;';
122
+ endif;
123
+
124
+ if ($order->shipping_method_title) :
125
+ echo '<small class="meta">' . __('Via', 'woocommerce') . ' ' . esc_html( $order->shipping_method_title ) . '</small>';
126
+ endif;
127
+ break;
128
+ case "total_cost" :
129
+ echo woocommerce_price($order->order_total);
130
+ break;
131
+ case "order_date" :
132
+
133
+ if ( '0000-00-00 00:00:00' == $post->post_date ) :
134
+ $t_time = $h_time = __( 'Unpublished', 'woocommerce' );
135
+ else :
136
+ $t_time = get_the_time( __( 'Y/m/d g:i:s A', 'woocommerce' ), $post );
137
+
138
+ $gmt_time = strtotime($post->post_date_gmt);
139
+ $time_diff = current_time('timestamp', 1) - $gmt_time;
140
+
141
+ if ( $time_diff > 0 && $time_diff < 24*60*60 )
142
+ $h_time = sprintf( __( '%s ago', 'woocommerce' ), human_time_diff( $gmt_time, current_time('timestamp', 1) ) );
143
+ else
144
+ $h_time = get_the_time( __( 'Y/m/d', 'woocommerce' ), $post );
145
+ endif;
146
+
147
+ echo '<abbr title="' . $t_time . '">' . apply_filters( 'post_date_column_time', $h_time, $post ) . '</abbr>';
148
+
149
+ break;
150
+ case "order_actions" :
151
+
152
+ ?><p>
153
+ <?php if (in_array($order->status, array('pending', 'on-hold'))) : ?><a class="button" href="<?php echo wp_nonce_url( admin_url('admin-ajax.php?action=woocommerce-mark-order-processing&order_id=' . $post->ID), 'woocommerce-mark-order-processing' ); ?>"><?php _e('Processing', 'woocommerce'); ?></a><?php endif; ?>
154
+ <?php if (in_array($order->status, array('pending', 'on-hold', 'processing'))) : ?><a class="button" href="<?php echo wp_nonce_url( admin_url('admin-ajax.php?action=woocommerce-mark-order-complete&order_id=' . $post->ID), 'woocommerce-mark-order-complete' ); ?>"><?php _e('Complete', 'woocommerce'); ?></a><?php endif; ?>
155
+ <a class="button" href="<?php echo admin_url('post.php?post='.$post->ID.'&action=edit'); ?>"><?php _e('View', 'woocommerce'); ?></a>
156
+ </p><?php
157
+
158
+ break;
159
+ case "note" :
160
+
161
+ if ($order->customer_note)
162
+ echo '<img src="'.$woocommerce->plugin_url().'/assets/images/note.png" alt="yes" class="tips" data-tip="'. __('Yes', 'woocommerce') .'" />';
163
+ else
164
+ echo '<img src="'.$woocommerce->plugin_url().'/assets/images/note-off.png" alt="no" class="tips" data-tip="'. __('No', 'woocommerce') .'" />';
165
+
166
+ break;
167
+ case "order_comments" :
168
+
169
+ echo '<div class="post-com-count-wrapper">
170
+ <a href="'. admin_url('post.php?post='.$post->ID.'&action=edit') .'" class="post-com-count"><span class="comment-count">'. $post->comment_count .'</span></a>
171
+ </div>';
172
+ break;
173
+ }
174
+ }
175
+
176
+
177
+ /**
178
+ * Largely unchanged from the WooCommerce original, just changed orderby
179
+ * ID to operate on the meta _order_number
180
+ */
181
+ function woocommerce_custom_shop_order_orderby( $vars ) {
182
+ global $typenow, $wp_query;
183
+ if ($typenow!='shop_order') return $vars;
184
+
185
+ // Sorting
186
+ if (isset( $vars['orderby'] )) :
187
+ if ( 'order_total' == $vars['orderby'] ) :
188
+ $vars = array_merge( $vars, array(
189
+ 'meta_key' => '_order_total',
190
+ 'orderby' => 'meta_value_num'
191
+ ) );
192
+ elseif ( 'ID' == $vars['orderby'] ) : // JES - added this
193
+ $vars = array_merge( $vars, array(
194
+ 'meta_key' => '_order_number',
195
+ 'orderby' => 'meta_value_num'
196
+ ) );
197
+ endif;
198
+
199
+ endif;
200
+
201
+ return $vars;
202
+ }
203
+
204
+
205
+ /**
206
+ * Remove the WooCommerce order data meta box and add our own
207
+ */
208
+ function woocommerce_meta_boxes() {
209
+ remove_meta_box( 'woocommerce-order-data', 'shop_order', 'normal' );
210
+ add_meta_box( 'woocommerce-order-data', __('Order Data', 'woocommerce'), array(&$this,'woocommerce_order_data_meta_box'), 'shop_order', 'normal', 'high' );
211
+ }
212
+
213
+
214
+ /**
215
+ * Largely unchanged from the WooCommerce original, just one point
216
+ * change identified below
217
+ */
218
+ function woocommerce_order_data_meta_box($post) {
219
+
220
+ global $post, $wpdb, $thepostid, $order_status, $woocommerce;
221
+
222
+ $thepostid = $post->ID;
223
+
224
+ $order = new WC_Order( $thepostid );
225
+
226
+ wp_nonce_field( 'woocommerce_save_data', 'woocommerce_meta_nonce' );
227
+
228
+ // Custom user
229
+ $customer_user = (int) get_post_meta($post->ID, '_customer_user', true);
230
+
231
+ // Order status
232
+ $order_status = wp_get_post_terms($post->ID, 'shop_order_status');
233
+ if ($order_status) :
234
+ $order_status = current($order_status);
235
+ $order_status = $order_status->slug;
236
+ else :
237
+ $order_status = 'pending';
238
+ endif;
239
+
240
+ if (!isset($post->post_title) || empty($post->post_title)) :
241
+ $order_title = 'Order';
242
+ else :
243
+ $order_title = $post->post_title;
244
+ endif;
245
+ ?>
246
+ <style type="text/css">
247
+ #titlediv, #major-publishing-actions, #minor-publishing-actions, #visibility, #submitdiv { display:none }
248
+ </style>
249
+ <div class="panel-wrap woocommerce">
250
+ <input name="post_title" type="hidden" value="<?php echo esc_attr( $order_title ); ?>" />
251
+ <input name="post_status" type="hidden" value="publish" />
252
+ <div id="order_data" class="panel">
253
+
254
+ <div class="order_data_left">
255
+
256
+ <h2><?php _e('Order Details', 'woocommerce'); ?> &mdash; <?php echo $order->get_order_number(); /* JES: changed $thepostid to $order->get_order_number() */ ?></h2>
257
+
258
+ <p class="form-field"><label for="order_status"><?php _e('Order status:', 'woocommerce') ?></label>
259
+ <select id="order_status" name="order_status" class="chosen_select">
260
+ <?php
261
+ $statuses = (array) get_terms('shop_order_status', array('hide_empty' => 0, 'orderby' => 'id'));
262
+ foreach ($statuses as $status) :
263
+ echo '<option value="'.$status->slug.'" ';
264
+ if ($status->slug==$order_status) echo 'selected="selected"';
265
+ echo '>'.__($status->name, 'woocommerce').'</option>';
266
+ endforeach;
267
+ ?>
268
+ </select></p>
269
+
270
+ <p class="form-field last"><label for="order_date"><?php _e('Order Date:', 'woocommerce') ?></label>
271
+ <input type="text" class="date-picker-field" name="order_date" id="order_date" maxlength="10" value="<?php echo date('Y-m-d', strtotime( $post->post_date ) ); ?>" /> @ <input type="text" class="hour" placeholder="<?php _e('h', 'woocommerce') ?>" name="order_date_hour" id="order_date_hour" maxlength="2" size="2" value="<?php echo date('H', strtotime( $post->post_date ) ); ?>" />:<input type="text" class="minute" placeholder="<?php _e('m', 'woocommerce') ?>" name="order_date_minute" id="order_date_minute" maxlength="2" size="2" value="<?php echo date('i', strtotime( $post->post_date ) ); ?>" />
272
+ </p>
273
+
274
+ <p class="form-field form-field-wide"><label for="customer_user"><?php _e('Customer:', 'woocommerce') ?></label>
275
+ <select id="customer_user" name="customer_user" class="chosen_select">
276
+ <option value=""><?php _e('Guest', 'woocommerce') ?></option>
277
+ <?php
278
+ $users = new WP_User_Query( array( 'orderby' => 'display_name' ) );
279
+ $users = $users->get_results();
280
+ if ($users) foreach ( $users as $user ) :
281
+ echo '<option value="'.$user->ID.'" '; selected($customer_user, $user->ID); echo '>' . $user->display_name . ' ('.$user->user_email.')</option>';
282
+ endforeach;
283
+ ?>
284
+ </select></p>
285
+
286
+ <p class="form-field form-field-wide"><label for="excerpt"><?php _e('Customer Note:', 'woocommerce') ?></label>
287
+ <textarea rows="1" cols="40" name="excerpt" tabindex="6" id="excerpt" placeholder="<?php _e('Customer\'s notes about the order', 'woocommerce'); ?>"><?php echo $post->post_excerpt; ?></textarea></p>
288
+
289
+ </div>
290
+ <div class="order_data_right">
291
+ <div class="order_data">
292
+ <h2><?php _e('Billing Details', 'woocommerce'); ?> <a class="edit_address" href="#">(<?php _e('Edit', 'woocommerce') ;?>)</a></h2>
293
+ <?php
294
+ $billing_data = apply_filters('woocommerce_admin_billing_fields', array(
295
+ 'first_name' => array(
296
+ 'label' => __('First Name', 'woocommerce'),
297
+ 'show' => false
298
+ ),
299
+ 'last_name' => array(
300
+ 'label' => __('Last Name', 'woocommerce'),
301
+ 'show' => false
302
+ ),
303
+ 'company' => array(
304
+ 'label' => __('Company', 'woocommerce'),
305
+ 'show' => false
306
+ ),
307
+ 'address_1' => array(
308
+ 'label' => __('Address 1', 'woocommerce'),
309
+ 'show' => false
310
+ ),
311
+ 'address_2' => array(
312
+ 'label' => __('Address 2', 'woocommerce'),
313
+ 'show' => false
314
+ ),
315
+ 'city' => array(
316
+ 'label' => __('City', 'woocommerce'),
317
+ 'show' => false
318
+ ),
319
+ 'postcode' => array(
320
+ 'label' => __('Postcode', 'woocommerce'),
321
+ 'show' => false
322
+ ),
323
+ 'country' => array(
324
+ 'label' => __('Country', 'woocommerce'),
325
+ 'show' => false,
326
+ 'type' => 'select',
327
+ 'options' => $woocommerce->countries->get_allowed_countries()
328
+ ),
329
+ 'state' => array(
330
+ 'label' => __('State/County', 'woocommerce'),
331
+ 'show' => false
332
+ ),
333
+ 'email' => array(
334
+ 'label' => __('Email', 'woocommerce'),
335
+ ),
336
+ 'phone' => array(
337
+ 'label' => __('Phone', 'woocommerce'),
338
+ ),
339
+ ));
340
+
341
+ // Display values
342
+ echo '<div class="address">';
343
+
344
+ if ($order->get_formatted_billing_address()) echo '<p><strong>'.__('Address', 'woocommerce').':</strong><br/> ' .$order->get_formatted_billing_address().'</p>'; else echo '<p class="none_set"><strong>'.__('Address', 'woocommerce').':</strong> ' . __('No billing address set.', 'woocommerce') . '</p>';
345
+
346
+ foreach ( $billing_data as $key => $field ) : if (isset($field['show']) && !$field['show']) continue;
347
+ $field_name = 'billing_'.$key;
348
+ if ( $order->$field_name ) echo '<p><strong>'.$field['label'].':</strong> '.$order->$field_name.'</p>';
349
+ endforeach;
350
+
351
+ echo '</div>';
352
+
353
+ // Display form
354
+ echo '<div class="edit_address"><p><button class="button load_customer_billing">'.__('Load customer billing address', 'woocommerce').'</button></p>';
355
+
356
+ foreach ( $billing_data as $key => $field ) :
357
+ if (!isset($field['type'])) $field['type'] = 'text';
358
+ switch ($field['type']) {
359
+ case "select" :
360
+ woocommerce_wp_select( array( 'id' => '_billing_' . $key, 'label' => $field['label'], 'options' => $field['options'] ) );
361
+ break;
362
+ default :
363
+ woocommerce_wp_text_input( array( 'id' => '_billing_' . $key, 'label' => $field['label'] ) );
364
+ break;
365
+ }
366
+ endforeach;
367
+
368
+ echo '</div>';
369
+ ?>
370
+ </div>
371
+ <div class="order_data order_data_alt">
372
+
373
+ <h2><?php _e('Shipping Details', 'woocommerce'); ?> <a class="edit_address" href="#">(<?php _e('Edit', 'woocommerce') ;?>)</a></h2>
374
+ <?php
375
+ $shipping_data = apply_filters('woocommerce_admin_shipping_fields', array(
376
+ 'first_name' => array(
377
+ 'label' => __('First Name', 'woocommerce'),
378
+ 'show' => false
379
+ ),
380
+ 'last_name' => array(
381
+ 'label' => __('Last Name', 'woocommerce'),
382
+ 'show' => false
383
+ ),
384
+ 'company' => array(
385
+ 'label' => __('Company', 'woocommerce'),
386
+ 'show' => false
387
+ ),
388
+ 'address_1' => array(
389
+ 'label' => __('Address 1', 'woocommerce'),
390
+ 'show' => false
391
+ ),
392
+ 'address_2' => array(
393
+ 'label' => __('Address 2', 'woocommerce'),
394
+ 'show' => false
395
+ ),
396
+ 'city' => array(
397
+ 'label' => __('City', 'woocommerce'),
398
+ 'show' => false
399
+ ),
400
+ 'postcode' => array(
401
+ 'label' => __('Postcode', 'woocommerce'),
402
+ 'show' => false
403
+ ),
404
+ 'country' => array(
405
+ 'label' => __('Country', 'woocommerce'),
406
+ 'show' => false,
407
+ 'type' => 'select',
408
+ 'options' => $woocommerce->countries->get_allowed_countries()
409
+ ),
410
+ 'state' => array(
411
+ 'label' => __('State/County', 'woocommerce'),
412
+ 'show' => false
413
+ ),
414
+ ));
415
+
416
+ // Display values
417
+ echo '<div class="address">';
418
+
419
+ if ($order->get_formatted_shipping_address()) echo '<p><strong>'.__('Address', 'woocommerce').':</strong><br/> ' .$order->get_formatted_shipping_address().'</p>'; else echo '<p class="none_set"><strong>'.__('Address', 'woocommerce').':</strong> ' . __('No shipping address set.', 'woocommerce') . '</p>';
420
+
421
+ foreach ( $shipping_data as $key => $field ) : if (isset($field['show']) && !$field['show']) continue;
422
+ $field_name = 'shipping_'.$key;
423
+ if ( $order->$field_name ) echo '<p><strong>'.$field['label'].':</strong> '.$order->$field_name.'</p>';
424
+ endforeach;
425
+
426
+ echo '</div>';
427
+
428
+ // Display form
429
+ echo '<div class="edit_address"><p><button class="button load_customer_shipping">'.__('Load customer shipping address', 'woocommerce').'</button></p>';
430
+
431
+ foreach ( $shipping_data as $key => $field ) :
432
+ if (!isset($field['type'])) $field['type'] = 'text';
433
+ switch ($field['type']) {
434
+ case "select" :
435
+ woocommerce_wp_select( array( 'id' => '_shipping_' . $key, 'label' => $field['label'], 'options' => $field['options'] ) );
436
+ break;
437
+ default :
438
+ woocommerce_wp_text_input( array( 'id' => '_shipping_' . $key, 'label' => $field['label'] ) );
439
+ break;
440
+ }
441
+ endforeach;
442
+
443
+ echo '</div>';
444
+
445
+ do_action('woocommerce_admin_order_data_after_shipping_address');
446
+ ?>
447
+ </div>
448
+ </div>
449
+ <div class="clear"></div>
450
+
451
+ </div>
452
+ </div>
453
+ <?php
454
+ }
455
+
456
+
457
+ /**
458
+ * Set the _order_number field for the newly created order
459
+ */
460
+ function set_sequential_order_number( $post_id, $post ) {
461
+ global $wpdb;
462
+
463
+ if ($post->post_type == 'shop_order' ) {
464
+ $order_number = get_post_meta($post_id, '_order_number', true);
465
+ if($order_number == "") {
466
+
467
+ // attempt the query up to 3 times for a much higher success rate if it fails (due to Deadlock)
468
+ $success = false;
469
+ for($i = 0; $i < 3; $i++) {
470
+ // this seems to me like the safest way to avoid order number clashes
471
+ $success = $wpdb->query($wpdb->prepare('INSERT INTO '.$wpdb->postmeta.' (post_id,meta_key,meta_value) SELECT '.$post_id.',"_order_number",if(max(cast(meta_value as UNSIGNED)) is null,1,max(cast(meta_value as UNSIGNED))+1) from '.$wpdb->postmeta.' where meta_key="_order_number"'));
472
+ }
473
+ }
474
+ }
475
+ }
476
+
477
+
478
+ /**
479
+ * Filter to return our _order_number field rather than the post ID
480
+ */
481
+ function get_order_number($order_number, $order) {
482
+ if(isset($order->order_custom_fields['_order_number'])) {
483
+ return '#'.$order->order_custom_fields['_order_number'][0];
484
+ }
485
+ return $order_number;
486
+ }
487
+
488
+
489
+ /**
490
+ * Run every time. Used since the activation hook is not executed when updating a plugin
491
+ */
492
+ private function install() {
493
+ $installed_version = get_option(WC_Seq_Order_Number::VERSION_OPTION_NAME);
494
+
495
+ if(!$installed_version) {
496
+ // initial install, set the order number for all existing orders to the post id
497
+ $orders = get_posts(array('numberposts' => '', 'post_type' => 'shop_order'));
498
+ if(is_array($orders)) {
499
+ foreach($orders as $order) {
500
+ if(get_post_meta($order->ID, '_order_number', true) == '') {
501
+ add_post_meta($order->ID, '_order_number', $order->ID);
502
+ }
503
+ }
504
+ }
505
+ }
506
+
507
+ if($installed_version != WC_Seq_Order_Number::VERSION) {
508
+ $this->upgrade($installed_version);
509
+
510
+ // new version number
511
+ update_option(WC_Seq_Order_Number::VERSION_OPTION_NAME, WC_Seq_Order_Number::VERSION);
512
+ }
513
+ }
514
+
515
+ /**
516
+ * Run when plugin version number changes
517
+ */
518
+ private function upgrade($installed_version) {
519
+ // upgrade code goes here
520
+ }
521
+ }
522
+ }
523
+
524
+ new WC_Seq_Order_Number();
525
+ }