📄 folderutil.inc.php
字号:
<?php
/**
* $Id: folderutil.inc.php 9562 2008-10-10 14:46:21Z kevin_fourie $
*
* High-level folder operations
*
* KnowledgeTree Community Edition
* Document Management Made Simple
* Copyright (C) 2008 KnowledgeTree Inc.
* Portions copyright The Jam Warehouse Software (Pty) Limited
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 3 as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* 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
* logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
* must display the words "Powered by KnowledgeTree" and retain the original
* copyright notice.
* Contributor( s): ______________________________________
*/
require_once(KT_LIB_DIR . '/storage/storagemanager.inc.php');
require_once(KT_LIB_DIR . '/subscriptions/subscriptions.inc.php');
require_once(KT_LIB_DIR . '/permissions/permission.inc.php');
require_once(KT_LIB_DIR . '/permissions/permissionutil.inc.php');
require_once(KT_LIB_DIR . '/users/User.inc');
require_once(KT_LIB_DIR . '/foldermanagement/foldertransaction.inc.php');
require_once(KT_LIB_DIR . '/browse/browseutil.inc.php');
require_once(KT_LIB_DIR . '/database/dbutil.inc');
class KTFolderUtil {
function _add($oParentFolder, $sFolderName, $oUser) {
if (PEAR::isError($oParentFolder)) {
return $oParentFolder;
}
if (PEAR::isError($oUser)) {
return $oUser;
}
$oStorage =& KTStorageManagerUtil::getSingleton();
$oFolder =& Folder::createFromArray(array(
'name' => ($sFolderName),
'description' => ($sFolderName),
'parentid' => $oParentFolder->getID(),
'creatorid' => $oUser->getID(),
));
if (PEAR::isError($oFolder)) {
return $oFolder;
}
$res = $oStorage->createFolder($oFolder);
if (PEAR::isError($res)) {
$oFolder->delete();
return $res;
}
return $oFolder;
}
function add($oParentFolder, $sFolderName, $oUser) {
$folderid=$oParentFolder->getId();
// check for conflicts first
if (Folder::folderExistsName($sFolderName,$folderid)) {
return PEAR::raiseError(sprintf(_kt('The folder %s already exists.'), $sFolderName));
}
$oFolder = KTFolderUtil::_add($oParentFolder, $sFolderName, $oUser);
if (PEAR::isError($oFolder)) {
return $oFolder;
}
$oTransaction = KTFolderTransaction::createFromArray(array(
'folderid' => $oFolder->getId(),
'comment' => _kt('Folder created'),
'transactionNS' => 'ktcore.transactions.create',
'userid' => $oUser->getId(),
'ip' => Session::getClientIP(),
));
// fire subscription alerts for the new folder
$oSubscriptionEvent = new SubscriptionEvent();
$oSubscriptionEvent->AddFolder($oFolder, $oParentFolder);
return $oFolder;
}
function move($oFolder, $oNewParentFolder, $oUser, $sReason=null) {
if ($oFolder->getId() == 1)
{
return PEAR::raiseError(_kt('Cannot move root folder!'));
}
if ($oFolder->getParentID() == $oNewParentFolder->getId())
{
// moved! done.
return;
}
$sFolderParentIds = $oFolder->getParentFolderIDs();
$sNewFolderParentIds = $oNewParentFolder->getParentFolderIDs();
if (strpos($sNewFolderParentIds, "$sFolderParentIds,") === 0)
{
return PEAR::raiseError(_kt('Cannot move folder into a descendant folder!'));
}
if (KTFolderUtil::exists($oNewParentFolder, $oFolder->getName())) {
return PEAR::raiseError(_kt('Folder with the same name already exists in the new parent folder'));
}
$oStorage =& KTStorageManagerUtil::getSingleton();
$iOriginalPermissionObjectId = $oFolder->getPermissionObjectId();
$iOriginalParentFolderId = $oFolder->getParentID();
if (empty($iOriginalParentFolderId)) {
// If we have no parent, then we're the root. If we're the
// root - how do we move inside something?
return PEAR::raiseError(_kt('Folder has no parent'));
}
$oOriginalParentFolder = Folder::get($iOriginalParentFolderId);
if (PEAR::isError($oOriginalParentFolder)) {
// If we have no parent, then we're the root. If we're the
// root - how do we move inside something?
return PEAR::raiseError(_kt('Folder parent does not exist'));
}
$iOriginalParentPermissionObjectId = $oOriginalParentFolder->getPermissionObjectId();
$iTargetPermissionObjectId = $oFolder->getPermissionObjectId();
$bChangePermissionObject = false;
if ($iOriginalPermissionObjectId == $iOriginalParentPermissionObjectId) {
// If the folder inherited from its parent, we should change
// its permissionobject
$bChangePermissionObject = true;
}
// First, deal with SQL, as it, at least, is guaranteed to be atomic
$table = 'folders';
if ($oNewParentFolder->getId() == 1)
{
$sNewFullPath = $oFolder->getName();
$sNewParentFolderIds = "1";
}
else
{
$sNewFullPath = $oNewParentFolder->getFullPath() . '/' . $oFolder->getName();
$sNewParentFolderIds = $oNewParentFolder->getParentFolderIDs() . ',' . $oNewParentFolder->getID();
}
// Update the moved folder first...
$sQuery = "UPDATE $table SET full_path = ?, parent_folder_ids = ?, parent_id = ? WHERE id = ?";
$aParams = array(
$sNewFullPath,
$sNewParentFolderIds,
$oNewParentFolder->getID(),
$oFolder->getID(),
);
$res = DBUtil::runQuery(array($sQuery, $aParams));
if (PEAR::isError($res)) {
return $res;
}
$sOldFolderPath = $oFolder->getFullPath();
$sQuery = "UPDATE $table SET full_path = CONCAT(?, SUBSTRING(full_path FROM ?)), parent_folder_ids = CONCAT(?, SUBSTRING(parent_folder_ids FROM ?)) WHERE full_path LIKE ?";
$aParams = array(
$sNewFullPath,
strlen($oFolder->getFullPath()) + 1,
$sNewParentFolderIds,
strlen($oFolder->getParentFolderIDs()) + 1,
"$sOldFolderPath%"
);
$res = DBUtil::runQuery(array($sQuery, $aParams));
if (PEAR::isError($res)) {
return $res;
}
$table = 'documents';
$sQuery = "UPDATE $table SET full_path = CONCAT(?, SUBSTRING(full_path FROM ?)), parent_folder_ids = CONCAT(?, SUBSTRING(parent_folder_ids FROM ?)) WHERE full_path LIKE ?";
// use same $aParams as above
$res = DBUtil::runQuery(array($sQuery, $aParams));
if (PEAR::isError($res)) {
return $res;
}
// Regenerate the folder object - ensure the updated information is taken into account
$oFolder = Folder::get($oFolder->getID());
$res = $oStorage->moveFolder($oFolder, $oNewParentFolder);
if (PEAR::isError($res)) {
return $res;
}
$sComment = sprintf(_kt("Folder moved from %s to %s"), $sOldPath, $sNewParentFolderPath);
if($sReason !== null) {
$sComment .= sprintf(_kt(" (reason: %s)"), $sReason);
}
$oTransaction = KTFolderTransaction::createFromArray(array(
'folderid' => $oFolder->getId(),
'comment' => $sComment,
'transactionNS' => 'ktcore.transactions.move',
'userid' => $oUser->getId(),
'ip' => Session::getClientIP(),
));
Document::clearAllCaches();
Folder::clearAllCaches();
$GLOBALS["_OBJECTCACHE"] = array();
if ($bChangePermissionObject) {
$aOptions = array(
'evenifnotowner' => true, // Inherit from parent folder, even though not permission owner
);
KTPermissionUtil::inheritPermissionObject($oFolder, $aOptions);
}
return true;
}
function rename($oFolder, $sNewName, $oUser) {
$oStorage =& KTStorageManagerUtil::getSingleton();
$sOldName = $oFolder->getName();
// First, deal with SQL, as it, at least, is guaranteed to be atomic
$table = "folders";
if ($oFolder->getId() == 1) {
$sOldPath = $oFolder->getName();
$sNewPath = $sNewName;
} else {
$sOldPath = $oFolder->getFullPath();
$sNewPath = dirname($oFolder->getFullPath()) . '/' . $sNewName;
}
$sQuery = "UPDATE $table SET full_path = CONCAT(?, SUBSTRING(full_path FROM ?)) WHERE full_path LIKE ? OR full_path = ?";
$aParams = array(
"$sNewPath/",
strlen($sOldPath) + 2,
$sOldPath.'/%',
$sOldPath,
);
$res = DBUtil::runQuery(array($sQuery, $aParams));
if (PEAR::isError($res)) {
return $res;
}
$table = "documents";
$sQuery = "UPDATE $table SET full_path = CONCAT(?, SUBSTRING(full_path FROM ?)) WHERE full_path LIKE ? OR full_path = ?";
$res = DBUtil::runQuery(array($sQuery, $aParams));
if (PEAR::isError($res)) {
return $res;
}
$res = $oStorage->renameFolder($oFolder, $sNewName);
if (PEAR::isError($res)) {
return $res;
}
$oFolder->setName($sNewName);
$oFolder->setDescription($sNewName);
$res = $oFolder->update();
$oTransaction = KTFolderTransaction::createFromArray(array(
'folderid' => $oFolder->getId(),
'comment' => sprintf(_kt("Renamed from \"%s\" to \"%s\""), $sOldName, $sNewName),
'transactionNS' => 'ktcore.transactions.rename',
'userid' => $_SESSION['userID'],
'ip' => Session::getClientIP(),
));
if (PEAR::isError($oTransaction)) {
return $oTransaction;
}
Document::clearAllCaches();
Folder::clearAllCaches();
return $res;
}
function exists($oParentFolder, $sName) {
return Folder::folderExistsName($sName, $oParentFolder->getID());
}
/* folderUtil::delete
*
* this function is _much_ more complex than it might seem.
* we need to:
* - recursively identify children
* - validate that permissions are allocated correctly.
* - step-by-step delete.
*/
function delete($oStartFolder, $oUser, $sReason, $aOptions = null) {
require_once(KT_LIB_DIR . '/unitmanagement/Unit.inc');
$oPerm = KTPermission::getByName('ktcore.permissions.delete');
$bIgnorePermissions = KTUtil::arrayGet($aOptions, 'ignore_permissions');
$aFolderIds = array(); // of oFolder
$aDocuments = array(); // of oDocument
$aFailedDocuments = array(); // of String
$aFailedFolders = array(); // of String
$aRemainingFolders = array($oStartFolder->getId());
DBUtil::startTransaction();
while (!empty($aRemainingFolders)) {
$iFolderId = array_pop($aRemainingFolders);
$oFolder = Folder::get($iFolderId);
if (PEAR::isError($oFolder) || ($oFolder == false)) {
DBUtil::rollback();
return PEAR::raiseError(sprintf(_kt('Failure resolving child folder with id = %d.'), $iFolderId));
}
$oUnit = Unit::getByFolder($oFolder);
if (!empty($oUnit)) {
DBUtil::rollback();
return PEAR::raiseError(sprintf(_kt('Cannot remove unit folder: %s.'), $oFolder->getName()));
}
// don't just stop ... plough on.
if (!$bIgnorePermissions && !KTPermissionUtil::userHasPermissionOnItem($oUser, $oPerm, $oFolder)) {
$aFailedFolders[] = $oFolder->getName();
} else {
$aFolderIds[] = $iFolderId;
}
// child documents
$aChildDocs = Document::getList(array('folder_id = ?',array($iFolderId)));
foreach ($aChildDocs as $oDoc) {
if (!$bIgnorePermissions && $oDoc->getImmutable()) {
if (!KTBrowseUtil::inAdminMode($oUser, $oStartFolder)) {
$aFailedDocuments[] = $oDoc->getName();
continue;
}
}
if ($bIgnorePermissions || (KTPermissionUtil::userHasPermissionOnItem($oUser, $oPerm, $oDoc) && ($oDoc->getIsCheckedOut() == false)) ) {
$aDocuments[] = $oDoc;
} else {
$aFailedDocuments[] = $oDoc->getName();
}
}
// child folders.
$aCFIds = Folder::getList(array('parent_id = ?', array($iFolderId)), array('ids' => true));
$aRemainingFolders = kt_array_merge($aRemainingFolders, $aCFIds);
}
// FIXME we could subdivide this to provide a per-item display (viz. bulk upload, etc.)
if ((!empty($aFailedDocuments) || (!empty($aFailedFolders)))) {
$sFD = '';
$sFF = '';
if (!empty($aFailedDocuments)) {
$sFD = _kt('Documents: ') . implode(', ', $aFailedDocuments) . '. ';
}
if (!empty($aFailedFolders)) {
$sFF = _kt('Folders: ') . implode(', ', $aFailedFolders) . '.';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -