VirtueMart: fix tricky conflict between OPC and Finalize plugins
A little time ago I had to fix a tricky conflict between two VirtueMart add-ons, namely OnePageCheckout and Finalize.
By fixing tha, i learned an important lesson on how to write your plugin. So I definitely think the all process it's worth sharing.
One Page Checkout for VirtueMartj
Made by Rupostel, OPC is a very handy suite of extensions for VirtueMart (component + plugin) that keeps your checkout process in one page.
Truth to be told, the code could do with a bit of refactoring, but it does its job and has a nice selection of themes to suit all tastes.
Of course it's quite complex because it has to control many parts of the checkout.
This - we'll see in a minute - it's one of the cause for the conflict.
Finalize for VirtueMart
Made by DayCounts, Finalize is a much simpler plugin that lets your user restart the payment process for pending order.
In other words, when a customer is looking at her order details and that order is still pending payment, she can see all the available methods to complete the payment.
In the e-commerce world, making life easier for customers is very important and this plugin is a reccomended add-on.
OPC is so complex that it has its own hooks; when some things happen in the component, some events are launched so that other parts of the component may be invoked.
One of this event is named getPaymentMethods.
Finalize it's much simpler and only does a few things on core Joomla events: onAfterDispatch, onBeforeRender and onAfterRender.
But... it has also a few helper methods.
By "helper method", I refer to all methods in a plugin which are not directly hooked to an event (if you know a bit about writing Joomla plugins you know what I mean, if not stay tuned because I may write something about it soon).
And by sheer coincidence, one of this methods is called "getPaymentMethods".
And since the Finalize plugin is a system plugin, it's always loaded; and when OPC launch the "getPaymentMethods" event, Finalize respond as well - but it's not supposed to.
Uh-oh, checkout broken.
Who's fault is this?
I do not like very much the choice of "getPaymentMethods" for an event name. And this is not a trivial sin: the more I learn about development, the more I can see that correct naming is one of the most important things.
But then again, creating a public helper method in your plugin class is also questionable.
So the important lesson for DayCounts, myself and everyone who writes Joomla plugins:
- in your plugin main file, only event handlers methods should be public, all other should be private
- even better, create a separated helper class so that your plugin main file contains only event handlers
The quickest fix in this case was just to rename the method in the Finalize plugin as finalizeGetPaymentMethods, and change the one line of code that called it.
We already mentioned this to the DayCounts people so they should fix it in the next versions.
I hope everything was clear enough, if you have questions or want to add your thoughts please feel free to let me know!