==== Изменения в классе Product ====
Во фронтальной части мы должны обеспечить следующее условие - отображению подлежат только "доступные" товары, то есть те, у которых стоит флаг is_available. Для этого мы создадим дополнительный статический метод findForFront():
class Product extends lmbActiveRecord
{
[...]
static function findForFront()
{
lmb_require('limb/dbal/src/criteria/lmbSQLRawCriteria.class.php');
$criteria = new lmbSQLRawCriteria('is_available = 1');
return lmbActiveRecord :: find('Product', $criteria);
}
}
С классом [[..:..:packages:dbal:criteria|lmbCriteria]] вы должны быть уже знакомы по реализации функционала по управлению пользователями. Здесь же мы использовали класс **lmbSQLRawCriteria** для вставки условия в запрос "как есть" (as is). Мы сразу решили использовать объектную форму критерии при вызове метода lmbActiveRecord :: find(), так как знаем, что нам придется в ближайшее время расширить этот функционал.
==== Шаблон product/display.html ====
Файл shop/template/product/display.html:
-
{$title}
Price:${$price|number:2, '.'}
-
{$description|nl2br|raw}
Обратите внимание на атрибут **find** тега [[..:..:packages:wact:tags:lmb_fetch_tags:lmb_active_record_fetch_tag|
getRequest();
if($request->hasAttribute('letter'))
$current_letter = $request->get('letter');
return new lmbCollection($this->_getEnglishLetters($current_letter));
}
function _getEnglishLetters($current_letter = '')
{
$result = array();
for($i = 'A'; $i <= 'Z'; $i++)
{
if(strlen($i) == 2)
break;
$result[$i]['letter'] = $i;
if ($i == $current_letter)
$result[$i]['current'] = true;
}
return $result;
}
}
?>
Класс AlphabetFetcher отнаследован от класса lmbFetcher. **lmbFetcher** - это базовый класс, от которого наследуются все остальные fetcher-ы. Дочерние классы перекрывают метод _creataDataset(), из которого они должны обязательно возращать итератор.
==== Изменения в шаблоне product/display.html ====
Теперь мы будем использовать новый AlphabetFetcher в шаблоне для вывода списка букв. Для этого нам необходимо немного модифицировать шаблон product/display.html.
Файл shop/template/product/display.html:
Display all
{$letter|uppercase}
{$letter|uppercase}
[...]
[[..:..:packages:wact:fetch_tags|Подробнее о fetcher-ах и о применении тега ]].
==== Изменения в классе Product для учитывания ограничений ====
Теперь нам необходимо, что метод Product :: findForFront() учитывал ограничения по первой букве названия товара, если необходимо.
Файл shop/src/model/Product.class.php:
getRequest();
lmb_require('limb/dbal/src/criteria/lmbSQLFieldCriteria.class.php');
lmb_require('limb/dbal/src/criteria/lmbSQLRawCriteria.class.php');
$criteria = new lmbSQLRawCriteria('is_available = 1');
self :: _appendLetterCriteria($criteria, $request);
return lmbActiveRecord :: find('Product', $criteria);
}
static protected function _appendLetterCriteria($criteria, $request)
{
if($letter = $request->get('letter'))
{
$criteria->addAnd(new lmbSQLFieldCriteria('title', $letter . '%', lmbSQLFieldCriteria :: LIKE));
return true;
}
}
}
?>
Метод Product :: _appendLetterCriteria($criteria, $request) добавляет в $criteria дополнительное условие, если в запросе $request есть поле letter. Мы использовали класс lmbSQLFieldCriteria для дополнительного условия. Обратите внимание, что знаки **%** для LIKE условия необходимо расставлять самостоятельно.
Сейчас можете попробовать этот новый функционал. Вы должны увидеть список букв и при нажатии на какую-либо из них, выборка товаров будет соответствующим образом ограничена:
{{{limb3:ru:tutorials:shop:alphabet.png|поиск по алфавиту}}}
===== Реализация формы поиска товаров =====
==== Добавление формы поиска в шаблон product/display.html ====
Добавим новую форму для поиска товаров. Поиск будет доступен по названию продукта, а также по цене (больше какого-либо значения и(или) меньше).
Модификация файла shop/template/product/display.html:
[...]
Search the products:
[...]
Обратите внимание на hidden поле **action** со значением search. При помощи этого поля мы фактически заставим контроллер ProductController выполнять действие search, а не display.
==== Модификация контроллера ProductController ====
Для того, чтобы после отправки данных с формы поиска товаров у нас отраватывал все тот же product/display.html шаблон и чтобы форма поиска содержала те данные, которые были с нее отправлены, нам необходимо модифицировать контроллер ProductController.
Файл shop/src/controller/ProductController.class.php:
setTemplate('product/display.html');
$this->useForm('search_form');
$this->setFormDatasource($this->request);
}
}
?>
Мы реализовали **doSearch()** метод, который выполняется при действии search. При помощи метода lmbController :: **setTemplate($template_path)** мы установили нужное нам название шаблона. Две другие строки метода связывают $request с формой в шаблоне, что позволяет отображать значения в полях формы после ее отправки.
==== Изменения в классе Product для учета новых критерий ====
Теперь можно модифицировать метод Product :: findForFront() для того, чтобы он учитывал данные, пришедшие с формы поиска.
Файл shop/src/model/Product.class.php:
getRequest();
lmb_require('limb/dbal/src/criteria/lmbSQLFieldCriteria.class.php');
lmb_require('limb/dbal/src/criteria/lmbSQLRawCriteria.class.php');
$criteria = new lmbSQLRawCriteria('is_available = 1');
if(!self :: _appendLetterCriteria($criteria, $request))
self :: _appendSearchCriteria($criteria, $request);
return lmbActiveRecord :: find('Product', $criteria);
}
static protected function _appendSearchCriteria($criteria, $request)
{
if(!$request->get('search'))
return false;
if($product = $request->get('product'))
$criteria->addAnd(new lmbSQLFieldCriteria('title', '%' . $product . '%', lmbSQLFieldCriteria :: LIKE));
if($price_less = $request->get('price_less'))
$criteria->addAnd(new lmbSQLFieldCriteria('price', $price_less, lmbSQLFieldCriteria :: LESS));
if($price_greater = $request->get('price_greater'))
$criteria->addAnd(new lmbSQLFieldCriteria('price', $price_greater, lmbSQLFieldCriteria :: GREATER));
}
static protected function _appendLetterCriteria($criteria, $request)
{
[...]
}
}
?>
Надеемся, что наши последние действия в комментариях не требуются, и все понятно.
===== Предварительные итоги =====
Небольшой скриншот того, как должен выглядеть список товаров при использовании формы поиска:
{{{limb3:ru:tutorials:shop:search_products.png|поиск продуктов}}}
===== Далее =====
У нас уже есть список доступных к продаже товаров, теперь настало время добавить потенциальным покупателям добавлять приглянувшиеся им товары к корзину и оформлять заказ.
Итак, следующий шаг: [[step6|Шаг6. Работа покупателей с корзиной заказа]]