Вывод ярлыков "Новинка", "Лидер" в VirtueMart

Во-первых: это придумал не я, я просто аккуратно записал как я ставил этот хак. Первоисточник находится на Жумлафоруме, вот в этой теме. Сам я разбираюсь слабо, так что вопросы лучше задавать там. Есть известный баг: галочки показывает только если не выбирать категорию в фильтре, при этом все работает, просто не видно.

Да, все это делалось на Жумле 1.5.26 и ВМ 1.1.9



Теперь что мы хотим получить, два скриншота, с админки и с магазина:

Thumbnail image

Thumbnail image

 

Теперь как мы это будем делать, работу можно условно разделить на три этапа: изменения в базе данных, вывод в админку и вывод в магазине. Прежде чем начать напоминаю, что пробовать это стоит только на копии и даже если все получится на копии, то сначала сделать полный бэкап рабочего сайта, а то будет больно и обидно. Если будет - я не виноват!

В базе нужно изменять руками, тут нет вариантов, а вот файлы можно взять в архиве, запаковано с полными путями. В моих файлах в голове вставлены комментарии, в которых указаны номера измененных строк, а так же комментарии вставлены непосредственно перед изменениями. В случае аварии можно воспользоваться архивом для отката - там файлы без изменений, но будьте внимательны с версией и установленными у Вас хаками. Архивы искать внизу, в самом конце. И хорошо бы прочитать от начала до конца все, хотя бы один раз, что бы понять что и откуда растет.   

 

1. Изменения в базе данных.

Изменений в базе безопасно и не затрагивает работу Жумлы и ВМ, просто добавляются новые поля, которые никак не мешают работе. Это самая безопасная часть хака, если только не наколбасить. Тут два варианта, самых частых -  с помощью phpMyAdmin или WebMin. Кому что подходит - у меня других нет. 

 

1.1. Изменения в базе данных - phpMyAdmin.

1.1.1. Открываем phpMyAdmin выбираем базу данных магазина и находим таблицу jos_vm_function добавляем в нее две функции. Выбираем вкладку "Вставить", заполняем и нажимаем ОК.

Thumbnail image

 

Вот данные которые нужно забить:

 Поле   Значение для первой функции   Значение для второй функции
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

 

В результате мы должны получить вот такую картину, если выберем вкладку "Обзор":

Thumbnail image

 

1.1.2. Теперь добавим в таблицу jos_vm_product еще два поля. Находим таблицу jos_vm_product. Заходим в нее, выбираем вкладку "Структура". Крутим вниз и находим "Добавить 1 поле(поля)" и в конце этой строки ОК, ничего не меняем, просто нажимаем.

stick05

 

В открывшемся окне первым делом снова жмем ОК, что бы разрешить сохранение двух полей сразу, затем их заполняем и жмем Сохранить.

Thumbnail image

Табличка, что бы можно было копи-пейст делать.

    Значение   Значение
Поле   product_is_new   product_is_leader
Тип   VARCHAR   VARCHAR
Длина   64   64
Сравнение   utf8_general_ci   utf8_general_ci
Атрибуты   НЕ ИЗМЕНЯЕМ   НЕ ИЗМЕНЯЕМ
Ноль   null   null
По умолчанию   NULL   NULL
Все, что ниже - не трогаем.

После сохранения мы можем увидеть, что к нашей таблице, в самом конце, добавились два новых поля, т.е. у нас все получилось и можно закрывать phpMyAdmin, он нам больше не нужен.

Thumbnail image

 

1.2. Изменения в базе данных - WebMin.

1.2.1. Открываем WebMin, выбираем Servers-MySQL Database Server. Открываем базу данных. В выпадающем меню выбираем таблицу jos_vm_function.

 Thumbnail image

 

  На открывшейся странице нажимаем "View Data".

Thumbnail image

 Теперь нажимаем "Add Row".

Thumbnail image

 Наконец вбиваем наши данные функции и нажимаем "Save". Повторяем шаги  для второй функции.

Thumbnail image

Вот для удобства табличка с данными:

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

В результате у нас добавится две строки с функциями, переходим к следующему этапу.

Thumbnail image

1.2.2. Добавляем в таблицу jos_vm_product еще два поля. Возвращаемся к выбору таблиц и выбираем jos_vm_product.

Thumbnail image

 

На открывшейся странице выбираем в выпадающем списке varchar и нажимаем Add field of type.

Thumbnail image

Заполняем и нажимаем "Create".

Thumbnail image

 

Повторяем операцию для поля product_is_new. Все делаем так же, только в поле Field name забиваем product_is_new. В результате получим два новых поля в таблице. 

Thumbnail image

Все, телодвижения с базой данных закончены.

 

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. Ставим в форме ввода нового товара два чекбокса.

Админка почти работает, теперь прикручиваем к форме ввода нового товара два новых чекбокса, если вводим товар вручную, то можно сразу отметить "Лидера" и "Новинку". Для меня фича абсолютно бесполезная, я ввожу таблицами, но кому то, может быть, пригодится.

stick08

Правим файл /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. Файлы.

Еще раз обращаю внимание: сделайте бекап, сохраните свои файлы и пробуйте на копии сайта. В моих файлах могут быть и другие хаки, я не смотрел пристально, так что пользуйтесь с осторожностью, выкладываю просто для удобства.

Архив с хаком.    Бэкап.    Иконки.

Вот и все!