Commit fa2ad31d741d9a2e350c1d7e9d158502201a5da9
1 parent
7ad57dc9
Changes to cmis object definitions
Story ID:2295472. Update KT CMIS implementation to 1.0 compliance Committed by: Paul Barrett
Showing
9 changed files
with
81 additions
and
47 deletions
lib/api/ktcmis/classes/CMISObject.inc.php
lib/api/ktcmis/classes/CMISPropertyCollection.inc.php
| ... | ... | @@ -61,7 +61,7 @@ abstract class CMISPropertyCollection { |
| 61 | 61 | // TODO these definitions belong in their own classe definition (see property type definions,) but here will do for now |
| 62 | 62 | static public $propertyTypes; |
| 63 | 63 | |
| 64 | - function __construct() | |
| 64 | + public function __construct() | |
| 65 | 65 | { |
| 66 | 66 | self::$propertyTypes = array('objectId' => 'propertyId', |
| 67 | 67 | 'author' => 'propertyString', |
| ... | ... | @@ -83,7 +83,7 @@ abstract class CMISPropertyCollection { |
| 83 | 83 | /** |
| 84 | 84 | * Gets the property value. |
| 85 | 85 | */ |
| 86 | - function getValue($field) | |
| 86 | + public function getValue($field) | |
| 87 | 87 | { |
| 88 | 88 | return $this->{$field}; |
| 89 | 89 | } |
| ... | ... | @@ -92,12 +92,12 @@ abstract class CMISPropertyCollection { |
| 92 | 92 | * Sets the property value. |
| 93 | 93 | */ |
| 94 | 94 | // for connection-tied live objects |
| 95 | - function setValue($field, $value) | |
| 95 | + public function setValue($field, $value) | |
| 96 | 96 | { |
| 97 | 97 | $this->{$field} = $value; |
| 98 | 98 | } |
| 99 | 99 | |
| 100 | - function getFieldType($field) | |
| 100 | + public function getFieldType($field) | |
| 101 | 101 | { |
| 102 | 102 | return $this->propertyTypes[$field]; |
| 103 | 103 | } | ... | ... |
lib/api/ktcmis/ktObjectService.inc.php
| ... | ... | @@ -113,22 +113,24 @@ class KTObjectService extends KTCMISBase { |
| 113 | 113 | * Creates a new document within the repository |
| 114 | 114 | * |
| 115 | 115 | * @param string $repositoryId The repository to which the document must be added |
| 116 | - * @param string $typeId Object Type id for the document object being created | |
| 117 | 116 | * @param array $properties Array of properties which must be applied to the created document object |
| 118 | 117 | * @param string $folderId The id of the folder which will be the parent of the created document object |
| 119 | 118 | * This parameter is optional IF unfilingCapability is supported |
| 120 | - * @param contentStream $contentStream optional content stream data | |
| 121 | - * @param string $versioningState optional version state value: checkedout/major/minor | |
| 119 | + * @param string $contentStream optional content stream data - expected as a base64 encoded string | |
| 120 | + * @param string $versioningState optional version state value: none/checkedout/major/minor | |
| 121 | + * @param $policies List of policy ids that MUST be applied | |
| 122 | + * @param $addACEs List of ACEs that MUST be added | |
| 123 | + * @param $removeACEs List of ACEs that MUST be removed | |
| 122 | 124 | * @return string $objectId The id of the created folder object |
| 123 | 125 | */ |
| 124 | - public function createDocument($repositoryId, $typeId, $properties, $folderId = null, | |
| 125 | - $contentStream = null, $versioningState = null) | |
| 126 | + public function createDocument($repositoryId, $properties, $folderId = null, $contentStream = null, $versioningState = null, | |
| 127 | + $policies = array(), $addACEs = array(), $removeACEs = array()) | |
| 126 | 128 | { |
| 127 | 129 | $objectId = null; |
| 128 | 130 | |
| 129 | 131 | try { |
| 130 | - $objectId = $this->ObjectService->createDocument($repositoryId, $typeId, $properties, $folderId, | |
| 131 | - $contentStream, $versioningState); | |
| 132 | + $objectId = $this->ObjectService->createDocument($repositoryId, $typeId, $properties, $folderId, $contentStream, | |
| 133 | + $versioningState,$policies, $addACEs, $removeACEs); | |
| 132 | 134 | } |
| 133 | 135 | catch (Exception $e) |
| 134 | 136 | { | ... | ... |
lib/api/ktcmis/objecttypes/CMISDocumentObject.inc.php
| ... | ... | @@ -57,7 +57,7 @@ class CMISDocumentObject extends CMISObject { |
| 57 | 57 | protected $ktapi; |
| 58 | 58 | |
| 59 | 59 | // TODO some of this should probably come from configuration files as it is repository specific |
| 60 | - function __construct($documentId = null, &$ktapi = null, $uri = null) | |
| 60 | + public function __construct($documentId = null, &$ktapi = null, $uri = null) | |
| 61 | 61 | { |
| 62 | 62 | $this->ktapi = $ktapi; |
| 63 | 63 | |
| ... | ... | @@ -102,7 +102,7 @@ class CMISDocumentObject extends CMISObject { |
| 102 | 102 | } |
| 103 | 103 | |
| 104 | 104 | // TODO abstract shared stuff to base class where possible |
| 105 | - private function _get($documentId) | |
| 105 | + protected function _get($documentId) | |
| 106 | 106 | { |
| 107 | 107 | $object = $this->ktapi->get_document_by_id((int)$documentId); |
| 108 | 108 | ... | ... |
lib/api/ktcmis/objecttypes/CMISFolderObject.inc.php
| ... | ... | @@ -88,7 +88,7 @@ class CMISFolderObject extends CMISObject { |
| 88 | 88 | } |
| 89 | 89 | |
| 90 | 90 | // TODO abstract shared stuff to base class where possible |
| 91 | - private function _get($folderId) | |
| 91 | + protected function _get($folderId) | |
| 92 | 92 | { |
| 93 | 93 | $object = $this->ktapi->get_folder_by_id((int)$folderId); |
| 94 | 94 | |
| ... | ... | @@ -125,7 +125,7 @@ class CMISFolderObject extends CMISObject { |
| 125 | 125 | $this->_setPropertyInternal('changeToken', null); |
| 126 | 126 | $this->_setPropertyInternal('name', $objectProperties['folder_name']); |
| 127 | 127 | $this->_setPropertyInternal('parentId', CMISUtil::encodeObjectId(FOLDER, $objectProperties['parent_id'])); |
| 128 | - $this->_setPropertyInternal('allowedChildObjectTypeIds', array('Document', 'Folder')); | |
| 128 | + $this->_setPropertyInternal('allowedChildObjectTypeIds', array('cmis:document', 'cmis:folder')); | |
| 129 | 129 | $this->_setPropertyInternal('author', $objectProperties['created_by']); |
| 130 | 130 | } |
| 131 | 131 | ... | ... |
lib/api/ktcmis/services/CMISObjectService.inc.php
| ... | ... | @@ -34,33 +34,34 @@ class CMISObjectService { |
| 34 | 34 | * Creates a new document within the repository |
| 35 | 35 | * |
| 36 | 36 | * @param string $repositoryId The repository to which the document must be added |
| 37 | - * @param string $typeId Object Type id for the document object being created | |
| 38 | 37 | * @param array $properties Array of properties which must be applied to the created document object |
| 39 | 38 | * @param string $folderId The id of the folder which will be the parent of the created document object |
| 40 | 39 | * This parameter is optional IF unfilingCapability is supported |
| 41 | 40 | * @param string $contentStream optional content stream data - expected as a base64 encoded string |
| 42 | - * @param string $versioningState optional version state value: checkedout/major/minor | |
| 41 | + * @param string $versioningState optional version state value: none/checkedout/major/minor | |
| 42 | + * @param $policies List of policy ids that MUST be applied | |
| 43 | + * @param $addACEs List of ACEs that MUST be added | |
| 44 | + * @param $removeACEs List of ACEs that MUST be removed | |
| 43 | 45 | * @return string $objectId The id of the created folder object |
| 44 | 46 | */ |
| 45 | 47 | // TODO throw ConstraintViolationException if: |
| 46 | 48 | // value of any of the properties violates the min/max/required/length constraints |
| 47 | 49 | // specified in the property definition in the Object-Type. |
| 48 | - public function createDocument($repositoryId, $typeId, $properties, $folderId = null, | |
| 49 | - $contentStream = null, $versioningState = null) | |
| 50 | + // TODO throw ConstraintViolationException if At least one of the permissions is used in | |
| 51 | + // an ACE provided which is not supported by the repository. | |
| 52 | + // NOTE typeId is supplied in the cmis:objectTypeId property in the properties array | |
| 53 | + public function createDocument($repositoryId, $properties, $folderId = null, $contentStream = null, | |
| 54 | + $versioningState = null, $policies = array(), $addACEs = array(), | |
| 55 | + $removeACEs = array()) | |
| 50 | 56 | { |
| 51 | 57 | $objectId = null; |
| 52 | 58 | |
| 53 | 59 | // fetch type definition of supplied type and check for base type "document", if not true throw exception |
| 54 | 60 | $RepositoryService = new CMISRepositoryService(); |
| 55 | 61 | try { |
| 56 | - $typeDefinition = $RepositoryService->getTypeDefinition($repositoryId, $typeId); | |
| 62 | + $typeDefinition = $RepositoryService->getTypeDefinition($repositoryId, $properties['objectTypeId']); | |
| 57 | 63 | } |
| 58 | - // NOTE Not sure that we should throw this specific exception, maybe just let the underlying | |
| 59 | - // exception propogate upward... | |
| 60 | - // Alternatively: throw new exception with original exception message appended | |
| 61 | - // NOTE The latter method has been adopted for the moment | |
| 62 | - catch (Exception $e) | |
| 63 | - { | |
| 64 | + catch (Exception $e) { | |
| 64 | 65 | throw new ConstraintViolationException('Object base type could not be determined. ' . $e->getMessage()); |
| 65 | 66 | } |
| 66 | 67 | |
| ... | ... | @@ -95,7 +96,7 @@ class CMISObjectService { |
| 95 | 96 | { |
| 96 | 97 | foreach($allowed as $type) |
| 97 | 98 | { |
| 98 | - if (strtolower($type) == strtolower($typeId)) | |
| 99 | + if (strtolower($type) == strtolower($properties['objectTypeId'])) | |
| 99 | 100 | { |
| 100 | 101 | $typeAllowed = true; |
| 101 | 102 | break; |
| ... | ... | @@ -117,9 +118,23 @@ class CMISObjectService { |
| 117 | 118 | } |
| 118 | 119 | |
| 119 | 120 | // if versionable attribute is set to false and versioningState is supplied, throw a ConstraintViolationException |
| 120 | - if (!$typeDefinition['attributes']['versionable'] && !empty($versioningState)) { | |
| 121 | - throw new ConstraintViolationException('This repository does not support versioning'); | |
| 121 | + if (!$typeDefinition['attributes']['versionable'] && (!empty($versioningState) || $versioningState != 'none')) { | |
| 122 | + throw new ConstraintViolationException('This object-type does not support versioning'); | |
| 123 | + } | |
| 124 | + else if ($typeDefinition['attributes']['versionable'] && (empty($versioningState) || $versioningState == 'none')) { | |
| 125 | + throw new ConstraintViolationException('Invalid versioning state supplied'); | |
| 122 | 126 | } |
| 127 | + | |
| 128 | + if (!$typeDefinition['attributes']['controllablePolicy'] && count($policies)) { | |
| 129 | + throw new ConstraintViolationException('This object-type does not support policies'); | |
| 130 | + } | |
| 131 | + | |
| 132 | + if (!$typeDefinition['attributes']['controllableACL'] && (count($addACEs) || count($removeACEs))) { | |
| 133 | + throw new ConstraintViolationException('This object-type does not support ACLs'); | |
| 134 | + } | |
| 135 | + | |
| 136 | + // TODO throw NameConstraintViolation if there is a violation with the given cmis:name property value | |
| 137 | + // OR choose a name which does not conflict | |
| 123 | 138 | |
| 124 | 139 | // TODO deal with $versioningState when supplied |
| 125 | 140 | |
| ... | ... | @@ -146,6 +161,10 @@ class CMISObjectService { |
| 146 | 161 | // this check isn't strictly necessary; however it is needed for a repository which does not support content streams |
| 147 | 162 | if (!is_null($contentStream)) |
| 148 | 163 | { |
| 164 | + if (!$typeDefinition['attributes']['contentStreamAllowed']) { | |
| 165 | + throw new StreamNotSupportedException('Content streams are not supported by this object-type'); | |
| 166 | + } | |
| 167 | + | |
| 149 | 168 | $tempfilename = CMISUtil::createTemporaryFile($contentStream); |
| 150 | 169 | |
| 151 | 170 | // metadata |
| ... | ... | @@ -210,6 +229,7 @@ class CMISObjectService { |
| 210 | 229 | include_once(KT_LIB_DIR . '/mime.inc.php'); |
| 211 | 230 | $KTMime = new KTMime(); |
| 212 | 231 | $mimetype = $KTMime->getMimeTypeFromFile($tempfilename); |
| 232 | + // extract type string from mimetype response | |
| 213 | 233 | preg_match('/^([^\/]*)\/([^\/]*)/', $mimetype, $matches); |
| 214 | 234 | if (($matches[1] == 'text') || ($matches[1] == 'image') || ($matches[1] == 'audio')) { |
| 215 | 235 | $mediatype = ucwords($matches[1]); | ... | ... |
webservice/atompub/cmis/KT_cmis_atom_server.services.inc.php
| ... | ... | @@ -143,8 +143,6 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { |
| 143 | 143 | $title = KT_cmis_atom_service_helper::getAtomValues($this->parsedXMLContent['@children'], 'title'); |
| 144 | 144 | $summary = KT_cmis_atom_service_helper::getAtomValues($this->parsedXMLContent['@children'], 'summary'); |
| 145 | 145 | |
| 146 | - $properties = array('name' => $title, 'summary' => $summary); | |
| 147 | - | |
| 148 | 146 | // determine whether this is a folder or a document action |
| 149 | 147 | // document action create will have a content tag <atom:content> or <content> containing base64 encoding of the document |
| 150 | 148 | // move action will have an existing id supplied as a parameter - not sure how this works yet as the CMIS clients we are |
| ... | ... | @@ -160,6 +158,7 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { |
| 160 | 158 | } |
| 161 | 159 | |
| 162 | 160 | $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->parsedXMLContent['@children']); |
| 161 | + $properties = array('name' => $title, 'summary' => $summary, 'typeId' => $cmisObjectProperties['objectTypeId']); | |
| 163 | 162 | |
| 164 | 163 | // check for existing object id as property of submitted object data |
| 165 | 164 | if (!empty($cmisObjectProperties['objectId'])) |
| ... | ... | @@ -175,14 +174,20 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { |
| 175 | 174 | |
| 176 | 175 | // determine type if object is being moved |
| 177 | 176 | if (!is_null($objectId)) { |
| 178 | - CMISUtil::decodeObjectId($objectId, $typeId); | |
| 177 | + CMISUtil::decodeObjectId($objectId, $cmisObjectProperties['objectTypeId']); | |
| 179 | 178 | } |
| 180 | 179 | |
| 181 | 180 | // check for content stream |
| 182 | - $content = KT_cmis_atom_service_helper::getAtomValues($this->parsedXMLContent['@children'], 'content'); | |
| 181 | + $content = KT_cmis_atom_service_helper::getAtomValues($this->parsedXMLContent['@children'], 'content'); | |
| 182 | + | |
| 183 | + global $default; | |
| 184 | +// $default->log->info('cmis object type id: ' . $cmisObjectProperties['objectTypeId']); | |
| 185 | +// $default->log->info(print_r($cmisObjectProperties, true)); | |
| 186 | +// $default->log->info(print_r($this->parsedXMLContent['@children'], true)); | |
| 187 | + $default->log->info(print_r($this->rawContent, true)); | |
| 183 | 188 | |
| 184 | - // TODO this will possibly need to change somewhat once Relationship Objects come into play. | |
| 185 | - if ((($action == 'create') && (is_null($content))) || ($typeId == 'Folder')) { | |
| 189 | + // TODO this will need to change somewhat once other object-types come into play. | |
| 190 | + if ((($action == 'create') && (is_null($content))) || ($cmisObjectProperties['objectTypeId'] == 'cmis:folder')) { | |
| 186 | 191 | $type = 'folder'; |
| 187 | 192 | } |
| 188 | 193 | else { |
| ... | ... | @@ -195,13 +200,14 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { |
| 195 | 200 | $error = null; |
| 196 | 201 | if ($action == 'create') |
| 197 | 202 | { |
| 203 | + // TODO detection and passing of optional parameters (policies, ACEs, etc...) | |
| 198 | 204 | if ($type == 'folder') |
| 199 | 205 | $newObjectId = $ObjectService->createFolder($repositoryId, ucwords($cmisObjectProperties['objectTypeId']), $properties, $folderId); |
| 200 | 206 | else |
| 201 | 207 | $newObjectId = $ObjectService->createDocument($repositoryId, ucwords($cmisObjectProperties['objectTypeId']), $properties, $folderId, $content); |
| 202 | 208 | |
| 203 | 209 | // check if returned Object Id is a valid CMIS Object Id |
| 204 | - CMISUtil::decodeObjectId($newObjectId, $typeId); | |
| 210 | + CMISUtil::decodeObjectId($newObjectId, $cmisObjectProperties['objectTypeId']); | |
| 205 | 211 | if ($typeId != 'Unknown') $success = true; |
| 206 | 212 | else $error = $newObjectId['message']; |
| 207 | 213 | } | ... | ... |
webservice/atompub/cmis/KT_cmis_atom_service_helper.inc.php
| ... | ... | @@ -479,9 +479,9 @@ class KT_cmis_atom_service_helper { |
| 479 | 479 | $baseCmisObject = KT_cmis_atom_service_helper::findTag('cmisra:object', $entryObject['@children'], null, true); |
| 480 | 480 | } |
| 481 | 481 | |
| 482 | - if(count($baseCmisObject)>0) | |
| 482 | + if(count($baseCmisObject) > 0) | |
| 483 | 483 | { |
| 484 | - foreach($baseCmisObject['@children'] as $key => $childElement) | |
| 484 | + foreach($baseCmisObject[0]['@children'] as $key => $childElement) | |
| 485 | 485 | { |
| 486 | 486 | if ($key == 'cmis:properties') |
| 487 | 487 | { |
| ... | ... | @@ -489,7 +489,8 @@ class KT_cmis_atom_service_helper { |
| 489 | 489 | { |
| 490 | 490 | foreach($cmisPropertyDefinition as $propertyType => $propertyDefinition) |
| 491 | 491 | { |
| 492 | - $properties[$propertyDefinition['@attributes']['cmis:name']] = $propertyDefinition['@children']['cmis:value'][0]['@value']; | |
| 492 | + $properties[$propertyDefinition['@attributes']['cmis:name']] | |
| 493 | + = $propertyDefinition['@children']['cmis:value'][0]['@value']; | |
| 493 | 494 | } |
| 494 | 495 | } |
| 495 | 496 | } |
| ... | ... | @@ -605,7 +606,8 @@ class KT_cmis_atom_service_helper { |
| 605 | 606 | } |
| 606 | 607 | |
| 607 | 608 | //TODO: Add key information to be able to find the same tag in the original struct (MarkH) |
| 608 | - static public function findTag($tagName=NULL,$xml=array(),$tagArray=NULL,$deep=false){ | |
| 609 | + static public function findTag($tagName=NULL,$xml=array(),$tagArray=NULL,$deep=false) | |
| 610 | + { | |
| 609 | 611 | $tagArray=is_array($tagArray)?$tagArray:array(); |
| 610 | 612 | foreach($xml as $xmlTag=>$content){ |
| 611 | 613 | if($xmlTag===$tagName){ | ... | ... |
webservice/classes/atompub/cmis/ObjectService.inc.php
| ... | ... | @@ -38,21 +38,25 @@ class ObjectService extends KTObjectService { |
| 38 | 38 | * Creates a new document within the repository |
| 39 | 39 | * |
| 40 | 40 | * @param string $repositoryId The repository to which the document must be added |
| 41 | - * @param string $typeId Object Type id for the document object being created | |
| 42 | 41 | * @param array $properties Array of properties which must be applied to the created document object |
| 43 | 42 | * @param string $folderId The id of the folder which will be the parent of the created document object |
| 44 | 43 | * This parameter is optional IF unfilingCapability is supported |
| 45 | - * @param contentStream $contentStream optional content stream data | |
| 46 | - * @param string $versioningState optional version state value: checkedout/major/minor | |
| 44 | + * @param string $contentStream optional content stream data - expected as a base64 encoded string | |
| 45 | + * @param string $versioningState optional version state value: none/checkedout/major/minor | |
| 46 | + * @param $policies List of policy ids that MUST be applied | |
| 47 | + * @param $addACEs List of ACEs that MUST be added | |
| 48 | + * @param $removeACEs List of ACEs that MUST be removed | |
| 47 | 49 | * @return string $objectId The id of the created folder object |
| 48 | 50 | */ |
| 49 | 51 | // TODO throw ConstraintViolationException if: |
| 50 | 52 | // value of any of the properties violates the min/max/required/length constraints |
| 51 | 53 | // specified in the property definition in the Object-Type. |
| 52 | - public function createDocument($repositoryId, $typeId, $properties, $folderId = null, | |
| 53 | - $contentStream = null, $versioningState = null) | |
| 54 | + public function createDocument($repositoryId, $properties, $folderId = null, $contentStream = null, | |
| 55 | + $versioningState = null, $policies = array(), $addACEs = array(), | |
| 56 | + $removeACEs = array()) | |
| 54 | 57 | { |
| 55 | - $result = parent::createDocument($repositoryId, $typeId, $properties, $folderId, $contentStream, $versioningState); | |
| 58 | + $result = parent::createDocument($repositoryId, $properties, $folderId, $contentStream, $versioningState, | |
| 59 | + $policies, $addACEs, $removeACEs); | |
| 56 | 60 | |
| 57 | 61 | if ($result['status_code'] == 0) { |
| 58 | 62 | return $result['results']; | ... | ... |