/** * removes deleted files that no longer exist in the filesystem from the database * * @return integer number of deleted files */ public function clearDeletedFilesFromDatabase() { if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Scanning database for deleted files ...'); } // get all file objects from db and check filesystem existance $filter = new Tinebase_Model_Tree_FileObjectFilter(); $start = 0; $limit = 500; $toDeleteIds = array(); do { $pagination = new Tinebase_Model_Pagination(array('start' => $start, 'limit' => $limit, 'sort' => 'id')); $fileObjects = $this->_fileObjectBackend->search($filter, $pagination); foreach ($fileObjects as $fileObject) { if ($fileObject->type == Tinebase_Model_Tree_FileObject::TYPE_FILE && $fileObject->hash && !file_exists($fileObject->getFilesystemPath())) { $toDeleteIds[] = $fileObject->getId(); } } $start += $limit; } while ($fileObjects->count() >= $limit); $nodeIdsToDelete = $this->_treeNodeBackend->search(new Tinebase_Model_Tree_Node_Filter(array(array('field' => 'object_id', 'operator' => 'in', 'value' => $toDeleteIds))), NULL, Tinebase_Backend_Sql_Abstract::IDCOL); $deleteCount = $this->_treeNodeBackend->delete($nodeIdsToDelete); if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Removed ' . $deleteCount . ' obsolete filenode(s) from the database.'); } return $deleteCount; }
/** * removes deleted files that no longer exist in the database from the filesystem * * @return integer number of deleted files */ public function clearDeletedFiles() { try { $dirIterator = new DirectoryIterator($this->_basePath); } catch (Exception $e) { throw new Tinebase_Exception_AccessDenied('Could not open files directory.'); } if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Scanning ' . $this->_basePath . ' for deleted files.'); } $deleteCount = 0; foreach ($dirIterator as $item) { $subDir = $item->getFileName(); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Checking ' . $subDir); } $subDirIterator = new DirectoryIterator($this->_basePath . '/' . $subDir); $hashsToCheck = array(); // loop dirs + check if files in dir are in tree_filerevisions foreach ($subDirIterator as $file) { if ($file->isFile()) { $hash = $subDir . $file->getFileName(); $hashsToCheck[] = $hash; } } $existingHashes = $this->_fileObjectBackend->checkRevisions($hashsToCheck); $hashesToDelete = array_diff($hashsToCheck, $existingHashes); // remove from filesystem if not existing any more foreach ($hashesToDelete as $hashToDelete) { $filename = $this->_basePath . '/' . $subDir . '/' . substr($hashToDelete, 3); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Deleting ' . $filename); } unlink($filename); $deleteCount++; } } if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Deleted ' . $deleteCount . ' obsolete file(s).'); } return $deleteCount; }
/** * test cleanup of deleted files (database) * * @see 0008062: add cleanup script for deleted files */ public function testDeletedFileCleanupFromDatabase() { $fileNode = $this->testCreateFileNodeWithTempfile(); // get "real" filesystem path + unlink $fileObjectBackend = new Tinebase_Tree_FileObject(); $fileObject = $fileObjectBackend->get($fileNode['object_id']); unlink($fileObject->getFilesystemPath()); $result = Tinebase_FileSystem::getInstance()->clearDeletedFilesFromDatabase(); $this->assertEquals(1, $result, 'should cleanup one file'); $result = Tinebase_FileSystem::getInstance()->clearDeletedFilesFromDatabase(); $this->assertEquals(0, $result, 'should cleanup no file'); // node should no longer be found try { $this->_json->getNode($fileNode['id']); $this->fail('tree node still exists: ' . print_r($fileNode, TRUE)); } catch (Tinebase_Exception_NotFound $tenf) { $this->assertEquals('Tinebase_Model_Tree_Node record with id = ' . $fileNode['id'] . ' not found!', $tenf->getMessage()); } }