Commit 9fa9c1c979ebca7cc657786aa3de0424b4962a8f

Authored by Paul Barrett
1 parent 8c4b9b73

Update getTypeDefinition

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

Committed by: Paul Barrett
lib/api/ktcmis/classes/CMISObject.inc.php
... ... @@ -78,6 +78,9 @@ abstract class CMISObject {
78 78  
79 79 public function __construct()
80 80 {
  81 + // set properties shared by all objects of this type
  82 + $this->_setSharedProperties();
  83 +
81 84 // $propertyDef = new PropertyDefinition();
82 85 // $this->properties[] = $propertyDef;
83 86 }
... ... @@ -159,6 +162,16 @@ abstract class CMISObject {
159 162 {
160 163 // override in child classes
161 164 }
  165 +
  166 + /**
  167 + * Sets properties which are shared between all objects of this type
  168 + */
  169 + protected function _setSharedProperties()
  170 + {
  171 + $this->_setPropertyInternal('objectTypeId', strtolower($this->getAttribute('id')));
  172 + // Needed to distinguish type
  173 + $this->_setPropertyInternal('baseTypeId', strtolower($this->getAttribute('id')));
  174 + }
162 175  
163 176 }
164 177  
... ...
lib/api/ktcmis/ktRepositoryService.inc.php
... ... @@ -165,25 +165,14 @@ class KTRepositoryService extends KTCMISBase {
165 165 public function getTypeDefinition($repositoryId, $typeId)
166 166 {
167 167 try {
168   - $typeDefinitionResult = $this->RepositoryService->getTypeDefinition($repositoryId, $typeId);
  168 + $typeDefinition = $this->RepositoryService->getTypeDefinition($repositoryId, $typeId);
169 169 }
170   - catch (Exception $e)
171   - {
172   - return array(
173   - "status_code" => 1,
174   - "message" => $e->getMessage()
175   - );
  170 + catch (Exception $e) {
  171 + // propogate upward
  172 + throw $e;
176 173 }
177   -
178   - // format as array style output
179   - // NOTE only concerned with attributes at this time
180   - // TODO add support for properties
181   - $typeDefinition = $typeDefinitionResult['attributes'];
182   -
183   - return array (
184   - "status_code" => 0,
185   - "results" => $typeDefinition
186   - );
  174 +
  175 + return $typeDefinition;
187 176 }
188 177  
189 178 }
... ...
lib/api/ktcmis/objecttypes/CMISDocumentObject.inc.php
... ... @@ -98,7 +98,7 @@ class CMISDocumentObject extends CMISObject {
98 98 }
99 99 }
100 100  
101   - // TODO throw exception if unable to create?
  101 + parent::__construct();
102 102 }
103 103  
104 104 // TODO abstract shared stuff to base class where possible
... ... @@ -124,10 +124,6 @@ class CMISDocumentObject extends CMISObject {
124 124 // also ktapidocument::get_download_url
125 125 // $this->_setPropertyInternal('uri', $uri);
126 126 $this->_setPropertyInternal('uri', '');
127   - // TODO what is this? Assuming it is the object type id, and not OUR document type?
128   - $this->_setPropertyInternal('objectTypeId', strtolower($this->getAttribute('id')));
129   - // Needed to distinguish type
130   - $this->_setPropertyInternal('baseTypeId', strtolower($this->getAttribute('id')));
131 127 $this->_setPropertyInternal('createdBy', $objectProperties['created_by']);
132 128 $this->_setPropertyInternal('creationDate', $objectProperties['created_date']);
133 129 $this->_setPropertyInternal('lastModifiedBy', $objectProperties['modified_by']);
... ...
lib/api/ktcmis/objecttypes/CMISFolderObject.inc.php
... ... @@ -85,6 +85,8 @@ class CMISFolderObject extends CMISObject {
85 85 throw new ObjectNotFoundException($e->getMessage());
86 86 }
87 87 }
  88 +
  89 + parent::__construct();
88 90 }
89 91  
90 92 // TODO abstract shared stuff to base class where possible
... ... @@ -111,10 +113,6 @@ class CMISFolderObject extends CMISObject {
111 113 // TODO this url is probably incorrect...needs to be checked
112 114 // $this->_setPropertyInternal('uri', $uri);
113 115 $this->_setPropertyInternal('uri', '');
114   - // TODO what is this? Assuming it is the object type id, and not OUR document type?
115   - $this->_setPropertyInternal('objectTypeId', strtolower($this->getAttribute('id')));
116   - // Needed to distinguish type
117   - $this->_setPropertyInternal('baseTypeId', strtolower($this->getAttribute('id')));
118 116 $this->_setPropertyInternal('createdBy', $objectProperties['created_by']);
119 117 // TODO cannot currently retrieve via ktapi or regular folder code - add as with created by
120 118 $this->_setPropertyInternal('creationDate', $objectProperties['created_date']);
... ... @@ -125,9 +123,17 @@ class CMISFolderObject extends CMISObject {
125 123 $this->_setPropertyInternal('changeToken', null);
126 124 $this->_setPropertyInternal('name', $objectProperties['folder_name']);
127 125 $this->_setPropertyInternal('parentId', CMISUtil::encodeObjectId(FOLDER, $objectProperties['parent_id']));
128   - $this->_setPropertyInternal('allowedChildObjectTypeIds', array('cmis:document', 'cmis:folder'));
129 126 $this->_setPropertyInternal('author', $objectProperties['created_by']);
130 127 }
  128 +
  129 + /**
  130 + * Sets properties shared between all objects of this type
  131 + */
  132 + protected function _setSharedProperties()
  133 + {
  134 + parent::_setSharedProperties();
  135 + $this->_setPropertyInternal('allowedChildObjectTypeIds', array('cmis:document', 'cmis:folder'));
  136 + }
131 137  
132 138 }
133 139  
... ...
lib/api/ktcmis/services/CMISRepositoryService.inc.php
... ... @@ -160,13 +160,15 @@ class CMISRepositoryService {
160 160 // NOTE this code may fit better in the Repository Class
161 161 function getTypeDefinition($repositoryId, $typeId)
162 162 {
  163 + global $default;
  164 + $default->log->debug();
  165 + $default->log->info(str_replace('cmis:', '', $typeId));
163 166 $typeId = ucwords(str_replace('cmis:', '', $typeId));
164 167 $object = 'CMIS' . $typeId . 'Object';
165 168  
166 169 // check whether the object type exists, return error if not
167 170 // consider throwing an exception instead (see General Exceptions)
168   - if (!file_exists(CMIS_DIR . '/objecttypes/' . $object . '.inc.php'))
169   - {
  171 + if (!file_exists(CMIS_DIR . '/objecttypes/' . $object . '.inc.php')) {
170 172 throw new InvalidArgumentException('Type ' . $typeId . ' is not supported');
171 173 }
172 174  
... ... @@ -174,8 +176,11 @@ class CMISRepositoryService {
174 176  
175 177 require_once(CMIS_DIR . '/objecttypes/' . $object . '.inc.php');
176 178 $cmisObject = new $object;
177   - $typeDefinition['attributes'] = $cmisObject->getAttributes();
178   - $typeDefinition['properties'] = $cmisObject->getProperties();
  179 +
  180 + // NOTE The specification is ambigous here: it states that this function must return the type properties, but
  181 + // the atompub example shows the type attributes, not properties; since most properties are only populated
  182 + // on creation of an instance of an object-type, we choose to go with the attributes and not the properties
  183 + $typeDefinition = $cmisObject->getAttributes();
179 184  
180 185 return $typeDefinition;
181 186 }
... ...
lib/api/ktcmis/util/CMISUtil.inc.php
... ... @@ -283,7 +283,7 @@ class CMISUtil {
283 283  
284 284 foreach(CMISPropertyCollection::$propertyTypes as $property => $type)
285 285 {
286   - // hack for Author property
  286 + // author property does not work the same as the others
287 287 if ($property == 'author') {
288 288 $object[$property] = array('value' => $properties->getValue($property));
289 289 }
... ...
webservice/atompub/cmis/KT_cmis_atom_server.services.inc.php
... ... @@ -91,8 +91,6 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service {
91 91 // TODO this only returns one parent, need to implement returnToRoot also
92 92 else if ($this->params[1] == 'parent')
93 93 {
94   - // abstract this to be used also by the document service (and the PWC service?) ???
95   - // alternatively use getFolderParent here makes sense and use getObjectParents when document service?
96 94 $folderId = $this->params[0];
97 95 $NavigationService = new KTNavigationService(KT_cmis_atom_service_helper::getKt());
98 96 $response = $NavigationService->getFolderParent($repositoryId, $folderId, false, false, false);
... ... @@ -403,8 +401,6 @@ class KT_cmis_atom_service_document extends KT_cmis_atom_service {
403 401 // update accordingly when updating to newer specification
404 402 if ($this->params[1] == 'parent')
405 403 {
406   - // abstract this to be used also by the document service (and the PWC service?) ???
407   - // alternatively use getFolderParent here makes sense and use getObjectParents when document service?
408 404 $NavigationService = new NavigationService(KT_cmis_atom_service_helper::getKt());
409 405 $response = $NavigationService->getObjectParents($repositoryId, $objectId, false, false);
410 406  
... ... @@ -701,28 +697,20 @@ class KT_cmis_atom_service_type extends KT_cmis_atom_service {
701 697 {
702 698 $RepositoryService = new KTRepositoryService();
703 699 $repositoryId = KT_cmis_atom_service_helper::getRepositoryId($RepositoryService);
  700 + $type = $this->params[0];
704 701  
705   - if (!isset($this->params[1])) {
706   - // For easier return in the wanted format, we call getTypes instead of getTypeDefinition.
707   - // Calling this with a single type specified returns an array containing the definition of
708   - // just the requested type.
709   - // NOTE could maybe be more efficient to call getTypeDefinition direct and then place in
710   - // an array on this side? or directly expose the individual entry response code and
711   - // call directly from here rather than via getTypeFeed.
712   - $type = ucwords($this->params[0]);
713   - $types = $RepositoryService->getTypes($repositoryId, $type);
714   -
715   - // hack for removing one level of access
716   - $types = $types['results'];
717   -
718   - $feed = KT_cmis_atom_service_helper::getTypeFeed($type, $types);
  702 + try {
  703 + $typeDefinition = $RepositoryService->getTypeDefinition($repositoryId, $type);
719 704 }
720   - else {
721   - // TODO dynamic dates, as needed everywhere
722   - // NOTE children of types not yet implemented and we don't support any non-basic types at this time
723   - $feed = $this->getTypeChildrenFeed($this->params[1]);
  705 + catch (Exception $e) {
  706 + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, $e->getMessage());
  707 + // Expose the responseFeed
  708 + $this->responseFeed = $feed;
  709 + return null;
724 710 }
725 711  
  712 + $feed = KT_cmis_atom_service_helper::getTypeFeed($type, array($typeDefinition));
  713 +
726 714 // Expose the responseFeed
727 715 $this->responseFeed=$feed;
728 716 }
... ...
webservice/atompub/cmis/KT_cmis_atom_service_helper.inc.php
... ... @@ -107,25 +107,25 @@ class KT_cmis_atom_service_helper {
107 107 * @param boolean $pwc Whether this is a PWC object
108 108 * @param $method The request method used (POST/GET/...)
109 109 */
110   - static public function createObjectEntry(&$response, $cmisEntry, $parent, $pwc = false, $method = 'GET')
  110 + static public function createObjectEntry(&$feed, $cmisEntry, $parent, $pwc = false, $method = 'GET')
111 111 {
112   - $workspace = $response->getWorkspace();
  112 + $workspace = $feed->getWorkspace();
113 113 $type = strtolower($cmisEntry['properties']['objectTypeId']['value']);
114 114  
115 115 // create entry
116   - $entry = $response->newEntry();
  116 + $entry = $feed->newEntry();
117 117  
118 118 // When request is a POST we will be returning only an object entry, not a full feed, and so this belongs here
119 119 if (($method == 'POST') || $pwc)
120 120 {
121 121 // append attributes
122   - $entry->appendChild($response->newAttr('xmlns', 'http://www.w3.org/2005/Atom'));
123   - $entry->appendChild($response->newAttr('xmlns:app', 'http://www.w3.org/2007/app'));
124   - $entry->appendChild($response->newAttr('xmlns:cmis', 'http://docs.oasis-open.org/ns/cmis/core/200908/'));
125   - $entry->appendChild($response->newAttr('xmlns:cmisra', 'http://docs.oasis-open.org/ns/cmis/restatom/200908/'));
  122 + $entry->appendChild($feed->newAttr('xmlns', 'http://www.w3.org/2005/Atom'));
  123 + $entry->appendChild($feed->newAttr('xmlns:app', 'http://www.w3.org/2007/app'));
  124 + $entry->appendChild($feed->newAttr('xmlns:cmis', 'http://docs.oasis-open.org/ns/cmis/core/200908/'));
  125 + $entry->appendChild($feed->newAttr('xmlns:cmisra', 'http://docs.oasis-open.org/ns/cmis/restatom/200908/'));
126 126 }
127 127  
128   - self::createObjectEntryContent($entry, $response, $cmisEntry, $parent, $pwc, $method);
  128 + self::createObjectEntryContent($entry, $feed, $cmisEntry, $parent, $pwc, $method);
129 129 }
130 130  
131 131 /**
... ... @@ -151,13 +151,13 @@ class KT_cmis_atom_service_helper {
151 151 // NOTE this approach appears to be necessary due to the structure of the underlying atompub code and specification,
152 152 // which does not directly support nesting - attempting to create a new feed and append it within the outer
153 153 // feed resulted in an empty cmisra:children node, so this approach was substituted
154   - static public function createChildObjectEntry(&$childrenFeed, $cmisEntry, $workspace, $response, $folderNam)
  154 + static public function createChildObjectEntry(&$childrenFeed, $cmisEntry, $workspace, $feed, $folderNam)
155 155 {
156 156 $type = strtolower($cmisEntry['properties']['objectTypeId']['value']);
157 157  
158 158 // create entry
159   - $entry = $response->newElement('entry');
160   - self::createObjectEntryContent($entry, $response, $cmisEntry);//, $parent, $pwc, $method);
  159 + $entry = $feed->newElement('entry');
  160 + self::createObjectEntryContent($entry, $feed, $cmisEntry);//, $parent, $pwc, $method);
161 161 $childrenFeed->appendChild($entry);
162 162 }
163 163  
... ... @@ -165,26 +165,26 @@ class KT_cmis_atom_service_helper {
165 165 * Creates the actual object entry: this is shared between other functions which require this content
166 166 *
167 167 * @param object $entry The entry object
168   - * @param object $response The response feed
  168 + * @param object $feed The response feed
169 169 * @param array $cmisEntry The CMIS object content
170 170 * @param string $parent The parent folder name
171 171 * @param boolean $pwc Whether this is a PWC object (will be returned slightly differently)
172 172 * @param string $method The calling method (slightly affects the output)
173 173 */
174   - static public function createObjectEntryContent($entry, &$response, $cmisEntry, $parent = '', $pwc = false, $method = 'GET')
  174 + static public function createObjectEntryContent($entry, &$feed, $cmisEntry, $parent = '', $pwc = false, $method = 'GET')
175 175 {
176 176 // TODO dynamic actual creator name
177   - $responseElement = $response->newField('author');
178   - $element = $response->newField('name', 'admin', $responseElement);
  177 + $responseElement = $feed->newField('author');
  178 + $element = $feed->newField('name', 'admin', $responseElement);
179 179 $entry->appendChild($responseElement);
180 180  
181 181 $typeString = str_replace('cmis:', '', $type);
182 182  
183 183 if (!empty($cmisEntry['properties']['contentStreamLength']['value']))
184 184 {
185   - $field = $response->newElement('content');
186   - $field->appendChild($response->newAttr('type', $cmisEntry['properties']['contentStreamMimeType']['value']));
187   - $field->appendChild($response->newAttr('src', CMIS_APP_BASE_URI . $workspace . '/' . $typeString
  185 + $field = $feed->newElement('content');
  186 + $field->appendChild($feed->newAttr('type', $cmisEntry['properties']['contentStreamMimeType']['value']));
  187 + $field->appendChild($feed->newAttr('src', CMIS_APP_BASE_URI . $workspace . '/' . $typeString
188 188 . '/' . $cmisEntry['properties']['objectId']['value']
189 189 . '/' . $cmisEntry['properties']['contentStreamFilename']['value']));
190 190 $entry->appendChild($field);
... ... @@ -192,37 +192,37 @@ class KT_cmis_atom_service_helper {
192 192  
193 193 // content & id tags
194 194 $id = $cmisEntry['properties']['objectId']['value'];
195   - $response->newField('id', 'urn:uuid:' . $id, $entry);
  195 + $feed->newField('id', 'urn:uuid:' . $id, $entry);
196 196  
197 197 // links
198   - $link = $response->newElement('link');
199   - $link->appendChild($response->newAttr('rel', 'self'));
200   - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/'
  198 + $link = $feed->newElement('link');
  199 + $link->appendChild($feed->newAttr('rel', 'self'));
  200 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/'
201 201 . (!$pwc ? $typeString : 'pwc') . '/'
202 202 . $cmisEntry['properties']['objectId']['value']));
203 203 $entry->appendChild($link);
204 204  
205   - $link = $response->newElement('link');
206   - $link->appendChild($response->newAttr('rel', 'edit'));
207   - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $typeString
  205 + $link = $feed->newElement('link');
  206 + $link->appendChild($feed->newAttr('rel', 'edit'));
  207 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $typeString
208 208 . '/' . $cmisEntry['properties']['objectId']['value']));
209 209 $entry->appendChild($link);
210 210  
211 211 if ((strtolower($cmisEntry['properties']['objectTypeId']['value']) == 'cmis:document')
212 212 && (!empty($cmisEntry['properties']['contentStreamLength']['value'])))
213 213 {
214   - $link = $response->newElement('link');
215   - $link->appendChild($response->newAttr('rel', 'edit-media'));
216   - $link->appendChild($response->newAttr('type', $cmisEntry['properties']['contentStreamMimeType']['value']));
217   - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $typeString
  214 + $link = $feed->newElement('link');
  215 + $link->appendChild($feed->newAttr('rel', 'edit-media'));
  216 + $link->appendChild($feed->newAttr('type', $cmisEntry['properties']['contentStreamMimeType']['value']));
  217 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $typeString
218 218 . '/' . $cmisEntry['properties']['objectId']['value']
219 219 . '/' . $cmisEntry['properties']['contentStreamFilename']['value']));
220 220 $entry->appendChild($link);
221 221  
222   - $link = $response->newElement('link');
223   - $link->appendChild($response->newAttr('rel', 'enclosure'));
224   - $link->appendChild($response->newAttr('type', $cmisEntry['properties']['contentStreamMimeType']['value']));
225   - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $typeString
  222 + $link = $feed->newElement('link');
  223 + $link->appendChild($feed->newAttr('rel', 'enclosure'));
  224 + $link->appendChild($feed->newAttr('type', $cmisEntry['properties']['contentStreamMimeType']['value']));
  225 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $typeString
226 226 . '/' . $cmisEntry['properties']['objectId']['value']
227 227 . '/' . $cmisEntry['properties']['contentStreamFilename']['value']));
228 228 $entry->appendChild($link);
... ... @@ -230,17 +230,17 @@ class KT_cmis_atom_service_helper {
230 230  
231 231 // according to spec this MUST be present, but spec says that links for function which are not supported
232 232 // do not need to be present, so unsure for the moment
233   - $link = $response->newElement('link');
234   - $link->appendChild($response->newAttr('rel', 'http://docs.oasis-open.org/ns/cmis/link/200908/allowableactions'));
235   - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $typeString . '/'
  233 + $link = $feed->newElement('link');
  234 + $link->appendChild($feed->newAttr('rel', 'http://docs.oasis-open.org/ns/cmis/link/200908/allowableactions'));
  235 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $typeString . '/'
236 236 . $cmisEntry['properties']['objectId']['value'] . '/allowableactions'));
237 237 $entry->appendChild($link);
238 238  
239 239 // according to spec this MUST be present, but spec says that links for function which are not supported
240 240 // do not need to be present, so unsure for the moment
241   - $link = $response->newElement('link');
242   - $link->appendChild($response->newAttr('rel', 'http://docs.oasis-open.org/ns/cmis/link/200908/relationships'));
243   - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $typeString . '/'
  241 + $link = $feed->newElement('link');
  242 + $link->appendChild($feed->newAttr('rel', 'http://docs.oasis-open.org/ns/cmis/link/200908/relationships'));
  243 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $typeString . '/'
244 244 . $cmisEntry['properties']['objectId']['value'] . '/rels'));
245 245 $entry->appendChild($link);
246 246  
... ... @@ -251,9 +251,9 @@ class KT_cmis_atom_service_helper {
251 251 if (!CMISUtil::isRootFolder(self::$repositoryId, $cmisEntry['properties']['objectId']['value'], self::$ktapi))
252 252 {
253 253 // TODO check parent link is correct, fix if needed
254   - $link = $response->newElement('link');
255   - $link->appendChild($response->newAttr('rel', 'up'));
256   - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/folder/'
  254 + $link = $feed->newElement('link');
  255 + $link->appendChild($feed->newAttr('rel', 'up'));
  256 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/folder/'
257 257 . $cmisEntry['properties']['parentId']['value']));
258 258 $entry->appendChild($link);
259 259 }
... ... @@ -261,16 +261,16 @@ class KT_cmis_atom_service_helper {
261 261 // Folder/Document specific links
262 262 if (strtolower($cmisEntry['properties']['objectTypeId']['value']) == 'cmis:folder')
263 263 {
264   - $link = $response->newElement('link');
265   - $link->appendChild($response->newAttr('rel', 'down'));
266   - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/'
  264 + $link = $feed->newElement('link');
  265 + $link->appendChild($feed->newAttr('rel', 'down'));
  266 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/'
267 267 . $typeString
268 268 . '/' . $cmisEntry['properties']['objectId']['value']
269 269 . '/children'));
270 270 $entry->appendChild($link);
271   - $link = $response->newElement('link');
272   - $link->appendChild($response->newAttr('rel', 'down'));
273   - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/'
  271 + $link = $feed->newElement('link');
  272 + $link->appendChild($feed->newAttr('rel', 'down'));
  273 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/'
274 274 . $typeString
275 275 . '/' . $cmisEntry['properties']['objectId']['value']
276 276 . '/descendants'));
... ... @@ -285,10 +285,10 @@ class KT_cmis_atom_service_helper {
285 285 // not sure yet where it must point...
286 286 if (!empty($cmisEntry['properties']['contentStreamLength']['value']))
287 287 {
288   - $link = $response->newElement('link');
289   - $link->appendChild($response->newAttr('rel', 'stream'));
290   - $link->appendChild($response->newAttr('type', $cmisEntry['properties']['contentStreamMimeType']['value']));
291   - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type
  288 + $link = $feed->newElement('link');
  289 + $link->appendChild($feed->newAttr('rel', 'stream'));
  290 + $link->appendChild($feed->newAttr('type', $cmisEntry['properties']['contentStreamMimeType']['value']));
  291 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type
292 292 . '/' . $cmisEntry['properties']['objectId']['value']
293 293 . '/' . $cmisEntry['properties']['contentStreamFilename']['value']));
294 294 $entry->appendChild($link);
... ... @@ -299,68 +299,51 @@ class KT_cmis_atom_service_helper {
299 299 // TODO separated code for PWC and actual document object
300 300 if (!empty($cmisEntry['properties']['versionSeriesCheckedOutId']['value']))
301 301 {
302   - $link = $response->newElement('link');
303   - $link->appendChild($response->newAttr('rel', 'pwc'));
304   - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type
  302 + $link = $feed->newElement('link');
  303 + $link->appendChild($feed->newAttr('rel', 'pwc'));
  304 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type
305 305 . '/' . $cmisEntry['properties']['objectId']['value']
306 306 . '/' . $cmisEntry['properties']['contentStreamFilename']['value']));
307 307 $entry->appendChild($link);
308   - $link = $response->newElement('link');
309   - $link->appendChild($response->newAttr('rel', 'source'));
310   - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type
  308 + $link = $feed->newElement('link');
  309 + $link->appendChild($feed->newAttr('rel', 'source'));
  310 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type
311 311 . '/' . $cmisEntry['properties']['objectId']['value']
312 312 . '/' . $cmisEntry['properties']['contentStreamFilename']['value']));
313 313 $entry->appendChild($link);
314 314 }
315 315  
316   -// $link = $response->newElement('link');
317   -// $link->appendChild($response->newAttr('rel', 'stream'));
318   -// $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type
  316 +// $link = $feed->newElement('link');
  317 +// $link->appendChild($feed->newAttr('rel', 'stream'));
  318 +// $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type
319 319 // . '/' . $cmisEntry['properties']['objectId']['value']
320 320 // . '/' . $cmisEntry['properties']['contentStreamFilename']['value']));
321 321 }
322 322  
323   - $link = $response->newElement('link');
324   - $link->appendChild($response->newAttr('rel', 'describedby'));
325   - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/type/' . $type));
  323 + $link = $feed->newElement('link');
  324 + $link->appendChild($feed->newAttr('rel', 'describedby'));
  325 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/type/' . $type));
326 326 $entry->appendChild($link);
327 327  
328   - $link = $response->newElement('link');
329   - $link->appendChild($response->newAttr('rel', 'service'));
330   - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . '/servicedocument'));
  328 + $link = $feed->newElement('link');
  329 + $link->appendChild($feed->newAttr('rel', 'service'));
  330 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . '/servicedocument'));
331 331 $entry->appendChild($link);
332 332  
333 333 // TODO proper date
334   - $entry->appendChild($response->newField('published', self::formatDatestamp()));
335   - $entry->appendChild($response->newElement('summary', $cmisEntry['properties']['name']['value']));
336   - $entry->appendChild($response->newElement('title', $cmisEntry['properties']['name']['value']));
337   - $entry->appendChild($response->newField('updated', self::formatDatestamp()));
  334 + $entry->appendChild($feed->newField('published', self::formatDatestamp()));
  335 + $entry->appendChild($feed->newElement('summary', $cmisEntry['properties']['name']['value']));
  336 + $entry->appendChild($feed->newElement('title', $cmisEntry['properties']['name']['value']));
  337 + $entry->appendChild($feed->newField('updated', self::formatDatestamp()));
338 338  
339 339 // main CMIS entry
340   - $objectElement = $response->newElement('cmisra:object');
341   - $propertiesElement = $response->newElement('cmis:properties');
342   -
343   - foreach($cmisEntry['properties'] as $propertyName => $property)
344   - {
345   - $propElement = $response->newElement('cmis:' . $property['type']);
346   -// $propElement->appendChild($response->newAttr('localName', 'rep-cmis:' . $propertyName));
347   - $propElement->appendChild($response->newAttr('propertyDefinitionId', 'cmis:' . $propertyName));
348   - if (!empty($property['value']))
349   - {
350   - if ($propertyName == 'contentStreamUri') {
351   - $property['value'] = CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' .$property['value'];
352   - }
353   - $response->newField('cmis:value', CMISUtil::boolToString($property['value']), $propElement);
354   - }
355   - $propertiesElement->appendChild($propElement);
356   - }
357   -
358   - $objectElement->appendChild($propertiesElement);
  340 + $objectElement = $feed->newElement('cmisra:object');
  341 + $objectElement->appendChild(self::createEntryPropertiesElement($feed, $cmisEntry['properties']));
359 342 $entry->appendChild($objectElement);
360 343  
361 344 // TODO check determination of when to add app:edited tag
362 345 // if ($method == 'POST') {
363   - $entry->appendChild($response->newElement('app:edited', self::formatDatestamp()));
  346 + $entry->appendChild($feed->newElement('app:edited', self::formatDatestamp()));
364 347 // }
365 348  
366 349 // TODO pathSegment entry
... ... @@ -368,14 +351,43 @@ class KT_cmis_atom_service_helper {
368 351 // deal with child objects
369 352 if (isset($cmisEntry['children'])) {
370 353 // add children node and fill with child entries
371   - $childrenFeed = $response->newElement('feed');
372   - self::createObjectChildrenFeed($childrenFeed, $cmisEntry['children'], $workspace, $response, '' /*folderName not passed through*/);
  354 + $childrenFeed = $feed->newElement('feed');
  355 + self::createObjectChildrenFeed($childrenFeed, $cmisEntry['children'], $workspace, $feed, '' /*folderName not passed through*/);
373 356  
374   - $childrenElement = $response->newElement('cmisra:children');
  357 + $childrenElement = $feed->newElement('cmisra:children');
375 358 $childrenElement->appendChild($childrenFeed);
376 359 $entry->appendChild($childrenElement);
377 360 }
378 361 }
  362 +
  363 + /**
  364 + * Shared function for creating an object properties node
  365 + *
  366 + * @param object $feed AtomPub response feed
  367 + * @param array $properties CMIS object properties
  368 + * @return object $propertiesElement AtomPub node
  369 + */
  370 + // TODO leave out unset properties?
  371 + static public function createEntryPropertiesElement(&$feed, $properties)
  372 + {
  373 + $propertiesElement = $feed->newElement('cmis:properties');
  374 + foreach($properties as $propertyName => $property)
  375 + {
  376 + $propElement = $feed->newElement('cmis:' . $property['type']);
  377 +// $propElement->appendChild($feed->newAttr('localName', 'rep-cmis:' . $propertyName));
  378 + $propElement->appendChild($feed->newAttr('propertyDefinitionId', 'cmis:' . $propertyName));
  379 + if (!empty($property['value']))
  380 + {
  381 + if ($propertyName == 'contentStreamUri') {
  382 + $property['value'] = CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' .$property['value'];
  383 + }
  384 + $feed->newField('cmis:value', CMISUtil::boolToString($property['value']), $propElement);
  385 + }
  386 + $propertiesElement->appendChild($propElement);
  387 + }
  388 +
  389 + return $propertiesElement;
  390 + }
379 391  
380 392 /**
381 393 * Retrieves the list of types|type definition as a CMIS AtomPub feed
... ... @@ -386,6 +398,10 @@ class KT_cmis_atom_service_helper {
386 398 */
387 399 static public function getTypeFeed($typeDef, $types)
388 400 {
  401 + global $default;
  402 +// $default->log->info(print_r($types));
  403 +// $default->log->info(print_r($types, true));
  404 + $default->log->info($typeDef);
389 405 $typesString = '';
390 406 $typesHeading = '';
391 407 switch($typeDef)
... ... @@ -417,21 +433,6 @@ class KT_cmis_atom_service_helper {
417 433 $element = $feed->newField('name', 'admin', $feedElement);
418 434 $feed->appendChild($feedElement);
419 435  
420   - // NOTE spec says this link MUST be present but is vague on where it points
421   - // as of 0.61c:
422   - // "The source link relation points to the underlying CMIS Type Definition as Atom Entry"
423   - // so what is the underlying CMIS Type Definition for a collection of base types?
424   - // suspect that it only applies when not listing all types, i.e. a base type is asked for
425   - /*
426   - $link = $feed->newElement('link');
427   - $link->appendChild($feed->newAttr('rel','source'));
428   - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/type/' . strtolower($type['typeId'])));
429   - $feed->appendChild($link);
430   - */
431   -
432   - // current time: format = 2009-07-13T14:49:27.659+02:00
433   - $feed->appendChild($feed->newElement('updated', self::formatDatestamp()));
434   -
435 436 foreach($types as $type)
436 437 {
437 438 $entry = $feed->newEntry();
... ... @@ -439,48 +440,37 @@ class KT_cmis_atom_service_helper {
439 440 $feedElement = $feed->newField('author');
440 441 $element = $feed->newField('name', 'admin', $feedElement);
441 442 $entry->appendChild($feedElement);
442   - $feedElement = $feed->newField('content', $type['typeId']);
  443 + $feedElement = $feed->newField('content', 'Type definition for ' . $type['baseId']);
443 444 $entry->appendChild($feedElement);
444 445  
445   - $feed->newField('id', 'urn:uuid:type-' . $type['typeId'], $feed);
446   -
447   - // TODO add parents link when not selecting a base type.
448   - // TODO add children link when type has children
449   - // TODO add descendants link when type has children
450   - // NOTE KnowledgeTree currently only supports base types so these are not important at the present time.
451   -
  446 + $feed->newField('id', 'urn:uuid:type-' . $type['baseId'], $feed);
  447 +
452 448 // links
453 449 $link = $feed->newElement('link');
454 450 $link->appendChild($feed->newAttr('rel','self'));
455   - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/type/' . strtolower($type['typeId'])));
  451 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/type/' . strtolower($type['baseId'])));
456 452 $entry->appendChild($link);
457 453 // TODO type link MUST point to base type
458 454 // KnowledgeTree currently only supports base types so this is not important
459 455 // at the present time as it will always point at the base type.
460 456 $link = $feed->newElement('link');
461 457 $link->appendChild($feed->newAttr('rel','type'));
462   - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/type/' . strtolower($type['typeId'])));
  458 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/type/' . strtolower($type['baseId'])));
463 459 $entry->appendChild($link);
464 460 $link = $feed->newElement('link');
465 461 $link->appendChild($feed->newAttr('rel','repository'));
466 462 $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . '/servicedocument'));
467 463 $entry->appendChild($link);
468   -
469   - $entry->appendChild($feed->newElement('summary', $type['typeId'] . ' Type'));
470   - $entry->appendChild($feed->newElement('title', $type['typeId']));
  464 +
  465 + $entry->appendChild($feed->newElement('summary', 'Summary for ' . $type['baseId'] . ' type'));
  466 + $entry->appendChild($feed->newElement('title', $type['baseId']));
471 467 $entry->appendChild($feed->newElement('updated', self::formatDatestamp()));
472   -
473   - // main CMIS entry
474   - $feedElement = $feed->newElement('cmis:' . strtolower($type['typeId']) . 'Type');
475   - foreach($type as $property => $value)
476   - {
477   - $feed->newField('cmis:' . $property, CMISUtil::boolToString($value), $feedElement);
478   - }
479   -
480   - $entry->appendChild($feedElement);
481 468  
482   - // after every entry, append a cmis:terminator tag
483   -// $entry->appendChild($feed->newElement('cmis:terminator'));
  469 + $objectElement = $feed->newElement('cmisra:type');
  470 + foreach($type as $property => $value) {
  471 + $feed->newField('cmis:' . $property, CMISUtil::boolToString($value), $objectElement);
  472 + }
  473 + $entry->appendChild($objectElement);
484 474 }
485 475  
486 476 return $feed;
... ...