Yii 1: поиск по сайту
Yii 3381
Для проекта на Yii 1 сделаем поиск по статьям.
Поиск будет производиться по тегам и слову/словочетанию.
Сам код контроллера
<?php
class SearchController extends Controller {
public function actionTag($tag) {
$tags = CHtml::encode($tag);
if (isset($tags)) {
$criteria = new CDbCriteria(array(
'condition' => 'status=1',
'order' => 'updated DESC',
));
$criteria->addSearchCondition('tags', $tags);
$dataProvider = new CActiveDataProvider('Articles', array(
'pagination' => array(
'pageSize' => 7,
'pageVar' => 'page',
),
'criteria' => $criteria,
));
if ($dataProvider) {
$this->breadcrumbs = array('Поиск по тегу: "' . $tags . '"');
$this->pageTitle('Поиск по тегу: "' . $tags . '"');
$this->render('tag', array(
'dataProvider' => $dataProvider,
'tag' => $tags,
));
} else
throw new CHttpException(404, 'Page not found');
} else
throw new CHttpException(404, 'Page not found');
}
public function actionIndex() {
$query = Yii::app()->request->getParam('searchword', null);
if (iconv_strlen($query, 'UTF-8') < 3) {
if (isset($_GET['searchword']))
Yii::app()->user->setFlash("error", "Минимальная длина слова для поиска должна быть больше 3 символов!");
$query = "";
$this->pageTitle('Поиск');
$this->breadcrumbs = array('Поиск');
$this->render('search');
}
else {
$criteria = new CDbCriteria();
$criteria->addSearchCondition('status', 1);
$criteria->addSearchCondition('name', $query);
$criteria->addSearchCondition('text', $query, true, 'OR');
$dataProvider = new CActiveDataProvider('Articles', array(
'pagination' => array(
'pageSize' => 7,
'pageVar' => 'page',
),
'criteria' => $criteria,
));
if ($dataProvider) {
$this->breadcrumbs = array('Поиск: "' . $query . '"');
$this->pageTitle('Поиск: "' . $query . '"');
$this->render('index', array(
'dataProvider' => $dataProvider,
'query' => $query,
));
} else {
throw new CHttpException(404, 'Page not found');
}
}
}
}
Функция $this->pageTitle('Поиск по тегу: "' . $tags . '"'); класса Controller устанавливает title страницы.
Ее код:
<?php
class Controller extends CController {
...
public function pageTitle($title) {
$_title = CHtml::encode($title);
if ($this->nameTitle) {
return $this->pageTitle = $this->name . " - " . $_title;
} else {
return $this->pageTitle = "" . $_title;
}
}
...
}
Все будет выводиться с помощью стандартного виджета Yii CListView.
При выводе найденных статей, используется функция Helper::getFragment($name, $query), которая выводит сокращенное название статьи и Helper::getDescription($text), которая выводит описание статьи до разметки в тексте "<p><!-- pagebreak --></p>".
Далее ставиться ссылка "подробнее".
У меня эти функции в классе Helper, в котором находятся необходимые функции форматирования.
Код функций:
<?php
...
public static function getFragment($text, $word, $symb = 200) {
$text = strip_tags($text);
$word = strip_tags($word);
if ($word) {
$pos = max(mb_stripos($text, $word, null, 'UTF-8') - 100, 0);
$fragment = mb_substr($text, $pos, $symb, 'UTF-8');
$highlighted = preg_replace('~(' . $word . ')~ui', '$1', $fragment);
} else {
$highlighted = mb_substr($text, 0, $symb, 'UTF-8');
}
return $highlighted;
}
public static function getDescription($text) {
$_text=$text;
$text = strstr($text, 'pagebreak');
if($text !== false){
$text = explode("<p><!-- pagebreak --></p>", $_text);
return $text[0];
} else {
return "";
}
}
...
Этот пример не надеется на премию "лучший пример поиска на Yii" ! =)