-
Reinhold Kainhofer authored
V1.6.1: Fix issues with updated/moved language files (need to remove old files from global language dir) Created and install ordernumber.script.php to run code on plugin update; Also removes the mysql table upon deinstallation.
Reinhold Kainhofer authoredV1.6.1: Fix issues with updated/moved language files (need to remove old files from global language dir) Created and install ordernumber.script.php to run code on plugin update; Also removes the mysql table upon deinstallation.
ordernumber.php 10.33 KiB
<?php
/**
* @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');
/* For php 5.2 we cannot use lambda functions or any other way to pass local variables to the callback.
The only way to pass a local variable to a callback for preg_replace_callback is to
create a class instance... */
class ReplacementCallback {
private $details;
private $nrtype;
function __construct($nrtype, $details) {
$this->details = $details;
$this->nrtype = $nrtype;
}
/* 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;
}
function replace ($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;
}
return self::randomString ($alphabet, $len);
case "vendorid": return ($this->details->virtuemart_vendor_id);
case "userid": return ($this->details->virtuemart_user_id);
case "ipaddress": return ($this->details->ip_address);
// Only for Invoice:
case "ordernumber": return ($this->details->order_number);
case "orderid": return ($this->details->virtuemart_order_id);
case "lastname": return ($this->details->last_name);
case "firstname": return ($this->details->first_name);
case "company": return ($this->details->company);
case "city": return ($this->details->city);
case "zip": return ($this->details->zip);
case "orderstatus": return ($this->details->order_status);
}
// No variable type matched, so don't replace, return the original string
return $match[0];
}
}
class plgVmShopperOrdernumber extends vmShopperPlugin {
function __construct(& $subject, $config) {
parent::__construct($subject, $config);
/* Create the database table */
$this->tableFields = array_keys ($this->getTableSQLFields ());
$this->onStoreInstallPluginTable($this->_psType);
}
public function getVmPluginCreateTableSQL () {
return $this->createTableSQL ('VM Shopper plugin: custom order and invoice numbers');
}
function getTableSQLFields () {
$SQLfields = array(
'id' => 'int(11) UNSIGNED NOT NULL AUTO_INCREMENT',
'number_type' => 'int(1) UNSIGNED',
'number_format' => 'varchar(255)',
'count' => 'int(1)',
);
return $SQLfields;
}
// We don't need this function, but the parent class declares it abstract, so we need to overload
function plgVmOnUpdateOrderBEShopper($_orderID) {}
/* Replace the format variables, match[1] is the variable name, match[2] and match[3] are only used for random fields */
/* Type 0 means order number, type 1 means invoice number, type 2 means customer number, 3 means order password */
function replace_fields ($fmt, $nrtype, $details) {
// 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
);
// // TODO: in php 5.3 and 5.4 we can easier pass $orderDetails to the callback
// function my_callback ($match) {
// return self::replacementCallback ($match, $details);
// };
// return preg_replace_callback ($patterns,
// function ($match) use ($details) {
// return self::replacementCallback ($match, $details);
// }, $fmt);
/* php 5.2 does not allow lambda functions and there is no other way to
pass a local variable to the callback than a class instance! */
$callback = new ReplacementCallback ($nrtype, $details);
return preg_replace_callback ($patterns, array($callback, 'replace'), $fmt);
}
/* Type 0 means order number, type 1 means invoice number, type 2 means customer number */
function format_number ($fmt, $details, $nrtype = 0, $global = 1, $padding = 1) {
// First, replace all variables:
$nr = $this->replace_fields ($fmt, $nrtype, $details);
// 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_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_escaped).'"';
} else {
$q = 'INSERT INTO `'.$this->_tablename.'` (`count`, `number_type`, `number_format`) VALUES ('.(int)$count.','.(int)$nrtype.', "'.($global?"":$nr_escaped).'")';
}
$db->setQuery( $q );
$db->query();
// return the format with the counter inserted
return str_replace ("#", sprintf('%0' . $padding . 's', $count), $nr);
}
function plgVmOnUserOrder(&$orderDetails/*,&$data*/) {
// Is order number customization enabled?
if ($this->params->get('customize_order_number')) {
$nrtype=0; /*order-nr*/
$fmt = $this->params->get ('order_number_format', "#");
$global = $this->params->get ('order_number_global', 1);
$padding = $this->params->get ('order_number_padding', 1);
$ordernr = $this->format_number ($fmt, $orderDetails, $nrtype, $global, $padding);
$orderDetails->order_number = $ordernr;
}
// Is order password customization enabled?
if ($this->params->get('customize_order_password')) {
$fmt = $this->params->get ('order_password_format', "[randomHex8]");
$passwd = $this->replace_fields ($fmt, 3, $orderDetails);
$orderDetails->order_pass = $passwd;
}
}
function plgVmOnUserInvoice($orderDetails,&$data) {
// Is order number customization enabled?
if ($this->params->get('customize_invoice_number')) {
// check the default configuration
$orderstatusForInvoice = VmConfig::get('inv_os',array());
if(!is_array($orderstatusForInvoice)) $orderstatusForInvoice = array($orderstatusForInvoice); //for backward compatibility 2.0.8e
$pdfInvoice = (int)VmConfig::get('pdf_invoice', 0); // backwards compatible
$force_create_invoice=JRequest::getInt('create_invoice', 0);
if ( in_array($orderDetails['order_status'],$orderstatusForInvoice) or $pdfInvoice==1 or $force_create_invoice==1 ){
$nrtype=1; /*invoice-nr*/
$fmt = $this->params->get ('invoice_number_format', "#");
$global = $this->params->get ('invoice_number_global', 1);
$padding = $this->params->get ('invoice_number_padding', 1);
$invoicenr = $this->format_number ($fmt, (object)$orderDetails, $nrtype, $global, $padding);
$data['invoice_number'] = $invoicenr;
return $data;
}
}
}
// Customizing the customer numbers requires VM >= 2.0.15b, earlier versions
// left out the & and thus didn't allow changing the user data
function plgVmOnUserStore(&$data) {
// Is order number customization enabled?
if ($this->params->get('customize_customer_number') && isset($data['customer_number_bycore']) && $data['customer_number_bycore']==1) {
$nrtype=2; /*customer-nr*/
$fmt = $this->params->get ('customer_number_format', "#");
$global = $this->params->get ('customer_number_global', 1);
$padding = $this->params->get ('customer_number_padding', 1);
$customernr = $this->format_number ($fmt, (object)$data, $nrtype, $global, $padding);
$data['customer_number'] = $customernr;
return $data;
}
}
}