Beispiel #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;
    }
Beispiel #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;
        }
    }
Beispiel #3
0
    /**
     * Collects stats that can be displayed on the index maintenance page
     */
    protected function get_stats()
    {
        if ($this->index_created()) {
            $sql = 'SELECT COUNT(post_id) as total_posts
				FROM ' . POSTS_TABLE;
            $result = $this->db->sql_query($sql);
            $this->stats['total_posts'] = (int) $this->db->sql_fetchfield('total_posts');
            $this->db->sql_freeresult($result);
            $sql = 'SELECT COUNT(p.post_id) as main_posts
				FROM ' . POSTS_TABLE . ' p, ' . SPHINX_TABLE . ' m
				WHERE p.post_id <= m.max_doc_id
					AND m.counter_id = 1';
            $result = $this->db->sql_query($sql);
            $this->stats['main_posts'] = (int) $this->db->sql_fetchfield('main_posts');
            $this->db->sql_freeresult($result);
        }
    }
Beispiel #4
0
    /**
     * Add an item which already has a database row at the end of the tree
     *
     * @param int	$item_id	The item to be added
     * @return array		Array with updated data, if the item was added successfully
     *					Empty array otherwise
     */
    protected function add_item_to_nestedset($item_id)
    {
        $sql = 'SELECT MAX(' . $this->column_right_id . ') AS ' . $this->column_right_id . '
			FROM ' . $this->table_name . '
			' . $this->get_sql_where('WHERE');
        $result = $this->db->sql_query($sql);
        $current_max_right_id = (int) $this->db->sql_fetchfield($this->column_right_id);
        $this->db->sql_freeresult($result);
        $update_item_data = array($this->column_parent_id => 0, $this->column_left_id => $current_max_right_id + 1, $this->column_right_id => $current_max_right_id + 2, $this->column_item_parents => '');
        $sql = 'UPDATE ' . $this->table_name . '
			SET ' . $this->db->sql_build_array('UPDATE', $update_item_data) . '
			WHERE ' . $this->column_item_id . ' = ' . (int) $item_id . '
				AND ' . $this->column_parent_id . ' = 0
				AND ' . $this->column_left_id . ' = 0
				AND ' . $this->column_right_id . ' = 0';
        $this->db->sql_query($sql);
        return $this->db->sql_affectedrows() == 1 ? $update_item_data : array();
    }
Beispiel #5
0
    function get_excluded_forums()
    {
        static $forum_ids;
        // Matches acp/acp_srcrd.php
        $cache_name = 'feed_excluded_forum_ids';
        if (!isset($forum_ids) && ($forum_ids = $this->cache->get('_' . $cache_name)) === false) {
            $sql = 'SELECT forum_id
				FROM ' . FORUMS_TABLE . '
				WHERE ' . $this->db->sql_bit_and('forum_options', FORUM_OPTION_FEED_EXCLUDE, '<> 0');
            $result = $this->db->sql_query($sql);
            $forum_ids = array();
            while ($forum_id = (int) $this->db->sql_fetchfield('forum_id')) {
                $forum_ids[$forum_id] = $forum_id;
            }
            $this->db->sql_freeresult($result);
            $this->cache->put('_' . $cache_name, $forum_ids);
        }
        return $forum_ids;
    }
Beispiel #6
0
    /**
     * Delete a subscription
     *
     * @param string $item_type Type identifier of the subscription
     * @param int $item_id The id of the item
     * @param string $method The method of the notification e.g. '', 'email', or 'jabber'
     * @param bool|int $user_id The user_id to add the subscription for (bool false for current user)
     */
    public function delete_subscription($item_type, $item_id = 0, $method = '', $user_id = false)
    {
        $user_id = $user_id === false ? $this->user->data['user_id'] : $user_id;
        // If no method, make sure that no other notification methods for this item are selected before deleting
        if ($method === '') {
            $sql = 'SELECT COUNT(*) as num_notifications
				FROM ' . $this->user_notifications_table . "\n\t\t\t\tWHERE item_type = '" . $this->db->sql_escape($item_type) . "'\n\t\t\t\t\tAND item_id = " . (int) $item_id . '
					AND user_id = ' . (int) $user_id . "\n\t\t\t\t\tAND method <> ''\n\t\t\t\t\tAND notify = 1";
            $this->db->sql_query($sql);
            $num_notifications = $this->db->sql_fetchfield('num_notifications');
            $this->db->sql_freeresult();
            if ($num_notifications) {
                return;
            }
        }
        $sql = 'UPDATE ' . $this->user_notifications_table . "\n\t\t\tSET notify = 0\n\t\t\tWHERE item_type = '" . $this->db->sql_escape($item_type) . "'\n\t\t\t\tAND item_id = " . (int) $item_id . '
				AND user_id = ' . (int) $user_id . "\n\t\t\t\tAND method = '" . $this->db->sql_escape($method) . "'";
        $this->db->sql_query($sql);
        if (!$this->db->sql_affectedrows()) {
            $sql = 'INSERT INTO ' . $this->user_notifications_table . ' ' . $this->db->sql_build_array('INSERT', array('item_type' => $item_type, 'item_id' => (int) $item_id, 'user_id' => (int) $user_id, 'method' => $method, 'notify' => 0));
            $this->db->sql_query($sql);
        }
    }
Beispiel #7
0
    /**
     * Module Remove
     *
     * Remove a module
     *
     * @param string $class The module class(acp|mcp|ucp)
     * @param int|string|bool $parent The parent module_id|module_langname(0 for no parent).
     * 	Use false to ignore the parent check and check class wide.
     * @param int|string $module The module id|module_langname
     * 	specify that here
     * @return null
     * @throws \src\db\migration\exception
     */
    public function remove($class, $parent = 0, $module = '')
    {
        // Imitation of module_add's "automatic" and "manual" method so the uninstaller works from the same set of instructions for umil_auto
        if (is_array($module)) {
            if (isset($module['module_langname'])) {
                // Manual Method
                return $this->remove($class, $parent, $module['module_langname']);
            }
            // Failed.
            if (!isset($module['module_basename'])) {
                throw new \src\db\migration\exception('MODULE_NOT_EXIST');
            }
            // Automatic method
            $basename = $module['module_basename'];
            $module_info = $this->get_module_info($class, $basename);
            foreach ($module_info['modes'] as $mode => $info) {
                if (!isset($module['modes']) || in_array($mode, $module['modes'])) {
                    $this->remove($class, $parent, $info['title']);
                }
            }
        } else {
            if (!$this->exists($class, $parent, $module)) {
                return;
            }
            $parent_sql = '';
            if ($parent !== false) {
                // Allows '' to be sent as 0
                $parent = $parent ?: 0;
                if (!is_numeric($parent)) {
                    $sql = 'SELECT module_id
						FROM ' . $this->modules_table . "\n\t\t\t\t\t\tWHERE module_langname = '" . $this->db->sql_escape($parent) . "'\n\t\t\t\t\t\t\tAND module_class = '" . $this->db->sql_escape($class) . "'";
                    $result = $this->db->sql_query($sql);
                    $module_id = $this->db->sql_fetchfield('module_id');
                    $this->db->sql_freeresult($result);
                    // we know it exists from the module_exists check
                    $parent_sql = 'AND parent_id = ' . (int) $module_id;
                } else {
                    $parent_sql = 'AND parent_id = ' . (int) $parent;
                }
            }
            $module_ids = array();
            if (!is_numeric($module)) {
                $sql = 'SELECT module_id
					FROM ' . $this->modules_table . "\n\t\t\t\t\tWHERE module_langname = '" . $this->db->sql_escape($module) . "'\n\t\t\t\t\t\tAND module_class = '" . $this->db->sql_escape($class) . "'\n\t\t\t\t\t\t{$parent_sql}";
                $result = $this->db->sql_query($sql);
                while ($module_id = $this->db->sql_fetchfield('module_id')) {
                    $module_ids[] = (int) $module_id;
                }
                $this->db->sql_freeresult($result);
            } else {
                $module_ids[] = (int) $module;
            }
            if (!class_exists('acp_modules')) {
                include $this->src_root_path . 'includes/acp/acp_modules.' . $this->php_ext;
                $this->user->add_lang('acp/modules');
            }
            $acp_modules = new \acp_modules();
            $acp_modules->module_class = $class;
            foreach ($module_ids as $module_id) {
                $result = $acp_modules->delete_module($module_id);
                if (!empty($result)) {
                    return;
                }
            }
            $this->cache->destroy("_modules_{$class}");
        }
    }
Beispiel #8
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;
    }
Beispiel #9
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;
    }
Beispiel #10
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;
 }
Beispiel #11
0
    /**
     * Permission Unset
     *
     * Allows you to unset (remove) permissions for a certain group/role
     *
     * @param string $name The name of the role/group
     * @param string|array $auth_option The auth_option or array of
     * 	auth_options you would like to set
     * @param string $type The type (role|group)
     * @return null
     * @throws \src\db\migration\exception
     */
    public function permission_unset($name, $auth_option, $type = 'role')
    {
        if (!is_array($auth_option)) {
            $auth_option = array($auth_option);
        }
        $to_remove = array();
        $sql = 'SELECT auth_option_id
			FROM ' . ACL_OPTIONS_TABLE . '
			WHERE ' . $this->db->sql_in_set('auth_option', $auth_option);
        $result = $this->db->sql_query($sql);
        while ($row = $this->db->sql_fetchrow($result)) {
            $to_remove[] = (int) $row['auth_option_id'];
        }
        $this->db->sql_freeresult($result);
        if (empty($to_remove)) {
            return;
        }
        $type = (string) $type;
        // Prevent PHP bug.
        switch ($type) {
            case 'role':
                $sql = 'SELECT role_id
					FROM ' . ACL_ROLES_TABLE . "\n\t\t\t\t\tWHERE role_name = '" . $this->db->sql_escape($name) . "'";
                $this->db->sql_query($sql);
                $role_id = (int) $this->db->sql_fetchfield('role_id');
                if (!$role_id) {
                    throw new \src\db\migration\exception('ROLE_NOT_EXIST', $name);
                }
                $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . '
					WHERE ' . $this->db->sql_in_set('auth_option_id', $to_remove) . '
						AND role_id = ' . (int) $role_id;
                $this->db->sql_query($sql);
                break;
            case 'group':
                $sql = 'SELECT group_id
					FROM ' . GROUPS_TABLE . "\n\t\t\t\t\tWHERE group_name = '" . $this->db->sql_escape($name) . "'";
                $this->db->sql_query($sql);
                $group_id = (int) $this->db->sql_fetchfield('group_id');
                if (!$group_id) {
                    throw new \src\db\migration\exception('GROUP_NOT_EXIST', $name);
                }
                // If the group has a role set for them we will remove the requested permissions from that role.
                $sql = 'SELECT auth_role_id
					FROM ' . ACL_GROUPS_TABLE . '
					WHERE group_id = ' . $group_id . '
						AND auth_role_id <> 0';
                $this->db->sql_query($sql);
                $role_id = (int) $this->db->sql_fetchfield('auth_role_id');
                if ($role_id) {
                    $sql = 'SELECT role_name
						FROM ' . ACL_ROLES_TABLE . '
						WHERE role_id = ' . $role_id;
                    $this->db->sql_query($sql);
                    $role_name = $this->db->sql_fetchfield('role_name');
                    return $this->permission_unset($role_name, $auth_option, 'role');
                }
                $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . '
					WHERE ' . $this->db->sql_in_set('auth_option_id', $to_remove);
                $this->db->sql_query($sql);
                break;
        }
        $this->auth->acl_clear_prefetch();
    }
Beispiel #12
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;
}