Php 当从前端或API调用时,Magento模型会给出不同的结果

Php 当从前端或API调用时,Magento模型会给出不同的结果,php,magento,Php,Magento,我创建了一个自定义Magento的API调用来检索与用户关联的报价Id 以下是我在自定义类中使用的代码: public function quoteid($customerId){ $quote = Mage::getModel('sales/quote')->loadByCustomer($customerId); return $quote->getEntityId(); } 通过API调用此函数总是会给我一个空EntityId 以下是我得到的结果: Mage_Sale

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

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

public function quoteid($customerId){
  $quote = Mage::getModel('sales/quote')->loadByCustomer($customerId);
  return $quote->getEntityId();
}
通过API调用此函数总是会给我一个空EntityId

以下是我得到的结果:

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
    (
    )

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

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返回的自定义select对象加载数据,这导致我们找到了罪魁祸首。在_getLoadSelect中,它使用sales/quote模型的getSharedStoreId函数检查是否存在与quote对象关联的存储ID。如果没有任何共享存储,它将不会返回任何报价数据

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

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

public function quoteid($customerId)
{
    $store = Mage::app()->getStore('<store_code>');
    $quote = Mage::getModel('sales/quote')
        ->setStore($store)
        ->loadByCustomer($customerId);
    return $quote->getEntityId();
}
app/code/core/Mage/Sales/Model/Resource/Quote.php


你完全正确。当我调用API时,存储代码是“admin”,当我从前端调用该方法时,存储代码是默认的。我在我的API函数中添加了->setStore,现在它就像一个符咒。因为我想确保我更改的存储只是那个方法,我调用的是singleton,而不是模型,因为我认为singleton的目的是$quote=Mage::getSingleton'sales/quote'->setStore$store->loadByCustomer$customerId;非常感谢你的帮助!我自己真的花了一些时间想弄明白这一点注意getSingleton调用。我认为您实际上应该坚持使用getModel,因为singleton的工作方式是它只创建模型的一个实例。因此,例如,如果您从代码中的任何其他地方调用getSingleton'sales/quote',即使是不同的类和函数,它仍然会返回相同的quote对象!这可能会导致未来出现不可预见的问题。感谢您的反馈。你对getSingleton的误用是完全正确的。我阅读了更多的文档,getModel绝对是我在这里需要的。
/**
 * 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;
}
/**
 * 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;
}