我有一个程序,可用于通过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/

10-11 20:08
查看更多