Commit 4130d930a8661c1ba23d7c1a2e3f289aa502e9f0

Authored by Jarrett Jordaan
2 parents 2877f303 07800ae6

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

lib/api/ktcmis/config/repositories.xml
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 <repositoryURI>http://127.0.0.1/</repositoryURI> 13 <repositoryURI>http://127.0.0.1/</repositoryURI>
14 <repositoryInfo> 14 <repositoryInfo>
15 <repositoryId>0ad7de04-7914-41b1-b5ee-be9f0b626437</repositoryId> 15 <repositoryId>0ad7de04-7914-41b1-b5ee-be9f0b626437</repositoryId>
16 - <repositoryName>KnowledgeTree</repositoryName> 16 + <repositoryName>KnowledgeTree DMS</repositoryName>
17 <repositoryRelationship>self</repositoryRelationship> 17 <repositoryRelationship>self</repositoryRelationship>
18 <repositoryDescription>KnowledgeTree Repository</repositoryDescription> 18 <repositoryDescription>KnowledgeTree Repository</repositoryDescription>
19 <vendorName>KnowledgeTree</vendorName> 19 <vendorName>KnowledgeTree</vendorName>
lib/api/ktcmis/ktcmis.inc.php
@@ -62,27 +62,42 @@ require_once(CMIS_DIR . &#39;/util/CMISUtil.inc.php&#39;); @@ -62,27 +62,42 @@ require_once(CMIS_DIR . &#39;/util/CMISUtil.inc.php&#39;);
62 */ 62 */
63 class KTCMISBase { 63 class KTCMISBase {
64 64
65 - /**  
66 - * KnowledgeTree API instance  
67 - *  
68 - * @var object  
69 - */  
70 - protected $ktapi;  
71 - /**  
72 - * KnowledgeTree API Session Identifier  
73 - *  
74 - * @var object  
75 - */  
76 - protected $session; 65 + // we want all child classes to share the ktapi and session instances, no matter where they are set from,
  66 + // so we declare them as static
  67 + static protected $ktapi;
  68 + static protected $session;
77 69
  70 + // TODO try to pick up existing session if possible, i.e. if the $session value is not empty
78 public function startSession($username, $password) 71 public function startSession($username, $password)
79 { 72 {
80 - $this->session = null; 73 +// echo $username." :: ".$password."<BR>";
  74 + // attempt to recover session if one exists
  75 + if (!is_null(self::$session) && !PEAR::isError(self::$session))
  76 + {
  77 +// echo "ATTEMPT TO RECOVER SESSION: ".print_r(self::$session, true)."<BR>\n";
  78 + self::$session =& self::$ktapi->get_active_session(self::$session->get_sessionid());
  79 + }
  80 +
  81 + // start new session if no existing session or problem getting existing session (expired, etc...)
  82 + if (is_null(self::$session) || PEAR::isError(self::$session))
  83 + {
  84 +// echo "ATTEMPT TO START NEW SESSION<BR>\n";
  85 + self::$ktapi = new KTAPI();
  86 + self::$session =& self::$ktapi->start_session($username, $password);
  87 + }
  88 +
  89 +// print_r(self::$ktapi);
  90 + return self::$session;
  91 + }
81 92
82 - $this->ktapi = new KTAPI();  
83 - $this->session =& $this->ktapi->start_session($username, $password); 93 + public function getInterface()
  94 + {
  95 + return self::$ktapi;
  96 + }
84 97
85 - return $this->session; 98 + public function getSession()
  99 + {
  100 + return self::$session;
86 } 101 }
87 102
88 // TODO what about destroying sessions? only on logout (which is not offered by the CMIS clients tested so far) 103 // TODO what about destroying sessions? only on logout (which is not offered by the CMIS clients tested so far)
@@ -244,7 +259,13 @@ class KTNavigationService extends KTCMISBase { @@ -244,7 +259,13 @@ class KTNavigationService extends KTCMISBase {
244 public function startSession($username, $password) 259 public function startSession($username, $password)
245 { 260 {
246 parent::startSession($username, $password); 261 parent::startSession($username, $password);
247 - $this->NavigationService->setInterface($this->ktapi); 262 + $this->setInterface();
  263 + return self::$session;
  264 + }
  265 +
  266 + public function setInterface()
  267 + {
  268 + $this->NavigationService->setInterface(self::$ktapi);
248 } 269 }
249 270
250 /** 271 /**
@@ -426,11 +447,17 @@ class KTObjectService extends KTCMISBase { @@ -426,11 +447,17 @@ class KTObjectService extends KTCMISBase {
426 // instantiate underlying CMIS service 447 // instantiate underlying CMIS service
427 $this->ObjectService = new CMISObjectService(); 448 $this->ObjectService = new CMISObjectService();
428 } 449 }
429 - 450 +
430 public function startSession($username, $password) 451 public function startSession($username, $password)
431 { 452 {
432 parent::startSession($username, $password); 453 parent::startSession($username, $password);
433 - $this->ObjectService->setInterface($this->ktapi); 454 + $this->setInterface();
  455 + return self::$session;
  456 + }
  457 +
  458 + public function setInterface()
  459 + {
  460 + $this->ObjectService->setInterface(self::$ktapi);
434 } 461 }
435 462
436 /** 463 /**
lib/api/ktcmis/objecttypes/CMISDocumentObject.inc.php
@@ -110,6 +110,7 @@ class CMISDocumentObject extends CMISBaseObject { @@ -110,6 +110,7 @@ class CMISDocumentObject extends CMISBaseObject {
110 } 110 }
111 111
112 $objectProperties = $object->get_detail(); 112 $objectProperties = $object->get_detail();
  113 +// print_r($objectProperties);
113 114
114 $this->_setPropertyInternal('ObjectId', CMISUtil::encodeObjectId($this->typeId, $objectProperties['document_id'])); 115 $this->_setPropertyInternal('ObjectId', CMISUtil::encodeObjectId($this->typeId, $objectProperties['document_id']));
115 // prevent doubled '/' chars 116 // prevent doubled '/' chars
@@ -131,6 +132,7 @@ class CMISDocumentObject extends CMISBaseObject { @@ -131,6 +132,7 @@ class CMISDocumentObject extends CMISBaseObject {
131 $this->_setPropertyInternal('LastModificationDate', $objectProperties['modified_date']); 132 $this->_setPropertyInternal('LastModificationDate', $objectProperties['modified_date']);
132 $this->_setPropertyInternal('ChangeToken', null); 133 $this->_setPropertyInternal('ChangeToken', null);
133 $this->_setPropertyInternal('Name', $objectProperties['title']); 134 $this->_setPropertyInternal('Name', $objectProperties['title']);
  135 + $this->_setPropertyInternal('ParentId', $objectProperties['folder_id']);
134 $this->_setPropertyInternal('IsImmutable', $objectProperties['is_immutable']); 136 $this->_setPropertyInternal('IsImmutable', $objectProperties['is_immutable']);
135 // NOTE if access to older versions is allowed, this will need to be checked, else just set to yes 137 // NOTE if access to older versions is allowed, this will need to be checked, else just set to yes
136 // see ktapi::get_document_version_history 138 // see ktapi::get_document_version_history
lib/api/ktcmis/services/CMISObjectService.inc.php
@@ -262,6 +262,12 @@ class CMISObjectService { @@ -262,6 +262,12 @@ class CMISObjectService {
262 throw new ConstraintViolationException('Parent folder may not hold objects of this type (' . $typeId . ')'); 262 throw new ConstraintViolationException('Parent folder may not hold objects of this type (' . $typeId . ')');
263 } 263 }
264 264
  265 + // TODO if name is blank! throw another exception (check type) - using RuntimeException for now
  266 + if (trim($properties['name']) == '')
  267 + {
  268 + throw new RuntimeException('Refusing to create an un-named folder');
  269 + }
  270 +
265 $response = $this->ktapi->create_folder((int)$folderId, $properties['name'], $sig_username = '', $sig_password = '', $reason = ''); 271 $response = $this->ktapi->create_folder((int)$folderId, $properties['name'], $sig_username = '', $sig_password = '', $reason = '');
266 if ($response['status_code'] != 0) 272 if ($response['status_code'] != 0)
267 { 273 {
lib/api/ktcmis/util/CMISUtil.inc.php
@@ -86,6 +86,12 @@ class CMISUtil { @@ -86,6 +86,12 @@ class CMISUtil {
86 */ 86 */
87 static public function decodeObjectId($objectId, &$typeId = null) 87 static public function decodeObjectId($objectId, &$typeId = null)
88 { 88 {
  89 + if (!is_string($objectId))
  90 + {
  91 + $typeId = 'Unknown';
  92 + return null;
  93 + }
  94 +
89 $typeId = null; 95 $typeId = null;
90 96
91 preg_match('/(\D)(\d*)/', $objectId, $matches); 97 preg_match('/(\D)(\d*)/', $objectId, $matches);
@@ -240,14 +246,11 @@ class CMISUtil { @@ -240,14 +246,11 @@ class CMISUtil {
240 'value' => $properties->getValue('Name')); 246 'value' => $properties->getValue('Name'));
241 $object['Author'] = array('value' => $properties->getValue('Author')); 247 $object['Author'] = array('value' => $properties->getValue('Author'));
242 248
243 - if (strtolower($properties->getValue('ObjectTypeId')) == 'folder')  
244 - {  
245 - $object['properties']['ParentId'] = array('type' => $properties->getFieldType('ParentId'),  
246 - 'value' => CMISUtil::encodeObjectId('Folder',  
247 - $properties->getValue('ParentId')));  
248 - } 249 + $object['properties']['ParentId'] = array('type' => $properties->getFieldType('ParentId'),
  250 + 'value' => CMISUtil::encodeObjectId('Folder',
  251 + $properties->getValue('ParentId')));
249 // TODO should check for content stream data before filling these in 252 // TODO should check for content stream data before filling these in
250 - else //if () 253 + if (strtolower($properties->getValue('ObjectTypeId')) == 'document')
251 { 254 {
252 $object['properties']['ContentStreamLength'] = array('type' => $properties->getFieldType('ContentStreamLength'), 255 $object['properties']['ContentStreamLength'] = array('type' => $properties->getFieldType('ContentStreamLength'),
253 'value' => $properties->getValue('ContentStreamLength')); 256 'value' => $properties->getValue('ContentStreamLength'));
webservice/atompub/cmis/KT_cmis_atom_server.services.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +include_once CMIS_ATOM_LIB_FOLDER . 'RepositoryService.inc.php';
  4 +include_once CMIS_ATOM_LIB_FOLDER . 'NavigationService.inc.php';
  5 +include_once CMIS_ATOM_LIB_FOLDER . 'ObjectService.inc.php';
  6 +include_once 'KT_cmis_atom_service_helper.inc.php';
  7 +
  8 +// TODO response if failed auth, need generic response which can be used by all code
  9 +
  10 +/**
  11 + * AtomPub Service: folder
  12 + *
  13 + * Returns children, descendants (up to arbitrary depth) or detail for a particular folder
  14 + *
  15 + */
  16 +class KT_cmis_atom_service_folder extends KT_cmis_atom_service
  17 +{
  18 + public function GET_action()
  19 + {
  20 + $RepositoryService = new RepositoryService();
  21 + $RepositoryService->startSession(self::$authData['username'], self::$authData['password']);
  22 + $repositories = $RepositoryService->getRepositories();
  23 + $repositoryId = $repositories[0]['repositoryId'];
  24 +
  25 + // TODO implement full path/node separation as with Alfresco - i.e. path requests come in on path/ and node requests come in on node/
  26 + // path request e.g.: Root Folder/DroppedDocuments
  27 + // node request e.g.: F1/children
  28 + // node request e.g.: F2
  29 + if (urldecode($this->params[0]) == 'Root Folder')
  30 + {
  31 + $folderId = CMISUtil::encodeObjectId('Folder', 1);
  32 + $folderName = urldecode($this->params[0]);
  33 + }
  34 + // this is a bit of a hack, but then it's to accomodate a bit of a hack to work with the knowledgetree/drupal cmis modules...
  35 + else if ($this->params[0] == 'path')
  36 + {
  37 + $ktapi =& $RepositoryService->getInterface();
  38 + $folderId = KT_cmis_atom_service_helper::getFolderId($this->params, $ktapi);
  39 + }
  40 + else
  41 + {
  42 + $folderId = $this->params[0];
  43 + $ObjectService = new ObjectService();
  44 + $ObjectService->startSession(self::$authData['username'], self::$authData['password']);
  45 + $cmisEntry = $ObjectService->getProperties($repositoryId, $folderId, false, false);
  46 + $folderName = $cmisEntry['properties']['Name']['value'];
  47 +// $feed = $this->getFolderChildrenFeed($NavigationService, $repositoryId, $newObjectId, $cmisEntry['properties']['Name']['value']);
  48 + }
  49 +
  50 + if (!empty($this->params[1]) && (($this->params[1] == 'children') || ($this->params[1] == 'descendants')))
  51 + {
  52 + $NavigationService = new NavigationService();
  53 + $NavigationService->startSession(self::$authData['username'], self::$authData['password']);
  54 +
  55 + $feed = $this->getFolderChildrenFeed($NavigationService, $repositoryId, $folderId, $folderName, $this->params[1]);
  56 + }
  57 + else
  58 + {
  59 + $ObjectService = new ObjectService();
  60 + $ObjectService->startSession(self::$authData['username'], self::$authData['password']);
  61 +
  62 + $feed = $this->getFolderFeed($ObjectService, $repositoryId, $folderId);
  63 + }
  64 +
  65 + //Expose the responseFeed
  66 + $this->responseFeed = $feed;
  67 + }
  68 +
  69 + public function POST_action()
  70 + {
  71 +// $username = $password = 'admin';
  72 + $RepositoryService = new RepositoryService();
  73 + $RepositoryService->startSession(self::$authData['username'], self::$authData['password']);
  74 + $repositories = $RepositoryService->getRepositories();
  75 + $repositoryId = $repositories[0]['repositoryId'];
  76 +
  77 + $folderId = $this->params[0];
  78 + $title = KT_cmis_atom_service_helper::getAtomValues($this->parsedXMLContent['@children'], 'title');
  79 + $summary = KT_cmis_atom_service_helper::getAtomValues($this->parsedXMLContent['@children'], 'summary');
  80 +
  81 + $properties = array('name' => $title, 'summary' => $summary);
  82 +
  83 + // determine whether this is a folder or a document create
  84 + // document create will have a content tag <atom:content> or <content> containing base64 encoding of the document
  85 + $content = KT_cmis_atom_service_helper::getAtomValues($this->parsedXMLContent['@children'], 'content');
  86 + if (is_null($content))
  87 + $type = 'folder';
  88 + else
  89 + $type = 'document';
  90 +
  91 + // TODO what if mime-type is incorrect? CMISSpaces appears to be sending text/plain on an executable file.
  92 + // perhaps because the content is text/plain once base64 encoded?
  93 + // How to determine the actual content type?
  94 + /*
  95 + * <atom:entry xmlns:atom="http://www.w3.org/2005/Atom" xmlns:cmis="http://www.cmis.org/2008/05">
  96 + * <atom:title>setup.txt</atom:title>
  97 + * <atom:summary>setup.txt</atom:summary>
  98 + * <atom:content type="text/plain">dGhpcyBiZSBzb21lIHRlc3QgY29udGVudCBmb3IgYSBkb2N1bWVudCwgeWVzPw==</atom:content>
  99 + * <cmis:object>
  100 + * <cmis:properties>
  101 + * <cmis:propertyString cmis:name="ObjectTypeId"><cmis:value>document</cmis:value></cmis:propertyString>
  102 + * </cmis:properties>
  103 + * </cmis:object>
  104 + * </atom:entry>
  105 + */
  106 +
  107 + $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->parsedXMLContent['@children']['cmis:object']
  108 + [0]['@children']['cmis:properties']
  109 + [0]['@children']);
  110 +
  111 + $ObjectService = new ObjectService();
  112 + $ObjectService->startSession(self::$authData['username'], self::$authData['password']);
  113 + if ($type == 'folder')
  114 + $newObjectId = $ObjectService->createFolder($repositoryId, ucwords($cmisObjectProperties['ObjectTypeId']), $properties, $folderId);
  115 + else
  116 + $newObjectId = $ObjectService->createDocument($repositoryId, ucwords($cmisObjectProperties['ObjectTypeId']), $properties, $folderId, $content);
  117 +
  118 + // check if returned Object Id is a valid CMIS Object Id
  119 + $dummy = CMISUtil::decodeObjectId($newObjectId, $typeId);
  120 + if ($typeId != 'Unknown')
  121 + {
  122 + $this->setStatus(self::STATUS_CREATED);
  123 + if ($type == 'folder')
  124 + {
  125 + $feed = $this->getFolderFeed($ObjectService, $repositoryId, $newObjectId);
  126 + }
  127 + else
  128 + {
  129 + $NavigationService = new NavigationService();
  130 + $NavigationService->startSession(self::$authData['username'], self::$authData['password']);
  131 + $cmisEntry = $ObjectService->getProperties($repositoryId, $folderId, false, false);
  132 + $feed = $this->getFolderChildrenFeed($NavigationService, $repositoryId, $folderId, $cmisEntry['properties']['Name']['value']);
  133 + }
  134 + }
  135 + else
  136 + {
  137 + $this->setStatus(self::STATUS_SERVER_ERROR);
  138 + $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, 'Error: ' . self::STATUS_SERVER_ERROR);
  139 + $entry = $feed->newEntry();
  140 + $feed->newField('error', $newObjectId['message'], $entry);
  141 + }
  142 +
  143 + //Expose the responseFeed
  144 + $this->responseFeed = $feed;
  145 + }
  146 +
  147 + /**
  148 + * Retrieves children/descendants of the specified folder
  149 + * TODO this currently only works in children mode, add descendants
  150 + *
  151 + * @param string $repositoryId
  152 + * @param string $folderId folder id for which children/descendants are requested
  153 + * @param string $feedType children or descendants
  154 + * @return string CMIS AtomPub feed
  155 + */
  156 + private function getFolderChildrenFeed($NavigationService, $repositoryId, $folderId, $folderName, $feedType = 'children')
  157 + {
  158 + if ($feedType == 'children')
  159 + {
  160 + $entries = $NavigationService->getChildren($repositoryId, $folderId, false, false);
  161 + }
  162 + else if ($feedType == 'descendants')
  163 + {
  164 + $entries = $NavigationService->getDescendants($repositoryId, $folderId, false, false);
  165 + }
  166 + else
  167 + {
  168 + // error, we shouldn't be here, if we are then the wrong service/function was called
  169 + }
  170 +
  171 + // $baseURI=NULL,$title=NULL,$link=NULL,$updated=NULL,$author=NULL,$id=NULL
  172 + $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, $folderName . ' ' . ucwords($feedType), null, null, null,
  173 + 'urn:uuid:' . $folderName . '-' . $feedType);
  174 +
  175 + foreach($entries as $cmisEntry)
  176 + {
  177 + KT_cmis_atom_service_helper::createObjectEntry($feed, $cmisEntry, $folderName);
  178 + }
  179 +
  180 + // <cmis:hasMoreItems>false</cmis:hasMoreItems>
  181 +
  182 + // global $childrenFeed
  183 + // $output = $childrenFeed[0];
  184 + // $output = $childrenFeed[1];
  185 +
  186 + return $feed;
  187 + }
  188 +
  189 + /**
  190 + * Retrieves data about a specific folder
  191 + *
  192 + * @param object $ObjectService The CMIS service
  193 + * @param string $repositoryId
  194 + * @param string $folderId
  195 + * @return string CMIS AtomPub feed
  196 + */
  197 + private function getFolderFeed($ObjectService, $repositoryId, $folderId)
  198 + {
  199 + $cmisEntry = $ObjectService->getProperties($repositoryId, $folderId, false, false);
  200 +
  201 + $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, $cmisEntry['properties']['ObjectTypeId']['value'], null, null, null,
  202 + 'urn:uuid:' . $cmisEntry['properties']['ObjectId']['value']);
  203 +
  204 + KT_cmis_atom_service_helper::createObjectEntry($feed, $cmisEntry, $folderName);
  205 +// // <cmis:hasMoreItems>false</cmis:hasMoreItems>
  206 +// // global $folderFeed;
  207 +// // $outputs =
  208 +
  209 + return $feed;
  210 + }
  211 +}
  212 +
  213 +/**
  214 + * AtomPub Service: types
  215 + *
  216 + * Returns a list of supported object types
  217 + *
  218 + */
  219 +class KT_cmis_atom_service_types extends KT_cmis_atom_service
  220 +{
  221 + public function GET_action()
  222 + {
  223 +// $username = $password = 'admin';
  224 + $RepositoryService = new RepositoryService();
  225 + // technically do not need to log in to access this information
  226 + // TODO consider requiring authentication even to access basic repository information
  227 + $RepositoryService->startSession(self::$authData['username'], self::$authData['password']);
  228 +
  229 + // fetch repository id
  230 + $repositories = $RepositoryService->getRepositories();
  231 + $repositoryId = $repositories[0]['repositoryId'];
  232 +
  233 + $types = $RepositoryService->getTypes($repositoryId);
  234 + $type = ((empty($this->params[0])) ? 'all' : $this->params[0]);
  235 + $feed = KT_cmis_atom_service_helper::getTypeFeed($type, $types);
  236 +
  237 + //Expose the responseFeed
  238 + $this->responseFeed = $feed;
  239 + }
  240 +}
  241 +
  242 +/**
  243 + * AtomPub Service: type
  244 + *
  245 + * Returns the type defintion for the selected type
  246 + *
  247 + */
  248 +class KT_cmis_atom_service_type extends KT_cmis_atom_service
  249 +{
  250 + public function GET_action()
  251 + {
  252 +// $username = $password = 'admin';
  253 + $RepositoryService = new RepositoryService();
  254 + // technically do not need to log in to access this information
  255 + // TODO consider requiring authentication even to access basic repository information
  256 + $RepositoryService->startSession(self::$authData['username'], self::$authData['password']);
  257 +
  258 + // fetch repository id
  259 + $repositories = $RepositoryService->getRepositories();
  260 + $repositoryId = $repositories[0]['repositoryId'];
  261 +
  262 + if (!isset($this->params[1]))
  263 + {
  264 + // For easier return in the wanted format, we call getTypes instead of getTypeDefinition.
  265 + // Calling this with a single type specified returns an array containing the definition of
  266 + // just the requested type.
  267 + // NOTE could maybe be more efficient to call getTypeDefinition direct and then place in
  268 + // an array on this side? or directly expose the individual entry response code and
  269 + // call directly from here rather than via getTypeFeed.
  270 + $type = ucwords($this->params[0]);
  271 + $types = $RepositoryService->getTypes($repositoryId, $type);
  272 + $feed = KT_cmis_atom_service_helper::getTypeFeed($type, $types);
  273 + }
  274 + else
  275 + {
  276 + // TODO dynamic dates, as needed everywhere
  277 + // NOTE children of types not yet implemented and we don't support any non-basic types at this time
  278 + $feed = $this->getTypeChildrenFeed($this->params[1]);
  279 + }
  280 +
  281 + //Expose the responseFeed
  282 + $this->responseFeed=$feed;
  283 + }
  284 + /**
  285 + * Retrieves a list of child types for the supplied type
  286 + *
  287 + * NOTE this currently returns a hard coded empty list, since we do not currently support child types
  288 + * TODO make dynamic if/when we support checking for child types (we don't actually need to support child types themselves)
  289 + *
  290 + * @param string $type
  291 + * @return string CMIS AtomPub feed
  292 + */
  293 + private function getTypeChildrenFeed()
  294 + {
  295 + //Create a new response feed
  296 + // $baseURI=NULL,$title=NULL,$link=NULL,$updated=NULL,$author=NULL,$id=NULL
  297 + $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, 'Child Types of ' . ucwords($this->params[0]), null, null, null,
  298 + $this->params[0] . '-children');
  299 +
  300 + // TODO actually fetch child types - to be implemented when we support child types in the API
  301 +
  302 + // id
  303 +
  304 + // links
  305 + $link = $feed->newElement('link');
  306 + $link->appendChild($feed->newAttr('rel','first'));
  307 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . 'type/' . $this->params[0] . '/' . $this->params[1] . '?pageNo=1&amp;pageSize=0'));
  308 + $link->appendChild($feed->newAttr('type', 'application/atom+xml;type=feed'));
  309 +
  310 + $link = $feed->newElement('link');
  311 + $link->appendChild($feed->newAttr('rel','last'));
  312 + // TODO set page number correctly - to be done when we support paging the the API
  313 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . 'type/' . $this->params[0] . '/' . $this->params[1] . '?pageNo=1&amp;pageSize=0'));
  314 + $link->appendChild($feed->newAttr('type', 'application/atom+xml;type=feed'));
  315 +
  316 + // TODO actual dynamic listing, currently we have no objects with which to test
  317 +
  318 + // TODO
  319 +// <updated>2009-06-23T13:40:32.786+02:00</updated>
  320 +// <cmis:hasMoreItems>false</cmis:hasMoreItems>
  321 +/*
  322 + // TODO need to create this dynamically now, will no longer work with static output
  323 + $output = '<?xml version="1.0" encoding="UTF-8"?>
  324 + <feed xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns:cmis="http://www.cmis.org/2008/05">
  325 + <id>urn:uuid:type-' . $type . '-children</id>
  326 + <link rel="self" href="' . CMIS_APP_BASE_URI . 'type/document/children"/>
  327 + <link rel="first" href="' . CMIS_APP_BASE_URI . 'type/document/children?pageNo=1&amp;pageSize=0&amp;guest=" type="application/atom+xml;type=feed"/>
  328 + <link rel="last" href="' . CMIS_APP_BASE_URI . 'type/document/children?pageNo=1&amp;pageSize=0&amp;guest=" type="application/atom+xml;type=feed"/>
  329 + <title>Child types of ' . $type . '</title>
  330 + <updated>2009-06-23T13:40:32.786+02:00</updated>
  331 + <cmis:hasMoreItems>false</cmis:hasMoreItems>
  332 + </feed>';
  333 +*/
  334 + return $feed;
  335 + }
  336 +
  337 +}
  338 +
  339 +/**
  340 + * AtomPub Service: checkedout
  341 + *
  342 + * Returns a list of checked out documents for the logged in user
  343 + *
  344 + */
  345 +// NOTE this is always an empty document, underlying API code still to be implemented
  346 +class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service
  347 +{
  348 + public function GET_action()
  349 + {
  350 +// $username = $password = 'admin';
  351 + $RepositoryService = new RepositoryService();
  352 + $NavigationService = new NavigationService();
  353 +
  354 + $NavigationService->startSession(self::$authData['username'], self::$authData['password']);
  355 +
  356 + $repositories = $RepositoryService->getRepositories();
  357 + $repositoryId = $repositories[0]['repositoryId'];
  358 +
  359 + $checkedout = $NavigationService->getCheckedoutDocs($repositoryId);
  360 +
  361 + //Create a new response feed
  362 + $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, 'Checked out Documents', null, null, null, 'urn:uuid:checkedout');
  363 +
  364 + foreach($checkedout as $document)
  365 + {
  366 + $entry = $feed->newEntry();
  367 + $objectElement = $feed->newElement('cmis:object');
  368 + $propertiesElement = $feed->newElement('cmis:properties');
  369 +
  370 + foreach($cmisEntry['properties'] as $propertyName => $property)
  371 + {
  372 + $propElement = $feed->newElement('cmis:' . $property['type']);
  373 + $propElement->appendChild($feed->newAttr('cmis:name', $propertyName));
  374 + $feed->newField('cmis:value', CMISUtil::boolToString($property['value']), $propElement);
  375 + $propertiesElement->appendChild($propElement);
  376 + }
  377 +
  378 + $objectElement->appendChild($propertiesElement);
  379 + $entry->appendChild($objectElement);
  380 + }
  381 +
  382 + $entry = null;
  383 + $feed->newField('hasMoreItems', 'false', $entry, true);
  384 +
  385 + //Expose the responseFeed
  386 + $this->responseFeed = $feed;
  387 + }
  388 +
  389 +}
  390 +
  391 +/**
  392 + * AtomPub Service: document
  393 + *
  394 + * Returns detail on a particular document
  395 + *
  396 + */
  397 +class KT_cmis_atom_service_document extends KT_cmis_atom_service
  398 +{
  399 + public function GET_action()
  400 + {
  401 +// $username = $password = 'admin';
  402 + $RepositoryService = new RepositoryService();
  403 +
  404 + $ObjectService = new ObjectService();
  405 + $ObjectService->startSession(self::$authData['username'], self::$authData['password']);
  406 +
  407 + $repositories = $RepositoryService->getRepositories();
  408 + $repositoryId = $repositories[0]['repositoryId'];
  409 +
  410 + $cmisEntry = $ObjectService->getProperties($repositoryId, $this->params[0], false, false);
  411 +
  412 + //Create a new response feed
  413 + $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, $cmisEntry['properties']['ObjectTypeId']['value'], null, null, null,
  414 + 'urn:uuid:' . $cmisEntry['properties']['ObjectId']['value']);
  415 +
  416 + KT_cmis_atom_service_helper::createObjectEntry($feed, $cmisEntry, $cmisEntry['properties']['ParentId']['value']);
  417 +
  418 + // <cmis:hasMoreItems>false</cmis:hasMoreItems>
  419 +
  420 +// global $docFeed;
  421 +// $output = $docFeed;
  422 +
  423 + //Expose the responseFeed
  424 + $this->responseFeed=$feed;
  425 + }
  426 +}
  427 +
  428 +$childrenFeed[] = '<?xml version="1.0" encoding="utf-8"?>
  429 + <feed xmlns="http://www.w3.org/2005/Atom" xmlns:cmis="http://www.cmis.org/2008/05">
  430 + <id>urn:uuid:28537649-8af2-4c74-aa92-5d8bbecac9ce-children</id>
  431 + <link rel="self" href="http://10.33.4.34/ktatompub/?/cmis/folder/F1/children"/>
  432 + <title>Root Folder Children</title>
  433 + <entry>
  434 + <id>urn:uuid:86224486-b7ae-4074-a793-82cd259b0026-folder</id>
  435 + <link rel="cmis-children" href="http://10.33.4.34/ktatompub/?cmis/folder/F2/children"/>
  436 +
  437 + <link rel="cmis-descendants" href="http://10.33.4.34/ktatompub/?cmis/folder/F2/descendants"/>
  438 + <link rel="cmis-type" href="http://10.33.4.34:8080/alfresco/service/api/type/folder"/>
  439 + <link rel="cmis-repository" href="http://10.33.4.34:8080/alfresco/service/api/repository"/>
  440 + <summary>DroppedDocuments</summary>
  441 + <title>DroppedDocuments</title>
  442 + <cmis:object>
  443 + <cmis:properties>
  444 + <cmis:propertyId cmis:name="ObjectId">
  445 +
  446 + <cmis:value>F2</cmis:value>
  447 + </cmis:propertyId>
  448 + <cmis:propertyString cmis:name="ObjectTypeId">
  449 + <cmis:value>Folder</cmis:value>
  450 + </cmis:propertyString>
  451 + <cmis:propertyString cmis:name="Name">
  452 + <cmis:value>DroppedDocuments</cmis:value>
  453 +
  454 + </cmis:propertyString>
  455 + </cmis:properties>
  456 + </cmis:object>
  457 + </entry>
  458 + <entry>
  459 + <id>urn:uuid:86224486-b7ae-4074-a793-82cd259b0026-folder</id>
  460 + <link rel="cmis-children" href="http://10.33.4.34/ktatompub/?cmis/folder/F4/children"/>
  461 + <link rel="cmis-descendants" href="http://10.33.4.34/ktatompub/?cmis/folder/F4/descendants"/>
  462 +
  463 + <link rel="cmis-type" href="http://10.33.4.34:8080/alfresco/service/api/type/folder"/>
  464 + <link rel="cmis-repository" href="http://10.33.4.34:8080/alfresco/service/api/repository"/>
  465 + <summary>Test KT Folder</summary>
  466 + <title>Test KT Folder</title>
  467 + <cmis:object>
  468 + <cmis:properties>
  469 + <cmis:propertyId cmis:name="ObjectId">
  470 + <cmis:value>F4</cmis:value>
  471 +
  472 + </cmis:propertyId>
  473 + <cmis:propertyString cmis:name="ObjectTypeId">
  474 + <cmis:value>Folder</cmis:value>
  475 + </cmis:propertyString>
  476 + <cmis:propertyString cmis:name="Name">
  477 + <cmis:value>Test KT Folder</cmis:value>
  478 + </cmis:propertyString>
  479 + </cmis:properties>
  480 +
  481 + </cmis:object>
  482 + </entry>
  483 + <entry>
  484 + <author><name>admin</name></author>
  485 + <content type="application/pdf" src="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/content.h4555-cmis-so.pdf"/><id>urn:uuid:2df9d676-f173-47bb-8ec1-41fa1186b66d</id>
  486 + <link rel="self" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d"/>
  487 +
  488 + <link rel="enclosure" type="application/pdf" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/content.h4555-cmis-so.pdf"/><link rel="edit" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d"/>
  489 + <link rel="edit-media" type="application/pdf" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/content.h4555-cmis-so.pdf"/><link rel="cmis-allowableactions" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/permissions"/>
  490 + <link rel="cmis-relationships" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/associations"/>
  491 + <link rel="cmis-parents" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/parents"/>
  492 + <link rel="cmis-allversions" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/versions"/>
  493 + <link rel="cmis-stream" type="application/pdf" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/content.h4555-cmis-so.pdf"/><link rel="cmis-type" href="http://10.33.4.34:8080/alfresco/service/api/type/document"/>
  494 + <link rel="cmis-repository" href="http://10.33.4.34:8080/alfresco/service/api/repository"/>
  495 + <published>2009-06-23T09:40:47.889+02:00</published>
  496 + <summary></summary>
  497 + <title>h4555-cmis-so.pdf</title>
  498 + <updated>2009-06-23T09:40:58.524+02:00</updated>
  499 +
  500 + <cmis:object>
  501 + <cmis:properties>
  502 + <cmis:propertyId cmis:name="ObjectId"><cmis:value>workspace://SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d</cmis:value></cmis:propertyId>
  503 + <cmis:propertyString cmis:name="BaseType"><cmis:value>document</cmis:value></cmis:propertyString>
  504 + <cmis:propertyString cmis:name="ObjectTypeId"><cmis:value>document</cmis:value></cmis:propertyString>
  505 + <cmis:propertyString cmis:name="CreatedBy"><cmis:value>admin</cmis:value></cmis:propertyString>
  506 +
  507 + <cmis:propertyDateTime cmis:name="CreationDate"><cmis:value>2009-06-23T09:40:47.889+02:00</cmis:value></cmis:propertyDateTime>
  508 + <cmis:propertyString cmis:name="LastModifiedBy"><cmis:value>admin</cmis:value></cmis:propertyString>
  509 + <cmis:propertyDateTime cmis:name="LastModificationDate"><cmis:value>2009-06-23T09:40:58.524+02:00</cmis:value></cmis:propertyDateTime>
  510 + <cmis:propertyString cmis:name="Name"><cmis:value>h4555-cmis-so.pdf</cmis:value></cmis:propertyString>
  511 + <cmis:propertyBoolean cmis:name="IsImmutable"><cmis:value>false</cmis:value></cmis:propertyBoolean>
  512 +
  513 + <cmis:propertyBoolean cmis:name="IsLatestVersion"><cmis:value>true</cmis:value></cmis:propertyBoolean>
  514 + <cmis:propertyBoolean cmis:name="IsMajorVersion"><cmis:value>false</cmis:value></cmis:propertyBoolean>
  515 + <cmis:propertyBoolean cmis:name="IsLatestMajorVersion"><cmis:value>false</cmis:value></cmis:propertyBoolean>
  516 + <cmis:propertyString cmis:name="VersionLabel"/>
  517 + <cmis:propertyId cmis:name="VersionSeriesId"><cmis:value>workspace://SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d</cmis:value></cmis:propertyId>
  518 +
  519 + <cmis:propertyBoolean cmis:name="IsVersionSeriesCheckedOut"><cmis:value>false</cmis:value></cmis:propertyBoolean>
  520 + <cmis:propertyString cmis:name="VersionSeriesCheckedOutBy"/>
  521 + <cmis:propertyId cmis:name="VersionSeriesCheckedOutId"/>
  522 + <cmis:propertyString cmis:name="CheckinComment"/>
  523 + <cmis:propertyInteger cmis:name="ContentStreamLength"><cmis:value>343084</cmis:value></cmis:propertyInteger>
  524 + <cmis:propertyString cmis:name="ContentStreamMimeType"><cmis:value>application/pdf</cmis:value></cmis:propertyString>
  525 + <cmis:propertyString cmis:name="ContentStreamFilename"><cmis:value>h4555-cmis-so.pdf</cmis:value></cmis:propertyString>
  526 +
  527 + <cmis:propertyString cmis:name="ContentStreamURI"><cmis:value>http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/content.h4555-cmis-so.pdf</cmis:value></cmis:propertyString>
  528 + </cmis:properties>
  529 + </cmis:object>
  530 +
  531 +
  532 + </entry>
  533 + </feed>';
  534 +
  535 + $childrenFeed[] = '<?xml version="1.0" encoding="UTF-8"?>
  536 +<feed xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns:cmis="http://www.cmis.org/2008/05" xmlns:alf="http://www.alfresco.org" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/">
  537 +<author><name>System</name></author>
  538 +<generator version="3.0.0 (Stable 1526)">Alfresco (Labs)</generator>
  539 +<icon>http://10.33.4.34:8080/alfresco/images/logo/AlfrescoLogo16.ico</icon>
  540 +<id>urn:uuid:28537649-8af2-4c74-aa92-5d8bbecac9ce-children</id>
  541 +<link rel="self" href="http://10.33.4.34:8080/alfresco/service/api/path/workspace/SpacesStore/Company%20Home/children"/>
  542 +<link rel="cmis-source" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce"/>
  543 +<link rel="first" href="http://10.33.4.34:8080/alfresco/service/api/path/workspace/SpacesStore/Company%20Home/children?pageNo=1&amp;pageSize=0&amp;guest=&amp;format=atomfeed" type="application/atom+xml;type=feed"/>
  544 +
  545 +<link rel="last" href="http://10.33.4.34:8080/alfresco/service/api/path/workspace/SpacesStore/Company%20Home/children?pageNo=1&amp;pageSize=0&amp;guest=&amp;format=atomfeed" type="application/atom+xml;type=feed"/>
  546 +<title>Company Home Children</title>
  547 +<updated>2009-06-18T10:20:29.937+02:00</updated>
  548 +<entry>
  549 +<author><name>System</name></author>
  550 +<content>e98319fa-76e4-478f-8ce8-a3a0fd683e2c</content>
  551 +<id>urn:uuid:e98319fa-76e4-478f-8ce8-a3a0fd683e2c</id>
  552 +
  553 +<link rel="self" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/e98319fa-76e4-478f-8ce8-a3a0fd683e2c"/>
  554 +<link rel="edit" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/e98319fa-76e4-478f-8ce8-a3a0fd683e2c"/>
  555 +<link rel="cmis-allowableactions" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/e98319fa-76e4-478f-8ce8-a3a0fd683e2c/permissions"/>
  556 +<link rel="cmis-relationships" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/e98319fa-76e4-478f-8ce8-a3a0fd683e2c/associations"/>
  557 +<link rel="cmis-parent" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce"/>
  558 +<link rel="cmis-folderparent" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/e98319fa-76e4-478f-8ce8-a3a0fd683e2c/parent"/>
  559 +<link rel="cmis-children" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/e98319fa-76e4-478f-8ce8-a3a0fd683e2c/children"/>
  560 +<link rel="cmis-descendants" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/e98319fa-76e4-478f-8ce8-a3a0fd683e2c/descendants"/>
  561 +<link rel="cmis-type" href="http://10.33.4.34:8080/alfresco/service/api/type/F/st_sites"/>
  562 +<link rel="cmis-repository" href="http://10.33.4.34:8080/alfresco/service/api/repository"/>
  563 +<published>2009-06-18T10:20:37.788+02:00</published>
  564 +<summary>Site Collaboration Spaces</summary>
  565 +<title>Sites</title>
  566 +<updated>2009-06-18T10:20:37.874+02:00</updated>
  567 +
  568 +<cmis:object>
  569 +<cmis:properties>
  570 +<cmis:propertyId cmis:name="ObjectId"><cmis:value>workspace://SpacesStore/e98319fa-76e4-478f-8ce8-a3a0fd683e2c</cmis:value></cmis:propertyId>
  571 +<cmis:propertyString cmis:name="BaseType"><cmis:value>folder</cmis:value></cmis:propertyString>
  572 +<cmis:propertyString cmis:name="ObjectTypeId"><cmis:value>F/st_sites</cmis:value></cmis:propertyString>
  573 +<cmis:propertyString cmis:name="CreatedBy"><cmis:value>System</cmis:value></cmis:propertyString>
  574 +
  575 +<cmis:propertyDateTime cmis:name="CreationDate"><cmis:value>2009-06-18T10:20:37.788+02:00</cmis:value></cmis:propertyDateTime>
  576 +<cmis:propertyString cmis:name="LastModifiedBy"><cmis:value>System</cmis:value></cmis:propertyString>
  577 +<cmis:propertyDateTime cmis:name="LastModificationDate"><cmis:value>2009-06-18T10:20:37.874+02:00</cmis:value></cmis:propertyDateTime>
  578 +<cmis:propertyString cmis:name="Name"><cmis:value>Sites</cmis:value></cmis:propertyString>
  579 +<cmis:propertyId cmis:name="ParentId"><cmis:value>workspace://SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce</cmis:value></cmis:propertyId>
  580 +
  581 +</cmis:properties>
  582 +</cmis:object>
  583 +<cmis:terminator/>
  584 +<app:edited>2009-06-18T10:20:37.874+02:00</app:edited>
  585 +<alf:icon>http://10.33.4.34:8080/alfresco/images/icons/space-icon-default-16.gif</alf:icon>
  586 +</entry>
  587 +<entry>
  588 +<author><name>System</name></author>
  589 +<content>8c80a0f7-74b4-4bd8-bb76-a2464e4b2d10</content>
  590 +<id>urn:uuid:8c80a0f7-74b4-4bd8-bb76-a2464e4b2d10</id>
  591 +
  592 +<link rel="self" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/8c80a0f7-74b4-4bd8-bb76-a2464e4b2d10"/>
  593 +<link rel="edit" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/8c80a0f7-74b4-4bd8-bb76-a2464e4b2d10"/>
  594 +<link rel="cmis-allowableactions" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/8c80a0f7-74b4-4bd8-bb76-a2464e4b2d10/permissions"/>
  595 +<link rel="cmis-relationships" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/8c80a0f7-74b4-4bd8-bb76-a2464e4b2d10/associations"/>
  596 +<link rel="cmis-parent" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce"/>
  597 +<link rel="cmis-folderparent" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/8c80a0f7-74b4-4bd8-bb76-a2464e4b2d10/parent"/>
  598 +<link rel="cmis-children" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/8c80a0f7-74b4-4bd8-bb76-a2464e4b2d10/children"/>
  599 +<link rel="cmis-descendants" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/8c80a0f7-74b4-4bd8-bb76-a2464e4b2d10/descendants"/>
  600 +<link rel="cmis-type" href="http://10.33.4.34:8080/alfresco/service/api/type/folder"/>
  601 +<link rel="cmis-repository" href="http://10.33.4.34:8080/alfresco/service/api/repository"/>
  602 +<published>2009-06-18T10:20:29.939+02:00</published>
  603 +<summary>User managed definitions</summary>
  604 +<title>Data Dictionary</title>
  605 +<updated>2009-06-18T10:20:30.004+02:00</updated>
  606 +
  607 +<cmis:object>
  608 +<cmis:properties>
  609 +<cmis:propertyId cmis:name="ObjectId"><cmis:value>workspace://SpacesStore/8c80a0f7-74b4-4bd8-bb76-a2464e4b2d10</cmis:value></cmis:propertyId>
  610 +<cmis:propertyString cmis:name="BaseType"><cmis:value>folder</cmis:value></cmis:propertyString>
  611 +<cmis:propertyString cmis:name="ObjectTypeId"><cmis:value>folder</cmis:value></cmis:propertyString>
  612 +<cmis:propertyString cmis:name="CreatedBy"><cmis:value>System</cmis:value></cmis:propertyString>
  613 +
  614 +<cmis:propertyDateTime cmis:name="CreationDate"><cmis:value>2009-06-18T10:20:29.939+02:00</cmis:value></cmis:propertyDateTime>
  615 +<cmis:propertyString cmis:name="LastModifiedBy"><cmis:value>System</cmis:value></cmis:propertyString>
  616 +<cmis:propertyDateTime cmis:name="LastModificationDate"><cmis:value>2009-06-18T10:20:30.004+02:00</cmis:value></cmis:propertyDateTime>
  617 +<cmis:propertyString cmis:name="Name"><cmis:value>Data Dictionary</cmis:value></cmis:propertyString>
  618 +<cmis:propertyId cmis:name="ParentId"><cmis:value>workspace://SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce</cmis:value></cmis:propertyId>
  619 +
  620 +</cmis:properties>
  621 +</cmis:object>
  622 +<cmis:terminator/>
  623 +<app:edited>2009-06-18T10:20:30.004+02:00</app:edited>
  624 +<alf:icon>http://10.33.4.34:8080/alfresco/images/icons/space-icon-default-16.gif</alf:icon>
  625 +</entry>
  626 +<entry>
  627 +<author><name>System</name></author>
  628 +<content>ba2524ef-7f3d-4ed4-84a0-8d99b6524737</content>
  629 +<id>urn:uuid:ba2524ef-7f3d-4ed4-84a0-8d99b6524737</id>
  630 +
  631 +<link rel="self" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/ba2524ef-7f3d-4ed4-84a0-8d99b6524737"/>
  632 +<link rel="edit" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/ba2524ef-7f3d-4ed4-84a0-8d99b6524737"/>
  633 +<link rel="cmis-allowableactions" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/ba2524ef-7f3d-4ed4-84a0-8d99b6524737/permissions"/>
  634 +<link rel="cmis-relationships" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/ba2524ef-7f3d-4ed4-84a0-8d99b6524737/associations"/>
  635 +<link rel="cmis-parent" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce"/>
  636 +<link rel="cmis-folderparent" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/ba2524ef-7f3d-4ed4-84a0-8d99b6524737/parent"/>
  637 +<link rel="cmis-children" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/ba2524ef-7f3d-4ed4-84a0-8d99b6524737/children"/>
  638 +<link rel="cmis-descendants" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/ba2524ef-7f3d-4ed4-84a0-8d99b6524737/descendants"/>
  639 +<link rel="cmis-type" href="http://10.33.4.34:8080/alfresco/service/api/type/folder"/>
  640 +<link rel="cmis-repository" href="http://10.33.4.34:8080/alfresco/service/api/repository"/>
  641 +<published>2009-06-18T10:20:30.312+02:00</published>
  642 +<summary>The guest root space</summary>
  643 +<title>Guest Home</title>
  644 +
  645 +<updated>2009-06-18T10:20:30.400+02:00</updated>
  646 +<cmis:object>
  647 +<cmis:properties>
  648 +<cmis:propertyId cmis:name="ObjectId"><cmis:value>workspace://SpacesStore/ba2524ef-7f3d-4ed4-84a0-8d99b6524737</cmis:value></cmis:propertyId>
  649 +<cmis:propertyString cmis:name="BaseType"><cmis:value>folder</cmis:value></cmis:propertyString>
  650 +<cmis:propertyString cmis:name="ObjectTypeId"><cmis:value>folder</cmis:value></cmis:propertyString>
  651 +<cmis:propertyString cmis:name="CreatedBy"><cmis:value>System</cmis:value></cmis:propertyString>
  652 +
  653 +<cmis:propertyDateTime cmis:name="CreationDate"><cmis:value>2009-06-18T10:20:30.312+02:00</cmis:value></cmis:propertyDateTime>
  654 +<cmis:propertyString cmis:name="LastModifiedBy"><cmis:value>System</cmis:value></cmis:propertyString>
  655 +<cmis:propertyDateTime cmis:name="LastModificationDate"><cmis:value>2009-06-18T10:20:30.400+02:00</cmis:value></cmis:propertyDateTime>
  656 +<cmis:propertyString cmis:name="Name"><cmis:value>Guest Home</cmis:value></cmis:propertyString>
  657 +<cmis:propertyId cmis:name="ParentId"><cmis:value>workspace://SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce</cmis:value></cmis:propertyId>
  658 +
  659 +</cmis:properties>
  660 +</cmis:object>
  661 +<cmis:terminator/>
  662 +<app:edited>2009-06-18T10:20:30.400+02:00</app:edited>
  663 +<alf:icon>http://10.33.4.34:8080/alfresco/images/icons/space-icon-default-16.gif</alf:icon>
  664 +</entry>
  665 +<entry>
  666 +<author><name>System</name></author>
  667 +<content>86224486-b7ae-4074-a793-82cd259b0026</content>
  668 +<id>urn:uuid:86224486-b7ae-4074-a793-82cd259b0026</id>
  669 +
  670 +<link rel="self" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/86224486-b7ae-4074-a793-82cd259b0026"/>
  671 +<link rel="edit" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/86224486-b7ae-4074-a793-82cd259b0026"/>
  672 +<link rel="cmis-allowableactions" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/86224486-b7ae-4074-a793-82cd259b0026/permissions"/>
  673 +<link rel="cmis-relationships" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/86224486-b7ae-4074-a793-82cd259b0026/associations"/>
  674 +<link rel="cmis-parent" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce"/>
  675 +<link rel="cmis-folderparent" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/86224486-b7ae-4074-a793-82cd259b0026/parent"/>
  676 +<link rel="cmis-children" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/86224486-b7ae-4074-a793-82cd259b0026/children"/>
  677 +<link rel="cmis-descendants" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/86224486-b7ae-4074-a793-82cd259b0026/descendants"/>
  678 +<link rel="cmis-type" href="http://10.33.4.34:8080/alfresco/service/api/type/folder"/>
  679 +<link rel="cmis-repository" href="http://10.33.4.34:8080/alfresco/service/api/repository"/>
  680 +<published>2009-06-18T10:20:30.402+02:00</published>
  681 +<summary>User Homes</summary>
  682 +<title>User Homes</title>
  683 +<updated>2009-06-18T10:20:30.428+02:00</updated>
  684 +
  685 +<cmis:object>
  686 +<cmis:properties>
  687 +<cmis:propertyId cmis:name="ObjectId"><cmis:value>workspace://SpacesStore/86224486-b7ae-4074-a793-82cd259b0026</cmis:value></cmis:propertyId>
  688 +<cmis:propertyString cmis:name="BaseType"><cmis:value>folder</cmis:value></cmis:propertyString>
  689 +<cmis:propertyString cmis:name="ObjectTypeId"><cmis:value>folder</cmis:value></cmis:propertyString>
  690 +<cmis:propertyString cmis:name="CreatedBy"><cmis:value>System</cmis:value></cmis:propertyString>
  691 +
  692 +<cmis:propertyDateTime cmis:name="CreationDate"><cmis:value>2009-06-18T10:20:30.402+02:00</cmis:value></cmis:propertyDateTime>
  693 +<cmis:propertyString cmis:name="LastModifiedBy"><cmis:value>System</cmis:value></cmis:propertyString>
  694 +<cmis:propertyDateTime cmis:name="LastModificationDate"><cmis:value>2009-06-18T10:20:30.428+02:00</cmis:value></cmis:propertyDateTime>
  695 +<cmis:propertyString cmis:name="Name"><cmis:value>User Homes</cmis:value></cmis:propertyString>
  696 +<cmis:propertyId cmis:name="ParentId"><cmis:value>workspace://SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce</cmis:value></cmis:propertyId>
  697 +
  698 +</cmis:properties>
  699 +</cmis:object>
  700 +<cmis:terminator/>
  701 +<app:edited>2009-06-18T10:20:30.428+02:00</app:edited>
  702 +<alf:icon>http://10.33.4.34:8080/alfresco/images/icons/space-icon-default-16.gif</alf:icon>
  703 +</entry>
  704 +<entry>
  705 +<author><name>System</name></author>
  706 +<content>0df9087f-e334-4890-a467-b60e3d6be92c</content>
  707 +<id>urn:uuid:0df9087f-e334-4890-a467-b60e3d6be92c</id>
  708 +
  709 +<link rel="self" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/0df9087f-e334-4890-a467-b60e3d6be92c"/>
  710 +<link rel="edit" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/0df9087f-e334-4890-a467-b60e3d6be92c"/>
  711 +<link rel="cmis-allowableactions" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/0df9087f-e334-4890-a467-b60e3d6be92c/permissions"/>
  712 +<link rel="cmis-relationships" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/0df9087f-e334-4890-a467-b60e3d6be92c/associations"/>
  713 +<link rel="cmis-parent" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce"/>
  714 +<link rel="cmis-folderparent" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/0df9087f-e334-4890-a467-b60e3d6be92c/parent"/>
  715 +<link rel="cmis-children" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/0df9087f-e334-4890-a467-b60e3d6be92c/children"/>
  716 +<link rel="cmis-descendants" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/0df9087f-e334-4890-a467-b60e3d6be92c/descendants"/>
  717 +<link rel="cmis-type" href="http://10.33.4.34:8080/alfresco/service/api/type/folder"/>
  718 +<link rel="cmis-repository" href="http://10.33.4.34:8080/alfresco/service/api/repository"/>
  719 +<published>2009-06-18T10:20:45.115+02:00</published>
  720 +<summary>Web Content Management Spaces</summary>
  721 +<title>Web Projects</title>
  722 +<updated>2009-06-18T10:20:45.137+02:00</updated>
  723 +
  724 +<cmis:object>
  725 +<cmis:properties>
  726 +<cmis:propertyId cmis:name="ObjectId"><cmis:value>workspace://SpacesStore/0df9087f-e334-4890-a467-b60e3d6be92c</cmis:value></cmis:propertyId>
  727 +<cmis:propertyString cmis:name="BaseType"><cmis:value>folder</cmis:value></cmis:propertyString>
  728 +<cmis:propertyString cmis:name="ObjectTypeId"><cmis:value>folder</cmis:value></cmis:propertyString>
  729 +<cmis:propertyString cmis:name="CreatedBy"><cmis:value>System</cmis:value></cmis:propertyString>
  730 +
  731 +<cmis:propertyDateTime cmis:name="CreationDate"><cmis:value>2009-06-18T10:20:45.115+02:00</cmis:value></cmis:propertyDateTime>
  732 +<cmis:propertyString cmis:name="LastModifiedBy"><cmis:value>System</cmis:value></cmis:propertyString>
  733 +<cmis:propertyDateTime cmis:name="LastModificationDate"><cmis:value>2009-06-18T10:20:45.137+02:00</cmis:value></cmis:propertyDateTime>
  734 +<cmis:propertyString cmis:name="Name"><cmis:value>Web Projects</cmis:value></cmis:propertyString>
  735 +<cmis:propertyId cmis:name="ParentId"><cmis:value>workspace://SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce</cmis:value></cmis:propertyId>
  736 +
  737 +</cmis:properties>
  738 +</cmis:object>
  739 +<cmis:terminator/>
  740 +<app:edited>2009-06-18T10:20:45.137+02:00</app:edited>
  741 +<alf:icon>http://10.33.4.34:8080/alfresco/images/icons/space-icon-default-16.gif</alf:icon>
  742 +</entry>
  743 +<entry>
  744 +<author><name>admin</name></author>
  745 +<content type="application/pdf" src="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/content.h4555-cmis-so.pdf"/><id>urn:uuid:2df9d676-f173-47bb-8ec1-41fa1186b66d</id>
  746 +<link rel="self" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d"/>
  747 +
  748 +<link rel="enclosure" type="application/pdf" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/content.h4555-cmis-so.pdf"/><link rel="edit" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d"/>
  749 +<link rel="edit-media" type="application/pdf" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/content.h4555-cmis-so.pdf"/><link rel="cmis-allowableactions" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/permissions"/>
  750 +<link rel="cmis-relationships" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/associations"/>
  751 +<link rel="cmis-parents" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/parents"/>
  752 +<link rel="cmis-allversions" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/versions"/>
  753 +<link rel="cmis-stream" type="application/pdf" href="http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/content.h4555-cmis-so.pdf"/><link rel="cmis-type" href="http://10.33.4.34:8080/alfresco/service/api/type/document"/>
  754 +<link rel="cmis-repository" href="http://10.33.4.34:8080/alfresco/service/api/repository"/>
  755 +<published>2009-06-23T09:40:47.889+02:00</published>
  756 +<summary></summary>
  757 +<title>h4555-cmis-so.pdf</title>
  758 +<updated>2009-06-23T09:40:58.524+02:00</updated>
  759 +
  760 +<cmis:object>
  761 +<cmis:properties>
  762 +<cmis:propertyId cmis:name="ObjectId"><cmis:value>workspace://SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d</cmis:value></cmis:propertyId>
  763 +<cmis:propertyString cmis:name="BaseType"><cmis:value>document</cmis:value></cmis:propertyString>
  764 +<cmis:propertyString cmis:name="ObjectTypeId"><cmis:value>document</cmis:value></cmis:propertyString>
  765 +<cmis:propertyString cmis:name="CreatedBy"><cmis:value>admin</cmis:value></cmis:propertyString>
  766 +
  767 +<cmis:propertyDateTime cmis:name="CreationDate"><cmis:value>2009-06-23T09:40:47.889+02:00</cmis:value></cmis:propertyDateTime>
  768 +<cmis:propertyString cmis:name="LastModifiedBy"><cmis:value>admin</cmis:value></cmis:propertyString>
  769 +<cmis:propertyDateTime cmis:name="LastModificationDate"><cmis:value>2009-06-23T09:40:58.524+02:00</cmis:value></cmis:propertyDateTime>
  770 +<cmis:propertyString cmis:name="Name"><cmis:value>h4555-cmis-so.pdf</cmis:value></cmis:propertyString>
  771 +<cmis:propertyBoolean cmis:name="IsImmutable"><cmis:value>false</cmis:value></cmis:propertyBoolean>
  772 +
  773 +<cmis:propertyBoolean cmis:name="IsLatestVersion"><cmis:value>true</cmis:value></cmis:propertyBoolean>
  774 +<cmis:propertyBoolean cmis:name="IsMajorVersion"><cmis:value>false</cmis:value></cmis:propertyBoolean>
  775 +<cmis:propertyBoolean cmis:name="IsLatestMajorVersion"><cmis:value>false</cmis:value></cmis:propertyBoolean>
  776 +<cmis:propertyString cmis:name="VersionLabel"/>
  777 +<cmis:propertyId cmis:name="VersionSeriesId"><cmis:value>workspace://SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d</cmis:value></cmis:propertyId>
  778 +
  779 +<cmis:propertyBoolean cmis:name="IsVersionSeriesCheckedOut"><cmis:value>false</cmis:value></cmis:propertyBoolean>
  780 +<cmis:propertyString cmis:name="VersionSeriesCheckedOutBy"/>
  781 +<cmis:propertyId cmis:name="VersionSeriesCheckedOutId"/>
  782 +<cmis:propertyString cmis:name="CheckinComment"/>
  783 +<cmis:propertyInteger cmis:name="ContentStreamLength"><cmis:value>343084</cmis:value></cmis:propertyInteger>
  784 +<cmis:propertyString cmis:name="ContentStreamMimeType"><cmis:value>application/pdf</cmis:value></cmis:propertyString>
  785 +<cmis:propertyString cmis:name="ContentStreamFilename"><cmis:value>h4555-cmis-so.pdf</cmis:value></cmis:propertyString>
  786 +
  787 +<cmis:propertyString cmis:name="ContentStreamURI"><cmis:value>http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/content.h4555-cmis-so.pdf</cmis:value></cmis:propertyString>
  788 +</cmis:properties>
  789 +</cmis:object>
  790 +<cmis:terminator/>
  791 +<app:edited>2009-06-23T09:40:58.524+02:00</app:edited>
  792 +<alf:icon>http://10.33.4.34:8080/alfresco/images/filetypes/pdf.gif</alf:icon>
  793 +</entry>
  794 +<cmis:hasMoreItems>false</cmis:hasMoreItems>
  795 +<opensearch:totalResults>6</opensearch:totalResults>
  796 +<opensearch:startIndex>0</opensearch:startIndex>
  797 +
  798 +<opensearch:itemsPerPage>0</opensearch:itemsPerPage>
  799 +</feed>';
  800 +
  801 +$folderFeed = '<?xml version="1.0" encoding="UTF-8"?>
  802 +<feed xmlns="http://www.w3.org/2005/Atom" xmlns:cmis="http://www.cmis.org/2008/05">
  803 +<entry>
  804 +<author><name>System</name></author>
  805 +<content>28537649-8af2-4c74-aa92-5d8bbecac9ce</content>
  806 +<id>urn:uuid:28537649-8af2-4c74-aa92-5d8bbecac9ce</id>
  807 +<link rel="self" href="http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce"/>
  808 +<link rel="edit" href="http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce"/>
  809 +<link rel="cmis-allowableactions" href="http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce/permissions"/>
  810 +<link rel="cmis-relationships" href="http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce/associations"/>
  811 +<link rel="cmis-children" href="http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce/children"/>
  812 +<link rel="cmis-descendants" href="http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce/descendants"/>
  813 +<link rel="cmis-type" href="http://127.0.0.1:8080/alfresco/service/api/type/folder"/>
  814 +<link rel="cmis-repository" href="http://127.0.0.1:8080/alfresco/service/api/repository"/>
  815 +<published>2009-06-18T10:20:29.871+02:00</published>
  816 +<summary>The company root space</summary>
  817 +<title>Company Home</title>
  818 +<updated>2009-06-18T10:20:29.937+02:00</updated>
  819 +<cmis:object>
  820 +<cmis:properties>
  821 +<cmis:propertyId cmis:name="ObjectId"><cmis:value>workspace://SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce</cmis:value></cmis:propertyId>
  822 +<cmis:propertyString cmis:name="BaseType"><cmis:value>folder</cmis:value></cmis:propertyString>
  823 +<cmis:propertyString cmis:name="ObjectTypeId"><cmis:value>folder</cmis:value></cmis:propertyString>
  824 +<cmis:propertyString cmis:name="CreatedBy"><cmis:value>System</cmis:value></cmis:propertyString>
  825 +<cmis:propertyDateTime cmis:name="CreationDate"><cmis:value>2009-06-18T10:20:29.871+02:00</cmis:value></cmis:propertyDateTime>
  826 +<cmis:propertyString cmis:name="LastModifiedBy"><cmis:value>System</cmis:value></cmis:propertyString>
  827 +<cmis:propertyDateTime cmis:name="LastModificationDate"><cmis:value>2009-06-18T10:20:29.937+02:00</cmis:value></cmis:propertyDateTime>
  828 +<cmis:propertyString cmis:name="Name"><cmis:value>Company Home</cmis:value></cmis:propertyString>
  829 +<cmis:propertyId cmis:name="ParentId"/>
  830 +</cmis:properties>
  831 +</cmis:object>
  832 +<cmis:terminator/>
  833 +<app:edited>2009-06-18T10:20:29.937+02:00</app:edited>
  834 +<alf:icon>http://127.0.0.1:8080/alfresco/images/icons/space-icon-default-16.gif</alf:icon>
  835 +</entry>
  836 +</feed>';
  837 +
  838 +$docFeed = '<?xml version="1.0" encoding="UTF-8"?>
  839 +<feed xmlns="http://www.w3.org/2005/Atom" xmlns:cmis="http://www.cmis.org/2008/05">
  840 +<entry>
  841 +<author><name>admin</name></author>
  842 +<content type="application/pdf" src="http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/content.h4555-cmis-so.pdf"/><id>urn:uuid:2df9d676-f173-47bb-8ec1-41fa1186b66d</id>
  843 +<link rel="self" href="http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d"/>
  844 +<link rel="enclosure" type="application/pdf" href="http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/content.h4555-cmis-so.pdf"/><link rel="edit" href="http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d"/>
  845 +<link rel="edit-media" type="application/pdf" href="http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/content.h4555-cmis-so.pdf"/><link rel="cmis-allowableactions" href="http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/permissions"/>
  846 +<link rel="cmis-relationships" href="http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/associations"/>
  847 +<link rel="cmis-parents" href="http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/parents"/>
  848 +<link rel="cmis-allversions" href="http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/versions"/>
  849 +<link rel="cmis-stream" type="application/pdf" href="http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/content.h4555-cmis-so.pdf"/><link rel="cmis-type" href="http://127.0.0.1:8080/alfresco/service/api/type/document"/>
  850 +<link rel="cmis-repository" href="http://127.0.0.1:8080/alfresco/service/api/repository"/>
  851 +<published>2009-06-23T09:40:47.889+02:00</published>
  852 +<summary></summary>
  853 +<title>h4555-cmis-so.pdf</title>
  854 +<updated>2009-06-23T09:40:58.524+02:00</updated>
  855 +<cmis:object>
  856 +<cmis:properties>
  857 +<cmis:propertyId cmis:name="ObjectId"><cmis:value>workspace://SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d</cmis:value></cmis:propertyId>
  858 +<cmis:propertyString cmis:name="BaseType"><cmis:value>document</cmis:value></cmis:propertyString>
  859 +<cmis:propertyString cmis:name="ObjectTypeId"><cmis:value>document</cmis:value></cmis:propertyString>
  860 +<cmis:propertyString cmis:name="CreatedBy"><cmis:value>admin</cmis:value></cmis:propertyString>
  861 +<cmis:propertyDateTime cmis:name="CreationDate"><cmis:value>2009-06-23T09:40:47.889+02:00</cmis:value></cmis:propertyDateTime>
  862 +<cmis:propertyString cmis:name="LastModifiedBy"><cmis:value>admin</cmis:value></cmis:propertyString>
  863 +<cmis:propertyDateTime cmis:name="LastModificationDate"><cmis:value>2009-06-23T09:40:58.524+02:00</cmis:value></cmis:propertyDateTime>
  864 +<cmis:propertyString cmis:name="Name"><cmis:value>h4555-cmis-so.pdf</cmis:value></cmis:propertyString>
  865 +<cmis:propertyBoolean cmis:name="IsImmutable"><cmis:value>false</cmis:value></cmis:propertyBoolean>
  866 +<cmis:propertyBoolean cmis:name="IsLatestVersion"><cmis:value>true</cmis:value></cmis:propertyBoolean>
  867 +<cmis:propertyBoolean cmis:name="IsMajorVersion"><cmis:value>false</cmis:value></cmis:propertyBoolean>
  868 +<cmis:propertyBoolean cmis:name="IsLatestMajorVersion"><cmis:value>false</cmis:value></cmis:propertyBoolean>
  869 +<cmis:propertyString cmis:name="VersionLabel"/>
  870 +<cmis:propertyId cmis:name="VersionSeriesId"><cmis:value>workspace://SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d</cmis:value></cmis:propertyId>
  871 +<cmis:propertyBoolean cmis:name="IsVersionSeriesCheckedOut"><cmis:value>false</cmis:value></cmis:propertyBoolean>
  872 +<cmis:propertyString cmis:name="VersionSeriesCheckedOutBy"/>
  873 +<cmis:propertyId cmis:name="VersionSeriesCheckedOutId"/>
  874 +<cmis:propertyString cmis:name="CheckinComment"/>
  875 +<cmis:propertyInteger cmis:name="ContentStreamLength"><cmis:value>343084</cmis:value></cmis:propertyInteger>
  876 +<cmis:propertyString cmis:name="ContentStreamMimeType"><cmis:value>application/pdf</cmis:value></cmis:propertyString>
  877 +<cmis:propertyString cmis:name="ContentStreamFilename"><cmis:value>h4555-cmis-so.pdf</cmis:value></cmis:propertyString>
  878 +<cmis:propertyString cmis:name="ContentStreamURI"><cmis:value>http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/content.h4555-cmis-so.pdf</cmis:value></cmis:propertyString>
  879 +</cmis:properties>
  880 +</cmis:object>
  881 +<cmis:terminator/>
  882 +<app:edited>2009-06-23T09:40:58.524+02:00</app:edited>
  883 +<alf:icon>http://127.0.0.1:8080/alfresco/images/filetypes/pdf.gif</alf:icon>
  884 +</entry>
  885 +</feed>';
  886 +?>
0 \ No newline at end of file 887 \ No newline at end of file
webservice/atompub/cmis/KT_cmis_atom_service_helper.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +class KT_cmis_atom_service_helper {
  4 +
  5 + /**
  6 + * Creates an AtomPub entry for a CMIS entry and adds it to the supplied feed
  7 + *
  8 + * @param object $feed The feed to which we add the entry
  9 + * @param array $cmisEntry The entry data
  10 + * @param string $parent The parent folder
  11 + */
  12 + static public function createObjectEntry(&$feed, $cmisEntry, $parent, $path)
  13 + {
  14 + // TODO next two lots of code (1 commented 1 not) must be replaced with something better
  15 +// $feed->newId('urn:uuid:' . $cmisEntry['properties']['Name']['value'] . '-'
  16 +// . strtolower($cmisEntry['properties']['ObjectTypeId']['value']), $entry);
  17 +
  18 +// echo $_SERVER['QUERY_STRING']."<BR>\n";
  19 +// preg_match('/^\/?[^\/]*\/folder\/(.*)\/[^\/]*\/?$/', trim($_SERVER['QUERY_STRING'], '/'), $matches);
  20 +// $path = $matches[1];
  21 +// $parent = preg_replace('/\/[^\/]*$/', '', $path);
  22 +// // TODO fix path to work on old method, after fixing drupal module to not require extended path
  23 +//
  24 +// $path = '';
  25 +
  26 + $id = $cmisEntry['properties']['ObjectId']['value'];
  27 + $entry = $feed->newEntry();
  28 + $feed->newField('id', 'urn:uuid:' . $id, $entry);
  29 +// print_r($cmisEntry);
  30 + // links
  31 + // TODO check parent link is correct, fix if needed
  32 + $link = $feed->newElement('link');
  33 + $link->appendChild($feed->newAttr('rel','cmis-parent'));
  34 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/folder/' . $cmisEntry['properties']['ParentId']['value']));
  35 + $entry->appendChild($link);
  36 +
  37 + if (strtolower($cmisEntry['properties']['ObjectTypeId']['value']) == 'folder')
  38 + {
  39 + // TODO check parent link is correct, fix if needed
  40 + $link = $feed->newElement('link');
  41 + $link->appendChild($feed->newAttr('rel','cmis-folderparent'));
  42 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/folder/' . $cmisEntry['properties']['ParentId']['value']));
  43 + $entry->appendChild($link);
  44 + $link = $feed->newElement('link');
  45 + $link->appendChild($feed->newAttr('rel','cmis-children'));
  46 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/'
  47 + . strtolower($cmisEntry['properties']['ObjectTypeId']['value'])
  48 + . '/' . $cmisEntry['properties']['ObjectId']['value']
  49 + . '/children'));
  50 + $entry->appendChild($link);
  51 + $link = $feed->newElement('link');
  52 + $link->appendChild($feed->newAttr('rel','cmis-descendants'));
  53 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/'
  54 + . strtolower($cmisEntry['properties']['ObjectTypeId']['value'])
  55 + . '/' . $cmisEntry['properties']['ObjectId']['value']
  56 + . '/descendants'));
  57 + $entry->appendChild($link);
  58 + }
  59 +
  60 + $link = $feed->newElement('link');
  61 + $link->appendChild($feed->newAttr('rel','cmis-type'));
  62 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/type/' . strtolower($cmisEntry['properties']['ObjectTypeId']['value'])));
  63 + $entry->appendChild($link);
  64 + $link = $feed->newElement('link');
  65 + $link->appendChild($feed->newAttr('rel','cmis-repository'));
  66 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/servicedocument'));
  67 + $entry->appendChild($link);
  68 + // end links
  69 +
  70 + $entry->appendChild($feed->newElement('summary', $cmisEntry['properties']['Name']['value']));
  71 + $entry->appendChild($feed->newElement('title', $cmisEntry['properties']['Name']['value']));
  72 +
  73 + // main CMIS entry
  74 + $objectElement = $feed->newElement('cmis:object');
  75 + $propertiesElement = $feed->newElement('cmis:properties');
  76 +
  77 + foreach($cmisEntry['properties'] as $propertyName => $property)
  78 + {
  79 + $propElement = $feed->newElement('cmis:' . $property['type']);
  80 + $propElement->appendChild($feed->newAttr('cmis:name', $propertyName));
  81 + $feed->newField('cmis:value', CMISUtil::boolToString($property['value']), $propElement);
  82 + $propertiesElement->appendChild($propElement);
  83 + }
  84 +
  85 + $objectElement->appendChild($propertiesElement);
  86 + $entry->appendChild($objectElement);
  87 + }
  88 +
  89 + /**
  90 + * Retrieves the list of types|type definition as a CMIS AtomPub feed
  91 + *
  92 + * @param string $typeDef Type requested - 'All Types' indicates a listing, else only a specific type
  93 + * @param array $types The types found
  94 + * @return string CMIS AtomPub feed
  95 + */
  96 + static public function getTypeFeed($typeDef, $types)
  97 + {
  98 + $typesString = '';
  99 + $typesHeading = '';
  100 + switch($typeDef)
  101 + {
  102 + case 'all':
  103 + case 'children':
  104 + case 'descendants':
  105 + $typesString = 'types-' . $typeDef;
  106 + $typesHeading = 'All Types';
  107 + break;
  108 + default:
  109 + $typesString = 'type-' . $typeDef;
  110 + $typesHeading = $typeDef;
  111 + break;
  112 + }
  113 +
  114 + //Create a new response feed
  115 + $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, $typesHeading, null, null, null, 'urn:uuid:' . $typesString);
  116 +
  117 + foreach($types as $type)
  118 + {
  119 + $entry = $feed->newEntry();
  120 + $feed->newId('urn:uuid:type-' . strtolower($type['typeId']), $entry);
  121 +
  122 + // links
  123 + $link = $feed->newElement('link');
  124 + $link->appendChild($feed->newAttr('rel','self'));
  125 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/type/' . strtolower($type['typeId'])));
  126 + $entry->appendChild($link);
  127 + $link = $feed->newElement('link');
  128 + $link->appendChild($feed->newAttr('rel','cmis-type'));
  129 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/type/' . strtolower($type['typeId'])));
  130 + $entry->appendChild($link);
  131 + $link = $feed->newElement('link');
  132 + $link->appendChild($feed->newAttr('rel','cmis-children'));
  133 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/type/' . strtolower($type['typeId']) . '/children'));
  134 + $entry->appendChild($link);
  135 + $link = $feed->newElement('link');
  136 + $link->appendChild($feed->newAttr('rel','cmis-descendants'));
  137 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/type/' . strtolower($type['typeId']) . '/descendants'));
  138 + $entry->appendChild($link);
  139 + $link = $feed->newElement('link');
  140 + $link->appendChild($feed->newAttr('rel','cmis-repository'));
  141 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/servicedocument'));
  142 + $entry->appendChild($link);
  143 +
  144 + $entry->appendChild($feed->newElement('summary', $type['typeId'] . ' Type'));
  145 + $entry->appendChild($feed->newElement('title', $type['typeId']));
  146 +
  147 + // main CMIS entry
  148 + $feedElement = $feed->newElement('cmis:' . strtolower($type['typeId']) . 'Type');
  149 + foreach($type as $property => $value)
  150 + {
  151 + $feed->newField($property, CMISUtil::boolToString($value), $feedElement);
  152 + }
  153 +
  154 + $entry->appendChild($feedElement);
  155 + }
  156 +
  157 + return $feed;
  158 + }
  159 +
  160 + /**
  161 + * Fetches the CMIS objectId based on the path
  162 + *
  163 + * @param array $path
  164 + * @param object $ktapi KTAPI instance
  165 + */
  166 + // TODO make this much more efficient than this messy method
  167 + static public function getFolderId($path, &$ktapi)
  168 + {
  169 + // lose first item
  170 + array_shift($path);
  171 +
  172 + $numQ = count($path);
  173 + $numFolders = $numQ;
  174 + $folderId = 1;
  175 +
  176 + $start = 0;
  177 + while($start < $numFolders)
  178 + {
  179 + $name = $path[$numQ-$numFolders+$start];
  180 + // hack to fix drupal url encoding issue
  181 + $name = str_replace('%2520', '%20', $name);
  182 +
  183 + $folderName = urldecode($name);
  184 + $folder = $ktapi->get_folder_by_name($folderName, $folderId);
  185 + $folderId = $folder->get_folderid();
  186 + ++$start;
  187 + }
  188 +
  189 + return CMISUtil::encodeObjectId('Folder', $folderId);
  190 + }
  191 +
  192 + static public function getCmisProperties($xmlArray)
  193 + {
  194 + $properties = array();
  195 +
  196 + foreach($xmlArray as $cmisPropertyDefinition)
  197 + {
  198 + foreach($cmisPropertyDefinition as $propertyType => $propertyDefinition)
  199 + {
  200 + $properties[$propertyDefinition['@attributes']['cmis:name']] = $propertyDefinition['@children']['cmis:value'][0]['@value'];
  201 + }
  202 + }
  203 +
  204 + return $properties;
  205 + }
  206 +
  207 + static public function getAtomValues($xmlArray, $tag)
  208 + {
  209 + if (!is_null($xmlArray['atom:'.$tag]))
  210 + return $xmlArray['atom:'.$tag][0]['@value'];
  211 + else if (!is_null($xmlArray[$tag]))
  212 + return $xmlArray[$tag][0]['@value'];
  213 +
  214 + return null;
  215 + }
  216 +
  217 +}
  218 +
  219 +?>
webservice/atompub/cmis/index.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +/**
  4 + * Framework for an Atom Publication Protocol Service
  5 + *
  6 + * KnowledgeTree Community Edition
  7 + * Document Management Made Simple
  8 + * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  9 + * Portions copyright The Jam Warehouse Software (Pty) Limited
  10 + *
  11 + * This program is free software; you can redistribute it and/or modify it under
  12 + * the terms of the GNU General Public License version 3 as published by the
  13 + * Free Software Foundation.
  14 + *
  15 + * This program is distributed in the hope that it will be useful, but WITHOUT
  16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  18 + * details.
  19 + *
  20 + * You should have received a copy of the GNU General Public License
  21 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  22 + *
  23 + * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
  24 + * California 94120-7775, or email info@knowledgetree.com.
  25 + *
  26 + * The interactive user interfaces in modified source and object code versions
  27 + * of this program must display Appropriate Legal Notices, as required under
  28 + * Section 5 of the GNU General Public License version 3.
  29 + *
  30 + * In accordance with Section 7(b) of the GNU General Public License version 3,
  31 + * these Appropriate Legal Notices must retain the display of the "Powered by
  32 + * KnowledgeTree" logo and retain the original copyright notice. If the display of the
  33 + * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
  34 + * must display the words "Powered by KnowledgeTree" and retain the original
  35 + * copyright notice.
  36 + * Contributor( s):
  37 + * Mark Holtzhausen <mark@knowledgetree.com>
  38 + * Paul Barrett <paul@knowledgetree.com>
  39 + *
  40 + */
  41 +
  42 +require_once('../../../config/dmsDefaults.php');
  43 +
  44 +define('KT_APP_BASE_URI', "http://".$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']).'/?/');
  45 +define('KT_APP_SYSTEM_URI', "http://".$_SERVER['HTTP_HOST']);
  46 +define('KT_ATOM_LIB_FOLDER', '../../classes/atompub/');
  47 +
  48 +// should make the "dms" part dynamic but right now this is needed fast
  49 +define('CMIS_APP_BASE_URI', trim(KT_APP_BASE_URI, '/'));
  50 +define('CMIS_APP_SYSTEM_URI', KT_APP_SYSTEM_URI);
  51 +define('CMIS_ATOM_LIB_FOLDER', trim(KT_ATOM_LIB_FOLDER, '/') . '/cmis/');
  52 +
  53 +// fetch username and password for auth; note that this apparently only works when PHP is run as an apache module
  54 +// TODO method to fetch username and password when running PHP as CGI, if possible
  55 +// HTTP Basic Auth:
  56 +$username = $_SERVER['PHP_AUTH_USER'];
  57 +$password = $_SERVER['PHP_AUTH_PW'];
  58 +
  59 +/**
  60 + * Includes
  61 + */
  62 +include_once(KT_ATOM_LIB_FOLDER.'XMLns2array.inc.php');
  63 +include_once(CMIS_ATOM_LIB_FOLDER.'KT_cmis_atom_server.inc.php');
  64 +include_once(CMIS_ATOM_LIB_FOLDER.'KT_cmis_atom_baseDoc.inc.php');
  65 +include_once(CMIS_ATOM_LIB_FOLDER.'KT_cmis_atom_responseFeed.inc.php'); //Containing the response feed class allowing easy atom feed generation
  66 +include_once(CMIS_ATOM_LIB_FOLDER.'KT_cmis_atom_serviceDoc.inc.php'); //Containing the servicedoc class allowing easy ServiceDocument generation
  67 +include_once(CMIS_ATOM_LIB_FOLDER.'KT_cmis_atom_service.inc.php'); //Containing the servicedoc class allowing easy ServiceDocument generation
  68 +
  69 +include_once('KT_cmis_atom_server.services.inc.php');
  70 +//Start the AtomPubProtocol Routing Engine
  71 +$APP = new KT_cmis_atom_server();
  72 +
  73 +// FIXME HACK! this should not happen every time, ONLY on a service doc request
  74 +// CMIS service document setup
  75 +$APP->initServiceDocument();
  76 +// FIXME HACK! this should not happen every time, ONLY on a service doc request
  77 +// User defined title tag
  78 +$APP->addWorkspaceTag('dms','atom:title',$APP->repositoryInfo['repositoryName']);
  79 +
  80 +/**
  81 + * Register Services
  82 + *
  83 + * Registered services are classes extended from KT_atom_service
  84 + * The registration process takes the following parameters
  85 + * Workspace :The workspace within which the service collection will be grouped
  86 + * ServiceName :This is the name by which the service/collection is exposed
  87 + * ServiceClass :This is the class name of the class to be instantiated when this service is accessed
  88 + * Title :This is the title given to the service/collection in the servicedocument
  89 + * http://ktatompub/index.php?/service/param1/param2
  90 + * http://ktatompub/?/folder/children/whatfoldertolookat
  91 + * http://ktatompub/{folder/folder2/folder3/}service/param1/param2
  92 +*/
  93 +// TODO consider a registerServices function which will, dependant on what is requested, register the appropriate services, keep the logic out of the index file
  94 +$APP->registerService('dms', 'folder', 'KT_cmis_atom_service_folder', 'Root Folder Children Collection',
  95 + array(rawurlencode($APP->repositoryInfo['rootFolderId']), 'children'), 'root-children');
  96 +$APP->registerService('dms', 'folder', 'KT_cmis_atom_service_folder', 'Root Folder Children Collection',
  97 + array(rawurlencode($APP->repositoryInfo['rootFolderId']), 'descendants'), 'root-descendants');
  98 +$APP->registerService('dms', 'checkedout', 'KT_cmis_atom_service_checkedout', 'Checked Out Document Collection', null, 'checkedout');
  99 +$APP->registerService('dms', 'types', 'KT_cmis_atom_service_types', 'Object Type Collection', null, 'types-children');
  100 +$APP->registerService('dms', 'types', 'KT_cmis_atom_service_types', 'Object Type Collection', null, 'types-descendants');
  101 +
  102 +// FIXME HACK! this should not happen every time, ONLY on a specific request, should NOT appear in service document as this is not definable at that time;
  103 +// SHOULD be appearing in types listing feed
  104 +// NOTE $requestParams is meaningless if not actually requesting this service, so not a good way to register the service really
  105 +$queryArray=split('/',trim($_SERVER['QUERY_STRING'],'/'));
  106 +$requestParams=array_slice($queryArray,2);
  107 +$APP->registerService('dms', 'type', 'KT_cmis_atom_service_type', 'Object Type Collection', explode('/', $requestParams), 'types-descendants');
  108 +// FIXME HACK! see above, this one for documents
  109 +$APP->registerService('dms', 'document', 'KT_cmis_atom_service_document', 'Object Type Collection', explode('/', $requestParams), 'types-descendants');
  110 +
  111 +//Execute the current url/header request
  112 +$APP->execute();
  113 +
  114 +//Render the resulting feed response
  115 +$APP->render();
  116 +
  117 +?>
webservice/classes/atompub/KT_atom_responseFeed.inc.php
@@ -4,11 +4,10 @@ class KT_atom_responseFeed extends KT_atom_baseDoc { @@ -4,11 +4,10 @@ class KT_atom_responseFeed extends KT_atom_baseDoc {
4 protected $baseURI=NULL; 4 protected $baseURI=NULL;
5 protected $feed=NULL; 5 protected $feed=NULL;
6 6
7 -  
8 - public function __construct($baseURI=NULL,$title=NULL,$link=NULL,$updated=NULL,$author=NULL,$id=NULL){ 7 + public function __construct($baseURI=NULL,$title=NULL,$link=NULL,$updated=NULL,$author=NULL,$id=NULL, $workspace = null){
9 parent::__construct(); 8 parent::__construct();
  9 + $this->baseURI = $baseURI;
10 $this->constructHeader(); 10 $this->constructHeader();
11 - $this->baseURI=$baseURI;  
12 } 11 }
13 12
14 protected function constructHeader(){ 13 protected function constructHeader(){
webservice/classes/atompub/KT_atom_server.inc.php
@@ -3,7 +3,7 @@ class KT_atom_server{ @@ -3,7 +3,7 @@ class KT_atom_server{
3 protected $services=array(); 3 protected $services=array();
4 protected $workspaceDetail=array(); 4 protected $workspaceDetail=array();
5 protected $errors=array(); 5 protected $errors=array();
6 - protected $output=''; 6 + public $output='';
7 protected $queryArray=array(); 7 protected $queryArray=array();
8 protected $serviceName=''; 8 protected $serviceName='';
9 protected $method=''; 9 protected $method='';
@@ -13,6 +13,9 @@ class KT_atom_server{ @@ -13,6 +13,9 @@ class KT_atom_server{
13 public function __construct(){ 13 public function __construct(){
14 } 14 }
15 15
  16 + protected function hook_beforeDocCreate($doc){return true;}
  17 + protected function hook_beforeDocRender($doc){return true;}
  18 +
16 /** 19 /**
17 * Run the server switchboard - find the correct service class to instantiate, execute & render that class with the passed parameteres 20 * Run the server switchboard - find the correct service class to instantiate, execute & render that class with the passed parameteres
18 * 21 *
@@ -22,23 +25,23 @@ class KT_atom_server{ @@ -22,23 +25,23 @@ class KT_atom_server{
22 $queryArray=split('/',trim($_SERVER['QUERY_STRING'],'/')); 25 $queryArray=split('/',trim($_SERVER['QUERY_STRING'],'/'));
23 $rawRequest=@file_get_contents('php://input'); 26 $rawRequest=@file_get_contents('php://input');
24 27
25 - $workspace=strtolower(trim($queryArray[0])); 28 + $workspace=strtolower(trim($queryArray[0]));
26 $serviceName=strtolower(trim($queryArray[1])); 29 $serviceName=strtolower(trim($queryArray[1]));
27 $requestParams=array_slice($queryArray,2); 30 $requestParams=array_slice($queryArray,2);
28 $this->queryArray=$queryArray; 31 $this->queryArray=$queryArray;
29 - $this->serviceName=$service; 32 + $this->serviceName=$serviceName;
30 $this->method=$reqMethod; 33 $this->method=$reqMethod;
31 $this->workspace=$workspace; 34 $this->workspace=$workspace;
32 -  
33 - if($workspace=='servicedocument'){ 35 +
  36 + if($workspace=='servicedocument'){
34 $this->serviceDocument(); 37 $this->serviceDocument();
35 return; 38 return;
36 } 39 }
37 - 40 +
38 $service=$this->getRegisteredService($workspace,$serviceName); 41 $service=$this->getRegisteredService($workspace,$serviceName);
39 if(is_array($service)){ 42 if(is_array($service)){
40 $serviceClass=$service['serviceClass']; 43 $serviceClass=$service['serviceClass'];
41 - echo 'made it'; 44 +// echo 'made it';
42 $serviceObject=new $serviceClass($reqMethod,$requestParams,$rawRequest); 45 $serviceObject=new $serviceClass($reqMethod,$requestParams,$rawRequest);
43 $this->output=$serviceObject->render(); 46 $this->output=$serviceObject->render();
44 }else{ 47 }else{
@@ -46,9 +49,10 @@ class KT_atom_server{ @@ -46,9 +49,10 @@ class KT_atom_server{
46 // return; 49 // return;
47 $serviceObject=new KT_atom_service($requestParams,$rawRequest); 50 $serviceObject=new KT_atom_service($requestParams,$rawRequest);
48 $serviceObject->setStatus(KT_atom_service::STATUS_NOT_FOUND); 51 $serviceObject->setStatus(KT_atom_service::STATUS_NOT_FOUND);
49 - $this->output=$serviceObject->render(); 52 + if($this->hook_beforeDocRender($serviceObject)) $this->output=$serviceObject->render();
50 } 53 }
51 $this->serviceObject=$serviceObject; 54 $this->serviceObject=$serviceObject;
  55 + return $serviceObject;
52 } 56 }
53 57
54 58
webservice/classes/atompub/KT_atom_service.inc.php
1 <?php 1 <?php
2 class KT_atom_service{ 2 class KT_atom_service{
3 - const STATUS_OK ='200 OK';  
4 - const STATUS_NOT_FOUND ='204 No Content';  
5 - const STATUS_NOT_ALLOWED ='204 Not Allowed';  
6 - const STATUS_NOT_AUTHENTICATED ='204 Not Authenticated';  
7 - const STATUS_CREATED ='201 Created';  
8 - const STATUS_UPDATED ='200 Updated';  
9 - const STATUS_NOT_MODIFIED ='304 Not Modified'; //For use with ETag & If-None-Match headers.  
10 - const STATUS_PRECONDITION_FAILED='412 Precondition Failed'; //Could not update document because another a newer version exist on the server than the one you are trying to update 3 + const STATUS_OK = '200 OK';
  4 + const STATUS_NOT_FOUND = '204 No Content';
  5 + const STATUS_NOT_ALLOWED = '204 Not Allowed';
  6 + const STATUS_NOT_AUTHENTICATED = '204 Not Authenticated';
  7 + const STATUS_CREATED = '201 Created';
  8 + const STATUS_UPDATED = '200 Updated';
  9 + const STATUS_NOT_MODIFIED = '304 Not Modified'; // For use with ETag & If-None-Match headers.
  10 + const STATUS_BAD_REQUEST = '400 Bad Request'; // Client issued a wrongly constructed request
  11 + const STATUS_PRECONDITION_FAILED = '412 Precondition Failed'; // Could not update document because another a newer version exist on the server than the one you are trying to update
  12 + const STATUS_SERVER_ERROR = '500 Internal Server Error'; // Server encountered an error processing the request
11 13
12 public $responseFeed=NULL; 14 public $responseFeed=NULL;
13 public $responseHeader=NULL; 15 public $responseHeader=NULL;
@@ -59,11 +61,17 @@ class KT_atom_service{ @@ -59,11 +61,17 @@ class KT_atom_service{
59 return $this->responseFeed->render(); 61 return $this->responseFeed->render();
60 } 62 }
61 63
62 - protected function xml2array($xml){  
63 - if(class_exists('')){ 64 + protected function xml2array($xml)
  65 + {
  66 + if (trim($xml) == '') return array();
  67 +
  68 + if(class_exists('XMLns2array'))
  69 + {
64 $array=XMLns2array::parse($xml); 70 $array=XMLns2array::parse($xml);
65 - }else{  
66 - $array=json_decode(json_encode(@simplexml_load_string($xml)),true); 71 + }
  72 + else
  73 + {
  74 + $array=json_decode(json_encode(@simplexml_load_string($xml)), true);
67 } 75 }
68 return $array; 76 return $array;
69 } 77 }
webservice/classes/atompub/cmis/KT_cmis_atom_baseDoc.inc.php 0 โ†’ 100644
  1 +<?php
  2 +/**
  3 + * Framework for an Atom Publication Protocol Service
  4 + *
  5 + * KnowledgeTree Community Edition
  6 + * Document Management Made Simple
  7 + * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  8 + * Portions copyright The Jam Warehouse Software (Pty) Limited
  9 + *
  10 + * This program is free software; you can redistribute it and/or modify it under
  11 + * the terms of the GNU General Public License version 3 as published by the
  12 + * Free Software Foundation.
  13 + *
  14 + * This program is distributed in the hope that it will be useful, but WITHOUT
  15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  17 + * details.
  18 + *
  19 + * You should have received a copy of the GNU General Public License
  20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21 + *
  22 + * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
  23 + * California 94120-7775, or email info@knowledgetree.com.
  24 + *
  25 + * The interactive user interfaces in modified source and object code versions
  26 + * of this program must display Appropriate Legal Notices, as required under
  27 + * Section 5 of the GNU General Public License version 3.
  28 + *
  29 + * In accordance with Section 7(b) of the GNU General Public License version 3,
  30 + * these Appropriate Legal Notices must retain the display of the "Powered by
  31 + * KnowledgeTree" logo and retain the original copyright notice. If the display of the
  32 + * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
  33 + * must display the words "Powered by KnowledgeTree" and retain the original
  34 + * copyright notice.
  35 + * Contributor( s):
  36 + * Mark Holtzhausen <mark@knowledgetree.com>
  37 + * Paul Barrett <paul@knowledgetree.com>
  38 + *
  39 + */
  40 +
  41 +/**
  42 + * Includes
  43 + */
  44 +
  45 +include_once(KT_ATOM_LIB_FOLDER.'KT_atom_baseDoc.inc.php'); //Containing the parent class allowing easy XML manipulation
  46 +
  47 +class KT_cmis_atom_baseDoc extends KT_atom_baseDoc {
  48 +
  49 + // override and extend as needed
  50 +
  51 +}
  52 +
  53 +?>
0 \ No newline at end of file 54 \ No newline at end of file
webservice/classes/atompub/cmis/KT_cmis_atom_responseFeed.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +include_once(KT_ATOM_LIB_FOLDER.'KT_atom_responseFeed.inc.php');
  4 +
  5 +class KT_cmis_atom_responseFeed extends KT_atom_responseFeed {
  6 +
  7 + // override and extend as needed
  8 +
  9 + public $workspace = null;
  10 +
  11 + public function __construct($baseURI = NULL, $title = NULL, $link = NULL, $updated = NULL, $author = NULL, $id = NULL)
  12 + {
  13 + $queryArray = split('/', trim($_SERVER['QUERY_STRING'], '/'));
  14 + $this->workspace = strtolower(trim($queryArray[0]));
  15 + $this->id = $id;
  16 + $this->title = $title;
  17 +
  18 + parent::__construct($baseURI, $title, $link, $updated, $author, $id);
  19 + }
  20 +
  21 + protected function constructHeader()
  22 + {
  23 + $feed = $this->newElement('feed');
  24 +// $feed->appendChild($this->newAttr('xmlns','http://www.w3.org/2007/app'));
  25 +// $feed->appendChild($this->newAttr('xmlns:atom','http://www.w3.org/2005/Atom'));
  26 + $feed->appendChild($this->newAttr('xmlns','http://www.w3.org/2005/Atom'));
  27 + $feed->appendChild($this->newAttr('xmlns:cmis','http://www.cmis.org/2008/05'));
  28 + $this->feed = &$feed;
  29 +
  30 + if (!is_null($this->id))
  31 + {
  32 + $this->newId($this->id, $this->feed);
  33 + }
  34 +
  35 + $link = $this->newElement('link');
  36 + $link->appendChild($this->newAttr('rel','self'));
  37 + $link->appendChild($this->newAttr('href', $this->baseURI . trim($_SERVER['QUERY_STRING'], '/')));
  38 + $feed->appendChild($link);
  39 +
  40 + if (!is_null($this->title))
  41 + {
  42 + $this->feed->appendChild($this->newElement('title', $this->title));
  43 + }
  44 +
  45 + $this->DOM->appendChild($this->feed);
  46 + }
  47 +
  48 + public function &newId($id, $entry = null)
  49 + {
  50 + $id = $this->newElement('id', $id);
  51 + if(isset($entry))$entry->appendChild($id);
  52 + return $id;
  53 + }
  54 +
  55 +// public function &newField($name = NULL, $value = NULL, &$entry = NULL)
  56 +// {
  57 +// $append = false;
  58 +//
  59 +// if(func_num_args() > 3)
  60 +// {
  61 +// $append = ((func_get_arg(3) === true) ? true : false);
  62 +// }
  63 +//
  64 +// $field = $this->newElement('cmis:' . $name, $value);
  65 +//
  66 +// if (isset($entry)) $entry->appendChild($field);
  67 +// else if ($append) $this->feed->appendChild($field);
  68 +//
  69 +// return $field;
  70 +// }
  71 +
  72 + /*
  73 + public function &newEntry()
  74 + {
  75 + $entry = $this->newElement('entry');
  76 + $this->feed->appendChild($entry);
  77 + return $entry;
  78 + }
  79 +
  80 + public function &newId($id, $entry = null)
  81 + {
  82 + $id = $this->newElement('id', $id);
  83 + if(isset($entry))$entry->appendChild($id);
  84 + return $id;
  85 + }
  86 +
  87 + public function &newField($name = NULL, $value = NULL, &$entry = NULL)
  88 + {
  89 + $append = false;
  90 +
  91 + if(func_num_args() > 3)
  92 + {
  93 + $append = ((func_get_arg(3) === true) ? true : false);
  94 + }
  95 +
  96 + $field = $this->newElement('cmis:' . $name,$value);
  97 +
  98 + if (isset($entry)) $entry->appendChild($field);
  99 + else if ($append) $this->feed->appendChild($field);
  100 +
  101 + return $field;
  102 + }
  103 + */
  104 +
  105 +}
  106 +
  107 +class KT_cmis_atom_ResponseFeed_GET extends KT_cmis_atom_responseFeed{}
  108 +class KT_cmis_atom_ResponseFeed_PUT extends KT_cmis_atom_responseFeed{}
  109 +class KT_cmis_atom_ResponseFeed_POST extends KT_cmis_atom_responseFeed{}
  110 +class KT_cmis_atom_ResponseFeed_DELETE extends KT_cmis_atom_responseFeed{}
  111 +
  112 +?>
0 \ No newline at end of file 113 \ No newline at end of file
webservice/classes/atompub/cmis/KT_cmis_atom_server.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +include_once(KT_ATOM_LIB_FOLDER . 'KT_atom_server.inc.php');
  4 +include_once('RepositoryService.inc.php');
  5 +
  6 +class KT_cmis_atom_server extends KT_atom_server {
  7 +
  8 + // override and extend as needed
  9 + public $repositoryInfo;
  10 +
  11 + public function initServiceDocument()
  12 + {
  13 + $queryArray = split('/', trim($_SERVER['QUERY_STRING'], '/'));
  14 + $workspace = strtolower(trim($queryArray[0]));
  15 + if ($workspace == 'servicedocument')
  16 + {
  17 + include 'services/cmis/RepositoryService.inc.php';
  18 + $RepositoryService = new RepositoryService();
  19 +
  20 + // fetch data for response
  21 + $repositories = $RepositoryService->getRepositories();
  22 + // fetch for default first repo; NOTE that this will probably have to change at some point, quick and dirty for now
  23 + $this->repositoryInfo = $RepositoryService->getRepositoryInfo($repositories[0]['repositoryId']);
  24 + }
  25 + }
  26 +
  27 + public function serviceDocument()
  28 + {
  29 + $service = new KT_cmis_atom_serviceDoc(KT_APP_BASE_URI);
  30 +
  31 + foreach($this->services as $workspace => $collection)
  32 + {
  33 + //Creating the Default Workspace for use with standard atomPub Clients
  34 + $ws = $service->newWorkspace();
  35 +
  36 + $hadDetail=false;
  37 + if(isset($this->workspaceDetail[$workspace]))
  38 + {
  39 + if(is_array($this->workspaceDetail[$workspace]))
  40 + {
  41 + foreach ($this->workspaceDetail[$workspace] as $wsTag=>$wsValue)
  42 + {
  43 + $ws->appendChild($service->newElement($wsTag,$wsValue));
  44 + $hadDetail=true;
  45 + }
  46 + }
  47 + }
  48 +
  49 + if(!$hadDetail) {
  50 + $ws->appendChild($service->newElement('atom:title',$workspace));
  51 + }
  52 +
  53 + $ws->appendChild($service->newAttr('cmis:repositoryRelationship', $this->repositoryInfo['repositoryRelationship']));
  54 +
  55 + // repository information
  56 + $element = $service->newElement('cmis:repositoryInfo');
  57 + foreach($this->repositoryInfo as $key => $repoData)
  58 + {
  59 + if ($key == 'rootFolderId')
  60 + {
  61 + $repoData = CMIS_APP_BASE_URI . $workspace . '/folder/' . rawurlencode($repoData);
  62 + }
  63 +
  64 + if (!is_array($repoData))
  65 + {
  66 + $element->appendChild($service->newElement('cmis:' . $key, $repoData));
  67 + }
  68 + else
  69 + {
  70 + $elementSub = $service->newElement('cmis:' . $key);
  71 + foreach($repoData as $key2 => $data)
  72 + {
  73 + $elementSub->appendChild($service->newElement('cmis:' . $key2, CMISUtil::boolToString($data)));
  74 + }
  75 + $element->appendChild($elementSub);
  76 + }
  77 + }
  78 + $ws->appendChild($element);
  79 +
  80 + foreach($collection as $serviceName => $serviceInstance)
  81 + {
  82 + foreach($serviceInstance as $instance)
  83 + {
  84 + $collectionStr = CMIS_APP_BASE_URI . $workspace . '/' . $serviceName . '/'
  85 + . (is_array($instance['parameters']) ? implode('/', $instance['parameters']).'/' : '');
  86 + $col = $service->newCollection($collectionStr, $instance['title'], $instance['collectionType'], $ws);
  87 + }
  88 + }
  89 + }
  90 +
  91 + $this->output = $service->getAPPdoc();
  92 + }
  93 +
  94 + public function registerService($workspace = NULL, $serviceName = NULL, $serviceClass = NULL, $title = NULL,
  95 + $serviceParameters = NULL, $collectionType = NULL)
  96 + {
  97 + $workspace = strtolower(trim($workspace));
  98 + $serviceName = strtolower(trim($serviceName));
  99 +
  100 + $serviceRecord = array(
  101 + 'fileName' => $fileName,
  102 + 'serviceClass' => $serviceClass,
  103 + 'title' => $title,
  104 + 'parameters' => $serviceParameters,
  105 + 'collectionType' => $collectionType
  106 + );
  107 +
  108 + $this->services[$workspace][$serviceName][] = $serviceRecord;
  109 + }
  110 +
  111 + public function getRegisteredService($workspace, $serviceName = NULL)
  112 + {
  113 + $serviceName = strtolower(trim($serviceName));
  114 + if(isset($this->services[$workspace][$serviceName]))
  115 + {
  116 + return $this->services[$workspace][$serviceName][0];
  117 + }
  118 +
  119 + return false;
  120 + }
  121 +
  122 +}
  123 +
  124 +?>
0 \ No newline at end of file 125 \ No newline at end of file
webservice/classes/atompub/cmis/KT_cmis_atom_service.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +include_once(KT_ATOM_LIB_FOLDER.'KT_atom_service.inc.php');
  4 +
  5 +class KT_cmis_atom_service extends KT_atom_service {
  6 +
  7 + // override and extend as needed
  8 +
  9 + static protected $authData = array();
  10 +
  11 + protected function parseHeaders()
  12 + {
  13 +// echo "PARSE HEADERS\n";
  14 + parent::parseHeaders();
  15 +// echo "CHECKING HEADERS\n";
  16 +// print_r($this->headers);
  17 +// print_r($_SERVER);
  18 + // attempt to fetch auth info from supplied headers
  19 + if (!empty($this->headers['Authorization']))
  20 + {
  21 + $auth = base64_decode(preg_replace('/Basic */', '', $this->headers['Authorization']));
  22 + $authData = explode(':', $auth);
  23 +// print_r($authData);
  24 + self::$authData['username'] = $authData[0];
  25 + self::$authData['password'] = $authData[1];
  26 + }
  27 + // if failed, attempt to fetch from $_SERVER array instead
  28 + else if (isset($_SERVER['PHP_AUTH_USER']))
  29 + {
  30 + self::$authData['username'] = $_SERVER['PHP_AUTH_USER'];
  31 + self::$authData['password'] = $_SERVER['PHP_AUTH_PW'];
  32 + }
  33 + }
  34 +
  35 +}
  36 +?>
0 \ No newline at end of file 37 \ No newline at end of file
webservice/classes/atompub/cmis/KT_cmis_atom_serviceDoc.inc.php 0 โ†’ 100644
  1 +<?php
  2 +/**
  3 + * Framework for an Atom Publication Protocol Service
  4 + *
  5 + * KnowledgeTree Community Edition
  6 + * Document Management Made Simple
  7 + * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  8 + * Portions copyright The Jam Warehouse Software (Pty) Limited
  9 + *
  10 + * This program is free software; you can redistribute it and/or modify it under
  11 + * the terms of the GNU General Public License version 3 as published by the
  12 + * Free Software Foundation.
  13 + *
  14 + * This program is distributed in the hope that it will be useful, but WITHOUT
  15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  17 + * details.
  18 + *
  19 + * You should have received a copy of the GNU General Public License
  20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21 + *
  22 + * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
  23 + * California 94120-7775, or email info@knowledgetree.com.
  24 + *
  25 + * The interactive user interfaces in modified source and object code versions
  26 + * of this program must display Appropriate Legal Notices, as required under
  27 + * Section 5 of the GNU General Public License version 3.
  28 + *
  29 + * In accordance with Section 7(b) of the GNU General Public License version 3,
  30 + * these Appropriate Legal Notices must retain the display of the "Powered by
  31 + * KnowledgeTree" logo and retain the original copyright notice. If the display of the
  32 + * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
  33 + * must display the words "Powered by KnowledgeTree" and retain the original
  34 + * copyright notice.
  35 + * Contributor( s):
  36 + * Mark Holtzhausen <mark@knowledgetree.com>
  37 + * Paul Barrett <paul@knowledgetree.com>
  38 + *
  39 + */
  40 +
  41 +
  42 +/**
  43 + * Includes
  44 + */
  45 +include_once(KT_ATOM_LIB_FOLDER.'KT_atom_serviceDoc.inc.php');
  46 +//include_once('KT_atom_baseDoc.inc.php');
  47 +
  48 +class KT_cmis_atom_serviceDoc extends KT_atom_serviceDoc {
  49 +
  50 + // override and extend as needed
  51 +
  52 + public $repositoryInfo = array();
  53 +
  54 + public function __construct($baseURI = NULL)
  55 + {
  56 + parent::__construct();
  57 +
  58 + // get repositoryInfo
  59 + // NOTE currently we only support one repository, which will be the first one found in the repositories.xml config
  60 + // TODO multiple repositories as individual workspaces
  61 +
  62 + include 'services/cmis/RepositoryService.inc.php';
  63 + $RepositoryService = new RepositoryService();
  64 +
  65 + // fetch data for response
  66 + $repositories = $RepositoryService->getRepositories();
  67 + // fetch for default first repo; NOTE that this will probably have to change at some point, quick and dirty for now
  68 + $this->repositoryInfo = $RepositoryService->getRepositoryInfo($repositories[0]['repositoryId']);
  69 + }
  70 +
  71 + protected function constructServiceDocumentHeaders()
  72 + {
  73 + $service = $this->newElement('service');
  74 + $service->appendChild($this->newAttr('xmlns', 'http://www.w3.org/2007/app'));
  75 + $service->appendChild($this->newAttr('xmlns:atom', 'http://www.w3.org/2005/Atom'));
  76 + $service->appendChild($this->newAttr('xmlns:cmis', 'http://www.cmis.org/2008/05'));
  77 + $this->service =& $service;
  78 + $this->DOM->appendChild($this->service);
  79 + }
  80 +
  81 + public function &newCollection($url = NULL, $title = NULL, $cmisCollectionType = NULL, &$ws = NULL)
  82 + {
  83 + $collection=$this->newElement('collection');
  84 + $collection->appendChild($this->newAttr('href', $url));
  85 + $collection->appendChild($this->newAttr('cmis:collectionType', $cmisCollectionType));
  86 + $collection->appendChild($this->newElement('atom:title', $title));
  87 + if(isset($ws))$ws->appendChild($collection);
  88 + return $collection;
  89 + }
  90 +
  91 +}
  92 +
  93 +/**
  94 +<?xml version="1.0" encoding="utf-8"?>
  95 +<service xmlns="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom">
  96 + <workspace>
  97 + <atom:title>Main Site</atom:title>
  98 + <collection href="http://example.org/blog/main" >
  99 + <atom:title>My Blog Entries</atom:title>
  100 + <categories href="http://example.com/cats/forMain.cats" />
  101 + </collection>
  102 + <collection href="http://example.org/blog/pic" >
  103 + <atom:title>Pictures</atom:title>
  104 + <accept>image/png</accept>
  105 + <accept>image/jpeg</accept>
  106 + <accept>image/gif</accept>
  107 + </collection>
  108 + </workspace>
  109 + <workspace>
  110 + <atom:title>Sidebar Blog</atom:title>
  111 + <collection href="http://example.org/sidebar/list" >
  112 + <atom:title>Remaindered Links</atom:title>
  113 + <accept>application/atom+xml;type=entry</accept>
  114 + <categories fixed="yes">
  115 + <atom:category scheme="http://example.org/extra-cats/" term="joke" />
  116 + <atom:category scheme="http://example.org/extra-cats/" term="serious" />
  117 + </categories>
  118 + </collection>
  119 + </workspace>
  120 +</service>
  121 +
  122 + */
  123 +
  124 +
  125 +?>
0 \ No newline at end of file 126 \ No newline at end of file
webservice/classes/atompub/cmis/NavigationService.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +require_once KT_LIB_DIR . '/api/ktcmis/ktcmis.inc.php';
  4 +
  5 +/**
  6 + * CMIS Service class which hooks into the KnowledgeTree interface
  7 + * for processing of CMIS queries and responses via atompub/webservices
  8 + */
  9 +
  10 +class NavigationService extends KTNavigationService {
  11 +
  12 + /**
  13 + * Get descendents of the specified folder, up to the depth indicated
  14 + *
  15 + * @param string $repositoryId
  16 + * @param string $folderId
  17 + * @param boolean $includeAllowableActions
  18 + * @param boolean $includeRelationships
  19 + * @param string $typeID
  20 + * @param int $depth
  21 + * @param string $filter
  22 + * @return cmisObjectType[]
  23 + */
  24 + public function getDescendants($repositoryId, $folderId, $includeAllowableActions, $includeRelationships,
  25 + $depth = 1, $typeID = 'Any', $filter = '')
  26 + {
  27 + $result = parent::getDescendants($repositoryId, $folderId, $includeAllowableActions,
  28 + $includeRelationships, $depth, $typeID, $filter);
  29 +
  30 + if ($result['status_code'] == 0)
  31 + {
  32 + return $result['results'];
  33 + }
  34 + }
  35 +
  36 + /**
  37 + * Get direct children of the specified folder
  38 + *
  39 + * @param string $repositoryId
  40 + * @param string $folderId
  41 + * @param boolean $includeAllowableActions
  42 + * @param boolean $includeRelationships
  43 + * @param string $typeID
  44 + * @param string $filter
  45 + * @param int $maxItems
  46 + * @param int $skipCount
  47 + * @return cmisObjectType[]
  48 + */
  49 + public function getChildren($repositoryId, $folderId, $includeAllowableActions, $includeRelationships,
  50 + $typeID = 'Any', $filter = '', $maxItems = 0, $skipCount = 0)
  51 + {
  52 + $result = parent::getChildren($repositoryId, $folderId, $includeAllowableActions, $includeRelationships,
  53 + $typeID, $filter, $maxItems, $skipCount);
  54 +
  55 + if ($result['status_code'] == 0)
  56 + {
  57 + return $result['results'];
  58 + }
  59 + }
  60 +
  61 + /**
  62 + * Gets the parent of the selected folder
  63 + *
  64 + * @param string $repositoryId
  65 + * @param string $folderId
  66 + * @param boolean $includeAllowableActions
  67 + * @param boolean $includeRelationships
  68 + * @param boolean $returnToRoot
  69 + * @param string $filter
  70 + * @return cmisObjectType[]
  71 + */
  72 + public function getFolderParent($repositoryId, $folderId, $includeAllowableActions, $includeRelationships, $returnToRoot, $filter = '')
  73 + {
  74 + $result = parent::getFolderParent($repositoryId, $folderId, $includeAllowableActions, $includeRelationships, $returnToRoot, $filter);
  75 +
  76 + if ($result['status_code'] == 0)
  77 + {
  78 + return $result['results'];
  79 + }
  80 + }
  81 +
  82 + /**
  83 + * Gets the parents for the selected object
  84 + *
  85 + * @param string $repositoryId
  86 + * @param string $folderId
  87 + * @param boolean $includeAllowableActions
  88 + * @param boolean $includeRelationships
  89 + * @param string $filter
  90 + * @return cmisObjectType[]
  91 + */
  92 + public function getObjectParents($repositoryId, $objectId, $includeAllowableActions, $includeRelationships, $filter = '')
  93 + {
  94 + $result = parent::getObjectParents($repositoryId, $objectId, $includeAllowableActions, $includeRelationships, $filter);
  95 +
  96 + if ($result['status_code'] == 0)
  97 + {
  98 + return $result['results'];
  99 + }
  100 + }
  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 +
  122 +}
  123 +
  124 +?>
webservice/classes/atompub/cmis/ObjectService.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +require_once KT_LIB_DIR . '/api/ktcmis/ktcmis.inc.php';
  4 +
  5 +/**
  6 + * CMIS Service class which hooks into the KnowledgeTree interface
  7 + * for processing of CMIS queries and responses via atompub/webservices
  8 + */
  9 +
  10 +class ObjectService extends KTObjectService {
  11 +
  12 + /**
  13 + * Fetches the properties for the specified object
  14 + *
  15 + * @param string $repositoryId
  16 + * @param string $objectId
  17 + * @param boolean $includeAllowableActions
  18 + * @param boolean $includeRelationships
  19 + * @param boolean $returnVersion
  20 + * @param string $filter
  21 + * @return object CMIS object properties
  22 + */
  23 + public function getProperties($repositoryId, $objectId, $includeAllowableActions, $includeRelationships,
  24 + $returnVersion = false, $filter = '')
  25 + {
  26 + $result = parent::getProperties($repositoryId, $objectId, $includeAllowableActions,
  27 + $returnVersion, $filter);
  28 +
  29 + if ($result['status_code'] == 0)
  30 + {
  31 + return $result['results'];
  32 + }
  33 + }
  34 +
  35 + /**
  36 + * Creates a new folder within the repository
  37 + *
  38 + * @param string $repositoryId The repository to which the folder must be added
  39 + * @param string $typeId Object Type id for the folder object being created
  40 + * @param array $properties Array of properties which must be applied to the created folder object
  41 + * @param string $folderId The id of the folder which will be the parent of the created folder object
  42 + * @return string $objectId The id of the created folder object
  43 + */
  44 + function createFolder($repositoryId, $typeId, $properties, $folderId)
  45 + {
  46 + $result = parent::createFolder($repositoryId, $typeId, $properties, $folderId);
  47 +
  48 + if ($result['status_code'] == 0)
  49 + {
  50 + return $result['results'];
  51 + }
  52 + else
  53 + {
  54 + return $result;
  55 + }
  56 + }
  57 +
  58 + /**
  59 + * Creates a new document within the repository
  60 + *
  61 + * @param string $repositoryId The repository to which the document must be added
  62 + * @param string $typeId Object Type id for the document object being created
  63 + * @param array $properties Array of properties which must be applied to the created document object
  64 + * @param string $folderId The id of the folder which will be the parent of the created document object
  65 + * This parameter is optional IF unfilingCapability is supported
  66 + * @param contentStream $contentStream optional content stream data
  67 + * @param string $versioningState optional version state value: checkedout/major/minor
  68 + * @return string $objectId The id of the created folder object
  69 + */
  70 + // TODO throw ConstraintViolationException if:
  71 + // value of any of the properties violates the min/max/required/length constraints
  72 + // specified in the property definition in the Object-Type.
  73 + function createDocument($repositoryId, $typeId, $properties, $folderId = null,
  74 + $contentStream = null, $versioningState = null)
  75 + {
  76 + $result = parent::createDocument($repositoryId, $typeId, $properties, $folderId, $contentStream, $versioningState);
  77 +
  78 + if ($result['status_code'] == 0)
  79 + {
  80 + return $result['results'];
  81 + }
  82 + else
  83 + {
  84 + return $result;
  85 + }
  86 + }
  87 +
  88 +}
  89 +
  90 +?>
webservice/classes/atompub/cmis/RepositoryService.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +/**
  4 + * CMIS Service class which hooks into the KnowledgeTree interface
  5 + * for processing of CMIS queries and responses via atompub/webservices
  6 + */
  7 +
  8 +require_once KT_LIB_DIR . '/api/ktcmis/ktcmis.inc.php';
  9 +
  10 +class RepositoryService extends KTRepositoryService {
  11 +
  12 + /**
  13 + * Fetches a list of available repositories
  14 + *
  15 + * @return cmisRepositoryEntryType[]
  16 + */
  17 + public function getRepositories()
  18 + {
  19 + $result = parent::getRepositories();
  20 +
  21 + if ($result['status_code'] == 0)
  22 + {
  23 + return $result['results'];
  24 + }
  25 + }
  26 +
  27 + /**
  28 + * Fetches information about the selected repository
  29 + *
  30 + * @param string $repositoryId
  31 + * @return cmisRepositoryInfoType
  32 + */
  33 + public function getRepositoryInfo($repositoryId)
  34 + {
  35 + $result = parent::getRepositoryInfo($repositoryId);
  36 +
  37 + if ($result['status_code'] == 0)
  38 + {
  39 + return $result['results'];
  40 + }
  41 + }
  42 +
  43 + /**
  44 + * Fetch the list of supported object types for the selected repository
  45 + *
  46 + * @param string $repositoryId The ID of the repository for which object types must be returned
  47 + * @param string $typeId The type to return, ALL if not set
  48 + * @param boolean $returnPropertyDefinitions Return property definitions as well if TRUE
  49 + * @param int $maxItems The maximum number of items to return
  50 + * @param int $skipCount The number of items to skip before starting to return results
  51 + * @param boolean $hasMoreItems TRUE if there are more items to return than were requested
  52 + * @return cmisTypeDefinitionType[]
  53 + */
  54 + public function getTypes($repositoryId, $typeId = '', $returnPropertyDefinitions = false,
  55 + $maxItems = 0, $skipCount = 0, &$hasMoreItems = false)
  56 + {
  57 + $result = parent::getTypes($repositoryId, $typeId, $returnPropertyDefinitions,
  58 + $maxItems, $skipCount, $hasMoreItems);
  59 +
  60 + if ($result['status_code'] == 0)
  61 + {
  62 + return $result['results'];
  63 + }
  64 + }
  65 +
  66 + /**
  67 + * Fetch the object type definition for the requested type
  68 + *
  69 + * @param string $repositoryId
  70 + * @param string $typeId
  71 + * @return cmisTypeDefinitionType
  72 + */
  73 + public function getTypeDefinition($repositoryId, $typeId)
  74 + {
  75 + $result = parent::getTypeDefinition($repositoryId, $typeId);
  76 +
  77 + if ($result['status_code'] == 0)
  78 + {
  79 + return $result['results'];
  80 + }
  81 + }
  82 +
  83 +}
  84 +
  85 +?>