Commit 8c4b9b73bf5bf8695e93a0e6ad994bed98fe3c03
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
Showing
4 changed files
with
95 additions
and
115 deletions
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 |