mallen Posted February 14, 2018 Share Posted February 14, 2018 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. }?> Quote Link to comment Share on other sites More sharing options...
mallen Posted February 14, 2018 Author Share Posted February 14, 2018 And if I try this I get ony one item and no duplicates shown. foreach (array_unique($group) as $vw) { Quote Link to comment Share on other sites More sharing options...
Psycho Posted February 14, 2018 Share Posted February 14, 2018 (edited) 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? Edited February 14, 2018 by Psycho Quote Link to comment Share on other sites More sharing options...
mallen Posted February 14, 2018 Author Share Posted February 14, 2018 Thanks. I will check out the variable name and try again. I appreciate you looking over to find anything I missed. Quote Link to comment Share on other sites More sharing options...
mallen Posted February 15, 2018 Author Share Posted February 15, 2018 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 ) ) //*/ } Quote Link to comment Share on other sites More sharing options...
Psycho Posted February 15, 2018 Share Posted February 15, 2018 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>"; } Quote Link to comment Share on other sites More sharing options...
mallen Posted February 15, 2018 Author Share Posted February 15, 2018 (edited) 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']); Edited February 15, 2018 by mallen Quote Link to comment Share on other sites More sharing options...
mallen Posted February 15, 2018 Author Share Posted February 15, 2018 Ignore the previous reply. It is working but just the list of products is not changing once I view a fourth product. Quote Link to comment Share on other sites More sharing options...
mallen Posted February 15, 2018 Author Share Posted February 15, 2018 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>"; } Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.