We’ve all been in a situation where we had to include a 3rd party Magento extension into our project. And we surely had some doubts whether that extension was a good choice or not. When I say a ‘good choice’ I’m not referring only to the functional component of the extension, but to the code quality component as well. I have seen many extensions doing what their description said they’d be doing, but they were doing it in a very wrong way.
Integrating a 3rd party module can cost less in terms of development time and the benefit is immediate, but it can also lead to the other side of the coin where the extension’s code induces issues in the current project, it may disrupt other components’ functionality or it can cost more time to debug or to scale up.
When choosing an extension, I go through a list of criteria that I think are relevant in helping me decide whether to include the extension in the current project or not. I will share this list with you and I hope it will help you to safely integrate 3rd party extensions into your codebase.
- I try to find an extension which is free or at least has a ‘money-back’ policy that will allow me to ‘return the product’ if it doesn’t satisfy my requirements.
- I take a careful look at the extension’s description section. I first pay attention to grammatical correctness (if the description has poorly constructed sentences, I get the impression that the vendor is not trustworthy or that they don’t pay respect to their future clients). Other things I take into consideration are the level of detail in the description, the clarity of the text and the screenshots. After checking these, you’ll be able to tell right away if this is a professional vendor who cares about their customers or not, and also if this description has actual technical information that you can use or just marketing ‘sugar-coating’. I look for extensions that offer demo sites where you can play with the functionality a little bit and see if it suits your needs (at a first glance at least).
- Another thing I pay attention to is the release notes section. If the extension hasn’t been updated in recent years, then I assume the support was dropped and, if I have problems, then no one will help me (especially if the extension is not free).
One other thing I usually check is the community feedback on the extension I want to integrate. This might not always apply as there are very good extensions that might satisfy your project’s needs but they are so young and do not have any feedback yet.
If you have experience with other modules released by a certain vendor, you might also have a general idea on how their extensions are ranked by the community.
I look for reviews and users’ feedback on extensions mostly on forums or on the extensions’ Magento Connect pages. I find that a vendor’s page can be biased and that reviews approved for display don’t always reflect the truth (thumbs down for doing that, guys).
What I look for specifically is possible problems that other people might have experienced with that extension, from installation to later life-cycle issues.
As a side note, I strongly advise you to contribute and write a review on every extension you analyze. Whether it’s good or bad, it will surely help the community and force vendors to raise or keep their standards high.
This one is pretty straight forward. The vendor description should offer details about the Magento version compatibility. You should choose an extension compatible with your Magento installation. There are cases where the Community compatible extensions work in the Enterprise versions too, but I advise you to choose wisely and be aware of differences between the Magento C.E. and E.E. features, so that you don’t invite bugs in.
PHP version compatibility
You should also check whether the extension’s code is compatible with the PHP version your project uses. I use the PHP Migration script to perform the static PHP version check. This script will offer you a report with all the identified issues, including the severity level and the PHP version that introduced the new standard (PHP from 5.3 to 7.0).
Other applications integrations
Cross browser compatibility requirements
If the extension offers frontend functionality, it should specify the major browser’s compatibility, which should be at least equal to your minimum browser version requirements. Otherwise, you might find yourself in the situation where the layout is all messed up because the extension doesn’t offer support for that browser version.
Encrypted extensions should be avoided as their codebase is obfuscated and it’s impossible to test, extend, debug or understand. You are supposed to trust a vendor’s description and hope for the best, while the code can hide serious security issues, bad logic implementations and can really affect the integrity of your shop.
I can’t trust a piece of code which does not reveal itself, as I work on projects where I have to debug production level issues. I can’t just tell the clients there is nothing I can do as we can’t see the code and we have to wait for the extension support team to provide a fix (which might help or might not) while the business is suffering and the extension is having its own way.
Another reason why you should avoid these kinds of extensions is that they slow down the system. This behavior can be observed especially with files encrypted with Ioncube and the penalty is obvious as, every time a PHP file is required, this encoding system will duplicate the time needed to open the file (the file gets opened by PHP and then by Ioncube again).
Code quality and style
The first components I am concerned with when checking the code are the style and quality, so I conduct a code review process prior to any 3rd party extension integration.
I use PHP CodeSniffer with ECG coding standard for Magento for static code analysis. The script performs a two-component analysis (Zend and Magento standards) and will identify the most common coding problems, such as:
- Coding style violations
- Direct usage of PHP superglobals or dangerous functions
- Direct SQL usage
- Direct object instantiation
- Model load(), save() and delete() methods or array counts inside loops
- Cyclomatic complexity over limits
- Inefficient methods usage on large data sets
- getFirstItem() collection method usage without collection limiting
and many, many more.
You should always check for usage of unsanitized data coming from inputs like: $_GET, $_POST, $_COOKIE, $_REQUEST and $_FILES. Improper input validation introduces vulnerabilities such as:
- SQL injection in methods like mysql_query() (I know… extensions should not execute SQL queries without Magento resource support, but I have seen such types of usage, unfortunately)
- Cross-site scripting in methods like file_get_contents(), file_put_contents(), echo, die, exit, print or printf
- Cross-site request forgery in forms without a form_key input
- Local and remote file inclusions or path traversals in methods like include_once(), include(), require_once(), require(), file_get_contents(), file(), copy() or unlink()
- PHP code injection in eval() method
- OS command injection in methods like exec() or shell_exec()
I use a rather old school way to check for these methods’ usage, which is manual search 🙂 But it pays off.
Another relevant component is related to the current Magento standards implied by security patches (which can change the ‘rules of the game’, like SUPEE-6788 did). So the extension should follow the up-to-date security standards.
Magento extensions should also provide the foundation for an easy future maintenance in terms of bugs prevention, isolation and facile debug possibility.
One condition for reaching maintainability is a good documentation. Now, this is a subjective topic, as there is such a thing as ‘self documenting code’ and there are extensions small enough to be easily understood by using proper naming and code readability, but I think all Magento extensions should provide a technical documentation and a fully documented code (docblocks for classes and methods as well as code comments and usage examples). This not only guides the future programmers in understanding the code and behavior, but it also represents a standard.
Another component is the way the solution was created with respect to system checks and fallbacks in case of breakdown. The solution should respond to questions like:
- What happens if the extension is disabled?
- If a functionality which passes data from one system to another is introduced, what happens if the webserver suddenly doesn’t respond? Is there a way to send that data later, after system recovery?
- If there are external application integrations (such as SOLR or Elasticsearch), what happens if the application ceases to respond?
The extension’s code should allow future development by other programmers. From what I’ve seen, problems occur when the method access level is not declared properly. Of course, private methods should process the current object’s states while not exposing the intermediary result to the outside, but let’s take this example: an extension with just one model class retrieves some data in a public method. The public method uses 3 other private methods. If you want to change the public method, you will need a rewrite for that method, right? But not only that… You will need to copy all the private methods as well, as you don’t have access to them via rewrite. This will suppress the extensibility of that module if an upgrade occurs. The upgrade will not be aware of the rewrite, thus the applied update will have no effect.
One other problem I faced is related to observers declaration. You can configure an observer by specifying the full class name or by using the < model_alias >/< class > reference. If you have the full class name in the configuration and you need to change something in the observer method, you will not be able to do it by normal rewrite. You will need to disable that observer and bind your own on the same event.
When adding a 3rd party extension in your project, you should always be aware of the dependencies it introduces and make sure they are treated properly. If the extension needs another module’s resources, it should have that dependency declared, otherwise you are vulnerable to a system crash if the required resource module is disabled.
This check can be done by accessing the ‘app/etc/modules/’ file and making sure that the ‘<depends>’ tag encloses the required resource’s module name.
Extensions are not just adding new functionality to the current project, but they are very often modifying Magento’s default behavior in order to respond to business requirements. This can be achieved by rewriting the core classes but, as you should know, the new extension may not be the first one to rewrite the resources, as most of the time a Magento shop is customized by various extensions (3rd party or internal ones).
What I check here is the list of rewrites and rewrite conflicts reported by the magerun tool (using dev:module:rewrite:list and dev:module:rewrite:conflict options) and make sure that the rewrites are consistent and don’t introduce conflicts. If they do, I plan on how to solve them by creating a proper workaround that will allow me to have the functionality in the existing code and the one added by the 3rd party extension without breaking any of them.
Another way to add functionality or to change the existing one is to listen to Magento dispatched events. What needs to be checked here is that the observers do not introduce bugs or big load time (a behavior I‘ve noticed on _after_save and _before_load entity events).
Pay attention to this, for every open integration point, such as a Magento event, makes the system vulnerable. The code inside observers should always contain checks and should be optimal. The observers should be declared in the appropriate scope. That is, if the observer is meant to work only in the admin area, it should be declared in the ‘adminhtml’ scope, not in the ‘global’ scope that will make it take effect on frontend access as well.
If the extension adds cronjobs tasks managed by Magento cron, I advise you to understand what the crons are going to do and try to imagine the scenario at production level.
I have encountered many extensions causing problems by processing large amounts of data and consuming the system resources, disrupting critical operations like price and stock ERP updates which were also managed by Magento cron tasks. There were cases where I had to keep the extension and the other functionalities up and running, so if you find yourself in this situation, check the solution I implemented here.
I always check the actions performed inside install or upgrade scripts. It may be a column being added to a core table or a column alteration; in any case, I advise you to acknowledge these changes (especially to Magento core tables) and to make sure they don’t disrupt the current implementations in your project (for example, introducing deadlocks on heavily used tables as sales_flat_order) and cause data loss.
Sometimes you’ll find entities data being added inside install or upgrade scripts (such as new attribute initial data on products). You should always be aware of these changes as they might trigger other operations like large data volume partial reindex or, if the processing takes too long and is too heavy, it might exceed the php.ini maximum execution time or memory allocation. The code inside these scripts should be optimal.
Helper classes should be used for translation or minimal utilitary functionality and should not process entity data. Keep in mind that Magento instantiates these classes as singletons. I have seen helpers acting like models in many 3rd party extensions as a false impression of code reuse.
Models, Blocks, Controllers
The code added into these classes should respect the MVC design pattern, meaning that the controllers should handle only layout load, request and response objects processing, models should be in charge of all data processing, and blocks should reference models for data extraction that must be displayed. You might wonder why I introduced this paragraph in the first place. Everyone knows what these classes should do. Well… not everyone. Sadly, there are extensions loading models or processing request data in their blocks or template files and controllers connecting directly to database.
The code inside these classes should be optimally implemented and the system’s performance should not be visibly affected (yes, this can be noticed without even testing the extension by tracing the code for unnecessary loads or non optimal data processing).
New files being written
You should check whether the extension writes files that are not images (reports, data extraction .csvs, logs) into the project’s public locations such as the ‘media’ folder. They will be automatically visible to everyone if no other interventions are performed (like HTTP authentication requirement or location change by rewrite).
Moving towards frontend functionality at last :). I’ve seen some extensions create a new design theme where the layout and templates are added and then guide you via a readme file on how to configure Magento to use that theme so that the extension will work.
I advise you not to follow these instructions as you most likely already have a custom theme declared and being used. By switching to the extension theme, you will lose your custom theme’s functionality. If the extension adds a new theme, you should copy those files inside your theme so that the extension will work properly.
If the template files are placed into the ‘base’ or ‘default’ packages and the extension overwrites core template files which are also overwritten by your theme, you should beware that a manual intervention is needed in order to keep what you already have and what the extension adds.
You should check the layout .xml file the extension adds, understand which pages and blocks are affected and check if they really exist in your theme.
You might find yourself in the situation where the block referenced by the extension was removed from your theme. Or in the situation where your current implementation replaces a controller route and the extension adds functionality to the old one (I have seen this happen in one page checkout extensions).
Another issue that might occur is related to core blocks being used or totally replaced in the layout .xml file. You should check if this is the case and plan a workaround for this, otherwise the existing functionality of the referenced pages might be affected or broken.
Meeting the requirements
Works as described on the vendor’s page
If the code analysis proved that the extension is worthy of being added to the project, I move one step further and integrate the code into the existing codebase.
Once installed and all the custom interventions that might have been required are added, it’s time to check the functionality.
I have seen extensions allowing multiple functionalities in a single package and the business needing only a few of them. You should make sure the other functionalities are also checked even if they are not needed now. Skipping this step can let bugs pass without being noticed at first, and later on it can disrupt the shop’s activity, being harder to fix.
Just check all the classes that are extended and perform a general functionality testing of the shop making sure it’s not altered in an undesired way.
You should always test the extension with developer mode and Magento debug logging on. I recommend that you keep Magento’s system.log and exception.log files open, as well as the webserver error.log and the browser console throughout the testing process. The extension should not introduce errors, untreated exceptions or warnings.
Of course, I had the great pleasure of working with really good extensions. I learned a lot from their professional approach and I had access to great support teams. While this article underlines the bad practices I personally encountered, it is far from my intention to generalize the idea that all modules are bad or to discredit the hard working people who respect the community and the standards, and provide good quality extensions.
3rd party extensions could save you development time and offer very useful functionalities which will empower your shop and satisfy your business needs. The market is full of thousands of such extensions, you just have to choose one. But choose wisely and give yourself some time to analyze it thoroughly. It will surely pay off.
This was my list of criteria I am looking for when choosing a 3rd party extension. What is yours?
by Diana Botean
The article was originally published here.