我创建了一个自定义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;
}