/** * Parse Attachments */ function parse_attachments($form_name, $mode, $forum_id, $submit, $preview, $refresh, $is_message = false) { global $config, $auth, $user, $phpbb_root_path, $phpEx, $db; $error = array(); $num_attachments = sizeof($this->attachment_data); $this->filename_data['filecomment'] = utf8_normalize_nfc(request_var('filecomment', '', true)); $upload_file = isset($_FILES[$form_name]) && $_FILES[$form_name]['name'] != 'none' && trim($_FILES[$form_name]['name']) ? true : false; $add_file = isset($_POST['add_file']) ? true : false; $delete_file = isset($_POST['delete_file']) ? true : false; // First of all adjust comments if changed $actual_comment_list = utf8_normalize_nfc(request_var('comment_list', array(''), true)); foreach ($actual_comment_list as $comment_key => $comment) { if (!isset($this->attachment_data[$comment_key])) { continue; } if ($this->attachment_data[$comment_key]['attach_comment'] != $actual_comment_list[$comment_key]) { $this->attachment_data[$comment_key]['attach_comment'] = $actual_comment_list[$comment_key]; } } $cfg = array(); $cfg['max_attachments'] = $is_message ? $config['max_attachments_pm'] : $config['max_attachments']; $forum_id = $is_message ? 0 : $forum_id; if ($submit && in_array($mode, array('post', 'reply', 'quote', 'edit')) && $upload_file) { if ($num_attachments < $cfg['max_attachments'] || $auth->acl_get('a_') || $auth->acl_get('m_', $forum_id)) { $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message); $error = $filedata['error']; if ($filedata['post_attach'] && !sizeof($error)) { $sql_ary = array('physical_filename' => $filedata['physical_filename'], 'attach_comment' => $this->filename_data['filecomment'], 'real_filename' => $filedata['real_filename'], 'extension' => $filedata['extension'], 'mimetype' => $filedata['mimetype'], 'filesize' => $filedata['filesize'], 'filetime' => $filedata['filetime'], 'thumbnail' => $filedata['thumbnail'], 'is_orphan' => 1, 'in_message' => $is_message ? 1 : 0, 'poster_id' => $user->data['user_id']); $db->sql_query('INSERT INTO ' . ATTACHMENTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); $new_entry = array('attach_id' => $db->sql_nextid(), 'is_orphan' => 1, 'real_filename' => $filedata['real_filename'], 'attach_comment' => $this->filename_data['filecomment']); $this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data); $this->message = preg_replace('#\\[attachment=([0-9]+)\\](.*?)\\[\\/attachment\\]#e', "'[attachment='.(\\1 + 1).']\\2[/attachment]'", $this->message); $this->filename_data['filecomment'] = ''; // This Variable is set to false here, because Attachments are entered into the // Database in two modes, one if the id_list is 0 and the second one if post_attach is true // Since post_attach is automatically switched to true if an Attachment got added to the filesystem, // but we are assigning an id of 0 here, we have to reset the post_attach variable to false. // // This is very relevant, because it could happen that the post got not submitted, but we do not // know this circumstance here. We could be at the posting page or we could be redirected to the entered // post. :) $filedata['post_attach'] = false; } } else { $error[] = sprintf($user->lang['TOO_MANY_ATTACHMENTS'], $cfg['max_attachments']); } } if ($preview || $refresh || sizeof($error)) { // Perform actions on temporary attachments if ($delete_file) { include_once $phpbb_root_path . 'includes/functions_admin.' . $phpEx; $index = array_keys(request_var('delete_file', array(0 => 0))); $index = !empty($index) ? $index[0] : false; if ($index !== false && !empty($this->attachment_data[$index])) { // delete selected attachment if ($this->attachment_data[$index]['is_orphan']) { $sql = 'SELECT attach_id, physical_filename, thumbnail FROM ' . ATTACHMENTS_TABLE . ' WHERE attach_id = ' . (int) $this->attachment_data[$index]['attach_id'] . ' AND is_orphan = 1 AND poster_id = ' . $user->data['user_id']; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row) { phpbb_unlink($row['physical_filename'], 'file'); if ($row['thumbnail']) { phpbb_unlink($row['physical_filename'], 'thumbnail'); } $db->sql_query('DELETE FROM ' . ATTACHMENTS_TABLE . ' WHERE attach_id = ' . (int) $this->attachment_data[$index]['attach_id']); } } else { delete_attachments('attach', array(intval($this->attachment_data[$index]['attach_id']))); } unset($this->attachment_data[$index]); $this->message = preg_replace('#\\[attachment=([0-9]+)\\](.*?)\\[\\/attachment\\]#e', "(\\1 == \$index) ? '' : ((\\1 > \$index) ? '[attachment=' . (\\1 - 1) . ']\\2[/attachment]' : '\\0')", $this->message); // Reindex Array $this->attachment_data = array_values($this->attachment_data); } } else { if (($add_file || $preview) && $upload_file) { if ($num_attachments < $cfg['max_attachments'] || $auth->acl_gets('m_', 'a_', $forum_id)) { $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message); $error = array_merge($error, $filedata['error']); if (!sizeof($error)) { $sql_ary = array('physical_filename' => $filedata['physical_filename'], 'attach_comment' => $this->filename_data['filecomment'], 'real_filename' => $filedata['real_filename'], 'extension' => $filedata['extension'], 'mimetype' => $filedata['mimetype'], 'filesize' => $filedata['filesize'], 'filetime' => $filedata['filetime'], 'thumbnail' => $filedata['thumbnail'], 'is_orphan' => 1, 'in_message' => $is_message ? 1 : 0, 'poster_id' => $user->data['user_id']); $db->sql_query('INSERT INTO ' . ATTACHMENTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); $new_entry = array('attach_id' => $db->sql_nextid(), 'is_orphan' => 1, 'real_filename' => $filedata['real_filename'], 'attach_comment' => $this->filename_data['filecomment']); $this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data); $this->message = preg_replace('#\\[attachment=([0-9]+)\\](.*?)\\[\\/attachment\\]#e', "'[attachment='.(\\1 + 1).']\\2[/attachment]'", $this->message); $this->filename_data['filecomment'] = ''; } } else { $error[] = sprintf($user->lang['TOO_MANY_ATTACHMENTS'], $cfg['max_attachments']); } } } } foreach ($error as $error_msg) { $this->warn_msg[] = $error_msg; } }
/** * Delete Attachments * * @param string $mode can be: post|message|topic|attach|user * @param mixed $ids can be: post_ids, message_ids, topic_ids, attach_ids, user_ids * @param bool $resync set this to false if you are deleting posts or topics */ function delete_attachments($mode, $ids, $resync = true) { global $db, $config; if (is_array($ids) && sizeof($ids)) { $ids = array_unique($ids); $ids = array_map('intval', $ids); } else { $ids = array((int) $ids); } if (!sizeof($ids)) { return false; } switch ($mode) { case 'post': case 'message': $sql_id = 'post_msg_id'; break; case 'topic': $sql_id = 'topic_id'; break; case 'user': $sql_id = 'poster_id'; break; case 'attach': default: $sql_id = 'attach_id'; $mode = 'attach'; break; } $post_ids = $message_ids = $topic_ids = $physical = array(); // Collect post and topic ids for later use if we need to touch remaining entries (if resync is enabled) $sql = 'SELECT post_msg_id, topic_id, in_message, physical_filename, thumbnail, filesize, is_orphan FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set($sql_id, $ids); $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { // We only need to store post/message/topic ids if resync is enabled and the file is not orphaned if ($resync && !$row['is_orphan']) { if (!$row['in_message']) { $post_ids[] = $row['post_msg_id']; $topic_ids[] = $row['topic_id']; } else { $message_ids[] = $row['post_msg_id']; } } $physical[] = array('filename' => $row['physical_filename'], 'thumbnail' => $row['thumbnail'], 'filesize' => $row['filesize'], 'is_orphan' => $row['is_orphan']); } $db->sql_freeresult($result); // Delete attachments $sql = 'DELETE FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set($sql_id, $ids); $db->sql_query($sql); $num_deleted = $db->sql_affectedrows(); if (!$num_deleted) { return 0; } // Delete attachments from filesystem $space_removed = $files_removed = 0; foreach ($physical as $file_ary) { if (phpbb_unlink($file_ary['filename'], 'file', true) && !$file_ary['is_orphan']) { // Only non-orphaned files count to the file size $space_removed += $file_ary['filesize']; $files_removed++; } if ($file_ary['thumbnail']) { phpbb_unlink($file_ary['filename'], 'thumbnail', true); } } if ($space_removed || $files_removed) { set_config('upload_dir_size', $config['upload_dir_size'] - $space_removed, true); set_config('num_files', $config['num_files'] - $files_removed, true); } // If we do not resync, we do not need to adjust any message, post, topic or user entries if (!$resync) { return $num_deleted; } // No more use for the original ids unset($ids); // Now, we need to resync posts, messages, topics. We go through every one of them $post_ids = array_unique($post_ids); $message_ids = array_unique($message_ids); $topic_ids = array_unique($topic_ids); // Update post indicators for posts now no longer having attachments if (sizeof($post_ids)) { $sql = 'UPDATE ' . POSTS_TABLE . ' SET post_attachment = 0 WHERE ' . $db->sql_in_set('post_id', $post_ids); $db->sql_query($sql); } // Update message table if messages are affected if (sizeof($message_ids)) { $sql = 'UPDATE ' . PRIVMSGS_TABLE . ' SET message_attachment = 0 WHERE ' . $db->sql_in_set('msg_id', $message_ids); $db->sql_query($sql); } // Now update the topics. This is a bit trickier, because there could be posts still having attachments within the topic if (sizeof($topic_ids)) { // Just check which topics are still having an assigned attachment not orphaned by querying the attachments table (much less entries expected) $sql = 'SELECT topic_id FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('topic_id', $topic_ids) . ' AND is_orphan = 0'; $result = $db->sql_query($sql); $remaining_ids = array(); while ($row = $db->sql_fetchrow($result)) { $remaining_ids[] = $row['topic_id']; } $db->sql_freeresult($result); // Now only unset those ids remaining $topic_ids = array_diff($topic_ids, $remaining_ids); if (sizeof($topic_ids)) { $sql = 'UPDATE ' . TOPICS_TABLE . ' SET topic_attachment = 0 WHERE ' . $db->sql_in_set('topic_id', $topic_ids); $db->sql_query($sql); } } return $num_deleted; }
function main($id, $mode) { global $db, $user, $auth, $template, $cache; global $config, $phpbb_admin_path, $phpbb_root_path, $phpEx; $user->add_lang(array('posting', 'viewtopic', 'acp/attachments')); $error = $notify = array(); $submit = isset($_POST['submit']) ? true : false; $action = request_var('action', ''); $form_key = 'acp_attach'; add_form_key($form_key); if ($submit && !check_form_key($form_key)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } switch ($mode) { case 'attach': $l_title = 'ACP_ATTACHMENT_SETTINGS'; break; case 'extensions': $l_title = 'ACP_MANAGE_EXTENSIONS'; break; case 'ext_groups': $l_title = 'ACP_EXTENSION_GROUPS'; break; case 'orphan': $l_title = 'ACP_ORPHAN_ATTACHMENTS'; break; default: trigger_error('NO_MODE', E_USER_ERROR); break; } $this->tpl_name = 'acp_attachments'; $this->page_title = $l_title; $template->assign_vars(array('L_TITLE' => $user->lang[$l_title], 'L_TITLE_EXPLAIN' => $user->lang[$l_title . '_EXPLAIN'], 'U_ACTION' => $this->u_action)); switch ($mode) { case 'attach': include_once $phpbb_root_path . 'includes/functions_posting.' . $phpEx; $sql = 'SELECT group_name, cat_id FROM ' . EXTENSION_GROUPS_TABLE . ' WHERE cat_id > 0 ORDER BY cat_id'; $result = $db->sql_query($sql); $s_assigned_groups = array(); while ($row = $db->sql_fetchrow($result)) { $s_assigned_groups[$row['cat_id']][] = $row['group_name']; } $db->sql_freeresult($result); $l_legend_cat_images = $user->lang['SETTINGS_CAT_IMAGES'] . ' [' . $user->lang['ASSIGNED_GROUP'] . ': ' . (!empty($s_assigned_groups[ATTACHMENT_CATEGORY_IMAGE]) ? implode(', ', $s_assigned_groups[ATTACHMENT_CATEGORY_IMAGE]) : $user->lang['NO_EXT_GROUP']) . ']'; $display_vars = array('title' => 'ACP_ATTACHMENT_SETTINGS', 'vars' => array('legend1' => 'ACP_ATTACHMENT_SETTINGS', 'img_max_width' => array('lang' => 'MAX_IMAGE_SIZE', 'validate' => 'int:0', 'type' => false, 'method' => false, 'explain' => false), 'img_max_height' => array('lang' => 'MAX_IMAGE_SIZE', 'validate' => 'int:0', 'type' => false, 'method' => false, 'explain' => false), 'img_link_width' => array('lang' => 'IMAGE_LINK_SIZE', 'validate' => 'int:0', 'type' => false, 'method' => false, 'explain' => false), 'img_link_height' => array('lang' => 'IMAGE_LINK_SIZE', 'validate' => 'int:0', 'type' => false, 'method' => false, 'explain' => false), 'allow_attachments' => array('lang' => 'ALLOW_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_pm_attach' => array('lang' => 'ALLOW_PM_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'upload_path' => array('lang' => 'UPLOAD_DIR', 'validate' => 'wpath', 'type' => 'text:25:100', 'explain' => true), 'display_order' => array('lang' => 'DISPLAY_ORDER', 'validate' => 'bool', 'type' => 'custom', 'method' => 'display_order', 'explain' => true), 'attachment_quota' => array('lang' => 'ATTACH_QUOTA', 'validate' => 'string', 'type' => 'custom', 'method' => 'max_filesize', 'explain' => true), 'max_filesize' => array('lang' => 'ATTACH_MAX_FILESIZE', 'validate' => 'string', 'type' => 'custom', 'method' => 'max_filesize', 'explain' => true), 'max_filesize_pm' => array('lang' => 'ATTACH_MAX_PM_FILESIZE', 'validate' => 'string', 'type' => 'custom', 'method' => 'max_filesize', 'explain' => true), 'max_attachments' => array('lang' => 'MAX_ATTACHMENTS', 'validate' => 'int', 'type' => 'text:3:3', 'explain' => false), 'max_attachments_pm' => array('lang' => 'MAX_ATTACHMENTS_PM', 'validate' => 'int', 'type' => 'text:3:3', 'explain' => false), 'secure_downloads' => array('lang' => 'SECURE_DOWNLOADS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'secure_allow_deny' => array('lang' => 'SECURE_ALLOW_DENY', 'validate' => 'int', 'type' => 'custom', 'method' => 'select_allow_deny', 'explain' => true), 'secure_allow_empty_referer' => array('lang' => 'SECURE_EMPTY_REFERRER', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'check_attachment_content' => array('lang' => 'CHECK_CONTENT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'legend2' => $l_legend_cat_images, 'img_display_inlined' => array('lang' => 'DISPLAY_INLINED', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'img_create_thumbnail' => array('lang' => 'CREATE_THUMBNAIL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'img_max_thumb_width' => array('lang' => 'MAX_THUMB_WIDTH', 'validate' => 'int', 'type' => 'text:7:15', 'explain' => true, 'append' => ' px'), 'img_min_thumb_filesize' => array('lang' => 'MIN_THUMB_FILESIZE', 'validate' => 'int', 'type' => 'text:7:15', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']), 'img_imagick' => array('lang' => 'IMAGICK_PATH', 'validate' => 'string', 'type' => 'text:20:200', 'explain' => true, 'append' => ' <span>[ <a href="' . $this->u_action . '&action=imgmagick">' . $user->lang['SEARCH_IMAGICK'] . '</a> ]</span>'), 'img_max' => array('lang' => 'MAX_IMAGE_SIZE', 'validate' => 'int', 'type' => 'dimension:3:4', 'explain' => true, 'append' => ' px'), 'img_link' => array('lang' => 'IMAGE_LINK_SIZE', 'validate' => 'int', 'type' => 'dimension:3:4', 'explain' => true, 'append' => ' px'))); $this->new_config = $config; $cfg_array = isset($_REQUEST['config']) ? request_var('config', array('' => '')) : $this->new_config; $error = array(); // We validate the complete config if whished validate_config_vars($display_vars['vars'], $cfg_array, $error); // Do not write values if there is an error if (sizeof($error)) { $submit = false; } // We go through the display_vars to make sure no one is trying to set variables he/she is not allowed to... foreach ($display_vars['vars'] as $config_name => $null) { if (!isset($cfg_array[$config_name]) || strpos($config_name, 'legend') !== false) { continue; } $this->new_config[$config_name] = $config_value = $cfg_array[$config_name]; if (in_array($config_name, array('attachment_quota', 'max_filesize', 'max_filesize_pm'))) { $size_var = request_var($config_name, ''); $this->new_config[$config_name] = $config_value = $size_var == 'kb' ? round($config_value * 1024) : ($size_var == 'mb' ? round($config_value * 1048576) : $config_value); } if ($submit) { set_config($config_name, $config_value); } } $this->perform_site_list(); if ($submit) { add_log('admin', 'LOG_CONFIG_ATTACH'); // Check Settings $this->test_upload($error, $this->new_config['upload_path'], false); if (!sizeof($error)) { trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action)); } } $template->assign_var('S_ATTACHMENT_SETTINGS', true); if ($action == 'imgmagick') { $this->new_config['img_imagick'] = $this->search_imagemagick(); } // We strip eventually manual added convert program, we only want the patch if ($this->new_config['img_imagick']) { // Change path separator $this->new_config['img_imagick'] = str_replace('\\', '/', $this->new_config['img_imagick']); $this->new_config['img_imagick'] = str_replace(array('convert', '.exe'), array('', ''), $this->new_config['img_imagick']); // Check for trailing slash if (substr($this->new_config['img_imagick'], -1) !== '/') { $this->new_config['img_imagick'] .= '/'; } } $supported_types = get_supported_image_types(); // Check Thumbnail Support if (!$this->new_config['img_imagick'] && (!isset($supported_types['format']) || !sizeof($supported_types['format']))) { $this->new_config['img_create_thumbnail'] = 0; } $template->assign_vars(array('U_SEARCH_IMAGICK' => $this->u_action . '&action=imgmagick', 'S_THUMBNAIL_SUPPORT' => !$this->new_config['img_imagick'] && (!isset($supported_types['format']) || !sizeof($supported_types['format'])) ? false : true)); // Secure Download Options - Same procedure as with banning $allow_deny = $this->new_config['secure_allow_deny'] ? 'ALLOWED' : 'DISALLOWED'; $sql = 'SELECT * FROM ' . SITELIST_TABLE; $result = $db->sql_query($sql); $defined_ips = ''; $ips = array(); while ($row = $db->sql_fetchrow($result)) { $value = $row['site_ip'] ? $row['site_ip'] : $row['site_hostname']; if ($value) { $defined_ips .= '<option' . ($row['ip_exclude'] ? ' class="sep"' : '') . ' value="' . $row['site_id'] . '">' . $value . '</option>'; $ips[$row['site_id']] = $value; } } $db->sql_freeresult($result); $template->assign_vars(array('S_SECURE_DOWNLOADS' => $this->new_config['secure_downloads'], 'S_DEFINED_IPS' => $defined_ips != '' ? true : false, 'S_WARNING' => sizeof($error) ? true : false, 'WARNING_MSG' => implode('<br />', $error), 'DEFINED_IPS' => $defined_ips, 'L_SECURE_TITLE' => $user->lang['DEFINE_' . $allow_deny . '_IPS'], 'L_IP_EXCLUDE' => $user->lang['EXCLUDE_FROM_' . $allow_deny . '_IP'], 'L_REMOVE_IPS' => $user->lang['REMOVE_' . $allow_deny . '_IPS'])); // Output relevant options foreach ($display_vars['vars'] as $config_key => $vars) { if (!is_array($vars) && strpos($config_key, 'legend') === false) { continue; } if (strpos($config_key, 'legend') !== false) { $template->assign_block_vars('options', array('S_LEGEND' => true, 'LEGEND' => isset($user->lang[$vars]) ? $user->lang[$vars] : $vars)); continue; } $type = explode(':', $vars['type']); $l_explain = ''; if ($vars['explain'] && isset($vars['lang_explain'])) { $l_explain = isset($user->lang[$vars['lang_explain']]) ? $user->lang[$vars['lang_explain']] : $vars['lang_explain']; } else { if ($vars['explain']) { $l_explain = isset($user->lang[$vars['lang'] . '_EXPLAIN']) ? $user->lang[$vars['lang'] . '_EXPLAIN'] : ''; } } $content = build_cfg_template($type, $config_key, $this->new_config, $config_key, $vars); if (empty($content)) { continue; } $template->assign_block_vars('options', array('KEY' => $config_key, 'TITLE' => $user->lang[$vars['lang']], 'S_EXPLAIN' => $vars['explain'], 'TITLE_EXPLAIN' => $l_explain, 'CONTENT' => $content)); unset($display_vars['vars'][$config_key]); } break; case 'extensions': if ($submit || isset($_POST['add_extension_check'])) { if ($submit) { // Change Extensions ? $extension_change_list = request_var('extension_change_list', array(0)); $group_select_list = request_var('group_select', array(0)); // Generate correct Change List $extensions = array(); for ($i = 0, $size = sizeof($extension_change_list); $i < $size; $i++) { $extensions[$extension_change_list[$i]]['group_id'] = $group_select_list[$i]; } $sql = 'SELECT * FROM ' . EXTENSIONS_TABLE . ' ORDER BY extension_id'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { if ($row['group_id'] != $extensions[$row['extension_id']]['group_id']) { $sql = 'UPDATE ' . EXTENSIONS_TABLE . ' SET group_id = ' . (int) $extensions[$row['extension_id']]['group_id'] . ' WHERE extension_id = ' . $row['extension_id']; $db->sql_query($sql); add_log('admin', 'LOG_ATTACH_EXT_UPDATE', $row['extension']); } } $db->sql_freeresult($result); // Delete Extension? $extension_id_list = request_var('extension_id_list', array(0)); if (sizeof($extension_id_list)) { $sql = 'SELECT extension FROM ' . EXTENSIONS_TABLE . ' WHERE ' . $db->sql_in_set('extension_id', $extension_id_list); $result = $db->sql_query($sql); $extension_list = ''; while ($row = $db->sql_fetchrow($result)) { $extension_list .= $extension_list == '' ? $row['extension'] : ', ' . $row['extension']; } $db->sql_freeresult($result); $sql = 'DELETE FROM ' . EXTENSIONS_TABLE . ' WHERE ' . $db->sql_in_set('extension_id', $extension_id_list); $db->sql_query($sql); add_log('admin', 'LOG_ATTACH_EXT_DEL', $extension_list); } } // Add Extension? $add_extension = strtolower(request_var('add_extension', '')); $add_extension_group = request_var('add_group_select', 0); $add = isset($_POST['add_extension_check']) ? true : false; if ($add_extension && $add) { if (!sizeof($error)) { $sql = 'SELECT extension_id FROM ' . EXTENSIONS_TABLE . "\n\t\t\t\t\t\t\t\tWHERE extension = '" . $db->sql_escape($add_extension) . "'"; $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) { $error[] = sprintf($user->lang['EXTENSION_EXIST'], $add_extension); } $db->sql_freeresult($result); if (!sizeof($error)) { $sql_ary = array('group_id' => $add_extension_group, 'extension' => $add_extension); $db->sql_query('INSERT INTO ' . EXTENSIONS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); add_log('admin', 'LOG_ATTACH_EXT_ADD', $add_extension); } } } if (!sizeof($error)) { $notify[] = $user->lang['EXTENSIONS_UPDATED']; } $cache->destroy('_extensions'); } $template->assign_vars(array('S_EXTENSIONS' => true, 'ADD_EXTENSION' => isset($add_extension) ? $add_extension : '', 'GROUP_SELECT_OPTIONS' => isset($_POST['add_extension_check']) ? $this->group_select('add_group_select', $add_extension_group, 'extension_group') : $this->group_select('add_group_select', false, 'extension_group'))); $sql = 'SELECT * FROM ' . EXTENSIONS_TABLE . ' ORDER BY group_id, extension'; $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) { $old_group_id = $row['group_id']; do { $s_spacer = false; $current_group_id = $row['group_id']; if ($old_group_id != $current_group_id) { $s_spacer = true; $old_group_id = $current_group_id; } $template->assign_block_vars('extensions', array('S_SPACER' => $s_spacer, 'EXTENSION_ID' => $row['extension_id'], 'EXTENSION' => $row['extension'], 'GROUP_OPTIONS' => $this->group_select('group_select[]', $row['group_id']))); } while ($row = $db->sql_fetchrow($result)); } $db->sql_freeresult($result); break; case 'ext_groups': $template->assign_var('S_EXTENSION_GROUPS', true); if ($submit) { $action = request_var('action', ''); $group_id = request_var('g', 0); if ($action != 'add' && $action != 'edit') { trigger_error('NO_MODE', E_USER_ERROR); } if (!$group_id && $action == 'edit') { trigger_error($user->lang['NO_EXT_GROUP_SPECIFIED'] . adm_back_link($this->u_action), E_USER_WARNING); } if ($group_id) { $sql = 'SELECT * FROM ' . EXTENSION_GROUPS_TABLE . "\n\t\t\t\t\t\t\tWHERE group_id = {$group_id}"; $result = $db->sql_query($sql); $ext_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$ext_row) { trigger_error($user->lang['NO_EXT_GROUP_SPECIFIED'] . adm_back_link($this->u_action), E_USER_WARNING); } } else { $ext_row = array(); } $group_name = utf8_normalize_nfc(request_var('group_name', '', true)); $new_group_name = $action == 'add' ? $group_name : ($ext_row['group_name'] != $group_name ? $group_name : ''); if (!$group_name) { $error[] = $user->lang['NO_EXT_GROUP_NAME']; } // Check New Group Name if ($new_group_name) { $sql = 'SELECT group_id FROM ' . EXTENSION_GROUPS_TABLE . "\n\t\t\t\t\t\t\tWHERE LOWER(group_name) = '" . $db->sql_escape(utf8_strtolower($new_group_name)) . "'"; $result = $db->sql_query($sql); if ($db->sql_fetchrow($result)) { $error[] = sprintf($user->lang['EXTENSION_GROUP_EXIST'], $new_group_name); } $db->sql_freeresult($result); } if (!sizeof($error)) { // Ok, build the update/insert array $upload_icon = request_var('upload_icon', 'no_image'); $size_select = request_var('size_select', 'b'); $forum_select = request_var('forum_select', false); $allowed_forums = request_var('allowed_forums', array(0)); $allow_in_pm = isset($_POST['allow_in_pm']) ? true : false; $max_filesize = request_var('max_filesize', 0); $max_filesize = $size_select == 'kb' ? round($max_filesize * 1024) : ($size_select == 'mb' ? round($max_filesize * 1048576) : $max_filesize); $allow_group = isset($_POST['allow_group']) ? true : false; if ($max_filesize == $config['max_filesize']) { $max_filesize = 0; } if (!sizeof($allowed_forums)) { $forum_select = false; } $group_ary = array('group_name' => $group_name, 'cat_id' => request_var('special_category', ATTACHMENT_CATEGORY_NONE), 'allow_group' => $allow_group ? 1 : 0, 'upload_icon' => $upload_icon == 'no_image' ? '' : $upload_icon, 'max_filesize' => $max_filesize, 'allowed_forums' => $forum_select ? serialize($allowed_forums) : '', 'allow_in_pm' => $allow_in_pm ? 1 : 0); if ($action == 'add') { $group_ary['download_mode'] = INLINE_LINK; } $sql = $action == 'add' ? 'INSERT INTO ' . EXTENSION_GROUPS_TABLE . ' ' : 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' SET '; $sql .= $db->sql_build_array($action == 'add' ? 'INSERT' : 'UPDATE', $group_ary); $sql .= $action == 'edit' ? " WHERE group_id = {$group_id}" : ''; $db->sql_query($sql); if ($action == 'add') { $group_id = $db->sql_nextid(); } add_log('admin', 'LOG_ATTACH_EXTGROUP_' . strtoupper($action), $group_name); } $extension_list = request_var('extensions', array(0)); if ($action == 'edit' && sizeof($extension_list)) { $sql = 'UPDATE ' . EXTENSIONS_TABLE . "\n\t\t\t\t\t\t\tSET group_id = 0\n\t\t\t\t\t\t\tWHERE group_id = {$group_id}"; $db->sql_query($sql); } if (sizeof($extension_list)) { $sql = 'UPDATE ' . EXTENSIONS_TABLE . "\n\t\t\t\t\t\t\tSET group_id = {$group_id}\n\t\t\t\t\t\t\tWHERE " . $db->sql_in_set('extension_id', $extension_list); $db->sql_query($sql); } $cache->destroy('_extensions'); if (!sizeof($error)) { $notify[] = $user->lang['SUCCESS_EXTENSION_GROUP_' . strtoupper($action)]; } } $cat_lang = array(ATTACHMENT_CATEGORY_NONE => $user->lang['NO_FILE_CAT'], ATTACHMENT_CATEGORY_IMAGE => $user->lang['CAT_IMAGES'], ATTACHMENT_CATEGORY_WM => $user->lang['CAT_WM_FILES'], ATTACHMENT_CATEGORY_RM => $user->lang['CAT_RM_FILES'], ATTACHMENT_CATEGORY_FLASH => $user->lang['CAT_FLASH_FILES'], ATTACHMENT_CATEGORY_QUICKTIME => $user->lang['CAT_QUICKTIME_FILES']); $group_id = request_var('g', 0); $action = isset($_POST['add']) ? 'add' : $action; switch ($action) { case 'delete': if (confirm_box(true)) { $sql = 'SELECT group_name FROM ' . EXTENSION_GROUPS_TABLE . "\n\t\t\t\t\t\t\t\tWHERE group_id = {$group_id}"; $result = $db->sql_query($sql); $group_name = (string) $db->sql_fetchfield('group_name'); $db->sql_freeresult($result); $sql = 'DELETE FROM ' . EXTENSION_GROUPS_TABLE . "\n\t\t\t\t\t\t\t\tWHERE group_id = {$group_id}"; $db->sql_query($sql); // Set corresponding Extensions to a pending Group $sql = 'UPDATE ' . EXTENSIONS_TABLE . "\n\t\t\t\t\t\t\t\tSET group_id = 0\n\t\t\t\t\t\t\t\tWHERE group_id = {$group_id}"; $db->sql_query($sql); add_log('admin', 'LOG_ATTACH_EXTGROUP_DEL', $group_name); $cache->destroy('_extensions'); trigger_error($user->lang['EXTENSION_GROUP_DELETED'] . adm_back_link($this->u_action)); } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array('i' => $id, 'mode' => $mode, 'group_id' => $group_id, 'action' => 'delete'))); } break; case 'edit': if (!$group_id) { trigger_error($user->lang['NO_EXT_GROUP_SPECIFIED'] . adm_back_link($this->u_action), E_USER_WARNING); } $sql = 'SELECT * FROM ' . EXTENSION_GROUPS_TABLE . "\n\t\t\t\t\t\t\tWHERE group_id = {$group_id}"; $result = $db->sql_query($sql); $ext_group_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); $forum_ids = !$ext_group_row['allowed_forums'] ? array() : unserialize(trim($ext_group_row['allowed_forums'])); // no break; // no break; case 'add': if ($action == 'add') { $ext_group_row = array('group_name' => utf8_normalize_nfc(request_var('group_name', '', true)), 'cat_id' => 0, 'allow_group' => 1, 'allow_in_pm' => 1, 'upload_icon' => '', 'max_filesize' => 0); $forum_ids = array(); } $extensions = array(); $sql = 'SELECT * FROM ' . EXTENSIONS_TABLE . "\n\t\t\t\t\t\t\tWHERE group_id = {$group_id}\n\t\t\t\t\t\t\t\tOR group_id = 0\n\t\t\t\t\t\t\tORDER BY extension"; $result = $db->sql_query($sql); $extensions = $db->sql_fetchrowset($result); $db->sql_freeresult($result); if ($ext_group_row['max_filesize'] == 0) { $ext_group_row['max_filesize'] = (int) $config['max_filesize']; } $size_format = $ext_group_row['max_filesize'] >= 1048576 ? 'mb' : ($ext_group_row['max_filesize'] >= 1024 ? 'kb' : 'b'); $ext_group_row['max_filesize'] = get_formatted_filesize($ext_group_row['max_filesize'], false); $img_path = $config['upload_icons_path']; $filename_list = ''; $no_image_select = false; $imglist = filelist($phpbb_root_path . $img_path); if (sizeof($imglist)) { $imglist = array_values($imglist); $imglist = $imglist[0]; foreach ($imglist as $key => $img) { if (!$ext_group_row['upload_icon']) { $no_image_select = true; $selected = ''; } else { $selected = $ext_group_row['upload_icon'] == $img ? ' selected="selected"' : ''; } if (strlen($img) > 255) { continue; } $filename_list .= '<option value="' . htmlspecialchars($img) . '"' . $selected . '>' . htmlspecialchars($img) . '</option>'; } } $i = 0; $assigned_extensions = ''; foreach ($extensions as $num => $row) { if ($row['group_id'] == $group_id && $group_id) { $assigned_extensions .= $i ? ', ' . $row['extension'] : $row['extension']; $i++; } } $s_extension_options = ''; foreach ($extensions as $row) { $s_extension_options .= '<option' . (!$row['group_id'] ? ' class="disabled"' : '') . ' value="' . $row['extension_id'] . '"' . ($row['group_id'] == $group_id && $group_id ? ' selected="selected"' : '') . '>' . $row['extension'] . '</option>'; } $template->assign_vars(array('PHPBB_ROOT_PATH' => $phpbb_root_path, 'IMG_PATH' => $img_path, 'ACTION' => $action, 'GROUP_ID' => $group_id, 'GROUP_NAME' => $ext_group_row['group_name'], 'ALLOW_GROUP' => $ext_group_row['allow_group'], 'ALLOW_IN_PM' => $ext_group_row['allow_in_pm'], 'UPLOAD_ICON_SRC' => $phpbb_root_path . $img_path . '/' . $ext_group_row['upload_icon'], 'EXTGROUP_FILESIZE' => $ext_group_row['max_filesize'], 'ASSIGNED_EXTENSIONS' => $assigned_extensions, 'S_CATEGORY_SELECT' => $this->category_select('special_category', $group_id, 'category'), 'S_EXT_GROUP_SIZE_OPTIONS' => size_select_options($size_format), 'S_EXTENSION_OPTIONS' => $s_extension_options, 'S_FILENAME_LIST' => $filename_list, 'S_EDIT_GROUP' => true, 'S_NO_IMAGE' => $no_image_select, 'S_FORUM_IDS' => sizeof($forum_ids) ? true : false, 'U_EXTENSIONS' => append_sid("{$phpbb_admin_path}index.{$phpEx}", "i={$id}&mode=extensions"), 'U_BACK' => $this->u_action, 'L_LEGEND' => $user->lang[strtoupper($action) . '_EXTENSION_GROUP'])); $s_forum_id_options = ''; /** @todo use in-built function **/ $sql = 'SELECT forum_id, forum_name, parent_id, forum_type, left_id, right_id FROM ' . FORUMS_TABLE . ' ORDER BY left_id ASC'; $result = $db->sql_query($sql, 600); $right = $cat_right = $padding_inc = 0; $padding = $forum_list = $holding = ''; $padding_store = array('0' => ''); while ($row = $db->sql_fetchrow($result)) { if ($row['forum_type'] == FORUM_CAT && $row['left_id'] + 1 == $row['right_id']) { // Non-postable forum with no subforums, don't display continue; } if (!$auth->acl_get('f_list', $row['forum_id'])) { // if the user does not have permissions to list this forum skip continue; } if ($row['left_id'] < $right) { $padding .= ' '; $padding_store[$row['parent_id']] = $padding; } else { if ($row['left_id'] > $right + 1) { $padding = empty($padding_store[$row['parent_id']]) ? '' : $padding_store[$row['parent_id']]; } } $right = $row['right_id']; $selected = in_array($row['forum_id'], $forum_ids) ? ' selected="selected"' : ''; if ($row['left_id'] > $cat_right) { // make sure we don't forget anything $s_forum_id_options .= $holding; $holding = ''; } if ($row['right_id'] - $row['left_id'] > 1) { $cat_right = max($cat_right, $row['right_id']); $holding .= '<option value="' . $row['forum_id'] . '"' . ($row['forum_type'] == FORUM_POST ? ' class="sep"' : '') . $selected . '>' . $padding . $row['forum_name'] . '</option>'; } else { $s_forum_id_options .= $holding . '<option value="' . $row['forum_id'] . '"' . ($row['forum_type'] == FORUM_POST ? ' class="sep"' : '') . $selected . '>' . $padding . $row['forum_name'] . '</option>'; $holding = ''; } } if ($holding) { $s_forum_id_options .= $holding; } $db->sql_freeresult($result); unset($padding_store); $template->assign_vars(array('S_FORUM_ID_OPTIONS' => $s_forum_id_options)); break; } $sql = 'SELECT * FROM ' . EXTENSION_GROUPS_TABLE . ' ORDER BY allow_group DESC, allow_in_pm DESC, group_name'; $result = $db->sql_query($sql); $old_allow_group = $old_allow_pm = 1; while ($row = $db->sql_fetchrow($result)) { $s_add_spacer = $old_allow_group != $row['allow_group'] || $old_allow_pm != $row['allow_in_pm'] ? true : false; $template->assign_block_vars('groups', array('S_ADD_SPACER' => $s_add_spacer, 'S_ALLOWED_IN_PM' => $row['allow_in_pm'] ? true : false, 'S_GROUP_ALLOWED' => $row['allow_group'] ? true : false, 'U_EDIT' => $this->u_action . "&action=edit&g={$row['group_id']}", 'U_DELETE' => $this->u_action . "&action=delete&g={$row['group_id']}", 'GROUP_NAME' => $row['group_name'], 'CATEGORY' => $cat_lang[$row['cat_id']])); $old_allow_group = $row['allow_group']; $old_allow_pm = $row['allow_in_pm']; } $db->sql_freeresult($result); break; case 'orphan': if ($submit) { $delete_files = isset($_POST['delete']) ? array_keys(request_var('delete', array('' => 0))) : array(); $add_files = isset($_POST['add']) ? array_keys(request_var('add', array('' => 0))) : array(); $post_ids = request_var('post_id', array('' => 0)); if (sizeof($delete_files)) { $sql = 'SELECT * FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('attach_id', $delete_files) . ' AND is_orphan = 1'; $result = $db->sql_query($sql); $delete_files = array(); while ($row = $db->sql_fetchrow($result)) { phpbb_unlink($row['physical_filename'], 'file'); if ($row['thumbnail']) { phpbb_unlink($row['physical_filename'], 'thumbnail'); } $delete_files[$row['attach_id']] = $row['real_filename']; } $db->sql_freeresult($result); } if (sizeof($delete_files)) { $sql = 'DELETE FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('attach_id', array_keys($delete_files)); $db->sql_query($sql); add_log('admin', 'LOG_ATTACH_ORPHAN_DEL', implode(', ', $delete_files)); $notify[] = sprintf($user->lang['LOG_ATTACH_ORPHAN_DEL'], implode(', ', $delete_files)); } $upload_list = array(); foreach ($add_files as $attach_id) { if (!isset($delete_files[$attach_id]) && !empty($post_ids[$attach_id])) { $upload_list[$attach_id] = $post_ids[$attach_id]; } } unset($add_files); if (sizeof($upload_list)) { $template->assign_var('S_UPLOADING_FILES', true); $sql = 'SELECT forum_id, forum_name FROM ' . FORUMS_TABLE; $result = $db->sql_query($sql); $forum_names = array(); while ($row = $db->sql_fetchrow($result)) { $forum_names[$row['forum_id']] = $row['forum_name']; } $db->sql_freeresult($result); $sql = 'SELECT forum_id, topic_id, post_id, poster_id FROM ' . POSTS_TABLE . ' WHERE ' . $db->sql_in_set('post_id', $upload_list); $result = $db->sql_query($sql); $post_info = array(); while ($row = $db->sql_fetchrow($result)) { $post_info[$row['post_id']] = $row; } $db->sql_freeresult($result); // Select those attachments we want to change... $sql = 'SELECT * FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('attach_id', array_keys($upload_list)) . ' AND is_orphan = 1'; $result = $db->sql_query($sql); $files_added = $space_taken = 0; while ($row = $db->sql_fetchrow($result)) { $post_row = $post_info[$upload_list[$row['attach_id']]]; $template->assign_block_vars('upload', array('FILE_INFO' => sprintf($user->lang['UPLOADING_FILE_TO'], $row['real_filename'], $post_row['post_id']), 'S_DENIED' => !$auth->acl_get('f_attach', $post_row['forum_id']) ? true : false, 'L_DENIED' => !$auth->acl_get('f_attach', $post_row['forum_id']) ? sprintf($user->lang['UPLOAD_DENIED_FORUM'], $forum_names[$row['forum_id']]) : '')); if (!$auth->acl_get('f_attach', $post_row['forum_id'])) { continue; } // Adjust attachment entry $sql_ary = array('in_message' => 0, 'is_orphan' => 0, 'poster_id' => $post_row['poster_id'], 'post_msg_id' => $post_row['post_id'], 'topic_id' => $post_row['topic_id']); $sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE attach_id = ' . $row['attach_id']; $db->sql_query($sql); $sql = 'UPDATE ' . POSTS_TABLE . ' SET post_attachment = 1 WHERE post_id = ' . $post_row['post_id']; $db->sql_query($sql); $sql = 'UPDATE ' . TOPICS_TABLE . ' SET topic_attachment = 1 WHERE topic_id = ' . $post_row['topic_id']; $db->sql_query($sql); $space_taken += $row['filesize']; $files_added++; add_log('admin', 'LOG_ATTACH_FILEUPLOAD', $post_row['post_id'], $row['real_filename']); } $db->sql_freeresult($result); if ($files_added) { set_config('upload_dir_size', $config['upload_dir_size'] + $space_taken, true); set_config('num_files', $config['num_files'] + $files_added, true); } } } $template->assign_vars(array('S_ORPHAN' => true)); // Just get the files with is_orphan set and older than 3 hours $sql = 'SELECT * FROM ' . ATTACHMENTS_TABLE . ' WHERE is_orphan = 1 AND filetime < ' . (time() - 3 * 60 * 60) . ' ORDER BY filetime DESC'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $template->assign_block_vars('orphan', array('FILESIZE' => get_formatted_filesize($row['filesize']), 'FILETIME' => $user->format_date($row['filetime']), 'REAL_FILENAME' => basename($row['real_filename']), 'PHYSICAL_FILENAME' => basename($row['physical_filename']), 'ATTACH_ID' => $row['attach_id'], 'POST_IDS' => !empty($post_ids[$row['attach_id']]) ? $post_ids[$row['attach_id']] : '', 'U_FILE' => append_sid($phpbb_root_path . 'download/file.' . $phpEx, 'mode=view&id=' . $row['attach_id']))); } $db->sql_freeresult($result); break; } if (sizeof($error)) { $template->assign_vars(array('S_WARNING' => true, 'WARNING_MSG' => implode('<br />', $error))); } if (sizeof($notify)) { $template->assign_vars(array('S_NOTIFY' => true, 'NOTIFY_MSG' => implode('<br />', $notify))); } }
/** * Parse Attachments */ function parse_attachments($form_name, $mode, $forum_id, $submit, $preview, $refresh, $is_message = false) { global $config, $auth, $user, $phpbb_root_path, $phpEx, $db, $request; $error = array(); $num_attachments = sizeof($this->attachment_data); $this->filename_data['filecomment'] = $request->variable('filecomment', '', true); $upload = $request->file($form_name); $upload_file = !empty($upload) && $upload['name'] !== 'none' && trim($upload['name']); $add_file = isset($_POST['add_file']) ? true : false; $delete_file = isset($_POST['delete_file']) ? true : false; // First of all adjust comments if changed $actual_comment_list = $request->variable('comment_list', array(''), true); foreach ($actual_comment_list as $comment_key => $comment) { if (!isset($this->attachment_data[$comment_key])) { continue; } if ($this->attachment_data[$comment_key]['attach_comment'] != $actual_comment_list[$comment_key]) { $this->attachment_data[$comment_key]['attach_comment'] = $actual_comment_list[$comment_key]; } } $cfg = array(); $cfg['max_attachments'] = $is_message ? $config['max_attachments_pm'] : $config['max_attachments']; $forum_id = $is_message ? 0 : $forum_id; if ($submit && in_array($mode, array('post', 'reply', 'quote', 'edit')) && $upload_file) { if ($num_attachments < $cfg['max_attachments'] || $auth->acl_get('a_') || $auth->acl_get('m_', $forum_id)) { $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message); $error = $filedata['error']; if ($filedata['post_attach'] && !sizeof($error)) { $sql_ary = array('physical_filename' => $filedata['physical_filename'], 'attach_comment' => $this->filename_data['filecomment'], 'real_filename' => $filedata['real_filename'], 'extension' => $filedata['extension'], 'mimetype' => $filedata['mimetype'], 'filesize' => $filedata['filesize'], 'filetime' => $filedata['filetime'], 'thumbnail' => $filedata['thumbnail'], 'is_orphan' => 1, 'in_message' => $is_message ? 1 : 0, 'poster_id' => $user->data['user_id']); $db->sql_query('INSERT INTO ' . ATTACHMENTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); $new_entry = array('attach_id' => $db->sql_nextid(), 'is_orphan' => 1, 'real_filename' => $filedata['real_filename'], 'attach_comment' => $this->filename_data['filecomment'], 'filesize' => $filedata['filesize']); $this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data); $this->message = preg_replace_callback('#\\[attachment=([0-9]+)\\](.*?)\\[\\/attachment\\]#', function ($match) { return '[attachment=' . ($match[1] + 1) . ']' . $match[2] . '[/attachment]'; }, $this->message); $this->filename_data['filecomment'] = ''; // This Variable is set to false here, because Attachments are entered into the // Database in two modes, one if the id_list is 0 and the second one if post_attach is true // Since post_attach is automatically switched to true if an Attachment got added to the filesystem, // but we are assigning an id of 0 here, we have to reset the post_attach variable to false. // // This is very relevant, because it could happen that the post got not submitted, but we do not // know this circumstance here. We could be at the posting page or we could be redirected to the entered // post. :) $filedata['post_attach'] = false; } } else { $error[] = $user->lang('TOO_MANY_ATTACHMENTS', (int) $cfg['max_attachments']); } } if ($preview || $refresh || sizeof($error)) { if (isset($this->plupload) && $this->plupload->is_active()) { $json_response = new \phpbb\json_response(); } // Perform actions on temporary attachments if ($delete_file) { include_once $phpbb_root_path . 'includes/functions_admin.' . $phpEx; $index = array_keys($request->variable('delete_file', array(0 => 0))); $index = !empty($index) ? $index[0] : false; if ($index !== false && !empty($this->attachment_data[$index])) { // delete selected attachment if ($this->attachment_data[$index]['is_orphan']) { $sql = 'SELECT attach_id, physical_filename, thumbnail FROM ' . ATTACHMENTS_TABLE . ' WHERE attach_id = ' . (int) $this->attachment_data[$index]['attach_id'] . ' AND is_orphan = 1 AND poster_id = ' . $user->data['user_id']; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row) { phpbb_unlink($row['physical_filename'], 'file'); if ($row['thumbnail']) { phpbb_unlink($row['physical_filename'], 'thumbnail'); } $db->sql_query('DELETE FROM ' . ATTACHMENTS_TABLE . ' WHERE attach_id = ' . (int) $this->attachment_data[$index]['attach_id']); } } else { delete_attachments('attach', array(intval($this->attachment_data[$index]['attach_id']))); } unset($this->attachment_data[$index]); $this->message = preg_replace_callback('#\\[attachment=([0-9]+)\\](.*?)\\[\\/attachment\\]#', function ($match) use($index) { return $match[1] == $index ? '' : ($match[1] > $index ? '[attachment=' . ($match[1] - 1) . ']' . $match[2] . '[/attachment]' : $match[0]); }, $this->message); // Reindex Array $this->attachment_data = array_values($this->attachment_data); if (isset($this->plupload) && $this->plupload->is_active()) { $json_response->send($this->attachment_data); } } } else { if (($add_file || $preview) && $upload_file) { if ($num_attachments < $cfg['max_attachments'] || $auth->acl_gets('m_', 'a_', $forum_id)) { $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message, false, $this->mimetype_guesser, $this->plupload); $error = array_merge($error, $filedata['error']); if (!sizeof($error)) { $sql_ary = array('physical_filename' => $filedata['physical_filename'], 'attach_comment' => $this->filename_data['filecomment'], 'real_filename' => $filedata['real_filename'], 'extension' => $filedata['extension'], 'mimetype' => $filedata['mimetype'], 'filesize' => $filedata['filesize'], 'filetime' => $filedata['filetime'], 'thumbnail' => $filedata['thumbnail'], 'is_orphan' => 1, 'in_message' => $is_message ? 1 : 0, 'poster_id' => $user->data['user_id']); $db->sql_query('INSERT INTO ' . ATTACHMENTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); $new_entry = array('attach_id' => $db->sql_nextid(), 'is_orphan' => 1, 'real_filename' => $filedata['real_filename'], 'attach_comment' => $this->filename_data['filecomment'], 'filesize' => $filedata['filesize']); $this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data); $this->message = preg_replace_callback('#\\[attachment=([0-9]+)\\](.*?)\\[\\/attachment\\]#', function ($match) { return '[attachment=' . ($match[1] + 1) . ']' . $match[2] . '[/attachment]'; }, $this->message); $this->filename_data['filecomment'] = ''; if (isset($this->plupload) && $this->plupload->is_active()) { $download_url = append_sid("{$phpbb_root_path}download/file.{$phpEx}", 'mode=view&id=' . $new_entry['attach_id']); // Send the client the attachment data to maintain state $json_response->send(array('data' => $this->attachment_data, 'download_url' => $download_url)); } } } else { $error[] = $user->lang('TOO_MANY_ATTACHMENTS', (int) $cfg['max_attachments']); } if (!empty($error) && isset($this->plupload) && $this->plupload->is_active()) { // If this is a plupload (and thus ajax) request, give the // client the first error we have $json_response->send(array('jsonrpc' => '2.0', 'id' => 'id', 'error' => array('code' => 105, 'message' => current($error)))); } } } } foreach ($error as $error_msg) { $this->warn_msg[] = $error_msg; } }
function delete_attachments($mode, $ids, $resync = TRUE) { global $_CLASS, $config; if (is_array($ids)) { $ids = array_unique($ids); } if (!sizeof($ids)) { return false; } $sql_id = $mode == 'user' ? 'poster_id' : ($mode == 'post' ? 'post_msg_id' : ($mode == 'topic' ? 'topic_id' : 'attach_id')); $post_ids = $topic_ids = $physical = array(); // Collect post and topics ids for later use if ($mode == 'attach' || $mode == 'user' || $mode == 'topic' && $resync) { $sql = 'SELECT post_msg_id as post_id, topic_id, physical_filename, thumbnail, filesize FROM ' . FORUMS_ATTACHMENTS_TABLE . ' WHERE ' . $sql_id . ' IN (' . implode(', ', $ids) . ')'; $result = $_CLASS['core_db']->query($sql); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $post_ids[] = $row['post_id']; $topic_ids[] = $row['topic_id']; $physical[] = array('filename' => $row['physical_filename'], 'thumbnail' => $row['thumbnail'], 'filesize' => $row['filesize']); } $_CLASS['core_db']->free_result($result); } if ($mode == 'post') { $sql = 'SELECT topic_id, physical_filename, thumbnail, filesize FROM ' . FORUMS_ATTACHMENTS_TABLE . ' WHERE post_msg_id IN (' . implode(', ', $ids) . ') AND in_message = 0'; $result = $_CLASS['core_db']->query($sql); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $topic_ids[] = $row['topic_id']; $physical[] = array('filename' => $row['physical_filename'], 'thumbnail' => $row['thumbnail'], 'filesize' => $row['filesize']); } $_CLASS['core_db']->free_result($result); } // Delete attachments $_CLASS['core_db']->query('DELETE FROM ' . FORUMS_ATTACHMENTS_TABLE . ' WHERE ' . $sql_id . ' IN (' . implode(', ', $ids) . ')'); $num_deleted = $_CLASS['core_db']->affected_rows(); if (!$num_deleted) { return 0; } // Delete attachments from filesystem $space_removed = $files_removed = 0; foreach ($physical as $file_ary) { if (phpbb_unlink($file_ary['filename'], 'file')) { $space_removed += $file_ary['filesize']; $files_removed++; } if ($file_ary['thumbnail']) { phpbb_unlink($file_ary['filename'], 'thumbnail'); } } set_config('upload_dir_size', $config['upload_dir_size'] - $space_removed, true); set_config('num_files', $config['num_files'] - $files_removed, true); if ($mode == 'topic' && !$resync) { return $num_deleted; } if ($mode == 'post') { $post_ids = $ids; } unset($ids); $post_ids = array_unique($post_ids); $topic_ids = array_unique($topic_ids); // Update post indicators if (sizeof($post_ids)) { if ($mode == 'post' || $mode == 'topic') { $_CLASS['core_db']->query('UPDATE ' . FORUMS_POSTS_TABLE . ' SET post_attachment = 0 WHERE post_id IN (' . implode(', ', $post_ids) . ')'); } if ($mode == 'user' || $mode == 'attach') { $remaining = array(); $sql = 'SELECT post_msg_id FROM ' . FORUMS_ATTACHMENTS_TABLE . ' WHERE post_msg_id IN (' . implode(', ', $post_ids) . ') AND in_message = 0'; $result = $_CLASS['core_db']->query($sql); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $remaining[] = $row['post_msg_id']; } $_CLASS['core_db']->free_result($result); $unset_ids = array_diff($post_ids, $remaining); if (sizeof($unset_ids)) { $_CLASS['core_db']->query('UPDATE ' . FORUMS_POSTS_TABLE . ' SET post_attachment = 0 WHERE post_id IN (' . implode(', ', $unset_ids) . ')'); } $remaining = array(); $sql = 'SELECT post_msg_id FROM ' . FORUMS_ATTACHMENTS_TABLE . ' WHERE post_msg_id IN (' . implode(', ', $post_ids) . ') AND in_message = 1'; $result = $_CLASS['core_db']->query($sql); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $remaining[] = $row['post_msg_id']; } $_CLASS['core_db']->free_result($result); $unset_ids = array_diff($post_ids, $remaining); if (sizeof($unset_ids)) { $_CLASS['core_db']->query('UPDATE ' . FORUMS_PRIVMSGS_TABLE . ' SET message_attachment = 0 WHERE msg_id IN (' . implode(', ', $unset_ids) . ')'); } } } if (sizeof($topic_ids)) { // Update topic indicator if ($mode == 'topic') { $_CLASS['core_db']->query('UPDATE ' . FORUMS_TOPICS_TABLE . ' SET topic_attachment = 0 WHERE topic_id IN (' . implode(', ', $topic_ids) . ')'); } if ($mode == 'post' || $mode == 'user' || $mode == 'attach') { $remaining = array(); $sql = 'SELECT topic_id FROM ' . FORUMS_ATTACHMENTS_TABLE . ' WHERE topic_id IN (' . implode(', ', $topic_ids) . ')'; $result = $_CLASS['core_db']->query($sql); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $remaining[] = $row['topic_id']; } $_CLASS['core_db']->free_result($result); $unset_ids = array_diff($topic_ids, $remaining); if (sizeof($unset_ids)) { $_CLASS['core_db']->query('UPDATE ' . FORUMS_TOPICS_TABLE . ' SET topic_attachment = 0 WHERE topic_id IN (' . implode(', ', $unset_ids) . ')'); } } } return $num_deleted; }
function delete_forum_content($forum_id) { global $_CLASS, $site_file_root; require_once $site_file_root . 'includes/forums/functions_posting.php'; $_CLASS['core_db']->transaction(); switch ($_CLASS['core_db']->db_layer) { // Needs updating and testing /* case 'mysql4': case 'mysqli': // Select then delete all attachments $sql = 'SELECT a.topic_id FROM ' . POSTS_TABLE . ' p, ' . ATTACHMENTS_TABLE . " a WHERE p.forum_id = $forum_id AND a.in_message = 0 AND a.topic_id = p.topic_id"; $result = $_CLASS['core_db']->query($sql); $topic_ids = array(); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $topic_ids[] = $row['topic_id']; } $_CLASS['core_db']->free_result($result); delete_attachments('topic', $topic_ids, false); // Delete everything else and thank MySQL for offering multi-table deletion $tables_ary = array( BOOKMARKS_TABLE => 'bm.topic_id', SEARCH_MATCH_TABLE => 'wm.post_id', REPORTS_TABLE => 're.post_id', TOPICS_WATCH_TABLE => 'tw.topic_id', TOPICS_TRACK_TABLE => 'tt.topic_id', POLL_OPTIONS_TABLE => 'po.topic_id', POLL_VOTES_TABLE => 'pv.topic_id' ); $sql = 'DELETE QUICK FROM ' . POSTS_TABLE; $sql_using = "\nUSING " . POSTS_TABLE . ' p'; $sql_where = "\nWHERE p.forum_id = $forum_id\n"; $sql_optimise = 'OPTIMIZE TABLE . ' . POSTS_TABLE; foreach ($tables_ary as $table => $field) { $sql .= ", $table"; $sql_using .= ", $table " . strtok($field, '.'); $sql_where .= "\nAND $field = p." . strtok(''); $sql_optimise .= ', ' . $table; } $_CLASS['core_db']->query($sql . $sql_using . $sql_where); $tables_ary = array(FORUMS_ACCESS_TABLE, TOPICS_TABLE, FORUMS_TRACK_TABLE, FORUMS_WATCH_TABLE, ACL_GROUPS_TABLE, ACL_USERS_TABLE, MODERATOR_TABLE, LOG_TABLE); foreach ($tables_ary as $table) { $_CLASS['core_db']->query("DELETE QUICK FROM $table WHERE forum_id = $forum_id"); $sql_optimise .= ', ' . $table; } // Now optimise a hell lot of tables $_CLASS['core_db']->query($sql_optimise); break; */ default: // Select then delete all attachments $sql = 'SELECT a.attach_id, a.physical_filename, a.thumbnail FROM ' . FORUMS_POSTS_TABLE . ' p, ' . FORUMS_ATTACHMENTS_TABLE . " a\n\t\t\t\tWHERE p.forum_id = {$forum_id}\n\t\t\t\t\tAND a.in_message = 0\n\t\t\t\t\tAND a.post_msg_id = p.post_id"; $result = $_CLASS['core_db']->query($sql); $attach_ids = array(); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $attach_ids[] = $row['attach_id']; phpbb_unlink($row['physical_filename'], 'file'); if ($row['thumbnail']) { phpbb_unlink($row['physical_filename'], 'thumbnail'); } } $_CLASS['core_db']->free_result($result); if (count($attach_ids)) { $attach_id_list = implode(',', array_unique($attach_ids)); $_CLASS['core_db']->query('DELETE FROM ' . FORUMS_ATTACHMENTS_TABLE . " WHERE attach_id IN ({$attach_id_list})"); unset($attach_ids, $attach_id_list); } // Delete everything else and curse your DB for not offering multi-table deletion $tables_ary = array('post_id' => array(FORUMS_SEARCH_MATCH_TABLE, FORUMS_REPORTS_TABLE), 'topic_id' => array(FORUMS_BOOKMARKS_TABLE, FORUMS_WATCH_TABLE, FORUMS_TRACK_TABLE, FORUMS_POLL_OPTIONS_TABLE, FORUMS_POLL_VOTES_TABLE)); foreach ($tables_ary as $field => $tables) { $start = 0; $id_array = array(); $sql = "SELECT {$field}\n\t\t\t\t\tFROM " . FORUMS_POSTS_TABLE . ' WHERE forum_id = ' . $forum_id; $result = $_CLASS['core_db']->query($sql); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $id_array[] = $row[$field]; } $_CLASS['core_db']->free_result($result); if (empty($id_array)) { continue; } foreach ($tables as $table) { $_CLASS['core_db']->query("DELETE FROM {$table} WHERE {$field} IN (" . implode(',', $id_array) . ')'); } } unset($id_array); $table_ary = array(FORUMS_POSTS_TABLE, FORUMS_TRACK_TABLE, FORUMS_WATCH_TABLE, FORUMS_TOPICS_TABLE, FORUMS_ACL_TABLE, FORUMS_MODERATOR_TABLE, FORUMS_LOG_TABLE); foreach ($table_ary as $table) { $_CLASS['core_db']->query("DELETE FROM {$table} WHERE forum_id = {$forum_id}"); } break; } $_CLASS['core_db']->transaction('commit'); // NEED to have this done at the end, maybe a cran $tables = array_unique(array_merge($tables_ary['post_id'], $tables_ary['topic_id'], $table_ary, array(FORUMS_ATTACHMENTS_TABLE))); $_CLASS['core_db']->optimize_tables($tables); }
function parse_attachments($form_name, $mode, $forum_id, $submit, $preview, $refresh, $is_message = false) { global $config, $_CLASS, $site_file_root, $forum_id; $error = array(); $num_attachments = sizeof($this->attachment_data); $this->filename_data['filecomment'] = request_var('filecomment', '', true); $upload_file = isset($_FILES[$form_name]) && $_FILES[$form_name]['name'] != 'none' && trim($_FILES[$form_name]['name']) ? true : false; $add_file = isset($_POST['add_file']); $delete_file = isset($_POST['delete_file']); $edit_comment = isset($_POST['edit_comment']); $cfg = array(); $cfg['max_attachments'] = $is_message ? $config['max_attachments_pm'] : $config['max_attachments']; $forum_id = $is_message ? 0 : $forum_id; if ($submit && in_array($mode, array('post', 'reply', 'quote', 'edit')) && $upload_file) { if ($num_attachments < $cfg['max_attachments'] || $_CLASS['auth']->acl_gets('m_', 'a_')) { $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message); $error = $filedata['error']; if ($filedata['post_attach'] && !sizeof($error)) { $new_entry = array('physical_filename' => $filedata['physical_filename'], 'comment' => $this->filename_data['filecomment'], 'real_filename' => $filedata['real_filename'], 'extension' => $filedata['extension'], 'mimetype' => $filedata['mimetype'], 'filesize' => $filedata['filesize'], 'filetime' => $filedata['filetime'], 'attach_id' => 0, 'thumbnail' => $filedata['thumbnail']); $this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data); $this->message = preg_replace('#\\[attachment=([0-9]+)\\](.*?)\\[\\/attachment\\]#e', "'[attachment='.(\\1 + 1).']\\2[/attachment]'", $this->message); $this->filename_data['filecomment'] = ''; // This Variable is set to false here, because Attachments are entered into the // Database in two modes, one if the id_list is 0 and the second one if post_attach is true // Since post_attach is automatically switched to true if an Attachment got added to the filesystem, // but we are assigning an id of 0 here, we have to reset the post_attach variable to false. // // This is very relevant, because it could happen that the post got not submitted, but we do not // know this circumstance here. We could be at the posting page or we could be redirected to the entered // post. :) $filedata['post_attach'] = false; } } else { $error[] = sprintf($_CLASS['core_user']->lang['TOO_MANY_ATTACHMENTS'], $cfg['max_attachments']); } } if ($preview || $refresh || sizeof($error)) { // Perform actions on temporary attachments if ($delete_file) { $index = (int) key($_POST['delete_file']); // delete selected attachment if (!$this->attachment_data[$index]['attach_id']) { phpbb_unlink($this->attachment_data[$index]['physical_filename'], 'file'); if ($this->attachment_data[$index]['thumbnail']) { phpbb_unlink($this->attachment_data[$index]['physical_filename'], 'thumbnail'); } } else { delete_attachments('attach', array(intval($this->attachment_data[$index]['attach_id']))); } unset($this->attachment_data[$index]); $this->message = preg_replace('#\\[attachment=([0-9]+)\\](.*?)\\[\\/attachment\\]#e', "(\\1 == \$index) ? '' : ((\\1 > \$index) ? '[attachment=' . (\\1 - 1) . ']\\2[/attachment]' : '\\0')", $this->message); // Reindex Array $this->attachment_data = array_values($this->attachment_data); } else { if ($edit_comment || $add_file || $preview) { if ($edit_comment) { $actual_comment_list = request_var('comment_list', array('')); foreach ($actual_comment_list as $index => $entry) { $this->attachment_data[$index]['comment'] = preg_replace('#&(\\#[0-9]+;)#', '&\\1', $entry); } } if (($add_file || $preview) && $upload_file) { if ($num_attachments < $cfg['max_attachments'] || $_CLASS['auth']->acl_gets('m_', 'a_')) { $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message); $error = array_merge($error, $filedata['error']); if (!sizeof($error)) { $new_entry = array('physical_filename' => $filedata['physical_filename'], 'comment' => $this->filename_data['filecomment'], 'real_filename' => $filedata['real_filename'], 'extension' => $filedata['extension'], 'mimetype' => $filedata['mimetype'], 'filesize' => $filedata['filesize'], 'filetime' => $filedata['filetime'], 'attach_id' => 0, 'thumbnail' => $filedata['thumbnail']); $this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data); $this->message = preg_replace('#\\[attachment=([0-9]+)\\](.*?)\\[\\/attachment\\]#e', "'[attachment='.(\\1 + 1).']\\2[/attachment]'", $this->message); $this->filename_data['filecomment'] = ''; } } else { $error[] = sprintf($_CLASS['core_user']->lang['TOO_MANY_ATTACHMENTS'], $cfg['max_attachments']); } } } } } foreach ($error as $error_msg) { $this->warn_msg[] = $error_msg; } }
/** * Delete Attachments * * @param string $mode can be: post|message|topic|attach|user * @param mixed $ids can be: post_ids, message_ids, topic_ids, attach_ids, user_ids * @param bool $resync set this to false if you are deleting posts or topics */ function delete_attachments($mode, $ids, $resync = true) { global $db, $config, $phpbb_dispatcher; // 0 is as bad as an empty array if (empty($ids)) { return false; } if (is_array($ids)) { $ids = array_unique($ids); $ids = array_map('intval', $ids); } else { $ids = array((int) $ids); } $sql_where = ''; switch ($mode) { case 'post': case 'message': $sql_id = 'post_msg_id'; $sql_where = ' AND in_message = ' . ($mode == 'message' ? 1 : 0); break; case 'topic': $sql_id = 'topic_id'; break; case 'user': $sql_id = 'poster_id'; break; case 'attach': default: $sql_id = 'attach_id'; $mode = 'attach'; break; } $post_ids = $message_ids = $topic_ids = $physical = array(); /** * Perform additional actions before collecting data for attachment(s) deletion * * @event core.delete_attachments_collect_data_before * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user * @var mixed ids Array or comma separated list of ids corresponding to the mode * @var bool resync Flag indicating if posts/messages/topics should be synchronized * @var string sql_id The field name to collect/delete data for depending on the mode * @since 3.1.7-RC1 */ $vars = array('mode', 'ids', 'resync', 'sql_id'); extract($phpbb_dispatcher->trigger_event('core.delete_attachments_collect_data_before', compact($vars))); // Collect post and topic ids for later use if we need to touch remaining entries (if resync is enabled) $sql = 'SELECT post_msg_id, topic_id, in_message, physical_filename, thumbnail, filesize, is_orphan FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set($sql_id, $ids); $sql .= $sql_where; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { // We only need to store post/message/topic ids if resync is enabled and the file is not orphaned if ($resync && !$row['is_orphan']) { if (!$row['in_message']) { $post_ids[] = $row['post_msg_id']; $topic_ids[] = $row['topic_id']; } else { $message_ids[] = $row['post_msg_id']; } } $physical[] = array('filename' => $row['physical_filename'], 'thumbnail' => $row['thumbnail'], 'filesize' => $row['filesize'], 'is_orphan' => $row['is_orphan']); } $db->sql_freeresult($result); /** * Perform additional actions before attachment(s) deletion * * @event core.delete_attachments_before * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user * @var mixed ids Array or comma separated list of ids corresponding to the mode * @var bool resync Flag indicating if posts/messages/topics should be synchronized * @var string sql_id The field name to collect/delete data for depending on the mode * @var array post_ids Array with post ids for deleted attachment(s) * @var array topic_ids Array with topic ids for deleted attachment(s) * @var array message_ids Array with private message ids for deleted attachment(s) * @var array physical Array with deleted attachment(s) physical file(s) data * @since 3.1.7-RC1 */ $vars = array('mode', 'ids', 'resync', 'sql_id', 'post_ids', 'topic_ids', 'message_ids', 'physical'); extract($phpbb_dispatcher->trigger_event('core.delete_attachments_before', compact($vars))); // Delete attachments $sql = 'DELETE FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set($sql_id, $ids); $sql .= $sql_where; $db->sql_query($sql); $num_deleted = $db->sql_affectedrows(); /** * Perform additional actions after attachment(s) deletion from the database * * @event core.delete_attachments_from_database_after * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user * @var mixed ids Array or comma separated list of ids corresponding to the mode * @var bool resync Flag indicating if posts/messages/topics should be synchronized * @var string sql_id The field name to collect/delete data for depending on the mode * @var array post_ids Array with post ids for deleted attachment(s) * @var array topic_ids Array with topic ids for deleted attachment(s) * @var array message_ids Array with private message ids for deleted attachment(s) * @var array physical Array with deleted attachment(s) physical file(s) data * @var int num_deleted The number of deleted attachment(s) from the database * @since 3.1.7-RC1 */ $vars = array('mode', 'ids', 'resync', 'sql_id', 'post_ids', 'topic_ids', 'message_ids', 'physical', 'num_deleted'); extract($phpbb_dispatcher->trigger_event('core.delete_attachments_from_database_after', compact($vars))); if (!$num_deleted) { return 0; } // Delete attachments from filesystem $space_removed = $files_removed = 0; foreach ($physical as $file_ary) { if (phpbb_unlink($file_ary['filename'], 'file', true) && !$file_ary['is_orphan']) { // Only non-orphaned files count to the file size $space_removed += $file_ary['filesize']; $files_removed++; } if ($file_ary['thumbnail']) { phpbb_unlink($file_ary['filename'], 'thumbnail', true); } } /** * Perform additional actions after attachment(s) deletion from the filesystem * * @event core.delete_attachments_from_filesystem_after * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user * @var mixed ids Array or comma separated list of ids corresponding to the mode * @var bool resync Flag indicating if posts/messages/topics should be synchronized * @var string sql_id The field name to collect/delete data for depending on the mode * @var array post_ids Array with post ids for deleted attachment(s) * @var array topic_ids Array with topic ids for deleted attachment(s) * @var array message_ids Array with private message ids for deleted attachment(s) * @var array physical Array with deleted attachment(s) physical file(s) data * @var int num_deleted The number of deleted attachment(s) from the database * @var int space_removed The size of deleted files(s) from the filesystem * @var int files_removed The number of deleted file(s) from the filesystem * @since 3.1.7-RC1 */ $vars = array('mode', 'ids', 'resync', 'sql_id', 'post_ids', 'topic_ids', 'message_ids', 'physical', 'num_deleted', 'space_removed', 'files_removed'); extract($phpbb_dispatcher->trigger_event('core.delete_attachments_from_filesystem_after', compact($vars))); if ($space_removed || $files_removed) { set_config_count('upload_dir_size', $space_removed * -1, true); set_config_count('num_files', $files_removed * -1, true); } // If we do not resync, we do not need to adjust any message, post, topic or user entries if (!$resync) { return $num_deleted; } // No more use for the original ids unset($ids); // Now, we need to resync posts, messages, topics. We go through every one of them $post_ids = array_unique($post_ids); $message_ids = array_unique($message_ids); $topic_ids = array_unique($topic_ids); // Update post indicators for posts now no longer having attachments if (sizeof($post_ids)) { // Just check which posts are still having an assigned attachment not orphaned by querying the attachments table $sql = 'SELECT post_msg_id FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('post_msg_id', $post_ids) . ' AND in_message = 0 AND is_orphan = 0'; $result = $db->sql_query($sql); $remaining_ids = array(); while ($row = $db->sql_fetchrow($result)) { $remaining_ids[] = $row['post_msg_id']; } $db->sql_freeresult($result); // Now only unset those ids remaining $post_ids = array_diff($post_ids, $remaining_ids); if (sizeof($post_ids)) { $sql = 'UPDATE ' . POSTS_TABLE . ' SET post_attachment = 0 WHERE ' . $db->sql_in_set('post_id', $post_ids); $db->sql_query($sql); } } // Update message table if messages are affected if (sizeof($message_ids)) { // Just check which messages are still having an assigned attachment not orphaned by querying the attachments table $sql = 'SELECT post_msg_id FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('post_msg_id', $message_ids) . ' AND in_message = 1 AND is_orphan = 0'; $result = $db->sql_query($sql); $remaining_ids = array(); while ($row = $db->sql_fetchrow($result)) { $remaining_ids[] = $row['post_msg_id']; } $db->sql_freeresult($result); // Now only unset those ids remaining $message_ids = array_diff($message_ids, $remaining_ids); if (sizeof($message_ids)) { $sql = 'UPDATE ' . PRIVMSGS_TABLE . ' SET message_attachment = 0 WHERE ' . $db->sql_in_set('msg_id', $message_ids); $db->sql_query($sql); } } // Now update the topics. This is a bit trickier, because there could be posts still having attachments within the topic if (sizeof($topic_ids)) { // Just check which topics are still having an assigned attachment not orphaned by querying the attachments table (much less entries expected) $sql = 'SELECT topic_id FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('topic_id', $topic_ids) . ' AND is_orphan = 0'; $result = $db->sql_query($sql); $remaining_ids = array(); while ($row = $db->sql_fetchrow($result)) { $remaining_ids[] = $row['topic_id']; } $db->sql_freeresult($result); // Now only unset those ids remaining $topic_ids = array_diff($topic_ids, $remaining_ids); if (sizeof($topic_ids)) { $sql = 'UPDATE ' . TOPICS_TABLE . ' SET topic_attachment = 0 WHERE ' . $db->sql_in_set('topic_id', $topic_ids); $db->sql_query($sql); } } return $num_deleted; }
<h1><?php echo $_CLASS['core_user']->lang[$l_title]; ?></h1> <p><?php echo $_CLASS['core_user']->lang[$l_title . '_EXPLAIN']; ?></p> <?php if ($submit && $mode == 'orphan') { $delete_files = (isset($_POST['delete'])) ? array_keys(request_var('delete', array('' => 0))) : array(); $add_files = (isset($_POST['add'])) ? array_keys(request_var('add', array('' => 0))) : array(); $post_ids = request_var('post_id', 0); foreach ($delete_files as $delete) { phpbb_unlink($delete); phpbb_unlink($delete, 'thumbnail'); } if (sizeof($delete_files)) { add_log('admin', sprintf($_CLASS['core_user']->lang['LOG_ATTACH_ORPHAN_DEL'], implode(', ', $delete_files))); $notify[] = sprintf($_CLASS['core_user']->lang['LOG_ATTACH_ORPHAN_DEL'], implode(', ', $delete_files)); } $upload_list = array(); foreach ($add_files as $file) { if (!in_array($file, $delete_files) && $post_ids[$file]) { $upload_list[$post_ids[$file]] = $file; }
/** * Delete Attachments * * @param string $mode can be: post|topic|attach|user * @param mixed $ids can be: post_ids, topic_ids, attach_ids, user_ids * @param bool $resync set this to false if you are deleting posts or topics */ function delete_attachments($mode, $ids, $resync = true) { global $db, $config; if (is_array($ids) && sizeof($ids)) { $ids = array_unique($ids); $ids = array_map('intval', $ids); } else { $ids = array((int) $ids); } if (!sizeof($ids)) { return false; } $sql_id = ($mode == 'user') ? 'poster_id' : (($mode == 'post') ? 'post_msg_id' : (($mode == 'topic') ? 'topic_id' : 'attach_id')); $post_ids = $topic_ids = $physical = array(); // Collect post and topics ids for later use if ($mode == 'attach' || $mode == 'user' || ($mode == 'topic' && $resync)) { $sql = 'SELECT post_msg_id as post_id, topic_id, physical_filename, thumbnail, filesize FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set($sql_id, $ids); $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $post_ids[] = $row['post_id']; $topic_ids[] = $row['topic_id']; $physical[] = array('filename' => $row['physical_filename'], 'thumbnail' => $row['thumbnail'], 'filesize' => $row['filesize']); } $db->sql_freeresult($result); } if ($mode == 'post') { $sql = 'SELECT topic_id, physical_filename, thumbnail, filesize FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('post_msg_id', $ids) . ' AND in_message = 0'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $topic_ids[] = $row['topic_id']; $physical[] = array('filename' => $row['physical_filename'], 'thumbnail' => $row['thumbnail'], 'filesize' => $row['filesize']); } $db->sql_freeresult($result); } // Delete attachments $sql = 'DELETE FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set($sql_id, $ids); $db->sql_query($sql); $num_deleted = $db->sql_affectedrows(); if (!$num_deleted) { return 0; } // Delete attachments from filesystem $space_removed = $files_removed = 0; foreach ($physical as $file_ary) { if (phpbb_unlink($file_ary['filename'], 'file', true)) { $space_removed += $file_ary['filesize']; $files_removed++; } if ($file_ary['thumbnail']) { phpbb_unlink($file_ary['filename'], 'thumbnail', true); } } set_config('upload_dir_size', $config['upload_dir_size'] - $space_removed, true); set_config('num_files', $config['num_files'] - $files_removed, true); if ($mode == 'topic' && !$resync) { return $num_deleted; } if ($mode == 'post') { $post_ids = $ids; } unset($ids); $post_ids = array_unique($post_ids); $topic_ids = array_unique($topic_ids); // Update post indicators if (sizeof($post_ids)) { if ($mode == 'post' || $mode == 'topic') { $sql = 'UPDATE ' . POSTS_TABLE . ' SET post_attachment = 0 WHERE ' . $db->sql_in_set('post_id', $post_ids); $db->sql_query($sql); } if ($mode == 'user' || $mode == 'attach') { $remaining = array(); $sql = 'SELECT post_msg_id FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('post_msg_id', $post_ids) . ' AND in_message = 0'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $remaining[] = $row['post_msg_id']; } $db->sql_freeresult($result); $unset_ids = array_diff($post_ids, $remaining); if (sizeof($unset_ids)) { $sql = 'UPDATE ' . POSTS_TABLE . ' SET post_attachment = 0 WHERE ' . $db->sql_in_set('post_id', $unset_ids); $db->sql_query($sql); } $remaining = array(); $sql = 'SELECT post_msg_id FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('post_msg_id', $post_ids) . ' AND in_message = 1'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $remaining[] = $row['post_msg_id']; } $db->sql_freeresult($result); $unset_ids = array_diff($post_ids, $remaining); if (sizeof($unset_ids)) { $sql = 'UPDATE ' . PRIVMSGS_TABLE . ' SET message_attachment = 0 WHERE ' . $db->sql_in_set('msg_id', $unset_ids); $db->sql_query($sql); } } } if (sizeof($topic_ids)) { // Update topic indicator if ($mode == 'topic') { $sql = 'UPDATE ' . TOPICS_TABLE . ' SET topic_attachment = 0 WHERE ' . $db->sql_in_set('topic_id', $topic_ids); $db->sql_query($sql); } if ($mode == 'post' || $mode == 'user' || $mode == 'attach') { $remaining = array(); $sql = 'SELECT topic_id FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('topic_id', $topic_ids); $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $remaining[] = $row['topic_id']; } $db->sql_freeresult($result); $unset_ids = array_diff($topic_ids, $remaining); if (sizeof($unset_ids)) { $sql = 'UPDATE ' . TOPICS_TABLE . ' SET topic_attachment = 0 WHERE ' . $db->sql_in_set('topic_id', $unset_ids); $db->sql_query($sql); } } } return $num_deleted; }