IIRC:
visitor_id
is NULL when it is a customer, thus customer_id
is not NULL.
customer_id
is NULL when it is not a logged in customer, thus visitor_id
is not NULL.
The case where both are NULL is not an easy one.
The vistor_id
is retrieved from the Mage_Log_Model_Visitor
class.
The only possibility that comes to my mind is that it is a visitor
that has an excluded user agent, which means that is a bot (like Google Bot).
As you can see from the constructor, the request logging is skipped in that case:
protected function _construct()
{
$this->_init('log/visitor');
$userAgent = $this->_httpHelper->getHttpUserAgent();
$ignoreAgents = $this->_config->getNode('global/ignore_user_agents');
if ($ignoreAgents) {
$ignoreAgents = $ignoreAgents->asArray();
if (in_array($userAgent, $ignoreAgents)) {
$this->_skipRequestLogging = true;
}
}
if ($this->_logCondition->isLogDisabled()) {
$this->_skipRequestLogging = true;
}
}
The ignored user agents are defined under app/code/core/Mage/Log/etc/config.xml
and are the following:
Finally, the case where both are not NULL
From what I understood, it happens in the following case:
- logged out customer visits a product page
- leaves the website
- comes back and logs in as a customer
- revisits the same product page
In that case, Magento will keep both values.
The visitor data is later set to NULL when the customer logs out with the following code:
public function purgeVisitorByCustomer(Mage_Reports_Model_Product_Index_Abstract $object)
{
/**
* Do nothing if customer not logged in
*/
if (!$object->getCustomerId()) {
return $this;
}
$bind = array('visitor_id' => null);
$where = array('customer_id = ?' => (int)$object->getCustomerId());
$this->_getWriteAdapter()->update($this->getMainTable(), $bind, $where);
return $this;
}