Beginners PHP question, probably easy for a PHP guru!

OK, my HTML/CSS is strong, my JS is ‘capable’ and my PHP is ‘weak’!

However, I’m trying to improve this situation. And I’m hoping solving this problem will help me understand PHP/MySQL a little better and put me on a path to PHP enlightenment. I hope some clever bean can offer some words of wisdom…

Background
I am building a site based on Cubecart (a PHP/MySQL ecommerce platform).

The problem
Here is a screengrab to show the issue (building it with MAMP at present so no live url):

At the footer of the site is a featured products section which displays products and prices. When a user switches currency (on the left), the price and currency symbol change accordingly.

In the right sidebar I have a popular products section, however, by default this does not show the price and currency symbol. How do I make it?

More information about how Cubecart works
Cubecart uses a controlling php file and then a tpl template file to control the output.

Example code from the working section
For example, the latest products section uses the following PHP file:

if (!defined('CC_INI_SET')) die("Access Denied");

$lang = getLang("includes".CC_DS."boxes".CC_DS."randomProd.inc.php");
$seed = mt_rand(1, 10000);

if(isset($_GET['catId'])) {
	$_GET['catId'] = (int)$_GET['catId'];
}

$whereClause	= (isset($_GET['catId'])) ? "AND I.cat_id=".$db->mySQLSafe($_GET['catId'])." AND I.cat_id > 0 AND C.hide != '1'" : "AND I.cat_id > 0";
$sql			= sprintf("SELECT I.name, I.image, I.productId FROM %1\\$sCubeCart_inventory AS I, %1\\$sCubeCart_category AS C WHERE I.cat_id = C.cat_id AND I.disabled != '1' AND C.hide = '0' AND (C.cat_desc != '##HIDDEN##' OR C.cat_desc IS NULL) %2\\$s ORDER BY RAND(%3\\$d) LIMIT 1", $glob['dbprefix'], $whereClause, $seed);
$randProd		= $db->select($sql);

if ($randProd) {
	if (($val = prodAltLang($randProd[0]['productId'])) !== false) {
		$randProd[0]['name'] = $val['name'];
	}

	$box_content = new XTemplate ('boxes'.CC_DS.'randomProd.tpl');

	$box_content->assign('LANG_RANDOM_PRODUCT',$lang['randomProd']['featured_prod']);
	$box_content->assign('PRODUCT_ID',$randProd[0]['productId']);
	$box_content->assign('PRODUCT_NAME',validHTML($randProd[0]['name']));

	$thumbRootPath	= imgPath($randProd[0]['image'],1,'root');
	$thumbRelPath	= imgPath($randProd[0]['image'],1,'rel');

	if (file_exists($thumbRootPath) && !empty($randProd[0]['image'])) {
		$box_content->assign('IMG_SRC', $thumbRelPath);
	} else {
		$box_content->assign('IMG_SRC', $GLOBALS['rootRel'].'skins/'. SKIN_FOLDER . '/styleImages/thumb_nophoto.gif');
	}

	$box_content->parse('random_prod');
	$box_content = $box_content->text('random_prod');

} else {
	$box_content = '';
}
?>

And then the following in the template file:

<div class="boxTitleRight">{LANG_RANDOM_PRODUCT}</div>
<div class="boxContentLeft" style="text-align: center">
	<a href="index.php?_a=viewProd&amp;productId={PRODUCT_ID}" title="{PRODUCT_NAME}"><img src="{IMG_SRC}" alt="{PRODUCT_NAME}" border="0" title="{PRODUCT_NAME}" /></a>
	<br />
	<span class="txtCopy"><a href="index.php?_a=viewProd&amp;productId={PRODUCT_ID}" title="{PRODUCT_NAME}" class="txtDefault">{PRODUCT_NAME}</a></span>
</div>

This code is somehow grabbing the price of the item and the correct currency and displaying it correctly. My thinking is I need to grab the relevant sections of code, stick them in my popularProducts.inc.php (the controlling file for the Popular Products section) and it will show the correct price and currency for each popular product item too.

However, what part of that little lot specifies the price and what currency to use?

Any pointers greatly appreciated.

Thanks - that cracked it. You the man.

Closee… instead of


$popProduct[$i]['price']

It should have been:


$popProduct['price']

So you’ll need to remove all the [$i]

tmapm - thanks for your continued input here. I realise this must be like pulling teeth! :wink:

OK, I’ve made the changes as suggested and no more error messages, however, no prices appearing either.

I’ve tried the PHP block two ways, firstly using ‘popProducts’:

//Ben's price add
	if (!salePrice($popProduct[$i]['price'], $popProduct[$i]['sale_price']) || !$config['saleMode']) {
			$box_content->assign('TXT_PRICE', priceFormat($popProduct[$i]['price'], true));
		} else {
			$box_content->assign('TXT_PRICE', "<span class='txtOldPrice'>".priceFormat($popProduct[$i]['price'], true)."</span>");
		}
	$salePrice = salePrice($popProduct[$i]['price'], $popProduct[$i]['sale_price']);

		$box_content->assign('TXT_SALE_PRICE', priceFormat($salePrice, true));
		//Ben's price add: END

And I’ve also tried using the ‘$popularProds’ instead. e.g.

//Ben's price add
	if (!salePrice($popularProds[$i]['price'], $popularProds[$i]['sale_price']) || !$config['saleMode']) {
			$box_content->assign('TXT_PRICE', priceFormat($popularProds[$i]['price'], true));
		} else {
			$box_content->assign('TXT_PRICE', "<span class='txtOldPrice'>".priceFormat($popularProds[$i]['price'], true)."</span>");
		}
	$salePrice = salePrice($popularProds[$i]['price'], $popularProds[$i]['sale_price']);

		$box_content->assign('TXT_SALE_PRICE', priceFormat($salePrice, true));
		//Ben's price add: END

But no dice. The relevant line in the TPL file is still:

<a title="{PRODUCT_NAME}" href="index.php?_a=viewProd&amp;productId={PRODUCT_ID}" class="txtDefault">{TXT_PRICE}</a>

tmapm - sent you a PM.

You’re looking at the wrong templates. I looked in a copy of 4.3.1. You’ll need to look at the following:

includes/content/index.inc.php 63 … 81 - 85


    $latestProducts = $db->select("SELECT I.productId, I.image, I.price, I.name, I.sale_price FROM ".$glob['dbprefix']."CubeCart_inventory AS I, ".$glob['dbprefix']."CubeCart_category AS C WHERE C.cat_id = I.cat_id AND I.disabled != '1' AND I.showFeatured = '1' AND I.cat_id > 0 AND C.hide != '1' ORDER BY I.productId DESC LIMIT ".$config['noLatestProds']);

...

        if (!salePrice($latestProducts[$i]['price'], $latestProducts[$i]['sale_price']) || !$config['saleMode']) {
            $index->assign("TXT_PRICE", priceFormat($latestProducts[$i]['price'], true));
        } else {
            $index->assign("TXT_PRICE", "<span class='txtOldPrice'>".priceFormat($latestProducts[$i]['price'], true)."</span>");
        }
        
        $salePrice = salePrice($latestProducts[$i]['price'], $latestProducts[$i]['sale_price']);
        
        $index->assign("TXT_SALE_PRICE", priceFormat($salePrice, true));


Then the template:

skin/–/–/content/index.tpl


<div class="LPPrice">{TXT_PRICE} {TXT_SALE_PRICE}</div>

You shoudl be able to figure out what you need from that.

It seems that the template that you have there is for the image and the product name. The pricing stuff occurs in some other place.

It seems that the price is fetched by some other code. That other code needs to know what it’s fetching the price for, so it makes sense that the product id is used at some other location to deal with the prices.

You should be able to use the product id to figure out where it is used to retrieve the appropriate prices.
That product id is assigned to the $box_content object, so it should be somewhere in there that the product id is used to fetch the prices.

Hi Paul,

That’s obviously the logically way to go about it. However, the only thing I can see in the template that may bring it though is {PRODUCT_NAME}. However, when I try and add that to the popular products template I don’t get any joy??

Am I looking at this problem the wrong way around? Give me another clue :wink:

How does the price get from where it is stored in the database, to being displayed on the screen?

Start from the price on the screen and trace it back to the database.

Thanks for the replies chaps. However, I feel like I’m sinking further and further beneath the surface here and PHP Ninjadom is a fast fading pipe dream…

As ever, any pointers appreciated.

I’m currently getting this error:
“Fatal error: Call to a member function assign() on a non-object in …includes/boxes/popularProducts.inc.php on line 72”

So I’ve clearly screwed the PHP some how. This is what I did…

Here’s my amended popularProducts.inc.php - I tried to add the relevant sections that tmapm suggested (it’s at lines 71-78, commented as ‘//Ben’s price add’) and added the {TXT_PRICE} in my popularProducts.tpl file

if (!defined('CC_INI_SET')) die("Access Denied");
## Only show if we have number of items set to > 0
if($config['noPopularBoxItems']) {
	## include lang file
	$lang = getLang('includes'.CC_DS.'boxes'.CC_DS.'popularProducts.inc.php');

## BF ADDED
$seed = mt_rand(1, 10000);
if(isset($_GET['catId'])) {
	$_GET['catId'] = (int)$_GET['catId'];
}

	## query database
	if ($config['pop_products_source']) {
		## inner join on inventory table to make sure the product exists still
		$cache = new cache('boxes.popularProds');
		$popularProds = $cache->readCache();

		if (!$cache->cacheStatus) {
			$popularProds = $db->select("SELECT I.name, I.image, I.price, I.sale_price, I.productId , COUNT(I.productId) AS total FROM ".$glob['dbprefix']."CubeCart_order_inv AS O, ".$glob['dbprefix']."CubeCart_inventory AS I, ".$glob['dbprefix']."CubeCart_category AS C WHERE O.productId = I.productId AND C.cat_id = I.cat_id AND C.hide != '1' AND I.disabled != '1' AND I.cat_id > 0 GROUP BY I.name DESC ORDER BY total DESC", $config['noPopularBoxItems']);
			$cache->writeCache($popularProds);
		}
	} else {
		## we wont cache this as it changes too quickly
		$popularProds = $db->select("SELECT I.name, I.image, I.price, I.sale_price, I.productId FROM ".$glob['dbprefix']."CubeCart_inventory AS I, ".$glob['dbprefix']."CubeCart_category AS C WHERE C.cat_id = I.cat_id AND I.cat_id > 0 AND I.disabled = '0' AND (C.cat_desc != '##HIDDEN##' OR C.cat_desc IS NULL) ORDER BY I.popularity DESC",$config['noPopularBoxItems']);
	}

	$box_content = new XTemplate('boxes'.CC_DS.'popularProducts.tpl');

	$box_content->assign('LANG_POPULAR_PRODUCTS_TITLE', $lang['popularProducts']['popular_products']);
	

	if ($popularProds) {
		foreach ($popularProds as $popProduct) {
			if (($val = prodAltLang($popProduct['productId']))) {
				$popProduct['name'] = $val['name'];
			}
			$popProduct['name']		= validHTML($popProduct['name']);

			$box_content->assign('DATA', $popProduct);
			
	//Ben's price add
	if (!salePrice($popularProducts[$i]['price'], $popularProducts[$i]['sale_price']) || !$config['saleMode']) {
			$index->assign('TXT_PRICE', priceFormat($popularProducts[$i]['price'], true));
		} else {
			$index->assign('TXT_PRICE', "<span class='txtOldPrice'>".priceFormat($popularProducts[$i]['price'], true)."</span>");
		}
	$salePrice = salePrice($popularProducts[$i]['price'], $popularProducts[$i]['sale_price']);

		$index->assign('TXT_SALE_PRICE', priceFormat($salePrice, true));
		//Ben's price add: END		
			
			
			//MOD Popular Product Images - START		
	$thumbRootPath	= imgPath($popProduct['image'],$thumb=1,$path="root");
	$thumbRelPath	= imgPath($popProduct['image'],$thumb=1,$path="rel");
	if (file_exists($thumbRootPath) && !empty($popProduct['image'])) {
		$box_content->assign("PROD_IMG_SRC", $thumbRelPath);
	} else {
		$box_content->assign("PROD_IMG_SRC", "skins/". SKIN_FOLDER . "/styleImages/thumb_nophoto.gif");
	}
	
//MOD Popular Product Images - END
			$box_content->parse('popular_products.li');
		}
	}

	$box_content->parse('popular_products');
	$box_content = $box_content->text('popular_products');
} else {
	$box_content = '';
}
?>

Few things to help you out. The code wasn’t copy and paste without modification in another file. Here are the changes you should make…

  1. You should have:

$box_content->assign

not


$index_content->assign

I see 3.

  1. After you fix this, you’re going to have another error. Look at the variable you are assigning the product as.

$popProduct

The copy and paste code again, will need some modifications to match this var instead of the


$popularProducts[$i]['price'] /* You need to change this to something starting with $popProduct .. it will look like the others. */

That’s it.