annotate forum/Sources/ManageAttachments.php @ 85:6d7b61434be7 website

Add a copy of this here, just in case!
author Chris Cannam
date Mon, 20 Jan 2014 11:02:36 +0000
parents e3e11437ecea
children
rev   line source
Chris@76 1 <?php
Chris@76 2
Chris@76 3 /**
Chris@76 4 * Simple Machines Forum (SMF)
Chris@76 5 *
Chris@76 6 * @package SMF
Chris@76 7 * @author Simple Machines http://www.simplemachines.org
Chris@76 8 * @copyright 2011 Simple Machines
Chris@76 9 * @license http://www.simplemachines.org/about/smf/license.php BSD
Chris@76 10 *
Chris@76 11 * @version 2.0
Chris@76 12 */
Chris@76 13
Chris@76 14 if (!defined('SMF'))
Chris@76 15 die('Hacking attempt...');
Chris@76 16
Chris@76 17 /* /!!!
Chris@76 18
Chris@76 19 void ManageAttachments()
Chris@76 20 - main 'Attachments and Avatars' center function.
Chris@76 21 - entry point for index.php?action=admin;area=manageattachments.
Chris@76 22 - requires the manage_attachments permission.
Chris@76 23 - load the ManageAttachments template.
Chris@76 24 - uses the Admin language file.
Chris@76 25 - uses the template layer 'manage_files' for showing the tab bar.
Chris@76 26 - calls a function based on the sub-action.
Chris@76 27
Chris@76 28 void ManageAttachmentSettings()
Chris@76 29 - show/change attachment settings.
Chris@76 30 - default sub action for the 'Attachments and Avatars' center.
Chris@76 31 - uses the 'attachments' sub template.
Chris@76 32 - called by index.php?action=admin;area=manageattachments;sa=attachements.
Chris@76 33
Chris@76 34 void ManageAvatarSettings()
Chris@76 35 - show/change avatar settings.
Chris@76 36 - called by index.php?action=admin;area=manageattachments;sa=avatars.
Chris@76 37 - uses the 'avatars' sub template.
Chris@76 38 - show/set permissions for permissions: 'profile_server_avatar',
Chris@76 39 'profile_upload_avatar' and 'profile_remote_avatar'.
Chris@76 40
Chris@76 41 void BrowseFiles()
Chris@76 42 - show a list of attachment or avatar files.
Chris@76 43 - called by ?action=admin;area=manageattachments;sa=browse for attachments and
Chris@76 44 ?action=admin;area=manageattachments;sa=browse;avatars for avatars.
Chris@76 45 - uses the 'browse' sub template
Chris@76 46 - allows sorting by name, date, size and member.
Chris@76 47 - paginates results.
Chris@76 48
Chris@76 49 void MaintainFiles()
Chris@76 50 - show several file maintenance options.
Chris@76 51 - called by ?action=admin;area=manageattachments;sa=maintain.
Chris@76 52 - uses the 'maintain' sub template.
Chris@76 53 - calculates file statistics (total file size, number of attachments,
Chris@76 54 number of avatars, attachment space available).
Chris@76 55
Chris@76 56 void MoveAvatars()
Chris@76 57 - move avatars from or to the attachment directory.
Chris@76 58 - called from the maintenance screen by
Chris@76 59 ?action=admin;area=manageattachments;sa=moveAvatars.
Chris@76 60
Chris@76 61 void RemoveAttachmentByAge()
Chris@76 62 - remove attachments older than a given age.
Chris@76 63 - called from the maintenance screen by
Chris@76 64 ?action=admin;area=manageattachments;sa=byAge.
Chris@76 65 - optionally adds a certain text to the messages the attachments were
Chris@76 66 removed from.
Chris@76 67
Chris@76 68 void RemoveAttachmentBySize()
Chris@76 69 - remove attachments larger than a given size.
Chris@76 70 - called from the maintenance screen by
Chris@76 71 ?action=admin;area=manageattachments;sa=bySize.
Chris@76 72 - optionally adds a certain text to the messages the attachments were
Chris@76 73 removed from.
Chris@76 74
Chris@76 75 void RemoveAttachment()
Chris@76 76 - remove a selection of attachments or avatars.
Chris@76 77 - called from the browse screen as submitted form by
Chris@76 78 ?action=admin;area=manageattachments;sa=remove
Chris@76 79
Chris@76 80 void RemoveAllAttachments()
Chris@76 81 - removes all attachments in a single click
Chris@76 82 - called from the maintenance screen by
Chris@76 83 ?action=admin;area=manageattachments;sa=removeall.
Chris@76 84
Chris@76 85 array removeAttachments(array condition, string query_type = '', bool return_affected_messages = false, bool autoThumbRemoval = true)
Chris@76 86 - removes attachments or avatars based on a given query condition.
Chris@76 87 - called by several remove avatar/attachment functions in this file.
Chris@76 88 - removes attachments based that match the $condition.
Chris@76 89 - allows query_types 'messages' and 'members', whichever is need by the
Chris@76 90 $condition parameter.
Chris@76 91
Chris@76 92 void RepairAttachments()
Chris@76 93 // !!!
Chris@76 94
Chris@76 95 void PauseAttachmentMaintenance()
Chris@76 96 // !!!
Chris@76 97
Chris@76 98 void ApproveAttach()
Chris@76 99 // !!!
Chris@76 100
Chris@76 101 void ApproveAttachments()
Chris@76 102 // !!!
Chris@76 103 */
Chris@76 104
Chris@76 105 // The main attachment management function.
Chris@76 106 function ManageAttachments()
Chris@76 107 {
Chris@76 108 global $txt, $modSettings, $scripturl, $context, $options;
Chris@76 109
Chris@76 110 // You have to be able to moderate the forum to do this.
Chris@76 111 isAllowedTo('manage_attachments');
Chris@76 112
Chris@76 113 // Setup the template stuff we'll probably need.
Chris@76 114 loadTemplate('ManageAttachments');
Chris@76 115
Chris@76 116 // If they want to delete attachment(s), delete them. (otherwise fall through..)
Chris@76 117 $subActions = array(
Chris@76 118 'attachments' => 'ManageAttachmentSettings',
Chris@76 119 'attachpaths' => 'ManageAttachmentPaths',
Chris@76 120 'avatars' => 'ManageAvatarSettings',
Chris@76 121 'browse' => 'BrowseFiles',
Chris@76 122 'byAge' => 'RemoveAttachmentByAge',
Chris@76 123 'bySize' => 'RemoveAttachmentBySize',
Chris@76 124 'maintenance' => 'MaintainFiles',
Chris@76 125 'moveAvatars' => 'MoveAvatars',
Chris@76 126 'repair' => 'RepairAttachments',
Chris@76 127 'remove' => 'RemoveAttachment',
Chris@76 128 'removeall' => 'RemoveAllAttachments'
Chris@76 129 );
Chris@76 130
Chris@76 131 // Pick the correct sub-action.
Chris@76 132 if (isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]))
Chris@76 133 $context['sub_action'] = $_REQUEST['sa'];
Chris@76 134 else
Chris@76 135 $context['sub_action'] = 'browse';
Chris@76 136
Chris@76 137 // Default page title is good.
Chris@76 138 $context['page_title'] = $txt['attachments_avatars'];
Chris@76 139
Chris@76 140 // This uses admin tabs - as it should!
Chris@76 141 $context[$context['admin_menu_name']]['tab_data'] = array(
Chris@76 142 'title' => $txt['attachments_avatars'],
Chris@76 143 'help' => 'manage_files',
Chris@76 144 'description' => $txt['attachments_desc'],
Chris@76 145 );
Chris@76 146
Chris@76 147 // Finally fall through to what we are doing.
Chris@76 148 $subActions[$context['sub_action']]();
Chris@76 149 }
Chris@76 150
Chris@76 151 function ManageAttachmentSettings($return_config = false)
Chris@76 152 {
Chris@76 153 global $txt, $modSettings, $scripturl, $context, $options, $sourcedir;
Chris@76 154
Chris@76 155 $context['valid_upload_dir'] = is_dir($modSettings['attachmentUploadDir']) && is_writable($modSettings['attachmentUploadDir']);
Chris@76 156
Chris@76 157 // Perform a test to see if the GD module is installed.
Chris@76 158 $testGD = get_extension_funcs('gd');
Chris@76 159
Chris@76 160 $config_vars = array(
Chris@76 161 array('title', 'attachment_manager_settings'),
Chris@76 162 // Are attachments enabled?
Chris@76 163 array('select', 'attachmentEnable', array($txt['attachmentEnable_deactivate'], $txt['attachmentEnable_enable_all'], $txt['attachmentEnable_disable_new'])),
Chris@76 164 '',
Chris@76 165 // Extension checks etc.
Chris@76 166 array('check', 'attachmentCheckExtensions'),
Chris@76 167 array('text', 'attachmentExtensions', 40),
Chris@76 168 array('check', 'attachmentRecodeLineEndings'),
Chris@76 169 '',
Chris@76 170 // Directory and size limits.
Chris@76 171 empty($modSettings['currentAttachmentUploadDir']) ? array('text', 'attachmentUploadDir', 40, 'invalid' => !$context['valid_upload_dir']) : array('var_message', 'attachmentUploadDir_multiple', 'message' => 'attachmentUploadDir_multiple_configure'),
Chris@76 172 array('text', 'attachmentDirSizeLimit', 6, 'postinput' => $txt['kilobyte']),
Chris@76 173 array('text', 'attachmentPostLimit', 6, 'postinput' => $txt['kilobyte']),
Chris@76 174 array('text', 'attachmentSizeLimit', 6, 'postinput' => $txt['kilobyte']),
Chris@76 175 array('text', 'attachmentNumPerPostLimit', 6),
Chris@76 176 '',
Chris@76 177 // Image settings.
Chris@76 178 array('warning', empty($testGD) ? 'attachment_gd_warning' : ''),
Chris@76 179 array('check', 'attachment_image_reencode'),
Chris@76 180 '',
Chris@76 181 array('warning', 'attachment_image_paranoid_warning'),
Chris@76 182 array('check', 'attachment_image_paranoid'),
Chris@76 183 '',
Chris@76 184 // Thumbnail settings.
Chris@76 185 array('check', 'attachmentShowImages'),
Chris@76 186 array('check', 'attachmentThumbnails'),
Chris@76 187 array('check', 'attachment_thumb_png'),
Chris@76 188 array('text', 'attachmentThumbWidth', 6),
Chris@76 189 array('text', 'attachmentThumbHeight', 6),
Chris@76 190 );
Chris@76 191
Chris@76 192 if ($return_config)
Chris@76 193 return $config_vars;
Chris@76 194
Chris@76 195 // These are very likely to come in handy! (i.e. without them we're doomed!)
Chris@76 196 require_once($sourcedir . '/ManagePermissions.php');
Chris@76 197 require_once($sourcedir . '/ManageServer.php');
Chris@76 198
Chris@76 199 // Saving settings?
Chris@76 200 if (isset($_GET['save']))
Chris@76 201 {
Chris@76 202 checkSession();
Chris@76 203
Chris@76 204 saveDBSettings($config_vars);
Chris@76 205 redirectexit('action=admin;area=manageattachments;sa=attachments');
Chris@76 206 }
Chris@76 207
Chris@76 208 $context['post_url'] = $scripturl . '?action=admin;area=manageattachments;save;sa=attachments';
Chris@76 209 prepareDBSettingContext($config_vars);
Chris@76 210
Chris@76 211 $context['sub_template'] = 'show_settings';
Chris@76 212 }
Chris@76 213
Chris@76 214 function ManageAvatarSettings($return_config = false)
Chris@76 215 {
Chris@76 216 global $txt, $context, $modSettings, $sourcedir, $scripturl;
Chris@76 217
Chris@76 218 // Perform a test to see if the GD module is installed.
Chris@76 219 $testGD = get_extension_funcs('gd');
Chris@76 220
Chris@76 221 $context['valid_avatar_dir'] = is_dir($modSettings['avatar_directory']);
Chris@76 222 $context['valid_custom_avatar_dir'] = empty($modSettings['custom_avatar_enabled']) || (!empty($modSettings['custom_avatar_dir']) && is_dir($modSettings['custom_avatar_dir']) && is_writable($modSettings['custom_avatar_dir']));
Chris@76 223
Chris@76 224 $config_vars = array(
Chris@76 225 // Server stored avatars!
Chris@76 226 array('title', 'avatar_server_stored'),
Chris@76 227 array('warning', empty($testGD) ? 'avatar_gd_warning' : ''),
Chris@76 228 array('permissions', 'profile_server_avatar', 0, $txt['avatar_server_stored_groups']),
Chris@76 229 array('text', 'avatar_directory', 40, 'invalid' => !$context['valid_avatar_dir']),
Chris@76 230 array('text', 'avatar_url', 40),
Chris@76 231 // External avatars?
Chris@76 232 array('title', 'avatar_external'),
Chris@76 233 array('permissions', 'profile_remote_avatar', 0, $txt['avatar_external_url_groups']),
Chris@76 234 array('check', 'avatar_download_external', 0, 'onchange' => 'fUpdateStatus();'),
Chris@76 235 array('text', 'avatar_max_width_external', 6),
Chris@76 236 array('text', 'avatar_max_height_external', 6),
Chris@76 237 array('select', 'avatar_action_too_large',
Chris@76 238 array(
Chris@76 239 'option_refuse' => $txt['option_refuse'],
Chris@76 240 'option_html_resize' => $txt['option_html_resize'],
Chris@76 241 'option_js_resize' => $txt['option_js_resize'],
Chris@76 242 'option_download_and_resize' => $txt['option_download_and_resize'],
Chris@76 243 ),
Chris@76 244 ),
Chris@76 245 // Uploadable avatars?
Chris@76 246 array('title', 'avatar_upload'),
Chris@76 247 array('permissions', 'profile_upload_avatar', 0, $txt['avatar_upload_groups']),
Chris@76 248 array('text', 'avatar_max_width_upload', 6),
Chris@76 249 array('text', 'avatar_max_height_upload', 6),
Chris@76 250 array('check', 'avatar_resize_upload', 'subtext' => $txt['avatar_resize_upload_note']),
Chris@76 251 array('check', 'avatar_reencode'),
Chris@76 252 '',
Chris@76 253 array('warning', 'avatar_paranoid_warning'),
Chris@76 254 array('check', 'avatar_paranoid'),
Chris@76 255 '',
Chris@76 256 array('check', 'avatar_download_png'),
Chris@76 257 array('select', 'custom_avatar_enabled', array($txt['option_attachment_dir'], $txt['option_specified_dir']), 'onchange' => 'fUpdateStatus();'),
Chris@76 258 array('text', 'custom_avatar_dir', 40, 'subtext' => $txt['custom_avatar_dir_desc'], 'invalid' => !$context['valid_custom_avatar_dir']),
Chris@76 259 array('text', 'custom_avatar_url', 40),
Chris@76 260 );
Chris@76 261
Chris@76 262 if ($return_config)
Chris@76 263 return $config_vars;
Chris@76 264
Chris@76 265 // We need these files for the inline permission settings, and the settings template.
Chris@76 266 require_once($sourcedir . '/ManagePermissions.php');
Chris@76 267 require_once($sourcedir . '/ManageServer.php');
Chris@76 268
Chris@76 269 // Saving avatar settings?
Chris@76 270 if (isset($_GET['save']))
Chris@76 271 {
Chris@76 272 checkSession();
Chris@76 273
Chris@76 274 // Just incase the admin forgot to set both custom avatar values, we disable it to prevent errors.
Chris@76 275 if (isset($_POST['custom_avatar_enabled']) && $_POST['custom_avatar_enabled'] == 1 && (empty($_POST['custom_avatar_dir']) || empty($_POST['custom_avatar_url'])))
Chris@76 276 $_POST['custom_avatar_enabled'] = 0;
Chris@76 277
Chris@76 278 saveDBSettings($config_vars);
Chris@76 279 redirectexit('action=admin;area=manageattachments;sa=avatars');
Chris@76 280 }
Chris@76 281
Chris@76 282 // Attempt to figure out if the admin is trying to break things.
Chris@76 283 $context['settings_save_onclick'] = 'return document.getElementById(\'custom_avatar_enabled\').value == 1 && (document.getElementById(\'custom_avatar_dir\').value == \'\' || document.getElementById(\'custom_avatar_url\').value == \'\') ? confirm(\'' . $txt['custom_avatar_check_empty'] . '\') : true;';
Chris@76 284
Chris@76 285 // Prepare the context.
Chris@76 286 $context['post_url'] = $scripturl . '?action=admin;area=manageattachments;save;sa=avatars';
Chris@76 287 prepareDBSettingContext($config_vars);
Chris@76 288
Chris@76 289 // Add a layer for the javascript.
Chris@76 290 $context['template_layers'][] = 'avatar_settings';
Chris@76 291 $context['sub_template'] = 'show_settings';
Chris@76 292 }
Chris@76 293
Chris@76 294 function BrowseFiles()
Chris@76 295 {
Chris@76 296 global $context, $txt, $scripturl, $options, $modSettings;
Chris@76 297 global $smcFunc, $sourcedir;
Chris@76 298
Chris@76 299 $context['sub_template'] = 'browse';
Chris@76 300
Chris@76 301 // Attachments or avatars?
Chris@76 302 $context['browse_type'] = isset($_REQUEST['avatars']) ? 'avatars' : (isset($_REQUEST['thumbs']) ? 'thumbs' : 'attachments');
Chris@76 303
Chris@76 304 // Set the options for the list component.
Chris@76 305 $listOptions = array(
Chris@76 306 'id' => 'file_list',
Chris@76 307 'title' => $txt['attachment_manager_' . ($context['browse_type'] === 'avatars' ? 'avatars' : ( $context['browse_type'] === 'thumbs' ? 'thumbs' : 'attachments'))],
Chris@76 308 'items_per_page' => $modSettings['defaultMaxMessages'],
Chris@76 309 'base_href' => $scripturl . '?action=admin;area=manageattachments;sa=browse' . ($context['browse_type'] === 'avatars' ? ';avatars' : ($context['browse_type'] === 'thumbs' ? ';thumbs' : '')),
Chris@76 310 'default_sort_col' => 'name',
Chris@76 311 'no_items_label' => $txt['attachment_manager_' . ($context['browse_type'] === 'avatars' ? 'avatars' : ( $context['browse_type'] === 'thumbs' ? 'thumbs' : 'attachments')) . '_no_entries'],
Chris@76 312 'get_items' => array(
Chris@76 313 'function' => 'list_getFiles',
Chris@76 314 'params' => array(
Chris@76 315 $context['browse_type'],
Chris@76 316 ),
Chris@76 317 ),
Chris@76 318 'get_count' => array(
Chris@76 319 'function' => 'list_getNumFiles',
Chris@76 320 'params' => array(
Chris@76 321 $context['browse_type'],
Chris@76 322 ),
Chris@76 323 ),
Chris@76 324 'columns' => array(
Chris@76 325 'name' => array(
Chris@76 326 'header' => array(
Chris@76 327 'value' => $txt['attachment_name'],
Chris@76 328 ),
Chris@76 329 'data' => array(
Chris@76 330 'function' => create_function('$rowData', '
Chris@76 331 global $modSettings, $context, $scripturl;
Chris@76 332
Chris@76 333 $link = \'<a href="\';
Chris@76 334
Chris@76 335 // In case of a custom avatar URL attachments have a fixed directory.
Chris@76 336 if ($rowData[\'attachment_type\'] == 1)
Chris@76 337 $link .= sprintf(\'%1$s/%2$s\', $modSettings[\'custom_avatar_url\'], $rowData[\'filename\']);
Chris@76 338
Chris@76 339 // By default avatars are downloaded almost as attachments.
Chris@76 340 elseif ($context[\'browse_type\'] == \'avatars\')
Chris@76 341 $link .= sprintf(\'%1$s?action=dlattach;type=avatar;attach=%2$d\', $scripturl, $rowData[\'id_attach\']);
Chris@76 342
Chris@76 343 // Normal attachments are always linked to a topic ID.
Chris@76 344 else
Chris@76 345 $link .= sprintf(\'%1$s?action=dlattach;topic=%2$d.0;attach=%3$d\', $scripturl, $rowData[\'id_topic\'], $rowData[\'id_attach\']);
Chris@76 346
Chris@76 347 $link .= \'"\';
Chris@76 348
Chris@76 349 // Show a popup on click if it\'s a picture and we know its dimensions.
Chris@76 350 if (!empty($rowData[\'width\']) && !empty($rowData[\'height\']))
Chris@76 351 $link .= sprintf(\' onclick="return reqWin(this.href\' . ($rowData[\'attachment_type\'] == 1 ? \'\' : \' + \\\';image\\\'\') . \', %1$d, %2$d, true);"\', $rowData[\'width\'] + 20, $rowData[\'height\'] + 20);
Chris@76 352
Chris@76 353 $link .= sprintf(\'>%1$s</a>\', preg_replace(\'~&amp;#(\\\\d{1,7}|x[0-9a-fA-F]{1,6});~\', \'&#\\\\1;\', htmlspecialchars($rowData[\'filename\'])));
Chris@76 354
Chris@76 355 // Show the dimensions.
Chris@76 356 if (!empty($rowData[\'width\']) && !empty($rowData[\'height\']))
Chris@76 357 $link .= sprintf(\' <span class="smalltext">%1$dx%2$d</span>\', $rowData[\'width\'], $rowData[\'height\']);
Chris@76 358
Chris@76 359 return $link;
Chris@76 360 '),
Chris@76 361 ),
Chris@76 362 'sort' => array(
Chris@76 363 'default' => 'a.filename',
Chris@76 364 'reverse' => 'a.filename DESC',
Chris@76 365 ),
Chris@76 366 ),
Chris@76 367 'filesize' => array(
Chris@76 368 'header' => array(
Chris@76 369 'value' => $txt['attachment_file_size'],
Chris@76 370 ),
Chris@76 371 'data' => array(
Chris@76 372 'function' => create_function('$rowData','
Chris@76 373 global $txt;
Chris@76 374
Chris@76 375 return sprintf(\'%1$s%2$s\', round($rowData[\'size\'] / 1024, 2), $txt[\'kilobyte\']);
Chris@76 376 '),
Chris@76 377 'class' => 'windowbg',
Chris@76 378 ),
Chris@76 379 'sort' => array(
Chris@76 380 'default' => 'a.size',
Chris@76 381 'reverse' => 'a.size DESC',
Chris@76 382 ),
Chris@76 383 ),
Chris@76 384 'member' => array(
Chris@76 385 'header' => array(
Chris@76 386 'value' => $context['browse_type'] == 'avatars' ? $txt['attachment_manager_member'] : $txt['posted_by'],
Chris@76 387 ),
Chris@76 388 'data' => array(
Chris@76 389 'function' => create_function('$rowData', '
Chris@76 390 global $scripturl;
Chris@76 391
Chris@76 392 // In case of an attachment, return the poster of the attachment.
Chris@76 393 if (empty($rowData[\'id_member\']))
Chris@76 394 return htmlspecialchars($rowData[\'poster_name\']);
Chris@76 395
Chris@76 396 // Otherwise it must be an avatar, return the link to the owner of it.
Chris@76 397 else
Chris@76 398 return sprintf(\'<a href="%1$s?action=profile;u=%2$d">%3$s</a>\', $scripturl, $rowData[\'id_member\'], $rowData[\'poster_name\']);
Chris@76 399 '),
Chris@76 400 ),
Chris@76 401 'sort' => array(
Chris@76 402 'default' => 'mem.real_name',
Chris@76 403 'reverse' => 'mem.real_name DESC',
Chris@76 404 ),
Chris@76 405 ),
Chris@76 406 'date' => array(
Chris@76 407 'header' => array(
Chris@76 408 'value' => $context['browse_type'] == 'avatars' ? $txt['attachment_manager_last_active'] : $txt['date'],
Chris@76 409 ),
Chris@76 410 'data' => array(
Chris@76 411 'function' => create_function('$rowData', '
Chris@76 412 global $txt, $context, $scripturl;
Chris@76 413
Chris@76 414 // The date the message containing the attachment was posted or the owner of the avatar was active.
Chris@76 415 $date = empty($rowData[\'poster_time\']) ? $txt[\'never\'] : timeformat($rowData[\'poster_time\']);
Chris@76 416
Chris@76 417 // Add a link to the topic in case of an attachment.
Chris@76 418 if ($context[\'browse_type\'] !== \'avatars\')
Chris@76 419 $date .= sprintf(\'<br />%1$s <a href="%2$s?topic=%3$d.0.msg%4$d#msg%4$d">%5$s</a>\', $txt[\'in\'], $scripturl, $rowData[\'id_topic\'], $rowData[\'id_msg\'], $rowData[\'subject\']);
Chris@76 420
Chris@76 421 return $date;
Chris@76 422 '),
Chris@76 423 'class' => 'windowbg',
Chris@76 424 ),
Chris@76 425 'sort' => array(
Chris@76 426 'default' => $context['browse_type'] === 'avatars' ? 'mem.last_login' : 'm.id_msg',
Chris@76 427 'reverse' => $context['browse_type'] === 'avatars' ? 'mem.last_login DESC' : 'm.id_msg DESC',
Chris@76 428 ),
Chris@76 429 ),
Chris@76 430 'downloads' => array(
Chris@76 431 'header' => array(
Chris@76 432 'value' => $txt['downloads'],
Chris@76 433 ),
Chris@76 434 'data' => array(
Chris@76 435 'function' => create_function('$rowData','
Chris@76 436 global $txt;
Chris@76 437
Chris@76 438 return comma_format($rowData[\'downloads\']);
Chris@76 439 '),
Chris@76 440 'class' => 'windowbg',
Chris@76 441 ),
Chris@76 442 'sort' => array(
Chris@76 443 'default' => 'a.downloads',
Chris@76 444 'reverse' => 'a.downloads DESC',
Chris@76 445 ),
Chris@76 446 ),
Chris@76 447 'check' => array(
Chris@76 448 'header' => array(
Chris@76 449 'value' => '<input type="checkbox" onclick="invertAll(this, this.form);" class="input_check" />',
Chris@76 450 ),
Chris@76 451 'data' => array(
Chris@76 452 'sprintf' => array(
Chris@76 453 'format' => '<input type="checkbox" name="remove[%1$d]" class="input_check" />',
Chris@76 454 'params' => array(
Chris@76 455 'id_attach' => false,
Chris@76 456 ),
Chris@76 457 ),
Chris@76 458 'style' => 'text-align: center',
Chris@76 459 ),
Chris@76 460 ),
Chris@76 461 ),
Chris@76 462 'form' => array(
Chris@76 463 'href' => $scripturl . '?action=admin;area=manageattachments;sa=remove' . ($context['browse_type'] === 'avatars' ? ';avatars' : ($context['browse_type'] === 'thumbs' ? ';thumbs' : '')),
Chris@76 464 'include_sort' => true,
Chris@76 465 'include_start' => true,
Chris@76 466 'hidden_fields' => array(
Chris@76 467 'type' => $context['browse_type'],
Chris@76 468 ),
Chris@76 469 ),
Chris@76 470 'additional_rows' => array(
Chris@76 471 array(
Chris@76 472 'position' => 'below_table_data',
Chris@76 473 'value' => '<input type="submit" name="remove_submit" class="button_submit" value="' . $txt['quickmod_delete_selected'] . '" onclick="return confirm(\'' . $txt['confirm_delete_attachments'] . '\');" />',
Chris@76 474 'style' => 'text-align: right;',
Chris@76 475 ),
Chris@76 476 ),
Chris@76 477 );
Chris@76 478
Chris@76 479 // Create the list.
Chris@76 480 require_once($sourcedir . '/Subs-List.php');
Chris@76 481 createList($listOptions);
Chris@76 482 }
Chris@76 483
Chris@76 484 function list_getFiles($start, $items_per_page, $sort, $browse_type)
Chris@76 485 {
Chris@76 486 global $smcFunc, $txt;
Chris@76 487
Chris@76 488 // Choose a query depending on what we are viewing.
Chris@76 489 if ($browse_type === 'avatars')
Chris@76 490 $request = $smcFunc['db_query']('', '
Chris@76 491 SELECT
Chris@76 492 {string:blank_text} AS id_msg, IFNULL(mem.real_name, {string:not_applicable_text}) AS poster_name,
Chris@76 493 mem.last_login AS poster_time, 0 AS id_topic, a.id_member, a.id_attach, a.filename, a.file_hash, a.attachment_type,
Chris@76 494 a.size, a.width, a.height, a.downloads, {string:blank_text} AS subject, 0 AS id_board
Chris@76 495 FROM {db_prefix}attachments AS a
Chris@76 496 LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = a.id_member)
Chris@76 497 WHERE a.id_member != {int:guest_id}
Chris@76 498 ORDER BY {raw:sort}
Chris@76 499 LIMIT {int:start}, {int:per_page}',
Chris@76 500 array(
Chris@76 501 'guest_id' => 0,
Chris@76 502 'blank_text' => '',
Chris@76 503 'not_applicable_text' => $txt['not_applicable'],
Chris@76 504 'sort' => $sort,
Chris@76 505 'start' => $start,
Chris@76 506 'per_page' => $items_per_page,
Chris@76 507 )
Chris@76 508 );
Chris@76 509 else
Chris@76 510 $request = $smcFunc['db_query']('', '
Chris@76 511 SELECT
Chris@76 512 m.id_msg, IFNULL(mem.real_name, m.poster_name) AS poster_name, m.poster_time, m.id_topic, m.id_member,
Chris@76 513 a.id_attach, a.filename, a.file_hash, a.attachment_type, a.size, a.width, a.height, a.downloads, mf.subject, t.id_board
Chris@76 514 FROM {db_prefix}attachments AS a
Chris@76 515 INNER JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg)
Chris@76 516 INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
Chris@76 517 INNER JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)
Chris@76 518 LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
Chris@76 519 WHERE a.attachment_type = {int:attachment_type}
Chris@76 520 ORDER BY {raw:sort}
Chris@76 521 LIMIT {int:start}, {int:per_page}',
Chris@76 522 array(
Chris@76 523 'attachment_type' => $browse_type == 'thumbs' ? '3' : '0',
Chris@76 524 'sort' => $sort,
Chris@76 525 'start' => $start,
Chris@76 526 'per_page' => $items_per_page,
Chris@76 527 )
Chris@76 528 );
Chris@76 529 $files = array();
Chris@76 530 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 531 $files[] = $row;
Chris@76 532 $smcFunc['db_free_result']($request);
Chris@76 533
Chris@76 534 return $files;
Chris@76 535 }
Chris@76 536
Chris@76 537 function list_getNumFiles($browse_type)
Chris@76 538 {
Chris@76 539 global $smcFunc;
Chris@76 540
Chris@76 541 // Depending on the type of file, different queries are used.
Chris@76 542 if ($browse_type === 'avatars')
Chris@76 543 $request = $smcFunc['db_query']('', '
Chris@76 544 SELECT COUNT(*)
Chris@76 545 FROM {db_prefix}attachments
Chris@76 546 WHERE id_member != {int:guest_id_member}',
Chris@76 547 array(
Chris@76 548 'guest_id_member' => 0,
Chris@76 549 )
Chris@76 550 );
Chris@76 551 else
Chris@76 552 $request = $smcFunc['db_query']('', '
Chris@76 553 SELECT COUNT(*) AS num_attach
Chris@76 554 FROM {db_prefix}attachments AS a
Chris@76 555 INNER JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg)
Chris@76 556 INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
Chris@76 557 INNER JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)
Chris@76 558 WHERE a.attachment_type = {int:attachment_type}
Chris@76 559 AND a.id_member = {int:guest_id_member}',
Chris@76 560 array(
Chris@76 561 'attachment_type' => $browse_type === 'thumbs' ? '3' : '0',
Chris@76 562 'guest_id_member' => 0,
Chris@76 563 )
Chris@76 564 );
Chris@76 565
Chris@76 566 list ($num_files) = $smcFunc['db_fetch_row']($request);
Chris@76 567 $smcFunc['db_free_result']($request);
Chris@76 568
Chris@76 569 return $num_files;
Chris@76 570 }
Chris@76 571
Chris@76 572 function MaintainFiles()
Chris@76 573 {
Chris@76 574 global $context, $modSettings, $txt, $smcFunc;
Chris@76 575
Chris@76 576 $context['sub_template'] = 'maintenance';
Chris@76 577
Chris@76 578 if (!empty($modSettings['currentAttachmentUploadDir']))
Chris@76 579 $attach_dirs = unserialize($modSettings['attachmentUploadDir']);
Chris@76 580 else
Chris@76 581 $attach_dirs = array($modSettings['attachmentUploadDir']);
Chris@76 582
Chris@76 583 // Get the number of attachments....
Chris@76 584 $request = $smcFunc['db_query']('', '
Chris@76 585 SELECT COUNT(*)
Chris@76 586 FROM {db_prefix}attachments
Chris@76 587 WHERE attachment_type = {int:attachment_type}
Chris@76 588 AND id_member = {int:guest_id_member}',
Chris@76 589 array(
Chris@76 590 'attachment_type' => 0,
Chris@76 591 'guest_id_member' => 0,
Chris@76 592 )
Chris@76 593 );
Chris@76 594 list ($context['num_attachments']) = $smcFunc['db_fetch_row']($request);
Chris@76 595 $smcFunc['db_free_result']($request);
Chris@76 596
Chris@76 597 // Also get the avatar amount....
Chris@76 598 $request = $smcFunc['db_query']('', '
Chris@76 599 SELECT COUNT(*)
Chris@76 600 FROM {db_prefix}attachments
Chris@76 601 WHERE id_member != {int:guest_id_member}',
Chris@76 602 array(
Chris@76 603 'guest_id_member' => 0,
Chris@76 604 )
Chris@76 605 );
Chris@76 606 list ($context['num_avatars']) = $smcFunc['db_fetch_row']($request);
Chris@76 607 $smcFunc['db_free_result']($request);
Chris@76 608
Chris@76 609 // Find out how big the directory is. We have to loop through all our attachment paths in case there's an old temp file in one of them.
Chris@76 610 $attachmentDirSize = 0;
Chris@76 611 foreach ($attach_dirs as $id => $attach_dir)
Chris@76 612 {
Chris@76 613 $dir = @opendir($attach_dir) or fatal_lang_error('cant_access_upload_path', 'critical');
Chris@76 614 while ($file = readdir($dir))
Chris@76 615 {
Chris@76 616 if ($file == '.' || $file == '..')
Chris@76 617 continue;
Chris@76 618
Chris@76 619 if (preg_match('~^post_tmp_\d+_\d+$~', $file) != 0)
Chris@76 620 {
Chris@76 621 // Temp file is more than 5 hours old!
Chris@76 622 if (filemtime($attach_dir . '/' . $file) < time() - 18000)
Chris@76 623 @unlink($attach_dir . '/' . $file);
Chris@76 624 continue;
Chris@76 625 }
Chris@76 626
Chris@76 627 // We're only counting the size of the current attachment directory.
Chris@76 628 if (empty($modSettings['currentAttachmentUploadDir']) || $modSettings['currentAttachmentUploadDir'] == $id)
Chris@76 629 $attachmentDirSize += filesize($attach_dir . '/' . $file);
Chris@76 630 }
Chris@76 631 closedir($dir);
Chris@76 632 }
Chris@76 633 // Divide it into kilobytes.
Chris@76 634 $attachmentDirSize /= 1024;
Chris@76 635
Chris@76 636 // If they specified a limit only....
Chris@76 637 if (!empty($modSettings['attachmentDirSizeLimit']))
Chris@76 638 $context['attachment_space'] = max(round($modSettings['attachmentDirSizeLimit'] - $attachmentDirSize, 2), 0);
Chris@76 639 $context['attachment_total_size'] = round($attachmentDirSize, 2);
Chris@76 640
Chris@76 641 $context['attach_multiple_dirs'] = !empty($modSettings['currentAttachmentUploadDir']);
Chris@76 642 }
Chris@76 643
Chris@76 644 // !!! Not implemented yet.
Chris@76 645 function MoveAvatars()
Chris@76 646 {
Chris@76 647 global $modSettings, $smcFunc;
Chris@76 648
Chris@76 649 // First make sure the custom avatar dir is writable.
Chris@76 650 if (!is_writable($modSettings['custom_avatar_dir']))
Chris@76 651 {
Chris@76 652 // Try to fix it.
Chris@76 653 @chmod($modSettings['custom_avatar_dir'], 0777);
Chris@76 654
Chris@76 655 // Guess that didn't work?
Chris@76 656 if (!is_writable($modSettings['custom_avatar_dir']))
Chris@76 657 fatal_lang_error('attachments_no_write', 'critical');
Chris@76 658 }
Chris@76 659
Chris@76 660 $request = $smcFunc['db_query']('', '
Chris@76 661 SELECT id_attach, id_folder, id_member, filename, file_hash
Chris@76 662 FROM {db_prefix}attachments
Chris@76 663 WHERE attachment_type = {int:attachment_type}
Chris@76 664 AND id_member > {int:guest_id_member}',
Chris@76 665 array(
Chris@76 666 'attachment_type' => 0,
Chris@76 667 'guest_id_member' => 0,
Chris@76 668 )
Chris@76 669 );
Chris@76 670 $updatedAvatars = array();
Chris@76 671 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 672 {
Chris@76 673 $filename = getAttachmentFilename($row['filename'], $row['id_attach'], $row['id_folder'], false, $row['file_hash']);
Chris@76 674
Chris@76 675 if (rename($filename, $modSettings['custom_avatar_dir'] . '/' . $row['filename']))
Chris@76 676 $updatedAvatars[] = $row['id_attach'];
Chris@76 677 }
Chris@76 678 $smcFunc['db_free_result']($request);
Chris@76 679
Chris@76 680 if (!empty($updatedAvatars))
Chris@76 681 $smcFunc['db_query']('', '
Chris@76 682 UPDATE {db_prefix}attachments
Chris@76 683 SET attachment_type = {int:attachment_type}
Chris@76 684 WHERE id_attach IN ({array_int:updated_avatars})',
Chris@76 685 array(
Chris@76 686 'updated_avatars' => $updatedAvatars,
Chris@76 687 'attachment_type' => 1,
Chris@76 688 )
Chris@76 689 );
Chris@76 690
Chris@76 691 redirectexit('action=admin;area=manageattachments;sa=maintenance');
Chris@76 692 }
Chris@76 693
Chris@76 694 function RemoveAttachmentByAge()
Chris@76 695 {
Chris@76 696 global $modSettings, $smcFunc;
Chris@76 697
Chris@76 698 checkSession('post', 'admin');
Chris@76 699
Chris@76 700 // !!! Ignore messages in topics that are stickied?
Chris@76 701
Chris@76 702 // Deleting an attachment?
Chris@76 703 if ($_REQUEST['type'] != 'avatars')
Chris@76 704 {
Chris@76 705 // Get all the old attachments.
Chris@76 706 $messages = removeAttachments(array('attachment_type' => 0, 'poster_time' => (time() - 24 * 60 * 60 * $_POST['age'])), 'messages', true);
Chris@76 707
Chris@76 708 // Update the messages to reflect the change.
Chris@76 709 if (!empty($messages))
Chris@76 710 $smcFunc['db_query']('', '
Chris@76 711 UPDATE {db_prefix}messages
Chris@76 712 SET body = CONCAT(body, ' . (!empty($_POST['notice']) ? '{string:notice}' : '') . ')
Chris@76 713 WHERE id_msg IN ({array_int:messages})',
Chris@76 714 array(
Chris@76 715 'messages' => $messages,
Chris@76 716 'notice' => empty($_POST['notice']) ? '' : '<br /><br />' . $_POST['notice'],
Chris@76 717 )
Chris@76 718 );
Chris@76 719 }
Chris@76 720 else
Chris@76 721 {
Chris@76 722 // Remove all the old avatars.
Chris@76 723 removeAttachments(array('not_id_member' => 0, 'last_login' => (time() - 24 * 60 * 60 * $_POST['age'])), 'members');
Chris@76 724 }
Chris@76 725 redirectexit('action=admin;area=manageattachments' . (empty($_REQUEST['avatars']) ? ';sa=maintenance' : ';avatars'));
Chris@76 726 }
Chris@76 727
Chris@76 728 function RemoveAttachmentBySize()
Chris@76 729 {
Chris@76 730 global $modSettings, $smcFunc;
Chris@76 731
Chris@76 732 checkSession('post', 'admin');
Chris@76 733
Chris@76 734 // Find humungous attachments.
Chris@76 735 $messages = removeAttachments(array('attachment_type' => 0, 'size' => 1024 * $_POST['size']), 'messages', true);
Chris@76 736
Chris@76 737 // And make a note on the post.
Chris@76 738 if (!empty($messages))
Chris@76 739 $smcFunc['db_query']('', '
Chris@76 740 UPDATE {db_prefix}messages
Chris@76 741 SET body = CONCAT(body, ' . (!empty($_POST['notice']) ? '{string:notice}' : '') . ')
Chris@76 742 WHERE id_msg IN ({array_int:messages})',
Chris@76 743 array(
Chris@76 744 'messages' => $messages,
Chris@76 745 'notice' => empty($_POST['notice']) ? '' : '<br /><br />' . $_POST['notice'],
Chris@76 746 )
Chris@76 747 );
Chris@76 748
Chris@76 749 redirectexit('action=admin;area=manageattachments;sa=maintenance');
Chris@76 750 }
Chris@76 751
Chris@76 752 function RemoveAttachment()
Chris@76 753 {
Chris@76 754 global $modSettings, $txt, $smcFunc;
Chris@76 755
Chris@76 756 checkSession('post');
Chris@76 757
Chris@76 758 if (!empty($_POST['remove']))
Chris@76 759 {
Chris@76 760 $attachments = array();
Chris@76 761 // There must be a quicker way to pass this safety test??
Chris@76 762 foreach ($_POST['remove'] as $removeID => $dummy)
Chris@76 763 $attachments[] = (int) $removeID;
Chris@76 764
Chris@76 765 if ($_REQUEST['type'] == 'avatars' && !empty($attachments))
Chris@76 766 removeAttachments(array('id_attach' => $attachments));
Chris@76 767 else if (!empty($attachments))
Chris@76 768 {
Chris@76 769 $messages = removeAttachments(array('id_attach' => $attachments), 'messages', true);
Chris@76 770
Chris@76 771 // And change the message to reflect this.
Chris@76 772 if (!empty($messages))
Chris@76 773 $smcFunc['db_query']('', '
Chris@76 774 UPDATE {db_prefix}messages
Chris@76 775 SET body = CONCAT(body, {string:deleted_message})
Chris@76 776 WHERE id_msg IN ({array_int:messages_affected})',
Chris@76 777 array(
Chris@76 778 'messages_affected' => $messages,
Chris@76 779 'deleted_message' => '<br /><br />' . $txt['attachment_delete_admin'],
Chris@76 780 )
Chris@76 781 );
Chris@76 782 }
Chris@76 783 }
Chris@76 784
Chris@76 785 $_GET['sort'] = isset($_GET['sort']) ? $_GET['sort'] : 'date';
Chris@76 786 redirectexit('action=admin;area=manageattachments;sa=browse;' . $_REQUEST['type'] . ';sort=' . $_GET['sort'] . (isset($_GET['desc']) ? ';desc' : '') . ';start=' . $_REQUEST['start']);
Chris@76 787 }
Chris@76 788
Chris@76 789 // !!! Not implemented (yet?)
Chris@76 790 function RemoveAllAttachments()
Chris@76 791 {
Chris@76 792 global $txt, $smcFunc;
Chris@76 793
Chris@76 794 checkSession('get', 'admin');
Chris@76 795
Chris@76 796 $messages = removeAttachments(array('attachment_type' => 0), '', true);
Chris@76 797
Chris@76 798 if (!isset($_POST['notice']))
Chris@76 799 $_POST['notice'] = $txt['attachment_delete_admin'];
Chris@76 800
Chris@76 801 // Add the notice on the end of the changed messages.
Chris@76 802 if (!empty($messages))
Chris@76 803 $smcFunc['db_query']('', '
Chris@76 804 UPDATE {db_prefix}messages
Chris@76 805 SET body = CONCAT(body, {string:deleted_message})
Chris@76 806 WHERE id_msg IN ({array_int:messages})',
Chris@76 807 array(
Chris@76 808 'messages' => $messages,
Chris@76 809 'deleted_message' => '<br /><br />' . $_POST['notice'],
Chris@76 810 )
Chris@76 811 );
Chris@76 812
Chris@76 813 redirectexit('action=admin;area=manageattachments;sa=maintenance');
Chris@76 814 }
Chris@76 815
Chris@76 816 // Removes attachments - allowed query_types: '', 'messages', 'members'
Chris@76 817 function removeAttachments($condition, $query_type = '', $return_affected_messages = false, $autoThumbRemoval = true)
Chris@76 818 {
Chris@76 819 global $modSettings, $smcFunc;
Chris@76 820
Chris@76 821 //!!! This might need more work!
Chris@76 822 $new_condition = array();
Chris@76 823 $query_parameter = array(
Chris@76 824 'thumb_attachment_type' => 3,
Chris@76 825 );
Chris@76 826
Chris@76 827 if (is_array($condition))
Chris@76 828 {
Chris@76 829 foreach ($condition as $real_type => $restriction)
Chris@76 830 {
Chris@76 831 // Doing a NOT?
Chris@76 832 $is_not = substr($real_type, 0, 4) == 'not_';
Chris@76 833 $type = $is_not ? substr($real_type, 4) : $real_type;
Chris@76 834
Chris@76 835 if (in_array($type, array('id_member', 'id_attach', 'id_msg')))
Chris@76 836 $new_condition[] = 'a.' . $type . ($is_not ? ' NOT' : '') . ' IN (' . (is_array($restriction) ? '{array_int:' . $real_type . '}' : '{int:' . $real_type . '}') . ')';
Chris@76 837 elseif ($type == 'attachment_type')
Chris@76 838 $new_condition[] = 'a.attachment_type = {int:' . $real_type . '}';
Chris@76 839 elseif ($type == 'poster_time')
Chris@76 840 $new_condition[] = 'm.poster_time < {int:' . $real_type . '}';
Chris@76 841 elseif ($type == 'last_login')
Chris@76 842 $new_condition[] = 'mem.last_login < {int:' . $real_type . '}';
Chris@76 843 elseif ($type == 'size')
Chris@76 844 $new_condition[] = 'a.size > {int:' . $real_type . '}';
Chris@76 845 elseif ($type == 'id_topic')
Chris@76 846 $new_condition[] = 'm.id_topic IN (' . (is_array($restriction) ? '{array_int:' . $real_type . '}' : '{int:' . $real_type . '}') . ')';
Chris@76 847
Chris@76 848 // Add the parameter!
Chris@76 849 $query_parameter[$real_type] = $restriction;
Chris@76 850 }
Chris@76 851 $condition = implode(' AND ', $new_condition);
Chris@76 852 }
Chris@76 853
Chris@76 854 // Delete it only if it exists...
Chris@76 855 $msgs = array();
Chris@76 856 $attach = array();
Chris@76 857 $parents = array();
Chris@76 858
Chris@76 859 // Get all the attachment names and id_msg's.
Chris@76 860 $request = $smcFunc['db_query']('', '
Chris@76 861 SELECT
Chris@76 862 a.id_folder, a.filename, a.file_hash, a.attachment_type, a.id_attach, a.id_member' . ($query_type == 'messages' ? ', m.id_msg' : ', a.id_msg') . ',
Chris@76 863 thumb.id_folder AS thumb_folder, IFNULL(thumb.id_attach, 0) AS id_thumb, thumb.filename AS thumb_filename, thumb.file_hash AS thumb_file_hash, thumb_parent.id_attach AS id_parent
Chris@76 864 FROM {db_prefix}attachments AS a' .($query_type == 'members' ? '
Chris@76 865 INNER JOIN {db_prefix}members AS mem ON (mem.id_member = a.id_member)' : ($query_type == 'messages' ? '
Chris@76 866 INNER JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg)' : '')) . '
Chris@76 867 LEFT JOIN {db_prefix}attachments AS thumb ON (thumb.id_attach = a.id_thumb)
Chris@76 868 LEFT JOIN {db_prefix}attachments AS thumb_parent ON (thumb.attachment_type = {int:thumb_attachment_type} AND thumb_parent.id_thumb = a.id_attach)
Chris@76 869 WHERE ' . $condition,
Chris@76 870 $query_parameter
Chris@76 871 );
Chris@76 872 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 873 {
Chris@76 874 // Figure out the "encrypted" filename and unlink it ;).
Chris@76 875 if ($row['attachment_type'] == 1)
Chris@76 876 @unlink($modSettings['custom_avatar_dir'] . '/' . $row['filename']);
Chris@76 877 else
Chris@76 878 {
Chris@76 879 $filename = getAttachmentFilename($row['filename'], $row['id_attach'], $row['id_folder'], false, $row['file_hash']);
Chris@76 880 @unlink($filename);
Chris@76 881
Chris@76 882 // If this was a thumb, the parent attachment should know about it.
Chris@76 883 if (!empty($row['id_parent']))
Chris@76 884 $parents[] = $row['id_parent'];
Chris@76 885
Chris@76 886 // If this attachments has a thumb, remove it as well.
Chris@76 887 if (!empty($row['id_thumb']) && $autoThumbRemoval)
Chris@76 888 {
Chris@76 889 $thumb_filename = getAttachmentFilename($row['thumb_filename'], $row['id_thumb'], $row['thumb_folder'], false, $row['thumb_file_hash']);
Chris@76 890 @unlink($thumb_filename);
Chris@76 891 $attach[] = $row['id_thumb'];
Chris@76 892 }
Chris@76 893 }
Chris@76 894
Chris@76 895 // Make a list.
Chris@76 896 if ($return_affected_messages && empty($row['attachment_type']))
Chris@76 897 $msgs[] = $row['id_msg'];
Chris@76 898 $attach[] = $row['id_attach'];
Chris@76 899 }
Chris@76 900 $smcFunc['db_free_result']($request);
Chris@76 901
Chris@76 902 // Removed attachments don't have to be updated anymore.
Chris@76 903 $parents = array_diff($parents, $attach);
Chris@76 904 if (!empty($parents))
Chris@76 905 $smcFunc['db_query']('', '
Chris@76 906 UPDATE {db_prefix}attachments
Chris@76 907 SET id_thumb = {int:no_thumb}
Chris@76 908 WHERE id_attach IN ({array_int:parent_attachments})',
Chris@76 909 array(
Chris@76 910 'parent_attachments' => $parents,
Chris@76 911 'no_thumb' => 0,
Chris@76 912 )
Chris@76 913 );
Chris@76 914
Chris@76 915 if (!empty($attach))
Chris@76 916 $smcFunc['db_query']('', '
Chris@76 917 DELETE FROM {db_prefix}attachments
Chris@76 918 WHERE id_attach IN ({array_int:attachment_list})',
Chris@76 919 array(
Chris@76 920 'attachment_list' => $attach,
Chris@76 921 )
Chris@76 922 );
Chris@76 923
Chris@76 924 if ($return_affected_messages)
Chris@76 925 return array_unique($msgs);
Chris@76 926 }
Chris@76 927
Chris@76 928 // This function should find attachments in the database that no longer exist and clear them, and fix filesize issues.
Chris@76 929 function RepairAttachments()
Chris@76 930 {
Chris@76 931 global $modSettings, $context, $txt, $smcFunc;
Chris@76 932
Chris@76 933 checkSession('get');
Chris@76 934
Chris@76 935 // If we choose cancel, redirect right back.
Chris@76 936 if (isset($_POST['cancel']))
Chris@76 937 redirectexit('action=admin;area=manageattachments;sa=maintenance');
Chris@76 938
Chris@76 939 // Try give us a while to sort this out...
Chris@76 940 @set_time_limit(600);
Chris@76 941
Chris@76 942 $_GET['step'] = empty($_GET['step']) ? 0 : (int) $_GET['step'];
Chris@76 943 $_GET['substep'] = empty($_GET['substep']) ? 0 : (int) $_GET['substep'];
Chris@76 944
Chris@76 945 // Don't recall the session just in case.
Chris@76 946 if ($_GET['step'] == 0 && $_GET['substep'] == 0)
Chris@76 947 {
Chris@76 948 unset($_SESSION['attachments_to_fix'], $_SESSION['attachments_to_fix2']);
Chris@76 949
Chris@76 950 // If we're actually fixing stuff - work out what.
Chris@76 951 if (isset($_GET['fixErrors']))
Chris@76 952 {
Chris@76 953 // Nothing?
Chris@76 954 if (empty($_POST['to_fix']))
Chris@76 955 redirectexit('action=admin;area=manageattachments;sa=maintenance');
Chris@76 956
Chris@76 957 $_SESSION['attachments_to_fix'] = array();
Chris@76 958 //!!! No need to do this I think.
Chris@76 959 foreach ($_POST['to_fix'] as $key => $value)
Chris@76 960 $_SESSION['attachments_to_fix'][] = $value;
Chris@76 961 }
Chris@76 962 }
Chris@76 963
Chris@76 964 // All the valid problems are here:
Chris@76 965 $context['repair_errors'] = array(
Chris@76 966 'missing_thumbnail_parent' => 0,
Chris@76 967 'parent_missing_thumbnail' => 0,
Chris@76 968 'file_missing_on_disk' => 0,
Chris@76 969 'file_wrong_size' => 0,
Chris@76 970 'file_size_of_zero' => 0,
Chris@76 971 'attachment_no_msg' => 0,
Chris@76 972 'avatar_no_member' => 0,
Chris@76 973 'wrong_folder' => 0,
Chris@76 974 );
Chris@76 975
Chris@76 976 $to_fix = !empty($_SESSION['attachments_to_fix']) ? $_SESSION['attachments_to_fix'] : array();
Chris@76 977 $context['repair_errors'] = isset($_SESSION['attachments_to_fix2']) ? $_SESSION['attachments_to_fix2'] : $context['repair_errors'];
Chris@76 978 $fix_errors = isset($_GET['fixErrors']) ? true : false;
Chris@76 979
Chris@76 980 // Get stranded thumbnails.
Chris@76 981 if ($_GET['step'] <= 0)
Chris@76 982 {
Chris@76 983 $result = $smcFunc['db_query']('', '
Chris@76 984 SELECT MAX(id_attach)
Chris@76 985 FROM {db_prefix}attachments
Chris@76 986 WHERE attachment_type = {int:thumbnail}',
Chris@76 987 array(
Chris@76 988 'thumbnail' => 3,
Chris@76 989 )
Chris@76 990 );
Chris@76 991 list ($thumbnails) = $smcFunc['db_fetch_row']($result);
Chris@76 992 $smcFunc['db_free_result']($result);
Chris@76 993
Chris@76 994 for (; $_GET['substep'] < $thumbnails; $_GET['substep'] += 500)
Chris@76 995 {
Chris@76 996 $to_remove = array();
Chris@76 997
Chris@76 998 $result = $smcFunc['db_query']('', '
Chris@76 999 SELECT thumb.id_attach, thumb.id_folder, thumb.filename, thumb.file_hash
Chris@76 1000 FROM {db_prefix}attachments AS thumb
Chris@76 1001 LEFT JOIN {db_prefix}attachments AS tparent ON (tparent.id_thumb = thumb.id_attach)
Chris@76 1002 WHERE thumb.id_attach BETWEEN {int:substep} AND {int:substep} + 499
Chris@76 1003 AND thumb.attachment_type = {int:thumbnail}
Chris@76 1004 AND tparent.id_attach IS NULL',
Chris@76 1005 array(
Chris@76 1006 'thumbnail' => 3,
Chris@76 1007 'substep' => $_GET['substep'],
Chris@76 1008 )
Chris@76 1009 );
Chris@76 1010 while ($row = $smcFunc['db_fetch_assoc']($result))
Chris@76 1011 {
Chris@76 1012 // Only do anything once... just in case
Chris@76 1013 if (!isset($to_remove[$row['id_attach']]))
Chris@76 1014 {
Chris@76 1015 $to_remove[$row['id_attach']] = $row['id_attach'];
Chris@76 1016 $context['repair_errors']['missing_thumbnail_parent']++;
Chris@76 1017
Chris@76 1018 // If we are repairing remove the file from disk now.
Chris@76 1019 if ($fix_errors && in_array('missing_thumbnail_parent', $to_fix))
Chris@76 1020 {
Chris@76 1021 $filename = getAttachmentFilename($row['filename'], $row['id_attach'], $row['id_folder'], false, $row['file_hash']);
Chris@76 1022 @unlink($filename);
Chris@76 1023 }
Chris@76 1024 }
Chris@76 1025 }
Chris@76 1026 if ($smcFunc['db_num_rows']($result) != 0)
Chris@76 1027 $to_fix[] = 'missing_thumbnail_parent';
Chris@76 1028 $smcFunc['db_free_result']($result);
Chris@76 1029
Chris@76 1030 // Do we need to delete what we have?
Chris@76 1031 if ($fix_errors && !empty($to_remove) && in_array('missing_thumbnail_parent', $to_fix))
Chris@76 1032 $smcFunc['db_query']('', '
Chris@76 1033 DELETE FROM {db_prefix}attachments
Chris@76 1034 WHERE id_attach IN ({array_int:to_remove})
Chris@76 1035 AND attachment_type = {int:attachment_type}',
Chris@76 1036 array(
Chris@76 1037 'to_remove' => $to_remove,
Chris@76 1038 'attachment_type' => 3,
Chris@76 1039 )
Chris@76 1040 );
Chris@76 1041
Chris@76 1042 pauseAttachmentMaintenance($to_fix, $thumbnails);
Chris@76 1043 }
Chris@76 1044
Chris@76 1045 $_GET['step'] = 1;
Chris@76 1046 $_GET['substep'] = 0;
Chris@76 1047 pauseAttachmentMaintenance($to_fix);
Chris@76 1048 }
Chris@76 1049
Chris@76 1050 // Find parents which think they have thumbnails, but actually, don't.
Chris@76 1051 if ($_GET['step'] <= 1)
Chris@76 1052 {
Chris@76 1053 $result = $smcFunc['db_query']('', '
Chris@76 1054 SELECT MAX(id_attach)
Chris@76 1055 FROM {db_prefix}attachments
Chris@76 1056 WHERE id_thumb != {int:no_thumb}',
Chris@76 1057 array(
Chris@76 1058 'no_thumb' => 0,
Chris@76 1059 )
Chris@76 1060 );
Chris@76 1061 list ($thumbnails) = $smcFunc['db_fetch_row']($result);
Chris@76 1062 $smcFunc['db_free_result']($result);
Chris@76 1063
Chris@76 1064 for (; $_GET['substep'] < $thumbnails; $_GET['substep'] += 500)
Chris@76 1065 {
Chris@76 1066 $to_update = array();
Chris@76 1067
Chris@76 1068 $result = $smcFunc['db_query']('', '
Chris@76 1069 SELECT a.id_attach
Chris@76 1070 FROM {db_prefix}attachments AS a
Chris@76 1071 LEFT JOIN {db_prefix}attachments AS thumb ON (thumb.id_attach = a.id_thumb)
Chris@76 1072 WHERE a.id_attach BETWEEN {int:substep} AND {int:substep} + 499
Chris@76 1073 AND a.id_thumb != {int:no_thumb}
Chris@76 1074 AND thumb.id_attach IS NULL',
Chris@76 1075 array(
Chris@76 1076 'no_thumb' => 0,
Chris@76 1077 'substep' => $_GET['substep'],
Chris@76 1078 )
Chris@76 1079 );
Chris@76 1080 while ($row = $smcFunc['db_fetch_assoc']($result))
Chris@76 1081 {
Chris@76 1082 $to_update[] = $row['id_attach'];
Chris@76 1083 $context['repair_errors']['parent_missing_thumbnail']++;
Chris@76 1084 }
Chris@76 1085 if ($smcFunc['db_num_rows']($result) != 0)
Chris@76 1086 $to_fix[] = 'parent_missing_thumbnail';
Chris@76 1087 $smcFunc['db_free_result']($result);
Chris@76 1088
Chris@76 1089 // Do we need to delete what we have?
Chris@76 1090 if ($fix_errors && !empty($to_update) && in_array('parent_missing_thumbnail', $to_fix))
Chris@76 1091 $smcFunc['db_query']('', '
Chris@76 1092 UPDATE {db_prefix}attachments
Chris@76 1093 SET id_thumb = {int:no_thumb}
Chris@76 1094 WHERE id_attach IN ({array_int:to_update})',
Chris@76 1095 array(
Chris@76 1096 'to_update' => $to_update,
Chris@76 1097 'no_thumb' => 0,
Chris@76 1098 )
Chris@76 1099 );
Chris@76 1100
Chris@76 1101 pauseAttachmentMaintenance($to_fix, $thumbnails);
Chris@76 1102 }
Chris@76 1103
Chris@76 1104 $_GET['step'] = 2;
Chris@76 1105 $_GET['substep'] = 0;
Chris@76 1106 pauseAttachmentMaintenance($to_fix);
Chris@76 1107 }
Chris@76 1108
Chris@76 1109 // This may take forever I'm afraid, but life sucks... recount EVERY attachments!
Chris@76 1110 if ($_GET['step'] <= 2)
Chris@76 1111 {
Chris@76 1112 $result = $smcFunc['db_query']('', '
Chris@76 1113 SELECT MAX(id_attach)
Chris@76 1114 FROM {db_prefix}attachments',
Chris@76 1115 array(
Chris@76 1116 )
Chris@76 1117 );
Chris@76 1118 list ($thumbnails) = $smcFunc['db_fetch_row']($result);
Chris@76 1119 $smcFunc['db_free_result']($result);
Chris@76 1120
Chris@76 1121 for (; $_GET['substep'] < $thumbnails; $_GET['substep'] += 250)
Chris@76 1122 {
Chris@76 1123 $to_remove = array();
Chris@76 1124 $errors_found = array();
Chris@76 1125
Chris@76 1126 $result = $smcFunc['db_query']('', '
Chris@76 1127 SELECT id_attach, id_folder, filename, file_hash, size, attachment_type
Chris@76 1128 FROM {db_prefix}attachments
Chris@76 1129 WHERE id_attach BETWEEN {int:substep} AND {int:substep} + 249',
Chris@76 1130 array(
Chris@76 1131 'substep' => $_GET['substep'],
Chris@76 1132 )
Chris@76 1133 );
Chris@76 1134 while ($row = $smcFunc['db_fetch_assoc']($result))
Chris@76 1135 {
Chris@76 1136 // Get the filename.
Chris@76 1137 if ($row['attachment_type'] == 1)
Chris@76 1138 $filename = $modSettings['custom_avatar_dir'] . '/' . $row['filename'];
Chris@76 1139 else
Chris@76 1140 $filename = getAttachmentFilename($row['filename'], $row['id_attach'], $row['id_folder'], false, $row['file_hash']);
Chris@76 1141
Chris@76 1142 // File doesn't exist?
Chris@76 1143 if (!file_exists($filename))
Chris@76 1144 {
Chris@76 1145 // If we're lucky it might just be in a different folder.
Chris@76 1146 if (!empty($modSettings['currentAttachmentUploadDir']))
Chris@76 1147 {
Chris@76 1148 // Get the attachment name with out the folder.
Chris@76 1149 $attachment_name = !empty($row['file_hash']) ? $row['id_attach'] . '_' . $row['file_hash'] : getLegacyAttachmentFilename($row['filename'], $row['id_attach'], null, true);
Chris@76 1150
Chris@76 1151 if (!is_array($modSettings['attachmentUploadDir']))
Chris@76 1152 $modSettings['attachmentUploadDir'] = unserialize($modSettings['attachmentUploadDir']);
Chris@76 1153
Chris@76 1154 // Loop through the other folders.
Chris@76 1155 foreach ($modSettings['attachmentUploadDir'] as $id => $dir)
Chris@76 1156 if (file_exists($dir . '/' . $attachment_name))
Chris@76 1157 {
Chris@76 1158 $context['repair_errors']['wrong_folder']++;
Chris@76 1159 $errors_found[] = 'wrong_folder';
Chris@76 1160
Chris@76 1161 // Are we going to fix this now?
Chris@76 1162 if ($fix_errors && in_array('wrong_folder', $to_fix))
Chris@76 1163 $smcFunc['db_query']('', '
Chris@76 1164 UPDATE {db_prefix}attachments
Chris@76 1165 SET id_folder = {int:new_folder}
Chris@76 1166 WHERE id_attach = {int:id_attach}',
Chris@76 1167 array(
Chris@76 1168 'new_folder' => $id,
Chris@76 1169 'id_attach' => $row['id_attach'],
Chris@76 1170 )
Chris@76 1171 );
Chris@76 1172
Chris@76 1173 continue 2;
Chris@76 1174 }
Chris@76 1175 }
Chris@76 1176
Chris@76 1177 $to_remove[] = $row['id_attach'];
Chris@76 1178 $context['repair_errors']['file_missing_on_disk']++;
Chris@76 1179 $errors_found[] = 'file_missing_on_disk';
Chris@76 1180 }
Chris@76 1181 elseif (filesize($filename) == 0)
Chris@76 1182 {
Chris@76 1183 $context['repair_errors']['file_size_of_zero']++;
Chris@76 1184 $errors_found[] = 'file_size_of_zero';
Chris@76 1185
Chris@76 1186 // Fixing?
Chris@76 1187 if ($fix_errors && in_array('file_size_of_zero', $to_fix))
Chris@76 1188 {
Chris@76 1189 $to_remove[] = $row['id_attach'];
Chris@76 1190 @unlink($filename);
Chris@76 1191 }
Chris@76 1192 }
Chris@76 1193 elseif (filesize($filename) != $row['size'])
Chris@76 1194 {
Chris@76 1195 $context['repair_errors']['file_wrong_size']++;
Chris@76 1196 $errors_found[] = 'file_wrong_size';
Chris@76 1197
Chris@76 1198 // Fix it here?
Chris@76 1199 if ($fix_errors && in_array('file_wrong_size', $to_fix))
Chris@76 1200 {
Chris@76 1201 $smcFunc['db_query']('', '
Chris@76 1202 UPDATE {db_prefix}attachments
Chris@76 1203 SET size = {int:filesize}
Chris@76 1204 WHERE id_attach = {int:id_attach}',
Chris@76 1205 array(
Chris@76 1206 'filesize' => filesize($filename),
Chris@76 1207 'id_attach' => $row['id_attach'],
Chris@76 1208 )
Chris@76 1209 );
Chris@76 1210 }
Chris@76 1211 }
Chris@76 1212 }
Chris@76 1213
Chris@76 1214 if (in_array('file_missing_on_disk', $errors_found))
Chris@76 1215 $to_fix[] = 'file_missing_on_disk';
Chris@76 1216 if (in_array('file_size_of_zero', $errors_found))
Chris@76 1217 $to_fix[] = 'file_size_of_zero';
Chris@76 1218 if (in_array('file_wrong_size', $errors_found))
Chris@76 1219 $to_fix[] = 'file_wrong_size';
Chris@76 1220 if (in_array('wrong_folder', $errors_found))
Chris@76 1221 $to_fix[] = 'wrong_folder';
Chris@76 1222 $smcFunc['db_free_result']($result);
Chris@76 1223
Chris@76 1224 // Do we need to delete what we have?
Chris@76 1225 if ($fix_errors && !empty($to_remove))
Chris@76 1226 {
Chris@76 1227 $smcFunc['db_query']('', '
Chris@76 1228 DELETE FROM {db_prefix}attachments
Chris@76 1229 WHERE id_attach IN ({array_int:to_remove})',
Chris@76 1230 array(
Chris@76 1231 'to_remove' => $to_remove,
Chris@76 1232 )
Chris@76 1233 );
Chris@76 1234 $smcFunc['db_query']('', '
Chris@76 1235 UPDATE {db_prefix}attachments
Chris@76 1236 SET id_thumb = {int:no_thumb}
Chris@76 1237 WHERE id_thumb IN ({array_int:to_remove})',
Chris@76 1238 array(
Chris@76 1239 'to_remove' => $to_remove,
Chris@76 1240 'no_thumb' => 0,
Chris@76 1241 )
Chris@76 1242 );
Chris@76 1243 }
Chris@76 1244
Chris@76 1245 pauseAttachmentMaintenance($to_fix, $thumbnails);
Chris@76 1246 }
Chris@76 1247
Chris@76 1248 $_GET['step'] = 3;
Chris@76 1249 $_GET['substep'] = 0;
Chris@76 1250 pauseAttachmentMaintenance($to_fix);
Chris@76 1251 }
Chris@76 1252
Chris@76 1253 // Get avatars with no members associated with them.
Chris@76 1254 if ($_GET['step'] <= 3)
Chris@76 1255 {
Chris@76 1256 $result = $smcFunc['db_query']('', '
Chris@76 1257 SELECT MAX(id_attach)
Chris@76 1258 FROM {db_prefix}attachments',
Chris@76 1259 array(
Chris@76 1260 )
Chris@76 1261 );
Chris@76 1262 list ($thumbnails) = $smcFunc['db_fetch_row']($result);
Chris@76 1263 $smcFunc['db_free_result']($result);
Chris@76 1264
Chris@76 1265 for (; $_GET['substep'] < $thumbnails; $_GET['substep'] += 500)
Chris@76 1266 {
Chris@76 1267 $to_remove = array();
Chris@76 1268
Chris@76 1269 $result = $smcFunc['db_query']('', '
Chris@76 1270 SELECT a.id_attach, a.id_folder, a.filename, a.file_hash, a.attachment_type
Chris@76 1271 FROM {db_prefix}attachments AS a
Chris@76 1272 LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = a.id_member)
Chris@76 1273 WHERE a.id_attach BETWEEN {int:substep} AND {int:substep} + 499
Chris@76 1274 AND a.id_member != {int:no_member}
Chris@76 1275 AND a.id_msg = {int:no_msg}
Chris@76 1276 AND mem.id_member IS NULL',
Chris@76 1277 array(
Chris@76 1278 'no_member' => 0,
Chris@76 1279 'no_msg' => 0,
Chris@76 1280 'substep' => $_GET['substep'],
Chris@76 1281 )
Chris@76 1282 );
Chris@76 1283 while ($row = $smcFunc['db_fetch_assoc']($result))
Chris@76 1284 {
Chris@76 1285 $to_remove[] = $row['id_attach'];
Chris@76 1286 $context['repair_errors']['avatar_no_member']++;
Chris@76 1287
Chris@76 1288 // If we are repairing remove the file from disk now.
Chris@76 1289 if ($fix_errors && in_array('avatar_no_member', $to_fix))
Chris@76 1290 {
Chris@76 1291 if ($row['attachment_type'] == 1)
Chris@76 1292 $filename = $modSettings['custom_avatar_dir'] . '/' . $row['filename'];
Chris@76 1293 else
Chris@76 1294 $filename = getAttachmentFilename($row['filename'], $row['id_attach'], $row['id_folder'], false, $row['file_hash']);
Chris@76 1295 @unlink($filename);
Chris@76 1296 }
Chris@76 1297 }
Chris@76 1298 if ($smcFunc['db_num_rows']($result) != 0)
Chris@76 1299 $to_fix[] = 'avatar_no_member';
Chris@76 1300 $smcFunc['db_free_result']($result);
Chris@76 1301
Chris@76 1302 // Do we need to delete what we have?
Chris@76 1303 if ($fix_errors && !empty($to_remove) && in_array('avatar_no_member', $to_fix))
Chris@76 1304 $smcFunc['db_query']('', '
Chris@76 1305 DELETE FROM {db_prefix}attachments
Chris@76 1306 WHERE id_attach IN ({array_int:to_remove})
Chris@76 1307 AND id_member != {int:no_member}
Chris@76 1308 AND id_msg = {int:no_msg}',
Chris@76 1309 array(
Chris@76 1310 'to_remove' => $to_remove,
Chris@76 1311 'no_member' => 0,
Chris@76 1312 'no_msg' => 0,
Chris@76 1313 )
Chris@76 1314 );
Chris@76 1315
Chris@76 1316 pauseAttachmentMaintenance($to_fix, $thumbnails);
Chris@76 1317 }
Chris@76 1318
Chris@76 1319 $_GET['step'] = 4;
Chris@76 1320 $_GET['substep'] = 0;
Chris@76 1321 pauseAttachmentMaintenance($to_fix);
Chris@76 1322 }
Chris@76 1323
Chris@76 1324 // What about attachments, who are missing a message :'(
Chris@76 1325 if ($_GET['step'] <= 4)
Chris@76 1326 {
Chris@76 1327 $result = $smcFunc['db_query']('', '
Chris@76 1328 SELECT MAX(id_attach)
Chris@76 1329 FROM {db_prefix}attachments',
Chris@76 1330 array(
Chris@76 1331 )
Chris@76 1332 );
Chris@76 1333 list ($thumbnails) = $smcFunc['db_fetch_row']($result);
Chris@76 1334 $smcFunc['db_free_result']($result);
Chris@76 1335
Chris@76 1336 for (; $_GET['substep'] < $thumbnails; $_GET['substep'] += 500)
Chris@76 1337 {
Chris@76 1338 $to_remove = array();
Chris@76 1339
Chris@76 1340 $result = $smcFunc['db_query']('', '
Chris@76 1341 SELECT a.id_attach, a.id_folder, a.filename, a.file_hash
Chris@76 1342 FROM {db_prefix}attachments AS a
Chris@76 1343 LEFT JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg)
Chris@76 1344 WHERE a.id_attach BETWEEN {int:substep} AND {int:substep} + 499
Chris@76 1345 AND a.id_member = {int:no_member}
Chris@76 1346 AND a.id_msg != {int:no_msg}
Chris@76 1347 AND m.id_msg IS NULL',
Chris@76 1348 array(
Chris@76 1349 'no_member' => 0,
Chris@76 1350 'no_msg' => 0,
Chris@76 1351 'substep' => $_GET['substep'],
Chris@76 1352 )
Chris@76 1353 );
Chris@76 1354 while ($row = $smcFunc['db_fetch_assoc']($result))
Chris@76 1355 {
Chris@76 1356 $to_remove[] = $row['id_attach'];
Chris@76 1357 $context['repair_errors']['attachment_no_msg']++;
Chris@76 1358
Chris@76 1359 // If we are repairing remove the file from disk now.
Chris@76 1360 if ($fix_errors && in_array('attachment_no_msg', $to_fix))
Chris@76 1361 {
Chris@76 1362 $filename = getAttachmentFilename($row['filename'], $row['id_attach'], $row['id_folder'], false, $row['file_hash']);
Chris@76 1363 @unlink($filename);
Chris@76 1364 }
Chris@76 1365 }
Chris@76 1366 if ($smcFunc['db_num_rows']($result) != 0)
Chris@76 1367 $to_fix[] = 'attachment_no_msg';
Chris@76 1368 $smcFunc['db_free_result']($result);
Chris@76 1369
Chris@76 1370 // Do we need to delete what we have?
Chris@76 1371 if ($fix_errors && !empty($to_remove) && in_array('attachment_no_msg', $to_fix))
Chris@76 1372 $smcFunc['db_query']('', '
Chris@76 1373 DELETE FROM {db_prefix}attachments
Chris@76 1374 WHERE id_attach IN ({array_int:to_remove})
Chris@76 1375 AND id_member = {int:no_member}
Chris@76 1376 AND id_msg != {int:no_msg}',
Chris@76 1377 array(
Chris@76 1378 'to_remove' => $to_remove,
Chris@76 1379 'no_member' => 0,
Chris@76 1380 'no_msg' => 0,
Chris@76 1381 )
Chris@76 1382 );
Chris@76 1383
Chris@76 1384 pauseAttachmentMaintenance($to_fix, $thumbnails);
Chris@76 1385 }
Chris@76 1386
Chris@76 1387 $_GET['step'] = 5;
Chris@76 1388 $_GET['substep'] = 0;
Chris@76 1389 pauseAttachmentMaintenance($to_fix);
Chris@76 1390 }
Chris@76 1391
Chris@76 1392 // Got here we must be doing well - just the template! :D
Chris@76 1393 $context['page_title'] = $txt['repair_attachments'];
Chris@76 1394 $context[$context['admin_menu_name']]['current_subsection'] = 'maintenance';
Chris@76 1395 $context['sub_template'] = 'attachment_repair';
Chris@76 1396
Chris@76 1397 // What stage are we at?
Chris@76 1398 $context['completed'] = $fix_errors ? true : false;
Chris@76 1399 $context['errors_found'] = !empty($to_fix) ? true : false;
Chris@76 1400
Chris@76 1401 }
Chris@76 1402
Chris@76 1403 function pauseAttachmentMaintenance($to_fix, $max_substep = 0)
Chris@76 1404 {
Chris@76 1405 global $context, $txt, $time_start;
Chris@76 1406
Chris@76 1407 // Try get more time...
Chris@76 1408 @set_time_limit(600);
Chris@76 1409 if (function_exists('apache_reset_timeout'))
Chris@76 1410 @apache_reset_timeout();
Chris@76 1411
Chris@76 1412 // Have we already used our maximum time?
Chris@76 1413 if (time() - array_sum(explode(' ', $time_start)) < 3)
Chris@76 1414 return;
Chris@76 1415
Chris@76 1416 $context['continue_get_data'] = '?action=admin;area=manageattachments;sa=repair' . (isset($_GET['fixErrors']) ? ';fixErrors' : '') . ';step=' . $_GET['step'] . ';substep=' . $_GET['substep'] . ';' . $context['session_var'] . '=' . $context['session_id'];
Chris@76 1417 $context['page_title'] = $txt['not_done_title'];
Chris@76 1418 $context['continue_post_data'] = '';
Chris@76 1419 $context['continue_countdown'] = '2';
Chris@76 1420 $context['sub_template'] = 'not_done';
Chris@76 1421
Chris@76 1422 // Specific stuff to not break this template!
Chris@76 1423 $context[$context['admin_menu_name']]['current_subsection'] = 'maintenance';
Chris@76 1424
Chris@76 1425 // Change these two if more steps are added!
Chris@76 1426 if (empty($max_substep))
Chris@76 1427 $context['continue_percent'] = round(($_GET['step'] * 100) / 25);
Chris@76 1428 else
Chris@76 1429 $context['continue_percent'] = round(($_GET['step'] * 100 + ($_GET['substep'] * 100) / $max_substep) / 25);
Chris@76 1430
Chris@76 1431 // Never more than 100%!
Chris@76 1432 $context['continue_percent'] = min($context['continue_percent'], 100);
Chris@76 1433
Chris@76 1434 $_SESSION['attachments_to_fix'] = $to_fix;
Chris@76 1435 $_SESSION['attachments_to_fix2'] = $context['repair_errors'];
Chris@76 1436
Chris@76 1437 obExit();
Chris@76 1438 }
Chris@76 1439
Chris@76 1440 // Called from a mouse click, works out what we want to do with attachments and actions it.
Chris@76 1441 function ApproveAttach()
Chris@76 1442 {
Chris@76 1443 global $smcFunc;
Chris@76 1444
Chris@76 1445 // Security is our primary concern...
Chris@76 1446 checkSession('get');
Chris@76 1447
Chris@76 1448 // If it approve or delete?
Chris@76 1449 $is_approve = !isset($_GET['sa']) || $_GET['sa'] != 'reject' ? true : false;
Chris@76 1450
Chris@76 1451 $attachments = array();
Chris@76 1452 // If we are approving all ID's in a message , get the ID's.
Chris@76 1453 if ($_GET['sa'] == 'all' && !empty($_GET['mid']))
Chris@76 1454 {
Chris@76 1455 $id_msg = (int) $_GET['mid'];
Chris@76 1456
Chris@76 1457 $request = $smcFunc['db_query']('', '
Chris@76 1458 SELECT id_attach
Chris@76 1459 FROM {db_prefix}attachments
Chris@76 1460 WHERE id_msg = {int:id_msg}
Chris@76 1461 AND approved = {int:is_approved}
Chris@76 1462 AND attachment_type = {int:attachment_type}',
Chris@76 1463 array(
Chris@76 1464 'id_msg' => $id_msg,
Chris@76 1465 'is_approved' => 0,
Chris@76 1466 'attachment_type' => 0,
Chris@76 1467 )
Chris@76 1468 );
Chris@76 1469 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 1470 $attachments[] = $row['id_attach'];
Chris@76 1471 $smcFunc['db_free_result']($request);
Chris@76 1472 }
Chris@76 1473 elseif (!empty($_GET['aid']))
Chris@76 1474 $attachments[] = (int) $_GET['aid'];
Chris@76 1475
Chris@76 1476 if (empty($attachments))
Chris@76 1477 fatal_lang_error('no_access', false);
Chris@76 1478
Chris@76 1479 // Now we have some ID's cleaned and ready to approve, but first - let's check we have permission!
Chris@76 1480 $allowed_boards = boardsAllowedTo('approve_posts');
Chris@76 1481
Chris@76 1482 // Validate the attachments exist and are the right approval state.
Chris@76 1483 $request = $smcFunc['db_query']('', '
Chris@76 1484 SELECT a.id_attach, m.id_board, m.id_msg, m.id_topic
Chris@76 1485 FROM {db_prefix}attachments AS a
Chris@76 1486 INNER JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg)
Chris@76 1487 WHERE a.id_attach IN ({array_int:attachments})
Chris@76 1488 AND a.attachment_type = {int:attachment_type}
Chris@76 1489 AND a.approved = {int:is_approved}',
Chris@76 1490 array(
Chris@76 1491 'attachments' => $attachments,
Chris@76 1492 'attachment_type' => 0,
Chris@76 1493 'is_approved' => 0,
Chris@76 1494 )
Chris@76 1495 );
Chris@76 1496 $attachments = array();
Chris@76 1497 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 1498 {
Chris@76 1499 // We can only add it if we can approve in this board!
Chris@76 1500 if ($allowed_boards = array(0) || in_array($row['id_board'], $allowed_boards))
Chris@76 1501 {
Chris@76 1502 $attachments[] = $row['id_attach'];
Chris@76 1503
Chris@76 1504 // Also come up witht he redirection URL.
Chris@76 1505 $redirect = 'topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'];
Chris@76 1506 }
Chris@76 1507 }
Chris@76 1508 $smcFunc['db_free_result']($request);
Chris@76 1509
Chris@76 1510 if (empty($attachments))
Chris@76 1511 fatal_lang_error('no_access', false);
Chris@76 1512
Chris@76 1513 // Finally, we are there. Follow through!
Chris@76 1514 if ($is_approve)
Chris@76 1515 ApproveAttachments($attachments);
Chris@76 1516 else
Chris@76 1517 removeAttachments(array('id_attach' => $attachments));
Chris@76 1518
Chris@76 1519 // Return to the topic....
Chris@76 1520 redirectexit($redirect);
Chris@76 1521 }
Chris@76 1522
Chris@76 1523 // Approve an attachment, or maybe even more - no permission check!
Chris@76 1524 function ApproveAttachments($attachments)
Chris@76 1525 {
Chris@76 1526 global $smcFunc;
Chris@76 1527
Chris@76 1528 if (empty($attachments))
Chris@76 1529 return 0;
Chris@76 1530
Chris@76 1531 // For safety, check for thumbnails...
Chris@76 1532 $request = $smcFunc['db_query']('', '
Chris@76 1533 SELECT
Chris@76 1534 a.id_attach, a.id_member, IFNULL(thumb.id_attach, 0) AS id_thumb
Chris@76 1535 FROM {db_prefix}attachments AS a
Chris@76 1536 LEFT JOIN {db_prefix}attachments AS thumb ON (thumb.id_attach = a.id_thumb)
Chris@76 1537 WHERE a.id_attach IN ({array_int:attachments})
Chris@76 1538 AND a.attachment_type = {int:attachment_type}',
Chris@76 1539 array(
Chris@76 1540 'attachments' => $attachments,
Chris@76 1541 'attachment_type' => 0,
Chris@76 1542 )
Chris@76 1543 );
Chris@76 1544 $attachments = array();
Chris@76 1545 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 1546 {
Chris@76 1547 // Update the thumbnail too...
Chris@76 1548 if (!empty($row['id_thumb']))
Chris@76 1549 $attachments[] = $row['id_thumb'];
Chris@76 1550
Chris@76 1551 $attachments[] = $row['id_attach'];
Chris@76 1552 }
Chris@76 1553 $smcFunc['db_free_result']($request);
Chris@76 1554
Chris@76 1555 // Approving an attachment is not hard - it's easy.
Chris@76 1556 $smcFunc['db_query']('', '
Chris@76 1557 UPDATE {db_prefix}attachments
Chris@76 1558 SET approved = {int:is_approved}
Chris@76 1559 WHERE id_attach IN ({array_int:attachments})',
Chris@76 1560 array(
Chris@76 1561 'attachments' => $attachments,
Chris@76 1562 'is_approved' => 1,
Chris@76 1563 )
Chris@76 1564 );
Chris@76 1565
Chris@76 1566 // Remove from the approval queue.
Chris@76 1567 $smcFunc['db_query']('', '
Chris@76 1568 DELETE FROM {db_prefix}approval_queue
Chris@76 1569 WHERE id_attach IN ({array_int:attachments})',
Chris@76 1570 array(
Chris@76 1571 'attachments' => $attachments,
Chris@76 1572 )
Chris@76 1573 );
Chris@76 1574 }
Chris@76 1575
Chris@76 1576 function ManageAttachmentPaths()
Chris@76 1577 {
Chris@76 1578 global $modSettings, $scripturl, $context, $txt, $sourcedir, $smcFunc;
Chris@76 1579
Chris@76 1580 // Saving?
Chris@76 1581 if (isset($_REQUEST['save']))
Chris@76 1582 {
Chris@76 1583 checkSession();
Chris@76 1584
Chris@76 1585 $new_dirs = array();
Chris@76 1586 foreach ($_POST['dirs'] as $id => $path)
Chris@76 1587 {
Chris@76 1588 $id = (int) $id;
Chris@76 1589 if ($id < 1)
Chris@76 1590 continue;
Chris@76 1591
Chris@76 1592 if (empty($path))
Chris@76 1593 {
Chris@76 1594 // Let's not try to delete a path with files in it.
Chris@76 1595 $request = $smcFunc['db_query']('', '
Chris@76 1596 SELECT COUNT(id_attach) AS num_attach
Chris@76 1597 FROM {db_prefix}attachments
Chris@76 1598 WHERE id_folder = {int:id_folder}',
Chris@76 1599 array(
Chris@76 1600 'id_folder' => (int) $id,
Chris@76 1601 )
Chris@76 1602 );
Chris@76 1603
Chris@76 1604 list ($num_attach) = $smcFunc['db_fetch_row']($request);
Chris@76 1605 $smcFunc['db_free_result']($request);
Chris@76 1606
Chris@76 1607 // It's safe to delete.
Chris@76 1608 if ($num_attach == 0)
Chris@76 1609 continue;
Chris@76 1610 }
Chris@76 1611
Chris@76 1612 $new_dirs[$id] = $path;
Chris@76 1613 }
Chris@76 1614
Chris@76 1615 // We need to make sure the current directory is right.
Chris@76 1616 $_POST['current_dir'] = (int) $_POST['current_dir'];
Chris@76 1617 if (empty($_POST['current_dir']) || empty($new_dirs[$_POST['current_dir']]))
Chris@76 1618 fatal_lang_error('attach_path_current_bad', false);
Chris@76 1619
Chris@76 1620 // Going back to just one path?
Chris@76 1621 if (count($new_dirs) == 1)
Chris@76 1622 {
Chris@76 1623 // We might need to reset the paths. This loop will just loop through once.
Chris@76 1624 foreach ($new_dirs as $id => $dir)
Chris@76 1625 {
Chris@76 1626 if ($id != 1)
Chris@76 1627 $smcFunc['db_query']('', '
Chris@76 1628 UPDATE {db_prefix}attachments
Chris@76 1629 SET id_folder = {int:default_folder}
Chris@76 1630 WHERE id_folder = {int:current_folder}',
Chris@76 1631 array(
Chris@76 1632 'default_folder' => 1,
Chris@76 1633 'current_folder' => $id,
Chris@76 1634 )
Chris@76 1635 );
Chris@76 1636
Chris@76 1637 updateSettings(array(
Chris@76 1638 'currentAttachmentUploadDir' => 0,
Chris@76 1639 'attachmentUploadDir' => $dir,
Chris@76 1640 ));
Chris@76 1641 }
Chris@76 1642 }
Chris@76 1643 else
Chris@76 1644 // Save it to the database.
Chris@76 1645 updateSettings(array(
Chris@76 1646 'currentAttachmentUploadDir' => $_POST['current_dir'],
Chris@76 1647 'attachmentUploadDir' => serialize($new_dirs),
Chris@76 1648 ));
Chris@76 1649 }
Chris@76 1650
Chris@76 1651 // Are they here for the first time?
Chris@76 1652 if (empty($modSettings['currentAttachmentUploadDir']))
Chris@76 1653 {
Chris@76 1654 $modSettings['attachmentUploadDir'] = array(
Chris@76 1655 1 => $modSettings['attachmentUploadDir']
Chris@76 1656 );
Chris@76 1657 $modSettings['currentAttachmentUploadDir'] = 1;
Chris@76 1658 }
Chris@76 1659 // Otherwise just load up their attachment paths.
Chris@76 1660 else
Chris@76 1661 $modSettings['attachmentUploadDir'] = unserialize($modSettings['attachmentUploadDir']);
Chris@76 1662
Chris@76 1663 $listOptions = array(
Chris@76 1664 'id' => 'attach_paths',
Chris@76 1665 'base_href' => $scripturl . '?action=admin;area=manageattachments;sa=attachpaths;' . $context['session_var'] . '=' . $context['session_id'],
Chris@76 1666 'title' => $txt['attach_paths'],
Chris@76 1667 'get_items' => array(
Chris@76 1668 'function' => 'list_getAttachDirs',
Chris@76 1669 ),
Chris@76 1670 'columns' => array(
Chris@76 1671 'current_dir' => array(
Chris@76 1672 'header' => array(
Chris@76 1673 'value' => $txt['attach_current_dir'],
Chris@76 1674 ),
Chris@76 1675 'data' => array(
Chris@76 1676 'function' => create_function('$rowData', '
Chris@76 1677 return \'<input type="radio" name="current_dir" value="\' . $rowData[\'id\'] . \'" \' . ($rowData[\'current\'] ? \'checked="checked"\' : \'\') . \' class="input_radio" />\';
Chris@76 1678 '),
Chris@76 1679 'style' => 'text-align: center; width: 15%;',
Chris@76 1680 ),
Chris@76 1681 ),
Chris@76 1682 'path' => array(
Chris@76 1683 'header' => array(
Chris@76 1684 'value' => $txt['attach_path'],
Chris@76 1685 ),
Chris@76 1686 'data' => array(
Chris@76 1687 'function' => create_function('$rowData', '
Chris@76 1688 return \'<input type="text" size="30" name="dirs[\' . $rowData[\'id\'] . \']" value="\' . $rowData[\'path\'] . \'" class="input_text" style="width: 100%" />\';
Chris@76 1689 '),
Chris@76 1690 'style' => 'text-align: center; width: 30%;',
Chris@76 1691 ),
Chris@76 1692 ),
Chris@76 1693 'current_size' => array(
Chris@76 1694 'header' => array(
Chris@76 1695 'value' => $txt['attach_current_size'],
Chris@76 1696 ),
Chris@76 1697 'data' => array(
Chris@76 1698 'db' => 'current_size',
Chris@76 1699 'style' => 'text-align: center; width: 15%;',
Chris@76 1700 ),
Chris@76 1701 ),
Chris@76 1702 'num_files' => array(
Chris@76 1703 'header' => array(
Chris@76 1704 'value' => $txt['attach_num_files'],
Chris@76 1705 ),
Chris@76 1706 'data' => array(
Chris@76 1707 'db' => 'num_files',
Chris@76 1708 'style' => 'text-align: center; width: 15%;',
Chris@76 1709 ),
Chris@76 1710 ),
Chris@76 1711 'status' => array(
Chris@76 1712 'header' => array(
Chris@76 1713 'value' => $txt['attach_dir_status'],
Chris@76 1714 ),
Chris@76 1715 'data' => array(
Chris@76 1716 'db' => 'status',
Chris@76 1717 'style' => 'text-align: center; width: 25%;',
Chris@76 1718 ),
Chris@76 1719 ),
Chris@76 1720 ),
Chris@76 1721 'form' => array(
Chris@76 1722 'href' => $scripturl . '?action=admin;area=manageattachments;sa=attachpaths;' . $context['session_var'] . '=' . $context['session_id'],
Chris@76 1723 ),
Chris@76 1724 'additional_rows' => array(
Chris@76 1725 array(
Chris@76 1726 'position' => 'below_table_data',
Chris@76 1727 'value' => '<input type="hidden" name="' . $context['session_var'] . '" value="' . $context['session_id'] . '" /><input type="submit" name="new_path" value="' . $txt['attach_add_path'] . '" class="button_submit" />&nbsp;<input type="submit" name="save" value="' . $txt['save'] . '" class="button_submit" />',
Chris@76 1728 'style' => 'text-align: right;',
Chris@76 1729 ),
Chris@76 1730 ),
Chris@76 1731 );
Chris@76 1732
Chris@76 1733 require_once($sourcedir . '/Subs-List.php');
Chris@76 1734 createList($listOptions);
Chris@76 1735
Chris@76 1736 // Fix up our template.
Chris@76 1737 $context[$context['admin_menu_name']]['current_subsection'] = 'attachments';
Chris@76 1738 $context['page_title'] = $txt['attach_path_manage'];
Chris@76 1739 $context['sub_template'] = 'attachment_paths';
Chris@76 1740 }
Chris@76 1741
Chris@76 1742 // Prepare the actual attachment directories to be displayed in the list.
Chris@76 1743 function list_getAttachDirs()
Chris@76 1744 {
Chris@76 1745 global $smcFunc, $modSettings, $context, $txt;
Chris@76 1746
Chris@76 1747 // The dirs should already have been unserialized but just in case...
Chris@76 1748 if (!is_array($modSettings['attachmentUploadDir']))
Chris@76 1749 $modSettings['attachmentUploadDir'] = unserialize($modSettings['attachmentUploadDir']);
Chris@76 1750
Chris@76 1751 $request = $smcFunc['db_query']('', '
Chris@76 1752 SELECT id_folder, COUNT(id_attach) AS num_attach
Chris@76 1753 FROM {db_prefix}attachments' . (empty($modSettings['custom_avatar_enabled']) ? '' : '
Chris@76 1754 WHERE attachment_type != {int:type_avatar}') . '
Chris@76 1755 GROUP BY id_folder',
Chris@76 1756 array(
Chris@76 1757 'type_avatar' => 1,
Chris@76 1758 )
Chris@76 1759 );
Chris@76 1760
Chris@76 1761 $expected_files = array();
Chris@76 1762 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 1763 $expected_files[$row['id_folder']] = $row['num_attach'];
Chris@76 1764 $smcFunc['db_free_result']($request);
Chris@76 1765
Chris@76 1766 $attachdirs = array();
Chris@76 1767 foreach ($modSettings['attachmentUploadDir'] as $id => $dir)
Chris@76 1768 {
Chris@76 1769 // If there aren't any attachments in this directory this won't exist.
Chris@76 1770 if (!isset($expected_files[$id]))
Chris@76 1771 $expected_files[$id] = 0;
Chris@76 1772
Chris@76 1773 // Check if the directory is doing okay.
Chris@76 1774 list ($status, $error, $size) = attachDirStatus($dir, $expected_files[$id]);
Chris@76 1775
Chris@76 1776 $attachdirs[] = array(
Chris@76 1777 'id' => $id,
Chris@76 1778 'current' => $id == $modSettings['currentAttachmentUploadDir'],
Chris@76 1779 'path' => $dir,
Chris@76 1780 'current_size' => $size,
Chris@76 1781 'num_files' => $expected_files[$id],
Chris@76 1782 'status' => ($error ? '<span class="error">' : '') . sprintf($txt['attach_dir_' . $status], $context['session_id'], $context['session_var']) . ($error ? '</span>' : ''),
Chris@76 1783 );
Chris@76 1784 }
Chris@76 1785
Chris@76 1786 // Just stick a new directory on at the bottom.
Chris@76 1787 if (isset($_REQUEST['new_path']))
Chris@76 1788 $attachdirs[] = array(
Chris@76 1789 'id' => max(array_merge(array_keys($expected_files), array_keys($modSettings['attachmentUploadDir']))) + 1,
Chris@76 1790 'current' => false,
Chris@76 1791 'path' => '',
Chris@76 1792 'current_size' => '',
Chris@76 1793 'num_files' => '',
Chris@76 1794 'status' => '',
Chris@76 1795 );
Chris@76 1796
Chris@76 1797 return $attachdirs;
Chris@76 1798 }
Chris@76 1799
Chris@76 1800 // Checks the status of an attachment directory and returns an array of the status key, if that status key signifies an error, and the folder size.
Chris@76 1801 function attachDirStatus($dir, $expected_files)
Chris@76 1802 {
Chris@76 1803 if (!is_dir($dir))
Chris@76 1804 return array('does_not_exist', true, '');
Chris@76 1805 elseif (!is_writable($dir))
Chris@76 1806 return array('not_writable', true, '');
Chris@76 1807
Chris@76 1808 // Everything is okay so far, start to scan through the directory.
Chris@76 1809 $dir_size = 0;
Chris@76 1810 $num_files = 0;
Chris@76 1811 $dir_handle = dir($dir);
Chris@76 1812 while ($file = $dir_handle->read())
Chris@76 1813 {
Chris@76 1814 // Now do we have a real file here?
Chris@76 1815 if (in_array($file, array('.', '..', '.htaccess', 'index.php')))
Chris@76 1816 continue;
Chris@76 1817
Chris@76 1818 $dir_size += filesize($dir . '/' . $file);
Chris@76 1819 $num_files++;
Chris@76 1820 }
Chris@76 1821 $dir_handle->close();
Chris@76 1822
Chris@76 1823 $dir_size = round($dir_size / 1024, 2);
Chris@76 1824
Chris@76 1825 if ($num_files < $expected_files)
Chris@76 1826 return array('files_missing', true, $dir_size);
Chris@76 1827 // Empty?
Chris@76 1828 elseif ($expected_files == 0)
Chris@76 1829 return array('unused', false, $dir_size);
Chris@76 1830 // All good!
Chris@76 1831 else
Chris@76 1832 return array('ok', false, $dir_size);
Chris@76 1833 }
Chris@76 1834
Chris@76 1835 ?>