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 72  
73 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 84 private function get($folderId)
80 85 {
81 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 93 // static $allowedChildObjectTypeIds;
... ...
search2/search/expr.inc.php
... ... @@ -1387,8 +1387,8 @@ class SQLQueryBuilder implements QueryBuilder
1387 1387 // }
1388 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 1394 else
... ... @@ -2399,7 +2399,18 @@ class OpExpr extends Expr
2399 2399  
2400 2400 // NOTE $oColumns = $oCriteria from calling function
2401 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 2414 public function checkValues($document_id, $oColumns)
2404 2415 {
2405 2416 foreach($oColumns as $column)
... ... @@ -2424,8 +2435,13 @@ class OpExpr extends Expr
2424 2435  
2425 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 2447 return true;
... ... @@ -2447,17 +2463,14 @@ class OpExpr extends Expr
2447 2463 $exprbuilder = new SQLQueryBuilder($this->getContext());
2448 2464 $exprbuilder->setIncludeStatus($this->incl_status);
2449 2465  
2450   - if (count($group) == 1)
2451   - {
  2466 + if (count($group) == 1) {
2452 2467 $sql = $exprbuilder->buildComplexQuery($group[0]);
2453 2468 }
2454   - else
2455   - {
  2469 + else {
2456 2470 $sql = $exprbuilder->buildSimpleQuery($op, $group);
2457 2471 }
2458 2472  
2459   - if (empty($sql))
2460   - {
  2473 + if (empty($sql)) {
2461 2474 return array();
2462 2475 }
2463 2476  
... ... @@ -2466,15 +2479,12 @@ class OpExpr extends Expr
2466 2479 $default->log->debug("SEARCH SQL: $sql");
2467 2480 $rs = DBUtil::getResultArray($sql);
2468 2481  
2469   - if (PEAR::isError($rs))
2470   - {
  2482 + if (PEAR::isError($rs)) {
2471 2483 throw new Exception($rs->getMessage());
2472 2484 }
2473 2485  
2474   - if (count($group) == 1)
2475   - {
  2486 + if (count($group) == 1) {
2476 2487 //$default->log->debug("CASE 1");
2477   -
2478 2488 $oCriteria = $this->checkComplexQuery($group[0]);
2479 2489 }
2480 2490 else
... ... @@ -2527,10 +2537,15 @@ class OpExpr extends Expr
2527 2537 {
2528 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 2543 if((count($oCriteria) > 0 && $this->checkValues($id, $oCriteria)) || count($oCriteria) == 0)
2531 2544 {
2532 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 2550 else
2536 2551 {
... ...
setup/wizard/lib/services/unixOpenOffice.php
... ... @@ -67,7 +67,7 @@ class unixOpenOffice extends unixService {
67 67 if(isset($options['binary'])) {
68 68 $this->setBin($options['binary']);
69 69 } else {
70   - $this->setBin("/usr/bin//soffice");
  70 + $this->setBin("/usr/bin/soffice");
71 71 }
72 72 $this->setPort("8100");
73 73 $this->setHost("localhost");
... ... @@ -137,11 +137,18 @@ class unixOpenOffice extends unixService {
137 137 public function start() {
138 138 $state = $this->status();
139 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 143 if(DEBUG) {
142 144 echo "Command : $cmd<br/>";
143 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 152 $response = $this->util->pexec($cmd);
146 153  
147 154 return $response;
... ...
setup/wizard/lib/services/unixService.php
... ... @@ -69,11 +69,11 @@ class unixService extends Service {
69 69 function setSystemDirs() {
70 70 $conf = $this->util->getDataFromSession('configuration');
71 71 $this->outputDir = $conf['paths']['logDirectory']['path'].DS;
72   - if($this->outputDir == '') {
  72 + if($this->outputDir == '' || $this->outputDir == '/') {
73 73 $this->outputDir = SYS_OUT_DIR;
74 74 }
75 75 $this->varDir = $conf['paths']['varDirectory']['path'].DS;
76   - if($this->varDir == '') {
  76 + if($this->varDir == '' || $this->varDir == '/') {
77 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 258 $paths = $this->getPathInfo($server['file_system_root']['value']);
259 259 if(!$edit) $this->temp_variables['paths'] = $paths;
260 260  
261   - // Running user
262   - // Logging
263   -
264 261 return $this->done;
265 262 }
266 263  
... ...
setup/wizard/steps/dependencies.php
... ... @@ -227,6 +227,8 @@ class dependencies extends Step
227 227 if($class == 'orange') {
228 228 $this->temp_variables['php_con'] = 'cross_orange';
229 229 }
  230 + if($setting < 0)
  231 + $setting = "unset";
230 232 $limits[$key]['setting'] = $this->prettySize($setting);
231 233 $limits[$key]['class'] = $class;
232 234 }
... ...
setup/wizard/steps/services.php
... ... @@ -220,7 +220,6 @@ class services extends Step
220 220 $srv->load();
221 221 $status = $this->serviceInstalled($srv);
222 222 if($status != 'STARTED') {
223   -// if(!$this->$class->installed) {
224 223 if(!WINDOWS_OS) { $binary = $this->$class->getBinary(); } // Get binary, if it exists
225 224 $passed = $this->$class->binaryChecks(); // Run Binary Pre Checks
226 225 if ($passed) { // Install Service
... ... @@ -576,7 +575,10 @@ class services extends Step
576 575 require_once("../lib/validation/$serv"."Validation.php");
577 576 require_once("../lib/services/$className.php");
578 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 582 $service->install();
581 583 echo "Install Service {$service->getName()}<br/>";
582 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 60 $repositoryId = $repositories[0]['repositoryId'];
61 61  
62 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 67 if (urldecode($this->params[0]) == 'Root Folder')
67 68 {
68 69 $folderId = CMISUtil::encodeObjectId('Folder', 1);
... ... @@ -87,6 +88,27 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service {
87 88  
88 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 112 else {
91 113 $folderId = $this->params[0];
92 114 }
... ... @@ -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 361 * AtomPub Service: document
540 362 */
541 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 375 $repositories = $RepositoryService->getRepositories();
554 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 399 // determine whether we want the document entry feed or the actual physical document content.
557 400 // this depends on $this->params[1]
558   - if (!empty($this->params[1]))
  401 + else if (!empty($this->params[1]))
559 402 {
560 403 KT_cmis_atom_service_helper::downloadContentStream($this, $ObjectService, $repositoryId);
561 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 409 // Expose the responseFeed
567 410 $this->responseFeed = $feed;
... ... @@ -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 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 97 // links
98 98 $link = $response->newElement('link');
99 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 102 $entry->appendChild($link);
102 103  
103 104 $link = $response->newElement('link');
... ...