magento bug

Most visited products - Issue with performance and flat catalog

Ever had a need to get most visited products within Magento? Most solutions and modules available use a reports/product_collection and addViewsCount() method for this. It does the job until you are in a need for performance or want to enable flat product's catalog.

Flat catalog issue

What is the problem? Using flat catalog change the way how products are read from database. Instead of complex query with multiple joins to get attributes of product build in EAV model, with flat catalog you need no joins to get attributes. And you do query different table.

While for Mage_Catalog catalog/product_collection it was kept in mind that there exists option of flat catalog for Magento, it was forgotten within Mage::getModel('reports/product_collection')->addViewsCount() method. Though you can fix this issue quite easily rewriting collection class, I would like recommend something different.

Performance problem

Mage_Report to get for you most visited products counts occurences for product view event within report_event table. This table is used to store 6 types of events and grows in size very fast. Having a website with 1000 views per hour, report_event table with 400 000 of records, any query using this table was a site performance killer.

Solution

The true problem of using reports/product_collection for calculating visit counts per product is that we mix up two things - events and reports. Solution for this I have chosen is creation of another table with calculated values of views for each product, table which is populated with cron based task making calculation using report_events, and packing this all together into one module.

Turning on modification of products views calculation and flat product catalog in this particular case decreased load of database 10 times.

Magento and PHP 5.3

Your Magento Site is hosted in a shared environment, PHP has been upgraded to 5.3 without any regards, and finally everything seems broken?

Don't panic. Without considering this as normal, the problem is already well known, and actually being corrected if it's not already the case. Theses errors come from pieces of code which have probably been produced a log time ago, and which are using deprecated PHP functions and syntaxes.

In case of emmergency, or if you just can't consider an upgrade, here's how you can fix it:

In "/lib/Varien/Object.php", line ~ 484, replace this method declaration (deprecated syntax):

public function __toString(array $arrAttributes = array(), $valueSeparator=',')

With:

public function __invoke(array $arrAttributes = array(), $valueSeparator=',')

Then, add this method just after __invoke, to be sure that direct call to the __toString method will still work:

function __toString() {
    return $this->__invoke( func_get_arg(0), func_get_arg(1) );
}

Afterwhat, you need to go on "split" function calls hunting, since this one is now forbidden, to replace them with the "explode" function, which works exactly the same way.

Example: in "/app/code/core/Mage/Core/Controller/Request/Http.php" line 274

Replace:

$host = split(':', $_SERVER['HTTP_HOST']);

With:

$host = explode(':', $_SERVER['HTTP_HOST']);

There is several occurencies of "split" to replace, but be careful, don't use a massive replace feature, you would replace occurencies of "preg_split" and "str_split" too, which are both used in Magento core source code, and which are still valids.

Finally, don't forget to check you locals Magento modules too!

Once all these modifications are done, your Magento site should be back online and working.

NOTE: these modifications alter Magento core (especially in "/app/code/core" and "/lib"), so you would be advise to not operating directly on a production.