diff --git a/bin/storageverification.php b/bin/storageverification.php
index 8469420..b0f071d 100644
--- a/bin/storageverification.php
+++ b/bin/storageverification.php
@@ -1,148 +1,190 @@
.
- *
- * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
+ *
+ * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
* California 94120-7775, or email info@knowledgetree.com.
- *
+ *
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
- *
+ *
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
- * KnowledgeTree" logo and retain the original copyright notice. If the display of the
+ * KnowledgeTree" logo and retain the original copyright notice. If the display of the
* logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
- * must display the words "Powered by KnowledgeTree" and retain the original
+ * must display the words "Powered by KnowledgeTree" and retain the original
* copyright notice.
* Contributor( s): ______________________________________
*/
require_once(dirname(__FILE__) . '/../config/dmsDefaults.php');
-require_once(KT_LIB_DIR . '/dispatcher.inc.php');
-$sectionName = 'Administration';
-require_once(KT_LIB_DIR . '/templating/kt3template.inc.php');
-
-require_once(KT_LIB_DIR . '/browse/browseutil.inc.php');
-
-class VerifyDispatcher extends KTDispatcher {
- function VerifyDispatcher() {
- $this->aIgnore = array(
- '.', '..',
- 'CVS',
- '.empty',
- '.htaccess',
- '.cvsignore',
- '.svn',
- );
-
- $oConfig =& KTConfig::getSingleton();
- $this->fsPath = $oConfig->get('urls/documentRoot');
-
- return parent::KTDispatcher();
+require_once(KT_LIB_DIR . '/storage/storagemanager.inc.php');
+
+// TODO: this does not verify files that are in the storage system, but not on the database. It is better that the storage system
+// be in sync with the database. However, we should have a better way to query the storage driver to give us a list of files.
+
+class StorageVerification
+{
+ private $count;
+ private $lineCount;
+ private $doc;
+ const DOCS_PER_DOT = 100;
+ const DOTS_PER_LINE = 80;
+ private $nl;
+ private $tab;
+
+ private
+ function error($msg)
+ {
+ $doc = $this->doc;
+ $documentId = $doc->getId();
+ $path = $doc->getFullPath();
+ $filename = $doc->getFileName();
+ $storagePath = $doc->getStoragePath();
+
+ print "{$this->nl}{$this->nl}";
+ print "Problem with Document ID: {$documentId}{$this->nl}";
+ print "{$this->tab}Path: {$path}{$this->nl}";
+ print "{$this->tab}Filename: {$filename}{$this->nl}";
+ print "{$this->tab}StoragePath: {$storagePath}{$this->nl}";
+ print "{$this->tab}Problem: {$msg}{$this->nl}{$this->nl}";
+ flush();
+ $this->count = 0;
+ $this->lineCount = 0;
+ $this->clearCache();
}
- function do_main() {
- global $aFoldersToRemove;
- global $aFilesToRemove;
- global $aRepoDocumentProblems;
- global $aRepoFolderProblems;
- global $aRepoVersionProblems;
+ private
+ function progress()
+ {
+ if ($this->count++ % StorageVerification::DOCS_PER_DOT == 0)
+ {
+ $this->lineCount++;
+ print '.';
+ flush();
+ }
+ if ($this->lineCount == StorageVerification::DOTS_PER_LINE )
+ {
+ print "{$this->nl}";
+ flush();
+ $this->lineCount = 0;
+ }
+ $this->clearCache();
+ }
- $this->checkDirectory('');
+ private
+ function clearCache()
+ {
+ $metadataid = $this->doc->getMetadataVersionId();
+ $contentid = $this->doc->getContentVersionId();
+ $iId = $this->doc->getId();
+ $cache = KTCache::getSingleton();
+ $cache->remove('KTDocumentMetadataVersion/id', $metadataid);
+ $cache->remove('KTDocumentContentVersion/id', $contentid);
+ $cache->remove('KTDocumentCore/id', $iId);
+ $cache->remove('Document/id', $iId);
+ unset($GLOBALS['_OBJECTCACHE']['KTDocumentMetadataVersion'][$metadataid]);
+ unset($GLOBALS['_OBJECTCACHE']['KTDocumentContentVersion'][$contentid]);
+ unset($GLOBALS['_OBJECTCACHE']['KTDocumentCore'][$iId]);
+
+ unset($this->doc);
+ }
- $aDocuments =& Document::getList();
- foreach ($aDocuments as $oDocument) {
- $this->checkRepoDocument($oDocument);
+ public
+ function run()
+ {
+ global $argc;
+
+ if (isset($argc))
+ {
+ $this->nl = "\n";
+ $this->tab = "\t";
+ print "Storage Verification{$this->nl}";
+ print "===================={$this->nl}";
}
+ else
+ {
+ $this->nl = '
';
+ $this->tab = ' ';
+ print "Storage Verification{$this->nl}";
- 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";
- }
+ $sql = "SELECT
+ dmv.id as metadata_version_id, dcv.document_id, dcv.md5hash, dcv.size
+ FROM
+ document_content_version dcv
+ INNER JOIN document_metadata_version dmv ON dcv.id=dmv.content_version_id";
+ $rows = DBUtil::getResultArray($sql);
+ $this->count = 0;
+ $this->lineCount = 0;
- $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);
+ $storage =& KTStorageManagerUtil::getSingleton();
+ foreach($rows as $row)
+ {
+ $doc = Document::get($row['document_id'], $row['metadata_version_id']);
+
+ if (PEAR::isError($doc))
+ {
+ $msg = $doc->getMessage();
+ $this->error($doc, "Error with document: {$msg}");
+ continue;
}
- if (is_file($subfullpath)) {
- $this->checkFile($subrelpath);
+ $this->doc = $doc;
+
+ $tmpPath = $storage->temporaryFile($doc);
+ if (!file_exists($tmpPath))
+ {
+ $this->error("Temporary file could not be resolved: {$tmpPath}");
+ continue;
}
- }
- }
- function checkFile($path, $first = true) {
- $oDocument = KTEntityUtil::getByDict('KTDocumentContentVersion', array(
- 'storage_path' => $path,
- ));
- if (is_a($oDocument, 'ktentitynoobjects')) {
- $this->aFilesToRemove[] = $path;
- return;
- }
- }
+ $expectedSize = $row['size'];
+ $currentSize = filesize($tmpPath);
+ if ($expectedSize != $currentSize)
+ {
+ $this->error("Filesize does not match. Expected: {$expectedSize} Current: {$currentSize}");
+ continue;
+ }
- 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),
- );
+ $expectedHash = $row['md5hash'];
+ $currentHash = md5_file($tmpPath);
+ if ($expectedHash != $currentHash)
+ {
+ $this->error("Hash does not match. Expected: {$expectedHash} Current: {$currentHash}");
+ continue;
}
+ $this->progress();
}
+
+ print "{$this->nl}Done.{$this->nl}{$this->nl}";
}
+
}
-$oDispatcher = new VerifyDispatcher;
-$oDispatcher->do_main();
+
+
+$verification = new StorageVerification();
+$verification->run();
?>