torrentpier-lts/library/includes/cron/jobs/attach_maintenance.php

233 lines
5.7 KiB
PHP

<?php
if (!defined('BB_ROOT')) die(basename(__FILE__));
DB()->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);