Commit 4ae0b1cc976c316ef96b74f79dda2399d82fcf21

Authored by Mark Holtzhausen
2 parents 4b23c54c 3021d9ce

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

Conflicts:
	.htaccess
.htaccess
... ... @@ -61,6 +61,10 @@ Options +SymLinksIfOwnerMatch
61 61 #AcceptPathInfo On
62 62  
63 63 AddOutputFilter DEFLATE text/html text/plain text/xml text/javascript application/x-javascript text/css
  64 +<<<<<<< HEAD:.htaccess
  65 +=======
  66 +# The following seems to breaking things on ZendServer - kgf
  67 +>>>>>>> 3021d9ce95b467f66a2f65312d7db0e1f55c0d8c:.htaccess
64 68 #ExpiresActive ON
65 69 #ExpiresByType text/html "access plus 1 day"
66 70 #ExpiresByType text/css "access plus 1 day"
... ...
ktatompub/services/cmis/NavigationService.inc.php
... ... @@ -99,6 +99,26 @@ class NavigationService extends KTNavigationService {
99 99 }
100 100 }
101 101  
  102 + /**
  103 + * Returns a list of checked out documents from the selected repository
  104 + *
  105 + * @param string $repositoryId
  106 + * @param string $folderId The folder for which checked out docs are requested
  107 + * @param string $filter
  108 + * @param int $maxItems
  109 + * @param int $skipCount
  110 + * @return array $checkedout The collection of checked out documents
  111 + */
  112 + function getCheckedoutDocs($repositoryId, $folderId = null, $filter = '', $maxItems = 0, $skipCount = 0)
  113 + {
  114 + $checkedout = parent::getObjectParents($repositoryId, $folderId, $filter, $maxItems, $skipCount);
  115 +
  116 + if ($result['status_code'] == 0)
  117 + {
  118 + return $result['results'];
  119 + }
  120 + }
  121 +
102 122 }
103 123  
104 124 ?>
... ...
ktatompub/services/cmis/ObjectFeed.inc.php
... ... @@ -74,7 +74,6 @@ class CMISObjectFeed {
74 74 // main CMIS entry
75 75 $objectElement = $feed->newElement('cmis:object');
76 76 $propertiesElement = $feed->newElement('cmis:properties');
77   - // <cmis:propertyId cmis:name="ObjectId"><cmis:value>D2</cmis:value></cmis:propertyId>
78 77  
79 78 foreach($cmisEntry['properties'] as $propertyName => $property)
80 79 {
... ...
ktatompub/services/cmis/ObjectService.inc.php
... ... @@ -25,7 +25,7 @@ class ObjectService extends KTObjectService {
25 25 {
26 26 $result = parent::getProperties($repositoryId, $objectId, $includeAllowableActions,
27 27 $returnVersion, $filter);
28   -print_r($result);echo "<BR><BR>";
  28 +
29 29 if ($result['status_code'] == 0)
30 30 {
31 31 return $result['results'];
... ...
ktatompub/services/cmis/RepositoryService.inc.php
... ... @@ -16,8 +16,6 @@ class RepositoryService extends KTRepositoryService {
16 16 */
17 17 public function getRepositories()
18 18 {
19   - global $default;
20   - $default->log->debug('getRepositories');
21 19 $result = parent::getRepositories();
22 20  
23 21 if ($result['status_code'] == 0)
... ...
ktatompub/services/cmis/checkedout.inc.php
... ... @@ -20,8 +20,28 @@ $NavigationService-&gt;startSession($username, $password);
20 20 $repositories = $RepositoryService->getRepositories();
21 21 $repositoryId = $repositories[0]['repositoryId'];
22 22  
  23 +$checkedout = $NavigationService->getCheckedoutDocs($repositoryId);
  24 +
23 25 $feed = new KTCMISAPPFeed(KT_APP_BASE_URI, 'Checked out Documents', null, null, null, 'urn:uuid:checkedout');
24 26  
  27 +foreach($checkedout as $document)
  28 +{
  29 + $entry = $feed->newEntry();
  30 + $objectElement = $feed->newElement('cmis:object');
  31 + $propertiesElement = $feed->newElement('cmis:properties');
  32 +
  33 + foreach($cmisEntry['properties'] as $propertyName => $property)
  34 + {
  35 + $propElement = $feed->newElement('cmis:' . $property['type']);
  36 + $propElement->appendChild($feed->newAttr('cmis:name', $propertyName));
  37 + $feed->newField('value', CMISUtil::boolToString($property['value']), $propElement);
  38 + $propertiesElement->appendChild($propElement);
  39 + }
  40 +
  41 + $objectElement->appendChild($propertiesElement);
  42 + $entry->appendChild($objectElement);
  43 +}
  44 +
25 45 $entry = null;
26 46 $feed->newField('hasMoreItems', 'false', $entry, true);
27 47  
... ...
ktatompub/services/cmis/document.inc.php
... ... @@ -29,66 +29,7 @@ class CMISDocumentFeed extends CMISObjectFeed {
29 29  
30 30 $output = $feed->getAPPdoc();
31 31  
32   -// $documentData = $ObjectService->getProperties($repositoryId, $documentId, false, false);
33   -//
34   -// $feed = new KTCMISAPPFeed(KT_APP_BASE_URI, 'Root Folder Children', null, null, null,
35   -// 'urn:uuid:' . $cmisEntry['properties']['ObjectId']['value'] . '-children');
36   -//
37   -// foreach($entries as $cmisEntry)
38   -// {
39   -// $entry = $feed->newEntry();
40   -// $feed->newId('urn:uuid:' . $cmisEntry['properties']['ObjectId']['value'] . '-'
41   -// . strtolower($cmisEntry['properties']['ObjectTypeId']['value']), $entry);
42   -//
43   -// // links
44   -// if (strtolower($cmisEntry['properties']['ObjectTypeId']['value']) == 'folder')
45   -// {
46   -// $link = $feed->newElement('link');
47   -// $link->appendChild($feed->newAttr('rel','cmis-children'));
48   -// $link->appendChild($feed->newAttr('href', CMIS_BASE_URI
49   -// . strtolower($cmisEntry['properties']['ObjectTypeId']['value'])
50   -// . '/' . $cmisEntry['properties']['ObjectId']['value'] . '/children'));
51   -// $entry->appendChild($link);
52   -// $link = $feed->newElement('link');
53   -// $link->appendChild($feed->newAttr('rel','cmis-descendants'));
54   -// $link->appendChild($feed->newAttr('href', CMIS_BASE_URI
55   -// . strtolower($cmisEntry['properties']['ObjectTypeId']['value'])
56   -// . '/' . $cmisEntry['properties']['ObjectId']['value'] . '/descendants'));
57   -// $entry->appendChild($link);
58   -// }
59   -// $link = $feed->newElement('link');
60   -// $link->appendChild($feed->newAttr('rel','cmis-type'));
61   -// $link->appendChild($feed->newAttr('href', CMIS_BASE_URI . 'type/' . strtolower($cmisEntry['properties']['ObjectTypeId']['value'])));
62   -// $entry->appendChild($link);
63   -// $link = $feed->newElement('link');
64   -// $link->appendChild($feed->newAttr('rel','cmis-repository'));
65   -// $link->appendChild($feed->newAttr('href', CMIS_BASE_URI . 'repository'));
66   -// $entry->appendChild($link);
67   -//
68   -// $entry->appendChild($feed->newElement('summary', $cmisEntry['properties']['Name']['value']));
69   -// $entry->appendChild($feed->newElement('title', $cmisEntry['properties']['Name']['value']));
70   -//
71   -// // main CMIS entry
72   -// $objectElement = $feed->newElement('cmis:object');
73   -// $propertiesElement = $feed->newElement('cmis:properties');
74   -// // <cmis:propertyId cmis:name="ObjectId"><cmis:value>D2</cmis:value></cmis:propertyId>
75   -//
76   -// foreach($cmisEntry['properties'] as $propertyName => $property)
77   -// {
78   -// $propElement = $feed->newElement('cmis:' . $property['type']);
79   -// $propElement->appendChild($feed->newAttr('cmis:name', $propertyName));
80   -// $feed->newField('value', CMISUtil::boolToString($property['value']), $propElement);
81   -// $propertiesElement->appendChild($propElement);
82   -// }
83   -//
84   -// $objectElement->appendChild($propertiesElement);
85   -// $entry->appendChild($objectElement);
86   -// }
87   -//
88   -// // <cmis:hasMoreItems>false</cmis:hasMoreItems>
89   -//
90   -// $output = $feed->getAPPdoc();
91   - $outputs = '<?xml version="1.0" encoding="UTF-8"?>
  32 + $outputs = '<?xml version="1.0" encoding="UTF-8"?>
92 33 <feed xmlns="http://www.w3.org/2005/Atom" xmlns:cmis="http://www.cmis.org/2008/05">
93 34 <entry>
94 35 <author><name>admin</name></author>
... ...
ktatompub/services/cmis/folder.inc.php
... ... @@ -5,6 +5,10 @@
5 5 * Output returned as an AtomPub feed
6 6 */
7 7  
  8 + // NOTE the static responses in the code are example responses and partial responses
  9 + // against which the dynamic response is being checked while we are still uncertain
  10 + // whether everything is as it should be
  11 +
8 12 include 'services/cmis/ObjectFeed.inc.php';
9 13  
10 14 class CMISFolderFeed extends CMISObjectFeed {
... ... @@ -440,6 +444,7 @@ class CMISFolderFeed extends CMISObjectFeed {
440 444 // <cmis:hasMoreItems>false</cmis:hasMoreItems>
441 445  
442 446 $output = $feed->getAPPdoc();
  447 +
443 448 $outputs = '<?xml version="1.0" encoding="UTF-8"?>
444 449 <feed xmlns="http://www.w3.org/2005/Atom" xmlns:cmis="http://www.cmis.org/2008/05">
445 450 <entry>
... ...
ktatompub/services/cmis/index.php
... ... @@ -8,40 +8,34 @@ include_once(&#39;lib/cmis/KTCMISAPPServiceDoc.inc.php&#39;);
8 8 include_once('lib/cmis/KTCMISAPPFeed.inc.php');
9 9  
10 10 define ('CMIS_BASE_URI', trim(KT_APP_BASE_URI, '/') . 'cmis/');
11   -//echo KT_APP_BASE_URI;exit;
12   -// hack for links not yet working in KT, use Alfresco to move things forward
  11 +// hack for links not yet working in KT, use Alfresco installation to move things forward
13 12 //define ('CMIS_BASE_URI_ALF', 'http://127.0.0.1:8080/alfresco/service/api/');
14   -//define ('CMIS_BASE_URI', 'http://10.33.4.34:8080/alfresco/service/api/');
15 13  
16 14 // fetch username and password for auth; note that this apparently only works when PHP is run as an apache module
17   -// TODO method to fetch username and password when running PHP as CGI
  15 +// TODO method to fetch username and password when running PHP as CGI, if possible
  16 +// HTTP Basic Auth:
18 17 $username = $_SERVER['PHP_AUTH_USER'];
19 18 $password = $_SERVER['PHP_AUTH_PW'];
20 19  
21   -// NOTE this is just for demonstration purposes and attempting to auth with clients which send the username/password differently
22   -// TODO disable once we have at least Drupal compatible login working, can re-enable if necessary
23   -if (($username == '') && ($password == ''))
24   -{
25   - $username = $password = 'admin';
26   -}
  20 +// TODO response if failed auth, need generic response which can be used by all code
27 21  
28 22 $arg = (isset($query[1]) ? $query[1] : '');
29 23  
30 24 switch($arg)
31 25 {
32   - case 'checkedout':
33   - include('services/cmis/checkedout.inc.php');
34   - break;
35   - case 'document':
  26 + case 'checkedout':
  27 + include('services/cmis/checkedout.inc.php');
  28 + break;
  29 + case 'document':
36 30 include('services/cmis/document.inc.php');
37 31 break;
38   - case 'folder':
  32 + case 'folder':
39 33 include('services/cmis/folder.inc.php');
40 34 break;
41 35 case 'type':
42 36 case 'types':
43   - include('services/cmis/types.inc.php');
44   - break;
  37 + include('services/cmis/types.inc.php');
  38 + break;
45 39 case 'repository':
46 40 default:
47 41 include('services/cmis/servicedocument.inc.php');
... ...
lib/api/ktcmis/classes/CMISPropertyCollection.inc.php
... ... @@ -54,8 +54,6 @@ abstract class CMISPropertyCollection {
54 54 static $LastModifiedBy;
55 55 static $LastModificationDate;
56 56 static $ChangeToken;
57   - static $ContentStreamLength;
58   - static $ContentStreamMimeType;
59 57 // TODO these definitions probably belong elsewhere, but here will do for now
60 58 static $propertyTypes;
61 59  
... ...
lib/api/ktcmis/classes/CMISRepository.inc.php
... ... @@ -167,44 +167,6 @@ class CMISRepository {
167 167 return $this->objectTypes;
168 168 }
169 169  
170   -// // TODO this function MUST accept the same arguments as the calling functions and respond accordingly
171   -// // TODO consider moving this into the RepositoryService class:
172   -// // anything which requires a repository id seems like it does not belong in the repository class
173   -// function getTypes()
174   -// {
175   -// $objectTypes = $this->objectTypes->getObjectTypes();
176   -//
177   -// // fetch the attributes for each type
178   -// foreach ($objectTypes as $key => $objectType)
179   -// {
180   -// $objectTypes[$key] = $this->getTypeDefinition($this->repositoryId, $objectType);
181   -// }
182   -//
183   -// return $objectTypes;
184   -// }
185   -
186   -// // TODO consider moving this into the RepositoryService class:
187   -// // anything which requires a repository id seems like it does not belong in the repository class
188   -// function getTypeDefinition($repositoryId, $typeId)
189   -// {
190   -// // TODO is this the best way of doing this?
191   -// switch ($typeId)
192   -// {
193   -// case 'Document':
194   -// require_once(CMIS_DIR . '/objecttypes/CMISDocumentObject.inc.php');
195   -// $tmpObject = new DocumentObject();
196   -// $objectAttributes = $tmpObject->getProperties();
197   -// break;
198   -// case 'Folder':
199   -// require_once(CMIS_DIR . '/objecttypes/CMISFolderObject.inc.php');
200   -// $tmpObject = new FolderObject();
201   -// $objectAttributes = $tmpObject->getProperties();
202   -// break;
203   -// }
204   -//
205   -// return $objectAttributes;
206   -// }
207   -
208 170 }
209 171  
210 172 ?>
... ...
lib/api/ktcmis/config/repositories.xml
... ... @@ -19,7 +19,7 @@
19 19 <vendorName>KnowledgeTree</vendorName>
20 20 <productName>KnowledgeTree Document Management System</productName>
21 21 <productVersion>3.6.2</productVersion>
22   - <rootFolderId>Root%20Folder</rootFolderId>
  22 + <rootFolderId>Root Folder</rootFolderId>
23 23 <cmisVersionsSupported>0.61c</cmisVersionsSupported>
24 24 </repositoryInfo>
25 25 <repositoryCapabilities>
... ...
lib/api/ktcmis/exceptions/ConstraintViolationException.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +class ConstraintViolationException extends Exception {
  4 +
  5 +}
  6 +
  7 +?>
... ...
lib/api/ktcmis/exceptions/InvalidArgumentException.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +class IllegalArgumentException extends Exception {
  4 +
  5 +}
  6 +
  7 +?>
... ...
lib/api/ktcmis/exceptions/ObjectNotFoundException.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +class ObjectNotFoundException extends Exception {
  4 +
  5 +}
  6 +
  7 +?>
... ...
lib/api/ktcmis/exceptions/StorageException.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +class StorageException extends Exception {
  4 +
  5 +}
  6 +
  7 +?>
... ...
lib/api/ktcmis/ktcmis.inc.php
... ... @@ -77,24 +77,15 @@ class KTCMISBase {
77 77  
78 78 public function startSession($username, $password)
79 79 {
80   - global $default;
81   - $default->log->debug("attempt auth with $username :: $password");
82 80 $this->session = null;
83   - // remove as soon as actual auth code is in place
84   - $username = 'admin';
85   - $password = 'admin';
  81 +
86 82 $this->ktapi = new KTAPI();
87 83 $this->session =& $this->ktapi->start_session($username, $password);
88 84  
89   - if (PEAR::isError($this->session))
90   - {
91   - $default->log->debug("FAILED $username :: $password FAILED");
92   - }
93   -
94 85 return $this->session;
95 86 }
96 87  
97   - // TODO what about destroying sessions?
  88 + // TODO what about destroying sessions? only on logout (which is not offered by the CMIS clients tested so far)
98 89 }
99 90  
100 91 /**
... ... @@ -161,8 +152,8 @@ class KTRepositoryService extends KTCMISBase {
161 152 );
162 153 }
163 154  
164   - // TODO output this manually, the function works but only for some objects so rather avoid it completely
165   - // NOTE the fact that it works for this instance is irrelevant...
  155 + // TODO output this manually, the function works but only for some objects so rather avoid it completely?
  156 + // NOTE the problems appear to be due to recursive objects
166 157 return array (
167 158 "status_code" => 0,
168 159 "results" => CMISUtil::objectToArray($repositoryInfo)
... ... @@ -177,13 +168,15 @@ class KTRepositoryService extends KTCMISBase {
177 168 public function getTypes($repositoryId, $typeId = '', $returnPropertyDefinitions = false,
178 169 $maxItems = 0, $skipCount = 0, &$hasMoreItems = false)
179 170 {
180   - $repositoryObjectTypeResult = $this->RepositoryService->getTypes($repositoryId, $typeId, $returnPropertyDefinitions,
181   - $maxItems, $skipCount, $hasMoreItems);
182   - if (PEAR::isError($repositoryObjectTypeResult))
  171 + try {
  172 + $repositoryObjectTypeResult = $this->RepositoryService->getTypes($repositoryId, $typeId, $returnPropertyDefinitions,
  173 + $maxItems, $skipCount, $hasMoreItems);
  174 + }
  175 + catch (Exception $e)
183 176 {
184 177 return array(
185 178 "status_code" => 1,
186   - "message" => "Failed getting supported object types"
  179 + "message" => $e->getMessage()
187 180 );
188 181 }
189 182  
... ... @@ -211,13 +204,14 @@ class KTRepositoryService extends KTCMISBase {
211 204 */
212 205 public function getTypeDefinition($repositoryId, $typeId)
213 206 {
214   - $typeDefinitionResult = $this->RepositoryService->getTypeDefinition($repositoryId, $typeId);
215   -
216   - if (PEAR::isError($typeDefinitionResult))
  207 + try {
  208 + $typeDefinitionResult = $this->RepositoryService->getTypeDefinition($repositoryId, $typeId);
  209 + }
  210 + catch (Exception $e)
217 211 {
218 212 return array(
219 213 "status_code" => 1,
220   - "message" => "Failed getting object type definition for $typeId"
  214 + "message" => $e->getMessage()
221 215 );
222 216 }
223 217  
... ... @@ -358,6 +352,66 @@ class KTNavigationService extends KTCMISBase {
358 352 );
359 353 }
360 354  
  355 + /**
  356 + * Gets the parents for the selected object
  357 + *
  358 + * @param string $repositoryId
  359 + * @param string $folderId
  360 + * @param boolean $includeAllowableActions
  361 + * @param boolean $includeRelationships
  362 + * @param string $filter
  363 + * @return ancestry[]
  364 + */
  365 + function getObjectParents($repositoryId, $objectId, $includeAllowableActions, $includeRelationships, $filter = '')
  366 + {
  367 + $ancestryResult = $this->NavigationService->getObjectParents($repositoryId, $objectId, $includeAllowableActions,
  368 + $includeRelationships);
  369 +
  370 + if (PEAR::isError($ancestryResult))
  371 + {
  372 + return array(
  373 + "status_code" => 1,
  374 + "message" => "Failed getting ancestry for object"
  375 + );
  376 + }
  377 +
  378 + $ancestry = CMISUtil::decodeObjectHierarchy($ancestryResult, 'child');
  379 +
  380 + return array(
  381 + "status_code" => 0,
  382 + "results" => $ancestry
  383 + );
  384 + }
  385 +
  386 + /**
  387 + * Returns a list of checked out documents from the selected repository
  388 + *
  389 + * @param string $repositoryId
  390 + * @param string $folderId The folder for which checked out docs are requested
  391 + * @param string $filter
  392 + * @param int $maxItems
  393 + * @param int $skipCount
  394 + * @return array $checkedout The collection of checked out documents
  395 + */
  396 + function getCheckedoutDocs($repositoryId, $folderId = null, $filter = '', $maxItems = 0, $skipCount = 0)
  397 + {
  398 + $checkedout = $this->NavigationService->getObjectParents($repositoryId, $objectId, $includeAllowableActions,
  399 + $includeRelationships);
  400 +
  401 + if (PEAR::isError($ancestryResult))
  402 + {
  403 + return array(
  404 + "status_code" => 1,
  405 + "message" => "Failed getting list of checked out documents"
  406 + );
  407 + }
  408 +
  409 + return array(
  410 + "status_code" => 0,
  411 + "results" => $checkedout
  412 + );
  413 + }
  414 +
361 415 }
362 416  
363 417 /**
... ... @@ -393,13 +447,15 @@ class KTObjectService extends KTCMISBase {
393 447 public function getProperties($repositoryId, $objectId, $includeAllowableActions, $includeRelationships,
394 448 $returnVersion = false, $filter = '')
395 449 {
396   - $propertyCollection = $this->ObjectService->getProperties($repositoryId, $objectId, $includeAllowableActions, $includeRelationships);
397   -
398   - if (PEAR::isError($propertiesResult))
  450 + try {
  451 + $propertyCollection = $this->ObjectService->getProperties($repositoryId, $objectId, $includeAllowableActions,
  452 + $includeRelationships);
  453 + }
  454 + catch (Exception $e)
399 455 {
400 456 return array(
401 457 "status_code" => 1,
402   - "message" => "Failed getting properties for object"
  458 + "message" => $e->getMessage()
403 459 );
404 460 }
405 461  
... ... @@ -411,6 +467,36 @@ class KTObjectService extends KTCMISBase {
411 467 );
412 468 }
413 469  
  470 + /**
  471 + * Function to create a folder
  472 + *
  473 + * @param string $repositoryId The repository to which the folder must be added
  474 + * @param string $typeId Object Type id for the folder object being created
  475 + * @param array $properties Array of properties which must be applied to the created folder object
  476 + * @param string $folderId The id of the folder which will be the parent of the created folder object
  477 + * @return string $objectId The id of the created folder object
  478 + */
  479 + function createFolder($repositoryId, $typeId, $properties, $folderId)
  480 + {
  481 + $objectId = null;
  482 +
  483 + try {
  484 + $objectId = $this->ObjectService->createFolder($repositoryId, $typeId, $properties, $folderId);
  485 + }
  486 + catch (Exception $e)
  487 + {
  488 + return array(
  489 + "status_code" => 1,
  490 + "message" => $e->getMessage()
  491 + );
  492 + }
  493 +
  494 + return array(
  495 + 'status_code' => 0,
  496 + 'results' => $objectId
  497 + );
  498 + }
  499 +
414 500 }
415 501  
416 502 ?>
... ...
lib/api/ktcmis/objecttypes/CMISDocumentObject.inc.php
... ... @@ -54,7 +54,7 @@ class CMISDocumentObject extends CMISBaseObject {
54 54 private $uri;
55 55  
56 56 // TODO some of this should probably come from configuration files as it is repository specific
57   - function CMISDocumentObject(&$ktapi = null, $uri = null)
  57 + function __construct($documentId = null, &$ktapi = null, $uri = null)
58 58 {
59 59 $this->ktapi = $ktapi;
60 60 // uri to use for document links
... ... @@ -92,12 +92,16 @@ class CMISDocumentObject extends CMISBaseObject {
92 92 // parent::__construct();
93 93  
94 94 // set document specific property definitions
95   -
  95 +
  96 + if (!is_null($documentId))
  97 + {
  98 + $this->_get($documentId);
  99 + }
96 100 }
97 101  
98   - function get($objectId)
  102 + private function _get($documentId)
99 103 {
100   - $object = $this->ktapi->get_document_by_id($objectId);
  104 + $object = $this->ktapi->get_document_by_id($documentId);
101 105  
102 106 // error?
103 107 if (PEAR::isError($object))
... ...
lib/api/ktcmis/objecttypes/CMISFolderObject.inc.php
... ... @@ -49,7 +49,7 @@ class CMISFolderObject extends CMISBaseObject {
49 49 var $ktapi;
50 50 var $uri;
51 51  
52   - function CMISFolderObject(&$ktapi = null, $uri = null)
  52 + function __construct($folderId = null, &$ktapi = null, $uri = null)
53 53 {
54 54 $this->ktapi = $ktapi;
55 55 $this->uri = $uri;
... ... @@ -69,11 +69,16 @@ class CMISFolderObject extends CMISBaseObject {
69 69  
70 70 // properties
71 71 $this->properties = new CMISFolderPropertyCollection();
  72 +
  73 + if (!is_null($folderId))
  74 + {
  75 + $this->_get($folderId);
  76 + }
72 77 }
73 78  
74   - function get($objectId)
  79 + private function _get($folderId)
75 80 {
76   - $object = $this->ktapi->get_folder_by_id($objectId);
  81 + $object = $this->ktapi->get_folder_by_id($folderId);
77 82  
78 83 // error?
79 84 if (PEAR::isError($object))
... ...
lib/api/ktcmis/services/CMISNavigationService.inc.php
... ... @@ -40,7 +40,6 @@
40 40 * @version Version 0.1
41 41 */
42 42  
43   -// really wanted to keep KT code out of here but I don't see how
44 43 require_once(KT_DIR . '/ktapi/ktapi.inc.php');
45 44 require_once(CMIS_DIR . '/util/CMISUtil.inc.php');
46 45  
... ... @@ -75,7 +74,6 @@ class CMISNavigationService {
75 74 // NOTE If the Repository supports the optional โ€œVersionSpecificFilingโ€ capability,
76 75 // then the repository SHALL return the document versions filed in the specified folder or its descendant folders.
77 76 // Otherwise, the latest version of the documents SHALL be returned.
78   -
79 77 // TODO FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid
80 78 function getDescendants($repositoryId, $folderId, $includeAllowableActions, $includeRelationships,
81 79 $depth = 1, $typeId = 'Any', $filter = '')
... ... @@ -156,8 +154,8 @@ class CMISNavigationService {
156 154 * @return array $ancestry
157 155 */
158 156 // TODO FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid
  157 + // TODO If this service method is invoked on the root folder of the Repository, then the Repository SHALL return an empty result set.
159 158 // NOTE SHOULD always include the โ€œObjectIdโ€ and โ€œParentIdโ€ properties for all objects returned
160   - // NOTE If this service method is invoked on the root folder of the Repository, then the Repository shall return an empty result set.
161 159 function getFolderParent($repositoryId, $folderId, $includeAllowableActions, $includeRelationships, $returnToRoot, $filter = '')
162 160 {
163 161 $ancestry = array();
... ... @@ -217,7 +215,7 @@ class CMISNavigationService {
217 215 * @return array $parents
218 216 */
219 217 // TODO ConstraintViolationException: The Repository SHALL throw this exception if this method is invoked
220   - // on an object who Object-Type Defintion specifies that it is not fileable.
  218 + // on an object who Object-Type Definition specifies that it is not fileable.
221 219 // FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid.
222 220 function getObjectParents($repositoryId, $objectId, $includeAllowableActions, $includeRelationships, $filter = '')
223 221 {
... ... @@ -245,6 +243,26 @@ class CMISNavigationService {
245 243 return $ancestry;
246 244 }
247 245  
  246 + /**
  247 + * Returns a list of checked out documents from the selected repository
  248 + *
  249 + * @param string $repositoryId
  250 + * @param string $folderId The folder for which checked out docs are requested
  251 + * @param string $filter
  252 + * @param int $maxItems
  253 + * @param int $skipCount
  254 + * @return array $checkedout The collection of checked out documents
  255 + */
  256 + // NOTE NOT YET IMPLEMENTED (this function is just a place holder at the moment :))
  257 + function getCheckedoutDocs($repositoryId, $folderId = null, $filter = '', $maxItems = 0, $skipCount = 0)
  258 + {
  259 + $checkedout = array();
  260 +
  261 +
  262 +
  263 + return $checkedout();
  264 + }
  265 +
248 266 }
249 267  
250 268 ?>
... ...
lib/api/ktcmis/services/CMISObjectService.inc.php
1 1 <?php
2 2  
3   -// really wanted to keep KT code out of here but I don't see how
4 3 require_once(KT_DIR . '/ktapi/ktapi.inc.php');
  4 +require_once(CMIS_DIR . '/exceptions/ConstraintViolationException.inc.php');
  5 +require_once(CMIS_DIR . '/exceptions/ObjectNotFoundException.inc.php');
  6 +require_once(CMIS_DIR . '/exceptions/StorageException.inc.php');
  7 +require_once(CMIS_DIR . '/services/CMISRepositoryService.inc.php');
5 8 require_once(CMIS_DIR . '/objecttypes/CMISDocumentObject.inc.php');
6 9 require_once(CMIS_DIR . '/objecttypes/CMISFolderObject.inc.php');
7 10 require_once(CMIS_DIR . '/classes/CMISRepository.inc.php');
... ... @@ -44,22 +47,85 @@ class CMISObjectService {
44 47  
45 48 $typeId = CMISUtil::decodeObjectId($objectId);
46 49  
  50 + if ($typeId == 'Unknown')
  51 + {
  52 + throw new ObjectNotFoundException('The type of the requested object could not be determined');
  53 + }
  54 +
47 55 switch($typeId)
48 56 {
49 57 case 'Document':
50   - $CMISObject = new CMISDocumentObject($this->ktapi, $repository->getRepositoryURI());
  58 + $CMISObject = new CMISDocumentObject($objectId, $this->ktapi, $repository->getRepositoryURI());
51 59 break;
52 60 case 'Folder':
53   - $CMISObject = new CMISFolderObject($this->ktapi, $repository->getRepositoryURI());
  61 + $CMISObject = new CMISFolderObject($objectId, $this->ktapi, $repository->getRepositoryURI());
54 62 break;
55 63 }
56 64  
57   - $CMISObject->get($objectId);
58 65 $properties = $CMISObject->getProperties();
59 66  
60 67 return $properties;
61 68 }
62 69  
  70 + /**
  71 + * Function to create a folder
  72 + *
  73 + * @param string $repositoryId The repository to which the folder must be added
  74 + * @param string $typeId Object Type id for the folder object being created
  75 + * @param array $properties Array of properties which must be applied to the created folder object
  76 + * @param string $folderId The id of the folder which will be the parent of the created folder object
  77 + * @return string $objectId The id of the created folder object
  78 + */
  79 + // TODO throw ConstraintViolationException if:
  80 + // value of any of the properties violates the min/max/required/length constraints
  81 + // specified in the property definition in the Object-Type.
  82 + function createFolder($repositoryId, $typeId, $properties, $folderId)
  83 + {
  84 + // fetch type definition of supplied type and check for base type "folder", if not true throw exception
  85 + $RepositoryService = new CMISRepositoryService();
  86 + try {
  87 + $typeDefinition = $RepositoryService->getTypeDefinition($repositoryId, $typeId);
  88 + }
  89 + catch (Exception $e)
  90 + {
  91 + throw new ConstraintViolationException('Object is not of base type folder.');
  92 + }
  93 +
  94 + if ($typeDefinition['attributes']['baseType'] != 'folder')
  95 + {
  96 + throw new ConstraintViolationException('Object is not of base type folder');
  97 + }
  98 +
  99 + // TODO determine whether this is in fact necessary or if we should require decoding in the calling code
  100 + // Attempt to decode $folderId, use as is if not detected as encoded
  101 + $objectId = $folderId;
  102 + $tmpTypeId = CMISUtil::decodeObjectId($objectId);
  103 + if ($tmpTypeId != 'Unknown')
  104 + $folderId = $objectId;
  105 +
  106 + // if parent folder is not allowed to hold this type, throw exception
  107 + $CMISFolder = new CMISFolderObject($folderId, $this->ktapi);
  108 + $folderProperties = $CMISFolder->getProperties();
  109 + $allowed = $folderProperties->getValue('AllowedChildObjectTypeIds');
  110 + if (!is_array($allowed) || !in_array($typeId, $allowed))
  111 + {
  112 + throw new ConstraintViolationException('Parent folder may not hold objects of this type (' . $typeId . ')');
  113 + }
  114 +
  115 + $response = $this->ktapi->create_folder($folderId, $properties['name'], $sig_username = '', $sig_password = '', $reason = '');
  116 + if ($response['status_code'] != 0)
  117 + {
  118 + // throw storageException
  119 + throw new StorageException('The repository was unable to create the folder - ' . $response['message']);
  120 + }
  121 + else
  122 + {
  123 + $objectId = CMISUtil::encodeObjectId('Folder', $response['results']['id']);
  124 + }
  125 +
  126 + return $objectId;
  127 + }
  128 +
63 129 }
64 130  
65 131 ?>
... ...
lib/api/ktcmis/services/CMISRepositoryService.inc.php
... ... @@ -43,6 +43,7 @@
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');
46 47  
47 48 /**
48 49 * CMIS Repository Service.
... ... @@ -98,10 +99,21 @@ class CMISRepositoryService {
98 99 * @return array $objectTypes
99 100 */
100 101 // NOTE this code may fit better within the Repository Class
  102 + // TODO return for specific type when $typeId is specified
  103 + // TODO other optional parameters
101 104 function getTypes($repositoryId, $typeId = '', $returnPropertyDefinitions = false,
102 105 $maxItems = 0, $skipCount = 0, &$hasMoreItems = false)
103 106 {
104   - // TODO throw invalidArgumentException if invalid typeId submitted
  107 + if ($typeId != '')
  108 + {
  109 + try {
  110 + $typeDefinition = $this->getTypeDefinition($repositoryId, $typeId);
  111 + }
  112 + catch (Exception $e)
  113 + {
  114 + throw new InvalidArgumentException('Type ' . $typeId . ' is not supported');
  115 + }
  116 + }
105 117  
106 118 $repository = new CMISRepository($repositoryId);
107 119 $supportedTypes = $repository->getTypes();
... ... @@ -140,15 +152,24 @@ class CMISRepositoryService {
140 152 * @param string $typeId The ID of the object type requested
141 153 * @return $array $typeDefinition
142 154 */
  155 + // NOTE this code may fit better in the Repository Class
143 156 function getTypeDefinition($repositoryId, $typeId)
144 157 {
  158 + $object = 'CMIS' . $typeId . 'Object';
  159 +
  160 + // check whether the object type exists, return error if not
  161 + // consider throwing an exception instead (see General Exceptions)
  162 + if (!file_exists(CMIS_DIR . '/objecttypes/' . $object . '.inc.php'))
  163 + {
  164 + throw new InvalidArgumentException('Type ' . $typeId . ' is not supported');
  165 + }
  166 +
145 167 $typeDefinition = array();
146 168  
147   - require_once(CMIS_DIR . '/objecttypes/CMIS' . $typeId . 'Object.inc.php');
148   - $object = 'CMIS' . $typeId . 'Object';
149   - $tmpObject = new $object;
150   - $typeDefinition['attributes'] = $tmpObject->getAttributes();
151   - $typeDefinition['properties'] = $tmpObject->getProperties();
  169 + require_once(CMIS_DIR . '/objecttypes/' . $object . '.inc.php');
  170 + $cmisObject = new $object;
  171 + $typeDefinition['attributes'] = $cmisObject->getAttributes();
  172 + $typeDefinition['properties'] = $cmisObject->getProperties();
152 173  
153 174 return $typeDefinition;
154 175 }
... ...
lib/api/ktcmis/util/CMISUtil.inc.php
... ... @@ -133,14 +133,13 @@ class CMISUtil {
133 133 switch($object['item_type'])
134 134 {
135 135 case 'D':
136   - $CMISObject = new CMISDocumentObject($ktapi, $repositoryURI);
  136 + $CMISObject = new CMISDocumentObject($object['id'], $ktapi, $repositoryURI);
137 137 break;
138 138 case 'F':
139   - $CMISObject = new CMISFolderObject($ktapi, $repositoryURI);
  139 + $CMISObject = new CMISFolderObject($object['id'], $ktapi, $repositoryURI);
140 140 break;
141 141 }
142 142  
143   - $CMISObject->get($object['id']);
144 143 $CMISArray[$count]['object'] = $CMISObject;
145 144  
146 145 // if sub-array
... ... @@ -184,8 +183,7 @@ class CMISUtil {
184 183  
185 184 if (isset($detail['id']))
186 185 {
187   - $CMISObject = new CMISFolderObject($ktapi, $repositoryURI);
188   - $CMISObject->get($detail['id']);
  186 + $CMISObject = new CMISFolderObject($detail['id'], $ktapi, $repositoryURI);
189 187 $CMISElement['object'] = $CMISObject;
190 188  
191 189 // if more parent elements
... ...
resources/css/kt-framing.css
... ... @@ -38,8 +38,8 @@ body
38 38 width: 80%;
39 39 min-height: 200px;
40 40 position: relative;
41   - top:100;
42   - left:100;
  41 + top:100px;
  42 + left:100px;
43 43 }
44 44  
45 45 #pageBody {
... ... @@ -52,9 +52,9 @@ body
52 52 min-height: 800px;
53 53 min-width: 600px;
54 54 height: auto;
55   -/* background-image: url(../../resources/graphics/page_bg.png);*/
  55 + /*background-image: url(../../resources/graphics/page_bg.gif);*/
56 56 /* background-repeat: repeat-x;*/
57   - z-index: 1;
  57 + z-index: 0;
58 58 }
59 59  
60 60 #bodyPad {
... ... @@ -1066,11 +1066,13 @@ a.main_nav_item {
1066 1066 position: relative;
1067 1067 padding: 0.1em 1em;
1068 1068 margin: 1em 0 0 0.5em;
  1069 + z-index:0; /*Added to accomadate pageBody background change*/
1069 1070 }
1070 1071  
1071 1072  
1072 1073 .ktInfo, .ktError {
1073 1074 position: relative;
  1075 + z-index:0; /*Added to accomadate pageBody background change*/
1074 1076 }
1075 1077  
1076 1078 #dashboardBox {
... ...
tests/ktcmis/testCmisApi.php
1 1 <?php
2 2 require_once (KT_DIR . '/tests/test.php');
3   -require_once (KT_DIR . '/ktcmis/ktcmis.inc.php');
  3 +require_once (KT_LIB_DIR . '/api/ktcmis/ktcmis.inc.php');
4 4  
5 5 // username and password for authentication
6 6 // must be set correctly for all of the tests to pass in all circumstances
7 7 define (KT_TEST_USER, 'admin');
8 8 define (KT_TEST_PASS, 'admin');
9 9  
  10 +// set to true to print out results
  11 +define (DEBUG_CMIS, false);
  12 +
10 13 /**
11 14 * These are the unit tests for the main KTCMIS class
12 15 *
... ... @@ -44,7 +47,6 @@ class CMISTestCase extends KTUnitTestCase {
44 47 public function setUp() {
45 48 $this->ktapi = new KTAPI();
46 49 $this->session = $this->ktapi->start_session(KT_TEST_USER, KT_TEST_PASS);
47   - $this->ktcmis = new KTCMIS($this->ktapi);
48 50 $this->root = $this->ktapi->get_root_folder();
49 51 $this->folders = array();
50 52 $this->docs = array();
... ... @@ -60,9 +62,11 @@ class CMISTestCase extends KTUnitTestCase {
60 62 // Repository service functions
61 63 function testRepositoryServices()
62 64 {
  65 + $RepositoryService = new KTRepositoryService();
  66 +
63 67 // TEST 1
64 68 // test get repositories
65   - $response = $this->ktcmis->getRepositories();
  69 + $response = $RepositoryService->getRepositories();
66 70  
67 71 $this->assertEqual($response['status_code'], 0);
68 72 $this->assertNotNull($response['results'][0]);
... ... @@ -91,7 +95,7 @@ class CMISTestCase extends KTUnitTestCase {
91 95 // test getting info for specified repository
92 96  
93 97 // get info
94   - $response = $this->ktcmis->getRepositoryInfo($repositoryId);
  98 + $response = $RepositoryService->getRepositoryInfo($repositoryId);
95 99  
96 100 $this->assertEqual($response['status_code'], 0);
97 101 $this->assertNotNull($response['results']);
... ... @@ -119,7 +123,7 @@ class CMISTestCase extends KTUnitTestCase {
119 123 // TEST 3
120 124 // test get object types supported by specified repository
121 125  
122   - $response = $this->ktcmis->getTypes($repositoryId);
  126 + $response = $RepositoryService->getTypes($repositoryId);
123 127  
124 128 $this->assertEqual($response['status_code'], 0);
125 129 $this->assertNotNull($response['results']);
... ... @@ -148,7 +152,7 @@ class CMISTestCase extends KTUnitTestCase {
148 152 // now get info
149 153 foreach ($types as $typeId)
150 154 {
151   - $response = $this->ktcmis->getTypeDefinition($repositoryId, $typeId);
  155 + $response = $RepositoryService->getTypeDefinition($repositoryId, $typeId);
152 156  
153 157 $this->assertEqual($response['status_code'], 0);
154 158 $this->assertNotNull($response['results']);
... ... @@ -169,18 +173,20 @@ class CMISTestCase extends KTUnitTestCase {
169 173 }
170 174  
171 175 // test printout
172   - echo '<div>&nbsp;</div>';
  176 + if (DEBUG_CMIS) echo '<div>&nbsp;</div>';
173 177 }
174 178  
175 179 // Navigation service functions
176 180 function testNavigationServices()
177 181 {
  182 + $NavigationService = new KTNavigationService();
  183 + $NavigationService->startSession(KT_TEST_USER, KT_TEST_PASS);
  184 +
178 185 // set up the folder/doc tree structure with which we will be testing
179 186 $this->createFolderDocStructure();
180 187  
181   - // TEST 1
182   - // test getting descendants
183   - $response = $this->ktcmis->getRepositories();
  188 + $RepositoryService = new KTRepositoryService();
  189 + $response = $RepositoryService->getRepositories();
184 190  
185 191 $this->assertEqual($response['status_code'], 0);
186 192 $this->assertNotNull($response['results'][0]);
... ... @@ -189,12 +195,15 @@ class CMISTestCase extends KTUnitTestCase {
189 195 $repository = $response['results'][0];
190 196 $repositoryId = $repository['repositoryId'];
191 197  
  198 + // TEST 1
  199 + // test getting descendants
192 200 // test descendant functionality on first of created folders, should have depth 2;
193 201 $folderid = 'F' . $this->folders[1];
  202 +// echo "FOLDER: $folderid<BR>";
194 203 // $folderid = 'F1';
195 204  
196 205 $depth = 2;
197   - $result = $this->ktcmis->getDescendants($repositoryId, $folderid, false, false, $depth);
  206 + $result = $NavigationService->getDescendants($repositoryId, $folderid, false, false, $depth);
198 207 // echo '<pre>'.print_r($result, true).'</pre>';
199 208 // var_dump($result);
200 209 $this->assertEqual($response['status_code'], 0);
... ... @@ -217,7 +226,7 @@ class CMISTestCase extends KTUnitTestCase {
217 226 // test getting direct children, using the second set of folders, should have a folder and a document as children
218 227 $folderid_2 = 'F' . $this->folders[0];
219 228  
220   - $result = $this->ktcmis->getChildren($repositoryId, $folderid_2, false, false);
  229 + $result = $NavigationService->getChildren($repositoryId, $folderid_2, false, false);
221 230 $this->assertNotNull($result['results']);
222 231  
223 232 $children = $result['results'];
... ... @@ -234,7 +243,7 @@ class CMISTestCase extends KTUnitTestCase {
234 243 // test getting folder parent, using first created folder, parent should be root folder
235 244  
236 245 // echo "OUTPUT FROM FIRST TEST<BR>";
237   - $ancestry = $this->ktcmis->getFolderParent($repositoryId, $folderid, false, false, false);
  246 + $ancestry = $NavigationService->getFolderParent($repositoryId, $folderid, false, false, false);
238 247 $this->assertNotNull($ancestry['results']);
239 248 // echo "OUTPUT FROM FIRST TEST<BR>";
240 249 // echo '<pre>'.print_r($ancestry, true).'</pre>';
... ... @@ -247,7 +256,7 @@ class CMISTestCase extends KTUnitTestCase {
247 256  
248 257 // echo "OUTPUT FROM SECOND TEST<BR>";
249 258 // TODO since here we are testing more than one level up, add check for depth as with testGetDescendants
250   - $ancestry = $this->ktcmis->getFolderParent($repositoryId, $subfolder_id, false, false, true);
  259 + $ancestry = $NavigationService->getFolderParent($repositoryId, $subfolder_id, false, false, true);
251 260 $this->assertNotNull($ancestry['results']);
252 261 // echo "OUTPUT FROM SECOND TEST<BR>";
253 262 // echo '<pre>'.print_r($ancestry, true).'</pre>';
... ... @@ -262,7 +271,7 @@ class CMISTestCase extends KTUnitTestCase {
262 271 // test getting object parent(s) with a document
263 272  
264 273 $objectId = 'D' . $this->docs[0]->get_documentid();
265   - $ancestry = $this->ktcmis->getObjectParents($repositoryId, $objectId, false, false);
  274 + $ancestry = $NavigationService->getObjectParents($repositoryId, $objectId, false, false);
266 275 $this->assertNotNull($ancestry);
267 276 // echo '<pre>'.print_r($ancestry, true).'</pre>';
268 277  
... ... @@ -273,7 +282,7 @@ class CMISTestCase extends KTUnitTestCase {
273 282 // test getting object parent(s) with a folder
274 283  
275 284 $objectId = 'F' . $this->subfolders[0];
276   - $ancestry = $this->ktcmis->getObjectParents($repositoryId, $objectId, false, false);
  285 + $ancestry = $NavigationService->getObjectParents($repositoryId, $objectId, false, false);
277 286 $this->assertNotNull($ancestry);
278 287 // echo '<pre>'.print_r($ancestry, true).'</pre>';
279 288  
... ... @@ -284,20 +293,21 @@ class CMISTestCase extends KTUnitTestCase {
284 293 $this->cleanupFolderDocStructure();
285 294  
286 295 // test printout
287   - echo '<div>&nbsp;</div>';
  296 + if (DEBUG_CMIS) echo '<div>&nbsp;</div>';
288 297 }
289 298  
290 299 // Object Services
291 300  
292 301 function testObjectServices()
293 302 {
  303 + $ObjectService = new KTObjectService();
  304 + $ObjectService->startSession(KT_TEST_USER, KT_TEST_PASS);
  305 +
294 306 // set up the folder/doc tree structure with which we will be testing
295 307 $this->createFolderDocStructure();
296   -
297   - // TEST 1
298   - // test getting properties for a specific object
299 308  
300   - $response = $this->ktcmis->getRepositories();
  309 + $RepositoryService = new KTRepositoryService();
  310 + $response = $RepositoryService->getRepositories();
301 311  
302 312 $this->assertEqual($response['status_code'], 0);
303 313 $this->assertNotNull($response['results'][0]);
... ... @@ -305,10 +315,12 @@ class CMISTestCase extends KTUnitTestCase {
305 315 // we only expect one repository
306 316 $repository = $response['results'][0];
307 317 $repositoryId = $repository['repositoryId'];
308   -
  318 +
  319 + // TEST 1
  320 + // test getting properties for a specific object
309 321 $objectId = 'F'.$this->folders[0];
310 322  
311   - $properties = $this->ktcmis->getProperties($repositoryId, $objectId, false, false);
  323 + $properties = $ObjectService->getProperties($repositoryId, $objectId, false, false);
312 324 $this->assertNotNull($properties['results']);
313 325 // echo '<pre>'.print_r($properties['results'], true).'</pre>';
314 326 //
... ... @@ -317,17 +329,41 @@ class CMISTestCase extends KTUnitTestCase {
317 329  
318 330 $objectId = 'D'.$this->docs[0]->get_documentid();
319 331  
320   - $properties = $this->ktcmis->getProperties($repositoryId, $objectId, false, false);
  332 + $properties = $ObjectService->getProperties($repositoryId, $objectId, false, false);
321 333 $this->assertNotNull($properties['results']);
322 334  
323 335 // test printout
324 336 $this->printTable($properties['results'][0], 'Properties for Folder Object ' . $objectId . ' (getProperties())');
325 337  
  338 + // TEST 2
  339 + // test creation of a folder (random name so that we don't have to clean up after)
  340 + // TODO test invalid type
  341 + // TODO test invalid parent folder
  342 + // TODO other invalid parameters
  343 + $created = $ObjectService->createFolder($repositoryId, 'Folder', array('name' => 'My Test Folder ' . mt_rand()), 'F1');
  344 + $this->assertNotNull($created['results']);
  345 +
  346 + if (!is_null($created['results']))
  347 + {
  348 + $folderId = $created['results'];
  349 +
  350 + // check that folder object actually exists
  351 + $properties = $ObjectService->getProperties($repositoryId, $folderId, false, false);
  352 + $this->assertNotNull($properties['results']);
  353 +
  354 + // test printout
  355 + $this->printTable($properties['results'][0], 'Properties for CMIS Created Folder Object ' . $folderId . ' (getProperties())');
  356 +
  357 + // delete
  358 + CMISUtil::decodeObjectId($folderId);
  359 + $this->ktapi->delete_folder($folderId, 'Testing API', KT_TEST_USER, KT_TEST_PASS);
  360 + }
  361 +
326 362 // tear down the folder/doc tree structure with which we were testing
327 363 $this->cleanupFolderDocStructure();
328 364  
329 365 // test printout
330   - echo '<div>&nbsp;</div>';
  366 + if (DEBUG_CMIS) echo '<div>&nbsp;</div>';
331 367 }
332 368  
333 369 /**
... ... @@ -493,8 +529,9 @@ class CMISTestCase extends KTUnitTestCase {
493 529  
494 530 function printTable($results, $header, $subheader = '', $depth = 1)
495 531 {
496   - // turn off for testing :)
497   -// return null;
  532 + if (!DEBUG_CMIS) return null;
  533 + if (!is_array($results)) return null;
  534 +
498 535 ?><div>&nbsp;</div>
499 536 <table border="2"><tr><td colspan="2"><div style="padding: 8px; background-color: green; color: white;"><?php
500 537 echo $header;
... ... @@ -542,6 +579,9 @@ class CMISTestCase extends KTUnitTestCase {
542 579  
543 580 function printTree($results, $header, $depth = 1)
544 581 {
  582 + if (!DEBUG_CMIS) return null;
  583 + if (!is_array($results)) return null;
  584 +
545 585 ?><div>&nbsp;</div>
546 586 <table border="2"><tr><td colspan="<?php echo 1 + $depth; ?>"><div style="padding: 8px; background-color: green; color: white;"><?php
547 587 echo $header;
... ...