Project

General

Profile

Actions

Plugin system » History » Revision 18

« Previous | Revision 18/42 (diff) | Next »
Valérie Isaksen, 06/11/2011 04:55 PM


Plugin system

Since VirtueMart v2, the Joomla! plugin system is used form payment and shipper plugins.

Installing plugins

During development the the VM2 branch, the plugins are not available as Joomla install packages, so for test environments, they must be installed manually.

Payment plugins

At the time of writing, only 2 of the former payment plugins have been converted to the new plugin system. Others should follow soon, all help is appreciated!!

Use the SQL query below to add the plugins to your database (assuming the table prefix is "jos_"):

J1.5:

INSERT INTO `jos_plugins` (`id`, `name`, `element`, `folder`, `access`, `ordering`
  , `published`, `iscore`, `client_id`, `checked_out`, `checked_out_time`, `params`)
VALUES
 (NULL, 'VMPayment - Authorize', 'authorize', 'vmpayment', 0, 0, 1, 0, 0, 0, '0000-00-00 00:00:00', '')
,(NULL, 'VMPayment - Cash on delivery', 'cashondel', 'vmpayment', 0, 0, 1, 0, 0, 0, '0000-00-00 00:00:00','');

J1.6:
INSERT INTO `jos_extensions` (`extension_id`,  `type`, `name`, `element`, `folder`, `access`, `ordering`
  , `enabled`, `protected`, `client_id`, `checked_out`, `checked_out_time`, `params`)
VALUES
 (NULL, 'plugin', 'plg_vmpayment_authorize', 'authorize', 'vmpayment', 1, 0, 1, 0, 0, 0, '0000-00-00 00:00:00', '')
,(NULL, 'plugin', 'plg_vmpayment_cashondel', 'cashondel', 'vmpayment', 1, 0, 1, 0, 0, 0, '0000-00-00 00:00:00','');

Next, when you did not use the svn checkout, copy the plugin files (authorize.php, authorize.xml, cashondel.php and cashondel.xml), located in the folder /plugins/vmpayment, to the Joomla plugin directory. If that doesn't exist, it must be created first.

Now, in the store maintenance, you can add payment methods based on one of these plugins. Note at this moment it is required to select a vendor!

Shipper plugins

This is very similar to the payment plugins. Only 1 plugin has been created (again: all help is appreciated!); 'standard', which provides a basic shipping option for postal services.
Note: Installing the sample data does NOT provide shipping rates anymore!

Use the SQL query below to add the plugins to your database (assuming the table prefix is "jos_"):

J1.5:

INSERT INTO `jos_plugins` (`id`, `name`, `element`, `folder`, `access`, `ordering`
  , `published`, `iscore`, `client_id`, `checked_out`, `checked_out_time`, `params`)
VALUES
 (NULL, 'By weight, ZIP and countries', 'weight_countries', 'vmshipper', 0, 0, 1, 0, 0, 0, '0000-00-00 00:00:00', '')
,(NULL, 'By products and countries', 'products_countries', 'vmshipper', 0, 0, 1, 0, 0, 0, '0000-00-00 00:00:00', '')
;

J1.6:

INSERT INTO `jos_extensions` (`extension_id`, `type`, `name`, `element`, `folder`, `access`, `ordering`
  , `enabled`, `protected`, `client_id`, `checked_out`, `checked_out_time`, `params`)
VALUES
 (NULL, 'plugin', 'plg_vmshipper_weight_countries', 'weight_countries', 'vmshipper', 1, 0, 1, 0, 0, 0, '0000-00-00 00:00:00', '')
,(NULL, 'plugin', 'plg_vmshipper_products_countries', 'products_countries', 'vmshipper', 1, 0, 1, 0, 0, 0, '0000-00-00 00:00:00', '')
;

Next, when you did not use the svn checkout, copy the plugin files (standard.php and standard.xml), located in the folder /plugins/vmshipper, to the Joomla plugin directory. If that doesn't exist, it must be created first.

Now use the 'Shipping' menu item in the backend to add 1 or more carriers based on this plugin. All you need to do here is give the shipper a name and select a vendor (this is optional; when no vendor is selected, this carrier is valid for all vendors).
Finally you can add the shipping rates for the created vendor. Make sure a there's always a valid shipping rate: customers select the carrier only and the plugin must be able to find a matching rate based on the total order weight and the shipto address!

Plugin Development

All plugins for VirtueMart should be developed confirming the Joomla! plugin development methods. Refer to http://docs.joomla.org/Tutorial:Plugins for developers documentation for Joomla! plugins.

Payment Plugins

Payment plugins are used both in the front-end and the backend. They must be created as classes deriving from the base class vmPaymentPlugin:

class plgVmPayment<myPlugin> extends vmPaymentPlugin {
    function plgVmPayment<myPlugin>(&$subject, $config) {
        $this->_pelement = basename(__FILE__, '.php');    // Required!
        $this->_createTable();                // Required, see below
        parent::__construct($subject, $config);
    }
}

Below is the list with events and a description on what moment they are fired.
  • plgVmOnSelectPayment() - This event is fired during the checkout process. It allows the shopper to select one of the available payment methods.
    It should display a radio button (name: paym_id) to select the payment method. Other information (like credit card info) might be selected as well, depending on the plugin.
    Return:
    It must return the HTML code for displaying the form (radio button and optional extra selections).
    Parameters:
    1. (VirtueMartCart object) The cart object
    2. (integer, default 0) ID of an already selected payment method ID, if any
  • plgVmOnPaymentSelectCheck() - This event is fired after the payment method has been selected. It can be used to store
    additional payment info in the cart.
    Return:
    Plugins that were not selected must return null, otherwise True of False must be returned indicating Success or Failure.
    Parameters:
    1. (VirtueMartCart object) The cart object
  • plgVmOnCheckoutCheckPaymentData() - This event is fired during the checkout process. It can be used to validate the payment data as entered by the user.
    Return:
    Plugins that were not selected must return null, otherwise True of False must be returned indicating Success or Failure.
    Parameters:
    None
  • plgVmOnConfirmedOrderStorePaymentData() - This event is fired after the payment has been processed; it stores the payment method-specific data.
    All plugins must reimplement this method.
    Return:
    If the plugin is NOT actually executed (not the selected payment method), this method must return NULL
    If this plugin IS executed, it MUST return the order status code that the order should get. This triggers the stock updates if required
    Parameters:
    1. (integer) The ordernumber being processed
    2. (object) Data from the cart
    3. (array) Price information for this order
  • plgVmOnShowOrderPaymentBE() - This method is fired when showing the order details in the backend. It displays the the payment method-specific data.
    All plugins must reimplement this method.
    Return:
    Null when for payment methods that were not selected, text (HTML) otherwise
    Parameters:
    1. (integer) The order ID
    2. (integer) Payment method used for this order
  • plgVmOnCancelPayment() - This event is fired each time the status of an order is changed to Cancelled. It can be used to refund payments, void authorization etc.
    When reimplementing this methis, the body must start with this code:
    $_paymethodID = $this->getPaymentMethodForOrder($_orderID);
    if (!$this->selectedThisMethod($this->_pelement, $_paymethodID)) {
        return;
    }

    Parameters:
    (integer The order ID
    (char) Previous order status
    (char) New order status
  • plgVmOnShipOrderPayment() - This event is fired when the status of an order is changed to Shipped. It can be used to confirm or capture payments
    When reimplementing this methis, the body must start with this code:
    $_paymethodID = $this->getPaymentMethodForOrder($_orderID);
    if (!$this->selectedThisMethod($this->_pelement, $_paymethodID)) {
        return;
    }

    Return:
    True on success, False on failure, Null if this plugin was not activated
    Parameters:
    1. (integer) Order ID

Other helper functions inherited from the base class:

  • _ createTable() - This method is used to create and maintain the plugin specific database table(s).
    It must be reimplemented by all plugins.
    Example:
    $_scheme = DbScheme::get_instance();
    $_scheme->create_scheme('#__vm_order_payment_'.$this->_pelement);
    $_schemeCols = array(
         'id' => array (
                 'type' => 'int'
                ,'length' => 11
                ,'auto_inc' => true
                ,'null' => false
        )
        ,'order_id' => array (
                 'type' => 'int'
                ,'length' => 11
                ,'null' => false
        )
        ,'payment_method_id' => array (
                 'type' => 'text'
                ,'null' => false
        )
    );
    $_schemeIdx = array(
         'idx_order_payment' => array(
                 'columns' => array ('order_id')
                ,'primary' => false
                ,'unique' => false
                ,'type' => null
        )
    );
    $_scheme->define_scheme($_schemeCols);
    $_scheme->define_index($_schemeIdx);
    if (!$_scheme->scheme()) {
        JError::raiseWarning(500, $_scheme->get_db_error());
    }
    $_scheme->reset();
    
  • getPaymentMethodForOrder() - Get the order payment ID for a given order number
    Return:
    The payment method ID, or -1 when not found
    Parameters:
    1. (integer) The order ID
  • getThisMethodName() - Get the name of the payment method.
    This method can not be reimplemented
    Return:
    Paymenent method name
    Parameters:
    1. (integer) The payment method ID
  • selectedThisMethod() - This method checks if the selected payment method matches the current plugin
    Return:
    True if the calling plugin has the given payment ID, False otherwise.
    Parameters:
    1. (string) Element name, taken from the plugin filename
    2. (integer) The payment method ID
  • writePaymentData() - This method writes all payment plugin specific data to the plugin's table
    Return:
    True if the calling plugin has the given payment ID, False otherwise.
    Parameters:
    1. (array) Indexed array in the format 'column_name' => 'value'
    2. (string) Table name

Shipper Plugins

Shipper plugins are used both in the front-end and the backend. They must be created as classes deriving from the base class vmShipperPlugin:

class plgVmShipper<myPlugin> extends vmShipperPlugin {
    function plgVmPayment<myPlugin>(&$subject, $config) {
        $this->_pelement = basename(__FILE__, '.php');    // Required!
        $this->_createTable();                // Required, see below
        parent::__construct($subject, $config);
    }
}

Here's a short overview of the events:
  • When a shopper selects a shipper, plgOnSelectShipper() is fired. It displays the shipper and can be used for collecting extra - shipper specific - info.
  • After selecting, plgVmShipperSelected() can be used to store extra shipper info in the cart. The selected shipper ID will be stored in the cart by the checkout process before this method is fired.
  • plgOnConfirmShipper() is fired when the order is confirmed and stored to the database. It is called before the rest of the order or stored, when reimplemented, it must include a call to parent::plgOnConfirmShipper() (or execute the same steps to put all data in the cart)
When a stored order is displayed in the backend, the following events are used:
  • plgVmOnShowOrderShipperBE() displays specific data about (a) shipment(s) (NOTE: this plugin is OUTSIDE any form!)
  • plgVmOnShowOrderLineShipperBE()) can be used to show information about a single orderline, e.g. display a package code at line level when more packages are shipped.
  • *plgVmOnEditOrderLineShipperBE() can be used add a package code for an order line when more packages are shipped.
  • plgVmOnUpdateOrderShipperBE() is fired inside a form. It can be used to add shipper data, like package code.
  • plgVmOnSaveOrderShipperBE() is fired from the backend after the order has been saved. If one of the show methods above have to option to add or edit info, this method must be used to save the data.
  • plgVmOnUpdateOrderLine() is fired from the backend after an order line has been saved. This method must be reimplemented if plgVmOnEditOrderLineShipperBE() is used.
The frontend 1 show method:
  • plgVmOnShowOrderShipperFE() collects and displays specific data about (a) shipment(s)

Below is the list with events and a description on what moment they are fired.

  • plgVmOnSelectShipper() - This event is fired during the checkout process. It allows the shopper to select one of the available shippers.
    It should display a radio button (name: shipper_id) to select the shipper. In the description, the shipping cost can also be displayed, based on the total order weight and the shipto country (this wil be calculated again during order confirmation)
    Return:
    HTML code to display the form
    Parameters:
    1. (VirtueMartCart object) Cart object
    2. (integer, default 0) ID of the currently shipper selected
  • plgVmOnShipperSelected() - This event is fired after the shipping method has been selected. It can be used to store additional shipper info in the cart.
    Return:
    True on succes, false on failures, null when this plugin was not selected.
    On errors, JError::raiseWarning (or JError::raiseError) must be used to set a message.
    Parameters:
    1. (VirtueMartCart object) Cart object
    2. (integer, default 0) ID of the shipper selected
  • plgVmOnShipperSelectedCalculatePrice() - This event is fired after the shipping method has been selected, and when calculating the cart prices.
    Return:
    True on succes, false on failures, null when this plugin was not selected.
    On errors, JError::raiseWarning (or JError::raiseError) must be used to set a message.
    Parameters:
    1. (VirtueMartCart object) Cart object
    2. (integer, default 0) ID of the shipper selected
    3. (array, default 0) Shipping array containing: shipping_name, shipping_value, shipping_rate_vat_id, shipping_currency_id
  • plgVmOnConfirmShipper() - This event is fired after the payment has been processed; it selects the actual shipping rate based on the shipto (country, zip) and/or order weight, and optionally writes extra info to the database (in which case this method must be reimplemented).
    Reimplementation is not required, but when done, the following check MUST be made:
    if (!$this->selectedThisShipper($this->_selement, $_cart->shipper_id)) {
        return null;
    }

    Return:
    The shipping rate ID
    Do not return parent::plgVmOnConfirmShipper($_cart); it is valid but will produce extra overhead!
    Parameters:
    1. (VirtueMartCart object) Cart object
  • plgVmOnShowOrderShipperBE() - This method is fired when showing the order details in the backend. It displays the shipper-specific data.
    NOTE, this plugin should NOT be used to display form fields, since it's called outside a form! Use *plgVmOnUpdateOrderBE()( instead!
    Return:
    Null for shippers that aren't active, text (HTML) otherwise
    Parameters:
    1. (integer) The order ID
    2. (integer) Vendor ID
    3. (object) Object with 2 properties 'carrier' and 'name'
  • plgVmOnEditOrderLineShipperBE() - This method is fired when editing the order line details in the backend. It can be used to add line specific package codes
    Return:
    Null for shippers that aren't active, text (HTML) otherwise
    Parameters:
    1. (integer) The order ID
    2. (integer) The order Line ID
  • plgVmOnUpdateOrderShipper() - Save updated order data to the shipper specific table
    Return:
    True on success, false on failures (the rest of the save-process will be skipped!), or null when this shipper is not actived.
    Parameters:
    1. (array) Form data
  • plgVmOnUpdateOrderLineShipper() - Save updated orderline data to the shipper specific table
    Return:
    True on success, false on failures (the rest of the save-process will be skipped!), or null when this shipper is not actived.
    Parameters:
    1. (array) Form data
  • plgVmOnShowOrderShipperFE() - This method is fired when showing the order details in the frontend. It displays the shipper-specific data.
    Return:
    Null for shippers that aren't active, text (HTML) otherwise
    Parameters:
    1. (integer) The order ID
  • plgVmOnShowOrderLineShipperFE() - This method is fired when showing the order details in the frontend, for every orderline. It can be used to display line specific package codes, e.g. with a link to external tracking and tracing systems
    Return:
    Null for shippers that aren't active, text (HTML) otherwise
    Parameters:
    1. (integer) The order ID
    2. (integer) The order LineID

Other helper functions inherited from the base class:

  • _ createTable() - This method is used to create and maintain the plugin specific database table(s).
    It must be reimplemented by all plugins.
    Example:
    $_scheme = DbScheme::get_instance();
    $_scheme->create_scheme('#__vm_order_shipper_'.$this->_selement);
    $_schemeCols = array(
         'id' => array (
                 'type' => 'int'
                ,'length' => 11
                ,'auto_inc' => true
                ,'null' => false
        )
        ,'order_id' => array (
                 'type' => 'int'
                ,'length' => 11
                ,'null' => false
        )
        ,'shipper_id' => array (
                 'type' => 'text'
                ,'null' => false
        )
    );
    $_schemeIdx = array(
         'idx_order_payment' => array(
                 'columns' => array ('order_id')
                ,'primary' => false
                ,'unique' => false
                ,'type' => null
        )
    );
    $_scheme->define_scheme($_schemeCols);
    $_scheme->define_index($_schemeIdx);
    if (!$_scheme->scheme()) {
        JError::raiseWarning(500, $_scheme->get_db_error());
    }
    $_scheme->reset();
    
  • getThisShipperName() - Get the name of the shipper
    Return:
    Shipper name
    Parameters:
    1. (integer) The Shipper ID
      final protected function ($_sid)
  • writeShipperData() - This method writes all shipper plugin specific data to the plugin's table
    Parameters:
    1. (array) Indexed array in the format 'column_name' => 'value'
    2. (string) Table name
  • getShippingRateIDForOrder() - Get the shipping rate ID for a given order number
    Return:
    The shipping rate ID, or -1 when not found
    Parameters:
    1. (integer) The order ID
  • getShippingRate() - Get the total price for a shipping rate
    Return:
    Price in display format
    Parameters:
    1. (integer) Shipping rate ID
  • getShipperIDForOrder() - Get the shipper ID for a given order number
    Return:
    The shipper ID, or -1 when not found
    Parameters:
    1. (integer) The order ID
  • selectShippingRate() - Select the shipping rate ID, based on the selected shipper in combination with the shipto address (country and zipcode) and the total order weight.
    Return:
    Shipping rate ID, -1 when no match is found. Only 1 selected ID will be returned; if more ID's match, the cheapest will be selected.
    Parameters:
    1. (VirtueMartCart object) Cart object
    2. (integer, default 0) Shipper ID, by default taken from the cart
  • selectedThisShipper() - This method checks if the selected shipper matches the current plugin
    Return:
    True if the calling plugin has the given payment ID
    Parameters:
    1. (string) Element name, taken from the plugin filename
    2. (integer) The shipper ID
  • getOrderWeight() - Get the total weight for the order, based on which the proper shipping rate can be selected.
    Return:
    Total weight for the order
    Parameters:
    1. (VirtueMartCart object) Cart object
  • getShippers() - Fill an array with all shippers found with this plugin for the current vendor
    Return:
    True when carrier(s) was (were) found for this vendor, false otherwise
    Parameters:
    1. (integer) The vendor ID taken from the cart.
  • validateVendor() - Check if this shipper has carriers for the current vendor.
    Return:
    True when a shipper_id was found for this vendor, false otherwise
    Parameters:
    1. (integer) The vendor ID taken from the cart.

Updated by Valérie Isaksen almost 13 years ago · 18 revisions