Jump to content
  • Checkout
  • Login
  • Get in touch

osCommerce

The e-commerce.

how to edit $cart array (remove unused attributes)


nobodyfamous

Recommended Posts

I am trying to remove product attributes that are not used when ordering a product. Some of the options are optional and by default will have "Please select" as the selected option.

 

When this occurs I would like to remove them from the attributes array in the cart array.

 

I started with a simple if statement that worked to keep them from displaying in shopping_cart.php, but would require it also in aacount_history.php, orders.php, the email generating code, etc. So it would be easier if I could just keep them from being inserted into the $cart array.

 

I am having trouble tracking down where the posted values from product_info.php get put into the array.

 

product_info.php posts to it's self, then application_top.php redirects based on the "action" value. You land on shopping_cart.php, yet I can not find where the Attributes are added to the $cart array. The catalog/includes/classes/shopping_cart.php looks like it should be in there, but I can't find it.

 

Eg. print_r($cart)

shoppingCart Object
(
   [contents] => Array
    (
	    [102{6}13{3}37{4}26{5}38] => Array
		    (
			    [qty] => 1
			    [attributes] => Array
				    (
					    [6] => 13
					    [3] => 37
					    [4] => 26
					    [5] => 38
				    )
		    )
	    [116{7}41{8}47{4}26{3}37{5}38{6}36] => Array
		    (
			    [qty] => 1
			    [attributes] => Array
				    (
					    [7] => 41
					    [8] => 47
					    [4] => 26
					    [3] => 37
					    [5] => 38
					    [6] => 36
				    )
		    )
    )
   [total] => 129.9
   [weight] => 0
   [cartID] => 58104
   [content_type] => physical
)

 

So lets say that all these attributes, except the first and third on each product came back with a value of 'Please select' when checked against the product_options_values.product_options_values_name table

 

I want them to be skipped over and not instead into the array, and thus not being part of the order either.

Link to comment
Share on other sites

The closest I came was this function in catalog/includes/classes/shopping_cart.php

   function get_products() {
  global $languages_id;
  if (!is_array($this->contents)) return false;
  $products_array = array();
  reset($this->contents);
  while (list($products_id, ) = each($this->contents)) {
    $products_query = tep_db_query("select p.products_id, pd.products_name, p.products_model, p.products_image, p.products_price, p.products_weight, p.products_tax_class_id from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd where p.products_id = '" . (int)$products_id . "' and pd.products_id = p.products_id and pd.language_id = '" . (int)$languages_id . "'");
    if ($products = tep_db_fetch_array($products_query)) {
	  $prid = $products['products_id'];
	  $products_price = $products['products_price'];
	  $specials_query = tep_db_query("select specials_new_products_price from " . TABLE_SPECIALS . " where products_id = '" . (int)$prid . "' and status = '1'");
	  if (tep_db_num_rows($specials_query)) {
	    $specials = tep_db_fetch_array($specials_query);
	    $products_price = $specials['specials_new_products_price'];
	  }
	  $products_array[] = array('id' => $products_id,
							    'name' => $products['products_name'],
							    'model' => $products['products_model'],
							    'image' => $products['products_image'],
							    'price' => $products_price,
							    'quantity' => $this->contents[$products_id]['qty'],
							    'weight' => $products['products_weight'],
							    'final_price' => ($products_price + $this->attributes_price($products_id)),
							    'tax_class_id' => $products['products_tax_class_id'],
							    'attributes' => (isset($this->contents[$products_id]['attributes']) ? $this->contents[$products_id]['attributes'] : ''));
    }
  }
  return $products_array;
   }

 

The end of that $products_array[] =

 

How does that 'attributes' logic work? I feel that is where I should write a loop to check each option, value, and if it is not equal to 'Please select' then added it, otherwise discard it.

 

Thanks for any help.

Link to comment
Share on other sites

I`m not clear what exactly your doing, but I suspect your not clear how the drop down works, read this http://www.oscommerce.com/forums/topic/342527-how-to-create-a-drop-down-selection-menu/

 

You should see that the the array has 'id' and 'text' the text element is what is displayed but its the id element that is passed.

Your 'Please select' will not be passed unless you've set that as the id too, which would be wrong, the id for your 'Please select' should be 0

 

when osC displays a drop down it will show the default value as the 'id' matching the default set (i.e. both will be numbers) if no 'id' values match the 'default' value then the first value in the array is set as the default, which is normally the 0 'id' matching the 'text' 'Please select'

 

I hope that's clear but suspect the explanation is'nt 100% so

Sam

 

Remember, What you think I ment may not be what I thought I ment when I said it.

 

Contributions:

 

Auto Backup your Database, Easy way

 

Multi Images with Fancy Pop-ups, Easy way

 

Products in columns with multi buy etc etc

 

Disable any Category or Product, Easy way

 

Secure & Improve your account pages et al.

Link to comment
Share on other sites

maybe I was not clear, these drop downs are being generated via "product attributes"

 

This shop, a flower shop, has many options to select from see these ones here (almost live shop, don't place orders)

 

You could truly leave every option unselected (Please select) and order the product. But then you end up with 5 rows of options as 'Please select' (the default option could also be 'None') We want to simply remove these options from ever getting entered into to the $cart array, this should also prevent them from getting into the 'orders_products_attributes table

 

If I simply edit this in shopping_cart.php

    while (list($option, $value) = each($products[$i]['attributes'])) {
	  $products_name .= '<br /><small><i> - ' . $products[$i][$option]['products_options_name'] . ' ' . $products[$i][$option]['products_options_values_name'] . '</i></small>';
    }

 

to look like this

 

    while (list($option, $value) = each($products[$i]['attributes'])) {
 if (strtolower($products[$i][$option]['products_options_values_name']) != 'please select') {
  $products_name .= '<br /><small><i> - ' . $products[$i][$option]['products_options_name'] . ' ' . $products[$i][$option]['products_options_values_name'] . '</i></small>';
 }
    }

 

it works to remove to options in the shopping cart, but I would need to repeat this for about 6 other places. It SHOULD be easier to keep them out of the order from the beginning (upon 'add to cart')

Link to comment
Share on other sites

Its a while since I dealt with this part of osC, but I think your looking at it wrong.

 

osC passes the add to cart array applying any attributes selected

 

within the cart it looks at 'has product attributes? if yes display those options with any attributes already selected as defaults

so even if you remove all mention of the attributes within the cart, as .has product attributes' is true, it will still display them.

 

It would probably be easiest to change the Please select' text in the cart to 'not required' or similar

Sam

 

Remember, What you think I ment may not be what I thought I ment when I said it.

 

Contributions:

 

Auto Backup your Database, Easy way

 

Multi Images with Fancy Pop-ups, Easy way

 

Products in columns with multi buy etc etc

 

Disable any Category or Product, Easy way

 

Secure & Improve your account pages et al.

Link to comment
Share on other sites

no, I am looking at it right. When I click 'Add to Cart' from product_info.php each option is posted, those options are then put into the cart array

 

eg. here is a cart with 2 products, the first has 6 options, the second has 4. these are the pairs of numbers in the $cart array

shoppingCart Object
(
   [contents] => Array
    (
	    [98{1}1{2}35{3}37{5}38{4}39{6}36] => Array
		    (
			    [qty] => 1
			    [attributes] => Array
				    (
					    [1] => 1
					    [2] => 35
					    [3] => 37
					    [5] => 38
					    [4] => 39
					    [6] => 36
				    )
		    )
	    [102{6}36{3}37{4}39{5}38] => Array
		    (
			    [qty] => 1
			    [attributes] => Array
				    (
					    [6] => 36
					    [3] => 37
					    [4] => 39
					    [5] => 38
				    )
		    )
    )
   [total] => 49.95
   [weight] => 0
   [cartID] => 56994
   [content_type] =>
)

 

How did they get there? When they where POSTed they where got and put into an array. I need to find when they are got (think $_POST['form_element_name']) and filter/ignore ones with values that relate back to 'Please Select'

 

P.S.

please don't take this as me arguing with you. Just looking for a very specific point in the code. Transition from $_POST variables.

Link to comment
Share on other sites

Yes they are posted, but even if you removed those elements from product_info.php so none are posted you would still see the options in the cart as product 'has product attributes'

Sam

 

Remember, What you think I ment may not be what I thought I ment when I said it.

 

Contributions:

 

Auto Backup your Database, Easy way

 

Multi Images with Fancy Pop-ups, Easy way

 

Products in columns with multi buy etc etc

 

Disable any Category or Product, Easy way

 

Secure & Improve your account pages et al.

Link to comment
Share on other sites

I don't think you follow what it is I want to do.

 

while viewing the product, ALL options (attributes) will be visible, if you choose to not select one (by selecting, please select) when you add it to the cart, the posted values will be checked, if they DO NOT equal 'Please select' add them to the array, if the do equal 'Please select' they will be left out.

 

I can write my own code to do this, I just need to find out where the values go from CLIENT SIDE data to SERVER SIDE data and filter them.

Link to comment
Share on other sites

I look at product_info.php, the forum tag looks like this (on my local host network)

<form name="cart_quantity" action="http://sdc.dyndns-home.com:8888/sites/silverHorseFlorist/www/catalog/product_info.php?cPath=28&products_id=102&action=add_product" method="post">

 

So I check back through product_info.php and look for the "action=add_product" part, it's not there, but rather in the included application_top.php

 

application_top.php around line 303

// Shopping cart actions
 if (isset($HTTP_GET_VARS['action'])) {

Yup, there is action, so we look through this if statement. . .

   switch ($HTTP_GET_VARS['action']) {
. . . . .
  // 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'])) {
						    $attributes = isset($HTTP_POST_VARS['id']) ? $HTTP_POST_VARS['id'] : '';
						    $cart->add_cart($HTTP_POST_VARS['products_id'], $cart->get_quantity(tep_get_uprid($HTTP_POST_VARS['products_id'], $attributes))+1, $attributes);
						  }
						  tep_redirect(tep_href_link($goto, tep_get_all_get_params($parameters)));
						  break;

So what did that do, I am a little fuzzy on it.

 

I know it is these 2 lines here, but whenever I see the ? I go ???

						    $attributes = isset($HTTP_POST_VARS['id']) ? $HTTP_POST_VARS['id'] : '';
						    $cart->add_cart($HTTP_POST_VARS['products_id'], $cart->get_quantity(tep_get_uprid($HTTP_POST_VARS['products_id'], $attributes))+1, $attributes);

I can't figure out what is going on here, but if I did. . . I could change the $attributes to NOT include what I don't want it to.

 

Maybe simply help me to understand what

$attributes = isset($HTTP_POST_VARS['id']) ? $HTTP_POST_VARS['id'] : '';

means.

 

I get this $attributes =

and I understand that 'isset($HTTP_POST_VARS['id'])' will return true or false

but then the ? and the : what are those for?

Link to comment
Share on other sites

The attributes from product_info are passed in an array 'id' which is an array of array's. Each array being a option/value pair, only the option id's are passed, as mentioned before the text is not.

 

The 'id' array is passed to $attributes ( see http://us.php.net/tut.php if you need to learn about php expressions) such that $attributes will be an array of the form array(4 => 2, 3 => 5) the first being the option the 2nd value repeated for every option (ie my example is for 2 options)

 

A unique product id is created based on the product_id and the specific option/value pairs in the $attributes array, which is then used to store the choice in the cart, so be aware if options are changed the unique id changes.

 

If the $attributes array is empty and the product has attributes the cart addition will be rejected

 

With 2.3.x you can delete options from the $attributes array but you must not delete all (see above)

 

You will need to find the 'id' for your 'Please select' text if you've added that through an option (look under 'id' in values in admin->attributes)

 

So just parse through the $attributes array and where an option has the value that matches the 'Please select' id, unset it, ensuring you leave at least one.

 

I hope that makes it a bit clearer :)

Sam

 

Remember, What you think I ment may not be what I thought I ment when I said it.

 

Contributions:

 

Auto Backup your Database, Easy way

 

Multi Images with Fancy Pop-ups, Easy way

 

Products in columns with multi buy etc etc

 

Disable any Category or Product, Easy way

 

Secure & Improve your account pages et al.

Link to comment
Share on other sites

ok, got it.

 

here is the code I added

		    if (isset($HTTP_POST_VARS['id'])) {
			 while (list($option, $value) = each($HTTP_POST_VARS['id'])) {
			  $quary = tep_db_query("SELECT products_options_values_name FROM products_options_values WHERE products_options_values.products_options_values_id=$value");
			  $name = tep_db_fetch_array($quary);
			  if (strtolower($name['products_options_values_name']) == 'please select') {
			   unset($HTTP_POST_VARS['id'][$option]);
			  }
			 }
		    }

 

This makes the "case" look like this (about line 334 in applications_top.php)

  case 'add_product' :    if (isset($HTTP_POST_VARS['products_id']) && is_numeric($HTTP_POST_VARS['products_id'])) {
		    if (isset($HTTP_POST_VARS['id'])) {
			 while (list($option, $value) = each($HTTP_POST_VARS['id'])) {
			  $quary = tep_db_query("SELECT products_options_values_name FROM products_options_values WHERE products_options_values.products_options_values_id=$value");
			  $name = tep_db_fetch_array($quary);
			  if (strtolower($name['products_options_values_name']) == 'please select') {
			   unset($HTTP_POST_VARS['id'][$option]);
			  }
			 }
		    }
		    $attributes = isset($HTTP_POST_VARS['id']) ? $HTTP_POST_VARS['id'] : '';
						    $cart->add_cart($HTTP_POST_VARS['products_id'], $cart->get_quantity(tep_get_uprid($HTTP_POST_VARS['products_id'], $attributes))+1, $attributes);
						  }
						  tep_redirect(tep_href_link($goto, tep_get_all_get_params($parameters)));
						  break;

Link to comment
Share on other sites

@@nobodyfamous Well done.

 

$HTTP_POST_VARS is depreciated, you should always use $_POST etc unless you want to re-write again later

You haven't allowed for the non-empty array issue.

Sam

 

Remember, What you think I ment may not be what I thought I ment when I said it.

 

Contributions:

 

Auto Backup your Database, Easy way

 

Multi Images with Fancy Pop-ups, Easy way

 

Products in columns with multi buy etc etc

 

Disable any Category or Product, Easy way

 

Secure & Improve your account pages et al.

Link to comment
Share on other sites

I just copied the code that was there. Didn't know if $HTTP_POST_VARS was a special thing set up by osC or not. As for the empty array, that will be handled by the Admin, just make sure at least one option can't be Please select. If that won't be possible, I will add some code to check if the array is empty, and insert a predefined option value set (the numbers, maybe (1) => 1) and it will be something like No Options Selected

Link to comment
Share on other sites

$HTTP_xxx_VARS

 

http://www.php.net/manual/en/reserved.variables.post.php

 

removed from php5.4 on

Sam

 

Remember, What you think I ment may not be what I thought I ment when I said it.

 

Contributions:

 

Auto Backup your Database, Easy way

 

Multi Images with Fancy Pop-ups, Easy way

 

Products in columns with multi buy etc etc

 

Disable any Category or Product, Easy way

 

Secure & Improve your account pages et al.

Link to comment
Share on other sites

It's not overly important that you use $_POST instead of $HTTP_POST_VARS

 

The compatibility layer solves that. For now it's fine, especially if the rest of the page still uses $HTTP_POST_VARS

Link to comment
Share on other sites

yes the compatibility layer references $_POST to $HTTP_POST_VARS etc

 

But as of php 5.4 use of $HTTP_POST_VARS etc will trigger a fatal error, so including them in new code is not very clever!

Sam

 

Remember, What you think I ment may not be what I thought I ment when I said it.

 

Contributions:

 

Auto Backup your Database, Easy way

 

Multi Images with Fancy Pop-ups, Easy way

 

Products in columns with multi buy etc etc

 

Disable any Category or Product, Easy way

 

Secure & Improve your account pages et al.

Link to comment
Share on other sites

Hmmm. It doesn't really make a difference for now if the rest of the page is covered with $HTTP_POST_VARS or $HTTP_GET_VARS and such.

 

At some point, even if 5.4 breaks it all, a search and replace will have to be done (and 1 or 2 extra to S & R does not make a scrap of difference).

 

People are getting too tied up in semantics. If it works now, fine. If 5.4 breaks it, fix it. If you want to code for 5.4 now, also fine. 5.5 will break it. /endless_loop

Link to comment
Share on other sites

Well I have always recommended that all depreciated vars be replaced as a matter of course when editing any page, I`m surprised that osC still includes them when they've been so long depreciated.

 

Why wait till you have to fix when you can prevent that now.

 

How many add-ons are still using depreciated because of this attitude? Its just creating un-neccessary issues?

Sam

 

Remember, What you think I ment may not be what I thought I ment when I said it.

 

Contributions:

 

Auto Backup your Database, Easy way

 

Multi Images with Fancy Pop-ups, Easy way

 

Products in columns with multi buy etc etc

 

Disable any Category or Product, Easy way

 

Secure & Improve your account pages et al.

Link to comment
Share on other sites

While I do agree with coding for the latest stable release of any code, I am no PHP wizard and when modifying an existing program, like osC, I code to match what is already there.

 

If I am modifying $bananas I use $bananas, not $apples.

 

Thanks for the heads up on the depreciated code, I just got an email from my host stating

we will be removing PHP 4 and older versions of PHP 5, replacing them with the newer, more stable, and more secure PHP 5.3.10.

 

I may do a simple S&R, though this cart is not on my servers.

Link to comment
Share on other sites

Archived

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

×
×
  • Create New...