控制Magento API调用的结果数

Gre*_*ick 10 php api magento

我有一个程序,我们用它通过API将我们的Magento商店连接到我们的后端库存控制系统.目前它所做的是查询Magento API以获取处于Pending状态的所有订单,将它们插入后端系统,然后将其状态设置为Magento中的Processing.由于我们的库存系统存在限制,我们一次只能插入有限数量的订单.我们通过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
Run Code Online (Sandbox Code Playgroud)

这样做的明显垮台是我仍然必须拉出所有待定订单,即使我将只与其中的10个一起工作.即如果我有200个待处理订单,API将返回所有200个订单,处理10,然后跳过其余订单.我想要做的是修改API调用的过滤器,在状态处理时只抽取10个订单.这将允许我删除if循环开销并使程序运行更有效,因为它只获取它需要的数据.

有谁知道如何应用这种类型的过滤器?我见过的所有内容都建议您只有在知道订单号并基于此设置限制时才能执行此操作.谢谢你的帮助!!!

Ala*_*orm 18

所有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
Run Code Online (Sandbox Code Playgroud)

一旦找到所有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>
Run Code Online (Sandbox Code Playgroud)

它看起来像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>
Run Code Online (Sandbox Code Playgroud)

我们感兴趣的第一个节点是<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>
Run Code Online (Sandbox Code Playgroud)

这点告诉我们,调用sales_order.list对应的方法items.结合上面的信息,我们现在知道API调用sales_order.list将运行与以下相同的PHP代码

$m = Mage::getModel('sales/order_api');
$results = $m->items($args);
Run Code Online (Sandbox Code Playgroud)

接下来,打开模型文件并查看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());
        }
    }        
}
Run Code Online (Sandbox Code Playgroud)

在此方法结束时,您可以看到该方法将遍历每个参数并尝试将其用作集合的过滤器.关键是字段,值是值搜索.如果您检查方法的其余部分,您将看到参数与集合交互以添加任何类型的分页或限制.

所以,这给你留下了三个选择.第一个是找到一组要传入的值

$collection->addFieldToFilter($field, $value);
Run Code Online (Sandbox Code Playgroud)

这会限制你的收藏.我的建议是使用array('from'=>'10','to'=>'20')语法的某种日期过滤器.

你的第二个选择是创建一个类重写,Mage_Sales_Model_Order_Api::items这会做一些额外的过滤.

您的第三个选择是调查创建一个模块,该模块添加了一个自定义API方法供您调用.

  • 这是回归API方法的精彩101,Alan.我相信它对许多用户非常有帮助(至少对于那些在询问^^之前真正使用搜索的用户).+1并添加到收藏夹. (5认同)