pxloft Posted March 26, 2015 Share Posted March 26, 2015 Is there a reason why a product in the "Most Viewed" section of the dashboard would repeat itself? I am on Prestashop 1.6.0.11 I have attached a screenshot so you can see what I'm talking about. Please help. Thank you. Link to comment Share on other sites More sharing options...
maiolif Posted March 28, 2015 Share Posted March 28, 2015 Same issue also to me. Issue found on 1.6.0.11, now running 1.6.0.14, same situation. Tried to remove dashboard module, clean cache, then reinstall but without result. Any idea? Link to comment Share on other sites More sharing options...
pxloft Posted March 28, 2015 Author Share Posted March 28, 2015 Is there anybody here that can help us? Moderator? Link to comment Share on other sites More sharing options...
PascalVG Posted March 29, 2015 Share Posted March 29, 2015 (edited) Looks like they don't GROUP (SQL) the data. Have no data to try it, but maybe someone try to add (red code): edit file: /modules/dashproducts/dashproducts.php (Make backup!!) public function getTotalViewed($date_from, $date_to, $limit = 10) { $gapi = Module::isInstalled('gapi') ? Module::getInstanceByName('gapi') : false; if (Validate::isLoadedObject($gapi) && $gapi->isConfigured()) { $products = array(); // Only works with the default product URL pattern at this time if ($result = $gapi->requestReportData('ga:pagePath', 'ga:visits', $date_from, $date_to, '-ga:visits', 'ga:pagePath=~/([a-z]{2}/)?([a-z]+/)?[0-9][0-9]*\-.*\.html$', 1, 10)) foreach ($result as $row) { if (preg_match('@/([a-z]{2}/)?([a-z]+/)?([0-9]+)\-.*\.html$@', $row['dimensions']['pagePath'], $matches)) $products[] = array('id_object' => (int)$matches[3], 'counter' => $row['metrics']['visits']); } return $products; } else return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' SELECT p.id_object, pv.counter FROM `'._DB_PREFIX_.'page_viewed` pv LEFT JOIN `'._DB_PREFIX_.'date_range` dr ON pv.`id_date_range` = dr.`id_date_range` LEFT JOIN `'._DB_PREFIX_.'page` p ON pv.`id_page` = p.`id_page` LEFT JOIN `'._DB_PREFIX_.'page_type` pt ON pt.`id_page_type` = p.`id_page_type` WHERE pt.`name` = \'product\' '.Shop::addSqlRestriction(false, 'pv').' AND dr.`time_start` BETWEEN "'.pSQL($date_from).'" AND "'.pSQL($date_to).'" AND dr.`time_end` BETWEEN "'.pSQL($date_from).'" AND "'.pSQL($date_to).'" GROUP BY p.`id_object` LIMIT '.(int)$limit); } As said, haven't tried, but give it a try. My 2 cents, Pascal Edited March 29, 2015 by PascalVG Changed type of comma used... (see edit history) Link to comment Share on other sites More sharing options...
HUHA Posted April 19, 2015 Share Posted April 19, 2015 (edited) Looks like they don't GROUP (SQL) the data. Have no data to try it, but maybe someone try to add (red code): edit file: /modules/dashproducts/dashproducts.php (Make backup!!) public function getTotalViewed($date_from, $date_to, $limit = 10) { $gapi = Module::isInstalled('gapi') ? Module::getInstanceByName('gapi') : false; if (Validate::isLoadedObject($gapi) && $gapi->isConfigured()) { $products = array(); // Only works with the default product URL pattern at this time if ($result = $gapi->requestReportData('ga:pagePath', 'ga:visits', $date_from, $date_to, '-ga:visits', 'ga:pagePath=~/([a-z]{2}/)?([a-z]+/)?[0-9][0-9]*\-.*\.html$', 1, 10)) foreach ($result as $row) { if (preg_match('@/([a-z]{2}/)?([a-z]+/)?([0-9]+)\-.*\.html$@', $row['dimensions']['pagePath'], $matches)) $products[] = array('id_object' => (int)$matches[3], 'counter' => $row['metrics']['visits']); } return $products; } else return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' SELECT p.id_object, pv.counter FROM `'._DB_PREFIX_.'page_viewed` pv LEFT JOIN `'._DB_PREFIX_.'date_range` dr ON pv.`id_date_range` = dr.`id_date_range` LEFT JOIN `'._DB_PREFIX_.'page` p ON pv.`id_page` = p.`id_page` LEFT JOIN `'._DB_PREFIX_.'page_type` pt ON pt.`id_page_type` = p.`id_page_type` WHERE pt.`name` = \'product\' '.Shop::addSqlRestriction(false, 'pv').' AND dr.`time_start` BETWEEN "'.pSQL($date_from).'" AND "'.pSQL($date_to).'" AND dr.`time_end` BETWEEN "'.pSQL($date_from).'" AND "'.pSQL($date_to).'" GROUP BY p.`id_object` LIMIT '.(int)$limit); } As said, haven't tried, but give it a try. My 2 cents, Pascal Hello I modiffied the file and the result is almos fine The total of the views for the same product from different days they are not summed togheter For the first product in the list, it was viewed 1 time but it has been added to cart 7 times and bought 5 times in the selected period of time. Still needs some query improvement. Please can someone take a look ? PrestaShop version 1.6.0.13 Edited April 19, 2015 by HUHA (see edit history) Link to comment Share on other sites More sharing options...
HUHA Posted April 22, 2015 Share Posted April 22, 2015 Someone, anyone ? Link to comment Share on other sites More sharing options...
HUHA Posted May 2, 2015 Share Posted May 2, 2015 Anyone ? Link to comment Share on other sites More sharing options...
sebastian.h Posted May 20, 2015 Share Posted May 20, 2015 Anyone ? HUHA, Have you solved the problem?? Link to comment Share on other sites More sharing options...
hrycek Posted May 21, 2015 Share Posted May 21, 2015 Hello I modiffied the file and the result is almos fine The total of the views for the same product from different days they are not summed togheter For the first product in the list, it was viewed 1 time but it has been added to cart 7 times and bought 5 times in the selected period of time. Still needs some query improvement. Please can someone take a look ? PrestaShop version 1.6.0.13 Edited by HUHA, 19 April 2015 - 06:25 PM. I have the same problem... The number of views is taken from first day only, not from all period of time... Link to comment Share on other sites More sharing options...
PascalVG Posted May 23, 2015 Share Posted May 23, 2015 I see that after this SQL, they do many more things with the result, to finally come up with the table, so just grouping as above didn't do the job, it just cut out all the 'double' lines ( i.e. lines with the same id_objet, which isn't what you want. What should be done is combining rows in the function: public function getTableMostViewed($date_from, $date_to) Where they go to the result of the SQL to build the table, but at the moment row by row, not combined. A lot of work to change, I'm afraid. You have to check if the 'current' id_obect is the same as the previous one,a and if so, NOT add a new row with all its fields, but add the field values of the current row to the field values of the previous row. In the way they wrote it, with loads of [ ]'s (i.e. "get next empty array value" will be used, so this makes it not easy to find the array of the previous row to ADD the current value (no clear index pointing to this field.) As you see, not so easy... Anyone who wants to try?? My 2 cents, pascal. Link to comment Share on other sites More sharing options...
PascalVG Posted May 23, 2015 Share Posted May 23, 2015 OK, let's try: Edit modules/dashproducts/dashproducts.php (Make backup!!!) Find function: public function getTableMostViewed($date_from, $date_to) Scroll down a little, and you will find this piece of code (Sample from PS 1.6.0.14). Then add the red code: ... if (Configuration::get('PS_STATSDATA_PAGESVIEWS')) { $products = $this->getTotalViewed($date_from, $date_to, (int)Configuration::get('DASHPRODUCT_NBR_SHOW_MOST_VIEWED')); $body = array(); if (is_array($products) && count($products)) { $previous_product = null; $previous_key = null; foreach ($products as $key => $product) { if (isset($previous_product) && $product['id_object'] == $previous_product['id_object']) { $products[$previous_key]['counter'] += $product['counter']; unset($products[$key]); } else { $previous_product = $product; $previous_key = $key; } } } if (is_array($products) && count($products)) foreach ($products as $product) { $product_obj = new Product((int)$product['id_object'], true, $this->context->language->id); if (!Validate::isLoadedObject($product_obj)) continue; $img = ''; ... What it does: I combined the rows BEFORE adding them to the table. I checked if the current row is the same as the previous one. If so, I added the views of the current row to the views of the previous row, and removed the current row out of the array. Something like: original array (result from SQL) : ID views 1 12 1 5 3 13 3 4 3 20 2 7 will become ID views 1 12 + 5 1 5 3 13 + 4 + 20 3 4 3 20 2 7 Then I feed this cleaned up array to the table Give it a try. Especially check the other columns in the table as well, as I don't have data to check it fully. N.B. Don't forget to take out the modification ( GROUP BY p.`id_object` ) from the SQL, otherwise it won't work!!! Let me know if it works, pascal 2 Link to comment Share on other sites More sharing options...
hrycek Posted May 27, 2015 Share Posted May 27, 2015 It works, really, really thank you Link to comment Share on other sites More sharing options...
pardus3420 Posted November 6, 2015 Share Posted November 6, 2015 teşekkürler PascalVG işe yarıyor. Link to comment Share on other sites More sharing options...
pardus3420 Posted November 7, 2015 Share Posted November 7, 2015 PascalVG Hi, excuse me. Little bit English. This code, you can sort in descending order? regards Link to comment Share on other sites More sharing options...
cvb_asturias Posted April 23, 2019 Share Posted April 23, 2019 (edited) Hello. This trick didn't work for me (PS 1.7.5). This is my solution, in function 'getTableMostViewed' below line if (Configuration::get('PS_STATSDATA_PAGESVIEWS')) { /* if you pick 50 rows, when grupped results in 8-10 products so I comment the original call and I substitute for an enough high number like 400, when groupped, it results in 50-60 products */ //$products = $this->getTotalViewed($date_from, $date_to, (int)Configuration::get('DASHPRODUCT_NBR_SHOW_MOST_VIEWED')); $products = $this->getTotalViewed($date_from, $date_to, 400); $body = array(); /* ADD THIS IF */ if (is_array($products) && count($products)) { $p = array(); foreach ($products as $key => $product) { if ($p[$product['id_object']] != 0) { $p[$product['id_object']] += $product['counter']; } else $p[$product['id_object']] = $product['counter']; } arsort($p); $products = array(); foreach ($p as $clave => $valor) { $products[] = array( 'id_object' => $clave, 'counter' => $valor ); } } and below if (is_array($products) && count($products)) {............ Edited April 23, 2019 by cvb_asturias (see edit history) 1 Link to comment Share on other sites More sharing options...
David Eschmeyer Posted October 4, 2019 Share Posted October 4, 2019 On 4/23/2019 at 7:10 AM, cvb_asturias said: Hello. This trick didn't work for me (PS 1.7.5). This is my solution, in function 'getTableMostViewed' below line if (Configuration::get('PS_STATSDATA_PAGESVIEWS')) { /* if you pick 50 rows, when grupped results in 8-10 products so I comment the original call and I substitute for an enough high number like 400, when groupped, it results in 50-60 products */ //$products = $this->getTotalViewed($date_from, $date_to, (int)Configuration::get('DASHPRODUCT_NBR_SHOW_MOST_VIEWED')); $products = $this->getTotalViewed($date_from, $date_to, 400); $body = array(); /* ADD THIS IF */ if (is_array($products) && count($products)) { $p = array(); foreach ($products as $key => $product) { if ($p[$product['id_object']] != 0) { $p[$product['id_object']] += $product['counter']; } else $p[$product['id_object']] = $product['counter']; } arsort($p); $products = array(); foreach ($p as $clave => $valor) { $products[] = array( 'id_object' => $clave, 'counter' => $valor ); } } and below if (is_array($products) && count($products)) {............ wonderful job! and this worked in 1.6.1.24. I made the number of rows to fetch very large so I can have accurate results for the year long view Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now