diff --git a/bin/storageverification.php b/bin/storageverification.php new file mode 100755 index 0000000..aca8573 --- /dev/null +++ b/bin/storageverification.php @@ -0,0 +1,113 @@ +aIgnore = array( + '.', '..', + 'CVS', + '.empty', + '.htaccess', + '.cvsignore', + '.svn', + ); + + $oConfig =& KTConfig::getSingleton(); + $this->fsPath = $oConfig->get('urls/documentRoot'); + + return parent::KTDispatcher(); + } + + function do_main() { + global $aFoldersToRemove; + global $aFilesToRemove; + global $aRepoDocumentProblems; + global $aRepoFolderProblems; + global $aRepoVersionProblems; + + + $this->checkDirectory(""); + + $aDocuments =& Document::getList(); + foreach ($aDocuments as $oDocument) { + $this->checkRepoDocument($oDocument); + } + + if (!($this->aFilesToRemove or $this->aRepoDocumentProblems)) { + return; + } + + $oTemplate =& + $this->oValidator->validateTemplate('ktcore/document/cleanup_script'); + $oTemplate->setData(array( + 'aFilesToRemove' => $this->aFilesToRemove, + 'aRepoDocumentProblems' => $this->aRepoDocumentProblems, + )); + print $oTemplate->render(); + exit(0); + } + + function checkDirectory($path) { + $fullpath = sprintf("%s/%s", $this->fsPath, $path); + + if (!is_dir($fullpath)) { + print "Not a directory: $fullpath\n"; + } + + $dh = @opendir($fullpath); + if ($dh === false) { + print "Could not open directory: $fullpath\n"; + } + while (($filename = readdir($dh)) !== false) { + if (in_array($filename, $this->aIgnore)) { continue; } + $subrelpath = sprintf("%s/%s", $path, $filename); + if (substr($subrelpath, 0, 1) == "/") { + $subrelpath = substr($subrelpath, 1); + } + $subfullpath = sprintf("%s/%s", $this->fsPath, $subrelpath); + if (is_dir($subfullpath)) { + $this->checkDirectory($subrelpath); + } + if (is_file($subfullpath)) { + $this->checkFile($subrelpath); + } + } + } + + function checkFile($path, $first = true) { + $oDocument = KTEntityUtil::getByDict('KTDocumentContentVersion', array( + 'storage_path' => $path, + )); + if (is_a($oDocument, 'ktentitynoobjects')) { + $this->aFilesToRemove[] = $path; + return; + } + } + + function checkRepoDocument($oDocument) { + global $aRepoDocumentProblems; + $aDCVs = KTDocumentContentVersion::getByDocument($oDocument); + foreach ($aDCVs as $oDCV) { + $sDocumentPath = $oDCV->getStoragePath(); + $sFullPath = sprintf("%s/%s", $this->fsPath, $sDocumentPath); + if (!is_file($sFullPath)) { + $this->aRepoDocumentProblems[] = array( + 'document' => $oDocument, + 'content' => $oDCV, + 'path' => $sDocumentPath, + 'doclink' => KTBrowseUtil::getUrlForDocument($oDocument), + ); + } + } + } +} +$oDispatcher = new VerifyDispatcher; +$oDispatcher->do_main(); + +?> diff --git a/templates/ktcore/document/cleanup_script.smarty b/templates/ktcore/document/cleanup_script.smarty new file mode 100644 index 0000000..a938969 --- /dev/null +++ b/templates/ktcore/document/cleanup_script.smarty @@ -0,0 +1,33 @@ +{i18n}Warning: Database is inconsistent with the contents of the repository.{/i18n} + + +{i18n}All paths are relative to your Documents directory.{/i18n} + + +{if $aRepoDocumentProblems} + + + +{i18n}These documents have versions that are not present on the filesystem. Consider restoring them from backups.{/i18n} + + +{foreach from=$aRepoDocumentProblems item=aInfo} +{assign var=oDocument value=$aInfo.document} +{assign var=oContent value=$aInfo.content} +{assign var=docname value=$oDocument->getName()} + {i18n arg_filepath="`$aInfo.path`" arg_docname="$docname" arg_doclink="`$aInfo.doclink`"}#docname# (#doclink# version {$oContent->getMajorVersionNumber()}.{$oContent->getMinorVersionNumber()}) — Cannot find file: #filepath#{/i18n} +{/foreach} + +{/if} + +{if $aFilesToRemove} + + + +{i18n}The following files are present in the repository, but do not exist in the database.{/i18n}: + +{foreach from=$aFilesToRemove item=sFile} + {$sFile|escape} +{/foreach} + +{/if}