diff --git a/ktwebdav/lib/KTWebDAVServer.inc.php b/ktwebdav/lib/KTWebDAVServer.inc.php index d69513f..3f234db 100644 --- a/ktwebdav/lib/KTWebDAVServer.inc.php +++ b/ktwebdav/lib/KTWebDAVServer.inc.php @@ -1132,9 +1132,10 @@ class KTWebDAVServer extends HTTP_WebDAV_Server /** * GET method helper + * Method takes a directory path and checks whether it refers to a document or folder. The relevant folder and/or document id is returned. * - * @param string directory path - * @return array or false + * @param $path string The directory path + * @return array or bool Either returns an array of folder/document id's or false if an error occurred */ function _folderOrDocument($path) { @@ -1142,14 +1143,14 @@ class KTWebDAVServer extends HTTP_WebDAV_Server $this->ktwebdavLog("Entering _folderOrDocument. path is " . $path, 'info', true); - if ( !(strstr($path,"__BAOBABCLIENT__") === false) ) { - return array(0, 1); - } - + /* ** Get the directory path and the folder/document being acted on ** */ $sFileName = basename($path); // for windows replace backslash with forwardslash $sFolderPath = str_replace("\\", '/', dirname($path) ); + /* ** Get the starting point for recursing through the directory structure + FolderId = 0 if we're in the root folder + FolderId = 1 the starting point for locating any other folder ** */ if ($sFolderPath == "/" || $sFolderPath == "/ktwebdav") { $this->ktwebdavLog("This is the root folder.", 'info', true); $sFolderPath = $this->rootFolder; @@ -1164,6 +1165,9 @@ class KTWebDAVServer extends HTTP_WebDAV_Server $this->ktwebdavLog("sFolderName is " . $sFolderPath, 'info', true); $this->ktwebdavLog("iFolderID is " . $iFolderID, 'info', true); + /* ** Break up the directory path into its component directory's, + recurse through the directory's to find the correct id of the current directory. + Avoids situations where several directory's have the same name. ** */ $aFolderNames = split('/', $sFolderPath); $this->ktwebdavLog("aFolderNames are: " . print_r($aFolderNames, true), 'info', true); @@ -1196,6 +1200,9 @@ class KTWebDAVServer extends HTTP_WebDAV_Server $this->ktwebdavLog("iFolderID set to " . $iFolderID, 'info', true); } + /* ** Get the document id using the basename and parent folder id as parameters. + If an id is obtained then the path refers to a document. + If no id is returned then the path refers to a folder or a non-existing document. ** */ // FIXME: Direct database access // $sQuery = "SELECT id FROM documents WHERE folder_id = ? AND filename = ? AND status_id = 1"; $sQuery = "SELECT D.id "; @@ -1214,12 +1221,18 @@ class KTWebDAVServer extends HTTP_WebDAV_Server return false; } + /* ** If the path refers to a folder or a non-existing document, + Get the folder id using the basename and parent folder id as parameters. + If an id is obtained then the path refers to an existing folder. + If no id is returned and the basename is empty then path refers to the root folder. + If no id is returned and the basename is not empty, then the path refers to either a non-existing folder or document. ** */ if ($iDocumentID === null) { $this->ktwebdavLog("iDocumentID is null", 'info', true); // FIXME: Direct database access $sQuery = "SELECT id FROM folders WHERE parent_id = ? AND name = ?"; $aParams = array($iFolderID, $sFileName); $id = DBUtil::getOneResultKey(array($sQuery, $aParams), 'id'); + if (PEAR::isError($id)) { $this->ktwebdavLog("A DB(2) error occurred in _folderOrDocument", 'info', true); return false; @@ -1235,6 +1248,7 @@ class KTWebDAVServer extends HTTP_WebDAV_Server $this->ktwebdavLog("Setting Location Header to " . "Location: " . $_SERVER["PHP_SELF"] . "/", 'info', true); header("Location: " . $_SERVER["PHP_SELF"] . "/"); } + $this->ktwebdavLog("DEBUG: return id ".$id, 'info', true); return array($id, null); } @@ -1647,24 +1661,16 @@ class KTWebDAVServer extends HTTP_WebDAV_Server /** * MOVE method handler + * Method checks if the source path refers to a document / folder then calls the appropriate method handler. * - * @param array parameter passing array + * @param $options array parameter passing array * @return string HTTP status code or false */ function MOVE($options) { - // Use the WebDAV standards way. - // See rfc2518 Section 8.9 - // This does a copy with delete - // FIXME: This way does not retain document history and other info - - //return $this->COPY($options, true); - - // Use the KT way. - // FIXME: This way does not allow overwrite - $this->ktwebdavLog("Entering MOVE. options are " . print_r($options, true), 'info', true); + /* ** Check that write is allowed ** */ if ($this->checkSafeMode()) { if (!empty($_SERVER["CONTENT_LENGTH"])) { // no body parsing yet @@ -1679,6 +1685,9 @@ class KTWebDAVServer extends HTTP_WebDAV_Server } */ + /* ** Get the path to the document/folder to be copied. + Call function to check if the path refers to a document or a folder. + Return 404 error if the path is invalid. ** */ $source_path = $options["path"]; // Fix for Mac Goliath @@ -1710,22 +1719,30 @@ class KTWebDAVServer extends HTTP_WebDAV_Server return "404 Not found - Document was not found."; } + /* ** Get the returned parent folder id and document/folder id. + If the parent folder id is false, return 404 error. + If the document id is either false or null, then the source is a folder. + If the document id exists then the source is a document. + If the source is a folder then call _MOVEFolder. + If the source is a document then check if its checked out and call _MOVEDocument. ** */ list($iFolderID, $iDocumentID) = $source_res; - if ($iDocumentID === false) { + if ($iFolderID === false && ($iDocumentID === false || is_null($iDocumentID))) { $this->ktwebdavLog("404 Not found - Folder was not found.", 'info', true); return "404 Not found - Folder was not found."; } - if (is_null($iDocumentID)) { + if (is_null($iDocumentID) || $iDocumentID === false) { // Source is a folder + $this->ktwebdavLog("Source is a Folder.", 'info', true); $movestat = $this->_MOVEFolder($options, $iFolderID); } else { // Source is a document + $this->ktwebdavLog("Source is a Document.", 'info', true); if ($this->canCopyMoveRenameDocument($iDocumentID)) { $movestat = $this->_MOVEDocument($options, $iFolderID, $iDocumentID); } else { - return "Cannot MOVE document because it is checked out by another user."; + return "423 Locked - Cannot MOVE document because it is checked out by another user."; } } @@ -1746,7 +1763,9 @@ class KTWebDAVServer extends HTTP_WebDAV_Server */ function _MOVEDocument($options, $iFolderID, $iDocumentID) { + /* ** Ensure that the destination path exists ** */ if ($options['dest'] == '') $options["dest"] = substr($options["dest_url"], strlen($_SERVER["SCRIPT_NAME"])); + $this->ktwebdavLog("Entering _MOVEDocument. options are " . print_r($options, true), 'info', true); // Fix for Mac Goliath // Modified - 25/10/07 - remove ktwebdav from document path @@ -1760,11 +1779,11 @@ class KTWebDAVServer extends HTTP_WebDAV_Server } } - $this->ktwebdavLog("Entering _MOVEDocument. options are " . print_r($options, true), 'info', true); global $default; $new = true; - //FIXME: refactor me into KTDocumentUtil + /* ** Get the relevant paths. Get the basename of the destination path as the destination filename. + Check whether the destination path refers to a folder / document. ** */ $oDocument = Document::get($iDocumentID); $oSrcFolder = Folder::get($iFolderID); $oUser =& User::get($this->userID); @@ -1772,36 +1791,16 @@ class KTWebDAVServer extends HTTP_WebDAV_Server $source_path = $options["path"]; $dest_path = urldecode($options["dest"]); - // Is this a rename? - if (dirname($source_path) == dirname($dest_path)) { - // This is a rename - //if ($options['overwrite'] != 'T') { - // $this->ktwebdavLog("This is a Rename. Overwrite needs to be TRUE.", 'info', true); - // return "412 Precondition Failed - This is a Rename. Overwrite needs to be TRUE."; - //} - $this->ktwebdavLog("Got an oDocument of " . print_r($oDocument, true), 'info', true); - $this->ktwebdavLog("Got a new name of " . basename($dest_path), 'info', true); - - // Check if the user has permissions to write this document - $oPerm =& KTPermission::getByName('ktcore.permissions.write'); - $oUser =& User::get($this->userID); - if (!KTPermissionUtil::userHasPermissionOnItem($oUser, $oPerm, $oDocument)) { - return "403 Forbidden - User does not have sufficient permissions"; - } - $res = KTDocumentUtil::rename($oDocument, basename($dest_path), $oUser); - if (PEAR::isError($res) || is_null($res) || ($res === false)) { - return "404 Not Found - " . $res->getMessage(); - } else { - $this->ktwebdavLog("201 Created", 'info', true); - return "201 Created"; - } - - } - + /* ** Get the source folder object. + If the destination document is null, then the destination is a folder, continue. + If the destination document returns an id, then the document exists. Check overwrite. + If overwrite is true, then check permissions and delete the document, continue. + If the destination document is false, then continue. ** */ list($iDestFolder, $iDestDoc) = $this->_folderOrDocument($dest_path); if (is_null($iDestDoc)) { // the dest is a folder + $this->ktwebdavLog("Destination is a folder.", 'info', true); } else if ($iDestDoc !== false) { // Document exists $this->ktwebdavLog("Destination Document exists.", 'info', true); @@ -1822,6 +1821,39 @@ class KTWebDAVServer extends HTTP_WebDAV_Server $new = false; } + /* ** Check if the source and destination directories are the same and the destination is not a folder. + Then action is probably a rename. + Check if user has permission to write to the document and folder. + Rename the document. ** */ + if ((dirname($source_path) == dirname($dest_path)) && !is_null($iDestDoc)) { + // This is a rename + $this->ktwebdavLog("This is a rename.", 'info', true); + $this->ktwebdavLog("Got an oDocument of " . print_r($oDocument, true), 'info', true); + $this->ktwebdavLog("Got a new name of " . basename($dest_path), 'info', true); + + // Check if the user has permissions to write this document + $oPerm =& KTPermission::getByName('ktcore.permissions.write'); + $oUser =& User::get($this->userID); + if (!KTPermissionUtil::userHasPermissionOnItem($oUser, $oPerm, $oDocument)) { + return "403 Forbidden - User does not have sufficient permissions"; + } + + // Perform rename + $res = KTDocumentUtil::rename($oDocument, basename($dest_path), $oUser); + if (PEAR::isError($res) || is_null($res) || ($res === false)) { + return "404 Not Found - " . $res->getMessage(); + } else if($new) { + $this->ktwebdavLog("201 Created", 'info', true); + return "201 Created"; + }else { + $this->ktwebdavLog("204 No Content", 'info', true); + return "204 No Content"; + } + } + + /* ** Get the destination folder object and the source document object. + Check if user has permission to write to the document and folder. + Move the document. ** */ $oDestFolder = Folder::get($iDestFolder); $this->ktwebdavLog("Got a destination folder of " . print_r($oDestFolder, true), 'info', true); @@ -1832,57 +1864,20 @@ class KTWebDAVServer extends HTTP_WebDAV_Server return "403 Forbidden - User does not have sufficient permissions"; } - $oOriginalFolder = $oSrcFolder; - $iOriginalFolderPermissionObjectId = $oOriginalFolder->getPermissionObjectId(); - $iDocumentPermissionObjectId = $oDocument->getPermissionObjectId(); + $reason = (isset($_SERVER['HTTP_REASON']) && !empty($_SERVER['HTTP_REASON'])) ? $_SERVER['HTTP_REASON'] : "KTWebDAV Move."; - if ($iDocumentPermissionObjectId === $iOriginalFolderPermissionObjectId) { - $oDocument->setPermissionObjectId($oDestFolder->getPermissionObjectId()); - } + $res = KTDocumentUtil::move($oDocument, $oDestFolder, $oUser, $reason); - //put the document in the new folder - $oDocument->setFolderID($oDestFolder->getId()); - if (!$oDocument->update(true)) { - return "502 Bad Gateway - Document update failed."; - } - - //move the document on the file system - $oStorage =& KTStorageManagerUtil::getSingleton(); - if (!$oStorage->moveDocument($oDocument, $oSrcFolder, $oDestFolder)) { - $oDocument->setFolderID($oSrcDocumentFolder->getId()); - $oDocument->update(true); - return "502 Bad Gateway"; - } - - $sMoveMessage = sprintf("Moved from %s/%s to %s/%s: %s", - $oSrcFolder->getFullPath(), - $oSrcFolder->getName(), - $oDestFolder->getFullPath(), - $oDestFolder->getName(), - $_SERVER['HTTP_REASON']); - - // create the document transaction record - $oDocumentTransaction = & new DocumentTransaction($oDocument, $sMoveMessage, 'ktcore.transactions.move'); - $oDocumentTransaction->create(); - - $oKTTriggerRegistry = KTTriggerRegistry::getSingleton(); - $aTriggers = $oKTTriggerRegistry->getTriggers('moveDocument', 'postValidate'); - foreach ($aTriggers as $aTrigger) { - $sTrigger = $aTrigger[0]; - $oTrigger = new $sTrigger; - $aInfo = array( - "document" => $oDocument, - "old_folder" => $oSrcFolder, - "new_folder" => $oDestFolder, - ); - $oTrigger->setInfo($aInfo); - $ret = $oTrigger->postValidate(); - // FIXME: handle trigger subfailures. + if(PEAR::isError($res)){ + $this->ktwebdavLog("Move on document failed: ".$res->getMessage(), 'info', true); + return "500 Internal Server Error - Move on document failed."; } if ($new) { + $this->ktwebdavLog("201 Created", 'info', true); return "201 Created"; } else { + $this->ktwebdavLog("204 No Content", 'info', true); return "204 No Content"; } } @@ -1897,11 +1892,13 @@ class KTWebDAVServer extends HTTP_WebDAV_Server */ function _MOVEFolder($options, $iFolderID) { + /* ** Ensure that the destination path exists ** */ if ($options['dest'] == '') $options["dest"] = substr($options["dest_url"], strlen($_SERVER["SCRIPT_NAME"])); $this->ktwebdavLog("Entering _MOVEFolder. options are " . print_r($options, true), 'info', true); + /* ** RFC 2518 Section 8.9.2. A folder move must have a depth of 'infinity'. + Check the requested depth. If depth is set to '0' or '1' return a 400 error. ** */ if ($options["depth"] != "infinity") { - // RFC 2518 Section 9.2, last paragraph $this->ktwebdavLog("400 Bad request", 'info', true); return "400 Bad request - depth must be 'inifinity'."; } @@ -1920,23 +1917,75 @@ class KTWebDAVServer extends HTTP_WebDAV_Server global $default; + /* ** Get the relevant paths. + Check whether the destination path refers to a folder / document. ** */ $source_path = $options["path"]; $dest_path = urldecode($options["dest"]); + list($iDestFolder, $iDestDoc) = $this->_folderOrDocument($dest_path); + /* ** Get the source folder objects. + If the destination document is null, then the destination is an existing folder. Check overwrite. + If overwrite is true, then check permissions and delete the folder, continue. + If the destination document returns an id, then the destination is a document, check overwrite. + If overwrite is true, then check permissions and delete the document, continue. + If the destination document is false, then continue. ** */ $oSrcFolder = Folder::get($iFolderID); + $oDestFolder = Folder::get($iDestFolder); - list($iDestFolder, $iDestDoc) = $this->_folderOrDocument($dest_path); + $new = true; + if (is_null($iDestDoc)) { + // Folder exists + $this->ktwebdavLog("Destination Folder exists.", 'info', true); + $oReplaceFolder = $oDestFolder; + if ($options['overwrite'] != 'T') { + $this->ktwebdavLog("Overwrite needs to be TRUE.", 'info', true); + return "412 Precondition Failed - Destination Folder exists. Overwrite needs to be TRUE."; + } + $this->ktwebdavLog("Overwrite is TRUE, deleting Destination Folder.", 'info', true); - $oDestFolder = Folder::get($iDestFolder); + // Check if the user has permissions to delete this folder + $oPerm =& KTPermission::getByName('ktcore.permissions.delete'); + $oUser =& User::get($this->userID); - // Is this a rename? - if (dirname($source_path) == dirname($dest_path)) { - // This is a rename - //if ($options['overwrite'] != 'T') { - // $this->ktwebdavLog("This is a Rename. Overwrite needs to be TRUE.", 'info', true); - // return "412 Precondition Failed - This is a Rename. Overwrite needs to be TRUE."; - //} + if (!KTPermissionUtil::userHasPermissionOnItem($oUser, $oPerm, $oReplaceFolder)) { + return "403 Forbidden - User does not have sufficient permissions"; + } + + KTFolderUtil::delete($oReplaceFolder, $oUser, 'KTWebDAV move overwrites target.'); + + // Destination folder has been replaced so we need to get the parent folder object + list($iDestFolder, $iDestDoc) = $this->_folderOrDocument($dest_path); + $oDestFolder = Folder::get($iDestFolder); + + $new = false; + } else if ($iDestDoc !== false) { + // Destination is a document + $this->ktwebdavLog("Destination is a document.", 'info', true); + $oReplaceDoc = Document::get($iDestDoc); + if ($options['overwrite'] != 'T') { + $this->ktwebdavLog("Overwrite needs to be TRUE.", 'info', true); + return "412 Precondition Failed - Destination Folder is a document. Overwrite needs to be TRUE."; + } + $this->ktwebdavLog("Overwrite is TRUE, deleting Destination Document.", 'info', true); + + // Check if the user has permissions to delete this document + $oPerm =& KTPermission::getByName('ktcore.permissions.delete'); + $oUser =& User::get($this->userID); + + if (!KTPermissionUtil::userHasPermissionOnItem($oUser, $oPerm, $oReplaceDoc)) { + return "403 Forbidden - User does not have sufficient permissions"; + } + KTDocumentUtil::delete($oReplaceDoc, 'KTWebDAV move overwrites target.'); + $new = false; + } + /* ** Check if the source and destination directories are the same and the destination is not an existing folder. + Then action is probably a rename. + Check if user has permission to write to the folder. + Rename the document. ** */ + if (dirname($source_path) == dirname($dest_path) && !is_null($iDestDoc)) { + // This is a rename + $this->ktwebdavLog("Rename collection.", 'info', true); $this->ktwebdavLog("Got an oSrcFolder of " . print_r($oSrcFolder, true), 'info', true); $this->ktwebdavLog("Got an new name of " . basename($dest_path), 'info', true); @@ -1952,36 +2001,22 @@ class KTWebDAVServer extends HTTP_WebDAV_Server if (PEAR::isError($res) || is_null($res) || ($res === false)) { return "404 Not Found - " . $res->getMessage(); } else { - $this->ktwebdavLog("201 Created", 'info', true); - return "201 Created"; - } - - } - - if (is_null($iDestDoc)) { - // the dest is a folder - } else if ($iDestDoc !== false) { - // Folder exists - $this->ktwebdavLog("Destination Folder exists.", 'info', true); - $oReplaceFolder = Folder::get($iDestDoc); - if ($options['overwrite'] != 'T') { - $this->ktwebdavLog("Overwrite needs to be TRUE.", 'info', true); - return "412 Precondition Failed - Destination Folder exists. Overwrite needs to be TRUE."; + if($new){ + $this->ktwebdavLog("201 Created", 'info', true); + return "201 Created"; + }else{ + $this->ktwebdavLog("204 No Content", 'info', true); + return "204 No Content"; + } } - $this->ktwebdavLog("Overwrite is TRUE, deleting Destination Folder.", 'info', true); - // Check if the user has permissions to delete this folder - $oPerm =& KTPermission::getByName('ktcore.permissions.delete'); - $oUser =& User::get($this->userID); - if (!KTPermissionUtil::userHasPermissionOnItem($oUser, $oPerm, $oReplaceFolder)) { - return "403 Forbidden - User does not have sufficient permissions"; - } - KTFolderUtil::delete($oReplaceFolder, 'KTWebDAV move overwrites target.'); - $new = false; } include_once(KT_LIB_DIR . '/foldermanagement/folderutil.inc.php'); + /* ** Get the destination folder object and the source document object. + Check if user has permission to write to the folder. + Move the folder. ** */ $oUser =& User::get($this->userID); $this->ktwebdavLog("Got an oSrcFolder of " . print_r($oSrcFolder, true), 'info', true); $this->ktwebdavLog("Got an oDestFolder of " . print_r($oDestFolder, true), 'info', true); @@ -1993,18 +2028,29 @@ class KTWebDAVServer extends HTTP_WebDAV_Server if (!KTPermissionUtil::userHasPermissionOnItem($oUser, $oPerm, $oDestFolder)) { return "403 Forbidden - User does not have sufficient permissions"; } - KTFolderUtil::move($oSrcFolder, $oDestFolder, $oUser); - $this->ktwebdavLog("201 Created", 'info', true); - return "201 Created"; + $res = KTFolderUtil::move($oSrcFolder, $oDestFolder, $oUser); + + if(PEAR::isError($res)){ + $this->ktwebdavLog("Move on folder failed: ".$res->getMessage(), 'info', true); + return "500 Internal Server Error - Move on folder failed."; + } + if($new){ + $this->ktwebdavLog("201 Created", 'info', true); + return "201 Created"; + }else{ + $this->ktwebdavLog("204 No Content", 'info', true); + return "204 No Content"; + } } /** * COPY method handler + * Method checks if the source path refers to a document / folder then calls the appropriate method handler. * - * @param array parameter passing array - * @param string delete source flag + * @param $options array parameter passing array + * @param $del string delete source flag * @return string HTTP status code or false */ function COPY($options, $del = false) @@ -2012,6 +2058,7 @@ class KTWebDAVServer extends HTTP_WebDAV_Server $this->ktwebdavLog("Entering COPY. options are " . print_r($options, true), 'info', true); $this->ktwebdavLog("del is: " . $del, 'info', true); + /* ** Check that writing to the server is allowed * **/ if ($this->checkSafeMode()) { if (!empty($_SERVER["CONTENT_LENGTH"])) { // no body parsing yet @@ -2025,6 +2072,10 @@ class KTWebDAVServer extends HTTP_WebDAV_Server return "502 bad gateway - No copying to different WebDAV Servers yet"; } */ + + /* ** Get the path to the document/folder to be copied. + Call function to check if the path refers to a document or a folder. + Return 404 error if the path is invalid. ** */ $source_path = $options["path"]; $this->ktwebdavLog("SourcePath is: " . $source_path, 'info', true); $source_res = $this->_folderOrDocument($source_path); @@ -2033,13 +2084,19 @@ class KTWebDAVServer extends HTTP_WebDAV_Server return "404 Not found - The document could not be found."; } + /* ** Get the returned parent folder id and document/folder id. + If the parent folder id is false, return 404 error. + If the document id is either false or null, then the source is a folder. + If the document id exists then the source is a document. + If the source is a folder then call _COPYFolder. + If the source is a document then check if its checked out and call _COPYDocument. ** */ list($iFolderID, $iDocumentID) = $source_res; - if ($iDocumentID === false) { + if ($iFolderID === false && ($iDocumentID === false || is_null($iDocumentID))) { $this->ktwebdavLog("404 Not found - The folder could not be found.", 'info', true); return "404 Not found - The folder could not be found."; } - if (is_null($iDocumentID)) { + if (is_null($iDocumentID) || $iDocumentID === false) { // Source is a folder $this->ktwebdavLog("Source is a Folder.", 'info', true); $copystat = $this->_COPYFolder($options, $iFolderID); @@ -2049,13 +2106,15 @@ class KTWebDAVServer extends HTTP_WebDAV_Server $this->ktwebdavLog("Source is a Document.", 'info', true); if ($this->canCopyMoveRenameDocument($iDocumentID)) { - $copystat = $this->_COPYDocument($options, $iFolderID, $iDocumentID, $dest_folder_id); + $copystat = $this->_COPYDocument($options, $iFolderID, $iDocumentID); } else { - return "Cannot COPY document because it is checked out by another user."; + // Document is locked + return "423 Locked - Cannot COPY document because it is checked out by another user."; } } + /* ** Deprecated. If the request is a move then delete the source ** // Delete the source if this is a move and the copy was ok if ($del && ($copystat{0} == "2")) { $delstat = $this->DELETE(array("path" => $options["path"])); @@ -2064,6 +2123,7 @@ class KTWebDAVServer extends HTTP_WebDAV_Server return $delstat; } } + */ $this->ktwebdavLog("Final copystat result is: " . $copystat, 'info', true); return $copystat; @@ -2074,16 +2134,30 @@ class KTWebDAVServer extends HTTP_WebDAV_Server /** * COPY method helper for Documents * - * @param array parameter passing array - * @param int Folder ID - * @param int Document ID + * @param $options array parameter passing array + * @param $iFolderID int Folder ID + * @param $iDocumentID int Document ID * @return string HTTP status code or false */ function _COPYDocument($options, $iFolderID, $iDocumentID) { + /* ** Ensure that the destination path exists ** */ if ($options['dest'] == '') $options["dest"] = substr($options["dest_url"], strlen($_SERVER["SCRIPT_NAME"])); $this->ktwebdavLog("Entering _COPYDocument. options are " . print_r($options, true), 'info', true); + /* ** Get the relevant paths. Get the basename of the destination path as the destination filename. + Check whether the destination path refers to a folder / document. ** */ + $source_path = $options["path"]; + $dest_path = urldecode($options["dest"]); + $sDestFileName = basename($dest_path); + + list($iDestFolder, $iDestDoc) = $this->_folderOrDocument($dest_path); + + if($iDestFolder === false){ + return "409 Conflict - Destination folder does not exist."; + } + + /* ** Depth must be infinity to copy a document ** */ if ($options["depth"] != "infinity") { // RFC 2518 Section 9.2, last paragraph $this->ktwebdavLog("400 Bad request", 'info', true); @@ -2092,17 +2166,20 @@ class KTWebDAVServer extends HTTP_WebDAV_Server global $default; - $source_path = $options["path"]; - $dest_path = urldecode($options["dest"]); - + /* ** Get the source folder object. + If the destination document is null, then the destination is a folder, set the destination filename to empty, continue. + If the destination document returns an id, then the document exists. Check overwrite. + If overwrite is true, then check permissions and delete the document, continue. + If the destination document is false, then continue. ** */ $oSrcFolder = Folder::get($iFolderID); - list($iDestFolder, $iDestDoc) = $this->_folderOrDocument($dest_path); - + $new = true; if (is_null($iDestDoc)) { // the dest is a folder // $this->ktwebdavLog("400 Bad request", 'info', true); - return "400 Bad request - Destination is a Folder"; + $this->ktwebdavLog("Destination is a folder.", 'info', true); + $sDestFileName = ''; + //return "400 Bad request - Destination is a Folder"; } else if ($iDestDoc !== false) { // Document exists $this->ktwebdavLog("Destination Document exists.", 'info', true); @@ -2123,25 +2200,33 @@ class KTWebDAVServer extends HTTP_WebDAV_Server $new = false; } + /* ** Get the destination folder object and the source document object. + Check if user has permission to write to the document and folder. + Copy the document. ** */ $oDestFolder = Folder::get($iDestFolder); $oSrcDoc = Document::get($iDocumentID); include_once(KT_LIB_DIR . '/foldermanagement/folderutil.inc.php'); - $this->ktwebdavLog("Got an oSrcDoc of " . print_r($oSrcDoc, true), 'info', true); - $this->ktwebdavLog("Got an oDestFolder of " . print_r($oDestFolder, true), 'info', true); + $this->ktwebdavLog("Got an oSrcDoc of " .$oSrcDoc->getName() . print_r($oSrcDoc, true), 'info', true); + $this->ktwebdavLog("Got an oDestFolder of " .$oDestFolder->getName() . print_r($oDestFolder, true), 'info', true); // Check if the user has permissions to write in this folder $oPerm =& KTPermission::getByName('ktcore.permissions.write'); $oUser =& User::get($this->userID); - if (!KTPermissionUtil::userHasPermissionOnItem($oUser, $oPerm, $oSrcDoc)) { + if (!KTPermissionUtil::userHasPermissionOnItem($oUser, $oPerm, $oDestFolder)) { return "403 Forbidden - User does not have sufficient permissions"; } - KTDocumentUtil::copy($oSrcDoc, $oDestFolder, $_SERVER['HTTP_REASON']); - // FIXME: Do failure checking here + $reason = (isset($_SERVER['HTTP_REASON']) && !empty($_SERVER['HTTP_REASON'])) ? $_SERVER['HTTP_REASON'] : "KTWebDAV Copy."; + + $oDesDoc = KTDocumentUtil::copy($oSrcDoc, $oDestFolder, $reason, $sDestFileName); + + if(PEAR::isError($oDesDoc)){ + $this->ktwebdavLog("Copy on document failed: ".$oDesDoc->getMessage(), 'info', true); + return "500 Internal Server Error - Copy on document failed."; + } - $new = false; if ($new) { $this->ktwebdavLog("201 Created", 'info', true); return "201 Created"; @@ -2160,37 +2245,52 @@ class KTWebDAVServer extends HTTP_WebDAV_Server */ function _COPYFolder($options, $iFolderID) { + /* ** Ensure that the destination path exists ** */ if ($options['dest'] == '') $options["dest"] = substr($options["dest_url"], strlen($_SERVER["SCRIPT_NAME"])); $this->ktwebdavLog("Entering _COPYFolder. options are " . print_r($options, true), 'info', true); + /* ** RFC 2518 Section 8.8.3. DAV compliant servers must support depth headers of '0' and 'infinity'. + Check the requested depth. If depth is set to '0', set copyall to false. A depth of 0 indicates + that the folder is copied without any children. If depth is set to '1', return a 400 error. ** */ + $copyAll = true; if ($options["depth"] != "infinity") { - // RFC 2518 Section 9.2, last paragraph - $this->ktwebdavLog("400 Bad request", 'info', true); - return "400 Bad request - Depth must be 'infinity'."; + if($options['depth'] == '0'){ + $copyAll = false; + $this->ktwebdavLog("Depth is 0. Copy only the base folder.", 'info', true); + }else{ + $this->ktwebdavLog("400 Bad request. Depth must be infinity or 0.", 'info', true); + return "400 Bad request - Depth must be 'infinity' or '0'."; + } } global $default; $new = true; + /* ** Get the relevant paths. Get the basename of the destination path as the destination path name. + Check whether the destination path refers to a folder / document. ** */ $source_path = $options["path"]; $dest_path = urldecode($options["dest"]); - - $oSrcFolder = Folder::get($iFolderID); + $sDestPathName = basename($dest_path); list($iDestFolder, $iDestDoc) = $this->_folderOrDocument($dest_path); + /* ** Get the source and destination folder objects. + If the destination document is null, then the destination is an existing folder. Check overwrite. + If overwrite is true, then check permissions and delete the folder, continue. + If the destination document returns an id, then the destination is a document, return 409 error. + If the destination document is false, then continue. ** */ + $oSrcFolder = Folder::get($iFolderID); $oDestFolder = Folder::get($iDestFolder); include_once(KT_LIB_DIR . '/foldermanagement/folderutil.inc.php'); - if (is_null($iDestDoc)) { - // the dest is a folder - $this->ktwebdavLog("The Destination is a Folder.", 'info', true); - } else if ($iDestDoc !== false) { - // Folder exists + if(is_null($iDestDoc)) { + // Destination is a folder and exists + //$sDestPathName = ''; $this->ktwebdavLog("Destination Folder exists.", 'info', true); - $oReplaceFolder = Folder::get($iDestDoc); + + $oReplaceFolder = $oDestFolder; if ($options['overwrite'] != 'T') { $this->ktwebdavLog("Overwrite needs to be TRUE.", 'info', true); return "412 Precondition Failed - Destination Folder exists. Overwrite needs to be TRUE."; @@ -2203,10 +2303,21 @@ class KTWebDAVServer extends HTTP_WebDAV_Server if (!KTPermissionUtil::userHasPermissionOnItem($oUser, $oPerm, $oReplaceFolder)) { return "403 Forbidden - User does not have sufficient permissions"; } - KTFolderUtil::delete($oReplaceFolder, 'KTWebDAV move overwrites target.'); + KTFolderUtil::delete($oReplaceFolder, $oUser, 'KTWebDAV move overwrites target.'); + + // Destination folder has been deleted - get new object of destination parent folder + list($iDestFolder, $iDestDoc) = $this->_folderOrDocument($dest_path); + $oDestFolder = Folder::get($iDestFolder); + $new = false; + } else if ($iDestDoc !== false) { + // Destination is a document + return "409 Conflict - Can't write a collection to a document"; } + /* ** Get the destination folder object and the source document object. + Check if user has permission to write to the folder. + Copy the document. Pass parameters for the destination folder name and the depth of copy. ** */ $oUser =& User::get($this->userID); $this->ktwebdavLog("Got an oSrcFolder of " . print_r($oSrcFolder, true), 'info', true); $this->ktwebdavLog("Got an oDestFolder of " . print_r($oDestFolder, true), 'info', true); @@ -2218,7 +2329,15 @@ class KTWebDAVServer extends HTTP_WebDAV_Server if (!KTPermissionUtil::userHasPermissionOnItem($oUser, $oPerm, $oDestFolder)) { return "403 Forbidden - User does not have sufficient permissions"; } - KTFolderUtil::copy($oSrcFolder, $oDestFolder, $oUser, 'KTWebDAV Copy.'); + + $reason = (isset($_SERVER['HTTP_REASON']) && !empty($_SERVER['HTTP_REASON'])) ? $_SERVER['HTTP_REASON'] : "KTWebDAV Copy."; + + $res = KTFolderUtil::copy($oSrcFolder, $oDestFolder, $oUser, $reason, $sDestPathName, $copyAll); + + if(PEAR::isError($res)){ + $this->ktwebdavLog("Copy on folder failed: ".$res->getMessage(), 'info', true); + return "500 Internal Server Error - Copy on folder failed."; + } if ($new) { $this->ktwebdavLog("201 Created", 'info', true); diff --git a/lib/documentmanagement/documentutil.inc.php b/lib/documentmanagement/documentutil.inc.php index 7e1dbf7..0a21c54 100644 --- a/lib/documentmanagement/documentutil.inc.php +++ b/lib/documentmanagement/documentutil.inc.php @@ -638,14 +638,14 @@ class KTDocumentUtil { return $oDocument; } // }}} - + function generateNewDocumentFilename($sDocFilename){ if(preg_match("/\([0-9]+\)(\.[^\.]+){1,}$/", $sDocFilename)){ preg_match("/\([0-9]+\)\./", $sDocFilename, $matches); $new_one = substr($matches[0], 1); $new_two = explode(')', $new_one); $new = $new_two[0]+1; - + $pattern[0] = '/\([0-9]+\)\./'; $replacement[0] = ' ('.$new.').'; $sFilename = preg_replace($pattern, $replacement, $sDocFilename); @@ -657,27 +657,27 @@ class KTDocumentUtil { } $sFilename = $prefix.$suffix; } - + return $sFilename; } - - function generateNewDocumentName($sDocName){ + + function generateNewDocumentName($sDocName){ if(preg_match("/\([0-9]+\)$/", $sDocName)){ preg_match("/\([0-9]+\)$/", $sDocName, $matches); $new_one = substr($matches[0], 1); $new_two = explode(')', $new_one); $new = $new_two[0]+1; - + $pattern[0] = '/\([0-9]+\)$/'; $replacement[0] = '('.$new.')'; $sName = preg_replace($pattern, $replacement, $sDocName); }else{ $sName = $sDocName.' (2)'; } - + return $sName; } - + // {{{ fileExists function fileExists($oFolder, $sFilename) { return Document::fileExists($sFilename, $oFolder->getID()); @@ -939,7 +939,7 @@ class KTDocumentUtil { } - function copy($oDocument, $oDestinationFolder, $sReason = null) { + 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'; @@ -958,23 +958,36 @@ class KTDocumentUtil { // we still have a bogus md_version, but integrity holds, so fix it now. $oCore = KTDocumentCore::get($id); + // Get the metadata version for the source document $sTable = KTUtil::getTableName('document_metadata_version'); $sQuery = 'SELECT * FROM ' . $sTable . ' WHERE id = ?'; $aParams = array($oDocument->getMetadataVersionId()); $aMDRow = DBUtil::getOneResult(array($sQuery, $aParams)); unset($aMDRow['id']); + + // Copy the source metadata into the destination document $aMDRow['document_id'] = $oCore->getId(); + if(!empty($sDestinationDocName)){ + $aMDRow['name'] = $sDestinationDocName; + $aMDRow['description'] = $sDestinationDocName; + } $id = DBUtil::autoInsert($sTable, $aMDRow); if (PEAR::isError($id)) { return $id; } $oCore->setMetadataVersionId($id); $oMDV = KTDocumentMetadataVersion::get($id); + // Get the content version for the source document $sTable = KTUtil::getTableName('document_content_version'); $sQuery = 'SELECT * FROM ' . $sTable . ' WHERE id = ?'; $aParams = array($oDocument->_oDocumentContentVersion->getId()); $aContentRow = DBUtil::getOneResult(array($sQuery, $aParams)); unset($aContentRow['id']); + + // Copy the source content into the destination document $aContentRow['document_id'] = $oCore->getId(); + if(!empty($sDestinationDocName)){ + $aContentRow['filename'] = $sDestinationDocName; + } $id = DBUtil::autoInsert($sTable, $aContentRow); if (PEAR::isError($id)) { return $id; } $oMDV->setContentVersionId($id); @@ -996,6 +1009,7 @@ class KTDocumentUtil { $res = KTDocumentUtil::copyMetadata($oNewDocument, $oDocument->getMetadataVersionId()); if (PEAR::isError($res)) { return $res; } + // Ensure the copied document is not checked out $oNewDocument->setIsCheckedOut(false); $oNewDocument->setCheckedOutUserID(-1); diff --git a/lib/foldermanagement/folderutil.inc.php b/lib/foldermanagement/folderutil.inc.php index c211726..fab0137 100644 --- a/lib/foldermanagement/folderutil.inc.php +++ b/lib/foldermanagement/folderutil.inc.php @@ -7,32 +7,32 @@ * KnowledgeTree Open Source Edition * Document Management Made Simple * Copyright (C) 2004 - 2007 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 . - * + * * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place, * Blake Street, Observatory, 7925 South Africa. 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 - * copyright notice. + * must display the words "Powered by KnowledgeTree" and retain the original + * copyright notice. * Contributor( s): ______________________________________ */ @@ -414,8 +414,9 @@ class KTFolderUtil { return true; } - function copy($oSrcFolder, $oDestFolder, $oUser, $sReason) { - if (KTFolderUtil::exists($oDestFolder, $oSrcFolder->getName())) { + function copy($oSrcFolder, $oDestFolder, $oUser, $sReason, $sDestFolderName = NULL, $copyAll = true) { + $sDestFolderName = (empty($sDestFolderName)) ? $oSrcFolder->getName() : $sDestFolderName; + if (KTFolderUtil::exists($oDestFolder, $sDestFolderName)) { return PEAR::raiseError(_kt("Folder with the same name already exists in the new parent folder")); } // @@ -437,7 +438,7 @@ class KTFolderUtil { DBUtil::startTransaction(); - while (!empty($aRemainingFolders)) { + while (!empty($aRemainingFolders) && $copyAll) { $iFolderId = array_pop($aRemainingFolders); $oFolder = Folder::get($iFolderId); if (PEAR::isError($oFolder) || ($oFolder == false)) { @@ -487,15 +488,18 @@ class KTFolderUtil { $aFolderMap = array(); - $sTable = KTUtil::getTableName('folders'); + $sTable = 'folders'; $sGetQuery = 'SELECT * FROM ' . $sTable . ' WHERE id = ? '; $aParams = array($oSrcFolder->getId()); $aRow = DBUtil::getOneResult(array($sGetQuery, $aParams)); unset($aRow['id']); + + $aRow['name'] = $sDestFolderName; + $aRow['description'] = $sDestFolderName; $aRow['parent_id'] = $oDestFolder->getId(); $aRow['parent_folder_ids'] = sprintf('%s,%s', $oDestFolder->getParentFolderIDs(), $oDestFolder->getId()); $aRow['full_path'] = sprintf('%s/%s', $oDestFolder->getFullPath(), $oDestFolder->getName()); - + $id = DBUtil::autoInsert($sTable, $aRow); if (PEAR::isError($id)) { DBUtil::rollback(); @@ -506,7 +510,7 @@ class KTFolderUtil { $aFolderMap[$sSrcFolderId]['parent_folder_ids'] = $aRow['parent_folder_ids']; $aFolderMap[$sSrcFolderId]['full_path'] = $aRow['full_path']; $aFolderMap[$sSrcFolderId]['name'] = $aRow['name']; - + $oNewBaseFolder = Folder::get($id); $res = $oStorage->createFolder($oNewBaseFolder); if (PEAR::isError($res)) { @@ -517,12 +521,13 @@ class KTFolderUtil { $aRemainingFolders = Folder::getList(array('parent_id = ?', array($oSrcFolder->getId())), array('ids' => true)); - while (!empty($aRemainingFolders)) { + while (!empty($aRemainingFolders) && $copyAll) { $iFolderId = array_pop($aRemainingFolders); $aParams = array($iFolderId); $aRow = DBUtil::getOneResult(array($sGetQuery, $aParams)); unset($aRow['id']); + // since we are nested, we will have solved the parent first. $sPrevParentId = $aRow['parent_id']; $aRow['parent_id'] = $aFolderMap[$aRow['parent_id']]['parent_id']; @@ -552,7 +557,7 @@ class KTFolderUtil { $aCFIds = Folder::getList(array('parent_id = ?', array($iFolderId)), array('ids' => true)); $aRemainingFolders = kt_array_merge($aRemainingFolders, $aCFIds); } - + // now we can go ahead. foreach ($aDocuments as $oDocument) { $oChildDestinationFolder = Folder::get($aFolderMap[$oDocument->getFolderID()]['parent_id']); diff --git a/lib/permissions/permissionutil.inc.php b/lib/permissions/permissionutil.inc.php index 9375520..2ffb6e4 100644 --- a/lib/permissions/permissionutil.inc.php +++ b/lib/permissions/permissionutil.inc.php @@ -5,32 +5,32 @@ * KnowledgeTree Open Source Edition * Document Management Made Simple * Copyright (C) 2004 - 2007 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 . - * + * * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place, * Blake Street, Observatory, 7925 South Africa. 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 - * copyright notice. + * must display the words "Powered by KnowledgeTree" and retain the original + * copyright notice. * Contributor( s): ______________________________________ * */ @@ -52,6 +52,9 @@ require_once(KT_LIB_DIR . "/workflow/workflowutil.inc.php"); require_once(KT_LIB_DIR . "/workflow/workflowstatepermissionsassignment.inc.php"); class KTPermissionUtil { + + static $permArr = array(); + // {{{ generateDescriptor /** * Generate a unique textual representation of a specific collection @@ -93,7 +96,7 @@ class KTPermissionUtil { $oDescriptor =& KTPermissionDescriptor::getByDescriptor(md5($sDescriptor)); if (PEAR::isError($oDescriptor)) { $oOriginalDescriptor = $oDescriptor; - + $oDescriptor =& KTPermissionDescriptor::createFromArray(array( "descriptortext" => $sDescriptor, )); @@ -112,7 +115,7 @@ class KTPermissionUtil { exit(0); } $oDescriptor->saveAllowed($aAllowed); - + } return $oDescriptor; } @@ -193,7 +196,7 @@ class KTPermissionUtil { $sWhere = 'permission_object_id = ?'; $aParams = array($oPO->getID()); $aFolders =& Folder::getList(array($sWhere, $aParams)); - if (!PEAR::isError($aFolders)) { + if (!PEAR::isError($aFolders)) { foreach ($aFolders as $oFolder) { KTPermissionUtil::updatePermissionLookup($oFolder); } @@ -253,7 +256,7 @@ class KTPermissionUtil { } } } - + $oChannel =& KTPermissionChannel::getSingleton(); if (is_a($oFolderOrDocument, 'Folder')) { $msg = sprintf("Updating folder %s", join("/", $oFolderOrDocument->getPathArray())); @@ -265,7 +268,7 @@ class KTPermissionUtil { } } $oChannel->sendMessage(new KTPermissionGenericMessage($msg)); - //var_dump($msg); + //var_dump($msg); $iPermissionObjectId = $oFolderOrDocument->getPermissionObjectID(); if (empty($iPermissionObjectId)) { return; @@ -311,7 +314,7 @@ class KTPermissionUtil { foreach ($aWorkflowStatePermissionAssignments as $oAssignment) { $iPermissionId = $oAssignment->getPermissionId(); $iPermissionDescriptorId = $oAssignment->getDescriptorId(); - + $oPD = KTPermissionDescriptor::get($iPermissionDescriptorId); $aGroupIDs = $oPD->getGroups(); $aUserIDs = array(); @@ -330,16 +333,16 @@ class KTPermissionUtil { $iRoleSourceFolder = null; if (is_a($oFolderOrDocument, 'KTDocumentCore') || is_a($oFolderOrDocument, 'Document')) { $iRoleSourceFolder = $oFolderOrDocument->getFolderID(); } else { $iRoleSourceFolder = $oFolderOrDocument->getId(); } - + // very minor perf win: map role_id (in context) to PD. - $_roleCache = array(); - + $_roleCache = array(); + foreach ($aMapPermAllowed as $iPermissionId => $aAllowed) { $aAfterRoles = array(); if (array_key_exists('role', $aAllowed)) { foreach ($aAllowed['role'] as $k => $iRoleId) { // store the PD <-> RoleId map - + // special-case "all" or "authenticated". if (($iRoleId == -3) || ($iRoleId == -4)) { $aAfterRoles[] = $iRoleId; @@ -366,15 +369,15 @@ class KTPermissionUtil { unset($aAllowed['role'][$k]); } - + } - unset($aMapPermAllowed[$iPermissionId]['role']); - if (!empty($aAfterRoles)) { + unset($aMapPermAllowed[$iPermissionId]['role']); + if (!empty($aAfterRoles)) { $aMapPermAllowed[$iPermissionId]['role'] = $aAfterRoles; } } - + /* print '
';
         print '=======' . $oFolderOrDocument->getName();
@@ -382,7 +385,7 @@ class KTPermissionUtil {
         var_dump($aMapPermAllowed);
         print '
'; */ - + $aMapPermDesc = array(); foreach ($aMapPermAllowed as $iPermissionId => $aAllowed) { @@ -404,6 +407,7 @@ class KTPermissionUtil { * and so forth. */ function userHasPermissionOnItem($oUser, $oPermission, $oFolderOrDocument) { + if (is_string($oPermission)) { $oPermission =& KTPermission::getByName($oPermission); } @@ -413,20 +417,44 @@ class KTPermissionUtil { if (PEAR::isError($oFolderOrDocument) || $oFolderOrDocument == null) { return false; } + + // Quick fix for multiple permissions look ups. + // For the current lookup, if the permissions have been checked then return their value + $iPermId = $oPermission->getID(); + $iDocId = $oFolderOrDocument->getID(); + $lookup = 'folders'; + if(is_a($oEntity, 'Document') || is_a($oEntity, 'DocumentProxy')){ + $lookup = 'docs'; + } + // check if permission has been set + // $permArr[permId] = array('folders' => array('id' => bool), 'docs' => array('id' => bool)); + if(isset($permArr[$iPermId][$lookup][$iDocId])){ + return $permArr[$iPermId][$lookup][$iDocId]; + } + + + $oPL = KTPermissionLookup::get($oFolderOrDocument->getPermissionLookupID()); $oPLA = KTPermissionLookupAssignment::getByPermissionAndLookup($oPermission, $oPL); if (PEAR::isError($oPLA)) { //print $oPL->getID(); + $permArr[$iPermId][$lookup][$iDocId] = false; return false; } $oPD = KTPermissionDescriptor::get($oPLA->getPermissionDescriptorID()); - + + // set permission array to true + $permArr[$iPermId][$lookup][$iDocId] = true; + + // check for permissions $aGroups = GroupUtil::listGroupsForUserExpand($oUser); if ($oPD->hasRoles(array(-3))) { return true; } // everyone has access. else if ($oPD->hasUsers(array($oUser))) { return true; } else if ($oPD->hasGroups($aGroups)) { return true; } else if ($oPD->hasRoles(array(-4)) && !$oUser->isAnonymous()) { return true; } - + + // permission isn't true, set to false + $permArr[$iPermId][$lookup][$iDocId] = false; return false; } // }}} @@ -496,7 +524,7 @@ class KTPermissionUtil { 'groupid' => $oOrigDC->getGroupId(), 'conditionid' => $oOrigDC->getConditionId(), )); - + $oNewDC->saveAssignment($oOrigDC->getAssignment()); } @@ -582,7 +610,7 @@ class KTPermissionUtil { $iNewPOID = $oFolder->getPermissionObjectID(); $oNewPO =& KTPermissionObject::get($iNewPOID); - + $oDocumentOrFolder->setPermissionObjectID($iNewPOID); $oDocumentOrFolder->update(); @@ -591,7 +619,7 @@ class KTPermissionUtil { KTPermissionUtil::updatePermissionLookup($oDocumentOrFolder); return; } - + $iFolderID = $oDocumentOrFolder->getID(); $sFolderIDs = Folder::generateFolderIDs($iFolderID); $sFolderIDs .= '%';