Exemple #1
0
 /**
  * Create topic/post visibility SQL for a given forum ID
  *
  * Note: Read permissions are not checked.
  *
  * @param $mode			string	Either "topic" or "post"
  * @param $forum_id		int		The forum id is used for permission checks
  * @param $table_alias	string	Table alias to prefix in SQL queries
  * @return string	The appropriate combination SQL logic for topic/post_visibility
  */
 public function get_visibility_sql($mode, $forum_id, $table_alias = '')
 {
     $where_sql = '';
     $get_visibility_sql_overwrite = false;
     /**
      * Allow changing the result of calling get_visibility_sql
      *
      * @event core.src_content_visibility_get_visibility_sql_before
      * @var	string		where_sql						Extra visibility conditions. It must end with either an SQL "AND" or an "OR"
      * @var	string		mode							Either "topic" or "post" depending on the query this is being used in
      * @var	array		forum_id						The forum id in which the search is made.
      * @var	string		table_alias						Table alias to prefix in SQL queries
      * @var	mixed		get_visibility_sql_overwrite	If a string, forces the function to return get_forums_visibility_sql_overwrite after executing the event
      * 													If false, get_visibility_sql continues normally
      * 													It must be either boolean or string
      * @since 3.1.4-RC1
      */
     $vars = array('where_sql', 'mode', 'forum_id', 'table_alias', 'get_visibility_sql_overwrite');
     extract($this->src_dispatcher->trigger_event('core.src_content_visibility_get_visibility_sql_before', compact($vars)));
     if ($get_visibility_sql_overwrite !== false) {
         return $get_visibility_sql_overwrite;
     }
     if ($this->auth->acl_get('m_approve', $forum_id)) {
         return $where_sql . '1 = 1';
     }
     return $where_sql . $table_alias . $mode . '_visibility = ' . ITEM_APPROVED;
 }
Exemple #2
0
    /**
     * Determine whether the user is allowed to read and/or moderate the forum of the topic
     *
     * @param	array	$topic_ids	Array with the topic ids
     *
     * @return	array		Returns an array with two keys 'm_' and 'read_f' which are also an array of topic_id => forum_id sets when the permissions are given. Sample:
     *						array(
     *							'permission' => array(
     *								topic_id => forum_id
     *							),
     *						),
     */
    protected function get_topic_auth(array $topic_ids)
    {
        $forum_auth = array('f_read' => array(), 'm_' => array());
        $topic_ids = array_unique($topic_ids);
        $sql = 'SELECT topic_id, forum_id
			FROM ' . TOPICS_TABLE . '
			WHERE ' . $this->db->sql_in_set('topic_id', array_map('intval', $topic_ids));
        $result = $this->db->sql_query($sql);
        while ($row = $this->db->sql_fetchrow($result)) {
            $row['topic_id'] = (int) $row['topic_id'];
            $row['forum_id'] = (int) $row['forum_id'];
            if ($this->auth->acl_get('f_read', $row['forum_id'])) {
                $forum_auth['f_read'][$row['topic_id']] = $row['forum_id'];
            }
            if ($this->auth->acl_gets('a_', 'm_', $row['forum_id'])) {
                $forum_auth['m_'][$row['topic_id']] = $row['forum_id'];
            }
        }
        $this->db->sql_freeresult($result);
        return $forum_auth;
    }
Exemple #3
0
/**
* Generate the debug output string
*
* @param \src\db\driver\driver_interface	$db			Database connection
* @param \src\config\config				$config		Config object
* @param \src\auth\auth					$auth		Auth object
* @param \src\user						$user		User object
* @param \src\event\dispatcher_interface	$src_dispatcher	Event dispatcher
* @return string
*/
function src_generate_debug_output(\src\db\driver\driver_interface $db, \src\config\config $config, \src\auth\auth $auth, \src\user $user, \src\event\dispatcher_interface $src_dispatcher)
{
    $debug_info = array();
    // Output page creation time
    if (defined('src_DISPLAY_LOAD_TIME')) {
        if (isset($GLOBALS['starttime'])) {
            $totaltime = microtime(true) - $GLOBALS['starttime'];
            $debug_info[] = sprintf('<abbr title="SQL time: %.3fs / PHP time: %.3fs">Time: %.3fs</abbr>', $db->get_sql_time(), $totaltime - $db->get_sql_time(), $totaltime);
        }
        $debug_info[] = sprintf('<abbr title="Cached: %d">Queries: %d</abbr>', $db->sql_num_queries(true), $db->sql_num_queries());
        $memory_usage = memory_get_peak_usage();
        if ($memory_usage) {
            $memory_usage = get_formatted_filesize($memory_usage);
            $debug_info[] = 'Peak Memory Usage: ' . $memory_usage;
        }
    }
    if (defined('DEBUG')) {
        $debug_info[] = 'GZIP: ' . ($config['gzip_compress'] && @extension_loaded('zlib') ? 'On' : 'Off');
        if ($user->load) {
            $debug_info[] = 'Load: ' . $user->load;
        }
        if ($auth->acl_get('a_')) {
            $debug_info[] = '<a href="' . build_url() . '&amp;explain=1">SQL Explain</a>';
        }
    }
    /**
     * Modify debug output information
     *
     * @event core.src_generate_debug_output
     * @var	array	debug_info		Array of strings with debug information
     *
     * @since 3.1.0-RC3
     */
    $vars = array('debug_info');
    extract($src_dispatcher->trigger_event('core.src_generate_debug_output', compact($vars)));
    return implode(' | ', $debug_info);
}
Exemple #4
0
 /**
  * Performs a search on keywords depending on display specific params. You have to run split_keywords() first
  *
  * @param	string		$type				contains either posts or topics depending on what should be searched for
  * @param	string		$fields				contains either titleonly (topic titles should be searched), msgonly (only message bodies should be searched), firstpost (only subject and body of the first post should be searched) or all (all post bodies and subjects should be searched)
  * @param	string		$terms				is either 'all' (use query as entered, words without prefix should default to "have to be in field") or 'any' (ignore search query parts and just return all posts that contain any of the specified words)
  * @param	array		$sort_by_sql		contains SQL code for the ORDER BY part of a query
  * @param	string		$sort_key			is the key of $sort_by_sql for the selected sorting
  * @param	string		$sort_dir			is either a or d representing ASC and DESC
  * @param	string		$sort_days			specifies the maximum amount of days a post may be old
  * @param	array		$ex_fid_ary			specifies an array of forum ids which should not be searched
  * @param	string		$post_visibility	specifies which types of posts the user can view in which forums
  * @param	int			$topic_id			is set to 0 or a topic id, if it is not 0 then only posts in this topic should be searched
  * @param	array		$author_ary			an array of author ids if the author should be ignored during the search the array is empty
  * @param	string		$author_name		specifies the author match, when ANONYMOUS is also a search-match
  * @param	array		&$id_ary			passed by reference, to be filled with ids for the page specified by $start and $per_page, should be ordered
  * @param	int			$start				indicates the first index of the page
  * @param	int			$per_page			number of ids each page is supposed to contain
  * @return	boolean|int						total number of results
  */
 public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $post_visibility, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page)
 {
     // No keywords? No posts.
     if (!strlen($this->search_query) && !sizeof($author_ary)) {
         return false;
     }
     $id_ary = array();
     $join_topic = $type != 'posts';
     // Sorting
     if ($type == 'topics') {
         switch ($sort_key) {
             case 'a':
                 $this->sphinx->SetGroupBy('topic_id', SPH_GROUPBY_ATTR, 'poster_id ' . ($sort_dir == 'a' ? 'ASC' : 'DESC'));
                 break;
             case 'f':
                 $this->sphinx->SetGroupBy('topic_id', SPH_GROUPBY_ATTR, 'forum_id ' . ($sort_dir == 'a' ? 'ASC' : 'DESC'));
                 break;
             case 'i':
             case 's':
                 $this->sphinx->SetGroupBy('topic_id', SPH_GROUPBY_ATTR, 'post_subject ' . ($sort_dir == 'a' ? 'ASC' : 'DESC'));
                 break;
             case 't':
             default:
                 $this->sphinx->SetGroupBy('topic_id', SPH_GROUPBY_ATTR, 'topic_last_post_time ' . ($sort_dir == 'a' ? 'ASC' : 'DESC'));
                 break;
         }
     } else {
         switch ($sort_key) {
             case 'a':
                 $this->sphinx->SetSortMode($sort_dir == 'a' ? SPH_SORT_ATTR_ASC : SPH_SORT_ATTR_DESC, 'poster_id');
                 break;
             case 'f':
                 $this->sphinx->SetSortMode($sort_dir == 'a' ? SPH_SORT_ATTR_ASC : SPH_SORT_ATTR_DESC, 'forum_id');
                 break;
             case 'i':
             case 's':
                 $this->sphinx->SetSortMode($sort_dir == 'a' ? SPH_SORT_ATTR_ASC : SPH_SORT_ATTR_DESC, 'post_subject');
                 break;
             case 't':
             default:
                 $this->sphinx->SetSortMode($sort_dir == 'a' ? SPH_SORT_ATTR_ASC : SPH_SORT_ATTR_DESC, 'post_time');
                 break;
         }
     }
     // Most narrow filters first
     if ($topic_id) {
         $this->sphinx->SetFilter('topic_id', array($topic_id));
     }
     $search_query_prefix = '';
     switch ($fields) {
         case 'titleonly':
             // Only search the title
             if ($terms == 'all') {
                 $search_query_prefix = '@title ';
             }
             // Weight for the title
             $this->sphinx->SetFieldWeights(array("title" => 5, "data" => 1));
             // 1 is first_post, 0 is not first post
             $this->sphinx->SetFilter('topic_first_post', array(1));
             break;
         case 'msgonly':
             // Only search the body
             if ($terms == 'all') {
                 $search_query_prefix = '@data ';
             }
             // Weight for the body
             $this->sphinx->SetFieldWeights(array("title" => 1, "data" => 5));
             break;
         case 'firstpost':
             // More relative weight for the title, also search the body
             $this->sphinx->SetFieldWeights(array("title" => 5, "data" => 1));
             // 1 is first_post, 0 is not first post
             $this->sphinx->SetFilter('topic_first_post', array(1));
             break;
         default:
             // More relative weight for the title, also search the body
             $this->sphinx->SetFieldWeights(array("title" => 5, "data" => 1));
             break;
     }
     if (sizeof($author_ary)) {
         $this->sphinx->SetFilter('poster_id', $author_ary);
     }
     // As this is not simply possible at the moment, we limit the result to approved posts.
     // This will make it impossible for moderators to search unapproved and softdeleted posts,
     // but at least it will also cause the same for normal users.
     $this->sphinx->SetFilter('post_visibility', array(ITEM_APPROVED));
     if (sizeof($ex_fid_ary)) {
         // All forums that a user is allowed to access
         $fid_ary = array_unique(array_intersect(array_keys($this->auth->acl_getf('f_read', true)), array_keys($this->auth->acl_getf('f_search', true))));
         // All forums that the user wants to and can search in
         $search_forums = array_diff($fid_ary, $ex_fid_ary);
         if (sizeof($search_forums)) {
             $this->sphinx->SetFilter('forum_id', $search_forums);
         }
     }
     $this->sphinx->SetFilter('deleted', array(0));
     $this->sphinx->SetLimits($start, (int) $per_page, SPHINX_MAX_MATCHES);
     $result = $this->sphinx->Query($search_query_prefix . str_replace('&quot;', '"', $this->search_query), $this->indexes);
     // Could be connection to localhost:9312 failed (errno=111,
     // msg=Connection refused) during rotate, retry if so
     $retries = SPHINX_CONNECT_RETRIES;
     while (!$result && strpos($this->sphinx->GetLastError(), "errno=111,") !== false && $retries--) {
         usleep(SPHINX_CONNECT_WAIT_TIME);
         $result = $this->sphinx->Query($search_query_prefix . str_replace('&quot;', '"', $this->search_query), $this->indexes);
     }
     if ($this->sphinx->GetLastError()) {
         add_log('critical', 'LOG_SPHINX_ERROR', $this->sphinx->GetLastError());
         if ($this->auth->acl_get('a_')) {
             trigger_error($this->user->lang('SPHINX_SEARCH_FAILED', $this->sphinx->GetLastError()));
         } else {
             trigger_error($this->user->lang('SPHINX_SEARCH_FAILED_LOG'));
         }
     }
     $result_count = $result['total_found'];
     if ($result_count && $start >= $result_count) {
         $start = floor(($result_count - 1) / $per_page) * $per_page;
         $this->sphinx->SetLimits((int) $start, (int) $per_page, SPHINX_MAX_MATCHES);
         $result = $this->sphinx->Query($search_query_prefix . str_replace('&quot;', '"', $this->search_query), $this->indexes);
         // Could be connection to localhost:9312 failed (errno=111,
         // msg=Connection refused) during rotate, retry if so
         $retries = SPHINX_CONNECT_RETRIES;
         while (!$result && strpos($this->sphinx->GetLastError(), "errno=111,") !== false && $retries--) {
             usleep(SPHINX_CONNECT_WAIT_TIME);
             $result = $this->sphinx->Query($search_query_prefix . str_replace('&quot;', '"', $this->search_query), $this->indexes);
         }
     }
     $id_ary = array();
     if (isset($result['matches'])) {
         if ($type == 'posts') {
             $id_ary = array_keys($result['matches']);
         } else {
             foreach ($result['matches'] as $key => $value) {
                 $id_ary[] = $value['attrs']['topic_id'];
             }
         }
     } else {
         return false;
     }
     $id_ary = array_slice($id_ary, 0, (int) $per_page);
     return $result_count;
 }
Exemple #5
0
/**
* Handles authentication when downloading attachments from PMs
*
* @param \src\db\driver\driver_interface $db The database object
* @param \src\auth\auth $auth The authentication object
* @param int $user_id The user id
* @param int $msg_id The id of the PM that we are downloading from
*
* @return null
*/
function src_download_handle_pm_auth($db, $auth, $user_id, $msg_id)
{
    if (!$auth->acl_get('u_pm_download')) {
        send_status_line(403, 'Forbidden');
        trigger_error('SORRY_AUTH_VIEW_ATTACH');
    }
    $allowed = src_download_check_pm_auth($db, $user_id, $msg_id);
    if (!$allowed) {
        send_status_line(403, 'Forbidden');
        trigger_error('ERROR_NO_ATTACHMENT');
    }
}