Jump to content
  • Checkout
  • Login
  • Get in touch

osCommerce

The e-commerce.

The "tep_draw_pull_down_menu" function


Guest

Recommended Posts

Posted

Hello, I am currently working on a customised version of osC 2.2rc2a which is fully XHTML 1.0 Strict compliant and I have come across a problem to do with the tep_draw_pull_down_menu function. Basically the product_info.php is fine apart from when you get a product which has attributes.

 

For example, on the default osC installation one of the products, a Matrox G400 32MB graphics card, has options for 'memory' and 'model'. Now when I look at the source code for the page generated, I get this:

 

<select name="id[4]" id="id[4]">
<select name="id[3]" id="id[3]">

 

Basically, the page does not validate because the name and ID contain the "[" and "]" characters which are not allowed.

 

If I click on the Add To Cart button, in the shopping_cart.php file the following can be found in the source code for the page generated:

 

<input type="hidden" name="id[2{4}3{3}6][4]" id="id[2{4}3{3}6][4]" value="3" />
<input type="hidden" name="id[2{4}3{3}6][3]" id="id[2{4}3{3}6][3]" value="6" />

 

Now I can obviously replace them with something else in product_info.php but I'm a bit lost as to where to change things in shopping_cart.php and possibly other files as well.

 

Can anyone advise on this at all?

 

Thanks.

Posted

Manipulating the square brackets in any way would have a knock on effect to the entire attribute workings, so you're going to have to look into that area in depth to ensure that changing them is that simple.

 

How committed are you to the "Strict" doctype? I have a fully validated XHTML 1.0 Transitional product_info.php page that validates with the square brackets in place.

Posted

The rest of product_info.php validates it's just these square brackets. I thought I could get away with using the HTML number equivalents for the square brackets (i.e. & #91 and & #93) but you can't even use the & sign in the ID token which is annoying me greatly. I would ideally like to have the entire site validated as XHTML 1.0 Strict as the majority of the site validates as this, I'm just not sure whereabouts I should be looking with regards to the attributes.

Posted

Before I post any kind of guidance.. are you using the QTPro contribution?

Posted

Ok, in that case I can tell you this much..

 

When a customer adds a product from the 'product_info.php' page it calls this code in 'includes/application_top.php':

 

	  // customer adds a product from the products page
  case 'add_product' :	if (isset($HTTP_POST_VARS['products_id']) && is_numeric($HTTP_POST_VARS['products_id'])) {
							$cart->add_cart($HTTP_POST_VARS['products_id'], $cart->get_quantity(tep_get_uprid($HTTP_POST_VARS['products_id'], $HTTP_POST_VARS['id']))+1, $HTTP_POST_VARS['id']);
						  }
						  tep_redirect(tep_href_link($goto, tep_get_all_get_params($parameters)));
						  break;

The last instance of '$HTTP_POST_VARS['id']' is where the attribute(s) from the 'product_info.php' page are carried to the 'add_cart()' function in 'includes/classes/shopping_cart.php':

 

	function add_cart($products_id, $qty = '1', $attributes = '', $notify = true) {
  global $new_products_id_in_cart, $customer_id;

  $products_id_string = tep_get_uprid($products_id, $attributes);
  $products_id = tep_get_prid($products_id_string);

  if (defined('MAX_QTY_IN_CART') && (MAX_QTY_IN_CART > 0) && ((int)$qty > MAX_QTY_IN_CART)) {
	$qty = MAX_QTY_IN_CART;
  }

  $attributes_pass_check = true;

  if (is_array($attributes)) {
	reset($attributes);
	while (list($option, $value) = each($attributes)) {
	  if (!is_numeric($option) || !is_numeric($value)) {
		$attributes_pass_check = false;
		break;
	  }
	}
  }

  if (is_numeric($products_id) && is_numeric($qty) && ($attributes_pass_check == true)) {
	$check_product_query = tep_db_query("select products_status from " . TABLE_PRODUCTS . " where products_id = '" . (int)$products_id . "'");
	$check_product = tep_db_fetch_array($check_product_query);

	if (($check_product !== false) && ($check_product['products_status'] == '1')) {
	  if ($notify == true) {
		$new_products_id_in_cart = $products_id;
		tep_session_register('new_products_id_in_cart');
	  }

	  if ($this->in_cart($products_id_string)) {
		$this->update_quantity($products_id_string, $qty, $attributes);
	  } else {
		$this->contents[$products_id_string] = array('qty' => (int)$qty);
// insert into database
		if (tep_session_is_registered('customer_id')) tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET . " (customers_id, products_id, customers_basket_quantity, customers_basket_date_added) values ('" . (int)$customer_id . "', '" . tep_db_input($products_id_string) . "', '" . (int)$qty . "', '" . date('Ymd') . "')");

		if (is_array($attributes)) {
		  reset($attributes);
		  while (list($option, $value) = each($attributes)) {
			$this->contents[$products_id_string]['attributes'][$option] = $value;
// insert into database
			if (tep_session_is_registered('customer_id')) tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " (customers_id, products_id, products_options_id, products_options_value_id) values ('" . (int)$customer_id . "', '" . tep_db_input($products_id_string) . "', '" . (int)$option . "', '" . (int)$value . "')");
		  }
		}
	  }

	  $this->cleanup();

// assign a temporary unique ID to the order contents to prevent hack attempts during the checkout procedure
	  $this->cartID = $this->generate_cart_id();
	}
  }
}

The particular parts of this function you're interested in are these:

 

	  $attributes_pass_check = true;

  if (is_array($attributes)) {
	reset($attributes);
	while (list($option, $value) = each($attributes)) {
	  if (!is_numeric($option) || !is_numeric($value)) {
		$attributes_pass_check = false;
		break;
	  }
	}
  }

			if (is_array($attributes)) {
		  reset($attributes);
		  while (list($option, $value) = each($attributes)) {
			$this->contents[$products_id_string]['attributes'][$option] = $value;
// insert into database
			if (tep_session_is_registered('customer_id')) tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " (customers_id, products_id, products_options_id, products_options_value_id) values ('" . (int)$customer_id . "', '" . tep_db_input($products_id_string) . "', '" . (int)$option . "', '" . (int)$value . "')");
		  }
		}

These break down the "id[x]" values to get the option ('Colour', 'Size', etc) and value ('Red', 'Blue', 'Medium', etc) ids. If you were to manipulate the form fields then you would most definitely have to rewrite this code to extract the two numbers osCommerce requires.

 

But these aren't the only functions you would have to manipulate, there are several key functions that all break down the current attribute format in the same way.

Posted

Sounds like a potentially mammoth task I think!

 

Thanks for the advice and help though, definately appreciated! :)

Posted

No problem. It's an interesting issue and I would certainly like to hear if you have any success with it.

Posted
Sounds like a potentially mammoth task I think!

 

Thanks for the advice and help though, definately appreciated! :)

 

this technique is also used extensively in the admin. take a look at admin/categories.php. a lot of the input fields are constructed with the brackets so that a variable number of languages can be supported.

 

i'm sure there are other areas that use this as well, so you should keep yours eyes out for them. likely candidates would be anywhere lists are processed, like the shopping cart. possibly even the address book, since one customer can have multiple addresses -- although i haven't looked at that code, i'm just guessing.

 

good luck.

Posted

Thanks Dave.

 

Address Book doesn't use attributes or square brackets in form fields so they are OK.

 

I'm not bothered about the admin side for now, I just want to make sure everything validates as Strict in the front end. Anything I break in the front end won't affect the admin anyway as the admin side uses it's own set of class/function files etc.

 

I've made some progress on replacing the curly brackets (i.e. { and }) with different characters (easy part), I just need to devise a way of converting a certain sequence of characters into square brackets for the functions (not so easy part).

 

If I manage to sort this out I will naturally post up details of what I've replaced so that it can help other people that wish their osC stores to validate as XHTML 1.0 Strict. :)

Posted

Right I think it's going to take a lot of investigation to get this recoded for Strict, so for now due to time constraints I am going to have to change this page (and any pages that need the square brackets in the ID tag) to Transitional for now.

 

Bit of a cop out for now, but once I finish this site I am working on I will be able to spend more time on this problem.

Posted

Ignore my last post, I managed to get it to validate with Strict! Yay!

 

All I had to do is use the 'name' token only, because validation will fail if there are square brackets or other 'illegal' characters in the 'ID' token.

 

Here is what I have done so far:

 

catalog/includes/functions/html_output.php

 

In my modified tep_draw_pull_down_menu function code, I had this:

 

$field = '<select name="' . tep_output_string($name) . '" id="' . tep_output_string($name) . '"';

I created a duplicate function called tep_draw_pull_down_menu_trans, the only difference between the two functions is the above quoted line of code is now changed to:

 

$field = '<select name="' . tep_output_string($name) . '"';

 

catalog/product_info.php

 

Search and replace tep_draw_pull_down_menu with tep_draw_pull_down_menu_trans. In the vanilla product_info.php file, the code you are looking for is on line 150:

 

<td class="main"><?php echo tep_draw_pull_down_menu('id[' . $products_options_name['products_options_id'] . ']', $products_options_array, $selected_attribute); ?></td>

That's it!

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...