Вход Регистрация
Файл: system/controllers/search/model.php
Строк: 132
<?php

class modelSearch extends cmsModel{

    protected 
$query;
    protected 
$original_query;
    protected 
$type;
    protected 
$date_interval;
    protected 
$three_symbol_search false;

    public function 
setQuery($query){

        
$query strip_tags(mb_strtolower(trim(urldecode($query))));

        
$this->original_query $query;

        
$this->query = array();

        
$stopwords string_get_stopwords(cmsCore::getLanguageName());

        if (
mb_strlen($query) == 3) {

            if(!
$stopwords || ($stopwords && !in_array($query$stopwords))){

                
$this->three_symbol_search true;

                
$this->query[] = $query;

                return 
true;

            }

            return 
false;

        }

        
$words explode(' '$query);

        foreach(
$words as $word){

            if (
mb_strlen($word)<3) { continue; }
            if(
$stopwords && in_array($word$stopwords)){ continue; }
            if (
mb_strlen($word)==3) { $this->query[] = $this->db->escape($word); continue; }

            if (
mb_strlen($word) >= 12) {
                
$word mb_substr($word0mb_strlen($word) - 4);
            } else if (
mb_strlen($word) >= 10) {
                
$word mb_substr($word0mb_strlen($word) - 3);
            } else if (
mb_strlen($word) >= 6) {
                
$word mb_substr($word0mb_strlen($word) - 2);
            } else {
                
$word mb_substr($word0mb_strlen($word) - 1);
            }

            
$this->query[] = $this->db->escape($word) . '*';

        }

        if (empty(
$this->query)) { return false; }

        return 
true;

    }

    public function 
setSearchType($type){
        
$this->type $type;
    }

    public function 
setDateInterval($date){
        
$this->date_interval $date;
    }

    public function 
getFullTextQuery(){

        
$ft_query '';

        switch (
$this->type){

            case 
'words':

                if (
$this->three_symbol_search) {

                    
$ft_query .= '%'.$this->db->escape($this->original_query).'%';

                } else {

                    
$ft_query .= '>"' $this->db->escape($this->original_query).'" <(';
                    
$ft_query .= '+' implode(' +'$this->query).')';

                }

                break;

            case 
'exact':

                if (
$this->three_symbol_search) {

                    
$ft_query .= $this->db->escape($this->original_query);

                } else {

                    
$ft_query .= '"' $this->db->escape($this->original_query) . '"';

                }

                break;

        }

        return 
$ft_query;

    }

    public function 
getSearchSQL($table_name$match_fields$select_fields$filters){

        
$match_fields  '`'.implode('`, `'$match_fields).'`';
        
$select_fields array_map(function($v){
            if(
is_numeric($v)){
                return 
$v;
            }
            return 
'`'.$v.'`';
        }, 
$select_fields);
        
$select_fields implode(', '$select_fields);

        
$query $this->getFullTextQuery();

        
$filter_sql '';

        if (
$this->date_interval != 'all'){

            switch (
$this->date_interval){
                case 
'w':
                    
$filter_sql .= "DATEDIFF(NOW(), date_pub) <= 7 AND ";
                    break;
                case 
'm':
                    
$filter_sql .= "DATE_SUB(NOW(), INTERVAL 1 MONTH) < date_pub AND ";
                    break;
                case 
'y':
                    
$filter_sql .= "DATE_SUB(NOW(), INTERVAL 1 YEAR) < date_pub AND ";
                    break;
            }

        }

        if(
$filters){
            
$_filter_sql = array();
            foreach (
$filters as $filter) {
                
$filter['value'] = $this->db->prepareValue($filter['field'], $filter['value']);
                
$_filter_sql[] = "`{$filter['field']}{$filter['condition']} {$filter['value']}";
            }
            
$filter_sql .= implode(' AND '$_filter_sql).' AND ';
        }

        if (
$this->three_symbol_search) {

            
$sql "SELECT {$select_fields}
                    FROM {#}
{$table_name}
                    WHERE 
{$filter_sql} CONCAT({$match_fields}) LIKE '{$query}'
                    "
;

        } else {

            if(
$select_fields == 1){

                
$sql "SELECT {$select_fields}
                        FROM {#}
{$table_name}
                        WHERE 
{$filter_sql} MATCH({$match_fields}) AGAINST ('{$query}' IN BOOLEAN MODE)
                        "
;

            } else {

                
$sql "SELECT {$select_fields}, MATCH({$match_fields}) AGAINST ('{$query}' IN BOOLEAN MODE) as fsort
                        FROM {#}
{$table_name}
                        WHERE 
{$filter_sql} MATCH({$match_fields}) AGAINST ('{$query}' IN BOOLEAN MODE)
                        ORDER BY fsort desc
                        "
;

            }

        }

        return 
$sql;

    }

    public function 
getSearchResultsCount($table_name$match_fields$filters){

        
$sql $this->getSearchSQL($table_name$match_fields, array('1'), $filters);

        
$sql_result $this->db->query($sql);

        return 
$this->db->numRows($sql_result);

    }

    public function 
getSearchResults($table_name$match_fields$select_fields$filters$item_callback=false$sources_name ''){

        
$sql $this->getSearchSQL($table_name$match_fields$select_fields$filters);

        if (
$this->limit){ $sql .= " LIMIT {$this->limit}"; }

        
$sql_result $this->db->query($sql);

        if (!
$this->db->numRows($sql_result)){
            return 
false;
        }

        
$items = array();

        while (
$item $this->db->fetchAssoc($sql_result)){

            foreach(
$match_fields as $field_name){
                
$item[$field_name] = $this->getHighlightedText($item[$field_name]);
            }

            if (
is_callable($item_callback)){
                
$item call_user_func_array($item_callback, array($item$this$sources_name$match_fields$select_fields));
                if (
$item === false){ continue; }
            }

            
$items[] = $item;

        }

        return 
$items;

    }

    public function 
getHighlightedText($text){

        
$text str_replace(array("n"'<br>''<br/>'), ' '$text);
        
$text strip_tags($text);
        
$text preg_replace('/s+/u'' '$text);

        
$found_words = array();
        
$found_sentences = array();

        foreach (
$this->query as $word){

            
$word preg_quote(rtrim($word'*'));

            if (
preg_match("/b({$word}w+)b/iu"$text$matches)){
                
$found_words[] = $matches[0];
            }

        }

        
$sentences explode('.'$text);
        
$sentences array_map(function($s){ return trim($s); }, $sentences);

        foreach(
$sentences as $sentence){
            
$is_found false;
            foreach(
$found_words as $word){
                if (
mb_strpos(mb_strtolower($sentence), mb_strtolower($word)) !== false){
                    
$sentence str_replace($word'<em>'.$word.'</em>'$sentence);
                    
$is_found true;
                }
            }
            if (
$is_found) { $found_sentences[] = $sentence; }
        }

        if (!
$found_sentences) { return $text; }

        
$found_sentences implode('... '$found_sentences);

        return 
$found_sentences.'...';

    }

}
Онлайн: 1
Реклама