Charlie's Breadcrumbs... THIS WORKS! (ISC 4.07)

Modules, Add-ons and custom code that's more than just a quick hack or Mod.
Post Reply
CharlieFoxtrot
Confirmed
Confirmed
Posts: 413
Joined: Sun Aug 09, 2009 1:23 pm

Charlie's Breadcrumbs... THIS WORKS! (ISC 4.07)

Post by CharlieFoxtrot »

Okay... here it is... the code modification (custom code) to create a single breadcrumb THAT DISPLAYS THE PATH USED TO GET TO THE PRODUCT! This is accomplished by analyzing the "HTTP_REFERER" and find an appropriate match from the list of available breadcrumbs.

The only time that this method won't work is when someone arrives at the product listing from a direct link (a bookmark, or a search engine page, etc.) When this happens, there is no internal path to follow... and no breadcrumb that matches any info from the HTTP_REFERER so the breadcrumb generator will loop through ALL available breadcrumbs and display the LAST ONE it finds.

This code works for ISC 4.07... it may work in other versions, but I have not tested it in other versions.

I am claiming a copyright on the added code. Individuals are free to add this code to your registered copy of the ISC software, but ISC is NOT free to include it in the software they distribute, sell, or use on their BigCommerce.


DO NOT RE-POST THIS CODE ON THE ISC WEB SITE! (Instead, just link to it here.)
REPEAT... DO NOT RE-POST THIS CODE ON THE ISC WEB SITE! Send them here... this is a great site that deserves more traffic.
KEEP THE COPYRIGHT NOTICES INTACT
Buy me a beer if you like this code well enough to use it. :-)


ISC VERSION: 4.07
FILE TO EDIT: ../includes/classes/class.product.php

SEARCH FOR:

Code: Select all

public function _BuildBreadCrumbs()
RENAME TO:

Code: Select all

public function ORIGINAL_BuildBreadCrumbs()
(Basically, you're leaving the entire function UNALTERED, except for its name, so that you can easily get back to your previous state in the event that this custom code doesn't work for you.)


SEARCH FOR:

Code: Select all

public function HandlePage()
This marks the very next function following "ORIGINAL_BuildBreadCrumbs". Once you locate it, you'll know that you've reached the end of the "ORIGINAL_BuildBreadCrumbs" function.


INSERT ABOVE THAT:

Code: Select all

public function _BuildBreadCrumbs()
{
	/*
		Build a list of one or more breadcrumb trails for this
		product based on which categories it appears in
	*/

	// Build the arrays that will contain the category names to build the trails
	$count = 0;

	$GLOBALS['BreadCrumbs'] = "";
	$GLOBALS['FindByCategory'] = "";

	// First we need to fetch the parent lists of all of the categories
	$trailCategories = array();
	$crumbList = array();
	$query = sprintf("
		SELECT c.categoryid, c.catparentlist
		FROM [|PREFIX|]categoryassociations ca
		INNER JOIN [|PREFIX|]categories c ON (c.categoryid=ca.categoryid)
		WHERE ca.productid='%d'",
		$GLOBALS['ISC_CLASS_DB']->Quote($this->GetProductId())
	);
	$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
	while ($row = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) {
		if ($row['catparentlist'] == '') {
			$row['catparentlist'] = $row['categoryid'];
		}
		$cats = explode(",", $row['catparentlist']);
		$trailCategories = array_merge($trailCategories, $cats);
		$crumbList[$row['categoryid']] = $row['catparentlist'];
	}

	$trailCategories = implode(",", array_unique($trailCategories));
	$categories = array();
	if ($trailCategories != '') {
		// Now load the names for the parent categories from the database
		$query = sprintf("SELECT categoryid, catname FROM [|PREFIX|]categories WHERE categoryid IN (%s)", $trailCategories);
		$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
		while ($row = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) {
			$categories[$row['categoryid']] = $row['catname'];
		}
	}

	// Now we have all of the information we need to build the trails, lets actually build them

	// ===================================================================
	// BEGIN COPYRIGHT © 2009 ~ CHARLIE FOXTROT (FOXTROTPRINTING.COM)

	// IS THE BREADCRUMB RELEVENT? ARE THERE ANY SIMILARITIES WITH THE REFERER??
	
	$wasCatBrowsing = false; // assume false until we determine it's true
	$catDirectory = "/categories/"; // Change this value if you've modified "categories" for a different language.
	$referrer = getenv("HTTP_REFERER"); // get the referrer for comparison... but first we need to clean it up a bit
	$wasCatBrowsing = strpos($referrer, $catDirectory); // Search for the word "categories". If true, we were browsing a category
	if ($wasCatBrowsing !== false) { // Not-false is true. We were browsing a category, so let's clean-up and trim-down the referrer
		$serverName = getenv("SERVER_NAME"); // we won't need this... we'll store its value in the array to be removed later
		$httpStuff = array($serverName, "http://", "https://"); // Items in this array will be stripped-out of the referrer comparison string
		$referrer = str_replace($httpStuff, "", $referrer); // ...so we need to delete these array elements from the referrer string
		$argPosition = strpos($referrer, "?"); // if the "?" exists then the next line will trim it and all unneeded arguments that follow it
		if ($argPosition !== false) { $referrer = substr($referrer, 0, $argPosition); }}

	// END COPYRIGHT © 2009 ~ CHARLIE FOXTROT (FOXTROTPRINTING.COM)
	// ===================================================================

	foreach ($crumbList as $productcatid => $trail) {
		$GLOBALS['CatTrailLink'] = $GLOBALS['ShopPath'];
		$GLOBALS['CatTrailName'] = GetLang('Home');
		$GLOBALS['BreadcrumbItems'] = $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet("BreadcrumbItem");
		$GLOBALS['FindByCategoryItems'] = "";

		$cats = explode(",", $trail);
		$breadcrumbitems = "";
		$findbycategoryitems = "";
		$hasAccess = true;

		foreach ($cats as $categoryid) {
			if(!CustomerGroupHasAccessToCategory($categoryid)) {
				/*
				if customer doesn't have access to this category and this category is the category of the product,
				dont print the trail, otherwise just exclude the category from the trail
				*/
				if ($categoryid == $productcatid) {
					$hasAccess = false;
					break;
				}
				continue;
			}
			if (isset($categories[$categoryid])) {
				$catname = $categories[$categoryid];
				$GLOBALS['CatTrailLink'] = CatLink($categoryid, $catname);
				$GLOBALS['CatTrailName'] = isc_html_escape($catname);

				// Fixed error with this by copying the 4.01 lines of code
				 $GLOBALS['BreadcrumbItems'] .= $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet("BreadcrumbItem");
				// Fixed error with this by copying the 4.01 lines of code
				$GLOBALS['FindByCategoryItems'] .= $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet("ProductFindByCategoryItem");

			}
		}

		if ($hasAccess) {
			$GLOBALS['CatTrailName'] = isc_html_escape($this->GetProductName());
			$GLOBALS['BreadcrumbItems'] .= $breadcrumbitems . $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet("BreadcrumbItemCurrent");

			// BELOW are the original ISC lines... they have been commented out and replaced 
			//$GLOBALS['BreadCrumbs'] .= $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet("ProductBreadCrumb");
			//$GLOBALS['FindByCategory'] .= $findbycategoryitems . $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet("ProductFindByCategory");

			// The modification below means that the LAST one found when looping will be the ONLY one displayed
			// The ".=" is now just "=" ... This means that every breadcrumb found during this loop REPLACES the previous
			// one (instead of stacking them one on top of the other). Not very efficient, but it's necessary to do while we
			// continue to search for a matching breadcrumb path (below). Ultimately, if no match is found, we still display
			// only ONE breadcrumb path: the last one found.

			$GLOBALS['BreadCrumbs'] = $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet("ProductBreadCrumb");
			$GLOBALS['FindByCategory'] = $findbycategoryitems . $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet("ProductFindByCategory");

			// ===================================================================
			//  BEGIN COPYRIGHT © 2009 ~ CHARLIE FOXTROT (FOXTROTPRINTING.COM)
			// However, if the breadcrumb matches our previous referrer, then stop looping and use THAT one.
			if ($wasCatBrowsing !== false) { // we were browsing a category, so check the current breadcrumb-string for a referrer-match
				$refMatch = strpos($GLOBALS['BreadCrumbs'], $referrer); // check to see if the referer-URL segment exists in this breadcrumb
				if ($refMatch !== false) { break; }} // if found, then we can stop looping and disply THIS breadcrumb
			//
			//  END COPYRIGHT © 2009 ~ CHARLIE FOXTROT (FOXTROTPRINTING.COM)
			// ===================================================================
		}
	}
}


Save your work. Upload the file. Test it.

BUY ME A BEER: PayPal to... charlie.foxtrot[at]foxtrotprinting[dot]com
Image
ISC 4.0.7

"... and let's be honest that whole "by design" thing is getting old too."
Tony Barnes
Posts: 744
Joined: Thu Jun 18, 2009 8:59 am

Re: Charlie's Breadcrumbs... THIS WORKS! (ISC 4.07)

Post by Tony Barnes »

Ok, so what's it supposed to do...?? I've installed it and my breadcrumbs look the same...

Oh, is it for when the product is in multiple categories...??? Think there's one to check. Ah, yes, seems to of done that. Any reason it was so important to you?
CharlieFoxtrot
Confirmed
Confirmed
Posts: 413
Joined: Sun Aug 09, 2009 1:23 pm

Re: Charlie's Breadcrumbs... THIS WORKS! (ISC 4.07)

Post by CharlieFoxtrot »

Tony Barnes wrote:Ok, so what's it supposed to do...?? I've installed it and my breadcrumbs look the same...

Oh, is it for when the product is in multiple categories...??? Think there's one to check. Ah, yes, seems to of done that. Any reason it was so important to you?
Hi Tony,

Yes, there are several reasons that this one is important to me. I think the benefit of this custom code becomes more apparent when a single item appears in multiple categories.

For those sites that typically list items in only one or two categories, then multiple breadcrumbs are not a big deal. ~ On those sites, having two breadcrumbs isn't terribly unattractive, and it's relatively easy for the customer to determine which one leads them back to the previous category. (Obviously this code would be of little value to the owners of those sites.)

However... for other sites that list their items in MANY categories, then this modification will be more valuable. It reduces the clutter of having a half-dozen breadcrumbs at the top of the listing.

And it makes certain that the ONE breadcrumb actually serves the intended purpose of "breadcrumbs" by allowing the customer easily backtrack to the PREVIOUS category that held their interest.

The other fix that's been circulating DID manage to trim-down the breadcrumb list to just ONE... but there was no guarantee that the single breadcrumb was one that provided the customer an easy way to return to the previous category. (This could make for a frustrated customer... or one who is unable to locate MORE items (or similar items) in the same category that she was browsing.)

If I recall correctly, the breadcrumb issue has been an annoyance that's irritated many people for quite a while... so I thought I'd share my solution. (Hopefully the programmers at Interspire won't steal it.)

Best always,
Charlie
ISC 4.0.7

"... and let's be honest that whole "by design" thing is getting old too."
Tony Barnes
Posts: 744
Joined: Thu Jun 18, 2009 8:59 am

Re: Charlie's Breadcrumbs... THIS WORKS! (ISC 4.07)

Post by Tony Barnes »

Well I can at least confirm for you that it works fine in 5.x

:D

Will let you know if we hit any issues with it
Iamdbat
Posts: 66
Joined: Sun Oct 18, 2009 1:47 am

Re: Charlie's Breadcrumbs... THIS WORKS! (ISC 4.07)

Post by Iamdbat »

WORKS PERFECT in 5.5.2 - well done Chalie :D
wezers
Posts: 27
Joined: Sat Feb 27, 2010 11:23 am

Re: Charlie's Breadcrumbs... THIS WORKS! (ISC 4.07)

Post by wezers »

not sure if this works in 5.5.4

I am getting hidden products showing up in the search results along with the hidden category

wes
CharlieFoxtrot
Confirmed
Confirmed
Posts: 413
Joined: Sun Aug 09, 2009 1:23 pm

Re: Charlie's Breadcrumbs... THIS WORKS! (ISC 4.07)

Post by CharlieFoxtrot »

wezers wrote: I am getting hidden products showing up in the search results along with the hidden category

wes
Hi Wes! ~ This modification should only have an effect on the breadcrumbs display... and nothing else. The changes in this modification do not do anything with the database or the search functions of the shopping cart.

I think that any anomalous search results you're seeing are due to quirks (bugs) within the code that actually does the search... not this code (which is limited to analyzing the customers previous location, and picking the appropriate breadcrumb to display that will lead the customer BACK to the previous location.)

I've ALSO see the type of search results that you've described. If I recall correctly, it's not enough to simply hide a category. ~ Hiding a category makes it impossible for customers to browse to items within the hidden category... but the items DO show up in search results.

Instead, you need to also hide (disable) EVERY ITEM within a hidden category to prevent them from being shown in the search results.

Again... if I recall correctly. :-) I'm posting this bit of advice without double-checking to be sure. // If someone knows differently, please let me know and I'll edit this post. (Or if I find out that I'm wrong, I'll let you know.)

Good luck.
Charlie
ISC 4.0.7

"... and let's be honest that whole "by design" thing is getting old too."
myshop
Posts: 51
Joined: Tue Jun 23, 2009 5:48 am
Location: NSW Australia
Contact:

Re: Charlie's Breadcrumbs... THIS WORKS! (ISC 4.07)

Post by myshop »

I just tried this on a 5.5.4 site - Works as well as it can.

I have noticed there is one less space in the breadcrumb compared to the breadcrumb on category pages?
windsurfer
Posts: 3
Joined: Fri Aug 13, 2010 6:32 pm

Re: Charlie's Breadcrumbs... THIS WORKS! (ISC 4.07)

Post by windsurfer »

Hi Charlie
Nice script, can this be modified to show the compatible models say at the bottom of a page that contains an item that is compatible with other models ?
Thanks in advance
Post Reply