diff --git a/webservice/atompub/cmis/KT_cmis_atom_server.services.inc.php b/webservice/atompub/cmis/KT_cmis_atom_server.services.inc.php index dfe65c7..039d4bd 100644 --- a/webservice/atompub/cmis/KT_cmis_atom_server.services.inc.php +++ b/webservice/atompub/cmis/KT_cmis_atom_server.services.inc.php @@ -43,22 +43,11 @@ include_once 'KT_cmis_atom_service_helper.inc.php'; * Returns children, descendants (up to arbitrary depth) or detail for a particular folder * */ -class KT_cmis_atom_service_folder extends KT_cmis_atom_service { +class KT_cmis_atom_service_folder extends KT_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; -// } - $repositories = $RepositoryService->getRepositories(); $repositoryId = $repositories[0]['repositoryId']; @@ -80,56 +69,19 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { { $folderId = $this->params[0]; $ObjectService = new ObjectService(KT_cmis_atom_service_helper::getKt()); - -// 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(KT_cmis_atom_service_helper::getKt()); - -// 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(KT_cmis_atom_service_helper::getKt()); - -// 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); + $feed = KT_cmis_atom_service_helper::getObjectFeed($ObjectService, $repositoryId, $folderId); } //Expose the responseFeed @@ -139,18 +91,6 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { 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']; @@ -168,70 +108,32 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { 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(KT_cmis_atom_service_helper::getKt()); -// 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); + CMISUtil::decodeObjectId($newObjectId, $typeId); + if ($typeId != 'Unknown') { $this->setStatus(self::STATUS_CREATED); if ($type == 'folder') { - $feed = $this->getFolderFeed($ObjectService, $repositoryId, $newObjectId); + $feed = KT_cmis_atom_service_helper::getObjectFeed($ObjectService, $repositoryId, $newObjectId, 'POST'); } else { $NavigationService = new NavigationService(KT_cmis_atom_service_helper::getKt()); - -// 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']); + $feed = $this->getFolderChildrenFeed($NavigationService, $repositoryId, $folderId, $cmisEntry['properties']['Name']['value'], 'POST'); } } else @@ -268,23 +170,30 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { } // $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, null); -// 'urn:uuid:' . $folderId . '-' . $feedType); - + $feed = new KT_cmis_atom_responseFeed_GET(CMIS_APP_BASE_URI); + $workspace = $feed->getWorkspace(); + + $feed->newField('title', $folderName . ' ' . ucwords($feedType), $feed); + // TODO dynamic? $feedElement = $feed->newField('author'); $element = $feed->newField('name', 'System', $feedElement); $feed->appendChild($feedElement); // id - $feed->appendChild($feed->newElement('id', 'urn:uuid:' . $folderId . '-' . $feedType)); + $feed->newField('id', 'urn:uuid:' . $folderId . '-' . $feedType, $feed); // TODO get actual most recent update time, only use current if no other available - $feed->appendChild($feed->newElement('updated', KT_cmis_atom_service_helper::formatDatestamp())); - + $feed->newField('updated', KT_cmis_atom_service_helper::formatDatestamp(), $feed); + $link = $feed->newElement('link'); - $link->appendChild($feed->newAttr('rel','source')); - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/folder/' . $folderId)); + $link->appendChild($feed->newAttr('rel', 'self')); + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/folder/' . $folderId . '/' . $feedType)); + $feed->appendChild($link); + + $link = $feed->newElement('link'); + $link->appendChild($feed->newAttr('rel', 'source')); + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/folder/' . $folderId)); $feed->appendChild($link); foreach($entries as $cmisEntry) @@ -292,7 +201,7 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { KT_cmis_atom_service_helper::createObjectEntry($feed, $cmisEntry, $folderName); // after each entry, add app:edited tag - $feed->appendChild($feed->newElement('app:edited', KT_cmis_atom_service_helper::formatDatestamp())); + $feed->newField('app:edited', KT_cmis_atom_service_helper::formatDatestamp(), $feed); } // false @@ -304,29 +213,6 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { 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; - } - } /** @@ -335,24 +221,11 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { * Returns a list of supported object types * */ -class KT_cmis_atom_service_types extends KT_cmis_atom_service { +class KT_cmis_atom_service_types extends KT_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']; @@ -372,23 +245,12 @@ class KT_cmis_atom_service_types extends KT_cmis_atom_service { * Returns the type defintion for the selected type * */ -class KT_cmis_atom_service_type extends KT_cmis_atom_service { +class KT_cmis_atom_service_type extends KT_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']; @@ -425,14 +287,14 @@ class KT_cmis_atom_service_type extends KT_cmis_atom_service { */ 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'); + //Create a new response feed + // $baseURI=NULL,$title=NULL,$link=NULL,$updated=NULL,$author=NULL,$id=NULL + $feed = new KT_cmis_atom_responseFeed_GET(CMIS_APP_BASE_URI); - // TODO actually fetch child types - to be implemented when we support child types in the API + $feed->newField('title', 'Child Types of ' . ucwords($this->params[0]), $feed); + $feed->newField('id', $this->params[0] . '-children', $feed); - // id + // TODO fetch child types - to be implemented when we support child types in the API // links $link = $feed->newElement('link'); @@ -446,24 +308,9 @@ class KT_cmis_atom_service_type extends KT_cmis_atom_service { $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 - '; -*/ + $feed->newField('updated', KT_cmis_atom_service_helper::formatDatestamp(), $feed); + $feed->newField('cmis:hasMoreItems', 'false', $feed); + return $feed; } @@ -476,31 +323,22 @@ class KT_cmis_atom_service_type extends KT_cmis_atom_service { * */ // 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 { +class KT_cmis_atom_service_checkedout extends KT_atom_service { public function GET_action() { $RepositoryService = new RepositoryService(); $NavigationService = new NavigationService(KT_cmis_atom_service_helper::getKt()); -// 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'); + $feed = new KT_cmis_atom_responseFeed_GET(CMIS_APP_BASE_URI); + + $feed->newField('title', 'Checked out Documents', $feed); // TODO dynamic? $feedElement = $feed->newField('author'); @@ -546,40 +384,28 @@ class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service { * Returns detail on a particular document * */ -class KT_cmis_atom_service_document extends KT_cmis_atom_service { +class KT_cmis_atom_service_document extends KT_atom_service { public function GET_action() { $RepositoryService = new RepositoryService(); $ObjectService = new ObjectService(KT_cmis_atom_service_helper::getKt()); -// 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']); + $feed = new KT_cmis_atom_responseFeed_GET(CMIS_APP_BASE_URI); + + $feed->newField('title', $cmisEntry['properties']['ObjectTypeId']['value'], $feed); + $feed->newField('id', 'urn:uuid:' . $cmisEntry['properties']['ObjectId']['value'], $feed); ; KT_cmis_atom_service_helper::createObjectEntry($feed, $cmisEntry, $cmisEntry['properties']['ParentId']['value']); // false - // global $docFeed; - // $output = $docFeed; - //Expose the responseFeed $this->responseFeed=$feed; } diff --git a/webservice/atompub/cmis/KT_cmis_atom_service_helper.inc.php b/webservice/atompub/cmis/KT_cmis_atom_service_helper.inc.php index 054ad39..e9d5ed5 100644 --- a/webservice/atompub/cmis/KT_cmis_atom_service_helper.inc.php +++ b/webservice/atompub/cmis/KT_cmis_atom_service_helper.inc.php @@ -5,104 +5,117 @@ class KT_cmis_atom_service_helper { protected static $kt = null; /** + * Retrieves data about a specific folder OR document within a folder + * + * @param object $ObjectService The CMIS service + * @param string $repositoryId + * @param string $folderId + * @return string CMIS AtomPub feed + */ + static public function getObjectFeed($ObjectService, $repositoryId, $objectId, $method = 'GET') + { + $cmisEntry = $ObjectService->getProperties($repositoryId, $objectId, false, false); + + if ($method == 'GET') { + $response = new KT_cmis_atom_responseFeed_GET(CMIS_APP_BASE_URI); + $response->newField('title', $cmisEntry['properties']['ObjectTypeId']['value'], $response); + $response->newField('id', 'urn:uuid:' . $cmisEntry['properties']['ObjectId']['value'], $response); + } + else if ($method == 'POST') { + $response = new KT_cmis_atom_response_POST(CMIS_APP_BASE_URI); + } + + KT_cmis_atom_service_helper::createObjectEntry($response, $cmisEntry, $folderName); + + if ($method == 'GET') { + $response->newField('cmis:hasMoreItems', 'false', $response); + } + + return $response; + } + + /** * Creates an AtomPub entry for a CMIS entry and adds it to the supplied feed * * @param object $feed The feed to which we add the entry * @param array $cmisEntry The entry data * @param string $parent The parent folder */ - static public function createObjectEntry(&$feed, $cmisEntry, $parent, $path) + static public function createObjectEntry(&$response, $cmisEntry, $parent, $method = 'POST') { + $workspace = $response->getWorkspace(); + // create entry - $entry = $feed->newEntry(); + $entry = $response->newEntry(); + + if ($method == 'POST') + { + // append attributes + $entry->appendChild($response->newAttr('xmlns', 'http://www.w3.org/2005/Atom')); + $entry->appendChild($response->newAttr('xmlns:app', 'http://www.w3.org/2007/app')); + $entry->appendChild($response->newAttr('xmlns:cmis', 'http://docs.oasis-open.org/ns/cmis/core/200901')); + } // TODO dynamic actual creator name - $feedElement = $feed->newField('author'); - $element = $feed->newField('name', 'admin', $feedElement); - $entry->appendChild($feedElement); + $responseElement = $response->newField('author'); + $element = $response->newField('name', 'admin', $responseElement); + $entry->appendChild($responseElement); // content & id tags $id = $cmisEntry['properties']['ObjectId']['value']; - $entry->appendChild($feed->newField('content', $id)); - $feed->newField('id', 'urn:uuid:' . $id, $entry); - - // links - /* - - - - - */ - // - - /* - - -System -2009-07-13T13:59:20.724+02:00 - -System -folder - -workspace://SpacesStore/b30ea6e5-1e3f-4133-82f4-172bc240a9a2 - */ + $entry->appendChild($response->newField('content', $id)); + $response->newField('id', 'urn:uuid:' . $id, $entry); $type = strtolower($cmisEntry['properties']['ObjectTypeId']['value']); - $link = $feed->newElement('link'); - $link->appendChild($feed->newAttr('rel','self')); - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/' . $type . '/' . $cmisEntry['properties']['ObjectId']['value'])); + // links + $link = $response->newElement('link'); + $link->appendChild($response->newAttr('rel','self')); + $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' . $cmisEntry['properties']['ObjectId']['value'])); $entry->appendChild($link); - $link = $feed->newElement('link'); - $link->appendChild($feed->newAttr('rel','edit')); - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/' . $type . '/' . $cmisEntry['properties']['ObjectId']['value'])); + $link = $response->newElement('link'); + $link->appendChild($response->newAttr('rel','edit')); + $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' . $cmisEntry['properties']['ObjectId']['value'])); $entry->appendChild($link); // according to spec this MUST be present, but spec says that links for function which are not supported // do not need to be present, so unsure for the moment - $link = $feed->newElement('link'); - $link->appendChild($feed->newAttr('rel', 'allowableactions')); - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/' . $type . '/' + $link = $response->newElement('link'); + $link->appendChild($response->newAttr('rel', 'allowableactions')); + $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' . $cmisEntry['properties']['ObjectId']['value'] . '/permissions')); $entry->appendChild($link); // according to spec this MUST be present, but spec says that links for function which are not supported // do not need to be present, so unsure for the moment - $link = $feed->newElement('link'); - $link->appendChild($feed->newAttr('rel', 'relationships')); - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/' . $type . '/' + $link = $response->newElement('link'); + $link->appendChild($response->newAttr('rel', 'relationships')); + $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' . $cmisEntry['properties']['ObjectId']['value'] . '/rels')); $entry->appendChild($link); // TODO check parent link is correct, fix if needed // TODO leave out if at root folder - $link = $feed->newElement('link'); - $link->appendChild($feed->newAttr('rel', 'parents')); - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/folder/' + $link = $response->newElement('link'); + $link->appendChild($response->newAttr('rel', 'parents')); + $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/folder/' . $cmisEntry['properties']['ObjectId']['value'] . '/parent')); $entry->appendChild($link); // Folder/Document specific links if (strtolower($cmisEntry['properties']['ObjectTypeId']['value']) == 'folder') { - // no longer valid, remove... -// // TODO check parent link is correct, fix if needed -// $link = $feed->newElement('link'); -// $link->appendChild($feed->newAttr('rel','folderparent')); -// $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/folder/' . $cmisEntry['properties']['ParentId']['value'])); -// $entry->appendChild($link); - - $link = $feed->newElement('link'); - $link->appendChild($feed->newAttr('rel','children')); - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/' + $link = $response->newElement('link'); + $link->appendChild($response->newAttr('rel','children')); + $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' . $cmisEntry['properties']['ObjectId']['value'] . '/children')); $entry->appendChild($link); - $link = $feed->newElement('link'); - $link->appendChild($feed->newAttr('rel','descendants')); - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/' + $link = $response->newElement('link'); + $link->appendChild($response->newAttr('rel','descendants')); + $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' . $cmisEntry['properties']['ObjectId']['value'] . '/descendants')); @@ -112,25 +125,25 @@ class KT_cmis_atom_service_helper { { // according to spec this MUST be present, but spec says that links for function which are not supported // do not need to be present, so unsure for the moment -// $link = $feed->newElement('link'); -// $link->appendChild($feed->newAttr('rel', 'allversions')); -// $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/' . $type . '/' . $cmisEntry['properties']['ParentId']['value'])); +// $link = $response->newElement('link'); +// $link->appendChild($response->newAttr('rel', 'allversions')); +// $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' . $cmisEntry['properties']['ParentId']['value'])); // $entry->appendChild($link); // according to spec this MUST be present, but spec says that links for function which are not supported // do not need to be present, so unsure for the moment -// $link = $feed->newElement('link'); -// $link->appendChild($feed->newAttr('rel', 'latestversion')); -// $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/' . $type . '/' . $cmisEntry['properties']['ParentId']['value'])); +// $link = $response->newElement('link'); +// $link->appendChild($response->newAttr('rel', 'latestversion')); +// $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' . $cmisEntry['properties']['ParentId']['value'])); // $entry->appendChild($link); // if there is a content stream, this link MUST be present // not sure yet where it must point... if (!empty($cmisEntry['properties']['ContentStreamLength']['value'])) { - $link = $feed->newElement('link'); - $link->appendChild($feed->newAttr('rel', 'stream')); - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/' . $type . '/' + $link = $response->newElement('link'); + $link->appendChild($response->newAttr('rel', 'stream')); + $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' . $cmisEntry['properties']['ObjectId']['value'])); $entry->appendChild($link); } @@ -138,47 +151,47 @@ class KT_cmis_atom_service_helper { // if the document is checked out and this is NOT the PWC, this link MUST be present // if (!empty($cmisEntry['properties']['ContentStreamLength']['value'])) // { -// $link = $feed->newElement('link'); -// $link->appendChild($feed->newAttr('rel', 'stream')); -// $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/' . $type . '/' . $cmisEntry['properties']['ParentId']['value'])); +// $link = $response->newElement('link'); +// $link->appendChild($response->newAttr('rel', 'stream')); +// $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' . $cmisEntry['properties']['ParentId']['value'])); // $entry->appendChild($link); // } } - $link = $feed->newElement('link'); - $link->appendChild($feed->newAttr('rel','type')); - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/type/' . $type)); + $link = $response->newElement('link'); + $link->appendChild($response->newAttr('rel','type')); + $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/type/' . $type)); $entry->appendChild($link); - $link = $feed->newElement('link'); - $link->appendChild($feed->newAttr('rel','repository')); - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . '/servicedocument')); + $link = $response->newElement('link'); + $link->appendChild($response->newAttr('rel','repository')); + $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . '/servicedocument')); $entry->appendChild($link); // according to spec this MUST be present, but spec says that links for function which are not supported // do not need to be present, so unsure for the moment - policies are being abandoned, or so I thought... -// $link = $feed->newElement('link'); -// $link->appendChild($feed->newAttr('rel', 'policies')); -// $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/' . $type . '/' . $cmisEntry['properties']['ParentId']['value'])); +// $link = $response->newElement('link'); +// $link->appendChild($response->newAttr('rel', 'policies')); +// $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' . $cmisEntry['properties']['ParentId']['value'])); // $entry->appendChild($link); // end links // TODO proper date - $entry->appendChild($feed->newField('published', self::formatDatestamp())); - $entry->appendChild($feed->newElement('summary', $cmisEntry['properties']['Name']['value'])); - $entry->appendChild($feed->newElement('title', $cmisEntry['properties']['Name']['value'])); - $entry->appendChild($feed->newField('updated', self::formatDatestamp())); + $entry->appendChild($response->newField('published', self::formatDatestamp())); + $entry->appendChild($response->newElement('summary', $cmisEntry['properties']['Name']['value'])); + $entry->appendChild($response->newElement('title', $cmisEntry['properties']['Name']['value'])); + $entry->appendChild($response->newField('updated', self::formatDatestamp())); // main CMIS entry - $objectElement = $feed->newElement('cmis:object'); - $propertiesElement = $feed->newElement('cmis:properties'); + $objectElement = $response->newElement('cmis:object'); + $propertiesElement = $response->newElement('cmis:properties'); foreach($cmisEntry['properties'] as $propertyName => $property) { - $propElement = $feed->newElement('cmis:' . $property['type']); - $propElement->appendChild($feed->newAttr('cmis:name', $propertyName)); + $propElement = $response->newElement('cmis:' . $property['type']); + $propElement->appendChild($response->newAttr('cmis:name', $propertyName)); if (!empty($property['value'])) { - $feed->newField('cmis:value', CMISUtil::boolToString($property['value']), $propElement); + $response->newField('cmis:value', CMISUtil::boolToString($property['value']), $propElement); } $propertiesElement->appendChild($propElement); } @@ -187,7 +200,11 @@ class KT_cmis_atom_service_helper { $entry->appendChild($objectElement); // after every entry, append a cmis:terminator tag - $entry->appendChild($feed->newElement('cmis:terminator')); + $entry->appendChild($response->newElement('cmis:terminator')); + + if ($method == 'POST') { + $entry->appendChild($response->newElement('app:edited', self::formatDatestamp())); + } } /** @@ -216,7 +233,11 @@ class KT_cmis_atom_service_helper { } //Create a new response feed - $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, $typesHeading, null, null, null, 'urn:uuid:' . $typesString); + $feed = new KT_cmis_atom_responseFeed_GET(CMIS_APP_BASE_URI); + $workspace = $feed->getWorkspace(); + + $feed->newField('title', $typesHeading, $feed); + $feed->newField('id', 'urn:uuid:' . $typesString, $feed); // TODO set page number correctly - to be done when we support paging the the API @@ -234,7 +255,7 @@ class KT_cmis_atom_service_helper { /* $link = $feed->newElement('link'); $link->appendChild($feed->newAttr('rel','source')); - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/type/' . strtolower($type['typeId']))); + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/type/' . strtolower($type['typeId']))); $feed->appendChild($link); */ @@ -251,11 +272,7 @@ class KT_cmis_atom_service_helper { $feedElement = $feed->newField('content', $type['typeId']); $entry->appendChild($feedElement); - // hack, force to lower case - $type['typeId'] = strtolower($type['typeId']); - - // NOTE should this be strtolower? thought so but maybe not always, Alfresco is not consistent... - $feed->newId('urn:uuid:type-' . strtolower($type['typeId']), $entry); + $feed->newField('id', 'urn:uuid:type-' . $type['typeId'], $feed); // TODO add parents link when not selecting a base type. // TODO add children link when type has children @@ -265,14 +282,14 @@ class KT_cmis_atom_service_helper { // links $link = $feed->newElement('link'); $link->appendChild($feed->newAttr('rel','self')); - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/type/' . strtolower($type['typeId']))); + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/type/' . strtolower($type['typeId']))); $entry->appendChild($link); // TODO type link MUST point to base type // KnowledgeTree currently only supports base types so this is not important // at the present time as it will always point at the base type. $link = $feed->newElement('link'); $link->appendChild($feed->newAttr('rel','type')); - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $feed->workspace . '/type/' . strtolower($type['typeId']))); + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/type/' . strtolower($type['typeId']))); $entry->appendChild($link); $link = $feed->newElement('link'); $link->appendChild($feed->newAttr('rel','repository')); @@ -302,7 +319,9 @@ class KT_cmis_atom_service_helper { static public function getErrorFeed(&$service, $status, $message) { $service->setStatus($status); - $feed = new KT_cmis_atom_responseFeed(CMIS_APP_BASE_URI, 'Error: ' . $status); + $feed = new KT_cmis_atom_responseFeed_GET(CMIS_APP_BASE_URI); + + $feed->newField('title', 'Error: ' . $status, $feed); $entry = $feed->newEntry(); $feed->newField('error', $message, $entry); diff --git a/webservice/atompub/cmis/index.php b/webservice/atompub/cmis/index.php index 71d6f5b..9fea1ed 100644 --- a/webservice/atompub/cmis/index.php +++ b/webservice/atompub/cmis/index.php @@ -55,8 +55,9 @@ define('CMIS_ATOM_LIB_FOLDER', trim(KT_ATOM_LIB_FOLDER, '/') . '/cmis/'); * Includes */ include_once(KT_ATOM_LIB_FOLDER.'XMLns2array.inc.php'); +include_once(KT_ATOM_LIB_FOLDER.'KT_atom_baseDoc.inc.php'); include_once(CMIS_ATOM_LIB_FOLDER.'KT_cmis_atom_server.inc.php'); -include_once(CMIS_ATOM_LIB_FOLDER.'KT_cmis_atom_baseDoc.inc.php'); +include_once(CMIS_ATOM_LIB_FOLDER.'KT_cmis_atom_response.inc.php'); //Containing the response feed class allowing easy atom feed generation include_once(CMIS_ATOM_LIB_FOLDER.'KT_cmis_atom_responseFeed.inc.php'); //Containing the response feed class allowing easy atom feed generation include_once(CMIS_ATOM_LIB_FOLDER.'KT_cmis_atom_serviceDoc.inc.php'); //Containing the servicedoc class allowing easy ServiceDocument generation include_once(CMIS_ATOM_LIB_FOLDER.'KT_cmis_atom_service.inc.php'); //Containing the servicedoc class allowing easy ServiceDocument generation diff --git a/webservice/classes/atompub/cmis/KT_cmis_atom_response.inc.php b/webservice/classes/atompub/cmis/KT_cmis_atom_response.inc.php new file mode 100644 index 0000000..aaeb22c --- /dev/null +++ b/webservice/classes/atompub/cmis/KT_cmis_atom_response.inc.php @@ -0,0 +1,36 @@ +workspace = strtolower(trim($queryArray[0])); + } + + function getWorkspace() + { + return $this->workspace; + } + + // TODO try to get rid of this function + function appendChild($element) + { + $this->feed->appendChild($element); + } + +} + +class KT_cmis_atom_Response_GET extends KT_cmis_atom_response{} +class KT_cmis_atom_Response_PUT extends KT_cmis_atom_response{} +class KT_cmis_atom_Response_POST extends KT_cmis_atom_response{} +class KT_cmis_atom_Response_DELETE extends KT_cmis_atom_response{} + +?> \ No newline at end of file diff --git a/webservice/classes/atompub/cmis/KT_cmis_atom_responseFeed.inc.php b/webservice/classes/atompub/cmis/KT_cmis_atom_responseFeed.inc.php index 2650a02..b97d4e2 100644 --- a/webservice/classes/atompub/cmis/KT_cmis_atom_responseFeed.inc.php +++ b/webservice/classes/atompub/cmis/KT_cmis_atom_responseFeed.inc.php @@ -5,27 +5,42 @@ include_once(KT_ATOM_LIB_FOLDER.'KT_atom_responseFeed.inc.php'); class KT_cmis_atom_responseFeed extends KT_atom_responseFeed { // override and extend as needed - - public $workspace = null; - public function __construct($baseURI = NULL, $title = NULL, $link = NULL, $updated = NULL, $author = NULL, $id = NULL) + static protected $workspace = null; + + /** + * Overridden constructor to allow easy adding of additional header attributes + * + * @param string $baseURI + */ + public function __construct($baseURI = null) { + parent::__construct($baseURI); + + // append additional tags + $this->feed->appendChild($this->newAttr('xmlns:app', 'http://www.w3.org/2007/app')); + $this->feed->appendChild($this->newAttr('xmlns:cmis', 'http://docs.oasis-open.org/ns/cmis/core/200901')); + + // require the workspace for creating links within responses $queryArray = split('/', trim($_SERVER['QUERY_STRING'], '/')); $this->workspace = strtolower(trim($queryArray[0])); - $this->id = $id; - $this->title = $title; - - parent::__construct($baseURI, $title, $link, $updated, $author, $id); } - protected function constructHeader() + function getWorkspace() { - $feed = $this->newElement('feed'); - $feed->appendChild($this->newAttr('xmlns','http://www.w3.org/2005/Atom')); - $feed->appendChild($this->newAttr('xmlns:app','http://www.w3.org/2007/app')); - $feed->appendChild($this->newAttr('xmlns:cmis','http://docs.oasis-open.org/ns/cmis/core/200901')); - $this->feed = &$feed; + return $this->workspace; + } + // TODO try to get rid of this function + function appendChild($element) + { + $this->feed->appendChild($element); + } + + // this is ALL going away...adjust all calling code... + /* + protected function constructHeader() + { if (!is_null($this->id)) { $this->newId($this->id, $this->feed); @@ -67,43 +82,8 @@ class KT_cmis_atom_responseFeed extends KT_atom_responseFeed { return $field; } - - function appendChild($element) - { - $this->feed->appendChild($element); - } - - /* - public function &newEntry() - { - $entry = $this->newElement('entry'); - $this->feed->appendChild($entry); - return $entry; - } - - public function &newId($id, $entry = null) - { - $id = $this->newElement('id', $id); - if(isset($entry))$entry->appendChild($id); - return $id; - } - - public function &newField($name = NULL, $value = NULL, &$entry = NULL) - { - $append = false; - - if(func_num_args() > 3) - { - $append = ((func_get_arg(3) === true) ? true : false); - } - - $field = $this->newElement('cmis:' . $name,$value); - - if (isset($entry)) $entry->appendChild($field); - else if ($append) $this->feed->appendChild($field); - - return $field; - } +\ + * */ } diff --git a/webservice/classes/atompub/cmis/KT_cmis_atom_server.inc.php b/webservice/classes/atompub/cmis/KT_cmis_atom_server.inc.php index 34664bb..1bd7711 100644 --- a/webservice/classes/atompub/cmis/KT_cmis_atom_server.inc.php +++ b/webservice/classes/atompub/cmis/KT_cmis_atom_server.inc.php @@ -120,26 +120,6 @@ class KT_cmis_atom_server extends KT_atom_server { return false; } -// // TODO we probably want this version in the base class for auth purposes -// public function render() -// { -// ob_end_clean(); -//// // possible additional headers, e.g. basic auth request -//// // FIXME this won't work with the service document as no service object exists -//// if (!is_null($this->serviceObject)) -//// { -//// $headers = $this->serviceObject->getHeaders(); -//// foreach ($headers as $header) -//// { -//// header($header); -//// } -//// } -// -// // TODO header: application/atom+xml for service doc? is how Alfresco does it but is it needed? -// header('Content-type: text/xml'); -// echo $this->output; -// } - } ?> \ No newline at end of file diff --git a/webservice/classes/atompub/cmis/KT_cmis_atom_service.inc.php b/webservice/classes/atompub/cmis/KT_cmis_atom_service.inc.php index 7ef09bf..26225ab 100644 --- a/webservice/classes/atompub/cmis/KT_cmis_atom_service.inc.php +++ b/webservice/classes/atompub/cmis/KT_cmis_atom_service.inc.php @@ -6,26 +6,5 @@ class KT_cmis_atom_service extends KT_atom_service { // override and extend as needed - static protected $authData = array(); - - protected function parseHeaders() - { - parent::parseHeaders(); - // attempt to fetch auth info from supplied headers - if (!empty($this->headers['Authorization'])) - { - $auth = base64_decode(preg_replace('/Basic */', '', $this->headers['Authorization'])); - $authData = explode(':', $auth); - self::$authData['username'] = $authData[0]; - self::$authData['password'] = $authData[1]; - } - // if failed, attempt to fetch from $_SERVER array instead - else if (isset($_SERVER['PHP_AUTH_USER'])) - { - self::$authData['username'] = $_SERVER['PHP_AUTH_USER']; - self::$authData['password'] = $_SERVER['PHP_AUTH_PW']; - } - } - } ?> \ No newline at end of file