startSession(self::$authData['username'], self::$authData['password']); } catch (Exception $e) { $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"'; $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage()); $this->responseFeed = $feed; return null; } $repositories = $RepositoryService->getRepositories(); $repositoryId = $repositories[0]['repositoryId']; // TODO implement full path/node separation as with Alfresco - i.e. path requests come in on path/ and node requests come in on node/ // path request e.g.: Root Folder/DroppedDocuments // node request e.g.: F1/children // node request e.g.: F2 if (urldecode($this->params[0]) == 'Root Folder') { $folderId = CMISUtil::encodeObjectId('Folder', 1); $folderName = urldecode($this->params[0]); } else if ($this->params[0] == 'path') { $ktapi =& $RepositoryService->getInterface(); $folderId = KT_cmis_atom_service_helper::getFolderId($this->params, $ktapi); } else { $folderId = $this->params[0]; $ObjectService = new ObjectService(); try { $ObjectService->startSession(self::$authData['username'], self::$authData['password']); } catch (Exception $e) { $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"'; $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage()); $this->responseFeed = $feed; return null; } $cmisEntry = $ObjectService->getProperties($repositoryId, $folderId, false, false); $folderName = $cmisEntry['properties']['Name']['value']; // $feed = $this->getFolderChildrenFeed($NavigationService, $repositoryId, $newObjectId, $cmisEntry['properties']['Name']['value']); } if (!empty($this->params[1]) && (($this->params[1] == 'children') || ($this->params[1] == 'descendants'))) { $NavigationService = new NavigationService(); try { $NavigationService->startSession(self::$authData['username'], self::$authData['password']); } catch (Exception $e) { $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"'; $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage()); $this->responseFeed = $feed; return null; } $feed = $this->getFolderChildrenFeed($NavigationService, $repositoryId, $folderId, $folderName, $this->params[1]); } else { $ObjectService = new ObjectService(); try { $ObjectService->startSession(self::$authData['username'], self::$authData['password']); } catch (Exception $e) { $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"'; $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage()); $this->responseFeed = $feed; return null; } $feed = $this->getFolderFeed($ObjectService, $repositoryId, $folderId); } //Expose the responseFeed $this->responseFeed = $feed; } public function POST_action() { $RepositoryService = new RepositoryService(); try { $RepositoryService->startSession(self::$authData['username'], self::$authData['password']); } catch (Exception $e) { $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"'; $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage()); $this->responseFeed = $feed; return null; } $repositories = $RepositoryService->getRepositories(); $repositoryId = $repositories[0]['repositoryId']; $folderId = $this->params[0]; $title = KT_cmis_atom_service_helper::getAtomValues($this->parsedXMLContent['@children'], 'title'); $summary = KT_cmis_atom_service_helper::getAtomValues($this->parsedXMLContent['@children'], 'summary'); $properties = array('name' => $title, 'summary' => $summary); // determine whether this is a folder or a document create // document create will have a content tag or containing base64 encoding of the document $content = KT_cmis_atom_service_helper::getAtomValues($this->parsedXMLContent['@children'], 'content'); if (is_null($content)) $type = 'folder'; else $type = 'document'; // TODO what if mime-type is incorrect? CMISSpaces appears to be sending text/plain on an executable file. // perhaps because the content is text/plain once base64 encoded? // How to determine the actual content type? /* * * setup.txt * setup.txt * dGhpcyBiZSBzb21lIHRlc3QgY29udGVudCBmb3IgYSBkb2N1bWVudCwgeWVzPw== * * * document * * * */ $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->parsedXMLContent['@children']['cmis:object'] [0]['@children']['cmis:properties'] [0]['@children']); $ObjectService = new ObjectService(); try { $ObjectService->startSession(self::$authData['username'], self::$authData['password']); } catch (Exception $e) { $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"'; $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage()); $this->responseFeed = $feed; return null; } if ($type == 'folder') $newObjectId = $ObjectService->createFolder($repositoryId, ucwords($cmisObjectProperties['ObjectTypeId']), $properties, $folderId); else $newObjectId = $ObjectService->createDocument($repositoryId, ucwords($cmisObjectProperties['ObjectTypeId']), $properties, $folderId, $content); // check if returned Object Id is a valid CMIS Object Id $dummy = CMISUtil::decodeObjectId($newObjectId, $typeId); if ($typeId != 'Unknown') { $this->setStatus(self::STATUS_CREATED); if ($type == 'folder') { $feed = $this->getFolderFeed($ObjectService, $repositoryId, $newObjectId); } else { $NavigationService = new NavigationService(); try { $NavigationService->startSession(self::$authData['username'], self::$authData['password']); } catch (Exception $e) { $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"'; $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage()); $this->responseFeed = $feed; return null; } $cmisEntry = $ObjectService->getProperties($repositoryId, $folderId, false, false); $feed = $this->getFolderChildrenFeed($NavigationService, $repositoryId, $folderId, $cmisEntry['properties']['Name']['value']); } } else { $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, $newObjectId['message']); } //Expose the responseFeed $this->responseFeed = $feed; } /** * Retrieves children/descendants of the specified folder * TODO this currently only works in children mode, add descendants * * @param string $repositoryId * @param string $folderId folder id for which children/descendants are requested * @param string $feedType children or descendants * @return string CMIS AtomPub feed */ private function getFolderChildrenFeed($NavigationService, $repositoryId, $folderId, $folderName, $feedType = 'children') { if ($feedType == 'children') { $entries = $NavigationService->getChildren($repositoryId, $folderId, false, false); } else if ($feedType == 'descendants') { $entries = $NavigationService->getDescendants($repositoryId, $folderId, false, false); } else { // error, we shouldn't be here, if we are then the wrong service/function was called } // $baseURI=NULL,$title=NULL,$link=NULL,$updated=NULL,$author=NULL,$id=NULL $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, $folderName . ' ' . ucwords($feedType), null, null, null, 'urn:uuid:' . $folderName . '-' . $feedType); foreach($entries as $cmisEntry) { KT_cmis_atom_service_helper::createObjectEntry($feed, $cmisEntry, $folderName); } // false // global $childrenFeed // $output = $childrenFeed[0]; // $output = $childrenFeed[1]; return $feed; } /** * Retrieves data about a specific folder * * @param object $ObjectService The CMIS service * @param string $repositoryId * @param string $folderId * @return string CMIS AtomPub feed */ private function getFolderFeed($ObjectService, $repositoryId, $folderId) { $cmisEntry = $ObjectService->getProperties($repositoryId, $folderId, false, false); $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, $cmisEntry['properties']['ObjectTypeId']['value'], null, null, null, 'urn:uuid:' . $cmisEntry['properties']['ObjectId']['value']); KT_cmis_atom_service_helper::createObjectEntry($feed, $cmisEntry, $folderName); // // false // // global $folderFeed; // // $outputs = return $feed; } } /** * AtomPub Service: types * * Returns a list of supported object types * */ class KT_cmis_atom_service_types extends KT_cmis_atom_service { public function GET_action() { $RepositoryService = new RepositoryService(); try { $RepositoryService->startSession(self::$authData['username'], self::$authData['password']); } catch (Exception $e) { $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"'; $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage()); $this->responseFeed = $feed; return null; } // fetch repository id $repositories = $RepositoryService->getRepositories(); $repositoryId = $repositories[0]['repositoryId']; $types = $RepositoryService->getTypes($repositoryId); $type = ((empty($this->params[0])) ? 'all' : $this->params[0]); $feed = KT_cmis_atom_service_helper::getTypeFeed($type, $types); //Expose the responseFeed $this->responseFeed = $feed; } } /** * AtomPub Service: type * * Returns the type defintion for the selected type * */ class KT_cmis_atom_service_type extends KT_cmis_atom_service { public function GET_action() { $RepositoryService = new RepositoryService(); try { $RepositoryService->startSession(self::$authData['username'], self::$authData['password']); } catch (Exception $e) { $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"'; $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage()); $this->responseFeed = $feed; return null; } // fetch repository id $repositories = $RepositoryService->getRepositories(); $repositoryId = $repositories[0]['repositoryId']; if (!isset($this->params[1])) { // For easier return in the wanted format, we call getTypes instead of getTypeDefinition. // Calling this with a single type specified returns an array containing the definition of // just the requested type. // NOTE could maybe be more efficient to call getTypeDefinition direct and then place in // an array on this side? or directly expose the individual entry response code and // call directly from here rather than via getTypeFeed. $type = ucwords($this->params[0]); $types = $RepositoryService->getTypes($repositoryId, $type); $feed = KT_cmis_atom_service_helper::getTypeFeed($type, $types); } else { // TODO dynamic dates, as needed everywhere // NOTE children of types not yet implemented and we don't support any non-basic types at this time $feed = $this->getTypeChildrenFeed($this->params[1]); } //Expose the responseFeed $this->responseFeed=$feed; } /** * Retrieves a list of child types for the supplied type * * NOTE this currently returns a hard coded empty list, since we do not currently support child types * TODO make dynamic if/when we support checking for child types (we don't actually need to support child types themselves) * * @param string $type * @return string CMIS AtomPub feed */ private function getTypeChildrenFeed() { //Create a new response feed // $baseURI=NULL,$title=NULL,$link=NULL,$updated=NULL,$author=NULL,$id=NULL $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, 'Child Types of ' . ucwords($this->params[0]), null, null, null, $this->params[0] . '-children'); // TODO actually fetch child types - to be implemented when we support child types in the API // id // links $link = $feed->newElement('link'); $link->appendChild($feed->newAttr('rel','first')); $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . 'type/' . $this->params[0] . '/' . $this->params[1] . '?pageNo=1&pageSize=0')); $link->appendChild($feed->newAttr('type', 'application/atom+xml;type=feed')); $link = $feed->newElement('link'); $link->appendChild($feed->newAttr('rel','last')); // TODO set page number correctly - to be done when we support paging the the API $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . 'type/' . $this->params[0] . '/' . $this->params[1] . '?pageNo=1&pageSize=0')); $link->appendChild($feed->newAttr('type', 'application/atom+xml;type=feed')); // TODO actual dynamic listing, currently we have no objects with which to test // TODO // 2009-06-23T13:40:32.786+02:00 // false /* // TODO need to create this dynamically now, will no longer work with static output $output = ' urn:uuid:type-' . $type . '-children Child types of ' . $type . ' 2009-06-23T13:40:32.786+02:00 false '; */ return $feed; } } /** * AtomPub Service: checkedout * * Returns a list of checked out documents for the logged in user * */ // NOTE this is always an empty document, underlying API code still to be implemented class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service { public function GET_action() { $RepositoryService = new RepositoryService(); $NavigationService = new NavigationService(); try { $NavigationService->startSession(self::$authData['username'], self::$authData['password']); } catch (Exception $e) { $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"'; $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage()); $this->responseFeed = $feed; return null; } $repositories = $RepositoryService->getRepositories(); $repositoryId = $repositories[0]['repositoryId']; $checkedout = $NavigationService->getCheckedoutDocs($repositoryId); //Create a new response feed $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, 'Checked out Documents', null, null, null, 'urn:uuid:checkedout'); foreach($checkedout as $document) { $entry = $feed->newEntry(); $objectElement = $feed->newElement('cmis:object'); $propertiesElement = $feed->newElement('cmis:properties'); foreach($cmisEntry['properties'] as $propertyName => $property) { $propElement = $feed->newElement('cmis:' . $property['type']); $propElement->appendChild($feed->newAttr('cmis:name', $propertyName)); $feed->newField('cmis:value', CMISUtil::boolToString($property['value']), $propElement); $propertiesElement->appendChild($propElement); } $objectElement->appendChild($propertiesElement); $entry->appendChild($objectElement); } $entry = null; $feed->newField('hasMoreItems', 'false', $entry, true); //Expose the responseFeed $this->responseFeed = $feed; } } /** * AtomPub Service: document * * Returns detail on a particular document * */ class KT_cmis_atom_service_document extends KT_cmis_atom_service { public function GET_action() { $RepositoryService = new RepositoryService(); $ObjectService = new ObjectService(); try { $ObjectService->startSession(self::$authData['username'], self::$authData['password']); } catch (Exception $e) { $this->headers[] = 'WWW-Authenticate: Basic realm="KnowledgeTree Secure Area"'; $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_NOT_AUTHENTICATED, $e->getMessage()); $this->responseFeed = $feed; return null; } $repositories = $RepositoryService->getRepositories(); $repositoryId = $repositories[0]['repositoryId']; $cmisEntry = $ObjectService->getProperties($repositoryId, $this->params[0], false, false); //Create a new response feed $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, $cmisEntry['properties']['ObjectTypeId']['value'], null, null, null, 'urn:uuid:' . $cmisEntry['properties']['ObjectId']['value']); KT_cmis_atom_service_helper::createObjectEntry($feed, $cmisEntry, $cmisEntry['properties']['ParentId']['value']); // false // global $docFeed; // $output = $docFeed; //Expose the responseFeed $this->responseFeed=$feed; } } $childrenFeed[] = ' urn:uuid:28537649-8af2-4c74-aa92-5d8bbecac9ce-children Root Folder Children urn:uuid:86224486-b7ae-4074-a793-82cd259b0026-folder DroppedDocuments DroppedDocuments F2 Folder DroppedDocuments urn:uuid:86224486-b7ae-4074-a793-82cd259b0026-folder Test KT Folder Test KT Folder F4 Folder Test KT Folder admin urn:uuid:2df9d676-f173-47bb-8ec1-41fa1186b66d 2009-06-23T09:40:47.889+02:00 h4555-cmis-so.pdf 2009-06-23T09:40:58.524+02:00 workspace://SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d document document admin 2009-06-23T09:40:47.889+02:00 admin 2009-06-23T09:40:58.524+02:00 h4555-cmis-so.pdf false true false false workspace://SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d false 343084 application/pdf h4555-cmis-so.pdf http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/content.h4555-cmis-so.pdf '; $childrenFeed[] = ' System Alfresco (Labs) http://10.33.4.34:8080/alfresco/images/logo/AlfrescoLogo16.ico urn:uuid:28537649-8af2-4c74-aa92-5d8bbecac9ce-children Company Home Children 2009-06-18T10:20:29.937+02:00 System e98319fa-76e4-478f-8ce8-a3a0fd683e2c urn:uuid:e98319fa-76e4-478f-8ce8-a3a0fd683e2c 2009-06-18T10:20:37.788+02:00 Site Collaboration Spaces Sites 2009-06-18T10:20:37.874+02:00 workspace://SpacesStore/e98319fa-76e4-478f-8ce8-a3a0fd683e2c folder F/st_sites System 2009-06-18T10:20:37.788+02:00 System 2009-06-18T10:20:37.874+02:00 Sites workspace://SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce 2009-06-18T10:20:37.874+02:00 http://10.33.4.34:8080/alfresco/images/icons/space-icon-default-16.gif System 8c80a0f7-74b4-4bd8-bb76-a2464e4b2d10 urn:uuid:8c80a0f7-74b4-4bd8-bb76-a2464e4b2d10 2009-06-18T10:20:29.939+02:00 User managed definitions Data Dictionary 2009-06-18T10:20:30.004+02:00 workspace://SpacesStore/8c80a0f7-74b4-4bd8-bb76-a2464e4b2d10 folder folder System 2009-06-18T10:20:29.939+02:00 System 2009-06-18T10:20:30.004+02:00 Data Dictionary workspace://SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce 2009-06-18T10:20:30.004+02:00 http://10.33.4.34:8080/alfresco/images/icons/space-icon-default-16.gif System ba2524ef-7f3d-4ed4-84a0-8d99b6524737 urn:uuid:ba2524ef-7f3d-4ed4-84a0-8d99b6524737 2009-06-18T10:20:30.312+02:00 The guest root space Guest Home 2009-06-18T10:20:30.400+02:00 workspace://SpacesStore/ba2524ef-7f3d-4ed4-84a0-8d99b6524737 folder folder System 2009-06-18T10:20:30.312+02:00 System 2009-06-18T10:20:30.400+02:00 Guest Home workspace://SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce 2009-06-18T10:20:30.400+02:00 http://10.33.4.34:8080/alfresco/images/icons/space-icon-default-16.gif System 86224486-b7ae-4074-a793-82cd259b0026 urn:uuid:86224486-b7ae-4074-a793-82cd259b0026 2009-06-18T10:20:30.402+02:00 User Homes User Homes 2009-06-18T10:20:30.428+02:00 workspace://SpacesStore/86224486-b7ae-4074-a793-82cd259b0026 folder folder System 2009-06-18T10:20:30.402+02:00 System 2009-06-18T10:20:30.428+02:00 User Homes workspace://SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce 2009-06-18T10:20:30.428+02:00 http://10.33.4.34:8080/alfresco/images/icons/space-icon-default-16.gif System 0df9087f-e334-4890-a467-b60e3d6be92c urn:uuid:0df9087f-e334-4890-a467-b60e3d6be92c 2009-06-18T10:20:45.115+02:00 Web Content Management Spaces Web Projects 2009-06-18T10:20:45.137+02:00 workspace://SpacesStore/0df9087f-e334-4890-a467-b60e3d6be92c folder folder System 2009-06-18T10:20:45.115+02:00 System 2009-06-18T10:20:45.137+02:00 Web Projects workspace://SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce 2009-06-18T10:20:45.137+02:00 http://10.33.4.34:8080/alfresco/images/icons/space-icon-default-16.gif admin urn:uuid:2df9d676-f173-47bb-8ec1-41fa1186b66d 2009-06-23T09:40:47.889+02:00 h4555-cmis-so.pdf 2009-06-23T09:40:58.524+02:00 workspace://SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d document document admin 2009-06-23T09:40:47.889+02:00 admin 2009-06-23T09:40:58.524+02:00 h4555-cmis-so.pdf false true false false workspace://SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d false 343084 application/pdf h4555-cmis-so.pdf http://10.33.4.34:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/content.h4555-cmis-so.pdf 2009-06-23T09:40:58.524+02:00 http://10.33.4.34:8080/alfresco/images/filetypes/pdf.gif false 6 0 0 '; $folderFeed = ' System 28537649-8af2-4c74-aa92-5d8bbecac9ce urn:uuid:28537649-8af2-4c74-aa92-5d8bbecac9ce 2009-06-18T10:20:29.871+02:00 The company root space Company Home 2009-06-18T10:20:29.937+02:00 workspace://SpacesStore/28537649-8af2-4c74-aa92-5d8bbecac9ce folder folder System 2009-06-18T10:20:29.871+02:00 System 2009-06-18T10:20:29.937+02:00 Company Home 2009-06-18T10:20:29.937+02:00 http://127.0.0.1:8080/alfresco/images/icons/space-icon-default-16.gif '; $docFeed = ' admin urn:uuid:2df9d676-f173-47bb-8ec1-41fa1186b66d 2009-06-23T09:40:47.889+02:00 h4555-cmis-so.pdf 2009-06-23T09:40:58.524+02:00 workspace://SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d document document admin 2009-06-23T09:40:47.889+02:00 admin 2009-06-23T09:40:58.524+02:00 h4555-cmis-so.pdf false true false false workspace://SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d false 343084 application/pdf h4555-cmis-so.pdf http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/2df9d676-f173-47bb-8ec1-41fa1186b66d/content.h4555-cmis-so.pdf 2009-06-23T09:40:58.524+02:00 http://127.0.0.1:8080/alfresco/images/filetypes/pdf.gif '; ?>