From 859d8f0108972e73a03d42adbbb8c79cd7230d5e Mon Sep 17 00:00:00 2001
From: Reinhold Kainhofer <reinhold@kainhofer.com>
Date: Mon, 20 Apr 2015 01:13:01 +0200
Subject: [PATCH] Improve table layout, clean up code, make sure the API order
 creation works

---
 TODO                                  |  7 +-
 assets/css/ordernumber-variables.css  | 18 ++++-
 assets/js/ordernumber-config.js       | 17 +++++
 woocommerce-advanced-ordernumbers.php | 94 ++++++++++++---------------
 4 files changed, 79 insertions(+), 57 deletions(-)
 create mode 100644 assets/js/ordernumber-config.js

diff --git a/TODO b/TODO
index 8b585fe..773ac61 100644
--- a/TODO
+++ b/TODO
@@ -4,12 +4,13 @@ OpenTools Advanced Ordernumbers for WooCommerce - Open TODOs
 - Make sure the numbers are generated only for new orders, not for existing ones
 - Check REST API
 - Would it make sense to configure the order password format?
+- Which plugins create invoices? => Can we customize their numbers?
 - Find out how multisite works and make the plugin work with it
-- Add action to create an updated / new order number for an existing order
-- implement woocommerce_hidden_order_itemmeta hook to hide the order number post meta?
 - Use $order->order_date for the date-relating fields!
 - Collect and return php warning messages (i.e. all other output) in the AJAX call and return it inside the JSON rather than as extra HTML.
-- Create order number also when ordering in the frontend
+- Add variable for custom replacements to indicate whether any/only virtual products are purchased
+- Add variable for custom replacements to indicate whether shipping is needed
+- Add variable for custom replacements to indicate whether any/only virtual products are purchased
 
 
 HOOKS for order handling:
diff --git a/assets/css/ordernumber-variables.css b/assets/css/ordernumber-variables.css
index 95bc83b..df2fa26 100644
--- a/assets/css/ordernumber-variables.css
+++ b/assets/css/ordernumber-variables.css
@@ -28,7 +28,7 @@ table.ordernumber_variables tbody > tr:nth-child(even) > td {
     background: #F0F0F0;
 }
 table.ordernumber_variables tbody tr td input {
-	width: 120px;
+	width: 100%;
 }
 .ordernumber-btn {
     cursor: pointer;
@@ -40,4 +40,18 @@ table.ordernumber_variables img {
 }
 tr.rowhidden {
 	display: none;
-}
\ No newline at end of file
+}
+
+/* Adjust the columns of the replacements table */
+col.variables_ifvar, col.variables_ifval {
+	width: 15%;
+}
+col.variables_ifop {
+	width: 10%;
+}
+col.variables_thenvar, col.variables_thenval {
+	width: 25%;
+}
+.variables_then, .variables_settings {
+	text-align: center;
+}
diff --git a/assets/js/ordernumber-config.js b/assets/js/ordernumber-config.js
new file mode 100644
index 0000000..bd8421a
--- /dev/null
+++ b/assets/js/ordernumber-config.js
@@ -0,0 +1,17 @@
+/**
+ * Ordernumber Admin JS
+ */
+jQuery( function ( $ ) {
+
+	$('input#customize_ordernumber').change(function() {
+		if ($(this).is(':checked')) {
+			$('#ordernumber_format').closest('tr').show();
+			$('#ordernumber_global').closest('tr').show();
+		} else {
+			$('#ordernumber_format').closest('tr').hide();
+			$('#ordernumber_global').closest('tr').hide();
+		}
+	}).change();
+
+
+});
diff --git a/woocommerce-advanced-ordernumbers.php b/woocommerce-advanced-ordernumbers.php
index 5edf7ed..d5687f8 100644
--- a/woocommerce-advanced-ordernumbers.php
+++ b/woocommerce-advanced-ordernumbers.php
@@ -26,8 +26,6 @@ if ( ! defined( 'ABSPATH' ) ) {
  * Check if WooCommerce is active
  **/
 if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
-    // Put your plugin code here
-    // Load the language files
 
 	if (!class_exists("OpenToolsOrdernumbers")) {
 		class OpenToolsOrdernumbers {
@@ -100,30 +98,6 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g
 						'type' 		=> 'checkbox',
 						'default'	=> 'no',
 					),
-// 					array(
-// 						'title' 	=> self::__( 'Counter Digits'),
-// 						'desc' 		=> self::__( 'Minimum number of digits for the number'),
-// 						'desc_tip'	=> true,
-// 						'id' 		=> 'ordernumber_padding',
-// 						'type' 		=> 'number',
-// 						'default'	=> '0'
-// 					),
-// 					array(
-// 						'title' 	=> self::__( 'Counter Start'),
-// 						'desc' 		=> self::__( 'Start value for each new counter'),
-// 						'desc_tip'	=> true,
-// 						'id' 		=> 'ordernumber_start',
-// 						'type' 		=> 'number',
-// 						'default'	=> '1'
-// 					),
-// 					array(
-// 						'title'		=> self::__( 'Counter step'),
-// 						'desc' 		=> self::__( 'By how much the counter will be increased after each order. Typically 1.'),
-// 						'desc_tip'	=> true,
-// 						'id' 		=> 'ordernumber_step',
-// 						'type' 		=> 'number',
-// 						'default'	=> '1'
-// 					),
 					array( 'type' => 'sectionend', 'id' => 'ordernumber_options' ),
 					
 					// TODO: customize order password, and other numbers!
@@ -160,9 +134,6 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g
 				add_option ('customize_ordernumber', '0');
 				add_option ('ordernumber_format',    "#");
 				add_option ('ordernumber_global',    'no');
-// 				add_option ('ordernumber_padding',   '1');
-// 				add_option ('ordernumber_start',     '1');
-// 				add_option ('ordernumber_step',      '1');
 				
  				add_option ('ordernumber_variables',  array());
 
@@ -276,6 +247,9 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g
 
 				wp_register_script( 'ordernumber-variables-script', self::js_url( 'ordernumber-variables.js'), array('jquery') );
 				wp_enqueue_script( 'ordernumber-variables-script');
+				
+				wp_register_script( 'ordernumber-admin', self::js_url( 'ordernumber-config.js'), array('jquery'));
+				wp_enqueue_script( 'ordernumber-admin');
 			}
 
 			/**
@@ -311,7 +285,7 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g
 							'variables_then'     => self::__( ''),
 							'variables_thenvar'  => self::__( 'Set variable ...'),
 							'variables_thenval'  => self::__( 'to value ...'),
-							'sort'     => '&nbsp;',
+							'sort'     => '',
 							'variables_settings' => '',
 						);
 					?>
@@ -372,22 +346,22 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g
 				);
 				$html  = '
 				<tr>
-					<td class="oton-replacement-variable"><input name="' . $name . '[conditionvar][]" value="' . (isset($values['conditionvar'])?$values['conditionvar']:'') . '" ' . $disabled . '/></td>
-					<td class="oton-replacement-op"      ><select name="' . $name . '[conditionop][]" ' . $disabled . '>';
+					<td class="variables_ifvar"><input name="' . $name . '[conditionvar][]" value="' . (isset($values['conditionvar'])?$values['conditionvar']:'') . '" ' . $disabled . '/></td>
+					<td class="variables_ifop"      ><select name="' . $name . '[conditionop][]" ' . $disabled . '>';
 				foreach ($operators as $op => $opname) {
 					$html .= '		<option value="' . esc_attr($op) . '" ' . (($op === $operator)?'selected':'') . '>' . esc_html($opname) . '</option>';
 				}
 				$html .= '</td>
-					<td class="oton-replacement-value"   ><input name="' . $name . '[conditionval][]" value="' . (isset($values['conditionval'])?$values['conditionval']:'') . '" ' . $disabled . '/></td>
-					<td>=></td>
-					<td class="oton-replacement-variable"><input name="' . $name . '[newvar][]"       value="' . (isset($values['newvar'])?$values['newvar']:'') .       '" ' . $disabled . '/></td>
-					<td class="oton-replacement-newvalue"><input name="' . $name . '[newval][]"       value="' . (isset($values['newval'])?$values['newval']:'') .       '" ' . $disabled . '/></td>
-					<td class="sort">&nbsp;</td>
-					<td><img src="' . self::img_url( 'icon-16-delete.png' ) . '" class="ordernumber-replacement-deletebtn ordernumber-btn"></td>
+					<td class="variables_ifval"   ><input name="' . $name . '[conditionval][]" value="' . (isset($values['conditionval'])?$values['conditionval']:'') . '" ' . $disabled . '/></td>
+					<td class="variables_then">=></td>
+					<td class="variables_thenvar"><input name="' . $name . '[newvar][]"       value="' . (isset($values['newvar'])?$values['newvar']:'') .       '" ' . $disabled . '/></td>
+					<td class="variables_thenval"><input name="' . $name . '[newval][]"       value="' . (isset($values['newval'])?$values['newval']:'') .       '" ' . $disabled . '/></td>
+					<td class="sort"></td>
+					<td class="variables_settings"><img src="' . self::img_url( 'icon-16-delete.png' ) . '" class="ordernumber-replacement-deletebtn ordernumber-btn"></td>
 				</tr>';
 				return $html;
 			}
-			
+
 			/** 
 			 * Store the variable replacements array into the options. Need to transpose the array before we can store it into the options...
 			 * This filter is called directly before the option is saved.
@@ -541,6 +515,7 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g
 			 */
 			public function add_order_action_new_number($actions) {
 				$actions['assign_new_ordernumber'] = self::__('Assign a new order number');
+				return $actions;
 			}
 			/**
 			 * Handle the "Assign a new order number" action from the edit order page in the backend
@@ -565,7 +540,6 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g
 					// Assign an order number:
 					$number = $this->assign_new_ordernumber($post_id, $post, $update);
 				}
-				
 			}
 
 			/**
@@ -709,6 +683,31 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g
 				$reps["[ordersubtotal]"]      = $order->get_subtotal();
 				$reps["[totaltax]"]      = $order->get_total_tax();
 				$reps["[totalshipping]"]      = $order->get_total_shipping();
+				
+				// List-valued properties for custom variable checks:
+				// TODO: Also implement variable for:
+				//  - Shipping needed
+				//  - Downloads available
+				$lineitems = $order->get_items();
+				$skus = array();
+				$categories = array();
+				$tags = array();
+				$shippingclasses = array();
+				foreach ($lineitems as $l) {
+					$p = $order->get_product_from_item($l);
+					$skus[$p->get_sku()] = 1;
+					foreach (wc_get_product_terms( $p->id, 'product_cat') as $c) {
+						$categories[$c->slug] = 1;
+					}
+					foreach (wc_get_product_terms( $p->id, 'product_tag') as $c) {
+						$tags[$c->slug] = 1;
+					}
+					$shippingclasses[$p->get_shipping_class()] = 1;
+				}
+				$reps["[skus]"] = array_keys($skus);
+				$reps["[categories]"] = array_keys($categories);
+				$reps["[tags]"] = array_keys($tags);
+				$reps["[shippingclasses]"] = array_keys($shippingclasses);
 			}
    
 			protected function setupShippingReplacements(&$reps, $order, $nrtype) {
@@ -800,6 +799,8 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g
 			protected function doReplacements ($fmt, $reps) {
 				// First, replace all random...[n] fields. This needs to be done with a regexp and a callback:
 				$fmt = preg_replace_callback ('/\[(random)(.*?)([0-9]*?)\]/', array($this, 'replaceRandom'), $fmt);
+				// Only use string-valued variables for replacement (array-valued variables can be used in custom variable definitions!)
+				$reps = array_filter($reps, function($v) { return !is_array($v);} );
 				return str_ireplace (array_keys($reps), array_values($reps), $fmt);
 			}
 			
@@ -836,20 +837,12 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g
 					}
 					
 // print("<pre>Counters regexp matches: ".print_r($counters,1)."</pre>");
-// 					$ctrsettings["${type}_padding"] = 
 					$fmt = preg_replace($regexp, "#", $fmt);
-				} else {
-// print("<pre>No counters match the regexp '$regexp' in the format '$fmt'</pre>");
 				}
-				// Replace all extended counter definitions by a single #
-				
 				// Split at a | to get the number format and a possibly different counter increment format
 				// If a separate counter format is given after the |, use it, otherwise reuse the number format itself as counter format
-				
-				
 				$parts = explode ("|", $fmt);
 				$ctrsettings["${type}_format"] = $parts[0];
-				
 				$ctrsettings["${type}_counter"] = ($ctrsettings["${type}_global"]=='yes')?"":$parts[(count($parts)>1)?1:0];
 				
 // print("<pre>Counter settings are: ".print_r($ctrsettings,1)."</pre>");
@@ -863,7 +856,7 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g
 				$format = $this->setupNumberFormatString($fmt, $type, $order, $reps);
 				$format = $this->doReplacements($format, $reps);
 				$ctrsettings = $this->extractCounterSettings ($format, $type, $ctrsettings);
-        
+
 				$countername = $ctrsettings["${type}_counter"];
 				// Look up the current counter
 				$count = $this->_getCounter($type, $countername, $ctrsettings["${type}_start"] - $ctrsettings["${type}_step"]) + $ctrsettings["${type}_step"];
@@ -883,9 +876,6 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g
 						"${type}_padding" => 1,
 						"${type}_step"    => 1,
 						"${type}_start"   => 1,
-// 						"${type}_padding" => get_option ($type.'_padding', 1),
-// 						"${type}_step"    => get_option ($type.'_step',    1),
-// 						"${type}_start"   => get_option ($type.'_start',   1),
 					);
 					$customvars = get_option ('ordernumber_variables',   array());
 
-- 
GitLab