我需要在magento数据上创建大量自定义报告.
我要做的第一项工作是改进集成到Magento的"查看产品"报告.
我已经设法确定该报告的数据来自'report_event'表,但是我需要了解这些数据的一些特点.
首先,我假设event_type_id为1(即根据参考表的'catalog_product_view'),列object_id和subject_id分别存储产品的ID和访问者的ID.但是,subject_id为零的条目数量很多,但object_id保存有效产品的id.
我需要知道的是如何发生这种情况......即如何在report_event表中获取以下全部为真的条目:
event_type_id = 1
object_id = [有效产品ID]
subject_id = 0
非常感谢您的期待
硅
TL; DR:
甲report_event.subject_id == 0通常是任一种的结果忽略用户代理,或明确地排除的路由触发通常会被记录由Magento的一个事件.
见app/code/core/Mage/Log/etc/config.xml:
<config>
<global>
<!-- : -->
<ignoredModules>
<entities>
<install/>
<adminhtml/>
<admin/>
</entities>
</ignoredModules>
<ignore_user_agents>
<google1>Googlebot/1.0 (googlebot@googlebot.com http://googlebot.com/)</google1>
<google2>Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)</google2>
<google3>Googlebot/2.1 (+http://www.googlebot.com/bot.html)</google3>
</ignore_user_agents>
<!-- : -->
</global>
</config>
Run Code Online (Sandbox Code Playgroud)
为了解释为什么会发生这种情况,我需要详细介绍.
当即将调度任何Magento控制器操作时,controller_action_predispatch将在实际发生操作的调度之前触发事件.
再看看app/code/core/Mage/Log/etc/config.xml:
<config>
<frontend>
<events>
<controller_action_predispatch>
<observers>
<log>
<class>log/visitor</class>
<method>initByRequest</method>
</log>
</observers>
</controller_action_predispatch>
<!-- : -->
</events>
</frontend>
</config>
Run Code Online (Sandbox Code Playgroud)
显示,Mage_Log模块定义了controller_action_predispatch事件的观察者,由方法表示Mage_Log_Model_Visitor::initByRequest():
public function initByRequest($observer)
{
if ($this->_skipRequestLogging || $this->isModuleIgnored($observer)) {
return $this;
}
$this->setData($this->_getSession()->getVisitorData());
$this->initServerData();
if (!$this->getId()) {
$this->setFirstVisitAt(now());
$this->setIsNewVisitor(true);
$this->save();
}
return $this;
}
Run Code Online (Sandbox Code Playgroud)
当发送当前请求的用户代理与其中一个(GoogleBot)匹配时,该属性$this->_skipRequestLogging将是.true<ignored_user_agents />
该方法$this->isModuleIgnored()只返回true,如果请求路由匹配的一个<ignoredModules />(即install/,adminhtml/或者admin/;在EE也api/).
关键是,如果其中一个都返回true,则观察者立即退出,即根本不会创建/保存访问者.
现在,为了进一步解释使用您的catalog_product_view案例作为示例,请查看另一个配置文件,app/code/core/Mage/Reports/etc/config.xml这次:
<config>
<frontend>
<events>
<catalog_controller_product_view>
<observers>
<reports>
<class>reports/event_observer</class>
<method>catalogProductView</method>
</reports>
</observers>
</catalog_controller_product_view>
<!-- : -->
</events>
</frontend>
</config>
Run Code Online (Sandbox Code Playgroud)
它定义了catalog_controller_product_view事件的观察者,由Mage_Reports_Model_Event_Observer::catalogProductView()方法表示
:
public function catalogProductView(Varien_Event_Observer $observer)
{
$productId = $observer->getEvent()->getProduct()->getId();
Mage::getModel('reports/product_index_viewed')
->setProductId($productId)
->save()
->calculate();
return $this->_event(Mage_Reports_Model_Event::EVENT_PRODUCT_VIEW, $productId);
}
Run Code Online (Sandbox Code Playgroud)
该观察者的最后一行调用该_event()方法:
protected function _event($eventTypeId, $objectId, $subjectId = null, $subtype = 0)
{
if (is_null($subjectId)) {
if (Mage::getSingleton('customer/session')->isLoggedIn()) {
$customer = Mage::getSingleton('customer/session')->getCustomer();
$subjectId = $customer->getId();
}
else {
$subjectId = Mage::getSingleton('log/visitor')->getId();
$subtype = 1;
}
}
$eventModel = Mage::getModel('reports/event');
$storeId = Mage::app()->getStore()->getId();
$eventModel
->setEventTypeId($eventTypeId)
->setObjectId($objectId)
->setSubjectId($subjectId)
->setSubtype($subtype)
->setStoreId($storeId);
$eventModel->save();
return $this;
}
Run Code Online (Sandbox Code Playgroud)
看看这个else块,尤其是这一行:
$subjectId = Mage::getSingleton('log/visitor')->getId();
Run Code Online (Sandbox Code Playgroud)
当访问者根本没有被创建/保存时,由于被忽略的用户代理或被排除的路由,那么$subjectId将是null.
由于表列subject_id定义为NOT NULL(请参阅app/code/core/Mage/Reports/sql/reports_setupSQL脚本),0因此最终将保存.
这是因为MySQL 的数据类型默认值.