Ejemplo n.º 1
0
    /**
     * Mass delete configuration options.
     *
     * @param array $keys       Set of configuration option names
     *
     * @return null
     */
    public function delete_array(array $keys)
    {
        $sql = 'DELETE
			FROM ' . $this->table . '
			WHERE ' . $this->db->sql_in_set('config_name', $keys, false, true);
        $this->db->sql_query($sql);
    }
Ejemplo n.º 2
0
    /**
     * Load user helper
     *
     * @param array $user_ids
     */
    public function load_users(array $user_ids)
    {
        $user_ids[] = ANONYMOUS;
        // Make user_ids unique and convert to integer.
        $user_ids = array_map('intval', array_unique($user_ids));
        // Do not load users we already have in $this->users
        $user_ids = array_diff($user_ids, array_keys($this->users));
        if (sizeof($user_ids)) {
            $sql = 'SELECT *
				FROM ' . $this->users_table . '
				WHERE ' . $this->db->sql_in_set('user_id', $user_ids);
            $result = $this->db->sql_query($sql);
            while ($row = $this->db->sql_fetchrow($result)) {
                $this->users[$row['user_id']] = $row;
            }
            $this->db->sql_freeresult($result);
        }
    }
Ejemplo n.º 3
0
/**
* Updates rows in given table from a set of values to a new value.
* If this results in rows violating uniqueness constraints, the duplicate
* rows are merged respecting notify_status (0 takes precedence over 1).
*
* The only supported table is topics_watch.
*
* @param \src\db\driver\driver_interface $db Database object
* @param string $table Table on which to perform the update
* @param string $column Column whose values to change
* @param array $from_values An array of values that should be changed
* @param int $to_value The new value
* @return null
*/
function src_update_rows_avoiding_duplicates_notify_status(\src\db\driver\driver_interface $db, $table, $column, $from_values, $to_value)
{
    $sql = "SELECT {$column}, user_id, notify_status\n\t\tFROM {$table}\n\t\tWHERE " . $db->sql_in_set($column, $from_values);
    $result = $db->sql_query($sql);
    $old_user_ids = array();
    while ($row = $db->sql_fetchrow($result)) {
        $old_user_ids[(int) $row['notify_status']][$row[$column]][] = (int) $row['user_id'];
    }
    $db->sql_freeresult($result);
    $sql = "SELECT {$column}, user_id\n\t\tFROM {$table}\n\t\tWHERE {$column} = " . (int) $to_value;
    $result = $db->sql_query($sql);
    $new_user_ids = array();
    while ($row = $db->sql_fetchrow($result)) {
        $new_user_ids[$row[$column]][] = (int) $row['user_id'];
    }
    $db->sql_freeresult($result);
    $queries = array();
    $extra_updates = array(0 => 'notify_status = 0', 1 => '');
    foreach ($from_values as $from_value) {
        foreach ($extra_updates as $notify_status => $extra_update) {
            if (!isset($old_user_ids[$notify_status][$from_value])) {
                continue;
            }
            if (empty($new_user_ids)) {
                $sql = "UPDATE {$table}\n\t\t\t\t\tSET {$column} = " . (int) $to_value . "\n\t\t\t\t\tWHERE {$column} = '" . $db->sql_escape($from_value) . "'";
                $queries[] = $sql;
            } else {
                $different_user_ids = array_diff($old_user_ids[$notify_status][$from_value], $new_user_ids[$to_value]);
                if (!empty($different_user_ids)) {
                    $sql = "UPDATE {$table}\n\t\t\t\t\t\tSET {$column} = " . (int) $to_value . "\n\t\t\t\t\t\tWHERE {$column} = '" . $db->sql_escape($from_value) . "'\n\t\t\t\t\t\tAND " . $db->sql_in_set('user_id', $different_user_ids);
                    $queries[] = $sql;
                }
                if ($extra_update) {
                    $same_user_ids = array_diff($old_user_ids[$notify_status][$from_value], $different_user_ids);
                    if (!empty($same_user_ids)) {
                        $sql = "UPDATE {$table}\n\t\t\t\t\t\t\tSET {$extra_update}\n\t\t\t\t\t\t\tWHERE {$column} = '" . (int) $to_value . "'\n\t\t\t\t\t\t\tAND " . $db->sql_in_set('user_id', $same_user_ids);
                        $queries[] = $sql;
                    }
                }
            }
        }
    }
    if (!empty($queries)) {
        $db->sql_transaction('begin');
        foreach ($queries as $sql) {
            $db->sql_query($sql);
        }
        $sql = "DELETE FROM {$table}\n\t\t\tWHERE " . $db->sql_in_set($column, $from_values);
        $db->sql_query($sql);
        $db->sql_transaction('commit');
    }
}
Ejemplo n.º 4
0
    /**
     * Delete a notification
     *
     * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $item_id is identical for the specified types)
     * @param int|array $item_id Identifier within the type (or array of ids)
     * @param mixed $parent_id Parent identifier within the type (or array of ids), used in combination with item_id if specified (Default: false; not checked)
     */
    public function delete_notifications($notification_type_name, $item_id, $parent_id = false)
    {
        if (is_array($notification_type_name)) {
            foreach ($notification_type_name as $type) {
                $this->delete_notifications($type, $item_id, $parent_id);
            }
            return;
        }
        $notification_type_id = $this->get_notification_type_id($notification_type_name);
        $sql = 'DELETE FROM ' . $this->notifications_table . '
			WHERE notification_type_id = ' . (int) $notification_type_id . '
				AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id) . ($parent_id !== false ? ' AND ' . (is_array($parent_id) ? $this->db->sql_in_set('item_parent_id', $parent_id) : 'item_parent_id = ' . (int) $parent_id) : '');
        $this->db->sql_query($sql);
    }
Ejemplo n.º 5
0
    /**
     * Prepare adding a subset to the nested set
     *
     * @param array	$subset_items		Subset of items to add
     * @param array	$new_parent	Item containing the right bound of the new parent
     * @return	int		New right id of the parent item
     */
    protected function prepare_adding_subset(array $subset_items, array $new_parent)
    {
        $diff = sizeof($subset_items) * 2;
        $sql_not_subset_items = $this->db->sql_in_set($this->column_item_id, $subset_items, true);
        $set_left_id = $this->db->sql_case($this->column_left_id . ' > ' . (int) $new_parent[$this->column_right_id], $this->column_left_id . ' + ' . $diff, $this->column_left_id);
        $set_right_id = $this->db->sql_case($this->column_right_id . ' >= ' . (int) $new_parent[$this->column_right_id], $this->column_right_id . ' + ' . $diff, $this->column_right_id);
        $sql = 'UPDATE ' . $this->table_name . '
			SET ' . $this->column_left_id . ' = ' . $set_left_id . ',
				' . $this->column_right_id . ' = ' . $set_right_id . '
			WHERE ' . $sql_not_subset_items . '
				' . $this->get_sql_where('AND');
        $this->db->sql_query($sql);
        return $new_parent[$this->column_right_id] + $diff;
    }
Ejemplo n.º 6
0
    /**
     * Tidy up indexes: Tag 'common words' and remove
     * words no longer referenced in the match table
     */
    public function tidy()
    {
        // Is the fulltext indexer disabled? If yes then we need not
        // carry on ... it's okay ... I know when I'm not wanted boo hoo
        if (!$this->config['fulltext_native_load_upd']) {
            set_config('search_last_gc', time(), true);
            return;
        }
        $destroy_cache_words = array();
        // Remove common words
        if ($this->config['num_posts'] >= 100 && $this->config['fulltext_native_common_thres']) {
            $common_threshold = (double) $this->config['fulltext_native_common_thres'] / 100.0;
            // First, get the IDs of common words
            $sql = 'SELECT word_id, word_text
				FROM ' . SEARCH_WORDLIST_TABLE . '
				WHERE word_count > ' . floor($this->config['num_posts'] * $common_threshold) . '
					OR word_common = 1';
            $result = $this->db->sql_query($sql);
            $sql_in = array();
            while ($row = $this->db->sql_fetchrow($result)) {
                $sql_in[] = $row['word_id'];
                $destroy_cache_words[] = $row['word_text'];
            }
            $this->db->sql_freeresult($result);
            if (sizeof($sql_in)) {
                // Flag the words
                $sql = 'UPDATE ' . SEARCH_WORDLIST_TABLE . '
					SET word_common = 1
					WHERE ' . $this->db->sql_in_set('word_id', $sql_in);
                $this->db->sql_query($sql);
                // by setting search_last_gc to the new time here we make sure that if a user reloads because the
                // following query takes too long, he won't run into it again
                set_config('search_last_gc', time(), true);
                // Delete the matches
                $sql = 'DELETE FROM ' . SEARCH_WORDMATCH_TABLE . '
					WHERE ' . $this->db->sql_in_set('word_id', $sql_in);
                $this->db->sql_query($sql);
            }
            unset($sql_in);
        }
        if (sizeof($destroy_cache_words)) {
            // destroy cached search results containing any of the words that are now common or were removed
            $this->destroy_cache(array_unique($destroy_cache_words));
        }
        set_config('search_last_gc', time(), true);
    }
Ejemplo n.º 7
0
    /**
     * Build Array for user insertion into custom profile fields table
     */
    public function build_insert_sql_array($cp_data)
    {
        $sql_not_in = array();
        foreach ($cp_data as $key => $null) {
            $sql_not_in[] = strncmp($key, 'pf_', 3) === 0 ? substr($key, 3) : $key;
        }
        $sql = 'SELECT f.field_type, f.field_ident, f.field_default_value, l.lang_default_value
			FROM ' . $this->fields_language_table . ' l, ' . $this->fields_table . ' f
			WHERE l.lang_id = ' . $this->user->get_iso_lang_id() . '
				' . (sizeof($sql_not_in) ? ' AND ' . $this->db->sql_in_set('f.field_ident', $sql_not_in, true) : '') . '
				AND l.field_id = f.field_id';
        $result = $this->db->sql_query($sql);
        while ($row = $this->db->sql_fetchrow($result)) {
            $profile_field = $this->type_collection[$row['field_type']];
            $cp_data['pf_' . $row['field_ident']] = $profile_field->get_default_field_value($row);
        }
        $this->db->sql_freeresult($result);
        return $cp_data;
    }
Ejemplo n.º 8
0
    /**
     * Find the users who want to receive notifications (helper)
     *
     * @param array $user_ids User IDs to check if they want to receive notifications
     * 		(Bool False to check all users besides anonymous and bots (USER_IGNORE))
     *
     * @return array
     */
    protected function check_user_notification_options($user_ids = false, $options = array())
    {
        $options = array_merge(array('ignore_users' => array(), 'item_type' => $this->get_type(), 'item_id' => 0), $options);
        if ($user_ids === false) {
            $user_ids = array();
            $sql = 'SELECT user_id
				FROM ' . USERS_TABLE . '
				WHERE user_id <> ' . ANONYMOUS . '
					AND user_type <> ' . USER_IGNORE;
            $result = $this->db->sql_query($sql);
            while ($row = $this->db->sql_fetchrow($result)) {
                $user_ids[] = $row['user_id'];
            }
            $this->db->sql_freeresult($result);
        }
        if (empty($user_ids)) {
            return array();
        }
        $rowset = $resulting_user_ids = array();
        $sql = 'SELECT user_id, method, notify
			FROM ' . $this->user_notifications_table . '
			WHERE ' . $this->db->sql_in_set('user_id', $user_ids) . "\n\t\t\t\tAND item_type = '" . $this->db->sql_escape($options['item_type']) . "'\n\t\t\t\tAND item_id = " . (int) $options['item_id'];
        $result = $this->db->sql_query($sql);
        while ($row = $this->db->sql_fetchrow($result)) {
            $resulting_user_ids[] = $row['user_id'];
            if (!$row['notify'] || isset($options['ignore_users'][$row['user_id']]) && in_array($row['method'], $options['ignore_users'][$row['user_id']])) {
                continue;
            }
            if (!isset($rowset[$row['user_id']])) {
                $rowset[$row['user_id']] = array();
            }
            $rowset[$row['user_id']][] = $row['method'];
        }
        $this->db->sql_freeresult($result);
        foreach ($user_ids as $user_id) {
            if (!in_array($user_id, $resulting_user_ids) && !isset($options['ignore_users'][$user_id])) {
                // No rows at all for this user, default to ''
                $rowset[$user_id] = array('');
            }
        }
        return $rowset;
    }
Ejemplo n.º 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;
    }
Ejemplo n.º 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;
 }
Ejemplo n.º 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();
    }
Ejemplo n.º 12
0
/**
* Increments the download count of all provided attachments
*
* @param \src\db\driver\driver_interface $db The database object
* @param array|int $ids The attach_id of each attachment
*
* @return null
*/
function src_increment_downloads($db, $ids)
{
    if (!is_array($ids)) {
        $ids = array($ids);
    }
    $sql = 'UPDATE ' . ATTACHMENTS_TABLE . '
		SET download_count = download_count + 1
		WHERE ' . $db->sql_in_set('attach_id', $ids);
    $db->sql_query($sql);
}