HOSTCMS v.6
ПОИСК
Ограничиваем поиск только по каталогу товаров
Настройка Типовой динамической страницы для поиска только товаров магазина.
Код Типовой динамической страницы "Поиск"
<?php
if (Core::moduleIsActive('search'))
{
$oSite = Core_Entity::factory('Site', CURRENT_SITE);
$Search_Controller_Show = new Search_Controller_Show($oSite);
$Search_Controller_Show
->limit(Core_Page::instance()->libParams['itemsOnPage'])
->parseUrl()
->len(Core_Page::instance()->libParams['maxlen'])
->query(Core_Array::getGet('text'))
->structure(Core_Page::instance()->structure);
//
// 'module_id' => 3 - здесь указываем id интернет-магазина
//
$Search_Controller_Show->modules(
array(
3 =>array(array('module_id' => 3, 'module_value_type' => 2))
)
);
$Search_Controller_Show
->xsl(
Core_Entity::factory('Xsl')->getByName(Core_Page::instance()->libParams['xsl'])
)
->show();
}
else
{
?>
<h1>Поиск</h1>
<p>Функционал недоступен, приобретите более старшую редакцию.</p>
<p>Модуль «<a href="http://www.hostcms.ru/hostcms/modules/search/">Поиск по сайту</a>» доступен в редакциях «<a href="http://www.hostcms.ru/hostcms/editions/corporation/">Корпорация</a>», «<a
href="http://www.hostcms.ru/hostcms/editions/business/">Бизнес</a>», «<a
href="http://www.hostcms.ru/hostcms/editions/small-business/">Малый бизнес</a>» и «<a
href="http://www.hostcms.ru/hostcms/editions/my-site/">Мой сайт</a>».</p>
<?php
}Class Search_Controller_Show
Доступные методы:
Доступные методы:
- query($query) поисковый запрос
- inner($inner) поиск по внутренним данным, например, Helpdesk. По умолчанию 0 - внешние данные, 1 - внутренние данные
- modules($modules) массив условий поиска по модулям
- itemsForbiddenTags(array('description')) массив тегов связанных элементов, запрещенных к передаче в генерируемый XML
- offset($offset) смещение, с которого выводить информационные элементы, по умолчанию 0
- limit($limit) количество выводимых элементов
$oSite = Core_Entity::factory('Site', CURRENT_SITE);
$Search_Controller_Show = new Search_Controller_Show($oSite);
$Search_Controller_Show
->limit(Core_Page::instance()->libParams['result_on_page'])
->parseUrl()
->len(Core_Page::instance()->libParams['maxlen'])
->query(Core_Array::getGet('text'));
$Search_Controller_Show
->xsl(
Core_Entity::factory('Xsl')->getByName(Core_Page::instance()->libParams['xsl'])
)
->show();Массив условий поиска по модулям позволяет ограничить область поиска по модулям и типам индексируемого контента. Ключами массива являются номера модулей, а значениями — массив идентификаторов элементов. Номера модулей:
0 – Структура сайта;
1 – Информационные системы;
2 – Форум;
3 – Интернет-магазин;
4 – HelpDesk.
Пример поиска по информационной системе с номером 5 и 7, а также по магазину с номером 17.
$Search_Controller_Show
->modules(
array(
1 => array (5, 7),
3 => array (17)
)
);Пример поиска по информационной системе с номером 5 и 7 (с дополнительным условием поиска только по информационным элементам), а также по магазину с номером 17.
$Search_Controller_Show
->modules(
array(
1 => array (5,
array('module_id' => 7, 'module_value_type' => 2)),
3 => array (17))
);При указании массива с дополнительными условиями он может принимать следующие аргументы:
module_id — целое число, ID сущности, например, магазин с кодом 7
module_value_type — целое число или массив, ID типа, например, 1 - группа, 2 - элемент (или товар)
module_value_id — целое число или массив, ID сущности указанного типа (например, ID товара или группы) при поиске только по ним.
Рабочий поиск по сайту с Autocomplete
HTML
<form action="/search/" class="top-search-form" method="GET">
<input id="search" name="src" placeholder="Поиск по каталогу" type="text" value="<?=isset($_GET['src'])?$_GET['src']:''?>" />
<input class="submitSearch" type="submit" value="" />
</form>
Код настроек Типовой динамической страницы "Поиск"
<?php
$text = strval(Core_Array::getGet('text'));
if ($text)
{
Core_Page::instance()->title('Поиск: ' . $text);
}
//Autocomplete
if (!is_null(Core_Array::getGet('autocomplete')) && !is_null(Core_Array::getGet('query')))
{
//$iShopId = 1;
$sQuery = Core_Str::stripTags(strval(Core_Array::getGet('query')));
$aJSON = array();
$aJSON['query'] = $sQuery;
$aJSON['suggestions'] = array();
$oShop_Items = Core_Entity::factory('Shop_Item');
$oShop_Items->queryBuilder()
->select('shop_items.*')
->join('shops', 'shop_items.shop_id', '=', 'shops.id')
->where('shops.site_id', '=', CURRENT_SITE)
->where('shop_items.active', '=', 1)
->where('modification_id', '=', '0')
->where('shop_items.name', 'LIKE', '%' . $sQuery . '%')
->limit(50);
$aShop_Items = $oShop_Items->findAll();
foreach ($aShop_Items as $oShop_Item)
{
$aJSON['suggestions'][] = array(
'value' => $oShop_Item->name,
'price' => $oShop_Item->price,
'data' => $oShop_Item->id
);
}
Core_Page::instance()->response
->status(200)
->header('Pragma', "no-cache")
->header('Cache-Control', "private, no-cache")
->header('Vary', "Accept")
->header('Last-Modified', gmdate('D, d M Y H:i:s', time()) . ' GMT')
->header('X-Powered-By', 'HostCMS')
->header('Content-Disposition', 'inline; filename="files.json"');
Core_Page::instance()->response
->body(json_encode($aJSON))
->header('Content-type', 'application/json; charset=utf-8');
Core_Page::instance()->response
->sendHeaders()
->showBody();
exit();
}
JavaScript / jQuery
// jQuery.Autocomplete selectors
$('#search').autocomplete({
serviceUrl: '/search/?autocomplete=1',
delimiter: ',',
maxHeight: 300,
width: 300,
deferRequestBy: 300,
appendTo: '.top-search-form',
onSelect: function (suggestion) {
$(this).closest("form").submit();
}
});
Шаблон XSL "Поиск" с показом карточек товаров
В результатх поиска выводим только товары интернет-магазина.
XSL
<!-- XSL шаблон "Поиск" -->
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">;
<xsl:output xmlns="http://www.w3.org/TR/xhtml1/strict"; doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" encoding="utf-8" indent="yes" method="html" omit-xml-declaration="no" version="1.0" media-type="text/xml"/>
<xsl:decimal-format name="my" decimal-separator="," grouping-separator=" "/>
<xsl:template match="/">
<xsl:apply-templates select="/site"/>
</xsl:template>
<xsl:template match="/site">
<h1>Поиск по каталогу женской одежды</h1>
<!-- Форма поиска -->
<!--form method="get" action="/search/" class="searchform2">
<input id="search_text" type="text" name="text" value="{query}" maxlength="200" class="input_search"/>
<input width="38" type="image" height="34" class="input_buttom_search" src="/images/icon-search.png" title="Искать" />
</form-->
<div class="clear"></div>
<xsl:if test="query!=''">
<!--<p>
<strong>Найдено <xsl:value-of select="total"/> <xsl:call-template name="declension">
<xsl:with-param name="number" select="total"/></xsl:call-template></strong>
</p>-->
<xsl:choose>
<xsl:when test="total!=0">
<h5 style="margin-top:15px;">Мы нашли для вас:</h5>
<div class="shop_table row products-grid">
<div class="row">
<xsl:apply-templates select="search_page"></xsl:apply-templates>
</div>
</div>
<!-- Строка ссылок на другие страницы результата поиска -->
<div class="pagination">
<xsl:variable name="count_pages" select="ceiling(total div limit)"/>
<xsl:variable name="visible_pages" select="5"/>
<xsl:variable name="real_visible_pages"><xsl:choose>
<xsl:when test="$count_pages < $visible_pages"><xsl:value-of select="$count_pages"/></xsl:when>
<xsl:otherwise><xsl:value-of select="$visible_pages"/></xsl:otherwise>
</xsl:choose></xsl:variable>
<!-- Считаем количество выводимых ссылок перед текущим элементом -->
<xsl:variable name="pre_count_page"><xsl:choose>
<xsl:when test="(page) - (floor($real_visible_pages div 2)) < 0">
<xsl:value-of select="page"/>
</xsl:when>
<xsl:when test="($count_pages - (page) - 1) < floor($real_visible_pages div 2)">
<xsl:value-of select="$real_visible_pages - ($count_pages - (page) - 1) - 1"/>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="round($real_visible_pages div 2) = $real_visible_pages div 2">
<xsl:value-of select="floor($real_visible_pages div 2) - 1"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="floor($real_visible_pages div 2)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose></xsl:variable>
<!-- Считаем количество выводимых ссылок после текущего элемента -->
<xsl:variable name="post_count_page"><xsl:choose>
<xsl:when test="0 > (page) - (floor($real_visible_pages div 2) - 1)">
<xsl:value-of select="$real_visible_pages - (page) - 1"/>
</xsl:when>
<xsl:when test="($count_pages - (page) - 1) < floor($real_visible_pages div 2)">
<xsl:value-of select="$real_visible_pages - $pre_count_page - 1"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$real_visible_pages - $pre_count_page - 1"/>
</xsl:otherwise>
</xsl:choose></xsl:variable>
<xsl:variable name="i"><xsl:choose>
<xsl:when test="(page) + 1 = $count_pages"><xsl:value-of select="(page) - $real_visible_pages + 1"/></xsl:when>
<xsl:when test="(page) - $pre_count_page > 0"><xsl:value-of select="(page) - $pre_count_page"/></xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose></xsl:variable>
<xsl:call-template name="for">
<xsl:with-param name="limit" select="limit"/>
<xsl:with-param name="page" select="page"/>
<xsl:with-param name="total" select="total"/>
<xsl:with-param name="i" select="$i"/>
<xsl:with-param name="post_count_page" select="$post_count_page"/>
<xsl:with-param name="pre_count_page" select="$pre_count_page"/>
<xsl:with-param name="visible_pages" select="$real_visible_pages"/>
</xsl:call-template>
<div style="clear: both"></div>
</div>
</xsl:when>
<xsl:otherwise>
<p style="margin-top:15px;">К сожалению, мы ничего не нашли по Вашему запросу.</p>
<p>Измените запрос или воспользуйтесь <a href="/map">картой сайта</a></p>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
<xsl:if test="query = ''">
<p>Введите поисковой запрос.</p>
</xsl:if>
</xsl:template>
<xsl:template match="search_page">
<xsl:if test="module = 3 and module_value_type = 2">
<xsl:apply-templates select="shop_item" mode="shop" />
</xsl:if>
</xsl:template>
<!-- Шаблон для товара -->
<xsl:template match="shop_item" mode="shop" >
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 item">
<div class="grid_wrap maxheight1">
<div class="product-image">
<a href="{url}" title="{name}">
<xsl:choose>
<xsl:when test="image_small != ''">
<img src="{dir}{image_small}" alt="{name}" class="img-responsive"/>
</xsl:when>
<xsl:otherwise>
<img src="/images/default-image.png"/>
</xsl:otherwise>
</xsl:choose>
</a>
<xsl:if test="discount != 0">
<span class="product-label">
<span class="label-sale">
<span class="sale-text">-<xsl:value-of disable-output-escaping="yes" select="round(shop_discount/percent)"/>%</span>
</span>
</span>
</xsl:if>
<xsl:variable name="shop_item_id" select="@id" />
<div class="product-buttons">
<div class="product-wishlist">
<span onclick="return $.addFavorite('{/shop/url}', {@id}, this)">
<xsl:if test="/shop/favorite/shop_item[@id = $shop_item_id]/node()">
<xsl:attribute name="class">favorite-current</xsl:attribute>
</xsl:if>
<i class="fa fa-heart-o"></i>
</span>
</div>
<div class="product-compare">
<span onclick="return $.addCompare('{/shop/url}', {@id}, this)">
<xsl:if test="/shop/comparing/shop_item[@id = $shop_item_id]/node()">
<xsl:attribute name="class">compare-current</xsl:attribute>
</xsl:if>
<i class="fa fa-bar-chart"></i>
</span>
</div>
</div>
<xsl:if test="modifications">
<div class="choice text-center">
<ul>
<xsl:for-each select="modifications/shop_item">
<xsl:sort order="ascending" select="."/>
<xsl:variable name="name1" select="name"/>
<xsl:variable name="name2" select="substring(name, 1, string-length(name) - 2)"/>
<li><xsl:value-of select="substring-after($name1, $name2)" /></li>
</xsl:for-each>
</ul>
</div>
</xsl:if>
</div>
<div class="product-content">
<div class="product-content-inner">
<h5 class="product-name">
<a href="{url}" title="{name}">
<xsl:value-of select="name"/>
</a>
</h5>
<xsl:if test="marking !=''">
<div class="marking">арт. <xsl:value-of select="marking" /></div>
</xsl:if>
</div>
</div>
<div class="product-action">
<div class="price-box">
<span class="regular-price">
<span class="price">
<xsl:apply-templates select="/shop/shop_currency/code">
<xsl:with-param name="value" select="price" />
</xsl:apply-templates>
</span>
<xsl:if test="discount != 0">
<span class="old-price">
<xsl:apply-templates select="/shop/shop_currency/code">
<xsl:with-param name="value" select="price + discount" />
</xsl:apply-templates>
</span>
</xsl:if>
</span>
<!-- <xsl:if test="count(shop_bonuses/shop_bonus)">
<div class="product-bonuses">
+<xsl:value-of select="shop_bonuses/total" /> бонусов
</div>
</xsl:if>-->
</div>
<div class="product-action-buttons">
<xsl:choose>
<xsl:when test="rest !=0">
<div class="shop-item-add-to-cart">
<a class="shop-item-add-to-cart-link" href="#" onclick="return $.bootstrapAddIntoCart('{/shop/url}cart/', {@id}, 1)" title="Добавить в корзину"><i class="fa fa-shopping-basket "></i></a>
</div>
</xsl:when>
<xsl:otherwise>
<span class="color1">на заказ</span>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="rest !=0">
</xsl:if>
<div class="shop-item-fast-order">
<span class="title hidden"><xsl:value-of select="name"/></span>
<!--a class="zakaz shop-item-fast-order-link" href="#" data-toggle="modal" data-target="#oneStepCheckout" title="Быстрый заказ"><i class="fa fa-shopping-cart"></i></a-->
<!--a class="shop-item-fast-order-link" href="#" onclick="return $.oneStepCheckout('{/shop/url}cart/', {@id}, 1)" title="Быстрый заказ" data-toggle="modal" data-target="#oneStepCheckout{@id}"><i class="fa fa-shopping-cart"></i></a-->
</div>
</div>
</div>
</div>
</div>
</xsl:template>
<xsl:template name="url" match="text()">
<xsl:param name="str" select="."/>
<xsl:param name="max">50</xsl:param>
<xsl:param name="hvost">10</xsl:param>
<xsl:param name="begin">
<xsl:choose>
<xsl:when test="string-length($str) > $max">
<xsl:value-of select="substring($str, 1, $max - $hvost)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring($str, 1)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:param name="end">
<xsl:choose>
<xsl:when test="string-length($str) > $max">
<xsl:value-of select="substring($str, string-length($str) - $hvost + 1, $hvost)"/>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:param name="result">
<xsl:choose>
<xsl:when test="$end != ''">
<xsl:value-of select="concat($begin, '…', $end)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$begin"/>
</xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:value-of disable-output-escaping="yes" select="$result"/>
</xsl:template>
<!-- Цикл для вывода строк ссылок -->
<xsl:template name="for">
<xsl:param name="i" select="0"/>
<xsl:param name="limit"/>
<xsl:param name="page"/>
<xsl:param name="total"/>
<xsl:param name="visible_pages"/>
<xsl:variable name="url" select="/site/url"/>
<xsl:variable name="n" select="$total div $limit"/>
<!-- Считаем количество выводимых ссылок перед текущим элементом -->
<xsl:variable name="pre_count_page">
<xsl:choose>
<xsl:when test="$page > ($n - (round($visible_pages div 2) - 1))">
<xsl:value-of select="$visible_pages - ($n - $page)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="round($visible_pages div 2) - 1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Считаем количество выводимых ссылок после текущего элемента -->
<xsl:variable name="post_count_page">
<xsl:choose>
<xsl:when test="0 > $page - (round($visible_pages div 2) - 1)">
<xsl:value-of select="$visible_pages - $page"/>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="round($visible_pages div 2) = ($visible_pages div 2)">
<xsl:value-of select="$visible_pages div 2"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="round($visible_pages div 2) - 1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if test="$i = 0 and $page != 0">
<span class="ctrl">
← Ctrl
</span>
</xsl:if>
<xsl:if test="$i >= $n and ($n - 1) > $page">
<span class="ctrl">
Ctrl →
</span>
</xsl:if>
<xsl:if test="$total > $limit and $n > $i">
<!-- Определяем адрес ссылки -->
<xsl:variable name="number_link">
<xsl:choose>
<!-- Если не нулевой уровень -->
<xsl:when test="$i != 0">page-<xsl:value-of select="$i + 1"/>/</xsl:when>
<!-- Иначе если нулевой уровень - просто ссылка на страницу со списком элементов -->
<xsl:otherwise></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Ставим ссылку на страницу-->
<xsl:if test="$i != $page">
<!-- Выводим ссылку на первую страницу -->
<xsl:if test="$page - $pre_count_page > 0 and $i = 0">
<a href="{$url}?text={/site/queryencode}" class="page_link" style="text-decoration: none;">←</a>
</xsl:if>
<xsl:choose>
<xsl:when test="$i >= ($page - $pre_count_page) and ($page + $post_count_page) >= $i">
<!-- Выводим ссылки на видимые страницы -->
<a href="{$url}{$number_link}?text={/site/queryencode}" class="page_link">
<xsl:value-of select="$i + 1"/>
</a>
</xsl:when>
<xsl:otherwise></xsl:otherwise>
</xsl:choose>
<!-- Выводим ссылку на последнюю страницу -->
<xsl:if test="$i+1 >= $n and $n > ($page + 1 + $post_count_page)">
<xsl:choose>
<xsl:when test="$n > round($n)">
<!-- Выводим ссылку на последнюю страницу -->
<a href="{$url}page-{round($n+1)}/?text={/site/queryencode}" class="page_link" style="text-decoration: none;">→</a>
</xsl:when>
<xsl:otherwise>
<a href="/page-{round($n)}/?text={/site/queryencode}" class="page_link" style="text-decoration: none;">→</a>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:if>
<!-- Ссылка на предыдущую страницу для Ctrl + влево -->
<xsl:if test="$page != 0 and $i = $page">
<xsl:variable name="prev_number_link">
<xsl:choose>
<!-- Если не нулевой уровень -->
<xsl:when test="($page) != 0">page-<xsl:value-of select="$i"/>/</xsl:when>
<!-- Иначе если нулевой уровень - просто ссылка на страницу со списком элементов -->
<xsl:otherwise></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<a href="{$url}{$prev_number_link}?text={/site/queryencode}" id="id_prev"></a>
</xsl:if>
<!-- Ссылка на следующую страницу для Ctrl + вправо -->
<xsl:if test="($n - 1) > $page and $i = $page">
<a href="{$url}page-{$page+2}/?text={/site/queryencode}" id="id_next"></a>
</xsl:if>
<!-- Не ставим ссылку на страницу-->
<xsl:if test="$i = $page">
<span class="current">
<xsl:value-of select="$i+1"/>
</span>
</xsl:if>
<!-- Рекурсивный вызов шаблона. НЕОБХОДИМО ПЕРЕДАВАТЬ ВСЕ НЕОБХОДИМЫЕ ПАРАМЕТРЫ! -->
<xsl:call-template name="for">
<xsl:with-param name="i" select="$i + 1"/>
<xsl:with-param name="limit" select="$limit"/>
<xsl:with-param name="page" select="$page"/>
<xsl:with-param name="total" select="$total"/>
<xsl:with-param name="visible_pages" select="$visible_pages"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<!-- Склонение после числительных -->
<xsl:template name="declension">
<xsl:param name="number" select="number"/>
<!-- Именительный падеж -->
<xsl:variable name="nominative">
<xsl:text>страница</xsl:text>
</xsl:variable>
<!-- Родительный падеж, единственное число -->
<xsl:variable name="genitive_singular">
<xsl:text>страницы</xsl:text>
</xsl:variable>
<xsl:variable name="genitive_plural">
<xsl:text>страниц</xsl:text>
</xsl:variable>
<xsl:variable name="last_digit">
<xsl:value-of select="$number mod 10"/>
</xsl:variable>
<xsl:variable name="last_two_digits">
<xsl:value-of select="$number mod 100"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$last_digit = 1 and $last_two_digits != 11">
<xsl:value-of select="$nominative"/>
</xsl:when>
<xsl:when test="$last_digit = 2 and $last_two_digits != 12 or $last_digit = 3 and $last_two_digits != 13 or $last_digit = 4 and $last_two_digits != 14">
<xsl:value-of select="$genitive_singular"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$genitive_plural"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>