Commit dac083c191f2b67c359cbaa455dbfdb087283af3

Authored by Jarrett Jordaan
2 parents ea695d97 2aaa0bf9

Merge branch 'edge' of git@github.com:ktgit/knowledgetree into edge

lib/api/ktcmis/ktObjectService.inc.php
@@ -181,12 +181,13 @@ class KTObjectService extends KTCMISBase { @@ -181,12 +181,13 @@ class KTObjectService extends KTCMISBase {
181 * 181 *
182 * @param string $repositoryId 182 * @param string $repositoryId
183 * @param string $objectId 183 * @param string $objectId
  184 + * @param string $streamId [optional for documents] Specifies the rendition to retrieve if not original document
184 * @return string $contentStream (binary or text data) 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 try { 189 try {
189 - $contentStream = $this->ObjectService->getContentStream($repositoryId, $objectId); 190 + $contentStream = $this->ObjectService->getContentStream($repositoryId, $objectId, $streamId);
190 } 191 }
191 catch (Exception $e) 192 catch (Exception $e)
192 { 193 {
lib/api/ktcmis/ktVersioningService.inc.php
@@ -110,15 +110,14 @@ class KTVersioningService extends KTCMISBase { @@ -110,15 +110,14 @@ class KTVersioningService extends KTCMISBase {
110 * Checks out a document and creates the PWC (Private Working Copy) which will represent the checked out document 110 * Checks out a document and creates the PWC (Private Working Copy) which will represent the checked out document
111 * 111 *
112 * @param string $repositoryId 112 * @param string $repositoryId
113 - * @param string $documentId  
114 - * @param string $changeToken [optional] 113 + * @param string $objectId
115 * @return array results 114 * @return array results
116 */ 115 */
117 // TODO set up delivery of content stream? or is that up to the CMIS client? 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 try { 119 try {
121 - $result = $this->VersioningService->checkOut($repositoryId, $documentId, $changeToken); 120 + $result = $this->VersioningService->checkOut($repositoryId, $objectId);
122 } 121 }
123 catch (Exception $e) 122 catch (Exception $e)
124 { 123 {
@@ -138,18 +137,17 @@ class KTVersioningService extends KTCMISBase { @@ -138,18 +137,17 @@ class KTVersioningService extends KTCMISBase {
138 * 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 * 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 * @param string $repositoryId 139 * @param string $repositoryId
141 - * @param string $documentId  
142 - * @param string $changeToken [optional] 140 + * @param string $objectId
143 */ 141 */
144 // TODO exceptions: 142 // TODO exceptions:
145 // • ConstraintViolationException: The Repository SHALL throw this exception if ANY of the following conditions are met: 143 // • ConstraintViolationException: The Repository SHALL throw this exception if ANY of the following conditions are met:
146 // o The Document’s Object-Type definition’s versionable attribute is FALSE. 144 // o The Document’s Object-Type definition’s versionable attribute is FALSE.
147 // • updateConflictException 145 // • updateConflictException
148 // • versioningException 146 // • versioningException
149 - public function cancelCheckOut($repositoryId, $documentId, $changeToken = '') 147 + public function cancelCheckOut($repositoryId, $objectId)
150 { 148 {
151 try { 149 try {
152 - $result = $this->VersioningService->cancelCheckOut($repositoryId, $documentId, $changeToken); 150 + $result = $this->VersioningService->cancelCheckOut($repositoryId, $objectId);
153 } 151 }
154 catch (Exception $e) 152 catch (Exception $e)
155 { 153 {
@@ -169,18 +167,22 @@ class KTVersioningService extends KTCMISBase { @@ -169,18 +167,22 @@ class KTVersioningService extends KTCMISBase {
169 * Checks in a checked out document 167 * Checks in a checked out document
170 * 168 *
171 * @param string $repositoryId 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 * @param array $properties [optional] 172 * @param array $properties [optional]
176 * @param contentStream $contentStream [optional] 173 * @param contentStream $contentStream [optional]
177 * @param string $checkinComment [optional] 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 try { 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 catch (Exception $e) 187 catch (Exception $e)
186 { 188 {
lib/api/ktcmis/services/CMISObjectService.inc.php
@@ -401,16 +401,16 @@ class CMISObjectService { @@ -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 * @param string $repositoryId 406 * @param string $repositoryId
407 * @param string $objectId 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 $contentStream = null; 415 $contentStream = null;
416 416
@@ -426,13 +426,11 @@ class CMISObjectService { @@ -426,13 +426,11 @@ class CMISObjectService {
426 $objectClass = 'CMIS' . $typeId . 'Object'; 426 $objectClass = 'CMIS' . $typeId . 'Object';
427 $CMISObject = new $objectClass($objectId, $this->ktapi); 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 if (($CMISObject->getAttribute('contentStreamAllowed') == 'notAllowed')) 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 // now go on to fetching the content stream 436 // now go on to fetching the content stream
lib/api/ktcmis/services/CMISVersioningService.inc.php
@@ -71,54 +71,58 @@ class CMISVersioningService { @@ -71,54 +71,58 @@ class CMISVersioningService {
71 * Checks out a document and creates the PWC (Private Working Copy) which will represent the checked out document 71 * Checks out a document and creates the PWC (Private Working Copy) which will represent the checked out document
72 * 72 *
73 * @param string $repositoryId 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 * @return boolean $contentCopied TRUE if contentStream is a copy of the document content stream, FALSE if contentStream not set 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 // NOTE since we need to return two values, we return one via argument by reference 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 // TODO set up delivery of content stream? or is that up to the CMIS client? 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 $contentCopied = false; 83 $contentCopied = false;
87 -  
88 - $documentId = CMISUtil::decodeObjectId($documentId, $typeId); 84 +
  85 + $objectId = CMISUtil::decodeObjectId($objectId, $typeId);
89 86
90 // 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 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 // TODO consider persisting in the database? How will this relate to JSR if we are switching to that? 88 // TODO consider persisting in the database? How will this relate to JSR if we are switching to that?
92 // 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 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 // TODO see if there is an easy way to modify this, else we may not have an easy way to persist PWC objects 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 // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository). 92 // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository).
96 try { 93 try {
97 - $pwc = new CMISDocumentObject($documentId, $this->ktapi); 94 + $pwc = new CMISDocumentObject($objectId, $this->ktapi);
98 } 95 }
99 catch (exception $e) { 96 catch (exception $e) {
100 throw new UpdateConflictException($e->getMessage()); 97 throw new UpdateConflictException($e->getMessage());
101 } 98 }
102 - 99 +
103 // throw exception if the object is not versionable 100 // throw exception if the object is not versionable
104 if (!$pwc->getAttribute('versionable')) { 101 if (!$pwc->getAttribute('versionable')) {
105 throw new ConstraintViolationException('This document is not versionable and may not be checked out'); 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 // NOTE KTAPI as currently implemented does not give a direct response which indicates if the document is already checked out, 110 // NOTE KTAPI as currently implemented does not give a direct response which indicates if the document is already checked out,
109 // as long as the same user is calling the checkout again, so should we add a check here specifically? 111 // as long as the same user is calling the checkout again, so should we add a check here specifically?
110 112
111 // run checkout process - set $download = false (third function argument) as we want to return the document content via the contentStream 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 // if there was an error, throw an exception 115 // if there was an error, throw an exception
114 if ($response['status_code'] == 1) { 116 if ($response['status_code'] == 1) {
115 throw new StorageException($response['message']); 117 throw new StorageException($response['message']);
116 - };  
117 - 118 + }
  119 +
118 // if successful, set $contentCopied = true; unless contentStream is not set 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 // mark document object as checked out 126 // mark document object as checked out
123 $pwc->setProperty('isVersionSeriesCheckedOut', true); 127 $pwc->setProperty('isVersionSeriesCheckedOut', true);
124 $userName = ''; 128 $userName = '';
@@ -127,8 +131,8 @@ class CMISVersioningService { @@ -127,8 +131,8 @@ class CMISVersioningService {
127 $userName = $user->getName(); 131 $userName = $user->getName();
128 } 132 }
129 $pwc->setProperty('versionSeriesCheckedOutBy', $userName); 133 $pwc->setProperty('versionSeriesCheckedOutBy', $userName);
130 - $pwc->setProperty('versionSeriesCheckedOutId', $documentId);  
131 - 134 + $pwc->setProperty('versionSeriesCheckedOutId', $objectId);
  135 +
132 return $contentCopied; 136 return $contentCopied;
133 } 137 }
134 138
@@ -136,19 +140,18 @@ class CMISVersioningService { @@ -136,19 +140,18 @@ class CMISVersioningService {
136 * 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" 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 * @param string $repositoryId 142 * @param string $repositoryId
139 - * @param string $documentId  
140 - * @param string $changeToken [optional] 143 + * @param string $objectId
141 */ 144 */
142 // TODO exceptions: 145 // TODO exceptions:
143 // • versioningException - The repository MAY throw this exception if the object is a non-current Document Version. 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 /* re-generate PWC object */ 151 /* re-generate PWC object */
149 // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository). 152 // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository).
150 try { 153 try {
151 - $pwc = new CMISDocumentObject($documentId, $this->ktapi); 154 + $pwc = new CMISDocumentObject($objectId, $this->ktapi);
152 } 155 }
153 catch (exception $e) { 156 catch (exception $e) {
154 throw new UpdateConflictException($e->getMessage()); 157 throw new UpdateConflictException($e->getMessage());
@@ -159,10 +162,15 @@ class CMISVersioningService { @@ -159,10 +162,15 @@ class CMISVersioningService {
159 throw new ConstraintViolationException('This document is not versionable and may not be checked out'); 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 // TODO delete PWC - since we are not persisting the PWC this is not necessary at the moment 170 // TODO delete PWC - since we are not persisting the PWC this is not necessary at the moment
163 171
164 // cancel checkout 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 // if there was any error in cancelling the checkout 175 // if there was any error in cancelling the checkout
168 if ($response['status_code'] == 1) { 176 if ($response['status_code'] == 1) {
@@ -174,28 +182,35 @@ class CMISVersioningService { @@ -174,28 +182,35 @@ class CMISVersioningService {
174 * Checks in a checked out document 182 * Checks in a checked out document
175 * 183 *
176 * @param string $repositoryId 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 * @param array $properties [optional] 187 * @param array $properties [optional]
181 * @param contentStream $contentStream [optional] 188 * @param contentStream $contentStream [optional]
182 * @param string $checkinComment [optional] 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 // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository). 206 // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository).
192 try { 207 try {
193 - $pwc = new CMISDocumentObject($documentId, $this->ktapi); 208 + $pwc = new CMISDocumentObject($objectId, $this->ktapi);
194 } 209 }
195 catch (exception $e) { 210 catch (exception $e) {
196 throw new UpdateConflictException($e->getMessage()); 211 throw new UpdateConflictException($e->getMessage());
197 } 212 }
198 - 213 +
199 // throw exception if the object is not versionable 214 // throw exception if the object is not versionable
200 if (!$pwc->getAttribute('versionable')) { 215 if (!$pwc->getAttribute('versionable')) {
201 throw new ConstraintViolationException('This document is not versionable and may not be checked in'); 216 throw new ConstraintViolationException('This document is not versionable and may not be checked in');
@@ -209,11 +224,17 @@ class CMISVersioningService { @@ -209,11 +224,17 @@ class CMISVersioningService {
209 // if we can't get the type definition, then we can't store the content 224 // if we can't get the type definition, then we can't store the content
210 throw new StorageException($e->getMessage()); 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 throw new StreamNotSupportedException('Content Streams are not supported'); 235 throw new StreamNotSupportedException('Content Streams are not supported');
215 } 236 }
216 - 237 +
217 // check that this is the latest version 238 // check that this is the latest version
218 if ($pwc->getProperty('isLatestVersion') != true) { 239 if ($pwc->getProperty('isLatestVersion') != true) {
219 throw new VersioningException('The document is not the latest version and cannot be checked in'); 240 throw new VersioningException('The document is not the latest version and cannot be checked in');
@@ -221,15 +242,16 @@ class CMISVersioningService { @@ -221,15 +242,16 @@ class CMISVersioningService {
221 242
222 // now do the checkin 243 // now do the checkin
223 $tempfilename = CMISUtil::createTemporaryFile($contentStream); 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 if ($response['status_code'] == 1) { 250 if ($response['status_code'] == 1) {
229 throw new RuntimeException('There was an error checking in the document: ' . $response['message']); 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,7 +34,7 @@ When POSTing an Atom Document, the atom fields take precedence over the CMIS pro
34 include_once CMIS_ATOM_LIB_FOLDER . 'RepositoryService.inc.php'; 34 include_once CMIS_ATOM_LIB_FOLDER . 'RepositoryService.inc.php';
35 include_once CMIS_ATOM_LIB_FOLDER . 'NavigationService.inc.php'; 35 include_once CMIS_ATOM_LIB_FOLDER . 'NavigationService.inc.php';
36 include_once CMIS_ATOM_LIB_FOLDER . 'ObjectService.inc.php'; 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 include_once 'KT_cmis_atom_service_helper.inc.php'; 38 include_once 'KT_cmis_atom_service_helper.inc.php';
39 39
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. 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,6 +157,7 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service {
157 $objectId = $this->params[2]; 157 $objectId = $this->params[2];
158 } 158 }
159 159
  160 + // get object properties - todo send through original properties array and not modified version
160 $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->rawContent); 161 $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->rawContent);
161 $properties = array('name' => $title, 'summary' => $summary, 'objectTypeId' => $cmisObjectProperties['cmis:objectTypeId']); 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,7 +189,6 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service {
188 189
189 $ObjectService = new ObjectService(KT_cmis_atom_service_helper::getKt()); 190 $ObjectService = new ObjectService(KT_cmis_atom_service_helper::getKt());
190 191
191 - global $default;  
192 $success = false; 192 $success = false;
193 $error = null; 193 $error = null;
194 if ($action == 'create') 194 if ($action == 'create')
@@ -430,7 +430,7 @@ class KT_cmis_atom_service_document extends KT_cmis_atom_service { @@ -430,7 +430,7 @@ class KT_cmis_atom_service_document extends KT_cmis_atom_service {
430 430
431 $repositoryId = KT_cmis_atom_service_helper::getRepositoryId($RepositoryService); 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 // attempt delete 435 // attempt delete
436 $response = $VersioningService->deleteAllVersions($repositoryId, $this->params[0]); 436 $response = $VersioningService->deleteAllVersions($repositoryId, $this->params[0]);
@@ -491,13 +491,12 @@ class KT_cmis_atom_service_pwc extends KT_cmis_atom_service { @@ -491,13 +491,12 @@ class KT_cmis_atom_service_pwc extends KT_cmis_atom_service {
491 491
492 $repositoryId = KT_cmis_atom_service_helper::getRepositoryId($RepositoryService); 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 $response = $VersioningService->cancelCheckout($repositoryId, $this->params[0]); 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 // Expose the responseFeed 500 // Expose the responseFeed
502 $this->responseFeed = $feed; 501 $this->responseFeed = $feed;
503 return null; 502 return null;
@@ -510,45 +509,41 @@ class KT_cmis_atom_service_pwc extends KT_cmis_atom_service { @@ -510,45 +509,41 @@ class KT_cmis_atom_service_pwc extends KT_cmis_atom_service {
510 public function PUT_action() 509 public function PUT_action()
511 { 510 {
512 $repositoryId = KT_cmis_atom_service_helper::getRepositoryId($RepositoryService); 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 $ObjectService = new ObjectService(KT_cmis_atom_service_helper::getKt()); 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 // check for content stream 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 // this is needed because KnowledgeTree will not accept a checkin without a content stream but CMISSpaces (and possibly 528 // this is needed because KnowledgeTree will not accept a checkin without a content stream but CMISSpaces (and possibly
533 // 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) 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 // NOTE that if the content is INTENDED to be empty this and all the above checks will FAIL! 530 // NOTE that if the content is INTENDED to be empty this and all the above checks will FAIL!
535 // FIXME this is horrible, terrible, ugly and bad! 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 // checkin function call 537 // checkin function call
543 // TODO dynamically detect version change type - leaving this for now as the CMIS clients tested do not appear to 538 // TODO dynamically detect version change type - leaving this for now as the CMIS clients tested do not appear to
544 // offer the choice to the user - perhaps it will turn out that this will come from somewhere else but for now 539 // offer the choice to the user - perhaps it will turn out that this will come from somewhere else but for now
545 // we assume minor version updates only 540 // we assume minor version updates only
546 $major = false; 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 // Expose the responseFeed 547 // Expose the responseFeed
553 $this->responseFeed = $feed; 548 $this->responseFeed = $feed;
554 return null; 549 return null;
@@ -630,7 +625,7 @@ class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service { @@ -630,7 +625,7 @@ class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service {
630 { 625 {
631 $repositoryId = KT_cmis_atom_service_helper::getRepositoryId($RepositoryService); 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 $ObjectService = new ObjectService(KT_cmis_atom_service_helper::getKt()); 629 $ObjectService = new ObjectService(KT_cmis_atom_service_helper::getKt());
635 630
636 $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->rawContent); 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,8 +641,7 @@ class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service {
646 641
647 $response = $VersioningService->checkOut($repositoryId, $cmisObjectProperties['cmis:objectId']); 642 $response = $VersioningService->checkOut($repositoryId, $cmisObjectProperties['cmis:objectId']);
648 643
649 - if (PEAR::isError($response))  
650 - { 644 + if ($response['status_code'] == 1) {
651 $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, 'No object was specified for checkout'); 645 $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, 'No object was specified for checkout');
652 // Expose the responseFeed 646 // Expose the responseFeed
653 $this->responseFeed = $feed; 647 $this->responseFeed = $feed;
webservice/atompub/cmis/index.php
@@ -49,6 +49,7 @@ define('KT_ATOM_LIB_FOLDER', '../../classes/atompub/'); @@ -49,6 +49,7 @@ define('KT_ATOM_LIB_FOLDER', '../../classes/atompub/');
49 define('CMIS_APP_BASE_URI', trim(KT_APP_BASE_URI, '/')); 49 define('CMIS_APP_BASE_URI', trim(KT_APP_BASE_URI, '/'));
50 define('CMIS_APP_SYSTEM_URI', KT_APP_SYSTEM_URI); 50 define('CMIS_APP_SYSTEM_URI', KT_APP_SYSTEM_URI);
51 define('CMIS_ATOM_LIB_FOLDER', trim(KT_ATOM_LIB_FOLDER, '/') . '/cmis/'); 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 * Check Realm Authentication 55 * Check Realm Authentication
webservice/classes/atompub/cmis/ObjectService.inc.php
@@ -89,11 +89,12 @@ class ObjectService extends KTObjectService { @@ -89,11 +89,12 @@ class ObjectService extends KTObjectService {
89 * 89 *
90 * @param string $repositoryId 90 * @param string $repositoryId
91 * @param string $objectId 91 * @param string $objectId
  92 + * @param string $streamId [optional for documents] Specifies the rendition to retrieve if not original document
92 * @return string $contentStream (binary or text data) 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 if ($result['status_code'] == 0) { 99 if ($result['status_code'] == 0) {
99 return $result['results']; 100 return $result['results'];
webservice/classes/atompub/cmis/VersioningService.inc.php
@@ -27,75 +27,6 @@ class VersioningService extends KTVersioningService { @@ -27,75 +27,6 @@ class VersioningService extends KTVersioningService {
27 return new PEAR_Error($result['message']); 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