Commit daa35381467b1962bb1e0deb8bdd34df0ab8a6cc

Authored by Paul Barrett
1 parent 8d56157a

Fix some AtomPub links and thereby fix browsing into subfolders in CMIS Spaces

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

Committed by: Paul Barrett
lib/api/ktcmis/objecttypes/CMISDocumentObject.inc.php
@@ -113,7 +113,7 @@ class CMISDocumentObject extends CMISObject { @@ -113,7 +113,7 @@ class CMISDocumentObject extends CMISObject {
113 113
114 $objectProperties = $object->get_detail(); 114 $objectProperties = $object->get_detail();
115 115
116 - $this->_setPropertyInternal('objectId', CMISUtil::encodeObjectId($this->typeId, $objectProperties['document_id'])); 116 + $this->_setPropertyInternal('objectId', CMISUtil::encodeObjectId($this->id, $objectProperties['document_id']));
117 // prevent doubled '/' chars 117 // prevent doubled '/' chars
118 $uri = preg_replace_callback('/([^:]\/)\//', 118 $uri = preg_replace_callback('/([^:]\/)\//',
119 create_function('$matches', 'return $matches[1];'), 119 create_function('$matches', 'return $matches[1];'),
lib/api/ktcmis/objecttypes/CMISFolderObject.inc.php
@@ -101,7 +101,7 @@ class CMISFolderObject extends CMISObject { @@ -101,7 +101,7 @@ class CMISFolderObject extends CMISObject {
101 101
102 $objectProperties = $object->get_detail(); 102 $objectProperties = $object->get_detail();
103 103
104 - $this->_setPropertyInternal('objectId', CMISUtil::encodeObjectId($this->typeId, $objectProperties['id'])); 104 + $this->_setPropertyInternal('objectId', CMISUtil::encodeObjectId($this->id, $objectProperties['id']));
105 // prevent doubled '/' chars 105 // prevent doubled '/' chars
106 $uri = preg_replace_callback('/([^:]\/)\//', 106 $uri = preg_replace_callback('/([^:]\/)\//',
107 create_function('$matches', 'return $matches[1];'), 107 create_function('$matches', 'return $matches[1];'),
lib/api/ktcmis/util/CMISUtil.inc.php
@@ -69,11 +69,13 @@ class CMISUtil { @@ -69,11 +69,13 @@ class CMISUtil {
69 { 69 {
70 case 'D': 70 case 'D':
71 case 'Document': 71 case 'Document':
  72 + case 'cmis:document':
72 case DOCUMENT: 73 case DOCUMENT:
73 $encoded = 'D' . $objectId; 74 $encoded = 'D' . $objectId;
74 break; 75 break;
75 case 'F': 76 case 'F':
76 case 'Folder': 77 case 'Folder':
  78 + case 'cmis:folder':
77 case FOLDER: 79 case FOLDER:
78 $encoded = 'F' . $objectId; 80 $encoded = 'F' . $objectId;
79 break; 81 break;
@@ -188,7 +190,7 @@ class CMISUtil { @@ -188,7 +190,7 @@ class CMISUtil {
188 else 190 else
189 { 191 {
190 // NOTE why is this necessary? That's what you get for not commenting it at the time 192 // NOTE why is this necessary? That's what you get for not commenting it at the time
191 - // TODO comment this properly 193 + // TODO comment this properly, once we know why it is happening
192 $CMISArray[$count] = self::createChildObjectHierarchy($object, $repositoryURI, $ktapi); 194 $CMISArray[$count] = self::createChildObjectHierarchy($object, $repositoryURI, $ktapi);
193 } 195 }
194 } 196 }
webservice/atompub/cmis/KT_cmis_atom_service_helper.inc.php
@@ -99,6 +99,8 @@ class KT_cmis_atom_service_helper { @@ -99,6 +99,8 @@ class KT_cmis_atom_service_helper {
99 * @param object $feed The feed to which we add the entry 99 * @param object $feed The feed to which we add the entry
100 * @param array $cmisEntry The entry data 100 * @param array $cmisEntry The entry data
101 * @param string $parent The parent folder 101 * @param string $parent The parent folder
  102 + * @param boolean $pwc Whether this is a PWC object
  103 + * @param $method The request method used (POST/GET/...)
102 */ 104 */
103 static public function createObjectEntry(&$response, $cmisEntry, $parent, $pwc = false, $method = 'GET') 105 static public function createObjectEntry(&$response, $cmisEntry, $parent, $pwc = false, $method = 'GET')
104 { 106 {
@@ -108,7 +110,7 @@ class KT_cmis_atom_service_helper { @@ -108,7 +110,7 @@ class KT_cmis_atom_service_helper {
108 // create entry 110 // create entry
109 $entry = $response->newEntry(); 111 $entry = $response->newEntry();
110 112
111 - // FIXME this maybe belongs in the response feed class only how? 113 + // When request is a POST we will be returning only an object entry, not a full feed, and so this belongs here
112 if (($method == 'POST') || $pwc) 114 if (($method == 'POST') || $pwc)
113 { 115 {
114 // append attributes 116 // append attributes
@@ -123,68 +125,70 @@ class KT_cmis_atom_service_helper { @@ -123,68 +125,70 @@ class KT_cmis_atom_service_helper {
123 $element = $response->newField('name', 'admin', $responseElement); 125 $element = $response->newField('name', 'admin', $responseElement);
124 $entry->appendChild($responseElement); 126 $entry->appendChild($responseElement);
125 127
  128 + $typeString = str_replace('cmis:', '', $type);
  129 +
126 if (!empty($cmisEntry['properties']['contentStreamLength']['value'])) 130 if (!empty($cmisEntry['properties']['contentStreamLength']['value']))
127 { 131 {
128 $field = $response->newElement('content'); 132 $field = $response->newElement('content');
129 $field->appendChild($response->newAttr('type', $cmisEntry['properties']['contentStreamMimeType']['value'])); 133 $field->appendChild($response->newAttr('type', $cmisEntry['properties']['contentStreamMimeType']['value']));
130 - $field->appendChild($response->newAttr('src', CMIS_APP_BASE_URI . $workspace . '/' . $type  
131 - . '/' . $cmisEntry['properties']['objectId']['value']  
132 - . '/' . $cmisEntry['properties']['contentStreamFilename']['value'])); 134 + $field->appendChild($response->newAttr('src', CMIS_APP_BASE_URI . $workspace . '/' . $typeString
  135 + . '/' . $cmisEntry['properties']['objectId']['value']
  136 + . '/' . $cmisEntry['properties']['contentStreamFilename']['value']));
133 $entry->appendChild($field); 137 $entry->appendChild($field);
134 } 138 }
135 139
136 // content & id tags 140 // content & id tags
137 $id = $cmisEntry['properties']['objectId']['value']; 141 $id = $cmisEntry['properties']['objectId']['value'];
138 -  
139 $response->newField('id', 'urn:uuid:' . $id, $entry); 142 $response->newField('id', 'urn:uuid:' . $id, $entry);
140 143
141 // links 144 // links
142 $link = $response->newElement('link'); 145 $link = $response->newElement('link');
143 $link->appendChild($response->newAttr('rel', 'self')); 146 $link->appendChild($response->newAttr('rel', 'self'));
144 - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . (!$pwc ? $type : 'pwc') . '/' 147 + $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/'
  148 + . (!$pwc ? $typeString : 'pwc') . '/'
145 . $cmisEntry['properties']['objectId']['value'])); 149 . $cmisEntry['properties']['objectId']['value']));
146 $entry->appendChild($link); 150 $entry->appendChild($link);
147 151
148 $link = $response->newElement('link'); 152 $link = $response->newElement('link');
149 $link->appendChild($response->newAttr('rel', 'edit')); 153 $link->appendChild($response->newAttr('rel', 'edit'));
150 - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type  
151 - . '/' . $cmisEntry['properties']['objectId']['value'])); 154 + $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $typeString
  155 + . '/' . $cmisEntry['properties']['objectId']['value']));
152 $entry->appendChild($link); 156 $entry->appendChild($link);
153 157
154 - if ((strtolower($cmisEntry['properties']['objectTypeId']['value']) == 'document') 158 + if ((strtolower($cmisEntry['properties']['objectTypeId']['value']) == 'cmis:document')
155 && (!empty($cmisEntry['properties']['contentStreamLength']['value']))) 159 && (!empty($cmisEntry['properties']['contentStreamLength']['value'])))
156 { 160 {
157 $link = $response->newElement('link'); 161 $link = $response->newElement('link');
158 $link->appendChild($response->newAttr('rel', 'edit-media')); 162 $link->appendChild($response->newAttr('rel', 'edit-media'));
159 $link->appendChild($response->newAttr('type', $cmisEntry['properties']['contentStreamMimeType']['value'])); 163 $link->appendChild($response->newAttr('type', $cmisEntry['properties']['contentStreamMimeType']['value']));
160 - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type  
161 - . '/' . $cmisEntry['properties']['objectId']['value']  
162 - . '/' . $cmisEntry['properties']['contentStreamFilename']['value'])); 164 + $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $typeString
  165 + . '/' . $cmisEntry['properties']['objectId']['value']
  166 + . '/' . $cmisEntry['properties']['contentStreamFilename']['value']));
163 $entry->appendChild($link); 167 $entry->appendChild($link);
164 168
165 $link = $response->newElement('link'); 169 $link = $response->newElement('link');
166 $link->appendChild($response->newAttr('rel', 'enclosure')); 170 $link->appendChild($response->newAttr('rel', 'enclosure'));
167 $link->appendChild($response->newAttr('type', $cmisEntry['properties']['contentStreamMimeType']['value'])); 171 $link->appendChild($response->newAttr('type', $cmisEntry['properties']['contentStreamMimeType']['value']));
168 - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type  
169 - . '/' . $cmisEntry['properties']['objectId']['value']  
170 - . '/' . $cmisEntry['properties']['contentStreamFilename']['value'])); 172 + $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $typeString
  173 + . '/' . $cmisEntry['properties']['objectId']['value']
  174 + . '/' . $cmisEntry['properties']['contentStreamFilename']['value']));
171 $entry->appendChild($link); 175 $entry->appendChild($link);
172 } 176 }
173 177
174 // according to spec this MUST be present, but spec says that links for function which are not supported 178 // according to spec this MUST be present, but spec says that links for function which are not supported
175 // do not need to be present, so unsure for the moment 179 // do not need to be present, so unsure for the moment
176 $link = $response->newElement('link'); 180 $link = $response->newElement('link');
177 - $link->appendChild($response->newAttr('rel', 'allowableactions'));  
178 - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/'  
179 - . $cmisEntry['properties']['objectId']['value'] . '/permissions')); 181 + $link->appendChild($response->newAttr('rel', 'http://docs.oasis-open.org/ns/cmis/link/200908/allowableactions'));
  182 + $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $typeString . '/'
  183 + . $cmisEntry['properties']['objectId']['value'] . '/allowableactions'));
180 $entry->appendChild($link); 184 $entry->appendChild($link);
181 185
182 // according to spec this MUST be present, but spec says that links for function which are not supported 186 // according to spec this MUST be present, but spec says that links for function which are not supported
183 // do not need to be present, so unsure for the moment 187 // do not need to be present, so unsure for the moment
184 $link = $response->newElement('link'); 188 $link = $response->newElement('link');
185 - $link->appendChild($response->newAttr('rel', 'relationships'));  
186 - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/'  
187 - . $cmisEntry['properties']['objectId']['value'] . '/rels')); 189 + $link->appendChild($response->newAttr('rel', 'http://docs.oasis-open.org/ns/cmis/link/200908/relationships'));
  190 + $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $typeString . '/'
  191 + . $cmisEntry['properties']['objectId']['value'] . '/rels'));
188 $entry->appendChild($link); 192 $entry->appendChild($link);
189 193
190 // if there is no parent or parent is 0, do not add the parent link 194 // if there is no parent or parent is 0, do not add the parent link
@@ -195,46 +199,35 @@ class KT_cmis_atom_service_helper { @@ -195,46 +199,35 @@ class KT_cmis_atom_service_helper {
195 { 199 {
196 // TODO check parent link is correct, fix if needed 200 // TODO check parent link is correct, fix if needed
197 $link = $response->newElement('link'); 201 $link = $response->newElement('link');
198 - $link->appendChild($response->newAttr('rel', 'parents')); 202 + $link->appendChild($response->newAttr('rel', 'up'));
199 $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/folder/' 203 $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/folder/'
200 - . $cmisEntry['properties']['objectId']['value'] . '/parent')); 204 + . $cmisEntry['properties']['parentId']['value']));
201 $entry->appendChild($link); 205 $entry->appendChild($link);
202 } 206 }
203 207
204 // Folder/Document specific links 208 // Folder/Document specific links
205 - if (strtolower($cmisEntry['properties']['objectTypeId']['value']) == 'folder') 209 + if (strtolower($cmisEntry['properties']['objectTypeId']['value']) == 'cmis:folder')
206 { 210 {
207 $link = $response->newElement('link'); 211 $link = $response->newElement('link');
208 - $link->appendChild($response->newAttr('rel', 'children')); 212 + $link->appendChild($response->newAttr('rel', 'down'));
209 $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' 213 $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/'
210 - . $type  
211 - . '/' . $cmisEntry['properties']['objectId']['value']  
212 - . '/children')); 214 + . $typeString
  215 + . '/' . $cmisEntry['properties']['objectId']['value']
  216 + . '/children'));
213 $entry->appendChild($link); 217 $entry->appendChild($link);
214 $link = $response->newElement('link'); 218 $link = $response->newElement('link');
215 - $link->appendChild($response->newAttr('rel', 'descendants')); 219 + $link->appendChild($response->newAttr('rel', 'down'));
216 $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' 220 $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/'
217 - . $type  
218 - . '/' . $cmisEntry['properties']['objectId']['value']  
219 - . '/descendants')); 221 + . $typeString
  222 + . '/' . $cmisEntry['properties']['objectId']['value']
  223 + . '/descendants'));
220 $entry->appendChild($link); 224 $entry->appendChild($link);
  225 +
  226 + // TODO add folder tree link when we have folder tree implemented
  227 + // this will probably use (much) the same code as the folder children functionality
221 } 228 }
222 - else if (strtolower($cmisEntry['properties']['objectTypeId']['value']) == 'document') 229 + else if (strtolower($cmisEntry['properties']['objectTypeId']['value']) == 'cmis:document')
223 { 230 {
224 - // according to spec this MUST be present, but spec says that links for function which are not supported  
225 - // do not need to be present, so unsure for the moment  
226 -// $link = $response->newElement('link');  
227 -// $link->appendChild($response->newAttr('rel', 'allversions'));  
228 -// $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' . $cmisEntry['properties']['parentId']['value']));  
229 -// $entry->appendChild($link);  
230 -  
231 - // according to spec this MUST be present, but spec says that links for function which are not supported  
232 - // do not need to be present, so unsure for the moment  
233 -// $link = $response->newElement('link');  
234 -// $link->appendChild($response->newAttr('rel', 'latestversion'));  
235 -// $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' . $cmisEntry['properties']['parentId']['value']));  
236 -// $entry->appendChild($link);  
237 -  
238 // if there is a content stream, this link MUST be present 231 // if there is a content stream, this link MUST be present
239 // not sure yet where it must point... 232 // not sure yet where it must point...
240 if (!empty($cmisEntry['properties']['contentStreamLength']['value'])) 233 if (!empty($cmisEntry['properties']['contentStreamLength']['value']))
@@ -251,7 +244,7 @@ class KT_cmis_atom_service_helper { @@ -251,7 +244,7 @@ class KT_cmis_atom_service_helper {
251 // if the document is checked out and this is NOT the PWC, this link MUST be present 244 // if the document is checked out and this is NOT the PWC, this link MUST be present
252 // NOTE at the moment the document and the PWC are the same object, so we always show it for a checked out document 245 // NOTE at the moment the document and the PWC are the same object, so we always show it for a checked out document
253 // TODO separated code for PWC and actual document object 246 // TODO separated code for PWC and actual document object
254 - if (!empty($cmisEntry['properties']['VersionSeriesCheckedOutId']['value'])) 247 + if (!empty($cmisEntry['properties']['versionSeriesCheckedOutId']['value']))
255 { 248 {
256 $link = $response->newElement('link'); 249 $link = $response->newElement('link');
257 $link->appendChild($response->newAttr('rel', 'pwc')); 250 $link->appendChild($response->newAttr('rel', 'pwc'));
@@ -275,23 +268,15 @@ class KT_cmis_atom_service_helper { @@ -275,23 +268,15 @@ class KT_cmis_atom_service_helper {
275 } 268 }
276 269
277 $link = $response->newElement('link'); 270 $link = $response->newElement('link');
278 - $link->appendChild($response->newAttr('rel', 'type')); 271 + $link->appendChild($response->newAttr('rel', 'describedby'));
279 $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/type/' . $type)); 272 $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/type/' . $type));
280 $entry->appendChild($link); 273 $entry->appendChild($link);
281 274
282 $link = $response->newElement('link'); 275 $link = $response->newElement('link');
283 - $link->appendChild($response->newAttr('rel', 'repository')); 276 + $link->appendChild($response->newAttr('rel', 'service'));
284 $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . '/servicedocument')); 277 $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . '/servicedocument'));
285 $entry->appendChild($link); 278 $entry->appendChild($link);
286 279
287 - // according to spec this MUST be present, but spec says that links for function which are not supported  
288 - // do not need to be present, so unsure for the moment - policies are being abandoned, or so I thought...  
289 -// $link = $response->newElement('link');  
290 -// $link->appendChild($response->newAttr('rel', 'policies'));  
291 -// $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' . $cmisEntry['properties']['parentId']['value']));  
292 -// $entry->appendChild($link);  
293 - // end links  
294 -  
295 // TODO proper date 280 // TODO proper date
296 $entry->appendChild($response->newField('published', self::formatDatestamp())); 281 $entry->appendChild($response->newField('published', self::formatDatestamp()));
297 $entry->appendChild($response->newElement('summary', $cmisEntry['properties']['name']['value'])); 282 $entry->appendChild($response->newElement('summary', $cmisEntry['properties']['name']['value']));