Пример #1
0
 public static function search($search, $categories)
 {
     if (!$categories) {
         return;
     }
     $token_length = self::get_token_length();
     $limit = Base_SearchCommon::get_recordset_limit_records();
     $tabs_priority = DB::GetAssoc('SELECT id,search_priority FROM recordbrowser_table_properties WHERE search_include>0');
     $categories = array_intersect($categories, array_keys($tabs_priority));
     $categories = array_map(create_function('$a', 'return DB::qstr($a);'), $categories);
     $texts = array_filter(preg_split('/[^\\p{L}0-9]/u', mb_strtolower($search)));
     $total_results = array();
     $total_max_score = 0;
     foreach ($texts as $text) {
         //for each word
         $len = mb_strlen($text);
         if ($len < $token_length) {
             continue;
         }
         //if word is less then token lenght - ignore it
         $results = array();
         $max_score = $len - $token_length + 1;
         $total_max_score += $len;
         for ($i = 0; $i <= $len - $token_length; $i++) {
             $word = mb_substr($text, $i, $token_length);
             $ret = DB::Execute('SELECT m.tab_id,m.record_id,m.field_id,m.position FROM recordbrowser_words_index w INNER JOIN recordbrowser_words_map m ON w.id=m.word_id WHERE w.word=%s AND m.tab_id IN (' . implode(',', $categories) . ')', array($word));
             while ($row = $ret->FetchRow()) {
                 $score = 1;
                 for ($k = 1; $k <= $token_length + 1; $k++) {
                     if (isset($results[$row['tab_id']][$row['record_id']][$row['field_id']][$row['position'] - $k])) {
                         $score += $results[$row['tab_id']][$row['record_id']][$row['field_id']][$row['position'] - $k];
                         break;
                     }
                 }
                 $results[$row['tab_id']][$row['record_id']][$row['field_id']][$row['position']] = min($max_score, $score);
             }
         }
         foreach ($results as $tab_id => $records) {
             foreach ($records as $record => $fields) {
                 //get max score for each field... if max score is 50% or more equal save it
                 foreach ($fields as $field => $scores) {
                     $max_score_local = max($scores);
                     if ($max_score_local > $max_score / 2) {
                         $results[$tab_id][$record][$field] = $max_score_local;
                     } else {
                         unset($results[$tab_id][$record][$field]);
                     }
                 }
                 //if some fields was saved
                 if ($results[$tab_id][$record]) {
                     $max = 0;
                     //get max score of all fields where the "word" was found
                     $max_fields = array();
                     //get field names with maximal score
                     foreach ($results[$tab_id][$record] as $field => $score) {
                         if ($max < $score) {
                             $max = $score;
                             $max_fields = array($field);
                         } elseif ($max == $score) {
                             $max_fields[] = $field;
                         }
                     }
                     $max += $token_length - 1;
                     if (!isset($total_results[$tab_id . '#' . $record])) {
                         $total_results[$tab_id . '#' . $record] = array('score' => 0, 'fields' => array(), 'fields_score' => array(), 'priority' => $tabs_priority[$tab_id]);
                     }
                     $total_results[$tab_id . '#' . $record]['score'] += $max;
                     $total_results[$tab_id . '#' . $record]['fields_score'][] = $max;
                     $total_results[$tab_id . '#' . $record]['fields'][] = $max_fields;
                 } else {
                     unset($results[$tab_id][$record]);
                 }
             }
         }
         unset($results);
     }
     if ($total_max_score == 0) {
         Epesi::alert(__('Displaying only partial results - please enter at least one word of 3 or more letters'));
         return;
     }
     //sort with score... if score is the same sort with qty of fields where the "word" was found
     uasort($total_results, create_function('$a,$b', 'return $a["score"]>$b["score"]?-1:($a["score"]<$b["score"]?1:($a["priority"]>$b["priority"]?-1:($a["priority"]<$b["priority"]?1:($a["fields"]>$b["fields"]?-1:1))));'));
     $tabs = DB::GetAssoc('SELECT id,tab FROM recordbrowser_table_properties WHERE search_include>0');
     $ret = array();
     $cols_cache = array();
     $count = 0;
     foreach ($total_results as $rec => $score) {
         list($tab_id, $id) = explode('#', $rec, 2);
         $tab = $tabs[$tab_id];
         $record = self::get_record($tab, $id);
         //get fields names translations
         if (!isset($cols_cache[$tab])) {
             $table_rows = self::init($tab);
             $cols_cache[$tab] = array();
             foreach ($table_rows as $col) {
                 $cols_cache[$tab][$col['pkey']] = array('name' => $col['name'], 'id' => $col['id']);
             }
         }
         //get access
         $has_access = self::get_access($tab, 'view', $record);
         if (!$has_access) {
             continue;
         }
         //no access at all
         //if there are fields that should not be visible, remove them from results list and recalculate score
         foreach ($score['fields'] as $fields_group => $fields) {
             foreach ($fields as $field_pos => $field_id) {
                 if (isset($cols_cache[$tab][$field_id])) {
                     $field = $cols_cache[$tab][$field_id]['id'];
                 } else {
                     $field = '';
                 }
                 if (!isset($has_access[$field]) || !$has_access[$field]) {
                     unset($score['fields'][$fields_group][$field_pos]);
                 }
             }
             if (empty($score['fields'][$fields_group])) {
                 $score['score'] -= $score['fields_score'][$fields_group];
                 unset($score['fields'][$fields_group]);
                 unset($score['fields_score'][$fields_group]);
             }
         }
         if (!$score['fields']) {
             continue;
         }
         $fields = array();
         foreach ($score['fields'] as $fields_group) {
             foreach ($fields_group as $field) {
                 $fields[] = _V($cols_cache[$tab][$field]['name']);
             }
         }
         //create link with default label
         $ret[] = self::create_default_linked_label($tab, $id) . ' <span style="color: red">' . round($score['score'] * 100 / $total_max_score) . '%</span> (' . implode(', ', $fields) . ')';
         $count++;
         if ($count >= $limit) {
             break;
         }
     }
     return $ret;
 }
Пример #2
0
	public static function search($word, $types) {
	        if(!$types) return;
	        
	        $r = null;
                $limit = Base_SearchCommon::get_recordset_limit_records();
	        $ret = array();
                
                foreach($types as $type) {
                    if($type=='files') {
		        $r = DB::SelectLimit('SELECT ua.id,uaf.original,ual.func,ual.args,ual.local,ua.f_title FROM utils_attachment_data_1 ua INNER JOIN utils_attachment_local AS ual ON ual.attachment=ua.id INNER JOIN utils_attachment_file AS uaf ON uaf.attach_id=ua.id WHERE ua.active=1 AND '.
				' uaf.original '.DB::like().' '.DB::Concat(DB::qstr('%'),'%s',DB::qstr('%')).' AND uaf.deleted=0', $limit, -1, array($word));
                    } elseif($type=='downloads') {
                        if(strlen($word)==32) {
                            $query = 'SELECT ua.id,uaf.original,ual.func,ual.args,ual.local,ua.f_title FROM utils_attachment_file uaf INNER JOIN utils_attachment_download uad ON uad.attach_file_id=uaf.id INNER JOIN utils_attachment_data_1 ua ON uaf.attach_id=ua.id INNER JOIN utils_attachment_local AS ual ON ual.attachment=ua.id WHERE uad.token='.DB::qstr($word);
                            $r = DB::Execute($query);
                        } else {
                            $query = parse_url($word,PHP_URL_QUERY);
                            if($query) {
                                $vars = array();
                                parse_str($query,$vars);
                                if($vars && isset($vars['id']) && isset($vars['token'])) {
                                    $query = 'SELECT ua.id,uaf.original,ual.func,ual.args,ual.local,ua.f_title FROM utils_attachment_file uaf INNER JOIN utils_attachment_download uad ON uad.attach_file_id=uaf.id INNER JOIN utils_attachment_data_1 ua ON uaf.attach_id=ua.id INNER JOIN utils_attachment_local AS ual ON ual.attachment=ua.id WHERE uad.id='.DB::qstr($vars['id']).' AND uad.token='.DB::qstr($vars['token']);
                                    $r = DB::Execute($query);
                                }
                            }
                        }
                    }
                
                    if($r) {
		        while($row = $r->FetchRow()) {
		            if(!self::get_access($row['id'])) continue;
			    $func = unserialize($row['func']);
                            $record = $func ? call_user_func_array($func, unserialize($row['args'])) : '';
                            if(!$record) continue;
                            $title = $row['original'].' - '.self::description_callback(Utils_RecordBrowserCommon::get_record('utils_attachment',$row['id']));
                            $title = Utils_RecordBrowserCommon::record_link_open_tag('utils_attachment', $row['id'])
                                 . __('Files').': ' . $title
                                 . Utils_RecordBrowserCommon::record_link_close_tag();
                            $ret[$row['id'].'#'.$row['local']] = $title . " ($record)";
		        }
                    }
                }
                return $ret;
	}