public function validate_search_word($word, $idx) { static $stopwords; // If the word is a keyword we don't want to index it, but we do want to be allowed to search it if ($this->is_keyword($word)) { return !$idx; } if (!isset($stopwords)) { if (!$this->feather->cache->isCached('stopwords')) { $this->feather->cache->store('stopwords', \FeatherBB\Model\Cache::get_config(), '+1 week'); } $stopwords = $this->feather->cache->retrieve('stopwords'); } // If it is a stopword it isn't valid if (in_array($word, $stopwords)) { return false; } // If the word is CJK we don't want to index it, but we do want to be allowed to search it if ($this->is_cjk($word)) { return !$idx; } // Exclude % and * when checking whether current word is valid $word = str_replace(array('%', '*'), '', $word); // Check the word is within the min/max length $num_chars = Utils::strlen($word); return $num_chars >= $this->feather->forum_env['FEATHER_SEARCH_MIN_WORD'] && $num_chars <= $this->feather->forum_env['FEATHER_SEARCH_MAX_WORD']; }
public function check_errors_before_edit($can_edit_subject, $errors) { $errors = $this->hook->fire('check_errors_before_edit_start', $errors); // If it's a topic it must contain a subject if ($can_edit_subject) { $subject = Utils::trim($this->request->post('req_subject')); if ($this->config['o_censoring'] == '1') { $censored_subject = Utils::trim(Utils::censor($subject)); } if ($subject == '') { $errors[] = __('No subject'); } elseif ($this->config['o_censoring'] == '1' && $censored_subject == '') { $errors[] = __('No subject after censoring'); } elseif (Utils::strlen($subject) > 70) { $errors[] = __('Too long subject'); } elseif ($this->config['p_subject_all_caps'] == '0' && Utils::is_all_uppercase($subject) && !$this->user->is_admmod) { $errors[] = __('All caps subject'); } } // Clean up message from POST $message = Utils::linebreaks(Utils::trim($this->request->post('req_message'))); // Here we use strlen() not Utils::strlen() as we want to limit the post to FEATHER_MAX_POSTSIZE bytes, not characters if (strlen($message) > $this->feather->forum_env['FEATHER_MAX_POSTSIZE']) { $errors[] = sprintf(__('Too long message'), Utils::forum_number_format($this->feather->forum_env['FEATHER_MAX_POSTSIZE'])); } elseif ($this->config['p_message_all_caps'] == '0' && Utils::is_all_uppercase($message) && !$this->user->is_admmod) { $errors[] = __('All caps message'); } // Validate BBCode syntax if ($this->config['p_message_bbcode'] == '1') { $message = $this->feather->parser->preparse_bbcode($message, $errors); } if (empty($errors)) { if ($message == '') { $errors[] = __('No message'); } elseif ($this->config['o_censoring'] == '1') { // Censor message to see if that causes problems $censored_message = Utils::trim(Utils::censor($message)); if ($censored_message == '') { $errors[] = __('No message after censoring'); } } } $errors = $this->hook->fire('check_errors_before_edit', $errors); return $errors; }
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(); }
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&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&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&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&keywords=' . urlencode($keywords) . '&author=' . urlencode($author) . '&forums=' . $search_type[2] . '&search_in=' . $search_type[3] . '&sort_by=' . $sort_by . '&sort_dir=' . $sort_dir . '&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; }
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; }
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; }
public function check_username($username, $errors, $exclude_id = null) { // Include UTF-8 function require_once ForumEnv::get('FEATHER_ROOT') . 'featherbb/Helpers/utf8/strcasecmp.php'; translate('register'); translate('prof_reg'); // Convert multiple whitespace characters into one (to prevent people from registering with indistinguishable usernames) $username = preg_replace('%\\s+%s', ' ', $username); // Validate username if (Utils::strlen($username) < 2) { $errors[] = __('Username too short'); } elseif (Utils::strlen($username) > 25) { // This usually doesn't happen since the form element only accepts 25 characters $errors[] = __('Username too long'); } elseif (!strcasecmp($username, 'Guest') || !utf8_strcasecmp($username, __('Guest'))) { $errors[] = __('Username guest'); } elseif (filter_var($username, FILTER_VALIDATE_IP)) { $errors[] = __('Username IP'); } elseif ((strpos($username, '[') !== false || strpos($username, ']') !== false) && strpos($username, '\'') !== false && strpos($username, '"') !== false) { $errors[] = __('Username reserved chars'); } elseif (preg_match('%(?:\\[/?(?:b|u|s|ins|del|em|i|h|colou?r|quote|code|img|url|email|list|\\*|topic|post|forum|user)\\]|\\[(?:img|url|quote|list)=)%i', $username)) { $errors[] = __('Username BBCode'); } // Check username for any censored words if (ForumSettings::get('o_censoring') == '1' && Utils::censor($username) != $username) { $errors[] = __('Username censor'); } // Check that the username (or a too similar username) is not already registered $query = !is_null($exclude_id) ? ' AND id!=' . $exclude_id : ''; $result = DB::for_table('online')->raw_query('SELECT username FROM ' . ForumSettings::get('db_prefix') . 'users WHERE (UPPER(username)=UPPER(:username1) OR UPPER(username)=UPPER(:username2)) AND id>1' . $query, array(':username1' => $username, ':username2' => Utils::ucp_preg_replace('%[^\\p{L}\\p{N}]%u', '', $username)))->find_one(); if ($result) { $busy = $result['username']; $errors[] = __('Username dupe 1') . ' ' . Utils::escape($busy) . '. ' . __('Username dupe 2'); } // Check username for any banned usernames foreach (Container::get('bans') as $cur_ban) { if ($cur_ban['username'] != '' && utf8_strtolower($username) == utf8_strtolower($cur_ban['username'])) { $errors[] = __('Banned username'); break; } } return $errors; }
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); } }
?> </span> </td> </tr> <tr> <th scope="row"><?php _e('SMTP password label'); ?> </th> <td> <label><input type="checkbox" name="form_smtp_change_pass" value="1" /> <?php _e('SMTP change password help'); ?> </label> <?php $smtp_pass = !empty(ForumSettings::get('o_smtp_pass')) ? Random::key(Utils::strlen(ForumSettings::get('o_smtp_pass')), true) : ''; ?> <input type="password" name="form_smtp_pass1" size="25" maxlength="50" value="<?php echo $smtp_pass; ?> " /> <input type="password" name="form_smtp_pass2" size="25" maxlength="50" value="<?php echo $smtp_pass; ?> " /> <span><?php _e('SMTP password help'); ?> </span> </td> </tr>
?> </span> </td> </tr> <tr> <th scope="row"><?php _e('SMTP password label'); ?> </th> <td> <label><input type="checkbox" name="form_smtp_change_pass" value="1" /> <?php _e('SMTP change password help'); ?> </label> <?php $smtp_pass = !empty($feather->forum_settings['o_smtp_pass']) ? Random::key(Utils::strlen($feather->forum_settings['o_smtp_pass']), true) : ''; ?> <input type="password" name="form_smtp_pass1" size="25" maxlength="50" value="<?php echo $smtp_pass; ?> " /> <input type="password" name="form_smtp_pass2" size="25" maxlength="50" value="<?php echo $smtp_pass; ?> " /> <span><?php _e('SMTP password help'); ?> </span> </td> </tr>
public function check_errors_before_post($fid, $tid, $qid, $pid, $page, $errors) { global $lang_antispam, $lang_antispam_questions; $fid = $this->hook->fire('check_errors_before_post_start', $fid); // Antispam feature if ($this->user->is_guest) { // It's a guest, so we have to validate the username $profile = new \FeatherBB\Model\Profile(); $errors = $profile->check_username(Utils::trim($this->request->post('req_username')), $errors); $errors = $this->hook->fire('check_errors_before_post_antispam', $errors); $question = $this->request->post('captcha_q') ? trim($this->request->post('captcha_q')) : ''; $answer = $this->request->post('captcha') ? strtoupper(trim($this->request->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) { $errors[] = __('Robot test fail'); } } // Flood protection if ($this->request->post('preview') != '' && $this->user->last_post != '' && time() - $this->user->last_post < $this->user->g_post_flood) { $errors[] = sprintf(__('Flood start'), $this->user->g_post_flood, $this->user->g_post_flood - (time() - $this->user->last_post)); } // If it's a new topic if ($fid) { $subject = Utils::trim($this->request->post('req_subject')); $subject = $this->hook->fire('check_errors_before_new_topic_subject', $subject); if ($this->config['o_censoring'] == '1') { $censored_subject = Utils::trim(Utils::censor($subject)); $censored_subject = $this->hook->fire('check_errors_before_censored', $censored_subject); } if ($subject == '') { $errors[] = __('No subject'); } elseif ($this->config['o_censoring'] == '1' && $censored_subject == '') { $errors[] = __('No subject after censoring'); } elseif (Utils::strlen($subject) > 70) { $errors[] = __('Too long subject'); } elseif ($this->config['p_subject_all_caps'] == '0' && Utils::is_all_uppercase($subject) && !$this->user->is_admmod) { $errors[] = __('All caps subject'); } $errors = $this->hook->fire('check_errors_before_new_topic_errors', $errors); } if ($this->user->is_guest) { $email = strtolower(Utils::trim($this->config['p_force_guest_email'] == '1' ? $this->request->post('req_email') : $this->request->post('email'))); if ($this->config['p_force_guest_email'] == '1' || $email != '') { $errors = $this->hook->fire('check_errors_before_post_email', $errors, $email); if (!$this->email->is_valid_email($email)) { $errors[] = __('Invalid email'); } // Check if it's a banned email address // we should only check guests because members' addresses are already verified if ($this->user->is_guest && $this->email->is_banned_email($email)) { if ($this->config['p_allow_banned_email'] == '0') { $errors[] = __('Banned email'); } $errors['banned_email'] = 1; // Used later when we send an alert email } } } // Clean up message from POST $message = Utils::linebreaks(Utils::trim($this->request->post('req_message'))); $message = $this->hook->fire('check_errors_before_post_message', $message); // Here we use strlen() not Utils::strlen() as we want to limit the post to FEATHER_MAX_POSTSIZE bytes, not characters if (strlen($message) > $this->feather->forum_env['FEATHER_MAX_POSTSIZE']) { $errors[] = sprintf(__('Too long message'), Utils::forum_number_format($this->feather->forum_env['FEATHER_MAX_POSTSIZE'])); } elseif ($this->config['p_message_all_caps'] == '0' && Utils::is_all_uppercase($message) && !$this->user->is_admmod) { $errors[] = __('All caps message'); } // Validate BBCode syntax if ($this->config['p_message_bbcode'] == '1') { $message = $this->feather->parser->preparse_bbcode($message, $errors); $message = $this->hook->fire('check_errors_before_post_bbcode', $message); } if (empty($errors)) { $errors = $this->hook->fire('check_errors_before_post_no_error', $errors); if ($message == '') { $errors[] = __('No message'); } elseif ($this->config['o_censoring'] == '1') { // Censor message to see if that causes problems $censored_message = Utils::trim(Utils::censor($message)); if ($censored_message == '') { $errors[] = __('No message after censoring'); } } } $errors = $this->hook->fire('check_errors_before_post', $errors); return $errors; }