diff --git a/lib/api/ktcmis/objecttypes/CMISFolderObject.inc.php b/lib/api/ktcmis/objecttypes/CMISFolderObject.inc.php index 51861dd..d97f53a 100644 --- a/lib/api/ktcmis/objecttypes/CMISFolderObject.inc.php +++ b/lib/api/ktcmis/objecttypes/CMISFolderObject.inc.php @@ -72,19 +72,22 @@ class CMISFolderObject extends CMISObject { if (!is_null($folderId)) { - $this->get($folderId); + try { + $this->get($folderId); + } + catch (exception $e) { + throw new ObjectNotFoundException($e->getMessage()); + } } } private function get($folderId) { $object = $this->ktapi->get_folder_by_id((int)$folderId); - - // error? - if (PEAR::isError($object)) - { - // throw an exception? - return $object; + + // folder does not exist? + if (PEAR::isError($object)) { + throw new ObjectNotFoundException('The folder you are trying to access does not exist or is inaccessible'); } // static $allowedChildObjectTypeIds; diff --git a/search2/search/expr.inc.php b/search2/search/expr.inc.php index dd63f0c..4578565 100755 --- a/search2/search/expr.inc.php +++ b/search2/search/expr.inc.php @@ -1387,8 +1387,8 @@ class SQLQueryBuilder implements QueryBuilder // } if ($this->used_tables['tag_words'] > 0) { - $sql .= ' LEFT OUTER JOIN document_tags dt ON dt.document_id=d.id ' . "\n" . - ' LEFT OUTER JOIN tag_words tw ON dt.tag_id = tw.id ' . "\n"; + $sql .= ' LEFT OUTER JOIN document_tags dt ON dt.document_id=d.id ' . "\n" + . ' LEFT OUTER JOIN tag_words tw ON dt.tag_id = tw.id ' . "\n"; } } else @@ -2399,7 +2399,18 @@ class OpExpr extends Expr // NOTE $oColumns = $oCriteria from calling function // TODO variable name change? - // WHat is the purpose of this function, it seems to be a double check on the search results but why is this needed? + // At the very least this needs to have added: + // 1. Correct verification of OR queries where one criterion fails + // 2. Correct verification of NOT queries (simple type covered, complex type not covered, but probably will be done by OR in (1) above + /** + * This function attempts to verify that matches made on html type fields do not match only on html tags + * but in fact match actual content. + * + * @param object $document_id + * @param object $oColumns + * @return boolean TRUE if match | FALSE if not + */ + // NOTE this function is currently unused as it is incomplete and not able to handle some complex queries public function checkValues($document_id, $oColumns) { foreach($oColumns as $column) @@ -2424,8 +2435,13 @@ class OpExpr extends Expr //$default->log->debug("POSITION: " . $position); - if($position === false) - return false; + if(!$column['not'] && ($position === false)) { + return false; + } + // cater for NOT queries + else if($column['not'] && ($position !== false)) { + return false; + } } return true; @@ -2447,17 +2463,14 @@ class OpExpr extends Expr $exprbuilder = new SQLQueryBuilder($this->getContext()); $exprbuilder->setIncludeStatus($this->incl_status); - if (count($group) == 1) - { + if (count($group) == 1) { $sql = $exprbuilder->buildComplexQuery($group[0]); } - else - { + else { $sql = $exprbuilder->buildSimpleQuery($op, $group); } - if (empty($sql)) - { + if (empty($sql)) { return array(); } @@ -2466,15 +2479,12 @@ class OpExpr extends Expr $default->log->debug("SEARCH SQL: $sql"); $rs = DBUtil::getResultArray($sql); - if (PEAR::isError($rs)) - { + if (PEAR::isError($rs)) { throw new Exception($rs->getMessage()); } - if (count($group) == 1) - { + if (count($group) == 1) { //$default->log->debug("CASE 1"); - $oCriteria = $this->checkComplexQuery($group[0]); } else @@ -2527,10 +2537,15 @@ class OpExpr extends Expr { if ($this->context == ExprContext::DOCUMENT) { + // NOTE removing the call to checkValues as the function only handles some query types, and is currently not so important as + // we are stripping most html tags from the html type inputs + /* if((count($oCriteria) > 0 && $this->checkValues($id, $oCriteria)) || count($oCriteria) == 0) { $results[$id] = new DocumentResultItem($id, $rank, $item['title'], $exprbuilder->getResultText($item), null, $this->incl_status); } + */ + $results[$id] = new DocumentResultItem($id, $rank, $item['title'], $exprbuilder->getResultText($item), null, $this->incl_status); } else { diff --git a/setup/wizard/lib/services/unixOpenOffice.php b/setup/wizard/lib/services/unixOpenOffice.php index e2bcafc..781e336 100644 --- a/setup/wizard/lib/services/unixOpenOffice.php +++ b/setup/wizard/lib/services/unixOpenOffice.php @@ -67,7 +67,7 @@ class unixOpenOffice extends unixService { if(isset($options['binary'])) { $this->setBin($options['binary']); } else { - $this->setBin("/usr/bin//soffice"); + $this->setBin("/usr/bin/soffice"); } $this->setPort("8100"); $this->setHost("localhost"); @@ -137,11 +137,18 @@ class unixOpenOffice extends unixService { public function start() { $state = $this->status(); if($state != 'STARTED') { - $cmd = "\"{$this->util->getJava()}\" -cp \"".SYS_DIR."\" openOffice ".$this->getBin(); + $cmd = "nohup ".$this->getBin().' -nofirststartwizard -nologo -headless -accept="socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" '." &1> /dev/null &"; +// $cmd = "\"{$this->util->getJava()}\" -cp \"".SYS_DIR."\" openOffice ".$this->getBin(); + if(DEBUG) { echo "Command : $cmd
"; return ; } +// $cmd = 'nohup /usr/lib/openoffice/program/soffice -nofirststartwizard -nologo -headless -accept="socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" &> /dev/null &'; +// $cmd = 'nohup /usr/lib/openoffice/program/soffice -nofirststartwizard -nologo -headless -accept="socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" &1> /dev/null &'; +// $cmd = '/usr/lib/openoffice/program/soffice -nofirststartwizard -nologo -headless -accept="socket,host=localhost,port=8100;urp;StarOffice.ServiceManager"'; +// $cmd = '/usr/lib/openoffice/program/soffice.bin -nofirststartwizard -nologo -headless -accept="socket,host=localhost,port=8100;urp;StarOffice.ServiceManager"'; +// $cmd = '/usr/lib/openoffice/program/soffice.bin -nofirststartwizard -nologo -headless -accept="socket,host=localhost,port=8100;urp;StarOffice.ServiceManager"'; $response = $this->util->pexec($cmd); return $response; diff --git a/setup/wizard/lib/services/unixService.php b/setup/wizard/lib/services/unixService.php index 278efe1..8e42ed2 100644 --- a/setup/wizard/lib/services/unixService.php +++ b/setup/wizard/lib/services/unixService.php @@ -69,11 +69,11 @@ class unixService extends Service { function setSystemDirs() { $conf = $this->util->getDataFromSession('configuration'); $this->outputDir = $conf['paths']['logDirectory']['path'].DS; - if($this->outputDir == '') { + if($this->outputDir == '' || $this->outputDir == '/') { $this->outputDir = SYS_OUT_DIR; } $this->varDir = $conf['paths']['varDirectory']['path'].DS; - if($this->varDir == '') { + if($this->varDir == '' || $this->varDir == '/') { $this->varDir = SYS_VAR_DIR; } } diff --git a/setup/wizard/lib/system/soffice.php b/setup/wizard/lib/system/soffice.php new file mode 100644 index 0000000..593d803 --- /dev/null +++ b/setup/wizard/lib/system/soffice.php @@ -0,0 +1,97 @@ + /dev/null &"; + $res = pexec($cmd); + print_r($res); +/** + * Portably execute a command on any of the supported platforms. + * + * @author KnowledgeTree Team + * @access public + * @param string $aCmd + * @param array $aOptions + * @return array + */ + function pexec($aCmd, $aOptions = null) { + if (is_array($aCmd)) { + $sCmd = safeShellString($aCmd); + } else { + $sCmd = $aCmd; + } + $sAppend = arrayGet($aOptions, 'append'); + if ($sAppend) { + $sCmd .= " >> " . escapeshellarg($sAppend); + } + $sPopen = arrayGet($aOptions, 'popen'); + if ($sPopen) { + if (WINDOWS_OS) { + $sCmd = "start /b \"kt\" " . $sCmd; + } + return popen($sCmd, $sPopen); + } + // for exec, check return code and output... + $aRet = array(); + $aOutput = array(); + $iRet = ''; + //if(WINDOWS_OS) { + // $sCmd = 'call '.$sCmd; + // } + + exec($sCmd, $aOutput, $iRet); + $aRet['ret'] = $iRet; + $aRet['out'] = $aOutput; + + return $aRet; + } + + /** + * + * + * @author KnowledgeTree Team + * @access public + * @return string + */ + function arrayGet($aArray, $sKey, $mDefault = null, $bDefaultIfEmpty = true) { + if (!is_array($aArray)) { + $aArray = (array) $aArray; + } + + if ($aArray !== 0 && $aArray !== '0' && empty($aArray)) { + return $mDefault; + } + if (array_key_exists($sKey, $aArray)) { + $mVal =& $aArray[$sKey]; + if (empty($mVal) && $bDefaultIfEmpty) { + return $mDefault; + } + return $mVal; + } + return $mDefault; + } + + /** + * + * + * @author KnowledgeTree Team + * @access public + * @return string + */ + function safeShellString () { + $aArgs = func_get_args(); + $aSafeArgs = array(); + if (is_array($aArgs[0])) { + $aArgs = $aArgs[0]; + } + $aSafeArgs[] = escapeshellarg(array_shift($aArgs)); + if (is_array($aArgs[0])) { + $aArgs = $aArgs; + } + foreach ($aArgs as $sArg) { + if (empty($sArg)) { + $aSafeArgs[] = "''"; + } else { + $aSafeArgs[] = escapeshellarg($sArg); + } + } + return join(" ", $aSafeArgs); + } +?> diff --git a/setup/wizard/steps/configuration.php b/setup/wizard/steps/configuration.php index e1c981e..50c7142 100644 --- a/setup/wizard/steps/configuration.php +++ b/setup/wizard/steps/configuration.php @@ -258,9 +258,6 @@ class configuration extends Step $paths = $this->getPathInfo($server['file_system_root']['value']); if(!$edit) $this->temp_variables['paths'] = $paths; - // Running user - // Logging - return $this->done; } diff --git a/setup/wizard/steps/dependencies.php b/setup/wizard/steps/dependencies.php index 993a222..85c4f3d 100644 --- a/setup/wizard/steps/dependencies.php +++ b/setup/wizard/steps/dependencies.php @@ -227,6 +227,8 @@ class dependencies extends Step if($class == 'orange') { $this->temp_variables['php_con'] = 'cross_orange'; } + if($setting < 0) + $setting = "unset"; $limits[$key]['setting'] = $this->prettySize($setting); $limits[$key]['class'] = $class; } diff --git a/setup/wizard/steps/services.php b/setup/wizard/steps/services.php index 53ac4b0..6f5d309 100644 --- a/setup/wizard/steps/services.php +++ b/setup/wizard/steps/services.php @@ -220,7 +220,6 @@ class services extends Step $srv->load(); $status = $this->serviceInstalled($srv); if($status != 'STARTED') { -// if(!$this->$class->installed) { if(!WINDOWS_OS) { $binary = $this->$class->getBinary(); } // Get binary, if it exists $passed = $this->$class->binaryChecks(); // Run Binary Pre Checks if ($passed) { // Install Service @@ -576,7 +575,10 @@ class services extends Step require_once("../lib/validation/$serv"."Validation.php"); require_once("../lib/services/$className.php"); $service = new $className(); - $service->load(); + $class = strtolower($serviceName)."Validation"; + $vClass = new $class(); + $passed = $vClass->binaryChecks(); // Run Binary Pre Checks + $service->load(array('binary'=>$passed)); $service->install(); echo "Install Service {$service->getName()}
"; echo "Status of service ".$service->status()."
"; 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 81b18ee..156ae4b 100644 --- a/webservice/atompub/cmis/KT_cmis_atom_server.services.inc.php +++ b/webservice/atompub/cmis/KT_cmis_atom_server.services.inc.php @@ -60,9 +60,10 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { $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 + // path request e.g.: path/Root Folder/DroppedDocuments + // node request e.g.: node/F1/children + // node request e.g.: node/F2/parent + // node request e.g.: node/F2 if (urldecode($this->params[0]) == 'Root Folder') { $folderId = CMISUtil::encodeObjectId('Folder', 1); @@ -87,6 +88,27 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { $folderName = $response['properties']['Name']['value']; } + // NOTE parent changes to parents in later specification + // TODO update when updating to later specification + // TODO this only returns one parent, need to implement returnToRoot also + else if ($this->params[1] == 'parent') + { + // abstract this to be used also by the document service (and the PWC service?) ??? + // alternatively use getFolderParent here makes sense and use getObjectParents when document service? + $folderId = $this->params[0]; + $NavigationService = new NavigationService(KT_cmis_atom_service_helper::getKt()); + $response = $NavigationService->getFolderParent($repositoryId, $folderId, false, false, false); + + if (PEAR::isError($response)) { + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, KT_cmis_atom_service::STATUS_SERVER_ERROR, $response->getMessage()); + $this->responseFeed = $feed; + return null; + } + + // we know that a folder will only have one parent, so we can assume element 0 + $folderId = $response[0]['properties']['ObjectId']['value']; + $folderName = $response[0]['properties']['Name']['value']; + } else { $folderId = $this->params[0]; } @@ -336,206 +358,6 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { } /** - * AtomPub Service: types - */ -class KT_cmis_atom_service_types extends KT_cmis_atom_service { - - public function GET_action() - { - $RepositoryService = new RepositoryService(); - $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 - */ -class KT_cmis_atom_service_type extends KT_cmis_atom_service { - - public function GET_action() - { - $RepositoryService = new RepositoryService(); - - // 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_GET(CMIS_APP_BASE_URI); - - $feed->newField('title', 'Child Types of ' . ucwords($this->params[0]), $feed); - $feed->newField('id', $this->params[0] . '-children', $feed); - - // TODO fetch child types - to be implemented when we support child types in the API - - // 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')); - - $feed->newField('updated', KT_cmis_atom_service_helper::formatDatestamp(), $feed); - $feed->newField('cmis:hasMoreItems', 'false', $feed); - - return $feed; - } - -} - -/** - * AtomPub Service: checkedout - */ -class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service { - - /** - * Deals with GET actions for checkedout documents. - */ - public function GET_action() - { - $RepositoryService = new RepositoryService(); - $NavigationService = new NavigationService(KT_cmis_atom_service_helper::getKt()); - - $repositories = $RepositoryService->getRepositories(); - $repositoryId = $repositories[0]['repositoryId']; - - $checkedout = $NavigationService->getCheckedOutDocs($repositoryId); - - //Create a new response feed - $feed = new KT_cmis_atom_responseFeed_GET(CMIS_APP_BASE_URI); - $workspace = $feed->getWorkspace(); - - $feed->newField('title', 'Checked out Documents', $feed); - - // TODO dynamic? - $feedElement = $feed->newField('author'); - $element = $feed->newField('name', 'admin', $feedElement); - $feed->appendChild($feedElement); - - $feed->appendChild($feed->newElement('id', 'urn:uuid:checkedout')); - - // 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())); - - $link = $feed->newElement('link'); - $link->appendChild($feed->newAttr('rel', 'self')); - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/checkedout')); - $feed->appendChild($link); - - $link = $feed->newElement('link'); - $link->appendChild($feed->newAttr('rel','first')); - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/checkedout/pageNo=1&pageSize=0')); - $link->appendChild($feed->newAttr('type', 'application/atom+xml;type=feed')); - $feed->appendChild($link); - - $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 . $workspace . '/checkedout/pageNo=1&pageSize=0')); - $link->appendChild($feed->newAttr('type', 'application/atom+xml;type=feed')); - $feed->appendChild($link); - - foreach($checkedout as $cmisEntry) - { - KT_cmis_atom_service_helper::createObjectEntry($feed, $cmisEntry, $folderName, true); - -// // after each entry, add app:edited tag -// $feed->newField('app:edited', KT_cmis_atom_service_helper::formatDatestamp(), $feed); - } - - $feed->newField('cmis:hasMoreItems', 'false', $feed); - - // Expose the responseFeed - $this->responseFeed = $feed; - } - - public function POST_action() - { - $RepositoryService = new RepositoryService(); - $VersioningService = new VersioningService(KT_cmis_atom_service_helper::getKt()); - $ObjectService = new ObjectService(KT_cmis_atom_service_helper::getKt()); - - $repositories = $RepositoryService->getRepositories(); - $repositoryId = $repositories[0]['repositoryId']; - - $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->parsedXMLContent['@children']); - - // check for existing object id as property of submitted object data - if (empty($cmisObjectProperties['ObjectId'])) - { - $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, 'No object was specified for checkout'); - // Expose the responseFeed - $this->responseFeed = $feed; - return null; - } - - $response = $VersioningService->checkOut($repositoryId, $cmisObjectProperties['ObjectId']); - - if (PEAR::isError($response)) - { - $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, 'No object was specified for checkout'); - // Expose the responseFeed - $this->responseFeed = $feed; - return null; - } - - $this->setStatus(self::STATUS_CREATED); - $feed = KT_cmis_atom_service_helper::getObjectFeed($this, $ObjectService, $repositoryId, $cmisObjectProperties['ObjectId'], 'POST'); - - // Expose the responseFeed - $this->responseFeed = $feed; - } - -} - -/** * AtomPub Service: document */ // TODO confirm that an error response is sent when a document has status "deleted" @@ -553,15 +375,36 @@ class KT_cmis_atom_service_document extends KT_cmis_atom_service { $repositories = $RepositoryService->getRepositories(); $repositoryId = $repositories[0]['repositoryId']; + $objectId = $this->params[0]; + + // TODO this is "parents" in later versions of the specification + // update accordingly when updating to newer specification + if ($this->params[1] == 'parent') + { + // abstract this to be used also by the document service (and the PWC service?) ??? + // alternatively use getFolderParent here makes sense and use getObjectParents when document service? + $NavigationService = new NavigationService(KT_cmis_atom_service_helper::getKt()); + $response = $NavigationService->getObjectParents($repositoryId, $objectId, false, false); + + if (PEAR::isError($response)) { + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, KT_cmis_atom_service::STATUS_SERVER_ERROR, $response->getMessage()); + $this->responseFeed = $feed; + return null; + } + + // for now a document will only have one parent as KnowledgeTree does not support multi-filing + // TODO update this code if/when multi-filing support is added + $objectId = $response[0]['properties']['ObjectId']['value']; + } // determine whether we want the document entry feed or the actual physical document content. // this depends on $this->params[1] - if (!empty($this->params[1])) + else if (!empty($this->params[1])) { KT_cmis_atom_service_helper::downloadContentStream($this, $ObjectService, $repositoryId); return null; } - $feed = KT_cmis_atom_service_helper::getObjectFeed($this, $ObjectService, $repositoryId, $this->params[0]); + $feed = KT_cmis_atom_service_helper::getObjectFeed($this, $ObjectService, $repositoryId, $objectId); // Expose the responseFeed $this->responseFeed = $feed; @@ -720,4 +563,204 @@ class KT_cmis_atom_service_pwc extends KT_cmis_atom_service { } +/** + * AtomPub Service: checkedout + */ +class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service { + + /** + * Deals with GET actions for checkedout documents. + */ + public function GET_action() + { + $RepositoryService = new RepositoryService(); + $NavigationService = new NavigationService(KT_cmis_atom_service_helper::getKt()); + + $repositories = $RepositoryService->getRepositories(); + $repositoryId = $repositories[0]['repositoryId']; + + $checkedout = $NavigationService->getCheckedOutDocs($repositoryId); + + //Create a new response feed + $feed = new KT_cmis_atom_responseFeed_GET(CMIS_APP_BASE_URI); + $workspace = $feed->getWorkspace(); + + $feed->newField('title', 'Checked out Documents', $feed); + + // TODO dynamic? + $feedElement = $feed->newField('author'); + $element = $feed->newField('name', 'admin', $feedElement); + $feed->appendChild($feedElement); + + $feed->appendChild($feed->newElement('id', 'urn:uuid:checkedout')); + + // 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())); + + $link = $feed->newElement('link'); + $link->appendChild($feed->newAttr('rel', 'self')); + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/checkedout')); + $feed->appendChild($link); + + $link = $feed->newElement('link'); + $link->appendChild($feed->newAttr('rel','first')); + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/checkedout/pageNo=1&pageSize=0')); + $link->appendChild($feed->newAttr('type', 'application/atom+xml;type=feed')); + $feed->appendChild($link); + + $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 . $workspace . '/checkedout/pageNo=1&pageSize=0')); + $link->appendChild($feed->newAttr('type', 'application/atom+xml;type=feed')); + $feed->appendChild($link); + + foreach($checkedout as $cmisEntry) + { + KT_cmis_atom_service_helper::createObjectEntry($feed, $cmisEntry, $folderName, true); + +// // after each entry, add app:edited tag +// $feed->newField('app:edited', KT_cmis_atom_service_helper::formatDatestamp(), $feed); + } + + $feed->newField('cmis:hasMoreItems', 'false', $feed); + + // Expose the responseFeed + $this->responseFeed = $feed; + } + + public function POST_action() + { + $RepositoryService = new RepositoryService(); + $VersioningService = new VersioningService(KT_cmis_atom_service_helper::getKt()); + $ObjectService = new ObjectService(KT_cmis_atom_service_helper::getKt()); + + $repositories = $RepositoryService->getRepositories(); + $repositoryId = $repositories[0]['repositoryId']; + + $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->parsedXMLContent['@children']); + + // check for existing object id as property of submitted object data + if (empty($cmisObjectProperties['ObjectId'])) + { + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, 'No object was specified for checkout'); + // Expose the responseFeed + $this->responseFeed = $feed; + return null; + } + + $response = $VersioningService->checkOut($repositoryId, $cmisObjectProperties['ObjectId']); + + if (PEAR::isError($response)) + { + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, 'No object was specified for checkout'); + // Expose the responseFeed + $this->responseFeed = $feed; + return null; + } + + $this->setStatus(self::STATUS_CREATED); + $feed = KT_cmis_atom_service_helper::getObjectFeed($this, $ObjectService, $repositoryId, $cmisObjectProperties['ObjectId'], 'POST'); + + // Expose the responseFeed + $this->responseFeed = $feed; + } + +} + +/** + * AtomPub Service: types + */ +class KT_cmis_atom_service_types extends KT_cmis_atom_service { + + public function GET_action() + { + $RepositoryService = new RepositoryService(); + $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 + */ +class KT_cmis_atom_service_type extends KT_cmis_atom_service { + + public function GET_action() + { + $RepositoryService = new RepositoryService(); + + // 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_GET(CMIS_APP_BASE_URI); + + $feed->newField('title', 'Child Types of ' . ucwords($this->params[0]), $feed); + $feed->newField('id', $this->params[0] . '-children', $feed); + + // TODO fetch child types - to be implemented when we support child types in the API + + // 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')); + + $feed->newField('updated', KT_cmis_atom_service_helper::formatDatestamp(), $feed); + $feed->newField('cmis:hasMoreItems', 'false', $feed); + + return $feed; + } + +} + ?> \ No newline at end of file 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 078e5fc..cf964c6 100644 --- a/webservice/atompub/cmis/KT_cmis_atom_service_helper.inc.php +++ b/webservice/atompub/cmis/KT_cmis_atom_service_helper.inc.php @@ -97,7 +97,8 @@ class KT_cmis_atom_service_helper { // links $link = $response->newElement('link'); $link->appendChild($response->newAttr('rel', 'self')); - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . (!$pwc ? $type : 'pwc') . '/' . $cmisEntry['properties']['ObjectId']['value'])); + $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . (!$pwc ? $type : 'pwc') . '/' + . $cmisEntry['properties']['ObjectId']['value'])); $entry->appendChild($link); $link = $response->newElement('link');