diff options
Diffstat (limited to 'phpBB/includes/acp/acp_attachments.php')
| -rw-r--r-- | phpBB/includes/acp/acp_attachments.php | 339 | 
1 files changed, 315 insertions, 24 deletions
| diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php index b32e401e14..39279e63d6 100644 --- a/phpBB/includes/acp/acp_attachments.php +++ b/phpBB/includes/acp/acp_attachments.php @@ -1,10 +1,13 @@  <?php  /**  * -* @package acp -* @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file.  *  */ @@ -16,19 +19,39 @@ if (!defined('IN_PHPBB'))  	exit;  } -/** -* @package acp -*/  class acp_attachments  { -	var $u_action; -	var $new_config; +	/** @var \phpbb\db\driver\driver_interface */ +	protected $db; + +	/** @var \phpbb\config\config */ +	protected $config; + +	/** @var ContainerBuilder */ +	protected $phpbb_container; + +	/** @var \phpbb\template\template */ +	protected $template; + +	/** @var \phpbb\user */ +	protected $user; + +	public $id; +	public $u_action; +	protected $new_config;  	function main($id, $mode)  	{ -		global $db, $user, $auth, $template, $cache; +		global $db, $user, $auth, $template, $cache, $phpbb_container;  		global $config, $phpbb_admin_path, $phpbb_root_path, $phpEx; +		$this->id = $id; +		$this->db = $db; +		$this->config = $config; +		$this->template = $template; +		$this->user = $user; +		$this->phpbb_container = $phpbb_container; +  		$user->add_lang(array('posting', 'viewtopic', 'acp/attachments'));  		$error = $notify = array(); @@ -61,6 +84,10 @@ class acp_attachments  				$l_title = 'ACP_ORPHAN_ATTACHMENTS';  			break; +			case 'manage': +				$l_title = 'ACP_MANAGE_ATTACHMENTS'; +			break; +  			default:  				trigger_error('NO_MODE', E_USER_ERROR);  			break; @@ -95,7 +122,7 @@ class acp_attachments  				}  				$db->sql_freeresult($result); -				$l_legend_cat_images = $user->lang['SETTINGS_CAT_IMAGES'] . ' [' . $user->lang['ASSIGNED_GROUP'] . ': ' . ((!empty($s_assigned_groups[ATTACHMENT_CATEGORY_IMAGE])) ? implode(', ', $s_assigned_groups[ATTACHMENT_CATEGORY_IMAGE]) : $user->lang['NO_EXT_GROUP']) . ']'; +				$l_legend_cat_images = $user->lang['SETTINGS_CAT_IMAGES'] . ' [' . $user->lang['ASSIGNED_GROUP'] . ': ' . ((!empty($s_assigned_groups[ATTACHMENT_CATEGORY_IMAGE])) ? implode($user->lang['COMMA_SEPARATOR'], $s_assigned_groups[ATTACHMENT_CATEGORY_IMAGE]) : $user->lang['NO_EXT_GROUP']) . ']';  				$display_vars = array(  					'title'	=> 'ACP_ATTACHMENT_SETTINGS', @@ -114,22 +141,21 @@ class acp_attachments  						'attachment_quota'		=> array('lang' => 'ATTACH_QUOTA',			'validate' => 'string',	'type' => 'custom', 'method' => 'max_filesize', 'explain' => true),  						'max_filesize'			=> array('lang' => 'ATTACH_MAX_FILESIZE',	'validate' => 'string',	'type' => 'custom', 'method' => 'max_filesize', 'explain' => true),  						'max_filesize_pm'		=> array('lang' => 'ATTACH_MAX_PM_FILESIZE','validate' => 'string',	'type' => 'custom', 'method' => 'max_filesize', 'explain' => true), -						'max_attachments'		=> array('lang' => 'MAX_ATTACHMENTS',		'validate' => 'int',	'type' => 'text:3:3', 'explain' => false), -						'max_attachments_pm'	=> array('lang' => 'MAX_ATTACHMENTS_PM',	'validate' => 'int',	'type' => 'text:3:3', 'explain' => false), +						'max_attachments'		=> array('lang' => 'MAX_ATTACHMENTS',		'validate' => 'int:0:999',	'type' => 'number:0:999', 'explain' => false), +						'max_attachments_pm'	=> array('lang' => 'MAX_ATTACHMENTS_PM',	'validate' => 'int:0:999',	'type' => 'number:0:999', 'explain' => false),  						'secure_downloads'		=> array('lang' => 'SECURE_DOWNLOADS',		'validate' => 'bool',	'type' => 'radio:yes_no', 'explain' => true),  						'secure_allow_deny'		=> array('lang' => 'SECURE_ALLOW_DENY',		'validate' => 'int',	'type' => 'custom', 'method' => 'select_allow_deny', 'explain' => true),  						'secure_allow_empty_referer'	=> array('lang' => 'SECURE_EMPTY_REFERER', 'validate' => 'bool',	'type' => 'radio:yes_no', 'explain' => true),  						'check_attachment_content' 		=> array('lang' => 'CHECK_CONTENT', 'validate' => 'bool',	'type' => 'radio:yes_no', 'explain' => true), -  						'legend2'					=> $l_legend_cat_images,  						'img_display_inlined'		=> array('lang' => 'DISPLAY_INLINED',		'validate' => 'bool',	'type' => 'radio:yes_no', 'explain' => true),  						'img_create_thumbnail'		=> array('lang' => 'CREATE_THUMBNAIL',		'validate' => 'bool',	'type' => 'radio:yes_no', 'explain' => true), -						'img_max_thumb_width'		=> array('lang' => 'MAX_THUMB_WIDTH',		'validate' => 'int',	'type' => 'text:7:15', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), -						'img_min_thumb_filesize'	=> array('lang' => 'MIN_THUMB_FILESIZE',	'validate' => 'int',	'type' => 'text:7:15', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']), +						'img_max_thumb_width'		=> array('lang' => 'MAX_THUMB_WIDTH',		'validate' => 'int:0:999999999999999',	'type' => 'number:0:999999999999999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), +						'img_min_thumb_filesize'	=> array('lang' => 'MIN_THUMB_FILESIZE',	'validate' => 'int:0:999999999999999',	'type' => 'number:0:999999999999999', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']),  						'img_imagick'				=> array('lang' => 'IMAGICK_PATH',			'validate' => 'string',	'type' => 'text:20:200', 'explain' => true, 'append' => '  <span>[ <a href="' . $this->u_action . '&action=imgmagick">' . $user->lang['SEARCH_IMAGICK'] . '</a> ]</span>'), -						'img_max'					=> array('lang' => 'MAX_IMAGE_SIZE',		'validate' => 'int',	'type' => 'dimension:3:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), -						'img_link'					=> array('lang' => 'IMAGE_LINK_SIZE',		'validate' => 'int',	'type' => 'dimension:3:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), +						'img_max'					=> array('lang' => 'MAX_IMAGE_SIZE',		'validate' => 'int:0:9999',	'type' => 'dimension:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), +						'img_link'					=> array('lang' => 'IMAGE_LINK_SIZE',		'validate' => 'int:0:9999',	'type' => 'dimension:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),  					)  				); @@ -745,7 +771,6 @@ class acp_attachments  						}  						$template->assign_vars(array( -							'PHPBB_ROOT_PATH'		=> $phpbb_root_path,  							'IMG_PATH'				=> $img_path,  							'ACTION'				=> $action,  							'GROUP_ID'				=> $group_id, @@ -914,7 +939,7 @@ class acp_attachments  						$db->sql_query($sql);  						add_log('admin', 'LOG_ATTACH_ORPHAN_DEL', implode(', ', $delete_files)); -						$notify[] = sprintf($user->lang['LOG_ATTACH_ORPHAN_DEL'], implode(', ', $delete_files)); +						$notify[] = sprintf($user->lang['LOG_ATTACH_ORPHAN_DEL'], implode($user->lang['COMMA_SEPARATOR'], $delete_files));  					}  					$upload_list = array(); @@ -1043,6 +1068,181 @@ class acp_attachments  				$db->sql_freeresult($result);  			break; + +			case 'manage': + +				if ($submit) +				{ +					$delete_files = (isset($_POST['delete'])) ? array_keys(request_var('delete', array('' => 0))) : array(); + +					if (sizeof($delete_files)) +					{ +						// Select those attachments we want to delete... +						$sql = 'SELECT real_filename +							FROM ' . ATTACHMENTS_TABLE . ' +							WHERE ' . $db->sql_in_set('attach_id', $delete_files) . ' +								AND is_orphan = 0'; +						$result = $db->sql_query($sql); +						while ($row = $db->sql_fetchrow($result)) +						{ +							$deleted_filenames[] = $row['real_filename']; +						} +						$db->sql_freeresult($result); + +						if ($num_deleted = delete_attachments('attach', $delete_files)) +						{ +							if (sizeof($delete_files) != $num_deleted) +							{ +								$error[] = $user->lang['FILES_GONE']; +							} +							add_log('admin', 'LOG_ATTACHMENTS_DELETED', implode(', ', $deleted_filenames)); +							$notify[] = sprintf($user->lang['LOG_ATTACHMENTS_DELETED'], implode($user->lang['COMMA_SEPARATOR'], $deleted_filenames)); +						} +						else +						{ +							$error[] = $user->lang['NO_FILES_TO_DELETE']; +						} +					} +				} + +				if ($action == 'stats') +				{ +					$this->handle_stats_resync(); +				} + +				$stats_error = $this->check_stats_accuracy(); + +				if ($stats_error) +				{ +					$error[] = $stats_error; +				} + +				$template->assign_vars(array( +					'S_MANAGE'		=> true, +				)); + +				$start		= request_var('start', 0); + +				// Sort keys +				$sort_days	= request_var('st', 0); +				$sort_key	= request_var('sk', 't'); +				$sort_dir	= request_var('sd', 'd'); + +				// Sorting +				$limit_days = array(0 => $user->lang['ALL_ENTRIES'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']); +				$sort_by_text = array('f' => $user->lang['FILENAME'], 't' => $user->lang['FILEDATE'], 's' => $user->lang['FILESIZE'], 'x' => $user->lang['EXTENSION'], 'd' => $user->lang['DOWNLOADS'],'p' => $user->lang['ATTACH_POST_TYPE'], 'u' => $user->lang['AUTHOR']); +				$sort_by_sql = array('f' => 'a.real_filename', 't' => 'a.filetime', 's' => 'a.filesize', 'x' => 'a.extension', 'd' => 'a.download_count', 'p' => 'a.in_message', 'u' => 'u.username'); + +				$s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = ''; +				gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param); + +				$min_filetime = ($sort_days) ? (time() - ($sort_days * 86400)) : ''; +				$limit_filetime = ($min_filetime) ? " AND a.filetime >= $min_filetime " : ''; +				$start = ($sort_days && isset($_POST['sort'])) ? 0 : $start; + +				$attachments_per_page = (int) $config['topics_per_page']; + +				$stats = $this->get_attachment_stats($limit_filetime); +				$num_files = $stats['num_files']; +				$total_size = $stats['upload_dir_size']; + +				// Make sure $start is set to the last page if it exceeds the amount +				$pagination = $phpbb_container->get('pagination'); +				$start = $pagination->validate_start($start, $attachments_per_page, $num_files); + +				// If the user is trying to reach the second half of the attachments list, fetch it starting from the end +				$store_reverse = false; +				$sql_limit = $attachments_per_page; + +				if ($start > $num_files / 2) +				{ +					$store_reverse = true; + +					// Select the sort order. Add time sort anchor for non-time sorting cases +					$sql_sort_anchor = ($sort_key != 't') ? ', a.filetime ' . (($sort_dir == 'd') ? 'ASC' : 'DESC') : ''; +					$sql_sort_order = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'ASC' : 'DESC') . $sql_sort_anchor; +					$sql_limit = $pagination->reverse_limit($start, $sql_limit, $num_files); +					$sql_start = $pagination->reverse_start($start, $sql_limit, $num_files); +				} +				else +				{ +					// Select the sort order. Add time sort anchor for non-time sorting cases +					$sql_sort_anchor = ($sort_key != 't') ? ', a.filetime ' . (($sort_dir == 'd') ? 'DESC' : 'ASC') : ''; +					$sql_sort_order = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC') . $sql_sort_anchor; +					$sql_start = $start; +				} + +				$attachments_list = array(); + +				// Just get the files +				$sql = 'SELECT a.*, u.username, u.user_colour, t.topic_title +					FROM ' . ATTACHMENTS_TABLE . ' a +					LEFT JOIN ' . USERS_TABLE . ' u ON (u.user_id = a.poster_id) +					LEFT JOIN ' . TOPICS_TABLE . " t ON (a.topic_id = t.topic_id) +					WHERE a.is_orphan = 0 +						$limit_filetime +					ORDER BY $sql_sort_order"; +				$result = $db->sql_query_limit($sql, $sql_limit, $sql_start); + +				$i = ($store_reverse) ? $sql_limit - 1 : 0; + +				// Store increment value in a variable to save some conditional calls +				$i_increment = ($store_reverse) ? -1 : 1; +				while ($attachment_row = $db->sql_fetchrow($result)) +				{ +					$attachments_list[$i] = $attachment_row; +					$i = $i + $i_increment; +				} +				$db->sql_freeresult($result); + +				$base_url = $this->u_action . "&$u_sort_param"; +				$pagination->generate_template_pagination($base_url, 'pagination', 'start', $num_files, $attachments_per_page, $start); + +				$template->assign_vars(array( +					'TOTAL_FILES'		=> $num_files, +					'TOTAL_SIZE'		=> get_formatted_filesize($total_size), + +					'S_LIMIT_DAYS'		=> $s_limit_days, +					'S_SORT_KEY'		=> $s_sort_key, +					'S_SORT_DIR'		=> $s_sort_dir) +				); + +				// Grab extensions +				$extensions = $cache->obtain_attach_extensions(true); + +				for ($i = 0, $end = sizeof($attachments_list); $i < $end; ++$i) +				{ +					$row = $attachments_list[$i]; + +					$row['extension'] = strtolower(trim((string) $row['extension'])); +					$comment = ($row['attach_comment'] && !$row['in_message']) ? str_replace(array("\n", "\r"), array('<br />', "\n"), $row['attach_comment']) : ''; +					$display_cat = $extensions[$row['extension']]['display_cat']; +					$l_downloaded_viewed = ($display_cat == ATTACHMENT_CATEGORY_NONE) ? 'DOWNLOAD_COUNTS' : 'VIEWED_COUNTS'; + +					$template->assign_block_vars('attachments', array( +						'ATTACHMENT_POSTER'	=> get_username_string('full', (int) $row['poster_id'], (string) $row['username'], (string) $row['user_colour'], (string) $row['username']), +						'FILESIZE'			=> get_formatted_filesize((int) $row['filesize']), +						'FILETIME'			=> $user->format_date((int) $row['filetime']), +						'REAL_FILENAME'		=> (!$row['in_message']) ? utf8_basename((string) $row['real_filename']) : '', +						'PHYSICAL_FILENAME'	=> utf8_basename((string) $row['physical_filename']), +						'EXT_GROUP_NAME'	=> (!empty($extensions[$row['extension']]['group_name'])) ? $user->lang['EXT_GROUP_' . $extensions[$row['extension']]['group_name']] : '', +						'COMMENT'			=> $comment, +						'TOPIC_TITLE'		=> (!$row['in_message']) ? (string) $row['topic_title'] : '', +						'ATTACH_ID'			=> (int) $row['attach_id'], +						'POST_ID'			=> (int) $row['post_msg_id'], +						'TOPIC_ID'			=> (int) $row['topic_id'], +						'POST_IDS'			=> (!empty($post_ids[$row['attach_id']])) ? (int) $post_ids[$row['attach_id']] : '', + +						'L_DOWNLOAD_COUNT'	=> $user->lang($l_downloaded_viewed, (int) $row['download_count']), + +						'S_IN_MESSAGE'		=> (bool) $row['in_message'], + +						'U_VIEW_TOPIC'		=> append_sid("{$phpbb_root_path}viewtopic.$phpEx", "t={$row['topic_id']}&p={$row['post_msg_id']}") . "#p{$row['post_msg_id']}", +						'U_FILE'			=> append_sid($phpbb_root_path . 'download/file.' . $phpEx, 'mode=view&id=' . $row['attach_id'])) +					); +				} + +			break;  		}  		if (sizeof($error)) @@ -1063,6 +1263,97 @@ class acp_attachments  	}  	/** +	* Get attachment file count and size of upload directory +	* +	* @param $limit string	Additional limit for WHERE clause to filter stats by. +	* @return array Returns array with stats: num_files and upload_dir_size +	*/ +	public function get_attachment_stats($limit = '') +	{ +		$sql = 'SELECT COUNT(a.attach_id) AS num_files, SUM(a.filesize) AS upload_dir_size +			FROM ' . ATTACHMENTS_TABLE . " a +			WHERE a.is_orphan = 0 +				$limit"; +		$result = $this->db->sql_query($sql); +		$row = $this->db->sql_fetchrow($result); +		$this->db->sql_freeresult($result); + +		return array( +			'num_files'			=> (int) $row['num_files'], +			'upload_dir_size'	=> (float) $row['upload_dir_size'], +		); +	} + +	/** +	* Set config attachment stat values +	* +	* @param $stats array	Array of config key => value pairs to set. +	* @return null +	*/ +	public function set_attachment_stats($stats) +	{ +		foreach ($stats as $key => $value) +		{ +			$this->config->set($key, $value, true); +		} +	} + +	/** +	* Check accuracy of attachment statistics. +	* +	* @param $resync bool	Resync stats if they're incorrect. +	* @return bool|string	Returns false if stats are correct or error message +	*	otherwise. +	*/ +	public function check_stats_accuracy() +	{ +		// Get fresh stats. +		$stats = $this->get_attachment_stats(); + +		// Get current files stats +		$num_files = (int) $this->config['num_files']; +		$total_size = (float) $this->config['upload_dir_size']; + +		if (($num_files != $stats['num_files']) || ($total_size != $stats['upload_dir_size'])) +		{ +			$u_resync = $this->u_action . '&action=stats'; + +			return $this->user->lang( +				'FILES_STATS_WRONG', +				(int) $stats['num_files'], +				get_formatted_filesize($stats['upload_dir_size']), +				'<a href="' . $u_resync . '">', +				'</a>' +			); +		} +		return false; +	} + +	/** +	* Handle stats resync. +	* +	* @return null +	*/ +	public function handle_stats_resync() +	{ +		if (!confirm_box(true)) +		{ +			confirm_box(false, $this->user->lang['RESYNC_FILES_STATS_CONFIRM'], build_hidden_fields(array( +				'i'			=> $this->id, +				'mode'		=> 'manage', +				'action'	=> 'stats', +			))); +		} +		else +		{ +			$this->set_attachment_stats($this->get_attachment_stats()); +			$log = $this->phpbb_container->get('log'); +			$log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_RESYNC_FILES_STATS'); +		} + +	} + +	/**  	* Build Select for category items  	*/  	function category_select($select_name, $group_id = false, $key = '') @@ -1235,6 +1526,7 @@ class acp_attachments  	function perform_site_list()  	{  		global $db, $user; +		global $request;  		if (isset($_REQUEST['securesubmit']))  		{ @@ -1243,7 +1535,7 @@ class acp_attachments  			$ip_list = array_unique(explode("\n", $ips));  			$ip_list_log = implode(', ', $ip_list); -			$ip_exclude = (!empty($_POST['ipexclude'])) ? 1 : 0; +			$ip_exclude = (int) $request->variable('ipexclude', false, false, \phpbb\request\request_interface::POST);  			$iplist = array();  			$hostlist = array(); @@ -1441,7 +1733,8 @@ class acp_attachments  		$size_var = $filesize['si_identifier'];  		$value = $filesize['value']; -		return '<input type="text" id="' . $key . '" size="8" maxlength="15" name="config[' . $key . ']" value="' . $value . '" /> <select name="' . $key . '">' . size_select_options($size_var) . '</select>'; +		// size="8" and maxlength="15" attributes as a fallback for browsers that do not support type="number" yet. +		return '<input type="number" id="' . $key . '" size="8" maxlength="15" min="0" name="config[' . $key . ']" value="' . $value . '" /> <select name="' . $key . '">' . size_select_options($size_var) . '</select>';  	}  	/** @@ -1455,5 +1748,3 @@ class acp_attachments  	}  } - -?>
\ No newline at end of file | 
