From a048b8efb0fa9dcb88131bf34a72073c8fff653b Mon Sep 17 00:00:00 2001
From: Reinhold Kainhofer <reinhold@kainhofer.com>
Date: Wed, 14 Nov 2012 18:04:57 +0100
Subject: [PATCH] Version 1.1: Some more variables implemented, German
 translation

---
 .gitignore                              |   1 +
 Makefile                                |  14 +--
 de-DE.plg_vmshopper_ordernumber.sys.ini |   1 +
 en-GB.plg_vmshopper_ordernumber.sys.ini |   1 +
 index.html                              |   1 +
 ordernumber.php                         | 110 ++++++++++++++----------
 ordernumber.xml                         |  76 +++++++---------
 7 files changed, 107 insertions(+), 97 deletions(-)
 create mode 100644 .gitignore
 create mode 120000 de-DE.plg_vmshopper_ordernumber.sys.ini
 create mode 120000 en-GB.plg_vmshopper_ordernumber.sys.ini
 create mode 100644 index.html

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b25c15b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*~
diff --git a/Makefile b/Makefile
index 7c6fccd..f97f3d7 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 0000000..d469f59
--- /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 0000000..3dac52b
--- /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 0000000..2efb97f
--- /dev/null
+++ b/index.html
@@ -0,0 +1 @@
+<!DOCTYPE html><title></title>
diff --git a/ordernumber.php b/ordernumber.php
index 1129d67..c581d12 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 7b4b3f1..aec6cd1 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
-      &lt;div style="font-weight: normal;"&gt;
-      &lt;p style="font-weight: normal;"&gt;
-		The format of the order and invoice numbers is a free-form text string, where &lt;tt&gt;#&lt;/tt&gt; indicates the running counter and &lt;tt&gt;[variable]&lt;/tt&gt; is understood as a variable and replaced by its current value. Currently, the following variables are available (case-insensitive):&lt;table border=1&gt;
-		&lt;tr&gt;&lt;td&gt;year&lt;/td&gt;&lt;td&gt;Current year (4 digits)&lt;/td&gt;&lt;/tr&gt;
-		&lt;tr&gt;&lt;td&gt;year2&lt;/td&gt;&lt;td&gt;Current year (2 digits)&lt;/td&gt;&lt;/tr&gt;
-		&lt;tr&gt;&lt;td&gt;month&lt;/td&gt;&lt;td&gt;Current month (2 digits); leading zeros if necessary&lt;/td&gt;&lt;/tr&gt;
-		&lt;tr&gt;&lt;td&gt;day&lt;/td&gt;&lt;td&gt;Current day (2 digits); leading zeros if necessary&lt;/td&gt;&lt;/tr&gt;
-		&lt;tr&gt;&lt;td&gt;hour&lt;/td&gt;&lt;td&gt;Current hour in 24-hour format; leading zeros if necessary&lt;/td&gt;&lt;/tr&gt;
-		&lt;tr&gt;&lt;td&gt;hour12&lt;/td&gt;&lt;td&gt;Current hour in 12-hour format; leading zeros if necessary&lt;/td&gt;&lt;/tr&gt;
-		&lt;tr&gt;&lt;td&gt;ampm&lt;/td&gt;&lt;td&gt;Current am-pm (for 12-hour format) in lower-case&lt;/td&gt;&lt;/tr&gt;
-		&lt;tr&gt;&lt;td&gt;minute&lt;/td&gt;&lt;td&gt;Current minute; leading zeros if necessary&lt;/td&gt;&lt;/tr&gt;
-		&lt;tr&gt;&lt;td&gt;second&lt;/td&gt;&lt;td&gt;Current second; leading zeros if necessary&lt;/td&gt;&lt;/tr&gt;
-&lt;!--		&lt;tr&gt;&lt;td&gt;customer&lt;/td&gt;&lt;td&gt;The customer ID of the order&lt;/td&gt;&lt;/tr&gt; --&gt;
-		&lt;tr&gt;&lt;td&gt;randomDigit[n]&lt;/td&gt;&lt;td&gt;Random sequences of n decimal digits (n=1 if not given).&lt;/td&gt;&lt;/tr&gt;
-		&lt;tr&gt;&lt;td&gt;randomHex[n]&lt;/td&gt;&lt;td&gt;Random sequences of n hexadecimal digits (n=1 if not given).&lt;/td&gt;&lt;/tr&gt;
-		&lt;tr&gt;&lt;td&gt;randomLetter[n]&lt;/td&gt;&lt;td&gt;Random sequences of n (upper- and lowercase) letters (n=1 if not given).&lt;/td&gt;&lt;/tr&gt;
-		&lt;tr&gt;&lt;td&gt;randomULetter[n]&lt;/td&gt;&lt;td&gt;Random sequences of n uppercase letters (n=1 if not given).&lt;/td&gt;&lt;/tr&gt;
-		&lt;tr&gt;&lt;td&gt;randomLLetter[n]&lt;/td&gt;&lt;td&gt;Random sequences of n lowercase letters (n=1 if not given).&lt;/td&gt;&lt;/tr&gt;
-		&lt;tr&gt;&lt;td&gt;randomAlphanum[n]&lt;/td&gt;&lt;td&gt;Random sequences of n general alphanumeric characters (A-Z, a-z, 0-9) (n=1 if not given).&lt;/td&gt;&lt;/tr&gt;
-		&lt;/table&gt;      
-	&lt;/div&gt;
-      </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="&lt;b&gt;Order numbers&lt;/b&gt;" />
-                <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="&lt;b&gt;Order password&lt;/b&gt;" />
-                <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="&lt;b&gt;Invoice numbers&lt;/b&gt;" />
-                <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>      
-- 
GitLab