Во-первых: это придумал не я, я просто аккуратно записал как я ставил этот хак. Первоисточник находится на Жумлафоруме, вот в этой теме. Сам я разбираюсь слабо, так что вопросы лучше задавать там. Есть известный баг: галочки показывает только если не выбирать категорию в фильтре, при этом все работает, просто не видно.
Да, все это делалось на Жумле 1.5.26 и ВМ 1.1.9
- 1.1. База данных myPhpAdmin
- 1.2. База Данных Webmin
- 2. Вывод в админке
- 3. Связь админки с базой
- 4. Форма ввода нового товара
- 5. Связь магазина с базой
- 6. Вывод ярлычков
- 7. Вывод во Fly Page
- 8. Файлы
Теперь что мы хотим получить, два скриншота, с админки и с магазина:
Теперь как мы это будем делать, работу можно условно разделить на три этапа: изменения в базе данных, вывод в админку и вывод в магазине. Прежде чем начать напоминаю, что пробовать это стоит только на копии и даже если все получится на копии, то сначала сделать полный бэкап рабочего сайта, а то будет больно и обидно. Если будет - я не виноват!
В базе нужно изменять руками, тут нет вариантов, а вот файлы можно взять в архиве, запаковано с полными путями. В моих файлах в голове вставлены комментарии, в которых указаны номера измененных строк, а так же комментарии вставлены непосредственно перед изменениями. В случае аварии можно воспользоваться архивом для отката - там файлы без изменений, но будьте внимательны с версией и установленными у Вас хаками. Архивы искать внизу, в самом конце. И хорошо бы прочитать от начала до конца все, хотя бы один раз, что бы понять что и откуда растет.
1. Изменения в базе данных.
Изменений в базе безопасно и не затрагивает работу Жумлы и ВМ, просто добавляются новые поля, которые никак не мешают работе. Это самая безопасная часть хака, если только не наколбасить. Тут два варианта, самых частых - с помощью phpMyAdmin или WebMin. Кому что подходит - у меня других нет.
1.1. Изменения в базе данных - phpMyAdmin.
1.1.1. Открываем phpMyAdmin выбираем базу данных магазина и находим таблицу jos_vm_function добавляем в нее две функции. Выбираем вкладку "Вставить", заполняем и нажимаем ОК.
Вот данные которые нужно забить:
Поле | Значение для первой функции | Значение для второй функции | ||
function_id | 195 | 196 | ||
module_id | 2 | 2 | ||
function_name | changeNewState | changeLeaderState | ||
function_class | ps_product | ps_product | ||
function_method | change_new_state | change_leader_state | ||
function_description | ваше объяснение, для удобства | ваше объяснение, для удобства | ||
function_perms | storeadmin,admin | storeadmin,admin |
В результате мы должны получить вот такую картину, если выберем вкладку "Обзор":
1.1.2. Теперь добавим в таблицу jos_vm_product еще два поля. Находим таблицу jos_vm_product. Заходим в нее, выбираем вкладку "Структура". Крутим вниз и находим "Добавить 1 поле(поля)" и в конце этой строки ОК, ничего не меняем, просто нажимаем.
В открывшемся окне первым делом снова жмем ОК, что бы разрешить сохранение двух полей сразу, затем их заполняем и жмем Сохранить.
Табличка, что бы можно было копи-пейст делать.
Значение | Значение | |||
Поле | product_is_new | product_is_leader | ||
Тип | VARCHAR | VARCHAR | ||
Длина | 64 | 64 | ||
Сравнение | utf8_general_ci | utf8_general_ci | ||
Атрибуты | НЕ ИЗМЕНЯЕМ | НЕ ИЗМЕНЯЕМ | ||
Ноль | null | null | ||
По умолчанию | NULL | NULL | ||
Все, что ниже - не трогаем. |
После сохранения мы можем увидеть, что к нашей таблице, в самом конце, добавились два новых поля, т.е. у нас все получилось и можно закрывать phpMyAdmin, он нам больше не нужен.
1.2. Изменения в базе данных - WebMin.
1.2.1. Открываем WebMin, выбираем Servers-MySQL Database Server. Открываем базу данных. В выпадающем меню выбираем таблицу jos_vm_function.
На открывшейся странице нажимаем "View Data".
Теперь нажимаем "Add Row".
Наконец вбиваем наши данные функции и нажимаем "Save". Повторяем шаги для второй функции.
Вот для удобства табличка с данными:
Field name | Data | Data |
function_id | 195 | 196 |
module-id | 2 | 2 |
function_name | changeNewState | changeLeaderState |
function_class | ps_product | ps_product |
function_description | ||
function_perms | storeadmin,admin | storeadmin,admin |
В результате у нас добавится две строки с функциями, переходим к следующему этапу.
1.2.2. Добавляем в таблицу jos_vm_product еще два поля. Возвращаемся к выбору таблиц и выбираем jos_vm_product.
На открывшейся странице выбираем в выпадающем списке varchar и нажимаем Add field of type.
Заполняем и нажимаем "Create".
Повторяем операцию для поля product_is_new. Все делаем так же, только в поле Field name забиваем product_is_new. В результате получим два новых поля в таблице.
Все, телодвижения с базой данных закончены.
2. Выводим в админке.
Изменяем файлы, дальше везде изменения красным. Делаем аккуратно, не торопимся. Свои файлы лучше сохранить, что бы в случае неприятностей можно было без проблем откатиться назад.
2.1. /administrator/components/com_virtuemart/html/product.product_list.php
Строка 247:
// these are the columns in the table
$columns = Array( '#' => '',
"<input type=\"checkbox\" name=\"toggle\" value=\"\" onclick=\"checkAll(".$num_rows.")\" />" => "",
$VM_LANG->_('PHPSHOP_PRODUCT_LIST_NAME') => "width=\"30%\"",
$VM_LANG->_('VM_PRODUCT_LIST_MEDIA') => 'width="5%"',
$VM_LANG->_('PHPSHOP_PRODUCT_LIST_SKU') => "width=\"15%\"",
$VM_LANG->_('PHPSHOP_PRODUCT_FORM_NEW_PRODUCT') => "width=\"15%\"",
$VM_LANG->_('PHPSHOP_PRODUCT_FORM_IS_LEADER') => "width=\"15%\"",
$VM_LANG->_('PHPSHOP_PRODUCT_PRICE_TITLE') => "width=\"10%\"",$VM_LANG->_('PHPSHOP_CATEGORY') => "width=\"15%\"" );
Строка 330:
//The product sku
$listObj->addCell( $db->f("product_sku") );
//Выводит колонку Новый
$tmpcell="<a href=\"". $sess->url($_SERVER['PHP_SELF']."?page=product.product_list&category_id=$category_id&product_id=
".$db->f("product_id")."&func=changeNewState");
if (!$db->f("product_is_new")) {$tmpcell .= "&task=is_new\">";}
else {$tmpcell .= "&task=isnt_new\">";}
$tmpcell .= vmCommonHTML::getYesNoIcon( $db->f("product_is_new"), "Новый", "Не новый" );
$tmpcell .= "</a>";
$listObj->addCell( $tmpcell );
//Выводит колонку Лидер
$tmpcell="<a href=\"". $sess->url($_SERVER['PHP_SELF']."?page=product.product_list&category_id=$category_id&product_id=
".$db->f("product_id")."&func=changeLeaderState");
if (!$db->f("product_is_leader")) {$tmpcell .= "&task=is_leader\">";}
else {$tmpcell .= "&task=isnt_leader\">";}
$tmpcell .= vmCommonHTML::getYesNoIcon( $db->f("product_is_leader"), "Лидер продаж", "Не лидер продаж" );
$tmpcell .= "</a>";
$listObj->addCell( $tmpcell );
Сохраняем, закрываем.
2.2. /administrator/components/com_virtuemart/languages/product/russian.php вставляем в любое место
'PHPSHOP_PRODUCT_FORM_NEW_PRODUCT' => 'Новинка?',
'PHPSHOP_PRODUCT_FORM_IS_LEADER' => 'Лидер продаж?',
Если в админке используется не русский, а другой язык, то вставляем в файл этого языка два новых заголовка для шапки в админке. Теперь, если мы пойдем в админку, то увидим готовый результат, но переключатели еще не работают. Сделаем это следующим шагом.
3. Связываем админку с базой.
3.1. /administrator/components/com_virtuemart/classes/ps_product.php в самом начале файла, строка 25:
class vm_ps_product extends vmAbstractObject {
var $_key = 'product_id';
var $_table_name = '#__{vm}_product';
/**********Вставлен блок с двумя функциями для ярлыков***************************************/
function change_new_state() {
$task = vmGet($_REQUEST, 'task', '');
$product_id = vmGet($_REQUEST, 'product_id', '');
$db = new ps_DB;
if ($task == 'is_new') {
$db->query("UPDATE #__{vm}_product SET product_is_new = 1 WHERE product_id=".$product_id);
}
else {
$db->query("UPDATE #__{vm}_product SET product_is_new = 0 WHERE product_id=".$product_id);
}
}
function change_leader_state() {
$task = vmGet($_REQUEST, 'task', '');
$product_id = vmGet($_REQUEST, 'product_id', '');
$db = new ps_DB;
if ($task == 'is_leader') {
$db->query("UPDATE #__{vm}_product SET product_is_leader = 1 WHERE product_id=".$product_id);
}
else {
$db->query("UPDATE #__{vm}_product SET product_is_leader = 0 WHERE product_id=".$product_id);
}
}
/****************Конец вставки*************************************************************/
Строка 336:
// Insert into DB
/************ Вставлены строки 369 и 370 ***************************************************/
$fields = array ( 'vendor_id' => $vendor_id,
'product_parent_id' => vmRequest::getInt('product_parent_id'),
'product_sku' => vmGet($d,'product_sku'),
'product_name' => vmGet($d,'product_name'),
'product_desc' => vmRequest::getVar('product_desc', '', 'default', '', VMREQUEST_ALLOWHTML),
'product_s_desc' => vmRequest::getVar('product_s_desc', '', 'default', '', VMREQUEST_ALLOWHTML),
'product_thumb_image' => vmGet($d,'product_thumb_image'),
'product_full_image' => vmGet($d,'product_full_image'),
'product_publish' => $d['product_publish'],
'product_weight' => vmRequest::getFloat('product_weight'),
'product_weight_uom' => vmGet($d,'product_weight_uom'),
'product_length' => vmRequest::getFloat('product_length'),
'product_width' => vmRequest::getFloat('product_width'),
'product_height' => vmRequest::getFloat('product_height'),
'product_lwh_uom' => vmGet($d,'product_lwh_uom'),
'product_unit' => vmGet($d,'product_unit'),
'product_packaging' => (($d["product_box"] << 16) | ($d["product_packaging"]&0xFFFF)),
'product_url' => vmGet($d,'product_url'),
'product_in_stock' => vmRequest::getInt('product_in_stock'),
'attribute' => ps_product_attribute::formatAttributeX(),
'custom_attribute' => vmGet($d,'product_custom_attribute'),
'product_available_date' => $d['product_available_date_timestamp'],
'product_availability' => vmGet($d,'product_availability'),
'product_special' => $d['product_special'],
'child_options' => $d['child_options'],
'quantity_options' => $d['quantity_options'],
'product_discount_id' => vmRequest::getInt('product_discount_id'),
'cdate' => $timestamp,
'mdate' => $timestamp,
'product_tax_id' => vmRequest::getInt('product_tax_id'),
'child_option_ids' => vmGet($d,'included_product_id'),
'product_is_new' => $d['product_is_new'],
'product_is_leader' => $d['product_is_leader'],
'product_order_levels' => $d['order_levels'] );
Строка 541:
// Insert into DB
//****************************************Вставлены строки 572 и 573********************************************/
$fields = array ( 'vendor_id' => $vendor_id,
'product_sku' => vmGet($d,'product_sku'),
'product_name' => vmGet($d,'product_name'),
'product_desc' => vmRequest::getVar('product_desc', '', 'default', '', VMREQUEST_ALLOWHTML),
'product_s_desc' => vmRequest::getVar('product_s_desc', '', 'default', '', VMREQUEST_ALLOWHTML),
'product_thumb_image' => vmGet($d,'product_thumb_image'),
'product_full_image' => vmGet($d,'product_full_image'),
'product_publish' => $d['product_publish'],
'product_weight' => vmRequest::getFloat('product_weight'),
'product_weight_uom' => vmGet($d,'product_weight_uom'),
'product_length' => vmRequest::getFloat('product_length'),
'product_width' => vmRequest::getFloat('product_width'),
'product_height' => vmRequest::getFloat('product_height'),
'product_lwh_uom' => vmGet($d,'product_lwh_uom'),
'product_unit' => vmGet($d,'product_unit'),
'product_packaging' => (($d["product_box"] << 16) | ($d["product_packaging"]&0xFFFF)),
'product_url' => vmGet($d,'product_url'),
'product_in_stock' => vmRequest::getInt('product_in_stock'),
'attribute' => ps_product_attribute::formatAttributeX(),
'custom_attribute' => vmGet($d,'product_custom_attribute'),
'product_available_date' => $d['product_available_date_timestamp'],
'product_availability' => vmGet($d,'product_availability'),
'product_special' => $d['product_special'],
'child_options' => $d['child_options'],
'quantity_options' => $d['quantity_options'],
'product_discount_id' => vmRequest::getInt('product_discount_id'),
'mdate' => $timestamp,
'product_tax_id' => vmRequest::getInt('product_tax_id'),
'child_option_ids' => vmGet($d,'included_product_id'),
'product_is_new' => $d['product_is_new'],
'product_is_leader' => $d['product_is_leader'],
'product_order_levels' => $d['order_levels'] );
Сохраняем, закрываем. Можно пойти в админку и потыркать, в админке уже все работает и, если пойти в базу руками, то там то же меняется содержимое наших новых полей.
4. Ставим в форме ввода нового товара два чекбокса.
Админка почти работает, теперь прикручиваем к форме ввода нового товара два новых чекбокса, если вводим товар вручную, то можно сразу отметить "Лидера" и "Новинку". Для меня фича абсолютно бесполезная, я ввожу таблицами, но кому то, может быть, пригодится.
Правим файл /administrator/components/com_virtuemart/html/product.product_form.php строка 218:
<table class="adminform">
<tr>
<td valign="top">
<table width="100%" border="0">
<tr>
<td align="left" colspan="2"><?php echo "<h2 >$info_label</h2>"; ?></td>
</tr>
<tr class="row0">
<td width="21%" ><div style="text-align:right;font-weight:bold;">
<?php echo $VM_LANG->_('PHPSHOP_PRODUCT_FORM_PUBLISH') ?>:</div>
</td>
<td width="79%" > <?php
if ($db->sf("product_publish")=="Y") {
echo "<input type=\"checkbox\" name=\"product_publish\" value=\"Y\" checked=\"checked\" />";
}
else {
echo "<input type=\"checkbox\" name=\"product_publish\" value=\"Y\" />";
}
?></td>
</tr>
<?//****************** Вставлено для Ярлычков ***************************************************************/?>
<tr class="row0">
<td width="21%" ><div style="text-align:right;font-weight:bold;">
<?php echo $VM_LANG->_('PHPSHOP_PRODUCT_FORM_NEW_PRODUCT') ?>:</div>
</td>
<td width="79%" > <?php
if ($db->sf("product_is_new")=="1") {
echo "<input type=\"checkbox\" name=\"product_is_new\" value=\"1\" checked=\"checked\" />";
}
else {
echo "<input type=\"checkbox\" name=\"product_is_new\" value=\"1\" />";
}
?></td>
</tr>
<tr class="row0">
<td width="21%" ><div style="text-align:right;font-weight:bold;">
<?php echo $VM_LANG->_('PHPSHOP_PRODUCT_FORM_IS_LEADER') ?>:</div>
</td>
<td width="79%" > <?php
if ($db->sf("product_is_leader")=="1") {
echo "<input type=\"checkbox\" name=\"product_is_leader\" value=\"1\" checked=\"checked\" />";
}
else {
echo "<input type=\"checkbox\" name=\"product_is_leader\" value=\"1\" />";
}
?></td>
</tr>
<?//******************* Конец вставки ***********************************************************************/?>
<tr class="row1">
5. Связываем магазин с базой.
5.1. Правим файл /administrator/components/com_virtuemart/html/shop_browse_queries.php - нужно вставить выделенное.
// These are the names of all fields we fetch data from
$fieldnames = "`#__{vm}_product`.`product_id`, `product_name`, `products_per_row`, `category_browsepage`,
`category_flypage`, `#__{vm}_category`.`category_id`, `product_full_image`, `product_is_new`, `product_is_leader`,
`product_thumb_image`, `product_s_desc`, `product_parent_id`, `product_publish`, `product_in_stock`, `product_sku`,
`product_url`, `product_weight`, `product_weight_uom`, `product_length`, `product_width`, `product_height`,
`product_lwh_uom`, `product_available_date`, `product_availability`, `#__{vm}_product`.`mdate`, `#__{vm}_product`.
`cdate`";
$count_name = "COUNT(DISTINCT `#__{vm}_product`.`product_sku`) as num_rows";
$table_names = '`#__{vm}_product`, `#__{vm}_category`, `#__{vm}_product_category_xref`,`#__{vm}_shopper_group`';
$join_array = array( 'LEFT JOIN `#__{vm}_product_price` ON `#__{vm}_product`.`product_id` = `#__{vm}_product_price`.
`product_id`' );
$where_clause = array();
5.2. Теперь даем магазину узнать про ярлычки. Правим /administrator/components/com_virtuemart/html/shop.browse.php строка 416:
$product_details = $VM_LANG->_('PHPSHOP_FLYPAGE_LBL');
if (PSHOP_ALLOW_REVIEWS == '1' && @$_REQUEST['output'] != "pdf") {
// Average customer rating: xxxxx
// Total votes: x
$product_rating = ps_reviews::allvotes( $db_browse->f("product_id") );
}
else {
$product_rating = "";
}
/******************* Вставлено для Ярлычков ************************/
if ($db_browse->f("product_is_new")) {$new_img = "<img src='".IMAGEURL."ps_image/ico_new.png'>";}
else {$new_img = "";}
if ($db_browse->f("product_is_leader")) {$leader_img = "<img src='".IMAGEURL."ps_image/ico_leader.png'>";}
else {$leader_img = "";}
/******************* Конец вставки **********************************/
// Add-to-Cart Button
if (USE_AS_CATALOGUE != '1' && $product_price != ""
&& $tpl->get_cfg( 'showAddtocartButtonOnProductList' )
&& !stristr( $product_price, $VM_LANG->_('PHPSHOP_PRODUCT_CALL') )
И строка 447:
// Unset these for the next product
unset($full_image_width);
unset($full_image_height);
/*************************** Вставлено для Ярлычков *****************/
$products[$i]['new_img'] = $new_img;
$products[$i]['leader_img'] = $leader_img;
/*************************** Конец вставки *************************/
$products[$i]['product_name'] = shopMakeHtmlSafe( $product_name );
$products[$i]['product_s_desc'] = $product_s_desc;
$products[$i]['product_details'] = $product_details;
Сохраняем, закрываем.
6. Выводим ярлычки.
6.1. Первым делом положим сами картинки ярлычков на сайт, у меня они сложены по адресу /components/com_virtuemart/shop_image/ps_image/ Архив с картинками так же смотрите внизу страницы.
6.2. И последнее, выводим сами ярлычки. Правим файл components/com_virtuemart/themes/default/templates/browse/includes/browse_layouttable.tpl.php фрагмент искать в строке 31, вставлять в строку 47:
foreach( $products as $product ) {
foreach( $product as $attr => $val ) {
// Using this we make all the variables available in the template
// translated example: $this->set( 'product_name', $product_name );
$this->set( $attr, $val );
}
$data[$row][] = '<a href="'.$product['product_flypage'].'" title="'.$product['product_name'].'">'.$product['product_name'].'</a>';
$data[$row][] = $product['product_sku'];
if( _SHOW_PRICES && $auth['show_prices'] ) {
$data[$row][] = $product['product_price'];
}
$data[$row][] = '<a href="'.$product['product_flypage'].'" title="'.$product['product_name'].'">'
. ps_product::image_tag( $product['product_thumb_image'] )
. '</a>';
/********************************************** Эта строка вставлена для Ярлычков ***********************************/
$img_cell .= "<div style='position: absolute; right: 0px; top: 0;'>".$product['new_img']."</div><div style='position:
absolute; right: 0px; bottom: 0;'>".$product['leader_img']."</div></div>";
$data[$row][] = $product['product_s_desc'];
if( $product['has_addtocart'] ) {
$data[$row][] = $product['form_addtocart'];
}
6.3. Теперь выводим ярлычки в категории. Если предыдущими файлами было все понятно, они у всех одинаковы или очень похожи, то тут могут возникнуть некоторые сложности: шаблоны вывода могут быть разными и вставлять нужно именно в тот шаблон, который выводит. Сначала идем в настройки ВМ, на закладку "Сайт" и смотрим какой у нас шаблон категории. Выбираем файл этого шаблона и лезем в него. У меня выводит файл /components/com_virtuemart/themes/default/templates/browse/browse_lite_pdf. Все файлы вывода категории лежат по одному пути, нужно выбрать правильный и вставить в него код сразу следом за выводом картинки товара. Поэксперементируйте с местом вставки, нужно ли, что бы ярлычек был ссылкой или нет, как его ставить сверху всего или под надписи, тут я никаких советов дать не могу. Но ничего сложного. Для примера мой файл, который обкусан до полной неузнаваемости, но идея, я надеюсь, будет понятна.
<?php if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' );
mm_showMyFileName(__FILE__);
?>
<table width="100%">
<tr><td><br><br><br></td><td></td><td></td><td></td></tr>
<tr>
<td style="width: 50px;"></td>
<td style="width: 200px;">
<a href="/<?php echo $product_flypage ?>"><?php echo ps_product::image_tag( urldecode($product_thumb_image),
'class="browseProductImage" border="0" title="'.$product_details.'" alt="'.$product_name.'"' ) ?>
</td>
<td style="width: 20px;"></td>
<td>
<a title= "<?php echo $product_details?>" href="/<?php echo $product_flypage ?>">
<div id="cat_newprod"><?php echo $new_img; ?></div>
<div id="cat_leader"><?php echo $leader_img; ?></div>
<h1><?php echo $product_name ?></h1><br>
<h5><?php echo $product_price ?><h5>
</a>
</td>
</tr>
<tr>
<td></td>
<td colspan="3">
<br><strong><?php echo $product_s_desc ?></strong>
</td>
</tr>
</table>
6.4. Можно уже попробовать и увидеть, что ярлычки вывелись абы как, что бы установить их в нужное место вставляем в файл /var/www/mar/components/com_virtuemart/themes/default свои стили. Я вставил вот такое в конец файла:
#cat_leader{
position:relative;
top: 160px;
left: -90px;
}
#cat_newprod{
position:relative;
top: 160px;
left: -90px;
}
7. Выводим во Fly Page.
Я этого не делал, просто копи-пейст. Соответственно в моих файлах этих изменений нет! Редактируемфайл /administrator/components/com_virtuemart/html/shop.product_details.php строка у меня 311
// Change Packaging - End
// PRODUCT IMAGE
$product_full_image = $product_parent_id!=0 && !$db_product->f("product_full_image") ?
$dbp->f("product_full_image") : $db_product->f("product_full_image"); // Change
/************************ Вставка для Ярлычков ******************************************/
if( $db_product->f("product_is_new")== "1" )
{
$new_img_fly = '<div id="newprod"><img src="'. $mosConfig_live_site .'/components/com_virtuemart/shop_image/ps_image/ico_new.png"
border="0" alt="Новинка" title="Новинка"></div>';
}
else {
$new_img_fly = "";
}
if( $db_product->f("product_is_leader") == "1" )
{
$leader_img_fly = '<div id="leader"><img src="'. $mosConfig_live_site .'/components/com_virtuemart/shop_image/ps_image/ico_leader.png"
border="0" alt="Лидер продаж" title="Лидер продаж"></div>';
}
else {
$leader_img_fly = "";
}
/************************Конец*********************************************************/
$product_thumb_image = $product_parent_id!=0 && !$db_product->f("product_thumb_image") ?
$dbp->f("product_thumb_image") : $db_product->f("product_thumb_image"); // Change
/* MORE IMAGES ??? */
$files = ps_product_files::getFilesForProduct( $product_id );
И в строке 460:
$tpl->set( "related_products", $related_products );
$tpl->set( "vendor_link", $vendor_link );
$tpl->set( "product_type", $product_type ); // Changed Product Type
$tpl->set( "product_packaging", $product_packaging ); // Changed Packaging
$tpl->set( "ask_seller_href", $ask_seller_href ); // Product Enquiry!
$tpl->set( "ask_seller_text", $ask_seller_text ); // Product Enquiry!
$tpl->set( "ask_seller", $ask_seller ); // Product Enquiry!
$tpl->set( "recent_products", $recent_products); // Recent products
$tpl->set( "new_img_fly", $new_img_fly); // Новинка!
$tpl->set( "leader_img_fly", $leader_img_fly); // Лидер продаж
Ищем по адресу components\com_virtuemart\themes\default_my\templates\product_details\ файл который выводит у Вас, к примеру flypage.tpl.php и добавляем в него:
<?php if( $this->get_cfg('showManufacturerLink') ) { $rowspan = 5; } else { $rowspan = 4; } ?>
<td width="33%" rowspan="<?php echo $rowspan; ?>" valign="top">
<?php echo $new_img_fly ?>
<?php echo $leader_img_fly ?>
<br/>
<?php echo urldecode( $product_image )?><br/><br/><?php echo $this->vmlistAdditionalImages( $product_id, $images )?></td>
<td rowspan="1" colspan="2">
<h1><?php echo $product_name ?> <?php echo $edit_link ?></h1>
</td>
</tr>
И добавляем к стилям еще два правила:
#newprod{
position:relative;
top:70px;
}
#leader{
position:relative;
top:70px;
}
8. Файлы.
Еще раз обращаю внимание: сделайте бекап, сохраните свои файлы и пробуйте на копии сайта. В моих файлах могут быть и другие хаки, я не смотрел пристально, так что пользуйтесь с осторожностью, выкладываю просто для удобства.
Вот и все!