Archive for the ‘Magento’ Category

October 24th, 2008

by Ben

Magento API Calls - Filter Parameters

One of the tasks ReadyToShip regularly needs to do is pull down all the orders from Magento that have been modified since the last time we got them. You would think this would be easy enough to do, since the sales_order.list API call provides a 'filter' parameter, used like so (this is perl but you should be able to easily figure it out for your own language):

my $server = Frontier::Client->new( url => "http://magentourl/api/xmlrpc/", debug => 1 );
 
my $sessionID = $server->call("login", ("username", "apikey"));
 
my $result = $server->call("call", ($sessionID, "sales_order.list", [
    {
        updated_at => {
            from => "2008-10-05 12:49:51"
        }
    }
]));

Unfortunately, the terms you can use are not very well documented. The wiki page gives an example of a 'like' match, but what else can we do with this filter parameter?

Well, I needed to find out so I started digging into the code and I found my way to the Varien_DB library where the SQL was constructed for these filters. And thus, I can deliver to you the following:

Parameters you can pass to a Magento API filter
from returns rows that are after this value (datetime only)
to returns rows that are before this value (datetime only)
eq returns rows equal to this value
neq returns rows not equal to this value
like returns rows that match this value (with % as a wildcard)
nlike returns rows that do not match this value (with % as a wildcard)
in returns rows where the value is in this array (pass an array in)
nin returns rows where the value is not in this array (pass an array in)
is unsure
null returns rows that are null
notnull returns rows that are not null
moreq unsure
gt returns rows greater than this value
lt returns rows less than this value
gteq returns rows greater than or equal to this value
lteq returns rows less than or equal to this value
finset unsure

I hope you find it useful!

 

October 22nd, 2008

by Ben

Writing a Magento Custom API call

I've been doing some work with the open source Magento web store software, mostly to do with their XMLRPC API for our ReadyToShip software. Inevitably, the requirement arised that couldn't be solved by the existing Magento API calls, so it was time to take a look at writing some code and building my own custom api call (as suggested by the Magento documentation).

Unfortunately, the documentation on doing so is kind of sketchy, so it was a slightly frustrating experience, not least because of the complexity of Magento's data structures. I've got a 'Hello World' API call working now though, and this post will have a dual purpose: to help others who have been wrestling with the same problem, and to actually get it straight what I did to get it working!

Before I start, can I just say that Mage::Log is your friend! I figured out a lot of what is going on here by throwing Mage::Log("Bla bla") throughout the existing Magento code.

OK, first steps, here is the directory structure of my custom files:

magento/
  |-- app/
      |-- code/
      |   |-- local/
      |       |-- CompanyName/
      |           |-- ModuleName/
      |               |-- etc/
      |               |    |-- api.xml
      |               |    |-- config.xml
      |               |-- Model/
      |                    |-- ObjectModel/
      |                         |-- Api.php
      |-- modules/
           |-- etc/
                |-- CompanyName_ModuleName.xml

A lot of directories for only 4 new files! But the directory structure is important, as Magento makes use of strict naming conventions to find where it's class and config files are.

OK, let's tell Magento that we're writing a new module, and in doing so, where to find it. Here are the contents of magento/app/etc/modules/CompanyName_ModuleName.xml :

<?xml version="1.0"?>
<config>
    <modules>
        <CompanyName_ModuleName>
            <active>true</active>
            <codePool>local</codePool>
        </CompanyName_ModuleName>
    </modules>
</config>

Pretty simple, huh? From this piece of XML, Magento knows to look in the magento/app/code/local/CompanyName/ModuleName directory for your module.

Next, let's take a look at the config file for our module. Here are the contents of magento/app/code/local/CompanyName/ModuleName/etc/config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <CompanyName_ModuleName>
            <version>0.1.0</version>
        </CompanyName_ModuleName>
    </modules>
        <global>
                <models>
                        <test>
                                <class>CompanyName_ModuleName_Model</class>
                        </test>
                </models>
        </global>
</config>

In this file we're defining an extra variable for our module (I suspect the <modules> section could go in the CompanyName_ModuleName.xml file, actually, as all the XML config is merged together), as well as telling Magento the base class name for the module (this is important to those constantly having Magento look under the Mage/ directory for your class files instead of your company name, a problem I struggled with for quite a while).

Next is the definition of our API call, here are the contents of magento/app/code/local/CompanyName/ModuleName/etc/api.xml:

<?xml version="1.0"?>
<config>
        <api>
                <resources>
                        <resource_name translate="title" module="companyname_modulename">
                        <title>Title Of My Resource</title>
                        <model>modulename/objectmodel_api</model>
                                <methods>
                                        <methodName translate="title" module="companyname_modulename">
                                                <title>Title Of My Method</title>
                                        </methodName>
                                </methods>
                        </resource_name>
                </resources>
        </api>
</config>

I'm still a bit fuzzy on exactly how this section works, but what I do know is that the <model> variable is what tells Magento where your class is. I think the resource name can be whatever you like, and I'm not sure where the module attribute is used as I seem to be able to set it to anything I like and it still works.

Finally, let's look at the API method itself, here are the contents of magento/app/code/local/CompanyName/ModuleName/Model/ObjectModel/Api.php:

<?php
class CompanyName_ModuleName_Model_ObjectModel_Api extends Mage_Api_Model_Resource_Abstract
{
        public function methodName($arg)
        {
                return "Hello World, here is my argument: " . $arg;
        }
}
?>

And there you have it! You can call your method using resource_name.methodName like you would any other API call.

Note: if you have Magento caching turned on, you will need to refresh the cache under System -> Cache Management before the changes to your model will take effect. This caught me out a few times as changes I'd made were not being reflected in the debug output, very frustrating! For debugging purposes I would suggest turning the caching off temporarily.

 

NAVIGATION

Home

Biography

Contact

Albums

Containment Failure

Live at the Starks '07

Reinitialise

Post Archives

Friends

All images, text and music on this page are licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 2.5 Australia License.