osCommerce 2.2 Milestone 2 Update 051113OpenCommercio 2.2 Milestone 2
versione di Aggiornamento 051113
Pacchetto aggiornamento del 13 Novembre 2005
Prefazione: di Angelo Gagliani, staff di opencommercio.com .
La versione 051113 di aggiornamento di OpenCommercio 2.2 Milestone 2 è una
release di OsCommerce italianizzata che non apporta nuove funzionalità al
sistema, ma corregge alcuni errori della versione stabile precedente. Ma
principalmente aggiunge alcune modifiche riguardo la sicurezza del negozio,
prevenendo eventuali iniezioni di codice malizioso che potrebbe danneggiare il
sistema. Perciò si consiglia a tutti gli utenti di OpenCommercio di aggiornare
il proprio sistema. Insomma, si tratta di una versione completa, aggiornata e
corretta che sostituisce la versione precedente.
Attenzione:
- nuove installazioni: installare il negozio come da Guida di installazione
inclusa nel pacchetto (installa.txt), che potrete trovare anche in formato PDF
stampabile nella sezione Download >> Documentazione sul nostro sito di supporto
http://www.opencommercio.com,
- negozi produttivi: questa versione non prevede uno script di aggiornamento
automatico, ma le modifiche devono essere effettuate con un copia e incolla
delle parti modificate per ogni file da aggiornare: non sovrascrivere i files
esistenti del vostro negozio con quelli nuovi se avete installato contributions
o se avete personalizzato il negozio: le contributions potrebbe non funzionare
correttamente e le personalizzazioni sparire... Procedere con pazienza, file
dopo file, nelle modifche come descritte in dettaglio più avanti.
I files in cui sono state effettuate delle modifiche sono:
catalog/admin/includes/classes/email.php
catalog/admin/includes/classes/split_page_results.php
catalog/admin/includes/classes/upload.php
catalog/admin/includes/functions/database.php
catalog/admin/includes/functions/general.php
catalog/admin/includes/functions/html_output.php
catalog/admin/categories.php
catalog/admin/file_manager.php
catalog/admin/orders.php
catalog/includes/classes/email.php
catalog/includes/classes/shopping_cart.php
catalog/includes/classes/split_page_results.php
catalog/includes/functions/database.php
catalog/includes/functions/general.php
catalog/includes/functions/html_output.php
catalog/includes/functions/sessions.php
catalog/advanced_search_result.php
catalog/index.php
catalog/redirect.php
Inoltre bisogna eseguire le seguenti query SQL per la compatibilità con MySQL
5.0 (si consiglia l'uso di PhpMyAdmin):
ALTER TABLE whos_online MODIFY COLUMN last_page_url VARCHAR(255) NOT NULL;
ALTER TABLE customers MODIFY COLUMN customers_default_address_id INTEGER;
ALTER TABLE customers_basket MODIFY COLUMN final_price DECIMAL(15,4);
Oltre alle modifiche nei suddetti files, sono state apportate anche altre
modifiche minori, come l'aggiornamento automatico dell'anno e l'aggiunta dell
nome del negozio affianco al copyright nel footer del negozio (modificabile nel
file /catalog/includes/languages/italian.php) e l'inserimento del nome del
negozio anche nel titolo delle p
agine.
Forum di supporto per l'installazione e l'aggiornamento di OpenCommercio:
http://www.openitaliaforum.com nella sezione E-Commerce.
Traduzione del file update-20051113 a cura di Angelo Gagliani, staff di
opencommercio.com .
Indice dei Contenuti
customer_country_id in addressbook. 2
Cannot re-assign $this. 3
limit -20, 20. 4
Database Input Enhancement 5
Adding Non-Existing Products To Cart 7
Session ID XSS Issue. 12
Validate Session ID.. 13
File Manager Problem.. 15
HTTP Header Injection. 16
E-Mail Header Injection. 18
Contact Us Form XSS Issue. 21
Open Redirector 22
Extra Slashes In New Products. 23
Order Status Filtering. 25
MySQL 5.0 Compatibility. 26
customer_country_id in addressbook
http://www.oscommerce.com/community/bugs,1662
Problema:
Quando il cliente aggiorna il proprio indirizzo nella pagina Il mio Profilo, il
valore della nazione è registrato in una variabile errata, che può provocare un
tasso d'imposta errato utilizzato nei prezzi dei prodotti.
Soluzione:
Le seguenti righe di codice devono essere sostituite nel file
catalog/address_book_process.php:
Riga 150, da così:
$customer_country_id = $country_id;
a così:
$customer_country_id = $country;
Riga 171, da così:
$customer_country_id = $country_id;
a così :
$customer_country_id = $country;
Cannot re-assign $this
http://www.oscommerce.com/community/bugs,1650
Problema:
Fatal error: Cannot re-assign $this in
/path/to/catalog/admin/includes/classes/upload.php on line 31
Soluzione:
Righe 27-34 in catalog/admin/includes/classes/upload.php devono essere cambiate
da così:
if ( ($this->parse() == true) && ($this->save() == true) ) {
return true;
} else {
// self destruct
$this = null;
return false;
}
a così :
if ( ($this->parse() == true) && ($this->save() == true) ) {
return true;
} else {
return false;
}
limit -20, 20
http://www.oscommerce.com/community/bugs,1605
Problema:
Errore 1064 - You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near '-20,
20' at line 1
Soluzione:
Riga 67 in catalog/includes/classes/split_page_results.php deve esere cambiata
da:
$this->sql_query .= " limit " . $offset . ", " . $this->number_of_rows_per_page;
a:
$this->sql_query .= " limit " . max($offset, 0) . ", " .
$this->number_of_rows_per_pag
e;
Riga 38 in catalog/admin/includes/classes/split_page_results.php deve essere
cambiata da:
$sql_query .= " limit " . $offset . ", " . $max_rows_per_page;
a:
$sql_query .= " limit " . max($offset, 0) . ", " . $max_rows_per_page;
Database Input Enhancement
Problema:
Le funzioni native MySQL dovrebbero essere usate di preferenza rispetto alla
funzione addslashes(), per proteggere in modo appropriato le query SQL eseguite
sul server del database.
Soluzione:
La seguente funzione deve essere sostituita nel file
catalog/includes/functions/database.php.
Righe 126-128, da:
function tep_db_input($string) {
return addslashes($string);
}
a:
function tep_db_input($string, $link = 'db_link') { global $$link; if (function_exists('mysql_real_escape_string')) { return mysql_real_escape_string($string, $$link); } elseif (function_exists('mysql_escape_string')) { return mysql_escape_string($string); } return addslashes($string);}
La seguente funzione deve essere sostituita nel file
catalog/admin/includes/functions/database.php.
Righe 130-132, da:
function tep_db_input($string) {
return addslashes($string);
}
a :
function tep_db_input($string, $link = 'db_link') { global $$link; if (function_exists('mysql_real_escape_string')) { return mysql_real_escape_string($string, $$link); } elseif (function_exists('mysql_escape_string')) { return mysql_escape_string($string); } return addslashes($string);}
Aggiungere prodotti inesistenti al carrello
http://www.oscommerce.com/community/bugs,1617
Problema:
E' possibile aggiungere prodotti inesistenti al carrello, bisogna prevenire
questa possibilità per i clienti di doverli poi rimuoverli dal carrello.
Soluzione:
Le seguenti funzioni devono essere sostituite nel file
catalog/includes/functions/general.php.
Righe 912-921, da:
function tep_get_uprid($prid, $params) {
$uprid = $prid;
if ( (is_array($params)) && (!strstr($prid, '{')) ) {
while (list($option, $value) = each($params)) {
$uprid = $uprid . '{' . $option . '}' . $value;
}
}
return $uprid;
}
a:
function tep_get_uprid($prid, $params) { if (is_numeric($prid)) { $uprid = $prid; if (is_array($params) && (sizeof($params) > 0)) { $attributes_check = true; $attributes_ids = ''; reset($params); while (list($option, $value) = each($params)) { if (is_numeric($option) && is_numeric($value)) { $attributes_ids .= '{' . (int)$option . '}' . (int)$value; }
else { $attributes_check = false; break; } } if ($attributes_check == true) { $uprid .= $attributes_ids; } } } else { $uprid = tep_get_prid($prid); if (is_numeric($uprid)) { if (strpos($prid, '{') !== false) { $attributes_check = true; $attributes_ids = ''; // strpos()+1 to remove up to and including the first { which would create an empty array element in explode() $attributes = explode('{', substr($prid, strpos($prid, '{')+1)); for ($i=0, $n=sizeof($attributes); $i<$n; $i++) { $pair = explode('}', $attributes[$i]); if (is_numeric($pair[0]) && is_numeric($pair[1])) { $attributes_ids .= '{' . (int)$pair[0] . '}' . (int)$pair[1]; } else { $attributes_check = false; break; } } if ($attributes_check == true) { $uprid .= $attributes_ids; } } } else { return false; } } return $uprid;} Righe 925-929, da:
function tep_get_prid($uprid) {
$pieces = explode('{', $uprid);
return $pieces[0];
}
a:
function tep_get_prid($uprid) { $pieces = explode('{', $uprid); if (is_numeric($pieces[0])) { return $pieces[0]; } else { return false; }}
Le seguenti funzioni devono essere sostituite nel file
catalog/includes/classes/shopping_cart.php.
Righe 78-108, da:
function add_cart($products_id, $qty = '1', $attributes = '', $notify = true) {
global $new_products_id_in_cart, $customer_id;
$products_id = tep_get_uprid($products_id, $attributes);
if ($notify == true) {
$new_products_id_in_cart = $products_id;
tep_session_register('new_products_id_in_cart');
}
if ($this->in_cart($products_id)) {
$this->update_quantity($products_id, $qty, $attributes);
} else {
$this->contents[] = array($products_id);
$this->contents[$products_id] = array('qty' => $qty);
// insert into database
if (tep_session_is_registered('customer_id')) tep_db_query("insert into " .
TABLE_CUSTOMERS_BASKET . " (customers_id, products_id,
customers_basket_quantity, customers_basket_date_added) values ('" .
(int)$customer_id . "', '" . tep_db_input($products_id) . "', '" . $qty . "', '"
. date('Ymd') . "')");
if (is_array($attributes)) {
reset($attributes);
while (list($option, $value) = each($attributes)) {
$this->contents[$products_id]['attributes'][$option] = $value;
// insert into database
if (tep_session_is_registered('customer_id')) tep_db_query("insert into
" . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " (customers_id, products_id,
products_options_id, products_options_value_id) values ('" . (int)$customer_id .
"', '" . tep_db_input($products_id) . "', '" . (int)$option . "', '" .
(int)$value . "')");
}
}
}
$this->cleanup();
// assign a temporary unique ID to the order contents to prevent hack attempts
during the checkout procedure
$this->cartID = $this->generate_cart_id();
}
a:
function add_cart($products_id, $qty = '1', $attributes = '', $notify = true) { global $new_products_id_in_cart, $customer_id; $products_id_string = tep_get_uprid($products_id, $attributes); $products_id = tep_get_prid($products_id_string); if (is_numeric($products_id) && is_numeric($qty)) { $check_product_query = tep_db_query("select products_status from " . TABLE_PRODUCTS . " where products_id = '" . (int)$products_id . "'"); $check_product = tep_db_fetch_array($check_product_query); if (($check_product !== false) && ($check_product['products_status'] == '1')) { if ($notify == true) { $new_products_id_in_cart = $products_id; tep_session_register('new_products_id_in_cart'); } if ($this->in_cart($products_id_string)) { $this->update_quantity($products_id_string, $qty, $attributes); } else { $this->contents[$products_id_string] = array('qty' => $qty);// insert into database if (tep_session_is_registered('customer_id')) tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET . " (customers_id, products_id, customers_basket_quantity, customers_basket_date_added) values ('" . (int)$customer_id . "', '" . tep_db_input($products_id_string) . "', '" . (int)$qty . "', '" . date('Ymd') . "')"); if (is_array($attributes)) { reset($attributes); while (list($option, $value) = each($attributes)) { $this->contents[$products_id_string]['attributes'][$option] = $value;// insert into database if (tep_session_is_registered('customer_id')) tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " (customers_id, products_id, products_options_id, products_options_value_id) values ('" . (int)$customer_id . "', '" . tep_db_input($products_id_string) . "', '" . (int)$option . "', '" . (int)$value . "')"); } } } $this->cleanup(); // assign a temporary unique ID to the order contents to prevent hack attempts during the checkout procedure $this->cartID = $this->generate_cart_id(); } }}
Righe 110-127, da:
function update_quantity($products_id, $quantity = '', $attributes = '') {
global $customer_id;
if (empty($quantity)) return true; // nothing needs to be updated if theres no
quantity, so we return true..
$this->contents[$products_id] = array('qty' => $quantity);
// update database
if (tep_session_is_registered('customer_id')) tep_db_query("update " .
TABLE_CUSTOMERS_BASKET . " set customers_basket_quantity = '" . $quantity . "'
where customers_id = '" . (int)$customer_id . "' and products_id = '" .
tep_db_input($products_id) . "'");
if (is_array($attributes)) {
reset($attributes);
while (list($option, $value) = each($attributes)) {
$this->contents[$products_id]['attributes'][$option] = $value;
// update database
if (tep_session_is_registered('customer_id')) tep_db_query("update " .
TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " set products_options_value_id = '" .
(int)$value . "' where customers_id = '" . (int)$customer_id . "' and
products_id = '" . tep_db_input($products_id) . "' and products_options_id = '"
. (int)$option . "'");
}
}
}
a:
function update_quantity($products_id, $quantity = '', $attributes = '') { global $customer_id; $products_id_string = tep_get_uprid($products_id, $attributes); $products_id = tep_get_prid($products_id_string); if (is_numeric($products_id) && isset($this->contents[$products_id_string]) && is_numeric($quantity)) { $this->contents[$products_id_string] = array('qty' => $quantity);// update database if (tep_session_is_registered('customer_id')) tep_db_query("update " . TABLE_CUSTOMERS_BASKET . " set customers_basket_quantity = '" . (int)$quantity . "' where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($products_id_string) . "'"); if (is_array($attributes)) { reset($attributes); while (list($option, $value) = each($attributes)) { $this->contents[$products_id_string]['attributes'][$option] = $value;// update database if (tep_session_is_registered('customer_id')) tep_db_query("update " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " set products_options_value_id = '" . (int)$value . "' where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($products_id_string) . "' and products_options_id = '" . (int)$option . "'"); } } }}
Problema del Session ID XSS
http://www.oscommerce.com/community/bugs,1546
Problema:
Esiste uno script generale del sito che deforma gli ID di sessione usati nella
funzione tep_href_link().
Soluzione:
Riga 66 nel file catalog/includes/functions/html_output.php deve essere
modificata da:
$link .= $separator . $_sid;
a:
$link .= $separator . tep_output_string($_sid);
Validare Session ID
Problema:
Validare l'ID della sessione e redirigere alla pagina principale quando viene
richiesto un ID sessione non valido.
Soluzione:
La seguente funzione deve essere sostituita nel file
catalog/includes/functions/sessions.php.
Righe 66-68, da:
function tep_session_start() {
return session_start();
}
a:
function tep_session_start() {
global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS;
$sane_session_id = true;
if (isset($HTTP_GET_VARS[tep_session_name()])) {
if (preg_match('/^[a-zA-Z0-9]+$/', $HTTP_GET_VARS[tep_session_name()]) ==
false) {
unset($HTTP_GET_VARS[tep_session_name()]);
$sane_session_id = false;
}
} elseif (isset($HTTP_POST_VARS[tep_session_name()])) {
if (preg_match('/^[a-zA-Z0-9]+$/', $HTTP_POST_VARS[tep_session_name()]) ==
false) {
unset($HTTP_POST_VARS[tep_session_name()]);
$sane_session_id = false;
}
} elseif (isset($HTTP_COOKIE_VARS[tep_session_name()])) {
if (preg_match('/^[a-zA-Z0-9]+$/', $HTTP_COOKIE_VARS[tep_session_name()]) ==
false) {
$session_data = session_get_cookie_params();
setcookie(tep_session_name(), '', time()-42000, $session_data['path'],
$session_data['domain']);
$sane_session_id = false;
}
}
if ($sane_session_id == false) {
tep_redirect(tep_href_link(FILENAME_DEFAULT, '', 'NONSSL', false));
}
return session_start();
}
Problema del File Manager
http://www.oscommerce.com/community/bugs,1391
Problema:
Errori di parsing quando si salva un file modificato attravero il File Manager.
Soluzione:
Riga 148 nel file catalog/admin/file_manager.php deve essere cambiato da:
$file_contents = htmlspecialchars(implode('', $file_array));
a:
$file_contents = addslashes(implode('', $file_array));
Nota: questa modifica richiede anche la modifica nel Contact Us Form XSS (vedi
più avanti) per funzionare in modo corretto.
HTTP Header Injection
Problema:
E' possibile, usando dati maliziosi, iniettare delle intestazioni (headers)
nelle richieste HTTP (problema di sicurezza).
Soluzione:
La seguente funzione deve essere sostituita nel file
catalog/includes/functions/general.php.
Righe 22-32, da:
function tep_redirect($url) {
if ( (ENABLE_SSL == true) && (getenv('HTTPS') == 'on') ) { // We are loading
an SSL page
if (substr($url, 0, strlen(HTTP_SERVER)) == HTTP_SERVER) { // NONSSL url
$url = HTTPS_SERVER . substr($url, strlen(HTTP_SERVER)); // Change it to
SSL
}
}
header('Location: ' . $url);
tep_exit();
}
a:
function tep_redirect($url) {
if ( (strstr($url, "\n") != false) || (strstr($url, "\r") != false) ) {
tep_redirect(tep_href_link(FILENAME_DEFAULT, '', 'NONSSL', false));
}
if ( (ENABLE_SSL == true) && (getenv('HTTPS') == 'on') ) { // We are loading
an SSL page
if (substr($url, 0, strlen(HTTP_SERVER)) == HTTP_SERVER) { // NONSSL url
$url = HTTPS_SERVER . substr($url, strlen(HTTP_SERVER)); // Change it to
SSL
}
}
header('Location: ' . $url);
tep_exit();
}
La seguente funzione deve essere sostituita nel file
catalog/admin/includes/functions/general.php.
Righe 15-26, da:
function tep_redirect($url) {
global $logger;
header('Location: ' . $url);
if (STORE_PAGE_PARSE_TIME == 'true') {
if (!is_object($logger)) $logger = new logger;
$logger->timer_stop();
}
exit;
}
a:
function tep_redirect($url) {
global $logger;
if ( (strstr($url, "\n") != false) || (strstr($url, "\r") != false) ) {
tep_redirect(tep_href_link(FILENAME_DEFAULT, '', 'NONSSL', false));
}
header('Location: ' . $url);
if (STORE_PAGE_PARSE_TIME == 'true') {
if (!is_object($logger)) $logger = new logger;
$logger->timer_stop();
}
exit;
}
E-Mail Header Injection
http://www.oscommerce.com/community/bugs,2488
Problema:
Usando dati maliziosi è possibile iniettare intestazioni (headers) nelle e-mail
che il negozio spedisce.
Soluzione:
La seguente funzione deve essere sostituita nel file
catalog/includes/classes/email.php e nel file
catalog/admin/includes/classes/email.php.
Righe 473-504, da:
function send($to_name, $to_addr, $from_name, $from_addr, $subject = '',
$headers = '') {
$to = (($to_name != '') ? '"' . $to_name . '" <' . $to_addr . '>' : $to_addr);
$from = (($from_name != '') ? '"' . $from_name . '" <' . $from_addr . '>' :
$from_addr);
if (is_string($headers)) {
$headers = explode($this->lf, trim($headers));
}
for ($i=0; $i<count($headers); $i++) {
if (is_array($headers[$i])) {
for ($j=0; $j<count($headers[$i]); $j++) {
if ($headers[$i][$j] != '') {
$xtra_headers[] = $headers[$i][$j];
}
}
}
&
nbsp; if ($headers[$i] != '') {
$xtra_headers[] = $headers[$i];
}
}
if (!isset($xtra_headers)) {
$xtra_headers = array();
}
if (EMAIL_TRANSPORT == 'smtp') {
return mail($to_addr, $subject, $this->output, 'From: ' . $from . $this->lf
. 'To: ' . $to . $this->lf . implode($this->lf, $this->headers) . $this->lf .
implode($this->lf, $xtra_headers));
} else {
return mail($to, $subject, $this->output, 'From:
'.$from.$this->lf.implode($this->lf,
$this->headers).$this->lf.implode($this->lf, $xtra_headers));
}
}
a:
function send($to_name, $to_addr, $from_name, $from_addr, $subject = '',
$headers = '') {
if ((strstr($to_name, "\n") != false) || (strstr($to_name, "\r") != false)) {
return false;
}
if ((strstr($to_addr, "\n") != false) || (strstr($to_addr, "\r") != false)) {
return false;
}
if ((strstr($subject, "\n") != false) || (strstr($subject, "\r") != false)) {
return false;
}
if ((strstr($from_name, "\n") != false) || (strstr($from_name, "\r") !=
false)) {
return false;
}
if ((strstr($from_addr, "\n") != false) || (strstr($from_addr, "\r") !=
false)) {
return false;
}
$to = (($to_name != '') ? '"' . $to_name . '" <' . $to_addr . '>' : $to_addr);
$from = (($from_name != '') ? '"' . $from_name . '" <' . $from_addr . '>' :
$from_addr);
if (is_string($headers)) {
$headers = explode($this->lf, trim($headers));
}
for ($i=0; $i<count($headers); $i++) {
if (is_array($headers[$i])) {
for ($j=0; $j<count($headers[$i]); $j++) {
if ($headers[$i][$j] != '') {
$xtra_headers[] = $headers[$i][$j];
}
}
}
if ($headers[$i] != '') {
$xtra_headers[] = $headers[$i];
}
}
if (!isset($xtra_headers)) {
$xtra_headers = array();
}
if (EMAIL_TRANSPORT == 'smtp') {
return mail($to_addr, $subject, $this->output, 'From: ' . $from . $this->lf
. 'To: ' . $to . $this->lf . implode($this->lf, $this->headers) . $this->lf .
implode($this->lf, $xtra_headers));
} else {
return mail($to, $subject, $this->output, 'From:
'.$from.$this->lf.implode($this->lf,
$this->headers).$this->lf.implode($this->lf, $xtra_headers));
}
}
Problema Contact Us Form XSS
http://www.oscommerce.com/community/bugs,2422
Problema:
Usando dati maliziosi, è possibile
iniettare codice HTML nella pagina.
Soluzione:
Righe 221-225 nel filecatalog/includes/functions/html_output.php devono essere
cambiati da:
if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {
$field .= stripslashes($GLOBALS[$name]);
} elseif (tep_not_null($text)) {
$field .= $text;
}
a:
if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {
$field .= tep_output_string_protected(stripslashes($GLOBALS[$name]));
} elseif (tep_not_null($text)) {
$field .= tep_output_string_protected($text);
}
Righe 244-248 nel file catalog/admin/includes/functions/html_output.php devono
essere cambiate da:
if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {
$field .= stripslashes($GLOBALS[$name]);
} elseif (tep_not_null($text)) {
$field .= $text;
}
a:
if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {
$field .= tep_output_string_protected(stripslashes($GLOBALS[$name]));
} elseif (tep_not_null($text)) {
$field .= tep_output_string_protected($text);
}
Open Redirector
http://www.oscommerce.com/community/bugs,2970
Problema:
Non c'è nessun controllo sull'URL nella pagina di ridirezione, permettendo così
a sorgenti esterni di utilizzare la pagina come ridirezione aperta.
Soluzione:
Righe 27-29 nel file catalog/redirect.php devono essere cambiate da:
if (isset($HTTP_GET_VARS['goto']) && tep_not_null($HTTP_GET_VARS['goto'])) {
tep_redirect('http://' . $HTTP_GET_VARS['goto']);
}
a:
if (isset($HTTP_GET_VARS['goto']) && tep_not_null($HTTP_GET_VARS['goto'])) {
$check_query = tep_db_query("select products_url from " .
TABLE_PRODUCTS_DESCRIPTION . " where products_url = '" .
tep_db_input($HTTP_GET_VARS['goto']) . "' limit 1");
if (tep_db_num_rows($check_query)) {
tep_redirect('http://' . $HTTP_GET_VARS['goto']);
}
}
Slash aggiuntivi nei nuovi prodotti
Problema:
Quando si inseriscono nuovo prodotti e si fa l'anteprima, cliccando il tasto
Indietro per modificare i dati dei prodotti appena inseriti, si aggiungono slah
extra agli apostrofi nei nomi dei prodotti e nella loro descrizione.
Soluzione:
Le seguenti righe devono essere sostituite nel file
catalog/admin/categories.php:
Riga 504, da:
<td class="main"><?php echo tep_image(DIR_WS_CATALOG_LANGUAGES .
$languages[$i]['directory'] . '/images/' . $languages[$i]['image'],
$languages[$i]['name']) . ' ' . tep_draw_input_field('products_name[' .
$languages[$i]['id'] . ']', (isset($products_name[$languages[$i]['id']]) ?
$products_name[$languages[$i]['id']] :
tep_get_products_name($pInfo->products_id, $languages[$i]['id']))); ?></td>
a:
<td class="main"><?php echo tep_image(DIR_WS_CATALOG_LANGUAGES .
$languages[$i]['directory'] . '/images/' . $languages[$i]['image'],
$languages[$i]['name']) . ' ' . tep_draw_input_field('products_name[' .
$languages[$i]['id'] . ']', (isset($products_name[$languages[$i]['id']]) ?
stripslashes($products_name[$languages[$i]['id']]) :
tep_get_products_name($pInfo->products_id, $languages[$i]['id']))); ?></td>
Riga 538, da:
<td class="main"><?php echo tep_draw_textarea_field('products_description[' .
$languages[$i]['id'] . ']', 'soft', '70', '15',
(isset($products_description[$languages[$i]['id']]) ?
$products_description[$languages[$i]['id']] :
tep_get_products_description($pInfo->products_id, $languages[$i]['id'])));
?></td>
a:
<td class="main"><?php echo tep_draw_textarea_field('products_description[' .
$languages[$i]['id'] . ']', 'soft', '70', '15',
(isset($products_description[$languages[$i]['id']]) ?
stripslashes($products_description[$languages[$i]['id']]) :
tep_get_products_description($pInfo->products_id, $languages[$i]['id'])));
?></td>
Riga 574, da:
<td class="main"><?php echo tep_image(DIR_WS_CATALOG_LANGUAGES .
$languages[$i]['directory'] . '/images/' . $languages[$i]['image'],
$languages[$i]['name']) . ' ' . tep_draw_input_field('products_url[' .
$languages[$i]['id'] . ']', (isset($products_url[$languages[$i]['id']]) ?
$products_url[$languages[$i]['id']] : tep_get_products_url($pInfo->products_id,
$languages[$i]['id']))); ?></td>
a:
<td class="main"><?php echo tep_image(DIR_WS_CATALOG_LANGUAGES .
$languages[$i]['directory'] . '/images/' . $languages[$i]['image'],
$languages[$i]['name']) . ' ' . tep_draw_input_field('products_url[' .
$languages[$i]['id'] . ']', (isset($products_url[$languages[$i]['id']]) ?
stripslashes($products_url[$languages[$i]['id']]) :
tep_get_products_url($pInfo->products_id, $languages[$i]['id']))); ?></td>
Filtrare lo stato degli ordini
http://www.oscommerce.com/community/bugs,1543
Problema:
Se si modifica il filtraggio dello stato degli ordini nel Pannello di
Amministrazione >> Clienti >> Pagina degli Ordini, selezionando "Tutti gli
ordini" viene visulaizzato un elenco vuoto di ordini.
Soluzione:
Riga 357 nel file catalog/admin/orders.php deve essere modificata da:
} elseif (isset($HTTP_GET_VARS['status'])) {
a:
} elseif (isset($HTTP_GET_VARS['status']) &&
is_numeric($HTTP_GET_VARS['status']) && ($HTTP_GET_VARS['status'] > 0)) {
Compatibilità MySQL 5.0
Problema:
MySQL 5.0 introduce modalità Server SQL come arte del supporto standard di SQL
2003, e usa un approccio molto più restrittivo nell'eseguire le query SQL. Ciò
viene attuato per default con l'impostazione STRICT_TRANS_TABLES come modalità
Server SQL.
A causa di questa nuova impostazione, MySQL non riesce a eseguire alcune query
SQL e produce un messaggio di errore.
<
br />Soluzione:
Righe 213-223 nel file catalog/advanced_search_result.php devono essere
modificate da:
$from_str = "from " . TABLE_PRODUCTS . " p left join " . TABLE_MANUFACTURERS . "
m using(manufacturers_id) left join " . TABLE_SPECIALS . " s on p.products_id =
s.products_id, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_CATEGORIES . "
c, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c";
if ( (DISPLAY_PRICE_WITH_TAX == 'true') && (tep_not_null($pfrom) ||
tep_not_null($pto)) ) {
if (!tep_session_is_registered('customer_country_id')) {
$customer_country_id = STORE_COUNTRY;
$customer_zone_id = STORE_ZONE;
}
$from_str .= " left join " . TABLE_TAX_RATES . " tr on p.products_tax_class_id
= tr.tax_class_id left join " . TABLE_ZONES_TO_GEO_ZONES . " gz on
tr.tax_zone_id = gz.geo_zone_id and (gz.zone_country_id is null or
gz.zone_country_id = '0' or gz.zone_country_id = '" . (int)$customer_country_id
. "') and (gz.zone_id is null or gz.zone_id = '0' or gz.zone_id = '" .
(int)$customer_zone_id . "')";
}
$where_str = " where p.products_status = '1' and p.products_id = pd.products_id
and pd.language_id = '" . (int)$languages_id . "' and p.products_id =
p2c.products_id and p2c.categories_id = c.categories_id ";
a:
$from_str = "from " . TABLE_PRODUCTS . " p left join " . TABLE_MANUFACTURERS . "
m using(manufacturers_id) left join " . TABLE_SPECIALS . " s on p.products_id =
s.products_id";
if ( (DISPLAY_PRICE_WITH_TAX == 'true') && (tep_not_null($pfrom) ||
tep_not_null($pto)) ) {
if (!tep_session_is_registered('customer_country_id')) {
$customer_country_id = STORE_COUNTRY;
$customer_zone_id = STORE_ZONE;
}
$from_str .= " left join " . TABLE_TAX_RATES . " tr on p.products_tax_class_id
= tr.tax_class_id left join " . TABLE_ZONES_TO_GEO_ZONES . " gz on
tr.tax_zone_id = gz.geo_zone_id and (gz.zone_country_id is null or
gz.zone_country_id = '0' or gz.zone_country_id = '" . (int)$customer_country_id
. "') and (gz.zone_id is null or gz.zone_id = '0' or gz.zone_id = '" .
(int)$customer_zone_id . "')";
}
$from_str .= ", " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_CATEGORIES . "
c, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c";
$where_str = " where p.products_status = '1' and p.products_id = pd.products_id
and pd.language_id = '" . (int)$languages_id . "' and p.products_id =
p2c.products_id and p2c.categories_id = c.categories_id ";
Le seguenti righe devono essere sostituite nel file catalog/index.php:
Riga 175, da:
$listing_sql = "select " . $select_column_list . " p.products_id,
p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status,
s.specials_new_products_price, NULL) as specials_new_products_price,
IF(s.status, s.specials_new_products_price, p.products_price) as final_price
from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " .
TABLE_MANUFACTURERS . " m, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c left join "
. TABLE_SPECIALS . " s on p.products_id = s.products_id where p.products_status
= '1' and p.manufacturers_id = m.manufacturers_id and m.manufacturers_id = '" .
(int)$HTTP_GET_VARS['m
anufacturers_id'] . "' and p.products_id = p2c.products_id
and pd.products_id = p2c.products_id and pd.language_id = '" .
(int)$languages_id . "' and p2c.categories_id = '" .
(int)$HTTP_GET_VARS['filter_id'] . "'";
a:
$listing_sql = "select " . $select_column_list . " p.products_id,
p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status,
s.specials_new_products_price, NULL) as specials_new_products_price,
IF(s.status, s.specials_new_products_price, p.products_price) as final_price
from " . TABLE_PRODUCTS . " p left join " . TABLE_SPECIALS . " s on
p.products_id = s.products_id, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " .
TABLE_MANUFACTURERS . " m, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c where
p.products_status = '1' and p.manufacturers_id = m.manufacturers_id and
m.manufacturers_id = '" . (int)$HTTP_GET_VARS['manufacturers_id'] . "' and
p.products_id = p2c.products_id and pd.products_id = p2c.products_id and
pd.language_id = '" . (int)$languages_id . "' and p2c.categories_id = '" .
(int)$HTTP_GET_VARS['filter_id'] . "'";
Riga 178, da:
$listing_sql = "select " . $select_column_list . " p.products_id,
p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status,
s.specials_new_products_price, NULL) as specials_new_products_price,
IF(s.status, s.specials_new_products_price, p.products_price) as final_price
from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " .
TABLE_MANUFACTURERS . " m left join " . TABLE_SPECIALS . " s on p.products_id =
s.products_id where p.products_status = '1' and pd.products_id = p.products_id
and pd.language_id = '" . (int)$languages_id . "' and p.manufacturers_id =
m.manufacturers_id and m.manufacturers_id = '" .
(int)$HTTP_GET_VARS['manufacturers_id'] . "'";
a:
$listing_sql = "select " . $select_column_list . " p.products_id,
p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status,
s.specials_new_products_price, NULL) as specials_new_products_price,
IF(s.status, s.specials_new_products_price, p.products_price) as final_price
from " . TABLE_PRODUCTS . " p left join " . TABLE_SPECIALS . " s on
p.products_id = s.products_id, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " .
TABLE_MANUFACTURERS . " m where p.products_status = '1' and pd.products_id =
p.products_id and pd.language_id = '" . (int)$languages_id . "' and
p.manufacturers_id = m.manufacturers_id and m.manufacturers_id = '" .
(int)$HTTP_GET_VARS['manufacturers_id'] . "'";
Riga 184, da:
$listing_sql = "select " . $select_column_list . " p.products_id,
p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status,
s.specials_new_products_price, NULL) as specials_new_products_price,
IF(s.status, s.specials_new_products_price, p.products_price) as final_price
from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " .
TABLE_MANUFACTURERS . " m, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c left join "
. TABLE_SPECIALS . " s on p.products_id = s.products_id where p.products_status
= '1' and p.manufacturers_id = m.manufacturers_id and m.manufacturers_id = '" .
(int)$HTTP_GET_VARS['filter_id'] . "' and p.products_id = p2c.products_id and
pd.products_id = p2c.products_id and pd.language_id = '" . (int)$languages_id .
"' and p2c.categories_id = '" . (int)$current_category_id . "'";
a:
$listing_sql = "select " . $select_column_list . " p.products_id,
p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status,
s.specials_new_products_price, NULL) as specials_new_products_price,
IF(s.status, s.specials_new_products_price, p.products_price) as final_price
from " . TABLE_PRODUCTS . " p left join " . TABLE_SPECIALS . " s on
p.products_id = s.products_id, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " .
TABLE_MANUFACTURERS . " m, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c where
p.products_status = '1' and p.manufacturers_id = m.manufacturers_id and
m.manufacturers_id = '" . (int)$HTTP_GET_VARS['filter_id'] . "' and
p.products_id = p2c.products_id and pd.products_id = p2c.products_id and
pd.language_id = '" . (int)$languages_id . "' and p2c.categories_id = '" .
(int)$current_category_id . "'";
Riga 187, da:
$listing_sql = "select " . $select_column_list . " p.products_id,
p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status,
s.specials_new_products_price, NULL) as specials_new_products_price,
IF(s.status, s.specials_new_products_price, p.products_price) as final_price
from " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_PRODUCTS . " p left join "
. TABLE_MANUFACTURERS . " m on p.manufacturers_id = m.manufacturers_id, " .
TABLE_PRODUCTS_TO_CATEGORIES . " p2c left join " . TABLE_SPECIALS . " s on
p.products_id = s.products_id where p.products_status = '1' and p.products_id =
p2c.products_id and pd.products_id = p2c.products_id and pd.language_id = '" .
(int)$languages_id . "' and p2c.categories_id = '" . (int)$current_category_id .
"'";
a:
$listing_sql = "select " . $select_column_list . " p.products_id,
p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status,
s.specials_new_products_price, NULL) as specials_new_products_price,
IF(s.status, s.specials_new_products_price, p.products_price) as final_price
from " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_PRODUCTS . " p left join "
. TABLE_MANUFACTURERS . " m on p.manufacturers_id = m.manufacturers_id left join
" . TABLE_SPECIALS . " s on p.products_id = s.products_id, " .
TABLE_PRODUCTS_TO_CATEGORIES . " p2c where p.products_status = '1' and
p.products_id = p2c.products_id and pd.products_id = p2c.products_id and
pd.language_id = '" . (int)$languages_id . "' and p2c.categories_id = '" .
(int)$current_category_id . "'";
Riga 292 nel file catalog/admin/categories.php deve essere modificato da:
tep_db_query("insert into " . TABLE_PRODUCTS . " (products_quantity,
products_model,products_image, products_price, products_date_added,
products_date_available, products_weight, products_status,
products_tax_class_id, manufacturers_id) values ('" .
tep_db_input($product['products_quantity']) . "', '" .
tep_db_input($product['products_model']) . "', '" .
tep_db_input($product['products_image']) . "', '" .
tep_db_input($product['products_price']) . "', now(), '" .
tep_db_input($product['products_date_available']) . "', '" .
tep_db_input($product['products_weight']) . "', '0', '" .
(int)$product['products_tax_class_id'] . "', '" .
(int)$product['manufacturers_id'] . "')");
a:
tep_db_query("insert into " . TABLE_PRODUCTS . " (products_quantity,
products_mod
el,products_image, products_price, products_date_added,
products_date_available, products_weight, products_status,
products_tax_class_id, manufacturers_id) values ('" .
tep_db_input($product['products_quantity']) . "', '" .
tep_db_input($product['products_model']) . "', '" .
tep_db_input($product['products_image']) . "', '" .
tep_db_input($product['products_price']) . "', now(), " .
(empty($product['products_date_available']) ? "null" : "'" .
tep_db_input($product['products_date_available']) . "'") . ", '" .
tep_db_input($product['products_weight']) . "', '0', '" .
(int)$product['products_tax_class_id'] . "', '" .
(int)$product['manufacturers_id'] . "')");
Inoltre, eseguire le seguenti query SQL :
ALTER TABLE whos_online MODIFY COLUMN last_page_url VARCHAR(255) NOT NULL;
ALTER TABLE customers MODIFY COLUMN customers_default_address_id INTEGER;
ALTER TABLE customers_basket MODIFY COLUMN final_price DECIMAL(15,4);