Thursday 9 April 2009

Models Models, who's got the Models

This all started with the Store model... Mage_Core_Model_Store

Magento has this nifty feature of handling multiple stores on one installation, all with their own configuration. So, naturally you'd think that the store object has access to its own config object. Well, no. It's peppered with calls to $this->getConfig($key) which in turn, calls Mage::getConfig()... the global config object. So, each time it calls it has to descend down the XML node structure 3 levels just to find its own store config, the nodes go like this
global / stores / $storeId

It would be nice to just have a subset of that node plugged onto the object of quick config lookups.

Normally, this would be simple, like pass the global Config object to the constructor of Store and find it's sub path once, then store a reference to it. But, Magento doesn't like constructors, they like the lazy getters instead.

But, Mage does have a 'getModel' method which will lookup the exact class name based on a configruable code and give you and instance... you can even pass an array of parameters to the constructor... cool.

The real problem - which is the whole point of this post - begins here, with getModel()

The App class initializes all the configured stores each request with _initStores(). It loads all stores with a database "Collection". The collection is a special type of itterable object which deals with mutliple objects mapped to database records at a time. Here's the code


$storeCollection = Mage::getModel('core/store')->getCollection()
->initCache($this->getCache(), 'app', array(Mage_Core_Model_Store::CACHE_TAG))
->setLoadDefault(true);

The problem here is two fold. Collections don't pass any arguments to your class's constructor and you need to create an empty object just to get access to the collection object. Mage::getModel('core/store') creates a blank store object, then you call getCollection() which returns Mysql4_Store_Collection object - a subclass of the special Collection object.

Collections are part of the lib/Varien/* family of libraries. They seem to be divorced from knowing anything about the Magento code. But Mage::getModel() is definitely a Magento native function, and it behaves completely differently than the object instantiation of the lib/Varien/Collection class. But they both make the same objects.

There are two ways around this, one is to connect the data collections back into the getModel() smartness of passing arguments. This seems to me like OOP spaghetti code though, as the data loading function is so far down in the collection library that it doesn't know anything about the required parameters. getModel() also doesn't know anything about the parameters, but it will pass any along that you give it.

What's really needed is one (1) consistent way of creating model objects which understands - globally - required constructor parameters. Without this sort of solution we're stuck in a constructor-less mess of getters and setters with no defined entry points to code in the Models.

Thinking about phemto... more later

No comments: