HowTo upgrade your VirtueMart2 plugin to VirtueMart3
This is a quick overview of several necessary changes when upgrading a VirtueMart2 plugin to VirtueMart3. The following list is by no means meant to be complete, it is just a list of all changes I had to do to upgrade my plugins to VM3. Much of this material comes straight from Milbo's blog "Code adjustments for VirtueMart 3".
This page does NOT try to list all differences needed to upgrade the plugin(s) from Joomla 2.x to Joomla 3. For this, we refer e.g. to https://techjoomla.com/joomla-development/joomla-30-conversion-changes-needed-when-converting-a-common-installable-package-for-joomla-15x-a-25x-to-joomla-30.html
The largest changes to VirtueMart are:
- VM3 uses Joomla 2 and 3's <config> tags in the plugin's xml file (VM2 used Joomla 1's <params> tags)
- VM3 introduced some new triggers (mostly similar to those from VM2, just with changed function signature)
- The custom fields sytem was completely changed internally
- The cart system was completely changed (affects mainly templates)
VM2 |
VM3 (+backwards compatibility with VM2) |
All Plugins |
|
|
|
<install version="1.5" type="plugin" group="vmcustom" method="upgrade"> ... </install> |
<extension version="2.5" type="plugin" group="vmcustom" method="upgrade"> ... </extension> |
|
|
<params addpath="/administrator/components/com_virtuemart/elements"> <param type="vmjpluginwarning" /> |
<vmconfig> <fields name="params" addfieldpath="/administrator/components/com_virtuemart/fields"> <fieldset name="shipment" label="VMSHIPMENT_RULES_PLUGIN_ADV" > <field type="spacer" default="VMSHIPMENT_RULES_PLUGIN_ADV" level="level1"/> ... </fieldset> </fields> </vmconfig> |
|
|
if (!class_exists('ShopFunctions')) require(JPATH_VM_ADMINISTRATOR . DS . 'helpers' . DS . 'shopfunctions.php'); class JElementVmLengthUnit extends JElement { var $_name = 'LengthUnit'; function fetchElement($nm, $selected, &$node, $control_name) { $html = "<input>...</input>"; return $html; } } |
defined('DS') or define('DS', DIRECTORY_SEPARATOR); if (!class_exists('ShopFunctions')) require(JPATH_VM_ADMINISTRATOR . DS . 'helpers' . DS . 'shopfunctions.php'); class JFormFieldVmLengthUnit extends JFormField { var $_name = 'vmLengthUnit'; protected function getInput() { $html = "<input>...</input>"; return $html; } } |
|
|
<files> ... <folder>elements</folder> </files> |
<files>
...
<folder>elements</folder>
<folder>fields</folder>
</files>
|
|
|
$var = JRequest::getInt('your_param', 0); |
$var = JFactory::getApplication()->input->getInt('your_param', 0); |
$field = $customfieldsModel->getProductCustomField ($virtuemart_customfield_id); |
$field = customfieldsModel->getCustomEmbeddedProductCustomField($virtuemart_customfield_id); |
Renamed general Triggers, Functions, Methods and Members |
|
function plgVmOnUpdateOrder($data, $old_order_status) |
function plgVmOnUpdateOrderPayment($data, $old_order_status) |
Shipping plugins |
|
|
|
- |
function plgVmDeclarePluginParamsShipmentVM3 (&$data) {
return $this->declarePluginParams ('shipment', $data);
}
|
|
|
$address = (($cart->ST == 0) ? $cart->BT : $cart->ST); |
if (method_exists($cart, 'getST')) { |
Custom field plugins |
|
Some database fields have changed. In the constructor, change "custom_params" to "customfield_params": | |
$this->setConfigParameterable ('custom_params', $varsToPush); |
if(!defined('VM_VERSION') or VM_VERSION < 3){ $this->setConfigParameterable ('custom_params', $varsToPush); } else { $this->setConfigParameterable ('customfield_params', $varsToPush); } |
In plgVmOnProductEdit change the HTML controls' names from custom_param to customfield_params: | |
$this->parseCustomParams($field); ... 'custom_param['.$row.'][your_param_name][]' |
if (!defined('VM_VERSION') or VM_VERSION < 3) { $this->parseCustomParams ($field); // Not needed in VM3! $paramName = 'custom_param'; } else { $paramName = 'customfield_params'; } ... $paramName.'['.$row.'][your_param_name][]' |
Several new triggers: | |
function plgVmDeclarePluginParamsCustom($psType,$name,$id, &$data){ return $this->declarePluginParams('custom', $name, $id, $data); } |
function plgVmDeclarePluginParamsCustomVM3(&$data){
return $this->declarePluginParams('custom', $data);
}
|
- |
function plgVmGetTablePluginParams($psType, $name, $id, &$xParams, &$varsToPush){
return $this->getTablePluginParams($psType, $name, $id, $xParams, $varsToPush);
}
|
function plgVmOnDisplayProductFE( $product, &$idx,&$field){ ... } function plgVmOnDisplayProductVariantFE($field,&$row,&$group) { ... } |
function plgVmOnDisplayProductFEVM3(&$product,&$group) {
// NO $this->parseCustomParams($field); needed any more!
..
}
|
$field = $customfieldsModel->getProductCustomField ($virtuemart_customfield_id); |
if (!defined('VM_VERSION') or VM_VERSION < 3) { // VM2 |
function plgVmDisplayInOrderFE($product, $row, &$html) { |
function plgVmDisplayInOrderFEVM3(&$product, &$productCustom, &$html) { |
$customs = $customModel->getproductCustomslist ($item->virtuemart_product_id); |
if (method_exists($customModel, 'getCustomEmbeddedProductCustomFields')) { // V3.x $customs = $customModel->getCustomEmbeddedProductCustomFields (array ($item->virtuemart_product_id)); } else { $customs = $customModel->getproductCustomslist ($item->virtuemart_product_id); // V2.x } |
To modify the price of a product with a custom field, you now need to use the plgVmPrepareCartProduct trigger and change the modificatorSum variable: | |
public function plgVmCalculateCustomVariant($product, &$productCustomsPrice, $selected){ |
public function plgVmPrepareCartProduct(&$product, &$customfield,$selected,&$modificatorSum){ |
Input controls (on the product page to let the customer enter specific values, like a custom text) have a different form control name customProductData instead of customPlugin (typically this needs to be changed in the template called by renderByLayout, e.g. in /plugins/vmcustom/yourplugin/yourplugin/tmpl/default.php) and have a different array structure: | |
$name='customPlugin[' . $viewData[0]->virtuemart_customfield_id . '][' . $this->_name . ']'. |
if (!defined('VM_VERSION') or VM_VERSION < 3) { // VM2: |