mirror of
				https://github.com/phpbb/phpbb.git
				synced 2025-10-26 21:21:32 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			651 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			651 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
| *
 | |
| * @package phpbb
 | |
| * @copyright (c) 2012 phpBB Group
 | |
| * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
 | |
| *
 | |
| */
 | |
| 
 | |
| namespace phpbb;
 | |
| 
 | |
| /**
 | |
| * phpbb_visibility
 | |
| * Handle fetching and setting the visibility for topics and posts
 | |
| * @package phpbb
 | |
| */
 | |
| class content_visibility
 | |
| {
 | |
| 	/**
 | |
| 	* Database object
 | |
| 	* @var \phpbb\db\driver\driver_interface
 | |
| 	*/
 | |
| 	protected $db;
 | |
| 
 | |
| 	/**
 | |
| 	* User object
 | |
| 	* @var \phpbb\user
 | |
| 	*/
 | |
| 	protected $user;
 | |
| 
 | |
| 	/**
 | |
| 	* Auth object
 | |
| 	* @var \phpbb\auth\auth
 | |
| 	*/
 | |
| 	protected $auth;
 | |
| 
 | |
| 	/**
 | |
| 	* phpBB root path
 | |
| 	* @var string
 | |
| 	*/
 | |
| 	protected $phpbb_root_path;
 | |
| 
 | |
| 	/**
 | |
| 	* PHP Extension
 | |
| 	* @var string
 | |
| 	*/
 | |
| 	protected $php_ext;
 | |
| 
 | |
| 	/**
 | |
| 	* Constructor
 | |
| 	*
 | |
| 	* @param	\phpbb\auth\auth		$auth	Auth object
 | |
| 	* @param	\phpbb\db\driver\driver_interface	$db		Database object
 | |
| 	* @param	\phpbb\user		$user	User object
 | |
| 	* @param	string		$phpbb_root_path	Root path
 | |
| 	* @param	string		$php_ext			PHP Extension
 | |
| 	* @return	null
 | |
| 	*/
 | |
| 	public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver_interface $db, \phpbb\user $user, $phpbb_root_path, $php_ext, $forums_table, $posts_table, $topics_table, $users_table)
 | |
| 	{
 | |
| 		$this->auth = $auth;
 | |
| 		$this->db = $db;
 | |
| 		$this->user = $user;
 | |
| 		$this->phpbb_root_path = $phpbb_root_path;
 | |
| 		$this->php_ext = $php_ext;
 | |
| 		$this->forums_table = $forums_table;
 | |
| 		$this->posts_table = $posts_table;
 | |
| 		$this->topics_table = $topics_table;
 | |
| 		$this->users_table = $users_table;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	* Can the current logged-in user soft-delete posts?
 | |
| 	*
 | |
| 	* @param $forum_id		int		Forum ID whose permissions to check
 | |
| 	* @param $poster_id		int		Poster ID of the post in question
 | |
| 	* @param $post_locked	bool	Is the post locked?
 | |
| 	* @return bool
 | |
| 	*/
 | |
| 	public function can_soft_delete($forum_id, $poster_id, $post_locked)
 | |
| 	{
 | |
| 		if ($this->auth->acl_get('m_softdelete', $forum_id))
 | |
| 		{
 | |
| 			return true;
 | |
| 		}
 | |
| 		else if ($this->auth->acl_get('f_softdelete', $forum_id) && $poster_id == $this->user->data['user_id'] && !$post_locked)
 | |
| 		{
 | |
| 			return true;
 | |
| 		}
 | |
| 
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	* Get the topics post count or the forums post/topic count based on permissions
 | |
| 	*
 | |
| 	* @param $mode			string	One of topic_posts, forum_posts or forum_topics
 | |
| 	* @param $data			array	Array with the topic/forum data to calculate from
 | |
| 	* @param $forum_id		int		The forum id is used for permission checks
 | |
| 	* @return int	Number of posts/topics the user can see in the topic/forum
 | |
| 	*/
 | |
| 	public function get_count($mode, $data, $forum_id)
 | |
| 	{
 | |
| 		if (!$this->auth->acl_get('m_approve', $forum_id))
 | |
| 		{
 | |
| 			return (int) $data[$mode . '_approved'];
 | |
| 		}
 | |
| 
 | |
| 		return (int) $data[$mode . '_approved'] + (int) $data[$mode . '_unapproved'] + (int) $data[$mode . '_softdeleted'];
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	* Create topic/post visibility SQL for a given forum ID
 | |
| 	*
 | |
| 	* Note: Read permissions are not checked.
 | |
| 	*
 | |
| 	* @param $mode			string	Either "topic" or "post"
 | |
| 	* @param $forum_id		int		The forum id is used for permission checks
 | |
| 	* @param $table_alias	string	Table alias to prefix in SQL queries
 | |
| 	* @return string	The appropriate combination SQL logic for topic/post_visibility
 | |
| 	*/
 | |
| 	public function get_visibility_sql($mode, $forum_id, $table_alias = '')
 | |
| 	{
 | |
| 		if ($this->auth->acl_get('m_approve', $forum_id))
 | |
| 		{
 | |
| 			return '1 = 1';
 | |
| 		}
 | |
| 
 | |
| 		return $table_alias . $mode . '_visibility = ' . ITEM_APPROVED;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	* Create topic/post visibility SQL for a set of forums
 | |
| 	*
 | |
| 	* Note: Read permissions are not checked. Forums without read permissions
 | |
| 	*		should not be in $forum_ids
 | |
| 	*
 | |
| 	* @param $mode			string	Either "topic" or "post"
 | |
| 	* @param $forum_ids		array	Array of forum ids which the posts/topics are limited to
 | |
| 	* @param $table_alias	string	Table alias to prefix in SQL queries
 | |
| 	* @return string	The appropriate combination SQL logic for topic/post_visibility
 | |
| 	*/
 | |
| 	public function get_forums_visibility_sql($mode, $forum_ids = array(), $table_alias = '')
 | |
| 	{
 | |
| 		$where_sql = '(';
 | |
| 
 | |
| 		$approve_forums = array_intersect($forum_ids, array_keys($this->auth->acl_getf('m_approve', true)));
 | |
| 
 | |
| 		if (sizeof($approve_forums))
 | |
| 		{
 | |
| 			// Remove moderator forums from the rest
 | |
| 			$forum_ids = array_diff($forum_ids, $approve_forums);
 | |
| 
 | |
| 			if (!sizeof($forum_ids))
 | |
| 			{
 | |
| 				// The user can see all posts/topics in all specified forums
 | |
| 				return $this->db->sql_in_set($table_alias . 'forum_id', $approve_forums);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				// Moderator can view all posts/topics in some forums
 | |
| 				$where_sql .= $this->db->sql_in_set($table_alias . 'forum_id', $approve_forums) . ' OR ';
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			// The user is just a normal user
 | |
| 			return $table_alias . $mode . '_visibility = ' . ITEM_APPROVED . '
 | |
| 				AND ' . $this->db->sql_in_set($table_alias . 'forum_id', $forum_ids, false, true);
 | |
| 		}
 | |
| 
 | |
| 		$where_sql .= '(' . $table_alias . $mode . '_visibility = ' . ITEM_APPROVED . '
 | |
| 			AND ' . $this->db->sql_in_set($table_alias . 'forum_id', $forum_ids) . '))';
 | |
| 
 | |
| 		return $where_sql;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	* Create topic/post visibility SQL for all forums on the board
 | |
| 	*
 | |
| 	* Note: Read permissions are not checked. Forums without read permissions
 | |
| 	*		should be in $exclude_forum_ids
 | |
| 	*
 | |
| 	* @param $mode				string	Either "topic" or "post"
 | |
| 	* @param $exclude_forum_ids	array	Array of forum ids which are excluded
 | |
| 	* @param $table_alias		string	Table alias to prefix in SQL queries
 | |
| 	* @return string	The appropriate combination SQL logic for topic/post_visibility
 | |
| 	*/
 | |
| 	public function get_global_visibility_sql($mode, $exclude_forum_ids = array(), $table_alias = '')
 | |
| 	{
 | |
| 		$where_sqls = array();
 | |
| 
 | |
| 		$approve_forums = array_diff(array_keys($this->auth->acl_getf('m_approve', true)), $exclude_forum_ids);
 | |
| 
 | |
| 		if (sizeof($exclude_forum_ids))
 | |
| 		{
 | |
| 			$where_sqls[] = '(' . $this->db->sql_in_set($table_alias . 'forum_id', $exclude_forum_ids, true) . '
 | |
| 				AND ' . $table_alias . $mode . '_visibility = ' . ITEM_APPROVED . ')';
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			$where_sqls[] = $table_alias . $mode . '_visibility = ' . ITEM_APPROVED;
 | |
| 		}
 | |
| 
 | |
| 		if (sizeof($approve_forums))
 | |
| 		{
 | |
| 			$where_sqls[] = $this->db->sql_in_set($table_alias . 'forum_id', $approve_forums);
 | |
| 			return '(' . implode(' OR ', $where_sqls) . ')';
 | |
| 		}
 | |
| 
 | |
| 		// There is only one element, so we just return that one
 | |
| 		return $where_sqls[0];
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	* Change visibility status of one post or all posts of a topic
 | |
| 	*
 | |
| 	* @param $visibility	int		Element of {ITEM_APPROVED, ITEM_DELETED}
 | |
| 	* @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 visibilty 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 occured.
 | |
| 	*/
 | |
| 	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)))
 | |
| 		{
 | |
| 			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 ($visibility == 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->phpbb_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->phpbb_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;
 | |
| 		}
 | |
| 
 | |
| 		// Update the topic's reply count and the forum's post count
 | |
| 		if ($update_topic_postcount)
 | |
| 		{
 | |
| 			$cur_posts = $cur_unapproved_posts = $cur_softdeleted_posts = 0;
 | |
| 			foreach ($postcount_visibility as $post_visibility => $visibility_posts)
 | |
| 			{
 | |
| 				// We need to substract the posts from the counters ...
 | |
| 				if ($post_visibility == ITEM_APPROVED)
 | |
| 				{
 | |
| 					$cur_posts += $visibility_posts;
 | |
| 				}
 | |
| 				else if ($post_visibility == ITEM_UNAPPROVED)
 | |
| 				{
 | |
| 					$cur_unapproved_posts += $visibility_posts;
 | |
| 				}
 | |
| 				else if ($post_visibility == ITEM_DELETED)
 | |
| 				{
 | |
| 					$cur_softdeleted_posts += $visibility_posts;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			$sql_ary = array();
 | |
| 			if ($visibility == ITEM_DELETED)
 | |
| 			{
 | |
| 				if ($cur_posts)
 | |
| 				{
 | |
| 					$sql_ary['posts_approved'] = ' - ' . $cur_posts;
 | |
| 				}
 | |
| 				if ($cur_unapproved_posts)
 | |
| 				{
 | |
| 					$sql_ary['posts_unapproved'] = ' - ' . $cur_unapproved_posts;
 | |
| 				}
 | |
| 				if ($cur_posts + $cur_unapproved_posts)
 | |
| 				{
 | |
| 					$sql_ary['posts_softdeleted'] = ' + ' . ($cur_posts + $cur_unapproved_posts);
 | |
| 				}
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				if ($cur_unapproved_posts)
 | |
| 				{
 | |
| 					$sql_ary['posts_unapproved'] = ' - ' . $cur_unapproved_posts;
 | |
| 				}
 | |
| 				if ($cur_softdeleted_posts)
 | |
| 				{
 | |
| 					$sql_ary['posts_softdeleted'] = ' - ' . $cur_softdeleted_posts;
 | |
| 				}
 | |
| 				if ($cur_softdeleted_posts + $cur_unapproved_posts)
 | |
| 				{
 | |
| 					$sql_ary['posts_approved'] = ' + ' . ($cur_softdeleted_posts + $cur_unapproved_posts);
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			if (sizeof($sql_ary))
 | |
| 			{
 | |
| 				$topic_sql = $forum_sql = array();
 | |
| 
 | |
| 				foreach ($sql_ary as $field => $value_change)
 | |
| 				{
 | |
| 					$topic_sql[] = 'topic_' . $field . ' = topic_' . $field . $value_change;
 | |
| 					$forum_sql[] = 'forum_' . $field . ' = forum_' . $field . $value_change;
 | |
| 				}
 | |
| 
 | |
| 				// Update the number for replies and posts
 | |
| 				$sql = 'UPDATE ' . $this->topics_table . '
 | |
| 					SET ' . implode(', ', $topic_sql) . '
 | |
| 					WHERE topic_id = ' . (int) $topic_id;
 | |
| 				$this->db->sql_query($sql);
 | |
| 
 | |
| 				$sql = 'UPDATE ' . $this->forums_table . '
 | |
| 					SET ' . implode(', ', $forum_sql) . '
 | |
| 					WHERE forum_id = ' . (int) $forum_id;
 | |
| 				$this->db->sql_query($sql);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return $data;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	* Set topic visibility
 | |
| 	*
 | |
| 	* Allows approving (which is akin to undeleting/restore) or soft deleting an entire topic.
 | |
| 	* Calls set_post_visibility as needed.
 | |
| 	*
 | |
| 	* Note: By default, when a soft deleted topic is restored. Only posts that
 | |
| 	*		were approved at the time of soft deleting, are being restored.
 | |
| 	*		Same applies to soft deleting. Only approved posts will be marked
 | |
| 	*		as soft deleted.
 | |
| 	*		If you want to update all posts, use the force option.
 | |
| 	*
 | |
| 	* @param $visibility	int		Element of {ITEM_APPROVED, ITEM_DELETED}
 | |
| 	* @param $topic_id		mixed	Topic ID to act on
 | |
| 	* @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 visibilty was changed.
 | |
| 	* @param $force_update_all	bool	Force to update all posts within the topic
 | |
| 	* @return array		Changed topic data, empty array if an error occured.
 | |
| 	*/
 | |
| 	public function set_topic_visibility($visibility, $topic_id, $forum_id, $user_id, $time, $reason, $force_update_all = false)
 | |
| 	{
 | |
| 		if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED)))
 | |
| 		{
 | |
| 			return array();
 | |
| 		}
 | |
| 
 | |
| 		if (!$force_update_all)
 | |
| 		{
 | |
| 			$sql = 'SELECT topic_visibility, topic_delete_time
 | |
| 				FROM ' . $this->topics_table . '
 | |
| 				WHERE topic_id = ' . (int) $topic_id;
 | |
| 			$result = $this->db->sql_query($sql);
 | |
| 			$original_topic_data = $this->db->sql_fetchrow($result);
 | |
| 			$this->db->sql_freeresult($result);
 | |
| 
 | |
| 			if (!$original_topic_data)
 | |
| 			{
 | |
| 				// The topic does not exist...
 | |
| 				return array();
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		// Note, we do not set a reason for the posts, just for the topic
 | |
| 		$data = array(
 | |
| 			'topic_visibility'		=> (int) $visibility,
 | |
| 			'topic_delete_user'		=> (int) $user_id,
 | |
| 			'topic_delete_time'		=> ((int) $time) ?: time(),
 | |
| 			'topic_delete_reason'	=> truncate_string($reason, 255, 255, false),
 | |
| 		);
 | |
| 
 | |
| 		$sql = 'UPDATE ' . $this->topics_table . '
 | |
| 			SET ' . $this->db->sql_build_array('UPDATE', $data) . '
 | |
| 			WHERE topic_id = ' . (int) $topic_id;
 | |
| 		$this->db->sql_query($sql);
 | |
| 
 | |
| 		if (!$this->db->sql_affectedrows())
 | |
| 		{
 | |
| 			return array();
 | |
| 		}
 | |
| 
 | |
| 		if (!$force_update_all && $original_topic_data['topic_delete_time'] && $original_topic_data['topic_visibility'] == ITEM_DELETED && $visibility == ITEM_APPROVED)
 | |
| 		{
 | |
| 			// If we're restoring a topic we only restore posts, that were soft deleted through the topic soft deletion.
 | |
| 			$this->set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true, $original_topic_data['topic_visibility'], $original_topic_data['topic_delete_time']);
 | |
| 		}
 | |
| 		else if (!$force_update_all && $original_topic_data['topic_visibility'] == ITEM_APPROVED && $visibility == ITEM_DELETED)
 | |
| 		{
 | |
| 			// If we're soft deleting a topic we only approved posts are soft deleted.
 | |
| 			$this->set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true, $original_topic_data['topic_visibility']);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			$this->set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true);
 | |
| 		}
 | |
| 
 | |
| 		return $data;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	* Add post to topic and forum statistics
 | |
| 	*
 | |
| 	* @param $data			array	Contains information from the topics table about given topic
 | |
| 	* @param $sql_data		array	Populated with the SQL changes, may be empty at call time
 | |
| 	* @return null
 | |
| 	*/
 | |
| 	public function add_post_to_statistic($data, &$sql_data)
 | |
| 	{
 | |
| 		$sql_data[$this->topics_table] = (($sql_data[$this->topics_table]) ? $sql_data[$this->topics_table] . ', ' : '') . 'topic_posts_approved = topic_posts_approved + 1';
 | |
| 
 | |
| 		$sql_data[$this->forums_table] = (($sql_data[$this->forums_table]) ? $sql_data[$this->forums_table] . ', ' : '') . 'forum_posts_approved = forum_posts_approved + 1';
 | |
| 
 | |
| 		if ($data['post_postcount'])
 | |
| 		{
 | |
| 			$sql_data[$this->users_table] = (($sql_data[$this->users_table]) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts + 1';
 | |
| 		}
 | |
| 
 | |
| 		set_config_count('num_posts', 1, true);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	* Remove post from topic and forum statistics
 | |
| 	*
 | |
| 	* @param $data			array	Contains information from the topics table about given topic
 | |
| 	* @param $sql_data		array	Populated with the SQL changes, may be empty at call time
 | |
| 	* @return null
 | |
| 	*/
 | |
| 	public function remove_post_from_statistic($data, &$sql_data)
 | |
| 	{
 | |
| 		$sql_data[$this->topics_table] = ((!empty($sql_data[$this->topics_table])) ? $sql_data[$this->topics_table] . ', ' : '') . 'topic_posts_approved = topic_posts_approved - 1';
 | |
| 		$sql_data[$this->forums_table] = ((!empty($sql_data[$this->forums_table])) ? $sql_data[$this->forums_table] . ', ' : '') . 'forum_posts_approved = forum_posts_approved - 1';
 | |
| 
 | |
| 		if ($data['post_postcount'])
 | |
| 		{
 | |
| 			$sql_data[$this->users_table] = ((!empty($sql_data[$this->users_table])) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts - 1';
 | |
| 		}
 | |
| 
 | |
| 		set_config_count('num_posts', -1, true);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	* Remove topic from forum statistics
 | |
| 	*
 | |
| 	* @param $topic_id		int		The topic to act on
 | |
| 	* @param $forum_id		int		Forum where the topic is found
 | |
| 	* @param $topic_row		array	Contains information from the topic, may be empty at call time
 | |
| 	* @param $sql_data		array	Populated with the SQL changes, may be empty at call time
 | |
| 	* @return null
 | |
| 	*/
 | |
| 	public function remove_topic_from_statistic($topic_id, $forum_id, &$topic_row, &$sql_data)
 | |
| 	{
 | |
| 		// Do we need to grab some topic informations?
 | |
| 		if (!sizeof($topic_row))
 | |
| 		{
 | |
| 			$sql = 'SELECT topic_type, topic_posts_approved, topic_posts_unapproved, topic_posts_softdeleted, topic_visibility
 | |
| 				FROM ' . $this->topics_table . '
 | |
| 				WHERE topic_id = ' . (int) $topic_id;
 | |
| 			$result = $this->db->sql_query($sql);
 | |
| 			$topic_row = $this->db->sql_fetchrow($result);
 | |
| 			$this->db->sql_freeresult($result);
 | |
| 		}
 | |
| 
 | |
| 		// If this is an edited topic or the first post the topic gets completely disapproved later on...
 | |
| 		$sql_data[$this->forums_table] = (($sql_data[$this->forums_table]) ? $sql_data[$this->forums_table] . ', ' : '') . 'forum_topics_approved = forum_topics_approved - 1';
 | |
| 		$sql_data[$this->forums_table] .= ', forum_posts_approved = forum_posts_approved - ' . $topic_row['topic_posts_approved'];
 | |
| 		$sql_data[$this->forums_table] .= ', forum_posts_unapproved = forum_posts_unapproved - ' . $topic_row['topic_posts_unapproved'];
 | |
| 		$sql_data[$this->forums_table] .= ', forum_posts_softdeleted = forum_posts_softdeleted - ' . $topic_row['topic_posts_softdeleted'];
 | |
| 
 | |
| 		set_config_count('num_topics', -1, true);
 | |
| 		set_config_count('num_posts', $topic_row['topic_posts_approved'] * (-1), true);
 | |
| 
 | |
| 		// Get user post count information
 | |
| 		$sql = 'SELECT poster_id, COUNT(post_id) AS num_posts
 | |
| 			FROM ' . $this->posts_table . '
 | |
| 			WHERE topic_id = ' . (int) $topic_id . '
 | |
| 				AND post_postcount = 1
 | |
| 				AND post_visibility = ' . ITEM_APPROVED . '
 | |
| 			GROUP BY poster_id';
 | |
| 		$result = $this->db->sql_query($sql);
 | |
| 
 | |
| 		$postcounts = array();
 | |
| 		while ($row = $this->db->sql_fetchrow($result))
 | |
| 		{
 | |
| 			$postcounts[(int) $row['num_posts']][] = (int) $row['poster_id'];
 | |
| 		}
 | |
| 		$this->db->sql_freeresult($result);
 | |
| 
 | |
| 		// Decrement users post count
 | |
| 		foreach ($postcounts as $num_posts => $poster_ids)
 | |
| 		{
 | |
| 			$sql = 'UPDATE ' . $this->users_table . '
 | |
| 				SET user_posts = 0
 | |
| 				WHERE user_posts < ' . $num_posts . '
 | |
| 					AND ' . $this->db->sql_in_set('user_id', $poster_ids);
 | |
| 			$this->db->sql_query($sql);
 | |
| 
 | |
| 			$sql = 'UPDATE ' . $this->users_table . '
 | |
| 				SET user_posts = user_posts - ' . $num_posts . '
 | |
| 				WHERE user_posts >= ' . $num_posts . '
 | |
| 					AND ' . $this->db->sql_in_set('user_id', $poster_ids);
 | |
| 			$this->db->sql_query($sql);
 | |
| 		}
 | |
| 	}
 | |
| }
 |