Jump to content
pxloft

Most Viewed in dashboard repeats

Recommended Posts

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.

 

post-908454-0-92910600-1427381364_thumb.png

 

Please help. Thank you.

 

Share this post


Link to post
Share on other sites

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?

Share this post


Link to post
Share on other sites

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 by PascalVG
Changed type of comma used... (see edit history)

Share this post


Link to post
Share on other sites

 

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

 

post-888776-0-72019700-1429459217_thumb.jpg

 

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 (see edit history)

Share this post


Link to post
Share on other sites

 

Hello

 I modiffied the file and the result is almos fine

 

post-888776-0-72019700-1429459217_thumb.

 

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...

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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
  • Like 2

Share this post


Link to post
Share on other sites
Posted (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 by cvb_asturias (see edit history)
  • Thanks 1

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

Cookies ensure the smooth running of our services. Using these, you accept the use of cookies. Learn More