$table_products_attributes_update = 0;
         } else {
             // UPDATE
             $sql7 = "UPDATE " . TABLE_PRODUCTS_ATTRIBUTES . " SET\n\t\t\t\t\t\t\tproducts_options_sort_order ='" . $values_names_index . "'\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\tproducts_id = '" . $v_products_id . "' AND\n\t\t\t\t\t\t\toptions_id = '" . $v_products_options_id . "' AND\n\t\t\t\t\t\t\toptions_values_id = '" . $a_products_options_values_id . "'";
             $errorcheck = ep_4_query($sql7);
             $table_products_attributes_update = 1;
         }
     }
     // Get max index id for TABLE_PRODUCTS_OPTIONS_VALUES
     $sql_max3 = "SELECT MAX(products_options_values_id) max FROM " . TABLE_PRODUCTS_OPTIONS_VALUES;
     $result3 = ep_4_query($sql_max3);
     $row3 = $ep_uses_mysqli ? mysqli_fetch_array($result3) : mysql_fetch_array($result3);
     $products_options_values_id = $row3['max'] + 1;
     // Get max index id for TABLE_PRODUCTS_OPTIONS_VALUES_TO_PRODUCTS_OPTIONS
     $sql_max2 = "SELECT MAX(products_options_values_to_products_options_id) max FROM " . TABLE_PRODUCTS_OPTIONS_VALUES_TO_PRODUCTS_OPTIONS;
     $result2 = ep_4_query($sql_max2);
     $row2 = $ep_uses_mysqli ? mysqli_fetch_array($result2) : mysql_fetch_array($result2);
     $products_options_values_to_products_options_id = $row2['max'] + 1;
     $values_names_index++;
     // mc12345678: allows for more room in sort order of options names: New = round(old/10)*10 + increment
     // $products_options_values_sort_order = $products_options_values_sort_order + $products_sort_order_increment;
     $products_options_values_sort_order = round($products_options_values_sort_order / 10) * 10 + $products_sort_order_increment;
 }
 // END: while #3
 if (!$table_products_attributes_update) {
     // FEEDBACK ========> implode(",", $values_names_array[1])
     $display_output .= sprintf('<br /><font color="green"><b>NEW ATTRIBUTE! - Model:</b> %s, <b>Option:</b> %s, <b>Values:</b> %s</font>', $v_products_model, $v_products_options_name[1], implode(",", $values_names_array[1]));
     $ep_import_count++;
     // record inserted
 } else {
     // FEEDBACK =======>
    $products_url_max_len = $products_url_max_len / 3;
    $artists_name_max_len = $artists_name_max_len / 3;
    $record_company_name_max_len = $record_company_name_max_len / 3;
    $music_genre_name_max_len = $music_genre_name_max_len / 3;
}
// test for Ajeh
//$ajeh_sql = 'SELECT * FROM '. TABLE_PRODUCTS .' WHERE '.TABLE_PRODUCTS.'.products_id NOT IN (SELECT '. TABLE_PRODUCTS_TO_CATEGORIES.'.products_id FROM '. TABLE_PRODUCTS_TO_CATEGORIES.')';
//$ajeh_result = ep_4_query($ajeh_sql);
// Pre-flight checks finish here
// check default language_id from configuration table DEFAULT_LANGUAGE
// chadd - really shouldn't do this! $epdlanguage_id is better replaced with $langcode[]
// $epdlanguage_id is the only value used here ( I assume for default language)
// default langauage should not be important since all installed languages are used $langcode[]
// and we should iterate through that array (even if only 1 stored value)
// $epdlanguage_id is used only in categories generation code since the products import code doesn't support multi-language categories
$epdlanguage_query = ep_4_query("SELECT languages_id, name FROM " . TABLE_LANGUAGES . " WHERE code = '" . DEFAULT_LANGUAGE . "'");
if ($ep_uses_mysqli ? mysqli_num_rows($epdlanguage_query) : mysql_num_rows($epdlanguage_query)) {
    $epdlanguage = $ep_uses_mysqli ? mysqli_fetch_array($epdlanguage_query) : mysql_fetch_array($epdlanguage_query);
    $epdlanguage_id = $epdlanguage['languages_id'];
    $epdlanguage_name = $epdlanguage['name'];
} else {
    exit("EP4 FATAL ERROR: No default language set.");
    // this should never happen
}
$langcode = ep_4_get_languages();
// array of currently used language codes ( 1, 2, 3, ...)
/*
if ( isset($_GET['export2']) ) { // working on attributes export 
	include_once('easypopulate_4_export2.php'); // this file contains all data import code
} */
if (isset($_POST['export']) or isset($_GET['export'])) {
         $row2 = $ep_uses_mysqli ? mysqli_fetch_array($result2) : mysql_fetch_array($result2);
         $row['v_manufacturers_name'] = $row2['manufacturers_name'];
     } else {
         // this is to fix the error on manufacturers name
         // $row['v_manufacturers_id'] = '0';  blank name mean 0 id - right? chadd 4-7-09
         $row['v_manufacturers_name'] = '';
         // no manufacturer name
     }
 }
 // Price/Qty/Discounts
 $discount_index = 1;
 while (isset($filelayout['v_discount_qty_' . $discount_index])) {
     if ($row['v_products_discount_type'] != '0') {
         // if v_products_discount_type == 0 then there are no quantity breaks
         $sql2 = 'SELECT discount_id, discount_qty, discount_price FROM ' . TABLE_PRODUCTS_DISCOUNT_QUANTITY . ' WHERE products_id = ' . $row['v_products_id'] . ' AND discount_id=' . $discount_index;
         $result2 = ep_4_query($sql2);
         $row2 = $ep_uses_mysqli ? mysqli_fetch_array($result2) : mysql_fetch_array($result2);
         $row['v_discount_price_' . $discount_index] = $row2['discount_price'];
         $row['v_discount_qty_' . $discount_index] = $row2['discount_qty'];
     }
     $discount_index++;
 }
 // We check the value of tax class and title instead of the id
 // Then we add the tax to price if $price_with_tax is set to 1
 $row_tax_multiplier = ep_4_get_tax_class_rate($row['v_tax_class_id']);
 $row['v_tax_class_title'] = zen_get_tax_class_title($row['v_tax_class_id']);
 $row['v_products_price'] = round($row['v_products_price'] + $price_with_tax * $row['v_products_price'] * $row_tax_multiplier / 100, 2);
 // Clean the texts that could break CSV file formatting
 $dataRow = '';
 $problem_chars = array("\r", "\n", "\t");
 // carriage return, newline, tab
function remove_easypopulate_4()
{
    global $db;
    $project = PROJECT_VERSION_MAJOR . '.' . PROJECT_VERSION_MINOR;
    $ep_uses_mysqli = PROJECT_VERSION_MAJOR > '1' || PROJECT_VERSION_MINOR >= '5.3' ? true : false;
    if (substr($project, 0, 5) == "1.3.8" || substr($project, 0, 5) == "1.3.9") {
        $sql = "SELECT configuration_group_id FROM " . TABLE_CONFIGURATION_GROUP . " WHERE configuration_group_title = 'Easy Populate 4' LIMIT 1";
        $result = ep_4_query($sql);
        if (mysql_num_rows($result)) {
            $ep_group_id = mysql_fetch_array($result);
            $db->Execute("DELETE FROM " . TABLE_CONFIGURATION . " WHERE configuration_group_id = " . $ep_group_id[0]);
            $db->Execute("DELETE FROM " . TABLE_CONFIGURATION_GROUP . " WHERE configuration_group_id = " . $ep_group_id[0]);
        }
    } elseif (substr($project, 0, 3) == "1.5") {
        $sql = "SELECT configuration_group_id FROM " . TABLE_CONFIGURATION_GROUP . " WHERE configuration_group_title = 'Easy Populate 4' LIMIT 1";
        $result = ep_4_query($sql);
        if ($ep_uses_mysqli ? mysqli_num_rows($result) : mysql_num_rows($result)) {
            $ep_group_id = $ep_uses_mysqli ? mysqli_fetch_array($result) : mysql_fetch_array($result);
            $db->Execute("DELETE FROM " . TABLE_CONFIGURATION . " WHERE configuration_group_id = " . $ep_group_id[0]);
            $db->Execute("DELETE FROM " . TABLE_CONFIGURATION_GROUP . " WHERE configuration_group_id = " . $ep_group_id[0]);
            $db->Execute("DELETE FROM " . TABLE_ADMIN_PAGES . " WHERE page_key = 'easypopulate_4'");
            $db->Execute("DELETE FROM " . TABLE_ADMIN_PAGES . " WHERE page_key = 'easypopulate_4_config'");
        }
    } else {
        // unsupported version
    }
}
             $result = ep_4_query($sql);
             if ($result) {
                 zen_record_admin_activity('Inserted special ' . (int) $v_products_id . ' via EP4.', 'info');
             }
             $specials_print .= sprintf(EASYPOPULATE_4_SPECIALS_NEW, $v_products_model, substr(strip_tags($v_products_name[$epdlanguage_id]), 0, 10), $v_products_price, $v_specials_price);
         } else {
             // existing product
             if ($v_specials_price == '0') {
                 // delete of existing requested
                 $db->Execute("DELETE FROM " . TABLE_SPECIALS . " WHERE products_id = '" . (int) $v_products_id . "'");
                 $specials_print .= sprintf(EASYPOPULATE_4_SPECIALS_DELETE, $v_products_model);
                 continue;
             }
             // just make an update
             $sql = "UPDATE " . TABLE_SPECIALS . " SET\n\t\t\t\t\t\tspecials_new_products_price\t= '" . $v_specials_price . "',\n\t\t\t\t\t\tspecials_last_modified\t\t= now(),\n\t\t\t\t\t\tspecials_date_available\t\t= '" . $v_specials_date_avail . "',\n\t\t\t\t\t\texpires_date\t\t\t\t= '" . $v_specials_expires_date . "',\n\t\t\t\t\t\tstatus\t\t\t\t\t\t= '1'\n\t\t\t\t\t\tWHERE products_id\t\t\t= '" . (int) $v_products_id . "'";
             $result = ep_4_query($sql);
             if ($result) {
                 zen_record_admin_activity('Updated special ' . (int) $v_products_id . ' via EP4.', 'info');
             }
             $specials_print .= sprintf(EASYPOPULATE_4_SPECIALS_UPDATE, $v_products_model, substr(strip_tags($v_products_name[$epdlanguage_id]), 0, 10), $v_products_price, $v_specials_price);
         }
         // we still have our special here
     }
     // end specials for this product
     // this is a test chadd - 12-08-2011
     // why not just update price_sorter after each product?
     // better yet, why not ONLY call if pricing was updated
     // ALL these affect pricing: products_tax_class_id, products_price, products_priced_by_attribute, product_is_free, product_is_call
     zen_update_products_price_sorter($v_products_id);
 } else {
     // this record is missing the product_model
             }
             // insert new into specials
             $sql = "INSERT INTO " . TABLE_SPECIALS . "\n\t\t\t\t\t\t(products_id,\n\t\t\t\t\t\tspecials_new_products_price,\n\t\t\t\t\t\tspecials_date_added,\n\t\t\t\t\t\tspecials_date_available,\n\t\t\t\t\t\texpires_date,\n\t\t\t\t\t\tstatus)\n\t\t\t\t\t\tVALUES (\n\t\t\t\t\t\t'" . (int) $v_products_id . "',\n\t\t\t\t\t\t'" . $v_specials_price . "',\n\t\t\t\t\t\tnow(),\n\t\t\t\t\t\t'" . $v_specials_date_avail . "',\n\t\t\t\t\t\t'" . $v_specials_expires_date . "',\n\t\t\t\t\t\t'1')";
             $result = ep_4_query($sql);
             $specials_print .= sprintf(EASYPOPULATE_4_SPECIALS_NEW, $v_products_model, substr(strip_tags($v_products_name[$epdlanguage_id]), 0, 10), $v_products_price, $v_specials_price);
         } else {
             // existing product
             if ($v_specials_price == '0') {
                 // delete of existing requested
                 $db->Execute("DELETE FROM " . TABLE_SPECIALS . " WHERE products_id = '" . (int) $v_products_id . "'");
                 $specials_print .= sprintf(EASYPOPULATE_4_SPECIALS_DELETE, $v_products_model);
                 continue;
             }
             // just make an update
             $sql = "UPDATE " . TABLE_SPECIALS . " SET\n\t\t\t\t\t\tspecials_new_products_price\t= '" . $v_specials_price . "',\n\t\t\t\t\t\tspecials_last_modified\t\t= now(),\n\t\t\t\t\t\tspecials_date_available\t\t= '" . $v_specials_date_avail . "',\n\t\t\t\t\t\texpires_date\t\t\t\t= '" . $v_specials_expires_date . "',\n\t\t\t\t\t\tstatus\t\t\t\t\t\t= '1'\n\t\t\t\t\t\tWHERE products_id\t\t\t= '" . (int) $v_products_id . "'";
             ep_4_query($sql);
             $specials_print .= sprintf(EASYPOPULATE_4_SPECIALS_UPDATE, $v_products_model, substr(strip_tags($v_products_name[$epdlanguage_id]), 0, 10), $v_products_price, $v_specials_price);
         }
         // we still have our special here
     }
     // end specials for this product
     // this is a test chadd - 12-08-2011
     // why not just update price_sorter after each product?
     // better yet, why not ONLY call if pricing was updated
     // ALL these affect pricing: products_tax_class_id, products_price, products_priced_by_attribute, product_is_free, product_is_call
     zen_update_products_price_sorter($v_products_id);
 } else {
     // this record is missing the product_model
     $display_output .= EASYPOPULATE_4_DISPLAY_RESULT_NO_MODEL;
     foreach ($items as $col => $summary) {
         if ($col == $filelayout['v_products_model']) {