Magento: First Impressions
Magento is a (if not the) open source shopping cart web-app out there. I've been developing a couple of different custom solutions based on it over the last few months, so here are my first impressions of Magento.
A short preface: you tend to notice things which get in your way or you've been used to and suddenly aren't available when you try a new platform. I've come from developing .NET ASP MVC sites, so some of the following gripes are closely related to that transition.
One good, one bad, and one ugly thing about Magento.
Magento is a very well featured platform out of the box. Credit card functionality, web service interfaces, complete catalog and search functions, email templates, and a back end admin section which is a beast unto itself! The amount of code I have not touched is a testament to how much Magento provides out of the box, no changes or additions required.
The mechanism to extend Magento uses dependency injection and quite fine grained class overrides. This promises great things on a product upgrade. I've experienced all too often the overhead of upgrading a 3rd party framework you've built your product on or around. It got to the point where I refuse to upgrade such frameworks unless there is a clear feature my client can benefit from or its a glaring security hole. We'll see how well Magento does in this regard when that upgrade comes!
The only slight problem with all that functionality was the giant configuration page. It was intimidating enough for me as a developer, but the site owner needed a training session to run through the main options. Even then, feature requests meant a 5 minute check through all the config options to see if it was possible by tweaking an option somewhere in the config pages!
Oh, and it has themes / templates. I'm still learning the current best practises for web layout, so I'm all too happy to let someone else do most of the layout for me!
In a word: documentation. Or lack thereof.
Such a powerful system requires some way to learn how to use it. Now I'd be a fool for thinking I could learn everything about Magento in one project, but I'd assume such a large product (with a community behind it) would have some basic developer tutorials. Alas no! Well, finding them for the current version was basically impossible. And the ones I came across were basically "here's the XML and directory structure you'll need, now you're on your own". It's very hard to find what anything means (indeed, the author of such articles were often unsure themselves!), rather, you just fiddle about with stuff until it does (mostly) what you want.
Perhaps the best introduction to Magento I found was on Alan Storm's site. He walked through what the meaning of the various config tags were, how to do some basic database queries, the MVC structure, and how to extend functionality. Even so, there were things he simply didn't cover (Magento is big, remember!) such as how particular functions are overridden and how to query custom attributes and custom options for products (which I do a lot of in my projects).
An important part of developing on a framework is moving from copying-and-pasting example code and hoping it works to understanding how to naturally work with the framework, how to discover new functionality within it, how to really get your head around how it works. After 2 months of developing for Magento, I don't feel like I've reached that stage yet.
Discovering functionality in Magento should be in their technical documentation. But it was never very useful (mainly because it just lists classes and methods with only superficial documentation, which meant I had to delve into the source code anyway). Google and Stackoverflow were much better resources.
I guess I'm used to using a combination of MSDN and Intellisense to discover functionality. And its amazing how powerful pressing . on an object is. Discovering an API goes from minutes reading a book / online documentation (or hours if it's poorly documented!) to seconds); a boon to productivity. It's true Microsoft's doco can be hit and miss at a very high level (their charting component is easiest to learn by blog post and example), but when you get deep into an API, especially in the BCL, every class and method has some level of documentation. And it's improved over time.
Methods silently failing.
This is a cardinal sin for developers. And is responsible for advancing my ever approaching baldness and consuming hours of debugging time. A method must either do what it says or fail with an error, anything else is simply evil. Two cases in point:
LoadByAttribute vs Load
$prodByAttr = Mage::getModel('catalog/product')->loadByAttribute('sku', 'some-sku')
$prodById = Mage::getModel('catalog/product')->load(12345)
I would assume both of these did the same thing. "Load" is the verb and "by attribute" is simply a way of describing how I want to load my product.
This is not the case. Loading by attribute returns a subset of a product (basically, enough to populate a browse catalog page). Loading by Id loads the entire product. The case which caught me out was this (assuming the above code refers to the same actual product):
$opts1 = $prodByAttr->getOptions(); // $opts1 is always an empty array
$opts2 = $prodById->getOptions(); // $opts2 contains custom options definitions for the product
I can't find where this behaviour is documented. And if, as a developer, I can't quickly and easily notice those two methods are slightly different, I'm going to get frustrated very quickly.
This relates to the above code. I want to add a product with some custom options:
$buyParms = array();
$buyParms['qty'] = 1;
$buyParms['options'] = array(
$this->getCustomOptionId($prodById, 'StartDate') => $startDate,
$this->getCustomOptionId($prodById, 'Locations') => $locations
$Mage::getSingleton('checkout/session')->getQuote()->addProduct($prodById, new Varien_Object($buyParms));
That should work, right? Maybe.
Depends on what the data type of the custom options are. If the StartDate is a date type rather than a text field, the above code won't work. Well, it will run, won't throw any exceptions, but just not add the product to the cart.
That's right, no error, no hint that I've done something wrong, just silentl failure. Epic Fail.
(To make it work I think you need to set a sub-property on StartDate called 'date' to the date value, but I never made it work, I just changed the custom option to a text field and admitted defeat).
To sum up, Magento is a powerful and well featured web cart. But as a developer, way too much still feels like magic. And when the magic goes wrong, its really really hard to figure out why and how to fix it. Magento really needs to improve the API documentation and shout it from the roof tops so every developer knows about it. Perhaps then it can call itself the open source shopping cart.