Jump to content



Photo
- - - - -

how to edit $cart array (remove unused attributes)


This topic has been archived. This means that you cannot reply to this topic.
21 replies to this topic

#1   nobodyfamous

nobodyfamous
  • Members
  • 103 posts

Posted 13 April 2012 - 18:15

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.

#2   nobodyfamous

nobodyfamous
  • Members
  • 103 posts

Posted 13 April 2012 - 18:23

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.

#3   spooks

spooks
  • Members
  • 7,017 posts

Posted 13 April 2012 - 18:57

I`m not clear what exactly your doing, but I suspect your not clear how the drop down works, read this http://forums.oscomm...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.

#4   nobodyfamous

nobodyfamous
  • Members
  • 103 posts

Posted 13 April 2012 - 19:38

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')

#5   spooks

spooks
  • Members
  • 7,017 posts

Posted 13 April 2012 - 19:52

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.

#6   nobodyfamous

nobodyfamous
  • Members
  • 103 posts

Posted 13 April 2012 - 20:06

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.

#7   spooks

spooks
  • Members
  • 7,017 posts

Posted 13 April 2012 - 22:38

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.

#8   nobodyfamous

nobodyfamous
  • Members
  • 103 posts

Posted 13 April 2012 - 22:56

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.

#9   nobodyfamous

nobodyfamous
  • Members
  • 103 posts

Posted 13 April 2012 - 23:30

Just re-reading this again, you said

osC passes the add to cart array applying any attributes selected


This is exactly the code I am looking for, where does this take place? file? line(s)?

#10   nobodyfamous

nobodyfamous
  • Members
  • 103 posts

Posted 13 April 2012 - 23:43

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&amp;products_id=102&amp;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?

#11   spooks

spooks
  • Members
  • 7,017 posts

Posted 14 April 2012 - 00:38

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 /smile.png' class='bbc_emoticon' alt=':)' />
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.

#12   nobodyfamous

nobodyfamous
  • Members
  • 103 posts

Posted 16 April 2012 - 15:55

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;


#13   nobodyfamous

nobodyfamous
  • Members
  • 103 posts

Posted 16 April 2012 - 15:56

I still don't know what; $variable = bool ? value : ''; does.

What are the operators ? and : doing?

#14   burt

burt

    Vanquisher of Demons

  • Community Team
  • 9,540 posts

Posted 16 April 2012 - 16:06

Comparison operator;

if ($a == $<img src='http://forums.oscommerce.com/public/style_emoticons/<#EMO_DIR#>/cool.png' class='bbc_emoticon' alt='B)' /> {
echo $c;
}
else {
echo $d;
}

is the same as

echo ($a == $<img src='http://forums.oscommerce.com/public/style_emoticons/<#EMO_DIR#>/cool.png' class='bbc_emoticon' alt='B)' /> ? $c : $d;

Edited by burt, 16 April 2012 - 16:07.

Responsive osCommerce, join in the fun:
http://forums.oscomm...rom-the-get-go/

--
Making your shop better, one osCommerce module at a time - get in touch, or get my newsletter every 1st of the month.

 

Big Bang Templates for 2.3.4


#15   spooks

spooks
  • Members
  • 7,017 posts

Posted 17 April 2012 - 08:32

@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.

#16   nobodyfamous

nobodyfamous
  • Members
  • 103 posts

Posted 17 April 2012 - 11:09

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

#17   spooks

spooks
  • Members
  • 7,017 posts

Posted 17 April 2012 - 13:30

$HTTP_xxx_VARS

http://www.php.net/m...iables.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.

#18   burt

burt

    Vanquisher of Demons

  • Community Team
  • 9,540 posts

Posted 18 April 2012 - 08:20

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

Responsive osCommerce, join in the fun:
http://forums.oscomm...rom-the-get-go/

--
Making your shop better, one osCommerce module at a time - get in touch, or get my newsletter every 1st of the month.

 

Big Bang Templates for 2.3.4


#19   spooks

spooks
  • Members
  • 7,017 posts

Posted 18 April 2012 - 09:19

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.

#20   burt

burt

    Vanquisher of Demons

  • Community Team
  • 9,540 posts

Posted 18 April 2012 - 09:35

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

Responsive osCommerce, join in the fun:
http://forums.oscomm...rom-the-get-go/

--
Making your shop better, one osCommerce module at a time - get in touch, or get my newsletter every 1st of the month.

 

Big Bang Templates for 2.3.4