From ae59d347e8dbcc17f8059f5c63cfe8743c65cd3f Mon Sep 17 00:00:00 2001 From: Paul Barrett Date: Tue, 2 Mar 2010 15:31:32 +0200 Subject: [PATCH] Update CMIS Move Document --- lib/api/ktcmis/ktObjectService.inc.php | 14 +++++++------- lib/api/ktcmis/services/CMISNavigationService.inc.php | 10 +++++----- lib/api/ktcmis/services/CMISObjectService.inc.php | 92 +++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------- lib/api/ktcmis/util/CMISUtil.inc.php | 26 ++++++++++++++------------ webservice/atompub/cmis/KT_cmis_atom_server.services.inc.php | 23 +++++++++++------------ webservice/atompub/cmis/KT_cmis_atom_service_helper.inc.php | 2 +- 6 files changed, 83 insertions(+), 84 deletions(-) diff --git a/lib/api/ktcmis/ktObjectService.inc.php b/lib/api/ktcmis/ktObjectService.inc.php index e3e293b..c2f8f63 100644 --- a/lib/api/ktcmis/ktObjectService.inc.php +++ b/lib/api/ktcmis/ktObjectService.inc.php @@ -200,16 +200,16 @@ class KTObjectService extends KTCMISBase { /** * Moves a fileable object from one folder to another. * - * @param object $repositoryId - * @param object $objectId - * @param object $changeToken [optional] - * @param object $targetFolderId - * @param object $sourceFolderId [optional] + * @param string $repositoryId + * @param string $objectId + * @param string $targetFolderId + * @param string $sourceFolderId + * @return string $objectId */ - public function moveObject($repositoryId, $objectId, $changeToken = '', $targetFolderId, $sourceFolderId = null) + public function moveObject($repositoryId, $objectId, $targetFolderId, $sourceFolderId) { try { - $this->ObjectService->moveObject($repositoryId, $objectId, $changeToken, $targetFolderId, $sourceFolderId); + $this->ObjectService->moveObject($repositoryId, $objectId, $targetFolderId, $sourceFolderId); } catch (Exception $e) { diff --git a/lib/api/ktcmis/services/CMISNavigationService.inc.php b/lib/api/ktcmis/services/CMISNavigationService.inc.php index 5a85f21..aaaf406 100644 --- a/lib/api/ktcmis/services/CMISNavigationService.inc.php +++ b/lib/api/ktcmis/services/CMISNavigationService.inc.php @@ -98,7 +98,7 @@ class CMISNavigationService { // if this is not a folder, cannot get children $folderId = CMISUtil::decodeObjectId($folderId, $type); - if ($type != 'Folder') { + if ($type != 'cmis:folder') { throw new invalidArgumentException('The specified object is not a folder'); } @@ -149,7 +149,7 @@ class CMISNavigationService { // if this is not a folder, cannot get descendants $folderId = CMISUtil::decodeObjectId($folderId, $type); - if ($type != 'Folder') { + if ($type != 'cmis:folder') { throw new InvalidArgumentException('The supplied object is not a folder, unable to return descendants'); } @@ -195,7 +195,7 @@ class CMISNavigationService { // if this is not a folder, cannot get folder parent :) $folderId = CMISUtil::decodeObjectId($folderId, $type); // NOTE this will quite possibly break the webservices - if ($type != 'Folder') + if ($type != 'cmis:folder') { return $ancestry; } @@ -257,12 +257,12 @@ class CMISNavigationService { // TODO - what about other types? only implementing folders and documents at the moment so ignore for now switch($typeId) { - case 'Document': + case 'cmis:document': $document = $this->ktapi->get_document_by_id($objectId); $parent = $document->ktapi_folder; $ancestry[] = $parent; break; - case 'Folder': + case 'cmis:folder': $folder = $this->ktapi->get_folder_by_id($objectId); $parent = $this->ktapi->get_folder_by_id($folder->get_parent_folder_id()); $ancestry[] = $parent; diff --git a/lib/api/ktcmis/services/CMISObjectService.inc.php b/lib/api/ktcmis/services/CMISObjectService.inc.php index 34eab81..7a38302 100644 --- a/lib/api/ktcmis/services/CMISObjectService.inc.php +++ b/lib/api/ktcmis/services/CMISObjectService.inc.php @@ -88,7 +88,7 @@ class CMISObjectService { // Attempt to decode $folderId, use as is if not detected as encoded $tmpObjectId = $folderId; $tmpObjectId = CMISUtil::decodeObjectId($tmpObjectId, $tmpTypeId); - if ($tmpTypeId != 'Unknown') + if ($tmpTypeId != 'unknown') $folderId = $tmpObjectId; // if parent folder is not allowed to hold this type, throw exception @@ -325,7 +325,7 @@ class CMISObjectService { // Attempt to decode $folderId, use as is if not detected as encoded $tmpObjectId = $folderId; $tmpObjectId = CMISUtil::decodeObjectId($tmpObjectId, $tmpTypeId); - if ($tmpTypeId != 'Unknown') + if ($tmpTypeId != 'unknown') $folderId = $tmpObjectId; // if parent folder is not allowed to hold this type, throw exception @@ -368,16 +368,16 @@ class CMISObjectService { $properties = array(); $objectId = CMISUtil::decodeObjectId($objectId, $typeId); - if ($typeId == 'Unknown') { + if ($typeId == 'unknown') { throw new ObjectNotFoundException('The type of the requested object could not be determined'); } switch($typeId) { - case 'Document': + case 'cmis:document': $CMISObject = new CMISDocumentObject($objectId, $this->ktapi, $repository->getRepositoryURI()); break; - case 'Folder': + case 'cmis:folder': $CMISObject = new CMISFolderObject($objectId, $this->ktapi, $repository->getRepositoryURI()); break; } @@ -409,15 +409,15 @@ class CMISObjectService { $contentStream = null; // decode $objectId - $objectId = CMISUtil::decodeObjectId($objectId, $typeId); + $objectId = CMISUtil::decodeObjectId($objectId, $typeId, $className); // unknown object type? - if ($typeId == 'Unknown') { + if ($typeId == 'unknown') { throw new ObjectNotFoundException('The type of the requested object could not be determined'); } // fetch type definition of supplied object type - $objectClass = 'CMIS' . $typeId . 'Object'; + $objectClass = 'CMIS' . $className . 'Object'; $CMISObject = new $objectClass($objectId, $this->ktapi); // if content stream is not allowed for this object type definition, or the specified object does not have @@ -444,37 +444,32 @@ class CMISObjectService { /** * Moves a fileable object from one folder to another. * - * @param object $repositoryId - * @param object $objectId - * @param object $changeToken [optional] - * @param object $targetFolderId - * @param object $sourceFolderId [optional] + * @param string $repositoryId + * @param string $objectId + * @param string $targetFolderId + * @param string $sourceFolderId + * @return string $objectId */ // TODO versioningException: The repository MAY throw this exception if the object is a non-current Document Version. - // TODO check whether object is in fact fileable? not strictly needed, but possibly should be here. - public function moveObject($repositoryId, $objectId, $changeToken = '', $targetFolderId, $sourceFolderId = null) + // TODO check whether object is in fact fileable? perhaps not strictly needed, but possibly should be here. + public function moveObject($repositoryId, $objectId, $targetFolderId, $sourceFolderId) { - // The $sourceFolderId parameter SHALL be specified if the Repository supports the optional 'unfiling' capability - if (is_null($sourceFolderId)) - { - $RepositoryService = new CMISRepositoryService(); - $info = $RepositoryService->getRepositoryInfo($repositoryId); - $capabilities = $info->getCapabilities(); - // check for unfiling capability - // NOTE this is only required once/if KnowledgeTree allows the source folder id to be optional, - // but it is required for CMIS specification compliance. - if ($capabilities->hasCapabilityUnfiling() === 'true') { - throw new RuntimeException('The source folder id MUST be supplied when unfiling is supported.'); - } - } - - // Attempt to decode $objectId, use as is if not detected as encoded + // attempt to decode $objectId, use as is if not detected as encoded $tmpObjectId = $objectId; - $tmpObjectId = CMISUtil::decodeObjectId($tmpObjectId, $typeId); - if ($tmpTypeId != 'Unknown') $objectId = $tmpObjectId; + $tmpObjectId = CMISUtil::decodeObjectId($tmpObjectId, $typeId, $className); + if ($tmpTypeId != 'unknown') $objectId = $tmpObjectId; + + $objectClass = 'CMIS' . $className . 'Object'; + $CMISObject = new $objectClass($objectId, $this->ktapi); $targetFolderId = CMISUtil::decodeObjectId($targetFolderId); + // check the $sourceFolderId parameter - if empty or does not match (at least one) parent of the specified object, + // throw exception + if (empty($sourceFolderId) || $CMISObject->getProperty('parentId') != $sourceFolderId) { + throw new InvalidArgumentException('The source folder id is invalid'); + } + // check type id of object against allowed child types for destination folder $CMISFolder = new CMISFolderObject($targetFolderId, $this->ktapi); $allowed = $CMISFolder->getProperty('allowedChildObjectTypeIds'); @@ -490,21 +485,26 @@ class CMISObjectService { // TODO add reasons and sig data // attempt to move object - if ($typeId == 'Folder') { + if ($typeId == 'cmis:folder') { $response = $this->ktapi->move_folder($objectId, $targetFolderId, $reason, $sig_username, $sig_password); } - else if ($typeId == 'Document') { + else if ($typeId == 'cmis:document') { $response = $this->ktapi->move_document($objectId, $targetFolderId, $reason, null, null, $sig_username, $sig_password); } else { $response['status_code'] = 1; $response['message'] = 'The object type could not be determined.'; } + + // TODO The repository may throw a NameConstrainViolationException if there is a name conflict (determined by KTAPI) + // or may choose a name which does not conflict // if failed, throw StorageException if ($response['status_code'] != 0) { throw new StorageException('The repository was unable to move the object: ' . $response['message']); - } + } + + return CMISUtil::encodeObjectId($objectId, $typeId); } /** @@ -524,14 +524,14 @@ class CMISObjectService { // TODO this should probably be a function, it is now used in two places... // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository). $exists = true; - if ($typeId == 'Folder') + if ($typeId == 'cmis:folder') { $object = $this->ktapi->get_folder_by_id($objectId); if (PEAR::isError($object)) { $exists = false; } } - else if ($typeId == 'Document') + else if ($typeId == 'cmis:document') { $object = $this->ktapi->get_document_by_id($objectId); if (PEAR::isError($object)) { @@ -548,7 +548,7 @@ class CMISObjectService { } global $default; // throw ConstraintViolationException if method is invoked on a Folder object that contains one or more objects - if ($typeId == 'Folder') + if ($typeId == 'cmis:folder') { $folderContent = $object->get_listing(); if (!PEAR::isError($folderContent)) @@ -563,7 +563,7 @@ class CMISObjectService { // TODO add the electronic signature capability $result = $this->ktapi->delete_folder($objectId, $reason, $sig_username, $sig_password); } - else if ($typeId == 'Document') + else if ($typeId == 'cmis:document') { // NOTE KnowledgeTree does not support deleting of individual versions and will always delete all versions // Throw an exception instead if individual version requested for delete @@ -625,7 +625,7 @@ class CMISObjectService { // throw updateConflictException if the operation is attempting to update an object that is no longer current // (as determined by the repository) - if ($typeId == 'Folder') { + if ($typeId == 'cmis:folder') { $object = $this->ktapi->get_folder_by_id($folderId); if (PEAR::isError($object)) { throw new updateConflictException('Unable to delete the object as it cannot be found.'); @@ -652,10 +652,10 @@ class CMISObjectService { foreach($folderContents as $folderObject) { if ($folderObject['item_type'] == 'F') { - $type = 'Folder'; + $type = 'cmis:folder'; } else if ($folderObject['item_type'] == 'D') { - $type = 'Document'; + $type = 'cmis:document'; } $failedToDelete[] = CMISUtil::encodeObjectId($type, $folderObject['id']); @@ -697,7 +697,7 @@ class CMISObjectService { // Attempt to decode $documentId, use as is if not detected as encoded $tmpObjectId = $documentId; $tmpObjectId = CMISUtil::decodeObjectId($tmpObjectId, $tmpTypeId); - if ($tmpTypeId != 'Unknown') + if ($tmpTypeId != 'unknown') $documentId = $tmpObjectId; // TODO deal with other types except documents @@ -715,8 +715,7 @@ class CMISObjectService { } $csFileName = $CMISDocument->getProperty('contentStreamFilename'); - if (!empty($csFileName) && (!$overwriteFlag)) - { + if (!empty($csFileName) && (!$overwriteFlag)) { throw new ContentAlreadyExistsException('Unable to overwrite existing content stream'); } @@ -724,8 +723,7 @@ class CMISObjectService { // update the document content from this temporary file as per usual // TODO Use checkin_document_with_metadata instead if metadata content submitted || update metadata separately? $response = $this->ktapi->checkin_document($documentId, $csFileName, 'CMIS setContentStream action', $tempfilename, false); - if ($response['status_code'] != 0) - { + if ($response['status_code'] != 0) { throw new StorageException('Unable to update the content stream. ' . $response['message']); } // else diff --git a/lib/api/ktcmis/util/CMISUtil.inc.php b/lib/api/ktcmis/util/CMISUtil.inc.php index 7ac5e5a..e3e977c 100644 --- a/lib/api/ktcmis/util/CMISUtil.inc.php +++ b/lib/api/ktcmis/util/CMISUtil.inc.php @@ -97,11 +97,11 @@ class CMISUtil { * @param string &$typeId * @return string $objectId */ - static public function decodeObjectId($objectId, &$typeId = null) + static public function decodeObjectId($objectId, &$typeId = null, &$className = '') { if (!is_string($objectId)) { - $typeId = 'Unknown'; + $typeId = 'unknown'; return null; } @@ -123,7 +123,7 @@ class CMISUtil { // method of doing this. // meantime this minor hack will get things working for the existing system structure, as the root // folder should always be id 1. - $typeId = 'Folder'; + $typeId = 'cmis:folder'; return '1'; } @@ -134,13 +134,15 @@ class CMISUtil { switch($type) { case 'D': - $typeId = 'Document'; + $typeId = 'cmis:document'; + $className = 'Document'; break; case 'F': - $typeId = 'Folder'; + $typeId = 'cmis:folder'; + $className = 'Folder'; break; default: - $typeId = 'Unknown'; + $typeId = 'unknown'; break; } @@ -498,14 +500,14 @@ class CMISUtil { public function contentExists($typeId, $objectId, &$ktapi) { $exists = true; - if ($typeId == 'Folder') + if ($typeId == 'cmis:folder') { $object = $ktapi->get_folder_by_id($objectId); if (PEAR::isError($object)) { $exists = false; } } - else if ($typeId == 'Document') + else if ($typeId == 'cmis:document') { $object = $ktapi->get_document_by_id($objectId); if (PEAR::isError($object)) { @@ -567,10 +569,10 @@ class CMISUtil { /** * Checks for the root folder * - * @param unknown_type $repositoryId - * @param unknown_type $folderId - * @param unknown_type $ktapi - * @return unknown + * @param string $repositoryId + * @param string $folderId + * @param object $ktapi + * @return boolean */ static public function isRootFolder($repositoryId, $folderId, &$ktapi) { diff --git a/webservice/atompub/cmis/KT_cmis_atom_server.services.inc.php b/webservice/atompub/cmis/KT_cmis_atom_server.services.inc.php index a537547..b1b5a8a 100644 --- a/webservice/atompub/cmis/KT_cmis_atom_server.services.inc.php +++ b/webservice/atompub/cmis/KT_cmis_atom_server.services.inc.php @@ -150,24 +150,23 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { // document action create will have a content tag or containing base64 encoding of the document // move action will have an existing id supplied as a parameter - not sure how this works yet as the CMIS clients we are // testing don't support move functionality at this time (2009/07/23) and so we are presuming the following format: - // /folder//children/ + // /folder/// // also possible that there will be an existing ObjectId property, try to cater for both until we know how it really works + // NOTE this also applies to the source folder id, see above // check for existing object id as parameter in url - if (isset($this->params[2])) - { + // if sourceFolderId parameter is submitted, this is a move + if (isset($this->params[1])) { $action = 'move'; - $objectId = $this->params[2]; + $sourceFolderId = $this->params[1]; } // get object properties - todo send through original properties array and not modified version - $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->rawContent); + $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisObjectProperties($this->rawContent); $properties = array('name' => $title, 'summary' => $summary, 'objectTypeId' => $cmisObjectProperties['cmis:objectTypeId']); // check for existing object id as property of submitted object data - if (!empty($cmisObjectProperties['cmis:objectId'])) - { - $action = 'move'; + if (!empty($cmisObjectProperties['cmis:objectId'])) { $objectId = $cmisObjectProperties['cmis:objectId']; } @@ -210,7 +209,7 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { $newObjectId = $newObjectId['results']; // check if returned Object Id is a valid CMIS Object Id CMISUtil::decodeObjectId($newObjectId, $typeId); - if ($typeId != 'Unknown') { + if ($typeId != 'unknown') { $success = true; } else { @@ -223,7 +222,7 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { } else if ($action == 'move') { - $response = $ObjectService->moveObject($repositoryId, $objectId, '', $folderId); + $response = $ObjectService->moveObject($repositoryId, $objectId, $folderId, $sourceFolderId); if ($response['status_code'] == 0) { $success = true; @@ -523,7 +522,7 @@ class KT_cmis_atom_service_pwc extends KT_cmis_atom_service { $ObjectService = new KTObjectService(KT_cmis_atom_service_helper::getKt()); // get object properties - $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->rawContent); + $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisObjectProperties($this->rawContent); // check for content stream $content = KT_cmis_atom_service_helper::getCmisContent($this->rawContent); @@ -635,7 +634,7 @@ class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service { $VersioningService = new KTVersioningService(KT_cmis_atom_service_helper::getKt()); $ObjectService = new KTObjectService(KT_cmis_atom_service_helper::getKt()); - $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->rawContent); + $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisObjectProperties($this->rawContent); // check for existing object id as property of submitted object data if (empty($cmisObjectProperties['cmis:objectId'])) diff --git a/webservice/atompub/cmis/KT_cmis_atom_service_helper.inc.php b/webservice/atompub/cmis/KT_cmis_atom_service_helper.inc.php index 8c2b27c..b5c92a5 100644 --- a/webservice/atompub/cmis/KT_cmis_atom_service_helper.inc.php +++ b/webservice/atompub/cmis/KT_cmis_atom_service_helper.inc.php @@ -530,7 +530,7 @@ class KT_cmis_atom_service_helper { return CMISUtil::encodeObjectId(FOLDER, $folderId); } - static public function getCmisProperties(&$xml) + static public function getCmisObjectProperties(&$xml) { $xmlReader = new XMLReader(); $xmlReader->XML($xml); -- libgit2 0.21.4