Commit 30d7fae36b0a8905c3ffa0193a3740e3fa79144a

Authored by Paul Barrett
1 parent e6428228

Updated CMIS API with Document Creation functionality

Removed conflicting exceptions

Updated CMIS API Unit Tests

Committed by: Paul Barrett

Reviewed by: Jarrett Jordaan
ktwebservice/KTUploadManager.inc.php
... ... @@ -110,6 +110,7 @@ class KTUploadManager
110 110 return ($tempdir == $this->temp_dir);
111 111 */
112 112 }
  113 +
113 114 function store_base64_file($base64, $prefix= 'sa_')
114 115 {
115 116 $tempfilename = $this->get_temp_filename($prefix);
... ...
lib/api/ktcmis/classes/CMISBaseObject.inc.php
... ... @@ -62,7 +62,7 @@ abstract class CMISBaseObject {
62 62 // TODO all we have here so far is getAttributes & getProperties
63 63 // add all the other methods as we go along
64 64  
65   - function __construct()
  65 + public function __construct()
66 66 {
67 67 // $propertyDef = new PropertyDefinition();
68 68 // $this->properties[] = $propertyDef;
... ... @@ -73,7 +73,7 @@ abstract class CMISBaseObject {
73 73 *
74 74 * @return array $attributes
75 75 */
76   - function getAttributes()
  76 + public function getAttributes()
77 77 {
78 78 $attributes = array();
79 79  
... ... @@ -95,7 +95,7 @@ abstract class CMISBaseObject {
95 95 return $attributes;
96 96 }
97 97  
98   - function getAttribute($field)
  98 + public function getAttribute($field)
99 99 {
100 100 return $this->{$field};
101 101 }
... ... @@ -104,7 +104,7 @@ abstract class CMISBaseObject {
104 104 * Sets properties for this type
105 105 * Obeys the rules as specified in the property definitions (once implemented)
106 106 */
107   - function setProperty($field, $value)
  107 + public function setProperty($field, $value)
108 108 {
109 109 $this->properties->setValue($field, $value);
110 110 }
... ... @@ -123,11 +123,26 @@ abstract class CMISBaseObject {
123 123 /**
124 124 * Fetches properties for this object type
125 125 */
126   - function getProperties()
  126 + public function getProperties()
127 127 {
128 128 return $this->properties;
129 129 }
130 130  
  131 + public function getProperty($property)
  132 + {
  133 + return $this->properties->getValue($property);
  134 + }
  135 +
  136 + public function reload($documentId)
  137 + {
  138 + $this->_get($documentId);
  139 + }
  140 +
  141 + private function _get($documentId)
  142 + {
  143 + // override in child classes
  144 + }
  145 +
131 146 }
132 147  
133 148 ?>
... ...
lib/api/ktcmis/exceptions/InvalidArgumentException.inc.php deleted
1   -<?php
2   -
3   -class IllegalArgumentException extends Exception {
4   -
5   -}
6   -
7   -?>
lib/api/ktcmis/exceptions/RuntimeException.inc.php deleted
1   -<?php
2   -
3   -class RuntimeException extends Exception {
4   -
5   -}
6   -
7   -?>
lib/api/ktcmis/ktcmis.inc.php
... ... @@ -480,7 +480,7 @@ class KTObjectService extends KTCMISBase {
480 480 * @return string $objectId The id of the created folder object
481 481 */
482 482 function createDocument($repositoryId, $typeId, $properties, $folderId = null,
483   - $contentStream = null, $versioningState = 'Major')
  483 + $contentStream = null, $versioningState = null)
484 484 {
485 485 $objectId = null;
486 486  
... ...
lib/api/ktcmis/objecttypes/CMISDocumentObject.inc.php
... ... @@ -48,8 +48,8 @@ require_once(CMIS_DIR . &#39;/util/CMISUtil.inc.php&#39;);
48 48  
49 49 class CMISDocumentObject extends CMISBaseObject {
50 50  
51   - private $versionable;
52   - private $contentStreamAllowed;
  51 + protected $versionable;
  52 + protected $contentStreamAllowed;
53 53 private $ktapi;
54 54 private $uri;
55 55  
... ... @@ -100,7 +100,7 @@ class CMISDocumentObject extends CMISBaseObject {
100 100  
101 101 private function _get($documentId)
102 102 {
103   - $object = $this->ktapi->get_document_by_id($documentId);
  103 + $object = $this->ktapi->get_document_by_id((int)$documentId);
104 104  
105 105 // error?
106 106 if (PEAR::isError($object))
... ...
lib/api/ktcmis/objecttypes/CMISFolderObject.inc.php
... ... @@ -46,10 +46,10 @@ require_once(CMIS_DIR . &#39;/util/CMISUtil.inc.php&#39;);
46 46  
47 47 class CMISFolderObject extends CMISBaseObject {
48 48  
49   - var $ktapi;
50   - var $uri;
  49 + private $ktapi;
  50 + private $uri;
51 51  
52   - function __construct($folderId = null, &$ktapi = null, $uri = null)
  52 + public function __construct($folderId = null, &$ktapi = null, $uri = null)
53 53 {
54 54 $this->ktapi = $ktapi;
55 55 $this->uri = $uri;
... ... @@ -78,7 +78,7 @@ class CMISFolderObject extends CMISBaseObject {
78 78  
79 79 private function _get($folderId)
80 80 {
81   - $object = $this->ktapi->get_folder_by_id($folderId);
  81 + $object = $this->ktapi->get_folder_by_id((int)$folderId);
82 82  
83 83 // error?
84 84 if (PEAR::isError($object))
... ...
lib/api/ktcmis/services/CMISNavigationService.inc.php
... ... @@ -83,7 +83,7 @@ class CMISNavigationService {
83 83 $repository = new CMISRepository($repositoryId);
84 84  
85 85 // if this is not a folder, cannot get descendants
86   - $type = CMISUtil::decodeObjectId($folderId);
  86 + $folderId = CMISUtil::decodeObjectId($folderId, $type);
87 87  
88 88 if ($type != 'Folder')
89 89 {
... ... @@ -125,7 +125,7 @@ class CMISNavigationService {
125 125 $repository = new CMISRepository($repositoryId);
126 126  
127 127 // if this is not a folder, cannot get children
128   - $type = CMISUtil::decodeObjectId($folderId);
  128 + $folderId = CMISUtil::decodeObjectId($folderId, $type);
129 129 // NOTE this will quite possibly break the webservices
130 130 if ($type != 'Folder')
131 131 {
... ... @@ -162,7 +162,7 @@ class CMISNavigationService {
162 162 $repository = new CMISRepository($repositoryId);
163 163  
164 164 // if this is not a folder, cannot get folder parent :)
165   - $type = CMISUtil::decodeObjectId($folderId);
  165 + $folderId = CMISUtil::decodeObjectId($folderId, $type);
166 166 // NOTE this will quite possibly break the webservices
167 167 if ($type != 'Folder')
168 168 {
... ... @@ -221,7 +221,7 @@ class CMISNavigationService {
221 221 {
222 222 $ancestry = array();
223 223  
224   - $typeId = CMISUtil::decodeObjectId($objectId);
  224 + $objectId = CMISUtil::decodeObjectId($objectId, $typeId);
225 225  
226 226 // TODO - what about other types? only implementing folders and documents at the moment so ignore for now
227 227 switch($typeId)
... ...
lib/api/ktcmis/services/CMISObjectService.inc.php
1 1 <?php
2 2  
3 3 require_once(KT_DIR . '/ktapi/ktapi.inc.php');
  4 +require_once(KT_DIR . '/ktwebservice/KTUploadManager.inc.php');
4 5 require_once(CMIS_DIR . '/exceptions/ConstraintViolationException.inc.php');
5 6 require_once(CMIS_DIR . '/exceptions/ContentAlreadyExistsException.inc.php');
6 7 require_once(CMIS_DIR . '/exceptions/ObjectNotFoundException.inc.php');
... ... @@ -8,6 +9,7 @@ require_once(CMIS_DIR . &#39;/exceptions/StorageException.inc.php&#39;);
8 9 require_once(CMIS_DIR . '/exceptions/StreamNotSupportedException.inc.php');
9 10 require_once(CMIS_DIR . '/exceptions/UpdateConflictException.inc.php');
10 11 require_once(CMIS_DIR . '/exceptions/VersioningException.inc.php');
  12 +require_once(CMIS_DIR . '/services/CMISNavigationService.inc.php');
11 13 require_once(CMIS_DIR . '/services/CMISRepositoryService.inc.php');
12 14 require_once(CMIS_DIR . '/objecttypes/CMISDocumentObject.inc.php');
13 15 require_once(CMIS_DIR . '/objecttypes/CMISFolderObject.inc.php');
... ... @@ -49,7 +51,7 @@ class CMISObjectService {
49 51 // TODO a better default value?
50 52 $properties = array();
51 53  
52   - $typeId = CMISUtil::decodeObjectId($objectId);
  54 + $objectId = CMISUtil::decodeObjectId($objectId, $typeId);
53 55  
54 56 if ($typeId == 'Unknown')
55 57 {
... ... @@ -86,14 +88,8 @@ class CMISObjectService {
86 88 // TODO throw ConstraintViolationException if:
87 89 // value of any of the properties violates the min/max/required/length constraints
88 90 // specified in the property definition in the Object-Type.
89   - // TODO throw ConstraintViolationException if:
90   - // The Object-Type definition specified by the typeId parameter's "contentStreamAllowed" attribute
91   - // is set to "required" and no contentStream input parameter is provided
92   - // TODO throw ConstraintViolationException if:
93   - // The Object-Type definition specified by the typeId parameter's "versionable" attribute
94   - // is set to "false" and a value for the versioningState input parameter is provided
95 91 function createDocument($repositoryId, $typeId, $properties, $folderId = null,
96   - $contentStream = null, $versioningState = 'Major')
  92 + $contentStream = null, $versioningState = null)
97 93 {
98 94 $objectId = null;
99 95  
... ... @@ -129,38 +125,22 @@ class CMISObjectService {
129 125  
130 126 // Attempt to decode $folderId, use as is if not detected as encoded
131 127 $tmpObjectId = $folderId;
132   - $tmpTypeId = CMISUtil::decodeObjectId($tmpObjectId);
  128 + $tmpObjectId = CMISUtil::decodeObjectId($tmpObjectId, $tmpTypeId);
133 129 if ($tmpTypeId != 'Unknown')
134 130 $folderId = $tmpObjectId;
135 131  
136 132 // if parent folder is not allowed to hold this type, throw exception
137 133 $CMISFolder = new CMISFolderObject($folderId, $this->ktapi);
138   - $folderProperties = $CMISFolder->getProperties();
139   - $allowed = $folderProperties->getValue('AllowedChildObjectTypeIds');
  134 + $allowed = $CMISFolder->getProperty('AllowedChildObjectTypeIds');
140 135 if (!is_array($allowed) || !in_array($typeId, $allowed))
141 136 {
142 137 throw new ConstraintViolationException('Parent folder may not hold objects of this type (' . $typeId . ')');
143 138 }
144 139  
145   - // set title and name identical if only one submitted
146   - if ($properties['title'] == '')
147   - {
148   - $properties['title'] = $properties['name'];
149   - }
150   - else if ($properties['name'] == '')
151   - {
152   - $properties['name'] = $properties['title'];
153   - }
154   -
155   - if ($properties['type'] == '')
156   - {
157   - $properties['type'] = $properties['Default'];
158   - }
159   -
160 140 // if content stream is required and no content stream is supplied, throw a ConstraintViolationException
161 141 if (($typeDefinition['attributes']['contentStreamAllowed'] == 'required') && empty($contentStream))
162 142 {
163   - throw new ConstraintViolationException('The Knowledgetree Repository requires a content stream for document creation. '
  143 + throw new ConstraintViolationException('This repository requires a content stream for document creation. '
164 144 . 'Refusing to create an empty document');
165 145 }
166 146 else if (($typeDefinition['attributes']['contentStreamAllowed'] == 'notAllowed') && !empty($contentStream))
... ... @@ -168,25 +148,66 @@ class CMISObjectService {
168 148 throw new StreamNotSupportedException('Content Streams are not supported');
169 149 }
170 150  
  151 + // if versionable attribute is set to false and versioningState is supplied, throw a ConstraintViolationException
  152 + if (!$typeDefinition['attributes']['versionable'] && !empty($versioningState))
  153 + {
  154 + throw new ConstraintViolationException('This repository does not support versioning');
  155 + }
  156 +
171 157 // TODO deal with $versioningState when supplied
172 158  
173   - // TODO Use add_document_with_metadata instead if metadata content submitted
174   - $response = $this->ktapi->add_document($folderId, $properties['title'], $properties['name'], $properties['type'], $uploadedFile);
175   - if ($response['status_code'] != 0)
  159 + // set title and name identical if only one submitted
  160 + if ($properties['title'] == '')
176 161 {
177   - throw new StorageException('The repository was unable to create the document - ' . $response['message']);
  162 + $properties['title'] = $properties['name'];
178 163 }
179   - else
  164 + else if ($properties['name'] == '')
180 165 {
181   - $objectId = CMISUtil::encodeObjectId('Document', $response['results']['id']);
  166 + $properties['name'] = $properties['title'];
182 167 }
183 168  
184   - // now that the document object exists, create the content stream from the supplied data
  169 + // TODO also set to Default if a non-supported type is submitted
  170 + if ($properties['type'] == '')
  171 + {
  172 + $properties['type'] = 'Default';
  173 + }
  174 +
  175 + // create the content stream from the supplied data
  176 + // NOTE since the repository is set to require a content stream and we don't currently have another way to get the document data
  177 + // this check isn't strictly necessary; however it is needed for a repository which does not support content streams
185 178 if (!empty($contentStream))
186 179 {
187   - // TODO changeToken support
188   - $changeToken = null;
189   - $this->setContentStream($repositoryId, $objectId, false, $contentStream, $changeToken);
  180 + // NOTE There is a function in CMISUtil to do this but since KTUploadManager exists and has more functionality
  181 + // which could come in useful at some point I decided to go with that instead (did not know it existed when
  182 + // I wrote the CMISUtil function)
  183 + $uploadManager = new KTUploadManager();
  184 + $file = $uploadManager->store_base64_file($contentStream, 'cmis_');
  185 + // create the document from this temporary file as per usual
  186 + // TODO Use add_document_with_metadata instead if metadata content submitted || update metadata separately?
  187 + $response = $this->ktapi->add_document((int)$folderId, $properties['title'], $properties['name'],
  188 + $properties['type'], $file);
  189 + if ($response['status_code'] != 0)
  190 + {
  191 + throw new StorageException('The repository was unable to create the document. ' . $response['message']);
  192 + }
  193 + else
  194 + {
  195 + $objectId = CMISUtil::encodeObjectId('Document', $response['results']['content_id']);
  196 + }
  197 +
  198 + // remove temporary file
  199 + @unlink($file);
  200 + }
  201 + // else create the document object in the database but don't actually create any content since none was supplied
  202 + // NOTE perhaps this content could be supplied in the $properties array?
  203 + else
  204 + {
  205 + // TODO creation of document without content. leaving this for now as we require content streams and any code
  206 + // here will therefore never be executed; if we implement some form of template based document creation
  207 + // then we may have something else to do here;
  208 + // for now we just throw a general RuntimeException, since we should not
  209 + // actually reach this code unless something is wrong; this may be removed or replaced later
  210 + throw new RuntimeException('Cannot create empty document');
190 211 }
191 212  
192 213 return $objectId;
... ... @@ -229,20 +250,19 @@ class CMISObjectService {
229 250  
230 251 // Attempt to decode $folderId, use as is if not detected as encoded
231 252 $tmpObjectId = $folderId;
232   - $tmpTypeId = CMISUtil::decodeObjectId($tmpObjectId);
  253 + $tmpObjectId = CMISUtil::decodeObjectId($tmpObjectId, $tmpTypeId);
233 254 if ($tmpTypeId != 'Unknown')
234 255 $folderId = $tmpObjectId;
235 256  
236 257 // if parent folder is not allowed to hold this type, throw exception
237 258 $CMISFolder = new CMISFolderObject($folderId, $this->ktapi);
238   - $folderProperties = $CMISFolder->getProperties();
239   - $allowed = $folderProperties->getValue('AllowedChildObjectTypeIds');
  259 + $allowed = $CMISFolder->getProperty('AllowedChildObjectTypeIds');
240 260 if (!is_array($allowed) || !in_array($typeId, $allowed))
241 261 {
242 262 throw new ConstraintViolationException('Parent folder may not hold objects of this type (' . $typeId . ')');
243 263 }
244 264  
245   - $response = $this->ktapi->create_folder($folderId, $properties['name'], $sig_username = '', $sig_password = '', $reason = '');
  265 + $response = $this->ktapi->create_folder((int)$folderId, $properties['name'], $sig_username = '', $sig_password = '', $reason = '');
246 266 if ($response['status_code'] != 0)
247 267 {
248 268 throw new StorageException('The repository was unable to create the folder - ' . $response['message']);
... ... @@ -255,6 +275,14 @@ class CMISObjectService {
255 275 return $objectId;
256 276 }
257 277  
  278 + // NOTE this function is presently incomplete and untested. Completion deferred to implementation of Checkout/Checkin
  279 + // functionality
  280 + // NOTE I am not sure yet when this function would ever be called - checkin would be able to update the content stream
  281 + // already and the only easy method we have (via KTAPI as it stands) to update the content is on checkin anyway.
  282 + // Additionally this function doesn't take a value for the versioning status (major/minor) and so cannot pass it
  283 + // on to the ktapi checkin function.
  284 + // I imagine this function may be called if we ever allow updating document content independent of checkin,
  285 + // or if we change some of the underlying code and call direct to the document functions and not via KTAPI.
258 286 /**
259 287 * Sets the content stream data for an existing document
260 288 *
... ... @@ -277,6 +305,17 @@ class CMISObjectService {
277 305 // versioningException: The repository MAY throw this exception if the object is a non-current Document Version.
278 306 function setContentStream($repositoryId, $documentId, $overwriteFlag, $contentStream, $changeToken = null)
279 307 {
  308 + // if no document id was supplied, we are going to create the underlying physical document
  309 + // NOTE while it might have been nice to keep this out of here, KTAPI has no method for creating a document without
  310 + // a physical upload, so we cannot create the document first and then add the upload as a content stream, the
  311 + // entire creation step needs to happen here.
  312 +
  313 + // Attempt to decode $documentId, use as is if not detected as encoded
  314 + $tmpObjectId = $documentId;
  315 + $tmpObjectId = CMISUtil::decodeObjectId($tmpObjectId, $tmpTypeId);
  316 + if ($tmpTypeId != 'Unknown')
  317 + $documentId = $tmpObjectId;
  318 +
280 319 // fetch type definition of supplied document
281 320 $CMISDocument = new CMISDocumentObject($documentId, $this->ktapi);
282 321  
... ... @@ -289,26 +328,34 @@ class CMISObjectService {
289 328 throw new StreamNotSupportedException('Content Streams are not allowed for this object type');
290 329 }
291 330  
292   - $properties = $CMISDocument->getProperties();
293   - if (!empty($properties->getValue('ContentStreamFilename')) && (!$overwriteFlag))
  331 + $csFileName = $CMISDocument->getProperty('ContentStreamFilename');
  332 + if (!empty($csFileName) && (!$overwriteFlag))
294 333 {
295 334 throw new ContentAlreadyExistsException('Unable to overwrite existing content stream');
296 335 }
297 336  
298   - // in order to set the stream we need to do the following:
299   - // 1. decode the stream from the supplied base64 encoding
300   - // 2. create a temporary file as if it were uploaded via a file upload dialog
301   - // 3. create the document content as per usual
302   - // 4. link to the created document object? this perhaps only happens on read anyway
303   -
304   - // if there is any problem updating the content stream, throw StorageException
305   - // TODO real test parameter instead of hard-coded FALSE
306   - if (false)
  337 + // NOTE There is a function in CMISUtil to do this but since KTUploadManager exists and has more functionality
  338 + // which could come in useful at some point I decided to go with that instead (did not know it existed when
  339 + // I wrote the CMISUtil function)
  340 + $uploadManager = new KTUploadManager();
  341 + $file = $uploadManager->store_base64_file($contentStream, 'cmis_');
  342 + // update the document content from this temporary file as per usual
  343 + // TODO Use checkin_document_with_metadata instead if metadata content submitted || update metadata separately?
  344 + $response = $this->ktapi->checkin_document($documentId, $csFileName, 'CMIS setContentStream action', $file, false);
  345 + if ($response['status_code'] != 0)
307 346 {
308   - throw new StorageException('Unable to update the content stream');
  347 + throw new StorageException('Unable to update the content stream. ' . $response['message']);
309 348 }
  349 +// else
  350 +// {
  351 +// $objectId = CMISUtil::encodeObjectId('Document', $response['results']['id']);
  352 +// }
  353 +
  354 + @unlink($csFile);
  355 + // update the CMIS document object with the content stream information
  356 +// $CMISDocument->reload($document['result']['document_id']);
310 357  
311   - return $documentId;
  358 + return $CMISDocument->getProperty('ObjectId');
312 359 }
313 360  
314 361 }
... ...
lib/api/ktcmis/services/CMISRepositoryService.inc.php
... ... @@ -43,7 +43,6 @@
43 43  
44 44 require_once(CMIS_DIR . '/classes/CMISRepository.inc.php');
45 45 require_once(CMIS_DIR . '/classes/CMISObjectTypes.inc.php');
46   -require_once(CMIS_DIR . '/exceptions/InvalidArgumentException.inc.php');
47 46  
48 47 /**
49 48 * CMIS Repository Service.
... ...
lib/api/ktcmis/util/CMISUtil.inc.php
... ... @@ -53,7 +53,7 @@ class CMISUtil {
53 53 * @param string $objectId
54 54 * @return string $encoded
55 55 */
56   - static function encodeObjectId($typeId, $objectId)
  56 + static public function encodeObjectId($typeId, $objectId)
57 57 {
58 58 $encoded = null;
59 59  
... ... @@ -84,7 +84,7 @@ class CMISUtil {
84 84 * @param string $objectId
85 85 * @return string $typeId
86 86 */
87   - static function decodeObjectId(&$objectId)
  87 + static public function decodeObjectId($objectId, &$typeId = null)
88 88 {
89 89 $typeId = null;
90 90  
... ... @@ -105,7 +105,7 @@ class CMISUtil {
105 105 break;
106 106 }
107 107  
108   - return $typeId;
  108 + return $objectId;
109 109 }
110 110  
111 111 /**
... ... @@ -118,7 +118,7 @@ class CMISUtil {
118 118 * @param object $ktapi // reference to ktapi instance
119 119 * @return array $CMISArray
120 120 */
121   - static function createChildObjectHierarchy($input, $repositoryURI, &$ktapi)
  121 + static public function createChildObjectHierarchy($input, $repositoryURI, &$ktapi)
122 122 {
123 123 $CMISArray = array();
124 124  
... ... @@ -172,7 +172,7 @@ class CMISUtil {
172 172 * @return array $CMISArray
173 173 */
174 174 // NOTE this will have to change if we implement multi-filing
175   - static function createParentObjectHierarchy($input, $repositoryURI, &$ktapi)
  175 + static public function createParentObjectHierarchy($input, $repositoryURI, &$ktapi)
176 176 {
177 177 $CMISArray = array();
178 178  
... ... @@ -209,7 +209,7 @@ class CMISUtil {
209 209 * @param string $linkText // 'child' or 'parent' - indicates direction of hierarchy => descending or ascending
210 210 * @return array $hierarchy
211 211 */
212   - static function decodeObjectHierarchy($input, $linkText)
  212 + static public function decodeObjectHierarchy($input, $linkText)
213 213 {
214 214 $hierarchy = array();
215 215  
... ... @@ -225,7 +225,7 @@ class CMISUtil {
225 225 return $hierarchy;
226 226 }
227 227  
228   - static function createObjectPropertiesEntry($properties)
  228 + static public function createObjectPropertiesEntry($properties)
229 229 {
230 230 $object = array();
231 231  
... ... @@ -281,7 +281,7 @@ class CMISUtil {
281 281 * @param object $data
282 282 * @return array $array
283 283 */
284   - static function objectToArray($data)
  284 + static public function objectToArray($data)
285 285 {
286 286 $array = array();
287 287  
... ... @@ -309,11 +309,35 @@ class CMISUtil {
309 309 * @param boolean/other $input
310 310 * @return string
311 311 */
312   - function boolToString($input)
  312 + static public function boolToString($input)
313 313 {
314 314 return (($input === true) ? 'true' : (($input === false) ? 'false' : $input));
315 315 }
316 316  
  317 + /**
  318 + * Creates a temporary file
  319 + * Cleanup is the responsibility of the calling code
  320 + *
  321 + * @param string|binary $content The content to be written to the file.
  322 + * @param string $uploadDir Optional upload directory. Will use the KnowledgeTree system tmp directory if not supplied.
  323 + * @return string The path to the created file (for reference and cleanup.)
  324 + */
  325 + static public function createTemporaryFile($content, $encoding = null, $uploadDir = null)
  326 + {
  327 + if(is_null($uploadDir))
  328 + {
  329 + $oKTConfig =& KTConfig::getSingleton();
  330 + $uploadDir = $oKTConfig->get('webservice/uploadDirectory');
  331 + }
  332 +
  333 + $temp = tempnam($uploadDir, 'myfile');
  334 + $fp = fopen($temp, 'wb');
  335 + fwrite($fp, ($encoding == 'base64' ? base64_decode($content) : $content));
  336 + fclose($fp);
  337 +
  338 + return $temp;
  339 + }
  340 +
317 341 }
318 342  
319 343 ?>
... ...
tests/ktcmis/testCmisApi.php
... ... @@ -355,10 +355,53 @@ class CMISTestCase extends KTUnitTestCase {
355 355 $this->printTable($properties['results'][0], 'Properties for CMIS Created Folder Object ' . $folderId . ' (getProperties())');
356 356  
357 357 // delete
358   - CMISUtil::decodeObjectId($folderId);
359   - $this->ktapi->delete_folder($folderId, 'Testing API', KT_TEST_USER, KT_TEST_PASS);
  358 + $this->ktapi->delete_folder(CMISUtil::decodeObjectId($folderId), 'Testing API', KT_TEST_USER, KT_TEST_PASS);
360 359 }
361 360  
  361 + // TEST 3
  362 + // test creation of document
  363 + $folderId = 'F'.$this->folders[0];
  364 + $folderId = 'F1';
  365 + $properties = array('name' => 'Test CMIS Document 1', 'title' => 'test_cmis_doc_' . mt_rand() . '.txt');
  366 + $contentStream = base64_encode('Some arbitrary text content');
  367 + $created = $ObjectService->createDocument($repositoryId, 'Document', $properties, $folderId, $contentStream);
  368 +
  369 + $this->assertNotNull($created['results']);
  370 +
  371 +// echo '<pre>'.print_r($created, true).'</pre>';
  372 +
  373 + if (!is_null($created['results']))
  374 + {
  375 + $documentId = $created['results'];
  376 +
  377 + // check that document object actually exists
  378 + $properties = $ObjectService->getProperties($repositoryId, $documentId, false, false);
  379 + $this->assertNotNull($properties['results']);
  380 +
  381 + // test printout
  382 + $this->printTable($properties['results'][0], 'Properties for CMIS Created Document Object ' . $documentId . ' (getProperties())');
  383 + }
  384 +
  385 +// // TEST 5
  386 +// // test updating content stream for existing document
  387 +// $contentStream = base64_encode('Some updated text content for the content stream');
  388 +// $updated = $ObjectService->setContentStream($repositoryId, $documentId, true, $contentStream);
  389 +//
  390 +// $this->assertNotNull($updated['results']);
  391 +//
  392 +//// echo '<pre>'.print_r($created, true).'</pre>';
  393 +//
  394 +// if (!is_null($updated['results']))
  395 +// {
  396 +//// $documentId = $updated['results'];
  397 +//
  398 +// // TODO test getContentStream here when we have it
  399 +//
  400 +// }
  401 +
  402 + // delete created document
  403 +// $this->ktapi->delete_document(CMISUtil::decodeObjectId($documentId), 'Testing API', false);
  404 +
362 405 // tear down the folder/doc tree structure with which we were testing
363 406 $this->cleanupFolderDocStructure();
364 407  
... ...