Magento模型在从前端或API调用时给出不同的结果


Magento Model gives different results when called from frontend or API

我创建了一个自定义Magento的API调用来检索与用户关联的报价ID。

以下是我在自定义类中使用的代码:

public function quoteid($customerId){
  $quote = Mage::getModel('sales/quote')->loadByCustomer($customerId);
  return $quote->getEntityId();
}

通过 API 调用此函数总是给我一个空的实体 ID。

这是我得到的结果:

Mage_Sales_Model_Quote Object
(
[_eventPrefix:protected] => sales_quote
[_eventObject:protected] => quote
[_customer:protected] => 
[_addresses:protected] => 
[_items:protected] => 
[_payments:protected] => 
[_errorInfoGroups:protected] => Array
    (
    )
[_preventSaving:protected] => 
[_resourceName:protected] => sales/quote
[_resource:protected] => 
[_resourceCollectionName:protected] => sales/quote_collection
[_cacheTag:protected] => 
[_dataSaveAllowed:protected] => 1
[_isObjectNew:protected] => 
[_data:protected] => Array
    (
    )
[_hasDataChanges:protected] => 
[_origData:protected] => Array
    (
    )
[_idFieldName:protected] => 
[_isDeleted:protected] => 
[_oldFieldsMap:protected] => Array
    (
    )
[_syncFieldsMap:protected] => Array
    (
    )
)

但是,如果我使用我知道的 customerId 从前端调用相同的代码行(我在索引中添加这些行.php并在我的网站上加载一个页面(,我会得到一个结果

Mage_Sales_Model_Quote Object
(
[_eventPrefix:protected] => sales_quote
[_eventObject:protected] => quote
[_customer:protected] => 
[_addresses:protected] => 
[_items:protected] => 
[_payments:protected] => 
[_errorInfoGroups:protected] => Array
    (
    )
[_preventSaving:protected] => 
[_resourceName:protected] => sales/quote
[_resource:protected] => 
[_resourceCollectionName:protected] => sales/quote_collection
[_cacheTag:protected] => 
[_dataSaveAllowed:protected] => 1
[_isObjectNew:protected] => 
[_data:protected] => Array
    (
        [entity_id] => 1234
        .... (ALL THE DATA HERE)
    )
[_hasDataChanges:protected] => 1
[_origData:protected] => 
[_idFieldName:protected] => 
[_isDeleted:protected] => 
[_oldFieldsMap:protected] => Array
    (
    )
[_syncFieldsMap:protected] => Array
    (
    )
)

我的问题是:- 你知道为什么使用相同的参数调用的相同方法会产生不同的结果,无论我从前端还是从 API 调用它?

我的猜测是,这与以下事实有关:通过前端,商店已完全加载,而在 API 调用中则不是。我会通过向您的函数添加 Mage::log() 调用来验证这一点,以查看加载了哪个存储:

Mage::log(Mage::app()->getStore());

这将是一个问题的原因在于loadByCustomer()的行为方式。跟踪loadByCustomer()函数,您会发现它只是包装了资源模型的同名函数。查看资源模型的函数,我们看到它尝试从 _getLoadSelect() 返回的自定义选择对象加载数据,这导致我们找到罪魁祸首。在_getLoadSelect()中,它使用sales/quote模型的getSharedStoreIds()函数检查是否存在与报价对象关联的商店 ID。如果没有任何共享存储,它不会返回任何报价数据!

那么,如何确保共享存储 ID 存在?好吧,如果您的 API 加载了错误的商店,您只需在报价对象上调用 setStore() 并传入有效的存储对象,然后再尝试按客户 ID 加载报价。

这可能看起来像这样(替换为您的商店代码或 ID(:

public function quoteid($customerId)
{
    $store = Mage::app()->getStore('<store_code>');
    $quote = Mage::getModel('sales/quote')
        ->setStore($store)
        ->loadByCustomer($customerId);
    return $quote->getEntityId();
}

源代码引用如下:

应用/代码/核心/法师/销售/模型/报价.php

/**
 * Loading quote data by customer
 *
 * @return Mage_Sales_Model_Quote
 */
public function loadByCustomer($customer)
{
    if ($customer instanceof Mage_Customer_Model_Customer) {
        $customerId = $customer->getId();
    }
    else {
        $customerId = (int) $customer;
    }
    $this->_getResource()->loadByCustomerId($this, $customerId); // HERE!
    $this->_afterLoad();
    return $this;
}
...
/**
 * Get all available store ids for quote
 *
 * @return array
 */
public function getSharedStoreIds()
{
    $ids = $this->_getData('shared_store_ids');
    if (is_null($ids) || !is_array($ids)) {
        if ($website = $this->getWebsite()) {
            return $website->getStoreIds();
        }
        return $this->getStore()->getWebsite()->getStoreIds();
    }
    return $ids;
}

应用程序/代码/核心/法师/销售/模型/资源/报价.php

/**
 * Load only active quote
 *
 * @param Mage_Sales_Model_Quote $quote
 * @param int $quoteId
 * @return Mage_Sales_Model_Resource_Quote
 */
public function loadActive($quote, $quoteId)
{
    $adapter = $this->_getReadAdapter();
    $select  = $this->_getLoadSelect('entity_id', $quoteId, $quote) // HERE!
        ->where('is_active = ?', 1);
    $data    = $adapter->fetchRow($select);
    if ($data) {
        $quote->setData($data);
    }
    $this->_afterLoad($quote);
    return $this;
}
...
/**
 * Retrieve select object for load object data
 *
 * @param string $field
 * @param mixed $value
 * @param Mage_Core_Model_Abstract $object
 * @return Varien_Db_Select
 */
protected function _getLoadSelect($field, $value, $object)
{
    $select   = parent::_getLoadSelect($field, $value, $object);
    $storeIds = $object->getSharedStoreIds(); // HERE!
    if ($storeIds) {
        $select->where('store_id IN (?)', $storeIds);
    } else {
        /**
         * For empty result
         */
        $select->where('store_id < ?', 0);
    }
    return $select;
}