shopping_cart logic - Help please
I'm porting my first mod from OSC, and i'm trying to work through some code changes that the mod makes to the shopping_cart.php file in OSC. Having done some digging, i've found that zen cart uses two files to create the shopping_cart output. modules\pages\shopping_cart\header_php.php and templates\tpl_shopping_cart_default.php.
The issue i have is that i don't want to put sql queries in the tpl file, as it appears they belong in the header_php file, but if i put them in there, then i can't get any output from the variables. Am i supposed to be collecting all the information into an array that is passed to the tpl_ file, or is it called in another way?
Hope that's clear enough.
Thanks in advance for any advice
Steve
Re: shopping_cart logic - Help please
Hi,
The best thing to do is to not add anything to the template or the header but to use an observer/notifier.
There is a load of information in the wiki....
http://www.zen-cart.com/wiki/index.p...Observer_Class
...including examples that show how to do things with the shopping cart.
Using an observer/notifier means that your contribution will touch less of the Zen Cart files and be easier to install and work better with upgrades.
Regards,
Christian.
Re: shopping_cart logic - Help please
Christian's right - using the observer/notifier system is a less-intrusive way of expanding functionality.
However, that said, any variables you create in the header_php.php file should still be accessible in the tpl template file for that page. There's no need to use an array to pass data unless it's array-type data. An array is just another variable anyway, so creating another variable shouldn't be a problem.
Re: shopping_cart logic - Help please
I've had a good read of the info on the Wiki, which is very useful, but leaves me with one question. Using the observer/notifier system, can you insert code in these files to structure the layout of the data that is created, or is it purely for logic code? If it is only for logic code, am i forced to hack core files to format the output as required?
Thanks
Steve
Re: shopping_cart logic - Help please
What you'll need to do is really determined by what you want to accomplish -- which you haven't shared.
Re: shopping_cart logic - Help please
What i'm trying to achieve is a port of the OScommerce Dangling Carrot mod, but with a few enhancements to its functionality. As it runs on OSC, it displays information in the shopping cart to show that you are close to the threshold for a gift, or you have reached the threshold and are now entitled to 'x' product. Modifications to the OSC mod will enable the site owner to set a discounted price for the gift through admin, so if for instance you spend $100 you can have 'y' product for $10 instead of $20. I realise that there are similar ideas presented on the wiki, but they lack the functionality that i am looking to put into the Dangling Carrot module.
Thanks
Steve
Re: shopping_cart logic - Help please
Okay.
What kinds of variables are you adding to the header_php.php that aren't showing up when the template is run? Is "everything" you added not showing up, or just "some" pieces? Perhaps some of your vars aren't echoing what you expected because you're not filling them with information properly ... ie: incorrect syntax on a loop through database results, etc.
One handy option you have with something like this is to put all your custom variable code into a new file named main_template_vars.php in the same folder as the header_php.php. All your vars can be built there, queries run, etc, and not have to touch the header_php.php file.
The header file is used mainly to establish prerequisites prior to the templating system kicking in to draw page content. If a page-redirect would be required, you need to know about it in the header_php stage so that no output goes to the browser and thus blocks the redirect etc.
The one drawback to using a main_template_vars file is that you'll need to manually call the template file at the end of it. Peek at /includes/modules/pages/specials/main_template_vars.php as an example of some queries running and vars being set, and then calling the template file.
Re: shopping_cart logic - Help please
Quote:
Originally Posted by
strelitzia
What i'm trying to achieve is a port of the OScommerce Dangling Carrot mod, but with a few enhancements to its functionality. As it runs on OSC, it displays information in the shopping cart to show that you are close to the threshold for a gift, or you have reached the threshold and are now entitled to 'x' product. Modifications to the OSC mod will enable the site owner to set a discounted price for the gift through admin, so if for instance you spend $100 you can have 'y' product for $10 instead of $20. I realise that there are similar ideas presented on the wiki, but they lack the functionality that i am looking to put into the Dangling Carrot module.
Thanks
Steve
There's this contribution in the downloads section that might be helpful to you.
Re: shopping_cart logic - Help please
And which mod would that be Clyde as it's not a link :-O
Might be able to take a peek at the code..see if i can use any of it.
Thanks
Steve
Re: shopping_cart logic - Help please
Quote:
Originally Posted by
strelitzia
And which mod would that be Clyde as it's not a link :-O
Might be able to take a peek at the code..see if i can use any of it.
Thanks
Steve
Sorry 'bout that, here's the link
Shopping Cart Free-Shipping-Qualifier Sidebox
Re: shopping_cart logic - Help please
Thanks Clyde, i'll take a look at that.
Dr Byte, useful information from you yet again. Thanks for the pointers.
Steve
Re: shopping_cart logic - Help please
Dr Byte...
The section of code below is requiring information from a new sql query that would be placed in the main_template_vars file, and also information from a query that is being made in the header_php.php file. What is the best solution to get around this issue?? Run the required sql query again in main_template_vars, or is there a way that data can be passed from header_php to main_template_vars?
Code:
if ($gift_exists == 0){
if ($products[$i]->fields['id'] == $gift->fields['products_id']) { // gift already in cart
$gift_exists = $products[$i]->fields['id'];
$gift_price = $gifts->fields['products_price'];
$deficit = $gift->fields['threshold'] - $num_in_cart + $gift_price;
break;
} else {
$deficit = $gift->fields['threshold'] - $num_in_cart;
}
} else {
$deficit = $gift->fields['threshold'] - $num_in_cart + $gift_price;
}
$gift->MoveNext();
Thanks
Steve
Re: shopping_cart logic - Help please
Once you loop through the results of a query, you have to re-run that query to loop through its content again.
If the variables set in header_php.php already contain the information you need, you can still reference them in main_template_vars.php, as they well already be set and available.
Re: shopping_cart logic - Help please
Ok. I understand what you're saying there. What i don't yet understand is in which order is the code processed? Does it call header_php.php before it calls main_template_vars.php
As an example, if i have a new query that takes data from a table to see what has been set as a free gift, it then has to check to see if any of the products in the cart are the free gift. How can ensure that it has already run the query to get the data on what is in the cart, before it runs the query to check against the list of gifts available?
Thanks
Steve
Re: shopping_cart logic - Help please
header_php.php runs first, followed by main_template_vars.php when the template section is executed.
http://www.zen-cart.com/index.php?ma...roducts_id=378
Re: shopping_cart logic - Help please
Oh drat...that throws my theory of why i can't get the results i want out of the window.
Using this code:
Code:
$num_in_cart = $currencies->format($_SESSION['cart']->show_total());
$products = $_SESSION['cart']->get_products();
$gift = $db->Execute("SELECT fg.*, p.products_id, p.products_model, p.products_price, p.products_image, p.products_status, pd.products_name FROM " . TABLE_CARROT . " fg, " . TABLE_PRODUCTS . " p
LEFT JOIN " . TABLE_PRODUCTS_DESCRIPTION . " pd ON (pd.products_id=fg.products_id)
WHERE pd.language_id = '" . (int)$_SESSION['languages_id'] . "' AND p.products_id = fg.products_id AND p.products_status = '1' ORDER BY fg.threshold ASC");
$threshold = 0;
$p=0;
$gift_price=0;
$gift_exists=0;
while (!$gift->EOF) { // loop through the current gifts
if ($gift_exists == 0){
if ($products[$i]->fields['id'] == $gift->fields['products_id']) { // gift already in cart
$gift_exists = $products[$i]->fields['id'];
$gift_price = $gift->fields['products_price'];
$deficit = $gift->fields['threshold'] - $num_in_cart + $gift_price;
break;
} else {
$deficit = $gift->fields['threshold'] - $num_in_cart;
}
} else {
$deficit = $gift->fields['threshold'] - $num_in_cart + $gift_price;
}
$gift->MoveNext();
if ( $deficit < 20 && $deficit > 0 ) {
$near_limit = 1;
} else {
$near_limit = 0;
}
if ($num_in_cart >= $gift->fields['threshold'] && $deficit <= 0) {
// cart could qualify for this gift
// check to see if in cart already
// add to gift list if not in cart
if ($gift['products_id'] != $gift_exists && $deficit <= 0) { // this particular gift is not in cart but qualifies
$freebie[$p]['message'] .= sprintf(TEXT_QUALIFIED_FOR_GIFT, $currencies->display_price($gift->fields['threshold'],zen_get_tax_rate($gift['products_tax_class_id'])));
$freebie[$p]['link'] = '<a href="' . zen_href_link($_GET['main_page'], zen_get_all_get_params(array('action')) . 'action=buy_now&products_id=' . $gift->fields['products_id']) . '">' . zen_image_button(BUTTON_IMAGE_BUY_NOW, BUTTON_BUY_NOW_ALT, 'class="listingBuyNowButton"' . $gift->fields['products_id'] ) . '</a>';
$freebie[$p]['name'] = $gift->fields['products_name'];
$freebie[$p]['id'] = $gift->fields['products_id'];
$freebie[$p]['image'] = $gift->fields['products_image'];
$p++;
} else if ($near_limit) {
if ($gift->fields['products_id'] != $gift_exists) { // this particular gift is not in cart
$freebie[$p]['message'] .= sprintf(TEXT_CLOSE_TO_FREE_GIFT, $currencies->display_price($deficit,tep_get_tax_rate($gift['products_tax_class_id'])));
$freebie[$p]['link'] = '';
$freebie[$p]['name'] = $gift->fields['products_name'];
$freebie[$p]['id'] = $gift->fields['products_id'];
$freebie[$p]['image'] = $gift->fields['products_image'];
$p++;
} else {
// cart cannot qualify for this gift
// remove if in cart
$cart->remove($gift->fields['products_id']);
}
} else {
// cart cannot qualify for this gift
// remove if in cart
$cart->remove($gift->fields['products_id']);
}
$threshold = $gift->fields['threshold'];
}
}
I am not getting the results i expect. If i echo any of the variables that are from the sql query written then i get the expected output, however, if i echo any output that combines $products[$i] which appears to be called in the header_php, then i don't get any output. I'm checking all my syntax in case i've written in an error, but thus far i havn't spotted anything obvious.
Can you see anything wrong in the above code?
Thanks
Steve
Re: shopping_cart logic - Help please
I'm not sure why your $gift->MoveNext() was in the middle of the while loop instead of at the end. Running that function changes the pointer of which $gift record you're pointing at, causing all the code below it to refer to the "next" record instead of the current one used in the first half.
Additionally, you're not even using the $products variable ... or rather, you were trying to use it, but using $products[$i] without looping through all the available iterations of $i when using it will leave you comparing wrong data with wrong data, and getting results you don't want or expect.
I've not tested the following, but I propose these changes may be a little closer to what you need:
Code:
$num_in_cart = $currencies->format($_SESSION['cart']->show_total());
$products = $_SESSION['cart']->get_products();
$gift = $db->Execute("SELECT fg.*, p.products_id, p.products_model, p.products_price, p.products_image, p.products_status, pd.products_name FROM " . TABLE_CARROT . " fg, " . TABLE_PRODUCTS . " p
LEFT JOIN " . TABLE_PRODUCTS_DESCRIPTION . " pd ON (pd.products_id=fg.products_id)
WHERE pd.language_id = '" . (int)$_SESSION['languages_id'] . "' AND p.products_id = fg.products_id AND p.products_status = '1' ORDER BY fg.threshold ASC");
$threshold = 0;
$p=0;
$gift_price=0;
$gift_exists=0;
while (!$gift->EOF) { // loop through the current gifts
if ($gift_exists == 0){
if ($_SESSION['cart']->in_cart($gift->fields['products_id'])) { // gift already in cart
$gift_exists = $gift->fields['products_id'];
$gift_price = $gift->fields['products_price'];
$deficit = $gift->fields['threshold'] - $num_in_cart + $gift_price;
break;
} else {
$deficit = $gift->fields['threshold'] - $num_in_cart;
}
} else {
$deficit = $gift->fields['threshold'] - $num_in_cart + $gift_price;
}
if ( $deficit < 20 && $deficit > 0 ) {
$near_limit = 1;
} else {
$near_limit = 0;
}
if ($num_in_cart >= $gift->fields['threshold'] && $deficit <= 0) {
// cart could qualify for this gift
// check to see if in cart already
// add to gift list if not in cart
if ($gift['products_id'] != $gift_exists && $deficit <= 0) { // this particular gift is not in cart but qualifies
$freebie[$p]['message'] .= sprintf(TEXT_QUALIFIED_FOR_GIFT, $currencies->display_price($gift->fields['threshold'],zen_get_tax_rate($gift['products_tax_class_id'])));
$freebie[$p]['link'] = '<a href="' . zen_href_link($_GET['main_page'], zen_get_all_get_params(array('action')) . 'action=buy_now&products_id=' . $gift->fields['products_id']) . '">' . zen_image_button(BUTTON_IMAGE_BUY_NOW, BUTTON_BUY_NOW_ALT, 'class="listingBuyNowButton"' . $gift->fields['products_id'] ) . '</a>';
$freebie[$p]['name'] = $gift->fields['products_name'];
$freebie[$p]['id'] = $gift->fields['products_id'];
$freebie[$p]['image'] = $gift->fields['products_image'];
$p++;
} else if ($near_limit) {
if ($gift->fields['products_id'] != $gift_exists) { // this particular gift is not in cart
$freebie[$p]['message'] .= sprintf(TEXT_CLOSE_TO_FREE_GIFT, $currencies->display_price($deficit,tep_get_tax_rate($gift['products_tax_class_id'])));
$freebie[$p]['link'] = '';
$freebie[$p]['name'] = $gift->fields['products_name'];
$freebie[$p]['id'] = $gift->fields['products_id'];
$freebie[$p]['image'] = $gift->fields['products_image'];
$p++;
} else {
// cart cannot qualify for this gift
// remove if in cart
$cart->remove($gift->fields['products_id']);
}
} else {
// cart cannot qualify for this gift
// remove if in cart
$cart->remove($gift->fields['products_id']);
}
$threshold = $gift->fields['threshold'];
}
$gift->MoveNext();
}
Re: shopping_cart logic - Help please
Quote:
Originally Posted by
DrByte
I'm not sure why your $gift->MoveNext() was in the middle of the while loop instead of at the end.
That was an error on my part during the conversion from OSC structure.. oops.
The changes you suggested worked fine, and the correct results are now accessible . I have another stumbling block that i'm struggling with.
The module adds a field to TABLE_PRODUCTS which is called product_carrot. This is set to either 1 or 0 by a switch in the admin section.
Part of the OSC code in shopping_cart is
Code:
if ($products[$i]['carrot'] == "1"){
$products_name = '<table border="0" cellspacing="2" cellpadding="2">' .
' <tr>' .
' <td class="productListing-data" align="center">' . tep_image(DIR_WS_IMAGES . $products[$i]['image'], $products[$i]['name'], SMALL_IMAGE_WIDTH, SMALL_IMAGE_HEIGHT) . '</td>' .
' <td class="productListing-data" valign="top"><b>' . $products[$i]['name'] . '</b>';
}
else{
$products_name = '<table border="0" cellspacing="2" cellpadding="2">' .
' <tr>' .
' <td class="productListing-data" align="center"><a href="' . tep_href_link(FILENAME_PRODUCT_INFO, 'products_id=' . $products[$i]['id']) . '">' . tep_image(DIR_WS_IMAGES . $products[$i]['image'], $products[$i]['name'], SMALL_IMAGE_WIDTH, SMALL_IMAGE_HEIGHT) . '</a></td>' .
' <td class="productListing-data" valign="top"><a href="' . tep_href_link(FILENAME_PRODUCT_INFO, 'products_id=' . $products[$i]['id']) . '"><b>' . $products[$i]['name'] . '</b></a>';
}
Changing this to suit ZC hasn't been a problem, except that if i echo $products[$i]['carrot'] to check the variable is filled, then i get no output. This leads me to believe that the contents of the field products_carrot is not being read from the db.
What i need to do is ensure that the products_carrot field from TABLE_PRODUCTS is passed to the shopping cart along with the rest of the data.
Any help greatly appreciated.
Thanks
Steve
Re: shopping_cart logic - Help please
Quote:
Originally Posted by
strelitzia
Changing this to suit ZC hasn't been a problem, except that if i echo $products[$i]['carrot'] to check the variable is filled, then i get no output. This leads me to believe that the contents of the field products_carrot is not being read from the db.
What i need to do is ensure that the products_carrot field from TABLE_PRODUCTS is passed to the shopping cart along with the rest of the data.
You'll have to add the additional field to the query in the shopping_cart class on line 1054 (circa v1.3.7.1) and also to the array built on line 1176.
Re: shopping_cart logic - Help please
Quote:
Originally Posted by
DrByte
You'll have to add the additional field to the query in the shopping_cart class on line 1054 (circa v1.3.7.1) and also to the array built on line 1176.
That's where i went wrong. I'd added the additional field to the query, but forgot to add it to the array! Beginners mistake and lack of true understanding there i fear!
I have another point that i could do with some advice on.
The original OSC shopping_cart.php file has three sections of code added to make the mod work. The first section is processed before any of the original code is processed, and this is now in my new main_template_vars.php file. The two remaining sections of mod code are run after some of the original code has been processed. Now, where i'm a bit stuck is knowing how i can get this code to be processed at the correct moment if it is in main_template_vars.php and not placed after the relevant code section in tpl_shopping_cart_default.php.
I'm trying to avoid making any changes to the tpl_shopping_cart_default.php and header_php.php files unless strictly necessary as i realise this impacts greatly on ease of future upgrades.
Thanks
Steve
Re: shopping_cart logic - Help please
Sometimes the logic that runs in the template shouldn't be in the template at all ... maybe moving the code into the main_template_vars, perhaps looping through the logic, and producing some variables to echo in the template might be the better choice.