Commit dac083c191f2b67c359cbaa455dbfdb087283af3
Merge branch 'edge' of git@github.com:ktgit/knowledgetree into edge
Showing
8 changed files
with
129 additions
and
179 deletions
lib/api/ktcmis/ktObjectService.inc.php
| ... | ... | @@ -181,12 +181,13 @@ class KTObjectService extends KTCMISBase { |
| 181 | 181 | * |
| 182 | 182 | * @param string $repositoryId |
| 183 | 183 | * @param string $objectId |
| 184 | + * @param string $streamId [optional for documents] Specifies the rendition to retrieve if not original document | |
| 184 | 185 | * @return string $contentStream (binary or text data) |
| 185 | 186 | */ |
| 186 | - function getContentStream($repositoryId, $objectId) | |
| 187 | + function getContentStream($repositoryId, $objectId, $streamId = null) | |
| 187 | 188 | { |
| 188 | 189 | try { |
| 189 | - $contentStream = $this->ObjectService->getContentStream($repositoryId, $objectId); | |
| 190 | + $contentStream = $this->ObjectService->getContentStream($repositoryId, $objectId, $streamId); | |
| 190 | 191 | } |
| 191 | 192 | catch (Exception $e) |
| 192 | 193 | { | ... | ... |
lib/api/ktcmis/ktVersioningService.inc.php
| ... | ... | @@ -110,15 +110,14 @@ class KTVersioningService extends KTCMISBase { |
| 110 | 110 | * Checks out a document and creates the PWC (Private Working Copy) which will represent the checked out document |
| 111 | 111 | * |
| 112 | 112 | * @param string $repositoryId |
| 113 | - * @param string $documentId | |
| 114 | - * @param string $changeToken [optional] | |
| 113 | + * @param string $objectId | |
| 115 | 114 | * @return array results |
| 116 | 115 | */ |
| 117 | 116 | // TODO set up delivery of content stream? or is that up to the CMIS client? |
| 118 | - public function checkOut($repositoryId, $documentId, $changeToken = '') | |
| 117 | + public function checkOut($repositoryId, $objectId) | |
| 119 | 118 | { |
| 120 | 119 | try { |
| 121 | - $result = $this->VersioningService->checkOut($repositoryId, $documentId, $changeToken); | |
| 120 | + $result = $this->VersioningService->checkOut($repositoryId, $objectId); | |
| 122 | 121 | } |
| 123 | 122 | catch (Exception $e) |
| 124 | 123 | { |
| ... | ... | @@ -138,18 +137,17 @@ class KTVersioningService extends KTCMISBase { |
| 138 | 137 | * Reverses the effect of a checkout: I.E. deletes the PWC (Private Working Copy) and re-sets the status of the document to "not checked out" |
| 139 | 138 | * |
| 140 | 139 | * @param string $repositoryId |
| 141 | - * @param string $documentId | |
| 142 | - * @param string $changeToken [optional] | |
| 140 | + * @param string $objectId | |
| 143 | 141 | */ |
| 144 | 142 | // TODO exceptions: |
| 145 | 143 | // • ConstraintViolationException: The Repository SHALL throw this exception if ANY of the following conditions are met: |
| 146 | 144 | // o The Document’s Object-Type definition’s versionable attribute is FALSE. |
| 147 | 145 | // • updateConflictException |
| 148 | 146 | // • versioningException |
| 149 | - public function cancelCheckOut($repositoryId, $documentId, $changeToken = '') | |
| 147 | + public function cancelCheckOut($repositoryId, $objectId) | |
| 150 | 148 | { |
| 151 | 149 | try { |
| 152 | - $result = $this->VersioningService->cancelCheckOut($repositoryId, $documentId, $changeToken); | |
| 150 | + $result = $this->VersioningService->cancelCheckOut($repositoryId, $objectId); | |
| 153 | 151 | } |
| 154 | 152 | catch (Exception $e) |
| 155 | 153 | { |
| ... | ... | @@ -169,18 +167,22 @@ class KTVersioningService extends KTCMISBase { |
| 169 | 167 | * Checks in a checked out document |
| 170 | 168 | * |
| 171 | 169 | * @param string $repositoryId |
| 172 | - * @param string $documentId | |
| 173 | - * @param boolean $major | |
| 174 | - * @param string $changeToken [optional] | |
| 170 | + * @param string $objectId | |
| 171 | + * @param boolean $major [optional] defaults to true | |
| 175 | 172 | * @param array $properties [optional] |
| 176 | 173 | * @param contentStream $contentStream [optional] |
| 177 | 174 | * @param string $checkinComment [optional] |
| 178 | - * @return string $documentId | |
| 175 | + * @param array $policies | |
| 176 | + * @param array $addACEs | |
| 177 | + * @param array $removeACEs | |
| 178 | + * @return string $objectId | |
| 179 | 179 | */ |
| 180 | - public function checkIn($repositoryId, $documentId, $major, $contentStream = null, $changeToken = '', $properties = array(), $checkinComment = '') | |
| 180 | + public function checkIn($repositoryId, $objectId, $major = true, $properties = array(), $contentStream = null, | |
| 181 | + $checkinComment = '', $policies = array(), $addACEs = array(), $removeACEs = array()) | |
| 181 | 182 | { |
| 182 | 183 | try { |
| 183 | - $result = $this->VersioningService->checkIn($repositoryId, $documentId, $major, $contentStream, $changeToken, $properties, $checkinComment); | |
| 184 | + $result = $this->VersioningService->checkIn($repositoryId, $objectId, $major, $properties, $contentStream, | |
| 185 | + $checkinComment, $policies, $addACEs, $removeACEs); | |
| 184 | 186 | } |
| 185 | 187 | catch (Exception $e) |
| 186 | 188 | { | ... | ... |
lib/api/ktcmis/services/CMISObjectService.inc.php
| ... | ... | @@ -401,16 +401,16 @@ class CMISObjectService { |
| 401 | 401 | } |
| 402 | 402 | |
| 403 | 403 | /** |
| 404 | - * Fetches the content stream data for an object | |
| 404 | + * Fetches the content stream data for an object, or fetched a rendition stream for a specified rendition | |
| 405 | 405 | * |
| 406 | 406 | * @param string $repositoryId |
| 407 | 407 | * @param string $objectId |
| 408 | - * @return string $contentStream (binary or text data) | |
| 408 | + * @param string $streamId [optional for documents] Specifies the rendition to retrieve if not original document | |
| 409 | + * @return string $contentStream (binary [base64 encoded] or text data) | |
| 409 | 410 | */ |
| 410 | - // NOTE streamNotSupportedException: The Repository SHALL throw this exception if the Object-Type definition | |
| 411 | - // specified by the objectId parameter’s “contentStreamAllowed� attribute is set to “not allowed�. | |
| 412 | - // | |
| 413 | - function getContentStream($repositoryId, $objectId) | |
| 411 | + // NOTE Each CMIS protocol binding MAY provide a way for fetching a sub-range within a content stream, | |
| 412 | + // in a manner appropriate to that protocol. | |
| 413 | + function getContentStream($repositoryId, $objectId, $streamId = null) | |
| 414 | 414 | { |
| 415 | 415 | $contentStream = null; |
| 416 | 416 | |
| ... | ... | @@ -426,13 +426,11 @@ class CMISObjectService { |
| 426 | 426 | $objectClass = 'CMIS' . $typeId . 'Object'; |
| 427 | 427 | $CMISObject = new $objectClass($objectId, $this->ktapi); |
| 428 | 428 | |
| 429 | - // if content stream is not allowed for this object type definition, throw a ConstraintViolationException | |
| 429 | + // if content stream is not allowed for this object type definition, or the specified object does not have | |
| 430 | + // a content/rendition stream, throw a ConstraintViolationException | |
| 430 | 431 | if (($CMISObject->getAttribute('contentStreamAllowed') == 'notAllowed')) |
| 431 | 432 | { |
| 432 | - // NOTE spec version 0.61c specifies both a ConstraintViolationException and a StreamNotSupportedException | |
| 433 | - // for this case. Choosing to throw StreamNotSupportedException until the specification is clarified | |
| 434 | - // as it is a more specific exception | |
| 435 | - throw new StreamNotSupportedException('Content Streams are not allowed for this object type'); | |
| 433 | + throw new ConstraintViolationException('This object does not have a content stream of the requested type'); | |
| 436 | 434 | } |
| 437 | 435 | |
| 438 | 436 | // now go on to fetching the content stream | ... | ... |
lib/api/ktcmis/services/CMISVersioningService.inc.php
| ... | ... | @@ -71,54 +71,58 @@ class CMISVersioningService { |
| 71 | 71 | * Checks out a document and creates the PWC (Private Working Copy) which will represent the checked out document |
| 72 | 72 | * |
| 73 | 73 | * @param string $repositoryId |
| 74 | - * @param string $documentId | |
| 75 | - * @param string $changeToken [optional] | |
| 76 | - * @return string $documentId The id of the PWC object | |
| 74 | + * @param string $objectId | |
| 75 | + * @return string $objectId The id of the PWC object | |
| 77 | 76 | * @return boolean $contentCopied TRUE if contentStream is a copy of the document content stream, FALSE if contentStream not set |
| 78 | 77 | */ |
| 79 | - // TODO exceptions: | |
| 80 | - // • versioningException: The repository MAY throw this exception if the object is a non-current Document Version. | |
| 81 | 78 | // NOTE since we need to return two values, we return one via argument by reference |
| 82 | - // since $documentId already exists in the argument list, that was chosen as the "return by reference" value | |
| 79 | + // since $objectId already exists in the argument list, that was chosen as the "return by reference" value | |
| 83 | 80 | // TODO set up delivery of content stream? or is that up to the CMIS client? |
| 84 | - public function checkOut($repositoryId, &$documentId, $changeToken = '') | |
| 81 | + public function checkOut($repositoryId, &$objectId) | |
| 85 | 82 | { |
| 86 | 83 | $contentCopied = false; |
| 87 | - | |
| 88 | - $documentId = CMISUtil::decodeObjectId($documentId, $typeId); | |
| 84 | + | |
| 85 | + $objectId = CMISUtil::decodeObjectId($objectId, $typeId); | |
| 89 | 86 | |
| 90 | 87 | // NOTE We are not planning on persisting the PWC beyond the current session, it will be re-created on access of the checked out document |
| 91 | 88 | // TODO consider persisting in the database? How will this relate to JSR if we are switching to that? |
| 92 | 89 | // NOTE within the current system it is assumed if a new document metadata version is created that this is the latest version of the document |
| 93 | 90 | // TODO see if there is an easy way to modify this, else we may not have an easy way to persist PWC objects |
| 94 | - | |
| 91 | + | |
| 95 | 92 | // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository). |
| 96 | 93 | try { |
| 97 | - $pwc = new CMISDocumentObject($documentId, $this->ktapi); | |
| 94 | + $pwc = new CMISDocumentObject($objectId, $this->ktapi); | |
| 98 | 95 | } |
| 99 | 96 | catch (exception $e) { |
| 100 | 97 | throw new UpdateConflictException($e->getMessage()); |
| 101 | 98 | } |
| 102 | - | |
| 99 | + | |
| 103 | 100 | // throw exception if the object is not versionable |
| 104 | 101 | if (!$pwc->getAttribute('versionable')) { |
| 105 | 102 | throw new ConstraintViolationException('This document is not versionable and may not be checked out'); |
| 106 | 103 | } |
| 107 | - | |
| 104 | + | |
| 105 | + // check that this is the latest version | |
| 106 | + if ($pwc->getProperty('isLatestVersion') != true) { | |
| 107 | + throw new VersioningException('The document is not the latest version and cannot be checked out'); | |
| 108 | + } | |
| 109 | + | |
| 108 | 110 | // NOTE KTAPI as currently implemented does not give a direct response which indicates if the document is already checked out, |
| 109 | 111 | // as long as the same user is calling the checkout again, so should we add a check here specifically? |
| 110 | 112 | |
| 111 | 113 | // run checkout process - set $download = false (third function argument) as we want to return the document content via the contentStream |
| 112 | - $response = $this->ktapi->checkout_document($documentId, 'CMIS Checkout Action', false, $sig_username, $sig_password); | |
| 114 | + $response = $this->ktapi->checkout_document($objectId, 'CMIS Checkout Action', false, $sig_username, $sig_password); | |
| 113 | 115 | // if there was an error, throw an exception |
| 114 | 116 | if ($response['status_code'] == 1) { |
| 115 | 117 | throw new StorageException($response['message']); |
| 116 | - }; | |
| 117 | - | |
| 118 | + } | |
| 119 | + | |
| 118 | 120 | // if successful, set $contentCopied = true; unless contentStream is not set |
| 119 | - if ($pwc->getProperty('contentStreamFilename') != '') $contentCopied = true; | |
| 120 | - $documentId = CMISUtil::encodeObjectId(DOCUMENT, $documentId); | |
| 121 | - | |
| 121 | + if ($pwc->getProperty('contentStreamFilename') != '') { | |
| 122 | + $contentCopied = true; | |
| 123 | + } | |
| 124 | + $objectId = CMISUtil::encodeObjectId(DOCUMENT, $objectId); | |
| 125 | + | |
| 122 | 126 | // mark document object as checked out |
| 123 | 127 | $pwc->setProperty('isVersionSeriesCheckedOut', true); |
| 124 | 128 | $userName = ''; |
| ... | ... | @@ -127,8 +131,8 @@ class CMISVersioningService { |
| 127 | 131 | $userName = $user->getName(); |
| 128 | 132 | } |
| 129 | 133 | $pwc->setProperty('versionSeriesCheckedOutBy', $userName); |
| 130 | - $pwc->setProperty('versionSeriesCheckedOutId', $documentId); | |
| 131 | - | |
| 134 | + $pwc->setProperty('versionSeriesCheckedOutId', $objectId); | |
| 135 | + | |
| 132 | 136 | return $contentCopied; |
| 133 | 137 | } |
| 134 | 138 | |
| ... | ... | @@ -136,19 +140,18 @@ class CMISVersioningService { |
| 136 | 140 | * Reverses the effect of a checkout: I.E. deletes the PWC (Private Working Copy) and re-sets the status of the document to "not checked out" |
| 137 | 141 | * |
| 138 | 142 | * @param string $repositoryId |
| 139 | - * @param string $documentId | |
| 140 | - * @param string $changeToken [optional] | |
| 143 | + * @param string $objectId | |
| 141 | 144 | */ |
| 142 | 145 | // TODO exceptions: |
| 143 | 146 | // • versioningException - The repository MAY throw this exception if the object is a non-current Document Version. |
| 144 | - public function cancelCheckOut($repositoryId, $documentId, $changeToken = '') | |
| 147 | + public function cancelCheckOut($repositoryId, $objectId) | |
| 145 | 148 | { |
| 146 | - $documentId = CMISUtil::decodeObjectId($documentId, $typeId); | |
| 149 | + $objectId = CMISUtil::decodeObjectId($objectId, $typeId); | |
| 147 | 150 | |
| 148 | 151 | /* re-generate PWC object */ |
| 149 | 152 | // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository). |
| 150 | 153 | try { |
| 151 | - $pwc = new CMISDocumentObject($documentId, $this->ktapi); | |
| 154 | + $pwc = new CMISDocumentObject($objectId, $this->ktapi); | |
| 152 | 155 | } |
| 153 | 156 | catch (exception $e) { |
| 154 | 157 | throw new UpdateConflictException($e->getMessage()); |
| ... | ... | @@ -159,10 +162,15 @@ class CMISVersioningService { |
| 159 | 162 | throw new ConstraintViolationException('This document is not versionable and may not be checked out'); |
| 160 | 163 | } |
| 161 | 164 | |
| 165 | + // check that this is the latest version | |
| 166 | + if ($pwc->getProperty('isLatestVersion') != true) { | |
| 167 | + throw new VersioningException('The document is not the latest version'); | |
| 168 | + } | |
| 169 | + | |
| 162 | 170 | // TODO delete PWC - since we are not persisting the PWC this is not necessary at the moment |
| 163 | 171 | |
| 164 | 172 | // cancel checkout |
| 165 | - $response = $this->ktapi->undo_document_checkout($documentId, 'CMIS Cancel Checkout Action', $sig_username, $sig_password); | |
| 173 | + $response = $this->ktapi->undo_document_checkout($objectId, 'CMIS Cancel Checkout Action', $sig_username, $sig_password); | |
| 166 | 174 | |
| 167 | 175 | // if there was any error in cancelling the checkout |
| 168 | 176 | if ($response['status_code'] == 1) { |
| ... | ... | @@ -174,28 +182,35 @@ class CMISVersioningService { |
| 174 | 182 | * Checks in a checked out document |
| 175 | 183 | * |
| 176 | 184 | * @param string $repositoryId |
| 177 | - * @param string $documentId | |
| 178 | - * @param boolean $major | |
| 179 | - * @param string $changeToken [optional] | |
| 185 | + * @param string $objectId | |
| 186 | + * @param boolean $major [optional] defaults to true | |
| 180 | 187 | * @param array $properties [optional] |
| 181 | 188 | * @param contentStream $contentStream [optional] |
| 182 | 189 | * @param string $checkinComment [optional] |
| 183 | - * @return string $documentId | |
| 190 | + * @param array $policies | |
| 191 | + * @param array $addACEs | |
| 192 | + * @param array $removeACEs | |
| 193 | + * @return string $objectId | |
| 184 | 194 | */ |
| 185 | - // TODO Exceptions: | |
| 186 | - // • versioningException - The repository MAY throw this exception if the object is a non-current Document Version | |
| 187 | - public function checkIn($repositoryId, $documentId, $major, $contentStream = null, $changeToken = '', $properties = array(), $checkinComment = '') | |
| 195 | + // NOTE For repositories that do NOT support the optional “capabilityPWCUpdatable” capability, the properties | |
| 196 | + // and contentStream input parameters MUST be provided on the checkIn method for updates to happen as part | |
| 197 | + // of checkIn. | |
| 198 | + // NOTE Only those properties whose values are different than the original value of the object need to be submitted. | |
| 199 | + // NOTE we are not actually doing anything with the properties at this time, only the content stream | |
| 200 | + // TODO filename changes and anything else supported in web interface, possibly additional supported by CMIS clients | |
| 201 | + public function checkIn($repositoryId, $objectId, $major = true, $properties = array(), $contentStream = null, | |
| 202 | + $checkinComment = '', $policies = array(), $addACEs = array(), $removeACEs = array()) | |
| 188 | 203 | { |
| 189 | - $documentId = CMISUtil::decodeObjectId($documentId, $typeId); | |
| 190 | - | |
| 204 | + $objectId = CMISUtil::decodeObjectId($objectId, $typeId); | |
| 205 | + | |
| 191 | 206 | // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository). |
| 192 | 207 | try { |
| 193 | - $pwc = new CMISDocumentObject($documentId, $this->ktapi); | |
| 208 | + $pwc = new CMISDocumentObject($objectId, $this->ktapi); | |
| 194 | 209 | } |
| 195 | 210 | catch (exception $e) { |
| 196 | 211 | throw new UpdateConflictException($e->getMessage()); |
| 197 | 212 | } |
| 198 | - | |
| 213 | + | |
| 199 | 214 | // throw exception if the object is not versionable |
| 200 | 215 | if (!$pwc->getAttribute('versionable')) { |
| 201 | 216 | throw new ConstraintViolationException('This document is not versionable and may not be checked in'); |
| ... | ... | @@ -209,11 +224,17 @@ class CMISVersioningService { |
| 209 | 224 | // if we can't get the type definition, then we can't store the content |
| 210 | 225 | throw new StorageException($e->getMessage()); |
| 211 | 226 | } |
| 212 | - | |
| 213 | - if (($typeDefinition['attributes']['contentStreamAllowed'] == 'notAllowed') && !empty($contentStream)) { | |
| 227 | + | |
| 228 | + // if content stream is required (capabilityPWCUpdatability == false) and no content stream is supplied, | |
| 229 | + // throw a ConstraintViolationException | |
| 230 | + if (($typeDefinition['attributes']['contentStreamAllowed'] == 'required') && is_null($contentStream)) { | |
| 231 | + throw new RuntimeException('This repository requires a content stream for document update on checkin. ' | |
| 232 | + . 'Refusing to checkin an empty document'); | |
| 233 | + } | |
| 234 | + else if (($typeDefinition['attributes']['contentStreamAllowed'] == 'notAllowed') && !empty($contentStream)) { | |
| 214 | 235 | throw new StreamNotSupportedException('Content Streams are not supported'); |
| 215 | 236 | } |
| 216 | - | |
| 237 | + | |
| 217 | 238 | // check that this is the latest version |
| 218 | 239 | if ($pwc->getProperty('isLatestVersion') != true) { |
| 219 | 240 | throw new VersioningException('The document is not the latest version and cannot be checked in'); |
| ... | ... | @@ -221,15 +242,16 @@ class CMISVersioningService { |
| 221 | 242 | |
| 222 | 243 | // now do the checkin |
| 223 | 244 | $tempfilename = CMISUtil::createTemporaryFile($contentStream); |
| 224 | - $response = $this->ktapi->checkin_document($documentId, $pwc->getProperty('contentStreamFilename'), $reason, $tempfilename, $major, | |
| 225 | - $sig_username, $sig_password); | |
| 226 | - | |
| 227 | - // if there was any error in cancelling the checkout | |
| 245 | + $reason = 'CMIS object checkin'; | |
| 246 | + $response = $this->ktapi->checkin_document($objectId, $pwc->getProperty('contentStreamFilename'), $reason, $tempfilename, $major, | |
| 247 | + $sig_username, $sig_password); | |
| 248 | + | |
| 249 | + // if there was any error checking in | |
| 228 | 250 | if ($response['status_code'] == 1) { |
| 229 | 251 | throw new RuntimeException('There was an error checking in the document: ' . $response['message']); |
| 230 | 252 | } |
| 231 | 253 | |
| 232 | - return CMISUtil::encodeObjectId(DOCUMENT, $documentId); | |
| 254 | + return CMISUtil::encodeObjectId(DOCUMENT, $objectId); | |
| 233 | 255 | } |
| 234 | 256 | |
| 235 | 257 | } | ... | ... |
webservice/atompub/cmis/KT_cmis_atom_server.services.inc.php
| ... | ... | @@ -34,7 +34,7 @@ When POSTing an Atom Document, the atom fields take precedence over the CMIS pro |
| 34 | 34 | include_once CMIS_ATOM_LIB_FOLDER . 'RepositoryService.inc.php'; |
| 35 | 35 | include_once CMIS_ATOM_LIB_FOLDER . 'NavigationService.inc.php'; |
| 36 | 36 | include_once CMIS_ATOM_LIB_FOLDER . 'ObjectService.inc.php'; |
| 37 | -include_once CMIS_ATOM_LIB_FOLDER . 'VersioningService.inc.php'; | |
| 37 | +include_once CMIS_API . '/ktVersioningService.inc.php'; | |
| 38 | 38 | include_once 'KT_cmis_atom_service_helper.inc.php'; |
| 39 | 39 | |
| 40 | 40 | // TODO consider changing all responses from the webservice layer to return PEAR errors or success results instead of the half/half we have at the moment. |
| ... | ... | @@ -157,6 +157,7 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { |
| 157 | 157 | $objectId = $this->params[2]; |
| 158 | 158 | } |
| 159 | 159 | |
| 160 | + // get object properties - todo send through original properties array and not modified version | |
| 160 | 161 | $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->rawContent); |
| 161 | 162 | $properties = array('name' => $title, 'summary' => $summary, 'objectTypeId' => $cmisObjectProperties['cmis:objectTypeId']); |
| 162 | 163 | |
| ... | ... | @@ -188,7 +189,6 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { |
| 188 | 189 | |
| 189 | 190 | $ObjectService = new ObjectService(KT_cmis_atom_service_helper::getKt()); |
| 190 | 191 | |
| 191 | - global $default; | |
| 192 | 192 | $success = false; |
| 193 | 193 | $error = null; |
| 194 | 194 | if ($action == 'create') |
| ... | ... | @@ -430,7 +430,7 @@ class KT_cmis_atom_service_document extends KT_cmis_atom_service { |
| 430 | 430 | |
| 431 | 431 | $repositoryId = KT_cmis_atom_service_helper::getRepositoryId($RepositoryService); |
| 432 | 432 | |
| 433 | - $VersioningService = new VersioningService(KT_cmis_atom_service_helper::getKt()); | |
| 433 | + $VersioningService = new KTVersioningService(KT_cmis_atom_service_helper::getKt()); | |
| 434 | 434 | |
| 435 | 435 | // attempt delete |
| 436 | 436 | $response = $VersioningService->deleteAllVersions($repositoryId, $this->params[0]); |
| ... | ... | @@ -491,13 +491,12 @@ class KT_cmis_atom_service_pwc extends KT_cmis_atom_service { |
| 491 | 491 | |
| 492 | 492 | $repositoryId = KT_cmis_atom_service_helper::getRepositoryId($RepositoryService); |
| 493 | 493 | |
| 494 | - $VersioningService = new VersioningService(KT_cmis_atom_service_helper::getKt()); | |
| 494 | + $VersioningService = new KTVersioningService(KT_cmis_atom_service_helper::getKt()); | |
| 495 | 495 | |
| 496 | 496 | $response = $VersioningService->cancelCheckout($repositoryId, $this->params[0]); |
| 497 | 497 | |
| 498 | - if (PEAR::isError($response)) | |
| 499 | - { | |
| 500 | - $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, $response->getMessage()); | |
| 498 | + if ($response['status_code'] == 1) { | |
| 499 | + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, $response['message']); | |
| 501 | 500 | // Expose the responseFeed |
| 502 | 501 | $this->responseFeed = $feed; |
| 503 | 502 | return null; |
| ... | ... | @@ -510,45 +509,41 @@ class KT_cmis_atom_service_pwc extends KT_cmis_atom_service { |
| 510 | 509 | public function PUT_action() |
| 511 | 510 | { |
| 512 | 511 | $repositoryId = KT_cmis_atom_service_helper::getRepositoryId($RepositoryService); |
| 513 | - | |
| 514 | - $VersioningService = new VersioningService(KT_cmis_atom_service_helper::getKt()); | |
| 512 | + $VersioningService = new KTVersioningService(KT_cmis_atom_service_helper::getKt()); | |
| 515 | 513 | $ObjectService = new ObjectService(KT_cmis_atom_service_helper::getKt()); |
| 514 | + | |
| 515 | + // get object properties | |
| 516 | + $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->rawContent); | |
| 516 | 517 | |
| 517 | 518 | // check for content stream |
| 518 | - // NOTE this is a hack! will not work with CMISSpaces at least, probably not with any client except RestTest and similar | |
| 519 | - // where we can manually modify the input | |
| 520 | - // first we try for an atom content tag | |
| 521 | - $content = KT_cmis_atom_service_helper::getAtomValues($this->rawContent, 'content'); | |
| 522 | - if (!empty($content)) { | |
| 523 | - $contentStream = $content; | |
| 524 | - } | |
| 525 | - // not found? try for a regular content tag | |
| 526 | - else { | |
| 527 | - $content = KT_cmis_atom_service_helper::findTag('content', $this->parsedXMLContent['@children'], null, false); | |
| 528 | - $contentStream = $content['@value']; | |
| 529 | - } | |
| 530 | - | |
| 531 | - // if we haven't found it now, the real hack begins - retrieve the EXISTING content and submit this as the contentStream | |
| 519 | + $content = KT_cmis_atom_service_helper::getCmisContent($this->rawContent); | |
| 520 | + // NOTE not sure about the text type, will need testing, most content will be base64 | |
| 521 | + $cmisContent = (isset($content['cmisra:base64']) | |
| 522 | + ? $content['cmisra:base64'] | |
| 523 | + : ((isset($content['cmisra:text'])) | |
| 524 | + ? $content['cmisra:text'] | |
| 525 | + : null)); | |
| 526 | + | |
| 527 | + // if we haven't found it now, the hack begins - retrieve the EXISTING content and submit this as the contentStream | |
| 532 | 528 | // this is needed because KnowledgeTree will not accept a checkin without a content stream but CMISSpaces (and possibly |
| 533 | 529 | // other CMIS clients are the same, does not send a content stream on checkin nor does it offer the user a method to choose one) |
| 534 | 530 | // NOTE that if the content is INTENDED to be empty this and all the above checks will FAIL! |
| 535 | 531 | // FIXME this is horrible, terrible, ugly and bad! |
| 536 | - if (empty($contentStream)) { | |
| 537 | - $contentStream = base64_encode(KT_cmis_atom_service_helper::getContentStream($this, $ObjectService, $repositoryId)); | |
| 532 | + if (empty($cmisContent)) { | |
| 533 | + $cmisContent = base64_encode(KT_cmis_atom_service_helper::getContentStream($this, $ObjectService, $repositoryId)); | |
| 538 | 534 | } |
| 539 | 535 | |
| 540 | - // and if we don't have it by now, we give up...but leave the error to be generated by the underlying KnowledgeTree code | |
| 541 | - | |
| 536 | + // and if we don't have the content stream by now, we give up...but leave the error to be generated by the underlying KnowledgeTree code | |
| 542 | 537 | // checkin function call |
| 543 | 538 | // TODO dynamically detect version change type - leaving this for now as the CMIS clients tested do not appear to |
| 544 | 539 | // offer the choice to the user - perhaps it will turn out that this will come from somewhere else but for now |
| 545 | 540 | // we assume minor version updates only |
| 546 | 541 | $major = false; |
| 547 | - $response = $VersioningService->checkIn($repositoryId, $this->params[0], $major, $contentStream); | |
| 548 | - | |
| 549 | - if (PEAR::isError($response)) | |
| 550 | - { | |
| 551 | - $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, $response->getMessage()); | |
| 542 | + $checkinComment = ''; | |
| 543 | + $response = $VersioningService->checkIn($repositoryId, $this->params[0], $major, $cmisObjectProperties, $cmisContent, $checkinComment); | |
| 544 | + | |
| 545 | + if ($response['status_code'] == 1) { | |
| 546 | + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, $response['message']); | |
| 552 | 547 | // Expose the responseFeed |
| 553 | 548 | $this->responseFeed = $feed; |
| 554 | 549 | return null; |
| ... | ... | @@ -630,7 +625,7 @@ class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service { |
| 630 | 625 | { |
| 631 | 626 | $repositoryId = KT_cmis_atom_service_helper::getRepositoryId($RepositoryService); |
| 632 | 627 | |
| 633 | - $VersioningService = new VersioningService(KT_cmis_atom_service_helper::getKt()); | |
| 628 | + $VersioningService = new KTVersioningService(KT_cmis_atom_service_helper::getKt()); | |
| 634 | 629 | $ObjectService = new ObjectService(KT_cmis_atom_service_helper::getKt()); |
| 635 | 630 | |
| 636 | 631 | $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->rawContent); |
| ... | ... | @@ -646,8 +641,7 @@ class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service { |
| 646 | 641 | |
| 647 | 642 | $response = $VersioningService->checkOut($repositoryId, $cmisObjectProperties['cmis:objectId']); |
| 648 | 643 | |
| 649 | - if (PEAR::isError($response)) | |
| 650 | - { | |
| 644 | + if ($response['status_code'] == 1) { | |
| 651 | 645 | $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, 'No object was specified for checkout'); |
| 652 | 646 | // Expose the responseFeed |
| 653 | 647 | $this->responseFeed = $feed; | ... | ... |
webservice/atompub/cmis/index.php
| ... | ... | @@ -49,6 +49,7 @@ define('KT_ATOM_LIB_FOLDER', '../../classes/atompub/'); |
| 49 | 49 | define('CMIS_APP_BASE_URI', trim(KT_APP_BASE_URI, '/')); |
| 50 | 50 | define('CMIS_APP_SYSTEM_URI', KT_APP_SYSTEM_URI); |
| 51 | 51 | define('CMIS_ATOM_LIB_FOLDER', trim(KT_ATOM_LIB_FOLDER, '/') . '/cmis/'); |
| 52 | +define('CMIS_API', KT_LIB_DIR . '/api/ktcmis'); | |
| 52 | 53 | |
| 53 | 54 | /** |
| 54 | 55 | * Check Realm Authentication | ... | ... |
webservice/classes/atompub/cmis/ObjectService.inc.php
| ... | ... | @@ -89,11 +89,12 @@ class ObjectService extends KTObjectService { |
| 89 | 89 | * |
| 90 | 90 | * @param string $repositoryId |
| 91 | 91 | * @param string $objectId |
| 92 | + * @param string $streamId [optional for documents] Specifies the rendition to retrieve if not original document | |
| 92 | 93 | * @return string $contentStream (binary or text data) |
| 93 | 94 | */ |
| 94 | - function getContentStream($repositoryId, $objectId) | |
| 95 | + function getContentStream($repositoryId, $objectId, $streamId = null) | |
| 95 | 96 | { |
| 96 | - $result = parent::getContentStream($repositoryId, $objectId); | |
| 97 | + $result = parent::getContentStream($repositoryId, $objectId, $streamId); | |
| 97 | 98 | |
| 98 | 99 | if ($result['status_code'] == 0) { |
| 99 | 100 | return $result['results']; | ... | ... |
webservice/classes/atompub/cmis/VersioningService.inc.php
| ... | ... | @@ -27,75 +27,6 @@ class VersioningService extends KTVersioningService { |
| 27 | 27 | return new PEAR_Error($result['message']); |
| 28 | 28 | } |
| 29 | 29 | } |
| 30 | - | |
| 31 | - /** | |
| 32 | - * Checks out a document and creates the PWC (Private Working Copy) which will represent the checked out document | |
| 33 | - * | |
| 34 | - * @param string $repositoryId | |
| 35 | - * @param string $documentId | |
| 36 | - * @param string $changeToken [optional] | |
| 37 | - * @return array results | |
| 38 | - */ | |
| 39 | - // TODO set up delivery of content stream? or is that up to the CMIS client? | |
| 40 | - public function checkOut($repositoryId, $documentId, $changeToken = '') | |
| 41 | - { | |
| 42 | - $result = parent::checkOut($repositoryId, $documentId, $changeToken); | |
| 43 | - | |
| 44 | - if ($result['status_code'] == 0) { | |
| 45 | - return $result['results']; | |
| 46 | - } | |
| 47 | - else { | |
| 48 | - return new PEAR_Error($result['message']); | |
| 49 | - } | |
| 50 | - } | |
| 51 | - | |
| 52 | - /** | |
| 53 | - * Reverses the effect of a checkout: I.E. deletes the PWC (Private Working Copy) and re-sets the status of the document to "not checked out" | |
| 54 | - * | |
| 55 | - * @param string $repositoryId | |
| 56 | - * @param string $documentId | |
| 57 | - * @param string $changeToken [optional] | |
| 58 | - */ | |
| 59 | - // TODO exceptions: | |
| 60 | - // • ConstraintViolationException: The Repository SHALL throw this exception if ANY of the following conditions are met: | |
| 61 | - // o The Document’s Object-Type definition’s versionable attribute is FALSE. | |
| 62 | - // • updateConflictException | |
| 63 | - // • versioningException | |
| 64 | - public function cancelCheckOut($repositoryId, $documentId, $changeToken = '') | |
| 65 | - { | |
| 66 | - $result = parent::cancelCheckOut($repositoryId, $documentId, $changeToken); | |
| 67 | - | |
| 68 | - if ($result['status_code'] == 0) { | |
| 69 | - return $result['results']; | |
| 70 | - } | |
| 71 | - else { | |
| 72 | - return new PEAR_Error($result['message']); | |
| 73 | - } | |
| 74 | - } | |
| 75 | - | |
| 76 | - /** | |
| 77 | - * Checks in a checked out document | |
| 78 | - * | |
| 79 | - * @param string $repositoryId | |
| 80 | - * @param string $documentId | |
| 81 | - * @param boolean $major | |
| 82 | - * @param string $changeToken [optional] | |
| 83 | - * @param array $properties [optional] | |
| 84 | - * @param contentStream $contentStream [optional] | |
| 85 | - * @param string $checkinComment [optional] | |
| 86 | - * @return string $documentId | |
| 87 | - */ | |
| 88 | - public function checkIn($repositoryId, $documentId, $major, $contentStream = null, $changeToken = '', $properties = array(), $checkinComment = '') | |
| 89 | - { | |
| 90 | - $result = parent::checkIn($repositoryId, $documentId, $major, $contentStream, $changeToken, $properties, $checkinComment); | |
| 91 | - | |
| 92 | - if ($result['status_code'] == 0) { | |
| 93 | - return $result['results']; | |
| 94 | - } | |
| 95 | - else { | |
| 96 | - return new PEAR_Error($result['message']); | |
| 97 | - } | |
| 98 | - } | |
| 99 | 30 | |
| 100 | 31 | } |
| 101 | 32 | ... | ... |