Commit 0461ffb8dce6f15d1c3a90a167acd2a06ad5c574

Authored by Megan Watson
2 parents 8fae89e7 4451bc81

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

lib/api/ktcmis/objecttypes/CMISFolderObject.inc.php
@@ -72,19 +72,22 @@ class CMISFolderObject extends CMISObject { @@ -72,19 +72,22 @@ class CMISFolderObject extends CMISObject {
72 72
73 if (!is_null($folderId)) 73 if (!is_null($folderId))
74 { 74 {
75 - $this->get($folderId); 75 + try {
  76 + $this->get($folderId);
  77 + }
  78 + catch (exception $e) {
  79 + throw new ObjectNotFoundException($e->getMessage());
  80 + }
76 } 81 }
77 } 82 }
78 83
79 private function get($folderId) 84 private function get($folderId)
80 { 85 {
81 $object = $this->ktapi->get_folder_by_id((int)$folderId); 86 $object = $this->ktapi->get_folder_by_id((int)$folderId);
82 -  
83 - // error?  
84 - if (PEAR::isError($object))  
85 - {  
86 - // throw an exception?  
87 - return $object; 87 +
  88 + // folder does not exist?
  89 + if (PEAR::isError($object)) {
  90 + throw new ObjectNotFoundException('The folder you are trying to access does not exist or is inaccessible');
88 } 91 }
89 92
90 // static $allowedChildObjectTypeIds; 93 // static $allowedChildObjectTypeIds;
search2/search/expr.inc.php
@@ -1387,8 +1387,8 @@ class SQLQueryBuilder implements QueryBuilder @@ -1387,8 +1387,8 @@ class SQLQueryBuilder implements QueryBuilder
1387 // } 1387 // }
1388 if ($this->used_tables['tag_words'] > 0) 1388 if ($this->used_tables['tag_words'] > 0)
1389 { 1389 {
1390 - $sql .= ' LEFT OUTER JOIN document_tags dt ON dt.document_id=d.id ' . "\n" .  
1391 - ' LEFT OUTER JOIN tag_words tw ON dt.tag_id = tw.id ' . "\n"; 1390 + $sql .= ' LEFT OUTER JOIN document_tags dt ON dt.document_id=d.id ' . "\n"
  1391 + . ' LEFT OUTER JOIN tag_words tw ON dt.tag_id = tw.id ' . "\n";
1392 } 1392 }
1393 } 1393 }
1394 else 1394 else
@@ -2399,7 +2399,18 @@ class OpExpr extends Expr @@ -2399,7 +2399,18 @@ class OpExpr extends Expr
2399 2399
2400 // NOTE $oColumns = $oCriteria from calling function 2400 // NOTE $oColumns = $oCriteria from calling function
2401 // TODO variable name change? 2401 // TODO variable name change?
2402 - // WHat is the purpose of this function, it seems to be a double check on the search results but why is this needed? 2402 + // At the very least this needs to have added:
  2403 + // 1. Correct verification of OR queries where one criterion fails
  2404 + // 2. Correct verification of NOT queries (simple type covered, complex type not covered, but probably will be done by OR in (1) above
  2405 + /**
  2406 + * This function attempts to verify that matches made on html type fields do not match only on html tags
  2407 + * but in fact match actual content.
  2408 + *
  2409 + * @param object $document_id
  2410 + * @param object $oColumns
  2411 + * @return boolean TRUE if match | FALSE if not
  2412 + */
  2413 + // NOTE this function is currently unused as it is incomplete and not able to handle some complex queries
2403 public function checkValues($document_id, $oColumns) 2414 public function checkValues($document_id, $oColumns)
2404 { 2415 {
2405 foreach($oColumns as $column) 2416 foreach($oColumns as $column)
@@ -2424,8 +2435,13 @@ class OpExpr extends Expr @@ -2424,8 +2435,13 @@ class OpExpr extends Expr
2424 2435
2425 //$default->log->debug("POSITION: " . $position); 2436 //$default->log->debug("POSITION: " . $position);
2426 2437
2427 - if($position === false)  
2428 - return false; 2438 + if(!$column['not'] && ($position === false)) {
  2439 + return false;
  2440 + }
  2441 + // cater for NOT queries
  2442 + else if($column['not'] && ($position !== false)) {
  2443 + return false;
  2444 + }
2429 } 2445 }
2430 2446
2431 return true; 2447 return true;
@@ -2447,17 +2463,14 @@ class OpExpr extends Expr @@ -2447,17 +2463,14 @@ class OpExpr extends Expr
2447 $exprbuilder = new SQLQueryBuilder($this->getContext()); 2463 $exprbuilder = new SQLQueryBuilder($this->getContext());
2448 $exprbuilder->setIncludeStatus($this->incl_status); 2464 $exprbuilder->setIncludeStatus($this->incl_status);
2449 2465
2450 - if (count($group) == 1)  
2451 - { 2466 + if (count($group) == 1) {
2452 $sql = $exprbuilder->buildComplexQuery($group[0]); 2467 $sql = $exprbuilder->buildComplexQuery($group[0]);
2453 } 2468 }
2454 - else  
2455 - { 2469 + else {
2456 $sql = $exprbuilder->buildSimpleQuery($op, $group); 2470 $sql = $exprbuilder->buildSimpleQuery($op, $group);
2457 } 2471 }
2458 2472
2459 - if (empty($sql))  
2460 - { 2473 + if (empty($sql)) {
2461 return array(); 2474 return array();
2462 } 2475 }
2463 2476
@@ -2466,15 +2479,12 @@ class OpExpr extends Expr @@ -2466,15 +2479,12 @@ class OpExpr extends Expr
2466 $default->log->debug("SEARCH SQL: $sql"); 2479 $default->log->debug("SEARCH SQL: $sql");
2467 $rs = DBUtil::getResultArray($sql); 2480 $rs = DBUtil::getResultArray($sql);
2468 2481
2469 - if (PEAR::isError($rs))  
2470 - { 2482 + if (PEAR::isError($rs)) {
2471 throw new Exception($rs->getMessage()); 2483 throw new Exception($rs->getMessage());
2472 } 2484 }
2473 2485
2474 - if (count($group) == 1)  
2475 - { 2486 + if (count($group) == 1) {
2476 //$default->log->debug("CASE 1"); 2487 //$default->log->debug("CASE 1");
2477 -  
2478 $oCriteria = $this->checkComplexQuery($group[0]); 2488 $oCriteria = $this->checkComplexQuery($group[0]);
2479 } 2489 }
2480 else 2490 else
@@ -2527,10 +2537,15 @@ class OpExpr extends Expr @@ -2527,10 +2537,15 @@ class OpExpr extends Expr
2527 { 2537 {
2528 if ($this->context == ExprContext::DOCUMENT) 2538 if ($this->context == ExprContext::DOCUMENT)
2529 { 2539 {
  2540 + // NOTE removing the call to checkValues as the function only handles some query types, and is currently not so important as
  2541 + // we are stripping most html tags from the html type inputs
  2542 + /*
2530 if((count($oCriteria) > 0 && $this->checkValues($id, $oCriteria)) || count($oCriteria) == 0) 2543 if((count($oCriteria) > 0 && $this->checkValues($id, $oCriteria)) || count($oCriteria) == 0)
2531 { 2544 {
2532 $results[$id] = new DocumentResultItem($id, $rank, $item['title'], $exprbuilder->getResultText($item), null, $this->incl_status); 2545 $results[$id] = new DocumentResultItem($id, $rank, $item['title'], $exprbuilder->getResultText($item), null, $this->incl_status);
2533 } 2546 }
  2547 + */
  2548 + $results[$id] = new DocumentResultItem($id, $rank, $item['title'], $exprbuilder->getResultText($item), null, $this->incl_status);
2534 } 2549 }
2535 else 2550 else
2536 { 2551 {
setup/wizard/lib/services/unixOpenOffice.php
@@ -67,7 +67,7 @@ class unixOpenOffice extends unixService { @@ -67,7 +67,7 @@ class unixOpenOffice extends unixService {
67 if(isset($options['binary'])) { 67 if(isset($options['binary'])) {
68 $this->setBin($options['binary']); 68 $this->setBin($options['binary']);
69 } else { 69 } else {
70 - $this->setBin("/usr/bin//soffice"); 70 + $this->setBin("/usr/bin/soffice");
71 } 71 }
72 $this->setPort("8100"); 72 $this->setPort("8100");
73 $this->setHost("localhost"); 73 $this->setHost("localhost");
@@ -137,11 +137,18 @@ class unixOpenOffice extends unixService { @@ -137,11 +137,18 @@ class unixOpenOffice extends unixService {
137 public function start() { 137 public function start() {
138 $state = $this->status(); 138 $state = $this->status();
139 if($state != 'STARTED') { 139 if($state != 'STARTED') {
140 - $cmd = "\"{$this->util->getJava()}\" -cp \"".SYS_DIR."\" openOffice ".$this->getBin(); 140 + $cmd = "nohup ".$this->getBin().' -nofirststartwizard -nologo -headless -accept="socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" '." &1> /dev/null &";
  141 +// $cmd = "\"{$this->util->getJava()}\" -cp \"".SYS_DIR."\" openOffice ".$this->getBin();
  142 +
141 if(DEBUG) { 143 if(DEBUG) {
142 echo "Command : $cmd<br/>"; 144 echo "Command : $cmd<br/>";
143 return ; 145 return ;
144 } 146 }
  147 +// $cmd = 'nohup /usr/lib/openoffice/program/soffice -nofirststartwizard -nologo -headless -accept="socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" &> /dev/null &';
  148 +// $cmd = 'nohup /usr/lib/openoffice/program/soffice -nofirststartwizard -nologo -headless -accept="socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" &1> /dev/null &';
  149 +// $cmd = '/usr/lib/openoffice/program/soffice -nofirststartwizard -nologo -headless -accept="socket,host=localhost,port=8100;urp;StarOffice.ServiceManager"';
  150 +// $cmd = '/usr/lib/openoffice/program/soffice.bin -nofirststartwizard -nologo -headless -accept="socket,host=localhost,port=8100;urp;StarOffice.ServiceManager"';
  151 +// $cmd = '/usr/lib/openoffice/program/soffice.bin -nofirststartwizard -nologo -headless -accept="socket,host=localhost,port=8100;urp;StarOffice.ServiceManager"';
145 $response = $this->util->pexec($cmd); 152 $response = $this->util->pexec($cmd);
146 153
147 return $response; 154 return $response;
setup/wizard/lib/services/unixService.php
@@ -69,11 +69,11 @@ class unixService extends Service { @@ -69,11 +69,11 @@ class unixService extends Service {
69 function setSystemDirs() { 69 function setSystemDirs() {
70 $conf = $this->util->getDataFromSession('configuration'); 70 $conf = $this->util->getDataFromSession('configuration');
71 $this->outputDir = $conf['paths']['logDirectory']['path'].DS; 71 $this->outputDir = $conf['paths']['logDirectory']['path'].DS;
72 - if($this->outputDir == '') { 72 + if($this->outputDir == '' || $this->outputDir == '/') {
73 $this->outputDir = SYS_OUT_DIR; 73 $this->outputDir = SYS_OUT_DIR;
74 } 74 }
75 $this->varDir = $conf['paths']['varDirectory']['path'].DS; 75 $this->varDir = $conf['paths']['varDirectory']['path'].DS;
76 - if($this->varDir == '') { 76 + if($this->varDir == '' || $this->varDir == '/') {
77 $this->varDir = SYS_VAR_DIR; 77 $this->varDir = SYS_VAR_DIR;
78 } 78 }
79 } 79 }
setup/wizard/lib/system/soffice.php 0 โ†’ 100644
  1 +<?php
  2 + $cmd = "nohup /usr/bin/soffice -nofirststartwizard -nologo -headless -accept=\"socket,host=localhost,port=8100;urp;StarOffice.ServiceManager\" &1> /dev/null &";
  3 + $res = pexec($cmd);
  4 + print_r($res);
  5 +/**
  6 + * Portably execute a command on any of the supported platforms.
  7 + *
  8 + * @author KnowledgeTree Team
  9 + * @access public
  10 + * @param string $aCmd
  11 + * @param array $aOptions
  12 + * @return array
  13 + */
  14 + function pexec($aCmd, $aOptions = null) {
  15 + if (is_array($aCmd)) {
  16 + $sCmd = safeShellString($aCmd);
  17 + } else {
  18 + $sCmd = $aCmd;
  19 + }
  20 + $sAppend = arrayGet($aOptions, 'append');
  21 + if ($sAppend) {
  22 + $sCmd .= " >> " . escapeshellarg($sAppend);
  23 + }
  24 + $sPopen = arrayGet($aOptions, 'popen');
  25 + if ($sPopen) {
  26 + if (WINDOWS_OS) {
  27 + $sCmd = "start /b \"kt\" " . $sCmd;
  28 + }
  29 + return popen($sCmd, $sPopen);
  30 + }
  31 + // for exec, check return code and output...
  32 + $aRet = array();
  33 + $aOutput = array();
  34 + $iRet = '';
  35 + //if(WINDOWS_OS) {
  36 + // $sCmd = 'call '.$sCmd;
  37 + // }
  38 +
  39 + exec($sCmd, $aOutput, $iRet);
  40 + $aRet['ret'] = $iRet;
  41 + $aRet['out'] = $aOutput;
  42 +
  43 + return $aRet;
  44 + }
  45 +
  46 + /**
  47 + *
  48 + *
  49 + * @author KnowledgeTree Team
  50 + * @access public
  51 + * @return string
  52 + */
  53 + function arrayGet($aArray, $sKey, $mDefault = null, $bDefaultIfEmpty = true) {
  54 + if (!is_array($aArray)) {
  55 + $aArray = (array) $aArray;
  56 + }
  57 +
  58 + if ($aArray !== 0 && $aArray !== '0' && empty($aArray)) {
  59 + return $mDefault;
  60 + }
  61 + if (array_key_exists($sKey, $aArray)) {
  62 + $mVal =& $aArray[$sKey];
  63 + if (empty($mVal) && $bDefaultIfEmpty) {
  64 + return $mDefault;
  65 + }
  66 + return $mVal;
  67 + }
  68 + return $mDefault;
  69 + }
  70 +
  71 + /**
  72 + *
  73 + *
  74 + * @author KnowledgeTree Team
  75 + * @access public
  76 + * @return string
  77 + */
  78 + function safeShellString () {
  79 + $aArgs = func_get_args();
  80 + $aSafeArgs = array();
  81 + if (is_array($aArgs[0])) {
  82 + $aArgs = $aArgs[0];
  83 + }
  84 + $aSafeArgs[] = escapeshellarg(array_shift($aArgs));
  85 + if (is_array($aArgs[0])) {
  86 + $aArgs = $aArgs;
  87 + }
  88 + foreach ($aArgs as $sArg) {
  89 + if (empty($sArg)) {
  90 + $aSafeArgs[] = "''";
  91 + } else {
  92 + $aSafeArgs[] = escapeshellarg($sArg);
  93 + }
  94 + }
  95 + return join(" ", $aSafeArgs);
  96 + }
  97 +?>
setup/wizard/steps/configuration.php
@@ -258,9 +258,6 @@ class configuration extends Step @@ -258,9 +258,6 @@ class configuration extends Step
258 $paths = $this->getPathInfo($server['file_system_root']['value']); 258 $paths = $this->getPathInfo($server['file_system_root']['value']);
259 if(!$edit) $this->temp_variables['paths'] = $paths; 259 if(!$edit) $this->temp_variables['paths'] = $paths;
260 260
261 - // Running user  
262 - // Logging  
263 -  
264 return $this->done; 261 return $this->done;
265 } 262 }
266 263
setup/wizard/steps/dependencies.php
@@ -227,6 +227,8 @@ class dependencies extends Step @@ -227,6 +227,8 @@ class dependencies extends Step
227 if($class == 'orange') { 227 if($class == 'orange') {
228 $this->temp_variables['php_con'] = 'cross_orange'; 228 $this->temp_variables['php_con'] = 'cross_orange';
229 } 229 }
  230 + if($setting < 0)
  231 + $setting = "unset";
230 $limits[$key]['setting'] = $this->prettySize($setting); 232 $limits[$key]['setting'] = $this->prettySize($setting);
231 $limits[$key]['class'] = $class; 233 $limits[$key]['class'] = $class;
232 } 234 }
setup/wizard/steps/services.php
@@ -220,7 +220,6 @@ class services extends Step @@ -220,7 +220,6 @@ class services extends Step
220 $srv->load(); 220 $srv->load();
221 $status = $this->serviceInstalled($srv); 221 $status = $this->serviceInstalled($srv);
222 if($status != 'STARTED') { 222 if($status != 'STARTED') {
223 -// if(!$this->$class->installed) {  
224 if(!WINDOWS_OS) { $binary = $this->$class->getBinary(); } // Get binary, if it exists 223 if(!WINDOWS_OS) { $binary = $this->$class->getBinary(); } // Get binary, if it exists
225 $passed = $this->$class->binaryChecks(); // Run Binary Pre Checks 224 $passed = $this->$class->binaryChecks(); // Run Binary Pre Checks
226 if ($passed) { // Install Service 225 if ($passed) { // Install Service
@@ -576,7 +575,10 @@ class services extends Step @@ -576,7 +575,10 @@ class services extends Step
576 require_once("../lib/validation/$serv"."Validation.php"); 575 require_once("../lib/validation/$serv"."Validation.php");
577 require_once("../lib/services/$className.php"); 576 require_once("../lib/services/$className.php");
578 $service = new $className(); 577 $service = new $className();
579 - $service->load(); 578 + $class = strtolower($serviceName)."Validation";
  579 + $vClass = new $class();
  580 + $passed = $vClass->binaryChecks(); // Run Binary Pre Checks
  581 + $service->load(array('binary'=>$passed));
580 $service->install(); 582 $service->install();
581 echo "Install Service {$service->getName()}<br/>"; 583 echo "Install Service {$service->getName()}<br/>";
582 echo "Status of service ".$service->status()."<br/>"; 584 echo "Status of service ".$service->status()."<br/>";
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 { @@ -60,9 +60,10 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service {
60 $repositoryId = $repositories[0]['repositoryId']; 60 $repositoryId = $repositories[0]['repositoryId'];
61 61
62 // TODO implement full path/node separation as with Alfresco - i.e. path requests come in on path/ and node requests come in on node/ 62 // TODO implement full path/node separation as with Alfresco - i.e. path requests come in on path/ and node requests come in on node/
63 - // path request e.g.: Root Folder/DroppedDocuments  
64 - // node request e.g.: F1/children  
65 - // node request e.g.: F2 63 + // path request e.g.: path/Root Folder/DroppedDocuments
  64 + // node request e.g.: node/F1/children
  65 + // node request e.g.: node/F2/parent
  66 + // node request e.g.: node/F2
66 if (urldecode($this->params[0]) == 'Root Folder') 67 if (urldecode($this->params[0]) == 'Root Folder')
67 { 68 {
68 $folderId = CMISUtil::encodeObjectId('Folder', 1); 69 $folderId = CMISUtil::encodeObjectId('Folder', 1);
@@ -87,6 +88,27 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { @@ -87,6 +88,27 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service {
87 88
88 $folderName = $response['properties']['Name']['value']; 89 $folderName = $response['properties']['Name']['value'];
89 } 90 }
  91 + // NOTE parent changes to parents in later specification
  92 + // TODO update when updating to later specification
  93 + // TODO this only returns one parent, need to implement returnToRoot also
  94 + else if ($this->params[1] == 'parent')
  95 + {
  96 + // abstract this to be used also by the document service (and the PWC service?) ???
  97 + // alternatively use getFolderParent here makes sense and use getObjectParents when document service?
  98 + $folderId = $this->params[0];
  99 + $NavigationService = new NavigationService(KT_cmis_atom_service_helper::getKt());
  100 + $response = $NavigationService->getFolderParent($repositoryId, $folderId, false, false, false);
  101 +
  102 + if (PEAR::isError($response)) {
  103 + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, KT_cmis_atom_service::STATUS_SERVER_ERROR, $response->getMessage());
  104 + $this->responseFeed = $feed;
  105 + return null;
  106 + }
  107 +
  108 + // we know that a folder will only have one parent, so we can assume element 0
  109 + $folderId = $response[0]['properties']['ObjectId']['value'];
  110 + $folderName = $response[0]['properties']['Name']['value'];
  111 + }
90 else { 112 else {
91 $folderId = $this->params[0]; 113 $folderId = $this->params[0];
92 } 114 }
@@ -336,206 +358,6 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service { @@ -336,206 +358,6 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service {
336 } 358 }
337 359
338 /** 360 /**
339 - * AtomPub Service: types  
340 - */  
341 -class KT_cmis_atom_service_types extends KT_cmis_atom_service {  
342 -  
343 - public function GET_action()  
344 - {  
345 - $RepositoryService = new RepositoryService();  
346 - $repositories = $RepositoryService->getRepositories();  
347 - $repositoryId = $repositories[0]['repositoryId'];  
348 -  
349 - $types = $RepositoryService->getTypes($repositoryId);  
350 - $type = ((empty($this->params[0])) ? 'all' : $this->params[0]);  
351 - $feed = KT_cmis_atom_service_helper::getTypeFeed($type, $types);  
352 -  
353 - // Expose the responseFeed  
354 - $this->responseFeed = $feed;  
355 - }  
356 -  
357 -}  
358 -  
359 -/**  
360 - * AtomPub Service: type  
361 - */  
362 -class KT_cmis_atom_service_type extends KT_cmis_atom_service {  
363 -  
364 - public function GET_action()  
365 - {  
366 - $RepositoryService = new RepositoryService();  
367 -  
368 - // fetch repository id  
369 - $repositories = $RepositoryService->getRepositories();  
370 - $repositoryId = $repositories[0]['repositoryId'];  
371 -  
372 - if (!isset($this->params[1])) {  
373 - // For easier return in the wanted format, we call getTypes instead of getTypeDefinition.  
374 - // Calling this with a single type specified returns an array containing the definition of  
375 - // just the requested type.  
376 - // NOTE could maybe be more efficient to call getTypeDefinition direct and then place in  
377 - // an array on this side? or directly expose the individual entry response code and  
378 - // call directly from here rather than via getTypeFeed.  
379 - $type = ucwords($this->params[0]);  
380 - $types = $RepositoryService->getTypes($repositoryId, $type);  
381 - $feed = KT_cmis_atom_service_helper::getTypeFeed($type, $types);  
382 - }  
383 - else {  
384 - // TODO dynamic dates, as needed everywhere  
385 - // NOTE children of types not yet implemented and we don't support any non-basic types at this time  
386 - $feed = $this->getTypeChildrenFeed($this->params[1]);  
387 - }  
388 -  
389 - // Expose the responseFeed  
390 - $this->responseFeed=$feed;  
391 - }  
392 -  
393 - /**  
394 - * Retrieves a list of child types for the supplied type  
395 - *  
396 - * NOTE this currently returns a hard coded empty list, since we do not currently support child types  
397 - * TODO make dynamic if/when we support checking for child types (we don't actually need to support child types themselves)  
398 - *  
399 - * @param string $type  
400 - * @return string CMIS AtomPub feed  
401 - */  
402 - private function getTypeChildrenFeed()  
403 - {  
404 - //Create a new response feed  
405 - // $baseURI=NULL,$title=NULL,$link=NULL,$updated=NULL,$author=NULL,$id=NULL  
406 - $feed = new KT_cmis_atom_responseFeed_GET(CMIS_APP_BASE_URI);  
407 -  
408 - $feed->newField('title', 'Child Types of ' . ucwords($this->params[0]), $feed);  
409 - $feed->newField('id', $this->params[0] . '-children', $feed);  
410 -  
411 - // TODO fetch child types - to be implemented when we support child types in the API  
412 -  
413 - // links  
414 - $link = $feed->newElement('link');  
415 - $link->appendChild($feed->newAttr('rel','first'));  
416 - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . 'type/' . $this->params[0] . '/' . $this->params[1] . '?pageNo=1&amp;pageSize=0'));  
417 - $link->appendChild($feed->newAttr('type', 'application/atom+xml;type=feed'));  
418 -  
419 - $link = $feed->newElement('link');  
420 - $link->appendChild($feed->newAttr('rel','last'));  
421 - // TODO set page number correctly - to be done when we support paging the the API  
422 - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . 'type/' . $this->params[0] . '/' . $this->params[1] . '?pageNo=1&amp;pageSize=0'));  
423 - $link->appendChild($feed->newAttr('type', 'application/atom+xml;type=feed'));  
424 -  
425 - $feed->newField('updated', KT_cmis_atom_service_helper::formatDatestamp(), $feed);  
426 - $feed->newField('cmis:hasMoreItems', 'false', $feed);  
427 -  
428 - return $feed;  
429 - }  
430 -  
431 -}  
432 -  
433 -/**  
434 - * AtomPub Service: checkedout  
435 - */  
436 -class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service {  
437 -  
438 - /**  
439 - * Deals with GET actions for checkedout documents.  
440 - */  
441 - public function GET_action()  
442 - {  
443 - $RepositoryService = new RepositoryService();  
444 - $NavigationService = new NavigationService(KT_cmis_atom_service_helper::getKt());  
445 -  
446 - $repositories = $RepositoryService->getRepositories();  
447 - $repositoryId = $repositories[0]['repositoryId'];  
448 -  
449 - $checkedout = $NavigationService->getCheckedOutDocs($repositoryId);  
450 -  
451 - //Create a new response feed  
452 - $feed = new KT_cmis_atom_responseFeed_GET(CMIS_APP_BASE_URI);  
453 - $workspace = $feed->getWorkspace();  
454 -  
455 - $feed->newField('title', 'Checked out Documents', $feed);  
456 -  
457 - // TODO dynamic?  
458 - $feedElement = $feed->newField('author');  
459 - $element = $feed->newField('name', 'admin', $feedElement);  
460 - $feed->appendChild($feedElement);  
461 -  
462 - $feed->appendChild($feed->newElement('id', 'urn:uuid:checkedout'));  
463 -  
464 - // TODO get actual most recent update time, only use current if no other available  
465 - $feed->appendChild($feed->newElement('updated', KT_cmis_atom_service_helper::formatDatestamp()));  
466 -  
467 - $link = $feed->newElement('link');  
468 - $link->appendChild($feed->newAttr('rel', 'self'));  
469 - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/checkedout'));  
470 - $feed->appendChild($link);  
471 -  
472 - $link = $feed->newElement('link');  
473 - $link->appendChild($feed->newAttr('rel','first'));  
474 - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/checkedout/pageNo=1&amp;pageSize=0'));  
475 - $link->appendChild($feed->newAttr('type', 'application/atom+xml;type=feed'));  
476 - $feed->appendChild($link);  
477 -  
478 - $link = $feed->newElement('link');  
479 - $link->appendChild($feed->newAttr('rel','last'));  
480 - // TODO set page number correctly - to be done when we support paging the the API  
481 - $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/checkedout/pageNo=1&amp;pageSize=0'));  
482 - $link->appendChild($feed->newAttr('type', 'application/atom+xml;type=feed'));  
483 - $feed->appendChild($link);  
484 -  
485 - foreach($checkedout as $cmisEntry)  
486 - {  
487 - KT_cmis_atom_service_helper::createObjectEntry($feed, $cmisEntry, $folderName, true);  
488 -  
489 -// // after each entry, add app:edited tag  
490 -// $feed->newField('app:edited', KT_cmis_atom_service_helper::formatDatestamp(), $feed);  
491 - }  
492 -  
493 - $feed->newField('cmis:hasMoreItems', 'false', $feed);  
494 -  
495 - // Expose the responseFeed  
496 - $this->responseFeed = $feed;  
497 - }  
498 -  
499 - public function POST_action()  
500 - {  
501 - $RepositoryService = new RepositoryService();  
502 - $VersioningService = new VersioningService(KT_cmis_atom_service_helper::getKt());  
503 - $ObjectService = new ObjectService(KT_cmis_atom_service_helper::getKt());  
504 -  
505 - $repositories = $RepositoryService->getRepositories();  
506 - $repositoryId = $repositories[0]['repositoryId'];  
507 -  
508 - $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->parsedXMLContent['@children']);  
509 -  
510 - // check for existing object id as property of submitted object data  
511 - if (empty($cmisObjectProperties['ObjectId']))  
512 - {  
513 - $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, 'No object was specified for checkout');  
514 - // Expose the responseFeed  
515 - $this->responseFeed = $feed;  
516 - return null;  
517 - }  
518 -  
519 - $response = $VersioningService->checkOut($repositoryId, $cmisObjectProperties['ObjectId']);  
520 -  
521 - if (PEAR::isError($response))  
522 - {  
523 - $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, 'No object was specified for checkout');  
524 - // Expose the responseFeed  
525 - $this->responseFeed = $feed;  
526 - return null;  
527 - }  
528 -  
529 - $this->setStatus(self::STATUS_CREATED);  
530 - $feed = KT_cmis_atom_service_helper::getObjectFeed($this, $ObjectService, $repositoryId, $cmisObjectProperties['ObjectId'], 'POST');  
531 -  
532 - // Expose the responseFeed  
533 - $this->responseFeed = $feed;  
534 - }  
535 -  
536 -}  
537 -  
538 -/**  
539 * AtomPub Service: document 361 * AtomPub Service: document
540 */ 362 */
541 // TODO confirm that an error response is sent when a document has status "deleted" 363 // 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 { @@ -553,15 +375,36 @@ class KT_cmis_atom_service_document extends KT_cmis_atom_service {
553 $repositories = $RepositoryService->getRepositories(); 375 $repositories = $RepositoryService->getRepositories();
554 $repositoryId = $repositories[0]['repositoryId']; 376 $repositoryId = $repositories[0]['repositoryId'];
555 377
  378 + $objectId = $this->params[0];
  379 +
  380 + // TODO this is "parents" in later versions of the specification
  381 + // update accordingly when updating to newer specification
  382 + if ($this->params[1] == 'parent')
  383 + {
  384 + // abstract this to be used also by the document service (and the PWC service?) ???
  385 + // alternatively use getFolderParent here makes sense and use getObjectParents when document service?
  386 + $NavigationService = new NavigationService(KT_cmis_atom_service_helper::getKt());
  387 + $response = $NavigationService->getObjectParents($repositoryId, $objectId, false, false);
  388 +
  389 + if (PEAR::isError($response)) {
  390 + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, KT_cmis_atom_service::STATUS_SERVER_ERROR, $response->getMessage());
  391 + $this->responseFeed = $feed;
  392 + return null;
  393 + }
  394 +
  395 + // for now a document will only have one parent as KnowledgeTree does not support multi-filing
  396 + // TODO update this code if/when multi-filing support is added
  397 + $objectId = $response[0]['properties']['ObjectId']['value'];
  398 + }
556 // determine whether we want the document entry feed or the actual physical document content. 399 // determine whether we want the document entry feed or the actual physical document content.
557 // this depends on $this->params[1] 400 // this depends on $this->params[1]
558 - if (!empty($this->params[1])) 401 + else if (!empty($this->params[1]))
559 { 402 {
560 KT_cmis_atom_service_helper::downloadContentStream($this, $ObjectService, $repositoryId); 403 KT_cmis_atom_service_helper::downloadContentStream($this, $ObjectService, $repositoryId);
561 return null; 404 return null;
562 } 405 }
563 406
564 - $feed = KT_cmis_atom_service_helper::getObjectFeed($this, $ObjectService, $repositoryId, $this->params[0]); 407 + $feed = KT_cmis_atom_service_helper::getObjectFeed($this, $ObjectService, $repositoryId, $objectId);
565 408
566 // Expose the responseFeed 409 // Expose the responseFeed
567 $this->responseFeed = $feed; 410 $this->responseFeed = $feed;
@@ -720,4 +563,204 @@ class KT_cmis_atom_service_pwc extends KT_cmis_atom_service { @@ -720,4 +563,204 @@ class KT_cmis_atom_service_pwc extends KT_cmis_atom_service {
720 563
721 } 564 }
722 565
  566 +/**
  567 + * AtomPub Service: checkedout
  568 + */
  569 +class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service {
  570 +
  571 + /**
  572 + * Deals with GET actions for checkedout documents.
  573 + */
  574 + public function GET_action()
  575 + {
  576 + $RepositoryService = new RepositoryService();
  577 + $NavigationService = new NavigationService(KT_cmis_atom_service_helper::getKt());
  578 +
  579 + $repositories = $RepositoryService->getRepositories();
  580 + $repositoryId = $repositories[0]['repositoryId'];
  581 +
  582 + $checkedout = $NavigationService->getCheckedOutDocs($repositoryId);
  583 +
  584 + //Create a new response feed
  585 + $feed = new KT_cmis_atom_responseFeed_GET(CMIS_APP_BASE_URI);
  586 + $workspace = $feed->getWorkspace();
  587 +
  588 + $feed->newField('title', 'Checked out Documents', $feed);
  589 +
  590 + // TODO dynamic?
  591 + $feedElement = $feed->newField('author');
  592 + $element = $feed->newField('name', 'admin', $feedElement);
  593 + $feed->appendChild($feedElement);
  594 +
  595 + $feed->appendChild($feed->newElement('id', 'urn:uuid:checkedout'));
  596 +
  597 + // TODO get actual most recent update time, only use current if no other available
  598 + $feed->appendChild($feed->newElement('updated', KT_cmis_atom_service_helper::formatDatestamp()));
  599 +
  600 + $link = $feed->newElement('link');
  601 + $link->appendChild($feed->newAttr('rel', 'self'));
  602 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/checkedout'));
  603 + $feed->appendChild($link);
  604 +
  605 + $link = $feed->newElement('link');
  606 + $link->appendChild($feed->newAttr('rel','first'));
  607 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/checkedout/pageNo=1&amp;pageSize=0'));
  608 + $link->appendChild($feed->newAttr('type', 'application/atom+xml;type=feed'));
  609 + $feed->appendChild($link);
  610 +
  611 + $link = $feed->newElement('link');
  612 + $link->appendChild($feed->newAttr('rel','last'));
  613 + // TODO set page number correctly - to be done when we support paging the the API
  614 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/checkedout/pageNo=1&amp;pageSize=0'));
  615 + $link->appendChild($feed->newAttr('type', 'application/atom+xml;type=feed'));
  616 + $feed->appendChild($link);
  617 +
  618 + foreach($checkedout as $cmisEntry)
  619 + {
  620 + KT_cmis_atom_service_helper::createObjectEntry($feed, $cmisEntry, $folderName, true);
  621 +
  622 +// // after each entry, add app:edited tag
  623 +// $feed->newField('app:edited', KT_cmis_atom_service_helper::formatDatestamp(), $feed);
  624 + }
  625 +
  626 + $feed->newField('cmis:hasMoreItems', 'false', $feed);
  627 +
  628 + // Expose the responseFeed
  629 + $this->responseFeed = $feed;
  630 + }
  631 +
  632 + public function POST_action()
  633 + {
  634 + $RepositoryService = new RepositoryService();
  635 + $VersioningService = new VersioningService(KT_cmis_atom_service_helper::getKt());
  636 + $ObjectService = new ObjectService(KT_cmis_atom_service_helper::getKt());
  637 +
  638 + $repositories = $RepositoryService->getRepositories();
  639 + $repositoryId = $repositories[0]['repositoryId'];
  640 +
  641 + $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->parsedXMLContent['@children']);
  642 +
  643 + // check for existing object id as property of submitted object data
  644 + if (empty($cmisObjectProperties['ObjectId']))
  645 + {
  646 + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, 'No object was specified for checkout');
  647 + // Expose the responseFeed
  648 + $this->responseFeed = $feed;
  649 + return null;
  650 + }
  651 +
  652 + $response = $VersioningService->checkOut($repositoryId, $cmisObjectProperties['ObjectId']);
  653 +
  654 + if (PEAR::isError($response))
  655 + {
  656 + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, 'No object was specified for checkout');
  657 + // Expose the responseFeed
  658 + $this->responseFeed = $feed;
  659 + return null;
  660 + }
  661 +
  662 + $this->setStatus(self::STATUS_CREATED);
  663 + $feed = KT_cmis_atom_service_helper::getObjectFeed($this, $ObjectService, $repositoryId, $cmisObjectProperties['ObjectId'], 'POST');
  664 +
  665 + // Expose the responseFeed
  666 + $this->responseFeed = $feed;
  667 + }
  668 +
  669 +}
  670 +
  671 +/**
  672 + * AtomPub Service: types
  673 + */
  674 +class KT_cmis_atom_service_types extends KT_cmis_atom_service {
  675 +
  676 + public function GET_action()
  677 + {
  678 + $RepositoryService = new RepositoryService();
  679 + $repositories = $RepositoryService->getRepositories();
  680 + $repositoryId = $repositories[0]['repositoryId'];
  681 +
  682 + $types = $RepositoryService->getTypes($repositoryId);
  683 + $type = ((empty($this->params[0])) ? 'all' : $this->params[0]);
  684 + $feed = KT_cmis_atom_service_helper::getTypeFeed($type, $types);
  685 +
  686 + // Expose the responseFeed
  687 + $this->responseFeed = $feed;
  688 + }
  689 +
  690 +}
  691 +
  692 +/**
  693 + * AtomPub Service: type
  694 + */
  695 +class KT_cmis_atom_service_type extends KT_cmis_atom_service {
  696 +
  697 + public function GET_action()
  698 + {
  699 + $RepositoryService = new RepositoryService();
  700 +
  701 + // fetch repository id
  702 + $repositories = $RepositoryService->getRepositories();
  703 + $repositoryId = $repositories[0]['repositoryId'];
  704 +
  705 + if (!isset($this->params[1])) {
  706 + // For easier return in the wanted format, we call getTypes instead of getTypeDefinition.
  707 + // Calling this with a single type specified returns an array containing the definition of
  708 + // just the requested type.
  709 + // NOTE could maybe be more efficient to call getTypeDefinition direct and then place in
  710 + // an array on this side? or directly expose the individual entry response code and
  711 + // call directly from here rather than via getTypeFeed.
  712 + $type = ucwords($this->params[0]);
  713 + $types = $RepositoryService->getTypes($repositoryId, $type);
  714 + $feed = KT_cmis_atom_service_helper::getTypeFeed($type, $types);
  715 + }
  716 + else {
  717 + // TODO dynamic dates, as needed everywhere
  718 + // NOTE children of types not yet implemented and we don't support any non-basic types at this time
  719 + $feed = $this->getTypeChildrenFeed($this->params[1]);
  720 + }
  721 +
  722 + // Expose the responseFeed
  723 + $this->responseFeed=$feed;
  724 + }
  725 +
  726 + /**
  727 + * Retrieves a list of child types for the supplied type
  728 + *
  729 + * NOTE this currently returns a hard coded empty list, since we do not currently support child types
  730 + * TODO make dynamic if/when we support checking for child types (we don't actually need to support child types themselves)
  731 + *
  732 + * @param string $type
  733 + * @return string CMIS AtomPub feed
  734 + */
  735 + private function getTypeChildrenFeed()
  736 + {
  737 + //Create a new response feed
  738 + // $baseURI=NULL,$title=NULL,$link=NULL,$updated=NULL,$author=NULL,$id=NULL
  739 + $feed = new KT_cmis_atom_responseFeed_GET(CMIS_APP_BASE_URI);
  740 +
  741 + $feed->newField('title', 'Child Types of ' . ucwords($this->params[0]), $feed);
  742 + $feed->newField('id', $this->params[0] . '-children', $feed);
  743 +
  744 + // TODO fetch child types - to be implemented when we support child types in the API
  745 +
  746 + // links
  747 + $link = $feed->newElement('link');
  748 + $link->appendChild($feed->newAttr('rel','first'));
  749 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . 'type/' . $this->params[0] . '/' . $this->params[1] . '?pageNo=1&amp;pageSize=0'));
  750 + $link->appendChild($feed->newAttr('type', 'application/atom+xml;type=feed'));
  751 +
  752 + $link = $feed->newElement('link');
  753 + $link->appendChild($feed->newAttr('rel','last'));
  754 + // TODO set page number correctly - to be done when we support paging the the API
  755 + $link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . 'type/' . $this->params[0] . '/' . $this->params[1] . '?pageNo=1&amp;pageSize=0'));
  756 + $link->appendChild($feed->newAttr('type', 'application/atom+xml;type=feed'));
  757 +
  758 + $feed->newField('updated', KT_cmis_atom_service_helper::formatDatestamp(), $feed);
  759 + $feed->newField('cmis:hasMoreItems', 'false', $feed);
  760 +
  761 + return $feed;
  762 + }
  763 +
  764 +}
  765 +
723 ?> 766 ?>
724 \ No newline at end of file 767 \ No newline at end of file
webservice/atompub/cmis/KT_cmis_atom_service_helper.inc.php
@@ -97,7 +97,8 @@ class KT_cmis_atom_service_helper { @@ -97,7 +97,8 @@ class KT_cmis_atom_service_helper {
97 // links 97 // links
98 $link = $response->newElement('link'); 98 $link = $response->newElement('link');
99 $link->appendChild($response->newAttr('rel', 'self')); 99 $link->appendChild($response->newAttr('rel', 'self'));
100 - $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . (!$pwc ? $type : 'pwc') . '/' . $cmisEntry['properties']['ObjectId']['value'])); 100 + $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . (!$pwc ? $type : 'pwc') . '/'
  101 + . $cmisEntry['properties']['ObjectId']['value']));
101 $entry->appendChild($link); 102 $entry->appendChild($link);
102 103
103 $link = $response->newElement('link'); 104 $link = $response->newElement('link');