Вообще это прекрасно, что было готовое решение, но не забывайте об эксцентричности вм...
Так как я воспользовался вашим решением, припишу кой чего своего.
Откройте файлик
shop.browse.php и найдите строку
while ($db_browse->next_record())
А теперь внимательно проследуем вниз...
$ps_product->show_price($db_browse->f("product_id")) - 4 запроса;
$ps_product->get_adjusted_attribute_price($db_browse->f('product_id')) - 2 запроса;
ps_product_files::getFilesForProduct($db_browse->f('product_id')) - 6 запросов;
ps_reviews::allvotes($db_browse->f("product_id")) - 1 запрос;
product_has_attributes($db_browse->f('product_id'), true) - 2 запроса
Итого вывод одного товара стоит 15 запросов... Руки за такое отрывать надо, а если по категориям файлов накопиться ну хотяб штук 200 - 200*15+39(системных) = 3039 запросов...
На локальном компьютере листинг 464 товаров занимал 11.5 секнд на 250 атлоне с 64 битным ПО... Понятно куда вас пошлют все хостеры с такими запросами...
Те, кто не использует моженые рейтинги товаров и не смотрят больше 50 товаров (хотя это 750 лишних запросов) или кому фиолетово ЗАРАНЕЕ ПРОШУ не читать и засунуть своё "мнение" поглубже.Так вот, на чём можно сэкономить.
show_price и get_adjusted_attribute_priceЯ аж удивился, но в запроснике (shop_browse_queries.php) даже уже был готовый JOIN, но ничего от туда не выбиралось. Так как цены у меня все были в рублях и о другом я даж и не думал (но при желании можно использовать класс вроде VMCURRENCY), то на этом я решил сэкономить. То есть добавляем
в основной SELECT shop_browse_queries.php
в районе $fieldnames = ...
`product_price_id`,`is_percent`,`amount`,`product_price`
и в районе $join_array = ...
'LEFT JOIN `#__{vm}_product_discount` ON `#__{vm}_product`.`product_discount_id` <> 0 AND `#__{vm}_product`.`product_discount_id` = `#__{vm}_product_discount`.`discount_id`'
(то есть доказываем, что ksort ниже (по причине его коммента) и лишние 4 запроса к базе нам не нужны.
в shop.browse.php комментим строку в районе $product_price = ...
и вставляем ниже
if ($db_browse->f("amount")) :
$product_price = '<span class="product-Old-Price"> '.$db_browse->f("product_price").' р.</span><span class="productPrice"> ';
$product_price_disc_val = $db_browse->f("is_percent") == 1 ? number_format ($db_browse->f("product_price") - ($db_browse->f("product_price") * $db_browse->f("amount") / 100), 0, '', ' ') : $db_browse->f("product_price") - $db_browse->f("amount");
$product_price .= $product_price_disc_val.' р. </span>';
else :
$product_price = '<span class="productPrice">'.$db_browse->f("product_price").' р.</span>';
endif;
теперь зачем-то очень нужный $product_price_raw = ... комментим тоже и ниже него вставляем
$product_price_disc_val_arr = $product_price_disc_val ? $product_price_disc_val : $db_browse->f("product_price");
$product_price_val_arr = $db_browse->f("product_price");
$product_price_id_arr = $db_browse->f("product_price_id");
$product_price_raw = Array (
'product_price' => "$product_price_disc_val_arr",
'product_currency' => RUB,
'product_base_price' => "$product_price_val_arr",
'product_has_multiple_prices' => '',
'product_price_id' => "$product_price_id_arr",
'item' => 1
);
Таким образом, без потери качества мы уже сэкономили 6 лишних запросов.
allvotesХоть один, но лишний запрос. К тому же убрать его просто элементарно.
в основной SELECT shop_browse_queries.php
в районе $fieldnames = ... дописываем поля
`votes`,`allvotes`,`rating`
и в районе $join_array = ... добавляем
'LEFT JOIN `#__{vm}_product_votes` ON `#__{vm}_product`.`product_id` = `#__{vm}_product_votes`.`product_id`'
теперь идём обратно в shop.browse.php комментим строку в районе $product_rating = ... и вставляем туда
$product_rating = allvotesx($db_browse->f("votes"), $db_browse->f("allvotes"), $db_browse->f("rating"), $db_browse->f("product_id"));
и в самом низу перед ?> вставляем нашу функцию:
function allvotesx ($votes, $allvotes, $rating, $product_id) {
$tpl = new $GLOBALS['VM_THEMECLASS']();
$allvotes = $allvotes ? $allvotes : 0;
$rating = $rating ? $rating : 0;
$tpl->set('allvotes', $allvotes );
$tpl->set('rating', $rating );
$tpl->set('product_id', $product_id );
return $tpl->fetch( 'common/votes_allvotes.tpl.php' );
}
На этом мы сэкономили уже 7 запросов... Честно говоря, getFilesForProduct и product_has_attributes были просто закомментены, по причине что getFilesForProduct - я вообще смутно представляю для чего оно, ибо даже в админке не видел где его можно натыкать, а product_has_attributes наверное кроме демо VirtueMart не использует никто... к тому же атрибуты можно получить из основного селекта путём добавления нужного поля (и это поле есть в таблице товаров и вывести чем-то подобным (смотреть ниже), но повторюсь - мне оно было не надо. Всё спасибо за внимание, и поменьше левых запросов к вашим базам данных
if ($special->attribute) :
$specials_data .= '<div class="attributes">';
$attr_arr = explode (';', $special->attribute);
foreach ($attr_arr as $attr) :
preg_match ('/^([^\,]+)\,(.*)$/', $attr, $matches);
$specials_data .= '<div class="special">'.$matches[1].': <select name="'.$matches[1].''.$special->product_id.'">';
$options_tag = explode (',', $matches[2]);
foreach ($options_tag as $option_tag) :
preg_match ('/^([^\[]+)\[?([^\]]+)?\]?$/', $option_tag, $matches);
$specials_data .= '<option value="'.$matches[1].'">'.$matches[1];
$specials_data .= $matches[2] ? ' ('.$matches[2].' руб.)' : '';
$specials_data .= '</option>';
endforeach;
$specials_data .= '</select></div>';
endforeach;
$specials_data .= '</div>';
endif;
Ещё есть один подлый момент в addtocart_form.tpl.php в виде $ps_product_attribute->show_quantity_box, он не стесняясь тоже плодит 1 запрос к базе. Надо немного поправить функцию, собственно ничего сложного.