361 lines
13 KiB
PHP
361 lines
13 KiB
PHP
<?php
|
|
/******************************************************************************
|
|
* ManageAttachments.php *
|
|
*******************************************************************************
|
|
* SMF: Simple Machines Forum *
|
|
* Open-Source Project Inspired by Zef Hemel (zef@zefhemel.com) *
|
|
* =========================================================================== *
|
|
* Software Version: SMF 1.0.1 *
|
|
* Software by: Simple Machines (http://www.simplemachines.org) *
|
|
* Copyright 2001-2005 by: Lewis Media (http://www.lewismedia.com) *
|
|
* Support, News, Updates at: http://www.simplemachines.org *
|
|
*******************************************************************************
|
|
* This program is free software; you may redistribute it and/or modify it *
|
|
* under the terms of the provided license as published by Lewis Media. *
|
|
* *
|
|
* This program is distributed in the hope that it is and will be useful, *
|
|
* but WITHOUT ANY WARRANTIES; without even any implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
|
* *
|
|
* See the "license.txt" file for details of the Simple Machines license. *
|
|
* The latest version can always be found at http://www.simplemachines.org. *
|
|
******************************************************************************/
|
|
if (!defined('SMF'))
|
|
die('Hacking attempt...');
|
|
|
|
// The main attachment management function.
|
|
function ManageAttachments()
|
|
{
|
|
global $txt, $db_prefix, $modSettings, $scripturl, $context, $options;
|
|
|
|
// You have to be able to moderate the forum to do this.
|
|
isAllowedTo('manage_attachments');
|
|
|
|
// Show the administration bar, etc.
|
|
adminIndex('manage_attachments');
|
|
|
|
// If they want to delete attachment(s), delete them. (otherwise fall through..)
|
|
$subActions = array(
|
|
'byAge' => 'RemoveAttachmentByAge',
|
|
'bySize' => 'RemoveAttachmentBySize',
|
|
'maintain' => 'MaintainAttachments',
|
|
'remove' => 'RemoveAttachment',
|
|
'removeall' => 'RemoveAllAttachments'
|
|
);
|
|
if (isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]))
|
|
$subActions[$_REQUEST['sa']]();
|
|
|
|
loadTemplate('ManageAttachments');
|
|
|
|
// Attachments or avatars?
|
|
$context['browse_avatars'] = isset($_REQUEST['avatars']);
|
|
|
|
// Get the number of attachments....
|
|
$request = db_query("
|
|
SELECT COUNT(ID_ATTACH)
|
|
FROM {$db_prefix}attachments
|
|
WHERE ID_MSG != 0", __FILE__, __LINE__);
|
|
list ($context['num_attachments']) = mysql_fetch_row($request);
|
|
mysql_free_result($request);
|
|
|
|
// Also get the avatar amount....
|
|
$request = db_query("
|
|
SELECT COUNT(ID_ATTACH)
|
|
FROM {$db_prefix}attachments
|
|
WHERE ID_MEMBER != 0", __FILE__, __LINE__);
|
|
list ($context['num_avatars']) = mysql_fetch_row($request);
|
|
mysql_free_result($request);
|
|
|
|
// Allow for sorting of each column...
|
|
$sort_methods = array(
|
|
'name' => 'a.filename',
|
|
'date' => $context['browse_avatars'] ? 'mem.lastLogin' : 'm.ID_MSG',
|
|
'size' => 'filesize',
|
|
'member' => 'mem.realName'
|
|
);
|
|
|
|
// Set up the importantant sorting variables... if they picked one...
|
|
if (!isset($_GET['sort']) || !isset($sort_methods[$_GET['sort']]))
|
|
{
|
|
$_GET['sort'] = 'date';
|
|
$descending = !empty($options['view_newest_first']);
|
|
}
|
|
// ... and if they didn't...
|
|
else
|
|
$descending = isset($_GET['desc']);
|
|
|
|
$context['sort_by'] = $_GET['sort'];
|
|
$_GET['sort'] = $sort_methods[$_GET['sort']];
|
|
$context['sort_direction'] = $descending ? 'down' : 'up';
|
|
|
|
// Get the page index ready......
|
|
if (!isset($_REQUEST['start']) || $_REQUEST['start'] < 0)
|
|
$_REQUEST['start'] = 0;
|
|
$context['start'] = $_REQUEST['start'];
|
|
|
|
$context['page_index'] = constructPageIndex($scripturl . '?action=manageattachments;' . ($context['browse_avatars'] ? 'avatars;' : '') . 'sort=' . $context['sort_by'] . ($context['sort_direction'] == 'down' ? ';desc' : ''), $context['start'], $context['browse_avatars'] ? $context['num_avatars'] : $context['num_attachments'], $modSettings['defaultMaxMessages']);
|
|
|
|
// Choose a query depending on what we are viewing.
|
|
if (!$context['browse_avatars'])
|
|
$request = db_query("
|
|
SELECT
|
|
m.ID_MSG, IFNULL(mem.realName, m.posterName) AS posterName, m.posterTime, m.ID_TOPIC, m.ID_MEMBER,
|
|
a.filename, IFNULL(a.size, 0) AS filesize, a.ID_ATTACH, a.downloads, mf.subject, t.ID_BOARD
|
|
FROM ({$db_prefix}attachments AS a, {$db_prefix}messages AS m, {$db_prefix}topics AS t, {$db_prefix}messages AS mf)
|
|
LEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = m.ID_MEMBER)
|
|
WHERE a.ID_MSG = m.ID_MSG
|
|
AND t.ID_TOPIC = m.ID_TOPIC
|
|
AND mf.ID_MSG = t.ID_FIRST_MSG
|
|
ORDER BY $_GET[sort] " . ($descending ? 'DESC' : 'ASC') . "
|
|
LIMIT $context[start], $modSettings[defaultMaxMessages]", __FILE__, __LINE__);
|
|
else
|
|
$request = db_query("
|
|
SELECT
|
|
'' AS ID_MSG, IFNULL(mem.realName, '$txt[470]') AS posterName, mem.lastLogin AS posterTime, 0 AS ID_TOPIC, a.ID_MEMBER,
|
|
a.filename, IFNULL(a.size, 0) AS filesize, a.ID_ATTACH, a.downloads, '' AS subject, 0 AS ID_BOARD
|
|
FROM {$db_prefix}attachments AS a
|
|
LEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = a.ID_MEMBER)
|
|
WHERE a.ID_MEMBER != 0
|
|
ORDER BY $_GET[sort] " . ($descending ? 'DESC' : 'ASC') . "
|
|
LIMIT $context[start], $modSettings[defaultMaxMessages]", __FILE__, __LINE__);
|
|
$context['posts'] = array();
|
|
while ($row = mysql_fetch_assoc($request))
|
|
$context['posts'][] = array(
|
|
'id' => $row['ID_MSG'],
|
|
'poster' => array(
|
|
'id' => $row['ID_MEMBER'],
|
|
'name' => $row['posterName'],
|
|
'href' => empty($row['ID_MEMBER']) ? '' : $scripturl . '?action=profile;u=' . $row['ID_MEMBER'],
|
|
'link' => empty($row['ID_MEMBER']) ? $row['posterName'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] . '">' . $row['posterName'] . '</a>'
|
|
),
|
|
'time' => empty($row['posterTime']) ? $txt['never'] : timeformat($row['posterTime']),
|
|
'timestamp' => $row['posterTime'],
|
|
'attachment' => array(
|
|
'id' => $row['ID_ATTACH'],
|
|
'size' => round($row['filesize'] / 1024, 2),
|
|
'name' => $row['filename'],
|
|
'downloads' => $row['downloads'],
|
|
'href' => $scripturl . '?action=dlattach;' . ($context['browse_avatars'] ? 'type=avatar;' : 'topic=' . $row['ID_TOPIC'] . '.0;') . 'id=' . $row['ID_ATTACH'],
|
|
'link' => '<a href="' . $scripturl . '?action=dlattach;' . ($context['browse_avatars'] ? 'type=avatar;' : 'topic=' . $row['ID_TOPIC'] . '.0;') . 'id=' . $row['ID_ATTACH'] . '">' . $row['filename'] . '</a>'
|
|
),
|
|
'topic' => $row['ID_TOPIC'],
|
|
'subject' => $row['subject'],
|
|
'link' => '<a href="' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '.0">' . $row['subject'] . '</a>'
|
|
);
|
|
mysql_free_result($request);
|
|
|
|
// Find out how big the directory is.
|
|
$attachmentDirSize = 0;
|
|
$dir = @opendir($modSettings['attachmentUploadDir']) or fatal_lang_error('smf115b');
|
|
while ($file = readdir($dir))
|
|
{
|
|
if (substr($file, 0, -1) == '.')
|
|
continue;
|
|
|
|
$attachmentDirSize += filesize($modSettings['attachmentUploadDir'] . '/' . $file);
|
|
}
|
|
closedir($dir);
|
|
// Divide it into kilobytes.
|
|
$attachmentDirSize /= 1024;
|
|
|
|
// If they specified a limit only....
|
|
if (!empty($modSettings['attachmentDirSizeLimit']))
|
|
$context['attachment_space'] = round($modSettings['attachmentDirSizeLimit'] - $attachmentDirSize, 2);
|
|
$context['attachment_total_size'] = round($attachmentDirSize, 2);
|
|
|
|
$context['page_title'] = $txt['smf201'];
|
|
}
|
|
|
|
function RemoveAttachmentByAge()
|
|
{
|
|
global $db_prefix, $modSettings;
|
|
|
|
checkSession('post', 'manageattachments');
|
|
|
|
// Deleting an attachment?
|
|
if ($_REQUEST['type'] != 'avatars')
|
|
{
|
|
// Get all the old attachments.
|
|
$messages = removeAttachments('a.ID_MSG > 0 AND m.posterTime < ' . (time() - 24 * 60 * 60 * $_POST['age']), 'messages', true);
|
|
|
|
// Update the messages to reflect the change.
|
|
if (!empty($messages))
|
|
db_query("
|
|
UPDATE {$db_prefix}messages
|
|
SET body = " . (!empty($_POST['notice']) ? "CONCAT(body, '\n\n$_POST[notice]')" : '') . "
|
|
WHERE ID_MSG IN (" . implode(', ', $messages) . ")
|
|
LIMIT " . count($messages), __FILE__, __LINE__);
|
|
}
|
|
else
|
|
{
|
|
// Remove all the old avatars.
|
|
removeAttachments('a.ID_MEMBER != 0 AND mem.lastLogin < ' . (time() - 24 * 60 * 60 * $_POST['age']), 'members');
|
|
}
|
|
redirectexit('action=manageattachments' . (empty($_REQUEST['avatars']) ? '' : ';avatars'));
|
|
}
|
|
|
|
function RemoveAttachmentBySize()
|
|
{
|
|
global $db_prefix, $modSettings;
|
|
|
|
checkSession('post', 'manageattachments');
|
|
|
|
// Find humungous attachments.
|
|
$messages = removeAttachments('a.ID_MSG > 0 AND a.size > ' . (1024 * $_POST['size']), 'messages', true);
|
|
|
|
// And make a note on the post.
|
|
if (!empty($messages))
|
|
db_query("
|
|
UPDATE {$db_prefix}messages
|
|
SET body = " . (!empty($_POST['notice']) ? "CONCAT(body, '\n\n$_POST[notice]')" : '') . "
|
|
WHERE ID_MSG IN (" . implode(',', $messages) . ")
|
|
LIMIT " . count($messages), __FILE__, __LINE__);
|
|
|
|
redirectexit('action=manageattachments');
|
|
}
|
|
|
|
function RemoveAttachment()
|
|
{
|
|
global $db_prefix, $modSettings, $txt;
|
|
|
|
checkSession('post', 'manageattachments');
|
|
|
|
if (!empty($_POST['remove']))
|
|
{
|
|
$attachments = array();
|
|
// There must be a quicker way to pass this safety test??
|
|
foreach ($_POST['remove'] as $removeID => $dummy)
|
|
$attachments[] = (int) $removeID;
|
|
|
|
if ($_REQUEST['type'] == 'avatars')
|
|
removeAttachments('a.ID_ATTACH IN (' . implode(', ', $attachments) . ')');
|
|
else
|
|
{
|
|
$messages = array_unique(removeAttachments('a.ID_ATTACH IN (' . implode(', ', $attachments) . ')', 'messages', true));
|
|
|
|
// And change the message to reflect this.
|
|
if (!empty($messages))
|
|
db_query("
|
|
UPDATE {$db_prefix}messages
|
|
SET body = CONCAT(body, '\n\n" . addslashes($txt['smf216']) . "')
|
|
WHERE ID_MSG IN (" . implode(', ', $messages) . ")
|
|
LIMIT " . count($messages), __FILE__, __LINE__);
|
|
}
|
|
}
|
|
|
|
redirectexit('action=manageattachments;' . ($_REQUEST['type'] == 'avatars' ? 'avatars;' : '') . 'start=' . $_REQUEST['start']);
|
|
}
|
|
|
|
function RemoveAllAttachments()
|
|
{
|
|
global $db_prefix, $txt;
|
|
|
|
checkSession('get', 'manageattachments');
|
|
|
|
$messages = removeAttachments('a.ID_MSG > 0', '', true);
|
|
|
|
if (!isset($_POST['notice']))
|
|
$_POST['notice'] = $txt['smf216'];
|
|
|
|
// Add the notice on the end of the changed messages.
|
|
if (!empty($messages))
|
|
db_query("
|
|
UPDATE {$db_prefix}messages
|
|
SET body = CONCAT(body, '\n\n$_POST[notice]')
|
|
WHERE ID_MSG IN (" . implode(',', $messages) . ")
|
|
LIMIT " . count($messages), __FILE__, __LINE__);
|
|
|
|
redirectexit('action=manageattachments');
|
|
}
|
|
|
|
// Removes attachments - allowed query_types: '', 'messages', 'members'
|
|
function removeAttachments($condition, $query_type = '', $return_affected_messages = false)
|
|
{
|
|
global $db_prefix, $modSettings;
|
|
|
|
// Delete it only if it exists...
|
|
$msgs = array();
|
|
$attach = array();
|
|
|
|
// Get all the attachment names and ID_MSGs.
|
|
$request = db_query("
|
|
SELECT a.filename, a.ID_ATTACH" . ($query_type == 'messages' ? ', m.ID_MSG' : ', a.ID_MSG') . "
|
|
FROM {$db_prefix}attachments AS a" .
|
|
($query_type == 'messages' ? ", {$db_prefix}messages AS m" : '') .
|
|
($query_type == 'members' ? ", {$db_prefix}members AS mem" : '') . "
|
|
WHERE $condition" . ($query_type == 'messages' ? '
|
|
AND m.ID_MSG = a.ID_MSG' : '') . ($query_type == 'members' ? '
|
|
AND mem.ID_MEMBER = a.ID_MEMBER' : ''), __FILE__, __LINE__);
|
|
while ($row = mysql_fetch_assoc($request))
|
|
{
|
|
// Figure out the "encrypted" filename and unlink it ;).
|
|
@unlink(getAttachmentFilename($row['filename'], $row['ID_ATTACH']));
|
|
|
|
// Make a list.
|
|
if ($return_affected_messages)
|
|
$msgs[] = $row['ID_MSG'];
|
|
$attach[] = $row['ID_ATTACH'];
|
|
}
|
|
mysql_free_result($request);
|
|
|
|
if (!empty($attach))
|
|
db_query("
|
|
DELETE FROM {$db_prefix}attachments
|
|
WHERE ID_ATTACH IN (" . implode(', ', $attach) . ")
|
|
LIMIT " . count($attach), __FILE__, __LINE__);
|
|
|
|
if ($return_affected_messages)
|
|
return $msgs;
|
|
}
|
|
|
|
// This function should find attachments in the database that no longer exist and clear them, and fix filesize issues.
|
|
function MaintainAttachments()
|
|
{
|
|
global $db_prefix, $modSettings;
|
|
|
|
$request = db_query("
|
|
SELECT ID_ATTACH, ID_MSG, ID_MEMBER, filename, IFNULL(size, 0) AS size, downloads
|
|
FROM {$db_prefix}attachments", __FILE__, __LINE__);
|
|
$removals = array();
|
|
$filesizes = array();
|
|
while ($row = mysql_fetch_assoc($request))
|
|
{
|
|
$filename = getAttachmentFilename($row['filename'], $row['ID_ATTACH']);
|
|
|
|
// Test if the file exists...
|
|
if (!file_exists($filename))
|
|
{
|
|
$removals[] = $row['ID_ATTACH'];
|
|
continue;
|
|
}
|
|
|
|
// Fetch the actual filesize.
|
|
$realFileSize = filesize($filename);
|
|
|
|
// If it's different that the previous one... we need to update the database.
|
|
if ($realFileSize != $row['size'] && $realFileSize !== false && $realFileSize !== null)
|
|
$filesizes[$row['ID_ATTACH']] = (int) $realFileSize;
|
|
}
|
|
mysql_free_result($request);
|
|
|
|
// Remove the missing ones...
|
|
if (!empty($removals))
|
|
{
|
|
removeAttachments('a.ID_ATTACH IN (' . implode(', ', $removals) . ')', 'messages');
|
|
$context['attachments_removed'] = count($removals);
|
|
}
|
|
|
|
// Update the database with the filesize fixes.
|
|
if (!empty($filesizes))
|
|
{
|
|
foreach ($filesizes as $attach => $filesize)
|
|
db_query("
|
|
UPDATE {$db_prefix}attachments
|
|
SET size = $filesize
|
|
WHERE ID_ATTACH = $attach
|
|
LIMIT 1", __FILE__, __LINE__);
|
|
$context['attachments_fixed'] = count($filesizes);
|
|
}
|
|
}
|
|
|
|
?>
|