Commit 39ac046469fd0103fdb20415950465e3a401fb0c

Authored by Jarrett Jordaan
2 parents 5b77af1a 3beb758d

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

config/dmsDefaults.php
... ... @@ -47,7 +47,7 @@ if (defined('DMS_DEFAULTS_INCLUDED'))
47 47 }
48 48  
49 49 define('DMS_DEFAULTS_INCLUDED',1);
50   -define('LATEST_WEBSERVICE_VERSION',3);
  50 +define('LATEST_WEBSERVICE_VERSION',2);
51 51  
52 52  
53 53 if (function_exists('apd_set_pprof_trace')) {
... ...
ktwebservice/webservice.php
... ... @@ -95,22 +95,22 @@ define('KTWS_ERR_DB_PROBLEM', 99);
95 95  
96 96 if (!defined('LATEST_WEBSERVICE_VERSION'))
97 97 {
98   - define('LATEST_WEBSERVICE_VERSION', 3);
  98 + define('LATEST_WEBSERVICE_VERSION', 2);
99 99 }
100 100  
101   - function bool2str($bool)
  101 +function bool2str($bool)
  102 +{
  103 + if (is_bool($bool))
102 104 {
103   - if (is_bool($bool))
104   - {
105   - return $bool?'true':'false';
106   - }
107   - if (is_numeric($bool))
108   - {
109   - return ($bool+0)?'true':'false';
110   - }
111   - // assume str
112   - return (strtolower($bool) == 'true')?'true':'false';
  105 + return $bool?'true':'false';
  106 + }
  107 + if (is_numeric($bool))
  108 + {
  109 + return ($bool+0)?'true':'false';
113 110 }
  111 + // assume str
  112 + return (strtolower($bool) == 'true')?'true':'false';
  113 +}
114 114  
115 115 class KTWebService
116 116 {
... ...
lib/api/ktcmis/ktObjectService.inc.php
... ... @@ -123,13 +123,13 @@ class KTObjectService extends KTCMISBase {
123 123 * @param $removeACEs List of ACEs that MUST be removed
124 124 * @return string $objectId The id of the created folder object
125 125 */
126   - public function createDocument($repositoryId, $properties, $folderId = null, $contentStream = null, $versioningState = null,
  126 + public function createDocument($repositoryId, $properties, $folderId = null, $contentStream = null, $versioningState = 'none',
127 127 $policies = array(), $addACEs = array(), $removeACEs = array())
128 128 {
129 129 $objectId = null;
130 130  
131 131 try {
132   - $objectId = $this->ObjectService->createDocument($repositoryId, $typeId, $properties, $folderId, $contentStream,
  132 + $objectId = $this->ObjectService->createDocument($repositoryId, $properties, $folderId, $contentStream,
133 133 $versioningState,$policies, $addACEs, $removeACEs);
134 134 }
135 135 catch (Exception $e)
... ...
lib/api/ktcmis/services/CMISObjectService.inc.php
... ... @@ -50,8 +50,12 @@ class CMISObjectService {
50 50 // TODO throw ConstraintViolationException if At least one of the permissions is used in
51 51 // an ACE provided which is not supported by the repository.
52 52 // NOTE typeId is supplied in the cmis:objectTypeId property in the properties array
  53 + // TODO support submission of content stream as an array containing mimetype and stream;
  54 + // for now we just filter on the other side so that only the stream comes through
  55 + // and continue to check the mime type dynamically (may need that anyway if none specified
  56 + // by CMIS client)
53 57 public function createDocument($repositoryId, $properties, $folderId = null, $contentStream = null,
54   - $versioningState = null, $policies = array(), $addACEs = array(),
  58 + $versioningState = 'none', $policies = array(), $addACEs = array(),
55 59 $removeACEs = array())
56 60 {
57 61 $objectId = null;
... ... @@ -164,7 +168,7 @@ class CMISObjectService {
164 168 if (!$typeDefinition['attributes']['contentStreamAllowed']) {
165 169 throw new StreamNotSupportedException('Content streams are not supported by this object-type');
166 170 }
167   -
  171 +
168 172 $tempfilename = CMISUtil::createTemporaryFile($contentStream);
169 173  
170 174 // metadata
... ...
lib/api/ktcmis/services/CMISRepositoryService.inc.php
... ... @@ -160,6 +160,7 @@ class CMISRepositoryService {
160 160 // NOTE this code may fit better in the Repository Class
161 161 function getTypeDefinition($repositoryId, $typeId)
162 162 {
  163 + $typeId = ucwords(str_replace('cmis:', '', $typeId));
163 164 $object = 'CMIS' . $typeId . 'Object';
164 165  
165 166 // check whether the object type exists, return error if not
... ... @@ -173,7 +174,7 @@ class CMISRepositoryService {
173 174  
174 175 require_once(CMIS_DIR . '/objecttypes/' . $object . '.inc.php');
175 176 $cmisObject = new $object;
176   - //$typeDefinition['attributes'] = $cmisObject->getAttributes();
  177 + $typeDefinition['attributes'] = $cmisObject->getAttributes();
177 178 $typeDefinition['properties'] = $cmisObject->getProperties();
178 179  
179 180 return $typeDefinition;
... ...
lib/workflow/workflowutil.inc.php
... ... @@ -5,32 +5,32 @@
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7 7 * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8   - *
9   - *
  8 + *
  9 + *
10 10 * This program is free software; you can redistribute it and/or modify it under
11 11 * the terms of the GNU General Public License version 3 as published by the
12 12 * Free Software Foundation.
13   - *
  13 + *
14 14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 16 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 17 * details.
18   - *
  18 + *
19 19 * You should have received a copy of the GNU General Public License
20 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21   - *
22   - * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
  21 + *
  22 + * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
23 23 * California 94120-7775, or email info@knowledgetree.com.
24   - *
  24 + *
25 25 * The interactive user interfaces in modified source and object code versions
26 26 * of this program must display Appropriate Legal Notices, as required under
27 27 * Section 5 of the GNU General Public License version 3.
28   - *
  28 + *
29 29 * In accordance with Section 7(b) of the GNU General Public License version 3,
30 30 * these Appropriate Legal Notices must retain the display of the "Powered by
31   - * KnowledgeTree" logo and retain the original copyright notice. If the display of the
  31 + * KnowledgeTree" logo and retain the original copyright notice. If the display of the
32 32 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33   - * must display the words "Powered by KnowledgeTree" and retain the original
  33 + * must display the words "Powered by KnowledgeTree" and retain the original
34 34 * copyright notice.
35 35 * Contributor( s): ______________________________________
36 36 *
... ... @@ -595,7 +595,7 @@ class KTWorkflowUtil {
595 595 $sTransactionComments = sprintf(_kt("Workflow state changed from %s to %s"), $sSourceState, $sTargetState);
596 596  
597 597 if ($sComments) {
598   - $sTransactionComments .= _kt("; Reason given was: ") . $sComments;
  598 + $sTransactionComments .= _kt("; Reason given was:") .' '. $sComments;
599 599 }
600 600 $oDocumentTransaction = new DocumentTransaction($oDocument, $sTransactionComments, 'ktcore.transactions.workflow_state_transition');
601 601 $oDocumentTransaction->create();
... ...
webservice/atompub/cmis/KT_cmis_atom_server.services.inc.php
... ... @@ -131,7 +131,7 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service {
131 131 * This includes creation/moving of both folders and documents.
132 132 */
133 133 public function POST_action()
134   - {
  134 + {
135 135 $repositoryId = KT_cmis_atom_service_helper::getRepositoryId($RepositoryService);
136 136  
137 137 // set default action, objectId and typeId
... ... @@ -140,8 +140,8 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service {
140 140 $typeId = null;
141 141  
142 142 $folderId = $this->params[0];
143   - $title = KT_cmis_atom_service_helper::getAtomValues($this->parsedXMLContent['@children'], 'title');
144   - $summary = KT_cmis_atom_service_helper::getAtomValues($this->parsedXMLContent['@children'], 'summary');
  143 + $title = KT_cmis_atom_service_helper::getAtomValues($this->rawContent, 'title');
  144 + $summary = KT_cmis_atom_service_helper::getAtomValues($this->rawContent, 'summary');
145 145  
146 146 // determine whether this is a folder or a document action
147 147 // document action create will have a content tag <atom:content> or <content> containing base64 encoding of the document
... ... @@ -157,14 +157,14 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service {
157 157 $objectId = $this->params[2];
158 158 }
159 159  
160   - $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->parsedXMLContent['@children']);
161   - $properties = array('name' => $title, 'summary' => $summary, 'typeId' => $cmisObjectProperties['objectTypeId']);
  160 + $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->rawContent);
  161 + $properties = array('name' => $title, 'summary' => $summary, 'objectTypeId' => $cmisObjectProperties['cmis:objectTypeId']);
162 162  
163 163 // check for existing object id as property of submitted object data
164   - if (!empty($cmisObjectProperties['objectId']))
  164 + if (!empty($cmisObjectProperties['cmis:objectId']))
165 165 {
166 166 $action = 'move';
167   - $objectId = $cmisObjectProperties['objectId'];
  167 + $objectId = $cmisObjectProperties['cmis:objectId'];
168 168 }
169 169  
170 170 // TODO there may be more to do for the checking of an existing object.
... ... @@ -174,53 +174,61 @@ class KT_cmis_atom_service_folder extends KT_cmis_atom_service {
174 174  
175 175 // determine type if object is being moved
176 176 if (!is_null($objectId)) {
177   - CMISUtil::decodeObjectId($objectId, $cmisObjectProperties['objectTypeId']);
  177 + CMISUtil::decodeObjectId($objectId, $cmisObjectProperties['cmis:objectTypeId']);
178 178 }
179 179  
180 180 // check for content stream
181   - $content = KT_cmis_atom_service_helper::getAtomValues($this->parsedXMLContent['@children'], 'content');
182   -
183   - global $default;
184   -// $default->log->info('cmis object type id: ' . $cmisObjectProperties['objectTypeId']);
185   -// $default->log->info(print_r($cmisObjectProperties, true));
186   -// $default->log->info(print_r($this->parsedXMLContent['@children'], true));
187   - $default->log->info(print_r($this->rawContent, true));
188   -
189   - // TODO this will need to change somewhat once other object-types come into play.
190   - if ((($action == 'create') && (is_null($content))) || ($cmisObjectProperties['objectTypeId'] == 'cmis:folder')) {
191   - $type = 'folder';
192   - }
193   - else {
194   - $type = 'document';
195   - }
  181 + $content = KT_cmis_atom_service_helper::getCmisContent($this->rawContent);
  182 + // NOTE not sure about the text type, will need testing, most content will be base64
  183 + $cmisContent = (isset($content['cmisra:base64'])
  184 + ? $content['cmisra:base64']
  185 + : ((isset($content['cmisra:text']))
  186 + ? $content['cmisra:text']
  187 + : null));
196 188  
197 189 $ObjectService = new ObjectService(KT_cmis_atom_service_helper::getKt());
198   -
  190 +
  191 + global $default;
199 192 $success = false;
200 193 $error = null;
201 194 if ($action == 'create')
202 195 {
203   - // TODO detection and passing of optional parameters (policies, ACEs, etc...)
204   - if ($type == 'folder')
205   - $newObjectId = $ObjectService->createFolder($repositoryId, ucwords($cmisObjectProperties['objectTypeId']), $properties, $folderId);
  196 + // TODO detection and passing of optional parameters (policies, ACEs, etc...) as well as support for other object-types
  197 + if ($cmisObjectProperties['cmis:objectTypeId'] == 'folder')
  198 + $newObjectId = $ObjectService->createFolder($repositoryId, ucwords($cmisObjectProperties['cmis:objectTypeId']), $properties, $folderId);
206 199 else
207   - $newObjectId = $ObjectService->createDocument($repositoryId, ucwords($cmisObjectProperties['objectTypeId']), $properties, $folderId, $content);
208   -
209   - // check if returned Object Id is a valid CMIS Object Id
210   - CMISUtil::decodeObjectId($newObjectId, $cmisObjectProperties['objectTypeId']);
211   - if ($typeId != 'Unknown') $success = true;
212   - else $error = $newObjectId['message'];
  200 + // NOTE for the moment only creation in minor versioning state
  201 + $newObjectId = $ObjectService->createDocument($repositoryId, $properties, $folderId, $cmisContent, 'minor');
  202 +
  203 + if (!PEAR::isError($newObjectId)) {
  204 + // check if returned Object Id is a valid CMIS Object Id
  205 + CMISUtil::decodeObjectId($newObjectId, $cmisObjectProperties['cmis:objectTypeId']);
  206 + if ($typeId != 'Unknown') {
  207 + $success = true;
  208 + }
  209 + else {
  210 + $error = 'Unknown Object Type';
  211 + }
  212 + }
  213 + else {
  214 + $error = $newObjectId->getMessage();
  215 + }
213 216 }
214 217 else if ($action == 'move')
215 218 {
216 219 $response = $ObjectService->moveObject($repositoryId, $objectId, '', $folderId);
217 220  
218   - if (!PEAR::isError($response)) $success = true;
219   - else $error = $response->getMessage();
  221 + if (!PEAR::isError($response)) {
  222 + $success = true;
  223 + }
  224 + else {
  225 + $error = $response->getMessage();
  226 + }
220 227  
221 228 // same object as before
222 229 $newObjectId = $objectId;
223   - $typeId = ucwords($type);
  230 + // FIXME why set this? it does not appear to get used
  231 + $typeId = ucwords($cmisObjectProperties['cmis:objectTypeId']);
224 232 }
225 233  
226 234 if ($success)
... ... @@ -510,7 +518,7 @@ class KT_cmis_atom_service_pwc extends KT_cmis_atom_service {
510 518 // NOTE this is a hack! will not work with CMISSpaces at least, probably not with any client except RestTest and similar
511 519 // where we can manually modify the input
512 520 // first we try for an atom content tag
513   - $content = KT_cmis_atom_service_helper::getAtomValues($this->parsedXMLContent['@children'], 'content');
  521 + $content = KT_cmis_atom_service_helper::getAtomValues($this->rawContent, 'content');
514 522 if (!empty($content)) {
515 523 $contentStream = $content;
516 524 }
... ... @@ -625,10 +633,10 @@ class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service {
625 633 $VersioningService = new VersioningService(KT_cmis_atom_service_helper::getKt());
626 634 $ObjectService = new ObjectService(KT_cmis_atom_service_helper::getKt());
627 635  
628   - $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->parsedXMLContent['@children']);
  636 + $cmisObjectProperties = KT_cmis_atom_service_helper::getCmisProperties($this->rawContent);
629 637  
630 638 // check for existing object id as property of submitted object data
631   - if (empty($cmisObjectProperties['objectId']))
  639 + if (empty($cmisObjectProperties['cmis:objectId']))
632 640 {
633 641 $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, 'No object was specified for checkout');
634 642 // Expose the responseFeed
... ... @@ -636,7 +644,7 @@ class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service {
636 644 return null;
637 645 }
638 646  
639   - $response = $VersioningService->checkOut($repositoryId, $cmisObjectProperties['objectId']);
  647 + $response = $VersioningService->checkOut($repositoryId, $cmisObjectProperties['cmis:objectId']);
640 648  
641 649 if (PEAR::isError($response))
642 650 {
... ... @@ -647,7 +655,7 @@ class KT_cmis_atom_service_checkedout extends KT_cmis_atom_service {
647 655 }
648 656  
649 657 $this->setStatus(self::STATUS_CREATED);
650   - $feed = KT_cmis_atom_service_helper::getObjectFeed($this, $ObjectService, $repositoryId, $cmisObjectProperties['objectId'], 'POST');
  658 + $feed = KT_cmis_atom_service_helper::getObjectFeed($this, $ObjectService, $repositoryId, $cmisObjectProperties['cmis:objectId'], 'POST');
651 659  
652 660 // Expose the responseFeed
653 661 $this->responseFeed = $feed;
... ...
webservice/atompub/cmis/KT_cmis_atom_service_helper.inc.php
... ... @@ -466,8 +466,97 @@ class KT_cmis_atom_service_helper {
466 466  
467 467 return CMISUtil::encodeObjectId(FOLDER, $folderId);
468 468 }
  469 +
  470 + static public function getCmisProperties(&$xml)
  471 + {
  472 + $xmlReader = new XMLReader();
  473 + $xmlReader->XML($xml);
  474 + $object = false;
  475 + $objectProperties = false;
  476 + $cmisObjectProperty = null;
  477 + $cmisObjectPropertiesCollection = array();
  478 + while ($xmlReader->read()) {
  479 + // get cmis object properties
  480 + if ($xmlReader->name == 'cmisra:object') {
  481 + $object = ($xmlReader->nodeType == XMLReader::ELEMENT);
  482 + // exit if we have finished reading the cmis object node
  483 + if (!$object) {
  484 + break;
  485 + }
  486 + }
  487 + else if ($object && ($xmlReader->name == 'cmis:properties')) {
  488 + $objectProperties = ($xmlReader->nodeType == XMLReader::ELEMENT);
  489 + }
  490 + else if ($objectProperties && ($xmlReader->nodeType == XMLReader::ELEMENT)) {
  491 + if (strstr($xmlReader->name, 'cmis:property') && $xmlReader->nodeType == XMLReader::ELEMENT) {
  492 + $cmisObjectProperty = $xmlReader->getAttribute('propertyDefinitionId');
  493 + }
  494 + else if ($xmlReader->name == 'cmis:value' && $xmlReader->nodeType == XMLReader::ELEMENT) {
  495 + // push to next read, which will be the text contained within the node
  496 + $xmlReader->read();
  497 + $cmisObjectPropertiesCollection[$cmisObjectProperty] = $xmlReader->value;
  498 + // reset for next value - may leave this out of final code
  499 + $cmisObjectProperty = null;
  500 + }
  501 + }
  502 + }
  503 +
  504 + return $cmisObjectPropertiesCollection;
  505 + }
  506 +
  507 + static public function getCmisContent(&$xml)
  508 + {
  509 + $xmlReader = new XMLReader();
  510 + $xmlReader->XML($xml);
  511 + $content = false;
  512 + $cmisContentProperty = null;
  513 + $cmisObjectContent = array();
  514 + while ($xmlReader->read()) {
  515 + if ($xmlReader->name == 'cmisra:content') {
  516 + $content = ($xmlReader->nodeType == XMLReader::ELEMENT);
  517 + // exit if we have finished reading the cmis content node
  518 + if (!$content) {
  519 + break;
  520 + }
  521 + }
  522 + else if ($content && ($xmlReader->nodeType == XMLReader::ELEMENT)) {
  523 + $cmisContentProperty = $xmlReader->name;
  524 + // push to next read, which will be the text contained within the node
  525 + $xmlReader->read();
  526 + $cmisObjectContent[$cmisContentProperty] = $xmlReader->value;
  527 + }
  528 + }
  529 +
  530 + return $cmisObjectContent;
  531 + }
  532 +
  533 + static public function getAtomValues(&$xml, $tag)
  534 + {
  535 + $returnTag = null;
  536 +
  537 + $xmlReader = new XMLReader();
  538 + $xmlReader->XML($xml);
  539 + $foundTag = false;
  540 + while ($xmlReader->read()) {
  541 + // using strstr because we may or may not have the tag preceded by "atom:"
  542 + // TODO ensure that this does not return incorrect matches
  543 + if (strstr($xmlReader->name, $tag)) {
  544 + $foundTag = ($xmlReader->nodeType == XMLReader::ELEMENT);
  545 + // exit if we have finished reading the cmis content node
  546 + if ($foundTag) {
  547 + $xmlReader->read();
  548 + $returnTag = $xmlReader->value;
  549 + }
  550 + else {
  551 + break;
  552 + }
  553 + }
  554 + }
  555 +
  556 + return $returnTag;
  557 + }
469 558  
470   - static public function getCmisProperties($xmlArray)
  559 + static public function getCmisPropertiesOld($xmlArray)
471 560 {
472 561 $properties = array();
473 562  
... ... @@ -500,7 +589,7 @@ class KT_cmis_atom_service_helper {
500 589 return $properties;
501 590 }
502 591  
503   - static public function getAtomValues($xmlArray, $tag)
  592 + static public function getAtomValuesOld($xmlArray, $tag)
504 593 {
505 594 if (!is_null($xmlArray['atom:'.$tag]))
506 595 return $xmlArray['atom:'.$tag][0]['@value'];
... ...
webservice/classes/atompub/KT_atom_service.inc.php
... ... @@ -68,12 +68,14 @@ class KT_atom_service{
68 68 public $parsedXMLContent='';
69 69 public $headers=array();
70 70  
71   - public function __construct($method,$params,$content){
  71 + public function __construct($method,$params,$content,$parse = true){
72 72 $this->method=$method;
73 73 $this->params=$params;
74 74 $this->rawContent=$content;
75 75 $this->parseHeaders();
76   - $this->parsedXMLContent=$this->xml2array($this->rawContent);
  76 + if ($parse) {
  77 + $this->parsedXMLContent=$this->xml2array($this->rawContent);
  78 + }
77 79 $this->setStatus(self::STATUS_OK);
78 80 $this->responseFeed=new KT_atom_responseFeed(KT_APP_BASE_URI);
79 81 switch(strtoupper($this->method)){
... ...
webservice/classes/atompub/cmis/KT_cmis_atom_service.inc.php
... ... @@ -9,6 +9,15 @@ class KT_cmis_atom_service extends KT_atom_service {
9 9 protected $serviceType = null;
10 10 protected $contentDownload = false;
11 11  
  12 + public function __construct($method, $params, $content)
  13 + {
  14 + // We are not going to use the parsed xml content, but rather the raw content;
  15 + // This is due to changes in the CMIS spec more than once requiring a change in
  16 + // the functions which fetch information from the parsed content; using XMLReader
  17 + // now which should be able to handle changes easier
  18 + parent::__construct($method, $params, $content, false);
  19 + }
  20 +
12 21 public function setContentDownload($contentDownload)
13 22 {
14 23 $this->contentDownload = $contentDownload;
... ...
webservice/classes/atompub/cmis/ObjectService.inc.php
... ... @@ -48,21 +48,18 @@ class ObjectService extends KTObjectService {
48 48 * @param $removeACEs List of ACEs that MUST be removed
49 49 * @return string $objectId The id of the created folder object
50 50 */
51   - // TODO throw ConstraintViolationException if:
52   - // value of any of the properties violates the min/max/required/length constraints
53   - // specified in the property definition in the Object-Type.
54 51 public function createDocument($repositoryId, $properties, $folderId = null, $contentStream = null,
55   - $versioningState = null, $policies = array(), $addACEs = array(),
  52 + $versioningState = 'none', $policies = array(), $addACEs = array(),
56 53 $removeACEs = array())
57 54 {
58 55 $result = parent::createDocument($repositoryId, $properties, $folderId, $contentStream, $versioningState,
59 56 $policies, $addACEs, $removeACEs);
60   -
  57 +
61 58 if ($result['status_code'] == 0) {
62 59 return $result['results'];
63 60 }
64 61 else {
65   - return $result;
  62 + return new PEAR_Error($result['message']);
66 63 }
67 64 }
68 65  
... ... @@ -83,7 +80,7 @@ class ObjectService extends KTObjectService {
83 80 return $result['results'];
84 81 }
85 82 else {
86   - return $result;
  83 + return new PEAR_Error($result['message']);
87 84 }
88 85 }
89 86  
... ... @@ -102,7 +99,7 @@ class ObjectService extends KTObjectService {
102 99 return $result['results'];
103 100 }
104 101 else {
105   - return new PEAR_Error($result['message']);
  102 + return new PEAR_Error($result['message']);
106 103 }
107 104 }
108 105  
... ...
webservice/clienttools/services/0.9/kt.php
... ... @@ -94,6 +94,31 @@ class kt extends client_service {
94 94 $this->setResponse ( $result );
95 95 return true;
96 96 }
  97 +
  98 + function get_checkedout_documents_list($params) {
  99 + $this->logTrace ((__METHOD__.'('.__FILE__.' '.__LINE__.')'), 'Enter Function' );
  100 + $kt = &$this->KT;
  101 +
  102 +
  103 + $params ['control'] = 'F_';
  104 + $params ['node'] = substr ( $params ['node'], strlen ( $params ['control'] ) );
  105 +
  106 + $folder = &$kt->get_folder_by_id ( $params ['node'] );
  107 + if (! $this->checkPearError ( $folder, "[error 1] Folder Not Found: {$params['control']}{$params['node']}", '', array () ))
  108 + return false;
  109 +
  110 + $types = (isset ( $params ['types'] ) ? $params ['types'] : 'D');
  111 + $listing = $folder->get_listing ( 1, $types );
  112 + foreach ( $listing as $item ) {
  113 + if ($item['checked_out_by'] == $params['user'])
  114 + {
  115 + $result[] = array ('text' => htmlspecialchars ( $item ['title'] ), 'id' => $item ['id'], 'filename' => $item ['filename']);
  116 + }
  117 + }
  118 +
  119 + $this->setResponse ( $result );
  120 + return true;
  121 + }
97 122  
98 123 function get_folder_contents($params) {
99 124 $this->logTrace ((__METHOD__.'('.__FILE__.' '.__LINE__.')'), 'Enter Function' );
... ...