Ejemplo n.º 1
0
    /**
     * Get number of groups, displayed on the legend
     *
     * @return	int		value of the last item displayed
     */
    public function get_group_count()
    {
        $sql = 'SELECT group_legend
			FROM ' . GROUPS_TABLE . '
			ORDER BY group_legend DESC';
        $result = $this->db->sql_query_limit($sql, 1);
        $group_count = (int) $this->db->sql_fetchfield('group_legend');
        $this->db->sql_freeresult($result);
        return $group_count;
    }
Ejemplo n.º 2
0
    /**
     * Return correct object for specified mode
     *
     * @param string	$mode		The feeds mode.
     * @param int	$forum_id	Forum id specified by the script if forum feed provided.
     * @param int	$topic_id	Topic id specified by the script if topic feed provided.
     *
     * @return object	Returns correct feeds object for specified mode.
     */
    function get_feed($mode, $forum_id, $topic_id)
    {
        switch ($mode) {
            case 'forums':
                if (!$this->config['feed_overall_forums']) {
                    return false;
                }
                return $this->container->get('feed.forums');
                break;
            case 'topics':
            case 'topics_new':
                if (!$this->config['feed_topics_new']) {
                    return false;
                }
                return $this->container->get('feed.topics');
                break;
            case 'topics_active':
                if (!$this->config['feed_topics_active']) {
                    return false;
                }
                return $this->container->get('feed.topics_active');
                break;
            case 'news':
                // Get at least one news forum
                $sql = 'SELECT forum_id
					FROM ' . FORUMS_TABLE . '
					WHERE ' . $this->db->sql_bit_and('forum_options', FORUM_OPTION_FEED_NEWS, '<> 0');
                $result = $this->db->sql_query_limit($sql, 1, 0, 600);
                $s_feed_news = (int) $this->db->sql_fetchfield('forum_id');
                $this->db->sql_freeresult($result);
                if (!$s_feed_news) {
                    return false;
                }
                return $this->container->get('feed.news');
                break;
            default:
                if ($topic_id && $this->config['feed_topic']) {
                    return $this->container->get('feed.topic')->set_topic_id($topic_id);
                } else {
                    if ($forum_id && $this->config['feed_forum']) {
                        return $this->container->get('feed.forum')->set_forum_id($forum_id);
                    } else {
                        if ($this->config['feed_overall']) {
                            return $this->container->get('feed.overall');
                        }
                    }
                }
                return false;
                break;
        }
    }
Ejemplo n.º 3
0
 function get_item()
 {
     if (!isset($this->result)) {
         if (!$this->get_sql()) {
             return false;
         }
         // Query database
         $sql = $this->db->sql_build_query('SELECT', $this->sql);
         $this->result = $this->db->sql_query_limit($sql, $this->num_items);
     }
     return $this->db->sql_fetchrow($this->result);
 }
Ejemplo n.º 4
0
    /**
     * Moves an item up/down
     *
     * @param	int		$teampage_id	teampage_id of the item to be moved
     * @param	int		$delta		number of steps:
     *								- positive = move up
     *								- negative = move down
     * @return	bool		True if the group was moved successfully
     */
    public function move_teampage($teampage_id, $delta)
    {
        $delta = (int) $delta;
        if (!$delta) {
            return false;
        }
        $move_up = $delta > 0 ? true : false;
        $data = $this->get_teampage_values($teampage_id);
        $current_value = (int) $data['teampage_position'];
        if ($current_value != self::GROUP_DISABLED) {
            $this->db->sql_transaction('begin');
            if (!$move_up && $data['teampage_parent'] == self::NO_PARENT) {
                // If we move items down, we need to grab the one sibling more,
                // so we do not ignore the children of the previous sibling.
                // We will remove the additional sibling later on.
                $delta = abs($delta) + 1;
            }
            $sql = 'SELECT teampage_id, teampage_position
				FROM ' . TEAMPAGE_TABLE . '
				WHERE teampage_parent = ' . (int) $data['teampage_parent'] . '
					AND teampage_position' . ($move_up ? ' < ' : ' > ') . $current_value . '
				ORDER BY teampage_position' . ($move_up ? ' DESC' : ' ASC');
            $result = $this->db->sql_query_limit($sql, $delta);
            $sibling_count = 0;
            $sibling_limit = $delta;
            // Reset the delta, as we recalculate the new real delta
            $delta = 0;
            while ($row = $this->db->sql_fetchrow($result)) {
                $sibling_count++;
                $delta = $current_value - $row['teampage_position'];
                // Remove the additional sibling we added previously
                // But only, if we included it, this is not be the case
                // when we reached the end of our list
                if (!$move_up && $data['teampage_parent'] == self::NO_PARENT && $sibling_count == $sibling_limit) {
                    $delta++;
                }
            }
            $this->db->sql_freeresult($result);
            if ($delta) {
                $sql = 'SELECT COUNT(teampage_id) as num_items
					FROM ' . TEAMPAGE_TABLE . '
					WHERE teampage_id = ' . (int) $teampage_id . '
						OR teampage_parent = ' . (int) $teampage_id;
                $result = $this->db->sql_query($sql);
                $num_items = (int) $this->db->sql_fetchfield('num_items');
                $this->db->sql_freeresult($result);
                // First we move all items between our current value and the target value up/down 1,
                // so we have a gap for our item to move.
                $sql = 'UPDATE ' . TEAMPAGE_TABLE . '
					SET teampage_position = teampage_position' . ($move_up ? ' + ' : ' - ') . $num_items . '
					WHERE teampage_position' . ($move_up ? ' >= ' : ' <= ') . ($current_value - $delta) . '
						AND teampage_position' . ($move_up ? ' < ' : ' > ') . $current_value . '
						AND NOT (teampage_id = ' . (int) $teampage_id . '
							OR teampage_parent = ' . (int) $teampage_id . ')';
                $this->db->sql_query($sql);
                $delta = !$move_up && $data['teampage_parent'] == self::NO_PARENT ? abs($delta) - ($num_items - 1) : abs($delta);
                // And now finally, when we moved some other items and built a gap,
                // we can move the desired item to it.
                $sql = 'UPDATE ' . TEAMPAGE_TABLE . '
					SET teampage_position = teampage_position ' . ($move_up ? ' - ' : ' + ') . $delta . '
					WHERE teampage_id = ' . (int) $teampage_id . '
						OR teampage_parent = ' . (int) $teampage_id;
                $this->db->sql_query($sql);
                $this->db->sql_transaction('commit');
                $this->cache->destroy('sql', TEAMPAGE_TABLE);
                return true;
            }
            $this->db->sql_transaction('commit');
        }
        $this->cache->destroy('sql', TEAMPAGE_TABLE);
        return false;
    }
Ejemplo n.º 5
0
    /**
     * Change visibility status of one post or all posts of a topic
     *
     * @param $visibility	int		Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE}
     * @param $post_id		mixed	Post ID or array of post IDs to act on,
     *								if it is empty, all posts of topic_id will be modified
     * @param $topic_id		int		Topic where $post_id is found
     * @param $forum_id		int		Forum where $topic_id is found
     * @param $user_id		int		User performing the action
     * @param $time			int		Timestamp when the action is performed
     * @param $reason		string	Reason why the visibility was changed.
     * @param $is_starter	bool	Is this the first post of the topic changed?
     * @param $is_latest		bool	Is this the last post of the topic changed?
     * @param $limit_visibility	mixed	Limit updating per topic_id to a certain visibility
     * @param $limit_delete_time	mixed	Limit updating per topic_id to a certain deletion time
     * @return array		Changed post data, empty array if an error occurred.
     */
    public function set_post_visibility($visibility, $post_id, $topic_id, $forum_id, $user_id, $time, $reason, $is_starter, $is_latest, $limit_visibility = false, $limit_delete_time = false)
    {
        if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE))) {
            return array();
        }
        if ($post_id) {
            if (is_array($post_id)) {
                $where_sql = $this->db->sql_in_set('post_id', array_map('intval', $post_id));
            } else {
                $where_sql = 'post_id = ' . (int) $post_id;
            }
            $where_sql .= ' AND topic_id = ' . (int) $topic_id;
        } else {
            $where_sql = 'topic_id = ' . (int) $topic_id;
            // Limit the posts to a certain visibility and deletion time
            // This allows us to only restore posts, that were approved
            // when the topic got soft deleted. So previous soft deleted
            // and unapproved posts are still soft deleted/unapproved
            if ($limit_visibility !== false) {
                $where_sql .= ' AND post_visibility = ' . (int) $limit_visibility;
            }
            if ($limit_delete_time !== false) {
                $where_sql .= ' AND post_delete_time = ' . (int) $limit_delete_time;
            }
        }
        $sql = 'SELECT poster_id, post_id, post_postcount, post_visibility
			FROM ' . $this->posts_table . '
			WHERE ' . $where_sql;
        $result = $this->db->sql_query($sql);
        $post_ids = $poster_postcounts = $postcounts = $postcount_visibility = array();
        while ($row = $this->db->sql_fetchrow($result)) {
            $post_ids[] = (int) $row['post_id'];
            if ($row['post_visibility'] != $visibility) {
                if ($row['post_postcount'] && !isset($poster_postcounts[(int) $row['poster_id']])) {
                    $poster_postcounts[(int) $row['poster_id']] = 1;
                } else {
                    if ($row['post_postcount']) {
                        $poster_postcounts[(int) $row['poster_id']]++;
                    }
                }
                if (!isset($postcount_visibility[$row['post_visibility']])) {
                    $postcount_visibility[$row['post_visibility']] = 1;
                } else {
                    $postcount_visibility[$row['post_visibility']]++;
                }
            }
        }
        $this->db->sql_freeresult($result);
        if (empty($post_ids)) {
            return array();
        }
        $data = array('post_visibility' => (int) $visibility, 'post_delete_user' => (int) $user_id, 'post_delete_time' => (int) $time ?: time(), 'post_delete_reason' => truncate_string($reason, 255, 255, false));
        $sql = 'UPDATE ' . $this->posts_table . '
			SET ' . $this->db->sql_build_array('UPDATE', $data) . '
			WHERE ' . $this->db->sql_in_set('post_id', $post_ids);
        $this->db->sql_query($sql);
        // Group the authors by post count, to reduce the number of queries
        foreach ($poster_postcounts as $poster_id => $num_posts) {
            $postcounts[$num_posts][] = $poster_id;
        }
        // Update users postcounts
        foreach ($postcounts as $num_posts => $poster_ids) {
            if (in_array($visibility, array(ITEM_REAPPROVE, ITEM_DELETED))) {
                $sql = 'UPDATE ' . $this->users_table . '
					SET user_posts = 0
					WHERE ' . $this->db->sql_in_set('user_id', $poster_ids) . '
						AND user_posts < ' . $num_posts;
                $this->db->sql_query($sql);
                $sql = 'UPDATE ' . $this->users_table . '
					SET user_posts = user_posts - ' . $num_posts . '
					WHERE ' . $this->db->sql_in_set('user_id', $poster_ids) . '
						AND user_posts >= ' . $num_posts;
                $this->db->sql_query($sql);
            } else {
                $sql = 'UPDATE ' . $this->users_table . '
					SET user_posts = user_posts + ' . $num_posts . '
					WHERE ' . $this->db->sql_in_set('user_id', $poster_ids);
                $this->db->sql_query($sql);
            }
        }
        $update_topic_postcount = true;
        // Sync the first/last topic information if needed
        if (!$is_starter && $is_latest) {
            if (!function_exists('update_post_information')) {
                include $this->src_root_path . 'includes/functions_posting.' . $this->php_ext;
            }
            // update_post_information can only update the last post info ...
            if ($topic_id) {
                update_post_information('topic', $topic_id, false);
            }
            if ($forum_id) {
                update_post_information('forum', $forum_id, false);
            }
        } else {
            if ($is_starter && $topic_id) {
                if (!function_exists('sync')) {
                    include $this->src_root_path . 'includes/functions_admin.' . $this->php_ext;
                }
                // ... so we need to use sync, if the first post is changed.
                // The forum is resynced recursive by sync() itself.
                sync('topic', 'topic_id', $topic_id, true);
                // sync recalculates the topic replies and forum posts by itself, so we don't do that.
                $update_topic_postcount = false;
            }
        }
        $topic_update_array = array();
        // Update the topic's reply count and the forum's post count
        if ($update_topic_postcount) {
            $field_alias = array(ITEM_APPROVED => 'posts_approved', ITEM_UNAPPROVED => 'posts_unapproved', ITEM_DELETED => 'posts_softdeleted', ITEM_REAPPROVE => 'posts_unapproved');
            $cur_posts = array_fill_keys($field_alias, 0);
            foreach ($postcount_visibility as $post_visibility => $visibility_posts) {
                $cur_posts[$field_alias[(int) $post_visibility]] += $visibility_posts;
            }
            $sql_ary = array();
            $recipient_field = $field_alias[$visibility];
            foreach ($cur_posts as $field => $count) {
                // Decrease the count for the old statuses.
                if ($count && $field != $recipient_field) {
                    $sql_ary[$field] = " - {$count}";
                }
            }
            // Add up the count from all statuses excluding the recipient status.
            $count_increase = array_sum(array_diff($cur_posts, array($recipient_field)));
            if ($count_increase) {
                $sql_ary[$recipient_field] = " + {$count_increase}";
            }
            if (sizeof($sql_ary)) {
                $forum_sql = array();
                foreach ($sql_ary as $field => $value_change) {
                    $topic_update_array[] = 'topic_' . $field . ' = topic_' . $field . $value_change;
                    $forum_sql[] = 'forum_' . $field . ' = forum_' . $field . $value_change;
                }
                $sql = 'UPDATE ' . $this->forums_table . '
					SET ' . implode(', ', $forum_sql) . '
					WHERE forum_id = ' . (int) $forum_id;
                $this->db->sql_query($sql);
            }
        }
        if ($post_id) {
            $sql = 'SELECT 1 AS has_attachments
				FROM ' . POSTS_TABLE . '
				WHERE topic_id = ' . (int) $topic_id . '
					AND post_attachment = 1
					AND post_visibility = ' . ITEM_APPROVED . '
					AND ' . $this->db->sql_in_set('post_id', $post_id, true);
            $result = $this->db->sql_query_limit($sql, 1);
            $has_attachment = (bool) $this->db->sql_fetchfield('has_attachments');
            $this->db->sql_freeresult($result);
            if ($has_attachment && $visibility == ITEM_APPROVED) {
                $topic_update_array[] = 'topic_attachment = 1';
            } else {
                if (!$has_attachment && $visibility != ITEM_APPROVED) {
                    $topic_update_array[] = 'topic_attachment = 0';
                }
            }
        }
        if (!empty($topic_update_array)) {
            // Update the number for replies and posts, and update the attachments flag
            $sql = 'UPDATE ' . $this->topics_table . '
				SET ' . implode(', ', $topic_update_array) . '
				WHERE topic_id = ' . (int) $topic_id;
            $this->db->sql_query($sql);
        }
        return $data;
    }
Ejemplo n.º 6
0
 /**
  * Performs a search on an author's posts without caring about message contents. Depends on display specific params
  *
  * @param	string		$type				contains either posts or topics depending on what should be searched for
  * @param	boolean		$firstpost_only		if true, only topic starting posts will be considered
  * @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
  * @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 author_search($type, $firstpost_only, $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 author? No posts
     if (!sizeof($author_ary)) {
         return 0;
     }
     // generate a search_key from all the options to identify the results
     $search_key = md5(implode('#', array('', $type, $firstpost_only ? 'firstpost' : '', '', '', $sort_days, $sort_key, $topic_id, implode(',', $ex_fid_ary), $post_visibility, implode(',', $author_ary), $author_name)));
     if ($start < 0) {
         $start = 0;
     }
     // try reading the results from cache
     $result_count = 0;
     if ($this->obtain_ids($search_key, $result_count, $id_ary, $start, $per_page, $sort_dir) == SEARCH_RESULT_IN_CACHE) {
         return $result_count;
     }
     $id_ary = array();
     // Create some display specific sql strings
     if ($author_name) {
         // first one matches post of registered users, second one guests and deleted users
         $sql_author = '(' . $this->db->sql_in_set('p.poster_id', array_diff($author_ary, array(ANONYMOUS)), false, true) . ' OR p.post_username ' . $author_name . ')';
     } else {
         $sql_author = $this->db->sql_in_set('p.poster_id', $author_ary);
     }
     $sql_fora = sizeof($ex_fid_ary) ? ' AND ' . $this->db->sql_in_set('p.forum_id', $ex_fid_ary, true) : '';
     $sql_topic_id = $topic_id ? ' AND p.topic_id = ' . (int) $topic_id : '';
     $sql_time = $sort_days ? ' AND p.post_time >= ' . (time() - $sort_days * 86400) : '';
     $sql_firstpost = $firstpost_only ? ' AND p.post_id = t.topic_first_post_id' : '';
     // Build sql strings for sorting
     $sql_sort = $sort_by_sql[$sort_key] . ($sort_dir == 'a' ? ' ASC' : ' DESC');
     $sql_sort_table = $sql_sort_join = '';
     switch ($sql_sort[0]) {
         case 'u':
             $sql_sort_table = USERS_TABLE . ' u, ';
             $sql_sort_join = $type == 'posts' ? ' AND u.user_id = p.poster_id ' : ' AND u.user_id = t.topic_poster ';
             break;
         case 't':
             $sql_sort_table = $type == 'posts' && !$firstpost_only ? TOPICS_TABLE . ' t, ' : '';
             $sql_sort_join = $type == 'posts' && !$firstpost_only ? ' AND t.topic_id = p.topic_id ' : '';
             break;
         case 'f':
             $sql_sort_table = FORUMS_TABLE . ' f, ';
             $sql_sort_join = ' AND f.forum_id = p.forum_id ';
             break;
     }
     $m_approve_fid_sql = ' AND ' . $post_visibility;
     /**
      * Allow changing the query used to search for posts by author in fulltext_mysql
      *
      * @event core.search_mysql_author_query_before
      * @var	int		result_count		The previous result count for the format of the query.
      *									Set to 0 to force a re-count
      * @var	string	sql_sort_table		CROSS JOIN'ed table to allow doing the sort chosen
      * @var	string	sql_sort_join		Condition to define how to join the CROSS JOIN'ed table specifyed in sql_sort_table
      * @var	array	author_ary			Array of user_id containing the users to filter the results to
      * @var	string	author_name			An extra username to search on
      * @var	string	sql_author			SQL WHERE condition for the post author ids
      * @var	int		topic_id			Limit the search to this topic_id only
      * @var	string	sql_topic_id		SQL of topic_id
      * @var	string	sort_by_sql			The possible predefined sort types
      * @var	string	sort_key			The sort type used from the possible sort types
      * @var	string	sort_dir			"a" for ASC or "d" dor DESC for the sort order used
      * @var	string	sql_sort			The result SQL when processing sort_by_sql + sort_key + sort_dir
      * @var	string	sort_days			Time, in days, that the oldest post showing can have
      * @var	string	sql_time			The SQL to search on the time specifyed by sort_days
      * @var	bool	firstpost_only		Wether or not to search only on the first post of the topics
      * @var	array	ex_fid_ary			Forum ids that must not be searched on
      * @var	array	sql_fora			SQL query for ex_fid_ary
      * @var	string	m_approve_fid_sql	WHERE clause condition on post_visibility restrictions
      * @var	int		start				How many posts to skip in the search results (used for pagination)
      * @since 3.1.5-RC1
      */
     $vars = array('result_count', 'sql_sort_table', 'sql_sort_join', 'author_ary', 'author_name', 'sql_author', 'topic_id', 'sql_topic_id', 'sort_by_sql', 'sort_key', 'sort_dir', 'sql_sort', 'sort_days', 'sql_time', 'firstpost_only', 'ex_fid_ary', 'sql_fora', 'm_approve_fid_sql', 'start');
     extract($this->src_dispatcher->trigger_event('core.search_mysql_author_query_before', compact($vars)));
     // If the cache was completely empty count the results
     $calc_results = $result_count ? '' : 'SQL_CALC_FOUND_ROWS ';
     // Build the query for really selecting the post_ids
     if ($type == 'posts') {
         $sql = "SELECT {$calc_results}p.post_id\n\t\t\t\tFROM " . $sql_sort_table . POSTS_TABLE . ' p' . ($firstpost_only ? ', ' . TOPICS_TABLE . ' t ' : ' ') . "\n\t\t\t\tWHERE {$sql_author}\n\t\t\t\t\t{$sql_topic_id}\n\t\t\t\t\t{$sql_firstpost}\n\t\t\t\t\t{$m_approve_fid_sql}\n\t\t\t\t\t{$sql_fora}\n\t\t\t\t\t{$sql_sort_join}\n\t\t\t\t\t{$sql_time}\n\t\t\t\tORDER BY {$sql_sort}";
         $field = 'post_id';
     } else {
         $sql = "SELECT {$calc_results}t.topic_id\n\t\t\t\tFROM " . $sql_sort_table . TOPICS_TABLE . ' t, ' . POSTS_TABLE . " p\n\t\t\t\tWHERE {$sql_author}\n\t\t\t\t\t{$sql_topic_id}\n\t\t\t\t\t{$sql_firstpost}\n\t\t\t\t\t{$m_approve_fid_sql}\n\t\t\t\t\t{$sql_fora}\n\t\t\t\t\tAND t.topic_id = p.topic_id\n\t\t\t\t\t{$sql_sort_join}\n\t\t\t\t\t{$sql_time}\n\t\t\t\tGROUP BY t.topic_id\n\t\t\t\tORDER BY {$sql_sort}";
         $field = 'topic_id';
     }
     // Only read one block of posts from the db and then cache it
     $result = $this->db->sql_query_limit($sql, $this->config['search_block_size'], $start);
     while ($row = $this->db->sql_fetchrow($result)) {
         $id_ary[] = (int) $row[$field];
     }
     $this->db->sql_freeresult($result);
     // retrieve the total result count if needed
     if (!$result_count) {
         $sql_found_rows = 'SELECT FOUND_ROWS() as result_count';
         $result = $this->db->sql_query($sql_found_rows);
         $result_count = (int) $this->db->sql_fetchfield('result_count');
         $this->db->sql_freeresult($result);
         if (!$result_count) {
             return false;
         }
     }
     if ($start >= $result_count) {
         $start = floor(($result_count - 1) / $per_page) * $per_page;
         $result = $this->db->sql_query_limit($sql, $this->config['search_block_size'], $start);
         while ($row = $this->db->sql_fetchrow($result)) {
             $id_ary[] = (int) $row[$field];
         }
         $this->db->sql_freeresult($result);
         $id_ary = array_unique($id_ary);
     }
     if (sizeof($id_ary)) {
         $this->save_ids($search_key, '', $author_ary, $result_count, $id_ary, $start, $sort_dir);
         $id_ary = array_slice($id_ary, 0, $per_page);
         return $result_count;
     }
     return false;
 }
Ejemplo n.º 7
0
    /**
     * Load the user's notifications
     *
     * @param array $options Optional options to control what notifications are loaded
     *				notification_id		Notification id to load (or array of notification ids)
     *				user_id				User id to load notifications for (Default: $user->data['user_id'])
     *				order_by			Order by (Default: notification_time)
     *				order_dir			Order direction (Default: DESC)
     * 				limit				Number of notifications to load (Default: 5)
     * 				start				Notifications offset (Default: 0)
     * 				all_unread			Load all unread notifications? If set to true, count_unread is set to true (Default: false)
     * 				count_unread		Count all unread notifications? (Default: false)
     * 				count_total			Count all notifications? (Default: false)
     * @return array Array of information based on the request with keys:
     *	'notifications'		array of notification type objects
     *	'unread_count'		number of unread notifications the user has if count_unread is true in the options
     *	'total_count'		number of notifications the user has if count_total is true in the options
     */
    public function load_notifications(array $options = array())
    {
        // Merge default options
        $options = array_merge(array('notification_id' => false, 'user_id' => $this->user->data['user_id'], 'order_by' => 'notification_time', 'order_dir' => 'DESC', 'limit' => 0, 'start' => 0, 'all_unread' => false, 'count_unread' => false, 'count_total' => false), $options);
        // If all_unread, count_unread must be true
        $options['count_unread'] = $options['all_unread'] ? true : $options['count_unread'];
        // Anonymous users and bots never receive notifications
        if ($options['user_id'] == $this->user->data['user_id'] && ($this->user->data['user_id'] == ANONYMOUS || $this->user->data['user_type'] == USER_IGNORE)) {
            return array('notifications' => array(), 'unread_count' => 0, 'total_count' => 0);
        }
        $notifications = $user_ids = array();
        $load_special = array();
        $total_count = $unread_count = 0;
        if ($options['count_unread']) {
            // Get the total number of unread notifications
            $sql = 'SELECT COUNT(n.notification_id) AS unread_count
				FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
				WHERE n.user_id = ' . (int) $options['user_id'] . '
					AND n.notification_read = 0
					AND nt.notification_type_id = n.notification_type_id
					AND nt.notification_type_enabled = 1';
            $result = $this->db->sql_query($sql);
            $unread_count = (int) $this->db->sql_fetchfield('unread_count');
            $this->db->sql_freeresult($result);
        }
        if ($options['count_total']) {
            // Get the total number of notifications
            $sql = 'SELECT COUNT(n.notification_id) AS total_count
				FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
				WHERE n.user_id = ' . (int) $options['user_id'] . '
					AND nt.notification_type_id = n.notification_type_id
					AND nt.notification_type_enabled = 1';
            $result = $this->db->sql_query($sql);
            $total_count = (int) $this->db->sql_fetchfield('total_count');
            $this->db->sql_freeresult($result);
        }
        if (!$options['count_total'] || $total_count) {
            $rowset = array();
            // Get the main notifications
            $sql = 'SELECT n.*, nt.notification_type_name
				FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
				WHERE n.user_id = ' . (int) $options['user_id'] . ($options['notification_id'] ? is_array($options['notification_id']) ? ' AND ' . $this->db->sql_in_set('n.notification_id', $options['notification_id']) : ' AND n.notification_id = ' . (int) $options['notification_id'] : '') . '
					AND nt.notification_type_id = n.notification_type_id
					AND nt.notification_type_enabled = 1
				ORDER BY n.' . $this->db->sql_escape($options['order_by']) . ' ' . $this->db->sql_escape($options['order_dir']);
            $result = $this->db->sql_query_limit($sql, $options['limit'], $options['start']);
            while ($row = $this->db->sql_fetchrow($result)) {
                $rowset[$row['notification_id']] = $row;
            }
            $this->db->sql_freeresult($result);
            // Get all unread notifications
            if ($unread_count && $options['all_unread'] && !empty($rowset)) {
                $sql = 'SELECT n.*, nt.notification_type_name
				FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
					WHERE n.user_id = ' . (int) $options['user_id'] . '
						AND n.notification_read = 0
						AND ' . $this->db->sql_in_set('n.notification_id', array_keys($rowset), true) . '
						AND nt.notification_type_id = n.notification_type_id
						AND nt.notification_type_enabled = 1
					ORDER BY n.' . $this->db->sql_escape($options['order_by']) . ' ' . $this->db->sql_escape($options['order_dir']);
                $result = $this->db->sql_query_limit($sql, $options['limit'], $options['start']);
                while ($row = $this->db->sql_fetchrow($result)) {
                    $rowset[$row['notification_id']] = $row;
                }
                $this->db->sql_freeresult($result);
            }
            foreach ($rowset as $row) {
                $notification = $this->get_item_type_class($row['notification_type_name'], $row);
                // Array of user_ids to query all at once
                $user_ids = array_merge($user_ids, $notification->users_to_query());
                // Some notification types also require querying additional tables themselves
                if (!isset($load_special[$row['notification_type_name']])) {
                    $load_special[$row['notification_type_name']] = array();
                }
                $load_special[$row['notification_type_name']] = array_merge($load_special[$row['notification_type_name']], $notification->get_load_special());
                $notifications[$row['notification_id']] = $notification;
            }
            $this->user_loader->load_users($user_ids);
            // Allow each type to load its own special items
            foreach ($load_special as $item_type => $data) {
                $item_class = $this->get_item_type_class($item_type);
                $item_class->load_special($data, $notifications);
            }
        }
        return array('notifications' => $notifications, 'unread_count' => $unread_count, 'total_count' => $total_count);
    }
Ejemplo n.º 8
0
/**
* Checks whether a user can download from a particular PM
*
* @param \src\db\driver\driver_interface $db The database object
* @param int $user_id The user id
* @param int $msg_id The id of the PM that we are downloading from
*
* @return bool Whether the user is allowed to download from that PM or not
*/
function src_download_check_pm_auth($db, $user_id, $msg_id)
{
    // Check if the attachment is within the users scope...
    $sql = 'SELECT msg_id
		FROM ' . PRIVMSGS_TO_TABLE . '
		WHERE msg_id = ' . (int) $msg_id . '
			AND (
				user_id = ' . (int) $user_id . '
				OR author_id = ' . (int) $user_id . '
			)';
    $result = $db->sql_query_limit($sql, 1);
    $allowed = (bool) $db->sql_fetchfield('msg_id');
    $db->sql_freeresult($result);
    return $allowed;
}
Ejemplo n.º 9
0
    /**
     * {@inheritdoc}
     */
    public function move($item_id, $delta)
    {
        if ($delta == 0) {
            return false;
        }
        $this->acquire_lock();
        $action = $delta > 0 ? 'move_up' : 'move_down';
        $delta = abs($delta);
        // Keep $this->get_sql_where() here, to ensure we are in the right tree.
        $sql = 'SELECT *
			FROM ' . $this->table_name . '
			WHERE ' . $this->column_item_id . ' = ' . (int) $item_id . '
				' . $this->get_sql_where();
        $result = $this->db->sql_query_limit($sql, $delta);
        $item = $this->db->sql_fetchrow($result);
        $this->db->sql_freeresult($result);
        if (!$item) {
            $this->lock->release();
            throw new \OutOfBoundsException($this->message_prefix . 'INVALID_ITEM');
        }
        /**
         * Fetch all the siblings between the item's current spot
         * and where we want to move it to. If there are less than $delta
         * siblings between the current spot and the target then the
         * item will move as far as possible
         */
        $sql = "SELECT {$this->column_item_id}, {$this->column_parent_id}, {$this->column_left_id}, {$this->column_right_id}, {$this->column_item_parents}\n\t\t\tFROM " . $this->table_name . '
			WHERE ' . $this->column_parent_id . ' = ' . (int) $item[$this->column_parent_id] . '
				' . $this->get_sql_where() . '
				AND ';
        if ($action == 'move_up') {
            $sql .= $this->column_right_id . ' < ' . (int) $item[$this->column_right_id] . ' ORDER BY ' . $this->column_right_id . ' DESC';
        } else {
            $sql .= $this->column_left_id . ' > ' . (int) $item[$this->column_left_id] . ' ORDER BY ' . $this->column_left_id . ' ASC';
        }
        $result = $this->db->sql_query_limit($sql, $delta);
        $target = false;
        while ($row = $this->db->sql_fetchrow($result)) {
            $target = $row;
        }
        $this->db->sql_freeresult($result);
        if (!$target) {
            $this->lock->release();
            // The item is already on top or bottom
            return false;
        }
        /**
         * $left_id and $right_id define the scope of the items that are affected by the move.
         * $diff_up and $diff_down are the values to substract or add to each item's left_id
         * and right_id in order to move them up or down.
         * $move_up_left and $move_up_right define the scope of the items that are moving
         * up. Other items in the scope of ($left_id, $right_id) are considered to move down.
         */
        if ($action == 'move_up') {
            $left_id = (int) $target[$this->column_left_id];
            $right_id = (int) $item[$this->column_right_id];
            $diff_up = (int) $item[$this->column_left_id] - (int) $target[$this->column_left_id];
            $diff_down = (int) $item[$this->column_right_id] + 1 - (int) $item[$this->column_left_id];
            $move_up_left = (int) $item[$this->column_left_id];
            $move_up_right = (int) $item[$this->column_right_id];
        } else {
            $left_id = (int) $item[$this->column_left_id];
            $right_id = (int) $target[$this->column_right_id];
            $diff_up = (int) $item[$this->column_right_id] + 1 - (int) $item[$this->column_left_id];
            $diff_down = (int) $target[$this->column_right_id] - (int) $item[$this->column_right_id];
            $move_up_left = (int) $item[$this->column_right_id] + 1;
            $move_up_right = (int) $target[$this->column_right_id];
        }
        // Now do the dirty job
        $sql = 'UPDATE ' . $this->table_name . '
			SET ' . $this->column_left_id . ' = ' . $this->column_left_id . ' + CASE
				WHEN ' . $this->column_left_id . " BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up}\n\t\t\t\tELSE {$diff_down}\n\t\t\tEND,\n\t\t\t" . $this->column_right_id . ' = ' . $this->column_right_id . ' + CASE
				WHEN ' . $this->column_right_id . " BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up}\n\t\t\t\tELSE {$diff_down}\n\t\t\tEND\n\t\t\tWHERE\n\t\t\t\t" . $this->column_left_id . " BETWEEN {$left_id} AND {$right_id}\n\t\t\t\tAND " . $this->column_right_id . " BETWEEN {$left_id} AND {$right_id}\n\t\t\t\t" . $this->get_sql_where();
        $this->db->sql_query($sql);
        $this->lock->release();
        return true;
    }