documentutil.inc.php

来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 1,474 行 · 第 1/4 页

PHP
1,474
字号
                $oDocument->delete();
                return $ret;
            }
        }

        // NEW SEARCH

        Indexer::index($oDocument);

        $oUploadChannel->sendMessage(new KTUploadGenericMessage(_kt('Creating transaction')));
        $aOptions = array('user' => $oUser);
        //create the document transaction record
        $oDocumentTransaction = new DocumentTransaction($oDocument, _kt('Document created'), 'ktcore.transactions.create', $aOptions);
        $res = $oDocumentTransaction->create();
        if (PEAR::isError($res)) {
            $oDocument->delete();
            return $res;
        }

        $oUploadChannel->sendMessage(new KTUploadGenericMessage(_kt('Sending subscriptions')));
        // fire subscription alerts for the checked in document
        $oSubscriptionEvent = new SubscriptionEvent();
        $oFolder = Folder::get($oDocument->getFolderID());
        $oSubscriptionEvent->AddDocument($oDocument, $oFolder);

        $oKTTriggerRegistry = KTTriggerRegistry::getSingleton();
        $aTriggers = $oKTTriggerRegistry->getTriggers('add', 'postValidate');

        foreach ($aTriggers as $aTrigger) {
            $sTrigger = $aTrigger[0];
            $oTrigger = new $sTrigger;
            $aInfo = array(
                'document' => $oDocument,
                'aOptions' => $aOrigOptions,
            );
            $oTrigger->setInfo($aInfo);
            $ret = $oTrigger->postValidate();

        }

        DBUtil::commit();

        $oUploadChannel->sendMessage(new KTUploadGenericMessage(_kt('Checking permissions...')));

        // Check if there are any dynamic conditions / permissions that need to be updated on the document
        // If there are dynamic conditions then update the permissions on the document
        // The dynamic condition test fails unless the document exists in the DB therefore update permissions after committing the transaction.
        include_once(KT_LIB_DIR.'/permissions/permissiondynamiccondition.inc.php');
        $iPermissionObjectId = $oFolder->getPermissionObjectID();
        $dynamicCondition = KTPermissionDynamicCondition::getByPermissionObjectId($iPermissionObjectId);

        if(!PEAR::isError($dynamicCondition) && !empty($dynamicCondition)){
            $res = KTPermissionUtil::updatePermissionLookup($oDocument);
        }

        $oUploadChannel->sendMessage(new KTUploadGenericMessage(_kt('All done...')));

        return $oDocument;
    }
    // }}}

    function incrementNameCollissionNumbering($sDocFilename, $skipExtension = false){

        $iDot = strpos($sDocFilename, '.');
        if ($skipExtension || $iDot === false)
        {
            if(preg_match("/\(([0-9]+)\)$/", $sDocFilename, $matches, PREG_OFFSET_CAPTURE)) {

                $iCount = $matches[1][0];
                $iPos = $matches[1][1];

                $iNewCount = $iCount + 1;
                $sDocFilename = substr($sDocFilename, 0, $iPos) . $iNewCount .  substr($sDocFilename, $iPos + strlen($iCount));
            }
            else {
                $sDocFilename = $sDocFilename . '(1)';
            }
        }
        else
        {
            if(preg_match("/\(([0-9]+)\)(\.[^\.]+)+$/", $sDocFilename, $matches, PREG_OFFSET_CAPTURE)) {

                $iCount = $matches[1][0];
                $iPos = $matches[1][1];

                $iNewCount = $iCount + 1;
                $sDocFilename = substr($sDocFilename, 0, $iPos) . $iNewCount .  substr($sDocFilename, $iPos + strlen($iCount));
            }
            else {
                $sDocFilename = substr($sDocFilename, 0, $iDot) . '(1)' . substr($sDocFilename, $iDot);
            }
        }
        return $sDocFilename;
    }


	function generateNewDocumentFilename($sDocFilename) {
	    return self::incrementNameCollissionNumbering($sDocFilename, false);
	}

	function generateNewDocumentName($sDocName){
	    return self::incrementNameCollissionNumbering($sDocName, true);

	}

    // {{{ fileExists
    function fileExists($oFolder, $sFilename) {
        return Document::fileExists($sFilename, $oFolder->getID());
    }
    // }}}

    // {{{ nameExists
    function nameExists($oFolder, $sName) {
        return Document::nameExists($sName, $oFolder->getID());
    }
    // }}}

    // {{{ storeContents
    /**
     * Stores contents (filelike) from source into the document storage
     */
    function storeContents(&$oDocument, $oContents = null, $aOptions = null) {
        if (is_null($aOptions)) {
            $aOptions = array();
        }
        if (PEAR::isError($oDocument)) {
            return PEAR::raiseError(sprintf(_kt("Couldn't store contents: %s"), $oDocument->getMessage()));
        }

        $bCanMove = KTUtil::arrayGet($aOptions, 'move');
        $oStorage =& KTStorageManagerUtil::getSingleton();

        $oKTConfig =& KTConfig::getSingleton();
        $sBasedir = $oKTConfig->get('urls/tmpDirectory');

        $sFilename = (isset($aOptions['temp_file'])) ? $aOptions['temp_file'] : '';

        if(empty($sFilename)){
            return PEAR::raiseError(sprintf(_kt("Couldn't store contents: %s"), _kt('The uploaded file does not exist.')));
        }

        $md5hash = md5_file($sFilename);
        $content = $oDocument->_oDocumentContentVersion;
        $content->setStorageHash($md5hash);
        $content->update();

        if (empty($aOptions)) $aOptions = array();
        $aOptions['md5hash'] = $md5hash;

        // detection of mime types needs to be refactored. this stuff is damn messy!
        $sType = KTMime::getMimeTypeFromFile($sFilename);
        $iMimeTypeId = KTMime::getMimeTypeID($sType, $oDocument->getFileName(), $sFilename);
        $oDocument->setMimeTypeId($iMimeTypeId);

        $res = $oStorage->upload($oDocument, $sFilename, $aOptions);
        if ($res === false) {
            return PEAR::raiseError(sprintf(_kt("Couldn't store contents: %s"), _kt('No reason given')));
        }
        if (PEAR::isError($res)) {
            return PEAR::raiseError(sprintf(_kt("Couldn't store contents: %s"), $res->getMessage()));
        }
        KTDocumentUtil::setComplete($oDocument, 'contents');

        if ($aOptions['cleanup_initial_file'] && file_exists($sFilename)) {
            @unlink($sFilename);
        }

        return true;
    }
    // }}}

    // {{{ delete
    function delete($oDocument, $sReason, $iDestFolderId = null) {
    	// use the deleteSymbolicLink function is this is a symlink
        if ($oDocument->isSymbolicLink())
        {
            return KTDocumentUtil::deleteSymbolicLink($oDocument);
        }

        $oDocument =& KTUtil::getObject('Document', $oDocument);
        if (is_null($iDestFolderId)) {
            $iDestFolderId = $oDocument->getFolderID();
        }
        $oStorageManager =& KTStorageManagerUtil::getSingleton();

        global $default;

        if (count(trim($sReason)) == 0) {
            return PEAR::raiseError(_kt('Deletion requires a reason'));
        }

        if (PEAR::isError($oDocument) || ($oDocument == false)) {
            return PEAR::raiseError(_kt('Invalid document object.'));
        }

        if ($oDocument->getIsCheckedOut() == true) {
            return PEAR::raiseError(sprintf(_kt('The document is checked out and cannot be deleted: %s'), $oDocument->getName()));
        }

        if(!KTWorkflowUtil::actionEnabledForDocument($oDocument, 'ktcore.actions.document.delete')){
            return PEAR::raiseError(_kt('Document cannot be deleted as it is restricted by the workflow.'));
        }

        // IF we're deleted ...
        if ($oDocument->getStatusID() == DELETED) {
            return true;
        }

        $oOrigFolder = Folder::get($oDocument->getFolderId());

        DBUtil::startTransaction();

        // flip the status id
        $oDocument->setStatusID(DELETED);

        // $iDestFolderId is DEPRECATED.
        $oDocument->setFolderID(null);
        $oDocument->setRestoreFolderId($oOrigFolder->getId());
        $oDocument->setRestoreFolderPath(Folder::generateFolderIDs($oOrigFolder->getId()));

        $res = $oDocument->update();

        if (PEAR::isError($res) || ($res == false)) {
            DBUtil::rollback();
            return PEAR::raiseError(_kt('There was a problem deleting the document from the database.'));
        }

        // now move the document to the delete folder
        $res = $oStorageManager->delete($oDocument);
        if (PEAR::isError($res) || ($res == false)) {
            //could not delete the document from the file system
            $default->log->error('Deletion: Filesystem error deleting document ' .
                $oDocument->getFileName() . ' from folder ' .
                Folder::getFolderPath($oDocument->getFolderID()) .
                ' id=' . $oDocument->getFolderID());

            // we use a _real_ transaction here ...

            DBUtil::rollback();

            /*
            //reverse the document deletion
            $oDocument->setStatusID(LIVE);
            $oDocument->update();
            */

            return PEAR::raiseError(_kt('There was a problem deleting the document from storage.'));
        }

        //delete all shortcuts linking to this document
        $aSymlinks = $oDocument->getSymbolicLinks();
        foreach($aSymlinks as $aSymlink){
        	$oShortcutDocument = Document::get($aSymlink['id']);
        	$oOwnerUser = User::get($oShortcutDocument->getOwnerID());

        	KTDocumentUtil::deleteSymbolicLink($aSymlink['id']);

        	//send an email to the owner of the shortcut
        	if($oOwnerUser->getEmail()!=null && $oOwnerUser->getEmailNotification() == true){
        		$emailTemplate = new EmailTemplate("kt3/notifications/notification.SymbolicLinkDeleted",array('user_name'=>$this->oUser->getName(),
        			'url'=>KTUtil::ktLink(KTBrowseUtil::getUrlForDocument($oShortcutDocument)),
        			'title' =>$oShortcutDocument->getName()));
        		$email = new EmailAlert($oOwnerUser->getEmail(),_kt("KnowledgeTree Notification"),$emailTemplate->getBody());
        		$email->send();
        	}
        }

        $oDocumentTransaction = new DocumentTransaction($oDocument, _kt('Document deleted: ') . $sReason, 'ktcore.transactions.delete');
        $oDocumentTransaction->create();

        $oDocument->setFolderID(1);

        DBUtil::commit();


	// we weren't doing notifications on this one
        $oSubscriptionEvent = new SubscriptionEvent();
        $oSubscriptionEvent->RemoveDocument($oDocument, $oOrigFolder);


        // document is now deleted:  triggers are best-effort.

        $oKTTriggerRegistry = KTTriggerRegistry::getSingleton();
        $aTriggers = $oKTTriggerRegistry->getTriggers('delete', 'postValidate');
        foreach ($aTriggers as $aTrigger) {
            $sTrigger = $aTrigger[0];
            $oTrigger = new $sTrigger;
            $aInfo = array(
                'document' => $oDocument,
            );
            $oTrigger->setInfo($aInfo);
            $ret = $oTrigger->postValidate();
            if (PEAR::isError($ret)) {
                $oDocument->delete();          // FIXME nbm: review that on-fail => delete is correct ?!
                return $ret;
            }
        }


    }
    // }}}

    function reindexDocument($oDocument) {

        Indexer::index($oDocument);
    }


    function canBeMoved($oDocument) {
        if ($oDocument->getIsCheckedOut()) {
            return false;
        }
        if (!KTWorkflowUtil::actionEnabledForDocument($oDocument, 'ktcore.actions.document.move')) {
            return false;
        }
        return true;
    }


    function copy($oDocument, $oDestinationFolder, $sReason = null, $sDestinationDocName = null) {
        // 1. generate a new triad of content, metadata and core objects.
        // 2. update the storage path.
		//print '--------------------------------- BEFORE';
        //print_r($oDocument);

        // TODO: this is not optimal. we have get() functions that will do SELECT when we already have the data in arrays

        // get the core record to be copied
        $sDocumentTable = KTUtil::getTableName('documents');
        $sQuery = 'SELECT * FROM ' . $sDocumentTable . ' WHERE id = ?';
        $aParams = array($oDocument->getId());
        $aCoreRow = DBUtil::getOneResult(array($sQuery, $aParams));
        // we unset the id as a new one will be created on insert
        unset($aCoreRow['id']);

        // get a copy of the latest metadata version for the copied document
        $iOldMetadataId = $aCoreRow['metadata_version_id'];
        $sMetadataTable = KTUtil::getTableName('document_metadata_version');
        $sQuery = 'SELECT * FROM ' . $sMetadataTable . ' WHERE id = ?';
        $aParams = array($iOldMetadataId);
        $aMDRow = DBUtil::getOneResult(array($sQuery, $aParams));
        // we unset the id as a new one will be created on insert
        unset($aMDRow['id']);

        // set the name for the document, possibly using name collission
        if (empty($sDestinationDocName)){
            $aMDRow['name'] = KTDocumentUtil::getUniqueDocumentName($oDestinationFolder, $aMDRow['name']);
        }
        else {
            $aMDRow['name'] = $sDestinationDocName;
        }

        // get a copy of the latest content version for the copied document
        $iOldContentId = $aMDRow['content_version_id'];
        $sContentTable = KTUtil::getTableName('document_content_version');
        $sQuery = 'SELECT * FROM ' . $sContentTable . ' WHERE id = ?';
        $aParams = array($iOldContentId);
        $aContentRow = DBUtil::getOneResult(array($sQuery, $aParams));
        // we unset the id as a new one will be created on insert
        unset($aContentRow['id']);

        // set the filename for the document, possibly using name collission
        if(empty($sDestinationDocName)) {
            $aContentRow['filename'] = KTDocumentUtil::getUniqueFilename($oDestinationFolder, $aContentRow['filename']);
        }
        else {
            $aContentRow['filename'] = $sDestinationDocName;
        }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?