Last active
August 29, 2015 14:15
-
-
Save sergant210/aa7a50d2b0ce882b2f3a to your computer and use it in GitHub Desktop.
Класс mSearch2ext
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* The extended class for mSearch2. | |
* Feature: search in found | |
*/ | |
require_once 'mSearch2.class.php'; | |
class mSearch2ext extends mSearch2 { | |
/** @var array $resources */ | |
public $resources = array(); | |
/** | |
* Search and return array with resources ids as a key and sum of weight as value | |
* | |
* @param $query | |
* @return array | |
*/ | |
public function Search($query) { | |
$string = preg_replace('/[^_-а-яёa-z0-9\s\.\/]+/iu', ' ', $this->modx->stripTags($query)); | |
$this->log('Filtered search query: "'.mb_strtolower($query.'"', 'UTF-8')); | |
$string = $this->query = $this->addAliases($string); | |
$this->log('Search query with processed aliases: "'.mb_strtolower($string.'"', 'UTF-8')); | |
$words = $this->getBaseForms($string, false); | |
$result = $all_words = $found_words = array(); | |
// Search by words index | |
if (!empty($words)) { | |
$q = $this->modx->newQuery('mseWord'); | |
$q->select($this->modx->getSelectColumns('mseWord', 'mseWord')); | |
$q->where(array('word:IN' => array_keys($words), 'field:IN' => array_keys($this->fields))); | |
// Search in found | |
if (!empty($this->resources) && is_array($this->resources)) $q->where(array('resource:IN' => $this->resources)); | |
$tstart = microtime(true); | |
if ($q->prepare() && $q->stmt->execute()) { | |
$this->modx->queryTime += microtime(true) - $tstart; | |
$this->modx->executedQueries++; | |
while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) { | |
if (isset($result[$row['resource']])) { | |
$result[$row['resource']] += $this->fields[$row['field']] * $row['count']; | |
} | |
else { | |
$result[$row['resource']] = $this->fields[$row['field']] * $row['count']; | |
} | |
if (isset($words[$row['word']])) { | |
$all_words[$row['resource']][$words[$row['word']]] = 1; | |
$found_words[$words[$row['word']]] = 1; | |
} | |
} | |
} | |
} | |
$added = 0; | |
if (!empty($found_words)) { | |
$this->log('Found results by words INDEX ('.implode(',',array_keys($words)).'): '.count($result)); | |
} | |
else { | |
$this->log('Nothing found by words INDEX'); | |
} | |
// Add bonuses | |
if (empty($this->config['onlyIndex'])) { | |
$bulk_words = $this->getBulkWords($query); | |
$tmp_words = preg_split($this->config['split_words'], $query, -1, PREG_SPLIT_NO_EMPTY); | |
if (count($bulk_words) > 1 || count($tmp_words) > 1 || empty($result)) { | |
if (!empty($this->config['exact_match_bonus']) || !empty($this->config['all_words_bonus'])) { | |
$exact = $this->simpleSearch($query); | |
// Exact match bonus | |
if (!empty($this->config['exact_match_bonus'])) { | |
foreach ($exact as $v) { | |
if (isset($result[$v])) { | |
$result[$v] += $this->config['exact_match_bonus']; | |
//$this->log('Added "exact match bonus" for a resource '.$v.' for words "'.implode(', ', $words).'": +'.$this->config['exact_match_bonus']); | |
} | |
else { | |
$result[$v] = $this->config['exact_match_bonus']; | |
//$this->log('Found resource '.$v.' by LIKE search with all words "'.implode(', ',$words).'": +'.$this->config['exact_match_bonus']); | |
$added ++; | |
} | |
} | |
} | |
if (!empty($this->config['all_words_bonus'])) { | |
if (count($bulk_words) > 1) { | |
// All words bonus | |
foreach ($all_words as $k => $v) { | |
if (count($bulk_words) == count($v)) { | |
$result[$k] += $this->config['all_words_bonus']; | |
//$this->log('Added "all words bonus" for a resource '.$k.' for words "'.implode(', ', $words).'": +'.$this->config['all_words_bonus']); | |
} | |
} | |
} | |
} | |
} | |
} | |
elseif (!empty($this->config['like_match_bonus'])) { | |
// Add the whole possible results for query | |
$all_results = $this->simpleSearch($query); | |
foreach ($all_results as $v) { | |
if (!isset($result[$v])) { | |
$weight = round($this->config['like_match_bonus']); | |
$result[$v] = $weight; | |
//$this->log('Found resource '.$v.' by LIKE search with all words "'.$query.'": +'.$weight); | |
$added ++; | |
} | |
} | |
} | |
// Add matches by %LIKE% search | |
if (!empty($this->config['like_match_bonus']) && $not_found = array_diff($bulk_words, $words)) { | |
foreach ($not_found as $word) { | |
$found = $this->simpleSearch($word); | |
foreach ($found as $v) { | |
$weight = round($this->config['like_match_bonus']); | |
if (!isset($result[$v])) { | |
$result[$v] = $weight; | |
//$this->log('Found resource '.$v.' by LIKE search with single word "'.$word.'": +'.$weight); | |
$added ++; | |
} | |
else { | |
$result[$v] += $weight; | |
//$this->log('Added "LIKE bonus" for a resource '.$v.' for word "'.$word.'": +'.$weight); | |
} | |
} | |
} | |
} | |
$this->log('Added resources by LIKE search: '.$added); | |
} | |
// Log the search query | |
/** @var mseQuery $object */ | |
if ($object = $this->modx->getObject('mseQuery', array('query' => $query))) { | |
$object->set('quantity', $object->get('quantity') + 1); | |
} | |
else { | |
$object = $this->modx->newObject('mseQuery'); | |
$object->set('query', $query); | |
$object->set('quantity', 1); | |
} | |
$object->set('found', count($result)); | |
$object->save(); | |
arsort($result); | |
return $result; | |
} | |
/** | |
* Search and return array with resources that matched for LIKE search | |
* | |
* @param $query | |
* | |
* @return array | |
*/ | |
public function simpleSearch($query) { | |
$string = preg_replace('/[^_-а-яёa-z0-9\s\.\/]+/iu', ' ', $this->modx->stripTags($query)); | |
$result = array(); | |
$q = $this->modx->newQuery('mseIntro'); | |
$q->select('`resource`'); | |
//Search in found | |
if (!empty($this->resources) && is_array($this->resources)) $q->where(array('resource:IN' => $this->resources)); | |
$q->where(array('intro:LIKE' => '%'.$string.'%')); | |
$tstart = microtime(true); | |
if ($q->prepare() && $q->stmt->execute()) { | |
$this->modx->queryTime += microtime(true) - $tstart; | |
$this->modx->executedQueries++; | |
$result = $q->stmt->fetchAll(PDO::FETCH_COLUMN); | |
} | |
return $result; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment