我有一个程序,我们使用它通过 API 将我们的 Magento 商店连接到我们的后端库存控制系统。目前它所做的是查询 Magento API 以获取所有处于待处理状态的订单,将它们插入后端系统,然后在 Magento 中将它们的状态设置为处理中。由于我们库存系统的限制,我们一次只能插入有限数量的订单。我们通过 if 循环运行整个过程来控制这一点,如下所示(仅供引用,代码已被编辑为仅显示此问题的关键部分):
//The maximum number of orders to download
$iMaxCount = 10 ;
try {
$proxy = new SoapClient($wsdl_url);
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
$sessionId = $proxy->login($login, $password);
//fetch the pending orders from the site
$field = array(array('status'=>array( 'pending') ));
$arr = $proxy->call($sessionId, 'sales_order.list', $field);
$iCnt = 0;
foreach($arr as $key => $value){
//only down up to the max count
if ($iCnt < $iMaxCount) {
[... Do the updating and insertion part of the program ...]
$iCnt++;
} //End of looping through orders
这样做的明显缺点是,即使我只处理其中的 10 个,我仍然必须提取所有待处理订单。即,如果我有 200 个挂单,API 将返回所有 200 个,处理 10 个,然后跳过其余部分。我想要做的是修改 API 调用的过滤器,以便在处理状态时一次只提取 10 个订单。这将允许我删除 if 循环开销并使程序运行更高效,因为它只获取它需要的数据。
有谁知道如何应用那种类型的过滤器?我所看到的一切都表明你只有在知道订单号并据此设置限制的情况下才能这样做。感谢您的帮助!!!
最佳答案
所有 API 调用最终都只是执行 PHP 代码。某处将有一个 PHP 方法接受通过 API 调用传入的参数,因此最好的办法是追踪该 PHP 代码的执行位置。
第 1 步是查找 API 调用的配置。在现代版本的 Magento 中,API 配置保存在名为 api.xml
的文件中
$ find app/code/core/Mage/ -name 'api.xml'
app/code/core/Mage/Api/etc/api.xml
app/code/core/Mage/Catalog/etc/api.xml
app/code/core/Mage/CatalogInventory/etc/api.xml
app/code/core/Mage/Checkout/etc/api.xml
app/code/core/Mage/Customer/etc/api.xml
app/code/core/Mage/Directory/etc/api.xml
app/code/core/Mage/GiftMessage/etc/api.xml
app/code/core/Mage/Sales/etc/api.xml
一旦找到所有 api.xml
文件,搜索它们以确定哪个配置了你的“顶级 api 命名空间”(不确定内部开发人员真正调用的是什么)
$ find app/code/core/Mage/ -name 'api.xml' | xargs grep sales_order
app/code/core/Mage/Sales/etc/api.xml: <sales_order translate="title" module="sales">
app/code/core/Mage/Sales/etc/api.xml: </sales_order>
app/code/core/Mage/Sales/etc/api.xml: <sales_order_shipment>
app/code/core/Mage/Sales/etc/api.xml: </sales_order_shipment>
app/code/core/Mage/Sales/etc/api.xml: <sales_order_invoice>
app/code/core/Mage/Sales/etc/api.xml: </sales_order_invoice>
app/code/core/Mage/Sales/etc/api.xml: <order>sales_order</order>
app/code/core/Mage/Sales/etc/api.xml: <order_shipment>sales_order_shipment</order_shipment>
app/code/core/Mage/Sales/etc/api.xml: <order_invoice>sales_order_invoice</order_invoice>
看起来像app/code/core/Mage/Sales/etc/api.xml
是我们想要的文件,因为它有一个 <sales_order />
标签。接下来,打开文件并查看 <sales_order />
节点。
<sales_order translate="title" module="sales">
<model>sales/order_api</model>
<title>Order API</title>
<acl>sales/order</acl>
<methods>
<list translate="title" module="sales">
<title>Retrieve list of orders by filters</title>
<method>items</method>
<acl>sales/order/info</acl>
</list>
<info translate="title" module="sales">
<title>Retrieve order information</title>
<acl>sales/order/info</acl>
</info>
我们感兴趣的第一个节点是<model>sales/order_api</model>
.这指定了将被实例化以处理 sales_order
中的任何 API 调用的对象。命名空间。
接下来,我们要寻找方法list
在<methods/>
节点。
<list translate="title" module="sales">
<title>Retrieve list of orders by filters</title>
<method>items</method>
<acl>sales/order/info</acl>
</list>
这个节点告诉我们调用sales_order.list
对应方法items
.结合上面找到的信息,我们现在知道 API 调用 sales_order.list
将运行等同于以下内容的 PHP 代码
$m = Mage::getModel('sales/order_api');
$results = $m->items($args);
接下来,打开模型文件并查看 items
方法
#File: app/code/core/Mage/Sales/Model/Order/Api.php
public function items($filters = null)
{
//..a bunch of code to instantiate a collection object..
if (is_array($filters)) {
try {
foreach ($filters as $field => $value) {
if (isset($this->_attributesMap['order'][$field])) {
$field = $this->_attributesMap['order'][$field];
}
$collection->addFieldToFilter($field, $value);
}
} catch (Mage_Core_Exception $e) {
$this->_fault('filters_invalid', $e->getMessage());
}
}
}
在此方法的末尾,您可以看到该方法将遍历每个参数并尝试将其用作集合的过滤器。键是字段,值是搜索的值。如果您检查该方法的其余部分,您会发现没有其他方法可以让参数与集合交互以添加任何类型的分页或限制。
因此,这为您提供了三个选项。第一个是find a set of values传递给
$collection->addFieldToFilter($field, $value);
那会限制你的收藏。我的建议是使用 array('from'=>'10','to'=>'20')
的某种日期过滤器语法。
您的第二个选择是为 Mage_Sales_Model_Order_Api::items
创建类重写做一些额外的过滤。
您的第三个选择是研究创建一个模块,添加一个自定义 API 方法供您调用。
关于php - 控制 Magento API 调用的结果数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7796688/