Jump to content

Getting unique items in array


mallen

Recommended Posts

I am creating a function to set a cookie of the last three viewed items and then display the items except the item I am on. The issue I am having is after the second product I view, it will show duplicate items. I outputted the query and there are no duplicates. I tried array_unique.

function definerecentview() {
global $wpdb;
$myvaluee = $_GET['singleProduct'];
add_action('init', 'definerecentview');
    if ( empty($_COOKIE['recently_viewed']))
        $viewed_products = array();
    else
        $viewed_products = (array) explode( ',', $_COOKIE['recently_viewed']);

    if ( ! in_array($myvalue, $viewed_products)) {
        $viewed_products[] = $myvaluee;
    }

    if (sizeof( $viewed_products ) > 4 ) {
        array_shift( $viewed_products );
    }

// Store cookie
setcookie( 'recently_viewed', implode( ',', $viewed_products ),time() + (86400 * 30), '/' );
$output = "";
$viewed = implode( ',',$viewed_products);
$unique = implode(',', array_unique(explode(',', $viewed)));//added		

$query = "SELECT * FROM products WHERE `prod_id` IN ($unique) AND `prod_id` != '". $this->curProduct ."' LIMIT 4";//don't show current item
	
$group = $wpdb->get_results($query, ARRAY_A);

echo "<div class='aroundrecent grid-area'>Recently Viewed";
echo "<div class='columnflex grid-area'>";	

foreach($group as $vw){

$output .= "<a href='#'><div class='recent grid-area'>";
$output .= "<div class='recentimg grid-area'><img src='/thumbnails/'.$vw['image']. "' alt='".$vw['prod_model']."'title='".$vw['prod_id']."' /></div>";
$output .= "<div class='recentmodel grid-area '>".$vw['prod_name']."</div>";
$output .= "<div class='recentnumber grid-area '>".$vw['prod_model']."</div>";		

$output .= "</div></a>";

echo $output;
}
echo "</div>";
echo "</div>";	
echo "</div>";	

var_dump($group);
//I will get this SELECT * FROM products WHERE `prod_id` IN (2619,2612,2272) AND `prod_id` != '2272' LIMIT 4
And it will show product 2619 twice.
}?>
Link to comment
Share on other sites

Why on earth are you storing the items in a comma separated string in the cookie? You are making this more complicated than it needs to be. Just store an array in the cookie. In fact, why do you keep converting back and forth between a comma separated string and an array in the code?

$viewed = implode( ',',$viewed_products);
$unique = implode(',', array_unique(explode(',', $viewed)));//added

You start with an array of viewed products and convert to a string. Then you conver that string back to an array to remove duplicates so you can then put back into a string! Wow, that is a lot of work that does nothing. Keep array data as an array and only convert to a string at the point where you need it (i.e. in the query).

 

Also, some of your variable names are confusing. For example

$myvaluee = $_GET['singleProduct'];

I have no idea what either of those are supposed to represent. A variable name should be intuitive. I also think '$myvaluee' is the source of your problem. Notice the double 'ee' at the end? I don't know if that is intentional or not, but you use that same variable spelled differently in different places:

$myvaluee = $_GET['singleProduct'];
 
if ( !in_array($myvalue, $viewed_products)) {
    $viewed_products[] = $myvaluee;
}
 
The more I look, the more problems I see. Is this a homework problem?
Link to comment
Share on other sites

I have printed the array and see I have the correct IDs I need to show. But the output always showed one duplicated product . But in the printed array it is correct.

function definerecentview() {//get the last 3 products viewed
global $wpdb;
$theProduct = $_GET['singleProduct'];//gets product id from URL that was viewed
add_action('init', 'definerecentview');
    if ( empty($_COOKIE['recently_viewed']))
        $viewed_products = array();
    else
        $viewed_products = (array) explode( ',', $_COOKIE['recently_viewed']);

    if ( ! in_array($theProduct, $viewed_products)) {
       $viewed_products[] = $theProduct;
    }

    if (sizeof( $viewed_products ) > 3) {
        array_shift( $viewed_products );
    }

// Store cookie
setcookie( 'recently_viewed', implode( ',', $viewed_products ),time() + (86400 * 30), '/' );
$output = "";
$listOfViewed = implode( ',',$viewed_products);
	
$query = "SELECT `prod_id` , `prod_model`, `prod_mainImage`, `prod_name` FROM products WHERE `prod_id` IN ($listOfViewed) AND `prod_id` != '". $this->curProduct ."' ";//don't show current item
	
$group = $wpdb->get_results($query, ARRAY_A);

echo "<div class='aroundrecent grid-area'>Recently Viewed";
echo "<div class='columnflex grid-area'>";	

foreach($group as $vw){

$output .= "<a href='#'><div class='recent grid-area'>";
$output .= "<div class='recentimg grid-area'><img src='" .PRODUCT_IMAGE .'/thumbnails/'.$vw['prod_mainImage']. "' alt='".$vw['prod_model']."'title='".$vw['prod_id']."' /></div>";
$output .= "<div class='recentmodel grid-area '>".$vw['prod_name']."</div>";
$output .= "<div class='recentnumber grid-area '>".$vw['prod_model']."</div>";		

$output .= "</div></a>";

echo $output;
}
echo "</div>";
echo "</div>";	
echo "</div>";	

print_r($group);/*Array ( [0] => Array ( [prod_id] => 2164 [prod_model] => XYZ [prod_mainImage] => RGTE.png [prod_name] => Widget 33 ) 
[1] => Array ( [prod_id] => 2478 [prod_model] => ABC [prod_mainImage] => GHTR.png [prod_name] => Widget 45 ) ) //*/

}
Link to comment
Share on other sites

The code is still a mess.

 

1. Stop converting arrays to string and back and forth repeatedly. 

2. Use comments - especially to explain any conditional checks (if/else statements)

3. You have a variable $theProduct defined in the script, but in the query you have $this->curProduct, which I assume should be the same. Where is that defined and why are you using two different variables?

 

4. Of course you have duplicates int eh output. In fact, I would expect you to have many duplicates! Here is your code to produce the output:

 

foreach($group as $vw){
 
    $output .= "<a href='#'><div class='recent grid-area'>";
    $output .= "<div class='recentimg grid-area'><img src='" .PRODUCT_IMAGE .'/thumbnails/'.$vw['prod_mainImage']. "' alt='".$vw['prod_model']."'title='".$vw['prod_id']."' /></div>";
    $output .= "<div class='recentmodel grid-area '>".$vw['prod_name']."</div>";
    $output .= "<div class='recentnumber grid-area '>".$vw['prod_model']."</div>"; 
    $output .= "</div></a>";
    
    echo $output;
}

 

In that loop you are APPENDING the content for the current foreach() record to the variable $content and the outputting the variable $content. But, the $content variable is not reset when the loop runs a second time, so the next record is appended to the existing content and output again. So, if you had three records, the output would look like this:

  • Record 1
  • Record 1
  • Record 2
  • Record 1
  • Record 2
  • Record 3

The red content would be output on the first iteration of the loop, the blue on the second and the green on the third. Move the actual output of the content after the loop is completed.

 

5. There is also a flaw in the logic for recently viewed. If the current product was the last item in the recently viewed list (i.e. the oldest viewed), it would not get added to the front of the recently viewed list and would fall off on the next product. You should always add the current product to the front of the list and then remove the duplicate (if it exists). That was the recently viewed list will always be the last n items the user viewed.

 

 

Try this (not tested)

 

<?php
 
function definerecentview() {//get the last 3 products viewed
    global $wpdb;
 
    //Set the current product ID
    $currentProduct = intval($_GET['singleProduct']);//gets product id from URL that was viewed
 
    add_action('init', 'definerecentview');
 
    //Set default of viewed products to empty array
    $viewed_products = array();
    //If there is a saved cookie value - use it
    if(isset($_COOKIE['recently_viewed']))
    {
        $viewed_products = unserialize($_COOKIE['recently_viewed']);
    }
    //If the current product exists in the array remove it
    if(in_array($currentProduct, $viewed_products))
    {
        unset($viewed_products[array_search($currentProduct, $viewed_products)]);
    }
    //Add the current product to the end of the array
    $viewed_products[] = $currentProduct;
 
    //Ensure length is no more than 3 items
    $viewed_products = array_slice($viewed_products, 0, 3);
 
    // Store cookie
    setcookie( 'recently_viewed', serialize($viewed_products), time()+(86400 * 30), '/' );
 
    //Run query to get records for recently viewed products
    $listOfViewed = implode( ',',$viewed_products);
    $query = "SELECT `prod_id` , `prod_model`, `prod_mainImage`, `prod_name`
              FROM products
              WHERE `prod_id` IN ($listOfViewed)
                AND `prod_id` != '{$currentProduct}' ";//don't show current item
    $recentProducts = $wpdb->get_results($query, ARRAY_A);
 
    //Create output for list of recent products
    $output = "";
    foreach($recentProducts as $prod)
    {
        $imgSrc = PRODUCT_IMAGE . "/thumbnails/{$prod['prod_mainImage']}'";
        $output .= "<a href='#'><div class='recent grid-area'>";
        $output .= "<div class='recentimg grid-area'>";
        $output .= "<img src='{$imgSrc}' alt='{$prod['prod_model']}'title='{$prod['prod_id']}' /></div>";
        $output .= "<div class='recentmodel grid-area '>{$prod['prod_name']}</div>";
        $output .= "<div class='recentnumber grid-area '>{$prod['prod_model']}</div>"; 
        $output .= "</div></a>";
    }
 
    //Output the content
    echo "<div class='aroundrecent grid-area'>Recently Viewed";
    echo "  <div class='columnflex grid-area'>{$output}</div>"; 
    echo "</div>";
}
Link to comment
Share on other sites

if(in_array($currentProduct, $viewed_products))

Warning: in_array() expects parameter 2 to be array, boolean 

I changed it to this and I don't get duplicates but the items don't change after I go to the fourth item. I want to show the last three items.

$viewed_products = (array) explode( ',', $_COOKIE['recently_viewed']);
Link to comment
Share on other sites

I made a couple changed and added array_shift and now it is showing 3 recent products and it changes.

function definerecentview() {//get the last 3 products viewed
    global $wpdb;
 
    //Set the current product ID
    $currentProduct = intval($_GET['singleProduct']);//gets product id from URL that was viewed
 
    add_action('init', 'definerecentview');
 
    //Set default of viewed products to empty array
    $viewed_products = array();
    //If there is a saved cookie value - use it
    if(isset($_COOKIE['recently_viewed']))
    {
        //$viewed_products = unserialize($_COOKIE['recently_viewed']);
		$viewed_products = (array) explode( ',', $_COOKIE['recently_viewed']);
    }
    //If the current product exists in the array remove it
    if(in_array($currentProduct, $viewed_products))
    {
        unset($viewed_products[array_search($currentProduct, $viewed_products)]);
    }
    //Add the current product to the end of the array
    $viewed_products[] = $currentProduct;
 
    //Ensure length is no more than 3 items
    //$viewed_products = array_slice($viewed_products, 0, 3);
	if (sizeof( $viewed_products ) > 4 ) {//changed and added here
        array_shift( $viewed_products );
    }
 
    // Store cookie
    //setcookie( 'recently_viewed', serialize($viewed_products), time()+(86400 * 30), '/' );
setcookie( 'recently_viewed',implode( ',', $viewed_products ), time()+(86400 * 30), '/' );//changed here
 
    //Run query to get records for recently viewed products
    $listOfViewed = implode( ',',$viewed_products);
    $query = "SELECT `prod_id` , `prod_model`, `prod_mainImage`, `prod_name`
              FROM products
              WHERE `prod_id` IN ($listOfViewed)
                AND `prod_id` != '{$currentProduct}' ";//don't show current item
    $recentProducts = $wpdb->get_results($query, ARRAY_A);
 
    //Create output for list of recent products
    $output = "";
    foreach($recentProducts as $prod)
    {
        $imgSrc = PRODUCT_IMAGE . "/thumbnails/{$prod['prod_mainImage']}'";
        $output .= "<a href='#'><div class='recent grid-area'>";
        $output .= "<div class='recentimg grid-area'>";
        $output .= "<img src='{$imgSrc}' alt='{$prod['prod_model']}'title='{$prod['prod_id']}' /></div>";
        $output .= "<div class='recentmodel grid-area '>{$prod['prod_name']}</div>";
        $output .= "<div class='recentnumber grid-area '>{$prod['prod_model']}</div>"; 
        $output .= "</div></a>";
    }
 
    //Output the content
    echo "<div class='aroundrecent grid-area'>Recently Viewed";
    echo "  <div class='columnflex grid-area'>{$output}</div>"; 
    echo "</div>";
}
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.