branko ajzele, senior developer / project manager

Posts / Articles

Magento collection filters and XmlRpc webservice

For the last 2-3 weeks, most of my work was related to custom Zend Framework based project for one of our client. Today I decided to play around with Magento.

Before I start with sample code and screen shots, keep in mind that all my sample code is placed in app/design/frontend/default/custom/template/catalog/product/view.phtml file. There is no particular reason for this, I was simply to lazy to separate it in external file, independet of Magento since I was not in the mood of configuring Zend Framework class auto loading in case I need to call something from Zend.

Anyhow, let’s get to it.

Assumptions: You have Magento installed, you have setup Webservice user and assign it a role, password and so on, you are accessing XmlRpc service instead of the Soap.

Below is the most basic call to Magento XmlRpc, it enables you to establish a session to Magento’s Webservice:

$client = new Zend_XmlRpc_Client('http://server/store/index.php/api/xmlrpc/');
$session = $client->call('login', array('remoteu', 'remotepass'));

If login was successful, $session variable will hold session id value. From this point on, you can use this id value to call other methods available trough XmlRpc. Let’s look at the another example.

This example builds on the first one by using the obtained session id to call catalog_product class and it list method.

$client = new Zend_XmlRpc_Client('http://server/store/index.php/api/xmlrpc/');
 
$session = $client->call('login', array('remoteu', 'remotepass'));
 
$filterData = array('type' => 'simple');
 
$products = $client->call('call', array($session, 'catalog_product.list', array($filterData)));
 
var_dump($products);

If your call went ok, then your $products variable should now contain array of arrays representing products, each arrar holding some piece of product related information.

xmlrpc-s1

Moving forward, I will not into the details of calling methods over the XmlRpc. I will focus on the filter part. Note the $filterData variable. Can we write that expression somehow different? Sure we can.

$client = new Zend_XmlRpc_Client('http://server/store/index.php/api/xmlrpc/');
 
$session = $client->call('login', array('remoteu', 'remotepass'));
 
$filterData = array('type' => array('in' => 'simple'));
 
$products = $client->call('call', array($session, 'catalog_product.list', array($filterData)));
 
var_dump($products);

Last two examples return same results. However, this one opens so much more possibilities. We transformed the expression array(‘type’ => ‘simple’) to array(‘type’ => array(‘in’ => ‘simple’)). This enables us to place multiple conditions for one type of field, in this case field called “type”.

Imagine now, if we wanted to get two of our somehow special products with one call. We could execute the following code to get it:

$client = new Zend_XmlRpc_Client('http://server/store/index.php/api/xmlrpc/');
 
$session = $client->call('login', array('remoteu', 'remotepass'));
 
$filterData = array(
    'url_key'   => array('nine-west-women-s-lucero-pump', 'ink-eater-krylon-bombear-destroyed-tee')
);
 
$products = $client->call('call', array($session, 'catalog_product.list', array($filterData)));
 
var_dump($products);

Above could would retrieve two products whose url_key values correspond to those written in array.
xmlrpc-s2

Let’s look at our array(‘type’ => array(‘in‘ => ‘simple’)) expression one more time. Where does the “in” part come from? Are there more of these “filter switches”? Yes there are, lot more. And here is the list:

  • “from”=>$fromValue, “to”=>$toValue
  • “like”=>$likeValue
  • “neq”=>$notEqualValue
  • “in”=>array($inValues)
  • “nin”=>array($notInValues)
  • “eq”=>$equal
  • “nlike”=>$notlike
  • “is”=>$is
  • “gt”=>$greaterthan
  • “lt”=>$lessthan
  • “gteq”=>$greterthanequal
  • “lteq”=>$lessthanequal
  • “finset”=>$unknown
  • “date”=>true, “to” => $now

Here is a sample code (copy-paste) from Salesrule.php file (line 67-77):

$collection = $_saleRule->getResourceCollection()
						->addFieldToFilter('from_date', array('date'=>true, 'to' => $now))
						->addFieldToFilter('website_ids',array('finset' => $websiteId))
						->addFieldToFilter('customer_group_ids', array('finset' => $custGroup))
						->addFieldToFilter('is_rss',1)
						->addFieldToFilter('is_active',1)
						->setOrder('from_date','desc');
$collection->getSelect()->where('to_date is null or to_date>=?', $now);
$collection->load();

Notice the use of “finset” and “date” filter usage in above code. Now combine these filters with XmlRpc method calls that accept array of filters and you get quite powerful queries over the Webservice.

Finally, before I wrap this up, one more important thing to keep in mind. Let’s look at our second code sample at the beginning of this article where we called catalog_product.list medhod. No matter what valid filter we pass to function, as a result you will always get certain fields. THis does not mean your filters wont return you right products, it simply mean you wont get product’s date value if you filtered by date, although you will get products from certain date range.

For catalog_product.list medhod you would get following fields: product_id, sku, name, set, type, category_ids. This is due to the reason that the return fields are hard coded. You can see that for mentioned method if you open the file app/code/core/Mage/Catalog/Model/Product/Api.php (line 76-90):

$result = array();
 
foreach ($collection as $product) {
	//$result[] = $product->getData();
	$result[] = array( // Basic product data
		'product_id' => $product->getId(),
		'sku'        => $product->getSku(),
		'name'       => $product->getName(),
		'set'        => $product->getAttributeSetId(),
		'type'       => $product->getTypeId(),
		'category_ids'       => $product->getCategoryIds()
	);
}
 
return $result;

Try changing ‘sku’ to ‘custom_ sku’ in this file then refresh your page that shows result to service call.

xmlrpc-s3

Hope this was helpful.

View Comments

  1. Can you tell me anything about creating orders via the API? I can’t seem to find a sales_order.create method or anything similar..?? I need to get orders from a 3rd party system into Magento. Any info would be great. Thanks!!

  2. Hey Branko,

    You forgot ‘nlike’ in the list above. On another note I can’t, for the life of me, figure out a way on my own or find a working example/documentation on how to add multiple fields of the same type to the same field, particularly with the like/nlike filter types.

    i.e. sales_order.list, array(array(‘title’ => array(‘nlike’ => array(‘%value1%’, ‘%value2%’)))

    which seems logical, does work. as do many other alternatives i’ve tried. hrm… any ideas?

  3. correction above: ‘…does *not* work…’

  4. Great examples using XmlRpc from the Zend Framework with Magento. Much needed when SOAP isn’t an option.

  5. vijayk /

    hai
    can u please tell me how to sum and group the field value using Mage::getModel,

    And also tell how to list main table field value while using Mage::getModel

  6. Rolando Garro /

    Im trying the following to get downloadable and enabled product list.

    $filters = array('type_id' => array('like'=>'downloadable'),'status'=>'disabled');
    //get product list
    $result= $this->SoapClient->call($this->SoapSession, 'catalog_product.list',array($filters));

    But is not working, not sure if status filter is correct.

    Any clue would be great. Thanks!!

  7. dizalamba /

    can you make a simple example web service using xml RPC,,,,
    may be it easier for me to understand how to code web service using xml rpc,,,
    thanks before,,,,

blog comments powered by Disqus