7

Today, I am running into the following problem: A module I developed works very well in a Magento 1.7 version store. Now, I need to adapt it to also work with a Magento 1.5 store.

One point at which the compatibility runs apart is in my collection where I am exending the class Mage_Core_Model_Resource_Db_Collection_Abstract. This class does not exist in Magento 1.5, but it has some nice functionality like getMainTable(). One thing I could do is to instead use the class Varien_Data_Collection_Db which is inherited from in Mage_Core_Model_Resource_Db_Collection_Abstract. This works, but then I cannot use the getMainTable() method anymore - even not in the 1.7 store where it actually exists.

How do you handle such version specific quirks? It seems absurd to write a custom class which implements the stuff version 1.7 already has and thereby duplicate code in that version. On the other hand, it is bad not to have the function and use worse coding habits like hard-coding instead. So, is there any good approach in writing Magento modules which are backwards-compatible?

9

You could create an intermediary class that implements all the functions that you require and depending on the version of magento call parent's implementation or use your own implementation:

model/Int.php

<?php
  if (!version_compare(Mage::getVersion(), '1.7', '>=')) {
    class N_M_Model_Int extends Mage_Core_Model_Resource_Db_Collection_Abstract
    {
    }
  } else {
    class N_M_Model_Int extends Varien_Data_Collection_Db
    {
      public function getMainTable()
      {
        // my implementation
      }
    }
  }
?>

model/Final.php

<?php
  class N_M_Model_Final extends N_M_Model_Int
  {
    // common code between all the versions
  }
?>
  • 1
    That's a fairly elegant solution to an ugly problem – philwinkle Feb 5 '13 at 14:43
  • Nice solution. Small detail: version_compare should not be negated in the if condition because that version is actually the newest. Also, one should note that this code does not test for Enterprise compatibility. – Lucasmus Sep 9 '13 at 0:10
3

This is perhaps not the exact answer you are looking for, but I can't imagine many people are developing extensions for older versions.

Just upgrade, its inevitable anyway

The obvious solution is for the 1.5 customer to upgrade to 1.7 (1.5 is a horribly broken release anyway).

But if you must

If we had to tackle it, it would just be a case of backing up the module with a secondary foundation module to back-port the core functionality that you require. Then when the time comes to upgrade, the dependency module could merely be deleted/removed.

The downsides being that you could potentially end up overriding abstract classes merely to add/modify a single function. The time invested in this could well be on par with just upgrading the store to begin with.

In terms of making extensions backwards compatible - it seems an odd practice - as you be making compromises for newer releases. Extensions tend to age naturally, so that rather being back-wards compatible; you develop upon it to make it forwards compatible.

If you've ever looked at the source code of 3rd party modules; they tend to be filled with Mage::getVersion() calls and conditional statements - all to be multi-version compatible. Its messy and should be avoided. In all reality - you should have different versions of extensions, for different versions of Magento. Otherwise you'll be faced supporting an extension that has deviations in class methods and an increasing number of conditional statements.

Although here's a good example of why not

I understand your logic. But what happens in cases such as the 1.4.1 > 1.4.2 upgrade and the EAV sales tables were dropped. Any newer functions operated on the basis of this table now being flat - so trying to back-port this is far more hassle than its worth. This may be an extreme and you'll clearly make a judgement call on how much time to invest.

The latest version of Magento is forever going to be a moving target and given the choice between making new modules work with older stores - or older modules work with newer stores. I know what we'd rather do. Deprecation of functions is slow and graceful and you have plenty of time to make them newer.

  • 1
    Writing a backwards compatible code is usualy far simpler than convincing a client to go to a newer version of his/here store. You mostly have issues that they already have third party extensions that don't work out of the box with a newer version of magento so they feel reluctant to upgrade. Besides backporting is not as complex as developing something new so backporting some functionality from later versions of magento is always an option - with it you can write code for the latest version of magento while still keeping back compatibility. – Domen Vrankar Feb 5 '13 at 14:49
  • I understand your logic. But what happens in cases such as the 1.4.1 > 1.4.2 upgrade and the EAV sales tables were dropped. Any newer functions operated on the basis of this table now being flat - so trying to backport this is far more hassle than its worth. The latest version of Magento is forever going to be a moving target and given the choice between making new modules work with older stores - or older modules work with newer stores. I know what we'd rather do. Deprecation of functions is slow and graceful. – Ben Lessani - Sonassi Feb 5 '13 at 15:34
  • I agree with you and I'd say that we're both right :) It depends on how extensive the changes to a certain part of Magento were and what kind of module you are writing - extending core functionality or writing your own functionality that is only loosly influenced by changes to magento. In the end it depends on situation and the amount of investment required :) – Domen Vrankar Feb 5 '13 at 15:55
  • My 2 cents: I have a client that is stuck on 1.5 specifically because an extension they are using to connect to their point of sale. I'd love to have them upgrade to the latest version, but they cannot, due to this one extension. Unfortunately, there will always be scenarios like this, so it's not as easy as having them upgrade – CCBlackburn Feb 6 '13 at 3:40
1

What you are facing is pretty easy to fix. Starting 1.6 some Mysql4 classes were moved on to Resource classes but backward compatibility is still supported as Magento developers have done the necessary.

For Mage_Core_Model_Resource_Db_Collection_Abstract classes use Mage_Core_Model_Mysql4_Collection_Abstract instead

For Mage_Core_Model_Resource_Db_Abstract classes use Mage_Core_Model_Mysql4_Abstract instead

If you go to those Mysql4 classes you will find that they are blank and are just extending the Resource classes properly

Hope this helps you out

0

In addition to Domen Vrankar's answer, you can also do something like:

<?php

if (!version_compare(Mage::getVersion(), '1.7', '>=')) {
    $code = "\nclass N_M_Model_Int extends Mage_Core_Model_Resource_Db_Collection_Abstract\n";
} else {
    $code = "\nclass N_M_Model_Int extends Varien_Data_Collection_Db\n";
}

$code .= <<<FEED
{
    //class implementation

} // END OF CLASS
FEED;

eval ( $code );

Not sure someone would prefer this method, but I've seen SweetTooth Rewards do this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.