diff --git a/woocommerce-advanced-ordernumbers.php b/woocommerce-advanced-ordernumbers.php index ebeff04f419c16e8b1c686f091dfd9dda6986e99..062a7d58ab2968c20e21541cf8365d54b851ffc2 100644 --- a/woocommerce-advanced-ordernumbers.php +++ b/woocommerce-advanced-ordernumbers.php @@ -28,7 +28,6 @@ if ( ! defined( 'ABSPATH' ) ) { if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) { // Put your plugin code here // Load the language files - load_plugin_textdomain('opentools-ordernumbers', false, basename( dirname( __FILE__ ) ) . '/languages' ); if (!class_exists("OpenToolsOrdernumbers")) { class OpenToolsOrdernumbers { @@ -36,65 +35,89 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g public $ordernumber_new_placeholder = "[New Order]"; public $ordernumber_counter_prefix = 'ordernumber-counter-'; + + /** + * STATIC HELPER FUNCTIONS, WooCommerce-specific + */ + public static function __($string) { + return __($string, 'opentools-advanced-ordernumbers'); + } + public static function rel_url($file) { + return plugins_url($file, __FILE__); + } + public static function img_url($img) { + return self::rel_url('assets/images/'.$img ); + } + public static function css_url($css) { + return self::rel_url('assets/css/'.$css ); + } + public static function js_url($js) { + return self::rel_url('assets/js/'.$js ); + } + + + + /** * Construct the plugin object */ public function __construct() { $plugin = plugin_basename(__FILE__); + load_plugin_textdomain('opentools-ordernumbers', false, basename( dirname( __FILE__ ) ) . '/languages' ); // Init settings $this->settings = array( array( - 'name' => __( 'Advanced Order Numbers', 'woocommerce-advanced-ordernumbers' ), - 'desc' => __( 'Configure the format and the counters of the order numbers in WooCommerce.', 'woocommerce-advanced-ordernumbers' ), + 'name' => self::__( 'Advanced Order Numbers'), + 'desc' => self::__( 'Configure the format and the counters of the order numbers in WooCommerce.'), 'type' => 'title', 'id' => 'ordernumber_options' ), array( - 'name' => __( 'Customize Order Numbers', 'woocommerce-advanced-ordernumbers' ), - 'desc' => __( 'Check to use custom order numbers rather than the default wordpress post ID.', 'woocommerce-advanced-ordernumbers' ), + 'name' => self::__( 'Customize Order Numbers'), + 'desc' => self::__( 'Check to use custom order numbers rather than the default wordpress post ID.'), 'id' => 'customize_ordernumber', 'type' => 'checkbox', 'default' => 'no' ), array( - 'title' => __( 'Order number format', 'woocommerce-advanced-ordernumbers' ), - 'desc' => __( 'The format for the order numbers (variables can be entered as [...], the counter is indicated by the #). To use a different counter name than displayed, put the custom counter name after a |, e.g. "[year]-[month]/#|[year]" to use the month in the order number, but reset the counter only yearly.', 'woocommerce-advanced-ordernumbers' ), + 'title' => self::__( 'Order number format'), + 'desc' => self::__( 'The format for the order numbers (variables can be entered as [...], the counter is indicated by the #). To use a different counter name than displayed, put the custom counter name after a |, e.g. "[year]-[month]/#|[year]" to use the month in the order number, but reset the counter only yearly.'), 'desc_tip' => true, 'id' => 'ordernumber_format', 'default' => '#', 'type' => 'text', ), array( - 'title' => __( 'Use global counter', 'woocommerce-advanced-ordernumbers' ), - 'desc' => __( 'A global counter is independent of the number format and will never reset. A non-global counter runs within the number format and will start from the inital value whenever any of the variables used in the format changes (to be precise: a new counter will be used, so it is possible to have multiple counters running in parallel).', 'woocommerce-advanced-ordernumbers' ), + 'title' => self::__( 'Use global counter'), + 'desc' => self::__( 'A global counter is independent of the number format and will never reset. A non-global counter runs within the number format and will start from the inital value whenever any of the variables used in the format changes (to be precise: a new counter will be used, so it is possible to have multiple counters running in parallel).'), 'desc_tip' => true, 'id' => 'ordernumber_global', 'type' => 'checkbox', 'default' => 'no' ), array( - 'title' => __( 'Counter Digits', 'woocommerce-advanced-ordernumbers' ), - 'desc' => __( 'Minimum number of digits for the number', 'woocommerce-advanced-ordernumbers' ), + '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' => __( 'Counter Start', 'woocommerce-advanced-ordernumbers' ), - 'desc' => __( 'Start value for each new counter', 'woocommerce-advanced-ordernumbers' ), + 'title' => self::__( 'Counter Start'), + 'desc' => self::__( 'Start value for each new counter'), 'desc_tip' => true, 'id' => 'ordernumber_start', 'type' => 'number', 'default' => '1' ), array( - 'title' => __( 'Counter step', 'woocommerce-advanced-ordernumbers' ), - 'desc' => __( 'By how much the counter will be increased after each order. Typically 1.', 'woocommerce-advanced-ordernumbers' ), + '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', @@ -105,27 +128,25 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g // TODO: customize order password, and other numbers! array( - 'name' => __( 'Custom Variables', 'woocommerce-advanced-ordernumbers' ), - 'desc' => __( 'Define your own (conditional) variables for use in the number formats', 'woocommerce-advanced-ordernumbers' ), + 'name' => self::__( 'Custom Variables'), + 'desc' => self::__( 'Define your own (conditional) variables for use in the number formats'), 'type' => 'title', 'id' => 'ordernumber_variables' ), array( -// 'title' => __( 'Custom ', 'woocommerce-advanced-ordernumbers' ), -// 'desc' => __( 'The format for the order numbers (variables can be entered as [...], the counter is indicated by the #). To use a different counter name than displayed, put the custom counter name after a |, e.g. "[year]-[month]/#|[year]" to use the month in the order number, but reset the counter only yearly.', 'woocommerce-advanced-ordernumbers' ), 'id' => 'ordernumber_variables', 'type' => 'ordernumber_variables', ), array( 'type' => 'sectionend', 'id' => 'ordernumber_variables' ), array( - 'name' => __( 'Current Counters', 'woocommerce-advanced-ordernumbers' ), + 'name' => self::__( 'Current Counters'), 'type' => 'title', 'id' => 'ordernumber_counters' ), array( - 'name' => __( 'All Ordernumber Counters', 'woocommerce-advanced-ordernumbers' ), - 'desc' => __( 'View and modify the current counter values. The counter value is the value used for the previous number. All changes are immediately applied!', 'woocommerce-advanced-ordernumbers' ), + 'name' => self::__( 'All Ordernumber Counters'), + 'desc' => self::__( 'View and modify the current counter values. The counter value is the value used for the previous number. All changes are immediately applied!'), 'desc_tip' => true, 'id' => 'ordernumber_counters', 'type' => 'ordernumber_counters', @@ -190,7 +211,7 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g foreach ($sections as $sec => $name ) { $newsections[$sec] = $name; if ($sec == '') { - $newsections['ordernumber'] = __( 'Order Numbers', 'woocommerce-advanced-ordernumbers'); + $newsections['ordernumber'] = self::__('Order Numbers'); } } return $newsections; @@ -216,10 +237,10 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g * Print the CSS for the counter values and counter variables tables to the page header in the WC backend admin setting page */ public function print_admin_styles () { - wp_register_style ( 'ordernumber-counter-style', plugins_url('assets/css/ordernumber-counter.css', __FILE__) ); + wp_register_style ( 'ordernumber-counter-style', self::css_url('ordernumber-counter.css') ); wp_enqueue_style('ordernumber-counter-style'); - wp_register_style ( 'ordernumber-variables-style', plugins_url('assets/css/ordernumber-variables.css', __FILE__) ); + wp_register_style ( 'ordernumber-variables-style', self::css_url('ordernumber-variables.css') ); wp_enqueue_style('ordernumber-variables-style'); } /** @@ -227,29 +248,29 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g */ public function print_admin_scripts() { - wp_register_script( 'ordernumber-counter-script', plugins_url( 'assets/js/ordernumber-counter.js', __FILE__), array('jquery') ); + wp_register_script( 'ordernumber-counter-script', self::js_url( 'ordernumber-counter.js', __FILE__), array('jquery') ); wp_enqueue_script( 'ordernumber-counter-script'); // Handle the translations: $localizations = array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ); - $localizations['ORDERNUMBER_JS_JSONERROR'] = __("Error reading response from server:"); - $localizations['ORDERNUMBER_JS_NOT_AUTHORIZED'] = __("You are not authorized to modify order number counters."); - $localizations['ORDERNUMBER_JS_NEWCOUNTER'] = __("Please enter the format/name of the new counter:"); - $localizations['ORDERNUMBER_JS_ADD_FAILED'] = __("Failed adding counter {0}"); - $localizations['ORDERNUMBER_JS_INVALID_COUNTERVALUE'] = __("You entered an invalid value for the counter.\n\n"); + $localizations['ORDERNUMBER_JS_JSONERROR'] = self::__("Error reading response from server:"); + $localizations['ORDERNUMBER_JS_NOT_AUTHORIZED'] = self::__("You are not authorized to modify order number counters."); + $localizations['ORDERNUMBER_JS_NEWCOUNTER'] = self::__("Please enter the format/name of the new counter:"); + $localizations['ORDERNUMBER_JS_ADD_FAILED'] = self::__("Failed adding counter {0}"); + $localizations['ORDERNUMBER_JS_INVALID_COUNTERVALUE'] = self::__("You entered an invalid value for the counter.\n\n"); - $localizations['ORDERNUMBER_JS_EDITCOUNTER'] = __("{0}Please enter the new value for the counter '{1}' (current value: {2}):"); - $localizations['ORDERNUMBER_JS_MODIFY_FAILED'] = __("Failed modifying counter {0}"); - $localizations['ORDERNUMBER_JS_DELETECOUNTER'] = __("Really delete counter '{0}' with value '{1}'?"); - $localizations['ORDERNUMBER_JS_DELETE_FAILED'] = __("Failed deleting counter {0}"); + $localizations['ORDERNUMBER_JS_EDITCOUNTER'] = self::__("{0}Please enter the new value for the counter '{1}' (current value: {2}):"); + $localizations['ORDERNUMBER_JS_MODIFY_FAILED'] = self::__("Failed modifying counter {0}"); + $localizations['ORDERNUMBER_JS_DELETECOUNTER'] = self::__("Really delete counter '{0}' with value '{1}'?"); + $localizations['ORDERNUMBER_JS_DELETE_FAILED'] = self::__("Failed deleting counter {0}"); // in JavaScript, object properties are accessed as ajax_object.ajax_url, ajax_object.we_value wp_localize_script( 'ordernumber-counter-script', 'ajax_ordernumber', $localizations ); - wp_register_script( 'ordernumber-variables-script', plugins_url( 'assets/js/ordernumber-variables.js', __FILE__), array('jquery') ); + wp_register_script( 'ordernumber-variables-script', self::js_url( 'ordernumber-variables.js'), array('jquery') ); wp_enqueue_script( 'ordernumber-variables-script'); } @@ -260,32 +281,35 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g $variables = get_option( $settings['id'], array() ); if (!is_array($variables)) { $variables = array(); - } -// echo "<pre>Admin field " . print_r($settings['id'],1) . " has value: " . print_r($variables, 1) . "</pre>"; - - // Description handling - $field_description = WC_Admin_Settings::get_field_description( $settings ); - extract( $field_description ); - ?> - + } ?> <tr valign="top"> <td class="forminp forminp-<?php echo sanitize_title( $settings['type'] ) ?>" colspan="2"> + <?php + print $this->customvar_admin_table($settings['id'], $variables); + ?> + </td> + </tr> + <?php + } + + protected function customvar_admin_table($id, $variables) { ?> + <table id="ordernumber_variables_template" style="display:none"> - <?php echo $this->create_replacements_row_html($settings['id'], array(), 'disabled'); ?> + <?php echo $this->create_replacements_row_html($id, array(), 'disabled'); ?> </table> <table id="ordernumber_variables" class="ordernumber_variables widefat wc_input_table sortable" cellspacing="0"> <?php - $columns = apply_filters( 'woocommerce_ordernumber_variables_columns', array( - 'variables_ifvar' => __( 'If variable ...', 'woocommerce-advanced-ordernumbers' ), + $columns = array( + 'variables_ifvar' => self::__( 'If variable ...'), 'variables_ifop' => '', - 'variables_ifval' => __( 'Value', 'woocommerce-advanced-ordernumbers' ), - 'variables_then' => __( '', 'woocommerce-advanced-ordernumbers' ), - 'variables_thenvar' => __( 'Set variable ...', 'woocommerce-advanced-ordernumbers' ), - 'variables_thenval' => __( 'to value ...', 'woocommerce-advanced-ordernumbers' ), + 'variables_ifval' => self::__( 'Value'), + 'variables_then' => self::__( ''), + 'variables_thenvar' => self::__( 'Set variable ...'), + 'variables_thenval' => self::__( 'to value ...'), 'sort' => ' ', 'variables_settings' => '', - ) ); + ); ?> <thead> <tr> @@ -297,8 +321,8 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g </tr> <tr id = "ordernumber-replacements-empty-row" class="oton-empty-row-notice <?php echo (empty($variables))?'':'rowhidden'; ?>"> <td class="oton-empty-row-notice" colspan="8"> - <em> <?php echo __('No custom variables have been defined.', 'woocommerce-advanced-ordernumbers'); ?></em> - <input type="hidden" name="<?php echo $settings['id']; ?>" value="" <?php echo (empty($variables))?'':'disabled'; ?>> + <em> <?php echo self::__('No custom variables have been defined.'); ?></em> + <input type="hidden" name="<?php echo $id; ?>" value="" <?php echo (empty($variables))?'':'disabled'; ?>> </td> </tr> </thead> @@ -313,36 +337,34 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g <tbody> <?php foreach ($variables as $var) { - echo $this->create_replacements_row_html($settings['id'], $var); + echo $this->create_replacements_row_html($id, $var); } ?> </tbody> <tfoot> <tr class='addreplacement_row'> <td colspan=8 class='variable_add'> <div class='ordernumber-variables-addbtn ordernumber-btn' onClick="ordernumberVariablesAddRow('ordernumber_variables_template', 'ordernumber_variables')"> - <div class='ordernumber-ajax-loading'><img src='<?php echo plugins_url( 'assets/images/icon-16-new.png', __FILE__ ); ?>' class='ordernumber-counter-addbtn' /></div> - <?php _e('Add new custom variable', 'woocommerce-advanced-ordernumbers'); ?> + <div class='ordernumber-ajax-loading'><img src='<?php echo self::img_url( 'icon-16-new.png' ); ?>' class='ordernumber-counter-addbtn' /></div> + <?php _e('Add new custom variable'); ?> </div> </td> </tr> </tfoot> </table> - </td> - </tr> - <?php + <?php } protected function create_replacements_row_html($name, $values = array(), $disabled = '') { $operator = (isset($values['conditionop'])?$values['conditionop']:''); $operators = array( 'equals' => '=', - 'contains' => __('contains', 'woocommerce-advanced-ordernumbers'), + 'contains' => self::__('contains'), 'smaller' => '<', 'smallerequal' => '<=', 'larger' => '>', 'largerequal' => '>=', - 'startswith' => __('starts with', 'woocommerce-advanced-ordernumbers'), - 'endswith' => __('ends with', 'woocommerce-advanced-ordernumbers'), + 'startswith' => self::__('starts with'), + 'endswith' => self::__('ends with'), ); $html = ' <tr> @@ -357,7 +379,7 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g <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"> </td> - <td><img src="' . plugins_url( 'assets/images/icon-16-delete.png', __FILE__ ) . '" class="ordernumber-replacement-deletebtn ordernumber-btn"></td> + <td><img src="' . self::img_url( 'icon-16-delete.png' ) . '" class="ordernumber-replacement-deletebtn ordernumber-btn"></td> </tr>'; return $html; } @@ -416,13 +438,13 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g <?php echo $tooltip_html; ?> </th> <td class="forminp forminp-<?php echo sanitize_title( $settings['type'] ) ?>"> - <img src='<?php echo plugins_url( 'assets/images/loading.gif', __FILE__ ); ?>' class='wc-ordernumber-loading' style="display: none; position: absolute; top: 2px; left: 0px; z-index: 9999;"/> + <img src='<?php echo self::img_url( 'loading.gif' ); ?>' class='wc-ordernumber-loading' style="display: none; position: absolute; top: 2px; left: 0px; z-index: 9999;"/> <table class="wc_ordernumber_counters widefat" cellspacing="0"> <?php $columns = apply_filters( 'woocommerce_ordernumber_counters_columns', array( - 'type' => __( '', 'woocommerce-advanced-ordernumbers' ), - 'name' => __( 'Counter name', 'woocommerce-advanced-ordernumbers' ), - 'value' => __( 'Counter value', 'woocommerce-advanced-ordernumbers' ), + 'type' => self::__( ''), + 'name' => self::__( 'Counter name'), + 'value' => self::__( 'Counter value'), 'settings' => '' ) ); ?> @@ -455,8 +477,8 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g <td class="counter_type"></td> <td colspan=3 class='counter_add'> <div class='ordernumber-counter-addbtn ordernumber-btn' onClick="ajaxAddCounter(this, 'ordernumber')"> - <div class='ordernumber-ajax-loading'><img src='<?php echo plugins_url( 'assets/images/icon-16-new.png', __FILE__ ); ?>' class='ordernumber-counter-addbtn' /></div> - <?php _e('Add new counter', 'woocommerce-advanced-ordernumbers'); ?> + <div class='ordernumber-ajax-loading'><img src='<?php echo self::img_url( 'icon-16-new.png' ); ?>' class='ordernumber-counter-addbtn' /></div> + <?php _e('Add new counter'); ?> </div> </td> </tr> @@ -470,17 +492,17 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g public function create_admin_counter_row ($type, $format, $value=0) { $html = " <tr class='counter_row counter_type_" . $type . "'> - <td class='counter_type'>" . __($type, 'wooocommerce-advanced-ordernumbers' ) . "</td> - <td class='counter_format'>" . (empty($format)?("<i>".__("[Global]", 'woocommerce-advanced-ordernumbers')."</i>"):esc_html($format)) . "</td> + <td class='counter_type'>" . self::__($type, 'wooocommerce-advanced-ordernumbers' ) . "</td> + <td class='counter_format'>" . (empty($format)?("<i>".self::__("[Global]")."</i>"):esc_html($format)) . "</td> <td class='counter_value'>" . esc_html($value) . "</td> <td class='counter_buttons'> <div class='ordernumber-ajax-loading'> - <img src='" . plugins_url( 'assets/images/icon-16-edit.png', __FILE__ ) . "' + <img src='" . self::img_url( 'icon-16-edit.png' ) . "' class='ordernumber-counter-editbtn ordernumber-btn' onClick='ajaxEditCounter(this, " . json_encode($type) . ", " . json_encode($format) . ", " . json_encode($value) . ")' /> </div> <div class='ordernumber-ajax-loading'> - <img src='" . plugins_url( 'assets/images/icon-16-delete.png', __FILE__ ) . "' + <img src='" . self::img_url( 'icon-16-delete.png' ) . "' class='ordernumber-counter-deletebtn ordernumber-btn' onClick='ajaxDeleteCounter(this, " . json_encode($type) . ", " . json_encode($format) . ", " . json_encode($value) . ")' /> </div> @@ -556,7 +578,7 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g $json = array('action' => 'add_counter', 'success' => 0); if ($this->_getCounter($type, $format, -1) != -1) { // Counter already exists => error message - $json['error'] = sprintf(__('Counter "%s" already exists, cannot create again.'), $format); + $json['error'] = sprintf(self::__('Counter "%s" already exists, cannot create again.'), $format); } else { $json['success'] = $this->_setCounter($type, $format, $value); $json['newrow'] = $this->create_admin_counter_row($type, $format, $value); @@ -570,12 +592,13 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g wp_send_json($json); } - /** - * Variable replacements: - * - Random strings/digits - * - Order properties - * - User properties - */ + + + /** *********************************************************** + * + * REPLACEMENT FUNCTIONS + * + **************************************************************/ /* Return a random "string" of the given length taken from the given alphabet */ static function randomString($alphabet, $len) { @@ -603,42 +626,37 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g } return self::randomString ($alphabet, $len); } - - - /* replace the variables in the given format. $type indicates the type of number, currently only 'ordernumber', because WooCommerce does not support invoices or customer numbers. We might allow the shop owner to customize the order password, though. */ - function replace_fields ($fmt, $type, $order) { - // First, replace all randomXXX[n] fields. This needs to be done with a regexp and a callback: - $fmt = preg_replace_callback ('/\[(random)(.*?)([0-9]*?)\]/', array($this, 'replaceRandom'), $fmt); - - $reps = array ( - "[year]" => date ("Y"), - "[year2]" => date ("y"), - "[month]" => date("m"), - "[day]" => date("d"), - "[hour]" => date("H"), - "[hour12]" => date("h"), - "[ampm]" => date("a"), - "[minute]" => date("i"), - "[second]" => date("s"), - "[orderid]" => $order->id, - ); + + protected function setupDateTimeReplacements (&$reps, $order, $nrtype) { + $utime = microtime(true); + $reps["[year]"] = date ("Y", $utime); + $reps["[year2]"] = date ("y", $utime); + $reps["[month]"] = date("m", $utime); + $reps["[day]"] = date("d", $utime); + $reps["[hour]"] = date("H", $utime); + $reps["[hour12]"] = date("h", $utime); + $reps["[ampm]"] = date("a", $utime); + $reps["[minute]"] = date("i", $utime); + $reps["[second]"] = date("s", $utime); + $milliseconds = (int)(1000*($utime - (int)$utime)); + $millisecondsstring = sprintf('%03d', $milliseconds); + $reps["[decisecond]"] = $millisecondsstring[0]; + $reps["[centisecond]"] = substr($millisecondsstring, 0, 2); + $reps["[millisecond]"] = $millisecondsstring; + } - $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; + protected function setupAddressReplacements(&$reps, $prefix, $address, $nrtype) { + $reps["[email]"] = $address->billing_email; + $reps["[firstname]"] = $address->billing_first_name; + $reps["[lastname]"] = $address->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]"] = $address->billing_company; + $reps["[zip]"] = $address->billing_postcode; + $reps["[postcode]"] = $address->billing_postcode; + $reps["[city]"] = $address->billing_city; - $country = $order->billing_country; - $state = $order->billing_state; + $country = $address->billing_country; + $state = $address->billing_state; $allcountries = WC()->countries->get_countries(); $states = WC()->countries->get_states($country); $reps["[country]"] = $country; @@ -646,28 +664,136 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g $reps["[state]"] = $state; $reps["[statename]"] = ( $country && $state && isset( $states[ $country ][ $state ] ) ) ? $states[ $country ][ $state ] : $state; + } + + protected function setupStoreReplacements (&$reps, $order, $nrtype) { + } + + protected function setupOrderReplacements (&$reps, $order, $nrtype) { + $reps["[orderid]"] = $order->id; + $reps["[ipaddress]"] = $order->customer_ip_address; - $reps["[articles]"] = $order->get_item_count(); + if ($nrtype != 'ordernumber') { + $reps["[ordernumber]"] = $order->get_order_number(); + } + $reps["[orderstatus]"] = $order->get_status(); $reps["[currency]"] = $order->get_order_currency(); + $reps["[userid]"] = $order->get_user_id(); + + $this->setupAddressReplacements($reps, "", $order, $nrtype); + + $reps["[articles]"] = $order->get_item_count(); // $reps["[downloadpermitted]"] = $order->is_download_permitted(); // $reps["[hasdownloads]"] = $order->has_downloadable_item(); // $reps["[coupons]"] = $order->get_used_coupons(); - - if ($type != 'ordernumber') { - $reps["[ordernumber]"] = $order->get_order_number(); - } - $user = $order->get_user(); - if ($user) { -// TODO: Shall we supply a variable for the user's login / display name? -// $reps["[user]"] = print_r($user,1); -// if (isset($order->username)) $reps["[username]"] = $order->username; + $reps["[ordertotal]"] = $order->get_total(); + $reps["[amount]"] = $order->get_total(); + $reps["[ordersubtotal]"] = $order->get_subtotal(); + $reps["[totaltax]"] = $order->get_total_tax(); + $reps["[totalshipping]"] = $order->get_total_shipping(); + } + + protected function setupShippingReplacements(&$reps, $order, $nrtype) { +// $reps["[shippingmethod]"] = $order->getShippingMethod(); + } + + /*protected function setupInvoiceReplacements (&$reps, $invoice, $order, $nrtype) { + $reps["[invoiceid]"] = $invoice->getId(); + }*/ + + protected function setupReplacements($nrtype, $order) { + $reps = array(); + $this->setupDateTimeReplacements($reps, $order, $nrtype); + $this->setupStoreReplacements($reps, $order, $nrtype); + $this->setupOrderReplacements($reps, $order, $nrtype); + $this->setupShippingReplacements($reps, $order, $nrtype); + $reps = apply_filters( 'opentools_ordernumber_replacements', $reps, $order, $nrtype); + return $reps; + } + + + protected function applyCustomVariables ($nrtype, $order, $reps, $customvars) { + foreach ($customvars as $c) { + $conditionvar = strtolower($c['conditionvar']); + $op = $c['conditionop']; + + $found = false; + $match = false; + $compareval = null; + + if (isset($reps[$conditionvar])) { + $found = true; + $compareval = $reps[$conditionvar]; + } elseif (isset($reps['['.$conditionvar.']'])) { + $found = true; + $compareval = $reps['['.$conditionvar.']']; + }/* elseif ($order && $compareval = $order->getData($conditionvar)) { + // TODO: Handle order property + $found = true; + }*/ else { + // TODO: Handly other possible properties! + // TODO: Print out warning that variable could not be found. + } + if ($found) { + $condval = $c['conditionval']; + switch ($op) { + case 'equals': + $match = ($compareval == $condval); break; + case 'contains': + if (is_array($compareval)) { + $match = in_array($condval, $compareval); + } else { + $match = strpos ($compareval, $condval); + } + break; + case 'smaller': + $match = ($compareval<$condval); break; + case 'smallerequal': + $match = ($compareval<=$condval); break; + case 'larger': + $match = ($compareval>$condval); break; + case 'largerequal': + $match = ($compareval>=$condval); break; + case 'startswith': + $match = (substr("$compareval", 0, strlen("$condval")) === "$condval"); break; + case 'endswith': + $match = (substr("$compareval", -strlen("$condval")) === "$condval"); break; + } + } elseif (empty($conditionvar)) { + $match = true; + } + if ($match) { + $varname = '['.strtolower($c['newvar']).']'; + $reps[$varname] = $c['newval']; + } } + return $reps; + } - // Allow customization via plugins: filter function($reps, $order, $type, $fmt) - $reps = apply_filters( 'opentools_ordernumber_replacements', $reps, $order, $type, $fmt); + 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); return str_ireplace (array_keys($reps), array_values($reps), $fmt); } + // Allow the user to override the format like any other custom variable: + protected function determineNumberFormatString($fmt, $type, $order, $reps) { + if (isset($reps['['.$type.'_format]'])) { + return $reps['['.$type.'_format]']; + } else { + return $fmt; + } + } + + + /* replace the variables in the given format. $type indicates the type of number, currently only 'ordernumber', because WooCommerce does not support invoices or customer numbers. We might allow the shop owner to customize the order password, though. */ + function replace_fields ($fmt, $type, $order, $customvars) { + $reps = $this->setupReplacements ($type, $order); + $reps = $this->applyCustomVariables ($type, $order, $reps, $customvars); + $format = $this->determineNumberFormatString($fmt, $type, $order, $reps); + return $this->doReplacements($format, $reps); + } + function create_ordernumber($orderid, $order, $type='ordernumber') { if (get_option('customize_'.$type, 'false')) { $fmt = get_option ($type.'_format', "#"); @@ -675,8 +801,9 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g $padding = get_option ($type.'_padding', 1); $step = get_option ($type.'_step', 1); $start = get_option ($type.'_start', 1)-$step; // The counter contains the PREVIOUS number! + $customvars = get_option ('ordernumber_variables', array()); - $nr = $this->replace_fields ($fmt, $type, $order); + $nr = $this->replace_fields ($fmt, $type, $order, $customvars); // 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