A few thoughts about code quality

While working with Magento I see a lot of 3rd party software (Magento extensions). I must say that the code quality in general is very poor. It’s not that poor as in WordPress in the old days but it’s bad. I’m not even talking about following Magento Coding Standard. I’m talking about simple and basic things:

  1. PHP code that produces ERR in Magento log is to be considered broken. 
  2. PHP code that produces WARN in Magento log is to be considered nearly broken and dangerous.
  3. HTML code that does not validate is to be considered broken.
  4. JS is simple – if some JS is broken on they thru parsing then very likely the rest of it (all other libs, scripts) won’t be parsed correctly. It’s very visible in the frontend.
I cannot accept it. 
What to do? Educate yourself, check your code, use CodeSniffer, write Unit Tests and check the logs.

Write better log when developing Magento extensions

I’ve noticed that just a few developers add proper logging to their Magento extensions and libraries. Also – Magento core team is not part of those developers. Their logging habits are quite poor. I’m sorry, guys, but Magento is really bad when it comes to logging. Compare it to any J2EE project with proper Log4J set up and you’ll see the difference. Sometimes it’s good to learn from those old n’ bald Java guys, also:) OK, so much ranting this time… Now to the logging.

Is I said – Magento gives you tough times when it comes to debugging and searching for problems. Basically it just does not output any useful info to log files. It makes our – developers’ – life hard.

It is in our own hands to do it better because there are tools existing in Magento but these are regrettably underused.

What needs to be logged?

First – all problems and errors.
Whenever you use try/catch then please do write exception to log. Please do write all requests to API-s and responses. This would really help. There’s a special helper for logging exceptions: Mage::logException(Exception $e)
Use at least that one although it just spits randomly formatted Exception to var/log/exception.log. I recommend to use the solution below for exception logging also. Just change the Zend log priority to Zend_Log::CRIT or Zend_Log:ERR.

Second – debug log. When you develop anything then it’s really good to log output of some methods, input parameters that come from Ajax queries and so on. So it’s partly your little helper during development and it’s also part of good coding practices.

Here I have an advice for you about how to log. Do it like this and I’ll exlain why:

Mage::log(sprintf('%s(%s): %s', __METHOD__, __LINE__, print_r($var, true)), Zend_Log::DEBUG, 'mymodule.log');

Now I explain the format. After you have written a considerable amount of code you start noticing that you don’t need some debug lines any more. When you do logging without __METHOD__ and __LINE__ then you need to search thru all your source to find where the f*** did you add that line that outputs “OK” to log… And of course it just helps to discover problems quicker when you see __METHOD__ (which contains class (==file) information) and the line number in the code.
$var in print_r is your variable that you want to log. Be careful with large Magento objects! Because Magento object model is built so that it contains almost everything in every object and does that recursively then it would kill your PHP. Be warned!
Then there’s Zend_Log::DEBUG which is log priority level. Magento does not do smart logging that would consider log priority levels. But at least the log priority is displayed in the log file because Magento’s self log format is like that:
$format = '%timestamp% %priorityName% (%priority%): %message%' . PHP_EOL;

And the last parameter is file name. I support module-based logging. When I’m in a good mood I do logging to 2 files: my module’s log file and system.log. So the system.log would contain ALL logs and my module’s log file would contain logs from my module only.

Third – when you want to get really anal regarding all possible issues in your code then you want to log all notifications, too.

When in trouble then there’s never too much log. It’s really easy to set up log rotation in Linux or OSX systems so the large files aren’t a problem (now I gave you an idea for a good Magento extension;))

Upcoming topics in Measure9

In order to keep interest high I’d like to shed some light to upcoming topics at Measure9:

  • Magento Unit testing and Continuous Integration with Atlassian Bamboo CI
  • Automated acceptance testing in a Magento Development Project (w behat, mink, Gherkin)
  • Syncing content and configuration between Magento instances
  • Tools used in Magento development projects
  • Processes that lead to successful Magento projects
  • and much more…
Thx,
Sven \m/

Standardized order export format for Magento

Background, rationale

Sometimes I dream that all integration processes would be standardized… Currently it’s not quite there yet but let’s do some first steps towards it.
I work a lot with Magento, architecture, analysis, integrations. Every customer thinks that he’s so special and to some extent they are. But they’re not when it comes to integrations. I want all customers to be the same when it comes to API-s, schemas, protocols. Not all external systems (ERP-s, accounting, shipping providers etc) provide an API to send orders so files are still needed for integration.

Magento Order XML Export Schema

In order to start standardizing order exporting from Magento I’ve created a XML schema that can be used to create and validate produced order XML file on both ends. It’s important to validate XML on the receiver’s end, too. It allows the receiving system to notice errors in XML format earlier and send notifications to sending system so that actions can be taken. When you need your orders to be imported to your ERP then you don’t want hear “silence” for weeks but you need your files moving all the time.
The idea behind XML Export is very simple – whenever an order is placed a file is generated and after that it’s up to other extensions and systems to do anything with that file.
Here is the schema:
< ?xml version="1.0" encoding="UTF-8"?>
          elementFormDefault=”qualified” targetNamespace=”http://eepohs.com/schemas/dx/order”           xmlns=”http://eepohs.com/schemas/dx/order”>
   
   
       
           
               
               
           
           
           
                          use=”required” fixed=”2.0″ />
       
   
   
   
   
       
           
                        minOccurs=”1″>
           
           
                        type=”xs:dateTime”>
           
           
           
           

           
           
       
   
   
   

   
   
       
           
                        minOccurs=”1″>
           
           
                        minOccurs=”1″>
           
           
                        minOccurs=”1″>
           
           
                        minOccurs=”1″>
           
           
                        minOccurs=”1″>
           
           
                        maxOccurs=”1″ minOccurs=”0″>
           
       
   
   
       
           
       
   

   
       
           
                        minOccurs=”1″>
           
           
                        maxOccurs=”1″ minOccurs=”0″>
           
           
                        maxOccurs=”1″ minOccurs=”0″>
           
           
                        minOccurs=”0″>
           
           
                        minOccurs=”0″>
           
       
   

   
       
           
                        minOccurs=”1″>
           
           
                        minOccurs=”1″>
           
           
                        minOccurs=”1″>
           
           
                        minOccurs=”1″>
           
           
                        minOccurs=”0″>
           
       
   

   
       
           
                        minOccurs=”1″>
           
           
                        minOccurs=”0″>
           
           
                        minOccurs=”0″>
           
       
   
   
   

   
       
           
                        minOccurs=”1″>
           
           
                        minOccurs=”0″>
           
           
                        minOccurs=”0″>
           
           
           
                        type=”xs:dateTime” maxOccurs=”1″ minOccurs=”0″>
           
       
   
   
Here is that schema for download:
This is the first draft.

More information about outputted XML and the simple order export extension will be posted here soon.

Feedback is welcome!