Advanced Search
Such as "Interspire Email Marketer API" or "Private Label Guide"
Home Page
Developer Forum NEW!

Articles

Email Marketer
Shopping Cart
Knowledge Manager
Website Publisher
Other Products
Miscellaneous

Blogs

Email Marketer
Shopping Cart
Knowledge Manager
Website Publisher
Other Products
Miscellaneous

Recent Blogs

Modifying Shopping Cart: "Sort by Letter" in Categories
Posted 10/6/2008 by Chris Boulton
Creating segment from the API
Posted 09/24/2008 by Hendri Kurniawan
What's using my space
Posted 06/11/2008 by Rodney Amato
The CAN SPAM Act and what it means to us.
Posted 06/2/2008 by Scott Tedmanson
20 Payment Methods Strong - More to Come!
Posted 05/31/2008 by Chris Boulton

RSS Interspire Shopping Cart Blog

Modifying Shopping Cart: "Sort by Letter" in Categories

In the Interspire Shopping Cart Control Panel, we allow you to break down products and customers by those beginning with a specific letter (A-Z). Today we'll be looking at implementing a modification that allows you to bring this functionality to the front end of your store when viewing a list of products in a particular category. Essentially you'll be able to click a letter in a predefined list and view a listing of all products beginning with that specific letter.

The end result of our modification will be similar to the following:

We'll be diving right in to the Interspire Shopping Cart code to make these modifications, so there's an assumption that you have a small about of technical knowledge of PHP/HTML, but even if you don't have the experience, you should be able to progress.

The first thing to do is make sure you have a backup copy of the files we'll be editing in case anything goes wrong.

Open: includes/classes/class.category.php

Find:

$query = "
	SELECT p.*, floor(prodratingtotal/prodnumratings) AS prodavgrating, imageisthumb, imagefile, ".GetProdCustomerGroupPriceSQL()."
	FROM idn_products p
	INNER JOIN idn_categoryassociations ca ON (p.productid = ca.productid)
	LEFT JOIN idn_product_images pi ON (p.productid=pi.imageprodid)
	WHERE ca.categoryid='".(int)$this->GetId()."' AND p.prodvisible='1' AND (imageisthumb=1 OR ISNULL(imageisthumb))
	ORDER BY ".$this->GetSortField().", p.prodname ASC
";

Replace it with:

$query = "
	SELECT p.*, floor(prodratingtotal/prodnumratings) AS prodavgrating, imageisthumb, imagefile, ".GetProdCustomerGroupPriceSQL()."
	FROM idn_products p
	INNER JOIN idn_categoryassociations ca ON (p.productid = ca.productid)
	LEFT JOIN idn_product_images pi ON (p.productid=pi.imageprodid)
	WHERE ca.categoryid='".(int)$this->GetId()."' AND p.prodvisible='1' AND (imageisthumb=1 OR ISNULL(imageisthumb))
";

if(isset($_REQUEST['letter']) && $_REQUEST['letter'] != '') {
	$letter = chr(ord($_REQUEST['letter']));
	if($_REQUEST['letter'] == '0-9') {
		$query .= " AND p.prodname NOT REGEXP('^[a-zA-Z]')";
	}
	else if(isc_strlen($letter) == 1) {
		$query .= " AND p.prodname LIKE '".$GLOBALS['ISC_CLASS_DB']->Quote($letter)."%'";
	}
}

$query .= "ORDER BY ".$this->GetSortField().", p.prodname ASC";

Find:

$query = "
	SELECT COUNT(p.productid) AS numproducts
	FROM idn_products p
	INNER JOIN idn_categoryassociations ca ON (p.productid = ca.productid)
	WHERE ca.categoryid='".(int)$this->GetId()."' and p.prodvisible='1'
";

Replace it with:

$query = "
	SELECT COUNT(p.productid) AS numproducts
	FROM idn_products p
	INNER JOIN idn_categoryassociations ca ON (p.productid = ca.productid)
	WHERE ca.categoryid='".(int)$this->GetId()."' and p.prodvisible='1'
";

if(isset($_REQUEST['letter']) && $_REQUEST['letter'] != '') {
	$letter = chr(ord($_REQUEST['letter']));
	if($_REQUEST['letter'] == '0-9') {
		$query .= " AND p.prodname NOT REGEXP('^[a-zA-Z]') ";
	}
	else if(isc_strlen($letter) == 1) {
		$query .= " AND p.prodname LIKE '".$GLOBALS['ISC_CLASS_DB']->Quote($letter)."%' ";
	}
}

Now we need to modify a few of the panels that handle the next/previous and sorting options to ensure that the selected letter is also included. We'll also add some code to build our letter list and highlight the active item (fun times).

Open: includes/display/CategoryContent.php

Find:

// Should we hide the comparison button?
if(GetConfig('EnableProductComparisons') == 0 || $GLOBALS['ISC_CLASS_CATEGORY']->GetNumProducts() < 2) {
	$GLOBALS['HideCompareItems'] = "none";
}

Under it add:

if($GLOBALS['ISC_CLASS_CATEGORY']->GetNumProducts() == 0 && !isset($_REQUEST['letter'])) {
	$GLOBALS['HideLetterList'] = 'display: none';
}
else {
	$letters = '0-9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z';
	$letters = explode(',', $letters);
	$GLOBALS['LetterList'] = '';
	if(!isset($_REQUEST['letter'])) {
		$GLOBALS['AllActive'] = 'ActiveLetter';
	}
	$GLOBALS['AllLettersLink'] = CatLink($GLOBALS['CatId'], $GLOBALS['ISC_CLASS_CATEGORY']->GetName(), false);
	foreach($letters as $letter) {
		$active = '';
		if(isset($_REQUEST['letter']) && $_REQUEST['letter'] == $letter) {
			$active = 'ActiveLetter';
		}
		$link = CatLink($GLOBALS['CatId'], $GLOBALS['ISC_CLASS_CATEGORY']->GetName(), false, array(
			'letter' => $letter
		));
		$GLOBALS['LetterList'] .= '<li class="'.$active.'"><a href="'.$link.'">'.isc_html_escape($letter).'</a></li>';
	}
}

Find:

$start = max($GLOBALS['ISC_CLASS_CATEGORY']->GetPage()-$num_pages_either_side_of_current,1);
$end = min($GLOBALS['ISC_CLASS_CATEGORY']->GetPage()+$num_pages_either_side_of_current, $GLOBALS['ISC_CLASS_CATEGORY']->GetNumPages());

Under it add:

$linkOptions = array(
	'sort' => $GLOBALS['ISC_CLASS_CATEGORY']->GetSort()
);
if(isset($_REQUEST['letter']) && (isc_strlen($_REQUEST['letter']) == 1 || $_REQUEST['letter'] == '0-9')) {
	$linkOptions['letter'] = $_REQUEST['letter'];
}

Open: includes/display/CategoryContent.php

Find:

$GLOBALS['PageLink'] = CatLink($GLOBALS['CatId'], $GLOBALS['ISC_CLASS_CATEGORY']->GetName(), false, array("page" => $page, "sort" => $GLOBALS['ISC_CLASS_CATEGORY']->GetSort()));

Replace with:

$GLOBALS['PageLink'] = CatLink($GLOBALS['CatId'], $GLOBALS['ISC_CLASS_CATEGORY']->GetName(), false, array_merge($linkOption, array('page' => $page)));

Find:

$GLOBALS['PrevLink'] = CatLink($GLOBALS['CatId'], $GLOBALS['ISC_CLASS_CATEGORY']->GetName(), false, array("page" => $GLOBALS['ISC_CLASS_CATEGORY']->GetPage()-1, "sort" => $GLOBALS['ISC_CLASS_CATEGORY']->GetSort()));

Replace with:

$GLOBALS['PrevLink'] = CatLink($GLOBALS['CatId'], $GLOBALS['ISC_CLASS_CATEGORY']->GetName(), false, array_merge($linkOption, array('page' => $GLOBALS['ISC_CLASS_CATEGORY']->GetPage()-1)));

Find:

$GLOBALS['NextLink'] = CatLink($GLOBALS['CatId'], $GLOBALS['ISC_CLASS_CATEGORY']->GetName(), false, array("page" => $GLOBALS['ISC_CLASS_CATEGORY']->GetPage()+1, "sort" => $GLOBALS['ISC_CLASS_CATEGORY']->GetSort()));

Replace with:

$GLOBALS['NextLink'] = CatLink($GLOBALS['CatId'], $GLOBALS['ISC_CLASS_CATEGORY']->GetName(), false, array_merge($linkOption, array('page' => $GLOBALS['ISC_CLASS_CATEGORY']->GetPage()+1)));

Open: includes/display/CategoryHeading.php

if($GLOBALS['EnableSEOUrls'] == 1) {
	$GLOBALS['URL'] = CatLink($GLOBALS['CatId'], $GLOBALS['ISC_CLASS_CATEGORY']->GetName(), false);
}
else {
	$GLOBALS['URL'] = $GLOBALS['ShopPath']."/categories.php";
	$GLOBALS['HiddenSortField'] = "<input type=\"hidden\" name=\"category\" value=\"".$catPath."\" />";
}</pre>

Replace it with:
<pre name="code" class="php">if($GLOBALS['EnableSEOUrls'] == 1) {
	$linkOptions = array();
	if(isset($_REQUEST['letter']) && (isc_strlen($_REQUEST['letter']) == 1 || $_REQUEST['letter'] == '0-9')) {
		$linkOptions['letter'] = $_REQUEST['letter'];	
	}
	$GLOBALS['URL'] = CatLink($GLOBALS['CatId'], $GLOBALS['ISC_CLASS_CATEGORY']->GetName(), false);
}
else {
	$GLOBALS['URL'] = $GLOBALS['ShopPath']."/categories.php";
	$GLOBALS['HiddenSortField'] = "<input type=\"hidden\" name=\"category\" value=\"".$catPath."\" />";
	if(isset($_REQUEST['letter']) && (isc_strlen($_REQUEST['letter']) == 1 || $_REQUEST['letter'] == '0-9')) {
		$GLOBALS['HiddenSortField'] .= "<input type=\"hidden\" name=\"letter\" value=\"".isc_html_escape($_REQUEST['letter'])."\" />";
	}
}

That's the end of the modifications we need to make to the PHP to get this all happening. Next up, we'll be implementing the modification in to your store design.

Open: templates/[name of the template you're using]/Panels/CategoryContent.html

Insert the HTML below where you'd like the list to appear:

<ul class="LetterSort" style="%%GLOBAL_HideLetterList%%">
	<li class="%%GLOBAL_AllActive%%"><a href="%%GLOBAL_AllLettersLink%%">All</a></li>
	%%GLOBAL_LetterList%%
</ul>

Open: templates/[name of the template you're using]/Styles/styles.css:

Add the following to the bottom of the stylesheet. (Adjust the layout, colours etc so it appears how you'd like it to)

.LetterSort, .LetterSort li {
	list-style: none;
	margin: 0;
	padding: 0;
}

.LetterSort {
	border: 1px solid #b9cfda;
	background: #dcf0f5;
	padding: 4px;
	text-align: center;
}

.LetterSort li {
	display: inline;
}

.LetterSort a {
	padding: 0 3px;
}

.LetterSort li.ActiveLetter a {
	font-weight: bold;
	text-decoration: none;
}

If you save all of the changes we've made, and upload the new files to your store you should have a listing of the letters A through Z and the 'All' and '0-9' links on the category views. Clicking these letters will show you products beginning with the selected letter.

If there are any questions, or you can't get this to work correctly on your store simply leave a comment.

20 Payment Methods Strong - More to Come!


We've just reached 20 built in payment methods in Interspire Shopping Cart and we're still looking to build support for plenty more in to future releases, tackling a few for each release. We've been working hard to ensure that no matter where you're running your store from there's some type of built in payment method that'll work for your location.

The upcoming Interspire Shopping Cart 3.5 release contains several new providers, all of which have been highly demanded by customers:
  • Moneris eSelectPlus DirectPost
  • PayPal PayFlow Pro
  • iDeal (Rabo Bank)
  • Google Checkout (Full level 2 integration)
We're looking to tackle another set of popular payment providers (such as PayPal Website Payments Pro + PayPal Express Checkout) in the release following Interspire Shopping Cart 3.5.

If you have any suggestions for additional payment providers that you'd like built in, simply leave a comment below or submit a feture request via the Interspire Client Area.

Customer Shipping Estimates in Interspire Shopping Cart 3.5

With the introduction of Shipping Zones in Interspire Shopping Cart 3.5, it's no longer possible for the "View Cart" to calculate the shipping cost of orders automatically as it would have previously if you were using the flat-rate shipping methods (by order total, order weight, per item, etc). The reason behind this is because now that shipping methods are location based, we need to know the location of the customer (where they'll possibly be shipping their order to) before we can calculate anything to do with shipping.

Customers can now choose to calculate the shipping cost of the current contents of their shoping cart from the "View Cart" page. Clicking on "Calculate Shipping & Handling" will present a small form that allows the customer to select their country, state and post code and then click "Calculate Shipping" to view a list of possible shipping methods and costs for their order.



A speedy AJAX request off to the server and in moments the customer will receive a list of shipping methods that can be applied to their order. From the list, a customer can then choose a shipping method and click "Update Shipping Cost" to view the adjusted subtotal of their order with this shipping method applied.



The address that the customer selected is then remembered so that when the contents of their cart changes and they wish to recalculate shipping again, they don't need to enter their details - it's all been pre-filled.

That just about covers all of the new shipping related features in the upcoming release of Interspire Shopping Cart 3.5, though there have also been a few other small tweaks/additions:
  • Digital orders can now have a handling fee applied to them. This is particularly useful if you need to cover bandwidth costs for large digital product files.
  • Portions of the shipping modules have been rewritten and cleaned up to meet the latest module documentation standards (which will be available on the Interspire Developers Network shortly)
As always, feedback and suggestions are always welcome.

Ideas for new Addons

The addons system in Interspire Shopping Cart has felt to me like it's been a bit underused so I've started making some simple addons that will hopefully help customers try and diagnose any problems they are having (and fix them) on the spot.

The first one I created was just a basic permissions checker so that you can make sure that all the things that need write access have it. Our installer and upgrade wizard check this as well but this addon will be useful if you move your site to another site, when you go live for example, to make sure everything is going to work ok.

The next addon I'm planning on writing is one that will check the hash of all the files in shopping cart to make sure that the file that is there is the one that is meant to be there. The most obvious use of this is to make sure that after you do an upgrade that you have uploaded all the files. This won't be able to account for changes to files that have been made intentionally but at least it will give customers a quick way to check what files are modified.

These two (assuming I finish the second one in time otherwise it will only be one) will be included for free with the next release of Interspire Shopping Cart.

Those are the two most obvious ideas to me for little addons that can quickly check parts of the store. I've got 1 more idea for an addon but that is a more ambitious project that I'm going to keep under my hat until I've had some time to test it out.

I'd be interested to see if anyone else has any other ideas for addons like this so if you have an idea that I might be able to quickly turn into an addon (I'm mainly thinking of ones that can check parts of your store to make sure everything is ok but all ideas are welcome) then please reply to this blog post.

Shipping Zones in Interspire Shopping Cart 3.5


In the next release of Interspire Shopping Cart, the entire shipping system has been redeveloped to include shipping zones (different shipping settings based on the location), table rates (highly configurable shipping) and much more. These are features that a lot of our customers have been requesting so I've tried to create a very flexible system but keep it easy to configure at the same time too.

A shipping zone is a list of regions (based on either one or more countries, states or postcodes) that your store can ship to and within each of these zones there can be many different shipping methods each with their own independent settings that will be used to calculate shipping for customers who fall in to that zone.

When creating or editing a shipping zone, there are various options that you can choose to configure this zone with:
  • Zone Type
    The type of shipping zone you wish this zone to be. Here you can choose a zone based one or more countries, a zone based on one or more states in different countries, or enter a list of postcodes that apply to a particular country (with wildcards too, so you don't need to enter every single post code)
  • Free Shipping
    Free shipping can now be enabled or disabled per shipping zone and the order total to qualify for free shipping can also be adjusted per zone.
  • Handling
    You can choose to not apply any handling fee for this shipping zone, choose to apply a common handling fee for all shipping methods that are in this zone or specify a handling fee for each of the different methods in this zone.
  • Shipping Methods
    An unlimited amount of shipping methods can be created and customised for each shipping zone. (More information on this below)

Shipping zones are automatically calculated for each customer during the checkout process based on the best/closes matching zone. This allows you to create very powerful shipping rules/calculations based on the destination. The way this works is as follows:
  • If the customer's address matches a postcode in a postcode based zone, this shipping zone will be used. If there is a full match of the postcode rather than a wildcard match, the full match will be used over the wildcard based match.
  • If the customer's address matches a state in a state based zone, this shipping zone will be used.
  • If the customer's address matches a country in a country based zone, this shipping zone will be used.
  • If there are no matches at all, the customer will fall back in to the "Default Shipping Zone" that applies to every other location.
As I previously mentioned, in each shipping zone you can configure as many different combinations of shipping methods as you like. This is a huge improvement over the current shipping in Interspire Shopping Cart 3.1 where you couldn't enable a combination of fixed & real time shipping quotes and couldn't have multiple combinations of a single shipping method (for example, you couldn't have two "Ship by Order Total" methods enabled with differen names such as Express Shipping or Standard Shipping).


When editing a zone, the "Shipping Methods" tab allows you to manage the shipping methods for this zone. If there are multiple shipping methods in a zone, the customer is given the choice of which shipping method to apply to their order. This allows you to offer services such as express shipping, registered shipping or standard shipping and allow the customer to choose which applies to their order.

Creating a shipping method within a zone is just as simple as configuring shipping before, you select the shipping module that this method will use, you can optionally change the display name of this shipping method, and then you configure the shipping method properties/settings.



As you can see - there's quite a lot to the new shipping zones/methods functionality that's vastly improved over our old shipping support in Interspire Shopping Cart. Any feedback is always welcomed. Shortly I'll have an overview of the new customer shipping estimates feature on the front end of the store and two features that everyone's been waiting for: single page & guest checkout.
While working on the Google Checkout module for Interspire Shopping Cart, I came across a bug with the PHP library supplied by Google.

It looks like there is a bug with the PHP library for Google Checkout supplied by Google with causes all merchant calculation callback requests for gift certificates to return invalid xml.

Despite what the comments in the bug report say, it looks like that bug made it into the 1.2.5c.zip which is currently available.

Welcome to the Interspire Developer Network

We've setup the Interspire Developer Network as a place where Interspire customers and partners can come to download not only installation and private label guides, but also technically orientated material including API documentation and integration manuals, articles and videos.

As well as articles, we have a tech-orientated blog setup for each of our products where Interspire developers will post details on upcoming features as they're being built. You can of course leave a comment at the end of every post with your questions or comments.

Thanks, and welcome to the Interspire Developer Network!


Mitchell Harper
Product Development Manager
Interspire Pty. Ltd.


No blogs found.