Ejemplo n.º 1
0
 public function display($req, $res, $args)
 {
     Container::get('hooks')->fire('controller.userlist.display');
     if (User::get()->g_view_users == '0') {
         throw new Error(__('No permission'), 403);
     }
     // Determine if we are allowed to view post counts
     $show_post_count = ForumSettings::get('o_show_post_count') == '1' || User::get()->is_admmod ? true : false;
     $username = Input::query('username') && User::get()->g_search_users == '1' ? Utils::trim(Input::query('username')) : '';
     $show_group = Input::query('show_group') ? intval(Input::query('show_group')) : -1;
     $sort_by = Input::query('sort_by') && (in_array(Input::query('sort_by'), array('username', 'registered')) || Input::query('sort_by') == 'num_posts' && $show_post_count) ? Input::query('sort_by') : 'username';
     $sort_dir = Input::query('sort_dir') && Input::query('sort_dir') == 'DESC' ? 'DESC' : 'ASC';
     $num_users = $this->model->fetch_user_count($username, $show_group);
     // Determine the user offset (based on $page)
     $num_pages = ceil($num_users / 50);
     $p = !Input::query('p') || $page <= 1 || $page > $num_pages ? 1 : intval($page);
     $start_from = 50 * ($p - 1);
     if (User::get()->g_search_users == '1') {
         $focus_element = array('userlist', 'username');
     } else {
         $focus_element = array();
     }
     // Generate paging links
     $paging_links = '<span class="pages-label">' . __('Pages') . ' </span>' . Url::paginate_old($num_pages, $p, '?username='******'&amp;show_group=' . $show_group . '&amp;sort_by=' . $sort_by . '&amp;sort_dir=' . $sort_dir);
     View::setPageInfo(array('title' => array(Utils::escape(ForumSettings::get('o_board_title')), __('User list')), 'active_page' => 'userlist', 'page_number' => $p, 'paging_links' => $paging_links, 'focus_element' => $focus_element, 'is_indexed' => true, 'username' => $username, 'show_group' => $show_group, 'sort_by' => $sort_by, 'sort_dir' => $sort_dir, 'show_post_count' => $show_post_count, 'dropdown_menu' => $this->model->generate_dropdown_menu($show_group), 'userlist_data' => $this->model->print_users($username, $start_from, $sort_by, $sort_dir, $show_group)))->addTemplate('userlist.php')->display();
 }
Ejemplo n.º 2
0
 public function display($req, $res, $args)
 {
     Container::get('hooks')->fire('controller.admin.maintenance.display');
     $action = '';
     if (Input::post('action')) {
         $action = Input::post('action');
     } elseif (Input::query('action')) {
         $action = Input::query('action');
     }
     if ($action == 'rebuild') {
         $this->model->rebuild();
         View::setPageInfo(array('page_title' => array(Utils::escape(ForumSettings::get('o_board_title')), __('Rebuilding search index')), 'query_str' => $this->model->get_query_str()))->addTemplate('admin/maintenance/rebuild.php')->display();
     }
     if ($action == 'prune') {
         $prune_from = Utils::trim(Input::post('prune_from'));
         $prune_sticky = intval(Input::post('prune_sticky'));
         AdminUtils::generateAdminMenu('maintenance');
         if (Input::post('prune_comply')) {
             $this->model->prune_comply($prune_from, $prune_sticky);
         }
         View::setPageInfo(array('title' => array(Utils::escape(ForumSettings::get('o_board_title')), __('Admin'), __('Prune')), 'active_page' => 'admin', 'admin_console' => true, 'prune_sticky' => $prune_sticky, 'prune_from' => $prune_from, 'prune' => $this->model->get_info_prune($prune_sticky, $prune_from)))->addTemplate('admin/maintenance/prune.php')->display();
     }
     AdminUtils::generateAdminMenu('maintenance');
     View::setPageInfo(array('title' => array(Utils::escape(ForumSettings::get('o_board_title')), __('Admin'), __('Maintenance')), 'active_page' => 'admin', 'admin_console' => true, 'first_id' => $this->model->get_first_id(), 'categories' => $this->model->get_categories()))->addTemplate('admin/maintenance/admin_maintenance.php')->display();
 }
Ejemplo n.º 3
0
 public function add_category()
 {
     $cat_name = Utils::trim($this->request->post('cat_name'));
     if ($cat_name == '') {
         Url::redirect($this->feather->urlFor('adminCategories'), __('Must enter name message'));
     }
     if ($this->model->add_category($cat_name)) {
         Url::redirect($this->feather->urlFor('adminCategories'), __('Category added redirect'));
     } else {
         //TODO, add error message
         Url::redirect($this->feather->urlFor('adminCategories'), __('Category added redirect'));
     }
 }
Ejemplo n.º 4
0
 public function add($req, $res, $args)
 {
     Container::get('hooks')->fire('controller.admin.categories.add');
     $cat_name = Utils::trim(Input::post('cat_name'));
     if ($cat_name == '') {
         return Router::redirect(Router::pathFor('adminCategories'), __('Must enter name message'));
     }
     if ($this->model->add_category($cat_name)) {
         return Router::redirect(Router::pathFor('adminCategories'), __('Category added redirect'));
     } else {
         //TODO, add error message
         return Router::redirect(Router::pathFor('adminCategories'), __('Category added redirect'));
     }
 }
Ejemplo n.º 5
0
 public function update_word()
 {
     $id = intval(key($this->request->post('update')));
     $search_for = Utils::trim($this->request->post('search_for')[$id]);
     $replace_with = Utils::trim($this->request->post('replace_with')[$id]);
     if ($search_for == '') {
         throw new Error(__('Must enter word message'), 400);
     }
     $set_search_word = array('search_for' => $search_for, 'replace_with' => $replace_with);
     $set_search_word = $this->hook->fire('update_censoring_word_start', $set_search_word);
     $result = DB::for_table('censoring')->find_one($id)->set($set_search_word)->save();
     // Regenerate the censoring cache
     $this->feather->cache->store('search_for', Cache::get_censoring('search_for'));
     $this->feather->cache->store('replace_with', Cache::get_censoring('replace_with'));
     Url::redirect($this->feather->urlFor('adminCensoring'), __('Word updated redirect'));
 }
Ejemplo n.º 6
0
 public function update_word()
 {
     $id = intval(key(Input::post('update')));
     $search_for = Utils::trim(Input::post('search_for')[$id]);
     $replace_with = Utils::trim(Input::post('replace_with')[$id]);
     if ($search_for == '') {
         throw new Error(__('Must enter word message'), 400);
     }
     $set_search_word = array('search_for' => $search_for, 'replace_with' => $replace_with);
     $set_search_word = Container::get('hooks')->fire('model.admin.censoring.update_censoring_word_start', $set_search_word);
     $result = DB::for_table('censoring')->find_one($id)->set($set_search_word)->save();
     // Regenerate the censoring cache
     Container::get('cache')->store('search_for', Cache::get_censoring('search_for'));
     Container::get('cache')->store('replace_with', Cache::get_censoring('replace_with'));
     return Router::redirect(Router::pathFor('adminCensoring'), __('Word updated redirect'));
 }
Ejemplo n.º 7
0
 public function forget()
 {
     if (!$this->feather->user->is_guest) {
         Url::redirect($this->feather->urlFor('home'), 'Already logged in');
     }
     if ($this->feather->request->isPost()) {
         // Validate the email address
         $email = strtolower(Utils::trim($this->feather->request->post('req_email')));
         if (!$this->feather->email->is_valid_email($email)) {
             throw new Error(__('Invalid email'), 400);
         }
         $user = ModelAuth::get_user_from_email($email);
         if ($user) {
             // Load the "activate password" template
             $mail_tpl = trim(file_get_contents($this->feather->forum_env['FEATHER_ROOT'] . 'featherbb/lang/' . $this->feather->user->language . '/mail_templates/activate_password.tpl'));
             $mail_tpl = $this->feather->hooks->fire('mail_tpl_password_forgotten', $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_message = trim(substr($mail_tpl, $first_crlf));
             // Do the generic replacements first (they apply to all emails sent out here)
             $mail_message = str_replace('<base_url>', Url::base() . '/', $mail_message);
             $mail_message = str_replace('<board_mailer>', $this->feather->forum_settings['o_board_title'], $mail_message);
             $mail_message = $this->feather->hooks->fire('mail_message_password_forgotten', $mail_message);
             if ($user->last_email_sent != '' && time() - $user->last_email_sent < 3600 && time() - $user->last_email_sent >= 0) {
                 throw new Error(sprintf(__('Email flood'), intval((3600 - (time() - $user->last_email_sent)) / 60)), 429);
             }
             // Generate a new password and a new password activation code
             $new_password = Random::pass(12);
             $new_password_key = Random::pass(8);
             ModelAuth::set_new_password($new_password, $new_password_key, $user->id);
             // Do the user specific replacements to the template
             $cur_mail_message = str_replace('<username>', $user->username, $mail_message);
             $cur_mail_message = str_replace('<activation_url>', $this->feather->urlFor('profileAction', ['action' => 'change_pass']) . '?key=' . $new_password_key, $cur_mail_message);
             $cur_mail_message = str_replace('<new_password>', $new_password, $cur_mail_message);
             $cur_mail_message = $this->feather->hooks->fire('cur_mail_message_password_forgotten', $cur_mail_message);
             $this->feather->email->feather_mail($email, $mail_subject, $cur_mail_message);
             Url::redirect($this->feather->urlFor('home'), __('Forget mail') . ' <a href="mailto:' . $this->feather->utils->escape($this->feather->forum_settings['o_admin_email']) . '">' . $this->feather->utils->escape($this->feather->forum_settings['o_admin_email']) . '</a>.', 200);
         } else {
             throw new Error(__('No email match') . ' ' . Utils::escape($email) . '.', 400);
         }
     }
     $this->feather->template->setPageInfo(array('active_page' => 'login', 'title' => array(Utils::escape($this->feather->forum_settings['o_board_title']), __('Request pass')), 'required_fields' => array('req_email' => __('Email')), 'focus_element' => array('request_pass', 'req_email')))->addTemplate('login/password_forgotten.php')->display();
 }
Ejemplo n.º 8
0
 public function display()
 {
     $action = '';
     if ($this->feather->request->post('action')) {
         $action = $this->feather->request->post('action');
     } elseif ($this->feather->request->get('action')) {
         $action = $this->feather->request->get('action');
     }
     if ($action == 'rebuild') {
         $this->model->rebuild();
         $this->feather->template->setPageInfo(array('page_title' => array(Utils::escape($this->feather->forum_settings['o_board_title']), __('Rebuilding search index')), 'query_str' => $this->model->get_query_str()))->addTemplate('admin/maintenance/rebuild.php')->display();
     }
     if ($action == 'prune') {
         $prune_from = Utils::trim($this->feather->request->post('prune_from'));
         $prune_sticky = intval($this->feather->request->post('prune_sticky'));
         AdminUtils::generateAdminMenu('maintenance');
         if ($this->feather->request->post('prune_comply')) {
             $this->model->prune_comply($prune_from, $prune_sticky);
         }
         $this->feather->template->setPageInfo(array('title' => array(Utils::escape($this->feather->forum_settings['o_board_title']), __('Admin'), __('Prune')), 'active_page' => 'admin', 'admin_console' => true, 'prune_sticky' => $prune_sticky, 'prune_from' => $prune_from, 'prune' => $this->model->get_info_prune($prune_sticky, $prune_from)))->addTemplate('admin/maintenance/prune.php')->display();
     }
     AdminUtils::generateAdminMenu('maintenance');
     $this->feather->template->setPageInfo(array('title' => array(Utils::escape($this->feather->forum_settings['o_board_title']), __('Admin'), __('Maintenance')), 'active_page' => 'admin', 'admin_console' => true, 'first_id' => $this->model->get_first_id(), 'categories' => $this->model->get_categories()))->addTemplate('admin/maintenance/admin_maintenance.php')->display();
 }
Ejemplo n.º 9
0
" /><br /></label>
<?php 
}
?>
                        <label class="required"><strong><?php 
_e('Message');
?>
 <span><?php 
_e('Required');
?>
</span></strong><br />
                        <textarea name="req_message" id="req_message" rows="20" cols="95" tabindex="<?php 
echo $cur_index++;
?>
"><?php 
echo Input::post('req_message') ? Utils::linebreaks(Utils::trim(Utils::escape(Input::post('req_message')))) : (isset($quote) ? $quote : '');
?>
</textarea><br /></label>
                        <ul class="bblinks">
                            <li><span><a href="<?php 
echo Router::pathFor('help') . '#bbcode';
?>
" onclick="window.open(this.href); return false;"><?php 
_e('BBCode');
?>
ok</a> <?php 
echo ForumSettings::get('p_message_bbcode') == '1' ? __('on') : __('off');
?>
</span></li>
                            <li><span><a href="<?php 
echo Router::pathFor('help') . '#url';
Ejemplo n.º 10
0
 public function get_info_prune($prune_sticky, $prune_from)
 {
     $prune = array();
     $prune['days'] = Utils::trim(Input::post('req_prune_days'));
     if ($prune['days'] == '' || preg_match('%[^0-9]%', $prune['days'])) {
         throw new Error(__('Days must be integer message'), 400);
     }
     $prune['date'] = time() - $prune['days'] * 86400;
     $prune = Container::get('hooks')->fire('model.admin.maintenance.get_info_prune.prune_dates', $prune);
     // Concatenate together the query for counting number of topics to prune
     $query = DB::for_table('topics')->where_lt('last_post', $prune['date'])->where_null('moved_to');
     if ($prune_sticky == '0') {
         $query = $query->where('sticky', 0);
     }
     if ($prune_from != 'all') {
         $query = $query->where('forum_id', intval($prune_from));
         // Fetch the forum name (just for cosmetic reasons)
         $forum = DB::for_table('forums')->where('id', $prune_from);
         $forum = Container::get('hooks')->fireDB('model.admin.maintenance.get_info_prune.forum_query', $forum);
         $forum = $forum->find_one_col('forum_name');
         $prune['forum'] = '"' . Utils::escape($forum) . '"';
     } else {
         $prune['forum'] = __('All forums');
     }
     $prune['num_topics'] = $query->count('id');
     if (!$prune['num_topics']) {
         throw new Error(sprintf(__('No old topics message'), $prune['days']), 404);
     }
     $prune = Container::get('hooks')->fire('model.admin.maintenance.get_info_prune.prune', $prune);
     return $prune;
 }
Ejemplo n.º 11
0
 public function update_options()
 {
     $form = array('board_title' => Utils::trim($this->request->post('form_board_title')), 'board_desc' => Utils::trim($this->request->post('form_board_desc')), 'base_url' => Utils::trim($this->request->post('form_base_url')), 'default_timezone' => floatval($this->request->post('form_default_timezone')), 'default_dst' => $this->request->post('form_default_dst') != '1' ? '0' : '1', 'default_lang' => Utils::trim($this->request->post('form_default_lang')), 'default_style' => Utils::trim($this->request->post('form_default_style')), 'time_format' => Utils::trim($this->request->post('form_time_format')), 'date_format' => Utils::trim($this->request->post('form_date_format')), 'timeout_visit' => intval($this->request->post('form_timeout_visit')) > 0 ? intval($this->request->post('form_timeout_visit')) : 1, 'timeout_online' => intval($this->request->post('form_timeout_online')) > 0 ? intval($this->request->post('form_timeout_online')) : 1, 'redirect_delay' => intval($this->request->post('form_redirect_delay')) >= 0 ? intval($this->request->post('form_redirect_delay')) : 0, 'show_version' => $this->request->post('form_show_version') != '1' ? '0' : '1', 'show_user_info' => $this->request->post('form_show_user_info') != '1' ? '0' : '1', 'show_post_count' => $this->request->post('form_show_post_count') != '1' ? '0' : '1', 'smilies' => $this->request->post('form_smilies') != '1' ? '0' : '1', 'smilies_sig' => $this->request->post('form_smilies_sig') != '1' ? '0' : '1', 'make_links' => $this->request->post('form_make_links') != '1' ? '0' : '1', 'topic_review' => intval($this->request->post('form_topic_review')) >= 0 ? intval($this->request->post('form_topic_review')) : 0, 'disp_topics_default' => intval($this->request->post('form_disp_topics_default')), 'disp_posts_default' => intval($this->request->post('form_disp_posts_default')), 'indent_num_spaces' => intval($this->request->post('form_indent_num_spaces')) >= 0 ? intval($this->request->post('form_indent_num_spaces')) : 0, 'quote_depth' => intval($this->request->post('form_quote_depth')) > 0 ? intval($this->request->post('form_quote_depth')) : 1, 'quickpost' => $this->request->post('form_quickpost') != '1' ? '0' : '1', 'users_online' => $this->request->post('form_users_online') != '1' ? '0' : '1', 'censoring' => $this->request->post('form_censoring') != '1' ? '0' : '1', 'signatures' => $this->request->post('form_signatures') != '1' ? '0' : '1', 'show_dot' => $this->request->post('form_show_dot') != '1' ? '0' : '1', 'topic_views' => $this->request->post('form_topic_views') != '1' ? '0' : '1', 'quickjump' => $this->request->post('form_quickjump') != '1' ? '0' : '1', 'gzip' => $this->request->post('form_gzip') != '1' ? '0' : '1', 'search_all_forums' => $this->request->post('form_search_all_forums') != '1' ? '0' : '1', 'additional_navlinks' => Utils::trim($this->request->post('form_additional_navlinks')), 'feed_type' => intval($this->request->post('form_feed_type')), 'feed_ttl' => intval($this->request->post('form_feed_ttl')), 'report_method' => intval($this->request->post('form_report_method')), 'mailing_list' => Utils::trim($this->request->post('form_mailing_list')), 'avatars' => $this->request->post('form_avatars') != '1' ? '0' : '1', 'avatars_dir' => Utils::trim($this->request->post('form_avatars_dir')), 'avatars_width' => intval($this->request->post('form_avatars_width')) > 0 ? intval($this->request->post('form_avatars_width')) : 1, 'avatars_height' => intval($this->request->post('form_avatars_height')) > 0 ? intval($this->request->post('form_avatars_height')) : 1, 'avatars_size' => intval($this->request->post('form_avatars_size')) > 0 ? intval($this->request->post('form_avatars_size')) : 1, 'admin_email' => strtolower(Utils::trim($this->request->post('form_admin_email'))), 'webmaster_email' => strtolower(Utils::trim($this->request->post('form_webmaster_email'))), 'forum_subscriptions' => $this->request->post('form_forum_subscriptions') != '1' ? '0' : '1', 'topic_subscriptions' => $this->request->post('form_topic_subscriptions') != '1' ? '0' : '1', 'smtp_host' => Utils::trim($this->request->post('form_smtp_host')), 'smtp_user' => Utils::trim($this->request->post('form_smtp_user')), 'smtp_ssl' => $this->request->post('form_smtp_ssl') != '1' ? '0' : '1', 'regs_allow' => $this->request->post('form_regs_allow') != '1' ? '0' : '1', 'regs_verify' => $this->request->post('form_regs_verify') != '1' ? '0' : '1', 'regs_report' => $this->request->post('form_regs_report') != '1' ? '0' : '1', 'rules' => $this->request->post('form_rules') != '1' ? '0' : '1', 'rules_message' => Utils::trim($this->request->post('form_rules_message')), 'default_email_setting' => intval($this->request->post('form_default_email_setting')), 'announcement' => $this->request->post('form_announcement') != '1' ? '0' : '1', 'announcement_message' => Utils::trim($this->request->post('form_announcement_message')), 'maintenance' => $this->request->post('form_maintenance') != '1' ? '0' : '1', 'maintenance_message' => Utils::trim($this->request->post('form_maintenance_message')));
     $form = $this->hook->fire('options.update_options.form', $form);
     if ($form['board_title'] == '') {
         throw new Error(__('Must enter title message'), 400);
     }
     // Make sure base_url doesn't end with a slash
     if (substr($form['base_url'], -1) == '/') {
         $form['base_url'] = substr($form['base_url'], 0, -1);
     }
     // Convert IDN to Punycode if needed
     if (preg_match('/[^\\x00-\\x7F]/', $form['base_url'])) {
         if (!function_exists('idn_to_ascii')) {
             throw new Error(__('Base URL problem'), 400);
         } else {
             $form['base_url'] = idn_to_ascii($form['base_url']);
         }
     }
     $languages = \FeatherBB\Core\Lister::getLangs();
     if (!in_array($form['default_lang'], $languages)) {
         throw new Error(__('Bad request'), 404);
     }
     $styles = \FeatherBB\Core\Lister::getStyles();
     if (!in_array($form['default_style'], $styles)) {
         throw new Error(__('Bad request'), 404);
     }
     if ($form['time_format'] == '') {
         $form['time_format'] = 'H:i:s';
     }
     if ($form['date_format'] == '') {
         $form['date_format'] = 'Y-m-d';
     }
     if (!$this->email->is_valid_email($form['admin_email'])) {
         throw new Error(__('Invalid e-mail message'), 400);
     }
     if (!$this->email->is_valid_email($form['webmaster_email'])) {
         throw new Error(__('Invalid webmaster e-mail message'), 400);
     }
     if ($form['mailing_list'] != '') {
         $form['mailing_list'] = strtolower(preg_replace('%\\s%S', '', $form['mailing_list']));
     }
     // Make sure avatars_dir doesn't end with a slash
     if (substr($form['avatars_dir'], -1) == '/') {
         $form['avatars_dir'] = substr($form['avatars_dir'], 0, -1);
     }
     if ($form['additional_navlinks'] != '') {
         $form['additional_navlinks'] = Utils::trim(Utils::linebreaks($form['additional_navlinks']));
     }
     // Change or enter a SMTP password
     if ($this->request->post('form_smtp_change_pass')) {
         $smtp_pass1 = $this->request->post('form_smtp_pass1') ? Utils::trim($this->request->post('form_smtp_pass1')) : '';
         $smtp_pass2 = $this->request->post('form_smtp_pass2') ? Utils::trim($this->request->post('form_smtp_pass2')) : '';
         if ($smtp_pass1 == $smtp_pass2) {
             $form['smtp_pass'] = $smtp_pass1;
         } else {
             throw new Error(__('SMTP passwords did not match'), 400);
         }
     }
     if ($form['announcement_message'] != '') {
         $form['announcement_message'] = Utils::linebreaks($form['announcement_message']);
     } else {
         $form['announcement_message'] = __('Enter announcement here');
         $form['announcement'] = '0';
     }
     if ($form['rules_message'] != '') {
         $form['rules_message'] = Utils::linebreaks($form['rules_message']);
     } else {
         $form['rules_message'] = __('Enter rules here');
         $form['rules'] = '0';
     }
     if ($form['maintenance_message'] != '') {
         $form['maintenance_message'] = Utils::linebreaks($form['maintenance_message']);
     } else {
         $form['maintenance_message'] = __('Default maintenance message');
         $form['maintenance'] = '0';
     }
     // Make sure the number of displayed topics and posts is between 3 and 75
     if ($form['disp_topics_default'] < 3) {
         $form['disp_topics_default'] = 3;
     } elseif ($form['disp_topics_default'] > 75) {
         $form['disp_topics_default'] = 75;
     }
     if ($form['disp_posts_default'] < 3) {
         $form['disp_posts_default'] = 3;
     } elseif ($form['disp_posts_default'] > 75) {
         $form['disp_posts_default'] = 75;
     }
     if ($form['feed_type'] < 0 || $form['feed_type'] > 2) {
         throw new Error(__('Bad request'), 400);
     }
     if ($form['feed_ttl'] < 0) {
         throw new Error(__('Bad request'), 400);
     }
     if ($form['report_method'] < 0 || $form['report_method'] > 2) {
         throw new Error(__('Bad request'), 400);
     }
     if ($form['default_email_setting'] < 0 || $form['default_email_setting'] > 2) {
         throw new Error(__('Bad request'), 400);
     }
     if ($form['timeout_online'] >= $form['timeout_visit']) {
         throw new Error(__('Timeout error message'), 400);
     }
     foreach ($form as $key => $input) {
         // Only update values that have changed
         if (array_key_exists('o_' . $key, $this->config) && $this->config['o_' . $key] != $input) {
             if ($input != '' || is_int($input)) {
                 DB::for_table('config')->where('conf_name', 'o_' . $key)->update_many('conf_value', $input);
             } else {
                 DB::for_table('config')->where('conf_name', 'o_' . $key)->update_many_expr('conf_value', 'NULL');
             }
         }
     }
     // Regenerate the config cache
     $this->feather->cache->store('config', Cache::get_config());
     $this->clear_feed_cache();
     Url::redirect($this->feather->urlFor('adminOptions'), __('Options updated redirect'));
 }
Ejemplo n.º 12
0
 public function edit_positions($req, $res, $args)
 {
     Container::get('hooks')->fire('controller.admin.forums.edit_positions');
     foreach (Input::post('position') as $args['forum_id'] => $position) {
         $position = (int) Utils::trim($position);
         $this->model->update_positions($args['forum_id'], $position);
     }
     // Regenerate the quick jump cache
     Container::get('cache')->store('quickjump', Cache::get_quickjump());
     return Router::redirect(Router::pathFor('adminForums'), __('Forums updated redirect'));
 }
Ejemplo n.º 13
0
 public function insert_report($post_id)
 {
     $post_id = $this->hook->fire('insert_report_start', $post_id);
     // Clean up reason from POST
     $reason = Utils::linebreaks(Utils::trim($this->request->post('req_reason')));
     if ($reason == '') {
         throw new Error(__('No reason'), 400);
     } elseif (strlen($reason) > 65535) {
         // TEXT field can only hold 65535 bytes
         throw new Error(__('Reason too long'), 400);
     }
     if ($this->user->last_report_sent != '' && time() - $this->user->last_report_sent < $this->user->g_report_flood && time() - $this->user->last_report_sent >= 0) {
         throw new Error(sprintf(__('Report flood'), $this->user->g_report_flood, $this->user->g_report_flood - (time() - $this->user->last_report_sent)), 429);
     }
     // Get the topic ID
     $topic = DB::for_table('posts')->select('topic_id')->where('id', $post_id);
     $topic = $this->hook->fireDB('insert_report_topic_id', $topic);
     $topic = $topic->find_one();
     if (!$topic) {
         throw new Error(__('Bad request'), 404);
     }
     // Get the subject and forum ID
     $report['select'] = array('subject', 'forum_id');
     $report = DB::for_table('topics')->select_many($report['select'])->where('id', $topic['topic_id']);
     $report = $this->hook->fireDB('insert_report_get_subject', $report);
     $report = $report->find_one();
     if (!$report) {
         throw new Error(__('Bad request'), 404);
     }
     // Should we use the internal report handling?
     if ($this->config['o_report_method'] == '0' || $this->config['o_report_method'] == '2') {
         // Insert the report
         $query['insert'] = array('post_id' => $post_id, 'topic_id' => $topic['topic_id'], 'forum_id' => $report['forum_id'], 'reported_by' => $this->user->id, 'created' => time(), 'message' => $reason);
         $query = DB::for_table('reports')->create()->set($query['insert']);
         $query = $this->hook->fireDB('insert_report_query', $query);
         $query = $query->save();
     }
     // Should we email the report?
     if ($this->config['o_report_method'] == '1' || $this->config['o_report_method'] == '2') {
         // We send it to the complete mailing-list in one swoop
         if ($this->config['o_mailing_list'] != '') {
             // Load the "new report" template
             $mail_tpl = trim(file_get_contents($this->feather->forum_env['FEATHER_ROOT'] . 'featherbb/lang/' . $this->user->language . '/mail_templates/new_report.tpl'));
             $mail_tpl = $this->hook->fire('insert_report_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_message = trim(substr($mail_tpl, $first_crlf));
             $mail_subject = str_replace('<forum_id>', $report['forum_id'], $mail_subject);
             $mail_subject = str_replace('<topic_subject>', $report['subject'], $mail_subject);
             $mail_message = str_replace('<username>', $this->user->username, $mail_message);
             $mail_message = str_replace('<post_url>', $this->feather->urlFor('viewPost', ['pid' => $post_id]) . '#p' . $post_id, $mail_message);
             $mail_message = str_replace('<reason>', $reason, $mail_message);
             $mail_message = str_replace('<board_mailer>', $this->config['o_board_title'], $mail_message);
             $mail_message = $this->hook->fire('insert_report_mail_message', $mail_message);
             $this->email->feather_mail($this->config['o_mailing_list'], $mail_subject, $mail_message);
         }
     }
     $last_report_sent = DB::for_table('users')->where('id', $this->user->id)->find_one()->set('last_report_sent', time());
     $last_report_sent = $this->hook->fireDB('insert_last_report_sent', $last_report_sent);
     $last_report_sent = $last_report_sent->save();
     Url::redirect($this->feather->urlFor('viewPost', ['pid' => $post_id]) . '#p' . $post_id, __('Report redirect'));
 }
Ejemplo n.º 14
0
 public function split_posts($tid, $fid, $p = null)
 {
     $posts = $this->request->post('posts') ? $this->request->post('posts') : array();
     $posts = $this->hook->fire('split_posts_start', $posts, $tid, $fid);
     if (empty($posts)) {
         throw new Error(__('No posts selected'), 404);
     }
     if ($this->request->post('split_posts_comply')) {
         if (@preg_match('%[^0-9,]%', $posts)) {
             throw new Error(__('Bad request'), 400);
         }
         $move_to_forum = $this->request->post('move_to_forum') ? intval($this->request->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 = $this->hook->fireDB('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', '=', $this->user->g_id), null, true)->where_any_is($result['where'])->where_null('f.redirect_url');
         $result = $this->hook->fireDB('split_posts_second_query', $result);
         $result = $result->find_one();
         if (!$result) {
             throw new Error(__('Bad request'), 404);
         }
         // Check subject
         $new_subject = $this->request->post('new_subject') ? Utils::trim($this->request->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 = $this->hook->fireDB('split_posts_topic_query', $topic);
         $topic = $topic->save();
         $new_tid = DB::get_db()->lastInsertId($this->feather->forum_settings['db_prefix'] . 'topics');
         // Move the posts to the new topic
         $move_posts = DB::for_table('posts')->where_in('id', $posts_array)->find_one()->set('topic_id', $new_tid);
         $move_posts = $this->hook->fireDB('split_posts_move_query', $move_posts);
         $move_posts = $move_posts->save();
         // Apply every subscription to both topics
         DB::for_table('topic_subscriptions')->raw_query('INSERT INTO ' . $this->feather->forum_settings['db_prefix'] . 'topic_subscriptions (user_id, topic_id) SELECT user_id, ' . $new_tid . ' FROM ' . $this->feather->forum_settings['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 = $this->hook->fireDB('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 = $this->hook->fireDB('split_posts_update_old_topic_query', $update_old_topic);
         $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 = $this->hook->fireDB('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 = $this->hook->fireDB('split_posts_update_new_topic_query', $update_new_topic);
         $update_new_topic = $update_new_topic->save();
         Forum::update($fid);
         Forum::update($move_to_forum);
         Url::redirect($this->feather->urlFor('Topic', array('id' => $new_tid)), __('Split posts redirect'));
     }
     $posts = $this->hook->fire('split_posts', $posts);
     return $posts;
 }
Ejemplo n.º 15
0
 public function get_user_search()
 {
     $form = $this->request->get('form') ? $this->request->get('form') : array();
     $form = $this->hook->fire('model.users.get_user_search.form', $form);
     $search = array();
     // trim() all elements in $form
     $form = array_map('trim', $form);
     $posts_greater = $this->request->get('posts_greater') ? Utils::trim($this->request->get('posts_greater')) : '';
     $posts_less = $this->request->get('posts_less') ? Utils::trim($this->request->get('posts_less')) : '';
     $last_post_after = $this->request->get('last_post_after') ? Utils::trim($this->request->get('last_post_after')) : '';
     $last_post_before = $this->request->get('last_post_before') ? Utils::trim($this->request->get('last_post_before')) : '';
     $last_visit_after = $this->request->get('last_visit_after') ? Utils::trim($this->request->get('last_visit_after')) : '';
     $last_visit_before = $this->request->get('last_visit_before') ? Utils::trim($this->request->get('last_visit_before')) : '';
     $registered_after = $this->request->get('registered_after') ? Utils::trim($this->request->get('registered_after')) : '';
     $registered_before = $this->request->get('registered_before') ? Utils::trim($this->request->get('registered_before')) : '';
     $order_by = $search['order_by'] = $this->request->get('order_by') && in_array($this->request->get('order_by'), array('username', 'email', 'num_posts', 'last_post', 'last_visit', 'registered')) ? $this->request->get('order_by') : 'username';
     $direction = $search['direction'] = $this->request->get('direction') && $this->request->get('direction') == 'DESC' ? 'DESC' : 'ASC';
     $user_group = $this->request->get('user_group') ? intval($this->request->get('user_group')) : -1;
     $search['query_str'][] = 'order_by=' . $order_by;
     $search['query_str'][] = 'direction=' . $direction;
     $search['query_str'][] = 'user_group=' . $user_group;
     if (preg_match('%[^0-9]%', $posts_greater . $posts_less)) {
         throw new Error(__('Non numeric message'), 400);
     }
     $search['conditions'] = array();
     // Try to convert date/time to timestamps
     if ($last_post_after != '') {
         $search['query_str'][] = 'last_post_after=' . $last_post_after;
         $last_post_after = strtotime($last_post_after);
         if ($last_post_after === false || $last_post_after == -1) {
             throw new Error(__('Invalid date time message'), 400);
         }
         $search['conditions'][] = 'u.last_post>' . $last_post_after;
     }
     if ($last_post_before != '') {
         $search['query_str'][] = 'last_post_before=' . $last_post_before;
         $last_post_before = strtotime($last_post_before);
         if ($last_post_before === false || $last_post_before == -1) {
             throw new Error(__('Invalid date time message'), 400);
         }
         $search['conditions'][] = 'u.last_post<' . $last_post_before;
     }
     if ($last_visit_after != '') {
         $search['query_str'][] = 'last_visit_after=' . $last_visit_after;
         $last_visit_after = strtotime($last_visit_after);
         if ($last_visit_after === false || $last_visit_after == -1) {
             throw new Error(__('Invalid date time message'), 400);
         }
         $search['conditions'][] = 'u.last_visit>' . $last_visit_after;
     }
     if ($last_visit_before != '') {
         $search['query_str'][] = 'last_visit_before=' . $last_visit_before;
         $last_visit_before = strtotime($last_visit_before);
         if ($last_visit_before === false || $last_visit_before == -1) {
             throw new Error(__('Invalid date time message'), 400);
         }
         $search['conditions'][] = 'u.last_visit<' . $last_visit_before;
     }
     if ($registered_after != '') {
         $search['query_str'][] = 'registered_after=' . $registered_after;
         $registered_after = strtotime($registered_after);
         if ($registered_after === false || $registered_after == -1) {
             throw new Error(__('Invalid date time message'), 400);
         }
         $search['conditions'][] = 'u.registered>' . $registered_after;
     }
     if ($registered_before != '') {
         $search['query_str'][] = 'registered_before=' . $registered_before;
         $registered_before = strtotime($registered_before);
         if ($registered_before === false || $registered_before == -1) {
             throw new Error(__('Invalid date time message'), 400);
         }
         $search['conditions'][] = 'u.registered<' . $registered_before;
     }
     $like_command = $this->feather->forum_settings['db_type'] == 'pgsql' ? 'ILIKE' : 'LIKE';
     foreach ($form as $key => $input) {
         if ($input != '' && in_array($key, array('username', 'email', 'title', 'realname', 'url', 'jabber', 'icq', 'msn', 'aim', 'yahoo', 'location', 'signature', 'admin_note'))) {
             $search['conditions'][] = 'u.' . str_replace("'", "''", $key) . ' ' . $like_command . ' \'' . str_replace("'", "''", str_replace('*', '%', $input)) . '\'';
             $search['query_str'][] = 'form%5B' . $key . '%5D=' . urlencode($input);
         }
     }
     if ($posts_greater != '') {
         $search['query_str'][] = 'posts_greater=' . $posts_greater;
         $search['conditions'][] = 'u.num_posts>' . $posts_greater;
     }
     if ($posts_less != '') {
         $search['query_str'][] = 'posts_less=' . $posts_less;
         $search['conditions'][] = 'u.num_posts<' . $posts_less;
     }
     if ($user_group > -1) {
         $search['conditions'][] = 'u.group_id=' . $user_group;
     }
     $search = $this->hook->fire('model.users.get_user_search.search', $search);
     return $search;
 }
Ejemplo n.º 16
0
 public function send_email($mail)
 {
     $mail = Container::get('hooks')->fire('model.profile.send_email_start', $mail);
     // Clean up message and subject from POST
     $subject = Utils::trim(Input::post('req_subject'));
     $message = Utils::trim(Input::post('req_message'));
     if ($subject == '') {
         throw new Error(__('No email subject'), 400);
     } elseif ($message == '') {
         throw new Error(__('No email message'), 400);
     } elseif (strlen($message) > ForumEnv::get('FEATHER_MAX_POSTSIZE')) {
         throw new Error(__('Too long email message'), 400);
     }
     if (User::get()->last_email_sent != '' && time() - User::get()->last_email_sent < User::get()->g_email_flood && time() - User::get()->last_email_sent >= 0) {
         throw new Error(sprintf(__('Email flood'), User::get()->g_email_flood, User::get()->g_email_flood - (time() - User::get()->last_email_sent)), 429);
     }
     // Load the "form email" template
     $mail_tpl = trim(file_get_contents(ForumEnv::get('FEATHER_ROOT') . 'featherbb/lang/' . User::get()->language . '/mail_templates/form_email.tpl'));
     $mail_tpl = Container::get('hooks')->fire('model.profile.send_email_mail_tpl', $mail_tpl);
     // The first row contains the subject
     $first_crlf = strpos($mail_tpl, "\n");
     $mail_subject = Utils::trim(substr($mail_tpl, 8, $first_crlf - 8));
     $mail_message = Utils::trim(substr($mail_tpl, $first_crlf));
     $mail_subject = str_replace('<mail_subject>', $subject, $mail_subject);
     $mail_message = str_replace('<sender>', User::get()->username, $mail_message);
     $mail_message = str_replace('<board_title>', ForumSettings::get('o_board_title'), $mail_message);
     $mail_message = str_replace('<mail_message>', $message, $mail_message);
     $mail_message = str_replace('<board_mailer>', ForumSettings::get('o_board_title'), $mail_message);
     $mail_message = Container::get('hooks')->fire('model.profile.send_email_mail_message', $mail_message);
     Container::get('email')->feather_mail($mail['recipient_email'], $mail_subject, $mail_message, User::get()->email, User::get()->username);
     $update_last_mail_sent = DB::for_table('users')->where('id', User::get()->id)->find_one()->set('last_email_sent', time());
     $update_last_mail_sent = Container::get('hooks')->fireDB('model.profile.send_email_update_last_mail_sent', $update_last_mail_sent);
     $update_last_mail_sent = $update_last_mail_sent->save();
     // Try to determine if the data in redirect_url is valid (if not, we redirect to index.php after the email is sent) TODO
     //$redirect_url = validate_redirect(Input::post('redirect_url'), 'index.php');
     return Router::redirect(Router::pathFor('home'), __('Email sent redirect'));
 }
Ejemplo n.º 17
0
 public function run()
 {
     Container::get('hooks')->fire('controller.install.run_install');
     if (Input::getParsedBodyParam('choose_lang')) {
         if (in_array(Utils::trim(Input::getParsedBodyParam('install_lang')), $this->available_langs)) {
             $this->install_lang = Input::getParsedBodyParam('install_lang');
         }
     }
     $csrf = new \FeatherBB\Middleware\Csrf();
     $csrf->generateNewToken(Container::get('request'));
     translate('install', 'featherbb', $this->install_lang);
     if (Request::isPost() && empty(Input::getParsedBodyParam('choose_lang'))) {
         $missing_fields = array();
         $data = array_map(function ($item) {
             return Utils::escape(Utils::trim($item));
         }, Input::getParsedBodyParam('install'));
         foreach ($data as $field => $value) {
             // Handle empty fields
             if (empty($value)) {
                 // If the field is required, or if user and pass are missing even though mysql or pgsql are selected as DB
                 if (!in_array($field, $this->optional_fields) || in_array($field, array('db_user')) && in_array($data['db_type'], array('mysql', 'pgsql'))) {
                     $missing_fields[] = $field;
                 }
             }
         }
         if (!empty($missing_fields)) {
             $this->errors = 'The following fields are required but are missing : ' . implode(', ', $missing_fields);
         } else {
             // Missing fields, so we don't need to validate the others
             // VALIDATION
             // Make sure base_url doesn't end with a slash
             if (substr($data['base_url'], -1) == '/') {
                 $data['base_url'] = substr($data['base_url'], 0, -1);
             }
             // Validate username and passwords
             if (Utils::strlen($data['username']) < 2) {
                 $this->errors[] = __('Username 1');
             } elseif (Utils::strlen($data['username']) > 25) {
                 // This usually doesn't happen since the form element only accepts 25 characters
                 $this->errors[] = __('Username 2');
             } elseif (!strcasecmp($data['username'], 'Guest')) {
                 $this->errors[] = __('Username 3');
             } elseif (preg_match('%[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}%', $data['username']) || preg_match('%((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))%', $data['username'])) {
                 $this->errors[] = __('Username 4');
             } elseif ((strpos($data['username'], '[') !== false || strpos($data['username'], ']') !== false) && strpos($data['username'], '\'') !== false && strpos($data['username'], '"') !== false) {
                 $this->errors[] = __('Username 5');
             } elseif (preg_match('%(?:\\[/?(?:b|u|i|h|colou?r|quote|code|img|url|email|list)\\]|\\[(?:code|quote|list)=)%i', $data['username'])) {
                 $this->errors[] = __('Username 6');
             }
             if (Utils::strlen($data['password']) < 6) {
                 $this->errors[] = __('Short password');
             } elseif ($data['password'] != $data['password_conf']) {
                 $this->errors[] = __('Passwords not match');
             }
             // Validate email
             if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
                 $this->errors[] = __('Wrong email');
             }
             // Validate language
             if (!in_array($data['default_lang'], Lister::getLangs())) {
                 $this->errors[] = __('Error default language');
             }
             // Check if the cache directory is writable
             if (!is_writable(ForumEnv::get('FORUM_CACHE_DIR'))) {
                 $this->errors[] = sprintf(__('Alert cache'), ForumEnv::get('FORUM_CACHE_DIR'));
             }
             // Check if default avatar directory is writable
             if (!is_writable(ForumEnv::get('FEATHER_ROOT') . 'style/img/avatars/')) {
                 $this->errors[] = sprintf(__('Alert avatar'), ForumEnv::get('FEATHER_ROOT') . 'style/img/avatars/');
             }
             // Validate db_prefix if existing
             if (!empty($data['db_prefix']) && (strlen($data['db_prefix']) > 0 && (!preg_match('%^[a-zA-Z_][a-zA-Z0-9_]*$%', $data['db_prefix']) || strlen($data['db_prefix']) > 40))) {
                 $this->errors[] = sprintf(__('Table prefix error'), $data['db_prefix']);
             }
         }
         // End validation and check errors
         if (!empty($this->errors)) {
             return View::setPageInfo(array('languages' => $this->available_langs, 'supported_dbs' => $this->supported_dbs, 'data' => $data, 'errors' => $this->errors))->addTemplate('install.php')->display(false);
         } else {
             $data['default_style'] = $this->default_style;
             $data['avatars'] = in_array(strtolower(@ini_get('file_uploads')), array('on', 'true', '1')) ? 1 : 0;
             return $this->create_config($data);
         }
     } else {
         $base_url = str_replace('index.php', '', Url::base());
         $data = array('title' => __('My FeatherBB Forum'), 'description' => __('Description'), 'base_url' => $base_url, 'default_lang' => $this->install_lang);
         return View::setPageInfo(array('languages' => $this->available_langs, 'supported_dbs' => $this->supported_dbs, 'data' => $data, 'alerts' => array()))->addTemplate('install.php')->display(false);
     }
 }
Ejemplo n.º 18
0
 public function password_forgotten()
 {
     $this->hook->fire('password_forgotten_start');
     if (!$this->user->is_guest) {
         header('Location: ' . Url::base());
         exit;
     }
     // Start with a clean slate
     $errors = array();
     if ($this->feather->request()->isPost()) {
         // Validate the email address
         $email = strtolower(Utils::trim($this->request->post('req_email')));
         if (!$this->email->is_valid_email($email)) {
             $errors[] = __('Invalid email');
         }
         // Did everything go according to plan?
         if (empty($errors)) {
             $result['select'] = array('id', 'username', 'last_email_sent');
             $result = DB::for_table('users')->select_many($result['select'])->where('email', $email);
             $result = $this->hook->fireDB('password_forgotten_query', $result);
             $result = $result->find_many();
             if ($result) {
                 // Load the "activate password" template
                 $mail_tpl = trim(file_get_contents($this->feather->forum_env['FEATHER_ROOT'] . 'featherbb/lang/' . $this->user->language . '/mail_templates/activate_password.tpl'));
                 $mail_tpl = $this->hook->fire('mail_tpl_password_forgotten', $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_message = trim(substr($mail_tpl, $first_crlf));
                 // Do the generic replacements first (they apply to all emails sent out here)
                 $mail_message = str_replace('<base_url>', Url::base() . '/', $mail_message);
                 $mail_message = str_replace('<board_mailer>', $this->config['o_board_title'], $mail_message);
                 $mail_message = $this->hook->fire('mail_message_password_forgotten', $mail_message);
                 // Loop through users we found
                 foreach ($result as $cur_hit) {
                     if ($cur_hit->last_email_sent != '' && time() - $cur_hit->last_email_sent < 3600 && time() - $cur_hit->last_email_sent >= 0) {
                         throw new Error(sprintf(__('Email flood'), intval((3600 - (time() - $cur_hit->last_email_sent)) / 60)), 429);
                     }
                     // Generate a new password and a new password activation code
                     $new_password = Random::pass(12);
                     $new_password_key = Random::pass(8);
                     $query['update'] = array('activate_string' => Random::hash($new_password), 'activate_key' => $new_password_key, 'last_email_sent' => time());
                     $query = DB::for_table('users')->where('id', $cur_hit->id)->find_one()->set($query['update']);
                     $query = $this->hook->fireDB('password_forgotten_mail_query', $query);
                     $query = $query->save();
                     // Do the user specific replacements to the template
                     $cur_mail_message = str_replace('<username>', $cur_hit->username, $mail_message);
                     $cur_mail_message = str_replace('<activation_url>', $this->feather->urlFor('profileAction', ['id' => $cur_hit->id, 'action' => 'change_pass']) . '?key=' . $new_password_key, $cur_mail_message);
                     $cur_mail_message = str_replace('<new_password>', $new_password, $cur_mail_message);
                     $cur_mail_message = $this->hook->fire('cur_mail_message_password_forgotten', $cur_mail_message);
                     $this->email->feather_mail($email, $mail_subject, $cur_mail_message);
                 }
                 throw new Error(__('Forget mail') . ' <a href="mailto:' . Utils::escape($this->config['o_admin_email']) . '">' . Utils::escape($this->config['o_admin_email']) . '</a>.', 400);
             } else {
                 $errors[] = __('No email match') . ' ' . Utils::escape($email) . '.';
             }
         }
     }
     $errors = $this->hook->fire('password_forgotten', $errors);
     return $errors;
 }
Ejemplo n.º 19
0
 public function update_profile($id, $info, $section)
 {
     $info = $this->hook->fire('update_profile_start', $info, $id, $section);
     $username_updated = false;
     $section = $this->hook->fire('update_profile_section', $section, $id, $info);
     // Validate input depending on section
     switch ($section) {
         case 'essentials':
             $form = array('timezone' => floatval($this->request->post('form_timezone')), 'dst' => $this->request->post('form_dst') ? '1' : '0', 'time_format' => intval($this->request->post('form_time_format')), 'date_format' => intval($this->request->post('form_date_format')));
             // Make sure we got a valid language string
             if ($this->request->post('form_language')) {
                 $languages = \FeatherBB\Core\Lister::getLangs();
                 $form['language'] = Utils::trim($this->request->post('form_language'));
                 if (!in_array($form['language'], $languages)) {
                     throw new Error(__('Bad request'), 404);
                 }
             }
             if ($this->user->is_admmod) {
                 $form['admin_note'] = Utils::trim($this->request->post('admin_note'));
                 // Are we allowed to change usernames?
                 if ($this->user->g_id == $this->feather->forum_env['FEATHER_ADMIN'] || $this->user->g_moderator == '1' && $this->user->g_mod_rename_users == '1') {
                     $form['username'] = Utils::trim($this->request->post('req_username'));
                     if ($form['username'] != $info['old_username']) {
                         $errors = '';
                         $errors = $this->check_username($form['username'], $errors, $id);
                         if (!empty($errors)) {
                             throw new Error($errors[0]);
                         }
                         $username_updated = true;
                     }
                 }
                 // We only allow administrators to update the post count
                 if ($this->user->g_id == $this->feather->forum_env['FEATHER_ADMIN']) {
                     $form['num_posts'] = intval($this->request->post('num_posts'));
                 }
             }
             if ($this->config['o_regs_verify'] == '0' || $this->user->is_admmod) {
                 // Validate the email address
                 $form['email'] = strtolower(Utils::trim($this->request->post('req_email')));
                 if (!$this->email->is_valid_email($form['email'])) {
                     throw new Error(__('Invalid email'));
                 }
             }
             break;
         case 'personal':
             $form = array('realname' => $this->request->post('form_realname') ? Utils::trim($this->request->post('form_realname')) : '', 'url' => $this->request->post('form_url') ? Utils::trim($this->request->post('form_url')) : '', 'location' => $this->request->post('form_location') ? Utils::trim($this->request->post('form_location')) : '');
             // Add http:// if the URL doesn't contain it already (while allowing https://, too)
             if ($this->user->g_post_links == '1') {
                 if ($form['url'] != '') {
                     $url = Url::is_valid($form['url']);
                     if ($url === false) {
                         throw new Error(__('Invalid website URL'));
                     }
                     $form['url'] = $url['url'];
                 }
             } else {
                 if (!empty($form['url'])) {
                     throw new Error(__('Website not allowed'));
                 }
                 $form['url'] = '';
             }
             if ($this->user->g_id == $this->feather->forum_env['FEATHER_ADMIN']) {
                 $form['title'] = Utils::trim($this->request->post('title'));
             } elseif ($this->user->g_set_title == '1') {
                 $form['title'] = Utils::trim($this->request->post('title'));
                 if ($form['title'] != '') {
                     // A list of words that the title may not contain
                     // If the language is English, there will be some duplicates, but it's not the end of the world
                     $forbidden = array('member', 'moderator', 'administrator', 'banned', 'guest', utf8_strtolower(__('Member')), utf8_strtolower(__('Moderator')), utf8_strtolower(__('Administrator')), utf8_strtolower(__('Banned')), utf8_strtolower(__('Guest')));
                     if (in_array(utf8_strtolower($form['title']), $forbidden)) {
                         throw new Error(__('Forbidden title'));
                     }
                 }
             }
             break;
         case 'messaging':
             $form = array('jabber' => Utils::trim($this->request->post('form_jabber')), 'icq' => Utils::trim($this->request->post('form_icq')), 'msn' => Utils::trim($this->request->post('form_msn')), 'aim' => Utils::trim($this->request->post('form_aim')), 'yahoo' => Utils::trim($this->request->post('form_yahoo')));
             // If the ICQ UIN contains anything other than digits it's invalid
             if (preg_match('%[^0-9]%', $form['icq'])) {
                 throw new Error(__('Bad ICQ'));
             }
             break;
         case 'personality':
             $form = array();
             // Clean up signature from POST
             if ($this->config['o_signatures'] == '1') {
                 $form['signature'] = Utils::linebreaks(Utils::trim($this->request->post('signature')));
                 // Validate signature
                 if (Utils::strlen($form['signature']) > $this->config['p_sig_length']) {
                     throw new Error(sprintf(__('Sig too long'), $this->config['p_sig_length'], Utils::strlen($form['signature']) - $this->config['p_sig_length']));
                 } elseif (substr_count($form['signature'], "\n") > $this->config['p_sig_lines'] - 1) {
                     throw new Error(sprintf(__('Sig too many lines'), $this->config['p_sig_lines']));
                 } elseif ($form['signature'] && $this->config['p_sig_all_caps'] == '0' && Utils::is_all_uppercase($form['signature']) && !$this->user->is_admmod) {
                     $form['signature'] = utf8_ucwords(utf8_strtolower($form['signature']));
                 }
                 // Validate BBCode syntax
                 if ($this->config['p_sig_bbcode'] == '1') {
                     $errors = array();
                     $form['signature'] = $this->feather->parser->preparse_bbcode($form['signature'], $errors, true);
                     if (count($errors) > 0) {
                         throw new Error('<ul><li>' . implode('</li><li>', $errors) . '</li></ul>');
                     }
                 }
             }
             break;
         case 'display':
             $form = array('disp_topics' => Utils::trim($this->request->post('form_disp_topics')), 'disp_posts' => Utils::trim($this->request->post('form_disp_posts')), 'show_smilies' => $this->request->post('form_show_smilies') ? '1' : '0', 'show_img' => $this->request->post('form_show_img') ? '1' : '0', 'show_img_sig' => $this->request->post('form_show_img_sig') ? '1' : '0', 'show_avatars' => $this->request->post('form_show_avatars') ? '1' : '0', 'show_sig' => $this->request->post('form_show_sig') ? '1' : '0');
             if ($form['disp_topics'] != '') {
                 $form['disp_topics'] = intval($form['disp_topics']);
                 if ($form['disp_topics'] < 3) {
                     $form['disp_topics'] = 3;
                 } elseif ($form['disp_topics'] > 75) {
                     $form['disp_topics'] = 75;
                 }
             }
             if ($form['disp_posts'] != '') {
                 $form['disp_posts'] = intval($form['disp_posts']);
                 if ($form['disp_posts'] < 3) {
                     $form['disp_posts'] = 3;
                 } elseif ($form['disp_posts'] > 75) {
                     $form['disp_posts'] = 75;
                 }
             }
             // Make sure we got a valid style string
             if ($this->request->post('form_style')) {
                 $styles = \FeatherBB\Core\Lister::getStyles();
                 $form['style'] = Utils::trim($this->request->post('form_style'));
                 if (!in_array($form['style'], $styles)) {
                     throw new Error(__('Bad request'), 404);
                 }
             }
             break;
         case 'privacy':
             $form = array('email_setting' => intval($this->request->post('form_email_setting')), 'notify_with_post' => $this->request->post('form_notify_with_post') ? '1' : '0', 'auto_notify' => $this->request->post('form_auto_notify') ? '1' : '0');
             if ($form['email_setting'] < 0 || $form['email_setting'] > 2) {
                 $form['email_setting'] = $this->config['o_default_email_setting'];
             }
             break;
         default:
             throw new Error(__('Bad request'), 404);
     }
     $form = $this->hook->fire('update_profile_form', $form, $section, $id, $info);
     // Single quotes around non-empty values and nothing for empty values
     $temp = array();
     foreach ($form as $key => $input) {
         $temp[$key] = $input;
     }
     if (empty($temp)) {
         throw new Error(__('Bad request'), 404);
     }
     $update_user = DB::for_table('users')->where('id', $id)->find_one()->set($temp);
     $update_user = $this->hook->fireDB('update_profile_query', $update_user);
     $update_user = $update_user->save();
     // If we changed the username we have to update some stuff
     if ($username_updated) {
         $bans_updated = DB::for_table('bans')->where('username', $info['old_username']);
         $bans_updated = $this->hook->fireDB('update_profile_bans_updated', $bans_updated);
         $bans_updated = $bans_updated->update_many('username', $form['username']);
         $update_poster_id = DB::for_table('posts')->where('poster_id', $id);
         $update_poster_id = $this->hook->fireDB('update_profile_poster_id', $update_poster_id);
         $update_poster_id = $update_poster_id->update_many('poster', $form['username']);
         $update_posts = DB::for_table('posts')->where('edited_by', $info['old_username']);
         $update_posts = $this->hook->fireDB('update_profile_posts', $update_posts);
         $update_posts = $update_posts->update_many('edited_by', $form['username']);
         $update_topics_poster = DB::for_table('topics')->where('poster', $info['old_username']);
         $update_topics_poster = $this->hook->fireDB('update_profile_topics_poster', $update_topics_poster);
         $update_topics_poster = $update_topics_poster->update_many('poster', $form['username']);
         $update_topics_last_poster = DB::for_table('topics')->where('last_poster', $info['old_username']);
         $update_topics_last_poster = $this->hook->fireDB('update_profile_topics_last_poster', $update_topics_last_poster);
         $update_topics_last_poster = $update_topics_last_poster->update_many('last_poster', $form['username']);
         $update_forums = DB::for_table('forums')->where('last_poster', $info['old_username']);
         $update_forums = $this->hook->fireDB('update_profile_forums', $update_forums);
         $update_forums = $update_forums->update_many('last_poster', $form['username']);
         $update_online = DB::for_table('online')->where('ident', $info['old_username']);
         $update_online = $this->hook->fireDB('update_profile_online', $update_online);
         $update_online = $update_online->update_many('ident', $form['username']);
         // If the user is a moderator or an administrator we have to update the moderator lists
         $group_id = DB::for_table('users')->where('id', $id);
         // TODO: restore hook
         // $group_id = $this->hook->fireDB('update_profile_group_id', $update_online);
         $group_id = $group_id->find_one_col('group_id');
         $group_mod = DB::for_table('groups')->where('g_id', $group_id);
         $group_mod = $this->hook->fireDB('update_profile_group_mod', $group_mod);
         $group_mod = $group_mod->find_one_col('g_moderator');
         if ($group_id == $this->feather->forum_env['FEATHER_ADMIN'] || $group_mod == '1') {
             // Loop through all forums
             $result = $this->loop_mod_forums();
             foreach ($result as $cur_forum) {
                 $cur_moderators = $cur_forum['moderators'] != '' ? unserialize($cur_forum['moderators']) : array();
                 if (in_array($id, $cur_moderators)) {
                     unset($cur_moderators[$info['old_username']]);
                     $cur_moderators[$form['username']] = $id;
                     uksort($cur_moderators, 'utf8_strcasecmp');
                     $update_mods = DB::for_table('forums')->where('id', $cur_forum['id'])->find_one()->set('moderators', serialize($cur_moderators));
                     $update_mods = $this->hook->fireDB('update_profile_mods', $update_mods);
                     $update_mods = $update_mods->save();
                 }
             }
         }
         // Regenerate the users info cache
         if (!$this->feather->cache->isCached('users_info')) {
             $this->feather->cache->store('users_info', Cache::get_users_info());
         }
         $stats = $this->feather->cache->retrieve('users_info');
         // Check if the bans table was updated and regenerate the bans cache when needed
         if ($bans_updated) {
             $this->feather->cache->store('bans', Cache::get_bans());
         }
     }
     $section = $this->hook->fireDB('update_profile', $section, $id);
     Url::redirect($this->feather->urlFor('profileSection', array('id' => $id, 'section' => $section)), __('Profile redirect'));
 }
Ejemplo n.º 20
0
 public function find_ban($start_from = false)
 {
     $ban_info = array();
     Container::get('hooks')->fire('model.admin.bans.find_ban_start');
     // trim() all elements in $form
     $ban_info['conditions'] = $ban_info['query_str'] = array();
     $expire_after = Input::query('expire_after') ? Utils::trim(Input::query('expire_after')) : '';
     $expire_before = Input::query('expire_before') ? Utils::trim(Input::query('expire_before')) : '';
     $ban_info['order_by'] = Input::query('order_by') && in_array(Input::query('order_by'), array('username', 'ip', 'email', 'expire')) ? 'b.' . Input::query('order_by') : 'b.username';
     $ban_info['direction'] = Input::query('direction') && Input::query('direction') == 'DESC' ? 'DESC' : 'ASC';
     $ban_info['query_str'][] = 'order_by=' . $ban_info['order_by'];
     $ban_info['query_str'][] = 'direction=' . $ban_info['direction'];
     // Build the query
     $result = DB::for_table('bans')->table_alias('b')->where_gt('b.id', 0);
     // Try to convert date/time to timestamps
     if ($expire_after != '') {
         $ban_info['query_str'][] = 'expire_after=' . $expire_after;
         $expire_after = strtotime($expire_after);
         if ($expire_after === false || $expire_after == -1) {
             throw new Error(__('Invalid date message'), 400);
         }
         $result = $result->where_gt('b.expire', $expire_after);
     }
     if ($expire_before != '') {
         $ban_info['query_str'][] = 'expire_before=' . $expire_before;
         $expire_before = strtotime($expire_before);
         if ($expire_before === false || $expire_before == -1) {
             throw new Error(__('Invalid date message'), 400);
         }
         $result = $result->where_lt('b.expire', $expire_before);
     }
     if (Input::query('username')) {
         $result = $result->where_like('b.username', str_replace('*', '%', Input::query('username')));
         $ban_info['query_str'][] = 'username='******'username'));
     }
     if (Input::query('ip')) {
         $result = $result->where_like('b.ip', str_replace('*', '%', Input::query('ip')));
         $ban_info['query_str'][] = 'ip=' . urlencode(Input::query('ip'));
     }
     if (Input::query('email')) {
         $result = $result->where_like('b.email', str_replace('*', '%', Input::query('email')));
         $ban_info['query_str'][] = 'email=' . urlencode(Input::query('email'));
     }
     if (Input::query('message')) {
         $result = $result->where_like('b.message', str_replace('*', '%', Input::query('message')));
         $ban_info['query_str'][] = 'message=' . urlencode(Input::query('message'));
     }
     // Fetch ban count
     if (is_numeric($start_from)) {
         $ban_info['data'] = array();
         $select_bans = array('b.id', 'b.username', 'b.ip', 'b.email', 'b.message', 'b.expire', 'b.ban_creator', 'ban_creator_username' => 'u.username');
         $result = $result->select_many($select_bans)->left_outer_join('users', array('b.ban_creator', '=', 'u.id'), 'u')->order_by($ban_info['order_by'], $ban_info['direction'])->offset($start_from)->limit(50)->find_many();
         foreach ($result as $cur_ban) {
             $ban_info['data'][] = $cur_ban;
         }
     } else {
         $ban_info['num_bans'] = $result->count('id');
     }
     Container::get('hooks')->fire('model.admin.bans.find_ban', $ban_info);
     return $ban_info;
 }
Ejemplo n.º 21
0
 public function send_notifications_new_topic($post, $cur_posting, $new_tid)
 {
     Container::get('hooks')->fire('model.post.send_notifications_new_topic_start', $post, $cur_posting, $new_tid);
     // Get any subscribed users that should be notified (banned users are excluded)
     $result['where'] = array(array('fp.read_forum' => 'IS NULL'), array('fp.read_forum' => '1'));
     $result['select'] = array('u.id', 'u.email', 'u.notify_with_post', 'u.language');
     $result = DB::for_table('users')->table_alias('u')->select_many($result['select'])->inner_join('forum_subscriptions', array('u.id', '=', 's.user_id'), 's')->left_outer_join('forum_perms', array('fp.forum_id', '=', $cur_posting['id']), 'fp', true)->left_outer_join('forum_perms', array('fp.group_id', '=', 'u.group_id'))->left_outer_join('bans', array('u.username', '=', 'b.username'), 'b')->where_null('b.username')->where_any_is($result['where'])->where('s.forum_id', $cur_posting['id'])->where_not_equal('u.id', User::get()->id);
     $result = Container::get('hooks')->fireDB('model.post.send_notifications_new_topic_query', $result);
     $result = $result->find_many();
     if ($result) {
         $notification_emails = array();
         $censored_message = Utils::trim(Utils::censor($post['message']));
         $censored_subject = Utils::trim(Utils::censor($post['subject']));
         if (ForumSettings::get('o_censoring') == '1') {
             $cleaned_message = Container::get('email')->bbcode2email($censored_message, -1);
         } else {
             $cleaned_message = Container::get('email')->bbcode2email($post['message'], -1);
         }
         // Loop through subscribed users and send emails
         foreach ($result as $cur_subscriber) {
             // Is the subscription email for $cur_subscriber['language'] cached or not?
             if (!isset($notification_emails[$cur_subscriber['language']])) {
                 if (file_exists(ForumEnv::get('FEATHER_ROOT') . 'featherbb/lang/' . $cur_subscriber['language'] . '/mail_templates/new_topic.tpl')) {
                     // Load the "new topic" template
                     $mail_tpl = trim(file_get_contents(ForumEnv::get('FEATHER_ROOT') . 'featherbb/lang/' . $cur_subscriber['language'] . '/mail_templates/new_topic.tpl'));
                     $mail_tpl = Container::get('hooks')->fire('model.post.send_notifications_new_topic_mail_tpl', $mail_tpl);
                     // Load the "new topic full" template (with post included)
                     $mail_tpl_full = trim(file_get_contents(ForumEnv::get('FEATHER_ROOT') . 'featherbb/lang/' . $cur_subscriber['language'] . '/mail_templates/new_topic_full.tpl'));
                     // The first row contains the subject (it also starts with "Subject:")
                     $first_crlf = strpos($mail_tpl, "\n");
                     $mail_subject = trim(substr($mail_tpl, 8, $first_crlf - 8));
                     $mail_message = trim(substr($mail_tpl, $first_crlf));
                     $first_crlf = strpos($mail_tpl_full, "\n");
                     $mail_subject_full = trim(substr($mail_tpl_full, 8, $first_crlf - 8));
                     $mail_message_full = trim(substr($mail_tpl_full, $first_crlf));
                     $mail_subject = str_replace('<forum_name>', $cur_posting['forum_name'], $mail_subject);
                     $mail_message = str_replace('<topic_subject>', ForumSettings::get('o_censoring') == '1' ? $censored_subject : $post['subject'], $mail_message);
                     $mail_message = str_replace('<forum_name>', $cur_posting['forum_name'], $mail_message);
                     $mail_message = str_replace('<poster>', $post['username'], $mail_message);
                     $mail_message = str_replace('<topic_url>', Router::pathFor('Topic', ['id' => $new_tid]), $mail_message);
                     $mail_message = str_replace('<unsubscribe_url>', Router::pathFor('unsubscribeTopic', ['id' => $cur_posting['id']]), $mail_message);
                     $mail_message = str_replace('<board_mailer>', ForumSettings::get('o_board_title'), $mail_message);
                     $mail_message = Container::get('hooks')->fire('model.post.send_notifications_new_topic_mail_message', $mail_message);
                     $mail_subject_full = str_replace('<forum_name>', $cur_posting['forum_name'], $mail_subject_full);
                     $mail_message_full = str_replace('<topic_subject>', ForumSettings::get('o_censoring') == '1' ? $censored_subject : $post['subject'], $mail_message_full);
                     $mail_message_full = str_replace('<forum_name>', $cur_posting['forum_name'], $mail_message_full);
                     $mail_message_full = str_replace('<poster>', $post['username'], $mail_message_full);
                     $mail_message_full = str_replace('<message>', $cleaned_message, $mail_message_full);
                     $mail_message_full = str_replace('<topic_url>', Router::pathFor('Topic', ['id' => $new_tid]), $mail_message_full);
                     $mail_message_full = str_replace('<unsubscribe_url>', Router::pathFor('unsubscribeTopic', ['id' => $tid]), $mail_message_full);
                     $mail_message_full = str_replace('<board_mailer>', ForumSettings::get('o_board_title'), $mail_message_full);
                     $mail_message_full = Container::get('hooks')->fire('model.post.send_notifications_new_topic_mail_message_full', $mail_message_full);
                     $notification_emails[$cur_subscriber['language']][0] = $mail_subject;
                     $notification_emails[$cur_subscriber['language']][1] = $mail_message;
                     $notification_emails[$cur_subscriber['language']][2] = $mail_subject_full;
                     $notification_emails[$cur_subscriber['language']][3] = $mail_message_full;
                 }
             }
             // We have to double check here because the templates could be missing
             if (isset($notification_emails[$cur_subscriber['language']])) {
                 if ($cur_subscriber['notify_with_post'] == '0') {
                     Container::get('email')->feather_mail($cur_subscriber['email'], $notification_emails[$cur_subscriber['language']][0], $notification_emails[$cur_subscriber['language']][1]);
                 } else {
                     Container::get('email')->feather_mail($cur_subscriber['email'], $notification_emails[$cur_subscriber['language']][2], $notification_emails[$cur_subscriber['language']][3]);
                 }
             }
         }
         Container::get('hooks')->fire('model.post.send_notifications_new_topic');
         unset($cleaned_message);
     }
 }
Ejemplo n.º 22
0
 public function check_for_errors()
 {
     $user = array();
     $user['errors'] = '';
     $user = Container::get('hooks')->fire('model.register.check_for_errors_start', $user);
     // Check that someone from this IP didn't register a user within the last hour (DoS prevention)
     $already_registered = DB::for_table('users')->where('registration_ip', Utils::getIp())->where_gt('registered', time() - 3600);
     $already_registered = Container::get('hooks')->fireDB('model.register.check_for_errors_ip_query', $already_registered);
     $already_registered = $already_registered->find_one();
     if ($already_registered) {
         throw new Error(__('Registration flood'), 429);
     }
     $user['username'] = Utils::trim(Input::post('req_user'));
     $user['email1'] = strtolower(Utils::trim(Input::post('req_email1')));
     if (ForumSettings::get('o_regs_verify') == '1') {
         $email2 = strtolower(Utils::trim(Input::post('req_email2')));
         $user['password1'] = Random::pass(12);
         $password2 = $user['password1'];
     } else {
         $user['password1'] = Utils::trim(Input::post('req_password1'));
         $password2 = Utils::trim(Input::post('req_password2'));
     }
     // Validate username and passwords
     $profile = new \FeatherBB\Model\Profile();
     $user['errors'] = $profile->check_username($user['username'], $user['errors']);
     if (Utils::strlen($user['password1']) < 6) {
         $user['errors'][] = __('Pass too short');
     } elseif ($user['password1'] != $password2) {
         $user['errors'][] = __('Pass not match');
     }
     // Antispam feature
     $lang_antispam_questions = (require ForumEnv::get('FEATHER_ROOT') . 'featherbb/lang/' . User::get()->language . '/antispam.php');
     $question = Input::post('captcha_q') ? trim(Input::post('captcha_q')) : '';
     $answer = Input::post('captcha') ? strtoupper(trim(Input::post('captcha'))) : '';
     $lang_antispam_questions_array = array();
     foreach ($lang_antispam_questions as $k => $v) {
         $lang_antispam_questions_array[md5($k)] = strtoupper($v);
     }
     if (empty($lang_antispam_questions_array[$question]) || $lang_antispam_questions_array[$question] != $answer) {
         $user['errors'][] = __('Robot test fail');
     }
     // Validate email
     if (!Container::get('email')->is_valid_email($user['email1'])) {
         $user['errors'][] = __('Invalid email');
     } elseif (ForumSettings::get('o_regs_verify') == '1' && $user['email1'] != $email2) {
         $user['errors'][] = __('Email not match');
     }
     // Check if it's a banned email address
     if (Container::get('email')->is_banned_email($user['email1'])) {
         if (ForumSettings::get('p_allow_banned_email') == '0') {
             $user['errors'][] = __('Banned email');
         }
         $user['banned_email'] = 1;
         // Used later when we send an alert email
     }
     // Check if someone else already has registered with that email address
     $dupe_list = array();
     $dupe_mail = DB::for_table('users')->select('username')->where('email', $user['email1']);
     $dupe_mail = Container::get('hooks')->fireDB('model.register.check_for_errors_dupe', $dupe_mail);
     $dupe_mail = $dupe_mail->find_many();
     if ($dupe_mail) {
         if (ForumSettings::get('p_allow_dupe_email') == '0') {
             $user['errors'][] = __('Dupe email');
         }
         foreach ($dupe_mail as $cur_dupe) {
             $dupe_list[] = $cur_dupe['username'];
         }
     }
     // Make sure we got a valid language string
     if (Input::post('language')) {
         $user['language'] = preg_replace('%[\\.\\\\/]%', '', Input::post('language'));
         if (!file_exists(ForumEnv::get('FEATHER_ROOT') . 'featherbb/lang/' . $user['language'] . '/common.po')) {
             throw new Error(__('Bad request'), 500);
         }
     } else {
         $user['language'] = ForumSettings::get('o_default_lang');
     }
     $user = Container::get('hooks')->fire('model.register.check_for_errors', $user);
     return $user;
 }
Ejemplo n.º 23
0
function output_html($feed)
{
    // Send the Content-type header in case the web server is setup to send something else
    header('Content-type: text/html; charset=utf-8');
    header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    foreach ($feed['items'] as $item) {
        if (utf8_strlen($item['title']) > FORUM_EXTERN_MAX_SUBJECT_LENGTH) {
            $subject_truncated = Utils::escape(Utils::trim(utf8_substr($item['title'], 0, FORUM_EXTERN_MAX_SUBJECT_LENGTH - 5))) . ' …';
        } else {
            $subject_truncated = Utils::escape($item['title']);
        }
        echo '<li><a href="' . Utils::escape($item['link']) . '" title="' . Utils::escape($item['title']) . '">' . $subject_truncated . '</a></li>' . "\n";
    }
}
Ejemplo n.º 24
0
 public function add_edit_group($groups)
 {
     if (Input::post('group_id')) {
         $group_id = Input::post('group_id');
     } else {
         $group_id = 0;
     }
     $group_id = Container::get('hooks')->fire('model.admin.groups.add_edit_group_start', $group_id);
     // Is this the admin group? (special rules apply)
     $is_admin_group = Input::post('group_id') && Input::post('group_id') == ForumEnv::get('FEATHER_ADMIN') ? true : false;
     // Set group title
     $title = Utils::trim(Input::post('req_title'));
     if ($title == '') {
         throw new Error(__('Must enter title message'), 400);
     }
     $title = Container::get('hooks')->fire('model.admin.groups.add_edit_group_set_title', $title);
     // Set user title
     $user_title = Utils::trim(Input::post('user_title'));
     $user_title = $user_title != '' ? $user_title : 'NULL';
     $user_title = Container::get('hooks')->fire('model.admin.groups.add_edit_group_set_user_title', $user_title);
     $promote_min_posts = Input::post('promote_min_posts') ? intval(Input::post('promote_min_posts')) : '0';
     if (Input::post('promote_next_group') && isset($groups[Input::post('promote_next_group')]) && !in_array(Input::post('promote_next_group'), array(ForumEnv::get('FEATHER_ADMIN'), ForumEnv::get('FEATHER_GUEST'))) && (Input::post('group_id') || Input::post('promote_next_group') != Input::post('group_id'))) {
         $promote_next_group = Input::post('promote_next_group');
     } else {
         $promote_next_group = '0';
     }
     $moderator = Input::post('moderator') && Input::post('moderator') == '1' ? '1' : '0';
     $mod_edit_users = $moderator == '1' && Input::post('mod_edit_users') == '1' ? '1' : '0';
     $mod_rename_users = $moderator == '1' && Input::post('mod_rename_users') == '1' ? '1' : '0';
     $mod_change_passwords = $moderator == '1' && Input::post('mod_change_passwords') == '1' ? '1' : '0';
     $mod_ban_users = $moderator == '1' && Input::post('mod_ban_users') == '1' ? '1' : '0';
     $mod_promote_users = $moderator == '1' && Input::post('mod_promote_users') == '1' ? '1' : '0';
     $read_board = Input::post('read_board') == 0 ? Input::post('read_board') : '1';
     $view_users = Input::post('view_users') && Input::post('view_users') == '1' || $is_admin_group ? '1' : '0';
     $post_replies = Input::post('post_replies') == 0 ? Input::post('post_replies') : '1';
     $post_topics = Input::post('post_topics') == 0 ? Input::post('post_topics') : '1';
     $edit_posts = Input::post('edit_posts') == 0 ? Input::post('edit_posts') : $is_admin_group ? '1' : '0';
     $delete_posts = Input::post('delete_posts') == 0 ? Input::post('delete_posts') : $is_admin_group ? '1' : '0';
     $delete_topics = Input::post('delete_topics') == 0 ? Input::post('delete_topics') : $is_admin_group ? '1' : '0';
     $post_links = Input::post('post_links') == 0 ? Input::post('post_links') : '1';
     $set_title = Input::post('set_title') == 0 ? Input::post('set_title') : $is_admin_group ? '1' : '0';
     $search = Input::post('search') == 0 ? Input::post('search') : '1';
     $search_users = Input::post('search_users') == 0 ? Input::post('search_users') : '1';
     $send_email = Input::post('send_email') && Input::post('send_email') == '1' || $is_admin_group ? '1' : '0';
     $post_flood = Input::post('post_flood') && Input::post('post_flood') >= 0 ? Input::post('post_flood') : '0';
     $search_flood = Input::post('search_flood') && Input::post('search_flood') >= 0 ? Input::post('search_flood') : '0';
     $email_flood = Input::post('email_flood') && Input::post('email_flood') >= 0 ? Input::post('email_flood') : '0';
     $report_flood = Input::post('report_flood') >= 0 ? Input::post('report_flood') : '0';
     $insert_update_group = array('g_title' => $title, 'g_user_title' => $user_title, 'g_promote_min_posts' => $promote_min_posts, 'g_promote_next_group' => $promote_next_group, 'g_moderator' => $moderator, 'g_mod_edit_users' => $mod_edit_users, 'g_mod_rename_users' => $mod_rename_users, 'g_mod_change_passwords' => $mod_change_passwords, 'g_mod_ban_users' => $mod_ban_users, 'g_mod_promote_users' => $mod_promote_users, 'g_read_board' => $read_board, 'g_view_users' => $view_users, 'g_post_replies' => $post_replies, 'g_post_topics' => $post_topics, 'g_edit_posts' => $edit_posts, 'g_delete_posts' => $delete_posts, 'g_delete_topics' => $delete_topics, 'g_post_links' => $post_links, 'g_set_title' => $set_title, 'g_search' => $search, 'g_search_users' => $search_users, 'g_send_email' => $send_email, 'g_search_flood' => $search_flood, 'g_email_flood' => $email_flood, 'g_report_flood' => $report_flood);
     $insert_update_group = Container::get('hooks')->fire('model.admin.groups.add_edit_group_data', $insert_update_group);
     if (Input::post('mode') == 'add') {
         // Creating a new group
         $title_exists = DB::for_table('groups')->where('g_title', $title)->find_one();
         if ($title_exists) {
             throw new Error(sprintf(__('Title already exists message'), Utils::escape($title)), 400);
         }
         $add = DB::for_table('groups')->create();
         $add->set($insert_update_group)->save();
         $new_group_id = Container::get('hooks')->fire('model.admin.groups.add_edit_group.new_group_id', (int) $add->id());
         // Set new preferences
         Container::get('prefs')->setGroup($new_group_id, array('post.min_interval' => (int) $post_flood));
         // Now lets copy the forum specific permissions from the group which this group is based on
         $select_forum_perms = array('forum_id', 'read_forum', 'post_replies', 'post_topics');
         $result = DB::for_table('forum_perms')->select_many($select_forum_perms)->where('group_id', Input::post('base_group'));
         $result = Container::get('hooks')->fireDB('model.admin.groups.add_edit_group.select_forum_perms_query', $result);
         $result = $result->find_many();
         foreach ($result as $cur_forum_perm) {
             $insert_perms = array('group_id' => $new_group_id, 'forum_id' => $cur_forum_perm['forum_id'], 'read_forum' => $cur_forum_perm['read_forum'], 'post_replies' => $cur_forum_perm['post_replies'], 'post_topics' => $cur_forum_perm['post_topics']);
             DB::for_table('forum_perms')->create()->set($insert_perms)->save();
         }
     } else {
         // We are editing an existing group
         $title_exists = DB::for_table('groups')->where('g_title', $title)->where_not_equal('g_id', Input::post('group_id'))->find_one();
         if ($title_exists) {
             throw new Error(sprintf(__('Title already exists message'), Utils::escape($title)), 400);
         }
         DB::for_table('groups')->find_one(Input::post('group_id'))->set($insert_update_group)->save();
         // Promote all users who would be promoted to this group on their next post
         if ($promote_next_group) {
             DB::for_table('users')->where('group_id', Input::post('group_id'))->where_gte('num_posts', $promote_min_posts)->update_many('group_id', $promote_next_group);
         }
     }
     $group_id = Input::post('mode') == 'add' ? $new_group_id : Input::post('group_id');
     $group_id = Container::get('hooks')->fire('model.admin.groups.add_edit_group.group_id', $group_id);
     // Regenerate the quick jump cache
     Container::get('cache')->store('quickjump', Cache::get_quickjump());
     if (Input::post('mode') == 'edit') {
         return Router::redirect(Router::pathFor('adminGroups'), __('Group edited redirect'));
     } else {
         return Router::redirect(Router::pathFor('adminGroups'), __('Group added redirect'));
     }
 }
Ejemplo n.º 25
0
 public function setup_variables($cur_post, $is_admmod, $can_edit_subject, $errors)
 {
     $this->hook->fire('setup_variables_start');
     $post = array();
     $post['hide_smilies'] = $this->request->post('hide_smilies') ? '1' : '0';
     $post['stick_topic'] = $this->request->post('stick_topic') ? '1' : '0';
     if (!$is_admmod) {
         $post['stick_topic'] = $cur_post['sticky'];
     }
     // Clean up message from POST
     $post['message'] = Utils::linebreaks(Utils::trim($this->request->post('req_message')));
     // Validate BBCode syntax
     if ($this->config['p_message_bbcode'] == '1') {
         $post['message'] = $this->feather->parser->preparse_bbcode($post['message'], $errors);
     }
     // Replace four-byte characters (MySQL cannot handle them)
     $post['message'] = Utils::strip_bad_multibyte_chars($post['message']);
     // Get the subject
     if ($can_edit_subject) {
         $post['subject'] = Utils::trim($this->request->post('req_subject'));
     }
     $post = $this->hook->fire('setup_variables_edit', $post);
     return $post;
 }
Ejemplo n.º 26
0
 public function get_search_results()
 {
     $search = array();
     $search = $this->hook->fire('get_search_results_start', $search);
     $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) {
             throw new Error(__('Bad request'), 400);
         }
     } elseif ($action == 'search') {
         $keywords = $this->request->get('keywords') ? utf8_strtolower(Utils::trim($this->request->get('keywords'))) : null;
         $author = $this->request->get('author') ? utf8_strtolower(Utils::trim($this->request->get('author'))) : null;
         if (preg_match('%^[\\*\\%]+$%', $keywords) || Utils::strlen(str_replace(array('*', '%'), '', $keywords)) < $this->feather->forum_env['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 = $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) {
             throw new Error(__('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) {
             throw new Error(__('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) {
             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 = $this->user->is_guest ? $this->request->getIp() : $this->user->username;
         $search_data = DB::for_table('search_cache')->where('id', $search_id)->where('ident', $ident);
         $search_data = $this->hook->fireDB('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 = $this->hook->fire('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'), 204);
         }
     } 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) {
                 throw new Error(sprintf(__('Search flood'), $this->user->g_search_flood, $this->user->g_search_flood - (time() - $this->user->last_search)), 429);
             }
             if (!$this->user->is_guest) {
                 $update_last_search = DB::for_table('users')->where('id', $this->user->id);
             } else {
                 $update_last_search = DB::for_table('online')->where('ident', $this->request->getIp());
             }
             $update_last_search = $this->hook->fireDB('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 = $this->hook->fire('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 = $this->hook->fire('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 = $this->hook->fire('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 ' . $this->feather->forum_settings['db_prefix'] . 'posts AS p INNER JOIN ' . $this->feather->forum_settings['db_prefix'] . 'topics AS t ON t.id=p.topic_id LEFT JOIN ' . $this->feather->forum_settings['db_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));
                             } else {
                                 $result = DB::for_table('posts')->raw_query('SELECT m.post_id, p.topic_id, ' . $sort_by_sql . ' AS sort_by FROM ' . $this->feather->forum_settings['db_prefix'] . 'search_words AS w INNER JOIN ' . $this->feather->forum_settings['db_prefix'] . 'search_matches AS m ON m.word_id = w.id INNER JOIN ' . $this->feather->forum_settings['db_prefix'] . 'posts AS p ON p.id=m.post_id INNER JOIN ' . $this->feather->forum_settings['db_prefix'] . 'topics AS t ON t.id=p.topic_id LEFT JOIN ' . $this->feather->forum_settings['db_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)));
                             }
                             $result = $this->hook->fireDB('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 = $this->hook->fire('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 = $this->hook->fireDB('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 ' . $this->feather->forum_settings['db_prefix'] . 'posts AS p INNER JOIN ' . $this->feather->forum_settings['db_prefix'] . 'topics AS t ON t.id=p.topic_id LEFT JOIN ' . $this->feather->forum_settings['db_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);
                     $result = $this->hook->fireDB('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($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', Utils::trim($this->request->get('author')), implode(',', $forums), $search_in);
             }
             $search_ids = $this->hook->fire('get_search_results_search_ids', $search_ids);
             $search_type = $this->hook->fire('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 = $this->hook->fire('get_search_results_search_ids', $search_ids);
             $search_type = $this->hook->fire('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 ($this->user->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', '=', $this->user->g_id), null, true)->where_any_is($result['where'])->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 = $this->hook->fire('get_search_results_topic_query', $result);
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     throw new Error(__('No new posts'), 204);
                 }
             } 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($result['where'])->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 = $this->hook->fire('get_search_results_topic_query', $result);
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     throw new Error(__('No recent posts'), 204);
                 }
             } 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($result['where'])->where('p.poster_id', $this->user->id)->group_by('t.id');
                 if ($this->feather->forum_settings['db_type'] == 'pgsql') {
                     $result = $result->group_by('t.last_post');
                 }
                 $result = $this->hook->fire('get_search_results_topic_query', $result);
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     throw new Error(__('No user posts'), 204);
                 }
             } 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($result['where'])->where('p.poster_id', $user_id)->order_by_desc('p.posted');
                 $result = $this->hook->fire('get_search_results_post_query', $result);
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     throw new Error(__('No user posts'), 404);
                 }
                 // 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($result['where'])->where('p.poster_id', $user_id)->order_by_desc('t.last_post');
                 $result = $this->hook->fire('get_search_results_topic_query', $result);
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     throw new Error(__('No user topics'), 404);
                 }
                 // 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) {
                     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', '=', $this->user->g_id), null, true)->where_any_is($result['where'])->order_by_desc('t.last_post');
                 $result = $this->hook->fire('get_search_results_topic_query', $result);
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     throw new Error(__('No subscriptions'), 404);
                 }
                 // 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($result['where'])->order_by_desc('t.last_post');
                 $result = $this->hook->fire('get_search_results_topic_query', $result);
                 $result = $result->find_many();
                 $num_hits = count($result);
                 if (!$num_hits) {
                     throw new Error(__('No unanswered'), 404);
                 }
             }
             $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 = $this->hook->fireDB('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 = $this->hook->fireDB('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 = $this->user->is_guest ? $this->request->getIp() : $this->user->username;
         $cache['insert'] = array('id' => $search_id, 'ident' => $ident, 'search_data' => $temp);
         $cache = DB::for_table('search_cache')->create()->set($cache['insert']);
         $cache = $this->hook->fireDB('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 (!$this->user->is_guest && $search_type[0] == 'action' && $search_type[1] == 'show_new') {
         $search['forum_actions'][] = '<a href="' . $this->feather->urlFor('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' ? $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">' . __('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 = $this->hook->fireDB('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 = $this->hook->fireDB('get_search_results_select_topics_query', $result);
         }
         $result = $result->find_many();
         $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="' . $this->feather->urlFor('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="' . $this->feather->urlFor('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 = $this->hook->fireDB('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="' . $this->feather->urlFor('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="' . $this->feather->urlFor('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="' . $this->feather->urlFor('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 = $this->hook->fire('get_search_results', $search);
     return $search;
 }
Ejemplo n.º 27
0
<?php 
}
?>
						<label class="required"><strong><?php 
_e('Message');
?>
 <span><?php 
_e('Required');
?>
</span></strong><br />
                        <script>postEditorToolbar('req_message');</script>
						<textarea name="req_message" id="req_message" rows="20" cols="95" tabindex="<?php 
echo $cur_index++;
?>
"><?php 
echo $feather->request->post('req_message') ? Utils::linebreaks(Utils::trim(Utils::escape($feather->request->post('req_message')))) : (isset($quote) ? $quote : '');
?>
</textarea><br /></label>
						<ul class="bblinks">
                            <li>ok</li>
							<li><span><a href="<?php 
echo $feather->urlFor('help') . '#bbcode';
?>
" onclick="window.open(this.href); return false;"><?php 
_e('BBCode');
?>
ok</a> <?php 
echo $feather->forum_settings['p_message_bbcode'] == '1' ? __('on') : __('off');
?>
</span></li>
							<li><span><a href="<?php 
Ejemplo n.º 28
0
 public function folders()
 {
     $errors = array();
     if ($this->request->post('add_folder')) {
         $folder = $this->request->post('req_folder') ? Utils::trim(Utils::escape($this->request->post('req_folder'))) : '';
         if ($folder == '') {
             $errors[] = __('No folder name', 'private_messages');
         } else {
             if (Utils::strlen($folder) < 4) {
                 $errors[] = __('Folder too short', 'private_messages');
             } else {
                 if (Utils::strlen($folder) > 30) {
                     $errors[] = __('Folder too long', 'private_messages');
                 } else {
                     if ($this->feather->forum_settings['o_censoring'] == '1' && Utils::censor($folder) == '') {
                         $errors[] = __('No folder after censoring', 'private_messages');
                     }
                 }
             }
         }
         // TODO: Check perms when ready
         // $data = array(
         // 	':uid'	=>	$panther_user['id'],
         // );
         //
         // if ($panther_user['g_pm_folder_limit'] != 0)
         // {
         // 	$ps = $db->select('folders', 'COUNT(id)', $data, 'user_id=:uid');
         // 	$num_folders = $ps->fetchColumn();
         //
         // 	if ($num_folders >= $panther_user['g_pm_folder_limit'])
         // 		$errors[] = sprintf($lang_pm['Folder limit'], $panther_user['g_pm_folder_limit']);
         // }
         if (empty($errors)) {
             $insert = array('user_id' => $this->feather->user->id, 'name' => $folder);
             $this->model->addFolder($insert);
             Url::redirect($this->feather->urlFor('Conversations.folders'), __('Folder added', 'private_messages'));
         }
     } else {
         if ($this->request->post('update_folder')) {
             $id = intval(key($this->request->post('update_folder')));
             var_dump($id);
             $errors = array();
             $folder = Utils::trim($this->request->post('folder')[$id]);
             if ($folder == '') {
                 $errors[] = __('No folder name', 'private_messages');
             } else {
                 if (Utils::strlen($folder) < 4) {
                     $errors[] = __('Folder too short', 'private_messages');
                 } else {
                     if (Utils::strlen($folder) > 30) {
                         $errors[] = __('Folder too long', 'private_messages');
                     } else {
                         if ($this->feather->forum_settings['o_censoring'] == '1' && Utils::censor($folder) == '') {
                             $errors[] = __('No folder after censoring', 'private_messages');
                         }
                     }
                 }
             }
             if (empty($errors)) {
                 $update = array('name' => $folder);
                 if ($this->model->updateFolder($this->feather->user->id, $id, $update)) {
                     Url::redirect($this->feather->urlFor('Conversations.folders'), __('Folder updated', 'private_messages'));
                 } else {
                     throw new Error(__('Error'), 403);
                 }
             }
         } else {
             if ($this->request->post('remove_folder')) {
                 $id = intval(key($this->request->post('remove_folder')));
                 // Before we do anything, check we blocked this user
                 if (!$this->model->checkFolderOwner($id, intval($this->feather->user->id))) {
                     throw new Error(__('No permission'), 403);
                 }
                 if ($this->model->removeFolder($this->feather->user->id, $id)) {
                     Url::redirect($this->feather->urlFor('Conversations.folders'), __('Folder removed', 'private_messages'));
                 } else {
                     throw new Error(__('Error'), 403);
                 }
             }
         }
     }
     Utils::generateBreadcrumbs(array($this->feather->urlFor('Conversations.home') => __('PMS', 'private_messages'), __('Options'), __('My Folders', 'private_messages')));
     $this->generateMenu('folders');
     $this->feather->template->setPageInfo(array('title' => array(Utils::escape($this->feather->config['o_board_title']), __('PMS', 'private_messages'), __('Blocked Users', 'private_messages')), 'admin_console' => true, 'errors' => $errors))->addTemplate('folders.php')->display();
 }
Ejemplo n.º 29
0
 public function edit_positions()
 {
     foreach ($this->request->post('position') as $forum_id => $position) {
         $position = (int) Utils::trim($position);
         $this->model->update_positions($forum_id, $position);
     }
     // Regenerate the quick jump cache
     $this->feather->cache->store('quickjump', Cache::get_quickjump());
     Url::redirect($this->feather->urlFor('adminForums'), __('Forums updated redirect'));
 }