Skip to content
Snippets Groups Projects
ordernumber.php 11.88 KiB
<?php
/**
 * @package VirtueMart 2 OrderNumber plugin for Joomla! 2.5
 * @author Reinhold Kainhofer, reinhold@kainhofer.com
 * @copyright (C) 2012-2014 - 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 {

    function __construct(& $subject, $config) {
        parent::__construct($subject, $config);
        /* Create the database table */
        $this->tableFields = array_keys ($this->getTableSQLFields ());
    }

    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) {}
    
    /* 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 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();
    }



    /* 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) {
        // 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"),
            "[userid]" => $details->virtuemart_user_id
        );
        if (isset($details->virtuemart_vendor_id)) $reps["[vendorid]"] = $details->virtuemart_vendor_id;
        
        if ($nrtype==0 or $nrtype == 1) { // Order nr and Invoice nr
            if (isset($details->ip_address)) $reps["[ipaddress]"] = $details->ip_address;
        }
        if ($nrtype==1 or $nrtype==2) { // Invoice nr and Customer nr
            if (isset($details->email)) $reps["[email]"] = $details->email;
            if (isset($details->title)) $reps["[title]"] = $details->title;
            if (isset($details->first_name)) $reps["[firstname]"] = $details->first_name;
            if (isset($details->middle_name)) $reps["[middlename]"] = $details->middle_name;
            if (isset($details->last_name)) $reps["[lastname]"] = $details->last_name;

            if (isset($details->company)) $reps["[company]"] = $details->company;
            if (isset($details->zip)) $reps["[zip]"] = $details->zip;
            if (isset($details->city)) $reps["[city]"] = $details->city;
        
            if (isset($details->virtuemart_country_id)) $reps["[countryid]"] = $details->virtuemart_country_id;
            if (isset($details->virtuemart_country_id)) {
                $country = $this->getCountryFromID ($details->virtuemart_country_id);
                if ($country) {
                    $reps["[country]"] = $country->country_name;
                    $reps["[countrycode2]"] = $country->country_2_code;
                    $reps["[countrycode3]"] = $country->country_3_code;
                }
            }

            if (isset($details->virtuemart_state_id)) $reps["[stateid]"] = $details->virtuemart_state_id;
        }
        if ($nrtype==1) {
            // Only for Invoice:
            if (isset($details->order_number)) $reps["[ordernumber]"] = $details->order_number;
            if (isset($details->virtuemart_order_id)) $reps["[orderid]"] = $details->virtuemart_order_id;
            if (isset($details->order_status)) $reps["[orderstatus]"] = $details->order_status;
        }
        if ($nrtype==2) {
            // Customer number:
            if (isset($details->username)) $reps["[username]"] = $details->username;
            if (isset($details->name)) $reps["[name]"] = $details->name;
            if (isset($details->user_is_vendor)) $reps["[user_is_vendor]"] = $details->user_is_vendor;
        }
        return str_ireplace (array_keys($reps), array_values($reps), $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);

        // 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 = $parts[(count($parts)>1)?1:0];

        // Look up the current counter
        $db = JFactory::getDBO();
        /* prevent sql injection attacks by escaping the user-entered format! Empty for global counter... */
        /* For global counting, simply read the empty number_format entries! */
        $counterfmt = $global?"":$db->getEscaped ($counterfmt);
        $q1 = 'SELECT `count` FROM `'.$this->_tablename.'` WHERE `number_type`='.(int)$nrtype.' AND `number_format`="'.$counterfmt.'"';
        $db->setQuery($q1);
        $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`="'.$counterfmt.'"';
        } else {
            $q = 'INSERT INTO `'.$this->_tablename.'` (`count`, `number_type`, `number_format`) VALUES ('.(int)$count.','.(int)$nrtype.', "'.$counterfmt.'")';
        }
        $db->setQuery( $q );
        $db->query();

        // return the format with the counter inserted
        return str_replace ("#", sprintf('%0' . $padding . 's', $count), $format);
    }


    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);
          // TODO: Check if ordernr already exists
          $orderDetails->order_number = $ordernr;
        }
        // Is order password customization enabled?
        if ($this->params->get('customize_order_password')) {
          $nrtype = 3; /* order password */
          $fmt = $this->params->get ('order_password_format', "[randomHex8]");
          $passwd = $this->replace_fields ($fmt, $nrtype, $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 = JFactory::getApplication()->input->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);
                // TODO: Check if ordernr already exists
                $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);
            // TODO: Check if ordernr already exists
            $data['customer_number'] = $customernr;
            return $data;
        }
    }


	/**
	 * plgVmOnSelfCallBE ... Called to execute some plugin action in the backend (e.g. set/reset dl counter, show statistics etc.)
	 */
/*	function plgVmOnSelfCallBE($type, $name, &$output) {
		if ($name != $this->_name || $type != 'vmshopper') return false;
		vmDebug('plgVmOnSelfCallBE');
		
		$db = JFactory::getDBO();
		$nullDate = $db->getNullDate();
	}*/

    
    /* In versions before VM 2.6.8, the onStoreInstallPluginTable function was protected, so the installer couldn't call it to create the plugin table...
       This function simply is a public wrapper to make this function available to the installer on all VM versions: */
	public function plgVmOnStoreInstallPluginTable($psType, $name='') {
		return $this->onStoreInstallPluginTable($psType, $name);
	}

}