diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..b25c15b81fae06e1c55946ac6270bfdb293870e8 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*~ diff --git a/Makefile b/Makefile index 7c6fccd43e32f7b17bdcd6aaceac4c00ab1c9e01..f97f3d7ef65d3f2da848be57c26fe4435a8e9a2c 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,16 @@ BASE=ordernumber PLUGINTYPE=vmshopper -VERSION=1.0 +VERSION=1.1 -PLUGINFILES=$(BASE).php $(BASE).xml +PLUGINFILES=$(BASE).php $(BASE).xml index.html TRANSDIR=../../../administrator/language/ -TRANSLATIONS=$(TRANSDIR)/en-GB/en-GB.plg_$(PLUGINTYPE)_$(BASE).sys.ini +TRANSLATIONS=$(call wildcard,$(TRANSDIR)/*/*.plg_$(PLUGINTYPE)_$(BASE).sys.ini) ZIPFILE=plg_$(PLUGINTYPE)_$(BASE)_v$(VERSION).zip zip: $(PLUGINFILES) $(TRANSLATIONS) - zip -r $(ZIPFILE) $(PLUGINFILES) - zip -r --junk-paths $(ZIPFILE) $(TRANSLATIONS) + @echo "Packing all files into distribution file $(ZIPFILE):" + @zip -r $(ZIPFILE) $(PLUGINFILES) + @zip -r --junk-paths $(ZIPFILE) $(TRANSLATIONS) - +clean: + rm -f $(ZIPFILE) diff --git a/de-DE.plg_vmshopper_ordernumber.sys.ini b/de-DE.plg_vmshopper_ordernumber.sys.ini new file mode 120000 index 0000000000000000000000000000000000000000..d469f59653819f75851bbe02ea38190d3f07e3fd --- /dev/null +++ b/de-DE.plg_vmshopper_ordernumber.sys.ini @@ -0,0 +1 @@ +../../../administrator/language/de-DE/de-DE.plg_vmshopper_ordernumber.sys.ini \ No newline at end of file diff --git a/en-GB.plg_vmshopper_ordernumber.sys.ini b/en-GB.plg_vmshopper_ordernumber.sys.ini new file mode 120000 index 0000000000000000000000000000000000000000..3dac52b47641670fc7ab4131232036bce1af719c --- /dev/null +++ b/en-GB.plg_vmshopper_ordernumber.sys.ini @@ -0,0 +1 @@ +../../../administrator/language/en-GB/en-GB.plg_vmshopper_ordernumber.sys.ini \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000000000000000000000000000000000000..2efb97f319a35f6bd80f1751134ed71ec11888eb --- /dev/null +++ b/index.html @@ -0,0 +1 @@ +<!DOCTYPE html><title></title> diff --git a/ordernumber.php b/ordernumber.php index 1129d67deac18aa5b9f068749a240c1b8c1bcfd6..c581d12876cc7c8cefa5805db817c1bcdf0d45a1 100644 --- a/ordernumber.php +++ b/ordernumber.php @@ -1,10 +1,13 @@ <?php -defined('_JEXEC') or die( 'Direct Access to ' . basename( __FILE__ ) . ' is not allowed.' ) ; /** - * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt - * - * - */ + * @package VirtueMart 2 OrderNumber plugin for Joomla! 2.5 + * @version $Id: mod_XYZ.php 599 2010-03-20 23:26:33Z you $ + * @author Reinhold Kainhofer, reinhold@kainhofer.com + * @copyright (C) 2012 - Reinhold Kainhofer + * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html +**/ + +defined('_JEXEC') or die( 'Direct Access to ' . basename( __FILE__ ) . ' is not allowed.' ) ; if (!class_exists('vmShopperPlugin')) require(JPATH_VM_PLUGINS . DS . 'vmshopperplugin.php'); class plgVmShopperOrdernumber extends vmShopperPlugin { @@ -44,44 +47,61 @@ class plgVmShopperOrdernumber extends vmShopperPlugin { } /* Replace the format variables, match[1] is the variable name, match[2] and match[3] are only used for random fields */ - function variable_replacement ($match) { - $varname = strtolower($match[1]); - switch ($varname) { - case "year": return date ("Y"); - case "year2": return date ("y"); - case "month": return date("m"); - case "day": return date("d"); - case "hour": return date("H"); - case "hour12": return date("h"); - case "ampm": return date("a"); - case "minute": return date("i"); - case "second": return date("s"); - case "random": - /* the regexp matches (random)(Type)(Len) as match 1 to 3, 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; + static function replacementCallback ($match, $orderDetails) { + $varname = strtolower($match[1]); + switch ($varname) { + case "year": return date ("Y"); + case "year2": return date ("y"); + case "month": return date("m"); + case "day": return date("d"); + case "hour": return date("H"); + case "hour12": return date("h"); + case "ampm": return date("a"); + case "minute": return date("i"); + case "second": return date("s"); + case "random": + /* the regexp matches (random)(Type)(Len) as match 1 to 3, 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); + case "vendorid": return ($orderDetails->virtuemart_vendor_id); + case "userid": return ($orderDetails->virtuemart_user_id); + case "ipaddress": return ($orderDetails->ip_address); + + // Only for Invoice: + case "ordernumber": return ($orderDetails->order_number); + case "orderid": return ($orderDetails->virtuemart_order_id); + case "lastname": return ($orderDetails->last_name); + case "firstname": return ($orderDetails->first_name); + case "company": return ($orderDetails->company); + case "city": return ($orderDetails->city); + case "zip": return ($orderDetails->zip); + case "orderstatus": return ($orderDetails->order_status); } - return self::randomString ($alphabet, $len); - } - // No variable type matched, so don't replace, return the original string - return $match[0]; - } - + // No variable type matched, so don't replace, return the original string + return $match[0]; + } + function replace_fields ($fmt, $orderDetails) { - // Match variables for the form random[type][count] and everything else. - // This makes it possible to handle "random" just like any other type! - return preg_replace_callback (':\[(?|(random)(.*?)([0-9]*?)|([^\]]+))\]:', 'self::variable_replacement', $fmt); + // Match variables for the form random[type][count] and everything else. + // This makes it possible to handle "random" just like any other type! + $patterns = array ( + '/\[(random)(.*?)([0-9]*?)\]/', // For randomTypeN, spit the three parts + '/\[([^\]]+)\]/' // Everything else matches whole variable name + ); + return preg_replace_callback ($patterns, function ($match) use ($orderDetails) { return self::replacementCallback ($match, $orderDetails); }, $fmt); } - + /* Type 0 means order number, type 1 means invoice number */ function format_number ($fmt, $orderDetails, $nrtype = 0, $global = 1) { // First, replace all variables: @@ -89,17 +109,19 @@ class plgVmShopperOrdernumber extends vmShopperPlugin { // Look up the current counter $db = JFactory::getDBO(); + /* prevent sql injection attacks by escaping the user-entered format! */ + $nr_escaped = $db->getEscaped ($nr); /* For global counting, simply read the empty number_format entries! */ - $q = 'SELECT `count` FROM `'.$this->_tablename.'` WHERE `number_type`='.(int)$nrtype.' AND `number_format`="'.($global?"":$nr).'"'; + $q = 'SELECT `count` FROM `'.$this->_tablename.'` WHERE `number_type`='.(int)$nrtype.' AND `number_format`="'.($global?"":$nr_escaped).'"'; $db->setQuery($q); $existing = $db->loadResult(); $count = $existing?($existing+1):1; // Insert new counter value into the db if ($existing) { - $q = 'UPDATE `'.$this->_tablename.'` SET `count`= "'.$count.'" WHERE `number_type`='.(int)$nrtype.' AND `number_format`="'.($global?"":$nr).'"'; + $q = 'UPDATE `'.$this->_tablename.'` SET `count`= "'.$count.'" WHERE `number_type`='.(int)$nrtype.' AND `number_format`="'.($global?"":$nr_escaped).'"'; } else { - $q = 'INSERT INTO `'.$this->_tablename.'` (`count`, `number_type`, `number_format`) VALUES ('.(int)$count.','.(int)$nrtype.', "'.($global?"":$nr).'")'; + $q = 'INSERT INTO `'.$this->_tablename.'` (`count`, `number_type`, `number_format`) VALUES ('.(int)$count.','.(int)$nrtype.', "'.($global?"":$nr_escaped).'")'; } $db->setQuery( $q ); $db->query(); @@ -132,7 +154,7 @@ class plgVmShopperOrdernumber extends vmShopperPlugin { $nrtype=1; /*invoice-nr*/ $fmt = $this->params->get ('invoice_number_format', "#"); $global = $this->params->get ('invoice_number_global', 1); - $invoicenr = $this->format_number ($fmt, $orderDetails, $nrtype, $global); + $invoicenr = $this->format_number ($fmt, (object)$orderDetails, $nrtype, $global); $data['invoice_number'] = $invoicenr; } } diff --git a/ordernumber.xml b/ordernumber.xml index 7b4b3f16c62537e638911bf535ebcbe9f6bd5d08..aec6cd15023b6ee1dececcf04865fbabb3b2bccb 100644 --- a/ordernumber.xml +++ b/ordernumber.xml @@ -1,36 +1,18 @@ <?xml version="1.0" encoding="UTF-8" ?> -<install version="1.5" type="plugin" group="vmshopper"> - <name>VM - Custom Order and Invoice Numbers</name> - <creationDate>November 2012</creationDate> +<install version="1.5" type="plugin" group="vmshopper" method="upgrade"> + <name>VMSHOPPER_ORDERNUMBER</name> + <creationDate>2012-11-13</creationDate> <author>Reinhold Kainhofer</author> + <authorEmail>reinhold@kainhofer.com</authorEmail> <authorUrl>http://www.kainhofer.com/</authorUrl> <copyright>Copyright (C) 2012 Reinhold Kainhofer. All rights reserved.</copyright> - <license>http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL</license> - <version>1.0.0</version> - <description>This plugin is used to create custom order and invoice numbers for Virtuemart 2 - <div style="font-weight: normal;"> - <p style="font-weight: normal;"> - The format of the order and invoice numbers is a free-form text string, where <tt>#</tt> indicates the running counter and <tt>[variable]</tt> is understood as a variable and replaced by its current value. Currently, the following variables are available (case-insensitive):<table border=1> - <tr><td>year</td><td>Current year (4 digits)</td></tr> - <tr><td>year2</td><td>Current year (2 digits)</td></tr> - <tr><td>month</td><td>Current month (2 digits); leading zeros if necessary</td></tr> - <tr><td>day</td><td>Current day (2 digits); leading zeros if necessary</td></tr> - <tr><td>hour</td><td>Current hour in 24-hour format; leading zeros if necessary</td></tr> - <tr><td>hour12</td><td>Current hour in 12-hour format; leading zeros if necessary</td></tr> - <tr><td>ampm</td><td>Current am-pm (for 12-hour format) in lower-case</td></tr> - <tr><td>minute</td><td>Current minute; leading zeros if necessary</td></tr> - <tr><td>second</td><td>Current second; leading zeros if necessary</td></tr> -<!-- <tr><td>customer</td><td>The customer ID of the order</td></tr> --> - <tr><td>randomDigit[n]</td><td>Random sequences of n decimal digits (n=1 if not given).</td></tr> - <tr><td>randomHex[n]</td><td>Random sequences of n hexadecimal digits (n=1 if not given).</td></tr> - <tr><td>randomLetter[n]</td><td>Random sequences of n (upper- and lowercase) letters (n=1 if not given).</td></tr> - <tr><td>randomULetter[n]</td><td>Random sequences of n uppercase letters (n=1 if not given).</td></tr> - <tr><td>randomLLetter[n]</td><td>Random sequences of n lowercase letters (n=1 if not given).</td></tr> - <tr><td>randomAlphanum[n]</td><td>Random sequences of n general alphanumeric characters (A-Z, a-z, 0-9) (n=1 if not given).</td></tr> - </table> - </div> - </description> + <license>http://www.gnu.org/licenses/gpl-3.0.html GNU/GPLv3</license> + <version>1.1.0</version> + <releaseDate>2012-11-13</releaseDate> + <releaseType>Major update</releaseType> + <downloadUrl>http://www.kainhofer.com/virtuemart-2-extensions/</downloadUrl> + <description>VMSHOPPER_ORDERNUMBER_DESC</description> <languages> <language tag="en-GB">en-GB.plg_vmshopper_ordernumber.sys.ini</language> @@ -41,33 +23,33 @@ <config> <fields name="params"> <fieldset name="basic"> - <field name="order_options" type="spacer" label="<b>Order numbers</b>" /> - <field name="customize_order_number" type="radio" default="0" label="Customize order numbers" description="Check here if you want customized order number formats rather than the default."> - <option value="1">Yes</option> - <option value="0">No</option> + <field name="order_options" type="spacer" label="PLG_ORDERNUMBER_ORDERNR" /> + <field name="customize_order_number" type="radio" default="0" label="PLG_ORDERNUMBER_ORDERNR_CUSTOMIZE" description="PLG_ORDERNUMBER_ORDERNR_CUSTOMIZE_DESC"> + <option value="1">PLG_ORDERNUMBER_YES</option> + <option value="0">PLG_ORDERNUMBER_NO</option> </field> - <field name="order_number_format" type="text" default="Order-[year][month]-#" label="Format of the order numbers" description="Here you can customize the order number"/> - <field name="order_number_global" type="radio" default="0" label="Counter" description="Choose whether you want one global counter or per-format value counters. E.g. with a format of '[year]-#' and the latter option checked, the order count will be within the year only."> - <option value="1">Global</option> - <option value="0">Separate counter per format value</option> + <field name="order_number_format" type="text" default="PLG_ORDERNUMBER_ORDERNR_FMT_DEFAULT" label="PLG_ORDERNUMBER_ORDERNR_FMT" description="PLG_ORDERNUMBER_ORDERNR_FMT_DESC"/> + <field name="order_number_global" type="radio" default="0" label="PLG_ORDERNUMBER_ORDERNR_COUNTER" description="PLG_ORDERNUMBER_ORDERNR_COUNTER_DESC"> + <option value="1">PLG_ORDERNUMBER_COUNTER_GLOBAL</option> + <option value="0">PLG_ORDERNUMBER_COUNTER_PERFORMAT</option> </field> - <field name="password_options" type="spacer" label="<b>Order password</b>" /> - <field name="customize_order_password" type="radio" default="0" label="Customize order password" description="Check here if you want customized order password formats rather than the default."> + <field name="password_options" type="spacer" label="PLG_ORDERNUMBER_PASSWD" /> + <field name="customize_order_password" type="radio" default="0" label="PLG_ORDERNUMBER_PASSWD_CUSTOMIZE" description="PLG_ORDERNUMBER_PASSWD_CUSTOMIZE_DESC"> <option value="1">Yes</option> <option value="0">No</option> </field> - <field name="order_password_format" type="text" default="p_[randomHex5]" label="Format of the order password" description="Here you can customize the order password (# is NOT replaced)"/> + <field name="order_password_format" type="text" default="PLG_ORDERNUMBER_PASSWD_FMT_DEFAULT" label="PLG_ORDERNUMBER_PASSWD_FMT" description="PLG_ORDERNUMBER_PASSWD_FMT_DESC"/> - <field name="invoice_options" type="spacer" label="<b>Invoice numbers</b>" /> - <field name="customize_invoice_number" type="radio" default="0" label="Customize invoice numbers" description="Check here if you want customized invoice number formats rather than the default."> - <option value="1">Yes</option> - <option value="0">No</option> + <field name="invoice_options" type="spacer" label="PLG_ORDERNUMBER_INVOICENR" /> + <field name="customize_invoice_number" type="radio" default="0" label="PLG_ORDERNUMBER_INVOICENR_CUSTOMIZE" description="PLG_ORDERNUMBER_INVOICENR_CUSTOMIZE_DESC"> + <option value="1">PLG_ORDERNUMBER_YES</option> + <option value="0">PLG_ORDERNUMBER_NO</option> </field> - <field name="invoice_number_format" type="text" default="[year]/#" label="Format of the invoice numbers" description="Here you can customize the invoice number"/> - <field name="invoice_number_global" type="radio" default="0" label="Counter" description="Choose whether you want one global counter or per-format value counters. E.g. with a format of '[year]-#' and the latter option checked, the invoice count will be within the year only."> - <option value="1">Global</option> - <option value="0">Separate counter per format value</option> + <field name="invoice_number_format" type="text" default="PLG_ORDERNUMBER_INVOICENR_FMT_DEFAULT" label="PLG_ORDERNUMBER_INVOICENR_FMT" description="PLG_ORDERNUMBER_INVOICENR_FMT_DESC"/> + <field name="invoice_number_global" type="radio" default="0" label="PLG_ORDERNUMBER_INVOICENR_COUNTER" description="PLG_ORDERNUMBER_INVOICENR_COUNTER_DESC"> + <option value="1">PLG_ORDERNUMBER_COUNTER_GLOBAL</option> + <option value="0">PLG_ORDERNUMBER_COUNTER_PERFORMAT</option> </field> </fieldset> </fields>