expect_slow_query(600); $fix_errors = true; $debug_mode = false; $tmp_attach_tbl = 'tmp_attachments'; $db_max_packet = 800000; $sql_limit = 3000; $check_attachments = false; $orphan_files = $orphan_db_attach = $orphan_tor = array(); $posts_without_attach = $topics_without_attach = array(); DB()->query(" CREATE TEMPORARY TABLE $tmp_attach_tbl ( physical_filename VARCHAR(255) NOT NULL default '', KEY physical_filename (physical_filename(20)) ) ENGINE = MyISAM DEFAULT CHARSET = utf8 "); DB()->add_shutdown_query("DROP TEMPORARY TABLE IF EXISTS $tmp_attach_tbl"); // Get attach_mod config $attach_dir = get_attachments_dir(); // Creates thumb directory if not exists $thumb_dir = "$attach_dir/" . THUMB_DIR; if (!is_dir($thumb_dir)) { @mkdir($thumb_dir, 0755); @chmod($thumb_dir, 0777); } // Get all names of existed attachments and insert them into $tmp_attach_tbl if ($dir = @opendir($attach_dir)) { $check_attachments = true; $files = array(); $f_len = 0; while (false !== ($f = readdir($dir))) { if ($f == 'index.php' || $f == '.htaccess' || is_dir("$attach_dir/$f") || is_link("$attach_dir/$f")) { continue; } $f = DB()->escape($f); $files[] = "('$f')"; $f_len += strlen($f) + 5; if ($f_len > $db_max_packet) { $files = join(',', $files); DB()->query("INSERT INTO $tmp_attach_tbl VALUES $files"); $files = array(); $f_len = 0; } } if ($files = join(',', $files)) { DB()->query("INSERT INTO $tmp_attach_tbl VALUES $files"); } closedir($dir); } if ($check_attachments) { // Delete bad records DB()->query(" DELETE a, d FROM ". BB_ATTACHMENTS_DESC ." d LEFT JOIN ". BB_ATTACHMENTS ." a USING(attach_id) WHERE ( d.physical_filename = '' OR d.real_filename = '' OR d.extension = '' OR d.mimetype = '' OR d.filesize = 0 OR d.filetime = 0 OR a.post_id = 0 ) "); // Delete attachments that exist in file system but not exist in DB $sql = "SELECT f.physical_filename FROM $tmp_attach_tbl f LEFT JOIN ". BB_ATTACHMENTS_DESC ." d USING(physical_filename) WHERE d.physical_filename IS NULL LIMIT $sql_limit"; foreach (DB()->fetch_rowset($sql) as $row) { if ($filename = basename($row['physical_filename'])) { if ($fix_errors) { @unlink("$attach_dir/$filename"); @unlink("$attach_dir/". THUMB_DIR .'/t_'. $filename); } if ($debug_mode) { $orphan_files[] = "$attach_dir/$filename"; } } } // Find DB records for attachments that exist in DB but not exist in file system $sql = "SELECT d.attach_id FROM ". BB_ATTACHMENTS_DESC ." d LEFT JOIN $tmp_attach_tbl f USING(physical_filename) WHERE f.physical_filename IS NULL LIMIT $sql_limit"; foreach (DB()->fetch_rowset($sql) as $row) { $orphan_db_attach[] = $row['attach_id']; } // Attachment exist in DESC_TABLE but not exist in ATTACH_TABLE $sql = "SELECT d.attach_id FROM ". BB_ATTACHMENTS_DESC ." d LEFT JOIN ". BB_ATTACHMENTS ." a USING(attach_id) WHERE a.attach_id IS NULL LIMIT $sql_limit"; foreach (DB()->fetch_rowset($sql) as $row) { $orphan_db_attach[] = $row['attach_id']; } // Attachment exist in ATTACH_TABLE but not exist in DESC_TABLE $sql = "SELECT a.attach_id FROM ". BB_ATTACHMENTS ." a LEFT JOIN ". BB_ATTACHMENTS_DESC ." d USING(attach_id) WHERE d.attach_id IS NULL LIMIT $sql_limit"; foreach (DB()->fetch_rowset($sql) as $row) { $orphan_db_attach[] = $row['attach_id']; } // Attachments without post $sql = "SELECT a.attach_id FROM ". BB_ATTACHMENTS ." a LEFT JOIN ". BB_POSTS ." p USING(post_id) WHERE p.post_id IS NULL LIMIT $sql_limit"; foreach (DB()->fetch_rowset($sql) as $row) { $orphan_db_attach[] = $row['attach_id']; } // Delete all orphan attachments if ($orphans_sql = join(',', $orphan_db_attach)) { if ($fix_errors) { DB()->query("DELETE FROM ". BB_ATTACHMENTS_DESC ." WHERE attach_id IN($orphans_sql)"); DB()->query("DELETE FROM ". BB_ATTACHMENTS ." WHERE attach_id IN($orphans_sql)"); } } // Torrents without attachments $sql = "SELECT tor.topic_id FROM ". BB_BT_TORRENTS ." tor LEFT JOIN ". BB_ATTACHMENTS_DESC ." d USING(attach_id) WHERE d.attach_id IS NULL LIMIT $sql_limit"; foreach (DB()->fetch_rowset($sql) as $row) { $orphan_tor[] = $row['topic_id']; } // Delete all orphan torrents if ($orphans_sql = join(',', $orphan_tor)) { if ($fix_errors) { DB()->query("DELETE FROM ". BB_BT_TORRENTS ." WHERE topic_id IN($orphans_sql)"); } } // Check post_attachment markers $sql = "SELECT p.post_id FROM ". BB_POSTS ." p LEFT JOIN ". BB_ATTACHMENTS ." a USING(post_id) WHERE p.post_attachment = 1 AND a.post_id IS NULL"; foreach (DB()->fetch_rowset($sql) as $row) { $posts_without_attach[] = $row['post_id']; } if ($posts_sql = join(',', $posts_without_attach)) { if ($fix_errors) { DB()->query("UPDATE ". BB_POSTS ." SET post_attachment = 0 WHERE post_id IN($posts_sql)"); } } // Check topic_attachment markers $sql = "SELECT t.topic_id FROM ". BB_POSTS ." p, ". BB_TOPICS ." t WHERE t.topic_id = p.topic_id AND t.topic_attachment = 1 GROUP BY p.topic_id HAVING SUM(p.post_attachment) = 0"; foreach (DB()->fetch_rowset($sql) as $row) { $topics_without_attach[] = $row['topic_id']; } if ($topics_sql = join(',', $topics_without_attach)) { if ($fix_errors) { DB()->query("UPDATE ". BB_TOPICS ." SET topic_attachment = 0 WHERE topic_id IN($topics_sql)"); } } } if ($debug_mode) { prn_r($orphan_files, '$orphan_files'); prn_r($orphan_db_attach, '$orphan_db_attach'); prn_r($orphan_tor, '$orphan_tor'); prn_r($posts_without_attach, '$posts_without_attach'); prn_r($topics_without_attach, '$topics_without_attach'); } DB()->query("DROP TEMPORARY TABLE $tmp_attach_tbl"); unset($fix_errors, $debug_mode);