View Single Post
  #5  
Old 04-30-2003, 09:52 PM
  minorgod's Avatar 
minorgod minorgod is offline
 

X-Adept
  
Join Date: Sep 2002
Location: Arivaca, AZ
Posts: 402
 

Default Solution to product options on products.tpl

Well it was harder than it should have been and this may not be the best way, but here's the code to do it in xcart 3.3.1.

You will need to modify the following files:
customer/products.php
skindirectory/customer/main/products.tpl

And you'll need to create the following file:
skindirectory/Modules/Product_Options/customer_options_productspage.tpl

I am pasting the code below with no warranty whatsoever. I have left extensive comments in the customer_options_productspage.tpl where certain functionality remains unfinished because I don't need it yet. It is also there to give other programmers a possible starting point for finishing this script.

Note: among the unimplemented functionality is price modification based on chosen options. In other words, if you have options that modify the price of your product, this code will not work as is. Othewise, you should be okay using this code, but I don't guarantee it.

Here's the code:

customer/products.php
Code:
<? /*****************************************************************************\ +-----------------------------------------------------------------------------+ | X-Cart | | Copyright (c) 2001-2002 Ruslan R. Fazliev. All rights reserved. | +-----------------------------------------------------------------------------+ | The Ruslan R. Fazliev forbids, under any circumstances, the unauthorized | | reproduction of software or use of illegally obtained software. Making | | illegal copies of software is prohibited. Individuals who violate copyright | | law and software licensing agreements may be subject to criminal or civil | | action by the owner of the copyright. | | | | 1. It is illegal to copy a software, and install that single program for | | simultaneous use on multiple machines. | | | | 2. Unauthorized copies of software may not be used in any way. This applies | | even though you yourself may not have made the illegal copy. | | | | 3. Purchase of the appropriate number of copies of a software is necessary | | for maintaining legal status. | | | | DISCLAIMER | | | | THIS SOFTWARE IS PROVIDED BY Ruslan R. Fazliev ``AS IS'' AND ANY | | EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | | DISCLAIMED. IN NO EVENT SHALL Ruslan R. Fazliev OR ITS | | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | | | The Initial Developer of the Original Code is Ruslan R. Fazliev. | | Portions created by Ruslan R. Fazliev are Copyright (C) 2001-2002 | | Ruslan R. Fazliev. All Rights Reserved. | +-----------------------------------------------------------------------------+ \*****************************************************************************/ # # $Id: products.php,v 1.30 2002/11/19 12:06:10 alfiya Exp $ # # Navigation code # $objects_per_page = $config["General"]["products_per_page"]; $total_nav_pages = ceil($current_category["product_count"]/$config["General"]["products_per_page"])+1; require "../include/navigation.php"; if($active_modules["Advanced_Statistics"]) include "../modules/Advanced_Statistics/cat_viewed.php"; //if($active_modules["Product_Options"]) // include "../modules/Product_Options/customer_options_productspage.php"; # # Get products data for current category and store it into $products array # $search_query = "($sql_tbl[products].categoryid='$cat' or $sql_tbl[products].categoryid1='$cat' or $sql_tbl[products].categoryid2='$cat' or $sql_tbl[products].categoryid3='$cat') and $sql_tbl[products].forsale='Y'"; $products = func_search_products($search_query, $user_account['membership'], $first_page,$current_category["product_count"]); if (count($products) ==0) $products=""; if($active_modules["Subscriptions"]) { include "../modules/Subscriptions/subscription.php"; } //--------Brett's Additions if($active_modules["DigitalSubscriptions"]) { include "../modules/DigitalSubscriptions/digital_subscription.php"; } //------------end Brett's Additions // Product Options Mod by Brett Brewer foreach($products as $key=>$value){ // first we loop through the products and get their options if they have any $query="SELECT * from $sql_tbl[product_options],$sql_tbl[product_options_js] WHERE $sql_tbl[product_options].productid='$value[productid]' AND $sql_tbl[product_options_js].productid='$value[productid]'"; $products[$key]['product_options']=func_query($query); } // now we loop through the products again and parse the options foreach($products as $key=>$value){ if(is_array($value['product_options'])) foreach($value['product_options'] as $k=>$v){ //we need to parse the options so that the template can understand them... // this is brute force value grabbing...the index 4 should be changed to a reference to an associative array index, // but I didn't see it when viewing the variables in the modified x-cart debugger window. $products[$key]['product_options'][$k]['options']=func_parse_options($v[4]); } } // now that we have all the options and the javascript code we need to parse the names of the // javascript functions and number them the same way the forms and form elements on the template will be numbered. // I'm not sure this is the best solution for this, but it was the only one I could think of. for($i=0;$i<count($products);$i++){ for($j=0;$j<count($products[$i]['product_options']);$j++){ $javascript=$products[$i]['product_options'][$j]['javascript_code']; $pattern="/product_option/i"; $replacement="product_option_".$i."_".$j; $new_javascript=preg_replace($pattern,$replacement,$javascript); $products[$i]['product_options'][$j]['javascript_code']=$new_javascript; //echo $replacement; } } // Now, presumably, the data is correctly formatted for the template. The code segments below represent fragments of the rest of the product.php page // that we are sort of emulating above. The code below needs to be implemented in some form so that any options that affect the price of each // product are taken into account. I haven't been able to figure this out yet. /* if($products) foreach($products as $key=>$value) { $productid = $value["productid"]; $amount = $value["amount"]; $options = $value["product_options"]; //echo " <pre>\$options:"; //print_r($options); //echo "</pre>"; // echo "end \$options "; # # Product options code # $query="select * from $sql_tbl[product_options] where productid='$value[productid]' order by orderby"; $product_option_lines = func_query($query); //echo $query; $product_options = array(); //echo " \$product_option_lines: <pre>"; //print_r($product_option_lines); //echo "</pre>"; //echo "end \$product_option_lines "; if($product_option_lines) foreach($product_option_lines as $product_option_line) $product_options[$product_option_line["optclass"]] = func_parse_options($product_option_line["options"]); $absolute_surcharge = 0; $percent_surcharge = 0; $this_product_options = ""; //echo " \$product_options: <pre>"; //print_r($product_options); //echo "</pre>"; //echo "end \$product_options "; */ # # Calculate option surcharges # /* echo " \$options: <pre>"; print_r($options); echo "</pre>"; echo "end \$options "; if(is_array($options)) foreach($options as $option) { $my_option = $product_options[$option["optclass"]][$option["optionindex"]]; echo " \$my_option: <pre>"; print_r($my_option); echo "</pre>"; echo "end \$my_option "; if(!empty($product_options[$option["optclass"]])) { $this_product_options.="$option[optclass]: $my_option[option]\n"; if($my_option["type"]=="absolute") $absolute_surcharge+=$my_option["surcharge"]; elseif($my_option["type"]=="percent") $percent_surcharge+=$my_option["surcharge"]; } else $this_product_options.="$option[optclass]: $option[optionindex]\n"; } $this_product_options = chop($this_product_options); echo " \$this_product_options:<pre>"; print_r($this_product_options); echo "</pre>"; echo "end \$this_product_options "; if($products[$key]['product_options']) foreach($products[$key]['product_options'] as $k=>$v){ $products[$key]['product_options'][$k]['options']=$this_product_options; } # # /Product options # }*/ //foreach($products as $key=>$value){ // if(is_array($value['product_options'])) // foreach($value['product_options'] as $k=>$v){ // $products[$key]['product_options'][$k]['options']=$product_options; // } //} //echo " \$products: <pre>"; //print_r($products); //echo "</pre>"; //-----END Product Options Mod by Brett Brewer $smarty->assign("products",$products); $smarty->assign("navigation_script","home.php?cat=$cat"); ?>

skindirectory/customer/main/products.tpl
Code:
{* $Id: products.tpl,v 1.21.2.1 2003/01/20 12:57:59 svowl Exp $ *} {section name=product loop=$products} <form name=orderform_{%product.index%} method=post action="cart.php?mode=add"> <table border=0 width=100%> <tr> <td width=90 align=center valign=top> <a href=../product.php?productid={$products[product].productid}&cat={$cat}&page={$navigation_page}>{include file="product_thumbnail.tpl" productid=$products[product].productid image_x=70 product=$products[product].product} {$lng.lbl_see_details}</a> </td> <td valign=top> {$products[product].product|escape}</font> <font size=1> {$products[product].descr|truncate:300:"...":true} </font> <hr size=1 noshade width=230 align=left> {if $active_modules.Subscriptions ne "" and $products[product].catalogprice} {include file="modules/Subscriptions/subscription_info_inlist.tpl"} {else} {if $products[product].price ne 0} {if $products[product].discount ne 0} <font class=MarketPrice>{$lng.lbl_market_price}: <s> {math equation="price/(1-(discount/100))" price=$products[product].price discount=$products[product].discount format="%d.00" assign=unformatted}{include file="currency.tpl" value=$unformatted} </s></font> {/if} <font class=ProductPrice>{$lng.lbl_our_price}: {include file="currency.tpl" value=$products[product].price}</font><font class=MarketPrice>{include file="customer/main/alter_currency_value.tpl" alter_currency_value=$products[product].price}</font>{if $products[product].discount ne 0}, save {$products[product].discount}%{/if}{if $config.General.use_vat eq "Y"}, {$lng.lbl_including_vat} {$products[product].vat}%{/if} {else} <font class=ProductPrice>{$lng.lbl_enter_your_price}</font> {/if} {/if} <table border="0" cellspacing="0" cellpadding="5"> {if $active_modules.Product_Options ne ""}{ include file="modules/Product_Options/customer_options_productspage.tpl"} {/if} <tr> <td>{$lng.lbl_quantity} {if $product.min_amount gt 1} <font class=ProductDetailsTitle>{$lng.txt_need_min_amount}{$product.min_amount}{$lng.lbl_items}</font> {/if} </td> <td> {if $config.General.show_in_stock eq "Y" and ($product.avail le 0 or $product.avail lt $product.min_amount)} {$lng.txt_out_of_stock} {else} {if $config.General.show_in_stock ne "Y"} {assign var="mq" value=$config.General.max_select_quantity} {else} {math equation="min(maxquantity+minamount, productquantity)+1" assign="mq" maxquantity=$config.General.max_select_quantity minamount=$product.min_amount productquantity=$product.avail} {/if} {if $products[product].distribution eq ""} <select name=amount> {if $product.min_amount le 1} {assign var="start_quantity" value=1} {else} {assign var="start_quantity" value=$product.min_amount} {/if} {section name=quantity loop=$mq start=$start_quantity} <option value="{%quantity.index%}" {if $smarty.get.quantity eq %quantity.index%}selected{/if}>{%quantity.index%}</option> {/section} </select> {else} <font class=ProductDetailsTitle>1</font> {$lng.txt_product_downloadable}<input type=hidden name=amount value=1> {/if} {/if} </td> </tr> </table> <a href="javascript:{if $products[product].product_options ne ""}if (FormValidation_{%product.index%}()){/if} document.orderform_{%product.index%}.submit()"> {include file="buttons/add_to_cart.tpl"}</a> <input type=hidden name=mode value=add> <input type=hidden name=productid value="{$products[product].productid}"> <input type=hidden name=cat value="{$smarty.get.cat}"> <input type=hidden name=page value="{$smarty.get.page}"> <a href="product.php?productid={$products[product].productid}&cat={$cat}&page={$navigation_page}">{include file="buttons/more_info.tpl"}</a> </td> </tr> </table> </form> <hr size="1" noshade> {/section}

skindirectory/modules/Product_Options/customer_options_productspage.tpl
Code:
{* $Id: customer_options.tpl,v 1.6 2002/10/22 10:27:05 olga Exp $ *} {section name=product_option loop=$products[product].product_options} <SCRIPT language=JavaScript1.2> <!-- function product_option_{%product.index%}_{%product_option.index%}(name_of_option) {literal}{ {/literal} for(i=0; i<={php}echo count($product_options) {/php}; i++) if (document.orderform_{%product.index%}[i].name.search(name_of_option) != -1) return document.orderform_{%product.index%}[i]; return -1; {literal} } {/literal} function FormValidation_{%product.index%}() {literal}{ {/literal} {if $products[product].product_options[product_option].javascript_code} {$products[product].product_options[product_option].javascript_code} {else} return true; {/if} {literal} } --> </SCRIPT> {/literal} <tr> <td valign=right align="left"> {$products[product].product_options[product_option].opttext} </td> <td valign=left> {if $products[product].product_options[product_option].options ne ""} {assign var="options" value=$products[product].product_options[product_option].options} <select name="product_options[{$products[product].product_options[product_option].optclass}]"> {section name=option loop=$options} <option value={$smarty.section.option.index}>{$options[option].option}{if $options[option].surcharge ne 0} ({if $options[option].type eq "absolute"}{$config.General.currency_symbol}{else}%{/if}{$options[option].surcharge}){/if}</option> {/section} </select> {else} <input type=text name="product_options[{$products[product].product_options[product_option].optclass}]" size=32> {/if} </td> </tr> {/section} {if $err eq "options" and $products[product].product_options[product_option].exceptions ne ""} <TR> <TD colspan=2><FONT class=CustomerMessage>Note: this product cannot be added to the cart with the following options combinations:</FONT></TD> </TR> <TR valign=top> <TD colspan=2> {section name=oi loop=$products.product_options[product_option].exceptions} * {$products.product_options[product_option].exceptions[oi].exception} {/section} </TD> </TR> {/if}

The above code really needs some cleaning up and there's still some code in there for my own custom mods that you may not have. I'll come back later and clean it up if anyone wants me to.

Enjoy.
__________________
www.brettbrewer.com
Getting back into x-cart dev after a long hiatus. Modded lots of x-carts from version 3.1.x to 4.1.x. Developer of ImageScaler mod, Pre-login per user coupon mod, Wordpress feed mod, DigitalSubscriptions mod, Phonetic bulk download keys addon for DownloadExpander mod, Serial Number Generator for ESD products, Custom CMS/LMS integrations, external products mod, and more.
Reply With Quote