19 September 2012

Developing Magento well

Magento comprises of around 8,000 files, 1,300,000 lines of code and 42,000 methods.  Although it makes use of many Zend Framework libraries, it is actually a very capable, in depth PHP framework in it's own right.  Couple these facts with the very sparse level of good, comprehensive development documentation and the fact that there is a vast mix of both bad and good snippets of development advice out there, and you can begin to imagine why some people have real trouble developing the framework, and also why there are so many badly developed stores out there.

Why are good working practices important when developing a Magento store?  Well, even though the end result may be the same from the point on the view of how the store actually operates, the code itself will be hugely easier to maintain if the store has been built well, it will also make a lot more sense to other developers should someone else come in on the project or take over from you.  I have worked on my fair share of badly developed stores and I can say without doubt that while building the same functionality, stores I take on that have been badly developed take longer to work on than stores that have been developed well.  It is true that a good, experienced developer is likely to charge more for their work than someone who is less experienced or capable, but it is justifiable as Magento really is software that demands significant experience and knowledge to develop well, and that only comes with many hours spent developing client stores.

Having said all that, in fact the main reason for developing a Magento store well is quite simply to make your life easier during an upgrade.  If you haven't yet, at some point you are probably going to have to perform a store upgrade for one of your clients and life is going to be a lot easier if upgrading a robust, solidly customised store than one with development issues that need to be ironed out first.

So here are my recommendations for developing a store well, this quick guide doesn't give any code examples it just discusses good working practice, but if you would like code examples leave a comment or get in touch and I will see what I can do.  I may also intermittently add extra points as and when I think of them.

The first three points are just general principles, while the rest are specific to developing Magento.

1. Make your code readable

Don't underestimate the importance of properly indenting the code you write.  When returning to a class or method you have written after a break or having someone else work on it, proper indentation makes everything a lot easier to follow and saves you time.

Some people go for tabs to indent their code, personally I use 4 space indents as this gives the most consistent rendering across different editors and IDE's, but the important thing here is to not mix the two.

2. Comment your code

Don't go overboard, but do include comments in your code.  Again this is about helping you or other developers out who work on what you have written.  Commenting can really speed up the process of becoming familiar with code and should remove the need to sometimes follow logic through probably a number of different classes and methods in order to understand what is going on.

3. Achieve one thing with one method

Keep your methods specific with their purpose being to achieve one thing only.  If you find a method is becoming too general having more than one purpose, break it up into as many methods as required ensuring each achieves just one thing.  This keeps your classes clear and accessible.

4. Use developer mode

Enabling developer mode will force you to write cleaner code with execution halting even for E_NOTICE level errors.  Realistically you may not be able to have it enabled all of the time as there are quite a few third party extension developers (including some very well known ones) out there who don't seem to have it enabled when they develop so you may well find you have third party extensions installed that throw E_NOTICE level errors.

5. Keep logic out of templates

Template files should be used purely for rendering out prepared data, you shouldn't be doing much more in here with PHP than outputting calls to block methods and running a few PHP functions.  Not only does this keep the template files clean and readable, but it also means that you can easily assign a new template to the relevant block file and still have access to all the same methods and therefore data.

Unfortunately when taking on a badly developed store, one of the most common things I have found is that the template files are full of code that should instead be found in blocks or helpers - it's generally just a tell tale sign of a lack of understanding of the Magento MVC architecture.  However something it's useful to remember when new to Magento is that all block files just perform a simple PHP include on the template file assigned to them (have a look in Mage_Core_Block_Template).  This gives you direct access to all the block methods via $this and makes it really easy to keep your templates clean.

6. Use observers first

There are a few different ways in which you can affect the results of calls to core methods, but the less impact you can have on the way that core code runs the better.  While editing core methods is never the right thing to, using an observer is pretty much the best way of achieving this.  It requires no code changes in any existing methods and instead allows you to run a listener method at specific points in a multitude of processes Magento runs.  Inside this method you can access relevant objects, which can be manipulated as required before letting the code run on using that modified object.  Pretty much any process that involves running a core module is going to allow you to use observers, you can also use them in third party modules as there are very general observers such as for when loading any model.

7. Then use rewrites

If using observers isn't possible or practical which it isn't always, the second best method is to use rewrites.  This does require modification of existing methods, but rewritten instead to run from a different file you define.  The good thing about rewrites is that it allows you to override just the methods you need to leaving all the other core methods in the class untouched and running from the original file you have rewritten.  When using this method you should in almost every case extend the class for the new file off the rewritten files class giving access to all of the original files methods and variables (except private of course).

Quite often you will find that the method you are overriding will return some data to the calling method, so where possible run the method you are overriding using parent:: modifying data before or after this (you may want to modify arguments passed to the parent method, or the result returned from calling the parent method).  Doing this means that your rewritten method functions similarly to an observer in that it leaves the core code intact and running as before, but allows you to modify data as required.  Note that this kind of approach is not always possible however.

8. Only then use local branch overrides

If using either observers nor rewrites is possible, then moving files from under app/code/core to the equivalent location under app/code/local will result in the local branch file being called instead of the core branch file.  This approach is more heavy handed and more likely to cause issues during an upgrade than the previous two thus should only be used when absolutely necessary.  An example of this might be when needing to modify an abstract class where there are no relevant observers as rewrites cannot be used here.

9. Use the right classes for the right things

Another sign of an inexperienced developer is having methods do the wrong things in the wrong classes, for instance building and manipulating collections in block files when this should be done in the relevant model.  Learn about each of the types of file Magento has, how they are linked and what they are designed to be used for.

10. Use local.xml for your layout

It's very likely you have used layout files in a theme which override core layouts, however using local.xml is a better way of achieving the same thing.  The benefit here is that it means that core layout files are left untouched, with only the required sections being modified via local.xml.  You can do everything in local.xml you can do in standard layout file and there are only a very small set of circumstances where it cannot be used (one for instance is when the standard layout file calls the addTab() method - there is unfortunately no removeTab() method to call as the reverse, although of course you could create one).

So that pretty much sums it up, hope you found it helpful.


  1. I've heard about Magento a couple of times. I admit I'm not a specialist when it comes to it but the article has proven to be quite helpful.