Пример #1
0
 public function remove()
 {
     $db = DB::get_db();
     $tables = ['pms_data', 'pms_folders', 'pms_messages', 'pms_conversations', 'pms_blocks'];
     $req = 'DROP TABLE IF EXISTS ' . implode(', ', $tables);
     return $db->exec($req);
 }
Пример #2
0
 public function get_query_str()
 {
     $query_str = '';
     $per_page = Input::query('i_per_page') ? intval(Input::query('i_per_page')) : 0;
     $per_page = Container::get('hooks')->fire('model.admin.maintenance.get_query_str.per_page', $per_page);
     $start_at = Input::query('i_start_at') ? intval(Input::query('i_start_at')) : 0;
     $start_at = Container::get('hooks')->fire('model.admin.maintenance.get_query_str.start_at', $start_at);
     // Fetch posts to process this cycle
     $result['select'] = array('p.id', 'p.message', 't.subject', 't.first_post_id');
     $result = DB::for_table('posts')->table_alias('p')->select_many($result['select'])->inner_join('topics', array('t.id', '=', 'p.topic_id'), 't')->where_gte('p.id', $start_at)->order_by_asc('p.id')->limit($per_page);
     $result = Container::get('hooks')->fireDB('model.admin.maintenance.get_query_str.query', $result);
     $result = $result->find_many();
     $end_at = 0;
     foreach ($result as $cur_item) {
         echo '<p><span>' . sprintf(__('Processing post'), $cur_item['id']) . '</span></p>' . "\n";
         if ($cur_item['id'] == $cur_item['first_post_id']) {
             $this->search->update_search_index('post', $cur_item['id'], $cur_item['message'], $cur_item['subject']);
         } else {
             $this->search->update_search_index('post', $cur_item['id'], $cur_item['message']);
         }
         $end_at = $cur_item['id'];
     }
     // Check if there is more work to do
     if ($end_at > 0) {
         $id = DB::for_table('posts')->where_gt('id', $end_at)->order_by_asc('id')->find_one_col('id');
         if ($id) {
             $query_str = '?action=rebuild&i_per_page=' . $per_page . '&i_start_at=' . intval($id);
         }
     }
     $pdo = DB::get_db();
     $pdo = null;
     $query_str = Container::get('hooks')->fire('model.admin.maintenance.get_query_str', $query_str);
     return $query_str;
 }
 public function remove()
 {
     $db = DB::get_db();
     $tables = ['pms_data', 'pms_folders', 'pms_messages', 'pms_conversations', 'pms_blocks'];
     foreach ($tables as $i) {
         $tableExists = DB::for_table($i)->raw_query('SHOW TABLES LIKE "' . ForumSettings::get('db_prefix') . $i . '"')->find_one();
         if ($tableExists) {
             $db->exec('DROP TABLE ' . ForumSettings::get('db_prefix') . $i);
         }
     }
     $columns = ['g_pm_limit', 'g_use_pm', 'g_pm_folder_limit'];
     foreach ($columns as $i) {
         $columnExists = DB::for_table('groups')->raw_query('SHOW COLUMNS FROM ' . ForumSettings::get('db_prefix') . 'groups LIKE \'' . $i . '\'')->find_one();
         if ($columnExists) {
             $db->exec('ALTER TABLE ' . ForumSettings::get('db_prefix') . 'groups DROP COLUMN ' . $i);
         }
     }
 }
Пример #4
0
 public function insert_user($user)
 {
     $user = Container::get('hooks')->fire('model.register.insert_user_start', $user);
     // Insert the new user into the database. We do this now to get the last inserted ID for later use
     $now = time();
     $intial_group_id = ForumSettings::get('o_regs_verify') == '0' ? ForumSettings::get('o_default_user_group') : ForumEnv::get('FEATHER_UNVERIFIED');
     $password_hash = Random::hash($user['password1']);
     // Add the user
     $user['insert'] = array('username' => $user['username'], 'group_id' => $intial_group_id, 'password' => $password_hash, 'email' => $user['email1'], 'email_setting' => ForumSettings::get('o_default_email_setting'), 'timezone' => ForumSettings::get('o_default_timezone'), 'dst' => 0, 'language' => $user['language'], 'style' => ForumSettings::get('o_default_style'), 'registered' => $now, 'registration_ip' => Utils::getIp(), 'last_visit' => $now);
     $user = DB::for_table('users')->create()->set($user['insert']);
     $user = Container::get('hooks')->fireDB('model.register.insert_user_query', $user);
     $user = $user->save();
     $new_uid = DB::get_db()->lastInsertId(ForumSettings::get('db_prefix') . 'users');
     // If the mailing list isn't empty, we may need to send out some alerts
     if (ForumSettings::get('o_mailing_list') != '') {
         // If we previously found out that the email was banned
         if (isset($user['banned_email'])) {
             // Load the "banned email register" template
             $mail_tpl = trim(file_get_contents(ForumEnv::get('FEATHER_ROOT') . 'featherbb/lang/' . User::get()->language . '/mail_templates/banned_email_register.tpl'));
             $mail_tpl = Container::get('hooks')->fire('model.register.insert_user_banned_mail_tpl', $mail_tpl);
             // The first row contains the subject
             $first_crlf = strpos($mail_tpl, "\n");
             $mail_subject = trim(substr($mail_tpl, 8, $first_crlf - 8));
             $mail_subject = Container::get('hooks')->fire('model.register.insert_user_banned_mail_subject', $mail_subject);
             $mail_message = trim(substr($mail_tpl, $first_crlf));
             $mail_message = str_replace('<username>', $user['username'], $mail_message);
             $mail_message = str_replace('<email>', $user['email1'], $mail_message);
             $mail_message = str_replace('<profile_url>', Router::pathFor('userProfile', ['id' => $new_uid]), $mail_message);
             $mail_message = str_replace('<board_mailer>', ForumSettings::get('o_board_title'), $mail_message);
             $mail_message = Container::get('hooks')->fire('model.register.insert_user_banned_mail_message', $mail_message);
             Container::get('email')->feather_mail(ForumSettings::get('o_mailing_list'), $mail_subject, $mail_message);
         }
         // If we previously found out that the email was a dupe
         if (!empty($dupe_list)) {
             // Load the "dupe email register" template
             $mail_tpl = trim(file_get_contents(ForumEnv::get('FEATHER_ROOT') . 'featherbb/lang/' . User::get()->language . '/mail_templates/dupe_email_register.tpl'));
             $mail_tpl = Container::get('hooks')->fire('model.register.insert_user_dupe_mail_tpl', $mail_tpl);
             // The first row contains the subject
             $first_crlf = strpos($mail_tpl, "\n");
             $mail_subject = trim(substr($mail_tpl, 8, $first_crlf - 8));
             $mail_subject = Container::get('hooks')->fire('model.register.insert_user_dupe_mail_subject', $mail_subject);
             $mail_message = trim(substr($mail_tpl, $first_crlf));
             $mail_message = str_replace('<username>', $user['username'], $mail_message);
             $mail_message = str_replace('<dupe_list>', implode(', ', $dupe_list), $mail_message);
             $mail_message = str_replace('<profile_url>', Router::pathFor('userProfile', ['id' => $new_uid]), $mail_message);
             $mail_message = str_replace('<board_mailer>', ForumSettings::get('o_board_title'), $mail_message);
             $mail_message = Container::get('hooks')->fire('model.register.insert_user_dupe_mail_message', $mail_message);
             Container::get('email')->feather_mail(ForumSettings::get('o_mailing_list'), $mail_subject, $mail_message);
         }
         // Should we alert people on the admin mailing list that a new user has registered?
         if (ForumSettings::get('o_regs_report') == '1') {
             // Load the "new user" template
             $mail_tpl = trim(file_get_contents(ForumEnv::get('FEATHER_ROOT') . 'featherbb/lang/' . User::get()->language . '/mail_templates/new_user.tpl'));
             $mail_tpl = Container::get('hooks')->fire('model.register.insert_user_new_mail_tpl', $mail_tpl);
             // The first row contains the subject
             $first_crlf = strpos($mail_tpl, "\n");
             $mail_subject = trim(substr($mail_tpl, 8, $first_crlf - 8));
             $mail_subject = Container::get('hooks')->fire('model.register.insert_user_new_mail_subject', $mail_subject);
             $mail_message = trim(substr($mail_tpl, $first_crlf));
             $mail_message = str_replace('<username>', $user['username'], $mail_message);
             $mail_message = str_replace('<base_url>', Router::pathFor('home'), $mail_message);
             $mail_message = str_replace('<profile_url>', Router::pathFor('userProfile', ['id' => $new_uid]), $mail_message);
             $mail_message = str_replace('<admin_url>', Router::pathFor('profileSection', ['id' => $new_uid, 'section' => 'admin']), $mail_message);
             $mail_message = str_replace('<board_mailer>', ForumSettings::get('o_board_title'), $mail_message);
             $mail_message = Container::get('hooks')->fire('model.register.insert_user_new_mail_message', $mail_message);
             Container::get('email')->feather_mail(ForumSettings::get('o_mailing_list'), $mail_subject, $mail_message);
         }
     }
     // Must the user verify the registration or do we log him/her in right now?
     if (ForumSettings::get('o_regs_verify') == '1') {
         // Load the "welcome" template
         $mail_tpl = trim(file_get_contents(ForumEnv::get('FEATHER_ROOT') . 'featherbb/lang/' . User::get()->language . '/mail_templates/welcome.tpl'));
         $mail_tpl = Container::get('hooks')->fire('model.register.insert_user_welcome_mail_tpl', $mail_tpl);
         // The first row contains the subject
         $first_crlf = strpos($mail_tpl, "\n");
         $mail_subject = trim(substr($mail_tpl, 8, $first_crlf - 8));
         $mail_subject = Container::get('hooks')->fire('model.register.insert_user_welcome_mail_subject', $mail_subject);
         $mail_message = trim(substr($mail_tpl, $first_crlf));
         $mail_subject = str_replace('<board_title>', ForumSettings::get('o_board_title'), $mail_subject);
         $mail_message = str_replace('<base_url>', Router::pathFor('home'), $mail_message);
         $mail_message = str_replace('<username>', $user['username'], $mail_message);
         $mail_message = str_replace('<password>', $user['password1'], $mail_message);
         $mail_message = str_replace('<login_url>', Router::pathFor('login'), $mail_message);
         $mail_message = str_replace('<board_mailer>', ForumSettings::get('o_board_title'), $mail_message);
         $mail_message = Container::get('hooks')->fire('model.register.insert_user_welcome_mail_message', $mail_message);
         Container::get('email')->feather_mail($user['email1'], $mail_subject, $mail_message);
         return Router::redirect(Router::pathFor('home'), __('Reg email') . ' <a href="mailto:' . Utils::escape(ForumSettings::get('o_admin_email')) . '">' . Utils::escape(ForumSettings::get('o_admin_email')) . '</a>.');
     }
     $user_object = new \stdClass();
     $user_object->id = $new_uid;
     $user_object->username = $user['username'];
     $expire = time() + ForumSettings::get('o_timeout_visit');
     $jwt = AuthModel::generate_jwt($user_object, $expire);
     AuthModel::feather_setcookie('Bearer ' . $jwt, $expire);
     // Refresh cache
     Container::get('cache')->store('users_info', Cache::get_users_info());
     Container::get('hooks')->fire('model.register.insert_user');
     return Router::redirect(Router::pathFor('home'), __('Reg complete'));
 }
Пример #5
0
 public function split_posts($tid, $fid, $p = null)
 {
     $posts = Input::post('posts') ? Input::post('posts') : array();
     $posts = Container::get('hooks')->fire('model.topic.split_posts_start', $posts, $tid, $fid);
     if (empty($posts)) {
         throw new Error(__('No posts selected'), 404);
     }
     if (Input::post('split_posts_comply')) {
         if (@preg_match('%[^0-9,]%', $posts)) {
             throw new Error(__('Bad request'), 400);
         }
         $move_to_forum = Input::post('move_to_forum') ? intval(Input::post('move_to_forum')) : 0;
         if ($move_to_forum < 1) {
             throw new Error(__('Bad request'), 400);
         }
         // How many posts did we just split off?
         $num_posts_splitted = substr_count($posts, ',') + 1;
         // Verify that the post IDs are valid
         $posts_array = explode(',', $posts);
         $result = DB::for_table('posts')->where_in('id', $posts_array)->where('topic_id', $tid);
         $result = Container::get('hooks')->fireDB('model.topic.split_posts_first_query', $result);
         $result = $result->find_many();
         if (count($result) != $num_posts_splitted) {
             throw new Error(__('Bad request'), 400);
         }
         unset($result);
         // Verify that the move to forum ID is valid
         $result['where'] = array(array('fp.post_topics' => 'IS NULL'), array('fp.post_topics' => '1'));
         $result = DB::for_table('forums')->table_alias('f')->left_outer_join('forum_perms', array('fp.forum_id', '=', $move_to_forum), 'fp', true)->left_outer_join('forum_perms', array('fp.group_id', '=', User::get()->g_id), null, true)->where_any_is($result['where'])->where_null('f.redirect_url');
         $result = Container::get('hooks')->fireDB('model.topic.split_posts_second_query', $result);
         $result = $result->find_one();
         if (!$result) {
             throw new Error(__('Bad request'), 404);
         }
         // Check subject
         $new_subject = Input::post('new_subject') ? Utils::trim(Input::post('new_subject')) : '';
         if ($new_subject == '') {
             throw new Error(__('No subject'), 400);
         } elseif (Utils::strlen($new_subject) > 70) {
             throw new Error(__('Too long subject'), 400);
         }
         // Get data from the new first post
         $select_first_post = array('id', 'poster', 'posted');
         $first_post_data = DB::for_table('posts')->select_many($select_first_post)->where_in('id', $posts_array)->order_by_asc('id')->find_one();
         // Create the new topic
         $topic['insert'] = array('poster' => $first_post_data['poster'], 'subject' => $new_subject, 'posted' => $first_post_data['posted'], 'first_post_id' => $first_post_data['id'], 'forum_id' => $move_to_forum);
         $topic = DB::for_table('topics')->create()->set($topic['insert']);
         $topic = Container::get('hooks')->fireDB('model.topic.split_posts_topic_query', $topic);
         $topic->save();
         $new_tid = DB::get_db()->lastInsertId(ForumSettings::get('db_prefix') . 'topics');
         // Move the posts to the new topic
         $move_posts = DB::for_table('posts')->where_in('id', $posts_array)->find_result_set()->set('topic_id', $new_tid);
         $move_posts = Container::get('hooks')->fireDB('model.topic.split_posts_move_query', $move_posts);
         $move_posts->save();
         // Apply every subscription to both topics
         DB::for_table('topic_subscriptions')->raw_query('INSERT INTO ' . ForumSettings::get('db_prefix') . 'topic_subscriptions (user_id, topic_id) SELECT user_id, ' . $new_tid . ' FROM ' . ForumSettings::get('db_prefix') . 'topic_subscriptions WHERE topic_id=:tid', array('tid' => $tid));
         // Get last_post, last_post_id, and last_poster from the topic and update it
         $last_old_post_data['select'] = array('id', 'poster', 'posted');
         $last_old_post_data = DB::for_table('posts')->select_many($last_old_post_data['select'])->where('topic_id', $tid)->order_by_desc('id');
         $last_old_post_data = Container::get('hooks')->fireDB('model.topic.split_posts_last_old_post_data_query', $last_old_post_data);
         $last_old_post_data = $last_old_post_data->find_one();
         // Update the old topic
         $update_old_topic['insert'] = array('last_post' => $last_old_post_data['posted'], 'last_post_id' => $last_old_post_data['id'], 'last_poster' => $last_old_post_data['poster']);
         $update_old_topic = DB::for_table('topics')->where('id', $tid)->find_one()->set($update_old_topic['insert'])->set_expr('num_replies', 'num_replies-' . $num_posts_splitted);
         $update_old_topic = Container::get('hooks')->fireDB('model.topic.split_posts_update_old_topic_query', $update_old_topic);
         $update_old_topic->save();
         // Get last_post, last_post_id, and last_poster from the new topic and update it
         $last_new_post_data['select'] = array('id', 'poster', 'posted');
         $last_new_post_data = DB::for_table('posts')->select_many($last_new_post_data['select'])->where('topic_id', $new_tid)->order_by_desc('id');
         $last_new_post_data = Container::get('hooks')->fireDB('model.topic.split_posts_last_new_post_query', $last_new_post_data);
         $last_new_post_data = $last_new_post_data->find_one();
         // Update the new topic
         $update_new_topic['insert'] = array('last_post' => $last_new_post_data['posted'], 'last_post_id' => $last_new_post_data['id'], 'last_poster' => $last_new_post_data['poster']);
         $update_new_topic = DB::for_table('topics')->where('id', $new_tid)->find_one()->set($update_new_topic['insert'])->set_expr('num_replies', 'num_replies-' . $num_posts_splitted - 1);
         $update_new_topic = Container::get('hooks')->fireDB('model.topic.split_posts_update_new_topic_query', $update_new_topic);
         $update_new_topic = $update_new_topic->save();
         Forum::update($fid);
         Forum::update($move_to_forum);
         return Router::redirect(Router::pathFor('Topic', array('id' => $new_tid)), __('Split posts redirect'));
     }
     $posts = Container::get('hooks')->fire('model.topic.split_posts', $posts);
     return $posts;
 }
Пример #6
0
 public function insert_topic($post, $fid)
 {
     $new = array();
     $new = Container::get('hooks')->fireDB('model.post.insert_topic_start', $new, $post, $fid);
     // Create the topic
     $topic['insert'] = array('poster' => $post['username'], 'subject' => $post['subject'], 'posted' => $post['time'], 'last_post' => $post['time'], 'last_poster' => $post['username'], 'sticky' => $post['stick_topic'], 'forum_id' => $fid);
     $topic = DB::for_table('topics')->create()->set($topic['insert']);
     $topic = Container::get('hooks')->fireDB('model.post.insert_topic_create', $topic);
     $topic = $topic->save();
     $new['tid'] = DB::get_db()->lastInsertId(ForumSettings::get('db_prefix') . 'topics');
     if (!User::get()->is_guest) {
         // To subscribe or not to subscribe, that ...
         if (ForumSettings::get('o_topic_subscriptions') == '1' && $post['subscribe']) {
             $subscription['insert'] = array('user_id' => User::get()->id, 'topic_id' => $new['tid']);
             $subscription = DB::for_table('topic_subscriptions')->create()->set($subscription['insert']);
             $subscription = Container::get('hooks')->fireDB('model.post.insert_topic_subscription_member', $subscription);
             $subscription = $subscription->save();
         }
         // Create the post ("topic post")
         $query['insert'] = array('poster' => $post['username'], 'poster_id' => User::get()->id, 'poster_ip' => Utils::getIp(), 'message' => $post['message'], 'hide_smilies' => $post['hide_smilies'], 'posted' => $post['time'], 'topic_id' => $new['tid']);
         $query = DB::for_table('posts')->create()->set($query['insert']);
         $query = Container::get('hooks')->fireDB('model.post.insert_topic_post_member', $query);
         $query = $query->save();
     } else {
         // It's a guest
         // Create the post ("topic post")
         $query['insert'] = array('poster' => $post['username'], 'poster_ip' => Utils::getIp(), 'message' => $post['message'], 'hide_smilies' => $post['hide_smilies'], 'posted' => $post['time'], 'topic_id' => $new['tid']);
         if (ForumSettings::get('p_force_guest_email') == '1' || $post['email'] != '') {
             $query['poster_email'] = $post['email'];
         }
         $query = DB::for_table('posts')->create()->set($query['insert']);
         $query = Container::get('hooks')->fireDB('model.post.insert_topic_post_member', $query);
         $query = $query->save();
     }
     $new['pid'] = DB::get_db()->lastInsertId(ForumSettings::get('db_prefix') . 'topics');
     // Update the topic with last_post_id
     unset($topic);
     $topic['update'] = array('last_post_id' => $new['pid'], 'first_post_id' => $new['pid']);
     $topic = DB::for_table('topics')->where('id', $new['tid'])->find_one()->set($topic['update']);
     $topic = Container::get('hooks')->fireDB('model.post.insert_topic_post_topic', $topic);
     $topic = $topic->save();
     $this->search->update_search_index('post', $new['pid'], $post['message'], $post['subject']);
     Forum::update($fid);
     $new = Container::get('hooks')->fireDB('model.post.insert_topic', $new);
     return $new;
 }
Пример #7
0
 public function create_table($table_name, $sql)
 {
     $db = DB::get_db();
     $req = preg_replace('/%t%/', '`' . $table_name . '`', $sql);
     return $db->exec($req);
 }
Пример #8
0
 public function update_search_index($mode, $post_id, $message, $subject = null)
 {
     $message = utf8_strtolower($message);
     $subject = utf8_strtolower($subject);
     // Remove any bbcode that we shouldn't index
     $message = $this->strip_bbcode($message);
     // Split old and new post/subject to obtain array of 'words'
     $words_message = $this->split_words($message, true);
     $words_subject = $subject ? $this->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 (ForumSettings::get('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 ' . ForumSettings::get('db_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 ' . ForumSettings::get('db_prefix') . 'search_matches (post_id, word_id, subject_match) SELECT ' . $post_id . ', id, ' . $subject_match . ' FROM ' . ForumSettings::get('db_prefix') . 'search_words WHERE word IN (' . $placeholders . ')', $wordlist);
         }
     }
     unset($words);
 }
Пример #9
0
 public function get_search_results()
 {
     $search = array();
     $search = Container::get('hooks')->fire('model.search.get_search_results_start', $search);
     $action = Input::query('action') ? Input::query('action') : null;
     $forums = Input::query('forums') ? is_array(Input::query('forums')) ? Input::query('forums') : array_filter(explode(',', Input::query('forums'))) : (Input::query('forums') ? array(Input::query('forums')) : array());
     $sort_dir = Input::query('sort_dir') && Input::query('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 (Input::query('search_id')) {
         $search_id = intval(Input::query('search_id'));
         if ($search_id < 1) {
             throw new Error(__('Bad request'), 400);
         }
     } elseif ($action == 'search') {
         $keywords = Input::query('keywords') ? utf8_strtolower(Utils::trim(Input::query('keywords'))) : null;
         $author = Input::query('author') ? utf8_strtolower(Utils::trim(Input::query('author'))) : null;
         if (preg_match('%^[\\*\\%]+$%', $keywords) || Utils::strlen(str_replace(array('*', '%'), '', $keywords)) < ForumEnv::get('FEATHER_SEARCH_MIN_WORD') && !$this->search->is_cjk($keywords)) {
             $keywords = '';
         }
         if (preg_match('%^[\\*\\%]+$%', $author) || Utils::strlen(str_replace(array('*', '%'), '', $author)) < 2) {
             $author = '';
         }
         if (!$keywords && !$author) {
             throw new Error(__('No terms'), 400);
         }
         if ($author) {
             $author = str_replace('*', '%', $author);
         }
         $show_as = Input::query('show_as') && Input::query('show_as') == 'topics' ? 'topics' : 'posts';
         $sort_by = Input::query('sort_by') ? intval(Input::query('sort_by')) : 0;
         $search_in = !Input::query('search_in') || Input::query('search_in') == '0' ? 0 : (Input::query('search_in') == '1' ? 1 : -1);
     } elseif ($action == 'show_user_posts' || $action == 'show_user_topics' || $action == 'show_subscriptions') {
         $user_id = Input::query('user_id') ? intval(Input::query('user_id')) : User::get()->id;
         if ($user_id < 2) {
             throw new Error(__('Bad request'), 404);
         }
         // Subscribed topics can only be viewed by admins, moderators and the users themselves
         if ($action == 'show_subscriptions' && !User::get()->is_admmod && $user_id != User::get()->id) {
             throw new Error(__('No permission'), 403);
         }
     } elseif ($action == 'show_recent') {
         $interval = Input::query('value') ? intval(Input::query('value')) : 86400;
     } elseif ($action == 'show_replies') {
         if (User::get()->is_guest) {
             throw new Error(__('Bad request'), 404);
         }
     } elseif ($action != 'show_new' && $action != 'show_unanswered') {
         throw new Error(__('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 = User::get()->is_guest ? Utils::getIp() : User::get()->username;
         $search_data = DB::for_table('search_cache')->where('id', $search_id)->where('ident', $ident);
         $search_data = Container::get('hooks')->fireDB('model.search.get_search_results_search_data_query', $search_data);
         $search_data = $search_data->find_one_col('search_data');
         if ($search_data) {
             $temp = unserialize($search_data);
             $temp = Container::get('hooks')->fire('model.search.get_search_results_temp', $temp);
             $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 {
             throw new Error(__('No hits'), 404);
         }
     } else {
         $keyword_results = $author_results = array();
         // Search a specific forum?
         $forum_sql = !empty($forums) || empty($forums) && ForumSettings::get('o_search_all_forums') == '0' && !User::get()->is_admmod ? ' AND t.forum_id IN (' . implode(',', $forums) . ')' : '';
         if (!empty($author) || !empty($keywords)) {
             // Flood protection
             if (User::get()->last_search && time() - User::get()->last_search < User::get()->g_search_flood && time() - User::get()->last_search >= 0) {
                 throw new Error(sprintf(__('Search flood'), User::get()->g_search_flood, User::get()->g_search_flood - (time() - User::get()->last_search)), 429);
             }
             if (!User::get()->is_guest) {
                 $update_last_search = DB::for_table('users')->where('id', User::get()->id);
             } else {
                 $update_last_search = DB::for_table('online')->where('ident', Utils::getIp());
             }
             $update_last_search = Container::get('hooks')->fireDB('model.search.get_search_results_update_last_search', $update_last_search);
             $update_last_search = $update_last_search->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;
             }
             $sort_by = Container::get('hooks')->fire('model.search.get_search_results_sort_by', $sort_by);
             // If it's a search for keywords
             if ($keywords) {
                 // split the keywords into words
                 $keywords_array = $this->search->split_words($keywords, false);
                 $keywords_array = Container::get('hooks')->fire('model.search.get_search_results_keywords_array', $keywords_array);
                 if (empty($keywords_array)) {
                     throw new Error(__('No hits'), 400);
                 }
                 // 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' : '';
                 $search_in_cond = Container::get('hooks')->fire('model.search.get_search_results_search_cond', $search_in_cond);
                 $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 ($this->search->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 ' . ForumSettings::get('db_prefix') . 'posts AS p INNER JOIN ' . ForumSettings::get('db_prefix') . 'topics AS t ON t.id=p.topic_id LEFT JOIN ' . ForumSettings::get('db_prefix') . 'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id=' . User::get()->g_id . ') WHERE (' . $where_cond_cjk . ') AND (fp.read_forum IS NULL OR fp.read_forum=1)' . $forum_sql, array(':where_cond' => $where_cond));
                             } else {
                                 $result = DB::for_table('posts')->raw_query('SELECT m.post_id, p.topic_id, ' . $sort_by_sql . ' AS sort_by FROM ' . ForumSettings::get('db_prefix') . 'search_words AS w INNER JOIN ' . ForumSettings::get('db_prefix') . 'search_matches AS m ON m.word_id = w.id INNER JOIN ' . ForumSettings::get('db_prefix') . 'posts AS p ON p.id=m.post_id INNER JOIN ' . ForumSettings::get('db_prefix') . 'topics AS t ON t.id=p.topic_id LEFT JOIN ' . ForumSettings::get('db_prefix') . 'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id=' . User::get()->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)));
                             }
                             $result = Container::get('hooks')->fireDB('model.search.get_search_results_search_first_query', $result);
                             $result = $result->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;
                     }
                 }
                 $keyword_results = Container::get('hooks')->fire('model.search.get_search_results_search_keyword_results', $keyword_results);
                 // 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
                 $keyword_results = array_combine($post_ids, $topic_ids);
                 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(__('Guest'))) {
                 $username_exists = DB::for_table('users')->select('id')->where_like('username', $author);
                 $username_exists = Container::get('hooks')->fireDB('model.search.get_search_results_username_exists', $username_exists);
                 $username_exists = $username_exists->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 ' . ForumSettings::get('db_prefix') . 'posts AS p INNER JOIN ' . ForumSettings::get('db_prefix') . 'topics AS t ON t.id=p.topic_id LEFT JOIN ' . ForumSettings::get('db_prefix') . 'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id=' . User::get()->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);
                     $result = Container::get('hooks')->fireDB('model.search.get_search_results_search_second_query', $result);
                     $result = $result->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, Utils::trim(Input::query('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', Utils::trim(Input::query('author')), implode(',', $forums), $search_in);
             }
             $search_ids = Container::get('hooks')->fire('model.search.get_search_results_search_ids', $search_ids);
             $search_type = Container::get('hooks')->fire('model.search.get_search_results_search_type', $search_type);
             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);
             $search_ids = Container::get('hooks')->fire('model.search.get_search_results_search_ids', $search_ids);
             $search_type = Container::get('hooks')->fire('model.search.get_search_results_search_type', $search_type);
             $num_hits = count($search_ids);
             if (!$num_hits) {
                 throw new Error(__('No hits'), 400);
             }
         } 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';
             $result['where'] = 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 (User::get()->is_guest) {
                     throw new Error(__('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', '=', User::get()->g_id), null, true)->where_any_is($result['where'])->where_gt('t.last_post', User::get()->last_visit)->where_null('t.moved_to')->order_by_desc('t.last_post');
                 if (Input::query('fid')) {
                     $result = $result->where('t.forum_id', intval(Input::query('fid')));
                 }
                 $result = Container::get('hooks')->fireDB('model.search.get_search_results_topic_query', $result);
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     return Router::redirect(Router::pathFor('home'), __('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', '=', User::get()->g_id), null, true)->where_any_is($result['where'])->where_gt('t.last_post', time() - $interval)->where_null('t.moved_to')->order_by_desc('t.last_post');
                 if (Input::query('fid')) {
                     $result = $result->where('t.forum_id', intval(Input::query('fid')));
                 }
                 $result = Container::get('hooks')->fireDB('model.search.get_search_results_topic_query', $result);
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     return Router::redirect(Router::pathFor('home'), __('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', '=', User::get()->g_id), null, true)->where_any_is($result['where'])->where('p.poster_id', User::get()->id)->group_by('t.id');
                 if (ForumSettings::get('db_type') == 'pgsql') {
                     $result = $result->group_by('t.last_post');
                 }
                 $result = Container::get('hooks')->fireDB('model.search.get_search_results_topic_query', $result);
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     return Router::redirect(Router::pathFor('home'), __('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', '=', User::get()->g_id), null, true)->where_any_is($result['where'])->where('p.poster_id', $user_id)->order_by_desc('p.posted');
                 $result = Container::get('hooks')->fireDB('model.search.get_search_results_post_query', $result);
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     return Router::redirect(Router::pathFor('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', '=', User::get()->g_id), null, true)->where_any_is($result['where'])->where('p.poster_id', $user_id)->order_by_desc('t.last_post');
                 $result = Container::get('hooks')->fireDB('model.search.get_search_results_topic_query', $result);
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     return Router::redirect(Router::pathFor('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 (User::get()->is_guest) {
                     throw new Error(__('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', '=', User::get()->g_id), null, true)->where_any_is($result['where'])->order_by_desc('t.last_post');
                 $result = Container::get('hooks')->fireDB('model.search.get_search_results_topic_query', $result);
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     return Router::redirect(Router::pathFor('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', '=', User::get()->g_id), null, true)->where('t.num_replies', 0)->where_null('t.moved_to')->where_any_is($result['where'])->order_by_desc('t.last_post');
                 $result = Container::get('hooks')->fireDB('model.search.get_search_results_topic_query', $result);
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     return Router::redirect(Router::pathFor('home'), __('No unanswered'));
                 }
             }
             $search_ids = array();
             foreach ($result as $row) {
                 $search_ids[] = $row['id'];
             }
             $pdo = DB::get_db();
             $pdo = null;
         } else {
             throw new Error(__('Bad request'), 404);
         }
         // Prune "old" search results
         $old_searches = array();
         $result = DB::for_table('online')->select('ident');
         $result = Container::get('hooks')->fireDB('model.search.get_search_results_prune_search', $result);
         $result = $result->find_many();
         if ($result) {
             foreach ($result as $row) {
                 $old_searches[] = $row['ident'];
             }
             $delete_cache = DB::for_table('search_cache')->where_not_in('ident', $old_searches);
             $delete_cache = Container::get('hooks')->fireDB('model.search.get_search_results_delete_cache', $delete_cache);
             $delete_cache = $delete_cache->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 = User::get()->is_guest ? Utils::getIp() : User::get()->username;
         $cache['insert'] = array('id' => $search_id, 'ident' => $ident, 'search_data' => $temp);
         $cache = DB::for_table('search_cache')->create()->set($cache['insert']);
         $cache = Container::get('hooks')->fireDB('model.search.get_search_results_update_cache', $cache);
         $cache = $cache->save();
     }
     // If we're on the new posts search, display a "mark all as read" link
     if (!User::get()->is_guest && $search_type[0] == 'action' && $search_type[1] == 'show_new') {
         $search['forum_actions'][] = '<a href="' . Router::pathFor('markRead') . '">' . __('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' ? User::get()->disp_posts : User::get()->disp_topics;
         $num_pages = ceil($num_hits / $per_page);
         $p = !Input::query('p') || Input::query('p') <= 1 || Input::query('p') > $num_pages ? 1 : intval(Input::query('p'));
         $start_from = $per_page * ($p - 1);
         $search['start_from'] = $start_from;
         // Generate paging links
         $search['paging_links'] = '<span class="pages-label">' . __('Pages') . ' </span>' . Url::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') {
             $result['select'] = 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($result['select'])->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);
             $result = Container::get('hooks')->fireDB('model.search.get_search_results_select_posts_query', $result);
         } else {
             $result['select'] = 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($result['select'])->inner_join('forums', array('f.id', '=', 't.forum_id'), 'f')->where_in('t.id', $search_ids)->order_by($sort_by_sql, $sort_dir);
             $result = Container::get('hooks')->fireDB('model.search.get_search_results_select_topics_query', $result);
         }
         $result = $result->find_array();
         $search['search_set'] = array();
         foreach ($result as $row) {
             $search['search_set'][] = $row;
         }
         $search['crumbs_text']['show_as'] = __('Search');
         if ($search_type[0] == 'action') {
             if ($search_type[1] == 'show_user_topics') {
                 $search['crumbs_text']['search_type'] = '<a href="' . Router::pathFor('search') . '?action=show_user_topics&amp;user_id=' . $search_type[2] . '">' . sprintf(__('Quick search show_user_topics'), Utils::escape($search['search_set'][0]['poster'])) . '</a>';
             } elseif ($search_type[1] == 'show_user_posts') {
                 $search['crumbs_text']['search_type'] = '<a href="' . Router::pathFor('search') . '?action=show_user_posts&amp;user_id=' . $search_type[2] . '">' . sprintf(__('Quick search show_user_posts'), Utils::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);
                 $subscriber_name = Container::get('hooks')->fireDB('model.search.get_search_results_subscriber_name', $result);
                 $subscriber_name = $subscriber_name->find_one_col('username');
                 if (!$subscriber_name) {
                     throw new Error(__('Bad request'), 404);
                 }
                 $search['crumbs_text']['search_type'] = '<a href="' . Router::pathFor('search') . '?action=show_subscription&amp;user_id=' . $subscriber_id . '">' . sprintf(__('Quick search show_subscriptions'), Utils::escape($subscriber_name)) . '</a>';
             } else {
                 $search_url = str_replace('_', '/', $search_type[1]);
                 $search['crumbs_text']['search_type'] = '<a href="' . Router::pathFor('search') . $search_url . '">' . __('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(__('By both show as ' . $show_as), Utils::escape($keywords), Utils::escape($author));
             } elseif ($search_type[0] == 'keywords') {
                 $keywords = $search_type[1];
                 $search['crumbs_text']['search_type'] = sprintf(__('By keywords show as ' . $show_as), Utils::escape($keywords));
             } elseif ($search_type[0] == 'author') {
                 $author = $search_type[1];
                 $search['crumbs_text']['search_type'] = sprintf(__('By user show as ' . $show_as), Utils::escape($author));
             }
             $search['crumbs_text']['search_type'] = '<a href="' . Router::pathFor('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;
     $search = Container::get('hooks')->fire('model.search.get_search_results', $search);
     return $search;
 }