phpbb\search\fulltext_native::index PHP Method

index() public method

Updates wordlist and wordmatch tables when a message is posted or changed
public index ( string $mode, integer $post_id, &$message, &$subject, integer $poster_id, integer $forum_id )
$mode string Contains the post mode: edit, post, reply, quote
$post_id integer The id of the post which is modified/created
$poster_id integer Post author's user id
$forum_id integer The id of the forum in which the post is located
    public function index($mode, $post_id, &$message, &$subject, $poster_id, $forum_id)
    {
        if (!$this->config['fulltext_native_load_upd']) {
            /**
             * The search indexer is disabled, return
             */
            return;
        }
        // Split old and new post/subject to obtain array of 'words'
        $split_text = $this->split_message($message);
        $split_title = $this->split_message($subject);
        $cur_words = array('post' => array(), 'title' => array());
        $words = array();
        if ($mode == 'edit') {
            $words['add']['post'] = array();
            $words['add']['title'] = array();
            $words['del']['post'] = array();
            $words['del']['title'] = array();
            $sql = 'SELECT w.word_id, w.word_text, m.title_match
				FROM ' . SEARCH_WORDLIST_TABLE . ' w, ' . SEARCH_WORDMATCH_TABLE . " m\n\t\t\t\tWHERE m.post_id = {$post_id}\n\t\t\t\t\tAND w.word_id = m.word_id";
            $result = $this->db->sql_query($sql);
            while ($row = $this->db->sql_fetchrow($result)) {
                $which = $row['title_match'] ? 'title' : 'post';
                $cur_words[$which][$row['word_text']] = $row['word_id'];
            }
            $this->db->sql_freeresult($result);
            $words['add']['post'] = array_diff($split_text, array_keys($cur_words['post']));
            $words['add']['title'] = array_diff($split_title, array_keys($cur_words['title']));
            $words['del']['post'] = array_diff(array_keys($cur_words['post']), $split_text);
            $words['del']['title'] = array_diff(array_keys($cur_words['title']), $split_title);
        } else {
            $words['add']['post'] = $split_text;
            $words['add']['title'] = $split_title;
            $words['del']['post'] = array();
            $words['del']['title'] = array();
        }
        unset($split_text);
        unset($split_title);
        // Get unique words from the above arrays
        $unique_add_words = array_unique(array_merge($words['add']['post'], $words['add']['title']));
        // We now have unique arrays of all words to be added and removed and
        // individual arrays of added and removed words for text and title. What
        // we need to do now is add the new words (if they don't already exist)
        // and then add (or remove) matches between the words and this post
        if (sizeof($unique_add_words)) {
            $sql = 'SELECT word_id, word_text
				FROM ' . SEARCH_WORDLIST_TABLE . '
				WHERE ' . $this->db->sql_in_set('word_text', $unique_add_words);
            $result = $this->db->sql_query($sql);
            $word_ids = array();
            while ($row = $this->db->sql_fetchrow($result)) {
                $word_ids[$row['word_text']] = $row['word_id'];
            }
            $this->db->sql_freeresult($result);
            $new_words = array_diff($unique_add_words, array_keys($word_ids));
            $this->db->sql_transaction('begin');
            if (sizeof($new_words)) {
                $sql_ary = array();
                foreach ($new_words as $word) {
                    $sql_ary[] = array('word_text' => (string) $word, 'word_count' => 0);
                }
                $this->db->sql_return_on_error(true);
                $this->db->sql_multi_insert(SEARCH_WORDLIST_TABLE, $sql_ary);
                $this->db->sql_return_on_error(false);
            }
            unset($new_words, $sql_ary);
        } else {
            $this->db->sql_transaction('begin');
        }
        // now update the search match table, remove links to removed words and add links to new words
        foreach ($words['del'] as $word_in => $word_ary) {
            $title_match = $word_in == 'title' ? 1 : 0;
            if (sizeof($word_ary)) {
                $sql_in = array();
                foreach ($word_ary as $word) {
                    $sql_in[] = $cur_words[$word_in][$word];
                }
                $sql = 'DELETE FROM ' . SEARCH_WORDMATCH_TABLE . '
					WHERE ' . $this->db->sql_in_set('word_id', $sql_in) . '
						AND post_id = ' . intval($post_id) . "\n\t\t\t\t\t\tAND title_match = {$title_match}";
                $this->db->sql_query($sql);
                $sql = 'UPDATE ' . SEARCH_WORDLIST_TABLE . '
					SET word_count = word_count - 1
					WHERE ' . $this->db->sql_in_set('word_id', $sql_in) . '
						AND word_count > 0';
                $this->db->sql_query($sql);
                unset($sql_in);
            }
        }
        $this->db->sql_return_on_error(true);
        foreach ($words['add'] as $word_in => $word_ary) {
            $title_match = $word_in == 'title' ? 1 : 0;
            if (sizeof($word_ary)) {
                $sql = 'INSERT INTO ' . SEARCH_WORDMATCH_TABLE . ' (post_id, word_id, title_match)
					SELECT ' . (int) $post_id . ', word_id, ' . (int) $title_match . '
					FROM ' . SEARCH_WORDLIST_TABLE . '
					WHERE ' . $this->db->sql_in_set('word_text', $word_ary);
                $this->db->sql_query($sql);
                $sql = 'UPDATE ' . SEARCH_WORDLIST_TABLE . '
					SET word_count = word_count + 1
					WHERE ' . $this->db->sql_in_set('word_text', $word_ary);
                $this->db->sql_query($sql);
            }
        }
        $this->db->sql_return_on_error(false);
        $this->db->sql_transaction('commit');
        // destroy cached search results containing any of the words removed or added
        $this->destroy_cache(array_unique(array_merge($words['add']['post'], $words['add']['title'], $words['del']['post'], $words['del']['title'])), array($poster_id));
        unset($unique_add_words);
        unset($words);
        unset($cur_words);
    }