When does the problem occur?
The problem occurs when the Virtuemart Admin creates a new user field or when he removes a standard user field.
Locating the bug in the source code
The bug can be traced back to the following lines in the file administrator/components/com_virtuemart/classes/ps_order_change.php:
line 227: $q = "INSERT INTO `#__{vm}_order_user_info` " ; line :228: $q .= "SELECT '', '$this->order_id', '" . $db->f( 'user_id' ) . "', address_type, address_type_name, company, title, last_name, first_name, middle_name, phone_1, phone_2, fax, address_1, address_2, city, state, country, zip, user_email, extra_field_1, extra_field_2, extra_field_3, extra_field_4, extra_field_5,bank_account_nr,bank_name,bank_sort_code,bank_iban, bank_account_holder,bank_account_type FROM #__{vm}_user_info WHERE user_id='" . $db->f( 'user_id' ) . "' AND user_info_id='" . $ship_to . "' AND address_type='ST'" ; When Virtuemart executes the sql above, the database will raise the following error:
Column count doesn't match value count at row 1
The SQL query fails to take into account the fact that the Virtuemart Admin can create and remove fields. Therefore, some of the fields mentioned in the SQL query may not even exist. At the same time, fields that were added by the Virtuemart Admin, and are mandatory, will not be mentioned in this SQL query.
Solving the problem
Replace lines 227 and 228 in the file administrator/components/com_virtuemart/classes/ps_order_change.php by the following lines:
$fields = array(); require_once( CLASSPATH . 'ps_userfield.php' ); $userfields = ps_userfield::getUserFields('', false, '', true, true ); foreach ( $userfields as $field ) { if ($field->name=='email') $fields[] = 'user_email'; else $fields[] = $field->name; } $fieldstr = implode( ',', $fields ); $q = "INSERT INTO `#__{vm}_order_user_info` (`order_info_id`,`order_id`,`user_id`, address_type, ".$fieldstr.") "; $q .= "SELECT NULL, '$this->order_id', '".$db->f( 'user_id' )."', address_type, ".$fieldstr." FROM #__{vm}_user_info WHERE user_id='" . $db->f( 'user_id' ) . "' AND user_info_id='" . $ship_to . "' AND address_type='ST'" ;
By constructing the SQL in this way, it takes into account all changes made by the Virtuemart Admin in the user fields. It will take into account that particular fields were removed and that particular fields were added.
|