Commit 8c4b9b73bf5bf8695e93a0e6ad994bed98fe3c03

Authored by Paul Barrett
1 parent e13a2af1

Update checkout, remove reference to no longer existing duplicated exception

Story ID:2295472. Update KT CMIS implementation to 1.0 compliance

Committed by: Paul Barrett
lib/api/ktcmis/ktNavigationService.inc.php
@@ -137,7 +137,7 @@ class KTNavigationService extends KTCMISBase { @@ -137,7 +137,7 @@ class KTNavigationService extends KTCMISBase {
137 { 137 {
138 return array( 138 return array(
139 "status_code" => 1, 139 "status_code" => 1,
140 - "message" => "Failed getting descendants for folder" 140 + "message" => "Failed getting children for folder"
141 ); 141 );
142 } 142 }
143 143
@@ -154,38 +154,32 @@ class KTNavigationService extends KTCMISBase { @@ -154,38 +154,32 @@ class KTNavigationService extends KTCMISBase {
154 * 154 *
155 * @param string $repositoryId 155 * @param string $repositoryId
156 * @param string $folderId 156 * @param string $folderId
157 - * @param boolean $includeAllowableActions  
158 - * @param boolean $includeRelationships  
159 - * @param boolean $returnToRoot  
160 * @param string $filter 157 * @param string $filter
161 - * @return ancestry[] 158 + * @return parent[]
162 */ 159 */
163 - public function getFolderParent($repositoryId, $folderId, $includeAllowableActions, $includeRelationships, $returnToRoot, $filter = '') 160 + public function getFolderParent($repositoryId, $folderId, $filter = '')
164 { 161 {
165 try { 162 try {
166 - $ancestryResult = $this->NavigationService->getFolderParent($repositoryId, $folderId, $includeAllowableActions,  
167 - $includeRelationships, $returnToRoot); 163 + $parent = $this->NavigationService->getFolderParent($repositoryId, $folderId, $filter);
168 } 164 }
169 catch (Exception $e) { 165 catch (Exception $e) {
170 return array( 166 return array(
171 "status_code" => 1, 167 "status_code" => 1,
172 - "message" => "Failed getting ancestry for folder: " . $e->getMessage() 168 + "message" => "Failed getting folder parent: " . $e->getMessage()
173 ); 169 );
174 } 170 }
175 171
176 - if (PEAR::isError($ancestryResult)) 172 + if (PEAR::isError($parent))
177 { 173 {
178 return array( 174 return array(
179 "status_code" => 1, 175 "status_code" => 1,
180 - "message" => "Failed getting ancestry for folder" 176 + "message" => "Failed getting folder parent"
181 ); 177 );
182 } 178 }
183 179
184 - $ancestry = CMISUtil::decodeObjectHierarchy($ancestryResult, 'children');  
185 -  
186 return array( 180 return array(
187 "status_code" => 0, 181 "status_code" => 0,
188 - "results" => $ancestry 182 + "results" => CMISUtil::createObjectPropertiesEntry($parent->getProperties())
189 ); 183 );
190 } 184 }
191 185
@@ -225,18 +219,27 @@ class KTNavigationService extends KTCMISBase { @@ -225,18 +219,27 @@ class KTNavigationService extends KTCMISBase {
225 * 219 *
226 * @param string $repositoryId 220 * @param string $repositoryId
227 * @param string $folderId The folder for which checked out docs are requested 221 * @param string $folderId The folder for which checked out docs are requested
228 - * @param string $filter  
229 - * @param boolean $includeAllowableActions  
230 - * @param boolean $includeRelationships  
231 * @param int $maxItems 222 * @param int $maxItems
232 * @param int $skipCount 223 * @param int $skipCount
233 - * @return array $checkedout The collection of checked out documents 224 + * @param string $filter
  225 + * @param enum $includeRelationships
  226 + * @param boolean $includeAllowableActions
  227 + * @param string $renditionFilter
  228 + * @return array $checkedout The collection of checked out document objects
  229 + * MUST include (unless not requested) for each object:
  230 + * array $properties
  231 + * array $relationships
  232 + * array $renditions
  233 + * $allowableActions
  234 + * @return boolean $hasMoreItems
  235 + * @return int $numItems [optional]
234 */ 236 */
235 - function getCheckedOutDocs($repositoryId, $includeAllowableActions, $includeRelationships, $folderId = null, $filter = '',  
236 - $maxItems = 0, $skipCount = 0) 237 + function getCheckedOutDocs($repositoryId, $folderId = null, $maxItems = 0, $skipCount = 0, $orderBy = '',
  238 + $filter = '', $includeRelationships = null, $includeAllowableActions = false, $renditionFilter = '')
237 { 239 {
238 - $checkedout = $this->NavigationService->getCheckedOutDocs($repositoryId, $includeAllowableActions, $includeRelationships,  
239 - $folderId, $filter, $maxItems, $skipCount); 240 + $checkedout = $this->NavigationService->getCheckedOutDocs($repositoryId, $folderId = null, $maxItems = 0, $skipCount = 0,
  241 + $orderBy, $filter, $includeRelationships, $includeAllowableActions,
  242 + $renditionFilter);
240 243
241 if (PEAR::isError($checkedout)) 244 if (PEAR::isError($checkedout))
242 { 245 {
lib/api/ktcmis/ktService.inc.php
@@ -48,7 +48,6 @@ require_once(realpath(dirname(__FILE__) . '/../../../config/dmsDefaults.php')); @@ -48,7 +48,6 @@ require_once(realpath(dirname(__FILE__) . '/../../../config/dmsDefaults.php'));
48 require_once(KT_DIR . '/ktapi/ktapi.inc.php'); 48 require_once(KT_DIR . '/ktapi/ktapi.inc.php');
49 49
50 define ('CMIS_DIR', KT_LIB_DIR . '/api/ktcmis'); 50 define ('CMIS_DIR', KT_LIB_DIR . '/api/ktcmis');
51 -require_once(CMIS_DIR . '/exceptions/PermissionDeniedException.inc.php');  
52 require_once(CMIS_DIR . '/util/CMISUtil.inc.php'); 51 require_once(CMIS_DIR . '/util/CMISUtil.inc.php');
53 52
54 /** 53 /**
lib/api/ktcmis/services/CMISNavigationService.inc.php
@@ -87,8 +87,8 @@ class CMISNavigationService { @@ -87,8 +87,8 @@ class CMISNavigationService {
87 // Otherwise, the latest version of the documents SHALL be returned. 87 // Otherwise, the latest version of the documents SHALL be returned.
88 // TODO FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid 88 // TODO FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid
89 function getChildren($repositoryId, $folderId, $includeAllowableActions = null, $includeRelationships = null, 89 function getChildren($repositoryId, $folderId, $includeAllowableActions = null, $includeRelationships = null,
90 - $typeId = 'Any', $filter = '', $maxItems = 0, $skipCount = 0, $orderBy = '', $renditionFilter = null,  
91 - $includePathSegment = false) 90 + $typeId = 'Any', $filter = '', $maxItems = 0, $skipCount = 0, $orderBy = '', $renditionFilter = null,
  91 + $includePathSegment = false)
92 { 92 {
93 // TODO paging 93 // TODO paging
94 // TODO optional parameters 94 // TODO optional parameters
@@ -134,13 +134,13 @@ class CMISNavigationService { @@ -134,13 +134,13 @@ class CMISNavigationService {
134 // NOTE If the Repository supports the optional โ€œVersionSpecificFiling๏ฟฝ๏ฟฝ? capability, 134 // NOTE If the Repository supports the optional โ€œVersionSpecificFiling๏ฟฝ๏ฟฝ? capability,
135 // then the repository SHALL return the document versions filed in the specified folder or its descendant folders. 135 // then the repository SHALL return the document versions filed in the specified folder or its descendant folders.
136 // Otherwise, the latest version of the documents SHALL be returned. 136 // Otherwise, the latest version of the documents SHALL be returned.
137 - // NOTE If the Repository supports the optional capability capabilityMutlifiling and the same document is encountered 137 + // NOTE If the Repository supports the optional capability capabilityMutlifiling and the same document is encountered
138 // multiple times in the hierarchy, then the repository MUST return that document each time is encountered. 138 // multiple times in the hierarchy, then the repository MUST return that document each time is encountered.
139 // NOTE The default value for the $depth parameter is repository specific and SHOULD be at least 2 or -1 139 // NOTE The default value for the $depth parameter is repository specific and SHOULD be at least 2 or -1
140 // Chosen 2 as the underlying code currently has no concept of digging all the way down 140 // Chosen 2 as the underlying code currently has no concept of digging all the way down
141 // TODO FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid 141 // TODO FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid
142 - function getDescendants($repositoryId, $folderId, $depth = 2, $filter = '', $includeRelationships = false, $renditionFilter = '',  
143 - $includeAllowableActions = false, $includePathSegment = false) 142 + function getDescendants($repositoryId, $folderId, $depth = 2, $filter = '', $includeRelationships = false, $renditionFilter = '',
  143 + $includeAllowableActions = false, $includePathSegment = false)
144 { 144 {
145 if ($depth == 0) { 145 if ($depth == 0) {
146 throw new InvalidArgumentException('Invalid depth argument supplied'); 146 throw new InvalidArgumentException('Invalid depth argument supplied');
@@ -148,11 +148,11 @@ class CMISNavigationService { @@ -148,11 +148,11 @@ class CMISNavigationService {
148 148
149 // if this is not a folder, cannot get descendants 149 // if this is not a folder, cannot get descendants
150 $folderId = CMISUtil::decodeObjectId($folderId, $type); 150 $folderId = CMISUtil::decodeObjectId($folderId, $type);
151 - 151 +
152 if ($type != 'cmis:folder') { 152 if ($type != 'cmis:folder') {
153 throw new InvalidArgumentException('The supplied object is not a folder, unable to return descendants'); 153 throw new InvalidArgumentException('The supplied object is not a folder, unable to return descendants');
154 } 154 }
155 - 155 +
156 // TODO optional parameters 156 // TODO optional parameters
157 $descendants = array(); 157 $descendants = array();
158 $repository = new CMISRepository($repositoryId); 158 $repository = new CMISRepository($repositoryId);
@@ -171,65 +171,35 @@ class CMISNavigationService { @@ -171,65 +171,35 @@ class CMISNavigationService {
171 * 171 *
172 * @param string $repositoryId 172 * @param string $repositoryId
173 * @param string $folderId 173 * @param string $folderId
174 - * @param boolean $includeAllowableActions  
175 - * @param boolean $includeRelationships  
176 - * @param boolean $returnToRoot If TRUE, then the repository SHALL return all folder objects  
177 - * that are ancestors of the specified folder.  
178 - * If FALSE, the repository SHALL return only the parent folder of the specified folder.  
179 * @param string $filter 174 * @param string $filter
180 - * @return array $ancestry 175 + * @return object $parent The parent folder object
181 */ 176 */
182 // TODO FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid 177 // TODO FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid
183 - // TODO If this service method is invoked on the root folder of the Repository, then the Repository SHALL return an empty result set.  
184 - // NOTE SHOULD always include the โ€œObjectId๏ฟฝ๏ฟฝ? and โ€œParentId๏ฟฝ๏ฟฝ? properties for all objects returned  
185 - function getFolderParent($repositoryId, $folderId, $includeAllowableActions, $includeRelationships, $returnToRoot, $filter = '') 178 + function getFolderParent($repositoryId, $folderId, $filter = '')
186 { 179 {
187 // NOTE the root folder obviously has no parent, throw an ObjectNotFoundException here if this is the root folder 180 // NOTE the root folder obviously has no parent, throw an ObjectNotFoundException here if this is the root folder
188 if (CMISUtil::isRootFolder($repositoryId, $folderId, $this->ktapi)) { 181 if (CMISUtil::isRootFolder($repositoryId, $folderId, $this->ktapi)) {
189 - throw new ObjectNotFoundException('Root folder has no parent'); 182 + throw new InvalidArgumentException('Root folder has no parent');
190 } 183 }
191 -  
192 - $ancestry = array();  
193 - $repository = new CMISRepository($repositoryId); 184 +
  185 + $parent = null;
194 186
195 // if this is not a folder, cannot get folder parent :) 187 // if this is not a folder, cannot get folder parent :)
196 $folderId = CMISUtil::decodeObjectId($folderId, $type); 188 $folderId = CMISUtil::decodeObjectId($folderId, $type);
197 - // NOTE this will quite possibly break the webservices  
198 - if ($type != 'cmis:folder')  
199 - {  
200 - return $ancestry; 189 + // this exception is not indicated in the CMIS Specification, but it just makes sense and so we include it here
  190 + if ($type != 'cmis:folder') {
  191 + throw new InvalidArgumentException('The specified object is not a folder');
201 } 192 }
202 193
203 $ktapiFolder = $this->ktapi->get_folder_by_id($folderId); 194 $ktapiFolder = $this->ktapi->get_folder_by_id($folderId);
204 -  
205 - if ($returnToRoot)  
206 - {  
207 - $folder = $ktapiFolder->get_folder();  
208 - $parents = $folder->generateFolderIDs($folderId);  
209 - // remove the id of the requesting folder and convert to array  
210 - $ancestry = explode(',', str_replace(','.$folderId, '', $parents));  
211 - // reverse to get bottom up listing? don't think so with the current implementation  
212 - // specifying that objectTypes may have children but do not have parents listed.  
213 -// $ancestry = array_reverse($ancestry);  
214 - }  
215 - else  
216 - {  
217 - $parent = $ktapiFolder->get_parent_folder_id();  
218 - $ancestry[] = $parent;  
219 - }  
220 -  
221 - // need some info about the parent(s) in order to correctly create the hierarchy  
222 - $tmpArray = array();  
223 - foreach ($ancestry as $key => $ancestor)  
224 - {  
225 - $tmpArray[$key] = $this->ktapi->get_folder_by_id($ancestor); 195 + if (PEAR::isError($ktapiFolder)) {
  196 + throw new RuntimeException($ktapiFolder->getMessage());
226 } 197 }
227 - $ancestry = $tmpArray;  
228 - unset($tmpArray);  
229 198
230 - $ancestry = CMISUtil::createParentObjectHierarchy($ancestry, $repository->getRepositoryURI, $this->ktapi);  
231 -  
232 - return $ancestry; 199 + $parentId = $ktapiFolder->get_parent_folder_id();
  200 + $parent = new CMISFolderObject(CMISUtil::encodeObjectId($parentId, FOLDER), $this->ktapi);
  201 +
  202 + return $parent;
233 } 203 }
234 204
235 /** 205 /**
@@ -279,18 +249,25 @@ class CMISNavigationService { @@ -279,18 +249,25 @@ class CMISNavigationService {
279 * 249 *
280 * @param string $repositoryId 250 * @param string $repositoryId
281 * @param string $folderId The folder for which checked out docs are requested 251 * @param string $folderId The folder for which checked out docs are requested
282 - * @param string $filter  
283 - * @param boolean $includeAllowableActions  
284 - * @param boolean $includeRelationships  
285 * @param int $maxItems 252 * @param int $maxItems
286 * @param int $skipCount 253 * @param int $skipCount
  254 + * @param string $filter
  255 + * @param enum $includeRelationships
  256 + * @param boolean $includeAllowableActions
  257 + * @param string $renditionFilter
287 * @return array $checkedout The collection of checked out document objects 258 * @return array $checkedout The collection of checked out document objects
  259 + * MUST include (unless not requested) for each object:
  260 + * array $properties
  261 + * array $relationships
  262 + * array $renditions
  263 + * $allowableActions
  264 + * @return boolean $hasMoreItems
  265 + * @return int $numItems [optional]
288 */ 266 */
289 // TODO exceptions: โ€ข FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid. 267 // TODO exceptions: โ€ข FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid.
290 - // TODO filter by folder id  
291 // TODO $filter and paging 268 // TODO $filter and paging
292 - function getCheckedOutDocs($repositoryId, $folderId = null, $filter = '', $includeAllowableActions = false, $includeRelationships = null,  
293 - $maxItems = 0, $skipCount = 0, $orderBy = '') 269 + function getCheckedOutDocs($repositoryId, $folderId = null, $maxItems = 0, $skipCount = 0, $orderBy = '',
  270 + $filter = '', $includeRelationships = null, $includeAllowableActions = false, $renditionFilter = '')
294 { 271 {
295 $checkedout = array(); 272 $checkedout = array();
296 273
lib/api/ktcmis/util/CMISUtil.inc.php
@@ -104,7 +104,7 @@ class CMISUtil { @@ -104,7 +104,7 @@ class CMISUtil {
104 $typeId = 'unknown'; 104 $typeId = 'unknown';
105 return null; 105 return null;
106 } 106 }
107 - 107 +
108 $typeId = null; 108 $typeId = null;
109 109
110 // NOTE Not sure whether this really belongs here, but probably this is the safest and most reliable place 110 // NOTE Not sure whether this really belongs here, but probably this is the safest and most reliable place
@@ -124,6 +124,7 @@ class CMISUtil { @@ -124,6 +124,7 @@ class CMISUtil {
124 // meantime this minor hack will get things working for the existing system structure, as the root 124 // meantime this minor hack will get things working for the existing system structure, as the root
125 // folder should always be id 1. 125 // folder should always be id 1.
126 $typeId = 'cmis:folder'; 126 $typeId = 'cmis:folder';
  127 + $className = 'Folder';
127 return '1'; 128 return '1';
128 } 129 }
129 130
@@ -180,9 +181,9 @@ class CMISUtil { @@ -180,9 +181,9 @@ class CMISUtil {
180 $CMISObject = new CMISFolderObject($object['id'], $ktapi, $repositoryURI); 181 $CMISObject = new CMISFolderObject($object['id'], $ktapi, $repositoryURI);
181 break; 182 break;
182 } 183 }
183 - 184 +
184 $CMISArray[$count]['object'] = $CMISObject; 185 $CMISArray[$count]['object'] = $CMISObject;
185 - 186 +
186 // if sub-array 187 // if sub-array
187 if (count($object['items']) > 0) { 188 if (count($object['items']) > 0) {
188 $CMISArray[$count]['children'] = self::createChildObjectHierarchy($object['items'], $repositoryURI, $ktapi); 189 $CMISArray[$count]['children'] = self::createChildObjectHierarchy($object['items'], $repositoryURI, $ktapi);
@@ -192,7 +193,7 @@ class CMISUtil { @@ -192,7 +193,7 @@ class CMISUtil {
192 { 193 {
193 // NOTE why is this necessary? That's what you get for not commenting it at the time 194 // NOTE why is this necessary? That's what you get for not commenting it at the time
194 // TODO comment this properly, once we know why it is happening 195 // TODO comment this properly, once we know why it is happening
195 -// $CMISArray[$count] = self::createChildObjectHierarchy($object, $repositoryURI, $ktapi); 196 + // $CMISArray[$count] = self::createChildObjectHierarchy($object, $repositoryURI, $ktapi);
196 } 197 }
197 } 198 }
198 } 199 }
@@ -251,14 +252,14 @@ class CMISUtil { @@ -251,14 +252,14 @@ class CMISUtil {
251 static public function decodeObjectHierarchy($input, $linkText = 'children') 252 static public function decodeObjectHierarchy($input, $linkText = 'children')
252 { 253 {
253 $hierarchy = array(); 254 $hierarchy = array();
254 - 255 +
255 // first, run through the base array to get the initial children 256 // first, run through the base array to get the initial children
256 foreach ($input as $key => $entry) 257 foreach ($input as $key => $entry)
257 { 258 {
258 $object = $entry['object']; 259 $object = $entry['object'];
259 $properties = $object->getProperties(); 260 $properties = $object->getProperties();
260 $hierarchy[$key] = self::createObjectPropertiesEntry($properties); 261 $hierarchy[$key] = self::createObjectPropertiesEntry($properties);
261 - 262 +
262 if (isset($entry[$linkText]) && count($entry[$linkText])) { 263 if (isset($entry[$linkText]) && count($entry[$linkText])) {
263 $hierarchy[$key][$linkText] = self::decodeObjectHierarchy($entry[$linkText], $linkText); 264 $hierarchy[$key][$linkText] = self::decodeObjectHierarchy($entry[$linkText], $linkText);
264 } 265 }
@@ -279,7 +280,7 @@ class CMISUtil { @@ -279,7 +280,7 @@ class CMISUtil {
279 static public function createObjectPropertiesEntry($properties) 280 static public function createObjectPropertiesEntry($properties)
280 { 281 {
281 $object = array(); 282 $object = array();
282 - 283 +
283 foreach(CMISPropertyCollection::$propertyTypes as $property => $type) 284 foreach(CMISPropertyCollection::$propertyTypes as $property => $type)
284 { 285 {
285 // hack for Author property 286 // hack for Author property
@@ -316,9 +317,9 @@ class CMISUtil { @@ -316,9 +317,9 @@ class CMISUtil {
316 // clean up ", )" - NOTE this may not be necessary, but is included for safety 317 // clean up ", )" - NOTE this may not be necessary, but is included for safety
317 $stringdata = preg_replace('/, *\r?\n? *\)/', ')', $stringdata); 318 $stringdata = preg_replace('/, *\r?\n? *\)/', ')', $stringdata);
318 319
319 - // NOTE is this while loop even needed?  
320 - while (preg_match('/\b[\w]*::__set_state\(/', $stringdata, $matches))  
321 - { 320 + // NOTE is this while loop even needed, or can we just run a preg_replace without the while?
  321 + // TODO find out...
  322 + while (preg_match('/\b[\w]*::__set_state\(/', $stringdata, $matches)) {
322 $stringdata = preg_replace('/\b[\w]*::__set_state\(/', $matches[1], $stringdata); 323 $stringdata = preg_replace('/\b[\w]*::__set_state\(/', $matches[1], $stringdata);
323 } 324 }
324 325
@@ -342,7 +343,7 @@ class CMISUtil { @@ -342,7 +343,7 @@ class CMISUtil {
342 } 343 }
343 344
344 // TODO more robust base64 encoding detection, if possible 345 // TODO more robust base64 encoding detection, if possible
345 - 346 +
346 /** 347 /**
347 * Checks the contentStream and ensures that it is a correct base64 string; 348 * Checks the contentStream and ensures that it is a correct base64 string;
348 * This is purely for clients such as CMISSpaces breaking the content into 349 * This is purely for clients such as CMISSpaces breaking the content into
@@ -363,23 +364,23 @@ class CMISUtil { @@ -363,23 +364,23 @@ class CMISUtil {
363 { 364 {
364 // always trim content, just in case, as the AtomPub specification says content may be padded with whitespace at the start and end. 365 // always trim content, just in case, as the AtomPub specification says content may be padded with whitespace at the start and end.
365 $contentStream = trim($contentStream); 366 $contentStream = trim($contentStream);
366 - 367 +
367 // check whether the content is encoded first, return as is if not 368 // check whether the content is encoded first, return as is if not
368 // Aโ€“Z, aโ€“z, 0โ€“9, +, / 369 // Aโ€“Z, aโ€“z, 0โ€“9, +, /
369 // NOTE this makes the (fairly reasonable) assumption that text content contains at least one space or punctuation character. 370 // NOTE this makes the (fairly reasonable) assumption that text content contains at least one space or punctuation character.
370 // of course this may fail should something be sent in plain text such as a passwords file containing sha1 or md5 hashes only. 371 // of course this may fail should something be sent in plain text such as a passwords file containing sha1 or md5 hashes only.
371 if (preg_match('/[^\w\/\+=\n]+/', $content)) return $contentStream; 372 if (preg_match('/[^\w\/\+=\n]+/', $content)) return $contentStream;
372 - 373 +
373 $decoded = ''; 374 $decoded = '';
374 - 375 +
375 // split the content stream on ={1,2} 376 // split the content stream on ={1,2}
376 $parts = preg_split('/(={1,2})/', $contentStream, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); 377 $parts = preg_split('/(={1,2})/', $contentStream, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
377 foreach($parts as $part) 378 foreach($parts as $part)
378 - { 379 + {
379 if (preg_match('/={1,2}/', $part)) { 380 if (preg_match('/={1,2}/', $part)) {
380 continue; 381 continue;
381 } 382 }
382 - 383 +
383 // lookahead for delimiter, because we may need it back. 384 // lookahead for delimiter, because we may need it back.
384 // NOTE that decoding appears to work fine without this, so this is just an "in case". 385 // NOTE that decoding appears to work fine without this, so this is just an "in case".
385 // NOTE that even with this it seems the present function works faster than the alternative below. 386 // NOTE that even with this it seems the present function works faster than the alternative below.
@@ -388,14 +389,14 @@ class CMISUtil { @@ -388,14 +389,14 @@ class CMISUtil {
388 $part .= $parts[$key+1]; 389 $part .= $parts[$key+1];
389 } 390 }
390 } 391 }
391 - 392 +
392 // decode, append to output 393 // decode, append to output
393 $decoded .= base64_decode($part); 394 $decoded .= base64_decode($part);
394 } 395 }
395 396
396 return $decoded; 397 return $decoded;
397 } 398 }
398 - 399 +
399 /** 400 /**
400 * Checks the contentStream and ensures that it is a correct base64 string; 401 * Checks the contentStream and ensures that it is a correct base64 string;
401 * This is purely for clients such as CMISSpaces breaking the content into 402 * This is purely for clients such as CMISSpaces breaking the content into
@@ -405,7 +406,7 @@ class CMISUtil { @@ -405,7 +406,7 @@ class CMISUtil {
405 * If it is not chunked it is decoded as is and sent back as a single stream. 406 * If it is not chunked it is decoded as is and sent back as a single stream.
406 * 407 *
407 * NOTE this function and the above need to be checked for efficiency. 408 * NOTE this function and the above need to be checked for efficiency.
408 - * The current one appears to be miles better (1/0/3 vs 14/4/57 on respective test files) 409 + * The other one appears to be miles better (1/0/3 vs 14/4/57 on respective test files)
409 * 410 *
410 * @param object $contentStream 411 * @param object $contentStream
411 * @return string decoded 412 * @return string decoded
@@ -414,13 +415,13 @@ class CMISUtil { @@ -414,13 +415,13 @@ class CMISUtil {
414 { 415 {
415 // always trim content, just in case, as the AtomPub specification says content may be padded with whitespace at the start and end. 416 // always trim content, just in case, as the AtomPub specification says content may be padded with whitespace at the start and end.
416 $contentStream = trim($contentStream); 417 $contentStream = trim($contentStream);
417 - 418 +
418 // check whether the content is encoded first, return as is if not 419 // check whether the content is encoded first, return as is if not
419 // Aโ€“Z, aโ€“z, 0โ€“9, +, / 420 // Aโ€“Z, aโ€“z, 0โ€“9, +, /
420 // NOTE this makes the (fairly reasonable) assumption that text content contains at least one space or punctuation character. 421 // NOTE this makes the (fairly reasonable) assumption that text content contains at least one space or punctuation character.
421 // of course this may fail should something be sent in plain text such as a passwords file containing sha1 or md5 hashes only. 422 // of course this may fail should something be sent in plain text such as a passwords file containing sha1 or md5 hashes only.
422 if (preg_match('/[^\w\/\+=\n]+/', $content)) return $contentStream; 423 if (preg_match('/[^\w\/\+=\n]+/', $content)) return $contentStream;
423 - 424 +
424 // check the content stream for any lines of unusual length (except the last line, which can be any length) 425 // check the content stream for any lines of unusual length (except the last line, which can be any length)
425 $count = -1; 426 $count = -1;
426 $length = 0; 427 $length = 0;
@@ -435,11 +436,11 @@ class CMISUtil { @@ -435,11 +436,11 @@ class CMISUtil {
435 foreach ($splitStream as $line) 436 foreach ($splitStream as $line)
436 { 437 {
437 $curlen = strlen($line); 438 $curlen = strlen($line);
438 - 439 +
439 if ($length == 0) { 440 if ($length == 0) {
440 $length = $curlen; 441 $length = $curlen;
441 } 442 }
442 - 443 +
443 // if we find one we know that we must split the line here and end the previous base64 string 444 // if we find one we know that we must split the line here and end the previous base64 string
444 if ($curlen > $length) 445 if ($curlen > $length)
445 { 446 {
@@ -457,7 +458,7 @@ class CMISUtil { @@ -457,7 +458,7 @@ class CMISUtil {
457 } 458 }
458 459
459 $decode[++$count] = $b64String . $lastChunk; 460 $decode[++$count] = $b64String . $lastChunk;
460 - 461 +
461 $b64String = $nextChunk . "\n"; 462 $b64String = $nextChunk . "\n";
462 $length = strlen($nextChunk); 463 $length = strlen($nextChunk);
463 464
@@ -488,7 +489,7 @@ class CMISUtil { @@ -488,7 +489,7 @@ class CMISUtil {
488 489
489 return $decoded; 490 return $decoded;
490 } 491 }
491 - 492 +
492 /** 493 /**
493 * Function to check whether a specified object exists within the KnowledgeTree system 494 * Function to check whether a specified object exists within the KnowledgeTree system
494 * 495 *
@@ -518,10 +519,10 @@ class CMISUtil { @@ -518,10 +519,10 @@ class CMISUtil {
518 else { 519 else {
519 $exists = false; 520 $exists = false;
520 } 521 }
521 - 522 +
522 return $exists; 523 return $exists;
523 } 524 }
524 - 525 +
525 /** 526 /**
526 * Creates a temporary file 527 * Creates a temporary file
527 * Cleanup is the responsibility of the calling code 528 * Cleanup is the responsibility of the calling code
@@ -533,22 +534,22 @@ class CMISUtil { @@ -533,22 +534,22 @@ class CMISUtil {
533 { 534 {
534 // if contentStream is empty, cannot create file 535 // if contentStream is empty, cannot create file
535 if (empty($contentStream)) return null; 536 if (empty($contentStream)) return null;
536 - 537 +
537 // TODO consider checking whether content is encoded (currently we expect encoded) 538 // TODO consider checking whether content is encoded (currently we expect encoded)
538 // TODO choose between this and the alternative decode function (see CMISUtil class) 539 // TODO choose between this and the alternative decode function (see CMISUtil class)
539 // this will require some basic benchmarking 540 // this will require some basic benchmarking
540 $contentStream = self::decodeChunkedContentStream($contentStream); 541 $contentStream = self::decodeChunkedContentStream($contentStream);
541 - 542 +
542 // NOTE There is a function in CMISUtil to do this, written for the unit tests but since KTUploadManager exists 543 // NOTE There is a function in CMISUtil to do this, written for the unit tests but since KTUploadManager exists
543 // and has more functionality which could come in useful at some point I decided to go with that instead 544 // and has more functionality which could come in useful at some point I decided to go with that instead
544 // (did not know this existed when I wrote the CMISUtil function) 545 // (did not know this existed when I wrote the CMISUtil function)
545 $uploadManager = new KTUploadManager(); 546 $uploadManager = new KTUploadManager();
546 // assumes already decoded from base64, should use store_base64_file if not 547 // assumes already decoded from base64, should use store_base64_file if not
547 $tempfilename = $uploadManager->store_file($contentStream, 'cmis_'); 548 $tempfilename = $uploadManager->store_file($contentStream, 'cmis_');
548 - 549 +
549 return $tempfilename; 550 return $tempfilename;
550 } 551 }
551 - 552 +
552 /** 553 /**
553 * attempts to fetch the folder id from a name 554 * attempts to fetch the folder id from a name
554 * 555 *
@@ -562,10 +563,10 @@ class CMISUtil { @@ -562,10 +563,10 @@ class CMISUtil {
562 static public function getIdFromName($name, &$ktapi) 563 static public function getIdFromName($name, &$ktapi)
563 { 564 {
564 $folder = $ktapi->get_folder_by_name($name); 565 $folder = $ktapi->get_folder_by_name($name);
565 - 566 +
566 return self::encodeObjectId(FOLDER, $folder->get_folderid()); 567 return self::encodeObjectId(FOLDER, $folder->get_folderid());
567 } 568 }
568 - 569 +
569 /** 570 /**
570 * Checks for the root folder 571 * Checks for the root folder
571 * 572 *
@@ -578,12 +579,12 @@ class CMISUtil { @@ -578,12 +579,12 @@ class CMISUtil {
578 { 579 {
579 $repository = new CMISRepository($repositoryId); 580 $repository = new CMISRepository($repositoryId);
580 $repositoryInfo = $repository->getRepositoryInfo(); 581 $repositoryInfo = $repository->getRepositoryInfo();
581 - 582 +
582 // NOTE this call is required to accomodate the definition of the root folder id in the config as required by the drupal module 583 // NOTE this call is required to accomodate the definition of the root folder id in the config as required by the drupal module
583 // we should try to update the drupal module to not require this, but this way is just easier at the moment, and most of 584 // we should try to update the drupal module to not require this, but this way is just easier at the moment, and most of
584 // the code accomodates it without any serious hacks 585 // the code accomodates it without any serious hacks
585 $rootFolder = self::getIdFromName($repositoryInfo->getRootFolderId(), $ktapi); 586 $rootFolder = self::getIdFromName($repositoryInfo->getRootFolderId(), $ktapi);
586 - 587 +
587 return $folderId == $rootFolder; 588 return $folderId == $rootFolder;
588 } 589 }
589 590