
Originally Posted by
DivaVocals
First I think your question/issue needs to be spun off into it's own thread, as it seems
wholly unrelated to support for this module.. Secondly (and I'm sure Ajeh will chime in as well) Your assumption about what happens if you add an additional attribute to your product is wrong... All of the products offered in my own store contain three attributes:
- Download (dropdown - priced by this attribute)
- Product option (dropdown - priced by this attribute)
- Text field
The download file only needs to be associated with the download dropdown, and during checkout the shipping page is indeed bypassed..
Believe *wholly* is a bit extreme when it was ajeh that was asking (albeit a year ago) of some other condition where a download existed and/or a product needed to be marked as virtual in order to be properly treated through the process... As for my "assumption" of what happens, follow the code... Discovered this condition a couple of weeks ago first in practice, then by code review and have been reviewing the instructions for assignment of downloadable products. The instructions well, aren't exactly wrong for the below condition, but do not recognize that it could occur or the need to mark the product as virtual in order to further bypass the shipping information request. It was only when reviewing this thread following a recent post that I found a related response/inquiry tieing this situation and may require modification of this plugin to support the condition.
Clean install of 1.5.3 downloaded from ZC, didn't even correct the reset of the shipping calculation for virtual products.
Follow the program code as below for a product-general setup like this:
Product setup to be Virtual: no, shipping address required; Always free Shipping: no, normal shipping rules.
Product not priced by attributes.
No model number is entered or model number entered does not contain GIFT.
An option name of downloads is added as a radiobutton, sort order 0.
An option name of assistance is added as a dropdown, sort order 20.
One option value for each download created off of the option name download populated with the name of the product to be tied, with sort order 10 for each of those option values.
Option values for the assistance option name are set with sort order 0, 10, 20 respectively for Please Select, Yes, and No values.
In attributes controller, Download Option Name/value pair selected, filename that exists (green dot) is entered for filename, # days and downloads is entered, save the attribute.
Option Name, with all 3 Option Values selected added to product.
'Please Select' is identified in attributes controller as display only, default. Therefore will not by a valid selection for adding to the cart.
Add item to cart, while logged in continue to checkout from the shopping cart.
includes/modules/pages/checkout_shipping/header_php.php line 76 pulls in the order class (require statement).
at line 77 $order = new order; which is a call to the order class without an order number to initiate/construct a new order variable.
The construct function of the order class, assigns internal variables to be blank/empty then calls the cart() function that is also in the order class.
The cart() function then sets the content_type = the active shopping cart's get_content_type() function.
line 1421 of the shopping_cart class begins the function get_content_type() which defaults to gv_only = false in this situation.
The code provided below is what identifies/returns the content_type (get_content_type function). A written interpretation is provided as the "summary". Follow either if you wish, but with a product setup as above in ZC 1.5.3 and the associated tables provided below, the resulting content_type is 'mixed' rather than 'virtual'. Is it the wrong condition to have? I might say that if there is nothing that actually is shipped or physically provided (ie. no weight to anything and perhaps some other factor(s) to consider) and there is a download associated, then perhaps it should remain virtual and not become mixed. I found a solution to my situation that didn't at first make sense from a store operation perspective but does from a coding perspective.
summary:
$this->content_type = false (initializes the content_type)
The cart has contents so enters the if statement.
One product (not zero or less) so enters while loop.
$free_ship_check->fields['products_virtual'] = 0; and $free_ship_check->fields['product_is_always_free_shipping'] = 0; based on the above assignments of virtual no and free shipping is no.
$virtual_check = false;
not a gift.
Product has attributes (Download and assistance) and free shipping is not equal to 2 (it equals zero).
while loop is entered and is expected to be visited no more than one more time.
virtual_check_query->fields['total'] is > 0 if the option_value for the product is included as a download, otherwise = 0.
in this case, the first attribute is the download option name, the query returns 1.
In the select case, the value is 'false' which results in a product type of 'virtual'.
back to the while loop.
The virtual_check_query->fields['total'] = 0 because the next attribute does not have a download associated with it.
This moves into the else area, the content_type currently is 'virtual'
the free_ship_check->fields['product_virtual'] = 0 so the content_type is set to 'mixed'.
back from the start, $gv_only = 'false' (because it was not provided when entering this function) therefore 'mixed' is returned ending further processing in this function. No further processing necessary as can no longer be identified as virtual only nor can it be identified as only physical. Same result occurs with Option Names in other sequence. In order for the above process to "naturally" indicate 'virtual' by itself, all attributes in the shopping_cart must contain a download (haven't yet considered the effect of all containing a download. If that means that the same download would be available multiple times in the order history, or if two different downloads might be possible if improperly assigned, etc..) or the product be specifically identified as virtual
Code:
/**
* Method to calculate the content type of a cart
*
* @param boolean whether to test for Gift Vouchers only
* @return string
*/
function get_content_type($gv_only = 'false') {
global $db;
$this->content_type = false;
$gift_voucher = 0;
// if ( (DOWNLOAD_ENABLED == 'true') && ($this->count_contents() > 0) ) {
if ( $this->count_contents() > 0 ) {
reset($this->contents);
while (list($products_id, ) = each($this->contents)) {
$free_ship_check = $db->Execute("select products_virtual, products_model, products_price, product_is_always_free_shipping from " . TABLE_PRODUCTS . " where products_id = '" . zen_get_prid($products_id) . "'");
$virtual_check = false;
if (preg_match('/^GIFT/', addslashes($free_ship_check->fields['products_model']))) {
// @TODO - fix GIFT price in cart special/attribute
$gift_special = zen_get_products_special_price(zen_get_prid($products_id), true);
$gift_pba = zen_get_products_price_is_priced_by_attributes(zen_get_prid($products_id));
//echo '$products_id: ' . zen_get_prid($products_id) . ' price: ' . ($free_ship_check->fields['products_price'] + $this->attributes_price($products_id)) . ' vs special price: ' . $gift_special . ' qty: ' . $this->contents[$products_id]['qty'] . ' PBA: ' . ($gift_pba ? 'YES' : 'NO') . '<br>';
if (!$gift_pba && $gift_special !=0 && $gift_special != $free_ship_check->fields['products_price']) {
$gift_voucher += ($gift_special * $this->contents[$products_id]['qty']);
} else {
$gift_voucher += ($free_ship_check->fields['products_price'] + $this->attributes_price($products_id)) * $this->contents[$products_id]['qty'];
}
}
// product_is_always_free_shipping = 2 is special requires shipping
// Example: Product with download
if (isset($this->contents[$products_id]['attributes']) and $free_ship_check->fields['product_is_always_free_shipping'] != 2) {
reset($this->contents[$products_id]['attributes']);
while (list(, $value) = each($this->contents[$products_id]['attributes'])) {
$virtual_check_query = "select count(*) as total
from " . TABLE_PRODUCTS_ATTRIBUTES . " pa, "
. TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad
where pa.products_id = '" . (int)$products_id . "'
and pa.options_values_id = '" . (int)$value . "'
and pa.products_attributes_id = pad.products_attributes_id";
$virtual_check = $db->Execute($virtual_check_query);
if ($virtual_check->fields['total'] > 0) {
switch ($this->content_type) {
case 'physical':
$this->content_type = 'mixed';
if ($gv_only == 'true') {
return $gift_voucher;
} else {
return $this->content_type;
}
break;
default:
$this->content_type = 'virtual';
break;
}
} else {
switch ($this->content_type) {
case 'virtual':
if ($free_ship_check->fields['products_virtual'] == '1') {
$this->content_type = 'virtual';
} else {
$this->content_type = 'mixed';
if ($gv_only == 'true') {
return $gift_voucher;
} else {
return $this->content_type;
}
}
break;
case 'physical':
if ($free_ship_check->fields['products_virtual'] == '1') {
$this->content_type = 'mixed';
if ($gv_only == 'true') {
return $gift_voucher;
} else {
return $this->content_type;
}
} else {
$this->content_type = 'physical';
}
break;
default:
if ($free_ship_check->fields['products_virtual'] == '1') {
$this->content_type = 'virtual';
} else {
$this->content_type = 'physical';
}
}
}
}
} else {
switch ($this->content_type) {
case 'virtual':
if ($free_ship_check->fields['products_virtual'] == '1') {
$this->content_type = 'virtual';
} else {
$this->content_type = 'mixed';
if ($gv_only == 'true') {
return $gift_voucher;
} else {
return $this->content_type;
}
}
break;
case 'physical':
if ($free_ship_check->fields['products_virtual'] == '1') {
$this->content_type = 'mixed';
if ($gv_only == 'true') {
return $gift_voucher;
} else {
return $this->content_type;
}
} else {
$this->content_type = 'physical';
}
break;
default:
if ($free_ship_check->fields['products_virtual'] == '1') {
$this->content_type = 'virtual';
} else {
$this->content_type = 'physical';
}
}
}
}
} else {
$this->content_type = 'physical';
}
if ($gv_only == 'true') {
return $gift_voucher;
} else {
return $this->content_type;
}
}
products_attributes table and products_attributes_download tables showing respective applicable columns:
applicable fields from products_attributes table for products_id = 8:
Code:
products_attributes_id |
products_id |
options_id |
options_values_id |
82 |
8 |
2 |
6 |
83 |
8 |
1 |
3 |
84 |
8 |
1 |
1 |
|
85 |
8 |
1 |
2 |
products_attributes_download table (the entire list within the table). Match only found in the last record:
Code:
products_attributes_id |
33 |
12 |
89 |
3 |
1 |
31 |
10 |
82 |
Bookmarks