phpbb\search\fulltext_postgres::keyword_search PHP Method

    public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $post_visibility, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page)
    {
        // No keywords? No posts
        if (!$this->search_query) {
            return false;
        }
        // When search query contains queries like -foo
        if (strpos($this->search_query, '+') === false) {
            return false;
        }
        // generate a search_key from all the options to identify the results
        $search_key = md5(implode('#', array(implode(', ', $this->split_words), $type, $fields, $terms, $sort_days, $sort_key, $topic_id, implode(',', $ex_fid_ary), $post_visibility, implode(',', $author_ary))));
        if ($start < 0) {
            $start = 0;
        }
        // try reading the results from cache
        $result_count = 0;
        if ($this->obtain_ids($search_key, $result_count, $id_ary, $start, $per_page, $sort_dir) == SEARCH_RESULT_IN_CACHE) {
            return $result_count;
        }
        $id_ary = array();
        $join_topic = $type == 'posts' ? false : true;
        // Build sql strings for sorting
        $sql_sort = $sort_by_sql[$sort_key] . ($sort_dir == 'a' ? ' ASC' : ' DESC');
        $sql_sort_table = $sql_sort_join = '';
        switch ($sql_sort[0]) {
            case 'u':
                $sql_sort_table = USERS_TABLE . ' u, ';
                $sql_sort_join = $type == 'posts' ? ' AND u.user_id = p.poster_id ' : ' AND u.user_id = t.topic_poster ';
                break;
            case 't':
                $join_topic = true;
                break;
            case 'f':
                $sql_sort_table = FORUMS_TABLE . ' f, ';
                $sql_sort_join = ' AND f.forum_id = p.forum_id ';
                break;
        }
        // Build some display specific sql strings
        switch ($fields) {
            case 'titleonly':
                $sql_match = 'p.post_subject';
                $sql_match_where = ' AND p.post_id = t.topic_first_post_id';
                $join_topic = true;
                break;
            case 'msgonly':
                $sql_match = 'p.post_text';
                $sql_match_where = '';
                break;
            case 'firstpost':
                $sql_match = 'p.post_subject, p.post_text';
                $sql_match_where = ' AND p.post_id = t.topic_first_post_id';
                $join_topic = true;
                break;
            default:
                $sql_match = 'p.post_subject, p.post_text';
                $sql_match_where = '';
                break;
        }
        $sql_select = $type == 'posts' ? 'p.post_id' : 'DISTINCT t.topic_id';
        $sql_from = $join_topic ? TOPICS_TABLE . ' t, ' : '';
        $field = $type == 'posts' ? 'post_id' : 'topic_id';
        $sql_author = sizeof($author_ary) == 1 ? ' = ' . $author_ary[0] : 'IN (' . implode(', ', $author_ary) . ')';
        if (sizeof($author_ary) && $author_name) {
            // first one matches post of registered users, second one guests and deleted users
            $sql_author = '(' . $this->db->sql_in_set('p.poster_id', array_diff($author_ary, array(ANONYMOUS)), false, true) . ' OR p.post_username ' . $author_name . ')';
        } else {
            if (sizeof($author_ary)) {
                $sql_author = ' AND ' . $this->db->sql_in_set('p.poster_id', $author_ary);
            } else {
                $sql_author = '';
            }
        }
        $sql_where_options = $sql_sort_join;
        $sql_where_options .= $topic_id ? ' AND p.topic_id = ' . $topic_id : '';
        $sql_where_options .= $join_topic ? ' AND t.topic_id = p.topic_id' : '';
        $sql_where_options .= sizeof($ex_fid_ary) ? ' AND ' . $this->db->sql_in_set('p.forum_id', $ex_fid_ary, true) : '';
        $sql_where_options .= ' AND ' . $post_visibility;
        $sql_where_options .= $sql_author;
        $sql_where_options .= $sort_days ? ' AND p.post_time >= ' . (time() - $sort_days * 86400) : '';
        $sql_where_options .= $sql_match_where;
        $tmp_sql_match = array();
        $sql_match = str_replace(',', " || ' ' ||", $sql_match);
        $tmp_sql_match = "to_tsvector ('" . $this->db->sql_escape($this->config['fulltext_postgres_ts_name']) . "', " . $sql_match . ") @@ to_tsquery ('" . $this->db->sql_escape($this->config['fulltext_postgres_ts_name']) . "', '" . $this->db->sql_escape($this->tsearch_query) . "')";
        $this->db->sql_transaction('begin');
        $sql_from = "FROM {$sql_from}{$sql_sort_table}" . POSTS_TABLE . " p";
        $sql_where = "WHERE (" . $tmp_sql_match . ")\n\t\t\t{$sql_where_options}";
        $sql = "SELECT {$sql_select}\n\t\t\t{$sql_from}\n\t\t\t{$sql_where}\n\t\t\tORDER BY {$sql_sort}";
        $result = $this->db->sql_query_limit($sql, $this->config['search_block_size'], $start);
        while ($row = $this->db->sql_fetchrow($result)) {
            $id_ary[] = $row[$field];
        }
        $this->db->sql_freeresult($result);
        $id_ary = array_unique($id_ary);
        // if the total result count is not cached yet, retrieve it from the db
        if (!$result_count) {
            $sql_count = "SELECT COUNT(*) as result_count\n\t\t\t\t{$sql_from}\n\t\t\t\t{$sql_where}";
            $result = $this->db->sql_query($sql_count);
            $result_count = (int) $this->db->sql_fetchfield('result_count');
            $this->db->sql_freeresult($result);
            if (!$result_count) {
                return false;
            }
        }
        $this->db->sql_transaction('commit');
        if ($start >= $result_count) {
            $start = floor(($result_count - 1) / $per_page) * $per_page;
            $result = $this->db->sql_query_limit($sql, $this->config['search_block_size'], $start);
            while ($row = $this->db->sql_fetchrow($result)) {
                $id_ary[] = $row[$field];
            }
            $this->db->sql_freeresult($result);
            $id_ary = array_unique($id_ary);
        }
        // store the ids, from start on then delete anything that isn't on the current page because we only need ids for one page
        $this->save_ids($search_key, implode(' ', $this->split_words), $author_ary, $result_count, $id_ary, $start, $sort_dir);
        $id_ary = array_slice($id_ary, 0, (int) $per_page);
        return $result_count;
    }