Commit cdae04ef authored by Reinhold Kainhofer's avatar Reinhold Kainhofer

Implement basic ordernumber assignment, properly add options to WooCommerce settings pages;

What is still missing is the detection whether an order is new or not. Old orders without ordernumbers should NOT be assigned a new ordernumber... No idea how I can find out this aspect
parent b46a2440
<div class="wrap">
<h2>OpenTools Advanced Ordernumbers</h2>
<form method="post" action="options.php">
<?php @settings_fields('create_ordernumbers-group'); ?>
<?php @do_settings_fields('create_ordernumbers-group'); ?>
<table class="form-table">
<tr valign="top">
<th scope="row"><label for="customize_ordernumbers">Customize Order Numbers</label></th>
<td><input type="text" name="customize_ordernumbers" id="customize_ordernumbers" value="<?php echo get_option('customize_ordernumbers'); ?>" /></td>
</tr>
<tr valign="top">
<th scope="row"><label for="ordernumber_format">Order Number Format</label></th>
<td><input type="text" name="ordernumber_format" id="ordernumber_format" value="<?php echo get_option('ordernumber_format'); ?>" /></td>
</tr>
<tr valign="top">
<th scope="row"><label for="ordernumber_counter_scope">Scope of the Counter</label></th>
<td><input type="text" name="ordernumber_counter_scope" id="ordernumber_counter_scope" value="<?php echo get_option('ordernumber_counter_scope'); ?>" /></td>
</tr>
</table>
<?php @submit_button(); ?>
</form>
</div>
\ No newline at end of file
......@@ -37,85 +37,335 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g
public function __construct()
{
$plugin = plugin_basename(__FILE__);
// 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' ),
'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' ),
'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' ),
'desc_tip' => true,
'id' => 'ordernumber_format',
'default' => '#',
'type' => 'text',
),
array(
'title' => __( 'Global', 'woocommerce-advanced-ordernumbers' ),
'desc' => __( 'Counter Scope', 'woocommerce-advanced-ordernumbers' ),
'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' ),
'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' ),
'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' ),
'desc_tip' => true,
'id' => 'ordernumber_step',
'type' => 'number',
'default' => '1'
),
array( 'type' => 'sectionend', 'id' => 'ordernumber_options' ),
// TODO: customize order password, and other numbers!
);
// Default options
add_option ('customize_ordernumber', '0');
add_option ('ordernumber_format', "#");
add_option ('ordernumber_global', '0');
add_option ('ordernumber_padding', '1');
add_option ('ordernumber_start', '1');
add_option ('ordernumber_step', '1');
// register actions
add_action( 'admin_init', array(&$this, 'admin_init'));
add_action( 'admin_menu', array(&$this, 'add_menu'));
// add_action( 'admin_init', array(&$this, 'admin_init'));
// add_action( 'admin_menu', array(&$this, 'add_menu'));
// TODO: Find the proper action hooks to hook into:
add_filter( 'woocommerce_get_sections_checkout', array($this, 'add_admin_section'),1);
// add_filter( 'woocommerce_get_settings_checkout', array( $this, 'admin_settings' ), 20, 2);
// The checkout page assumes all subpages are payment gateways, so we have to override this:
add_action( 'woocommerce_settings_checkout', array( $this, 'output' ) );
add_action( 'woocommerce_settings_save_checkout', array( $this, 'save' ) );
add_action( 'woocommerce_update_options_catalog', array( $this, 'save_admin_settings' ) ); // < 2.1
add_action( 'woocommerce_update_options_products', array( $this, 'save_admin_settings' ) ); // 2.1 +
// register filters
add_filter("plugin_action_links_$plugin", array(&$this, 'plugin_settings_link'));
add_filter ('woocommerce_order_number', array(&$this, 'get_ordernumber'), 10, 2/*<= Also get the order object! */);
}
/**
* Activate the plugin
*/
public static function activate()
{
// Do nothing
}
// Activate the plugin
public static function activate() {}
/**
* Deactivate the plugin
*/
public static function deactivate()
{
// Do nothing
// Deactivate the plugin
public static function deactivate() {}
function add_admin_section($sections) {
$sections['ordernumber'] = __( 'Order Numbers', 'woocommerce-advanced-ordernumbers');
return $sections;
}
public function output() {
global $current_section;
if ($current_section == 'ordernumber') {
$settings = $this->settings;
WC_Admin_Settings::output_fields( $settings );
}
}
/**
* hook into WP's admin_init action hook
*/
public function admin_init()
{
// Set up the settings for this plugin
$this->init_settings();
// Possibly do additional admin_init tasks
public function save() {
global $current_section;
if ($current_section == 'ordernumber') {
$settings = $this->settings;
WC_Admin_Settings::save_fields( $settings );
}
}
// // Save the settings
// function save_admin_settings() {
// woocommerce_update_options( $this->settings );
// }
// /**
// * hook into WP's admin_init action hook
// */
// public function admin_init()
// {
// // Set up the settings for this plugin
// $this->init_settings();
// // Possibly do additional admin_init tasks
// }
// /**
// * Initialize some custom settings
// */
// public function init_settings()
// {
// // register the settings for this plugin
// // TODO: Properly design the set of options needed
// register_setting('opentools-ordernumbers-group', 'customize_ordernumbers');
// register_setting('opentools-ordernumbers-group', 'ordernumber_format');
// register_setting('opentools-ordernumbers-group', 'ordernumber_counter_scope');
// }
// /**
// * add a menu
// */
// public function add_menu()
// {
// // TODO: Move this inside the WooCommerce configuration!
// add_options_page(
// 'Advanced Ordernumber Plugin Settings', // The title to be displayed in the browser window for this page.
// 'OpenTools Advanced Ordernumbers', // The text to be displayed for this menu item
// 'manage_options', // Which type of users can see this menu item
// 'opentools-ordernumbers', // The unique ID - that is, the slug - for this menu item
// array(&$this, 'plugin_settings_page') // The name of the function to call when rendering this menu's page
// );
// }
// function plugin_settings_link($links)
// {
// $settings_link = '<a href="options-general.php?page=opentools-ordernumbers">Settings</a>';
// array_unshift($links, $settings_link);
// return $links;
// }
// /**
// * Menu Callback
// */
// public function plugin_settings_page()
// {
// if(!current_user_can('manage_options'))
// {
// wp_die(__('You do not have sufficient permissions to access this page.'));
// }
//
// // Render the settings template
// include(sprintf("%s/templates/settings.php", dirname(__FILE__)));
// }
/**
* Initialize some custom settings
*/
public function init_settings()
{
// register the settings for this plugin
// TODO: Properly design the set of options needed
register_setting('opentools-ordernumbers-group', 'customize_ordernumbers');
register_setting('opentools-ordernumbers-group', 'ordernumber_format');
register_setting('opentools-ordernumbers-group', 'ordernumber_counter_scope');
* Counter handling (simple loading/storing counters)
*/
function _getCounter($type, $format, $start=1) {
$count = get_option ('ordernumber-counter-'.$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);
}
/**
* add a menu
*/
public function add_menu()
{
// TODO: Move this inside the WooCommerce configuration!
add_options_page('Advanced Ordernumber Plugin Settings', 'OpenTools Advanced Ordernumbers',
'manage_options', 'opentools-ordernumbers', array(&$this, 'plugin_settings_page'));
} // END public function add_menu()
function plugin_settings_link($links)
{
$settings_link = '<a href="options-general.php?page=opentools-ordernumbers">Settings</a>';
array_unshift($links, $settings_link);
return $links;
* Variable replacements:
* - Random strings/digits
* - Order properties
* - User properties
*/
/* Return a random "string" of the given length taken from the given alphabet */
static function randomString($alphabet, $len) {
$alen = strlen($alphabet);
$r = "";
for ($n=0; $n<$len; $n++) {
$r .= $alphabet[mt_rand(0, $alen-1)];
}
return $r;
}
/**
* Menu Callback
*/
public function plugin_settings_page()
{
if(!current_user_can('manage_options'))
{
wp_die(__('You do not have sufficient permissions to access this page.'));
function replaceRandom ($match) {
/* the regexp matches (random)(Type)(Len) as match, Type and Len is optional */
$len = ($match[3]?$match[3]:1);
// Fallback: If no Type is given, use Digit
$alphabet = "0123456789";
// Select the correct alphabet depending on Type
switch (strtolower($match[2])) {
case "digit": $alphabet = "0123456789"; break;
case "hex": $alphabet = "0123456789abcdef"; break;
case "letter": $alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; break;
case "uletter": $alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; break;
case "lletter": $alphabet = "abcdefghijklmnopqrstuvwxyz"; break;
case "alphanum": $alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; break;
}
return self::randomString ($alphabet, $len);
}
/* Extract the country information from the given ID */
// static function getCountryFromID ($country_id) {
// $db = JFactory::getDBO();
// $query = 'SELECT * FROM `#__virtuemart_countries` WHERE `virtuemart_country_id` = ' . (int)$country_id;
// $db->setQuery($query);
// return $db->loadObject();
// }
// Render the settings template
include(sprintf("%s/templates/settings.php", dirname(__FILE__)));
/* Type 0 means order number, type 1 means invoice number, type 2 means customer number, 3 means order password */
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,
"[userid]" => $order->get_user_id(),
);
// if (isset($order->virtuemart_vendor_id)) $reps["[vendorid]"] = $order->virtuemart_vendor_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["[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["[countryname]"] = ( isset( $allcountries[ $country ] ) ) ? $allcountries[ $country ] : $country;
$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["[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;
}
// Allow customization via plugins: filter function($reps, $order, $type, $fmt)
$reps = apply_filters( 'opentools_ordernumber_replacements', $reps, $order, $type, $fmt);
// return print_r($reps,1);
return str_ireplace (array_keys($reps), array_values($reps), $fmt);
}
function create_ordernumber($orderid, $order, $type='ordernumber') {
if (get_option('customize_'.$type, 'false')) {
$fmt = get_option ($type.'_format', "#");
$global = get_option ($type.'_global', 1);
$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!
$nr = $this->replace_fields ($fmt, $type, $order);
// 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 ("|", $nr);
$format = $parts[0];
$counterfmt = ($global==1)?"":$parts[(count($parts)>1)?1:0];
// Look up the current counter
$count = $this->_getCounter($type, $counterfmt, $start) + $step;
$this->_setCounter($type, $counterfmt, $count);
// return the format with the counter inserted
$number = str_replace ("#", sprintf('%0' . $padding . 's', $count), $format);
update_post_meta( $orderid, 'Order Number', $number );
return $number;
} else {
return $orderid;
}
}
/**
* The hook to customize order numbers (requests the order number from the database; creates a new ordernumber if no entry exists in the database)
*/
......@@ -123,19 +373,17 @@ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', g
$stored_number = get_post_meta( $orderid, 'Order Number', 'true');
if (!empty($stored_number)) {
return $stored_number;
} else {
} elseif (get_option('customize_ordernumber', 'false')) {
// create a new one (if this is a new order, otherwise we don't have/generate a number!)
$number = $this->create_ordernumber($orderid, $order);
update_post_meta( $orderid, 'Order Number', $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>");
return $orderid;
}
}
function create_ordernumber($orderid, $order) {
$rnd=rand(100, 1000000);
return "Order-$orderid-Number-$rnd";
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment