Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Отказ от depth параметра #11

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 22 additions & 10 deletions assets/snippets/evoSearch/evoSearch.snippet.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
$eSS->params['rel'] = isset($eSS->params['rel']) ? str_replace(',', '.', round($eSS->params['rel'], 2)) : str_replace(',', '.', 0.01);

$eSS->Set('txt_original', $eSS->sanitarTag($_GET['search']), true);
$modx->setPlaceholder('stat_request', $eSS->Get('txt_original'));
$modx->setPlaceholder('stat_request', $eSS->Get('txt_original'));
//echo '<br>'.$eSS->Get('txt_original').'<br>';

$query = $eSS->makeSearchSQL();
Expand All @@ -40,15 +40,30 @@
}

if ($worker == 'DocLister') {
$eSS->params['parents'] = "0";
$eSS->params['depth'] = "7";
$eSS->params['showParent'] = "1";
$eSS->params['idType'] = 'parents';
$eSS->params['parents'] = '';
$eSS->params['ignoreEmpty'] = '1';

$eSS->params['addWhereList'] = $query['addWhereList'];
$eSS->params['selectFields'] = $query['selectFields'];


$eSS->params['orderBy'] = $query['orderBy'];
if ($eSS->params['extract'] == '1') {
$eSS->params['prepare'] = array($eSS, 'prepareExtractor');
include_once('evoSearchDLPrepare.class.php');
$eSS->params['bulk_words_stemmer'] = $eSS->bulk_words_stemmer;
$eSS->params['ext_content_field'] = $eSS->ext_content_field;

/**
* Получение prepare сниппетов из параметров BeforePrepare и AfterPrepare
* для совмещения с обязательным вызовом метода evoSearchDLPrepare::makeHighlight
*/
$prepare = isset($eSS->params['BeforePrepare']) ? explode(",", $eSS->params['BeforePrepare']) : '';
$prepare[] = 'evoSearchDLPrepare::makeHighlight';
$prepare[] = isset($eSS->params['AfterPrepare']) ? $eSS->params['AfterPrepare'] : '';
$eSS->params['prepare'] = trim(implode(",", $prepare), ',');
}

$output .= $eSS->modx->runSnippet($worker, $eSS->params);
} else if ($worker == 'Ditto') {
$eSS->params['extenders'] = 'nosort';
Expand All @@ -60,15 +75,12 @@

if ($output == '' && $worker == 'DocLister' && $eSS->params['addSearch'] != '0') {
$eSS->makeAddQueryForEmptyResult($bulk_words_original);
if ($eSS->params['extract'] == '1') {
$eSS->params['prepare'] = array($eSS, 'prepareExtractor');
}

$output .= $eSS->modx->runSnippet($worker, $eSS->params);
}
if ($eSS->params['show_stat'] == '1' && $worker == 'DocLister') {
$output = $eSS->getSearchResultInfo() . $output;
}

}

echo $output != '' ? $output : (!isset($_REQUEST['search']) ? '' : '<div class="noResult">' . $eSS->parseNoresult($noResult) . '</div>');
return $output != '' ? $output : (!isset($_REQUEST['search']) ? '' : '<div class="noResult">' . $eSS->parseNoresult($noResult) . '</div>');
54 changes: 54 additions & 0 deletions assets/snippets/evoSearch/evoSearchDLPrepare.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

//Класс для prepare-сниппета DocLister (готовим данные для плейсхолдера [+extract+] в чанк вывода результатов DocLister
class evoSearchDLPrepare{
//делаем подсветку на основе стеммера
public static function makeHighlight ($data, $modx, $_DL, $_extDL) {
$bulk_words_stemmer = $_DL->getCFGDef('bulk_words_stemmer', array());

if (is_array($bulk_words_stemmer) && !empty($bulk_words_stemmer)) {
$input = implode('|', $bulk_words_stemmer);
$input = str_replace('\\', '', $input);
$pattern = '/(' . $input . ')([^\.\s\;\:"\'\(\)!?,]*)?/ius';
$replacement = '<span class="evoSearch_highlight">$1$2</span>';
if ($_DL->getCFGDef('extract_with_tv', 0) == '1') {
$ext_content_field = $_DL->getCFGDef('ext_content_field');
$text = self::getTextForHighlight($data[$ext_content_field], $modx, $_DL);
} else{
$text = self::getTextForHighlight($data["content"], $modx, $_DL);
}
$pagetitle = $modx->stripTags($data["pagetitle"]);
$data["extract"] = preg_replace($pattern, $replacement, $text);
$data["pagetitle"] = preg_replace($pattern, $replacement, $pagetitle);
}
return $data;
}

//вырезаем нужный кусок текста нужной длины (примерно)
protected static function getTextForHighlight($text, $modx, $_DL) {
$maxlength = $_DL->getCFGDef('maxlength', 350);
$max_length = (int)$maxlength != 0 ? (int)$maxlength : 350;
$limit = $max_length + 12;
$text = $modx->stripTags($text);
$pos = array();
$bulk_words_stemmer = $_DL->getCFGDef('bulk_words_stemmer', array());
foreach ($bulk_words_stemmer as $word) {
$pos[$word] = mb_strripos(mb_strtolower($text, 'UTF-8'), $word, 0, 'UTF-8');
}
foreach ($pos as $word => $position) {
$length = mb_strlen($text, 'UTF-8');
if ($position == 0 && $length > $limit) {
$text = mb_substr($text, $position, $max_length, 'UTF-8') . ' ... ';
} else if ($position < $max_length && $length > $limit) {
$text = ' ... ' . mb_substr($text, $position, $max_length, 'UTF-8') . ' ... ';
} else if ($position + $limit >= $length && $length > $limit) {
$text = mb_substr($text, $position);
} else if ($length > $limit){
$text = ' ... ' . mb_substr($text, $position, $max_length, 'UTF-8') . ' ... ';
} else {

}
}
return $text;
}
}
88 changes: 26 additions & 62 deletions assets/snippets/evoSearch/snippet.class.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<?php

if(file_exists(MODX_BASE_PATH.'assets/snippets/DocLister/lib/DLTemplate.class.php')){
include_once(MODX_BASE_PATH.'assets/snippets/DocLister/lib/DLTemplate.class.php');
}

class evoSearchSnippet {

public $params = array();
Expand Down Expand Up @@ -46,59 +50,6 @@ public function __construct($modx, $params, $min_length = 2, $ext_content_field
$this->stemmer = $this->getStemmer();
}

//функция для prepare-сниппета DocLister (готовим данные для плейсхолдера [+extract+] в чанк вывода результатов DocLister
public function prepareExtractor($data) {
$data = $this->makeHighlight ($data);
return $data;
}

//делаем подсветку на основе стеммера
public function makeHighlight ($data) {
if (is_array($this->bulk_words_stemmer) && !empty($this->bulk_words_stemmer)) {
$input = implode('|', $this->bulk_words_stemmer);
$input = str_replace('\\', '', $input);
$pattern = '/(' . $input . ')([^\.\s\;\:"\'\(\)!?,]*)?/ius';
$replacement = '<span class="evoSearch_highlight">$1$2</span>';
if (isset($this->params['extract_with_tv']) && $this->params['extract_with_tv'] == '1') {
$text = $this->getTextForHighlight($data[$this->ext_content_field]);
} else{
$text = $this->getTextForHighlight($data["content"]);
}
$pagetitle = $this->modx->stripTags($data["pagetitle"]);
$data["extract"] = preg_replace($pattern, $replacement, $text);
$data["pagetitle"] = preg_replace($pattern, $replacement, $pagetitle);
}
return $data;
}

//вырезаем нужный кусок текста нужной длины (примерно)
private function getTextForHighlight($text) {
$max_length = isset($this->params['maxlength']) && (int)$this->params['maxlength'] != 0 ? (int)$this->params['maxlength'] : 350;
$limit = $max_length + 12;
$text = $this->modx->stripTags($text);
$pos = array();
foreach ($this->bulk_words_stemmer as $word) {
$pos[$word] = mb_strripos(mb_strtolower($text, 'UTF-8'), $word, 0, 'UTF-8');
}
foreach ($pos as $word => $position) {
$length = mb_strlen($text, 'UTF-8');
if ($position == 0 && $length > $limit) {
$text = mb_substr($text, $position, $max_length, 'UTF-8') . ' ... ';
} else if ($position < $max_length && $length > $limit) {
$text = ' ... ' . mb_substr($text, $position, $max_length, 'UTF-8') . ' ... ';
} else if ($position + $limit >= $length && $length > $limit) {
$text = mb_substr($text, $position);
} else if ($length > $limit){
$text = ' ... ' . mb_substr($text, $position, $max_length, 'UTF-8') . ' ... ';
} else {

}
}
return $text;
}



/**
* Возвращает все словоформы слов поискового запроса
*
Expand All @@ -118,11 +69,11 @@ public function Words2AllForms($text) {
// Extend graminfo for getAllFormsWithGramInfo method call
'with_gramtab' => false,
// Enable prediction by suffix
'predict_by_suffix' => true,
'predict_by_suffix' => true,
// Enable prediction by prefix
'predict_by_db' => true
);

$words = $this->makeWordsFromText($text);
$bulk_words = $this->makeBulkWords($words);

Expand Down Expand Up @@ -221,12 +172,12 @@ public function makeAddQueryForEmptyResult($bulk_words_original, $txt_original =
$this->params['documents'] = ''; //очищаем список документов, если там что-то было
$this->params['addWhereList'] = 'c.searchable=1'; //условия поиска только среди доступных для поиска
//$this->params['sortType'] = 'doclist'; - тут будем сортировать по умолчанию - по дате создания/публикации

//берем id всех документов сайта
$q = $this->modx->db->query("SELECT id FROM " . $this->content_table . " WHERE `searchable`='1' AND `deleted`='0' AND `published`='1'");
$documents = $this->makeStringFromQuery($q);
$this->params['documents'] = $documents;

$s = implode(",", $bulk_words_original);
if ($s != '') {//если в поиске есть хоть одно значимое слово, то будем искать
$this->params['filters'] = 'OR(content:pagetitle:eq:' . $txt_original . ';content:pagetitle:like-r:' . $txt_original . ';content:pagetitle:like-l:' . $txt_original . ';content:pagetitle:like: ' . $txt_original . ' ;content:pagetitle:against:' . $txt_original . ';content:' . $this->ext_content_field . ',' . $this->ext_content_index_field . ':against:' . $txt_original . ')';
Expand All @@ -244,14 +195,14 @@ public function getSearchResultInfo() {
$to = $from - 1 + $display;
if ($count && $count != '0' && $count != '') {
$out .= $this->parseTpl(
array('[+stat_request+]', '[+stat_total+]', '[+stat_display+]', '[+stat_from+]', '[+stat_to+]'),
array('stat_request', 'stat_total', 'stat_display', 'stat_from', 'stat_to'),
array($this->Get('txt_original'), $count, $display, $from, $to),
$this->params['statTpl']
);
}
$this->setPlaceholders(
array(
'stat_total' => $count,
'stat_total' => $count,
'stat_display' => $display,
'stat_from' => $from,
'stat_to' => $to
Expand All @@ -261,7 +212,20 @@ public function getSearchResultInfo() {
}

public function parseTpl($arr1, $arr2, $tpl) {
return str_replace($arr1, $arr2, $tpl);
if(class_exists('DLTemplate')){
$tplObj = DLTemplate::getInstance($this->modx);
$html = $tplObj->getChunk($tpl);
if(empty($html)){
$html = $tpl;
}
$out = $tplObj->parseChunk('@CODE: '.$html, array_combine($arr1, $arr2));
}else{
foreach($arr1 as &$val){
$val = '[+'.$val.'+]';
}
$out = str_replace($arr1, $arr2, $tpl);
}
return $out;
}

public function sanitarTag($data) {
Expand All @@ -281,7 +245,7 @@ public function setPlaceholders($data = array()) {
}

public function parseNoresult($noResult) {
return $this->parseTpl(array('[+stat_request+]'), array($this->Get('txt_original')), $noResult);
return $this->parseTpl(array('stat_request'), array($this->Get('txt_original')), $noResult);
}

}//class end
}//class end
11 changes: 5 additions & 6 deletions install/assets/snippets/snippet.evoSearch.tpl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//<?php
/**
* evoSearch
*
*
* Вывод результатов поиска
*
* @author webber ([email protected])
Expand All @@ -11,11 +11,11 @@
* @internal @modx_category Search
* @internal @installset base, sample
*/

//поиск по сайту с учетом словоформ (словаря phpMorphy)
//работает совместно с плагином evoSearch (плагин индексирует, сниппет выводит результаты)
//для работы необходим установленный сниппет DocLister
//пример вызова - для вывода результатов [!evoSearch? &tpl=`evoSearch`!],
//пример вызова - для вывода результатов [!evoSearch? &tpl=`evoSearch`!],
//ПАРАМЕТРЫ
// + &noResult = `Ничего не найдено` - строка, которая выводится при отсутствии результата поиска )необязательно)
// + &addSearch = `0` - для опционального отключения дополнительного поиска при пустом fulltext-search (по умолчанию - 1)
Expand All @@ -25,11 +25,10 @@
// + &statTpl - шаблон показа статистики (по умолчанию - <div class="evoSearch_info">По запросу <b>[+stat_request+]</b> найдено всего <b>[+stat_total+]</b>. Показано <b>[+stat_display+]</b>, c [+stat_from+] по [+stat_to+]</div> ), где
// [+stat_request+] - запрос из строки $_GET['search']
// [+stat_total+] - найдено всего
// [+stat_display+] - показано на текущей странице с [+stat_from+] по [+stat_to+]
// [+stat_display+] - показано на текущей странице с [+stat_from+] по [+stat_to+]
// + &rel = `1` - релевантность поиска, по умолчанию 2, чем выше цифра - тем более релевантные результаты и тем их меньше
//
//остальные параметры - дублируют параметры вызова DocLister
//обрабатывает $_GET['search'] в качестве входной строки для поиска

require_once MODX_BASE_PATH . "assets/snippets/evoSearch/evoSearch.snippet.php";

return require MODX_BASE_PATH . "assets/snippets/evoSearch/evoSearch.snippet.php";