Yii 1: поиск по сайту

Yii   481  

Для проекта на 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.

Этот пример не надеется на премию "лучший пример поиска на Yii" ! =)