Example #1
0
function search_text_in_db($searchstr, $base_sql, $where_search, $add_where = array(), $strict = false)
{
    global $db, $config;
    //$stopword_array = @file($root_path . 'languages/lang_' . $config['default_lang'] . '/search_stopwords.txt');
    //$synonym_array = @file($root_path . 'languages/lang_' . $config['default_lang'] . '/search_synonyms.txt');
    $match_types = array('or', 'not', 'and');
    $add_where = sizeof($add_where) ? ' AND ' . implode(' AND ', $add_where) : '';
    $cleansearchstr = searchfield($searchstr);
    $lower_searchstr = utf_strtolower($searchstr);
    if ($strict) {
        $split_search = array($lower_searchstr);
    } else {
        $split_search = split_words($cleansearchstr);
        if ($lower_searchstr != $searchstr) {
            $search_full_string = true;
            foreach ($match_types as $_null => $match_type) {
                if (strpos($lower_searchstr, $match_type) !== false) {
                    $search_full_string = false;
                }
            }
            if ($search_full_string) {
                $split_search[] = $lower_searchstr;
            }
        }
    }
    $word_count = 0;
    $current_match_type = 'and';
    $word_match = array();
    $result_list = array();
    for ($i = 0; $i < sizeof($split_search); $i++) {
        if (utf_strlen(str_replace(array('*', '%'), '', trim($split_search[$i]))) < $config['search_min_chars'] && !in_array($split_search[$i], $match_types)) {
            $split_search[$i] = '';
            continue;
        }
        switch ($split_search[$i]) {
            case 'and':
                $current_match_type = 'and';
                break;
            case 'or':
                $current_match_type = 'or';
                break;
            case 'not':
                $current_match_type = 'not';
                break;
            default:
                if (!empty($search_terms)) {
                    $current_match_type = 'and';
                }
                if ($strict) {
                    $search = $where_search . ' = \'' . sqlesc($split_search[$i]) . '\'' . $add_where;
                } else {
                    $match_word = str_replace('*', '%', $split_search[$i]);
                    $search = $where_search . ' LIKE \'%' . sqlesc($match_word) . '%\'' . $add_where;
                    //$search = $where_search . ' REGEXP \'[[:<:]]' . $db->sql_escape($match_word) . '[[:>:]]\'' . $add_where;
                }
                $sql = $base_sql . ' WHERE ' . $search;
                $result = sql_query($sql);
                $row = array();
                while ($temp_row = mysqli_fetch_row($result)) {
                    $row[$temp_row['id']] = 1;
                    if (!$word_count) {
                        $result_list[$temp_row['id']] = 1;
                    } else {
                        if ($current_match_type == 'or') {
                            $result_list[$temp_row['id']] = 1;
                        } else {
                            if ($current_match_type == 'not') {
                                $result_list[$temp_row['id']] = 0;
                            }
                        }
                    }
                }
                if ($current_match_type == 'and' && $word_count) {
                    @reset($result_list);
                    foreach ($result_list as $id => $match_count) {
                        if (!isset($row[$id]) || !$row[$id]) {
                            //$result_list[$id] = 0;
                            @($result_list[$id] -= 1);
                        } else {
                            @($result_list[$id] += 1);
                        }
                    }
                }
                $word_count++;
                mysqli_fetch_assoc($result);
        }
    }
    @reset($result_list);
    $search_ids = array();
    foreach ($result_list as $id => $matches) {
        if ($matches > 0) {
            //if ( $matches ) {
            $search_ids[] = $id;
        }
    }
    unset($result_list);
    return $search_ids;
}
Example #2
0
function update_search_index($mode, $post_id, $message, $subject = null)
{
    global $db_type;
    // Get Slim current session
    $feather = \Slim\Slim::getInstance();
    $message = utf8_strtolower($message);
    $subject = utf8_strtolower($subject);
    // Remove any bbcode that we shouldn't index
    $message = strip_bbcode($message);
    // Split old and new post/subject to obtain array of 'words'
    $words_message = split_words($message, true);
    $words_subject = $subject ? split_words($subject, true) : array();
    if ($mode == 'edit') {
        $select_update_search_index = array('w.id', 'w.word', 'm.subject_match');
        $result = \DB::for_table('search_words')->table_alias('w')->select_many($select_update_search_index)->inner_join('search_matches', array('w.id', '=', 'm.word_id'), 'm')->where('m.post_id', $post_id)->find_many();
        // Declare here to stop array_keys() and array_diff() from complaining if not set
        $cur_words['post'] = array();
        $cur_words['subject'] = array();
        foreach ($result as $row) {
            $match_in = $row['subject_match'] ? 'subject' : 'post';
            $cur_words[$match_in][$row['word']] = $row['id'];
        }
        $pdo = \DB::get_db();
        $pdo = null;
        $words['add']['post'] = array_diff($words_message, array_keys($cur_words['post']));
        $words['add']['subject'] = array_diff($words_subject, array_keys($cur_words['subject']));
        $words['del']['post'] = array_diff(array_keys($cur_words['post']), $words_message);
        $words['del']['subject'] = array_diff(array_keys($cur_words['subject']), $words_subject);
    } else {
        $words['add']['post'] = $words_message;
        $words['add']['subject'] = $words_subject;
        $words['del']['post'] = array();
        $words['del']['subject'] = array();
    }
    unset($words_message);
    unset($words_subject);
    // Get unique words from the above arrays
    $unique_words = array_unique(array_merge($words['add']['post'], $words['add']['subject']));
    if (!empty($unique_words)) {
        $select_unique_words = array('id', 'word');
        $result = \DB::for_table('search_words')->select_many($select_unique_words)->where_in('word', $unique_words)->find_many();
        $word_ids = array();
        foreach ($result as $row) {
            $word_ids[$row['word']] = $row['id'];
        }
        $pdo = \DB::get_db();
        $pdo = null;
        $new_words = array_values(array_diff($unique_words, array_keys($word_ids)));
        unset($unique_words);
        if (!empty($new_words)) {
            switch ($db_type) {
                case 'mysql':
                case 'mysqli':
                case 'mysql_innodb':
                case 'mysqli_innodb':
                    // Quite dirty, right? :-)
                    $placeholders = rtrim(str_repeat('(?), ', count($new_words)), ', ');
                    \DB::for_table('search_words')->raw_execute('INSERT INTO ' . $feather->prefix . 'search_words (word) VALUES ' . $placeholders, $new_words);
                    break;
                default:
                    foreach ($new_words as $word) {
                        $word_insert['word'] = $word;
                        \DB::for_table('search_words')->create()->set($word_insert)->save();
                    }
                    break;
            }
        }
        unset($new_words);
    }
    // Delete matches (only if editing a post)
    foreach ($words['del'] as $match_in => $wordlist) {
        $subject_match = $match_in == 'subject' ? 1 : 0;
        if (!empty($wordlist)) {
            $sql = array();
            foreach ($wordlist as $word) {
                $sql[] = $cur_words[$match_in][$word];
            }
            \DB::for_table('search_matches')->where_in('word_id', $sql)->where('post_id', $post_id)->where('subject_match', $subject_match)->delete_many();
        }
    }
    // Add new matches
    foreach ($words['add'] as $match_in => $wordlist) {
        $subject_match = $match_in == 'subject' ? 1 : 0;
        if (!empty($wordlist)) {
            $wordlist = array_values($wordlist);
            $placeholders = rtrim(str_repeat('?, ', count($wordlist)), ', ');
            \DB::for_table('search_words')->raw_execute('INSERT INTO ' . $feather->prefix . 'search_matches (post_id, word_id, subject_match) SELECT ' . $post_id . ', id, ' . $subject_match . ' FROM ' . $feather->prefix . 'search_words WHERE word IN (' . $placeholders . ')', $wordlist);
        }
    }
    unset($words);
}
Example #3
0
 function main($action)
 {
     global $template, $lang, $config, $pafiledb_config, $db, $images, $user;
     if (!$this->auth_global['auth_search']) {
         if (!$user->data['session_logged_in']) {
             redirect(append_sid(CMS_PAGE_LOGIN . '?redirect=dload.' . PHP_EXT . '&action=stats', true));
         }
         $message = sprintf($lang['Sorry_auth_search'], $this->auth_global['auth_search_type']);
         message_die(GENERAL_MESSAGE, $message);
     }
     include IP_ROOT_PATH . 'includes/functions_search.' . PHP_EXT;
     $search_keywords = request_var('search_keywords', '', true);
     $search_keywords = htmlspecialchars_decode($search_keywords, ENT_COMPAT);
     $search_author = request_var('search_author', '', true);
     $search_author = htmlspecialchars_decode($search_author, ENT_COMPAT);
     $search_id = request_var('search_id', 0);
     $search_terms = request_var('search_terms', '');
     $search_terms = $search_terms == 'all' ? 1 : 0;
     $cat_id = request_var('cat_id', 0);
     $comments_search = request_var('comments_search', '');
     $comments_search = $comments_search == 'YES' ? 1 : 0;
     $start = request_var('start', 0);
     $start = $start < 0 ? 0 : $start;
     $sort_method = request_var('sort_method', $pafiledb_config['sort_method']);
     $sort_method = check_var_value($sort_method, array('file_name', 'file_time', 'file_dls', 'file_rating', 'file_update_time'));
     $sort_method = $sort_method == 'file_rating' ? 'rating' : $sort_method;
     $sort_order = request_var('order', $pafiledb_config['sort_order']);
     $sort_order = check_var_value($sort_order, array('DESC', 'ASC'));
     $limit_sql = $start == 0 ? $pafiledb_config['settings_file_page'] : $start . ',' . $pafiledb_config['settings_file_page'];
     // encoding match for workaround
     $multibyte_charset = 'utf-8, big5, shift_jis, euc-kr, gb2312';
     if (isset($_POST['submit']) || $search_author != '' || $search_keywords != '' || $search_id) {
         $store_vars = array('search_results', 'total_match_count', 'split_search', 'sort_method', 'sort_order');
         if ($search_author != '' || $search_keywords != '') {
             if ($search_author != '' && $search_keywords == '') {
                 $search_author = str_replace('*', '%', trim($search_author));
                 $sql = get_users_sql($search_author, true, false, true, false);
                 $result = $db->sql_query($sql);
                 $matching_userids = '';
                 if ($row = $db->sql_fetchrow($result)) {
                     do {
                         $matching_userids .= ($matching_userids != '' ? ', ' : '') . $row['user_id'];
                     } while ($row = $db->sql_fetchrow($result));
                 } else {
                     message_die(GENERAL_MESSAGE, $lang['No_search_match']);
                 }
                 $sql = "SELECT *\n\t\t\t\t\t\tFROM " . PA_FILES_TABLE . "\n\t\t\t\t\t\tWHERE user_id IN ({$matching_userids})";
                 $result = $db->sql_query($sql);
                 $search_ids = array();
                 while ($row = $db->sql_fetchrow($result)) {
                     if ($this->auth[$row['file_catid']]['auth_view']) {
                         $search_ids[] = $row['file_id'];
                     }
                 }
                 $db->sql_freeresult($result);
                 $total_match_count = sizeof($search_ids);
             } elseif ($search_keywords != '') {
                 stopwords_synonyms_init();
                 $split_search = array();
                 $split_search = !strstr($multibyte_charset, $lang['ENCODING']) ? split_words(clean_words('search', stripslashes($search_keywords), $stopwords_array, $synonyms_array), 'search') : split(' ', $search_keywords);
                 $word_count = 0;
                 $current_match_type = 'or';
                 $word_match = array();
                 $result_list = array();
                 for ($i = 0; $i < sizeof($split_search); $i++) {
                     switch ($split_search[$i]) {
                         case 'and':
                             $current_match_type = 'and';
                             break;
                         case 'or':
                             $current_match_type = 'or';
                             break;
                         case 'not':
                             $current_match_type = 'not';
                             break;
                         default:
                             if (!empty($search_terms)) {
                                 $current_match_type = 'and';
                             }
                             $match_word = addslashes('%' . str_replace('*', '', $split_search[$i]) . '%');
                             $sql = "SELECT file_id\n\t\t\t\t\t\t\t\t\tFROM " . PA_FILES_TABLE . "\n\t\t\t\t\t\t\t\t\tWHERE (file_name LIKE '{$match_word}'\n\t\t\t\t\t\t\t\t\tOR file_creator LIKE '{$match_word}'\n\t\t\t\t\t\t\t\t\tOR file_desc LIKE '{$match_word}'\n\t\t\t\t\t\t\t\t\tOR file_longdesc LIKE '{$match_word}')";
                             $result = $db->sql_query($sql);
                             $row = array();
                             while ($temp_row = $db->sql_fetchrow($result)) {
                                 $row[$temp_row['file_id']] = 1;
                                 if (!$word_count) {
                                     $result_list[$temp_row['file_id']] = 1;
                                 } elseif ($current_match_type == 'or') {
                                     $result_list[$temp_row['file_id']] = 1;
                                 } elseif ($current_match_type == 'not') {
                                     $result_list[$temp_row['file_id']] = 0;
                                 }
                             }
                             if ($current_match_type == 'and' && $word_count) {
                                 @reset($result_list);
                                 while (list($file_id, $match_count) = @each($result_list)) {
                                     if (!$row[$file_id]) {
                                         $result_list[$file_id] = 0;
                                     }
                                 }
                             }
                             if ($comments_search) {
                                 $sql = "SELECT file_id\n\t\t\t\t\t\t\t\t\tFROM " . PA_COMMENTS_TABLE . "\n\t\t\t\t\t\t\t\t\tWHERE (comments_title LIKE '{$match_word}'\n\t\t\t\t\t\t\t\t\tOR comments_text LIKE '{$match_word}')";
                                 $result = $db->sql_query($sql);
                                 $row = array();
                                 while ($temp_row = $db->sql_fetchrow($result)) {
                                     $row[$temp_row['file_id']] = 1;
                                     if (!$word_count) {
                                         $result_list[$temp_row['file_id']] = 1;
                                     } else {
                                         if ($current_match_type == 'or') {
                                             $result_list[$temp_row['file_id']] = 1;
                                         } else {
                                             if ($current_match_type == 'not') {
                                                 $result_list[$temp_row['file_id']] = 0;
                                             }
                                         }
                                     }
                                 }
                                 if ($current_match_type == 'and' && $word_count) {
                                     @reset($result_list);
                                     while (list($file_id, $match_count) = @each($result_list)) {
                                         if (!$row[$file_id]) {
                                             $result_list[$file_id] = 0;
                                         }
                                     }
                                 }
                             }
                             $word_count++;
                             $db->sql_freeresult($result);
                     }
                 }
                 @reset($result_list);
                 $search_ids = array();
                 while (list($file_id, $matches) = each($result_list)) {
                     if ($matches) {
                         $search_ids[] = $file_id;
                     }
                 }
                 unset($result_list);
                 $total_match_count = sizeof($search_ids);
             }
             // Author name search
             if ($search_author != '') {
                 $search_author = str_replace('*', '%', trim($db->sql_escape($search_author)));
             }
             if ($total_match_count) {
                 $where_sql = $cat_id ? 'AND file_catid IN (' . $this->gen_cat_ids($cat_id, '') . ')' : '';
                 if ($search_author == '') {
                     $sql = "SELECT file_id, file_catid\n\t\t\t\t\t\t\tFROM " . PA_FILES_TABLE . "\n\t\t\t\t\t\t\tWHERE file_id IN (" . implode(", ", $search_ids) . ")\n\t\t\t\t\t\t\t\t{$where_sql}\n\t\t\t\t\t\t\tGROUP BY file_id";
                 } else {
                     $from_sql = PA_FILES_TABLE . " f";
                     if ($search_author != '') {
                         $from_sql .= ", " . USERS_TABLE . " u";
                         $where_sql .= " AND u.user_id = f.user_id AND u.username LIKE '{$search_author}' ";
                     }
                     $where_sql .= $cat_id ? 'AND file_catid IN (' . $this->gen_cat_ids($cat_id, '') . ')' : '';
                     $sql = "SELECT f.file_id, f.file_catid\n\t\t\t\t\t\t\tFROM {$from_sql}\n\t\t\t\t\t\t\tWHERE f.file_id IN (" . implode(", ", $search_ids) . ")\n\t\t\t\t\t\t\t{$where_sql}\n\t\t\t\t\t\t\tGROUP BY f.file_id";
                 }
                 $result = $db->sql_query($sql);
                 $search_ids = array();
                 while ($row = $db->sql_fetchrow($result)) {
                     if ($this->auth[$row['file_catid']]['auth_view']) {
                         $search_ids[] = $row['file_id'];
                     }
                 }
                 $db->sql_freeresult($result);
                 $total_match_count = sizeof($search_ids);
             } else {
                 message_die(GENERAL_MESSAGE, $lang['No_search_match']);
             }
             //
             // Finish building query (for all combinations)
             // and run it ...
             //
             $expiry_time = $current_time - $config['session_length'];
             $sql = "SELECT session_id\n\t\t\t\t\tFROM " . SESSIONS_TABLE . "\n\t\t\t\t\tWHERE session_time > {$expiry_time}";
             $db->sql_return_on_error(true);
             $result = $db->sql_query($sql);
             $db->sql_return_on_error(false);
             if ($result) {
                 $delete_search_ids = array();
                 while ($row = $db->sql_fetchrow($result)) {
                     $delete_search_ids[] = "'" . $row['session_id'] . "'";
                 }
                 if (sizeof($delete_search_ids)) {
                     $sql = "DELETE FROM " . SEARCH_TABLE . "\n\t\t\t\t\t\t\tWHERE session_id NOT IN (" . implode(", ", $delete_search_ids) . ")";
                     $result = $db->sql_query($sql);
                 }
             }
             // Store new result data
             $search_results = implode(', ', $search_ids);
             $store_search_data = array();
             for ($i = 0; $i < sizeof($store_vars); $i++) {
                 $store_search_data[$store_vars[$i]] = ${$store_vars}[$i];
             }
             $result_array = serialize($store_search_data);
             unset($store_search_data);
             mt_srand((double) microtime() * 1000000);
             $search_id = mt_rand();
             $sql = "UPDATE " . SEARCH_TABLE . "\n\t\t\t\t\tSET search_id = {$search_id}, search_array = '" . $db->sql_escape($result_array) . "'\n\t\t\t\t\tWHERE session_id = '" . $user->data['session_id'] . "'";
             $db->sql_return_on_error(true);
             $result = $db->sql_query($sql);
             $db->sql_return_on_error(false);
             if (!$result || !$db->sql_affectedrows()) {
                 $sql = "INSERT INTO " . SEARCH_TABLE . " (search_id, session_id, search_array)\n\t\t\t\t\t\tVALUES({$search_id}, '" . $user->data['session_id'] . "', '" . $db->sql_escape($result_array) . "')";
                 $result = $db->sql_query($sql);
             }
         } else {
             $search_id = intval($search_id);
             if ($search_id) {
                 $sql = "SELECT search_array\n\t\t\t\t\t\tFROM " . SEARCH_TABLE . "\n\t\t\t\t\t\tWHERE search_id = {$search_id}\n\t\t\t\t\t\tAND session_id = '" . $user->data['session_id'] . "'";
                 $result = $db->sql_query($sql);
                 if ($row = $db->sql_fetchrow($result)) {
                     $search_data = unserialize($row['search_array']);
                     for ($i = 0; $i < sizeof($store_vars); $i++) {
                         ${$store_vars}[$i] = $search_data[$store_vars[$i]];
                     }
                 }
             }
         }
         if ($search_results != '') {
             $sql = "SELECT f1.*, AVG(r.rate_point) AS rating, COUNT(r.votes_file) AS total_votes, u.user_id, u.username, u.user_active, u.user_color, c.cat_id, c.cat_name, COUNT(cm.comments_id) AS total_comments\n\t\t\t\t\tFROM (" . PA_FILES_TABLE . " AS f1, " . PA_CATEGORY_TABLE . " AS c)\n\t\t\t\t\t\tLEFT JOIN " . PA_VOTES_TABLE . " AS r ON f1.file_id = r.votes_file\n\t\t\t\t\t\tLEFT JOIN " . USERS_TABLE . " AS u ON f1.user_id = u.user_id\n\t\t\t\t\t\tLEFT JOIN " . PA_COMMENTS_TABLE . " AS cm ON f1.file_id = cm.file_id\n\t\t\t\t\tWHERE f1.file_id IN ({$search_results})\n\t\t\t\t\tAND c.cat_id = f1.file_catid\n\t\t\t\t\tAND f1.file_approved = '1'\n\t\t\t\t\tGROUP BY f1.file_id\n\t\t\t\t\tORDER BY {$sort_method} {$sort_order}\n\t\t\t\t\tLIMIT {$limit_sql}";
             $result = $db->sql_query($sql);
             $searchset = array();
             while ($row = $db->sql_fetchrow($result)) {
                 $searchset[] = $row;
             }
             $db->sql_freeresult($result);
             $l_search_matches = $total_match_count == 1 ? sprintf($lang['Found_search_match'], $total_match_count) : sprintf($lang['Found_search_matches'], $total_match_count);
             $template->assign_vars(array('L_SEARCH_MATCHES' => $l_search_matches));
             for ($i = 0; $i < sizeof($searchset); $i++) {
                 $cat_url = append_sid('dload.' . PHP_EXT . '?action=category&amp;cat_id=' . $searchset[$i]['cat_id']);
                 $file_url = append_sid('dload.' . PHP_EXT . '?action=file&amp;file_id=' . $searchset[$i]['file_id']);
                 //===================================================
                 // Format the date for the given file
                 //===================================================
                 $date = create_date_ip($config['default_dateformat'], $searchset[$i]['file_time'], $config['board_timezone']);
                 //===================================================
                 // Get rating for the file and format it
                 //===================================================
                 //$rating = ($searchset[$i]['rating'] != 0) ? round($searchset[$i]['rating'], 2) . ' / 10' : $lang['Not_rated'];
                 //$rating2 = ($searchset[$i]['rating'] != 0) ? sprintf("%.1f", round(($searchset[$i]['rating']), 2) / 2) : '0.0';
                 $rating2 = $searchset[$i]['rating'] != 0 ? sprintf("%.1f", round($searchset[$i]['rating'], 0) / 2) : '0.0';
                 //===================================================
                 // If the file is new then put a new image in front of it
                 //===================================================
                 $is_new = false;
                 if (time() - $pafiledb_config['settings_newdays'] * 24 * 60 * 60 < $searchset[$i]['file_time']) {
                     $is_new = true;
                 }
                 $xs_new = $is_new ? '-new' : '';
                 //===================================================
                 // Get the post icon fot this file
                 //===================================================
                 if ($searchset[$i]['file_pin'] != FILE_PINNED) {
                     if ($searchset[$i]['file_posticon'] == 'none' || $searchset[$i]['file_posticon'] == 'none.gif') {
                         $posticon = '<img src="' . IP_ROOT_PATH . FILES_ICONS_DIR . 'default.png" alt="" />';
                         //$posticon = '&nbsp;';
                     } else {
                         $posticon = '<img src="' . FILES_ICONS_DIR . $searchset[$i]['file_posticon'] . '" alt="" />';
                     }
                 } else {
                     $posticon = '<img src="' . $images['forum_link'] . '" alt="" />';
                 }
                 $poster = $searchset[$i]['user_id'] == ANONYMOUS ? $lang['Guest'] : colorize_username($searchset[$i]['user_id'], $searchset[$i]['username'], $searchset[$i]['user_color'], $searchset[$i]['user_active']);
                 $template->assign_block_vars('searchresults', array('CAT_NAME' => $searchset[$i]['cat_name'], 'FILE_NEW_IMAGE' => $images['pa_file_new'], 'PIN_IMAGE' => $posticon, 'L_HOME' => $lang['Home'], 'CURRENT_TIME' => sprintf($lang['Current_time'], create_date($config['default_dateformat'], time(), $config['board_timezone'])), 'XS_NEW' => $xs_new, 'IS_NEW_FILE' => $is_new, 'FILE_NAME' => $searchset[$i]['file_name'], 'FILE_DESC' => $searchset[$i]['file_desc'], 'FILE_SUBMITER' => $poster, 'DATE' => $date, 'RATING' => $rating2, 'DOWNLOADS' => $searchset[$i]['file_dls'], 'U_FILE' => $file_url, 'U_CAT' => $cat_url));
             }
             $base_url = append_sid('dload.' . PHP_EXT . '?action=search&amp;search_id=' . $search_id);
             $template->assign_vars(array('PAGINATION' => generate_pagination($base_url, $total_match_count, $pafiledb_config['settings_file_page'], $start), 'PAGE_NUMBER' => sprintf($lang['Page_of'], floor($start / $pafiledb_config['settings_file_page']) + 1, ceil($total_match_count / $pafiledb_config['settings_file_page'])), 'DOWNLOAD' => $pafiledb_config['settings_dbname'], 'L_HOME' => $lang['Home'], 'U_INDEX_HOME' => append_sid(CMS_PAGE_HOME), 'U_DOWNLOAD' => append_sid('dload.' . PHP_EXT), 'L_HOME' => $lang['Home'], 'CURRENT_TIME' => sprintf($lang['Current_time'], create_date($config['default_dateformat'], time(), $config['board_timezone'])), 'XS_NEW' => $xs_new, 'L_INDEX' => sprintf($lang['Forum_Index'], $config['sitename']), 'L_RATE' => $lang['DlRating'], 'L_DOWNLOADS' => $lang['Dls'], 'L_DATE' => $lang['Date'], 'L_NAME' => $lang['Name'], 'L_FILE' => $lang['File'], 'L_SUBMITER' => $lang['Submiter'], 'L_CATEGORY' => $lang['Category'], 'L_NEW_FILE' => $lang['New_file']));
             $this->display($lang['Download'], 'pa_search_result.tpl');
         } else {
             message_die(GENERAL_MESSAGE, $lang['No_search_match']);
         }
     }
     if (!isset($_POST['submit']) || $search_author == '' && $search_keywords == '' && !$search_id) {
         $dropmenu = $this->jumpmenu_option();
         $template->assign_vars(array('S_SEARCH_ACTION' => append_sid('dload.php'), 'S_CAT_MENU' => $dropmenu, 'DOWNLOAD' => $pafiledb_config['settings_dbname'], 'U_INDEX_HOME' => append_sid(CMS_PAGE_HOME), 'U_DOWNLOAD' => append_sid('dload.' . PHP_EXT), 'L_HOME' => $lang['Home'], 'CURRENT_TIME' => sprintf($lang['Current_time'], create_date($config['default_dateformat'], time(), $config['board_timezone'])), 'XS_NEW' => $xs_new, 'L_YES' => $lang['Yes'], 'L_NO' => $lang['No'], 'L_SEARCH_OPTIONS' => $lang['Search_options'], 'L_SEARCH_KEYWORDS' => $lang['Search_keywords'], 'L_SEARCH_KEYWORDS_EXPLAIN' => $lang['Search_keywords_explain'], 'L_SEARCH_AUTHOR' => $lang['Search_author'], 'L_SEARCH_AUTHOR_EXPLAIN' => $lang['Search_author_explain'], 'L_SEARCH_ANY_TERMS' => $lang['Search_for_any'], 'L_SEARCH_ALL_TERMS' => $lang['Search_for_all'], 'L_INCLUDE_COMMENTS' => $lang['Include_comments'], 'L_SORT_BY' => $lang['Select_sort_method'], 'L_SORT_DIR' => $lang['Order'], 'L_SORT_ASCENDING' => $lang['Sort_Ascending'], 'L_SORT_DESCENDING' => $lang['Sort_Descending'], 'L_INDEX' => sprintf($lang['Forum_Index'], $config['sitename']), 'L_RATING' => $lang['DlRating'], 'L_DOWNLOADS' => $lang['Dls'], 'L_DATE' => $lang['Date'], 'L_NAME' => $lang['Name'], 'L_UPDATE_TIME' => $lang['Update_time'], 'L_SEARCH' => $lang['Search'], 'L_SEARCH_FOR' => $lang['Search_for'], 'L_ALL' => $lang['All'], 'L_CHOOSE_CAT' => $lang['Choose_cat']));
         $this->display($lang['Download'], 'pa_search_body.tpl');
     }
 }
Example #4
0
function add_search_words($mode, $post_id, $post_text, $post_title = '')
{
    global $db, $phpbb_root_path, $board_config, $lang;
    $stopword_array = @file($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . "/search_stopwords.txt");
    $synonym_array = @file($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . "/search_synonyms.txt");
    $search_raw_words = array();
    $search_raw_words['text'] = split_words(clean_words('post', $post_text, $stopword_array, $synonym_array));
    $search_raw_words['title'] = split_words(clean_words('post', $post_title, $stopword_array, $synonym_array));
    @set_time_limit(0);
    $word = array();
    $word_insert_sql = array();
    while (list($word_in, $search_matches) = @each($search_raw_words)) {
        $word_insert_sql[$word_in] = '';
        if (!empty($search_matches)) {
            for ($i = 0; $i < count($search_matches); $i++) {
                $search_matches[$i] = trim($search_matches[$i]);
                if ($search_matches[$i] != '') {
                    $word[] = $search_matches[$i];
                    if (!strstr($word_insert_sql[$word_in], "'" . $search_matches[$i] . "'")) {
                        $word_insert_sql[$word_in] .= $word_insert_sql[$word_in] != "" ? ", '" . $search_matches[$i] . "'" : "'" . $search_matches[$i] . "'";
                    }
                }
            }
        }
    }
    if (count($word)) {
        sort($word);
        $prev_word = '';
        $word_text_sql = '';
        $temp_word = array();
        for ($i = 0; $i < count($word); $i++) {
            if ($word[$i] != $prev_word) {
                $temp_word[] = $word[$i];
                $word_text_sql .= ($word_text_sql != '' ? ', ' : '') . "'" . $word[$i] . "'";
            }
            $prev_word = $word[$i];
        }
        $word = $temp_word;
        $check_words = array();
        switch (SQL_LAYER) {
            case 'postgresql':
            case 'msaccess':
            case 'mssql-odbc':
            case 'oracle':
            case 'db2':
                $sql = "SELECT word_id, word_text\r\n                                        FROM " . SEARCH_WORD_TABLE . "\r\n                                        WHERE word_text IN ({$word_text_sql})";
                if (!($result = $db->sql_query($sql))) {
                    message_die(GENERAL_ERROR, 'Could not select words', '', __LINE__, __FILE__, $sql);
                }
                while ($row = $db->sql_fetchrow($result)) {
                    $check_words[$row['word_text']] = $row['word_id'];
                }
                break;
        }
        $value_sql = '';
        $match_word = array();
        for ($i = 0; $i < count($word); $i++) {
            $new_match = true;
            if (isset($check_words[$word[$i]])) {
                $new_match = false;
            }
            if ($new_match) {
                switch (SQL_LAYER) {
                    case 'mysql':
                    case 'mysql4':
                        $value_sql .= ($value_sql != '' ? ', ' : '') . '(\'' . $word[$i] . '\', 0)';
                        break;
                    case 'mssql':
                    case 'mssql-odbc':
                        $value_sql .= ($value_sql != '' ? ' UNION ALL ' : '') . "SELECT '" . $word[$i] . "', 0";
                        break;
                    default:
                        $sql = "INSERT INTO " . SEARCH_WORD_TABLE . " (word_text, word_common)\r\n                                                        VALUES ('" . $word[$i] . "', '0')";
                        if (!$db->sql_query($sql)) {
                            message_die(GENERAL_ERROR, 'Could not insert new word', '', __LINE__, __FILE__, $sql);
                        }
                        break;
                }
            }
        }
        if ($value_sql != '') {
            switch (SQL_LAYER) {
                case 'mysql':
                case 'mysql4':
                    $sql = "INSERT IGNORE INTO " . SEARCH_WORD_TABLE . " (word_text, word_common)\r\n                                                VALUES {$value_sql}";
                    break;
                case 'mssql':
                case 'mssql-odbc':
                    $sql = "INSERT INTO " . SEARCH_WORD_TABLE . " (word_text, word_common)\r\n                                                {$value_sql}";
                    break;
            }
            if (!$db->sql_query($sql)) {
                message_die(GENERAL_ERROR, 'Could not insert new word', '', __LINE__, __FILE__, $sql);
            }
        }
    }
    while (list($word_in, $match_sql) = @each($word_insert_sql)) {
        $title_match = $word_in == 'title' ? 1 : 0;
        if ($match_sql != '') {
            $sql = "INSERT INTO " . SEARCH_MATCH_TABLE . " (post_id, word_id, title_match)\r\n                                SELECT {$post_id}, word_id, {$title_match}\r\n                                        FROM " . SEARCH_WORD_TABLE . "\r\n                                        WHERE word_text IN ({$match_sql})";
            if (!$db->sql_query($sql)) {
                message_die(GENERAL_ERROR, 'Could not insert new word matches', '', __LINE__, __FILE__, $sql);
            }
        }
    }
    if ($mode == 'single') {
        remove_common('single', 4 / 10, $word);
    }
    return;
}
Example #5
0
/**
* Get similar topics
* If user is guest or bot it will create a cache list in topics table to save some SQL charge
*/
function get_similar_topics($similar_forums_auth, $topic_id, $topic_title, $similar_topics_ids = '', $topic_desc = '')
{
    global $db, $config, $user, $lang;
    $similar_topics = array();
    if ($similar_topics_ids !== '' && (!$user->data['session_logged_in'] || $user->data['is_bot'])) {
        if ($similar_topics_ids == 'empty') {
            return $similar_topics;
        }
        $topics_array = $similar_topics_ids;
        $sql = "SELECT t.*, u.user_id, u.username, u.user_active, u.user_color, u2.username as user2, u2.user_id as id2, u2.user_active as user_active2, u2.user_color as user_color2, f.forum_id, f.forum_name, p.post_time, p.post_username\n\t\t\t\t\tFROM " . TOPICS_TABLE . " t, " . USERS_TABLE . " u, " . FORUMS_TABLE . " f, " . POSTS_TABLE . " p, " . USERS_TABLE . " u2\n\t\t\t\t\tWHERE t.topic_id IN (" . $topics_array . ")\n\t\t\t\t\t\tAND t.forum_id = f.forum_id\n\t\t\t\t\t\tAND p.poster_id = u2.user_id\n\t\t\t\t\t\tAND p.post_id = t.topic_last_post_id\n\t\t\t\t\t\tAND t.topic_poster = u.user_id\n\t\t\t\t\t\tAND t.topic_status <> " . TOPIC_MOVED . "\n\t\t\t\t\tGROUP BY t.topic_id\n\t\t\t\t\tORDER BY p.post_time";
        $result = $db->sql_query($sql);
        $similar_topics = $db->sql_fetchrowset($result);
        $db->sql_freeresult($result);
        return $similar_topics;
    }
    if ($config['similar_ignore_forums_ids']) {
        $ignore_forums_ids = array_map('intval', explode("\n", trim($config['similar_ignore_forums_ids'])));
    } else {
        $ignore_forums_ids = array();
    }
    // Get forum auth information to insure privacy of hidden topics
    $forums_auth_sql = '';
    //foreach ($similar_forums_auth as $k=>$v)
    //$similar_forums_auth = auth(AUTH_ALL, AUTH_LIST_ALL, $user->data);
    foreach ($similar_forums_auth as $k => $v) {
        if (sizeof($ignore_forums_ids) && in_array($k, $ignore_forums_ids)) {
            continue;
        }
        if ($v['auth_view'] && $v['auth_read']) {
            $forums_auth_sql .= ($forums_auth_sql == '' ? '' : ', ') . $k;
        }
    }
    if ($forums_auth_sql != '') {
        $forums_auth_sql = ' AND t.forum_id IN (' . $forums_auth_sql . ') ';
    }
    if ($config['similar_stopwords']) {
        // encoding match for workaround
        $multibyte_charset = 'utf-8, big5, shift_jis, euc-kr, gb2312';
        // check against stopwords start
        @(include_once IP_ROOT_PATH . 'includes/functions_search.' . PHP_EXT);
        stopwords_synonyms_init();
        $synonyms_array = array();
        // check against stopwords end
        $title_search = '';
        $title_search_array = !strstr($multibyte_charset, $lang['ENCODING']) ? split_words(clean_words('post', $topic_title, $stopwords_array, $synonyms_array), 'search') : split(' ', $topic_title);
        for ($i = 0; $i < sizeof($title_search_array); $i++) {
            $title_search .= ($title_search == '' ? '' : ' ') . $title_search_array[$i];
        }
    } else {
        $title_search = $topic_title;
    }
    /*
    if (!empty($topic_desc) && $config['similar_topicdesc'])
    {
    	if ($config['similar_stopwords'])
    	{
    		$topicdesc = '';
    		$topic_desc_array = (!strstr($multibyte_charset, $lang['ENCODING'])) ? split_words(clean_words('post', $topic_desc, $stopwords_array, $synonyms_array), 'search') : split(' ', $topic_desc);
    		for ($i = 0; $i < sizeof($topic_desc_array); $i++)
    		{
    			$topicdesc .= (($topicdesc == '') ? '': ' ') . $topic_desc_array[$i];
    		}
    	}
    	else
    	{
    		$topicdesc = $topic_desc;
    	}
    	$sql_topic_desc = "+MATCH(t.topic_desc) AGAINST('" . $db->sql_escape($topicdesc) . "')";
    }
    
    $sql_match = "MATCH(t.topic_title) AGAINST('" . $db->sql_escape($title_search) . "')" . $sql_topic_desc;
    */
    $sql_match = "MATCH(t.topic_title) AGAINST('" . $db->sql_escape($title_search) . "')";
    if ($config['similar_sort_type'] == 'time') {
        $sql_sort = 'p.post_time';
    } else {
        $sql_sort = 'relevance';
    }
    //ORDER BY t.topic_type DESC, ' . $sql_sort . ' DESC LIMIT 0,' . intval($config['similar_max_topics']);
    $sql = "SELECT t.*, u.user_id, u.username, u.user_active, u.user_color, u2.username as user2, u2.user_id as id2, u2.user_active as user_active2, u2.user_color as user_color2, f.forum_id, f.forum_name, p.post_time, p.post_username, {$sql_match} as relevance\n\t\t\t\tFROM " . TOPICS_TABLE . " t, " . USERS_TABLE . " u, " . FORUMS_TABLE . " f, " . POSTS_TABLE . " p, " . USERS_TABLE . " u2\n\t\t\t\tWHERE t.topic_id <> {$topic_id} {$forums_auth_sql}\n\t\t\t\t\tAND {$sql_match}\n\t\t\t\t\tAND t.forum_id = f.forum_id\n\t\t\t\t\tAND p.poster_id = u2.user_id\n\t\t\t\t\tAND p.post_id = t.topic_last_post_id\n\t\t\t\t\tAND t.topic_poster = u.user_id\n\t\t\t\t\tAND t.topic_status <> " . TOPIC_MOVED . "\n\t\t\t\tGROUP BY t.topic_id\n\t\t\t\tORDER BY " . $sql_sort . " DESC LIMIT 0," . intval($config['similar_max_topics']);
    $result = $db->sql_query($sql);
    $similar_topics = $db->sql_fetchrowset($result);
    $db->sql_freeresult($result);
    $count_similar = sizeof($similar_topics);
    if (!$user->data['session_logged_in'] || $user->data['is_bot']) {
        $similar_ids_array = 'empty';
        if (!empty($count_similar)) {
            $similar_ids_array = '';
            for ($i = 0; $i < $count_similar; $i++) {
                $similar_ids_array .= (empty($similar_ids_array) ? '' : ',') . $similar_topics[$i]['topic_id'];
            }
        }
        $sql = "UPDATE " . TOPICS_TABLE . " SET topic_similar_topics = '" . $similar_ids_array . "' WHERE topic_id = " . $topic_id;
        $result = $db->sql_query($sql);
    }
    return $similar_topics;
}
Example #6
0
         }
     }
     if (!($result = $db->sql_query($sql))) {
         message_die(GENERAL_ERROR, 'Could not obtain matched posts list', '', __LINE__, __FILE__, $sql);
     }
     $search_ids = array();
     while ($row = $db->sql_fetchrow($result)) {
         $search_ids[] = $row['post_id'];
     }
     $db->sql_freeresult($result);
     $total_match_count = count($search_ids);
 } else {
     if ($search_keywords != '') {
         $stopword_array = file('language/' . $board_config['default_lang'] . '/Forums/search_stopwords.txt');
         $synonym_array = file('language/' . $board_config['default_lang'] . '/Forums/search_synonyms.txt');
         $split_search = !strstr($multibyte_charset, $lang['ENCODING']) ? split_words(clean_words('search', $search_keywords, $stopword_array, $synonym_array), 'search') : split(' ', $search_keywords);
         $search_msg_only = !$search_fields ? "AND m.title_match = 0" : (strstr($multibyte_charset, $lang['ENCODING']) ? '' : '');
         $word_count = 0;
         $current_match_type = 'or';
         $word_match = array();
         $result_list = array();
         for ($i = 0; $i < count($split_search); $i++) {
             if (preg_match('#^[\\*%]+$#', trim($split_search[$i])) || preg_match('#^[^\\*]{1,2}$#', str_replace(array('*', '%'), '', trim($split_search[$i])))) {
                 $split_search[$i] = '';
                 continue;
             }
             switch ($split_search[$i]) {
                 case 'and':
                     $current_match_type = 'and';
                     break;
                 case 'or':
Example #7
0
function add_search_words($mode, $post_id, $post_text, $post_title = '')
{
    $stopword_array = @file("core/lib/phpbb/search_stopwords.txt");
    $synonym_array = @file("core/lib/phpbb/search_synonyms.txt");
    $search_raw_words = array();
    $search_raw_words['text'] = split_words(clean_words('post', $post_text, $stopword_array, $synonym_array));
    $search_raw_words['title'] = split_words(clean_words('post', $post_title, $stopword_array, $synonym_array));
    @set_time_limit(0);
    $word = array();
    $word_insert_sql = array();
    while (list($word_in, $search_matches) = @each($search_raw_words)) {
        $word_insert_sql[$word_in] = '';
        if (!empty($search_matches)) {
            for ($i = 0; $i < count($search_matches); $i++) {
                $search_matches[$i] = trim($search_matches[$i]);
                if ($search_matches[$i] != '') {
                    $word[] = $search_matches[$i];
                    if (!strstr($word_insert_sql[$word_in], "'" . $search_matches[$i] . "'")) {
                        $word_insert_sql[$word_in] .= $word_insert_sql[$word_in] != "" ? ", '" . $search_matches[$i] . "'" : "'" . $search_matches[$i] . "'";
                    }
                }
            }
        }
    }
    if (count($word)) {
        sort($word);
        $prev_word = '';
        $word_text_sql = '';
        $temp_word = array();
        for ($i = 0; $i < count($word); $i++) {
            if ($word[$i] != $prev_word) {
                $temp_word[] = $word[$i];
                $word_text_sql .= ($word_text_sql != '' ? ', ' : '') . "'" . $word[$i] . "'";
            }
            $prev_word = $word[$i];
        }
        $word = $temp_word;
        $check_words = array();
        $value_sql = '';
        $match_word = array();
        for ($i = 0; $i < count($word); $i++) {
            $new_match = true;
            if (isset($check_words[$word[$i]])) {
                $new_match = false;
            }
            if ($new_match) {
                $value_sql .= ($value_sql != '' ? ', ' : '') . '(\'' . $word[$i] . '\', 0)';
            }
        }
        if ($value_sql != '') {
            $sql = "INSERT IGNORE INTO `z_phpbb_search_wordlist` (word_text, word_common) \n                VALUES {$value_sql}";
            mysql_query($sql);
        }
    }
    while (list($word_in, $match_sql) = @each($word_insert_sql)) {
        $title_match = $word_in == 'title' ? 1 : 0;
        if ($match_sql != '') {
            $sql = "INSERT INTO z_phpbb_search_wordmatch (post_id, word_id, title_match) \n                SELECT {$post_id}, word_id, {$title_match}  \n                FROM z_phpbb_search_wordlist \n                WHERE word_text IN ({$match_sql})";
            mysql_query($sql);
        }
    }
    if ($mode == 'single') {
        remove_common('single', 4 / 10, $word);
    }
    return;
}
Example #8
0
function update_search_index($mode, $post_id, $message, $subject = null)
{
    global $db_type, $forum_db;
    $return = ($hook = get_hook('si_fn_update_search_index_start')) ? eval($hook) : null;
    if ($return != null) {
        return;
    }
    $message = utf8_strtolower($message);
    $subject = utf8_strtolower($subject);
    // Split old and new post/subject to obtain array of 'words'
    $words_message = split_words($message);
    $words_subject = empty($subject) ? array() : split_words($subject);
    if ($mode == 'edit') {
        $query = array('SELECT' => 'w.id, w.word, m.subject_match', 'FROM' => 'search_words AS w', 'JOINS' => array(array('INNER JOIN' => 'search_matches AS m', 'ON' => 'w.id=m.word_id')), 'WHERE' => 'm.post_id=' . $post_id);
        ($hook = get_hook('si_fn_update_search_index_qr_get_current_words')) ? eval($hook) : null;
        $result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
        // Declare here to stop array_keys() and array_diff() from complaining if not set
        $cur_words = array('post' => array(), 'subject' => array());
        while ($row = $forum_db->fetch_assoc($result)) {
            $cur_words[$row['subject_match'] == 1 ? 'subject' : 'post'][$row['word']] = $row['id'];
        }
        $forum_db->free_result($result);
        $words = array('add' => array('post' => array_diff($words_message, array_keys($cur_words['post'])), 'subject' => array_diff($words_subject, array_keys($cur_words['subject']))), 'del' => array('post' => array_diff(array_keys($cur_words['post']), $words_message), 'subject' => array_diff(array_keys($cur_words['subject']), $words_subject)));
    } else {
        $words = array('add' => array('post' => $words_message, 'subject' => $words_subject), 'del' => array('post' => array(), 'subject' => array()));
    }
    // Get unique words from the above arrays
    $unique_words = array_unique(array_merge($words['add']['post'], $words['add']['subject']));
    if (!empty($unique_words)) {
        $query = array('SELECT' => 'id, word', 'FROM' => 'search_words', 'WHERE' => 'word IN(\'' . implode('\',\'', array_map(array($forum_db, 'escape'), $unique_words)) . '\')');
        ($hook = get_hook('si_fn_update_search_index_qr_get_existing_words')) ? eval($hook) : null;
        $result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
        $existing_words = array();
        while ($row = $forum_db->fetch_row($result)) {
            $existing_words[] = $row[1];
        }
        $forum_db->free_result($result);
        $new_words = array_diff($unique_words, $existing_words);
        if (!empty($new_words)) {
            $query = array('INSERT' => 'word', 'INTO' => 'search_words', 'VALUES' => preg_replace('#^(.*)$#', '\'\\1\'', array_map(array($forum_db, 'escape'), $new_words)));
            ($hook = get_hook('si_fn_update_search_index_qr_insert_words')) ? eval($hook) : null;
            $forum_db->query_build($query) or error(__FILE__, __LINE__);
        }
    }
    // Delete matches (only if editing a post)
    foreach ($words['del'] as $match_in => $wordlist) {
        if (!empty($wordlist)) {
            $word_ids = array();
            foreach ($wordlist as $word) {
                $word_ids[] = $cur_words[$match_in][$word];
            }
            $query = array('DELETE' => 'search_matches', 'WHERE' => 'word_id IN (' . implode(', ', $word_ids) . ') AND post_id=' . $post_id . ' AND subject_match=' . ($match_in == 'subject' ? '1' : '0'));
            ($hook = get_hook('si_fn_update_search_index_qr_delete_matches')) ? eval($hook) : null;
            $forum_db->query_build($query) or error(__FILE__, __LINE__);
        }
    }
    // Add new matches
    foreach ($words['add'] as $match_in => $wordlist) {
        if (!empty($wordlist)) {
            $subquery = array('SELECT' => $post_id . ', id, ' . ($match_in == 'subject' ? '1' : '0'), 'FROM' => 'search_words', 'WHERE' => 'word IN (\'' . implode('\',\'', array_map(array($forum_db, 'escape'), $wordlist)) . '\')');
            // Really this should use the query builder too, though it doesn't currently support the syntax
            $sql = 'INSERT INTO ' . $forum_db->prefix . 'search_matches (post_id, word_id, subject_match) ' . $forum_db->query_build($subquery, true);
            ($hook = get_hook('si_fn_update_search_index_qr_add_matches')) ? eval($hook) : null;
            $forum_db->query($sql) or error(__FILE__, __LINE__);
        }
    }
    unset($words);
}
Example #9
0
function update_search_index($mode, $post_id, $message, $subject = null)
{
    global $db;
    $message = utf8_strtolower($message);
    $subject = utf8_strtolower($subject);
    // Remove any bbcode that we shouldn't index
    $message = strip_bbcode($message);
    // Split old and new post/subject to obtain array of 'words'
    $words_message = split_words($message, true);
    $words_subject = $subject ? split_words($subject, true) : array();
    if ($mode == 'edit') {
        $data = array(':id' => $post_id);
        $ps = $db->run('SELECT w.id, w.word, m.subject_match FROM ' . $db->prefix . 'search_words AS w INNER JOIN ' . $db->prefix . 'search_matches AS m ON w.id=m.word_id WHERE m.post_id=:id', $data);
        // Declare here to stop array_keys() and array_diff() from complaining if not set
        $cur_words['post'] = array();
        $cur_words['subject'] = array();
        foreach ($ps as $result) {
            $match_in = $result['subject_match'] ? 'subject' : 'post';
            $cur_words[$match_in][$result['word']] = $result['id'];
        }
        $db->free_result($ps);
        $words['add']['post'] = array_diff($words_message, array_keys($cur_words['post']));
        $words['add']['subject'] = array_diff($words_subject, array_keys($cur_words['subject']));
        $words['del']['post'] = array_diff(array_keys($cur_words['post']), $words_message);
        $words['del']['subject'] = array_diff(array_keys($cur_words['subject']), $words_subject);
    } else {
        $words['add']['post'] = $words_message;
        $words['add']['subject'] = $words_subject;
        $words['del']['post'] = array();
        $words['del']['subject'] = array();
    }
    unset($words_message);
    unset($words_subject);
    // Get unique words from the above arrays
    $unique_words = array_unique(array_merge($words['add']['post'], $words['add']['subject']));
    $data = $placeholders = array();
    foreach ($unique_words as $word) {
        $placeholders[] = '?';
        $data[] = $word;
    }
    if (!empty($unique_words)) {
        $ps = $db->run('SELECT id, word FROM ' . $db->prefix . 'search_words WHERE word IN(' . implode(',', $placeholders) . ')', array_values($data));
        $word_ids = array();
        foreach ($ps as $cur_row) {
            $word_ids[$cur_row['word']] = $cur_row['id'];
        }
        $db->free_result($ps);
        $new_words = array_diff($unique_words, array_keys($word_ids));
        unset($unique_words);
        if (!empty($new_words)) {
            foreach ($new_words as $word) {
                $data = array('word' => $word);
                $db->insert('search_words', $data);
            }
        }
        unset($new_words);
    }
    // Delete matches (only if editing a post)
    foreach ($words['del'] as $match_in => $wordlist) {
        $placeholders = $data = array();
        if (!empty($wordlist)) {
            foreach ($wordlist as $word) {
                $placeholders[] = '?';
                $data[] = $cur_words[$match_in][$word];
            }
            $data[] = $post_id;
            $data[] = $match_in == 'subject' ? 1 : 0;
            $db->run('DELETE FROM ' . $db->prefix . 'search_matches WHERE word_id IN(' . implode(',', $placeholders) . ') AND post_id=? AND subject_match=?', $data);
        }
    }
    // Add new matches
    foreach ($words['add'] as $match_in => $wordlist) {
        $placeholders = $data = array();
        $subject_match = $match_in == 'subject' ? 1 : 0;
        foreach ($wordlist as $word) {
            $placeholders[] = '?';
            $data[] = $word;
        }
        if (!empty($wordlist)) {
            $db->run('INSERT INTO ' . $db->prefix . 'search_matches (post_id, word_id, subject_match) SELECT ' . $post_id . ', id, ' . $subject_match . ' FROM ' . $db->prefix . 'search_words WHERE word IN(' . implode(',', $placeholders) . ')', $data);
        }
    }
    unset($words);
}
Example #10
0
 public function get_search_results()
 {
     global $db_type, $lang_common, $lang_search;
     $search = array();
     $action = $this->request->get('action') ? $this->request->get('action') : null;
     $forums = $this->request->get('forums') ? is_array($this->request->get('forums')) ? $this->request->get('forums') : array_filter(explode(',', $this->request->get('forums'))) : ($this->request->get('forums') ? array($this->request->get('forums')) : array());
     $sort_dir = $this->request->get('sort_dir') && $this->request->get('sort_dir') == 'DESC' ? 'DESC' : 'ASC';
     $forums = array_map('intval', $forums);
     // Allow the old action names for backwards compatibility reasons
     if ($action == 'show_user') {
         $action = 'show_user_posts';
     } elseif ($action == 'show_24h') {
         $action = 'show_recent';
     }
     // If a search_id was supplied
     if ($this->request->get('search_id')) {
         $search_id = intval($this->request->get('search_id'));
         if ($search_id < 1) {
             message($lang_common['Bad request'], '404');
         }
     } elseif ($action == 'search') {
         $keywords = $this->request->get('keywords') ? utf8_strtolower(feather_trim($this->request->get('keywords'))) : null;
         $author = $this->request->get('author') ? utf8_strtolower(feather_trim($this->request->get('author'))) : null;
         if (preg_match('%^[\\*\\%]+$%', $keywords) || feather_strlen(str_replace(array('*', '%'), '', $keywords)) < FEATHER_SEARCH_MIN_WORD && !is_cjk($keywords)) {
             $keywords = '';
         }
         if (preg_match('%^[\\*\\%]+$%', $author) || feather_strlen(str_replace(array('*', '%'), '', $author)) < 2) {
             $author = '';
         }
         if (!$keywords && !$author) {
             message($lang_search['No terms']);
         }
         if ($author) {
             $author = str_replace('*', '%', $author);
         }
         $show_as = $this->request->get('show_as') && $this->request->get('show_as') == 'topics' ? 'topics' : 'posts';
         $sort_by = $this->request->get('sort_by') ? intval($this->request->get('sort_by')) : 0;
         $search_in = !$this->request->get('search_in') || $this->request->get('search_in') == '0' ? 0 : ($this->request->get('search_in') == '1' ? 1 : -1);
     } elseif ($action == 'show_user_posts' || $action == 'show_user_topics' || $action == 'show_subscriptions') {
         $user_id = $this->request->get('user_id') ? intval($this->request->get('user_id')) : $this->user->id;
         if ($user_id < 2) {
             message($lang_common['Bad request'], '404');
         }
         // Subscribed topics can only be viewed by admins, moderators and the users themselves
         if ($action == 'show_subscriptions' && !$this->user->is_admmod && $user_id != $this->user->id) {
             message($lang_common['No permission'], '403');
         }
     } elseif ($action == 'show_recent') {
         $interval = $this->request->get('value') ? intval($this->request->get('value')) : 86400;
     } elseif ($action == 'show_replies') {
         if ($this->user->is_guest) {
             message($lang_common['Bad request'], '404');
         }
     } elseif ($action != 'show_new' && $action != 'show_unanswered') {
         message($lang_common['Bad request'], '404');
     }
     // If a valid search_id was supplied we attempt to fetch the search results from the db
     if (isset($search_id)) {
         $ident = $this->user->is_guest ? get_remote_address() : $this->user->username;
         $search_data = DB::for_table('search_cache')->where('id', $search_id)->where('ident', $ident)->find_one_col('search_data');
         if ($search_data) {
             $temp = unserialize($search_data);
             $search_ids = unserialize($temp['search_ids']);
             $num_hits = $temp['num_hits'];
             $sort_by = $temp['sort_by'];
             $sort_dir = $temp['sort_dir'];
             $show_as = $temp['show_as'];
             $search_type = $temp['search_type'];
             unset($temp);
         } else {
             message($lang_search['No hits']);
         }
     } else {
         $keyword_results = $author_results = array();
         // Search a specific forum?
         $forum_sql = !empty($forums) || empty($forums) && $this->config['o_search_all_forums'] == '0' && !$this->user->is_admmod ? ' AND t.forum_id IN (' . implode(',', $forums) . ')' : '';
         if (!empty($author) || !empty($keywords)) {
             // Flood protection
             if ($this->user->last_search && time() - $this->user->last_search < $this->user->g_search_flood && time() - $this->user->last_search >= 0) {
                 message(sprintf($lang_search['Search flood'], $this->user->g_search_flood, $this->user->g_search_flood - (time() - $this->user->last_search)));
             }
             if (!$this->user->is_guest) {
                 DB::for_table('users')->where('id', $this->user->id)->update_many('last_search', time());
             } else {
                 DB::for_table('online')->where('ident', get_remote_address())->update_many('last_search', time());
             }
             switch ($sort_by) {
                 case 1:
                     $sort_by_sql = $show_as == 'topics' ? 't.poster' : 'p.poster';
                     $sort_type = SORT_STRING;
                     break;
                 case 2:
                     $sort_by_sql = 't.subject';
                     $sort_type = SORT_STRING;
                     break;
                 case 3:
                     $sort_by_sql = 't.forum_id';
                     $sort_type = SORT_NUMERIC;
                     break;
                 case 4:
                     $sort_by_sql = 't.last_post';
                     $sort_type = SORT_NUMERIC;
                     break;
                 default:
                     $sort_by_sql = $show_as == 'topics' ? 't.last_post' : 'p.posted';
                     $sort_type = SORT_NUMERIC;
                     break;
             }
             // If it's a search for keywords
             if ($keywords) {
                 // split the keywords into words
                 $keywords_array = split_words($keywords, false);
                 if (empty($keywords_array)) {
                     message($lang_search['No hits']);
                 }
                 // Should we search in message body or topic subject specifically?
                 $search_in_cond = $search_in ? $search_in > 0 ? ' AND m.subject_match = 0' : ' AND m.subject_match = 1' : '';
                 $word_count = 0;
                 $match_type = 'and';
                 $sort_data = array();
                 foreach ($keywords_array as $cur_word) {
                     switch ($cur_word) {
                         case 'and':
                         case 'or':
                         case 'not':
                             $match_type = $cur_word;
                             break;
                         default:
                             if (is_cjk($cur_word)) {
                                 $where_cond = str_replace('*', '%', $cur_word);
                                 $where_cond_cjk = $search_in ? $search_in > 0 ? 'p.message LIKE %:where_cond%' : 't.subject LIKE %:where_cond%' : 'p.message LIKE %:where_cond% OR t.subject LIKE %:where_cond%';
                                 $result = DB::for_table('posts')->raw_query('SELECT p.id AS post_id, p.topic_id, ' . $sort_by_sql . ' AS sort_by FROM ' . $this->feather->prefix . 'posts AS p INNER JOIN ' . $this->feather->prefix . 'topics AS t ON t.id=p.topic_id LEFT JOIN ' . $this->feather->prefix . 'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id=' . $this->user->g_id . ') WHERE (' . $where_cond_cjk . ') AND (fp.read_forum IS NULL OR fp.read_forum=1)' . $forum_sql, array(':where_cond' => $where_cond))->find_many();
                             } else {
                                 $result = DB::for_table('posts')->raw_query('SELECT m.post_id, p.topic_id, ' . $sort_by_sql . ' AS sort_by FROM ' . $this->feather->prefix . 'search_words AS w INNER JOIN ' . $this->feather->prefix . 'search_matches AS m ON m.word_id = w.id INNER JOIN ' . $this->feather->prefix . 'posts AS p ON p.id=m.post_id INNER JOIN ' . $this->feather->prefix . 'topics AS t ON t.id=p.topic_id LEFT JOIN ' . $this->feather->prefix . 'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id=' . $this->user->g_id . ') WHERE w.word LIKE :where_cond' . $search_in_cond . ' AND (fp.read_forum IS NULL OR fp.read_forum=1)' . $forum_sql, array(':where_cond' => str_replace('*', '%', $cur_word)))->find_many();
                             }
                             $row = array();
                             foreach ($result as $temp) {
                                 $row[$temp['post_id']] = $temp['topic_id'];
                                 if (!$word_count) {
                                     $keyword_results[$temp['post_id']] = $temp['topic_id'];
                                     $sort_data[$temp['post_id']] = $temp['sort_by'];
                                 } elseif ($match_type == 'or') {
                                     $keyword_results[$temp['post_id']] = $temp['topic_id'];
                                     $sort_data[$temp['post_id']] = $temp['sort_by'];
                                 } elseif ($match_type == 'not') {
                                     unset($keyword_results[$temp['post_id']]);
                                     unset($sort_data[$temp['post_id']]);
                                 }
                             }
                             if ($match_type == 'and' && $word_count) {
                                 foreach ($keyword_results as $post_id => $topic_id) {
                                     if (!isset($row[$post_id])) {
                                         unset($keyword_results[$post_id]);
                                         unset($sort_data[$post_id]);
                                     }
                                 }
                             }
                             ++$word_count;
                             $pdo = DB::get_db();
                             $pdo = null;
                             break;
                     }
                 }
                 // Sort the results - annoyingly array_multisort re-indexes arrays with numeric keys, so we need to split the keys out into a separate array then combine them again after
                 $post_ids = array_keys($keyword_results);
                 $topic_ids = array_values($keyword_results);
                 array_multisort(array_values($sort_data), $sort_dir == 'DESC' ? SORT_DESC : SORT_ASC, $sort_type, $post_ids, $topic_ids);
                 // combine the arrays back into a key=>value array (array_combine is PHP5 only unfortunately)
                 $num_results = count($keyword_results);
                 $keyword_results = array();
                 for ($i = 0; $i < $num_results; $i++) {
                     $keyword_results[$post_ids[$i]] = $topic_ids[$i];
                 }
                 unset($sort_data, $post_ids, $topic_ids);
             }
             // If it's a search for author name (and that author name isn't Guest)
             if ($author && $author != 'guest' && $author != utf8_strtolower($lang_common['Guest'])) {
                 $username_exists = DB::for_table('users')->select('id')->where_like('username', $author)->find_many();
                 if ($username_exists) {
                     $user_ids = array();
                     foreach ($username_exists as $row) {
                         $user_ids[] = $row['id'];
                     }
                     $result = DB::for_table('posts')->raw_query('SELECT p.id AS post_id, p.topic_id FROM ' . $this->feather->prefix . 'posts AS p INNER JOIN ' . $this->feather->prefix . 'topics AS t ON t.id=p.topic_id LEFT JOIN ' . $this->feather->prefix . 'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id=' . $this->user->g_id . ') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.poster_id IN(' . implode(',', $user_ids) . ')' . $forum_sql . ' ORDER BY ' . $sort_by_sql . ' ' . $sort_dir)->find_many();
                     foreach ($result as $temp) {
                         $author_results[$temp['post_id']] = $temp['topic_id'];
                     }
                     $pdo = DB::get_db();
                     $pdo = null;
                 }
             }
             // If we searched for both keywords and author name we want the intersection between the results
             if ($author && $keywords) {
                 $search_ids = array_intersect_assoc($keyword_results, $author_results);
                 $search_type = array('both', array($keywords, feather_trim($this->request->get('author'))), implode(',', $forums), $search_in);
             } elseif ($keywords) {
                 $search_ids = $keyword_results;
                 $search_type = array('keywords', $keywords, implode(',', $forums), $search_in);
             } else {
                 $search_ids = $author_results;
                 $search_type = array('author', feather_trim($this->request->get('author')), implode(',', $forums), $search_in);
             }
             unset($keyword_results, $author_results);
             if ($show_as == 'topics') {
                 $search_ids = array_values($search_ids);
             } else {
                 $search_ids = array_keys($search_ids);
             }
             $search_ids = array_unique($search_ids);
             $num_hits = count($search_ids);
             if (!$num_hits) {
                 message($lang_search['No hits']);
             }
         } elseif ($action == 'show_new' || $action == 'show_recent' || $action == 'show_replies' || $action == 'show_user_posts' || $action == 'show_user_topics' || $action == 'show_subscriptions' || $action == 'show_unanswered') {
             $search_type = array('action', $action);
             $show_as = 'topics';
             // We want to sort things after last post
             $sort_by = 0;
             $sort_dir = 'DESC';
             $where_search_action = array(array('fp.read_forum' => 'IS NULL'), array('fp.read_forum' => '1'));
             // If it's a search for new posts since last visit
             if ($action == 'show_new') {
                 if ($this->user->is_guest) {
                     message($lang_common['No permission'], '403');
                 }
                 $result = DB::for_table('topics')->table_alias('t')->select('t.id')->left_outer_join('forum_perms', array('fp.forum_id', '=', 't.forum_id'), 'fp')->left_outer_join('forum_perms', array('fp.group_id', '=', $this->user->g_id), null, true)->where_any_is($where_search_action)->where_gt('t.last_post', $this->user->last_visit)->where_null('t.moved_to')->order_by_desc('t.last_post');
                 if ($this->request->get('fid')) {
                     $result = $result->where('t.forum_id', intval($this->request->get('fid')));
                 }
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     message($lang_search['No new posts']);
                 }
             } elseif ($action == 'show_recent') {
                 $result = DB::for_table('topics')->table_alias('t')->select('t.id')->left_outer_join('forum_perms', array('fp.forum_id', '=', 't.forum_id'), 'fp')->left_outer_join('forum_perms', array('fp.group_id', '=', $this->user->g_id), null, true)->where_any_is($where_search_action)->where_gt('t.last_post', time() - $interval)->where_null('t.moved_to')->order_by_desc('t.last_post');
                 if ($this->request->get('fid')) {
                     $result = $result->where('t.forum_id', intval($this->request->get('fid')));
                 }
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     message($lang_search['No recent posts']);
                 }
             } elseif ($action == 'show_replies') {
                 $result = DB::for_table('topics')->table_alias('t')->select('t.id')->inner_join('posts', array('t.id', '=', 'p.topic_id'), 'p')->left_outer_join('forum_perms', array('fp.forum_id', '=', 't.forum_id'), 'fp')->left_outer_join('forum_perms', array('fp.group_id', '=', $this->user->g_id), null, true)->where_any_is($where_search_action)->where('p.poster_id', $this->user->id)->group_by('t.id');
                 if ($db_type == 'pgsql') {
                     $result = $result->group_by('t.last_post');
                 }
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     message($lang_search['No user posts']);
                 }
             } elseif ($action == 'show_user_posts') {
                 $show_as = 'posts';
                 $result = DB::for_table('posts')->table_alias('p')->select('p.id')->inner_join('topics', array('p.topic_id', '=', 't.id'), 't')->left_outer_join('forum_perms', array('fp.forum_id', '=', 't.forum_id'), 'fp')->left_outer_join('forum_perms', array('fp.group_id', '=', $this->user->g_id), null, true)->where_any_is($where_search_action)->where('p.poster_id', $user_id)->order_by_desc('p.posted');
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     message($lang_search['No user posts']);
                 }
                 // Pass on the user ID so that we can later know whose posts we're searching for
                 $search_type[2] = $user_id;
             } elseif ($action == 'show_user_topics') {
                 $result = DB::for_table('topics')->table_alias('t')->select('t.id')->inner_join('posts', array('t.first_post_id', '=', 'p.id'), 'p')->left_outer_join('forum_perms', array('fp.forum_id', '=', 't.forum_id'), 'fp')->left_outer_join('forum_perms', array('fp.group_id', '=', $this->user->g_id), null, true)->where_any_is($where_search_action)->where('p.poster_id', $user_id)->order_by_desc('t.last_post');
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     message($lang_search['No user topics']);
                 }
                 // Pass on the user ID so that we can later know whose topics we're searching for
                 $search_type[2] = $user_id;
             } elseif ($action == 'show_subscriptions') {
                 if ($this->user->is_guest) {
                     message($lang_common['Bad request'], '404');
                 }
                 $result = DB::for_table('topics')->table_alias('t')->select('t.id')->inner_join('topic_subscriptions', array('t.id', '=', 's.topic_id'), 's')->inner_join('topic_subscriptions', array('s.user_id', '=', $user_id), null, true)->left_outer_join('forum_perms', array('fp.forum_id', '=', 't.forum_id'), 'fp')->left_outer_join('forum_perms', array('fp.group_id', '=', $this->user->g_id), null, true)->where_any_is($where_search_action)->order_by_desc('t.last_post');
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     message($lang_search['No subscriptions']);
                 }
                 // Pass on user ID so that we can later know whose subscriptions we're searching for
                 $search_type[2] = $user_id;
             } else {
                 $result = DB::for_table('topics')->table_alias('t')->select('t.id')->left_outer_join('forum_perms', array('fp.forum_id', '=', 't.forum_id'), 'fp')->left_outer_join('forum_perms', array('fp.group_id', '=', $this->user->g_id), null, true)->where('t.num_replies', 0)->where_null('t.moved_to')->where_any_is($where_search_action)->order_by_desc('t.last_post');
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     message($lang_search['No unanswered']);
                 }
             }
             $search_ids = array();
             foreach ($result as $row) {
                 $search_ids[] = $row['id'];
             }
             $pdo = DB::get_db();
             $pdo = null;
         } else {
             message($lang_common['Bad request'], '404');
         }
         // Prune "old" search results
         $old_searches = array();
         $result = DB::for_table('online')->select('ident')->find_many();
         if ($result) {
             foreach ($result as $row) {
                 $old_searches[] = $row['ident'];
             }
             DB::for_table('search_cache')->where_not_in('ident', $old_searches)->delete_many();
         }
         // Fill an array with our results and search properties
         $temp = serialize(array('search_ids' => serialize($search_ids), 'num_hits' => $num_hits, 'sort_by' => $sort_by, 'sort_dir' => $sort_dir, 'show_as' => $show_as, 'search_type' => $search_type));
         $search_id = mt_rand(1, 2147483647);
         $ident = $this->user->is_guest ? get_remote_address() : $this->user->username;
         $insert_cache = array('id' => $search_id, 'ident' => $ident, 'search_data' => $temp);
         DB::for_table('search_cache')->create()->set($insert_cache)->save();
         if ($search_type[0] != 'action') {
             $this->db->end_transaction();
             $this->db->close();
             // Redirect the user to the cached result page
             header('Location: ' . get_link('search/?search_id=' . $search_id));
             exit;
         }
     }
     // If we're on the new posts search, display a "mark all as read" link
     if (!$this->user->is_guest && $search_type[0] == 'action' && $search_type[1] == 'show_new') {
         $search['forum_actions'][] = '<a href="' . get_link('mark-read/') . '">' . $lang_common['Mark all as read'] . '</a>';
     }
     // Fetch results to display
     if (!empty($search_ids)) {
         // We have results
         $search['is_result'] = true;
         switch ($sort_by) {
             case 1:
                 $sort_by_sql = $show_as == 'topics' ? 't.poster' : 'p.poster';
                 break;
             case 2:
                 $sort_by_sql = 't.subject';
                 break;
             case 3:
                 $sort_by_sql = 't.forum_id';
                 break;
             default:
                 $sort_by_sql = $show_as == 'topics' ? 't.last_post' : 'p.posted';
                 break;
         }
         // Determine the topic or post offset (based on $_GET['p'])
         $per_page = $show_as == 'posts' ? $this->user->disp_posts : $this->user->disp_topics;
         $num_pages = ceil($num_hits / $per_page);
         $p = !$this->request->get('p') || $this->request->get('p') <= 1 || $this->request->get('p') > $num_pages ? 1 : intval($this->request->get('p'));
         $start_from = $per_page * ($p - 1);
         $search['start_from'] = $start_from;
         // Generate paging links
         $search['paging_links'] = '<span class="pages-label">' . $lang_common['Pages'] . ' </span>' . paginate_old($num_pages, $p, '?search_id=' . $search_id);
         // throw away the first $start_from of $search_ids, only keep the top $per_page of $search_ids
         $search_ids = array_slice($search_ids, $start_from, $per_page);
         // Run the query and fetch the results
         if ($show_as == 'posts') {
             $select_search_post = array('pid' => 'p.id', 'pposter' => 'p.poster', 'pposted' => 'p.posted', 'p.poster_id', 'p.message', 'p.hide_smilies', 'tid' => 't.id', 't.poster', 't.subject', 't.first_post_id', 't.last_post', 't.last_post_id', 't.last_poster', 't.num_replies', 't.forum_id', 'f.forum_name');
             $result = DB::for_table('posts')->table_alias('p')->select_many($select_search_post)->inner_join('topics', array('t.id', '=', 'p.topic_id'), 't')->inner_join('forums', array('f.id', '=', 't.forum_id'), 'f')->where_in('p.id', $search_ids)->order_by($sort_by_sql, $sort_dir)->find_many();
         } else {
             $select_search_topic = array('tid' => 't.id', 't.poster', 't.subject', 't.last_post', 't.last_post_id', 't.last_poster', 't.num_replies', 't.closed', 't.sticky', 't.forum_id', 'f.forum_name');
             $result = DB::for_table('topics')->table_alias('t')->select_many($select_search_topic)->inner_join('forums', array('f.id', '=', 't.forum_id'), 'f')->where_in('t.id', $search_ids)->order_by($sort_by_sql, $sort_dir)->find_many();
         }
         $search['search_set'] = array();
         foreach ($result as $row) {
             $search['search_set'][] = $row;
         }
         $search['crumbs_text']['show_as'] = $lang_search['Search'];
         if ($search_type[0] == 'action') {
             if ($search_type[1] == 'show_user_topics') {
                 $search['crumbs_text']['search_type'] = '<a href="' . get_link('search/?action=show_user_topics&amp;user_id=' . $search_type[2]) . '">' . sprintf($lang_search['Quick search show_user_topics'], feather_escape($search['search_set'][0]['poster'])) . '</a>';
             } elseif ($search_type[1] == 'show_user_posts') {
                 $search['crumbs_text']['search_type'] = '<a href="' . get_link('search/?action=show_user_posts&amp;user_id=' . $search_type[2]) . '">' . sprintf($lang_search['Quick search show_user_posts'], feather_escape($search['search_set'][0]['pposter'])) . '</a>';
             } elseif ($search_type[1] == 'show_subscriptions') {
                 // Fetch username of subscriber
                 $subscriber_id = $search_type[2];
                 $subscriber_name = DB::for_table('users')->where('id', $subscriber_id)->find_one_col('username');
                 if (!$subscriber_name) {
                     message($lang_common['Bad request'], '404');
                 }
                 $search['crumbs_text']['search_type'] = '<a href="' . get_link('search/?action=show_subscription&amp;user_id=' . $subscriber_id) . '">' . sprintf($lang_search['Quick search show_subscriptions'], feather_escape($subscriber_name)) . '</a>';
             } else {
                 $search_url = str_replace('_', '/', $search_type[1]);
                 $search['crumbs_text']['search_type'] = '<a href="' . get_link('search/' . $search_url . '/') . '">' . $lang_search['Quick search ' . $search_type[1]] . '</a>';
             }
         } else {
             $keywords = $author = '';
             if ($search_type[0] == 'both') {
                 list($keywords, $author) = $search_type[1];
                 $search['crumbs_text']['search_type'] = sprintf($lang_search['By both show as ' . $show_as], feather_escape($keywords), feather_escape($author));
             } elseif ($search_type[0] == 'keywords') {
                 $keywords = $search_type[1];
                 $search['crumbs_text']['search_type'] = sprintf($lang_search['By keywords show as ' . $show_as], feather_escape($keywords));
             } elseif ($search_type[0] == 'author') {
                 $author = $search_type[1];
                 $search['crumbs_text']['search_type'] = sprintf($lang_search['By user show as ' . $show_as], feather_escape($author));
             }
             $search['crumbs_text']['search_type'] = '<a href="' . get_link('search/?action=search&amp;keywords=' . urlencode($keywords) . '&amp;author=' . urlencode($author) . '&amp;forums=' . $search_type[2] . '&amp;search_in=' . $search_type[3] . '&amp;sort_by=' . $sort_by . '&amp;sort_dir=' . $sort_dir . '&amp;show_as=' . $show_as) . '">' . $search['crumbs_text']['search_type'] . '</a>';
         }
     }
     $search['show_as'] = $show_as;
     return $search;
 }
Example #11
0
     if (!($result = $db->sql_query($sql))) {
         message_die(GENERAL_ERROR, 'Could not obtain matched posts list', '', __LINE__, __FILE__, $sql);
     }
     $search_ids = array();
     while ($row = $db->sql_fetchrow($result)) {
         $search_ids[] = $row['post_id'];
     }
     $db->sql_freeresult($result);
     $total_match_count = count($search_ids);
 } else {
     if ($search_keywords != '') {
         $stopword_array = @file($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . '/search_stopwords.txt');
         $synonym_array = @file($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . '/search_synonyms.txt');
         $split_search = array();
         $cleaned_search = clean_words('search', stripslashes($search_keywords), $stopword_array, $synonym_array);
         $split_search = split_words($cleaned_search, 'search');
         $search_msg_only = !$search_fields ? "AND m.title_match = 0" : '';
         $word_count = 0;
         $current_match_type = 'or';
         $word_match = array();
         $result_list = array();
         for ($i = 0; $i < count($split_search); $i++) {
             switch ($split_search[$i]) {
                 case 'and':
                     $current_match_type = 'and';
                     break;
                 case 'or':
                     $current_match_type = 'or';
                     break;
                 case 'not':
                     $current_match_type = 'not';
Example #12
0
 $result_array = array(array(), array(), array());
 $i = 0;
 while ($row && ($post_size <= $board_config['dbmtnc_rebuildcfg_maxmemory'] * 1024 || $i < $board_config['dbmtnc_rebuildcfg_minposts'])) {
     $last_post = $row['post_id'];
     // handle text
     $word_list = split_words(clean_words('post', $row['post_text'], $empty_array, $empty_array));
     foreach ($word_list as $word) {
         // cutting of long words in functions_search.php seems not to work under some conditions - so check it again
         if ($word != '' && strlen($word) <= 20) {
             $result_array[0][] = $last_post;
             $result_array[1][] = 0;
             $result_array[2][] = $word;
         }
     }
     // handle subject
     $word_list = split_words(clean_words('post', $row['post_subject'], $empty_array, $empty_array));
     foreach ($word_list as $word) {
         // cutting of long words in functions_search.php seems not to work under some conditions - so check it again
         if ($word != '' && strlen($word) <= 20) {
             $result_array[0][] = $last_post;
             $result_array[1][] = 1;
             $result_array[2][] = $word;
         }
     }
     unset($word_list);
     $row = $db->sql_fetchrow($result);
     $i++;
     $post_size += strlen($row['post_text']) + strlen($row['post_subject']);
 }
 // sort array
 array_multisort($result_array[2], SORT_ASC, SORT_STRING, $result_array[0], SORT_ASC, SORT_NUMERIC, $result_array[1]);
Example #13
0
function update_search_index($mode, $post_id, $message, $subject = null)
{
    global $db;
    // Split old and new post/subject to obtain array of 'words'
    $words_message = split_words($message);
    $words_subject = $subject ? split_words($subject) : array();
    if ($mode == 'edit') {
        $result = $db->query('SELECT w.id, w.word, m.subject_match FROM ' . $db->prefix . 'search_words AS w INNER JOIN ' . $db->prefix . 'search_matches AS m ON w.id=m.word_id WHERE m.post_id=' . $post_id) or error('Unable to fetch search index words', __FILE__, __LINE__, $db->error());
        // Declare here to stop array_keys() and array_diff() from complaining if not set
        $cur_words['post'] = array();
        $cur_words['subject'] = array();
        while ($row = $db->fetch_row($result)) {
            $match_in = $row[2] ? 'subject' : 'post';
            $cur_words[$match_in][$row[1]] = $row[0];
        }
        $db->free_result($result);
        $words['add']['post'] = array_diff($words_message, array_keys($cur_words['post']));
        $words['add']['subject'] = array_diff($words_subject, array_keys($cur_words['subject']));
        $words['del']['post'] = array_diff(array_keys($cur_words['post']), $words_message);
        $words['del']['subject'] = array_diff(array_keys($cur_words['subject']), $words_subject);
    } else {
        $words['add']['post'] = $words_message;
        $words['add']['subject'] = $words_subject;
        $words['del']['post'] = array();
        $words['del']['subject'] = array();
    }
    unset($words_message);
    unset($words_subject);
    // Get unique words from the above arrays
    $unique_words = array_unique(array_merge($words['add']['post'], $words['add']['subject']));
    if ($unique_words) {
        $result = $db->query('SELECT id, word FROM ' . $db->prefix . 'search_words WHERE word IN(' . implode(',', preg_replace('#^(.*)$#u', '\'\\1\'', $unique_words)) . ')') or error('Unable to fetch search index words', __FILE__, __LINE__, $db->error());
        $word_ids = array();
        while ($row = $db->fetch_row($result)) {
            $word_ids[$row[1]] = $row[0];
        }
        $db->free_result($result);
        $new_words = array_unique(array_diff($unique_words, array_keys($word_ids)));
        unset($unique_words);
        if ($new_words) {
            $db->query('INSERT INTO ' . $db->prefix . 'search_words (word) VALUES' . implode(',', preg_replace('#^(.*)$#u', '(\'\\1\')', $new_words))) or error('Unable to insert search index words', __FILE__, __LINE__, $db->error());
        }
        unset($new_words);
    }
    // Delete matches (only if editing a post)
    while (list($match_in, $wordlist) = @each($words['del'])) {
        $subject_match = $match_in == 'subject' ? 1 : 0;
        if ($wordlist) {
            $sql = null;
            while (list(, $word) = @each($wordlist)) {
                $sql .= ($sql ? ',' : '') . $cur_words[$match_in][$word];
            }
            $db->query('DELETE FROM ' . $db->prefix . 'search_matches WHERE word_id IN(' . $sql . ') AND post_id=' . $post_id . ' AND subject_match=' . $subject_match) or error('Unable to delete search index word matches', __FILE__, __LINE__, $db->error());
        }
    }
    // Add new matches
    while (list($match_in, $wordlist) = @each($words['add'])) {
        $subject_match = $match_in == 'subject' ? 1 : 0;
        if ($wordlist) {
            $db->query('INSERT INTO ' . $db->prefix . 'search_matches (post_id, word_id, subject_match) SELECT ' . $post_id . ', id, ' . $subject_match . ' FROM ' . $db->prefix . 'search_words WHERE word IN(' . implode(',', preg_replace('#^(.*)$#', '\'\\1\'', $wordlist)) . ')') or error('Unable to insert search index word matches', __FILE__, __LINE__, $db->error());
        }
    }
    unset($words);
}
Example #14
0
function update_search_index($mode, $post_id, $message, $subject = null)
{
    global $db_type, $db;
    $message = utf8_strtolower($message);
    $subject = utf8_strtolower($subject);
    // Remove any bbcode that we shouldn't index
    $message = strip_bbcode($message);
    // Split old and new post/subject to obtain array of 'words'
    $words_message = split_words($message, true);
    $words_subject = $subject ? split_words($subject, true) : array();
    if ($mode == 'edit') {
        // Declare here to stop array_keys() and array_diff() from complaining if not set
        $cur_words = array('post' => array(), 'subject' => array());
        $query = $db->select(array('wid' => 'w.id', 'word' => 'w.word', 'subject_match' => 'm.subject_match'), 'search_words AS w');
        $query->innerJoin('m', 'search_matches AS m', 'w.id = m.word_id');
        $query->where = 'm.post_id = :post_id';
        $params = array(':post_id' => $post_id);
        $result = $query->run($params);
        foreach ($result as $cur_word) {
            $match_in = $cur_word['subject_match'] ? 'subject' : 'post';
            $cur_words[$match_in][$cur_word['word']] = $cur_word['id'];
        }
        unset($query, $params, $result);
        $words['add']['post'] = array_diff($words_message, array_keys($cur_words['post']));
        $words['add']['subject'] = array_diff($words_subject, array_keys($cur_words['subject']));
        $words['del']['post'] = array_diff(array_keys($cur_words['post']), $words_message);
        $words['del']['subject'] = array_diff(array_keys($cur_words['subject']), $words_subject);
    } else {
        $words['add']['post'] = $words_message;
        $words['add']['subject'] = $words_subject;
        $words['del']['post'] = array();
        $words['del']['subject'] = array();
    }
    unset($words_message);
    unset($words_subject);
    // Get unique words from the above arrays
    $unique_words = array_unique(array_merge($words['add']['post'], $words['add']['subject']));
    if (!empty($unique_words)) {
        $word_ids = array();
        $query = $db->select(array('id' => 'w.id', 'word' => 'w.word'), 'search_words AS w');
        $query->where = 'w.word IN :words';
        $params = array(':words' => $unique_words);
        $result = $query->run($params);
        foreach ($result as $cur_word) {
            $word_ids[$cur_word['word']] = $cur_word['id'];
        }
        unset($result, $query, $params);
        $new_words = array_diff($unique_words, array_keys($word_ids));
        unset($unique_words);
        if (!empty($new_words)) {
            $insert_query = $db->insert(array('word' => ':word'), 'search_words');
            foreach ($new_words as $cur_word) {
                $params = array(':word' => $cur_word);
                $insert_query->run($params);
                unset($params);
            }
            unset($insert_query);
        }
        unset($new_words);
    }
    $delete_query = $db->delete('search_matches');
    $delete_query->where = 'word_id IN :wids AND post_id = :post_id AND subject_match = :subject_match';
    // Delete matches (only if editing a post)
    foreach ($words['del'] as $match_in => $wordlist) {
        $subject_match = $match_in == 'subject' ? 1 : 0;
        if (!empty($wordlist)) {
            $word_ids = array();
            foreach ($wordlist as $cur_word) {
                $word_ids[] = $cur_words[$match_in][$cur_word];
            }
            $params = array(':wids' => $word_ids, ':post_id' => $post_id, ':subject_match' => $subject_match);
            $delete_query->run($params);
            unset($params);
        }
    }
    unset($delete_query);
    // Add new matches
    foreach ($words['add'] as $match_in => $wordlist) {
        $subject_match = $match_in == 'subject' ? 1 : 0;
        if (!empty($wordlist)) {
            $db->query('INSERT INTO ' . $db->prefix . 'search_matches (post_id, word_id, subject_match) SELECT ' . $post_id . ', id, ' . $subject_match . ' FROM ' . $db->prefix . 'search_words WHERE word IN(' . implode(',', array_map(array($db, 'quote'), $wordlist)) . ')') or error('Unable to insert search index word matches', __FILE__, __LINE__, $db->error());
        }
    }
    unset($words);
}
Example #15
0
function update_search_index($mode, $post_id, $message, $subject = null)
{
    global $db_type, $db;
    $message = utf8_strtolower($message);
    $subject = utf8_strtolower($subject);
    // Remove any bbcode that we shouldn't index
    $message = strip_bbcode($message);
    // Split old and new post/subject to obtain array of 'words'
    $words_message = split_words($message, true);
    $words_subject = $subject ? split_words($subject, true) : array();
    if ($mode == 'edit') {
        $result = $db->query('SELECT w.id, w.word, m.subject_match FROM ' . $db->prefix . 'search_words AS w INNER JOIN ' . $db->prefix . 'search_matches AS m ON w.id=m.word_id WHERE m.post_id=' . $post_id, true) or error('Unable to fetch search index words', __FILE__, __LINE__, $db->error());
        // Declare here to stop array_keys() and array_diff() from complaining if not set
        $cur_words['post'] = array();
        $cur_words['subject'] = array();
        while ($row = $db->fetch_row($result)) {
            $match_in = $row[2] ? 'subject' : 'post';
            $cur_words[$match_in][$row[1]] = $row[0];
        }
        $db->free_result($result);
        $words['add']['post'] = array_diff($words_message, array_keys($cur_words['post']));
        $words['add']['subject'] = array_diff($words_subject, array_keys($cur_words['subject']));
        $words['del']['post'] = array_diff(array_keys($cur_words['post']), $words_message);
        $words['del']['subject'] = array_diff(array_keys($cur_words['subject']), $words_subject);
    } else {
        $words['add']['post'] = $words_message;
        $words['add']['subject'] = $words_subject;
        $words['del']['post'] = array();
        $words['del']['subject'] = array();
    }
    unset($words_message);
    unset($words_subject);
    // Get unique words from the above arrays
    $unique_words = array_unique(array_merge($words['add']['post'], $words['add']['subject']));
    if (!empty($unique_words)) {
        $result = $db->query('SELECT id, word FROM ' . $db->prefix . 'search_words WHERE word IN(\'' . implode('\',\'', array_map(array($db, 'escape'), $unique_words)) . '\')', true) or error('Unable to fetch search index words', __FILE__, __LINE__, $db->error());
        $word_ids = array();
        while ($row = $db->fetch_row($result)) {
            $word_ids[$row[1]] = $row[0];
        }
        $db->free_result($result);
        $new_words = array_diff($unique_words, array_keys($word_ids));
        unset($unique_words);
        if (!empty($new_words)) {
            switch ($db_type) {
                case 'mysql':
                case 'mysqli':
                case 'mysql_innodb':
                case 'mysqli_innodb':
                    $db->query('INSERT INTO ' . $db->prefix . 'search_words (word) VALUES(\'' . implode('\'),(\'', array_map(array($db, 'escape'), $new_words)) . '\')');
                    break;
                default:
                    foreach ($new_words as $word) {
                        $db->query('INSERT INTO ' . $db->prefix . 'search_words (word) VALUES(\'' . $db->escape($word) . '\')');
                    }
                    break;
            }
        }
        unset($new_words);
    }
    // Delete matches (only if editing a post)
    foreach ($words['del'] as $match_in => $wordlist) {
        $subject_match = $match_in == 'subject' ? 1 : 0;
        if (!empty($wordlist)) {
            $sql = '';
            foreach ($wordlist as $word) {
                $sql .= ($sql != '' ? ',' : '') . $cur_words[$match_in][$word];
            }
            $db->query('DELETE FROM ' . $db->prefix . 'search_matches WHERE word_id IN(' . $sql . ') AND post_id=' . $post_id . ' AND subject_match=' . $subject_match) or error('Unable to delete search index word matches', __FILE__, __LINE__, $db->error());
        }
    }
    // Add new matches
    foreach ($words['add'] as $match_in => $wordlist) {
        $subject_match = $match_in == 'subject' ? 1 : 0;
        if (!empty($wordlist)) {
            $db->query('INSERT INTO ' . $db->prefix . 'search_matches (post_id, word_id, subject_match) SELECT ' . $post_id . ', id, ' . $subject_match . ' FROM ' . $db->prefix . 'search_words WHERE word IN(\'' . implode('\',\'', array_map(array($db, 'escape'), $wordlist)) . '\')') or error('Unable to insert search index word matches', __FILE__, __LINE__, $db->error());
        }
    }
    unset($words);
}
Example #16
0
<?php

if (!defined("WIKINI_VERSION")) {
    die("acc&egrave;s direct interdit");
}
include_once "tools/tags/libs/tags.functions.php";
//mot clés utilisés d'office
$tags = $this->GetParameter('tags');
$tagsvirgule = implode(',', split_words($tags));
//mot clés cachés d'office
$notags = $this->GetParameter('notags');
//peut on éditer les pages?
$lienedit = $this->GetParameter('edit');
$titrerss = $this->GetParameter('titrerss');
//classe CSS associée
$class = $this->GetParameter('class');
if (empty($class)) {
    $class = 'microblog';
}
//template billets microblog
$vue = $this->GetParameter('vue');
if (empty($vue)) {
    $vue = 'bulle_microblog.tpl.html';
}
//formulaire de microblog au dessus ou en dessous
$enhaut = $this->GetParameter('enhaut');
if (empty($enhaut)) {
    $enhaut = "oui";
}
//formulaire microblog seul ou avec la liste des billets?
$afficher = $this->GetParameter('afficher');
Example #17
0
function add_search_words($mode, $post_id, $post_text, $post_title = '')
{
    global $db, $config, $lang;
    global $stopwords_array, $synonyms_array;
    stopwords_synonyms_init();
    $search_raw_words = array();
    $search_raw_words['text'] = split_words(clean_words('post', $post_text, $stopwords_array, $synonyms_array));
    $search_raw_words['title'] = split_words(clean_words('post', $post_title, $stopwords_array, $synonyms_array));
    @set_time_limit(0);
    $word = array();
    $word_insert_sql = array();
    while (list($word_in, $search_matches) = @each($search_raw_words)) {
        $word_insert_sql[$word_in] = '';
        if (!empty($search_matches)) {
            for ($i = 0; $i < sizeof($search_matches); $i++) {
                $search_matches[$i] = trim($search_matches[$i]);
                if ($search_matches[$i] != '') {
                    $word[] = $search_matches[$i];
                    if (!strstr($word_insert_sql[$word_in], "'" . $search_matches[$i] . "'")) {
                        $word_insert_sql[$word_in] .= $word_insert_sql[$word_in] != "" ? ", '" . $search_matches[$i] . "'" : "'" . $search_matches[$i] . "'";
                    }
                }
            }
        }
    }
    if (sizeof($word)) {
        sort($word);
        $prev_word = '';
        $word_text_sql = '';
        $temp_word = array();
        for ($i = 0; $i < sizeof($word); $i++) {
            if ($word[$i] != $prev_word) {
                $temp_word[] = $word[$i];
                $word_text_sql .= ($word_text_sql != '' ? ', ' : '') . "'" . $word[$i] . "'";
            }
            $prev_word = $word[$i];
        }
        $word = $temp_word;
        $check_words = array();
        $value_sql = '';
        $match_word = array();
        for ($i = 0; $i < sizeof($word); $i++) {
            $new_match = true;
            if (isset($check_words[$word[$i]])) {
                $new_match = false;
            }
            if ($new_match) {
                $value_sql .= ($value_sql != '' ? ', ' : '') . '(\'' . $word[$i] . '\', 0)';
            }
        }
        if ($value_sql != '') {
            $sql = "INSERT IGNORE INTO " . SEARCH_WORD_TABLE . " (word_text, word_common)\n\t\t\t\t\t\t\tVALUES {$value_sql}";
            $db->sql_query($sql);
        }
    }
    while (list($word_in, $match_sql) = @each($word_insert_sql)) {
        $title_match = $word_in == 'title' ? 1 : 0;
        if ($match_sql != '') {
            $sql = "INSERT INTO " . SEARCH_MATCH_TABLE . " (post_id, word_id, title_match)\n\t\t\t\tSELECT {$post_id}, word_id, {$title_match}\n\t\t\t\t\tFROM " . SEARCH_WORD_TABLE . "\n\t\t\t\t\tWHERE word_text IN ({$match_sql})";
            $db->sql_query($sql);
        }
    }
    if ($mode == 'single') {
        remove_common('single', 4 / 10, $word);
    }
    return;
}
function clean_file($file, $url, $type, $charSet, $use_nofollow, $use_robot, $can_leave_domain)
{
    global $db_con, $entities, $index_host, $index_meta_keywords, $index_meta_description, $case_sensitive, $utf_16;
    global $home_charset, $chrSet, $del_secchars, $index_rss, $converter_dir, $div_all, $div_hyphen, $del_dups;
    global $bb_decode, $ent_decode, $cn_seg, $quotes, $dup_quotes, $clear, $only_links, $text_length, $strict_high;
    global $use_divs, $not_divs, $not_divlist, $use_divlist, $ignore_fulltxt, $index_meta_title, $js_reloc;
    global $use_elems, $not_elems, $use_elementslist, $not_elementslist, $del_elems, $conv_puny, $include_dir;
    $new = array();
    $data = array();
    $string = '';
    $home_charset = strtoupper($home_charset);
    if ($utf_16) {
        //$file = mb_ereg_replace("\\0", "", $file);
        $file = utf16_to_utf8($file);
    }
    //      kill useless blanks, under scores and line feeds
    $file = preg_replace("/[  |\r\n|\\_]+/i", " ", $file);
    $urlparts = parse_addr($url);
    $host = $urlparts['host'];
    //remove filename from path and all tags which should be ignored
    $path = preg_replace('/([^\\/]+)$/i', "", $urlparts['path']);
    if ($use_nofollow == '1') {
        $file = preg_replace("@<!--sphider_noindex-->.*?<!--\\/sphider_noindex-->@si", " ", $file);
    }
    //  parse the HTML head
    $headdata = get_head_data($file, $url, $use_nofollow, $use_robot, $can_leave_domain, $type);
    $title = $headdata['title'];
    $description = $headdata['description'];
    $keywords = $headdata['keywords'];
    $file = preg_replace("@<head>.*?</head>@si", " ", $file);
    //  remove HTML head from file
    $file = preg_replace("@<!--.*?-->@si", " ", $file);
    $file = preg_replace("@<script[^>]*?>.*?<\\/script>@si", " ", $file);
    //$file = str_replace("window.location.replace", " ", $file);
    $file = preg_replace("@<style[^>]*>.*?<\\/style>@si", " ", $file);
    $file = preg_replace("/<link rel[^<>]*>/i", " ", $file);
    $file = preg_replace("@<div style=(\"|')display\\:none(\"|').*?<\\/div>@si", " ", $file);
    $file = preg_replace("@<a.*?>@si", " ", $file);
    $file = preg_replace("@<(object|img|audio|video).*?>@si", " ", $file);
    $file = preg_replace("@<(align|alt|data|body|form|height|input|id|name|span|src|table|td|type|width|layer|span).*?>@si", " ", $file);
    $file = preg_replace("@\\{document\\..*?\\}@si", " ", $file);
    //  if activated in Admin settings, ignore the full text
    if ($ignore_fulltxt == '1') {
        $file = '';
    }
    // if activated in Admin settings, remove all div contents as defined in common 'divs_not' list
    if ($not_divs == '1') {
        // JFIELD parse the doc into a DOM tree so we can
        // do cool stuff like exclude certain divs
        // echo "<pre>\n";
        global $myFile;
        $myFile = "";
        $myDepth = 0;
        $dom = new DOMDocument();
        $dom->loadHTML($file);
        /*
        // JFIELD figuring out image exclusion and stuff
        echo "<pre>HEY:\n";
        echo "$title\n";
        echo "$description\n";
        echo "$url\n";
        //var_dump( $dom->getElementById('shared-image-desc') );
        echo "</pre>\n";
        */
        // probably a better way to get the doc
        // than skipping over the non-doc like this
        foreach ($dom->childNodes as $item) {
            if (!$item->tagName) {
                continue;
            }
            recurseNodes($item);
        }
        $file = $myFile;
        // wikipedia - don't index content of image pages
        if (preg_match("/\\/images\\//", $url) && preg_match("/^File\\:/", $title)) {
            // image description stopwords
            $mystopwords = explode(" ", "wikipedia schools english featured article sos children file");
            $mydesc = str_replace($mystopwords, " ", strtolower($description));
            $description = '';
            // otherwise the unstripped version gets used
            $title = str_replace("File:", "", $title);
            // remove this noise
            $file = "{$title} {$mydesc} picture image";
        }
        // echo "</pre>\n";
        // END JFIELD
    }
    // if activated in Admin settings, fetch all div contents as defined in common 'divs_use' list
    if ($use_divs == '1') {
        foreach ($use_divlist as $thisid) {
            //    try to find divs with id as specified in common 'divs' list
            //  regexp ?
            if (strpos($thisid, "/") == "1" && strrpos($thisid, "/") == strlen($thisid) - 1) {
                $thisid = substr($thisid, 2, strlen($thisid) - 3);
                //  remove the regex capsules
            } else {
                //  for string input only
                if (strrpos($thisid, "*") == strlen($thisid) - 1) {
                    $thisid = str_replace("*", "(.*?)", $thisid);
                    //  replace wildcards at the end of string input
                }
            }
            if (preg_match_all("@(<div class|<div id)=(\"|')" . $thisid . "(\"|').*?(</div>)@si", $file, $found_divs, PREG_OFFSET_CAPTURE)) {
                foreach ($found_divs[0] as $another_div) {
                    //  walk through all found divs. Usually W3C does not allow more than one div with this id. But who knows . . . .
                    $this_divstart = $another_div[1];
                    //  get actual startpos from div-array
                    $i = "end";
                    //  if required $i will become the loop counter for nested divs
                    $nextstart = strpos($file, "<div", $this_divstart + 4);
                    //  find start pos of next div
                    $nextend = strpos($file, "</div", $this_divstart + 4);
                    //  find end pos of next div
                    //check for nested divs
                    $start1 = strpos($file, "<div", $nextstart + 4);
                    // find start pos of next div
                    if ($start1 && $start1 < $nextend) {
                        $i = "0";
                        //  yes, nested
                    }
                    while ($i != "end") {
                        //  loop for (multiple) 'nested divs'
                        $i = '0';
                        while ($nextstart && $nextstart < $nextend) {
                            // next div is a nested div?
                            $nextend1 = strpos($file, "</div", $nextstart + 4);
                            //  this is only the endpos of current div
                            $nextend = strpos($file, "</div", $nextend1 + 6);
                            //  find end pos of next div
                            $nextstart = strpos($file, "<div", $nextstart + 4);
                            // find start pos of next div
                            if ($nextstart && $nextstart < $nextend1) {
                                //  again nested in next layer?
                                $i++;
                                //  counter for next level nested divs
                            }
                        }
                        //  if nested divs were found, correct end pos of div to be deleted
                        while ($i > '1') {
                            $nextend = strpos($file, "</div", $nextend + 6);
                            $i--;
                        }
                        $nextend1 = strpos($file, "</div", $nextend + 6);
                        //  $nextend from former div (might have been nested)
                        if ($nextend1) {
                            $nextend = $nextend1;
                            //  defines next endpos
                        }
                        if (!$nextstart || $nextend < $nextstart) {
                            $i = 'end';
                            //  no longer nested divs
                        }
                    }
                    //  collect all divs to be indexed
                    $all_divs[] = substr($file, $this_divstart, $nextend + 6 - $this_divstart);
                }
                //  add content of all found divs to full text
                foreach ($all_divs as $use_thisdiv) {
                    $divfile .= " " . $use_thisdiv;
                }
            }
        }
        $file = $divfile;
        //  now this will be used as the body part of the page content
    }
    // if activated in Admin settings, fetch the content of all elements as defined in common 'elements_use' list and use the content of these elements as page content
    if ($use_elems == '1') {
        foreach ($use_elementslist as $this_element) {
            //    try to find elements with id as specified in common 'elöements_use' list
            //  regexp ?
            if (strpos($this_element, "/") == "1" && strrpos($this_element, "/") == strlen($this_element) - 1) {
                $this_element = substr($this_element, 2, strlen($this_element) - 3);
                //  remove the regex capsules
            }
            if (preg_match_all("@<{$this_element}.*?>.*?<\\/{$this_element}>@si", $file, $found_elements, PREG_OFFSET_CAPTURE)) {
                foreach ($found_elements as $new_element) {
                    //  walk through all found elementss.
                    foreach ($new_element as $new) {
                        //  build substring without content tags
                        $string = $new[0];
                        $string = substr($string, strpos($string, ">") + 1);
                        $string = substr($string, 0, strrpos($string, "<"));
                        //  collect all elements to be indexed
                        $all_elements[] = $string;
                    }
                }
            }
        }
        $file = '';
        //  add content of all found elements to full text
        foreach ($all_elements as $use_thiselem) {
            $file .= " " . $use_thiselem;
            //  now all this will be used as the body part of the page content
        }
    }
    // if activated in Admin settings, fetch the content of all elements as defined in common 'elements_not' list and delete that part of the page
    if ($not_elems == '1') {
        foreach ($not_elementslist as $this_element) {
            //    try to find elements with id as specified in common 'elements_not' list
            //  regexp ?
            if (strpos($this_element, "/") == "1" && strrpos($this_element, "/") == strlen($this_element) - 1) {
                $this_element = substr($this_element, 2, strlen($this_element) - 3);
                //  remove the regex capsules
            }
            if (preg_match_all("@<{$this_element}.*?>.*?<\\/{$this_element}>@si", $file, $found_elements, PREG_OFFSET_CAPTURE)) {
                foreach ($found_elements as $new_element) {
                    //  walk through all found elementss.
                    foreach ($new_element as $new) {
                        //  collect all elements to be ignored
                        $all_elements[] = $new[0];
                    }
                }
            }
        }
        //  remove the content of all found elements from full text
        foreach ($all_elements as $use_thiselem) {
            $file = str_replace($use_thiselem, " ", $file);
        }
    }
    //  parse bbcode
    if ($bb_decode == '1') {
        $file = bbcode($file);
    }
    $file = preg_replace("@<div.*?>@si", " ", $file);
    $file = preg_replace("@<\\/.*?>@si", " ", $file);
    //create spaces between tags, so that removing tags doesnt concatenate strings
    $file = preg_replace("/<[\\w ]+>/", "\\0 ", $file);
    $file = preg_replace("/<\\/[\\w ]+>/", "\\0 ", $file);
    $file = preg_replace("@<\\/a>@si", " ", $file);
    //  remove lost end tag
    //$file = strip_tags($file);  //  remove the content of HTML tags from $file (does not work for invalid written and unclosed tags)
    //  replaced since Sphider-plus version 2.7
    //  remove the content of HTML tags from $file
    $found_tags = array();
    $another_tag = array();
    if (preg_match_all("@<.*?>@s", $file, $found_tags, PREG_OFFSET_CAPTURE)) {
        foreach ($found_tags[0] as $another_tag) {
            //  walk through all found tags.
            if (strlen($another_tag[0]) < "500") {
                //  delete this tag from full text if not too long (unclosed)
                $file = str_replace($another_tag[0], " ", $file);
            }
        }
    }
    if ($del_elems) {
        //  if activated in Admin backend, delete  &lt; element /&gt; from full text
        $found_tags = array();
        $another_tag = array();
        if (preg_match_all("@\\&lt;.*?\\&gt;@s", $file, $found_tags, PREG_OFFSET_CAPTURE)) {
            foreach ($found_tags[0] as $another_tag) {
                //  walk through all found tags.
                $file = str_replace($another_tag[0], " ", $file);
            }
        }
    }
    if ($conv_puny) {
        //  make punycode readable
        require_once "{$include_dir}/idna_converter.php";
        // Initialize the converter class
        $IDN = new idna_convert(array('idn_version' => 2008));
        $found_tags = array();
        $another_tag = array();
        $this_tag = '';
        $file = str_replace("http", " http", $file);
        //place a blank in front of all http's
        if (preg_match_all("@http.*? @s", $file, $found_tags, PREG_OFFSET_CAPTURE)) {
            foreach ($found_tags[0] as $another_tag) {
                //  walk through all found tags.
                // Decode the URL to readable format
                $this_tag = $IDN->decode(rawurldecode($another_tag[0]));
                $this_tag = rawurldecode($this_tag);
                $file = str_replace($another_tag[0], $this_tag, $file);
            }
        }
    }
    $file = str_replace(" ", " ", $file);
    //  replace special (long) blanks with standard blank
    $file = str_replace("—", "'", $file);
    //  replace  invalid coded quotations
    $file = str_replace("©", "&#151;", $file);
    //  replace  invalid coded long dash with correct long dash
    $file = preg_replace("/   +/", " ", $file);
    //  replace TABs with a standard blank
    $file = preg_replace("/  +/", " ", $file);
    //  kill duplicate blanks
    $file = preg_replace("/__+/", " ", $file);
    //  kill duplicate underscore
    $file = preg_replace("/--+/", " ", $file);
    //  kill duplicate hyphens
    $file = preg_replace("/\\*\\*+/", " ", $file);
    //  kill duplicate stars
    $file = preg_replace("/\\#\\#+/", " ", $file);
    //  kill duplicate hash tags
    $file = str_replace(" &nbsp;", " ", $file);
    $file = str_replace("&nbsp;&nbsp;", " ", $file);
    //  kill duplicate &nbsp; blanks
    $file = str_replace("&shy;", "", $file);
    //  kill  break character
    $file = preg_replace("/\\☨\\☨+/", " ", $file);
    //  kill duplicates. . .  Yes, I've met something
    $file = preg_replace("/\\(\\(+/", " ", $file);
    //  kill duplicates.  . .  no comment
    $file = preg_replace("/\\<\\<+/", " ", $file);
    //  kill duplicates
    $file = preg_replace("/\\>\\>+/", " ", $file);
    //  kill duplicates
    $file = preg_replace("/\\*\\~+/", " ", $file);
    //  kill duplicates
    $file = preg_replace("/\\+\\++/", " ", $file);
    //  kill duplicates
    $file = preg_replace("/\\=\\=+/", " ", $file);
    //  kill duplicates
    $file = preg_replace("/\\~\\~+/", " ", $file);
    //  kill duplicates
    //  kill some other duplicates, already met on the Internet
    if ($del_dups) {
        $file = preg_replace("/\\(\\(+/", " ", $file);
        $file = preg_replace("/\\)\\)+/", " ", $file);
        $file = preg_replace("/\\~\\~+/", " ", $file);
        $file = preg_replace("/\\=\\=+/", " ", $file);
        $file = preg_replace("/\\?\\?+/", " ", $file);
        $file = preg_replace("/\\!\\!+/", " ", $file);
        $file = preg_replace("/\\.\\.+/", " ", $file);
        $file = preg_replace("/\\<\\<+/", " ", $file);
        $file = preg_replace("/\\>\\>+/", " ", $file);
        $file = preg_replace("/\\:\\:+/", " ", $file);
        $file = preg_replace("/\\+\\++/", " ", $file);
        $file = preg_replace("/\\-\\-+/", " ", $file);
        $file = preg_replace("/\\*\\*+/", " ", $file);
    }
    $file = str_replace(" &nbsp;", " ", $file);
    $file = str_replace("&nbsp;&nbsp;", " ", $file);
    //  kill duplicate &nbsp; blanks
    $file = str_replace("&shy;", "", $file);
    //  kill  break character
    //  kill some special cases
    $file = str_replace("&quot;", "\"", $file);
    $file = str_replace("…", " ", $file);
    if ($text_length != "0") {
        //  build substring of full text until last space in front of $text_length
        $file = substr($file, 0, strrpos(substr($file, 0, $text_length), " "));
    }
    if ($index_host == 1) {
        //  separate words in host and path
        $host_sep = preg_replace("/\\.|\\/|\\\\/", " ", $host);
        $path_sep = preg_replace("/\\.|\\/|\\\\/", " ", $path);
        $file = $file . " " . $host . " " . $host_sep;
        $file = $file . " " . $path . " " . $path_sep;
    }
    if ($headdata['title'] && $index_meta_title) {
        $file = $file . " " . $title;
    }
    if ($index_meta_description == 1) {
        $file = $file . " " . $description;
    }
    if ($index_meta_keywords == 1) {
        $file = $file . " " . $keywords;
    }
    if ($ent_decode == '1') {
        //  as it seems, the PHP function html_entity_decode() has some problems.
        //  In case that 2 entities are placed directly together like: &mdash;&nbsp;
        //  we are obliged to be helpful by eliminating one of them
        $file = str_replace("&nbsp;", " ", $file);
        //  now PHP does not get confused
        $file = html_entity_decode($file, ENT_QUOTES, 'UTF-8');
        $title = str_replace("&nbsp;", " ", $title);
        $title = html_entity_decode($title, ENT_QUOTES, 'UTF-8');
    }
    //  correct some other trash found on the Internet
    $file = str_replace("�", "fi", $file);
    $file = str_replace("fl", "fl", $file);
    //  for URLs use entities, so that links become readable in full text
    $file = str_replace("<a href=\"http://www.", "&lt;a href=&quot;http://www.", $file);
    //  replace .. with a standard blank
    $file = str_replace("...", " ", $file);
    //  kill duplicate blanks  " ", \r, \t, \n and \f
    if (preg_match("@8859|utf@", $charSet)) {
        $file = preg_replace("/[\\s,]+/", " ", $file);
    }
    if ($index_rss == '1') {
        $file = preg_replace('/0b/si', '.', $file);
        // try to correct bad charset interpretation
        $file = preg_replace('//si', '\'', $file);
        $trash = array("\r\n", "\n", "\r", "0E", "0C", "0I");
        // kill 'LF' and the others
    } else {
        $trash = array("\r\n", "\f", "\n", "\r", "\t");
    }
    $replace = ' ';
    $file = str_replace($trash, $replace, $file);
    $fulltext = $file;
    //  required for result listing as extract around the keywords and for PHRASE search
    if ($del_secchars) {
        $file = del_secchars($file);
    }
    //  use the cleaned $file to just highlight the pure query term in result listing
    if ($strict_high) {
        $fulltext = $file;
    }
    //  convert all single quotes into standard quote
    if ($quotes == '1') {
        $all_quotes = array("&#8216;" => "'", "&lsquo;" => "'", "&#8217;" => "'", "&rsquo;" => "'", "&#8242;" => "'", "&prime;" => "'", "‘" => "'", "‘" => "'", "´" => "'", "`" => "'", "’" => "'", "‘" => "'", "’" => "'", "’" => "'");
        //reset($all_quotes);
        while ($char = each($all_quotes)) {
            $file = preg_replace("/" . $char[0] . "/si", $char[1], $file);
            $title = preg_replace("/" . $char[0] . "/si", $char[1], $title);
            $description = preg_replace("/" . $char[0] . "/si", $char[1], $description);
            $keywords = preg_replace("/" . $char[0] . "/si", $char[1], $keywords);
        }
    }
    //  convert all double quotes into standard quotations
    if ($dup_quotes == '1') {
        $all_quotes = array("“" => "\"", "�" => "\"", "„" => "\"");
        reset($all_quotes);
        while ($char = each($all_quotes)) {
            $file = preg_replace("/" . $char[0] . "/i", $char[1], $file);
            $title = preg_replace("/" . $char[0] . "/i", $char[1], $title);
            $description = preg_replace("/" . $char[0] . "/i", $char[1], $description);
            $keywords = preg_replace("/" . $char[0] . "/i", $char[1], $keywords);
        }
    }
    //  split words at hyphen, single quote, dot and comma into their basics
    if ($div_all || $div_hyphen) {
        $file = split_words($file);
        // jfield: yes, we want to index words split on hyphens,
        // but what does that have to do with changing the appearance
        // of the title? sphider_plus, you so crazy
        // $title          = split_words($title);
        $description = split_words($description);
        $keywords = split_words($keywords);
    }
    reset($entities);
    while ($char = each($entities)) {
        $file = preg_replace("/" . $char[0] . "/i", $char[1], $file);
        $title = preg_replace("/" . $char[0] . "/i", $char[1], $title);
        $description = preg_replace("/" . $char[0] . "/i", $char[1], $description);
        $keywords = preg_replace("/" . $char[0] . "/i", $char[1], $keywords);
    }
    //  replace special (long) blanks in title
    $title = str_replace(" ", " ", $title);
    //remove all the fancy jokes some webmasters add
    $title = preg_replace("@<(.*?)>@si", "", $title);
    $title = preg_replace("@ +@si", " ", $title);
    //  replace TABs with a standard blank
    $fulltext = preg_replace("/   +/", " ", $fulltext);
    $count = count(preg_split("/[\\s,]+/", $fulltext));
    $data['fulltext'] = $db_con->real_escape_string($fulltext);
    $data['content'] = $file;
    $data['title'] = $db_con->real_escape_string($title);
    $data['description'] = $db_con->real_escape_string($description);
    $data['keywords'] = $db_con->real_escape_string($keywords);
    $data['host'] = $host;
    $data['path'] = $path;
    $data['nofollow'] = $headdata['nofollow'];
    $data['noindex'] = $headdata['noindex'];
    $data['base'] = $headdata['base'];
    $data['cano_link'] = $headdata['cano_link'];
    $data['count'] = $count;
    $data['refresh'] = $headdata['refresh'];
    $data['wait'] = $headdata['wait'];
    if ($clear == 1) {
        unset($char, $file, $fulltext, $path_sep, $headdata, $regs, $urlparts, $host);
    }
    return $data;
}
Example #19
0
         $sort_by_sql = 't.forum_id';
         $sort_type = SORT_NUMERIC;
         break;
     case 4:
         $sort_by_sql = 't.last_post';
         $sort_type = SORT_NUMERIC;
         break;
     default:
         $sort_by_sql = $show_as == 'topics' ? 't.last_post' : 'p.posted';
         $sort_type = SORT_NUMERIC;
         break;
 }
 // If it's a search for keywords
 if ($keywords) {
     // split the keywords into words
     $keywords_array = split_words($keywords, false);
     if (empty($keywords_array)) {
         message($lang_search['No hits']);
     }
     // Should we search in message body or topic subject specifically?
     $search_in_cond = $search_in ? $search_in > 0 ? ' AND m.subject_match = 0' : ' AND m.subject_match = 1' : '';
     $word_count = 0;
     $match_type = 'and';
     $sort_data = array();
     foreach ($keywords_array as $cur_word) {
         $data = array();
         $data[] = $panther_user['g_id'];
         switch ($cur_word) {
             case 'and':
             case 'or':
             case 'not':
Example #20
0
function add_search_words($mode, $post_id, $post_text, $post_title = '', $topic_id = '')
{
    global $ft_cfg, $lang;
    $stopword_array = @file(FT_ROOT . 'language/lang_' . $ft_cfg['default_lang'] . "/search_stopwords.txt");
    $synonym_array = @file(FT_ROOT . 'language/lang_' . $ft_cfg['default_lang'] . "/search_synonyms.txt");
    $search_raw_words = array();
    $search_raw_words['text'] = split_words(clean_words('post', $post_text, $stopword_array, $synonym_array));
    $search_raw_words['title'] = split_words(clean_words('post', $post_title, $stopword_array, $synonym_array));
    @set_time_limit(0);
    $word = array();
    $word_insert_sql = array();
    while (list($word_in, $search_matches) = @each($search_raw_words)) {
        $word_insert_sql[$word_in] = '';
        if (!empty($search_matches)) {
            for ($i = 0, $cnt = count($search_matches); $i < $cnt; $i++) {
                $search_matches[$i] = @$search_matches[$i] ? trim($search_matches[$i]) : '';
                if ($search_matches[$i] != '') {
                    $word[] = $search_matches[$i];
                    if (!strstr($word_insert_sql[$word_in], "'" . $search_matches[$i] . "'")) {
                        $word_insert_sql[$word_in] .= $word_insert_sql[$word_in] != "" ? ", '" . $search_matches[$i] . "'" : "'" . $search_matches[$i] . "'";
                    }
                }
            }
        }
    }
    if (count($word)) {
        sort($word);
        $prev_word = '';
        $word_text_sql = '';
        $temp_word = array();
        for ($i = 0; $i < count($word); $i++) {
            if ($word[$i] != $prev_word) {
                $temp_word[] = $word[$i];
                $word_text_sql .= ($word_text_sql != '' ? ', ' : '') . "'" . $word[$i] . "'";
            }
            $prev_word = $word[$i];
        }
        $word = $temp_word;
        $check_words = array();
        $value_sql = '';
        $match_word = array();
        for ($i = 0; $i < count($word); $i++) {
            $new_match = true;
            if (isset($check_words[$word[$i]])) {
                $new_match = false;
            }
            if ($new_match) {
                $sql = "INSERT INTO " . SEARCH_WORD_TABLE . " (word_text, word_common)\n\t\t\t\t\tVALUES ('" . $word[$i] . "', 0)";
                if (!DB()->sql_query($sql)) {
                    message_die(GENERAL_ERROR, 'Could not insert new word', '', __LINE__, __FILE__, $sql);
                }
            }
        }
        if ($value_sql != '') {
            $sql = "INSERT IGNORE INTO " . SEARCH_WORD_TABLE . " (word_text, word_common)\n\t\t\t\tVALUES {$value_sql}";
            if (!DB()->sql_query($sql)) {
                message_die(GENERAL_ERROR, 'Could not insert new word', '', __LINE__, __FILE__, $sql);
            }
        }
    }
    while (list($word_in, $match_sql) = @each($word_insert_sql)) {
        $title_match = $word_in == 'title' ? 1 : 0;
        if ($match_sql != '') {
            $sql = "INSERT INTO " . SEARCH_MATCH_TABLE . " (post_id, word_id, title_match)\n\t\t\t\tSELECT {$post_id}, word_id, {$title_match}\n\t\t\t\t\tFROM " . SEARCH_WORD_TABLE . "\n\t\t\t\t\tWHERE word_text IN ({$match_sql})";
            if (!DB()->sql_query($sql)) {
                message_die(GENERAL_ERROR, 'Could not insert new word matches', '', __LINE__, __FILE__, $sql);
            }
        }
    }
    if ($mode == 'single') {
        remove_common('single', 4 / 10, $word);
    }
    return;
}