Post by Skrubis » Tue Nov 15, 2011 12:38 am

Hello,

I am trying to set up next and previous links for products in the same category.
based on http://forum.opencart.com/viewtopic.php?t=17355
I am currently running 1.5.1.3.

The original concept is based on 1.4.x or 1.3.x, so there are some things that need to be changed, I would really appreciate if you could be able to help fix the code for 1.5.x

The modification is done as follows:

1. In /catalog/model/catalog/product.php in ModelCatalogProduct class
OPENCART generates a table which connects products to categories. We use this table to get our product IDs corresponding to the category ID. Therefore I added this function to the ModelCatalogProduct class

But one more query is needed: The problem with the first function is that it includes both activated and deactivated products. We use this function to filter out the activated products:

Code: Select all

   public function getProductsIDbyCategoryID($category_id) {
      $query = $this->db->query("SELECT `product_id` FROM  `product_to_category` WHERE  `category_id` =  '".$category_id."'");
                          
      return $query->rows;
   } 

 public function getStatusByProductID($product_id) { 
   
      $query = $this->db->query("SELECT `status` FROM `product` WHERE `product_id`=".$product_id);
      return $query->rows;
   }
2. In /catalog/controller/product/product.php
Having built the queries, I changed the controller. First we need to know what category we are talking about, which we can see in the 'path' variable in the URL. I changed the following code adding what´s in between '//ADDITION' and ' //END ADDITION' tags. The code is basically the same as in the category.php file.
ORIGINAL CODE FOR 1.3.x or 1.4.x included.

Code: Select all

if (isset($this->request->get['path'])) {
         $path = '';
            
         // ADDITION
         $parts = explode('_', $this->request->get['path']);
         // END ADDITION

         foreach (explode('_', $this->request->get['path']) as $path_id) {
            $category_info = $this->model_catalog_category->getCategory($path_id);
            
            if (!$path) {
               $path = $path_id;
            } else {
               $path .= '_' . $path_id;
            }
            
            if ($category_info) {
               $this->document->breadcrumbs[] = array(
                  'href'      => $this->model_tool_seo_url->rewrite(HTTP_SERVER . 'index.php?route=product/category&path=' . $path),
                  'text'      => $category_info['name'],
                  'separator' => $this->language->get('text_separator')
               );
            }
         }

      // ADDITION
               $category_id = array_pop($parts);
      } else {
         $category_id = 0;
      }
         
      $this->data['category_id'] = $category_id;
         
      // END ADDITION

Code: Select all

$this->load->model('catalog/product');
      
      if (isset($this->request->get['product_id'])) {
         $product_id = $this->request->get['product_id'];
      } else {
         $product_id = 0;
      }
      
      // ADDITTION!!!
      
      $productsByCategoryID = $this->model_catalog_product->getProductsIDbyCategoryID($category_id); // create an array with our products
      
      
      for ($i=0;$i < count($productsByCategoryID); $i++) { // remove items that are not activated
         $statusProducts = $this->model_catalog_product->getStatusByProductID($productsByCategoryID[$i]["product_id"]);
         if ($statusProducts[0]["status"] == 0) {
            unset( $productsByCategoryID[$i] );
         }
      }
      
      foreach ($productsByCategoryID as $key => $value){
                if ($productsByCategoryID[$key]["product_id"] == $product_id) {
               $next = current ($productsByCategoryID); //move back and forward in the array to create the hyperlinks for the NEXT and PREVIOUS buttons.

               prev($productsByCategoryID);
               if (!$next) {
                  end ($productsByCategoryID);
               }
               $prev = prev ($productsByCategoryID);
               
               $url = 'index.php?route=product/product';
            
               if (isset($this->request->get['path'])) {
                  $url .= '&path=' . $this->request->get['path'];
               }
                               
               if ($next){ // there is only a next button if there is a next product to see
                     $url_next = $url.'&product_id='. $next["product_id"];
                     $this->data['next_url'] = $url_next;
               }else {
                  $this->data['next_url'] = FALSE;
               }
               if ($prev){ // same here
                  $url_prev = $url.'&product_id='. $prev["product_id"];
                  $this->data['previous_url'] = $url_prev;
               } else {
                  $this->data['previous_url'] = FALSE;
               }
            }   
            next ($productsByCategoryID); // set the array pointer to the next product
       }
      
      // END

3. In /catalog/view/theme/{template name}/template/product/product.tpl add the buttons
Secondly i created the hyperlinks for the next and previous button. the code goes after the MODEL is loaded and the product_id is defined. again between the ADDITION and END ADDITION tags.

Code: Select all

 <?php if ($previous_url) { ?>
           <a href="<?php echo ($previous_url); ?>"><</a>
        <?php } ?>
        <?php if ($next_url) { ?>
           
           <a href="<?php echo ($next_url); ?>">></a>
        <?php } ?>
This would be really useful for a lot of opencart users, so any help will be great!
Thanks in advance! O0
Also, I commit to pay for a coffee/beer at your favorite place via paypal to your account.

New member

Posts

Joined
Fri Feb 11, 2011 7:25 pm

Post by pprmkr » Tue Nov 15, 2011 3:02 am

I don't like beer, but my engine runs on coffee :laugh:

Please try this new module and report back ...

Attachments

New module: Previous Next Product


User avatar
Active Member

Posts

Joined
Sat Jan 08, 2011 11:05 pm
Location - Netherlands

Post by Skrubis » Tue Nov 15, 2011 5:02 am

Thanks, you almost have your coffee,
Works pretty well, unlike the other modules floating around, this one really checks if the product is actually in the category you are viewing. It gives me some errors about foreach() in admin section, but works pretty well, just need to add its tpl to my product tpl when enabled on product pages for easy mods on placement.

The main problem, any possiblity to make it display SEO urls on next/prev links instead of product ID, without this I wil get lots and lots of duplicate content in the eyes of robots.

New member

Posts

Joined
Fri Feb 11, 2011 7:25 pm

Post by jimmyphong » Tue Nov 15, 2011 9:28 am

I has some code nice wanna to share you , i has code it in today !

Pre and Next link in product page !
Support !

Auto fill if exit category id
Multilanguage
Multi store
Easy Control
Fast Query (::) )

Step 1: Open file
catalog/model/catalog/product.php
add a function get next and prev link !
Code:

Code: Select all

public function GetNextandPreLink($data = array()){
		$filter = '';
		if (!empty($data['filter_category_id'])) {
				if (!empty($data['filter_sub_category'])) {
					$implode_data = array();
					
					$implode_data[] = "p2c.category_id = '" . (int)$data['filter_category_id'] . "'";
					
					$this->load->model('catalog/category');
					
					$categories = $this->model_catalog_category->getCategoriesByParentId($data['filter_category_id']);
										
					foreach ($categories as $category_id) {
						$implode_data[] = "p2c.category_id = '" . (int)$category_id . "'";
					}
								
					$filter .= " AND (" . implode(' OR ', $implode_data) . ")";			
				} else {
					$filter .= " AND p2c.category_id = '" . (int)$data['filter_category_id'] . "'";
				}
			}
		$sql1 = "SELECT p.product_id as next,p2d.name next_title FROM ".DB_PREFIX."product p LEFT JOIN ".DB_PREFIX."product_to_category p2c ON(p.product_id = p2c.product_id) LEFT JOIN ".DB_PREFIX."product_description p2d ON(p.product_id = p2d.product_id) LEFT JOIN ".DB_PREFIX."product_to_store p2s ON(p.product_id = p2s.product_id) WHERE p2d.language_id = '".(int)$this->config->get('config_language_id')."' AND p2s.store_id = '".(int)$this->config->get('config_store_id')."' AND p.status = '1' AND p.date_available <= NOW() AND p.product_id > '".$data['product_id']."' ".$filter." ORDER BY p.product_id ASC LIMIT 1";
		$sql2 = "SELECT p.product_id as prev,p2d.name prev_title FROM ".DB_PREFIX."product p LEFT JOIN ".DB_PREFIX."product_to_category p2c ON(p.product_id = p2c.product_id) LEFT JOIN ".DB_PREFIX."product_description p2d ON(p.product_id = p2d.product_id) LEFT JOIN ".DB_PREFIX."product_to_store p2s ON(p.product_id = p2s.product_id) WHERE p2d.language_id = '".(int)$this->config->get('config_language_id')."' AND p2s.store_id = '".(int)$this->config->get('config_store_id')."' AND p.status = '1' AND p.date_available <= NOW() AND p.product_id < '".$data['product_id']."' ".$filter." ORDER BY p.product_id DESC LIMIT 1";
		
		$prev = $this->db->query($sql1)->row;
		$next = $this->db->query($sql2)->row;
		$query = array_merge($prev,$next);
		return $query;
		
	}
Open file :

Code: Select all

catalog/controller/product/product.php
add code affter code :

Code: Select all

$this->model_catalog_product->updateViewed($this->request->get['product_id']);
add the code :

Code: Select all

if (isset($this->request->get['path'])) {
				$path = '';
			
				$parts = explode('_', (string)$this->request->get['path']);
			
				foreach ($parts as $path_id) {
					if (!$path) {
						$path = $path_id;
					} else {
						$path .= '_' . $path_id;
					}
				}		
		
				$category_id = array_pop($parts);
				$category_link = "&path=".$category_id;
			} else {
				$category_id = 0;
				$category_link = "";
			}
		
			$data = array(
				'filter_category_id' => $category_id,
				'product_id' => $product_id
			);
			
			$results = $this->model_catalog_product->GetNextandPreLink($data);
			
			if(isset($results['next']) && isset($results['next_title'])){
				$this->data['link_next'] = "<a href=".$this->url->link('product/product',$category_link.'&product_id='.$results['next']).">".$results['next_title']."</a>";
			}else{
				$this->data['link_next'] = null;
			}
			
			
			if(isset($results['prev']) && isset($results['prev_title'])){
				$this->data['link_prev'] = "<a href=".$this->url->link('product/product',$category_link.'&product_id='.$results['prev']).">".$results['prev_title']."</a>";
			}else{
				$this->data['link_prev'] = null;
			}
			
this code will be return two value :

$this->data['link_next'];
$this->data['link_prev'];

you can using 2 value in product.tpl anywhere you wana !

Regards
Jimmy
Last edited by jimmyphong on Tue Nov 15, 2011 5:15 pm, edited 1 time in total.

News CMS || Plus SEO || Live Price change with Option Select


Active Member

Posts

Joined
Sat Aug 13, 2011 2:48 am


Post by Skrubis » Tue Nov 15, 2011 5:01 pm

Hey, Jimmy

Thanks for the code, but gives me undefined index for both prev and next echos.

For model- Do I have to add the chunk of code as a seperate function inside ModelCatalogProduct class? Tried in many ways, still echoing prev or next links in tpl gives me undefined inxex.

New member

Posts

Joined
Fri Feb 11, 2011 7:25 pm

Post by jimmyphong » Tue Nov 15, 2011 5:20 pm

Skrubis wrote:Hey, Jimmy

Thanks for the code, but gives me undefined index for both prev and next echos.

For model- Do I have to add the chunk of code as a seperate function inside ModelCatalogProduct class? Tried in many ways, still echoing prev or next links in tpl gives me undefined inxex.

are you sure has add a code in cotroller file ?
this code will be call model and render to view in MVC.

Code: Select all

if (isset($this->request->get['path'])) {
            $path = '';
         
            $parts = explode('_', (string)$this->request->get['path']);
         
            foreach ($parts as $path_id) {
               if (!$path) {
                  $path = $path_id;
               } else {
                  $path .= '_' . $path_id;
               }
            }      
      
            $category_id = array_pop($parts);
            $category_link = "&path=".$category_id;
         } else {
            $category_id = 0;
            $category_link = "";
         }
      
         $data = array(
            'filter_category_id' => $category_id,
            'product_id' => $product_id
         );
         
         $results = $this->model_catalog_product->GetNextandPreLink($data);
         
         if(isset($results['next']) && isset($results['next_title'])){
            $this->data['link_next'] = "<a href=".$this->url->link('product/product',$category_link.'&product_id='.$results['next']).">".$results['next_title']."</a>";
         }else{
            $this->data['link_next'] = null;
         }
         
         
         if(isset($results['prev']) && isset($results['prev_title'])){
            $this->data['link_prev'] = "<a href=".$this->url->link('product/product',$category_link.'&product_id='.$results['prev']).">".$results['prev_title']."</a>";
         }else{
            $this->data['link_prev'] = null;
         }
in controller file ?
file controller catalog/controller/product/product.php

find in you controller with below code and add affter :

Code: Select all

$this->model_catalog_product->updateViewed($this->request->get['product_id']);

News CMS || Plus SEO || Live Price change with Option Select


Active Member

Posts

Joined
Sat Aug 13, 2011 2:48 am


Post by Skrubis » Tue Nov 15, 2011 5:38 pm

My controller:

Code: Select all

http://pastebin.com/bdeFhQwF
2.My Model:

Code: Select all

http://pastebin.com/DjZf3aVB
How I tried to get the links echoed:

Code: Select all

		<?php echo $this->data['link_prev'];?>
		<?php echo $this->data['link_prev'];?>
Gives me error in header:

Code: Select all

Notice: Undefined index: prev in /var/www/html/kinleaves/store/catalog/controller/product/product.php on line 383
And error in product tpl whre echo is made:

Code: Select all

Notice: Undefined index: link_prev in /var/www/html/kinleaves/store/catalog/view/theme/shoppica/template/product/product.tpl on line 41	 Notice: Undefined index: link_prev in /var/www/html/kinleaves/store/catalog/view/theme/shoppica/template/product/product.tpl

New member

Posts

Joined
Fri Feb 11, 2011 7:25 pm

Post by jimmyphong » Tue Nov 15, 2011 5:50 pm

Skrubis wrote:My controller:

Code: Select all

http://pastebin.com/bdeFhQwF
2.My Model:

Code: Select all

http://pastebin.com/DjZf3aVB
How I tried to get the links echoed:

Code: Select all

		<?php echo $this->data['link_prev'];?>
		<?php echo $this->data['link_prev'];?>
Gives me error in header:

Code: Select all

Notice: Undefined index: prev in /var/www/html/kinleaves/store/catalog/controller/product/product.php on line 383
And error in product tpl whre echo is made:

Code: Select all

Notice: Undefined index: link_prev in /var/www/html/kinleaves/store/catalog/view/theme/shoppica/template/product/product.tpl on line 41	 Notice: Undefined index: link_prev in /var/www/html/kinleaves/store/catalog/view/theme/shoppica/template/product/product.tpl

Oh No my friend ! :laugh:
in template file you only echo the prefix in data of controller : :joker:

example :

<?php echo $link_next; ?>
<?php echo $link_prev; ?>

do not echo with $data[]

:crazy:

hahha

Code: Select all

Notice: Undefined index: prev in /var/www/html/kinleaves/store/catalog/controller/product/product.php on line 383
for this error , i has edit in code you coppy a code in controller , recoppy again !
Ready work !

Regards
You are so funny nice to help you work ! ::)

News CMS || Plus SEO || Live Price change with Option Select


Active Member

Posts

Joined
Sat Aug 13, 2011 2:48 am


Post by Skrubis » Tue Nov 15, 2011 6:00 pm

any possibility to make it run by seo urls?

New member

Posts

Joined
Fri Feb 11, 2011 7:25 pm

Post by jimmyphong » Tue Nov 15, 2011 6:09 pm

Skrubis wrote:any possibility to make it run by seo urls?
yes all possibility !
Regards
Jimmy

News CMS || Plus SEO || Live Price change with Option Select


Active Member

Posts

Joined
Sat Aug 13, 2011 2:48 am


Post by Skrubis » Tue Nov 15, 2011 6:17 pm

Ok, I just found out that SEO already works.

Thanks!

New member

Posts

Joined
Fri Feb 11, 2011 7:25 pm

Post by pprmkr » Wed Nov 16, 2011 3:09 am

Skrubis wrote:It gives me some errors about foreach() in admin section, but works pretty well, just need to add its tpl to my product tpl when enabled on product pages for easy mods on placement.

The main problem, any possiblity to make it display SEO urls on next/prev links instead of product ID, without this I wil get lots and lots of duplicate content in the eyes of robots.
Solved error foreach ...
On line 73 of /admin/controller/module/prevnext.php missing:

Code: Select all

$this->data['modules'] = array();
Added it, so download again or add it yourself ...

The SEO urls display OK.

Attachments

New line added to controller, complete package


User avatar
Active Member

Posts

Joined
Sat Jan 08, 2011 11:05 pm
Location - Netherlands

Post by pprmkr » Wed Nov 16, 2011 4:19 am

Found an other error: fresh install -> error explode ....

Please download altered version

Deleted code on line 97 in controller ...

Code: Select all

		if ($this->request->post['prevnext_module'] !== '') {
			$modules = explode(',', $this->request->post['prevnext_module']);
		} else {
			$modules = array();
		}	

User avatar
Active Member

Posts

Joined
Sat Jan 08, 2011 11:05 pm
Location - Netherlands

Post by Skrubis » Wed Nov 16, 2011 11:31 pm

Thanks for the help for both of you-

Coffee went to Jimmy Phong.

New member

Posts

Joined
Fri Feb 11, 2011 7:25 pm

Post by Petran » Sat Dec 03, 2011 7:39 pm

Great module, thanks.
Ik used it at https://pavana.nl , changed the css a bit to let it float in the corner at the right.

Got one thing though: When you look at the breadcrump above the first product it says
Home > Wierook > Wierook India > HEM Wierookstokjes > HEM 7 Powers

When I use the PrevNext navigation the breadcrump becomes
Home > HEM Afrikaanse Musk

Not a very big deal but can this be changed anywhere?

Regards,
Petran

http://www.pavana.nl


Newbie

Posts

Joined
Fri Jul 01, 2011 10:45 pm

Post by pprmkr » Sun Dec 04, 2011 4:19 pm

The first call sets the categorie where the product is in, then a search for the products in that categorie.
After that the product_id is used as the order to show previous, next, first and last.

To show the full path, each call needs to search for parent categories to set the breadcrumb.

I will look into that ...

User avatar
Active Member

Posts

Joined
Sat Jan 08, 2011 11:05 pm
Location - Netherlands

Post by leapDesign » Tue Jan 24, 2012 12:19 am

Hi pprmkr,

I just used your prevnext module and it works great other than when I have SEO urls enabled it sets the link to only be the product name, /product-name

I need it so that the link contains the category and the product name i.e. /category/product name

I have tried to implement this myself but didn't really get anywhere, if you could help it would be greatly appreciated.

Thanks

Newbie

Posts

Joined
Sat Dec 10, 2011 12:17 am

Post by freakyal » Wed Feb 15, 2012 11:14 pm

Hi pprmkr,

I was wondering if you have had a chance to look at the behaviour mentioned by Petran. It would be great if the links at the top of the product page still had the parent and/or subcategory links for navigation purposes.

Home >> Parent Category >> Sub Category >> Product

Thanks,
Al

Newbie

Posts

Joined
Sun Jan 22, 2012 1:23 am

Post by Slo » Thu Feb 23, 2012 6:45 pm

Hello, good day :)
please tell me how to make a request to the previous and next product, sorted in alphabetical order?
Sorting items in a shop in alphabetical order, and in the Previous and Next buttons, sorted by id.

Slo
Newbie

Posts

Joined
Thu Feb 23, 2012 6:36 pm

Post by Slo » Thu Mar 01, 2012 10:23 am

rewrote the module to fit their needs, thanks in my first post did not pay attention. i'm noob, or not a noob ... :) thx
ps i'm sorry, my english very bad O0

Slo
Newbie

Posts

Joined
Thu Feb 23, 2012 6:36 pm
Who is online

Users browsing this forum: No registered users and 15 guests