소스 검색

First commit adding Ema's auto manage attachment folders mod into the changes I've made to the attachments system.

Kays48 12 년 전
부모
커밋
6cbb267907

+ 109 - 8
Sources/ManageAttachments.php

@@ -78,7 +78,7 @@ function ManageAttachments()
 /**
  * Allows to show/change attachment settings.
  * This is the default sub-action of the 'Attachments and Avatars' center.
- * Called by index.php?action=admin;area=manageattachments;sa=attachements.
+ * Called by index.php?action=admin;area=manageattachments;sa=attachments.
  *
  * @param bool $return_config = false
  * @uses 'attachments' sub template.
@@ -88,12 +88,41 @@ function ManageAttachmentSettings($return_config = false)
 {
 	global $txt, $modSettings, $scripturl, $context, $options, $sourcedir;
 
-	$context['valid_upload_dir'] = is_dir($modSettings['attachmentUploadDir']) && is_writable($modSettings['attachmentUploadDir']);
+	require_once($sourcedir . '/Attachments.php');
+
+	// Get the current attachment directory.
+	if (!empty($modSettings['currentAttachmentUploadDir']))
+	{
+		if (!is_array($modSettings['attachmentUploadDir']))
+			$modSettings['attachmentUploadDir'] = unserialize($modSettings['attachmentUploadDir']);
+		$context['attachmentUploadDir'] = $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']];
+	}
+	else
+		$context['attachmentUploadDir'] = $modSettings['attachmentUploadDir'];
+
+	// If not set, show a default path for the base directory
+	if (!isset($_GET['save']) && empty($modSettings['basedirectory_for_attachments']))
+		if (!empty($modSettings['currentAttachmentUploadDir']))
+			$modSettings['basedirectory_for_attachments'] = $modSettings['attachmentUploadDir'][1];
+		else
+			$modSettings['basedirectory_for_attachments'] = $context['attachmentUploadDir'];
+
+	if (!empty($modSettings['automanage_attachments']))
+		automanage_attachments_check_directory();
+
+	$context['valid_upload_dir'] = is_dir($context['attachmentUploadDir']) && is_writable($context['attachmentUploadDir']);
+
+	if (!empty($modSettings['automanage_attachments']))
+		$context['valid_basedirectory'] =  !empty($modSettings['basedirectory_for_attachments']) && is_writable($modSettings['basedirectory_for_attachments']);
+	else
+		$context['valid_basedirectory'] = true;
+
+	$txt['attachmentUploadDir_multiple_configure'] = '<a href="' . $scripturl . '?action=admin;area=manageattachments;sa=attachpaths">[' . $txt['attachmentUploadDir_multiple_configure'] . ']</a>';
+	$txt['basedirectory_for_attachments_warning'] = $txt['basedirectory_for_attachments'] . $txt['basedirectory_for_attachments_warning'];
 
 	// Perform a test to see if the GD module or ImageMagick are installed.
 	$testImg = get_extension_funcs('gd') || class_exists('Imagick');
-	$txt['attachmentUploadDir_multiple_configure'] = '<a href="' . $scripturl . '?action=admin;area=manageattachments;sa=attachpaths">[' . $txt['attachmentUploadDir_multiple_configure'] . ']</a>';
-	
+
 	// See if we can find if the server is set up to support the attacment limits
 	$post_max_size = ini_get('post_max_size');
 	$upload_max_filesize = ini_get('upload_max_filesize');
@@ -109,15 +138,21 @@ function ManageAttachmentSettings($return_config = false)
 			array('check', 'attachmentRecodeLineEndings'),
 		'',
 			// Directory and size limits.
-			empty($modSettings['currentAttachmentUploadDir']) ? array('text', 'attachmentUploadDir', 'subtext' => $txt['attachmentUploadDir_multiple_configure'], 40, 'invalid' => !$context['valid_upload_dir']) : array('var_message', 'attachmentUploadDir_multiple', 'message' => 'attachmentUploadDir_multiple_configure'),
+			array('select', 'automanage_attachments', array(0 => $txt['attachments_normal'], 1 => $txt['attachments_auto_space'], 2 => $txt['attachments_auto_years'], 3 => $txt['attachments_auto_months'], 4 => $txt['attachments_auto_16'], 5 => $txt['attachments_auto_16x16'])),
+			array('text', 'basedirectory_for_attachments', 40, 'invalid' => empty($context['valid_basedirectory']),	'text_label' => (!empty($context['valid_basedirectory']) ? $txt['basedirectory_for_attachments'] : $txt['basedirectory_for_attachments_warning'])),
+			array('check', 'use_subdirectories_for_attachments', 'subtext' => $txt['use_subdirectories_for_attachments_note']),
+			(empty($modSettings['currentAttachmentUploadDir'])) ? array('text', 'attachmentUploadDir', 40, 'invalid' => !$context['valid_upload_dir']) : array('var_message', 'attachmentUploadDir_multiple', 'message' =>  'attachmentUploadDir_multiple_configure'),
+			array('int', 'attachmentDirFileLimit', 'subtext' => $txt['zero_for_no_limit'], 6),
 			array('int', 'attachmentDirSizeLimit', 'subtext' => $txt['zero_for_no_limit'], 6, 'postinput' => $txt['kilobyte']),
+		'',
+			// Posting limits
 			array('int', 'attachmentPostLimit', 'subtext' => $txt['zero_for_no_limit'], 6, 'postinput' => $txt['kilobyte']),
 			array('warning', empty($testPM) ? 'attachment_postsize_warning' : ''),
 			array('int', 'attachmentSizeLimit', 'subtext' => $txt['zero_for_no_limit'], 6, 'postinput' => $txt['kilobyte']),
 			array('warning', empty($testUM) ? 'attachment_filesize_warning' : ''),
 			array('int', 'attachmentNumPerPostLimit', 'subtext' => $txt['zero_for_no_limit'], 6),
 			// Security Items
-		array('title', 'attachment_security_settings'),
+			array('title', 'attachment_security_settings'),
 			// Extension checks etc.
 			array('check', 'attachmentCheckExtensions'),
 			array('text', 'attachmentExtensions', 40),
@@ -139,6 +174,40 @@ function ManageAttachmentSettings($return_config = false)
 			array('text', 'attachmentThumbHeight', 6),
 	);
 
+	$context['settings_post_javascript'] = '
+	var storing_type = document.getElementById(\'automanage_attachments\');
+	var base_dir = document.getElementById(\'use_subdirectories_for_attachments\');
+
+	mod_addEvent(storing_type, \'change\', mod_toggleSubDir);
+	mod_addEvent(base_dir, \'change\', mod_toggleBaseDir);
+	mod_toggleSubDir();
+
+	function mod_addEvent(control, ev, fn){
+		if (control.addEventListener){
+			control.addEventListener(ev, fn, false);
+		} else if (control.attachEvent){
+			control.attachEvent(\'on\'+ev, fn);
+		}
+	}
+
+	function mod_toggleSubDir(){
+		var select_elem = document.getElementById(\'automanage_attachments\');
+		var use_sub_dir = document.getElementById(\'use_subdirectories_for_attachments\');
+
+		use_sub_dir.disabled = !Boolean(select_elem.selectedIndex);
+		mod_toggleBaseDir();
+	}
+	function mod_toggleBaseDir(){
+		var select_elem = document.getElementById(\'automanage_attachments\');
+		var sub_dir = document.getElementById(\'use_subdirectories_for_attachments\');
+		var dir_elem = document.getElementById(\'basedirectory_for_attachments\');
+		if(select_elem.selectedIndex==0){
+			dir_elem.disabled = 1;
+		} else {
+			dir_elem.disabled = !sub_dir.checked;
+		}
+	}';
+
 	call_integration_hook('integrate_modify_attachment_settings', array(&$config_vars));
 
 	if ($return_config)
@@ -153,6 +222,37 @@ function ManageAttachmentSettings($return_config = false)
 	{
 		checkSession();
 
+		// Is this needed now ???
+		if(isset($_POST['use_subdirectories_for_attachments']) && empty($_POST['basedirectory_for_attachments']))
+			$_POST['basedirectory_for_attachments'] = (!empty($modSettings['use_subdirectories_for_attachments']) ? ($modSettings['basedirectory_for_attachments']) : $boarddir);
+
+		// @Todo add "basedirectory_for_attachments" to install & upgrade scripts
+		if (!isset($modSettings['basedirectory_for_attachments']))
+			$modSettings['basedirectory_for_attachments'] = '';
+
+		// Create a new base directory if that's being changed and not there.
+		if (!empty($_POST['basedirectory_for_attachments']) && !is_dir($_POST['basedirectory_for_attachments']))
+		{
+			if (!automanage_attachments_create_directory($_POST['basedirectory_for_attachments'], true))
+				// Some sort of an error here also maybe??
+				$_POST['basedirectory_for_attachments'] = $modSettings['basedirectory_for_attachments'];
+		}
+
+		// Build an array of knowm base directories.
+		if (empty($modSettings['attachment_basedirectories']))
+			$modSettings['attachment_basedirectories'] = array();
+		else
+			$modSettings['attachment_basedirectories'] = unserialize($modSettings['attachment_basedirectories']);
+
+		if (!in_array($_POST['basedirectory_for_attachments'], $modSettings['attachment_basedirectories']))
+		{
+			$modSettings['attachment_basedirectories'][] = $_POST['basedirectory_for_attachments'];
+			updateSettings(array(
+				'attachment_basedirectories' => serialize($modSettings['attachment_basedirectories']),
+			));
+		}
+
+
 		call_integration_hook('integrate_save_attachment_settings');
 
 		saveDBSettings($config_vars);
@@ -1874,7 +1974,7 @@ function ManageAttachmentPaths()
 				),
 				'data' => array(
 					'function' => create_function('$rowData', '
-						return \'<input type="radio" name="current_dir" value="\' . $rowData[\'id\'] . \'" \' . ($rowData[\'current\'] ? \'checked="checked"\' : \'\') . \' class="input_radio" />\';
+						return \'<input type="radio" name="current_dir" value="\' . $rowData[\'id\'] . \'" \' . ($rowData[\'current\'] ? \' checked="checked"\' : \'\') . ($rowData[\'automanage_attachments\'] ? \' disabled="disabled""\' : \'\') . \' class="input_radio" />\';
 					'),
 					'style' => 'text-align: center; width: 15%;',
 				),
@@ -1885,7 +1985,7 @@ function ManageAttachmentPaths()
 				),
 				'data' => array(
 					'function' => create_function('$rowData', '
-						return \'<input type="text" size="30" name="dirs[\' . $rowData[\'id\'] . \']" value="\' . $rowData[\'path\'] . \'" class="input_text" style="width: 100%" />\';
+						return \'<input type="text" size="40" name="dirs[\' . $rowData[\'id\'] . \']" value="\' . $rowData[\'path\'] . \'" class="input_text" style="width: 100%" />\';
 					'),
 					'style' => 'text-align: center; width: 30%;',
 				),
@@ -1978,6 +2078,7 @@ function list_getAttachDirs()
 		$attachdirs[] = array(
 			'id' => $id,
 			'current' => $id == $modSettings['currentAttachmentUploadDir'],
+			'automanage_attachments' => isset($modSettings['automanage_attachments']) && $modSettings['automanage_attachments'] > 1 ? true : false,
 			'path' => $dir,
 			'current_size' => $size,
 			'num_files' => $expected_files[$id],

+ 12 - 190
Sources/Post.php

@@ -546,7 +546,7 @@ function Post()
 			// Do all bulletin board code tags, with or without smileys.
 			$context['preview_message'] = parse_bbc($context['preview_message'], isset($_REQUEST['ns']) ? 0 : 1);
 			censorText($context['preview_message']);
-			
+
 			if ($form_subject != '')
 			{
 				$context['preview_subject'] = $form_subject;
@@ -632,7 +632,7 @@ function Post()
 						'attachment_type' => 0,
 					)
 				);
-				
+
 				while ($row = $smcFunc['db_fetch_assoc']($request))
 				{
 					if ($row['filesize'] <= 0)
@@ -742,7 +742,7 @@ function Post()
 		// Show an "approve" box if the user can approve it, and the message isn't approved.
 		if (!$row['approved'] && !$context['show_approval'])
 			$context['show_approval'] = allowedTo('approve_posts');
-		
+
 		// Sort the attachments so they are in the order saved
 		$temp = array();
 		foreach ($attachment_stuff as $attachment)
@@ -752,7 +752,7 @@ function Post()
 
 		}
 		ksort($temp);
-		
+
 		// Load up 'em attachments!
 		foreach ($temp as $attachment)
 		{
@@ -1100,12 +1100,12 @@ function Post()
 
 	if (!empty($context['icons']))
 		$context['icons'][count($context['icons']) - 1]['is_last'] = true;
-	
+
 	// Are we starting a poll? if set the poll icon as selected if its available
 	if (isset($_REQUEST['poll']))
 	{
 	    foreach ($context['icons'] as $icons)
-		{  
+		{
 			if (isset($icons['value']) && $icons['value'] == 'poll')
 			{
 				// if found we are done
@@ -1315,189 +1315,10 @@ function Post2()
 	$context['can_post_attachment'] = !empty($modSettings['attachmentEnable']) && $modSettings['attachmentEnable'] == 1 && (allowedTo('post_attachment') || ($modSettings['postmod_active'] && allowedTo('post_unapproved_attachments')));
 	if ($context['can_post_attachment'] && !empty($_FILES['attachment']) && empty($_POST['from_qr']))
 	{
-		// Make sure we're uploading to the right place.
-		if (!empty($modSettings['currentAttachmentUploadDir']))
-		{
-			if (!is_array($modSettings['attachmentUploadDir']))
-				$modSettings['attachmentUploadDir'] = unserialize($modSettings['attachmentUploadDir']);
-			// The current directory, of course!
-			$context['attach_dir'] = $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']];
-		}
-		else
-			$context['attach_dir'] = $modSettings['attachmentUploadDir'];
-
-		// Is the attachments folder actualy there?
-		if (!is_dir($context['attach_dir']))
-		{
-			$initial_error = 'attach_folder_warning';
-			log_error(sprintf($txt['attach_folder_admin_warning'], $context['attach_dir']), 'critical');
-		}
-
-		// Check that the attachments folder is writable. No sense in proceeding if it isn't.
-		if (empty($initial_error) && !is_writable($context['attach_dir']))
-		{
-			// But, let's try to make it writable first.
-			chmod($context['attach_dir'], 0755);
-			if (!is_writable($context['attach_dir']))
-			{
-				chmod($context['attach_dir'], 0775);
-				if (!is_writable($context['attach_dir']))
-				{
-					chmod($context['attach_dir'], 0777);
-					if (!is_writable($context['attach_dir']))
-						$initial_error = 'attachments_no_write';
-				}
-			}
-		}
-
-		if (!isset($initial_error) && !isset($context['attachments']))
-		{
-			// If this isn't a new post, check the current attachments.
-			if (isset($_REQUEST['msg']))
-			{
-				$request = $smcFunc['db_query']('', '
-					SELECT COUNT(*), SUM(size)
-					FROM {db_prefix}attachments
-					WHERE id_msg = {int:id_msg}
-						AND attachment_type = {int:attachment_type}',
-					array(
-						'id_msg' => (int) $_REQUEST['msg'],
-						'attachment_type' => 0,
-					)
-				);
-				list ($context['attachments']['quantity'], $context['attachments']['total_size']) = $smcFunc['db_fetch_row']($request);
-				$smcFunc['db_free_result']($request);
-			}
-			else
-				$context['attachments'] = array(
-					'quantity' => 0,
-					'total_size' => 0,
-				);
-		}
-
-		// Hmm. There are still files in session.
-		$ignore_temp = false;
-		if (!empty($_SESSION['temp_attachments']['post']['files']) && count($_SESSION['temp_attachments']) > 1)
-		{
-			// Let's try to keep them. But...
-			$ignore_temp = true;
-			// If new files are being added. We can't ignore those
-			foreach ($_FILES['attachment']['tmp_name'] as $dummy)
-				if (!empty($dummy))
-				{
-					$ignore_temp = false;
-					break;
-				}
-
-			// Need to make space for the new files. So, bye bye.
-			if (!$ignore_temp)
-			{
-				foreach ($_SESSION['temp_attachments'] as $attachID => $attachment)
-					if (strpos($attachID, 'post_tmp_' . $user_info['id']) !== false)
-						unlink($attachment['tmp_name']);
-
-				$context['we_are_history'] = $txt['error_temp_attachments_flushed'];
-				$_SESSION['temp_attachments'] = array();
-			}
-		}
-
-		if (!isset($_FILES['attachment']['name']))
-			$_FILES['attachment']['tmp_name'] = array();
-
-		if (!isset($_SESSION['temp_attachments']))
-			$_SESSION['temp_attachments'] = array();
-
-		// Remember where we are at. If it's anywhere at all.
-		if (!$ignore_temp)
-			$_SESSION['temp_attachments']['post'] = array(
-				'msg' => !empty($_REQUEST['msg']) ? $_REQUEST['msg'] : 0,
-				'last_msg' => !empty($_REQUEST['last_msg']) ? $_REQUEST['last_msg'] : 0,
-				'topic' => !empty($topic) ? $topic : 0,
-				'board' => !empty($board) ? $board : 0,
-			);
-
-		// If we have an itital error, lets just display it.
-		if (!empty($initial_error))
-		{
-			$_SESSION['temp_attachments']['initial_error'] = $initial_error;
-
-			// And delete the files 'cos they ain't going nowhere.
-			foreach ($_FILES['attachment']['tmp_name'] as $n => $dummy)
-				if (file_exists($_FILES['attachment']['tmp_name'][$n]))
-					unlink($_FILES['attachment']['tmp_name'][$n]);
-
-			$_FILES['attachment']['tmp_name'] = array();
-		}
-
-		// Loop through $_FILES['attachment'] array and move each file to the current attachments folder.
-		foreach ($_FILES['attachment']['tmp_name'] as $n => $dummy)
-		{
-			if ($_FILES['attachment']['name'][$n] == '')
-				continue;
-
-			// First, let's first check for PHP upload errors.
-			$errors = array();
-			if (!empty($_FILES['attachment']['error'][$n]))
-			{
-				if ($_FILES['attachment']['error'][$n] == 2)
-					$errors[] = array('file_too_big', array($modSettings['attachmentSizeLimit']));
-				elseif ($_FILES['attachment']['error'][$n] == 6)
-					log_error($_FILES['attachment']['name'][$n] . ': ' . $txt['php_upload_error_6'], 'critical');
-				else
-					log_error($_FILES['attachment']['name'][$n] . ': ' . $txt['php_upload_error_' . $_FILES['attachment']['error'][$n]]);
-				if (empty($errors))
-					$errors[] = 'attach_php_error';
-			}
-
-			// Try to move and rename the file before doing any more checks on it.
-			$attachID = 'post_tmp_' . $user_info['id'] . '_' . md5(mt_rand());
-			$destName = $context['attach_dir'] . '/' . $attachID;
-			if (empty($errors))
-			{
-				$_SESSION['temp_attachments'][$attachID] = array(
-					'name' => htmlspecialchars(basename($_FILES['attachment']['name'][$n])),
-					'tmp_name' => $destName,
-					'size' => $_FILES['attachment']['size'][$n],
-					'type' => $_FILES['attachment']['type'][$n],
-					'errors' => array(),
-				);
-
-				// Move the file to the attachments folder with a temp name for now.
-				if (@move_uploaded_file($_FILES['attachment']['tmp_name'][$n], $destName))
-					@chmod($destName, 0644);
-				else
-				{
-					$_SESSION['temp_attachments'][$attachID]['errors'][] = 'attach_timeout';
-					if (file_exists($_FILES['attachment']['tmp_name'][$n]))
-						unlink($_FILES['attachment']['tmp_name'][$n]);
-				}
-			}
-			else
-			{
-				$_SESSION['temp_attachments'][$attachID] = array(
-					'name' => htmlspecialchars(basename($_FILES['attachment']['name'][$n])),
-					'tmp_name' => $destName,
-					'errors' => $errors,
-				);
+		 require_once($sourcedir . '/Attachments.php');
+		 processAttachments();
+	}
 
-				if (file_exists($_FILES['attachment']['tmp_name'][$n]))
-					unlink($_FILES['attachment']['tmp_name'][$n]);
-			}
-			// If there's no errors to this pont. We still do need to apply some addtional checks before we are finished.
-			if (empty($_SESSION['temp_attachments'][$attachID]['errors']))
-				attachmentChecks($attachID);
-		}
-	}
-	// Mod authors, finally a hook to hang an alternate attachment upload system upon
-	// Upload to the current attachment folder with the file name $attachID or 'post_tmp_' . $user_info['id'] . '_' . md5(mt_rand())
-	// Populate $_SESSION['temp_attachments'][$attachID] with the following:
-	//   name => The file name
-	//   tmp_name => Path to the temp file ($context['attach_dir'] . '/' . $attachID).
-	//   size => File size (required).
-	//   type => MIME type (optional if not available on upload).
-	//   errors => An array of errors (use the index of the $txt variable for that error).
-	// Template changes can be done using "integrate_upload_template".
-	call_integration_hook('integrate_attachment_upload', array());
 
 	// If this isn't a new topic load the topic info that we need.
 	if (!empty($topic))
@@ -1926,6 +1747,7 @@ function Post2()
 				'tmp_name' => $attachment['tmp_name'],
 				'size' => isset($attachment['size']) ? $attachment['size'] : 0,
 				'mime_type' => isset($attachment['type']) ? $attachment['type'] : '',
+				'id_folder' => $attachment['id_folder'],
 				'approved' => !$modSettings['postmod_active'] || allowedTo('post_attachment'),
 				'errors' => $attachment['errors'],
 			);
@@ -1949,7 +1771,7 @@ function Post2()
 
 				// Sort out the errors for display and delete any associated files.
 				$attach_errors[] = '<dt>' . vsprintf($txt['attach_warning'], $attachment['name']) . '</dt>';
-				$log_these = array('attachments_no_write', 'attach_timeout', 'ran_out_of_space', 'cant_access_upload_path', 'attach_0_byte_file');
+				$log_these = array('attachments_no_create', 'attachments_no_write', 'attach_timeout', 'ran_out_of_space', 'cant_access_upload_path', 'attach_0_byte_file');
 				foreach ($attachmentOptions['errors'] as $error)
 				{
 					if (!is_array($error))
@@ -2001,7 +1823,7 @@ function Post2()
 			$pollOptions,
 			array('id_poll', 'id_choice')
 		);
-		
+
 		call_integration_hook('integrate_poll_add_edit', array($id_poll, false));
 	}
 	else

+ 1 - 303
Sources/Subs-Post.php

@@ -2089,308 +2089,6 @@ function createPost(&$msgOptions, &$topicOptions, &$posterOptions)
 	return true;
 }
 
-/**
- * Create an attachment, with the given array of parameters.
- * - Adds any addtional or missing parameters to $attachmentOptions.
- * - Renames the temporary file.
- * - Creates a thumbnail if the file is an image and the option enabled.
- *
- * @param array $attachmentOptions
- */
-function createAttachment(&$attachmentOptions)
-{
-	global $modSettings, $sourcedir, $smcFunc, $context;
-	global $txt, $boarddir;
-
-	require_once($sourcedir . '/Subs-Graphics.php');
-
-	if (!empty($modSettings['currentAttachmentUploadDir']))
-		$id_folder = $modSettings['currentAttachmentUploadDir'];
-	else
-		$id_folder = 1;
-
-	// These are the only valid image types for SMF.
-	$validImageTypes = array(
-		1 => 'gif',
-		2 => 'jpeg',
-		3 => 'png',
-		5 => 'psd',
-		6 => 'bmp',
-		7 => 'tiff',
-		8 => 'tiff',
-		9 => 'jpeg',
-		14 => 'iff'
-	);
-
-	// If this is an image we need to set a few additional parameters.
-	$size = @getimagesize($attachmentOptions['tmp_name']);
-	list ($attachmentOptions['width'], $attachmentOptions['height']) = $size;
-
-	// If it's an image get the mime type right.
-	if (empty($attachmentOptions['mime_type']) && $attachmentOptions['width'])
-	{
-		// Got a proper mime type?
-		if (!empty($size['mime']))
-			$attachmentOptions['mime_type'] = $size['mime'];
-		// Otherwise a valid one?
-		elseif (isset($validImageTypes[$size[2]]))
-			$attachmentOptions['mime_type'] = 'image/' . $validImageTypes[$size[2]];
-	}
-
-	// Get the hash if no hash has been given yet.
-	if (empty($attachmentOptions['file_hash']))
-		$attachmentOptions['file_hash'] = getAttachmentFilename($attachmentOptions['name'], false, null, true);
-
-	// Assuming no-one set the extension let's take a look at it.
-	if (empty($attachmentOptions['fileext']))
-	{
-		$attachmentOptions['fileext'] = strtolower(strrpos($attachmentOptions['name'], '.') !== false ? substr($attachmentOptions['name'], strrpos($attachmentOptions['name'], '.') + 1) : '');
-		if (strlen($attachmentOptions['fileext']) > 8 || '.' . $attachmentOptions['fileext'] == $attachmentOptions['name'])
-			$attachmentOptions['fileext'] = '';
-	}
-
-	$smcFunc['db_insert']('',
-		'{db_prefix}attachments',
-		array(
-			'id_folder' => 'int', 'id_msg' => 'int', 'filename' => 'string-255', 'file_hash' => 'string-40', 'fileext' => 'string-8',
-			'size' => 'int', 'width' => 'int', 'height' => 'int',
-			'mime_type' => 'string-20', 'approved' => 'int',
-		),
-		array(
-			$id_folder, (int) $attachmentOptions['post'], $attachmentOptions['name'], $attachmentOptions['file_hash'], $attachmentOptions['fileext'],
-			(int) $attachmentOptions['size'], (empty($attachmentOptions['width']) ? 0 : (int) $attachmentOptions['width']), (empty($attachmentOptions['height']) ? '0' : (int) $attachmentOptions['height']),
-			(!empty($attachmentOptions['mime_type']) ? $attachmentOptions['mime_type'] : ''), (int) $attachmentOptions['approved'],
-		),
-		array('id_attach')
-	);
-	$attachmentOptions['id'] = $smcFunc['db_insert_id']('{db_prefix}attachments', 'id_attach');
-
-	// @todo Add an error here maybe?
-	if (empty($attachmentOptions['id']))
-		return false;
-
-	// Now that we have the attach id, let's rename this sucker and finish up.
-	$attachmentOptions['destination'] = getAttachmentFilename(basename($attachmentOptions['name']), $attachmentOptions['id'], $id_folder, false, $attachmentOptions['file_hash']);
-	rename($attachmentOptions['tmp_name'], $attachmentOptions['destination']);
-
-	// If it's not approved then add to the approval queue.
-	if (!$attachmentOptions['approved'])
-		$smcFunc['db_insert']('',
-			'{db_prefix}approval_queue',
-			array(
-				'id_attach' => 'int', 'id_msg' => 'int',
-			),
-			array(
-				$attachmentOptions['id'], (int) $attachmentOptions['post'],
-			),
-			array()
-		);
-
-	if (empty($modSettings['attachmentThumbnails']) || (empty($attachmentOptions['width']) && empty($attachmentOptions['height'])))
-		return true;
-
-	// Like thumbnails, do we?
-	if (!empty($modSettings['attachmentThumbWidth']) && !empty($modSettings['attachmentThumbHeight']) && ($attachmentOptions['width'] > $modSettings['attachmentThumbWidth'] || $attachmentOptions['height'] > $modSettings['attachmentThumbHeight']))
-	{
-		if (createThumbnail($attachmentOptions['destination'], $modSettings['attachmentThumbWidth'], $modSettings['attachmentThumbHeight']))
-		{
-			// Figure out how big we actually made it.
-			$size = @getimagesize($attachmentOptions['destination'] . '_thumb');
-			list ($thumb_width, $thumb_height) = $size;
-
-			if (!empty($size['mime']))
-				$thumb_mime = $size['mime'];
-			elseif (isset($validImageTypes[$size[2]]))
-				$thumb_mime = 'image/' . $validImageTypes[$size[2]];
-			// Lord only knows how this happened...
-			else
-				$thumb_mime = '';
-
-			$thumb_filename = $attachmentOptions['name'] . '_thumb';
-			$thumb_size = filesize($attachmentOptions['destination'] . '_thumb');
-			$thumb_file_hash = getAttachmentFilename($thumb_filename, false, null, true);
-
-			// To the database we go!
-			$smcFunc['db_insert']('',
-				'{db_prefix}attachments',
-				array(
-					'id_folder' => 'int', 'id_msg' => 'int', 'attachment_type' => 'int', 'filename' => 'string-255', 'file_hash' => 'string-40', 'fileext' => 'string-8',
-					'size' => 'int', 'width' => 'int', 'height' => 'int', 'mime_type' => 'string-20', 'approved' => 'int',
-				),
-				array(
-					$id_folder, (int) $attachmentOptions['post'], 3, $thumb_filename, $thumb_file_hash, $attachmentOptions['fileext'],
-					$thumb_size, $thumb_width, $thumb_height, $thumb_mime, (int) $attachmentOptions['approved'],
-				),
-				array('id_attach')
-			);
-			$attachmentOptions['thumb'] = $smcFunc['db_insert_id']('{db_prefix}attachments', 'id_attach');
-
-			if (!empty($attachmentOptions['thumb']))
-			{
-				$smcFunc['db_query']('', '
-					UPDATE {db_prefix}attachments
-					SET id_thumb = {int:id_thumb}
-					WHERE id_attach = {int:id_attach}',
-					array(
-						'id_thumb' => $attachmentOptions['thumb'],
-						'id_attach' => $attachmentOptions['id'],
-					)
-				);
-
-				rename($attachmentOptions['destination'] . '_thumb', getAttachmentFilename($thumb_filename, $attachmentOptions['thumb'], $id_folder, false, $thumb_file_hash));
-			}
-		}
-	}
-	return true;
-}
-
-/**
- * Performs various checks on an uploaded file.
- * - Requires that $_SESSION['temp_attachments'][$attachID] be properly populated.
- *
- * @param $attachID
- */
-function attachmentChecks($attachID)
-{
-	global $modSettings, $context, $sourcedir, $smcFunc;
-
-	// No data or missing data .... Not necessarily needed, but in case a mod author missed something.
-	if ( empty($_SESSION['temp_attachments'][$attachID]))
-		$errror = '$_SESSION[\'temp_attachments\'][$attachID]';
-	elseif (empty($attachID))
-		$errror = '$attachID';
-	elseif (empty($context['attachments']))
-		$errror = '$context[\'attachments\']';
-	elseif (empty($context['attach_dir']))
-		$errror = '$context[\'attach_dir\']';
-		
-	// Let's get their attention.
-	if (!empty($error))
-		fatal_lang_error('attach_check_nag', 'debug', array($error));
-
-	// These are the only valid image types for SMF.
-	$validImageTypes = array(
-		1 => 'gif',
-		2 => 'jpeg',
-		3 => 'png',
-		5 => 'psd',
-		6 => 'bmp',
-		7 => 'tiff',
-		8 => 'tiff',
-		9 => 'jpeg',
-		14 => 'iff'
-	);
-
-	// Just in case this slipped by the first checks, we stop it here and now
-	if ($_SESSION['temp_attachments'][$attachID]['size'] == 0)
-	{
-		$_SESSION['temp_attachments'][$attachID]['errors'][] = 'attach_0_byte_file';
-		return false;
-	}
-
-	// First, the dreaded security check. Sorry folks, but this can't be avoided
-	$size = @getimagesize($_SESSION['temp_attachments'][$attachID]['tmp_name']);
-	if (isset($validImageTypes[$size[2]]))
-	{
-		require_once($sourcedir . '/Subs-Graphics.php');
-		if (!checkImageContents($_SESSION['temp_attachments'][$attachID]['tmp_name'], !empty($modSettings['attachment_image_paranoid'])))
-		{
-			// It's bad. Last chance, maybe we can re-encode it?
-			if (empty($modSettings['attachment_image_reencode']) || (!reencodeImage($_SESSION['temp_attachments'][$attachID]['tmp_name'], $size[2])))
-			{
-				// Nothing to do: not allowed or not successful re-encoding it.
-				$_SESSION['temp_attachments'][$attachID]['errors'][] = 'bad_attachment';
-				return false;
-			}
-			// Success! However, successes usually come for a price:
-			// we might get a new format for our image...
-			$old_format = $size[2];
-			$size = @getimagesize($attachmentOptions['tmp_name']);
-			if (!(empty($size)) && ($size[2] != $old_format))
-			{
-				if (isset($validImageTypes[$size[2]]))
-					$_SESSION['temp_attachments'][$attachID]['type'] = 'image/' . $validImageTypes[$size[2]];
-			}
-		}
-	}
-
-	if (!empty($modSettings['attachmentDirSizeLimit']))
-	{
-		// Check the folder size if it hasn't been done already.
-		if (!isset($context['dir_size']))
-		{
-			$request = $smcFunc['db_query']('', '
-				SELECT SUM(size)
-				FROM {db_prefix}attachments
-				WHERE id_folder = {int:folder_id}',
-				array(
-					'folder_id' => empty($modSettings['currentAttachmentUploadDir']) ? 1 : $modSettings['currentAttachmentUploadDir'],
-				)
-			);
-			list ($context['dir_size']) = $smcFunc['db_fetch_row']($request);
-			$smcFunc['db_free_result']($request);
-		}
-
-		$context['dir_size'] += $_SESSION['temp_attachments'][$attachID]['size'];
-
-		// Soon to be too big - warn the admins...
-		if (empty($modSettings['attachment_full_notified']) && $modSettings['attachmentDirSizeLimit'] > 4000 && $context['dir_size'] > ($modSettings['attachmentDirSizeLimit'] - 2000) * 1024)
-		{
-			require_once($sourcedir . '/Subs-Admin.php');
-			emailAdmins('admin_attachments_full');
-			updateSettings(array('attachment_full_notified' => 1));
-		}
-
-		// Too big!  Maybe you could zip it or something...
-		if ($context['dir_size'] > $modSettings['attachmentDirSizeLimit'] * 1024)
-			$_SESSION['temp_attachments'][$attachID]['errors'][] = 'ran_out_of_space';
-	}
-
-	// Is the file too big?
-	$context['attachments']['total_size'] += $_SESSION['temp_attachments'][$attachID]['size'];
-	if (!empty($modSettings['attachmentSizeLimit']) && $_SESSION['temp_attachments'][$attachID]['size'] > $modSettings['attachmentSizeLimit'] * 1024)
-		$_SESSION['temp_attachments'][$attachID]['errors'][] = array('file_too_big', array(comma_format($modSettings['attachmentSizeLimit'], 0)));
-
-	// Check the total upload size for this post...
-	if (!empty($modSettings['attachmentPostLimit']) && $context['attachments']['total_size'] > $modSettings['attachmentPostLimit'] * 1024)
-		$_SESSION['temp_attachments'][$attachID]['errors'][] = array('attach_max_total_file_size', array(comma_format($modSettings['attachmentPostLimit'], 0), comma_format($modSettings['attachmentPostLimit'] - (($context['attachments']['total_size'] - $_SESSION['temp_attachments'][$attachID]['size']) / 1024), 0)));
-
-	// Have we reached the maximum number of files we are allowed?
-	$context['attachments']['quantity']++;
-	
-	// Set a max limit if none exists
-	if (empty($modSettings['attachmentNumPerPostLimit']) && $context['attachments']['quantity'] >= 50)
-		$modSettings['attachmentNumPerPostLimit'] = 50;
-
-	if (!empty($modSettings['attachmentNumPerPostLimit']) && $context['attachments']['quantity'] > $modSettings['attachmentNumPerPostLimit'])
-		$_SESSION['temp_attachments'][$attachID]['errors'][] = array('attachments_limit_per_post', array($modSettings['attachmentNumPerPostLimit']));
-
-	// File extension check
-	if (!empty($modSettings['attachmentCheckExtensions']))
-	{
-		$allowed = explode(',', strtolower($modSettings['attachmentExtensions']));
-		foreach ($allowed as $k => $dummy)
-			$allowed[$k] = trim($dummy);
-
-		if (!in_array(strtolower(substr(strrchr($_SESSION['temp_attachments'][$attachID]['name'], '.'), 1)), $allowed))
-		{
-			$allowed_extensions = strtr(strtolower($modSettings['attachmentExtensions']), array(',' => ', '));
-			$_SESSION['temp_attachments'][$attachID]['errors'][] = array('cant_upload_type', array($allowed_extensions));
-		}
-	}
-
-	// back up to the previous one if there's been an error.
-	if (!empty($_SESSION['temp_attachments'][$attachID]['errors']))
-	{
-		$context['dir_size'] -= $_SESSION['temp_attachments'][$attachID]['size'];
-		$context['attachments']['total_size'] -= $_SESSION['temp_attachments'][$attachID]['size'];
-		$context['attachments']['quantity']--;
-		return false;
-	}
-
-	return true;
-}
-
 /**
  * Modifying a post...
  *
@@ -2419,7 +2117,7 @@ function modifyPost(&$msgOptions, &$topicOptions, &$posterOptions)
 	if (isset($msgOptions['body']))
 	{
 		$messages_columns['body'] = $msgOptions['body'];
-		
+
 		// using a custom search index, then lets get the old message so we can update our index as needed
 		if (!empty($modSettings['search_custom_index_config']))
 		{

+ 2 - 2
Themes/default/Post.template.php

@@ -426,7 +426,7 @@ function template_main()
 	{
 		echo '
 					<dl id="postAttachment2">';
-		
+
 		// But, only show them if they haven't reached a limit. Or a mod author hasn't hidden them.
 		if ($context['num_allowed_attachments'] > 0 || !empty($context['dont_show_them']))
 		{
@@ -436,7 +436,7 @@ function template_main()
 						</dt>
 						<dd class="smalltext">
 							', empty($modSettings['attachmentSizeLimit']) ? '' : ('<input type="hidden" name="MAX_FILE_SIZE" value="' . $modSettings['attachmentSizeLimit'] * 1028 . '" />'), '
-							<input type="file" size="60" name="attachment[]" id="attachment1" class="input_file" /> (<a href="javascript:void(0);" onclick="cleanFileInput(\'attachment1\');">', $txt['clean_attach'], '</a>)';
+							<input type="file" multiple="multiple" size="60" name="attachment[]" id="attachment1" class="input_file" /> (<a href="javascript:void(0);" onclick="cleanFileInput(\'attachment1\');">', $txt['clean_attach'], '</a>)';
 
 			// Show more boxes if they aren't approaching that limit.
 			if ($context['num_allowed_attachments'] > 1)

+ 10 - 10
Themes/default/index.template.php

@@ -120,7 +120,7 @@ function template_html_above()
 	// It doesn't appear to like being called by short syntax. Please test if contemplating changes.
 	echo '
 	<script type="text/javascript" src="', $settings['theme_url'], '/scripts/smf_jquery_plugins.js"></script>';
-	
+
 	// Here comes the JavaScript bits!
 	echo '
 	<script type="text/javascript" src="', $settings['default_theme_url'], '/scripts/script.js?alp21"></script>
@@ -154,7 +154,7 @@ function template_html_above()
 		$(document).ready(function() {
 			// menu drop downs
 			$("ul.dropmenu").superfish();
-			
+
 			// tooltips
 			$(".preview").SMFtooltip();
 
@@ -165,7 +165,7 @@ function template_html_above()
 
 	// load in any javascript files from mods and themes
 	template_javascript();
-		
+
 	echo '
 	<meta http-equiv="Content-Type" content="text/html; charset=', $context['character_set'], '" />
 	<meta name="description" content="', $context['page_title_html_safe'], '" />', !empty($context['meta_keywords']) ? '
@@ -299,22 +299,22 @@ function template_body_above()
 	echo '
 			</div>
 			<div class="news normaltext">';
-	
+
 	if ($context['allow_search'])
 	{
 		echo '
 			<form id="search_form" action="', $scripturl, '?action=search2" method="post" accept-charset="', $context['character_set'], '">
 				<input type="text" name="search" value="" class="input_text" />&nbsp;';
-		
+
 		// Using the quick search dropdown?
 		if (!empty($modSettings['search_dropdown']))
 		{
 			$selected = !empty($context['current_topic']) ? 'current_topic' : (!empty($context['current_board']) ? 'current_board' : 'all');
-			
+
 			echo '
 				<select name="search_selection">
 					<option value="all"', ($selected == 'all' ? ' selected="selected"' : ''), '>', $txt['search_entireforum'], ' </option>';
-				
+
 				// Can't limit it to a specific topic if we are not in one
 				if (!empty($context['current_topic']))
 					echo '
@@ -328,7 +328,7 @@ function template_body_above()
 					<option value="members"', ($selected == 'members' ? ' selected="selected"' : ''), '>', $txt['search_members'], ' </option>
 				</select>';
 		}
-		
+
 		// Search within current topic?
 		if (!empty($context['current_topic']))
 			echo '
@@ -341,7 +341,7 @@ function template_body_above()
 		echo '
 				<input type="submit" name="search2" value="', $txt['search'], '" class="button_submit" />
 				<input type="hidden" name="advanced" value="0" />
-			</form>';	
+			</form>';
 	}
 
 	// Show a random news item? (or you could pick one from news_lines...)
@@ -501,7 +501,7 @@ function template_menu()
 		<div id="main_menu">
 			<ul class="dropmenu" id="menu_nav">';
 
-	// Note: Menu markup has been cleaned up to remove unnecessary spans and classes. 
+	// Note: Menu markup has been cleaned up to remove unnecessary spans and classes.
 	foreach ($context['menu_buttons'] as $act => $button)
 	{
 		echo '

+ 20 - 3
Themes/default/languages/Admin.english.php

@@ -351,9 +351,8 @@ $txt['attachmentCheckExtensions'] = 'Check attachment\'s extension';
 $txt['attachmentExtensions'] = 'Allowed attachment extensions';
 $txt['attachmentRecodeLineEndings'] = 'Recode line endings in textual attachments';
 $txt['attachmentShowImages'] = 'Display image attachments as pictures under post';
-$txt['attachmentEncryptFilenames'] = 'Encrypt stored filenames';
-$txt['attachmentUploadDir'] = 'Attachments directory';
-$txt['attachmentUploadDir_multiple'] = 'Attachments directory';
+$txt['attachmentUploadDir'] = 'Current attachments directory';
+$txt['attachmentUploadDir_multiple'] = 'Current attachments directory';
 $txt['attachmentUploadDir_multiple_configure'] = 'Configure multiple attachment directories';
 $txt['attachmentDirSizeLimit'] = 'Max attachment folder space';
 $txt['attachmentPostLimit'] = 'Max attachment size per post';
@@ -391,6 +390,24 @@ $txt['attach_num_files'] = 'Files';
 $txt['attach_dir_status'] = 'Status';
 $txt['attach_add_path'] = 'Add Path';
 $txt['attach_path_current_bad'] = 'Invalid current attachment path.';
+$txt['attachmentDirFileLimit'] = 'Maximum number of files per directory';
+
+$txt['automanage_attachments'] = 'Choose the method for the management of the attachment directories';
+$txt['attachments_normal'] = '(Manual) SMF default behaviour';
+$txt['attachments_auto_years'] = '(Auto) Subdivide by years';
+$txt['attachments_auto_months'] = '(Auto) Subdivide by years and months';
+$txt['attachments_auto_days'] = '(Auto) Subdivide by years, months and days';
+$txt['attachments_auto_16'] = '(Auto) 16 random folders';
+$txt['attachments_auto_16x16'] = '(Auto) 16 random folders with 16 random sub-folders';
+$txt['attachments_auto_space'] = '(Auto) When either directory space limit is reached';
+//$txt['attachments_auto_files'] = 'Change directory when file limit is reached';
+
+$txt['use_subdirectories_for_attachments'] = 'Create new directories within this directory';
+$txt['use_subdirectories_for_attachments_note'] = 'Otherwise any new directories will be created within the forum\'s main directory.';
+//$txt['use_subdirectories_for_attachments_note'] = '<span class="smalltext">Otherwise any new directories will be created within the forum\'s main directory</span>';
+
+$txt['basedirectory_for_attachments'] = 'Base directory for attachments';
+$txt['basedirectory_for_attachments_warning'] = '<div class="smalltext">Please note that the directory is wrong. SMF will use the last directory used before this was introduced</div>';
 
 $txt['mods_cat_avatars'] = 'Avatars';
 $txt['avatar_directory'] = 'Avatars directory';

+ 3 - 1
Themes/default/languages/Post.english.php

@@ -226,8 +226,10 @@ $txt['cant_access_upload_path'] = 'Cannot access attachments upload path!';
 $txt['file_too_big'] = 'Your file is too large. The maximum attachment size allowed is %1$d KB.';
 $txt['attach_timeout'] = 'Your attachment couldn\'t be saved. This might happen because it took too long to upload or the file is bigger than the server will allow.<br /><br />Please consult your server administrator for more information.';
 $txt['bad_attachment'] = 'Your attachment has failed security checks and cannot be uploaded. Please consult the forum administrator.';
-$txt['ran_out_of_space'] = 'The upload folder is full. Please try a smaller file and/or contact an administrator.';
+$txt['ran_out_of_space'] = 'The upload folder is full. Please contact an administrator about this problem.';
 $txt['attachments_no_write'] = 'The attachments upload directory is not writable.  Your attachment or avatar cannot be saved.';
+$txt['attachments_no_create'] = 'Unable to create a new attachment directory.  Your attachment or avatar cannot be saved.';
 $txt['attachments_limit_per_post'] = 'You may not upload more than %1$d attachments per post';
 
+
 ?>