Когда я столкнулся с необходимостью добавить дополнительное поле к товару VirtueMart 1.1.5 я столкнулся с проблемой. В сети есть информация по добавлению дополнительного поля к VirtueMart 1.0 или 1.1.2 которая не актуальна для последних версий магазина.

Задача у меня стояла сделать выпадающий список select, данные из которого должны были отображаться не только на странице товара (fly), но и в списке товаров категории (browse). Кроме того значения каждого параметра (option), должны были выводиться с разными стилями, а это означало что нужно применять в моем случае div-ы с разными значениями class или id. Пришлось использовать несколько источников, к сожалению я после того как задача была решена я нашел на форуме публикацию которая значительно могла облегчить мне жизнь (см. возможно будет полезна топик на форуме)

Задача: Поле с выпадающим списком, отображение на странице товара и в списке товаров категории, вывод выбранного параметра со своим стилем!

Версия VirtueMart: 1.1.5

Версия Joomla: 1.5.8

Файлы:
/administrator/components/com_virtuemart/classes/ps_product.php
/administrator/components/com_virtuemart/html/product.product_form.php
/administrator/components/com_virtuemart/html/shop.browse.php
/administrator/components/com_virtuemart/html/shop_browse_queries.php
/administrator/components/com_virtuemart/languages/common/russian.php
/components/com_virtuemart/themes/default/templates/product_details/flypage.tpl.php (если этот шаблон Вы используете см. в админке на странице категории товара)
/components/com_virtuemart/themes/default/templates/browse/browse_1.php (если этот шаблон Вы используете см. в админке на странице категории товара)

Шаг 1. Создание поля в базе данных MYSQL.

Откройте phpMyAdmin выберите БД с которой которая хранит данные нужного сайта. Из списка таблиц нужно выбрать _vm_product и нажать на иконку напротив «Структура» (см. принт скрин № 1)
дополнительное поле VM скрин 1
Перед вами список полей выбранной таблицы. Найдите функцию добавления новых полей сразу под списком (см. принт скрин №2). И проставьте параметры добавления количество: 1, В конец таблицы и нажмите ОК
дополнительное поле VM скрин 2
Теперь необходимо заполнить параметры нового поля:
дополнительное поле VM скрин 3
Поле: product_novoepole (это имя поля которое должно быть уникальным, именно его Вы будете использовать в последствии для работы)
Тип: VARCHAR
Длинна\значения1: 255
По умолчанию: NULL
Сравнение: укажите кодировку в которой работаете
Null: поставьте галочку
Сохранить

Шаг 2. Добавление поля select для отображения в товаре для админки

Я разместил свое поле после краткого описания товара, Вы можете отобразить его там где хотите по аналогии с моим примером. В файле /administrator/components/com_virtuemart/html/product.product_form.php найдите код в районе 365 строки:

<td width="71%"  valign="top">
                          <textarea class="inputbox" name="product_s_desc" id="short_desc" cols="35" rows="6" ><?php echo $db->sf("product_s_desc"); ?></textarea> 
                      </td>
                </tr>

 

И после него добавьте код Вашего нового поля:

<tr class="row1"> 
                      <td width="29%" valign="top"><div style="text-align:right;font-weight:bold;">
                          <?php echo $VM_LANG->_('PHPSHOP_PRODUCT_FORM_NOVOEPOLE') ?>:</div>
                      </td>
                      <td width="71%"  valign="top">

<select name="product_novoepole">

<?php 
$svobodno = $VM_LANG->_('PHPSHOP_PRODUCT_FORM_SVOBODNO');
$zanyato = $VM_LANG->_('PHPSHOP_PRODUCT_FORM_ZANYATO');

?> 
<option value="<?php echo $VM_LANG->_('PHPSHOP_PRODUCT_FORM_VYBOR'); ?>" disabled="disabled" ><?php echo $VM_LANG->_('PHPSHOP_PRODUCT_FORM_VYBOR'); ?></option>
<option value="<?php echo $VM_LANG->_('PHPSHOP_PRODUCT_FORM_SVOBODNO'); ?>" <?php if ($db->sf("product_novoepole") == $svobodno) echo "selected=\"selected\""; ?> ><?php echo $VM_LANG->_('PHPSHOP_PRODUCT_FORM_SVOBODNO'); ?></option>
<option value="<?php echo $VM_LANG->_('PHPSHOP_PRODUCT_FORM_ZANYATO'); ?>" <?php if ($db->sf("product_novoepole") == $zanyato)  echo "selected=\"selected\""; ?>  ><?php echo $VM_LANG->_('PHPSHOP_PRODUCT_FORM_ZANYATO'); ?></option>

</select>

</td>
</tr>

 

Теперь откройте товар в админке или создайте новый, теперь созданное поле выводится под кратким описанием.

Шаг 3. Подготовим вывод поля в списке категории и для поиска.

Откройте файл /administrator/components/com_virtuemart/html/shop.browse.php и найдите код в районе 451 строки

unset($full_image_width);
        unset($full_image_height);

        $products[$i]['product_name'] = shopMakeHtmlSafe( $product_name );
        $products[$i]['product_s_desc'] = $product_s_desc;

И вставьте после него:

$products[$i]['product_novoepole'] = $product_novoepole;

 

Найдите код (295 стр.)

// If it is item get parent:
		$product_parent_id = $db_browse->f("product_parent_id");
		if ($product_parent_id != 0) {
			$dbp->query("SELECT product_full_image,product_thumb_image,product_name,product_s_desc FROM #__{vm}_product WHERE product_id='$product_parent_id'" );
			$dbp->next_record();
		}

В следующей строке после product_s_desc поставьте запятую и впишите имя своего поля product_novoepole :

$dbp->query("SELECT product_full_image,product_thumb_image,product_name,product_s_desc FROM #__{vm}_product WHERE product_id='$product_parent_id'" );
//После SELECT product_full_image,product_thumb_image,product_name,product_s_desc поставьте запятую и введите product_novoepole

 

Найдите код:

if( empty($product_s_desc) && $product_parent_id!=0 ) {
			$product_s_desc = $dbp->f("product_s_desc"); // Use product_s_desc from Parent Product
		}

 

После него вставьте (405 строка):

$product_novoepole = $db_browse->f("product_novoepole");
        if( empty($product_novoepole) && $product_parent_id!=0 ) {
            $product_nalich = $dbp->f("product_novoepole); 
        }

 

Далее откройте файл /administrator/components/com_virtuemart/html/shop_browse_queries.php и найдите в нем код (строка 39):

// These are the names of all fields we fetch data from
$fieldnames = "`product_name`,`products_per_row`,`category_browsepage`,`category_flypage`,`#__{vm}_category`.`category_id`,
                `#__{vm}_product`.`product_id`,`product_full_image`,`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_in_stock`,`product_available_date`,`product_availability`,`#__{vm}_product`.`mdate`, `#__{vm}_product`.`cdate`";

 

И добавьте после например product_s_desc название своего поля получится так:

// These are the names of all fields we fetch data from
$fieldnames = "`product_name`,`products_per_row`,`category_browsepage`,`category_flypage`,`#__{vm}_category`.`category_id`,
                `#__{vm}_product`.`product_id`,`product_full_image`,`product_thumb_image`,`product_s_desc`,`product_novoepole`,`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_in_stock`,`product_available_date`,`product_availability`,`#__{vm}_product`.`mdate`, `#__{vm}_product`.`cdate`";

 

Найдите код (строка 98)

foreach( $keywordArr as $searchstring ) {
        $sq .= "\n (`#__{vm}_product`.`product_name` LIKE '%$searchstring%' OR ";
        $sq .= "\n `#__{vm}_product`.`product_sku` LIKE '%$searchstring%' OR ";
        $sq .= "\n `#__{vm}_product`.`product_s_desc` LIKE '%$searchstring%' OR ";

 

После него вставьте:

 

Найдите код (строка 128):

case "desc":
			$sq .= "\n (`#__{vm}_product`.`product_s_desc` LIKE '%$searchstring%' OR ";

 

После добавьте:

$sq .= "\n (`#__{vm}_product`.`product_novoepole` LIKE '%$searchstring%' OR ";

 

Чуть ниже найдите код:

default:
			$sq .= "\n (`#__{vm}_product`.`product_name` LIKE '%$searchstring%' OR ";

 

И добавьте после:

>$sq .= "\n `#__{vm}_product`.`product_novoepole` LIKE '%$searchstring%' OR ";

 

Опуститесь на несколько строк ниже (160 стр.) и увидите такой же блок как и предыдущий повторите те же действия.

Шаг 4. Связь с БД

Откройте файл /administrator/components/com_virtuemart/classes/ps_product.php и найдите код (290 стр.):

// Insert into DB
		$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_novoepole' => vmRequest::getVar('product_novoepole', '', 'default', '', VMREQUEST_ALLOWHTML),

 

Найдите код (488 стр.):

// Insert into DB
        $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_novoepole' => vmRequest::getVar('product_novoepole', '', 'default', '', VMREQUEST_ALLOWHTML),

 

Найдите код (2700 стр.):

if ( $category_id ) {
            $q  = "SELECT DISTINCT product_sku,#__{vm}_product.product_id,product_name,product_s_desc,product_thumb_image, product_full_image, product_in_stock, product_url FROM #__{vm}_product, #__{vm}_product_category_xref, #__{vm}_category WHERE \n";

 

И добавьте свое поле, получится так:

if ( $category_id ) {
	        $q  = "SELECT DISTINCT product_sku,#__{vm}_product.product_id,product_name,product_s_desc,product_novoepole,product_thumb_image, product_full_image, product_in_stock, product_url FROM #__{vm}_product, #__{vm}_product_category_xref, #__{vm}_category WHERE \n";

 

Ниже найдите код (2713 стр.):

else {
	        $q  = "SELECT DISTINCT product_sku,product_id,product_name,product_s_desc,product_thumb_image, product_full_image, product_in_stock, product_url FROM #__{vm}_product WHERE ";

 

И добавьте свое поле, получится так:

else {
	        $q  = "SELECT DISTINCT product_sku,product_id,product_name,product_s_desc,product_novoepole,product_thumb_image, product_full_image, product_in_stock, product_url FROM #__{vm}_product WHERE ";

 

Найдите код 2738 (стр.):

if (_SHOW_PRICES == '1') {
				    // Show price, but without "including X% tax"
				    $price = $this->show_price( $db->f("product_id"), false );
			    }
                $featured_products[$i]['product_price'] = $price;
                $featured_products[$i]['product_s_desc'] = $db->f("product_s_desc");

 

После него добавьте:

$featured_products[$i]['product_novoepole'] = $db->f("product_novoepole");

 

Найдите код (2821 стр.):

$q = "SELECT product_name, category_name, c.category_flypage,product_s_desc,product_thumb_image ";

 

Добавьте свое поле, получится так:

$q = "SELECT product_name, category_name, c.category_flypage,product_s_desc,product_novoepole,product_thumb_image ";

 

Найдите код (2836 стр.):

$q = "SELECT product_name,category_name, c.category_flypage,product_s_desc,product_thumb_image ";

 

Добавьте свое поле, получится так:

$q = "SELECT product_name,category_name, c.category_flypage,product_s_desc,product_novoepole,product_thumb_image ";

 

Найдите код (2845 стр.)

$recent[$k]['product_s_desc'] = $db->f("product_s_desc");
                if($recent[$k]['product_s_desc']=="" && !empty($prod_id_p)) {
                    $recent[$k]['product_s_desc'] = $dbp->f("product_s_desc");
                }

 

После него добавьте:

$recent[$k]['product_novoepole'] = $db->f("product_novoepole");
                if($recent[$k]['product_novoepole']=="" && !empty($prod_id_p)) {
                    $recent[$k]['product_novoepole'] = $dbp->f("product_novoepole");
                }

 

Шаг 5. Пишем перевод.

В самом начале мы использовали названия для поля и его опция в виде:

$VM_LANG->_('PHPSHOP_PRODUCT_FORM_SVOBODNO');
$VM_LANG->_('PHPSHOP_PRODUCT_FORM_ZANYATO');
$VM_LANG->_('PHPSHOP_PRODUCT_FORM_VYBOR');
$VM_LANG->_('PHPSHOP_PRODUCT_FORM_NOVOEPOLE')

 

Теперь им нужно присвоить русские значения для вывода пользователям и в админку. Откройте файл /administrator/components/com_virtuemart/languages/common/russian.php и по аналогии в любом месте укажите

'PHPSHOP_PRODUCT_FORM_NOVOEPOLE' => 'Новое поле',
'PHPSHOP_PRODUCT_FORM_VYBOR' => 'Выбрать',
'PHPSHOP_PRODUCT_FORM_SVOBODNO' => 'Свободно',
'PHPSHOP_PRODUCT_FORM_ZANYATO' => 'Занято',

 

Шаг 6. Выводим результат на странице товара или в списке категории.

Теперь что бы отобразить результат необходимо открыть файлы /components/com_virtuemart/themes/default/templates/product_details/flypage.tpl.php, /components/com_virtuemart/themes/default/templates/browse/browse_1.php и добавить в нужном месте заглушку:

 <?php echo $product_novoepole  ?>

 

Например для того что бы решить свою задачу с присвоением разных стилей опциям списка я вписал туда такой код:

<?php 
$svobodno = $VM_LANG->_('PHPSHOP_PRODUCT_FORM_SVOBODNO');
$zanyato = $VM_LANG->_('PHPSHOP_PRODUCT_FORM_ZANYATO');
if ($product_novoepole == $svobodno) echo "<div id=\"svobodno\"> $product_novoepole </div>"; 
if ($product_novoepole == $zanyato) echo "<div id=\"zanyato\"> $product_novoepole </div>"; 

?>