From d91361d355c228b15ef13315074120eb08d7a65d Mon Sep 17 00:00:00 2001 From: Jared Hancock <gravydish@gmail.com> Date: Tue, 20 Mar 2012 20:14:01 -0500 Subject: [PATCH] Add deleteOrphans() utility to the File class to remove unused files Also add a cron job to perform the task on demand Change the implementation for Ticket::deleteAttachments to call this method after simply removing all entries from the %ticket_attachment table --- include/class.canned.php | 25 ++++--------------------- include/class.cron.php | 12 +++++++++--- include/class.faq.php | 24 ++++-------------------- include/class.file.php | 18 ++++++++++++++++++ include/class.ticket.php | 13 ++++--------- 5 files changed, 39 insertions(+), 53 deletions(-) diff --git a/include/class.canned.php b/include/class.canned.php index 00c46de33..6c6c1ac1c 100644 --- a/include/class.canned.php +++ b/include/class.canned.php @@ -143,30 +143,13 @@ class Canned { return $i; } - function deleteAttachment($fileId) { - - $sql='DELETE FROM '.CANNED_ATTACHMENT_TABLE - .' WHERE canned_id='.db_input($this->getId()) - .' AND file_id='.db_input($fileId) - .' LIMIT 1'; - - if(!db_query($sql) || !db_affected_rows()) - return false; - - - if(($file=AttachmentFile::lookup($fileId)) && !$file->isInuse()) - $file->delete(); - - return true; - } - function deleteAttachments(){ $deleted=0; - if(($attachments = $this->getAttachments())) { - foreach($attachments as $attachment) - if($attachment['id'] && $this->deleteAttachment($attachment['id'])) - $deleted++; + $sql='DELETE FROM '.CANNED_ATTACHMENT_TABLE + .' WHERE canned_id='.db_input($this->getId()); + if(db_query($sql) && db_affected_rows()) { + $deleted = AttachmentFile::deleteOrphans(); } return $deleted; diff --git a/include/class.cron.php b/include/class.cron.php index 3fd2d652c..ddc4d2973 100644 --- a/include/class.cron.php +++ b/include/class.cron.php @@ -34,10 +34,16 @@ class Cron { Sys::purgeLogs(); } + function CleanOrphanedFiles() { + require_once(INCLUDE_DIR.'class.file.php'); + AttachmentFile::deleteOrphans(); + } + function run(){ //called by outside cron NOT autocron - Cron::MailFetcher(); - Cron::TicketMonitor(); - cron::PurgeLogs(); + self::MailFetcher(); + self::TicketMonitor(); + self::PurgeLogs(); + self::CleanOrphanedFiles(); } } ?> diff --git a/include/class.faq.php b/include/class.faq.php index 63b0848e4..99d6def27 100644 --- a/include/class.faq.php +++ b/include/class.faq.php @@ -217,29 +217,13 @@ class FAQ { return $i; } - function deleteAttachment($fileId) { - - $sql='DELETE FROM '.FAQ_ATTACHMENT_TABLE - .' WHERE faq_id='.db_input($this->getId()) - .' AND file_id='.db_input($fileId) - .' LIMIT 1'; - - if(!db_query($sql) || !db_affected_rows()) - return false; - - if(($file=AttachmentFile::lookup($fileId)) && !$file->isInuse()) - $file->delete(); - - return true; - } - function deleteAttachments(){ $deleted=0; - if(($attachments = $this->getAttachments())) { - foreach($attachments as $attachment) - if($attachment['id'] && $this->deleteAttachment($attachment['id'])) - $deleted++; + $sql='DELETE FROM '.FAQ_ATTACHMENT_TABLE + .' WHERE faq_id='.db_input($this->getId()); + if(db_query($sql) && db_affected_rows()) { + $deleted = AttachmentFile::deleteOrphans(); } return $deleted; diff --git a/include/class.file.php b/include/class.file.php index af38bfd59..91bd1cddc 100644 --- a/include/class.file.php +++ b/include/class.file.php @@ -193,6 +193,24 @@ class AttachmentFile { return ($id && ($file = new AttachmentFile($id)) && $file->getId()==$id)?$file:null; } + /** + * Removes files and associated meta-data for files which no ticket, + * canned-response, or faq point to any more. + */ + /* static */ function deleteOrphans() { + $res=db_query( + 'DELETE FROM '.FILE_TABLE.' WHERE id NOT IN (' + # DISTINCT implies sort and may not be necessary + .'SELECT DISTINCT(file_id) FROM (' + .'SELECT file_id FROM '.TICKET_ATTACHMENT_TABLE + .' UNION ALL ' + .'SELECT file_id FROM '.CANNED_ATTACHMENT_TABLE + .' UNION ALL ' + .'SELECT file_id FROM '.FAQ_ATTACHMENT_TABLE + .') still_loved' + .')'); + return db_affected_rows(); + } } class AttachmentList { diff --git a/include/class.ticket.php b/include/class.ticket.php index edb9ac460..20d8734cd 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -1424,15 +1424,10 @@ class Ticket{ global $cfg; $deleted=0; - if(($attachments = $this->getAttachments())) { - //Clear reference table - XXX: some attachments might be orphaned - db_query('DELETE FROM '.TICKET_ATTACHMENT_TABLE.' WHERE ticket_id='.db_input($this->getId())); - //Delete file from DB IF NOT inuse. - foreach($attachments as $attachment) { - if(($file=AttachmentFile::lookup($attachment['file_id'])) && !$file->isInuse() && $file->delete()) - $deleted++; - } - } + // Clear reference table + $res=db_query('DELETE FROM '.TICKET_ATTACHMENT_TABLE.' WHERE ticket_id='.db_input($this->getId())); + if ($res && db_affected_rows()) + $deleted = AttachmentFile::deleteOrphans(); return $deleted; } -- GitLab