Перейти к содержимому


Правила форума

Внимание!!! Если не можете скачать, пожалуйста ознакомьтесь с условиями получения доступа с файлам форума. Правила форума


Штатные ошибки ShopCMS, из коробки :).


Сообщений в теме: 37

#1 badisoft

    Продвинутый пользователь

  • VIP
  • 4 986 сообщений
Репутация: 761
Мастер

Отправлено 09 ноября 2014 - 15:57

Решил собрать в кучу и худо-бедно причесать найденные в ShopCMS штатные ошибки и странности:

================================================
Штатная ошибка. Из-за нее незарегистрированный пользователь не сможет скачать купленный им электронный товар.

В файле core/includes/processor/get_file.php
строку:

$q = db_query("select order_time from ".ORDERS_TABLE." where orderID=".orderID);


нужно заменить на:

$q = db_query("select order_time from ".ORDERS_TABLE." where orderID=".$orderID);


P.S. Чтобы незарегистрированный пользователь мог получить ссылку на электронный товар, нужно в общих настройках админ-панели поставить галочку напротив пункта E-mail отчеты для покупателей

=====================

Нашел ошибку в catalog_extra.php (штатную). Перепутаны таблицы, это вызывает ошибку SQL при удалении варианта характеристики.
Исправление:

#db_query("delete from ".CATEGORY_PRODUCT_OPTIONS_TABLE." where variantID=".$variantid);
db_query("delete from ".CATEGORY_PRODUCT_OPTION_VARIANTS." where variantID=".$variantid);


=============================

Штатная ошибка: При импорте из CSV варианты характеристик, содержащие символы '"<>& двоятся, т.е. создаются столько раз, сколько товаров с таким вариантом характеристики.

Исправление: в функции optOptionValueExists строку

" where optionID=".(int)$optionID." and option_value='".xEscSQL(trim($value_name))."';");


заменяем на

#" where optionID=".(int)$optionID." and option_value='".xEscSQL(trim($value_name))."';");
" where optionID=".(int)$optionID." and option_value='".xToText(trim($value_name))."';");



=============================

Есть в discount_functions.php функция _calculateGeneralPriceDiscount, возвращающая размер скидки в зависимости от суммы заказа. Выглядит она вот так:

function _calculateGeneralPriceDiscount( $orderPrice, $log )
{
		$customerID = (int)regGetIdByLogin($log);
		$q = db_query("select discount_id, price_range, percent_discount from ".
						ORDER_PRICE_DISCOUNT_TABLE." order by price_range " );
		$data = array();
		while( $row = db_fetch_row($q) ) $data[] = $row;

		if ( count($data) != 0 )
		{
				for( $i=0; $i<count($data)-1; $i++ )
				{
						if ( $data[$i][ "price_range" ] < $orderPrice
								&& $orderPrice < $data[$i+1][ "price_range" ]  )
								return $data[$i][ "percent_discount" ];
				}
				if (  $data[ count($data)-1 ][ "price_range" ] < $orderPrice  )
						return $data[ count($data)-1 ][ "percent_discount" ];
		}

		return 0;
}


Если сумма заказа совпадает с суммой, от которой начинается новая скидка, то скидка будет ноль :).
Т.е. если до 5000руб скидка 4%, а от 5000руб - 5%, то на заказ 4999руб будет скидка 4%, на 5001руб - 5%, а вот на 5000руб - 0% :))).

В общем, зачем там такой развесистый код я не понял и заменил на:

function _calculateGeneralPriceDiscount( $orderPrice, $log )
{
$data = db_query("SELECT price_range, percent_discount FROM ".ORDER_PRICE_DISCOUNT_TABLE." ORDER BY price_range");
$discount = 0;
while( $row = db_fetch_row($data) ) if ($row['price_range'] <= $orderPrice) $discount = $row['percent_discount'];
return $discount;
}


===========================

Нашел не ошибку, но весьма странный стиль программирования.
файл cart_functions.php, функция cartGetCartContent()

$costUC = GetPriceProductWithOption( $variants, $shopping_cart_item["productID"] );
$tmp = array(
"productID" =>  $product["productID"],
...
"costUC" => $costUC,
"cost"   => show_price($cart_item["Quantity"]*GetPriceProductWithOption($variants,$shopping_cart_item["productID"])),
...


Зачем вычислять второй раз GetPriceProductWithOption($variants,$shopping_cart_item["productID"]), когда ровно это же число находится в переменной $costUC строкой выше? Оно ведь нифига не бесплатно:

function GetPriceProductWithOption($variants, $productID)
{
		$q=db_query("select Price from ".PRODUCTS_TABLE." where productID=".(int)$productID);
		$r=db_fetch_row($q);
		$base_price = (float)$r[0];
		$full_price = (float)$base_price;
		foreach($variants as $vars)
		{
				$q1=db_query("select price_surplus from ".PRODUCTS_OPTIONS_SET_TABLE.
						" where productID=".(int)$productID." AND variantID=".(int)$vars);
				$r1=db_fetch_row($q1);
				$full_price += $r1["price_surplus"];
		}
		return $full_price;
}


т.е. при десяти возможных вариантах получаем лишних 11 SQL-запросов.

А если посмотреть, то и вообще всю функцию GetPriceProductWithOption можно заменить на "двухзапросную". Первым запросом получаем базовую цену, вторым - изменение от базовой для переданного набора вариантов.

function GetPriceProductWithOption($variants, $productID)
{
$row=db_fetch_assoc(db_query("SELECT Price FROM ".PRODUCTS_TABLE." WHERE productID=$productID LIMIT 1"));
if (!$variants) return $row['Price'];
$row1=db_fetch_assoc(db_query("SELECT SUM(price_surplus) AS price_surplus FROM ".PRODUCTS_OPTIONS_SET_TABLE." WHERE productID=$productID AND variantID IN (".implode(',',$variants).")"));
return $row['Price']+$row1['price_surplus'];
}




=================================

На этот раз ошибка ни на что не влияющая, но прикольная :).
файл product_functions.php
функция GetExtraParametrs
в SQL-запросе чудный текст (два раза повторяется одно условие):

WHERE povvt.optionID='.$_Row['optionID'].' AND post.productID='.$_Row['productID'].' AND povvt.optionID='.$_Row['optionID']


==================================

Ошибка: штатный и аж четыре раза встречающийся в index.php код совершенно бессмысленен:

if ($smarty -> get_template_vars("main_content_template") == ("category.tpl.html" || "category_search_result.tpl.html"))


Это кусок условия вывода блоков. Левого, правого, верхнего, нижнего. Четыре одинаковых куска кода.

Правильно так:

if ($smarty -> get_template_vars("main_content_template") == "category.tpl.html" || get_template_vars("main_content_template") == "category_search_result.tpl.html")


==================================

Не ошибка. Просто заменяем многострочное извращение с ob_start() на var_export(), появившийся в PHP5
Снимает проблему "белого экрана" в некоторых редких случаях.

function db_query($s) //database query

[...]

/*
			ob_start();
			var_dump($_GET);
			var_dump($_POST);
			$tmpa=ob_get_contents();
			ob_end_clean();
			$out .= $tmpa;
*/
			$out .= var_export($_REQUEST,true);


====================================

Аналогично.

function error_reporting_log($error_num, $error_var, $error_file, $error_line) {

[...]

/*
			ob_start();
			var_dump($_GET);
			var_dump($_POST);
			$tmpa = ob_get_contents();
			ob_end_clean();
			$out .= $tmpa;
*/
			$out .= var_export($_REQUEST,true);


========================================

Если разрешено задавать количество товара при добавлении в корзину (опция "Разрешить указывать количество товара для добавления в корзину"), а у товара задана не единица в минимальном заказе (скажем, купить можно начиная от N штук), то при задании в окошке выбранного количества числа M получим в корзине не М товаров, а M+N-1. Происходит это потому, что товар добавляется поштучно в цикле от 1 до M (см. shopping_cart.php)

for ($mcn=0; $mcn<$_GET["multyaddcount"]; $mcn++) cartAddToCart( $_GET["add2cart"], $variants );


но при каждом "поштучном" добавлении происходит проверка корзины и если товара там еще нет (первое добавление), то добавляется не 1, а N (см. cart_functions.php, cartAddToCart)

$count_to_order = 1;
....
if ( $item_index == -1 ) $count_to_order = $min_order_amount;
....
db_query("UPDATE ".SHOPPING_CARTS_TABLE." SET Quantity=".(int)$count_to_order....


Решение:

1. в файле cart_functions.php в функции cartAddToCart заменяем

return true;


на

return $count_to_order;


все равно нигде (ни в одном месте из двух :)) не проверяется, что вернула эта функция.

2. в файле cart.php находим строку cartAddToCart

и заменяем

for ( $mcn = 0; $mcn < $_GET["multyaddcount"]; $mcn++ )
	cartAddToCart(( int ) $_GET["addproduct"], $variants);


на

for ( $mcn = 0; $mcn < $_GET["multyaddcount"]; $mcn+=$added )
	if (!$added = cartAddToCart(( int ) $_GET["addproduct"], $variants)) break;


3. в файле shopping_cart.php находим строку cartAddToCart

и заменяем

for ($mcn=0; $mcn<$_GET["multyaddcount"]; $mcn++) cartAddToCart( $_GET["add2cart"], $variants );


на

for ($mcn=0; $mcn<$_GET["multyaddcount"]; $mcn+=$added) if (!$added = cartAddToCart( $_GET["add2cart"], $variants )) break;


============================================

В модулях курьерской доставки (файлы class.courier2.php и class.courier.php) SQL-таблица SS__courier_rates не имеет префикса, т.е. при двух и более сайтах в одной SQL-базе могут быть проблемы,
т.к. при удалении этого модуля доставки таблица чистится либо удаляется.

============================================

Не ошибка, просто упрощаем код:

1. в файле cart.php

заменяем

		  if ( isset ( $_SESSION["log"] ))
			  //taking products from database
			  {
			  $q = db_query("select itemID, Quantity FROM ".SHOPPING_CARTS_TABLE." WHERE customerID=".( int ) regGetIdByLogin($_SESSION["log"]));
			  while ( $row = db_fetch_row($q)) {
				  $q1 = db_query("select productID from ".SHOPPING_CART_ITEMS_TABLE." where itemID=".( int ) $row["itemID"]);
				  $r1 = db_fetch_row($q1);
				  $variants = GetConfigurationByItemId($row["itemID"]);
				  $k += GetPriceProductWithOption($variants, $r1["productID"]) * $row["Quantity"];
				  $cnt += $row["Quantity"];
			  }
		  }
		  else
			  if ( isset ( $_SESSION["gids"] ))
				  //...session vars
				  {
				  for ( $i = 0; $i < count($_SESSION["gids"]); $i++ ) {
					  if ( $_SESSION["gids"][$i] ) {
						  $t = db_query("select Price FROM ".PRODUCTS_TABLE." WHERE productID=".( int ) $_SESSION["gids"][$i]);
						  $rr = db_fetch_row($t);
						  $sum = $rr["Price"];
						  // $rr["Price"]
						  foreach ( $_SESSION["configurations"][$i] as $varconf ) {
							  $q1 = db_query("select price_surplus from ".PRODUCTS_OPTIONS_SET_TABLE." where variantID=".( int ) $varconf." AND productID=".( int ) $_SESSION["gids"][$i]);
							  $r1 = db_fetch_row($q1);
							  $sum += $r1["price_surplus"];
						  }
						  $k += $_SESSION["counts"][$i] * $sum;
						  $cnt += $_SESSION["counts"][$i];
					  }
				  }
			  }


на

$k = $resCart["total_price"];
#$k = $resCart["total_price"] - $resDiscount["discount_standart_unit"]; // если хотим видеть в корзине сумму сразу со скидкой
foreach ($resCart["cart_content"] as $rc) $cnt += $rc["quantity"];



2. в файле shopping_cart_info.php

заменяем

		if (isset($_SESSION["log"])) //taking products from database
		{
				$q = db_query("select itemID, Quantity FROM ".SHOPPING_CARTS_TABLE.
								" WHERE customerID=".regGetIdByLogin($_SESSION["log"]));
				while ($row = db_fetch_row($q))
				{
						$q1=db_query("select productID from ".SHOPPING_CART_ITEMS_TABLE.
								" where itemID=".$row["itemID"]);
						$r1=db_fetch_row($q1);
						if($r1["productID"]){
						$variants=GetConfigurationByItemId( $row["itemID"] );
						$k += GetPriceProductWithOption($variants, $r1["productID"])*$row["Quantity"];
						$cnt+=$row["Quantity"];
						}
				}
		}
		else
		if (isset($_SESSION["gids"])) //...session vars
		{
				for ($i=0; $i<count($_SESSION["gids"]); $i++)
				{
						if ($_SESSION["gids"][$i])
						{
								$t = db_query("select Price FROM ".PRODUCTS_TABLE." WHERE productID=".(int)$_SESSION["gids"][$i]);
								$rr = db_fetch_row($t);

								$sum=$rr["Price"];

								// $rr["Price"]
								foreach( $_SESSION["configurations"][$i] as $vars )
								{
										$q1=db_query("select price_surplus from ".PRODUCTS_OPTIONS_SET_TABLE.
												" where variantID=".(int)$vars." AND productID=".(int)$_SESSION["gids"][$i]);
										$r1=db_fetch_row($q1);
										$sum+=$r1["price_surplus"];
								}

								$k += $_SESSION["counts"][$i]*$sum;
								$cnt += $_SESSION["counts"][$i];
						}
				}
		}


на

$resCart = cartGetCartContent();
$k = $resCart["total_price"];
#$resDiscount = dscCalculateDiscount($resCart["total_price"], isset ( $_SESSION["log"] ) ? $_SESSION["log"] : ""); // если хотим видеть в корзине сумму сразу со скидкой
#$k = $resCart["total_price"] - $resDiscount["discount_standart_unit"];
foreach ($resCart["cart_content"] as $rc) $cnt += $rc["quantity"];


=============================================

Не ошибка, хотя как посмотреть. Дополнение резко сокращает количество SQL-запросов при сохранении настроек товаров и категорий. Актуально для сайтов с большим количеством категорий. Например, штатно на тысяче категорий будет 16тысяч (!!!) SQL-запросов. Здесь, насколько я помню, четыре запроса не зависимо от количества категорий.


Установка:

В файле category_functions.php

1. в функции update_psCount

строку

update_pCount($parent);


заменяем на

update_pCount_new($parent);


2. куда-нибудь рядом добавляем две функции

function update_sCount_new($parent, $counts = array(1 => array ('subcats' => 0,'admin_count' => 0,'customer_count' => 0)))
{
global $mc;
foreach (array_keys ($mc,(int)$parent) as $val)
	{
	$counts[$val]['subcats'] = count(array_keys($mc, $val));
	$counts[$val]['admin_count'] = 0;
	$counts[$val]['customer_count'] = 0;
	if ($counts[$val]['subcats']) $counts = update_sCount_new($val,$counts);
	}
return $counts;
}

function update_pCount_new($parent)
{
global $fc;
$qstr = array(
	"SELECT categoryID, COUNT(*) AS admcount, COUNT(NULLIF(enabled,0)) AS count FROM ".PRODUCTS_TABLE." GROUP BY categoryID",
	"SELECT pc.categoryID, COUNT(*) AS admcount, COUNT(NULLIF(enabled,0)) AS count FROM ".CATEGORIY_PRODUCT_TABLE." AS pc JOIN ".PRODUCTS_TABLE." USING (productID) GROUP BY pc.categoryID");
$counts = update_sCount_new($parent);
foreach ($qstr as $str)
	{
	$data = db_query($str);
	while ($row=db_fetch_assoc($data))
		{
		$categoryID = (int)$row['categoryID'];
		while ($categoryID)
			{
			$counts[$categoryID]['admin_count'] += (int)$row['admcount'];
			$counts[$categoryID]['customer_count'] += (int)$row['count'];
			$categoryID = $fc[$categoryID]['parent'];
			}
		}
	}
$data = db_query("SELECT categoryID, subcount, products_count, products_count_admin FROM ".CATEGORIES_TABLE);
while ($row = db_fetch_assoc($data))
	{
	$categoryID = (int)$row['categoryID'];
	if ((int)$row['subcount'] != $counts[$categoryID]['subcats'] || (int)$row['products_count'] != $counts[$categoryID]['customer_count'] || (int)$row['products_count_admin'] != $counts[$categoryID]['admin_count'])
		db_query("UPDATE ".CATEGORIES_TABLE." SET subcount=".$counts[$categoryID]['subcats'].", products_count=".$counts[$categoryID]['customer_count'].", products_count_admin=".$counts[$categoryID]['admin_count']." WHERE categoryID=$categoryID");
	}
}


http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#2 Lada

    Продвинутый пользователь

  • Download User
  • PipPipPip
  • 107 сообщений
Репутация: 7
Начинающий
  • ГородЧита

Отправлено 11 ноября 2014 - 15:54

Большое Вам спасибо, особенно было актуально то, что незарегистрированный пользователь не мог скачать купленный им электронный товар.
Из-за этого приходилось выставлять ОБЯЗАТЕЛЬНУЮ регистрацию..
А когда в магазине товар смешанный - цифровой и физический, то теряли натурально большой процент клиентов, которые брали физические товары и их смущала эта обязательная регистрация..

#3 badisoft

    Продвинутый пользователь

  • VIP
  • 4 986 сообщений
Репутация: 761
Мастер

Отправлено 11 ноября 2014 - 16:06

Просмотр сообщенияLada сказал:

Большое Вам спасибо, особенно было актуально то, что незарегистрированный пользователь не мог скачать купленный им электронный товар.
Это единственная найденная не мной ошибка. Так что спасибо не мне :).
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#4 Jeck2000

    Продвинутый пользователь

  • Assistent vsupport.ru
  • PipPipPip
  • 157 сообщений
Репутация: 8
Начинающий
  • ГородСанкт-Петербург

Отправлено 13 ноября 2014 - 20:07

Огромное спасибо за оптимизацию запросов при сохранении товара или категории при условии огромного кол-ва категорий. В разы ускорило процесс сохранения

#5 badisoft

    Продвинутый пользователь

  • VIP
  • 4 986 сообщений
Репутация: 761
Мастер

Отправлено 18 ноября 2014 - 13:46

Ошибка в исправлении ошибки :).
Функция
function GetPriceProductWithOption($variants, $productID)
при пустом массиве $variants (у товара нет вариантов характеристик) выполняла неверный запрос. На результат не влияет, но появляется запись в логе ошибок. Исправлено.
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#6 Revived

    Продвинутый пользователь

  • Assistent vsupport.ru
  • PipPipPip
  • 51 сообщений
Репутация: 0
Начинающий

Отправлено 19 ноября 2014 - 23:23

Спасибо, раньше долго удалялось и сохранялось

#7 FusSheva

    Продвинутый пользователь

  • Assistent vsupport.ru
  • PipPipPip
  • 204 сообщений
Репутация: 7
Начинающий

Отправлено 18 декабря 2014 - 15:52

Просмотр сообщенияbadisoft (09 ноября 2014 - 15:57) писал:

Дополнение резко сокращает количество SQL-запросов при сохранении настроек товаров и категорий.

Вы толковый специалист badisoft, не раз в этом убеждался.
Добавление картинок (что подразумевает каждый раз сохранение товара) теперь добавляются на ура быстро!
Браво, badisoft !!! Большое человеческое спасибо!
Каждый человек способен на многое. Но к сожалению, не каждый знает на что он способен.

#8 badisoft

    Продвинутый пользователь

  • VIP
  • 4 986 сообщений
Репутация: 761
Мастер

Отправлено 16 апреля 2015 - 23:03

Хех... Неисчерпаем ShopCMS на мелкие и не очень ошибки :).

При электронной торговле в детальном описании некорректно показывается размер файла.

В файле product_detailed.php есть такой код

$size = filesize("core/files/".$a["eproduct_filename"]);
if ($size > 1000) $size = round ($size / 1000);
$a["eproduct_filesize"] = $size." Kb";


Очевидно, что если размер файла меньше 1000 байт (например, 700байт), то он будет показан как 700Кб.
Лечение:

#$size = filesize("core/files/".$a["eproduct_filename"]);
#if ($size > 1000) $size = round ($size / 1000);
#$a["eproduct_filesize"] = $size." Kb";
$a["eproduct_filesize"] = ceil(filesize("core/files/".$a["eproduct_filename"])/1024.0).'кб';


При этом размер будет откругляться до килобайта в большую сторону, т.е. 300байт будет показано как 1кб, а 2049байт как 3кб.

Отдельно странно, что в ShopCMS в разных местах разный размер килобайта :).
Здесь он 1000 байт, а в функции _sendOrderNotifycationToCustomer(), отсылающей письмо клиенту уже 1024 байта, т.к. там размер файла для показа в мегабайтах делится на 1048576 (1024х1024).
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#9 badisoft

    Продвинутый пользователь

  • VIP
  • 4 986 сообщений
Репутация: 761
Мастер

Отправлено 03 августа 2015 - 20:48

Хех... Интересно, я помру раньше, чем ошибки кончатся? :)

Вне зависимости от установки галки "Разрешить покупателям оставлять мнения о товаре" прямая ссылка с тем самым "оставлять мнение о товаре" (site.ru/index.php?productID=XXX&discuss=yes) вполне работает. Со всеми вытекающими по части спама, хотя его никто кроме админа и не увидит. Лечение простое. В файле product_discussion.php в начале добавляем
# BEGIN устранение доступности формы обсуждения, если она запрещена
if (CONF_USE_DISCUSS)
{
# END устранение доступности формы обсуждения, если она запрещена

а в конце
# BEGIN устранение доступности формы обсуждения, если она запрещена
}
# END устранение доступности формы обсуждения, если она запрещена


http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#10 FusSheva

    Продвинутый пользователь

  • Assistent vsupport.ru
  • PipPipPip
  • 204 сообщений
Репутация: 7
Начинающий

Отправлено 03 августа 2015 - 22:16

Живите долго! Вы нам нужны! :)
Проверил, теперь при запрете выбрасывает на главную (без записи).
Каждый человек способен на многое. Но к сожалению, не каждый знает на что он способен.

#11 badisoft

    Продвинутый пользователь

  • VIP
  • 4 986 сообщений
Репутация: 761
Мастер

Отправлено 17 сентября 2015 - 13:25

Еще пара ошибок (они уже были описаны в других ветках).

=============================
Штатная ошибка: При импорте из CSV если в каталоге присутствует наименование взятое в кавычки "Товар" то импорт не обновляет данные товары а считает их как новыми, кавычки не распознает

Причина: Название товара перед сохранением в таблицу обрабатывается функцией htmlspecialchars, т.е., к примеру, про'вер"ка будет лежать в таблице как про&#039;вер&quot;ка, но при идентификации товара этого преобразования не делается, т.е. сравнение выглядит как name LIKE 'про\'вер"ка'. Естественно, названия не совпадают и товар заносится как новый.

Исправление:

В файле catalog_import_functions.php в функции _importProduct в строке


" LIKE '".xEscSQL(trim($row[$identity_column]))."'");



заменяем xEscSQL на ToText.

Таких строк там две, достаточно заменить в первой, но можно и в обоих (если в коде товара тоже могут быть кавычки).

============================

Хехе... В 3.1.3 не только старые ошибки не исправлены, но и новых добавлено. Я уже две нашел :).
Исправления:

1. файл product_detailed.tpl.html
Используется смарти-массив $popular_products вместо $product_related, в результате вместо фотки товара в "рекомендуемых" получаем фотку хрен знает чего :).

#<a href="{if $smarty.const.CONF_MOD_REWRITE eq 1}product_{$product_related[i].productID}.html{else}index.php?productID={$product_related[i].productID}{/if}"><img src="data/{$popular_products[i].filename}" alt="" class="thumbnail"></a>
<a href="{if $smarty.const.CONF_MOD_REWRITE eq 1}product_{$product_related[i].productID}.html{else}index.php?productID={$product_related[i].productID}{/if}"><img src="data/{$product_related[i].filename}" alt="" class="thumbnail"></a>

2. файл product_detailed.php
Ну, тут очевидно. Просто перепутан массив.

#$r["filename"] = "small/".$row["filename"];
$r["filename"] = "small/".$r["filename"];


============================
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#12 qwezi

    Новичок

  • Пользователи
  • Pip
  • 2 сообщений
Репутация: 0
Начинающий

Отправлено 18 сентября 2015 - 09:24

Добрый день. подскажите, пожалуйста, как исправить:
Если писать названия блоков, название сайта, кейвордс, название доставки и т.д. на Русском языке, после сохранения остается пустое поле.
Как это исправить?

#13 badisoft

    Продвинутый пользователь

  • VIP
  • 4 986 сообщений
Репутация: 761
Мастер

Отправлено 18 сентября 2015 - 10:06

Просмотр сообщенияqwezi сказал:

Как это исправить?
Поставить PHP версии 5.3 или ниже.

PS. На форуме есть "поиск". Проблема описана уже раз десять, если не больше. А эта тема совсем о другом - о ШТАТНЫХ ошибках.
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#14 badisoft

    Продвинутый пользователь

  • VIP
  • 4 986 сообщений
Репутация: 761
Мастер

Отправлено 22 сентября 2015 - 14:11

Написал импорт из CSV, которому наплевать на размер CSV, хоть гигабайт и стопицоттыщ товаров, т.к. импорт идет АЯКС-запросами по заданному количеству строк из CSV-файла. Но это так, вводная. Пока писал, нашел вопиющую ошибку при импорте характеристик. Характеристики идут последними столбцами. Перед ними столбцы с фотографиями. Так вот сколько столбцов с фотографиями - столько будет потеряно (не импортировано) последних столбцов характеристик.

Это один из вариантов массива $updated_extra_option, который передается в функцию _importExtraOptionValues. Столбцов с фотографиями в этом CSV-файле двадцать, а характеристик всего семь, так нагляднее.
array (
  0 => 0,
  1 => 0,
  2 => 0,
  3 => 0,
  4 => 0,
  5 => 0,
  6 => 0,
  7 => 0,
  8 => 0,
  9 => 0,
  10 => 0,
  11 => 0,
  12 => 0,
  13 => 0,
  14 => 0,
  15 => 0,
  16 => 0,
  17 => 0,
  18 => 0,
  19 => 0,
  20 => 0,
  21 => 0,
  22 => 0,
  23 => 0,
  24 => 0,
  38 => '75',
  39 => '76',
  40 => '77',
  41 => '78',
  42 => '79',
  43 => '80',
  44 => '81',
)
Элементы 38-44 это номера характеристик (optionID), а ключи - номера столбцов. Обращу внимание, что элементов 25-37 нет. Так уж написано в ShopCMS, что столбцы с фотографиями в этом массиве отсутствуют.
А это цикл обработки этого массива в той же функции:
for ($j=0; $j<count($updated_extra_option); $j++)
		{
				if (isset($updated_extra_option[$j]) && $updated_extra_option[$j]) //a column which is an extra option
...

Понятно, да? функция count честно показывает, что в массиве 32 элемента и цикл НИКОГДА не дойдет до элементов 38-44, т.е. до столбцов с характеристиками товара.

Решение:
# BEGIN исправляем ошибку импорта характеристик товара
/*
		for ($j=0; $j<count($updated_extra_option); $j++)
		{
				if (isset($updated_extra_option[$j]) && $updated_extra_option[$j]) //a column which is an extra option
				{
						$optionID = $updated_extra_option[$j];
*/
		foreach ($updated_extra_option as $j => $optionID)
		{
				if ($optionID) //a column which is an extra option
				{
# END исправляем ошибку импорта характеристик товара


PS. Кстати, кто поделится CSV-файлом на 100500тыщ каких-нибудь товаров (для проверки) - буду благодарен :).
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#15 badisoft

    Продвинутый пользователь

  • VIP
  • 4 986 сообщений
Репутация: 761
Мастер

Отправлено 30 сентября 2015 - 21:03

Покупателем нашлась еще одна ошибка. Если оплатить заказ (статус заказа изменится на "оплачен"), а потом перейти по ссылке из емейла "отменить заказ", то статус заказа изменится на отменен. И сколько раз перейти по ссылке, столько раз он будет отменен с соответствующим появлением записи в истории изменения статусов заказа.

Пока только констатирую ошибку, не изучал и не исправлял.
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#16 Jeck2000

    Продвинутый пользователь

  • Assistent vsupport.ru
  • PipPipPip
  • 157 сообщений
Репутация: 8
Начинающий
  • ГородСанкт-Петербург

Отправлено 11 октября 2015 - 13:55

Цитата

Штатная ошибка: При импорте из CSV варианты характеристик, содержащие символы '"&amp;lt;&amp;gt;&amp;amp; двоятся, т.е. создаются столько раз, сколько товаров с таким вариантом характеристики.

badisoft, такой вопрос, а нет ли там еще какого-нибудь глюка с импортом в плане присутствия символа "/" в названии? Пробую импортировать исправленный CSV файл (исправленный в смысле отредактированный под мои нужды), так вот то же, при импорте товары добавляются как новые. Исправление как у тебя написано сделал (замена на ToText), но это не повлияло на результат. Товары добавились как новые в главную, хотя имеют абсолютно идентичные названия

#17 badisoft

    Продвинутый пользователь

  • VIP
  • 4 986 сообщений
Репутация: 761
Мастер

Отправлено 22 октября 2015 - 18:39

та-да-да-дам! И почему я не удивлен? в общем, еще одна.

===================
Штатная ошибка.
В таблице товаров и в настройке категории при переносе товаров в другую категорию перенос осуществляется перезаписью categoryID в таблице товаров, т.е. меняется только основная категория, а доп.категории остаются неизменными.
В результате получаем следующую картину: товар показывается в списке товаров доп.категории, но при попытке переноса в другую остается не перенесенным, ведь информация о доп.категории при этом не меняется.

Исправление:

1. для таблицы товаров:
в файле catalog_products_categories.php
вместо

elseif ( $_POST["add_command"]=="prod_move"){db_query( "UPDATE ".PRODUCTS_TABLE." SET categoryID = ".(int)$_POST["prod_categoryID"]." WHERE productID=".(int)$key);}


вставляем

# BEGIN исправляем перенос из добавочной категории
#elseif ( $_POST["add_command"]=="prod_move"){db_query( "UPDATE ".PRODUCTS_TABLE." SET categoryID = ".(int)$_POST["prod_categoryID"]." WHERE productID=".(int)$key);}
elseif ( $_POST["add_command"]=="prod_move")
	{
	$prd = db_fetch_assoc(db_query("SELECT categoryID FROM ".PRODUCTS_TABLE." WHERE productID=".(int)$key." LIMIT 1"));
    if (isset($_GET['search']) || !isset($_GET['categoryID']) || $prd['categoryID']==(int)$_GET['categoryID']) // это основная категория товара (либо результат поиска, где категория у товаров разная)
	    db_query( "UPDATE ".PRODUCTS_TABLE." SET categoryID = ".(int)$_POST["prod_categoryID"]." WHERE productID=".(int)$key);
	else // это доп категория товара
		db_query( "UPDATE ".CATEGORIY_PRODUCT_TABLE." SET categoryID = ".(int)$_POST["prod_categoryID"]." WHERE categoryID=".(int)$_GET['categoryID']." AND productID=".(int)$key);
	}
# END исправляем перенос из добавочной категории



2. для редактирования категории (там есть пункт "Перенести все товары из этой категории в [...]"):
в файле admin.php
после

db_query("update ".PRODUCTS_TABLE." SET categoryID=".(int)$_POST["removeto"]." WHERE categoryID=".(int)$_POST["must_delete"]);


вставляем

# BEGIN исправляем перенос из добавочной категории
db_query("update ".CATEGORIY_PRODUCT_TABLE." SET categoryID=".(int)$_POST["removeto"]." WHERE categoryID=".(int)$_POST["must_delete"]);
# END исправляем перенос из добавочной категории


http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#18 badisoft

    Продвинутый пользователь

  • VIP
  • 4 986 сообщений
Репутация: 761
Мастер

Отправлено 28 октября 2015 - 14:57

Хм... Иногда очень хочется посмотреть на программиста, который писал ShopCMS. Сколько у него рук и откуда растут :).
Есть в order_amount_functions.php такая функция.
function oaGetClearPrice( $cartContent )
{
	    $res = 0;
	    for( $i=0; $i<count($cartContent["cart_content"]); $i++ )
	    {
			    $cartItem = $cartContent["cart_content"][$i];
			    $res += $cartItem["quantity"]*$cartItem["costUC"];
	    }
	    return $res;
}

Вроде, совершенно нормальная функция, правда?
Явно считает некую общую сумму.
Но есть нюанс.
Эта считаемая сумма (уже подсчитанная ранее, в функции GetCartContent) передается в эту функцию в этом же массиве данных - $cartContent["total_price"].
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#19 badisoft

    Продвинутый пользователь

  • VIP
  • 4 986 сообщений
Репутация: 761
Мастер

Отправлено 07 ноября 2015 - 21:10

Просмотр сообщенияbadisoft сказал:

Покупателем нашлась еще одна ошибка. Если оплатить заказ (статус заказа изменится на "оплачен"), а потом перейти по ссылке из емейла "отменить заказ", то статус заказа изменится на отменен. И сколько раз перейти по ссылке, столько раз он будет отменен с соответствующим появлением записи в истории изменения статусов заказа. Пока только констатирую ошибку, не изучал и не исправлял.
Штатная ошибка.
Заказу со статусом доставлено, т.е. по сути закрытому заказу клиент может сменить статус на "Отменен" если уже после оплаты кликнет по ссылке в полученном емейле "отменить заказ".
Вроде и незачем ему кликать, заказ оплатил, товар получил, но вот уже два раза :).

Исправление:

в файле order_functions.php в функции deactivate_order

вместо

$q = db_query("select orderID FROM ".ORDERS_TABLE." WHERE custlink='".xEscSQL($actlink)."' ");
if($pql = db_fetch_row($q)){


вставляем

# BEGIN не даем отменить уже оплаченный заказ
#$q = db_query("select orderID FROM ".ORDERS_TABLE." WHERE custlink='".xEscSQL($actlink)."' ");
#if($pql = db_fetch_row($q)){
$q = db_query("select orderID,statusID FROM ".ORDERS_TABLE." WHERE custlink='".xEscSQL($actlink)."' ");
if($pql = db_fetch_row($q) && $pql["statusID"] != ostGetCompletedOrderStatus()){
# END не даем отменить уже оплаченный заказ


http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#20 badisoft

    Продвинутый пользователь

  • VIP
  • 4 986 сообщений
Репутация: 761
Мастер

Отправлено 08 декабря 2015 - 21:10

Очередная обалденная штатная ошибка, которая не понятно почему до сих пор никем не была замечена.
В user.js есть JS-функция _formatPrice, она форматирует цену товара исходя из заданного округления валюты.
Эта функция выводит цену товара как минимум в категории и подробном описании.
Округление валюты в админке мы можем задать как угодно. Положительным числом (сколько знаков ПОСЛЕ запятой) или отрицательным числом (сколько знаков ПЕРЕД запятой). Скажем, при заданном округлении "-1" цена "127.16" должна округлиться до "130". Но эта функция берет округление ПО МОДУЛЮ! Без учета знака! Т.е. "-1" ничем не отличается от "1" и "127.16" будет округлено до "127.2". Что и было замечено одним из клиентов.

Исправление:
function _formatPrice( number, decimals, dec_point, thousands_sep ) {
// BEGIN исправление ошибки при "отрицательном" округлении в настройке валют
	var c = Math.pow(10,decimals);
	var s = Math.round(number*c)/c;
	s = s.toString();
	var d = (s.split("."))[1];
	s = (s.split("."))[0];
	var t = '';
	thousands_sep = (typeof thousands_sep == "undefined")?' ':thousands_sep;
	dec_point = (typeof dec_point == "undefined")?'.':dec_point;
	for (var i=s.length-1;i>=0;i--)
		{
		t = s.charAt(i)+t;
		if ((s.length-i)%3==0 && i>0) t = thousands_sep+t;
		}
	s = t + ((typeof d == "undefined")?'':(dec_point+d));
/*	
	var n = number, prec = decimals;
	n = !isFinite(+n) ? 0 : +n;
	prec = !isFinite(+prec) ? 0 : Math.abs(prec);
	var sep = (typeof thousands_sep == "undefined") ? ' ' : thousands_sep;
	var dec = (typeof dec_point == "undefined") ? '.' : dec_point;

	var s = (prec > 0) ? n.toFixed(prec) : Math.round(n).toFixed(prec);

	var abs = Math.abs(n).toFixed(prec);
	var _, i;

	if (abs >= 1000) {
		_ = abs.split(/\D/);
		i = _[0].length % 3 || 3;

		_[0] = s.slice(0,i + (n < 0)) +
			  _[0].slice(i).replace(/(\d{3})/g, sep+'$1');

		s = _.join(dec);
	} else {
		s = s.replace('.', dec);
	}
*/
// END исправление ошибки при "отрицательном" округлении в настройке валют
	return s;
}

PS. Я, честно говоря, офигеваю. Это не ошибка и не опечатка, это специально так написано. Занахера?
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)