Here is a mod we posted on the Interspire forum but had requests to also post it here...
The mod is free. We also offer installation for a small fee.
Additional Product Images as Thumbnails
Additional Product Images as Thumbnails
- Attachments
-
- Secondary_Thumbnails_5-0-4.zip
- (11.28 KiB) Downloaded 1078 times
-
- Posts: 1
- Joined: Sat Sep 05, 2009 11:48 pm
Re: Additional Product Images as Thumbnails
I know product images are going to be overhauled in the near future but am wondering if anybody has this mod working in 5.0.6?
Re: Additional Product Images as Thumbnails
Jgaris,
Can you post "Secondary Thumbanils 5.0.6.zip ?
Thank you!
Can you post "Secondary Thumbanils 5.0.6.zip ?
Thank you!
-
- Site Admin
- Posts: 1854
- Joined: Wed Jun 17, 2009 6:30 pm
- Location: South Yorkshire UK
- Contact:
Re: Additional Product Images as Thumbnails
The class.product.php file is easy to update...
Open: includes/classes/class.product.php
Find:
After, Add:
Unfortunately the display/ProductDetails.php has been almost completely rewritten between 5.0.4 and 5.0.6 so it's definitely not compatible or wise to continue to use it...
Open: includes/classes/class.product.php
Find:
Code: Select all
$GLOBALS['CurrentProductLink'] = ProdLink($this->_prodname);
}
}
Code: Select all
public function GetImages()
{
$images = array();
$query = "
SELECT *
FROM [|PREFIX|]product_images
WHERE imageprodid='".$this->_prodid."' AND imageisthumb='0'
ORDER BY imagesort
";
$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
while ($row = $GLOBALS['ISC_CLASS_DB']->Fetch($result))
$images[] = $row;
return $images;
}
-
- Posts: 744
- Joined: Thu Jun 18, 2009 8:59 am
Re: Additional Product Images as Thumbnails
This is being implemented properly in the next ISC release I believe
Re: Additional Product Images as Thumbnails
>Martin
That fist line of code doesn't appear in my class.product.php file:
Would you mind posting the version of display/ProductDetails.php that you have?
>Tony
I can't wait for the next release, but thanks for your input!
That fist line of code doesn't appear in my class.product.php file:
Code: Select all
<?php
class ISC_PRODUCT
{
var $_product = array();
var $_prodid = 0;
var $_prodprice = 0;
var $_prodcalculatedprice = 0;
var $_prodretailprice = 0;
var $_prodsaleprice = 0;
var $_prodimages = 0;
var $_prodfixedshippingcost = 0;
var $_prodtype = 0;
var $_prodweight = 0;
var $_prodavgrating = 0;
var $_prodoptionsrequired = 0;
var $_prodnumreviews = 0;
var $_prodnumcustomfields = 0;
var $_prodinvtrack = 0;
var $_prodcurrentinv = 0;
var $_prodallowpurchases = 1;
var $_prodhideprice = 0;
var $_prodcallforpricinglabel = '';
var $_prodname = "";
var $_prodthumb = "";
var $_proddesc = "";
var $_prodbrandname = "";
var $_prodavailability = "";
var $_prodrelatedproducts = "";
var $_prodlayoutfile = "";
var $_prodsku = "";
var $_prodpagetitle = '';
var $_prodmetakeywords = '';
var $_prodmetadesc = '';
var $_prodfreeshipping = false;
var $_prodvariations = array();
var $_prodvariationcombinations = array();
var $_prodvariationoptions = array();
var $_currencyrecord = null;
function __construct($productid=0)
{
// Load the data for this product
$this->_SetProductData($productid);
// Add it to the list of recently viewed products
if($productid == 0) {
$this->_AddToRecentlyViewedProducts();
// Workout the breadcrumb(s)
$this->_BuildBreadCrumbs();
// Track a view for this page
$this->_TrackView();
}
}
function _SetProductData($productid=0)
{
if ($productid == 0) {
// Retrieve the query string variables. Can't use the $_GET array
// because of SEO friendly links in the URL
SetPGQVariablesManually();
if (isset($_REQUEST['product'])) {
$product = $_REQUEST['product'];
}
else if(isset($GLOBALS['PathInfo'][1])) {
$product = preg_replace('#\.html$#i', '', $GLOBALS['PathInfo'][1]);
}
else {
$product = '';
}
$product = $GLOBALS['ISC_CLASS_DB']->Quote(MakeURLNormal($product));
$productSQL = sprintf("p.prodname='%s'", $product);
}
else {
$productSQL = sprintf("p.productid='%s'", (int)$productid);
}
$query = "
SELECT p.*, FLOOR(prodratingtotal/prodnumratings) AS prodavgrating, imageisthumb, imagefile, ".GetProdCustomerGroupPriceSQL().",
(SELECT COUNT(fieldid) FROM [|PREFIX|]product_customfields WHERE fieldprodid=p.productid) AS numcustomfields,
(SELECT COUNT(reviewid) FROM [|PREFIX|]reviews WHERE revstatus='1' AND revproductid=p.productid AND revstatus='1') AS numreviews,
(SELECT brandname FROM [|PREFIX|]brands WHERE brandid=p.prodbrandid) AS prodbrandname,
(SELECT COUNT(imageid) FROM [|PREFIX|]product_images WHERE imageprodid=p.productid AND imageisthumb=0) AS numimages
FROM [|PREFIX|]products p
LEFT JOIN [|PREFIX|]product_images pi ON (p.productid=pi.imageprodid)
WHERE ".$productSQL." AND p.prodvisible='1' AND (imageisthumb=1 OR ISNULL(imageisthumb))
";
$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
if ($row = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) {
$this->_product = $row;
$this->_prodid = $row['productid'];
$this->_prodname = $row['prodname'];
$this->_prodsku = $row['prodcode'];
$this->_prodthumb = $row['imagefile'];
$this->_proddesc = $row['proddesc'];
$this->_prodimages = $row['numimages'];
$this->_prodprice = $row['prodprice'];
$this->_prodretailprice = $row['prodretailprice'];
$this->_prodsaleprice = $row['prodsaleprice'];
$this->_prodfixedshippingcost = $row['prodfixedshippingcost'];
$this->_prodbrandname = $row['prodbrandname'];
$this->_prodweight = $row['prodweight'];
$this->_prodavgrating = (int)$row['prodavgrating'];
$this->_prodcalculatedprice = $row['prodcalculatedprice'];
$this->_prodoptionsrequired = $row['prodoptionsrequired'];
$this->_prodnumreviews = $row['numreviews'];
$this->_prodavailability = $row['prodavailability'];
$this->_prodnumcustomfields = $row['numcustomfields'];
$this->_prodrelatedproducts = $row['prodrelatedproducts'];
if($row['prodlayoutfile'] != '') {
$File = str_replace(array(".html", ".htm"), "", $row['prodlayoutfile']);
if(!file_exists(ISC_BASE_PATH."/templates/".GetConfig('template')."/".$row['prodlayoutfile'])) {
$this->_prodlayoutfile = 'product';
}
else {
$this->_prodlayoutfile = $File;
}
}
else {
$this->_prodlayoutfile = 'product';
}
$this->_prodpagetitle = $row['prodpagetitle'];
$this->_prodmetakeywords = $row['prodmetakeywords'];
$this->_prodmetadesc = $row['prodmetadesc'];
$this->_prodinvtrack = $row['prodinvtrack'];
$this->_prodcurrentinv = $row['prodcurrentinv'];
if ($row['prodtype'] == 1) {
$this->_prodtype = PT_PHYSICAL;
} else {
$this->_prodtype = PT_DIGITAL;
}
if ($row['prodfreeshipping'] == 0) {
$this->_prodfreeshipping = false;
} else {
$this->_prodfreeshipping = true;
}
$this->_prodallowpurchases = $row['prodallowpurchases'];
$this->_prodhideprice = $row['prodhideprice'];
$this->_prodcallforpricinglabel = $row['prodcallforpricinglabel'];
// If there are product variations, set them up
if($row['prodvariationid'] > 0) {
$this->SetupProductVariations();
}
}
}
/**
* Track a view for this product by updating the prodnumviews field in the products table
*/
function _TrackView()
{
$query = sprintf("update [|PREFIX|]products set prodnumviews=prodnumviews+1 where productid='%d'", $this->_prodid);
$GLOBALS['ISC_CLASS_DB']->Query($query);
}
function _AddToRecentlyViewedProducts()
{
/*
Store this product's ID in a persistent cookie
that will be used to remember the last 5 products
that this person has viewed
*/
$viewed_products = array();
if (isset($_COOKIE['RECENTLY_VIEWED_PRODUCTS'])) {
$viewed_products = explode(",", $_COOKIE['RECENTLY_VIEWED_PRODUCTS']);
}
if (in_array($this->GetProductId(), $viewed_products)) {
// Remove it from the array
foreach ($viewed_products as $k=>$v) {
if ($v == $this->GetProductId()) {
unset($viewed_products[$k]);
}
}
}
// Add it to the list
$viewed_products[] = $this->GetProductId();
// Only store the 5 most recent product Id's
if (sizeof($viewed_products) > 5) {
$reverse_viewed_products = array_reverse($viewed_products);
$viewed_products = array();
for ($i = 0; $i < 5; $i++) {
$viewed_products[] = $reverse_viewed_products[$i];
}
// Reverse the array so the oldest products show first
$viewed_products = array_reverse($viewed_products);
}
$new_viewed_products = implode(",", $viewed_products);
// Persist the cookie for 30 days
ISC_SetCookie("RECENTLY_VIEWED_PRODUCTS", $new_viewed_products, time() + (3600*24*30));
// Persist the cookie session-wide for use on the cart page
$_SESSION['RECENTLY_VIEWED_PRODUCTS'] = $new_viewed_products;
}
function SetupProductVariations()
{
// Get a list of product variations for this product from the database
$optionList = array();
$query = "
SELECT *
FROM [|PREFIX|]product_variation_combinations
WHERE vcproductid='".$GLOBALS['ISC_CLASS_DB']->Quote($this->GetProductId())."' AND vcenabled='1'
";
$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
while ($combination = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) {
$variationOptions = explode(",", $combination['vcoptionids']);
// Product options must be sorted numerically for the javascript selections to work
sort($variationOptions);
$combination['vcoptionids'] = implode(",", $variationOptions);
$this->_prodvariationcombinations[] = $combination;
// Add the list of options available to the list we'll be selecting below
$optionList = array_merge($optionList, $variationOptions);
}
if(!empty($optionList)) {
// Fetch the list of option names and values
$optionList = implode(",", array_unique($optionList));
$query = "
SELECT *
FROM [|PREFIX|]product_variation_options
WHERE voptionid IN (".$optionList.")
ORDER BY voptionid
";
$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
$variationNames = array();
$count = 0;
while($option = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) {
if(!isset($variationNames[$option['voname']])) {
++$count;
$variationNames[$option['voname']] = $count;
}
else {
$count = $variationNames[$option['voname']];
}
if(!isset($this->_prodvariations[$option['voname']])) {
$this->_prodvariations[$option['voname']] = array();
}
$this->_prodvariations[$option['voname']][] = $option;
$this->_prodvariationslookup[$option['voptionid']] = $count;
$this->_prodvariationoptions[$option['voptionid']] = $option;
}
}
}
function GetVariationCombination($combination)
{
if(!is_array($combination)) {
$combination = explode(",", $combination);
}
// Sort it numerically
sort($combination, SORT_NUMERIC);
$combination = implode(",", $combination);
foreach($this->_prodvariationcombinations as $variation) {
// Sort this combination numerically too
$vcombination = explode(",", $variation['vcoptionids']);
sort($vcombination, SORT_NUMERIC);
$vcombination = implode(",", $vcombination);
if($vcombination == $combination) {
return $variation['combinationid'];
}
}
// Nothing found, return false
return false;
}
function GetProductVariationCombinationJavascript()
{
if(empty($this->_prodvariationcombinations)) {
return '';
}
$script = "<script type=\"text/javascript\">\n";
$script .= " var VariationList = new Array();\n";
foreach($this->_prodvariationcombinations as $variation) {
$variationPrice = CurrencyConvertFormatPrice(CalcProductVariationPrice($this->_prodcalculatedprice, $variation['vcpricediff'], $variation['vcprice'], $this->_product));
$variationWeight = FormatWeight(CalcProductVariationWeight($this->_prodweight, $variation['vcweightdiff'], $variation['vcweight']), true);
if($variation['vcthumb'] != '') {
$thumb = $GLOBALS['ShopPath']."/".GetConfig('ImageDirectory')."/".$variation['vcthumb'];
}
else {
$thumb = '';
}
if($variation['vcimage'] != '') {
$image = $GLOBALS['ShopPath'].'/'.GetConfig('ImageDirectory').'/'.$variation['vcimage'];
}
else {
$image = '';
}
$ids = explode(",", $variation['vcoptionids']);
$optionList = array();
foreach($ids as $id) {
$key = $this->_prodvariationslookup[$id];
$optionList[$key] = $id;
}
ksort($optionList);
$optionList = implode(",", $optionList);
$script .= " VariationList[".$variation['combinationid']."] = {";
$script .= " combination: '".$optionList."', ";
$script .= " price: '".$variationPrice."', ";
$script .= " sku: '".isc_html_escape($variation['vcsku'])."', ";
$script .= " weight: '".$variationWeight."', ";
$script .= " thumb: '".$thumb."', ";
$script .= " image: '".$image."', ";
// Tracking inventory on a product variation level
if($this->_prodinvtrack == 2) {
if(GetConfig('ShowInventory') == 1) {
$script .= "stock: '".$variation['vcstock']."', ";
}
if($variation['vcstock'] <= 0) {
$script .= " instock: false";
}
else {
$script .= " instock: true";
}
}
else {
$script .= " instock: true";
}
$script .= "};\n";
}
$script .= "</script>";
return $script;
}
function GetProductVariations()
{
return $this->_prodvariations;
}
function GetProductInventoryTracking()
{
return $this->_prodinvtrack;
}
function GetInventoryLevel()
{
return $this->_prodcurrentinv;
}
function IsOptionRequired()
{
if ($this->_prodoptionsrequired == 1) {
return true;
} else {
return false;
}
}
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
foreach ($crumbList as $trail) {
$GLOBALS['CatTrailLink'] = $GLOBALS['ShopPath'];
$GLOBALS['CatTrailName'] = GetLang('Home');
$GLOBALS['BreadcrumbItems'] = $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet("BreadcrumbItem");
$GLOBALS['FindByCategoryItems'] = "";
$cats = explode(",", $trail);
foreach ($cats as $categoryid) {
if(!CustomerGroupHasAccessToCategory($categoryid)) {
continue;
}
if (isset($categories[$categoryid])) {
$catname = $categories[$categoryid];
$GLOBALS['CatTrailLink'] = CatLink($categoryid, $catname);
$GLOBALS['CatTrailName'] = isc_html_escape($catname);
$GLOBALS['BreadcrumbItems'] .= $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet("BreadcrumbItem");
$GLOBALS['FindByCategoryItems'] .= $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet("ProductFindByCategoryItem");
}
}
$GLOBALS['CatTrailName'] = isc_html_escape($this->GetProductName());
$GLOBALS['BreadcrumbItems'] .= $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet("BreadcrumbItemCurrent");
$GLOBALS['BreadCrumbs'] .= $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet("ProductBreadCrumb");
$GLOBALS['FindByCategory'] .= $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet("ProductFindByCategory");
}
}
function HandlePage()
{
$this->ShowPage();
}
function HasFreeShipping()
{
return $this->_prodfreeshipping;
}
function GetFixedShippingCost()
{
return $this->_prodfixedshippingcost;
}
function GetProduct()
{
return $this->_product;
}
function GetProductName()
{
return $this->_prodname;
}
function GetProductId()
{
return $this->_prodid;
}
function GetThumb()
{
return $this->_prodthumb;
}
function GetDesc()
{
return $this->_proddesc;
}
function GetNumImages()
{
return $this->_prodimages;
}
function GetPrice()
{
return $this->_prodprice;
}
function GetRetailPrice()
{
return $this->_prodretailprice;
}
function GetSalePrice()
{
return $this->_prodsaleprice;
}
function GetCalculatedPrice()
{
return CalculateProductPrice($this->_product, true, true, false);
}
function GetFinalPrice()
{
return CalcProdCustomerGroupPrice($this->_product, $this->_prodcalculatedprice);
}
function GetBrandName()
{
return $this->_prodbrandname;
}
function GetProductType()
{
return $this->_prodtype;
}
function GetWeight()
{
return FormatWeight($this->_prodweight, true);
}
function GetRating()
{
return $this->_prodavgrating;
}
function GetNumReviews()
{
return $this->_prodnumreviews;
}
function GetSKU()
{
return $this->_prodsku;
}
function GetAvailability()
{
return $this->_prodavailability;
}
function GetNumCustomFields()
{
return $this->_prodnumcustomfields;
}
function GetRelatedProducts()
{
// Related products are set to automatic, find them
return GetRelatedProducts($this->_prodid, $this->_prodname, $this->_prodrelatedproducts);
}
function IsPurchasingAllowed()
{
return $this->_prodallowpurchases;
}
function ArePricesHidden()
{
if(!GetConfig('ShowProductPrice') || $this->_prodhideprice == 1) {
return true;
}
return false;
}
function GetProductCallForPricingLabel()
{
return $this->_prodcallforpricinglabel;
}
function GetPageTitle()
{
return $this->_prodpagetitle;
}
public function GetProductWarranty()
{
return $this->_product['prodwarranty'];
}
function BuildTitle()
{
$title = '';
if ($this->GetPageTitle()!="") {
$title = $this->GetPageTitle();
} elseif ($this->GetProductName()!="") {
$title = sprintf("%s - %s", $this->GetProductName(), GetConfig('StoreName'));
} else {
$title = sprintf("%s %s", GetConfig('StoreName'), GetLang('Products'));
}
return $title;
}
function ShowPage()
{
if ($this->_prodid > 0) {
// Check that the customer has permisison to view this product
$canView = false;
$productCategories = explode(',', $this->_product['prodcatids']);
foreach($productCategories as $categoryId) {
// Do we have permission to access this category?
if(CustomerGroupHasAccessToCategory($categoryId)) {
$canView = true;
}
}
if($canView == false) {
$noPermissionsPage = GetClass('ISC_403');
$noPermissionsPage->HandlePage();
exit;
}
if ($this->_prodmetakeywords != "") {
$GLOBALS['ISC_CLASS_TEMPLATE']->SetMetaKeywords(isc_html_escape($this->_prodmetakeywords));
}
if ($this->_prodmetadesc != "") {
$GLOBALS['ISC_CLASS_TEMPLATE']->SetMetaDescription(isc_html_escape($this->_prodmetadesc));
}
$GLOBALS['CompareLink'] = CompareLink();
// If we're showing images as a lightbox, we need to load up the URLs for the other images for this product
if(GetConfig('ProductImageMode') == 'lightbox') {
$GLOBALS['AdditionalStylesheets'] = array(
GetConfig('ShopPath').'/javascript/jquery/plugins/lightbox/lightbox.css'
);
}
$GLOBALS['ISC_CLASS_TEMPLATE']->SetTemplate($this->_prodlayoutfile);
$GLOBALS['ISC_CLASS_TEMPLATE']->ParseTemplate();
}
// Visiting an invalid product, show a lovely error message
else {
ShowInvalidError('product');
die();
}
}
}
?>
>Tony
I can't wait for the next release, but thanks for your input!