Задача стояла в следующем: "Сделать единый список товаров добавленных в избранное, без каких либо наворотов."
1 Редактируем карточку товара
Самое первое, что необходимо сделать - это отредактировать карточку товара и добавить собственно ссылку "В избранное".
componens\com_virtuemart\themes\default\templates\product_details\flypage.tpl.php
В начало файла инклудим файл обработки, о нём немного дальше
include_once "administrator".DS."components".DS."com_virtuemart".DS."html".DS."favorites.add.php";
Дальше, в удобное место вставляем отображение ссылки. Тут же проверяем авторизирован пользователь, если нет выдаём ему форму авторизации
<?php if (!ps_favorites::CheckAuthorization()) { echo 'Добавить в <a href="#login" title="Для добавления в избранное, необходимо авторизоваться" class="wishlist_button fancy">избранное </a>'; //Отобразится модульное окно авторизации } elseif (favorites_check_add($product_id)) { echo 'Уже добавлено в <a href="/index.php?option=com_virtuemart&Itemid=28&lang=en&page=favorites.index" title="">избранное</a>'; } else { favorites_show_button($product_id,$category_id,$page); echo '<div class="favorites_add">Добавить в <a class="wishlist_button" title="Добавить в избранное" href="#"> избранное </a></div>'; } ?>
2 Рабочая часть
Теперь необходимо создать новый класс, а также файлы обработки
Создаем файл, с названием класса ps_favorites, в нём будут функции непосредственно работающие с базой (обновление, удаление, получение данных)
\administrator\components\com_virtuemart\classes\ps_favorites.php
<?php if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' ); /* * @version 1.0 * @cписок желаний для VirtueMart 1.x * @copyright by GAAlferov 2013 * http://gaalferov.com */ class ps_favorites { function FavoritesAdd (&$d) { /* Добавление товара в избранные */ global $db, $my, $vmInputFilter; //глобальные переменные virtuemart $d = $vmInputFilter->safeSQL( $d ); $this->CheckTable(); if ($this->CheckAuthorization()) { if ($this->CheckFavoritesAdd($d)) { $q = " INSERT INTO `#__{vm}_favorites` "; $q .= " (`id`, `user_id`, `product_id`, `created`) VALUES "; $q .= " ( NULL, '" . $my->id . "', '" . $d['product_id'] . "', NOW() )"; $result = $db->query( $q ); echo "Товар успешно добавлен в избранное.<br>"; return true; } } return false; } function FavoritesDelete (&$d) { /* Удаление товара из избранного */ global $db, $vmInputFilter; $d = $vmInputFilter->safeSQL( $d ); $this->CheckTable(); if ($this->CheckAuthorization()) { $q = " DELETE FROM `#__{vm}_favorites` "; $q .= " WHERE id =".$d['favorites_id']; $result = $db->query( $q ); return true; } return false; } /*Получение списка избранных таворов, а также их атрибутов */ function get_favorites_list($user_id) { global $db,$vmInputFilter; $user_id = $vmInputFilter->safeSQL( $user_id ); $q = ' SELECT * FROM `#__{vm}_favorites` fav JOIN #__vm_product prod ON fav.product_id = prod.product_id JOIN #__vm_product_price prodprice ON prod.product_id = prodprice.product_id JOIN #__vm_product_category_xref prodcat ON prod.product_id = prodcat.product_id WHERE fav.`user_id` = ' . $user_id. ' '; $db->query( $q ); if ($db->loadAssocList()) { return $db->loadAssocList(); } return false; } /*Проверка, есть ли вообще таблица*/ function CheckTable() { global $db; $q = "CREATE TABLE IF NOT EXISTS `#__{vm}_favorites` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL, `product_id` int(11) NOT NULL, `created` datetime NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"; $db->query( $q ); return true; } /*Проверка авторизирован пользователь или нет*/ function CheckAuthorization() { global $my; if ((@$_SESSION['auth']['user_id'] != $my->id) || empty( $my->id ) || ( $my->id == 0)) { return false; } return true; } /*Проверка. Если товар уже есть в избранном*/ function CheckFavoritesAdd($d) { global $db, $my; $q = ' SELECT `id` FROM `#__{vm}_favorites` WHERE `product_id` = ' . $d['product_id']. ' AND `user_id` = ' . $my->id . ' '; $db->query( $q ); if ($db->loadResult()) { return false; } return true; } } ?>
Теперь добавим два вспомогательных файла.
administrator\components\com_virtuemart\html\favorites.add.php (вывод кнопки добавления в избранное + проверка добавлен ли товар в избранное)
<?php if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' ); /* * @version 1.0 * @cписок желаний для VirtueMart 1.x * @copyright by GAAlferov 2013 * http://gaalferov.com */ mm_showMyFileName( __FILE__ ); /* Подключаем класс обработки */ require_once(CLASSPATH . 'ps_favorites.php' ); function favorites_show_button( $product_id, $category_id, $page) { // Показать ссылку на добавление товара в избранное echo '<form action="'.URL.'index.php?page=' . $page . '&product_id=' . $product_id . '&category_id=' . $category_id . '&option=com_virtuemart&Itemid=' . $GLOBALS['sess']->getShopItemid() . '" method="post" name="favoritesadd" id="favoritesadd">'; echo '<input type="hidden" name="quantity" value="1">'; echo '<input type="hidden" name="page" value="' . $page . '" />'; echo '<input type="hidden" name="product_id" value="' . $product_id . '" />'; echo '<input type="hidden" name="category_id" value="' . $category_id . '" />'; echo '<input type="hidden" name="func" value="favoritesadd" />'; echo '<input type="hidden" name="option" value="' . $GLOBALS['option'] . '" />'; echo '<input type="hidden" name="Itemid" value="' . $GLOBALS['sess']->getShopItemid() . '" />'; echo '</form>'; } function favorites_check_add( $product_id) { // Проверка, добавлен ли товар в избранное $d=array("product_id"=>$product_id); if (ps_favorites::CheckFavoritesAdd($d)){ return false; //Товар ещё не добавлен в избранные } return true; //Товар добавлен в избранные } ?>
administrator\components\com_virtuemart\html\favorites.index.php (вывод списка избранного в кабинете пользователя)
<?php if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' ); /* * @version 1.0 * @cписок желаний для VirtueMart 1.x * @copyright by GAAlferov 2013 * http://gaalferov.com */ mm_showMyFileName( __FILE__ ); /* Подключаем классы */ require_once(CLASSPATH . 'ps_favorites.php' ); require_once(CLASSPATH . 'ps_product.php' ); // Путь (хлебные крошки) $pathway = array(); $pathway[] = $vm_mainframe->vmPathwayItem( $VM_LANG->_('PHPSHOP_ACCOUNT_TITLE'), $sess->url( SECUREURL .'index.php?page=account.index' ) ); $pathway[] = $vm_mainframe->vmPathwayItem( $VM_LANG->_('PHPSHOP_FAVORITES_TITLE') ); $vm_mainframe->vmAppendPathway( $pathway ); //Получаем id пользователя if (intval( JRequest::getInt('uid'))) { $user_id = intval( JRequest::getInt('uid')); } else { global $my; $user_id = $my->id; } $output = ''; //В данной переменной будет всё содержимое show_favorites_list( $output, $user_id); //Вызов функции формирования списка избранных товаров echo $output; function show_favorites_list( &$output, $user_id) { $favories_item_list = ''; $document = JFactory::getDocument(); $document->setTitle($GLOBALS['VM_LANG']->_('PHPSHOP_FAVORITES_TITLE')); $favorites_list = ps_favorites::get_favorites_list( $user_id ); if ($favorites_list) { foreach ($favorites_list as $all_item) { $base_url = 'index.php?option=com_virtuemart&Itemid='.$GLOBALS['sess']->getShopItemid(); $ps_product = new ps_product(); $product_image = $ps_product->image_tag( $all_item['product_thumb_image'], "alt=\"" . $all_item['product_name'] . "\"", 1 ); $product_id = $all_item['product_id']; $category_id = $all_item['category_id']; $product_url = JRoute::_($base_url . '&page=shop.product_details&flypage=flypage.tpl&category_id='.$category_id.'&product_id='.$product_id); $product_name = $all_item['product_name']; $product_price = $ps_product->show_price( $product_id ); $addtocart_link = $base_url . '&page=shop.cart'; $uniqid = uniqid('addtocart_'); $product_in_stock = $all_item['product_in_stock']; $remove_link = $base_url . '&page=favorites.index&func=FavoritesDelete&favorites_id='.$all_item['id']; //Проверка остатка товара if( CHECK_STOCK == '1' && !$product_in_stock) { $notify = true; } else { $notify = false; } $favories_item_list .= ' <tr class="wish-row"> <td>'.$product_image.'</td> <td class="leftt"> <p><a href="'.$product_url.'" title="'.$product_name.'">'.$product_name.'</a></p> <p>'.$product_price.'</p> </td> <td> <form action="'.$addtocart_link.'" method="post" name="addtocart" id="'.$uniqid.'" class="addtocart_form left" data-notifi="'.$notify.'"> <input type="submit" style="background: url('/components/com_virtuemart/themes/images/add-cart-sm.png'); width:24px; height:24px; border:0px; padding:0px; margin:0px;" value=" " /> <input type="hidden" name="func" value="cartAdd" /> <input type="hidden" name="product_id" value="'.$product_id.'" /> <input type="hidden" name="category_id" value="'.$category_id.'" /> <input type="hidden" name="prod_id[]" value="'.$product_id.'" /> <input type="hidden" name="quantity" value="1" /> </form> <form action="'.$remove_link.'" method="post" class="left"> <input type="submit" style="background: url('/components/com_virtuemart/themes/default/images/remove_from_cart.png'); width:17px; height:16px; border:0px; padding:0px; margin:0px;" value=" " /> </form> </td> <tr>'; } } $to_output = '<div class="b_article-f box-shadow"> <h1><span>'.$GLOBALS["VM_LANG"]->_("PHPSHOP_FAVORITES_TITLE").'</span></h1> <table cellpadding="0" cellspacing="0" border="0" width="100%" class="bigbasket"> <thead> <tr> <th class="leftt">Изображение</th> <th>Описание</th> <th>Действия</th> </tr> </thead> <tbody> '.$favories_item_list.' </tbody> </table> </div>'; $output .= $to_output; return true; } ?>
И в конце необходимо создать новую таблицу, модуль, и добавить две функции в virtuemart
-- Create new table CREATE TABLE IF NOT EXISTS `gaa_vm_favorites` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL, `product_id` int(11) NOT NULL, `created` datetime NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; -- Add new module INSERT INTO `gaa_vm_module` (`module_id`, `module_name`, `module_description`, `module_perms`, `module_publish`, `list_order`) VALUES (NULL, 'favorites', 'Избранные товары', 'shopper,adder,storeadmin,admin,none', 'Y', 14); -- Add new function INSERT INTO `gaa_vm_function` (`function_id`, `module_id`, `function_name`, `function_class`, `function_method`, `function_description`, `function_perms`) VALUES (NULL, 12844, 'favoritesadd', 'ps_favorites', 'favoritesadd', 'Добавить товар в избранное', 'none'), (NULL, 12844, 'favoritesdelete', 'ps_favorites', 'FavoritesDelete', 'Удалить товар из избранного', 'none');
Конечно же по данному описанию, очень тяжело будет всё повторить начинающему программисту, но такова цель и не преследовалась. Данная информация нужна лишь как помощь программисту, который первый раз пишет хак для virtuemart.
Моменты на которые хотелось бы обратить внимание:
1) Добавление товара происходит с помощью формы, в которой фигурирует такая строка:
<input type="hidden" name="func" value="favoritesadd">
Что это такое? Эта строка показывает какую функцию в virtuemart использовать, а именно вызывается сначала функция virtuemart - favoritesadd, а с неё идёт указатель, что использовать функцию favoritesadd из класса ps_favorites.
2) Делаем хлебные крошки в админке (favorites.index.php)
// Путь (хлебные крошки) $pathway = array(); $pathway[] = $vm_mainframe->vmPathwayItem( $VM_LANG->_('PHPSHOP_ACCOUNT_TITLE'), $sess->url( SECUREURL .'index.php?page=account.index' ) ); $pathway[] = $vm_mainframe->vmPathwayItem( $VM_LANG->_('PHPSHOP_FAVORITES_TITLE') ); $vm_mainframe->vmAppendPathway( $pathway );
Ниже вы можете посмотреть как это все выглядит, а также скачать архив со всеми файлами.
Будет вопросы, обращайтесь, помогу чем смогу.
Вот тут это всё работает ->