Commit 0dc18e599cec87a33967248806a8d3d681fce4b8

Authored by Megan Watson
2 parents 379c1a11 ae916961

Merge branch 'edge'

Conflicts:
	ktapi/KTAPIDocument.inc.php
	ktapi/KTAPIFolder.inc.php
Showing 957 changed files with 44033 additions and 15937 deletions

Too many changes.

To preserve performance only 100 of 957 files are displayed.

.gitattributes 0 โ†’ 100644
  1 +.cvsignore export-ignore
  2 +docs/phpdoc/.empty export-ignore
  3 +thirdparty/simpletest/simpletest/docs/fr/server_stubs_documentation.html export-ignore
  4 +thirdparty/simpletest/simpletest/test/support/collector/collectable.2 export-ignore
  5 +thirdparty/simpletest/simpletest/test/support/collector/collectable.1 export-ignore
  6 +templates/ktcore/forms/widgets/info.smarty export-ignore
  7 +tests/util/ktutil/dataset1/a export-ignore
  8 +tests/util/ktutil/dataset1/f export-ignore
  9 +tests/util/ktutil/dataset1/y export-ignore
  10 +tests/util/ktutil/dataset1/b/q export-ignore
  11 +tests/util/ktutil/dataset1/b/t export-ignore
  12 +tests/util/ktutil/dataset1/b/w export-ignore
... ...
about.php
... ... @@ -5,7 +5,7 @@
5 5 *
6 6 * KnowledgeTree Community Edition
7 7 * Document Management Made Simple
8   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  8 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
9 9 *
10 10 *
11 11 * This program is free software; you can redistribute it and/or modify it under
... ...
action.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ...
admin.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ...
bin/.htaccess
1   -Order deny,allow
2   -Allow from all
3   -
4   -IndexIgnore *.*
  1 +Order allow,deny
  2 +Allow from 127.0.0.1, localhost
... ...
bin/automated_upgrade.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ...
bin/checkopenoffice.php
... ... @@ -6,7 +6,7 @@
6 6 *
7 7 * KnowledgeTree Community Edition
8 8 * Document Management Made Simple
9   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  9 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
10 10 *
11 11 *
12 12 * This program is free software; you can redistribute it and/or modify it under
... ...
bin/cleanup.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ...
bin/expungeall.php
... ... @@ -6,7 +6,7 @@
6 6 *
7 7 * KnowledgeTree Community Edition
8 8 * Document Management Made Simple
9   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  9 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
10 10 *
11 11 *
12 12 * This program is free software; you can redistribute it and/or modify it under
... ...
bin/md5_validation.php
... ... @@ -6,7 +6,7 @@
6 6 *
7 7 * KnowledgeTree Community Edition
8 8 * Document Management Made Simple
9   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  9 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
10 10 *
11 11 *
12 12 * This program is free software; you can redistribute it and/or modify it under
... ...
bin/recreateIndexes.php
... ... @@ -5,7 +5,7 @@
5 5 *
6 6 * KnowledgeTree Community Edition
7 7 * Document Management Made Simple
8   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  8 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
9 9 *
10 10 *
11 11 * This program is free software; you can redistribute it and/or modify it under
... ...
bin/scheduler.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ...
bin/storageverification.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ...
bin/system_info.php
... ... @@ -6,7 +6,7 @@
6 6 *
7 7 * KnowledgeTree Community Edition
8 8 * Document Management Made Simple
9   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  9 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
10 10 *
11 11 *
12 12 * This program is free software; you can redistribute it and/or modify it under
... ...
bin/upgrade/pear-upgrade.bat deleted
1   -
2   -; TEST ALL PEAR LIBRARIES BEFORE UPGRADING INTO RELEASE
3   -
4   -PATH=%PATH%;c:\php5\PEAR
5   -
6   -pear channel-update pear.php.net
7   -pear config-set php_dir "C:\kt\kt.trunk\thirdparty\pear"
8   -
9   -pear config-set preferred_state stable
10   -
11   -pear upgrade --alldeps PEAR
12   -pear upgrade --alldeps Cache_Lite
13   -pear upgrade --alldeps Config
14   -pear upgrade --alldeps DB
15   -pear upgrade --alldeps File
16   -
17   -;pear upgrade --alldeps MDB2#mysql
18   -
19   -pear upgrade --alldeps Log
20   -pear upgrade --alldeps PHP_Compat
21   -
22   -pear config-set preferred_state beta
23   -pear upgrade --alldeps File_Gettext
24   -pear upgrade --alldeps Net_LDAP
25   -pear upgrade --alldeps SOAP
26   -pear config-set preferred_state stable
27   -
bin/upgrade/pre-upgrade-3.0b3.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ...
bin/upgrade/upgrade-to-2.0.6.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ...
bin/win32/installScheduler.php
... ... @@ -5,7 +5,7 @@
5 5 *
6 6 * KnowledgeTree Community Edition
7 7 * Document Management Made Simple
8   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  8 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
9 9 *
10 10 *
11 11 * This program is free software; you can redistribute it and/or modify it under
... ...
bin/win32/schedulerService.php
... ... @@ -5,7 +5,7 @@
5 5 *
6 6 * KnowledgeTree Community Edition
7 7 * Document Management Made Simple
8   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  8 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
9 9 *
10 10 *
11 11 * This program is free software; you can redistribute it and/or modify it under
... ...
bin/win32/schedulerServiceStatus.php
... ... @@ -5,7 +5,7 @@
5 5 *
6 6 * KnowledgeTree Community Edition
7 7 * Document Management Made Simple
8   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  8 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
9 9 *
10 10 *
11 11 * This program is free software; you can redistribute it and/or modify it under
... ...
bin/win32/uninstallScheduler.php
... ... @@ -5,7 +5,7 @@
5 5 *
6 6 * KnowledgeTree Community Edition
7 7 * Document Management Made Simple
8   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  8 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
9 9 *
10 10 *
11 11 * This program is free software; you can redistribute it and/or modify it under
... ...
browse.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ...
call_home.php deleted
1   -<?php
2   -/*
3   -* Data incoming format: <installation guid>|<user count>|<document count>|<KT version>|<KT edition>|<OS info>
4   -*/
5   -
6   -$data = isset($_REQUEST['system_info']) ? strip_tags($_REQUEST['system_info']) : '';
7   -
8   -if(empty($data)){
9   - exit(0);
10   -}
11   -
12   -$file = 'var/system_info.txt';
13   -$fp = fopen($file, 'a');
14   -fwrite($fp, $data."\n");
15   -fclose($fp);
16   -
17   -exit(0);
18   -?>
19 0 \ No newline at end of file
config/dmsDefaults.php
... ... @@ -6,7 +6,7 @@
6 6 *
7 7 * KnowledgeTree Community Edition
8 8 * Document Management Made Simple
9   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  9 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
10 10 *
11 11 *
12 12 * This program is free software; you can redistribute it and/or modify it under
... ...
config/siteMap.inc
... ... @@ -6,7 +6,7 @@
6 6 *
7 7 * KnowledgeTree Community Edition
8 8 * Document Management Made Simple
9   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  9 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
10 10 *
11 11 *
12 12 * This program is free software; you can redistribute it and/or modify it under
... ...
config/tableMappings.inc
... ... @@ -6,7 +6,7 @@
6 6 *
7 7 * KnowledgeTree Community Edition
8 8 * Document Management Made Simple
9   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  9 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
10 10 *
11 11 *
12 12 * This program is free software; you can redistribute it and/or modify it under
... ...
control.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -44,7 +44,6 @@ if(!$iu-&gt;isSystemInstalled()) {
44 44 $iu->redirect("setup/wizard");
45 45 exit(0);
46 46 }
47   -
48 47 // main library routines and defaults
49 48 require_once('config/dmsDefaults.php');
50 49  
... ...
customerrorpage.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ...
dashboard.php
... ... @@ -8,7 +8,7 @@
8 8 *
9 9 * KnowledgeTree Community Edition
10 10 * Document Management Made Simple
11   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  11 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
12 12 *
13 13 *
14 14 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -135,9 +135,25 @@ class DashboardDispatcher extends KTStandardDispatcher {
135 135 'dashlets_left' => $aDashletsLeft,
136 136 'dashlets_right' => $aDashletsRight,
137 137 );
  138 +
  139 + // TODO : Is this ok?
  140 + if(file_exists(KT_DIR.DIRECTORY_SEPARATOR.'var'.DIRECTORY_SEPARATOR.'bin'.DIRECTORY_SEPARATOR."firstlogin.lock")) {
  141 + $this->runFirstLoginWizard($oTemplate, $aTemplateData);
  142 + }
  143 +
138 144 return $oTemplate->render($aTemplateData);
139 145 }
140 146  
  147 + //
  148 + function runFirstLoginWizard($oTemplate, $aTemplateData) {
  149 + $this->oPage->requireCSSResource('setup/wizard/resources/css/modal.css');
  150 + $this->oPage->requireJSResource('setup/wizard/resources/js/jquery-1.4.2.min.js');
  151 + //$this->oPage->requireJSResource('thirdpartyjs/jquery/jquery-1.3.2.min.js');
  152 + $this->oPage->requireJSResource('thirdpartyjs/jquery/jquery_noconflict.js');
  153 + $this->oPage->requireJSResource('setup/wizard/resources/js/firstlogin.js');
  154 +
  155 + }
  156 +
141 157 // return some kind of ID for each dashlet
142 158 // currently uses the class name
143 159 function _getDashletId($oDashlet) {
... ...
docs/COPYING
1 1 KnowledgeTree Community Edition
2 2 Document Management Made Simple
3   -Copyright (C) 2008, 2009 KnowledgeTree Inc.
  3 +Copyright (C) 2008-2010 KnowledgeTree Inc.
4 4  
5 5 This program is free software; you can redistribute it and/or modify it under
6 6 the terms of the GNU General Public License version 3 as published by the
... ...
docs/VERSION-NAME.txt
1   -3.7.0.3
2 1 \ No newline at end of file
  2 +3.7.0.4
3 3 \ No newline at end of file
... ...
docs/VERSION-OSS-DEV.txt
1   -3.7.0.3
2 1 \ No newline at end of file
  2 +3.7.0.4
3 3 \ No newline at end of file
... ...
docs/VERSION-OSS.txt
1   -3.7.0.3
2 1 \ No newline at end of file
  2 +3.7.0.4
3 3 \ No newline at end of file
... ...
docs/VERSION.txt
1   -3.7.0.3
2 1 \ No newline at end of file
  2 +3.7.0.4
3 3 \ No newline at end of file
... ...
download_notification.php
1 1 <?php
2 2 /*
3   - * Electronic Signatures ajax functionality
4 3 *
5   - * The contents of this file are subject to the KnowledgeTree
6   - * Commercial Editions On-Premise License ("License");
7   - * You may not use this file except in compliance with the License.
8   - * You may obtain a copy of the License at
9   - * http://www.knowledgetree.com/about/legal/
10   - * The terms of this license may change from time to time and the latest
11   - * license will be published from time to time at the above Internet address.
  4 + * KnowledgeTree Community Edition
  5 + * Document Management Made Simple
  6 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
12 7 *
13   - * This edition of the KnowledgeTree software
14   - * is NOT licensed to you under Open Source terms.
15   - * You may not redistribute this source code.
16   - * For more information please see the License above.
17 8 *
18   - * (c) 2008, 2009 KnowledgeTree Inc.
19   - * All Rights Reserved.
  9 + * This program is free software; you can redistribute it and/or modify it under
  10 + * the terms of the GNU General Public License version 3 as published by the
  11 + * Free Software Foundation.
20 12 *
21   - * @copyright 2008-2009, KnowledgeTree Inc.
  13 + * This program is distributed in the hope that it will be useful, but WITHOUT
  14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  15 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  16 + * details.
  17 + *
  18 + * You should have received a copy of the GNU General Public License
  19 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20 + *
  21 + * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
  22 + * California 94120-7775, or email info@knowledgetree.com.
  23 + *
  24 + * The interactive user interfaces in modified source and object code versions
  25 + * of this program must display Appropriate Legal Notices, as required under
  26 + * Section 5 of the GNU General Public License version 3.
  27 + *
  28 + * In accordance with Section 7(b) of the GNU General Public License version 3,
  29 + * these Appropriate Legal Notices must retain the display of the "Powered by
  30 + * KnowledgeTree" logo and retain the original copyright notice. If the display of the
  31 + * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
  32 + * must display the words "Powered by KnowledgeTree" and retain the original
  33 + * copyright notice.
  34 + * Contributor( s): ______________________________________
  35 + *
  36 + */
  37 +
  38 +/**
  39 + *
  40 + * @copyright 2008-2010, KnowledgeTree Inc.
22 41 * @license GNU General Public License version 3
23 42 * @author KnowledgeTree Team
24 43 * @package Electronic Signatures
... ...
examples/fieldsynchronisation/syncFieldFromLDAP.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ...
help.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ...
ktapi/KTAPIAcl.inc.php
1 1 <?php
2 2  
3 3 /**
4   - * Contains the basic Acl functionality for KTAPI.
  4 + *
  5 + * $Id$
5 6 *
6 7 * KnowledgeTree Community Edition
7 8 * Document Management Made Simple
8   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
9   - *
  9 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
  10 + *
10 11 *
11 12 * This program is free software; you can redistribute it and/or modify it under
12 13 * the terms of the GNU General Public License version 3 as published by the
... ... @@ -33,8 +34,13 @@
33 34 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
34 35 * must display the words "Powered by KnowledgeTree" and retain the original
35 36 * copyright notice.
  37 + * Contributor( s): ______________________________________
  38 + */
  39 +
  40 +/**
  41 + * Contains the basic Acl functionality for KTAPI.
36 42 *
37   - * @copyright 2008-2009, KnowledgeTree Inc.
  43 + * @copyright 2008-2010, KnowledgeTree Inc.
38 44 * @license GNU General Public License version 3
39 45 * @author KnowledgeTree Team
40 46 * @package KTAPI
... ... @@ -814,14 +820,10 @@ abstract class KTAPI_AllocationBase extends KTAPI_Dynamic
814 820  
815 821 break;
816 822 case 'KTAPI_Document':
817   - DocumentTransaction::createFromArray(array(
818   - 'folderid' => $objectId,
819   - 'comment' => $comment,
820   - 'transactionNS' => $namespace,
821   - 'userid' => $_SESSION['userID'],
822   - 'ip' => Session::getClientIP(),
823   - ));
  823 + $oDocumentTransaction = new DocumentTransaction($object, $comment, $namespace);
  824 + $res = $oDocumentTransaction->create();
824 825 break;
  826 +
825 827 default:
826 828 throw new Exception('Unexpected type: ' . $type);
827 829 }
... ...
ktapi/KTAPIBulkActions.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -32,8 +32,11 @@
32 32 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33 33 * must display the words "Powered by KnowledgeTree" and retain the original
34 34 * copyright notice.
35   - *
36   - * @copyright 2008-2009, KnowledgeTree Inc.
  35 + * Contributor( s): ______________________________________
  36 + */
  37 +
  38 +/**
  39 + * @copyright 2008-2010, KnowledgeTree Inc.
37 40 * @license GNU General Public License version 3
38 41 * @author KnowledgeTree Team
39 42 * @package KTAPI
... ...
ktapi/KTAPICollection.inc.php
... ... @@ -5,7 +5,7 @@
5 5 *
6 6 * KnowledgeTree Community Edition
7 7 * Document Management Made Simple
8   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  8 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
9 9 *
10 10 *
11 11 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -33,8 +33,11 @@
33 33 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
34 34 * must display the words "Powered by KnowledgeTree" and retain the original
35 35 * copyright notice.
36   - *
37   - * @copyright 2008-2009, KnowledgeTree Inc.
  36 + * Contributor( s): ______________________________________
  37 + */
  38 +
  39 +/**
  40 + * @copyright 2008-2010, KnowledgeTree Inc.
38 41 * @license GNU General Public License version 3
39 42 * @author KnowledgeTree Team
40 43 * @package KTAPI
... ...
ktapi/KTAPIConstants.inc.php
... ... @@ -4,36 +4,39 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
8   - *
9   - *
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
  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   - *
36   - * @copyright 2008-2009, KnowledgeTree Inc.
  35 + * Contributor( s): ______________________________________
  36 + */
  37 +
  38 +/**
  39 + * @copyright 2008-2010, KnowledgeTree Inc.
37 40 * @license GNU General Public License version 3
38 41 * @author KnowledgeTree Team
39 42 * @package KTAPI
... ... @@ -50,6 +53,7 @@ define(&#39;KTAPI_ERROR_SESSION_INVALID&#39;, &#39;The session could not be resolved.&#39;);
50 53 define('KTAPI_ERROR_PERMISSION_INVALID', 'The permission could not be resolved.');
51 54 define('KTAPI_ERROR_FOLDER_INVALID', 'The folder could not be resolved.');
52 55 define('KTAPI_ERROR_DOCUMENT_INVALID', 'The document could not be resolved.');
  56 +define('KTAPI_ERROR_VERSION_INVALID', 'The document version could not be resolved.');
53 57 define('KTAPI_ERROR_USER_INVALID', 'The user could not be resolved.');
54 58 define('KTAPI_ERROR_KTAPI_INVALID', 'The ktapi could not be resolved.');
55 59 define('KTAPI_ERROR_INSUFFICIENT_PERMISSIONS', 'The user does not have sufficient permissions to access the resource.');
... ...
ktapi/KTAPIDocument.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -32,8 +32,11 @@
32 32 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33 33 * must display the words "Powered by KnowledgeTree" and retain the original
34 34 * copyright notice.
35   - *
36   - * @copyright 2008-2009, KnowledgeTree Inc.
  35 + * Contributor( s): ______________________________________
  36 + */
  37 +
  38 +/**
  39 + * @copyright 2008-2010, KnowledgeTree Inc.
37 40 * @license GNU General Public License version 3
38 41 * @author KnowledgeTree Team
39 42 * @package KTAPI
... ... @@ -88,24 +91,30 @@ class KTAPI_Document extends KTAPI_FolderItem
88 91 }
89 92  
90 93 /**
91   - * This is used to get a document based on document id.
  94 + * This is used to get a document based on document id. Or a version of the document based on the metadata version id
92 95 *
93 96 * @author KnowledgeTree Team
94 97 * @static
95 98 * @access public
96 99 * @param KTAPI $ktapi The ktapi object
97 100 * @param int $documentid The document id
  101 + * @param int $iMetadataVersionId Optional. The metadata version id
98 102 * @return KTAPI_Document The document object
99 103 */
100   - function &get(&$ktapi, $documentid)
  104 + function &get(&$ktapi, $documentid, $iMetadataVersionId = null)
101 105 {
102   - assert(!is_null($ktapi));
103   - assert(is_a($ktapi, 'KTAPI'));
104   - assert(is_numeric($documentid));
  106 + if(is_null($ktapi) || !is_a($ktapi, 'KTAPI')){
  107 + return PEAR::raiseError('A valid KTAPI object is needed');
  108 + }
105 109  
  110 + if(!is_numeric($documentid)){
  111 + return PEAR::raiseError('A valid document id is required');
  112 + }
  113 +
  114 + // ensure documentid is an integer
106 115 $documentid += 0;
107 116  
108   - $document = &Document::get($documentid);
  117 + $document = &Document::get($documentid, $iMetadataVersionId);
109 118 if (is_null($document) || PEAR::isError($document))
110 119 {
111 120 return new KTAPI_Error(KTAPI_ERROR_DOCUMENT_INVALID,$document );
... ... @@ -134,6 +143,30 @@ class KTAPI_Document extends KTAPI_FolderItem
134 143 }
135 144  
136 145 /**
  146 + * This is used to get a document based on the document id and the metadata version
  147 + *
  148 + * @author KnowledgeTree Team
  149 + * @static
  150 + * @access public
  151 + * @param KTAPI $ktapi The ktapi object
  152 + * @param int $documentid The document id
  153 + * @param int $metadataVersion The metadata version (0,1,2)
  154 + * @return KTAPI_Document The document object
  155 + */
  156 + function &get_by_metadata_version(&$ktapi, $documentid, $metadataVersion)
  157 + {
  158 + // get the metadata version id
  159 + $iMetadataVersionId = Document::getMetadataVersionIdFromVersion($documentid, $metadataVersion);
  160 + if (is_null($iMetadataVersionId) || PEAR::isError($iMetadataVersionId))
  161 + {
  162 + return new KTAPI_Error(KTAPI_ERROR_VERSION_INVALID, $iMetadataVersionId );
  163 + }
  164 +
  165 + // get the KTAPI_Document object
  166 + return self::get($ktapi, $documentid, $iMetadataVersionId);
  167 + }
  168 +
  169 + /**
137 170 * Checks if a document has been deleted
138 171 *
139 172 * @author KnowledgeTree Team
... ... @@ -2108,6 +2141,18 @@ class KTAPI_Document extends KTAPI_FolderItem
2108 2141 }
2109 2142  
2110 2143 /**
  2144 + * Gets the content version id of the document
  2145 + *
  2146 + * @author KnowledgeTree Team
  2147 + * @access public
  2148 + * @return integer the content version id
  2149 + */
  2150 + function get_content_version()
  2151 + {
  2152 + return $this->document->getContentVersionId();
  2153 + }
  2154 +
  2155 + /**
2111 2156 * Gets the url which can be used to download the document.
2112 2157 *
2113 2158 * @param int $version Not implemented. The content version of the document
... ... @@ -2134,13 +2179,14 @@ class KTAPI_Document extends KTAPI_FolderItem
2134 2179 * @author KnowledgeTree Team
2135 2180 * @access public
2136 2181 */
2137   - function download()
  2182 + function download($version = null)
2138 2183 {
2139 2184 $storage =& KTStorageManagerUtil::getSingleton();
2140 2185 $options = array();
2141 2186  
  2187 + $comment = (!is_null($version)) ? 'Document version '.$version.' downloaded' : 'Document downloaded';
2142 2188 $oDocumentTransaction = new DocumentTransaction($this->document, 'Document downloaded', 'ktcore.transactions.download', $aOptions);
2143   - $oDocumentTransaction->create();
  2189 + return $oDocumentTransaction->create();
2144 2190 }
2145 2191  
2146 2192 /**
... ... @@ -2238,6 +2284,17 @@ class KTAPI_Document extends KTAPI_FolderItem
2238 2284 }
2239 2285  
2240 2286 /**
  2287 + * Get the content version id using the document (content) version - major/minor version
  2288 + *
  2289 + * @param string $version
  2290 + * @return int
  2291 + */
  2292 + function get_content_version_id_from_version($version)
  2293 + {
  2294 + return $this->document->getContentVersionIdFromVersion($version);
  2295 + }
  2296 +
  2297 + /**
2241 2298 * This expunges a document from the system.
2242 2299 *
2243 2300 * <code>
... ... @@ -2557,10 +2614,13 @@ class KTAPI_Document extends KTAPI_FolderItem
2557 2614 */
2558 2615 public function addDocumentToUserHistory()
2559 2616 {
2560   - require_once(KT_DIR . '/plugins/commercial/network/userhistory/UserHistoryActions.php');
2561   -
2562   - $docAction = new UserHistoryDocumentAction($this->document, $this->ktapi->get_user());
2563   - $docAction->_show();
  2617 + if (KTPluginUtil::pluginIsActive('brad.UserHistory.plugin')) {
  2618 + $path = KTPluginUtil::getPluginPath('brad.UserHistory.plugin');
  2619 + require_once($path . 'UserHistoryActions.php');
  2620 +
  2621 + $docAction = new UserHistoryDocumentAction($this->document, $this->ktapi->get_user());
  2622 + $docAction->_show();
  2623 + }
2564 2624 }
2565 2625  
2566 2626 /**
... ... @@ -2575,4 +2635,4 @@ class KTAPI_Document extends KTAPI_FolderItem
2575 2635 }
2576 2636 }
2577 2637  
2578 2638 -?>
  2639 +?>
2579 2640 \ No newline at end of file
... ...
ktapi/KTAPIFolder.inc.php
1 1 <?php
2 2 /**
3   - * Folder API for KnowledgeTree
  3 + *
  4 + * $Id$
4 5 *
5 6 * KnowledgeTree Community Edition
6 7 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  8 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 9 *
9 10 *
10 11 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -32,8 +33,13 @@
32 33 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33 34 * must display the words "Powered by KnowledgeTree" and retain the original
34 35 * copyright notice.
  36 + * Contributor( s): ______________________________________
  37 + */
  38 +
  39 +/**
  40 + * Folder API for KnowledgeTree
35 41 *
36   - * @copyright 2008-2009, KnowledgeTree Inc.
  42 + * @copyright 2008-2010, KnowledgeTree Inc.
37 43 * @license GNU General Public License version 3
38 44 * @author KnowledgeTree Team
39 45 * @package KTAPI
... ... @@ -80,9 +86,13 @@ class KTAPI_Folder extends KTAPI_FolderItem
80 86 */
81 87 function get(&$ktapi, $folderid)
82 88 {
83   - assert(!is_null($ktapi));
84   - assert(is_a($ktapi, 'KTAPI'));
85   - assert(is_numeric($folderid));
  89 + if(is_null($ktapi) || !is_a($ktapi, 'KTAPI')){
  90 + return PEAR::raiseError('A valid KTAPI object is needed');
  91 + }
  92 +
  93 + if(!is_numeric($folderid)){
  94 + return PEAR::raiseError('A valid folder id is required');
  95 + }
86 96  
87 97 $folderid += 0;
88 98  
... ... @@ -288,7 +298,7 @@ class KTAPI_Folder extends KTAPI_FolderItem
288 298 * @access public
289 299 * @param KTAPI $ktapi
290 300 * @param string $foldername
291   - * @param int $folderid
  301 + * @param int $folderid The parent folder id
292 302 * @return KTAPI_Folder
293 303 */
294 304 function _get_folder_by_name($ktapi, $foldername, $folderid)
... ... @@ -377,7 +387,8 @@ class KTAPI_Folder extends KTAPI_FolderItem
377 387  
378 388 if (!empty($foldername) && ($foldername != '.'))
379 389 {
380   - $ktapi_folder = $this->get_folder_by_name($foldername);
  390 + // TODO confirm that this addition of the parent folder id as second parameter is correct and necessary
  391 + $ktapi_folder = $this->get_folder_by_name($foldername, $this->folderid);
381 392 }
382 393  
383 394 $currentFolderName = $this->get_folder_name();
... ... @@ -391,7 +402,8 @@ class KTAPI_Folder extends KTAPI_FolderItem
391 402 else
392 403 {
393 404 $foldername = substr($foldername, strlen($currentFolderName)+1);
394   - $ktapi_folder = $this->get_folder_by_name($foldername);
  405 + // TODO confirm that this addition of the parent folder id as second parameter is correct and necessary
  406 + $ktapi_folder = $this->get_folder_by_name($foldername, $this->folderid);
395 407 }
396 408 }
397 409  
... ... @@ -550,8 +562,8 @@ class KTAPI_Folder extends KTAPI_FolderItem
550 562  
551 563 foreach ($folder_children as $folder)
552 564 {
553   -
554   - if(KTPermissionUtil::userHasPermissionOnItem($user, $folder_permission, $folder)
  565 +
  566 + if(KTPermissionUtil::userHasPermissionOnItem($user, $folder_permission, $folder)
555 567 /*|| KTPermissionUtil::userHasPermissionOnItem($user, $read_permission, $folder)*/)
556 568 {
557 569 if ($depth-1 > 0)
... ... @@ -1594,7 +1606,7 @@ class KTAPI_Folder extends KTAPI_FolderItem
1594 1606  
1595 1607 return $_SESSION['errorMessage'];
1596 1608 }
1597   -
  1609 +
1598 1610 /**
1599 1611 * Method to add a Document to the User's History
1600 1612 *
... ... @@ -1604,11 +1616,25 @@ class KTAPI_Folder extends KTAPI_FolderItem
1604 1616 */
1605 1617 public function addFolderToUserHistory()
1606 1618 {
1607   - require_once(KT_DIR . '/plugins/commercial/network/userhistory/UserHistoryActions.php');
1608   -
1609   - $docAction = new UserHistoryFolderAction($this->folder, $this->ktapi->get_user());
1610   - $docAction->_show();
  1619 + if (KTPluginUtil::pluginIsActive('brad.UserHistory.plugin')) {
  1620 + $path = KTPluginUtil::getPluginPath('brad.UserHistory.plugin');
  1621 + require_once($path.'UserHistoryActions.php');
  1622 +
  1623 + $folderAction = new UserHistoryFolderAction($this->folder, $this->ktapi->get_user());
  1624 + $folderAction->_show();
  1625 + }
  1626 + }
  1627 +
  1628 + /**
  1629 + * Method to get the Ids of all the Parent Folders
  1630 + *
  1631 + * @author KnowledgeTree Team
  1632 + * @access public
  1633 + */
  1634 + public function getParentFolderIDs()
  1635 + {
  1636 + return $this->folder->getParentFolderIDs();
1611 1637 }
1612 1638 }
1613 1639  
1614 1640 -?>
  1641 +?>
1615 1642 \ No newline at end of file
... ...
ktapi/KTAPISession.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -32,8 +32,11 @@
32 32 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33 33 * must display the words "Powered by KnowledgeTree" and retain the original
34 34 * copyright notice.
35   - *
36   - * @copyright 2008-2009, KnowledgeTree Inc.
  35 + * Contributor( s): ______________________________________
  36 + */
  37 +
  38 +/**
  39 + * @copyright 2008-2010, KnowledgeTree Inc.
37 40 * @license GNU General Public License version 3
38 41 * @author KnowledgeTree Team
39 42 * @package KTAPI
... ...
ktapi/KTAPITrigger.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ...
ktapi/ktapi.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   -* Copyright (C) 2008,2009 KnowledgeTree Inc.
  7 +* Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -32,8 +32,12 @@
32 32 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33 33 * must display the words "Powered by KnowledgeTree" and retain the original
34 34 * copyright notice.
  35 +* Contributor( s): ______________________________________
  36 +*/
  37 +
  38 +/**
35 39 *
36   -* @copyright 2008-2009, KnowledgeTree Inc.
  40 +* @copyright 2008-2010, KnowledgeTree Inc.
37 41 * @license GNU General Public License version 3
38 42 * @author KnowledgeTree Team
39 43 * @package KTAPI
... ... @@ -842,11 +846,12 @@ class KTAPI
842 846 * @author KnowledgeTree Team
843 847 * @access public
844 848 * @param string $foldername The folder name
  849 + * @param int $parent_id The folder in which to search for the requested child folder
845 850 * @return object $folder The KTAPI_Folder object
846 851 */
847   - public function &get_folder_by_name($foldername, $parentId = 1)
  852 + public function &get_folder_by_name($foldername, $parent_id = 1)
848 853 {
849   - $folder = KTAPI_Folder::_get_folder_by_name($this, $foldername, $parentId);
  854 + $folder = KTAPI_Folder::_get_folder_by_name($this, $foldername, $parent_id);
850 855 return $folder;
851 856 }
852 857  
... ... @@ -865,6 +870,22 @@ class KTAPI
865 870 }
866 871  
867 872 /**
  873 + * This returns a refererence to a document based on document id.
  874 + *
  875 + * @author KnowledgeTree Team
  876 + * @access public
  877 + * @param integer $documentid The document id
  878 + * @param integer $metadataVersion The metadata version of the document (not the id)
  879 + * @return object $document The KTAPI_Document object
  880 + */
  881 + public function &get_document_by_metadata_version($documentid, $metadataVersion)
  882 + {
  883 + // Get the document using the metadata version
  884 + $document = KTAPI_Document::get_by_metadata_version($this, $documentid, $metadataVersion);
  885 + return $document;
  886 + }
  887 +
  888 + /**
868 889 * This returns a document type id based on the name or an error object.
869 890 *
870 891 * @author KnowledgeTree Team
... ... @@ -2027,14 +2048,14 @@ class KTAPI
2027 2048 function get_folder_shortcuts($folder_id)
2028 2049 {
2029 2050 $folder = $this->get_folder_by_id($folder_id);
2030   - if(PEAR::isError($folder)){
  2051 + if(PEAR::isError($folder)) {
2031 2052 $response['status_code'] = 1;
2032 2053 $response['message']= $folder->getMessage();
2033 2054 return $response;
2034 2055 }
2035 2056  
2036 2057 $shortcuts = $folder->get_shortcuts();
2037   - if(PEAR::isError($shortcuts)){
  2058 + if(PEAR::isError($shortcuts)) {
2038 2059 $response['status_code'] = 1;
2039 2060 $response['message']= $shortcuts->getMessage();
2040 2061 return $response;
... ... @@ -2054,10 +2075,10 @@ class KTAPI
2054 2075 * @param string $folder_name The name of the folder
2055 2076 * @return array Response 'results' contains kt_folder_detail | 'message' contains error message on failure
2056 2077 */
2057   - function get_folder_detail_by_name($folder_name)
  2078 + function get_folder_detail_by_name($folder_name, $parent_id = 1)
2058 2079 {
2059   - $folder = &$this->get_folder_by_name($folder_name);
2060   - if(PEAR::isError($folder)){
  2080 + $folder = &$this->get_folder_by_name($folder_name, $parent_id);
  2081 + if(PEAR::isError($folder)) {
2061 2082 $response['status_code'] = 1;
2062 2083 $response['message']= $folder->getMessage();
2063 2084 return $response;
... ... @@ -2343,7 +2364,7 @@ class KTAPI
2343 2364 $sourceName = $src_folder->get_folder_name();
2344 2365 $targetPath = $tgt_folder->get_full_path();
2345 2366  
2346   - $response['results'] = $this->get_folder_detail_by_name($targetPath . '/' . $sourceName);
  2367 + $response['results'] = $this->get_folder_detail_by_name($targetPath . '/' . $sourceName, $source_id);
2347 2368 return $response;
2348 2369 }
2349 2370  
... ... @@ -4714,21 +4735,28 @@ class KTAPI
4714 4735 }
4715 4736 return $response;
4716 4737 }
4717   -
  4738 +
  4739 + /**
  4740 + * Method to check whether content version is the latest for a specific document
  4741 + *
  4742 + * @author KnowledgeTree Team
  4743 + * @access public
  4744 + * @param string $documentID The id of the document
  4745 + * @param string $contentID The id of the content version to check
  4746 + * @return bool $response The formatted response array
  4747 + */
4718 4748 public function is_latest_version($documentID, $contentID)
4719   - {
4720   - $sql = 'SELECT COUNT(document_content_version.id) AS newdocumentcount
4721   - FROM document_content_version
4722   - WHERE document_content_version.document_id ="'.$documentID.'" AND
4723   - document_content_version.id > "'.$contentID.'"';
  4749 + {
  4750 + $document = $this->get_document_by_id($documentID);
4724 4751  
4725   - $row = DBUtil::getOneResult($sql);
4726   - $row = (int)$row['newdocumentcount'];
  4752 + $maxcontentID = $document->get_content_version();
4727 4753  
4728   - if ($row > 0) {
  4754 + if ($maxcontentID > $contentID) {
4729 4755 $response['is_latest'] = 'FALSE';
  4756 + $response['max_contentID'] = $maxcontentID;
4730 4757 } else {
4731 4758 $response['is_latest'] = 'TRUE';
  4759 + $response['max_contentID'] = $contentID;
4732 4760 }
4733 4761  
4734 4762 $response['status_code'] = 0;
... ... @@ -4811,6 +4839,58 @@ class KTAPI
4811 4839  
4812 4840 return $response;
4813 4841 }
  4842 +
  4843 + /**
  4844 + * Method to get the Recently Viewed Documents
  4845 + *
  4846 + * @author KnowledgeTree Team
  4847 + * @access public
  4848 + */
  4849 + public function getRecentlyViewedDocuments()
  4850 + {
  4851 + if (KTPluginUtil::pluginIsActive('brad.UserHistory.plugin')) {
  4852 + $path = KTPluginUtil::getPluginPath('brad.UserHistory.plugin');
  4853 + require_once($path.'UserHistoryActions.php');
  4854 + $user = $this->get_user();
  4855 +
  4856 + if (is_null($user) || PEAR::isError($user))
  4857 + {
  4858 + $result = new PEAR_Error(KTAPI_ERROR_USER_INVALID);
  4859 + return $result;
  4860 + }
  4861 +
  4862 + return UserHistoryDocumentEntry::getByUser($user);
  4863 +
  4864 + } else {
  4865 + return array();
  4866 + }
  4867 + }
  4868 +
  4869 + /**
  4870 + * Method to get the Recently Viewed Folders
  4871 + *
  4872 + * @author KnowledgeTree Team
  4873 + * @access public
  4874 + */
  4875 + public function getRecentlyViewedFolders()
  4876 + {
  4877 + if (KTPluginUtil::pluginIsActive('brad.UserHistory.plugin')) {
  4878 + $path = KTPluginUtil::getPluginPath('brad.UserHistory.plugin');
  4879 + require_once($path.'UserHistoryActions.php');
  4880 + $user = $this->get_user();
  4881 +
  4882 + if (is_null($user) || PEAR::isError($user))
  4883 + {
  4884 + $result = new PEAR_Error(KTAPI_ERROR_USER_INVALID);
  4885 + return $result;
  4886 + }
  4887 +
  4888 + return UserHistoryFolderEntry::getByUser($user);
  4889 +
  4890 + } else {
  4891 + return array();
  4892 + }
  4893 + }
4814 4894 }
4815 4895  
4816 4896  
... ...
ktwebdav/index.php
... ... @@ -5,7 +5,7 @@
5 5 *
6 6 * KnowledgeTree Community Edition
7 7 * Document Management Made Simple
8   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  8 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
9 9 *
10 10 *
11 11 * This program is free software; you can redistribute it and/or modify it under
... ...
ktwebdav/ktwebdav.php
... ... @@ -5,7 +5,7 @@
5 5 *
6 6 * KnowledgeTree Community Edition
7 7 * Document Management Made Simple
8   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  8 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
9 9 *
10 10 *
11 11 * This program is free software; you can redistribute it and/or modify it under
... ...
ktwebdav/lib/KTWebDAVServer.inc.php
... ... @@ -5,7 +5,7 @@
5 5 *
6 6 * KnowledgeTree Community Edition
7 7 * Document Management Made Simple
8   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  8 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
9 9 *
10 10 *
11 11 * This program is free software; you can redistribute it and/or modify it under
... ...
ktwebservice/KTDownloadManager.inc.php
... ... @@ -8,8 +8,8 @@
8 8 *
9 9 * KnowledgeTree Community Edition
10 10 * Document Management Made Simple
11   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
12   - *
  11 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
  12 + *
13 13 *
14 14 * This program is free software; you can redistribute it and/or modify it under
15 15 * the terms of the GNU General Public License version 3 as published by the
... ... @@ -76,44 +76,41 @@ class KTDownloadManager
76 76 {
77 77 $this->session = $session;
78 78 }
79   -
  79 +
80 80 /**
81 81 * This returns
82 82 *
83 83 * @access public
84 84 * @param KTAPI_Document $document
  85 + * @param int $content_version_id Optional. The id of the requested content version
85 86 * @return string
86 87 */
87   - function allow_download($document, $content_version = null, $multipart = false) {
  88 + function allow_download($document, $content_version_id = null, $multipart = false) {
88 89 assert ( ! is_null ( $document ) );
89   -
90   - $content_version = 0;
  90 +
91 91 $filesize = 0;
92   -
  92 +
93 93 if ($document instanceof KTAPI_Document) {
94 94 $doc_id = $document->documentid;
95   - $content_version = $document->document->getContentVersionId ();
  95 + //$content_version_id = (is_numeric($content_version_id)) ? $content_version_id : $document->document->getContentVersionId();
96 96 $filesize = $document->document->getFileSize ();
97 97 } else if ($document instanceof Document || $document instanceof DocumentProxy) {
98 98 $doc_id = $document->getId ();
99   - $content_version = $document->getContentVersionId ();
  99 + //$content_version_id = (is_numeric($content_version_id)) ? $content_version_id : $document->getContentVersionId();
100 100 $filesize = $document->getFileSize ();
101 101 } else if (is_numeric ( $document )) {
102 102 $doc_id = $document;
103 103 } else
104 104 die ( 'gracefully' );
105   -
106   - //assert(is_a($document, 'KTAPI_Document'));
107   -
108   -
109   - $hash = sha1 ( "$doc_id $this->session $this->random" );
110   -
111   - $id = DBUtil::autoInsert ( 'download_files', array ('document_id' => $doc_id, 'session' => $this->session, 'download_date' => date ( 'Y-m-d H:i:s' ), 'content_version' => $content_version, 'filesize' => $filesize, 'hash' => $hash ), array ('noid' => true ) );
112   -
113   - return $multipart?$this->build_multipart_url( $hash, $doc_id ):$this->build_url ( $hash, $doc_id );
  105 +
  106 + $hash = sha1 ( "$doc_id $content_version_id $this->session $this->random" );
  107 +
  108 + $id = DBUtil::autoInsert ( 'download_files', array ('document_id' => $doc_id, 'session' => $this->session, 'download_date' => date ( 'Y-m-d H:i:s' ), 'content_version' => $content_version_id, 'filesize' => $filesize, 'hash' => $hash ), array ('noid' => true ) );
  109 +
  110 + return $multipart ? $this->build_multipart_url( $hash, $doc_id ) : $this->build_url ( $hash, $doc_id );
114 111 }
115   -
116   -
  112 +
  113 +
117 114 /**
118 115 * This returns the url used to download a document.
119 116 *
... ... @@ -125,21 +122,24 @@ class KTDownloadManager
125 122 function build_url($hash, $documentid) {
126 123 return $this->download_url . "?code=$hash&d=$documentid&u=$this->session";
127 124 }
128   -
  125 +
129 126 function build_multipart_url($hash, $documentId) {
130   -// return '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@';
131 127 return $this->multipart_download_url . "?code=$hash&d=$documentId&u=$this->session";
132 128 }
133 129  
134   -
135 130 /**
136 131 * This starts a download.
137 132 *
138 133 * @access public
  134 + *
  135 + * @param int $document_id
  136 + * @param string $hash
  137 + * @param string $apptype
  138 + * @return mixed
139 139 */
140   - function download($document_id, $hash, $version = null, $apptype = 'ws')
  140 + function download($document_id, $hash, $apptype = 'ws')
141 141 {
142   - $sql = "SELECT 1 FROM download_files WHERE hash=? AND session=? AND document_id=?";
  142 + $sql = "SELECT content_version FROM download_files WHERE hash=? AND session=? AND document_id=?";
143 143 $rows = DBUtil::getResultArray(array($sql, array($hash, $this->session, $document_id)));
144 144 if (PEAR::isError($rows))
145 145 {
... ... @@ -151,11 +151,14 @@ class KTDownloadManager
151 151 return new PEAR_Error('Invalid session.');
152 152 }
153 153  
  154 + // Get the content version id
  155 + $content_version_id = $rows[0]['content_version'];
  156 +
154 157 // If document is being downloaded by an external user bypass the session checking
155 158 $check = strstr($this->session, 'ktext_'.$document_id);
156 159 if($check == 0 && $check !== false){
157 160 // Use external download function
158   - return $this->download_ext($document_id, $hash, $version = null);
  161 + return $this->download_ext($document_id, $hash, $content_version_id);
159 162 }
160 163  
161 164 $storage =& KTStorageManagerUtil::getSingleton();
... ... @@ -173,11 +176,9 @@ class KTDownloadManager
173 176 return $document;
174 177 }
175 178  
176   - if (!empty($version))
  179 + if (!empty($content_version_id))
177 180 {
178   - $version = KTDocumentContentVersion::get($version);
179   -
180   - $res = $storage->downloadVersion($document->document, $version);
  181 + $res = $storage->downloadVersion($document->document, $content_version_id);
181 182 }
182 183 else
183 184 {
... ... @@ -193,8 +194,8 @@ class KTDownloadManager
193 194  
194 195 return true;
195 196 }
196   -
197   - function download_ext($document_id, $hash, $version = null)
  197 +
  198 + function download_ext($document_id, $hash, $content_version_id = null)
198 199 {
199 200 $storage =& KTStorageManagerUtil::getSingleton();
200 201 $document = Document::get($document_id);
... ... @@ -203,11 +204,9 @@ class KTDownloadManager
203 204 return $document;
204 205 }
205 206  
206   - if (!empty($version))
  207 + if (!empty($content_version_id))
207 208 {
208   - $version = KTDocumentContentVersion::get($version);
209   -
210   - $res = $storage->downloadVersion($document, $version);
  209 + $res = $storage->downloadVersion($document, $content_version_id);
211 210 }
212 211 else
213 212 {
... ... @@ -237,4 +236,4 @@ class KTDownloadManager
237 236 DBUtil::runQuery($sql);
238 237 }
239 238 }
240 239 -?>
  240 +?>
241 241 \ No newline at end of file
... ...
ktwebservice/KTUploadManager.inc.php
... ... @@ -8,7 +8,7 @@
8 8 *
9 9 * KnowledgeTree Community Edition
10 10 * Document Management Made Simple
11   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  11 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
12 12 *
13 13 *
14 14 * This program is free software; you can redistribute it and/or modify it under
... ...
ktwebservice/KTWebService.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ...
ktwebservice/download.php
... ... @@ -6,8 +6,8 @@
6 6 *
7 7 * KnowledgeTree Community Edition
8 8 * Document Management Made Simple
9   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
10   - *
  9 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
  10 + *
11 11 *
12 12 * This program is free software; you can redistribute it and/or modify it under
13 13 * the terms of the GNU General Public License version 3 as published by the
... ... @@ -73,7 +73,7 @@ require_once(&#39;KTDownloadManager.inc.php&#39;);
73 73 $download_manager = new KTDownloadManager();
74 74 $download_manager->set_session($session);
75 75  
76   -$response = $download_manager->download($document_id, $hash, null, $apptype);
  76 +$response = $download_manager->download($document_id, $hash, $apptype);
77 77 if (PEAR::isError($response))
78 78 {
79 79 $msg = urlencode($response->getMessage());
... ...
ktwebservice/download_cleanup.php
... ... @@ -8,7 +8,7 @@
8 8 *
9 9 * KnowledgeTree Community Edition
10 10 * Document Management Made Simple
11   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  11 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
12 12 *
13 13 *
14 14 * This program is free software; you can redistribute it and/or modify it under
... ...
ktwebservice/index.php
... ... @@ -8,7 +8,7 @@
8 8 *
9 9 * KnowledgeTree Community Edition
10 10 * Document Management Made Simple
11   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  11 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
12 12 *
13 13 *
14 14 * This program is free software; you can redistribute it and/or modify it under
... ...
ktwebservice/upload.php
... ... @@ -8,7 +8,7 @@
8 8 *
9 9 * KnowledgeTree Community Edition
10 10 * Document Management Made Simple
11   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  11 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
12 12 *
13 13 *
14 14 * This program is free software; you can redistribute it and/or modify it under
... ...
ktwebservice/upload_cleanup.php
... ... @@ -8,7 +8,7 @@
8 8 *
9 9 * KnowledgeTree Community Edition
10 10 * Document Management Made Simple
11   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  11 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
12 12 *
13 13 *
14 14 * This program is free software; you can redistribute it and/or modify it under
... ...
ktwebservice/webservice.php
... ... @@ -8,7 +8,7 @@
8 8 *
9 9 * KnowledgeTree Community Edition
10 10 * Document Management Made Simple
11   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  11 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
12 12 *
13 13 *
14 14 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -60,8 +60,6 @@ if (defined(&#39;HAS_SEARCH_FUNCTIONALITY&#39;))
60 60 require_once(KT_DIR . '/search2/search/search.inc.php');
61 61 }
62 62  
63   -// TODO: allow downloading of metadata versions
64   -// TODO: allow downloading of document versions
65 63 // TODO: chunking search results
66 64 // TODO: add basic permissions management - add permissions to folder based on user/groups
67 65 // TODO: refactor!!! download manager, split this file into a few smaller ones, etc
... ... @@ -72,7 +70,7 @@ if (defined(&#39;HAS_SEARCH_FUNCTIONALITY&#39;))
72 70 // TODO: ktwsapi/php must be made compatible with v2/v3
73 71 // TODO: subscriptions/notifications
74 72  
75   -// NOTE: some features are not implemented yet. most expected for v3. e.g. oem_document_no, custom_document_no, download($version)., get_metadata($version)
  73 +// NOTE: some features are not implemented yet. most expected for v3. e.g. oem_document_no, custom_document_no
76 74  
77 75 // Status Codes as defined in the specification.
78 76  
... ... @@ -100,19 +98,19 @@ if (!defined(&#39;LATEST_WEBSERVICE_VERSION&#39;))
100 98 define('LATEST_WEBSERVICE_VERSION', 2);
101 99 }
102 100  
103   - function bool2str($bool)
  101 +function bool2str($bool)
  102 +{
  103 + if (is_bool($bool))
104 104 {
105   - if (is_bool($bool))
106   - {
107   - return $bool?'true':'false';
108   - }
109   - if (is_numeric($bool))
110   - {
111   - return ($bool+0)?'true':'false';
112   - }
113   - // assume str
114   - return (strtolower($bool) == 'true')?'true':'false';
  105 + return $bool?'true':'false';
  106 + }
  107 + if (is_numeric($bool))
  108 + {
  109 + return ($bool+0)?'true':'false';
115 110 }
  111 + // assume str
  112 + return (strtolower($bool) == 'true')?'true':'false';
  113 +}
116 114  
117 115 class KTWebService
118 116 {
... ... @@ -769,13 +767,17 @@ class KTWebService
769 767  
770 768 // get_folder_detail_by_name
771 769 $this->__dispatch_map['get_folder_detail_by_name'] =
772   - array('in' => array('session_id' => 'string', 'folder_name' => 'string' ),
  770 + array('in' => array('session_id' => 'string', 'folder_name' => 'string'),
773 771 'out' => array('return' => "{urn:$this->namespace}kt_folder_detail"),
774 772 );
775 773  
776 774 if ($this->version >=3)
777 775 {
778   - $this->__dispatch_map['get_folder_detail_by_name']['in'] = array('session_id' => 'string', 'folder_id' => 'int', 'create'=>'boolean' );
  776 + // NOTE that there was a bug: folder_id should be folder_name and be of type int - this is fixed in the second version below
  777 + // additionally the function has no "create" parameter
  778 + //$this->__dispatch_map['get_folder_detail_by_name']['in'] = array('session_id' => 'string', 'folder_id' => 'int', 'create'=>'boolean' );
  779 + // now
  780 + $this->__dispatch_map['get_folder_detail_by_name']['in'] = array('session_id' => 'string', 'folder_name' => 'string', 'parent_id'=>'int' );
779 781 }
780 782  
781 783 // get_folder_contents
... ... @@ -1521,22 +1523,23 @@ class KTWebService
1521 1523 *
1522 1524 * @param string $session_id
1523 1525 * @param string $folder_name
  1526 + * @param integer $parent_id The parent folder in which to look for the named folder
1524 1527 * @return kt_folder_detail. status_code can be KTWS_ERR_INVALID_SESSION, KTWS_ERR_INVALID_FOLDER, or KTWS_SUCCESS.
1525 1528 */
1526   - function get_folder_detail_by_name($session_id, $folder_name)
  1529 + function get_folder_detail_by_name($session_id, $folder_name, $parent_id = 1)
1527 1530 {
1528   - $this->debug("get_folder_detail_by_name('$session_id','$folder_name')");
  1531 + $this->debug("get_folder_detail_by_name('$session_id','$folder_name','$parent_id')");
1529 1532 $kt = &$this->get_ktapi($session_id);
1530 1533 if (is_array($kt))
1531 1534 {
1532 1535 return new SOAP_Value('return',"{urn:$this->namespace}kt_folder_detail", $kt);
1533 1536 }
1534 1537  
1535   - $folder = &$kt->get_folder_by_name($folder_name);
  1538 + $folder = &$kt->get_folder_by_name($folder_name, $parent_id);
1536 1539 if (PEAR::isError($folder))
1537 1540 {
1538 1541 $response = KTWebService::_status(KTWS_ERR_INVALID_FOLDER,$folder);
1539   - $this->debug("get_folder_detail_by_name - cannot get folder $folder_name - " . $folder->getMessage(), $session_id);
  1542 + $this->debug("get_folder_detail_by_name - cannot get folder $folder_name (looking in folder $parent_id) - " . $folder->getMessage(), $session_id);
1540 1543 return new SOAP_Value('return',"{urn:$this->namespace}kt_folder_detail", $response);
1541 1544 }
1542 1545  
... ... @@ -1897,11 +1900,10 @@ class KTWebService
1897 1900  
1898 1901 if ($this->version >=2)
1899 1902 {
1900   -
1901 1903 $sourceName = $src_folder->get_folder_name();
1902 1904 $targetPath = $tgt_folder->get_full_path();
1903 1905  
1904   - $response = $this->get_folder_detail_by_name($session_id, $targetPath . '/' . $sourceName);
  1906 + $response = $this->get_folder_detail_by_name($session_id, $targetPath . '/' . $sourceName, $source_id);
1905 1907  
1906 1908 return $response;
1907 1909 }
... ... @@ -2940,12 +2942,13 @@ class KTWebService
2940 2942 *
2941 2943 * @param string $session_id
2942 2944 * @param int $document_id
  2945 + * @param string $version The document (content) version - "major version" . "minor version"
2943 2946  
2944 2947 * @return kt_response. status_code can be KTWS_ERR_INVALID_SESSION, KTWS_ERR_INVALID_DOCUMENT or KTWS_SUCCESS
2945 2948 */
2946 2949 function download_document($session_id, $document_id, $version=null)
2947 2950 {
2948   - $this->debug("download_document('$session_id',$document_id)");
  2951 + $this->debug("download_document('$session_id',$document_id, '$version')");
2949 2952  
2950 2953 $kt = &$this->get_ktapi($session_id );
2951 2954 if (is_array($kt))
... ... @@ -2964,11 +2967,23 @@ class KTWebService
2964 2967 return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response);
2965 2968 }
2966 2969  
2967   - $result = $document->download();
  2970 + $content_version_id = null;
  2971 + if(!empty($version)){
  2972 + // Get the content version id for the given document version
  2973 + $content_version_id = $document->get_content_version_id_from_version($version);
  2974 + if (PEAR::isError($content_version_id))
  2975 + {
  2976 + $response['message'] = $result->getMessage();
  2977 + $this->debug("download_document - cannot get version $version - " . $result->getMessage(), $session_id);
  2978 + return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response);
  2979 + }
  2980 + }
  2981 +
  2982 + $result = $document->download($version);
2968 2983 if (PEAR::isError($result))
2969 2984 {
2970 2985 $response['message'] = $result->getMessage();
2971   - $this->debug("download_document - cannot download - " . $result->getMessage(), $session_id);
  2986 + $this->debug("download_document - cannot download (version $version) - " . $result->getMessage(), $session_id);
2972 2987 return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response);
2973 2988 }
2974 2989  
... ... @@ -2976,7 +2991,7 @@ class KTWebService
2976 2991 $download_manager = new KTDownloadManager();
2977 2992 $download_manager->set_session($session->session);
2978 2993 $download_manager->cleanup();
2979   - $url = $download_manager->allow_download($document);
  2994 + $url = $download_manager->allow_download($document, $content_version_id);
2980 2995  
2981 2996 $response['status_code'] = KTWS_SUCCESS;
2982 2997 $response['message'] = $url;
... ... @@ -3012,7 +3027,19 @@ class KTWebService
3012 3027 return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response);
3013 3028 }
3014 3029  
3015   - $result = $document->download();
  3030 + $content_version_id = null;
  3031 + if(!empty($version)){
  3032 + // Get the content version id for the given document version
  3033 + $content_version_id = $document->get_content_version_id_from_version($version);
  3034 + if (PEAR::isError($content_version_id))
  3035 + {
  3036 + $response['message'] = $result->getMessage();
  3037 + $this->debug("download_document - cannot get version $version - " . $result->getMessage(), $session_id);
  3038 + return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response);
  3039 + }
  3040 + }
  3041 +
  3042 + $result = $document->download($version);
3016 3043 if (PEAR::isError($result))
3017 3044 {
3018 3045 $response['message'] = $result->getMessage();
... ... @@ -3020,24 +3047,33 @@ class KTWebService
3020 3047 return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response);
3021 3048 }
3022 3049  
3023   - $content='';
  3050 + $content = '';
  3051 + $oStorage =& KTStorageManagerUtil::getSingleton();
3024 3052  
3025   - $document = $document->document;
  3053 + // for a specified version
  3054 + if(is_numeric($content_version_id)){
  3055 + $filename = $oStorage->temporaryFileForVersion($content_version_id);
3026 3056  
3027   - $oStorage =& KTStorageManagerUtil::getSingleton();
3028   - $filename = $oStorage->temporaryFile($document);
3029   -
3030   - $fp=fopen($filename,'rb');
3031   - if ($fp === false)
3032   - {
  3057 + if(!$filename){
3033 3058 $response['message'] = 'The file is not in the storage system. Please contact an administrator!';
3034   - $this->debug("download_small_document - cannot write $filename", $session_id);
  3059 + $this->debug("download_small_document - $filename cannot be found in the storage system", $session_id);
3035 3060 return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response);
3036   - }
3037   - $content = fread($fp, filesize($filename));
3038   - fclose($fp);
3039   - $content = base64_encode($content);
  3061 + }
  3062 + }else{
  3063 + $document = $document->document;
  3064 + $filename = $oStorage->temporaryFile($document);
  3065 + }
3040 3066  
  3067 + $fp=fopen($filename,'rb');
  3068 + if ($fp === false)
  3069 + {
  3070 + $response['message'] = 'The file is not in the storage system. Please contact an administrator!';
  3071 + $this->debug("download_small_document - cannot read $filename", $session_id);
  3072 + return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response);
  3073 + }
  3074 + $content = fread($fp, filesize($filename));
  3075 + fclose($fp);
  3076 + $content = base64_encode($content);
3041 3077  
3042 3078 $response['status_code'] = KTWS_SUCCESS;
3043 3079 $response['message'] = $content;
... ... @@ -3739,9 +3775,9 @@ class KTWebService
3739 3775 * @param int $document_id
3740 3776 * @return kt_metadata_response
3741 3777 */
3742   - function get_document_metadata($session_id,$document_id)
  3778 + function get_document_metadata($session_id, $document_id, $version = null)
3743 3779 {
3744   - $this->debug("get_document_metadata('$session_id',$document_id)");
  3780 + $this->debug("get_document_metadata('$session_id',$document_id, $version)");
3745 3781  
3746 3782 $kt = &$this->get_ktapi($session_id );
3747 3783 if (is_array($kt))
... ... @@ -3751,7 +3787,12 @@ class KTWebService
3751 3787  
3752 3788 $response = KTWebService::_status(KTWS_ERR_INVALID_DOCUMENT);
3753 3789  
3754   - $document = &$kt->get_document_by_id($document_id);
  3790 + if(is_numeric($version)){
  3791 + $document = &$kt->get_document_by_metadata_version($document_id, $version);
  3792 + }else {
  3793 + $document = &$kt->get_document_by_id($document_id);
  3794 + }
  3795 +
3755 3796 if (PEAR::isError($document))
3756 3797 {
3757 3798 $response['message'] = $document->getMessage();
... ...
lib/actions/actionregistry.inc.php
... ... @@ -4,8 +4,8 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
8   - * John
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
  8 + *
9 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
... ...
lib/actions/bulkaction.php
... ... @@ -5,8 +5,8 @@
5 5 *
6 6 * KnowledgeTree Community Edition
7 7 * Document Management Made Simple
8   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
9   - * John
  8 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
  9 + *
10 10 *
11 11 * This program is free software; you can redistribute it and/or modify it under
12 12 * the terms of the GNU General Public License version 3 as published by the
... ...
lib/actions/documentaction.inc.php
... ... @@ -4,8 +4,8 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
8   - * John
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
  8 + *
9 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
... ...
lib/actions/documentviewlet.inc.php
... ... @@ -5,8 +5,8 @@
5 5 *
6 6 * KnowledgeTree Community Edition
7 7 * Document Management Made Simple
8   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
9   - * John
  8 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
  9 + *
10 10 *
11 11 * This program is free software; you can redistribute it and/or modify it under
12 12 * the terms of the GNU General Public License version 3 as published by the
... ...
lib/actions/entitylist.php
... ... @@ -5,8 +5,8 @@
5 5 *
6 6 * KnowledgeTree Community Edition
7 7 * Document Management Made Simple
8   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
9   - * John
  8 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
  9 + *
10 10 *
11 11 * This program is free software; you can redistribute it and/or modify it under
12 12 * the terms of the GNU General Public License version 3 as published by the
... ...
lib/actions/folderaction.inc.php
... ... @@ -4,8 +4,8 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
8   - * John
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
  8 + *
9 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
... ...
lib/actions/portletregistry.inc.php
... ... @@ -4,8 +4,8 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
8   - * John
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
  8 + *
9 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
... ...
lib/alert/delivery/EmailAlert.inc
... ... @@ -6,7 +6,7 @@
6 6 *
7 7 * KnowledgeTree Community Edition
8 8 * Document Management Made Simple
9   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  9 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
10 10 *
11 11 *
12 12 * This program is free software; you can redistribute it and/or modify it under
... ...
lib/alert/delivery/SMSAlert.inc
... ... @@ -6,7 +6,7 @@
6 6 *
7 7 * KnowledgeTree Community Edition
8 8 * Document Management Made Simple
9   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  9 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
10 10 *
11 11 *
12 12 * This program is free software; you can redistribute it and/or modify it under
... ...
lib/api/ktcmis/classes/CMISDocumentPropertyCollection.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008,2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -32,8 +32,12 @@
32 32 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33 33 * must display the words "Powered by KnowledgeTree" and retain the original
34 34 * copyright notice.
  35 + * Contributor( s): ______________________________________
  36 + */
  37 +
  38 +/**
35 39 *
36   - * @copyright 2008-2009, KnowledgeTree Inc.
  40 + * @copyright 2008-2010, KnowledgeTree Inc.
37 41 * @license GNU General Public License version 3
38 42 * @author KnowledgeTree Team
39 43 * @package KTCMIS
... ... @@ -47,35 +51,35 @@ require_once(CMIS_DIR . &#39;/classes/CMISPropertyCollection.inc.php&#39;);
47 51 */
48 52 class CMISDocumentPropertyCollection extends CMISPropertyCollection {
49 53  
50   - static $Name;
51   - static $IsImmutable;
52   - static $IsLatestVersion;
53   - static $IsMajorVersion;
54   - static $IsLatestMajorVersion;
55   - static $VersionLabel;
56   - static $VersionSeriesId;
57   - static $IsVersionSeriesCheckedOut;
58   - static $VersionSeriesCheckedOutBy;
59   - static $VersionSeriesCheckedOutId;
60   - static $CheckinComment;
61   - static $ContentStreamLength;
62   - static $ContentStreamMimeType;
63   - static $ContentStreamFilename;
64   - static $ContentStreamUri;
  54 + static $name;
  55 + static $isImmutable;
  56 + static $isLatestVersion;
  57 + static $isMajorVersion;
  58 + static $isLatestMajorVersion;
  59 + static $versionLabel;
  60 + static $versionSeriesId;
  61 + static $isVersionSeriesCheckedOut;
  62 + static $versionSeriesCheckedOutBy;
  63 + static $versionSeriesCheckedOutId;
  64 + static $checkinComment;
  65 + static $contentStreamLength;
  66 + static $contentStreamMimeType;
  67 + static $contentStreamFilename;
  68 + static $contentStreamUri;
65 69  
66 70 function __construct()
67 71 {
68 72 parent::__construct();
69   - self::$propertyTypes = array_merge(self::$propertyTypes, array('ContentStreamAllowed' => 'propertyString',
70   - 'ContentStreamLength' => 'propertyInteger',
71   - 'ContentStreamMimeType' => 'propertyString',
72   - 'ContentStreamFilename' => 'propertyString',
73   - 'ContentStreamUri' => 'propertyUri',
74   - 'IsLatestVersion' => 'propertyBoolean',
75   - 'IsVersionSeriesCheckedOut' => 'propertyBoolean',
76   - 'VersionSeriesCheckedOutBy' => 'propertyString',
77   - 'VersionSeriesCheckedOutId' => 'propertyId',
78   - 'VersionLabel' => 'propertyString'));
  73 + self::$propertyTypes = array_merge(self::$propertyTypes, array('contentStreamAllowed' => 'propertyString',
  74 + 'contentStreamLength' => 'propertyInteger',
  75 + 'contentStreamMimeType' => 'propertyString',
  76 + 'contentStreamFilename' => 'propertyString',
  77 + 'contentStreamUri' => 'propertyUri',
  78 + 'isLatestVersion' => 'propertyBoolean',
  79 + 'isVersionSeriesCheckedOut' => 'propertyBoolean',
  80 + 'versionSeriesCheckedOutBy' => 'propertyString',
  81 + 'versionSeriesCheckedOutId' => 'propertyId',
  82 + 'versionLabel' => 'propertyString'));
79 83 }
80 84  
81 85 }
... ...
lib/api/ktcmis/classes/CMISFolderPropertyCollection.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008,2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -32,8 +32,12 @@
32 32 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33 33 * must display the words "Powered by KnowledgeTree" and retain the original
34 34 * copyright notice.
  35 + * Contributor( s): ______________________________________
  36 + */
  37 +
  38 +/**
35 39 *
36   - * @copyright 2008-2009, KnowledgeTree Inc.
  40 + * @copyright 2008-2010, KnowledgeTree Inc.
37 41 * @license GNU General Public License version 3
38 42 * @author KnowledgeTree Team
39 43 * @package KTCMIS
... ... @@ -47,9 +51,9 @@ require_once(CMIS_DIR . &#39;/classes/CMISPropertyCollection.inc.php&#39;);
47 51 */
48 52 class CMISFolderPropertyCollection extends CMISPropertyCollection {
49 53  
50   - static $Name;
51   - static $ParentId;
52   - static $AllowedChildObjectTypeIds;
  54 + static $name;
  55 + static $parentId;
  56 + static $allowedChildObjectTypeIds;
53 57  
54 58 function __construct()
55 59 {
... ...
lib/api/ktcmis/classes/CMISObject.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008,2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -32,30 +32,45 @@
32 32 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33 33 * must display the words "Powered by KnowledgeTree" and retain the original
34 34 * copyright notice.
  35 + * Contributor( s): ______________________________________
  36 + */
  37 +
  38 +/**
35 39 *
36   - * @copyright 2008-2009, KnowledgeTree Inc.
  40 + * @copyright 2008-2010, KnowledgeTree Inc.
37 41 * @license GNU General Public License version 3
38 42 * @author KnowledgeTree Team
39 43 * @package KTCMIS
40 44 * @version Version 0.1
41 45 */
42 46  
43   -abstract class CMISObject {
  47 +// NOTE designation "opaque" means the value may not be changed
  48 +
  49 +// TODO consider attributes as a class similar to property definitions, in order to more easily extract without having
  50 +// to have attribute specific code
44 51  
45   - protected $typeId;
46   - protected $queryName;
47   - protected $displayName;
48   - protected $baseType;
49   - protected $baseTypeQueryName;
50   - protected $parentId;
51   - protected $description;
52   - protected $creatable;
53   - protected $fileable;
54   - protected $queryable;
55   - protected $includedInSupertypeQuery;
56   - protected $controllable; // NOTE deprecated? part of policy objects specification, policy objects are indicated as TODO remove
57   - protected $contentStreamAllowed = 'notAllowed';
  52 +abstract class CMISObject {
58 53  
  54 + protected $id; // ID (opaque); identifies the object-type in the repository
  55 + protected $localName; // String (opaque, optional); local name for object-type - need not be set
  56 + protected $localNamespace; // String (opaque, optional); optional local namespace for object-type - need not be set
  57 + // NOTE queryName should not contain characters that negatively interact with BNF grammar
  58 + protected $queryName; // String (opaque); used for query and filter operations on object-types
  59 + protected $displayName; // String (optional); used for presentation by application
  60 + protected $baseId; // Enum; indicates base type
  61 + protected $parentId; // ID; id of immediate parent type; must be "not set" for a base type (Document, Folder, Relationship, Policy)
  62 + protected $description; // String (optional); used for presentation by application
  63 + protected $creatable; // Boolean; indicates whether new objects of this type may be created
  64 + protected $fileable; // Boolean; indicates whether objects of this type are fileable
  65 + protected $queryable; // Boolean; indicates whether this object-type can appear inthe FROM clause of a query statement
  66 + protected $controllablePolicy; // Boolean; indicates whether objects of this type are controllable via policies
  67 + protected $controllableACL; // Boolean; indicates whether objects of this type are controllable by ACLs
  68 + protected $fulltextIndexed; // Boolean; indicates whether objects of this type are indexed for full-text search
  69 + // for querying via the CONTAINS() query predicate
  70 + protected $includedInSupertypeQuery; // Boolean; indicates whether this type and sub-types appear in a query of this type's ancestor types
  71 + // For example: if Invoice is a sub-type of cmis:document, if this is TRUE on Invoice then for a query
  72 + // 391 on cmis:document, instances of Invoice will be returned if they match.
  73 +
59 74 protected $properties; // list of property objects which define the additional properties for this object
60 75  
61 76 // TODO all we have here so far is getAttributes & getProperties
... ... @@ -63,6 +78,9 @@ abstract class CMISObject {
63 78  
64 79 public function __construct()
65 80 {
  81 + // set properties shared by all objects of this type
  82 + $this->_setSharedProperties();
  83 +
66 84 // $propertyDef = new PropertyDefinition();
67 85 // $this->properties[] = $propertyDef;
68 86 }
... ... @@ -78,18 +96,21 @@ abstract class CMISObject {
78 96  
79 97 // TODO look at how chemistry does this and implement something similar
80 98 // for now this is fine as we are just trying to get things up and running :)
81   - $attributes['typeId'] = $this->typeId;
  99 + $attributes['id'] = $this->id;
  100 + $attributes['localName'] = $this->localName;
  101 + $attributes['localNamespace'] = $this->localNamespace;
82 102 $attributes['queryName'] = $this->queryName;
83 103 $attributes['displayName'] = $this->displayName;
84   - $attributes['baseType'] = $this->baseType;
85   - $attributes['baseTypeQueryName'] = $this->baseTypeQueryName;
  104 + $attributes['baseId'] = $this->baseId;
86 105 $attributes['parentId'] = $this->parentId;
87 106 $attributes['description'] = $this->description;
88 107 $attributes['creatable'] = $this->creatable;
89 108 $attributes['fileable'] = $this->fileable;
90 109 $attributes['queryable'] = $this->queryable;
  110 + $attributes['controllablePolicy'] = $this->controllablePolicy;
  111 + $attributes['controllableACL'] = $this->controllableACL;
  112 + $attributes['fulltextIndexed'] = $this->fulltextIndexed;
91 113 $attributes['includedInSupertypeQuery'] = $this->includedInSupertypeQuery;
92   - $attributes['controllable'] = $this->includedInSupertypeQuery;
93 114  
94 115 return $attributes;
95 116 }
... ... @@ -132,15 +153,25 @@ abstract class CMISObject {
132 153 return $this->properties->getValue($property);
133 154 }
134 155  
135   - public function reload($documentId)
  156 + public function reload($objectId)
136 157 {
137   - $this->_get($documentId);
  158 + $this->_get($objectId);
138 159 }
139 160  
140   - private function _get($documentId)
  161 + protected function _get($objectId)
141 162 {
142 163 // override in child classes
143 164 }
  165 +
  166 + /**
  167 + * Sets properties which are shared between all objects of this type
  168 + */
  169 + protected function _setSharedProperties()
  170 + {
  171 + $this->_setPropertyInternal('objectTypeId', strtolower($this->getAttribute('id')));
  172 + // Needed to distinguish type
  173 + $this->_setPropertyInternal('baseTypeId', strtolower($this->getAttribute('id')));
  174 + }
144 175  
145 176 }
146 177  
... ...
lib/api/ktcmis/classes/CMISPropertyCollection.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008,2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -32,8 +32,12 @@
32 32 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33 33 * must display the words "Powered by KnowledgeTree" and retain the original
34 34 * copyright notice.
  35 + * Contributor( s): ______________________________________
  36 + */
  37 +
  38 +/**
35 39 *
36   - * @copyright 2008-2009, KnowledgeTree Inc.
  40 + * @copyright 2008-2010, KnowledgeTree Inc.
37 41 * @license GNU General Public License version 3
38 42 * @author KnowledgeTree Team
39 43 * @package KTCMIS
... ... @@ -45,41 +49,41 @@
45 49 */
46 50 abstract class CMISPropertyCollection {
47 51  
48   - static $ObjectId;
49   - static $BaseType;
50   - static $Uri;
51   - static $ObjectTypeId;
52   - static $CreatedBy;
53   - static $CreationDate;
54   - static $LastModifiedBy;
55   - static $LastModificationDate;
56   - static $ChangeToken;
  52 + static $objectId;
  53 + static $baseTypeId;
  54 + static $uri;
  55 + static $objectTypeId;
  56 + static $createdBy;
  57 + static $creationDate;
  58 + static $lastModifiedBy;
  59 + static $lastModificationDate;
  60 + static $changeToken;
57 61 // TODO these definitions belong in their own classe definition (see property type definions,) but here will do for now
58 62 static public $propertyTypes;
59 63  
60   - function __construct()
  64 + public function __construct()
61 65 {
62   - self::$propertyTypes = array('ObjectId' => 'propertyId',
63   - 'Author' => 'propertyString',
64   - 'BaseType' => 'propertyString',
65   - 'ObjectTypeId' => 'propertyId',
66   - 'CreatedBy' => 'propertyString',
67   - 'CreationDate' => 'propertyDateTime',
68   - 'LastModifiedBy' => 'propertyString',
69   - 'LastModificationDate' => 'propertyDateTime',
70   - 'Name' => 'propertyString',
71   - 'Uri' => 'propertyUri',
72   - 'AllowedChildObjectTypeIds' => 'propertyId',
73   - 'CreatedBy' => 'propertyString',
74   - 'CreationDate' => 'propertyDateTime',
75   - 'ChangeToken' => 'propertyString',
76   - 'ParentId' => 'propertyId');
  66 + self::$propertyTypes = array('objectId' => 'propertyId',
  67 + 'author' => 'propertyString',
  68 + 'baseTypeId' => 'propertyId',
  69 + 'objectTypeId' => 'propertyId',
  70 + 'createdBy' => 'propertyString',
  71 + 'creationDate' => 'propertyDateTime',
  72 + 'lastModifiedBy' => 'propertyString',
  73 + 'lastModificationDate' => 'propertyDateTime',
  74 + 'name' => 'propertyString',
  75 + 'uri' => 'propertyUri',
  76 + 'allowedChildObjectTypeIds' => 'propertyId',
  77 + 'createdBy' => 'propertyString',
  78 + 'creationDate' => 'propertyDateTime',
  79 + 'changeToken' => 'propertyString',
  80 + 'parentId' => 'propertyId');
77 81 }
78 82  
79 83 /**
80 84 * Gets the property value.
81 85 */
82   - function getValue($field)
  86 + public function getValue($field)
83 87 {
84 88 return $this->{$field};
85 89 }
... ... @@ -88,12 +92,12 @@ abstract class CMISPropertyCollection {
88 92 * Sets the property value.
89 93 */
90 94 // for connection-tied live objects
91   - function setValue($field, $value)
  95 + public function setValue($field, $value)
92 96 {
93 97 $this->{$field} = $value;
94 98 }
95 99  
96   - function getFieldType($field)
  100 + public function getFieldType($field)
97 101 {
98 102 return $this->propertyTypes[$field];
99 103 }
... ...
lib/api/ktcmis/classes/CMISRepository.inc.php
... ... @@ -5,7 +5,7 @@
5 5 *
6 6 * KnowledgeTree Community Edition
7 7 * Document Management Made Simple
8   -* Copyright (C) 2008,2009 KnowledgeTree Inc.
  8 +* Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
9 9 *
10 10 *
11 11 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -33,8 +33,12 @@
33 33 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
34 34 * must display the words "Powered by KnowledgeTree" and retain the original
35 35 * copyright notice.
  36 +* Contributor( s): ______________________________________
  37 +*/
  38 +
  39 +/**
36 40 *
37   -* @copyright 2008-2009, KnowledgeTree Inc.
  41 +* @copyright 2008-2010, KnowledgeTree Inc.
38 42 * @license GNU General Public License version 3
39 43 * @author KnowledgeTree Team
40 44 * @package KTCMIS
... ... @@ -80,6 +84,7 @@ class CMISRepository {
80 84 foreach($xml->repository as $repository)
81 85 {
82 86 $currentRepo = $repository->repositoryInfo[0]->repositoryId;
  87 + // TODO this is no longer correct - is an object of SimpleXMLElement and not a string or int
83 88 if ((int)$currentRepo == $this->repositoryId)
84 89 {
85 90 $config = $repository;
... ...
lib/api/ktcmis/classes/CMISRepositoryCapabilities.inc.php
... ... @@ -5,7 +5,7 @@
5 5 *
6 6 * KnowledgeTree Community Edition
7 7 * Document Management Made Simple
8   - * Copyright (C) 2008,2009 KnowledgeTree Inc.
  8 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
9 9 *
10 10 *
11 11 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -33,8 +33,12 @@
33 33 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
34 34 * must display the words "Powered by KnowledgeTree" and retain the original
35 35 * copyright notice.
  36 + * Contributor( s): ______________________________________
  37 + */
  38 +
  39 +/**
36 40 *
37   - * @copyright 2008-2009, KnowledgeTree Inc.
  41 + * @copyright 2008-2010, KnowledgeTree Inc.
38 42 * @license GNU General Public License version 3
39 43 * @author KnowledgeTree Team
40 44 * @package KTCMIS
... ... @@ -42,20 +46,34 @@
42 46 */
43 47  
44 48 class CMISRepositoryCapabilities {
45   -
46   - // boolean values
47   - protected $capabilityMultifiling;
48   - protected $capabilityUnfiling;
49   - protected $capabilityVersionSpecificFiling;
50   - protected $capabilityPWCUpdateable;
51   - protected $capabilityPWCSearchable;
52   - protected $capabilityAllVersionsSearchable;
53   -
54   - // non-boolean values
55   - // TODO these should be defined as classes/enums which will only accept the defined values when set
56   - protected $capabilityQuery;
57   - protected $capabilityFullText;
58   - protected $capabilityJoin;
  49 +
  50 + // TODO we need an enum equivalent class which can be used to define acceptable values for all which are not boolean
  51 +
  52 + // navigation capabilities
  53 + protected $capabilityGetDescendants; // true/false
  54 + protected $capabilityGetFolderTree; // true/false
  55 +
  56 + // object capabilities
  57 + protected $capabilityContentStreamUpdatability; // none/anytime/pwconly
  58 + protected $capabilityChanges; // none/objectidsonly/properties/all
  59 + protected $capabilityRenditions; // none/read
  60 +
  61 + // filing capabilities
  62 + protected $capabilityMultifiling; // true/false
  63 + protected $capabilityUnfiling; // true/false
  64 + protected $capabilityVersionSpecificFiling; // true/false
  65 +
  66 + // versioning capabilities
  67 + protected $capabilityPWCUpdateable; // true/false
  68 + protected $capabilityPWCSearchable; // true/false
  69 + protected $capabilityAllVersionsSearchable; // true/false
  70 +
  71 + // query capabilities
  72 + protected $capabilityQuery; // none/metadataonly/fulltextonly/bothseparate/bothcombined
  73 + protected $capabilityJoin; // none/inneronly/innerandouter
  74 +
  75 + // acl capabilities
  76 + protected $capabilityACL; // none/discover/manage
59 77  
60 78 /**
61 79 * Set a single field value
... ... @@ -63,90 +81,105 @@ class CMISRepositoryCapabilities {
63 81 * @param string $field
64 82 * @param string/int $value
65 83 * @return a collection of repository entries
  84 + *
  85 + * TODO when we have the enum class in place we will need to check whether the value is of type enum and call its set function
  86 + * to ensure that the rules are followed
66 87 */
67 88 function setFieldValue($field, $value)
68 89 {
69 90 $this->{$field} = ($value == 'true' ? true : ($value == 'false' ? false : $value));
70 91 }
71   -
  92 +
72 93 /**
73 94 * Gets the value of the capabilityMultifiling property.
74 95 *
75 96 */
76   - public function hasCapabilityMultifiling() {
77   - return $this->capabilityMultifiling;
  97 + public function hasCapabilityGetDescendants() {
  98 + return $this->capabilityGetDescendants;
78 99 }
79   -
  100 +
80 101 /**
81   - * Sets the value of the capabilityMultifiling property.
  102 + * Gets the value of the capabilityMultifiling property.
82 103 *
83 104 */
84   - public function setCapabilityMultifiling($value) {
85   - $this->capabilityMultifiling = $value;
  105 + public function hasCapabilityGetFolderTree() {
  106 + return $this->capabilityGetFolderTree;
86 107 }
87   -
  108 +
88 109 /**
89   - * Gets the value of the capabilityUnfiling property.
  110 + * Gets the value of the capabilityContentStreamUpdatability property.
  111 + *
  112 + * @return
  113 + * possible object is
  114 + * {@link EnumCapabilityContentStreamUpdatability }
90 115 *
91 116 */
92   - public function hasCapabilityUnfiling() {
93   - return $this->capabilityUnfiling;
  117 + public function getCapabilityContentStreamUpdatability() {
  118 + return $this->capabilityContentStreamUpdatability;
94 119 }
95   -
  120 +
96 121 /**
97   - * Sets the value of the capabilityUnfiling property.
  122 + * Gets the value of the capabilityChanges property.
  123 + *
  124 + * @return
  125 + * possible object is
  126 + * {@link EnumCapabilityChanges }
98 127 *
99 128 */
100   - public function setCapabilityUnfiling($value) {
101   - $this->capabilityUnfiling = $value;
  129 + public function getCapabilityChanges() {
  130 + return $this->capabilityChanges;
102 131 }
103   -
  132 +
104 133 /**
105   - * Gets the value of the capabilityVersionSpecificFiling property.
  134 + * Gets the value of the capabilityRenditions property.
  135 + *
  136 + * @return
  137 + * possible object is
  138 + * {@link EnumCapabilityRenditions }
106 139 *
107 140 */
108   - public function hasCapabilityVersionSpecificFiling() {
109   - return $this->capabilityVersionSpecificFiling;
  141 + public function getCapabilityRenditions() {
  142 + return $this->capabilityRenditions;
110 143 }
111   -
  144 +
112 145 /**
113   - * Sets the value of the capabilityVersionSpecificFiling property.
  146 + * Gets the value of the capabilityMultifiling property.
114 147 *
115 148 */
116   - public function setCapabilityVersionSpecificFiling($value) {
117   - $this->capabilityVersionSpecificFiling = $value;
  149 + public function hasCapabilityMultifiling() {
  150 + return $this->capabilityMultifiling;
118 151 }
119 152  
120 153 /**
121   - * Gets the value of the capabilityPWCUpdateable property.
  154 + * Gets the value of the capabilityUnfiling property.
122 155 *
123 156 */
124   - public function hasCapabilityPWCUpdateable() {
125   - return $this->capabilityPWCUpdateable;
  157 + public function hasCapabilityUnfiling() {
  158 + return $this->capabilityUnfiling;
126 159 }
127   -
  160 +
128 161 /**
129   - * Sets the value of the capabilityPWCUpdateable property.
  162 + * Gets the value of the capabilityVersionSpecificFiling property.
130 163 *
131 164 */
132   - public function setCapabilityPWCUpdateable($value) {
133   - $this->capabilityPWCUpdateable = $value;
  165 + public function hasCapabilityVersionSpecificFiling() {
  166 + return $this->capabilityVersionSpecificFiling;
134 167 }
135 168  
136 169 /**
137   - * Gets the value of the capabilityPWCSearchable property.
  170 + * Gets the value of the capabilityPWCUpdateable property.
138 171 *
139 172 */
140   - public function hasCapabilityPWCSearchable() {
141   - return $this->capabilityPWCSearchable;
  173 + public function hasCapabilityPWCUpdateable() {
  174 + return $this->capabilityPWCUpdateable;
142 175 }
143 176  
144 177 /**
145   - * Sets the value of the capabilityPWCSearchable property.
  178 + * Gets the value of the capabilityPWCSearchable property.
146 179 *
147 180 */
148   - public function setCapabilityPWCSearchable($value) {
149   - $this->capabilityPWCSearchable = $value;
  181 + public function hasCapabilityPWCSearchable() {
  182 + return $this->capabilityPWCSearchable;
150 183 }
151 184  
152 185 /**
... ... @@ -156,15 +189,7 @@ class CMISRepositoryCapabilities {
156 189 public function hasCapabilityAllVersionsSearchable() {
157 190 return $this->capabilityAllVersionsSearchable;
158 191 }
159   -
160   - /**
161   - * Sets the value of the capabilityAllVersionsSearchable property.
162   - *
163   - */
164   - public function setCapabilityAllVersionsSearchable($value) {
165   - $this->capabilityAllVersionsSearchable = $value;
166   - }
167   -
  192 +
168 193 /**
169 194 * Gets the value of the capabilityQuery property.
170 195 *
... ... @@ -178,18 +203,6 @@ class CMISRepositoryCapabilities {
178 203 }
179 204  
180 205 /**
181   - * Sets the value of the capabilityQuery property.
182   - *
183   - * @param value
184   - * allowed object is
185   - * {@link EnumCapabilityQuery }
186   - *
187   - */
188   - public function setCapabilityQuery($value) {
189   - $this->capabilityQuery = $value;
190   - }
191   -
192   - /**
193 206 * Gets the value of the capabilityJoin property.
194 207 *
195 208 * @return
... ... @@ -202,39 +215,15 @@ class CMISRepositoryCapabilities {
202 215 }
203 216  
204 217 /**
205   - * Sets the value of the capabilityJoin property.
206   - *
207   - * @param value
208   - * allowed object is
209   - * {@link EnumCapabilityJoin }
210   - *
211   - */
212   - public function setCapabilityJoin($value) {
213   - $this->capabilityJoin = $value;
214   - }
215   -
216   - /**
217   - * Gets the value of the capabilityFullText property.
  218 + * Gets the value of the capabilityACL property.
218 219 *
219 220 * @return
220 221 * possible object is
221   - * {@link EnumCapabilityFullText }
222   - *
223   - */
224   - public function getCapabilityFullText() {
225   - return $this->capabilityFullText;
226   - }
227   -
228   - /**
229   - * Sets the value of the capabilityFullText property.
230   - *
231   - * @param value
232   - * allowed object is
233   - * {@link EnumCapabilityFullText }
  222 + * {@link EnumCapabilityACL }
234 223 *
235 224 */
236   - public function setCapabilityFullText($value) {
237   - $this->capabilityFullText = $value;
  225 + public function getCapabilityACL() {
  226 + return $this->capabilityACL;
238 227 }
239 228  
240 229 // /**
... ...
lib/api/ktcmis/classes/CMISRepositoryInfo.inc.php
... ... @@ -5,7 +5,7 @@
5 5 *
6 6 * KnowledgeTree Community Edition
7 7 * Document Management Made Simple
8   - * Copyright (C) 2008,2009 KnowledgeTree Inc.
  8 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
9 9 *
10 10 *
11 11 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -33,8 +33,12 @@
33 33 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
34 34 * must display the words "Powered by KnowledgeTree" and retain the original
35 35 * copyright notice.
  36 + * Contributor( s): ______________________________________
  37 + */
  38 +
  39 +/**
36 40 *
37   - * @copyright 2008-2009, KnowledgeTree Inc.
  41 + * @copyright 2008-2010, KnowledgeTree Inc.
38 42 * @license GNU General Public License version 3
39 43 * @author KnowledgeTree Team
40 44 * @package KTCMIS
... ...
lib/api/ktcmis/classes/Enum.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +/**
  4 + * Base class for enumerators
  5 + */
  6 +
  7 +// TODO enable creation of enum instances on the fly - this will most likely be done in an extending class
  8 +
  9 +abstract class Enum {
  10 +
  11 + // actual implementation of these will be in child classes
  12 + static protected $name;
  13 + static protected $values;
  14 + static protected $value;
  15 +
  16 + /**
  17 + * Sets the value of the enumerator
  18 + *
  19 + * @param unknown_type $value
  20 + * @throws invalidArgumentException if the given value does not match one of the allowed values
  21 + *
  22 + * Extending classes may override this function to add their own additional rules for how an enum may be set,
  23 + * but they should always call this parent function afterward to invoke the base rule that the value must be
  24 + * one of the defined values
  25 + */
  26 + static protected function set($value)
  27 + {
  28 + if (!in_array($value, self::$values)) {
  29 + throw new InvalidArgumentException("Unable to set value for $name: Illegal input ($value)");
  30 + }
  31 +
  32 + self::$value = $value;
  33 + }
  34 +
  35 + /**
  36 + * Returns the currently set value, or null if unset
  37 + *
  38 + * @return $value the currently set value
  39 + */
  40 + static protected function get()
  41 + {
  42 + return self::$value;
  43 + }
  44 +
  45 +}
  46 +
  47 +?>
0 48 \ No newline at end of file
... ...
lib/api/ktcmis/config/repositories.xml
... ... @@ -4,8 +4,7 @@
4 4 Document : repositories.xml
5 5 Created on : 25 May 2009, 10:33 AM
6 6 Author : KnowledgeTree Team
7   - Description:
8   - Contains definitions for all repositories accessible via the CMIS API.
  7 + Description: Contains definitions for all repositories accessible via the CMIS API.
9 8 -->
10 9  
11 10 <!--
... ... @@ -30,15 +29,20 @@
30 29 <cmisVersionsSupported>0.61</cmisVersionsSupported>
31 30 </repositoryInfo>
32 31 <repositoryCapabilities>
  32 + <capabilityGetDescendants>true</capabilityGetDescendants>
  33 + <capabilityGetFolderTree>true</capabilityGetFolderTree>
  34 + <capabilityContentStreamUpdatability>pwconly</capabilityContentStreamUpdatability>
  35 + <capabilityChanges>none</capabilityChanges>
  36 + <capabilityRenditions>none</capabilityRenditions>
33 37 <capabilityMultifiling>false</capabilityMultifiling>
34 38 <capabilityUnfiling>false</capabilityUnfiling>
35 39 <capabilityVersionSpecificFiling>false</capabilityVersionSpecificFiling>
36 40 <capabilityPWCUpdateable>false</capabilityPWCUpdateable>
37 41 <capabilityPWCSearchable>false</capabilityPWCSearchable>
38 42 <capabilityAllVersionsSearchable>false</capabilityAllVersionsSearchable>
39   - <capabilityQuery>None</capabilityQuery>
40   - <capabilityFullText>None</capabilityFullText>
41   - <capabilityJoin>NoJoin</capabilityJoin>
  43 + <capabilityQuery>none</capabilityQuery>
  44 + <capabilityJoin>none</capabilityJoin>
  45 + <capabilityACL>none</capabilityACL>
42 46 </repositoryCapabilities>
43 47 <supportedTypes>
44 48 <objectType>Document</objectType>
... ...
lib/api/ktcmis/enums/EnumCapabilityACL.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +/**
  4 + * Enumaerator class for capabilityACL
  5 + */
  6 +
  7 +require_once(realpath(dirname(__FILE__) . '/../../../../config/dmsDefaults.php'));
  8 +
  9 +define ('CMIS_DIR', KT_LIB_DIR . '/api/ktcmis');
  10 +require_once(CMIS_DIR . '/classes/Enum.inc.php');
  11 +
  12 +class EnumCapabilityACL extends Enum {
  13 +
  14 + static protected $name = 'capabilityACL';
  15 + static protected $values = array('none', 'discover', 'manage');
  16 +
  17 + /**
  18 + * Sets the value of the enumerator
  19 + *
  20 + * @param unknown_type $value
  21 + * @throws invalidArgumentException if the given value does not match one of the allowed values
  22 + * (exception is thrown in parent class function)
  23 + */
  24 + static protected function set($value)
  25 + {
  26 + parent::set($value);
  27 + }
  28 +
  29 +}
  30 +
  31 +?>
0 32 \ No newline at end of file
... ...
lib/api/ktcmis/enums/EnumCapabilityChanges.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +/**
  4 + * Enumaerator class for capabilityChanges
  5 + */
  6 +
  7 +require_once(realpath(dirname(__FILE__) . '/../../../../config/dmsDefaults.php'));
  8 +
  9 +define ('CMIS_DIR', KT_LIB_DIR . '/api/ktcmis');
  10 +require_once(CMIS_DIR . '/classes/Enum.inc.php');
  11 +
  12 +class EnumCapabilityChanges extends Enum {
  13 +
  14 + static protected $name = 'capabilityChanges';
  15 + static protected $values = array('none', 'objectidsonly', 'properties', 'all');
  16 +
  17 + /**
  18 + * Sets the value of the enumerator
  19 + *
  20 + * @param unknown_type $value
  21 + * @throws invalidArgumentException if the given value does not match one of the allowed values
  22 + * (exception is thrown in parent class function)
  23 + */
  24 + static protected function set($value)
  25 + {
  26 + parent::set($value);
  27 + }
  28 +
  29 +}
  30 +
  31 +?>
0 32 \ No newline at end of file
... ...
lib/api/ktcmis/enums/EnumCapabilityContentStreamUpdatability.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +/**
  4 + * Enumaerator class for capabilityContentStreamUpdatability
  5 + */
  6 +
  7 +require_once(realpath(dirname(__FILE__) . '/../../../../config/dmsDefaults.php'));
  8 +
  9 +define ('CMIS_DIR', KT_LIB_DIR . '/api/ktcmis');
  10 +require_once(CMIS_DIR . '/classes/Enum.inc.php');
  11 +
  12 +class EnumCapabilityContentStreamUpdatability extends Enum {
  13 +
  14 + static protected $name = 'capabilityContentStreamUpdatability';
  15 + static protected $values = array('none', 'anytime', 'pwconly');
  16 +
  17 + /**
  18 + * Sets the value of the enumerator
  19 + *
  20 + * @param unknown_type $value
  21 + * @throws invalidArgumentException if the given value does not match one of the allowed values
  22 + * (exception is thrown in parent class function)
  23 + */
  24 + static protected function set($value)
  25 + {
  26 + parent::set($value);
  27 + }
  28 +
  29 +}
  30 +
  31 +?>
0 32 \ No newline at end of file
... ...
lib/api/ktcmis/enums/EnumCapabilityJoin.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +/**
  4 + * Enumaerator class for capabilityJoin
  5 + */
  6 +
  7 +require_once(realpath(dirname(__FILE__) . '/../../../../config/dmsDefaults.php'));
  8 +
  9 +define ('CMIS_DIR', KT_LIB_DIR . '/api/ktcmis');
  10 +require_once(CMIS_DIR . '/classes/Enum.inc.php');
  11 +
  12 +class EnumCapabilityJoin extends Enum {
  13 +
  14 + static protected $name = 'capabilityJoin';
  15 + static protected $values = array('none', 'inneronly', 'innerandouter');
  16 +
  17 + /**
  18 + * Sets the value of the enumerator
  19 + *
  20 + * @param unknown_type $value
  21 + * @throws invalidArgumentException if the given value does not match one of the allowed values
  22 + * (exception is thrown in parent class function)
  23 + */
  24 + static protected function set($value)
  25 + {
  26 + parent::set($value);
  27 + }
  28 +
  29 +}
  30 +
  31 +?>
0 32 \ No newline at end of file
... ...
lib/api/ktcmis/enums/EnumCapabilityQuery.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +/**
  4 + * Enumaerator class for capabilityQuery
  5 + */
  6 +
  7 +require_once(realpath(dirname(__FILE__) . '/../../../../config/dmsDefaults.php'));
  8 +
  9 +define ('CMIS_DIR', KT_LIB_DIR . '/api/ktcmis');
  10 +require_once(CMIS_DIR . '/classes/Enum.inc.php');
  11 +
  12 +class EnumCapabilityQuery extends Enum {
  13 +
  14 + static protected $name = 'capabilityQuery';
  15 + static protected $values = array('none', 'metadataonly', 'fulltextonly', 'bothseparate', 'bothcombined');
  16 +
  17 + /**
  18 + * Sets the value of the enumerator
  19 + *
  20 + * @param unknown_type $value
  21 + * @throws invalidArgumentException if the given value does not match one of the allowed values
  22 + * (exception is thrown in parent class function)
  23 + */
  24 + static protected function set($value)
  25 + {
  26 + parent::set($value);
  27 + }
  28 +
  29 +}
  30 +
  31 +?>
0 32 \ No newline at end of file
... ...
lib/api/ktcmis/enums/EnumCapabilityRenditions.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +/**
  4 + * Enumaerator class for capabilityRenditions
  5 + */
  6 +
  7 +require_once(realpath(dirname(__FILE__) . '/../../../../config/dmsDefaults.php'));
  8 +
  9 +define ('CMIS_DIR', KT_LIB_DIR . '/api/ktcmis');
  10 +require_once(CMIS_DIR . '/classes/Enum.inc.php');
  11 +
  12 +class EnumCapabilityRenditions extends Enum {
  13 +
  14 + static protected $name = 'capabilityRenditions';
  15 + static protected $values = array('none', 'objectidsonly', 'properties', 'all');
  16 +
  17 + /**
  18 + * Sets the value of the enumerator
  19 + *
  20 + * @param unknown_type $value
  21 + * @throws invalidArgumentException if the given value does not match one of the allowed values
  22 + * (exception is thrown in parent class function)
  23 + */
  24 + static protected function set($value)
  25 + {
  26 + parent::set($value);
  27 + }
  28 +
  29 +}
  30 +
  31 +?>
0 32 \ No newline at end of file
... ...
lib/api/ktcmis/exceptions/PermissionDeniedException.inc.php renamed to lib/api/ktcmis/exceptions/NameConstraintViolationException.inc.php
1 1 <?php
2 2  
3   -class PermissionDeniedException extends Exception {
  3 +class NameConstraintViolationException extends Exception {
4 4  
5 5 }
6 6  
... ...
lib/api/ktcmis/ktNavigationService.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   -* Copyright (C) 2008,2009 KnowledgeTree Inc.
  7 +* Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -32,8 +32,12 @@
32 32 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33 33 * must display the words "Powered by KnowledgeTree" and retain the original
34 34 * copyright notice.
  35 +* Contributor( s): ______________________________________
  36 +*/
  37 +
  38 +/**
35 39 *
36   -* @copyright 2008-2009, KnowledgeTree Inc.
  40 +* @copyright 2008-2010, KnowledgeTree Inc.
37 41 * @license GNU General Public License version 3
38 42 * @author KnowledgeTree Team
39 43 * @package KTCMIS
... ... @@ -76,19 +80,20 @@ class KTNavigationService extends KTCMISBase {
76 80 *
77 81 * @param string $repositoryId
78 82 * @param string $folderId
79   - * @param boolean $includeAllowableActions
80   - * @param boolean $includeRelationships
81   - * @param string $typeID
82 83 * @param int $depth
83 84 * @param string $filter
  85 + * @param boolean $includeRelationships
  86 + * @param string $renditionFilter
  87 + * @param boolean $includeAllowableAc
84 88 * @return array $descendants
85 89 */
86   - public function getDescendants($repositoryId, $folderId, $includeAllowableActions, $includeRelationships,
87   - $depth = 1, $typeID = 'Any', $filter = '')
  90 + public function getDescendants($repositoryId, $folderId, $depth = 2, $filter = '', $includeRelationships = false, $renditionFilter = '',
  91 + $includeAllowableActions = false, $includePathSegment = false)
88 92 {
89 93 // TODO optional parameters
90   - $descendantsResult = $this->NavigationService->getDescendants($repositoryId, $folderId, $includeAllowableActions,
91   - $includeRelationships, $depth);
  94 + $descendantsResult = $this->NavigationService->getDescendants($repositoryId, $folderId, $depth, $filter,
  95 + $includeRelationships = false, $renditionFilter = '',
  96 + $includeAllowableActions = false, $includePathSegment = false);
92 97  
93 98 if (PEAR::isError($descendantsResult))
94 99 {
... ... @@ -97,11 +102,11 @@ class KTNavigationService extends KTCMISBase {
97 102 "message" => "Failed getting descendants for folder"
98 103 );
99 104 }
100   -
  105 +
101 106 // format for webservices consumption
102 107 // NOTE this will almost definitely be changing in the future, this is just to get something working
103   - $descendants = CMISUtil::decodeObjectHierarchy($descendantsResult, 'child');
104   -
  108 + $descendants = CMISUtil::decodeObjectHierarchy($descendantsResult, 'children');
  109 +
105 110 return array (
106 111 "status_code" => 0,
107 112 "results" => $descendants
... ... @@ -122,7 +127,7 @@ class KTNavigationService extends KTCMISBase {
122 127 * @return array $descendants
123 128 */
124 129 public function getChildren($repositoryId, $folderId, $includeAllowableActions, $includeRelationships,
125   - $typeID = 'Any', $filter = '', $maxItems = 0, $skipCount = 0)
  130 + $typeID = 'Any', $filter = '', $maxItems = 0, $skipCount = 0)
126 131 {
127 132 // TODO paging
128 133 // TODO optional parameters
... ... @@ -132,11 +137,11 @@ class KTNavigationService extends KTCMISBase {
132 137 {
133 138 return array(
134 139 "status_code" => 1,
135   - "message" => "Failed getting descendants for folder"
  140 + "message" => "Failed getting children for folder"
136 141 );
137 142 }
138 143  
139   - $children = CMISUtil::decodeObjectHierarchy($childrenResult, 'child');
  144 + $children = CMISUtil::decodeObjectHierarchy($childrenResult, 'children');
140 145  
141 146 return array(
142 147 "status_code" => 0,
... ... @@ -149,38 +154,32 @@ class KTNavigationService extends KTCMISBase {
149 154 *
150 155 * @param string $repositoryId
151 156 * @param string $folderId
152   - * @param boolean $includeAllowableActions
153   - * @param boolean $includeRelationships
154   - * @param boolean $returnToRoot
155 157 * @param string $filter
156   - * @return ancestry[]
  158 + * @return parent[]
157 159 */
158   - public function getFolderParent($repositoryId, $folderId, $includeAllowableActions, $includeRelationships, $returnToRoot, $filter = '')
  160 + public function getFolderParent($repositoryId, $folderId, $filter = '')
159 161 {
160 162 try {
161   - $ancestryResult = $this->NavigationService->getFolderParent($repositoryId, $folderId, $includeAllowableActions,
162   - $includeRelationships, $returnToRoot);
  163 + $parent = $this->NavigationService->getFolderParent($repositoryId, $folderId, $filter);
163 164 }
164 165 catch (Exception $e) {
165 166 return array(
166 167 "status_code" => 1,
167   - "message" => "Failed getting ancestry for folder: " . $e->getMessage()
  168 + "message" => "Failed getting folder parent: " . $e->getMessage()
168 169 );
169 170 }
170   -
171   - if (PEAR::isError($ancestryResult))
  171 +
  172 + if (PEAR::isError($parent))
172 173 {
173 174 return array(
174 175 "status_code" => 1,
175   - "message" => "Failed getting ancestry for folder"
  176 + "message" => "Failed getting folder parent"
176 177 );
177 178 }
178   -
179   - $ancestry = CMISUtil::decodeObjectHierarchy($ancestryResult, 'child');
180   -
  179 +
181 180 return array(
182 181 "status_code" => 0,
183   - "results" => $ancestry
  182 + "results" => CMISUtil::createObjectPropertiesEntry($parent->getProperties())
184 183 );
185 184 }
186 185  
... ... @@ -196,10 +195,18 @@ class KTNavigationService extends KTCMISBase {
196 195 */
197 196 function getObjectParents($repositoryId, $objectId, $includeAllowableActions, $includeRelationships, $filter = '')
198 197 {
199   - $ancestryResult = $this->NavigationService->getObjectParents($repositoryId, $objectId, $includeAllowableActions,
200   - $includeRelationships);
  198 + try {
  199 + $ancestry = $this->NavigationService->getObjectParents($repositoryId, $objectId, $includeAllowableActions,
  200 + $includeRelationships);
  201 + }
  202 + catch (Exception $e) {
  203 + return array(
  204 + "status_code" => 1,
  205 + "message" => $e->getMessage()
  206 + );
  207 + }
201 208  
202   - if (PEAR::isError($ancestryResult))
  209 + if (PEAR::isError($ancestry))
203 210 {
204 211 return array(
205 212 "status_code" => 1,
... ... @@ -207,8 +214,6 @@ class KTNavigationService extends KTCMISBase {
207 214 );
208 215 }
209 216  
210   - $ancestry = CMISUtil::decodeObjectHierarchy($ancestryResult, 'child');
211   -
212 217 return array(
213 218 "status_code" => 0,
214 219 "results" => $ancestry
... ... @@ -220,18 +225,27 @@ class KTNavigationService extends KTCMISBase {
220 225 *
221 226 * @param string $repositoryId
222 227 * @param string $folderId The folder for which checked out docs are requested
223   - * @param string $filter
224   - * @param boolean $includeAllowableActions
225   - * @param boolean $includeRelationships
226 228 * @param int $maxItems
227 229 * @param int $skipCount
228   - * @return array $checkedout The collection of checked out documents
  230 + * @param string $filter
  231 + * @param enum $includeRelationships
  232 + * @param boolean $includeAllowableActions
  233 + * @param string $renditionFilter
  234 + * @return array $checkedout The collection of checked out document objects
  235 + * MUST include (unless not requested) for each object:
  236 + * array $properties
  237 + * array $relationships
  238 + * array $renditions
  239 + * $allowableActions
  240 + * @return boolean $hasMoreItems
  241 + * @return int $numItems [optional]
229 242 */
230   - function getCheckedOutDocs($repositoryId, $includeAllowableActions, $includeRelationships, $folderId = null, $filter = '',
231   - $maxItems = 0, $skipCount = 0)
  243 + function getCheckedOutDocs($repositoryId, $folderId = null, $maxItems = 0, $skipCount = 0, $orderBy = '',
  244 + $filter = '', $includeRelationships = null, $includeAllowableActions = false, $renditionFilter = '')
232 245 {
233   - $checkedout = $this->NavigationService->getCheckedOutDocs($repositoryId, $includeAllowableActions, $includeRelationships,
234   - $folderId, $filter, $maxItems, $skipCount);
  246 + $checkedout = $this->NavigationService->getCheckedOutDocs($repositoryId, $folderId = null, $maxItems = 0, $skipCount = 0,
  247 + $orderBy, $filter, $includeRelationships, $includeAllowableActions,
  248 + $renditionFilter);
235 249  
236 250 if (PEAR::isError($checkedout))
237 251 {
... ...
lib/api/ktcmis/ktObjectService.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   -* Copyright (C) 2008,2009 KnowledgeTree Inc.
  7 +* Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -32,8 +32,12 @@
32 32 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33 33 * must display the words "Powered by KnowledgeTree" and retain the original
34 34 * copyright notice.
  35 +* Contributor( s): ______________________________________
  36 +*/
  37 +
  38 +/**
35 39 *
36   -* @copyright 2008-2009, KnowledgeTree Inc.
  40 +* @copyright 2008-2010, KnowledgeTree Inc.
37 41 * @license GNU General Public License version 3
38 42 * @author KnowledgeTree Team
39 43 * @package KTCMIS
... ... @@ -76,17 +80,13 @@ class KTObjectService extends KTCMISBase {
76 80 *
77 81 * @param string $repositoryId
78 82 * @param string $objectId
79   - * @param boolean $includeAllowableActions
80   - * @param boolean $includeRelationships
81   - * @param string $returnVersion
82 83 * @param string $filter
83 84 * @return properties[]
84 85 */
85   - public function getProperties($repositoryId, $objectId, $includeAllowableActions, $includeRelationships,
86   - $returnVersion = false, $filter = '')
  86 + public function getProperties($repositoryId, $objectId, $filter = '')
87 87 {
88 88 try {
89   - $propertyCollection = $this->ObjectService->getProperties($repositoryId, $objectId, $includeAllowableActions,
  89 + $properties = $this->ObjectService->getProperties($repositoryId, $objectId, $includeAllowableActions,
90 90 $includeRelationships);
91 91 }
92 92 catch (Exception $e)
... ... @@ -97,8 +97,6 @@ class KTObjectService extends KTCMISBase {
97 97 );
98 98 }
99 99  
100   - $properties = CMISUtil::createObjectPropertiesEntry($propertyCollection);
101   -
102 100 return array(
103 101 "status_code" => 0,
104 102 "results" => $properties
... ... @@ -109,22 +107,24 @@ class KTObjectService extends KTCMISBase {
109 107 * Creates a new document within the repository
110 108 *
111 109 * @param string $repositoryId The repository to which the document must be added
112   - * @param string $typeId Object Type id for the document object being created
113 110 * @param array $properties Array of properties which must be applied to the created document object
114 111 * @param string $folderId The id of the folder which will be the parent of the created document object
115 112 * This parameter is optional IF unfilingCapability is supported
116   - * @param contentStream $contentStream optional content stream data
117   - * @param string $versioningState optional version state value: checkedout/major/minor
  113 + * @param string $contentStream optional content stream data - expected as a base64 encoded string
  114 + * @param string $versioningState optional version state value: none/checkedout/major/minor
  115 + * @param $policies List of policy ids that MUST be applied
  116 + * @param $addACEs List of ACEs that MUST be added
  117 + * @param $removeACEs List of ACEs that MUST be removed
118 118 * @return string $objectId The id of the created folder object
119 119 */
120   - public function createDocument($repositoryId, $typeId, $properties, $folderId = null,
121   - $contentStream = null, $versioningState = null)
  120 + public function createDocument($repositoryId, $properties, $folderId = null, $contentStream = null, $versioningState = 'none',
  121 + $policies = array(), $addACEs = array(), $removeACEs = array())
122 122 {
123 123 $objectId = null;
124 124  
125 125 try {
126   - $objectId = $this->ObjectService->createDocument($repositoryId, $typeId, $properties, $folderId,
127   - $contentStream, $versioningState);
  126 + $objectId = $this->ObjectService->createDocument($repositoryId, $properties, $folderId, $contentStream,
  127 + $versioningState,$policies, $addACEs, $removeACEs);
128 128 }
129 129 catch (Exception $e)
130 130 {
... ... @@ -144,17 +144,19 @@ class KTObjectService extends KTCMISBase {
144 144 * Creates a new folder within the repository
145 145 *
146 146 * @param string $repositoryId The repository to which the folder must be added
147   - * @param string $typeId Object Type id for the folder object being created
148 147 * @param array $properties Array of properties which must be applied to the created folder object
149 148 * @param string $folderId The id of the folder which will be the parent of the created folder object
  149 + * @param array $policies List of policy ids that MUST be applied
  150 + * @param $addACEs List of ACEs that MUST be added
  151 + * @param $removeACEs List of ACEs that MUST be removed
150 152 * @return string $objectId The id of the created folder object
151 153 */
152   - public function createFolder($repositoryId, $typeId, $properties, $folderId)
  154 + public function createFolder($repositoryId, $properties, $folderId, $policies = array(), $addACEs = array(), $removeACEs = array())
153 155 {
154 156 $objectId = null;
155 157  
156 158 try {
157   - $objectId = $this->ObjectService->createFolder($repositoryId, $typeId, $properties, $folderId);
  159 + $objectId = $this->ObjectService->createFolder($repositoryId, $properties, $folderId, $policies, $addACEs, $removeACEs);
158 160 }
159 161 catch (Exception $e)
160 162 {
... ... @@ -175,12 +177,13 @@ class KTObjectService extends KTCMISBase {
175 177 *
176 178 * @param string $repositoryId
177 179 * @param string $objectId
  180 + * @param string $streamId [optional for documents] Specifies the rendition to retrieve if not original document
178 181 * @return string $contentStream (binary or text data)
179 182 */
180   - function getContentStream($repositoryId, $objectId)
  183 + function getContentStream($repositoryId, $objectId, $streamId = null)
181 184 {
182 185 try {
183   - $contentStream = $this->ObjectService->getContentStream($repositoryId, $objectId);
  186 + $contentStream = $this->ObjectService->getContentStream($repositoryId, $objectId, $streamId);
184 187 }
185 188 catch (Exception $e)
186 189 {
... ... @@ -199,16 +202,16 @@ class KTObjectService extends KTCMISBase {
199 202 /**
200 203 * Moves a fileable object from one folder to another.
201 204 *
202   - * @param object $repositoryId
203   - * @param object $objectId
204   - * @param object $changeToken [optional]
205   - * @param object $targetFolderId
206   - * @param object $sourceFolderId [optional]
  205 + * @param string $repositoryId
  206 + * @param string $objectId
  207 + * @param string $targetFolderId
  208 + * @param string $sourceFolderId
  209 + * @return string $objectId
207 210 */
208   - public function moveObject($repositoryId, $objectId, $changeToken = '', $targetFolderId, $sourceFolderId = null)
  211 + public function moveObject($repositoryId, $objectId, $targetFolderId, $sourceFolderId)
209 212 {
210 213 try {
211   - $this->ObjectService->moveObject($repositoryId, $objectId, $changeToken, $targetFolderId, $sourceFolderId);
  214 + $this->ObjectService->moveObject($repositoryId, $objectId, $targetFolderId, $sourceFolderId);
212 215 }
213 216 catch (Exception $e)
214 217 {
... ... @@ -229,15 +232,13 @@ class KTObjectService extends KTCMISBase {
229 232 *
230 233 * @param string $repositoryId
231 234 * @param string $objectId
232   - * @param string $changeToken [optional]
  235 + * @param string $allVersions [optional] If true, delete all versions
233 236 * @return array
234 237 */
235   - // NOTE Invoking this service method on an object SHALL not delete the entire version series for a Document Object.
236   - // To delete an entire version series, use the deleteAllVersions() service
237   - public function deleteObject($repositoryId, $objectId, $changeToken = null)
  238 + public function deleteObject($repositoryId, $objectId, $allVersions = true)
238 239 {
239 240 try {
240   - $this->ObjectService->deleteObject($repositoryId, $objectId, $changeToken);
  241 + $this->ObjectService->deleteObject($repositoryId, $objectId, $allVersions);
241 242 }
242 243 catch (Exception $e)
243 244 {
... ...
lib/api/ktcmis/ktRepositoryService.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   -* Copyright (C) 2008,2009 KnowledgeTree Inc.
  7 +* Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -32,8 +32,12 @@
32 32 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33 33 * must display the words "Powered by KnowledgeTree" and retain the original
34 34 * copyright notice.
  35 +* Contributor( s): ______________________________________
  36 +*/
  37 +
  38 +/**
35 39 *
36   -* @copyright 2008-2009, KnowledgeTree Inc.
  40 +* @copyright 2008-2010, KnowledgeTree Inc.
37 41 * @license GNU General Public License version 3
38 42 * @author KnowledgeTree Team
39 43 * @package KTCMIS
... ... @@ -82,7 +86,7 @@ class KTRepositoryService extends KTCMISBase {
82 86 {
83 87 $repositoryList[$count]['repositoryId'] = $repository->getRepositoryId();
84 88 $repositoryList[$count]['repositoryName'] = $repository->getRepositoryName();
85   - $repositoryList[$count]['repositoryURI'] = $repository->getRepositoryURI();
  89 + //$repositoryList[$count]['repositoryURI'] = $repository->getRepositoryURI();
86 90 ++$count;
87 91 }
88 92  
... ... @@ -161,25 +165,14 @@ class KTRepositoryService extends KTCMISBase {
161 165 public function getTypeDefinition($repositoryId, $typeId)
162 166 {
163 167 try {
164   - $typeDefinitionResult = $this->RepositoryService->getTypeDefinition($repositoryId, $typeId);
  168 + $typeDefinition = $this->RepositoryService->getTypeDefinition($repositoryId, $typeId);
165 169 }
166   - catch (Exception $e)
167   - {
168   - return array(
169   - "status_code" => 1,
170   - "message" => $e->getMessage()
171   - );
  170 + catch (Exception $e) {
  171 + // propogate upward
  172 + throw $e;
172 173 }
173   -
174   - // format as array style output
175   - // NOTE only concerned with attributes at this time
176   - // TODO add support for properties
177   - $typeDefinition = $typeDefinitionResult['attributes'];
178   -
179   - return array (
180   - "status_code" => 0,
181   - "results" => $typeDefinition
182   - );
  174 +
  175 + return $typeDefinition;
183 176 }
184 177  
185 178 }
... ...
lib/api/ktcmis/ktService.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   -* Copyright (C) 2008,2009 KnowledgeTree Inc.
  7 +* Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -32,8 +32,12 @@
32 32 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33 33 * must display the words "Powered by KnowledgeTree" and retain the original
34 34 * copyright notice.
  35 +* Contributor( s): ______________________________________
  36 +*/
  37 +
  38 +/**
35 39 *
36   -* @copyright 2008-2009, KnowledgeTree Inc.
  40 +* @copyright 2008-2010, KnowledgeTree Inc.
37 41 * @license GNU General Public License version 3
38 42 * @author KnowledgeTree Team
39 43 * @package KTCMIS
... ... @@ -44,7 +48,6 @@ require_once(realpath(dirname(__FILE__) . &#39;/../../../config/dmsDefaults.php&#39;));
44 48 require_once(KT_DIR . '/ktapi/ktapi.inc.php');
45 49  
46 50 define ('CMIS_DIR', KT_LIB_DIR . '/api/ktcmis');
47   -require_once(CMIS_DIR . '/exceptions/PermissionDeniedException.inc.php');
48 51 require_once(CMIS_DIR . '/util/CMISUtil.inc.php');
49 52  
50 53 /**
... ...
lib/api/ktcmis/ktVersioningService.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   -* Copyright (C) 2008,2009 KnowledgeTree Inc.
  7 +* Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -32,8 +32,12 @@
32 32 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33 33 * must display the words "Powered by KnowledgeTree" and retain the original
34 34 * copyright notice.
  35 +* Contributor( s): ______________________________________
  36 +*/
  37 +
  38 +/**
35 39 *
36   -* @copyright 2008-2009, KnowledgeTree Inc.
  40 +* @copyright 2008-2010, KnowledgeTree Inc.
37 41 * @license GNU General Public License version 3
38 42 * @author KnowledgeTree Team
39 43 * @package KTCMIS
... ... @@ -77,44 +81,17 @@ class KTVersioningService extends KTCMISBase {
77 81 }
78 82  
79 83 /**
80   - * Deletes all Document Objects in the specified Version Series, including the Private Working Copy
81   - *
82   - * @param string $repositoryId
83   - * @param string $versionSeriesId
84   - * @return boolean true if successful
85   - */
86   - public function deleteAllVersions($repositoryId, $versionSeriesId)
87   - {
88   - try {
89   - $result = $this->VersioningService->deleteAllVersions($repositoryId, $versionSeriesId);
90   - }
91   - catch (Exception $e)
92   - {
93   - return array(
94   - "status_code" => 1,
95   - "message" => $e->getMessage()
96   - );
97   - }
98   -
99   - return array(
100   - 'status_code' => 0,
101   - 'results' => $result
102   - );
103   - }
104   -
105   - /**
106 84 * Checks out a document and creates the PWC (Private Working Copy) which will represent the checked out document
107 85 *
108 86 * @param string $repositoryId
109   - * @param string $documentId
110   - * @param string $changeToken [optional]
  87 + * @param string $objectId
111 88 * @return array results
112 89 */
113 90 // TODO set up delivery of content stream? or is that up to the CMIS client?
114   - public function checkOut($repositoryId, $documentId, $changeToken = '')
  91 + public function checkOut($repositoryId, $objectId)
115 92 {
116 93 try {
117   - $result = $this->VersioningService->checkOut($repositoryId, $documentId, $changeToken);
  94 + $result = $this->VersioningService->checkOut($repositoryId, $objectId);
118 95 }
119 96 catch (Exception $e)
120 97 {
... ... @@ -134,18 +111,17 @@ class KTVersioningService extends KTCMISBase {
134 111 * Reverses the effect of a checkout: I.E. deletes the PWC (Private Working Copy) and re-sets the status of the document to "not checked out"
135 112 *
136 113 * @param string $repositoryId
137   - * @param string $documentId
138   - * @param string $changeToken [optional]
  114 + * @param string $objectId
139 115 */
140 116 // TODO exceptions:
141 117 // โ€ข ConstraintViolationException: The Repository SHALL throw this exception if ANY of the following conditions are met:
142 118 // o The Documentโ€™s Object-Type definitionโ€™s versionable attribute is FALSE.
143 119 // โ€ข updateConflictException
144 120 // โ€ข versioningException
145   - public function cancelCheckOut($repositoryId, $documentId, $changeToken = '')
  121 + public function cancelCheckOut($repositoryId, $objectId)
146 122 {
147 123 try {
148   - $result = $this->VersioningService->cancelCheckOut($repositoryId, $documentId, $changeToken);
  124 + $result = $this->VersioningService->cancelCheckOut($repositoryId, $objectId);
149 125 }
150 126 catch (Exception $e)
151 127 {
... ... @@ -165,18 +141,22 @@ class KTVersioningService extends KTCMISBase {
165 141 * Checks in a checked out document
166 142 *
167 143 * @param string $repositoryId
168   - * @param string $documentId
169   - * @param boolean $major
170   - * @param string $changeToken [optional]
  144 + * @param string $objectId
  145 + * @param boolean $major [optional] defaults to true
171 146 * @param array $properties [optional]
172 147 * @param contentStream $contentStream [optional]
173 148 * @param string $checkinComment [optional]
174   - * @return string $documentId
  149 + * @param array $policies
  150 + * @param array $addACEs
  151 + * @param array $removeACEs
  152 + * @return string $objectId
175 153 */
176   - public function checkIn($repositoryId, $documentId, $major, $contentStream = null, $changeToken = '', $properties = array(), $checkinComment = '')
  154 + public function checkIn($repositoryId, $objectId, $major = true, $properties = array(), $contentStream = null,
  155 + $checkinComment = '', $policies = array(), $addACEs = array(), $removeACEs = array())
177 156 {
178 157 try {
179   - $result = $this->VersioningService->checkIn($repositoryId, $documentId, $major, $contentStream, $changeToken, $properties, $checkinComment);
  158 + $result = $this->VersioningService->checkIn($repositoryId, $objectId, $major, $properties, $contentStream,
  159 + $checkinComment, $policies, $addACEs, $removeACEs);
180 160 }
181 161 catch (Exception $e)
182 162 {
... ...
lib/api/ktcmis/objecttypes/CMISDocumentObject.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008,2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -32,8 +32,12 @@
32 32 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33 33 * must display the words "Powered by KnowledgeTree" and retain the original
34 34 * copyright notice.
  35 + * Contributor( s): ______________________________________
  36 + */
  37 +
  38 +/**
35 39 *
36   - * @copyright 2008-2009, KnowledgeTree Inc.
  40 + * @copyright 2008-2010, KnowledgeTree Inc.
37 41 * @license GNU General Public License version 3
38 42 * @author KnowledgeTree Team
39 43 * @package KTCMIS
... ... @@ -48,41 +52,34 @@ require_once(CMIS_DIR . &#39;/util/CMISUtil.inc.php&#39;);
48 52  
49 53 class CMISDocumentObject extends CMISObject {
50 54  
51   - protected $versionable;
52   - private $ktapi;
53   - private $uri;
54   -
  55 + protected $versionable; // Bolean; indicates whether objects of this type are versionable
  56 + protected $contentStreamAllowed; // Enum; notallowed, allowed, required
  57 + protected $ktapi;
  58 +
55 59 // TODO some of this should probably come from configuration files as it is repository specific
56   - function __construct($documentId = null, &$ktapi = null, $uri = null)
  60 + public function __construct($documentId = null, &$ktapi = null, $uri = null)
57 61 {
58 62 $this->ktapi = $ktapi;
59   - // uri to use for document links
60   - $this->uri = $uri;
61 63  
62 64 // attributes
63   - $this->typeId = 'Document'; // <repository-specific>
64   - $this->queryName = 'Document';
65   - $this->displayName = ''; // <repository-specific>
66   - $this->baseType = 'document';
67   - $this->baseTypeQueryName = 'Document';
68   - $this->parentId = null; // MUST NOT be set
69   - $this->description = ''; // <repository-specific>
70   - $this->creatable = ''; // <repository-specific>
71   - /*
72   - * fileable SHOULD be set as follows:
73   - * If the repository does NOT support the โ€œun-filingโ€ capability:
74   - * TRUE
75   - * If the repository does support the โ€œun-filingโ€ capability:
76   - * <repository-specific>, but SHOULD be TRUE
77   - */
78   - $this->fileable = true; // TODO implement check for whether un-filing is supported
  65 + $this->id = 'cmis:document';
  66 + $this->localName = null; // <repository-specific>
  67 + $this->localNamespace = null; // <repository-specific>
  68 + $this->queryName = 'cmis:document';
  69 + $this->displayName = 'Document'; // <repository-specific>
  70 + $this->baseId = 'cmis:document';
  71 + $this->parentId = null; // MUST NOT be set for base document object-type
  72 + $this->description = null; // <repository-specific>
  73 + $this->creatable = true; // <repository-specific>
  74 + $this->fileable = true;
79 75 $this->queryable = true; // SHOULD be true
80   - $this->includedInSupertypeQuery = true; //
81   - // TODO determine what these next 3 should be
82   - $this->controllable = false; // <repository-specific>
  76 + $this->controllablePolicy = false; // <repository-specific>
  77 + $this->includedInSupertypeQuery = true; // <repository-specific>
83 78 $this->versionable = true; // <repository-specific>
84   - $this->contentStreamAllowed = 'required'; // <repository-specific> notAllowed/allowed/required
85   -
  79 + $this->contentStreamAllowed = 'required'; // <repository-specific> notallowed/allowed/required
  80 + $this->controllableACL = false; // <repository-specific>
  81 + $this->fulltextIndexed = false; // <repository-specific>
  82 +
86 83 // properties
87 84 $this->properties = new CMISDocumentPropertyCollection();
88 85  
... ... @@ -94,17 +91,18 @@ class CMISDocumentObject extends CMISObject {
94 91 if (!is_null($documentId))
95 92 {
96 93 try {
97   - $this->get($documentId);
  94 + $this->_get($documentId);
98 95 }
99 96 catch (exception $e) {
100 97 throw new ObjectNotFoundException($e->getMessage());
101 98 }
102 99 }
103 100  
104   - // TODO throw exception if unable to create?
  101 + parent::__construct();
105 102 }
106   -
107   - private function get($documentId)
  103 +
  104 + // TODO abstract shared stuff to base class where possible
  105 + protected function _get($documentId)
108 106 {
109 107 $object = $this->ktapi->get_document_by_id((int)$documentId);
110 108  
... ... @@ -115,7 +113,7 @@ class CMISDocumentObject extends CMISObject {
115 113  
116 114 $objectProperties = $object->get_detail();
117 115  
118   - $this->_setPropertyInternal('ObjectId', CMISUtil::encodeObjectId($this->typeId, $objectProperties['document_id']));
  116 + $this->_setPropertyInternal('objectId', CMISUtil::encodeObjectId($this->id, $objectProperties['document_id']));
119 117 // prevent doubled '/' chars
120 118 $uri = preg_replace_callback('/([^:]\/)\//',
121 119 create_function('$matches', 'return $matches[1];'),
... ... @@ -124,33 +122,29 @@ class CMISDocumentObject extends CMISObject {
124 122 . $objectProperties['document_id']);
125 123 // NOTE what about instead creating a downloadable version with appropriate link? see ktapi::download_document
126 124 // also ktapidocument::get_download_url
127   -// $this->_setPropertyInternal('Uri', $uri);
128   - $this->_setPropertyInternal('Uri', '');
129   - // TODO what is this? Assuming it is the object type id, and not OUR document type?
130   - $this->_setPropertyInternal('ObjectTypeId', $this->getAttribute('typeId'));
131   - // Needed to distinguish type
132   - $this->_setPropertyInternal('BaseType', strtolower($this->getAttribute('typeId')));
133   - $this->_setPropertyInternal('CreatedBy', $objectProperties['created_by']);
134   - $this->_setPropertyInternal('CreationDate', $objectProperties['created_date']);
135   - $this->_setPropertyInternal('LastModifiedBy', $objectProperties['modified_by']);
136   - $this->_setPropertyInternal('LastModificationDate', $objectProperties['modified_date']);
137   - $this->_setPropertyInternal('ChangeToken', null);
138   - $this->_setPropertyInternal('Name', $objectProperties['title']);
139   - $this->_setPropertyInternal('ParentId', $objectProperties['folder_id']);
140   - $this->_setPropertyInternal('IsImmutable', $objectProperties['is_immutable']);
  125 +// $this->_setPropertyInternal('uri', $uri);
  126 + $this->_setPropertyInternal('uri', '');
  127 + $this->_setPropertyInternal('createdBy', $objectProperties['created_by']);
  128 + $this->_setPropertyInternal('creationDate', $objectProperties['created_date']);
  129 + $this->_setPropertyInternal('lastModifiedBy', $objectProperties['modified_by']);
  130 + $this->_setPropertyInternal('lastModificationDate', $objectProperties['modified_date']);
  131 + $this->_setPropertyInternal('changeToken', null);
  132 + $this->_setPropertyInternal('name', $objectProperties['title']);
  133 + $this->_setPropertyInternal('parentId', CMISUtil::encodeObjectId(FOLDER, $objectProperties['folder_id']));
  134 + $this->_setPropertyInternal('isImmutable', $objectProperties['is_immutable']);
141 135 // NOTE if access to older versions is allowed, this will need to be checked, else just set to yes
142 136 // see ktapi::get_document_version_history
143 137 // NOTE see ktapi::is_latest_version
144   - $this->_setPropertyInternal('IsLatestVersion', true);
145   - $this->_setPropertyInternal('IsMajorVersion', (strstr($objectProperties['version'], '.') ? false : true));
  138 + $this->_setPropertyInternal('isLatestVersion', true);
  139 + $this->_setPropertyInternal('isMajorVersion', (strstr($objectProperties['version'], '.') ? false : true));
146 140 // NOTE if access to older versions is allowed, this will need to be checked, else just set to yes
147 141 // see ktapi::get_document_version_history
148 142 // NOTE see ktapi::is_latest_version
149   - $this->_setPropertyInternal('IsLatestMajorVersion', true);
150   - $this->_setPropertyInternal('VersionLabel', $objectProperties['version']);
  143 + $this->_setPropertyInternal('isLatestMajorVersion', true);
  144 + $this->_setPropertyInternal('versionLabel', $objectProperties['version']);
151 145 // VersionSeriesId should be the id of the latest version
152 146 // NOTE this may change in the future but is easiest for the current implementation
153   - $this->_setPropertyInternal('VersionSeriesId', $objectProperties['version']);
  147 + $this->_setPropertyInternal('versionSeriesId', $objectProperties['version']);
154 148 if ($objectProperties['checked_out_by'] != 'n/a')
155 149 {
156 150 $checkedOut = true;
... ... @@ -164,18 +158,34 @@ class CMISDocumentObject extends CMISObject {
164 158 $checkedOutBy = null;
165 159 $checkedOutId = null;
166 160 }
167   - $this->_setPropertyInternal('IsVersionSeriesCheckedOut', $checkedOut);
168   - $this->_setPropertyInternal('VersionSeriesCheckedOutBy', $checkedOutBy);
  161 + $this->_setPropertyInternal('isVersionSeriesCheckedOut', $checkedOut);
  162 + $this->_setPropertyInternal('versionSeriesCheckedOutBy', $checkedOutBy);
169 163 // TODO presumably this is the ID of the Private Working Copy created on checkout?
170 164 // will find out more when we do checkout/checkin
171   - $this->_setPropertyInternal('VersionSeriesCheckedOutId', $checkedOutId);
  165 + $this->_setPropertyInternal('versionSeriesCheckedOutId', $checkedOutId);
172 166 // TODO currently not returned by KnowledgeTree?
173   - $this->_setPropertyInternal('CheckinComment', null);
174   - $this->_setPropertyInternal('ContentStreamLength', $objectProperties['filesize']);
175   - $this->_setPropertyInternal('ContentStreamMimeType', $objectProperties['mime_type']);
176   - $this->_setPropertyInternal('ContentStreamFilename', $objectProperties['filename']);
177   - $this->_setPropertyInternal('ContentStreamUri', $this->getProperty('ObjectId') . '/' . $objectProperties['filename']);
178   - $this->_setPropertyInternal('Author', $objectProperties['created_by']);
  167 + $this->_setPropertyInternal('checkinComment', null);
  168 + $this->_setPropertyInternal('contentStreamLength', $objectProperties['filesize']);
  169 + $this->_setPropertyInternal('contentStreamMimeType', $objectProperties['mime_type']);
  170 + $this->_setPropertyInternal('contentStreamFilename', $objectProperties['filename']);
  171 + $this->_setPropertyInternal('contentStreamUri', $this->getProperty('objectId') . '/' . $objectProperties['filename']);
  172 + $this->_setPropertyInternal('author', $objectProperties['created_by']);
  173 + }
  174 +
  175 + /**
  176 + * Returns a listing of all attributes in an array
  177 + *
  178 + * @return array $attributes
  179 + */
  180 + public function getAttributes()
  181 + {
  182 + $attributes = parent::getAttributes();
  183 +
  184 + // add document object-type specific attributes
  185 + $attributes['versionable'] = $this->versionable;
  186 + $attributes['contentStreamAllowed'] = $this->contentStreamAllowed;
  187 +
  188 + return $attributes;
179 189 }
180 190  
181 191 }
... ...
lib/api/ktcmis/objecttypes/CMISFolderObject.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008,2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -32,8 +32,12 @@
32 32 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33 33 * must display the words "Powered by KnowledgeTree" and retain the original
34 34 * copyright notice.
  35 + * Contributor( s): ______________________________________
  36 + */
  37 +
  38 +/**
35 39 *
36   - * @copyright 2008-2009, KnowledgeTree Inc.
  40 + * @copyright 2008-2010, KnowledgeTree Inc.
37 41 * @license GNU General Public License version 3
38 42 * @author KnowledgeTree Team
39 43 * @package KTCMIS
... ... @@ -46,42 +50,47 @@ require_once(CMIS_DIR . &#39;/util/CMISUtil.inc.php&#39;);
46 50  
47 51 class CMISFolderObject extends CMISObject {
48 52  
49   - private $ktapi;
50   - private $uri;
  53 + protected $ktapi;
51 54  
52 55 public function __construct($folderId = null, &$ktapi = null, $uri = null)
53 56 {
54 57 $this->ktapi = $ktapi;
55   - $this->uri = $uri;
56 58  
57   - $this->typeId = 'Folder'; // <repository-specific>
58   - $this->queryName = 'Folder';
59   - $this->displayName = ''; // <repository-specific>
60   - $this->baseType = 'folder';
61   - $this->baseTypeQueryName = 'Folder';
  59 + $this->id = 'cmis:folder'; // <repository-specific>
  60 + $this->localName = null; // <repository-specific>
  61 + $this->localNamespace = null; // <repository-specific>
  62 + $this->queryName = 'cmis:folder';
  63 + $this->displayName = 'Folder'; // <repository-specific>
  64 + $this->baseId = 'cmis:folder';
62 65 $this->parentId = null; // MUST NOT be set
63   - $this->description = ''; // <repository-specific>
64   - $this->creatable = ''; // <repository-specific>
  66 + $this->description = null; // <repository-specific>
  67 + $this->creatable = true; // <repository-specific>
65 68 $this->fileable = true;
66 69 $this->queryable = true; // SHOULD be true
67   - $this->includedInSupertypeQuery = true; //
68   - $this->controllable = ''; // <repository-specific>
69   -
  70 + $this->controllablePolicy = false; // <repository-specific>
  71 + $this->includedInSupertypeQuery = true; // <repository-specific>
  72 + $this->contentStreamAllowed = 'required'; // <repository-specific> notallowed/allowed/required
  73 + $this->controllableACL = false; // <repository-specific>
  74 + $this->fulltextIndexed = false; // <repository-specific>
  75 +
70 76 // properties
71 77 $this->properties = new CMISFolderPropertyCollection();
72 78  
73 79 if (!is_null($folderId))
74 80 {
75 81 try {
76   - $this->get($folderId);
  82 + $this->_get($folderId);
77 83 }
78 84 catch (exception $e) {
79 85 throw new ObjectNotFoundException($e->getMessage());
80 86 }
81 87 }
  88 +
  89 + parent::__construct();
82 90 }
83 91  
84   - private function get($folderId)
  92 + // TODO abstract shared stuff to base class where possible
  93 + protected function _get($folderId)
85 94 {
86 95 $object = $this->ktapi->get_folder_by_id((int)$folderId);
87 96  
... ... @@ -94,7 +103,7 @@ class CMISFolderObject extends CMISObject {
94 103  
95 104 $objectProperties = $object->get_detail();
96 105  
97   - $this->_setPropertyInternal('ObjectId', CMISUtil::encodeObjectId($this->typeId, $objectProperties['id']));
  106 + $this->_setPropertyInternal('objectId', CMISUtil::encodeObjectId($this->id, $objectProperties['id']));
98 107 // prevent doubled '/' chars
99 108 $uri = preg_replace_callback('/([^:]\/)\//',
100 109 create_function('$matches', 'return $matches[1];'),
... ... @@ -102,24 +111,28 @@ class CMISFolderObject extends CMISObject {
102 111 . '/browse.php?fFolderId='
103 112 . $objectProperties['id']);
104 113 // TODO this url is probably incorrect...needs to be checked
105   -// $this->_setPropertyInternal('Uri', $uri);
106   - $this->_setPropertyInternal('Uri', '');
107   - // TODO what is this? Assuming it is the object type id, and not OUR document type?
108   - $this->_setPropertyInternal('ObjectTypeId', $this->getAttribute('typeId'));
109   - // Needed to distinguish type
110   - $this->_setPropertyInternal('BaseType', strtolower($this->getAttribute('typeId')));
111   - $this->_setPropertyInternal('CreatedBy', $objectProperties['created_by']);
  114 +// $this->_setPropertyInternal('uri', $uri);
  115 + $this->_setPropertyInternal('uri', '');
  116 + $this->_setPropertyInternal('createdBy', $objectProperties['created_by']);
112 117 // TODO cannot currently retrieve via ktapi or regular folder code - add as with created by
113   - $this->_setPropertyInternal('CreationDate', $objectProperties['created_date']);
  118 + $this->_setPropertyInternal('creationDate', $objectProperties['created_date']);
114 119 // TODO cannot currently retrieve via ktapi or regular folder code - add as with created by
115   - $this->_setPropertyInternal('LastModifiedBy', $objectProperties['modified_by']);
  120 + $this->_setPropertyInternal('lastModifiedBy', $objectProperties['modified_by']);
116 121 // TODO cannot currently retrieve via ktapi or regular folder code - add as with created by
117   - $this->_setPropertyInternal('LastModificationDate', $objectProperties['modified_date']);
118   - $this->_setPropertyInternal('ChangeToken', null);
119   - $this->_setPropertyInternal('Name', $objectProperties['folder_name']);
120   - $this->_setPropertyInternal('ParentId', $objectProperties['parent_id']);
121   - $this->_setPropertyInternal('AllowedChildObjectTypeIds', array('Document', 'Folder'));
122   - $this->_setPropertyInternal('Author', $objectProperties['created_by']);
  122 + $this->_setPropertyInternal('lastModificationDate', $objectProperties['modified_date']);
  123 + $this->_setPropertyInternal('changeToken', null);
  124 + $this->_setPropertyInternal('name', $objectProperties['folder_name']);
  125 + $this->_setPropertyInternal('parentId', CMISUtil::encodeObjectId(FOLDER, $objectProperties['parent_id']));
  126 + $this->_setPropertyInternal('author', $objectProperties['created_by']);
  127 + }
  128 +
  129 + /**
  130 + * Sets properties shared between all objects of this type
  131 + */
  132 + protected function _setSharedProperties()
  133 + {
  134 + parent::_setSharedProperties();
  135 + $this->_setPropertyInternal('allowedChildObjectTypeIds', array('cmis:document', 'cmis:folder'));
123 136 }
124 137  
125 138 }
... ...
lib/api/ktcmis/services/CMISNavigationService.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008,2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -32,8 +32,12 @@
32 32 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33 33 * must display the words "Powered by KnowledgeTree" and retain the original
34 34 * copyright notice.
  35 + * Contributor( s): ______________________________________
  36 + */
  37 +
  38 +/**
35 39 *
36   - * @copyright 2008-2009, KnowledgeTree Inc.
  40 + * @copyright 2008-2010, KnowledgeTree Inc.
37 41 * @license GNU General Public License version 3
38 42 * @author KnowledgeTree Team
39 43 * @package KTCMIS
... ... @@ -58,85 +62,108 @@ class CMISNavigationService {
58 62 }
59 63  
60 64 /**
61   - * Get descendents of the specified folder, up to the depth indicated
  65 + * Get direct children of the specified folder
62 66 *
63 67 * @param string $repositoryId
64 68 * @param string $folderId
65 69 * @param boolean $includeAllowableActions
66 70 * @param boolean $includeRelationships
67 71 * @param string $typeId
68   - * @param int $depth
69 72 * @param string $filter
  73 + * @param int $maxItems
  74 + * @param int $skipCount
70 75 * @return array $descendants
  76 + * MUST include (unless not requested) for each object:
  77 + * array $properties
  78 + * array $relationships
  79 + * array $renditions
  80 + * $allowableActions
  81 + * string $pathSegment
  82 + * boolean $hasMoreItems
  83 + * int $numItems [optional]
71 84 */
72   -
73   - // NOTE This method does NOT support paging as defined in the paging section
74   - // NOTE If the Repository supports the optional รขโ‚ฌล“VersionSpecificFilingรขโ‚ฌ? capability,
  85 + // NOTE If the Repository supports the optional รขโ‚ฌล“VersionSpecificFilingรฏยฟยฝรฏยฟยฝ? capability,
75 86 // then the repository SHALL return the document versions filed in the specified folder or its descendant folders.
76 87 // Otherwise, the latest version of the documents SHALL be returned.
77 88 // TODO FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid
78   - function getDescendants($repositoryId, $folderId, $includeAllowableActions, $includeRelationships,
79   - $depth = 1, $typeId = 'Any', $filter = '')
  89 + function getChildren($repositoryId, $folderId, $includeAllowableActions = null, $includeRelationships = null,
  90 + $typeId = 'Any', $filter = '', $maxItems = 0, $skipCount = 0, $orderBy = '', $renditionFilter = null,
  91 + $includePathSegment = false)
80 92 {
  93 + // TODO paging
81 94 // TODO optional parameters
82   - $descendants = array();
  95 + $children = array();
83 96 $repository = new CMISRepository($repositoryId);
84 97  
85   - // if this is not a folder, cannot get descendants
  98 + // if this is not a folder, cannot get children
86 99 $folderId = CMISUtil::decodeObjectId($folderId, $type);
87   -
88   - if ($type != 'Folder')
89   - {
90   - return $descendants;
  100 +
  101 + if ($type != 'cmis:folder') {
  102 + throw new invalidArgumentException('The specified object is not a folder');
91 103 }
92 104  
93 105 $folder = $this->ktapi->get_folder_by_id($folderId);
94   - $descendants = $folder->get_listing($depth);
  106 + $children = $folder->get_listing();
95 107  
96   - // parse ktapi descendants result into a list of CMIS objects
97   - $descendants = CMISUtil::createChildObjectHierarchy($descendants, $repository->getRepositoryURI, $this->ktapi);
  108 + $children = CMISUtil::createChildObjectHierarchy($children, $repository->getRepositoryURI, $this->ktapi);
98 109  
99   - return $descendants;
  110 + return $children;
100 111 }
101 112  
102 113 /**
103   - * Get direct children of the specified folder
  114 + * Get descendents of the specified folder, up to the depth indicated
104 115 *
105 116 * @param string $repositoryId
106 117 * @param string $folderId
107   - * @param boolean $includeAllowableActions
108   - * @param boolean $includeRelationships
109   - * @param string $typeId
  118 + * @param int $depth
110 119 * @param string $filter
111   - * @param int $maxItems
112   - * @param int $skipCount
  120 + * @param boolean $includeRelationships
  121 + * @param string $renditionFilter
  122 + * @param boolean $includeAllowableActions
  123 + * @param boolean $includePathSegment
113 124 * @return array $descendants
  125 + * MUST include (unless not requested) for each object:
  126 + * array $properties
  127 + * array $relationships
  128 + * array $renditions
  129 + * $allowableActions
  130 + * string $pathSegment
114 131 */
115   - // NOTE If the Repository supports the optional รขโ‚ฌล“VersionSpecificFilingรขโ‚ฌ? capability,
  132 +
  133 + // NOTE This method does NOT support paging as defined in the paging section
  134 + // NOTE If the Repository supports the optional รขโ‚ฌล“VersionSpecificFilingรฏยฟยฝรฏยฟยฝ? capability,
116 135 // then the repository SHALL return the document versions filed in the specified folder or its descendant folders.
117 136 // Otherwise, the latest version of the documents SHALL be returned.
  137 + // NOTE If the Repository supports the optional capability capabilityMutlifiling and the same document is encountered
  138 + // multiple times in the hierarchy, then the repository MUST return that document each time is encountered.
  139 + // NOTE The default value for the $depth parameter is repository specific and SHOULD be at least 2 or -1
  140 + // Chosen 2 as the underlying code currently has no concept of digging all the way down
118 141 // TODO FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid
119   - function getChildren($repositoryId, $folderId, $includeAllowableActions, $includeRelationships,
120   - $typeId = 'Any', $filter = '', $maxItems = 0, $skipCount = 0)
  142 + function getDescendants($repositoryId, $folderId, $depth = 2, $filter = '', $includeRelationships = false, $renditionFilter = '',
  143 + $includeAllowableActions = false, $includePathSegment = false)
121 144 {
122   - // TODO paging
123   - // TODO optional parameters
124   - $children = array();
125   - $repository = new CMISRepository($repositoryId);
  145 + if ($depth == 0) {
  146 + throw new InvalidArgumentException('Invalid depth argument supplied');
  147 + }
126 148  
127   - // if this is not a folder, cannot get children
  149 + // if this is not a folder, cannot get descendants
128 150 $folderId = CMISUtil::decodeObjectId($folderId, $type);
129   - // NOTE this will quite possibly break the webservices
130   - if ($type != 'Folder') {
131   - return $children;
  151 +
  152 + if ($type != 'cmis:folder') {
  153 + throw new InvalidArgumentException('The supplied object is not a folder, unable to return descendants');
132 154 }
133 155  
  156 + // TODO optional parameters
  157 + $descendants = array();
  158 + $repository = new CMISRepository($repositoryId);
  159 +
134 160 $folder = $this->ktapi->get_folder_by_id($folderId);
135   - $children = $folder->get_listing();
  161 + $descendants = $folder->get_listing($depth);
136 162  
137   - $children = CMISUtil::createChildObjectHierarchy($children, $repository->getRepositoryURI, $this->ktapi);
  163 + // parse ktapi descendants result into a list of CMIS objects
  164 + $descendants = CMISUtil::createChildObjectHierarchy($descendants, $repository->getRepositoryURI, $this->ktapi);
138 165  
139   - return $children;
  166 + return $descendants;
140 167 }
141 168  
142 169 /**
... ... @@ -144,105 +171,102 @@ class CMISNavigationService {
144 171 *
145 172 * @param string $repositoryId
146 173 * @param string $folderId
147   - * @param boolean $includeAllowableActions
148   - * @param boolean $includeRelationships
149   - * @param boolean $returnToRoot If TRUE, then the repository SHALL return all folder objects
150   - * that are ancestors of the specified folder.
151   - * If FALSE, the repository SHALL return only the parent folder of the specified folder.
152 174 * @param string $filter
153   - * @return array $ancestry
  175 + * @return object $parent The parent folder object
154 176 */
155 177 // TODO FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid
156   - // TODO If this service method is invoked on the root folder of the Repository, then the Repository SHALL return an empty result set.
157   - // NOTE SHOULD always include the รขโ‚ฌล“ObjectIdรขโ‚ฌ? and รขโ‚ฌล“ParentIdรขโ‚ฌ? properties for all objects returned
158   - function getFolderParent($repositoryId, $folderId, $includeAllowableActions, $includeRelationships, $returnToRoot, $filter = '')
  178 + function getFolderParent($repositoryId, $folderId, $filter = '')
159 179 {
160 180 // NOTE the root folder obviously has no parent, throw an ObjectNotFoundException here if this is the root folder
161 181 if (CMISUtil::isRootFolder($repositoryId, $folderId, $this->ktapi)) {
162   - throw new ObjectNotFoundException('Root folder has no parent');
  182 + throw new InvalidArgumentException('Root folder has no parent');
163 183 }
164   -
165   - $ancestry = array();
166   - $repository = new CMISRepository($repositoryId);
  184 +
  185 + $parent = null;
167 186  
168 187 // if this is not a folder, cannot get folder parent :)
169 188 $folderId = CMISUtil::decodeObjectId($folderId, $type);
170   - // NOTE this will quite possibly break the webservices
171   - if ($type != 'Folder')
172   - {
173   - return $ancestry;
  189 + // this exception is not indicated in the CMIS Specification, but it just makes sense and so we include it here
  190 + if ($type != 'cmis:folder') {
  191 + throw new InvalidArgumentException('The specified object is not a folder');
174 192 }
175 193  
176 194 $ktapiFolder = $this->ktapi->get_folder_by_id($folderId);
177   -
178   - if ($returnToRoot)
179   - {
180   - $folder = $ktapiFolder->get_folder();
181   - $parents = $folder->generateFolderIDs($folderId);
182   - // remove the id of the requesting folder and convert to array
183   - $ancestry = explode(',', str_replace(','.$folderId, '', $parents));
184   - // reverse to get bottom up listing? don't think so with the current implementation
185   - // specifying that objectTypes may have children but do not have parents listed.
186   -// $ancestry = array_reverse($ancestry);
187   - }
188   - else
189   - {
190   - $parent = $ktapiFolder->get_parent_folder_id();
191   - $ancestry[] = $parent;
  195 + if (PEAR::isError($ktapiFolder)) {
  196 + throw new RuntimeException($ktapiFolder->getMessage());
192 197 }
193 198  
194   - // need some info about the parent(s) in order to correctly create the hierarchy
195   - $tmpArray = array();
196   - foreach ($ancestry as $key => $ancestor)
197   - {
198   - $tmpArray[$key] = $this->ktapi->get_folder_by_id($ancestor);
199   - }
200   - $ancestry = $tmpArray;
201   - unset($tmpArray);
202   -
203   - $ancestry = CMISUtil::createParentObjectHierarchy($ancestry, $repository->getRepositoryURI, $this->ktapi);
204   -
205   - return $ancestry;
  199 + $parentId = $ktapiFolder->get_parent_folder_id();
  200 + $parent = new CMISFolderObject($parentId, $this->ktapi);
  201 +
  202 + return $parent;
206 203 }
207 204  
208 205 /**
209   - * Fetches the parent(s) of the specified object
  206 + * Gets the parent folder(s) for the specified non-folder, fileable object.
210 207 * Multiple parents may exist if a repository supports multi-filing
211 208 * It is also possible that linked documents/folders may qualify as having multiple parents
212 209 * as they are essentially the same object
213 210 *
214 211 * @param string $repositoryId
215 212 * @param string $objectId
216   - * @param boolean $includeAllowableActions
217   - * @param boolean $includeRelationships
218   - * @param string $filter
219   - * @return array $parents
  213 + * @param string $filter [optional]
  214 + * @param enum $includeRelationships [optional]
  215 + * @param string $renditionFilter [optional]
  216 + * @param boolean $includeAllowableActions [optional]
  217 + * @param boolean $includeRelativePathSegment [optional]
  218 + * @return array $parents - empty for unfiled objects or the root folder
  219 + * MUST include (unless not requested) for each object:
  220 + * array $properties
  221 + * array $relationships
  222 + * array $renditions
  223 + * $allowableActions
  224 + * string $relativePathSegment
220 225 */
221   - // TODO ConstraintViolationException: The Repository SHALL throw this exception if this method is invoked
222   - // on an object who Object-Type Definition specifies that it is not fileable.
223   - // FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid.
224   - function getObjectParents($repositoryId, $objectId, $includeAllowableActions, $includeRelationships, $filter = '')
  226 + // TODO FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid.
  227 + function getObjectParents($repositoryId, $objectId, $filter = '', $includeRelationships = null, $renditionFilter = '',
  228 + $includeAllowableActions = false, $includeRelativePathSegment = false)
225 229 {
226 230 $ancestry = array();
227 231  
228 232 $objectId = CMISUtil::decodeObjectId($objectId, $typeId);
  233 +
  234 + // if type is a folder, this function does not apply
  235 + if ($typeId == 'cmis:folder') {
  236 + throw new InvalidArgumentException('Cannot call this function for a folder object');
  237 + }
  238 +
  239 + $objectTypeId = ucwords(str_replace('cmis:', '', $typeId));
  240 + $object = 'CMIS' . $objectTypeId . 'Object';
  241 +
  242 + if (!file_exists(CMIS_DIR . '/objecttypes/' . $object . '.inc.php')) {
  243 + throw new InvalidArgumentException('Type ' . $typeId . ' is not supported');
  244 + }
  245 +
  246 + require_once(CMIS_DIR . '/objecttypes/' . $object . '.inc.php');
  247 + $cmisObject = new $object;
  248 +
  249 + if (!$cmisObject->getAttribute('fileable')) {
  250 + throw new ConstraintViolationException('Unable to get parents of non-filable object');
  251 + }
229 252  
230 253 // TODO - what about other types? only implementing folders and documents at the moment so ignore for now
  254 + // NOTE this will change if we implement multi-filing and/or unfiling
231 255 switch($typeId)
232 256 {
233   - case 'Document':
  257 + case 'cmis:document':
234 258 $document = $this->ktapi->get_document_by_id($objectId);
235   - $parent = $document->ktapi_folder;
236   - $ancestry[] = $parent;
237   - break;
238   - case 'Folder':
239   - $folder = $this->ktapi->get_folder_by_id($objectId);
240   - $parent = $this->ktapi->get_folder_by_id($folder->get_parent_folder_id());
241   - $ancestry[] = $parent;
242   - break;
  259 + if ($document->is_deleted()) {
  260 + throw new InvalidArgumentException('The requested object has been deleted');
  261 + }
  262 + $ancestry[] = $document->ktapi_folder->get_folderid();
  263 + break;
  264 + }
  265 +
  266 + foreach ($ancestry as $key => $parentId) {
  267 + $CMISObject = new CMISFolderObject($parentId, $this->ktapi, $repositoryURI);
  268 + $ancestry[$key] = CMISUtil::createObjectPropertiesEntry($CMISObject->getProperties());
243 269 }
244   -
245   - $ancestry = CMISUtil::createParentObjectHierarchy($ancestry, $repository->getRepositoryURI, $this->ktapi);
246 270  
247 271 return $ancestry;
248 272 }
... ... @@ -252,19 +276,25 @@ class CMISNavigationService {
252 276 *
253 277 * @param string $repositoryId
254 278 * @param string $folderId The folder for which checked out docs are requested
255   - * @param string $filter
256   - * @param boolean $includeAllowableActions
257   - * @param boolean $includeRelationships
258 279 * @param int $maxItems
259 280 * @param int $skipCount
  281 + * @param string $filter
  282 + * @param enum $includeRelationships
  283 + * @param boolean $includeAllowableActions
  284 + * @param string $renditionFilter
260 285 * @return array $checkedout The collection of checked out document objects
  286 + * MUST include (unless not requested) for each object:
  287 + * array $properties
  288 + * array $relationships
  289 + * array $renditions
  290 + * $allowableActions
  291 + * @return boolean $hasMoreItems
  292 + * @return int $numItems [optional]
261 293 */
262   - // NOTE NOT YET IMPLEMENTED (this function is just a place holder at the moment :))
263 294 // TODO exceptions: รขโ‚ฌยข FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid.
264   - // TODO filter by folder id
265 295 // TODO $filter and paging
266   - function getCheckedOutDocs($repositoryId, $folderId = null, $filter = '', $includeAllowableActions, $includeRelationships,
267   - $maxItems = 0, $skipCount = 0)
  296 + function getCheckedOutDocs($repositoryId, $folderId = null, $maxItems = 0, $skipCount = 0, $orderBy = '',
  297 + $filter = '', $includeRelationships = null, $includeAllowableActions = false, $renditionFilter = '')
268 298 {
269 299 $checkedout = array();
270 300  
... ... @@ -273,7 +303,7 @@ class CMISNavigationService {
273 303 {
274 304 $CMISDocument = new CMISDocumentObject($document->getId(), $this->ktapi);
275 305 // set version label property - possibly belongs in document class
276   - $CMISDocument->setProperty('VersionLabel', $CMISDocument->getProperty('VersionSeriesCheckedOutId'));
  306 + $CMISDocument->setProperty('versionLabel', $CMISDocument->getProperty('versionSeriesCheckedOutId'));
277 307 $checkedout[] = $CMISDocument->getProperties();
278 308 }
279 309  
... ...
lib/api/ktcmis/services/CMISObjectService.inc.php
... ... @@ -4,6 +4,7 @@ require_once(KT_DIR . &#39;/ktapi/ktapi.inc.php&#39;);
4 4 require_once(KT_DIR . '/ktwebservice/KTUploadManager.inc.php');
5 5 require_once(CMIS_DIR . '/exceptions/ConstraintViolationException.inc.php');
6 6 require_once(CMIS_DIR . '/exceptions/ContentAlreadyExistsException.inc.php');
  7 +require_once(CMIS_DIR . '/exceptions/NameConstraintViolationException.inc.php');
7 8 require_once(CMIS_DIR . '/exceptions/ObjectNotFoundException.inc.php');
8 9 require_once(CMIS_DIR . '/exceptions/StorageException.inc.php');
9 10 require_once(CMIS_DIR . '/exceptions/StreamNotSupportedException.inc.php');
... ... @@ -34,38 +35,42 @@ class CMISObjectService {
34 35 * Creates a new document within the repository
35 36 *
36 37 * @param string $repositoryId The repository to which the document must be added
37   - * @param string $typeId Object Type id for the document object being created
38 38 * @param array $properties Array of properties which must be applied to the created document object
39 39 * @param string $folderId The id of the folder which will be the parent of the created document object
40 40 * This parameter is optional IF unfilingCapability is supported
41 41 * @param string $contentStream optional content stream data - expected as a base64 encoded string
42   - * @param string $versioningState optional version state value: checkedout/major/minor
  42 + * @param string $versioningState optional version state value: none/checkedout/major/minor
  43 + * @param $policies List of policy ids that MUST be applied
  44 + * @param $addACEs List of ACEs that MUST be added
  45 + * @param $removeACEs List of ACEs that MUST be removed
43 46 * @return string $objectId The id of the created folder object
44 47 */
45 48 // TODO throw ConstraintViolationException if:
46 49 // value of any of the properties violates the min/max/required/length constraints
47 50 // specified in the property definition in the Object-Type.
48   - public function createDocument($repositoryId, $typeId, $properties, $folderId = null,
49   - $contentStream = null, $versioningState = null)
  51 + // TODO throw ConstraintViolationException if At least one of the permissions is used in
  52 + // an ACE provided which is not supported by the repository.
  53 + // NOTE typeId is supplied in the cmis:objectTypeId property in the properties array
  54 + // TODO support submission of content stream as an array containing mimetype and stream;
  55 + // for now we just filter on the other side so that only the stream comes through
  56 + // and continue to check the mime type dynamically (may need that anyway if none specified
  57 + // by CMIS client)
  58 + public function createDocument($repositoryId, $properties, $folderId = null, $contentStream = null,
  59 + $versioningState = 'none', $policies = array(), $addACEs = array(),
  60 + $removeACEs = array())
50 61 {
51 62 $objectId = null;
52 63  
53 64 // fetch type definition of supplied type and check for base type "document", if not true throw exception
54 65 $RepositoryService = new CMISRepositoryService();
55 66 try {
56   - $typeDefinition = $RepositoryService->getTypeDefinition($repositoryId, $typeId);
  67 + $typeDefinition = $RepositoryService->getTypeDefinition($repositoryId, $properties['objectTypeId']);
57 68 }
58   - // NOTE Not sure that we should throw this specific exception, maybe just let the underlying
59   - // exception propogate upward...
60   - // Alternatively: throw new exception with original exception message appended
61   - // NOTE The latter method has been adopted for the moment
62   - catch (Exception $e)
63   - {
  69 + catch (Exception $e) {
64 70 throw new ConstraintViolationException('Object base type could not be determined. ' . $e->getMessage());
65 71 }
66 72  
67   - if ($typeDefinition['attributes']['baseType'] != 'document')
68   - {
  73 + if ($typeDefinition['attributes']['baseId'] != 'cmis:document') {
69 74 throw new ConstraintViolationException('Object is not of base type document');
70 75 }
71 76  
... ... @@ -83,19 +88,19 @@ class CMISObjectService {
83 88 // Attempt to decode $folderId, use as is if not detected as encoded
84 89 $tmpObjectId = $folderId;
85 90 $tmpObjectId = CMISUtil::decodeObjectId($tmpObjectId, $tmpTypeId);
86   - if ($tmpTypeId != 'Unknown')
  91 + if ($tmpTypeId != 'unknown')
87 92 $folderId = $tmpObjectId;
88 93  
89 94 // if parent folder is not allowed to hold this type, throw exception
90 95 $CMISFolder = new CMISFolderObject($folderId, $this->ktapi);
91   - $allowed = $CMISFolder->getProperty('AllowedChildObjectTypeIds');
  96 + $allowed = $CMISFolder->getProperty('allowedChildObjectTypeIds');
92 97 $typeAllowed = false;
93 98  
94 99 if (is_array($allowed))
95 100 {
96 101 foreach($allowed as $type)
97 102 {
98   - if (strtolower($type) == strtolower($typeId))
  103 + if (strtolower($type) == strtolower($properties['objectTypeId']))
99 104 {
100 105 $typeAllowed = true;
101 106 break;
... ... @@ -117,8 +122,19 @@ class CMISObjectService {
117 122 }
118 123  
119 124 // if versionable attribute is set to false and versioningState is supplied, throw a ConstraintViolationException
120   - if (!$typeDefinition['attributes']['versionable'] && !empty($versioningState)) {
121   - throw new ConstraintViolationException('This repository does not support versioning');
  125 + if (!$typeDefinition['attributes']['versionable'] && (!empty($versioningState) || $versioningState != 'none')) {
  126 + throw new ConstraintViolationException('This object-type does not support versioning');
  127 + }
  128 + else if ($typeDefinition['attributes']['versionable'] && (empty($versioningState) || $versioningState == 'none')) {
  129 + throw new ConstraintViolationException('Invalid versioning state supplied');
  130 + }
  131 +
  132 + if (!$typeDefinition['attributes']['controllablePolicy'] && count($policies)) {
  133 + throw new ConstraintViolationException('This object-type does not support policies');
  134 + }
  135 +
  136 + if (!$typeDefinition['attributes']['controllableACL'] && (count($addACEs) || count($removeACEs))) {
  137 + throw new ConstraintViolationException('This object-type does not support ACLs');
122 138 }
123 139  
124 140 // TODO deal with $versioningState when supplied
... ... @@ -131,9 +147,10 @@ class CMISObjectService {
131 147 $properties['name'] = $properties['title'];
132 148 }
133 149  
134   - // if name is blank throw exception (check type) - using invalidArgument Exception for now
  150 + // throw NameConstraintViolation if there is a violation with the given cmis:name property value
  151 + // OR choose a name which does not conflict
135 152 if (trim($properties['name']) == '') {
136   - throw new InvalidArgumentException('Refusing to create an un-named document');
  153 + throw new NameConstraintViolationException('Refusing to create an un-named document');
137 154 }
138 155  
139 156 // TODO also set to Default if a non-supported type is submitted
... ... @@ -146,6 +163,10 @@ class CMISObjectService {
146 163 // this check isn't strictly necessary; however it is needed for a repository which does not support content streams
147 164 if (!is_null($contentStream))
148 165 {
  166 + if (!$typeDefinition['attributes']['contentStreamAllowed']) {
  167 + throw new StreamNotSupportedException('Content streams are not supported by this object-type');
  168 + }
  169 +
149 170 $tempfilename = CMISUtil::createTemporaryFile($contentStream);
150 171  
151 172 // metadata
... ... @@ -210,6 +231,7 @@ class CMISObjectService {
210 231 include_once(KT_LIB_DIR . '/mime.inc.php');
211 232 $KTMime = new KTMime();
212 233 $mimetype = $KTMime->getMimeTypeFromFile($tempfilename);
  234 + // extract type string from mimetype response
213 235 preg_match('/^([^\/]*)\/([^\/]*)/', $mimetype, $matches);
214 236 if (($matches[1] == 'text') || ($matches[1] == 'image') || ($matches[1] == 'audio')) {
215 237 $mediatype = ucwords($matches[1]);
... ... @@ -244,7 +266,7 @@ class CMISObjectService {
244 266 throw new StorageException('The repository was unable to create the document. ' . $response['message']);
245 267 }
246 268 else {
247   - $objectId = CMISUtil::encodeObjectId('Document', $response['results']['document_id']);
  269 + $objectId = CMISUtil::encodeObjectId(DOCUMENT, $response['results']['document_id']);
248 270 }
249 271  
250 272 // remove temporary file
... ... @@ -269,22 +291,26 @@ class CMISObjectService {
269 291 * Creates a new folder within the repository
270 292 *
271 293 * @param string $repositoryId The repository to which the folder must be added
272   - * @param string $typeId Object Type id for the folder object being created
273 294 * @param array $properties Array of properties which must be applied to the created folder object
274 295 * @param string $folderId The id of the folder which will be the parent of the created folder object
  296 + * @param array $policies List of policy ids that MUST be applied
  297 + * @param $addACEs List of ACEs that MUST be added
  298 + * @param $removeACEs List of ACEs that MUST be removed
275 299 * @return string $objectId The id of the created folder object
276 300 */
277 301 // TODO throw ConstraintViolationException if:
278 302 // value of any of the properties violates the min/max/required/length constraints
279 303 // specified in the property definition in the Object-Type.
280   - public function createFolder($repositoryId, $typeId, $properties, $folderId)
  304 + // TODO throw ConstraintViolationException if At least one of the permissions is used in
  305 + // an ACE provided which is not supported by the repository.
  306 + public function createFolder($repositoryId, $properties, $folderId, $policies = array(), $addACEs = array(), $removeACEs = array())
281 307 {
282 308 $objectId = null;
283 309  
284 310 // fetch type definition of supplied type and check for base type "folder", if not true throw exception
285 311 $RepositoryService = new CMISRepositoryService();
286 312 try {
287   - $typeDefinition = $RepositoryService->getTypeDefinition($repositoryId, $typeId);
  313 + $typeDefinition = $RepositoryService->getTypeDefinition($repositoryId, $properties['objectTypeId']);
288 314 }
289 315 // NOTE Not sure that we should throw this specific exception, maybe just let the underlying
290 316 // exception propogate upward...
... ... @@ -294,35 +320,51 @@ class CMISObjectService {
294 320 throw new ConstraintViolationException('Object is not of base type folder. ' . $e->getMessage());
295 321 }
296 322  
297   - if ($typeDefinition['attributes']['baseType'] != 'folder') {
  323 + if ($typeDefinition['attributes']['baseId'] != 'cmis:folder') {
298 324 throw new ConstraintViolationException('Object is not of base type folder');
299 325 }
300 326  
301 327 // Attempt to decode $folderId, use as is if not detected as encoded
302 328 $tmpObjectId = $folderId;
303 329 $tmpObjectId = CMISUtil::decodeObjectId($tmpObjectId, $tmpTypeId);
304   - if ($tmpTypeId != 'Unknown')
  330 + if ($tmpTypeId != 'unknown')
305 331 $folderId = $tmpObjectId;
306 332  
307 333 // if parent folder is not allowed to hold this type, throw exception
308 334 $CMISFolder = new CMISFolderObject($folderId, $this->ktapi);
309   - $allowed = $CMISFolder->getProperty('AllowedChildObjectTypeIds');
310   - if (!is_array($allowed) || !in_array($typeId, $allowed)) {
311   - throw new ConstraintViolationException('Parent folder may not hold objects of this type (' . $typeId . ')');
  335 + $allowed = $CMISFolder->getProperty('allowedChildObjectTypeIds');
  336 + if (!is_array($allowed) || !in_array($properties['objectTypeId'], $allowed)) {
  337 + throw new ConstraintViolationException('Parent folder may not hold objects of this type (' . $properties['objectTypeId'] . ')');
312 338 }
313   -
314   - // TODO if name is blank! throw another exception (check type) - using invalidArgument Exception for now
  339 +
  340 + if (!$typeDefinition['attributes']['controllablePolicy'] && count($policies)) {
  341 + throw new ConstraintViolationException('This object-type does not support policies');
  342 + }
  343 +
  344 + if (!$typeDefinition['attributes']['controllableACL'] && (count($addACEs) || count($removeACEs))) {
  345 + throw new ConstraintViolationException('This object-type does not support ACLs');
  346 + }
  347 +
  348 + // set title and name identical if only one submitted
  349 + if ($properties['title'] == '') {
  350 + $properties['title'] = $properties['name'];
  351 + }
  352 + else if ($properties['name'] == '') {
  353 + $properties['name'] = $properties['title'];
  354 + }
  355 +
  356 + // throw NameConstraintViolation if there is a violation with the given cmis:name property value
  357 + // OR choose a name which does not conflict
315 358 if (trim($properties['name']) == '') {
316   - throw new InvalidArgumentException('Refusing to create an un-named folder');
  359 + throw new NameConstraintViolationException('Refusing to create an un-named folder');
317 360 }
318 361  
319 362 $response = $this->ktapi->create_folder((int)$folderId, $properties['name'], $sig_username = '', $sig_password = '', $reason = '');
320 363 if ($response['status_code'] != 0) {
321 364 throw new StorageException('The repository was unable to create the folder: ' . $response['message']);
322 365 }
323   - else
324   - {
325   - $objectId = CMISUtil::encodeObjectId('Folder', $response['results']['id']);
  366 + else {
  367 + $objectId = CMISUtil::encodeObjectId(FOLDER, $response['results']['id']);
326 368 }
327 369  
328 370 return $objectId;
... ... @@ -333,82 +375,74 @@ class CMISObjectService {
333 375 *
334 376 * @param string $repositoryId
335 377 * @param string $objectId
336   - * @param boolean $includeAllowableActions
337   - * @param boolean $includeRelationships
338   - * @param boolean $returnVersion
339 378 * @param string $filter
340 379 * @return object CMIS object properties
341 380 */
342 381 // TODO optional parameter support
343 382 // TODO FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid
344   - public function getProperties($repositoryId, $objectId, $includeAllowableActions, $includeRelationships,
345   - $returnVersion = false, $filter = '')
  383 + public function getProperties($repositoryId, $objectId, $filter = '')
346 384 {
347 385 $repository = new CMISRepository($repositoryId);
348   -
349   - // TODO a better default value?
350 386 $properties = array();
351   -
352 387 $objectId = CMISUtil::decodeObjectId($objectId, $typeId);
353 388  
354   - if ($typeId == 'Unknown') {
  389 + if ($typeId == 'unknown') {
355 390 throw new ObjectNotFoundException('The type of the requested object could not be determined');
356 391 }
357 392  
358 393 switch($typeId)
359 394 {
360   - case 'Document':
  395 + case 'cmis:document':
361 396 $CMISObject = new CMISDocumentObject($objectId, $this->ktapi, $repository->getRepositoryURI());
362 397 break;
363   - case 'Folder':
  398 + case 'cmis:folder':
364 399 $CMISObject = new CMISFolderObject($objectId, $this->ktapi, $repository->getRepositoryURI());
365 400 break;
366 401 }
367 402  
368 403 // check that we were actually able to retrieve a real object
369   - $objectId = $CMISObject->getProperty('ObjectId');
  404 + $objectId = $CMISObject->getProperty('objectId');
370 405 if (empty($objectId)) {
371 406 throw new ObjectNotFoundException('The requested object could not be found');
372 407 }
373 408  
374   - $properties = $CMISObject->getProperties();
  409 + $propertyCollection = $CMISObject->getProperties();
  410 + $properties = CMISUtil::createObjectPropertiesEntry($propertyCollection);
375 411  
376 412 return $properties;
377 413 }
378 414  
379 415 /**
380   - * Fetches the content stream data for an object
  416 + * Fetches the content stream data for an object, or fetched a rendition stream for a specified rendition
381 417 *
382 418 * @param string $repositoryId
383 419 * @param string $objectId
384   - * @return string $contentStream (binary or text data)
  420 + * @param string $streamId [optional for documents] Specifies the rendition to retrieve if not original document
  421 + * @return string $contentStream (binary [base64 encoded] or text data)
385 422 */
386   - // NOTE streamNotSupportedException: The Repository SHALL throw this exception if the Object-Type definition
387   - // specified by the objectId parameterโ€™s โ€œcontentStreamAllowedโ€ attribute is set to โ€œnot allowedโ€.
388   - //
389   - function getContentStream($repositoryId, $objectId)
  423 + // NOTE Each CMIS protocol binding MAY provide a way for fetching a sub-range within a content stream,
  424 + // in a manner appropriate to that protocol.
  425 + function getContentStream($repositoryId, $objectId, $streamId = null)
390 426 {
391 427 $contentStream = null;
392 428  
393 429 // decode $objectId
394   - $objectId = CMISUtil::decodeObjectId($objectId, $typeId);
  430 + $objectId = CMISUtil::decodeObjectId($objectId, $typeId, $className);
395 431  
396 432 // unknown object type?
397   - if ($typeId == 'Unknown') {
  433 + if ($typeId == 'unknown') {
398 434 throw new ObjectNotFoundException('The type of the requested object could not be determined');
399 435 }
400 436  
401 437 // fetch type definition of supplied object type
402   - $objectClass = 'CMIS' . $typeId . 'Object';
  438 + $objectClass = 'CMIS' . $className . 'Object';
403 439 $CMISObject = new $objectClass($objectId, $this->ktapi);
404 440  
405   - // if content stream is not allowed for this object type definition, throw a ConstraintViolationException
  441 + // if content stream is not allowed for this object type definition, or the specified object does not have
  442 + // a content/rendition stream, throw a ConstraintViolationException
406 443 if (($CMISObject->getAttribute('contentStreamAllowed') == 'notAllowed'))
407 444 {
408   - // NOTE spec version 0.61c specifies both a ConstraintViolationException and a StreamNotSupportedException
409   - // for this case. Choosing to throw StreamNotSupportedException until the specification is clarified
410   - // as it is a more specific exception
411   - throw new StreamNotSupportedException('Content Streams are not allowed for this object type');
  445 + throw new ConstraintViolationException('This object does not have a content stream of the requested type');
412 446 }
413 447  
414 448 // now go on to fetching the content stream
... ... @@ -428,40 +462,35 @@ class CMISObjectService {
428 462 /**
429 463 * Moves a fileable object from one folder to another.
430 464 *
431   - * @param object $repositoryId
432   - * @param object $objectId
433   - * @param object $changeToken [optional]
434   - * @param object $targetFolderId
435   - * @param object $sourceFolderId [optional]
  465 + * @param string $repositoryId
  466 + * @param string $objectId
  467 + * @param string $targetFolderId
  468 + * @param string $sourceFolderId
  469 + * @return string $objectId
436 470 */
437 471 // TODO versioningException: The repository MAY throw this exception if the object is a non-current Document Version.
438   - // TODO check whether object is in fact fileable? not strictly needed, but possibly should be here.
439   - public function moveObject($repositoryId, $objectId, $changeToken = '', $targetFolderId, $sourceFolderId = null)
  472 + // TODO check whether object is in fact fileable? perhaps not strictly needed, but possibly should be here.
  473 + public function moveObject($repositoryId, $objectId, $targetFolderId, $sourceFolderId)
440 474 {
441   - // The $sourceFolderId parameter SHALL be specified if the Repository supports the optional 'unfiling' capability
442   - if (is_null($sourceFolderId))
443   - {
444   - $RepositoryService = new CMISRepositoryService();
445   - $info = $RepositoryService->getRepositoryInfo($repositoryId);
446   - $capabilities = $info->getCapabilities();
447   - // check for unfiling capability
448   - // NOTE this is only required once/if KnowledgeTree allows the source folder id to be optional,
449   - // but it is required for CMIS specification compliance.
450   - if ($capabilities->hasCapabilityUnfiling() === 'true') {
451   - throw new RuntimeException('The source folder id MUST be supplied when unfiling is supported.');
452   - }
453   - }
454   -
455   - // Attempt to decode $objectId, use as is if not detected as encoded
  475 + // attempt to decode $objectId, use as is if not detected as encoded
456 476 $tmpObjectId = $objectId;
457   - $tmpObjectId = CMISUtil::decodeObjectId($tmpObjectId, $typeId);
458   - if ($tmpTypeId != 'Unknown') $objectId = $tmpObjectId;
  477 + $tmpObjectId = CMISUtil::decodeObjectId($tmpObjectId, $typeId, $className);
  478 + if ($tmpTypeId != 'unknown') $objectId = $tmpObjectId;
  479 +
  480 + $objectClass = 'CMIS' . $className . 'Object';
  481 + $CMISObject = new $objectClass($objectId, $this->ktapi);
459 482  
460 483 $targetFolderId = CMISUtil::decodeObjectId($targetFolderId);
461 484  
  485 + // check the $sourceFolderId parameter - if empty or does not match (at least one) parent of the specified object,
  486 + // throw exception
  487 + if (empty($sourceFolderId) || $CMISObject->getProperty('parentId') != $sourceFolderId) {
  488 + throw new InvalidArgumentException('The source folder id is invalid');
  489 + }
  490 +
462 491 // check type id of object against allowed child types for destination folder
463 492 $CMISFolder = new CMISFolderObject($targetFolderId, $this->ktapi);
464   - $allowed = $CMISFolder->getProperty('AllowedChildObjectTypeIds');
  493 + $allowed = $CMISFolder->getProperty('allowedChildObjectTypeIds');
465 494 if (!is_array($allowed) || !in_array($typeId, $allowed)) {
466 495 throw new ConstraintViolationException('Parent folder may not hold objects of this type (' . $typeId . ')');
467 496 }
... ... @@ -474,21 +503,26 @@ class CMISObjectService {
474 503  
475 504 // TODO add reasons and sig data
476 505 // attempt to move object
477   - if ($typeId == 'Folder') {
  506 + if ($typeId == 'cmis:folder') {
478 507 $response = $this->ktapi->move_folder($objectId, $targetFolderId, $reason, $sig_username, $sig_password);
479 508 }
480   - else if ($typeId == 'Document') {
  509 + else if ($typeId == 'cmis:document') {
481 510 $response = $this->ktapi->move_document($objectId, $targetFolderId, $reason, null, null, $sig_username, $sig_password);
482 511 }
483 512 else {
484 513 $response['status_code'] = 1;
485 514 $response['message'] = 'The object type could not be determined.';
486 515 }
  516 +
  517 + // TODO The repository may throw a NameConstrainViolationException if there is a name conflict (determined by KTAPI)
  518 + // or may choose a name which does not conflict
487 519  
488 520 // if failed, throw StorageException
489 521 if ($response['status_code'] != 0) {
490 522 throw new StorageException('The repository was unable to move the object: ' . $response['message']);
491   - }
  523 + }
  524 +
  525 + return CMISUtil::encodeObjectId($objectId, $typeId);
492 526 }
493 527  
494 528 /**
... ... @@ -496,12 +530,11 @@ class CMISObjectService {
496 530 *
497 531 * @param string $repositoryId
498 532 * @param string $objectId
499   - * @param string $changeToken [optional]
500   - * @return boolean true on success (exception should be thrown otherwise)
  533 + * @param string $allVersions [optional] If true, delete all versions
501 534 */
502   - // NOTE Invoking this service method on an object SHALL not delete the entire version series for a Document Object.
503   - // To delete an entire version series, use the deleteAllVersions() service
504   - public function deleteObject($repositoryId, $objectId, $changeToken = null)
  535 + // NOTE Invoking this service method on an object SHALL not delete the entire version series for a Document Object
  536 + // if $allVersions is false.
  537 + public function deleteObject($repositoryId, $objectId, $allVersions = true)
505 538 {
506 539 // determine object type and internal id
507 540 $objectId = CMISUtil::decodeObjectId($objectId, $typeId);
... ... @@ -509,14 +542,14 @@ class CMISObjectService {
509 542 // TODO this should probably be a function, it is now used in two places...
510 543 // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository).
511 544 $exists = true;
512   - if ($typeId == 'Folder')
  545 + if ($typeId == 'cmis:folder')
513 546 {
514 547 $object = $this->ktapi->get_folder_by_id($objectId);
515 548 if (PEAR::isError($object)) {
516 549 $exists = false;
517 550 }
518 551 }
519   - else if ($typeId == 'Document')
  552 + else if ($typeId == 'cmis:document')
520 553 {
521 554 $object = $this->ktapi->get_document_by_id($objectId);
522 555 if (PEAR::isError($object)) {
... ... @@ -533,7 +566,7 @@ class CMISObjectService {
533 566 }
534 567  
535 568 // throw ConstraintViolationException if method is invoked on a Folder object that contains one or more objects
536   - if ($typeId == 'Folder')
  569 + if ($typeId == 'cmis:folder')
537 570 {
538 571 $folderContent = $object->get_listing();
539 572 if (!PEAR::isError($folderContent))
... ... @@ -548,16 +581,19 @@ class CMISObjectService {
548 581 // TODO add the electronic signature capability
549 582 $result = $this->ktapi->delete_folder($objectId, $reason, $sig_username, $sig_password);
550 583 }
551   - else if ($typeId == 'Document')
  584 + else if ($typeId == 'cmis:document')
552 585 {
  586 + // NOTE KnowledgeTree does not support deleting of individual versions and will always delete all versions
  587 + // Throw an exception instead if individual version requested for delete
553 588 // since we do not allow deleting of only the latest version we must throw an exception when this function is called on any document
554 589 // which has more than one version. Okay to delete if there is only the one version.
555   - $versions = $object->get_version_history();
556   - if (count($versions) > 1)
557   - {
558   - // NOTE possibly may want to just throw a RuntimeException rather than this CMIS specific exception.
559   - throw new ConstraintViolationException('This function may not be used to delete an object which has multiple versions. '
560   - . 'Since the repository does not allow deleting of only the latest version, nothing can be deleted.');
  590 + if (!$allVersions) {
  591 + $versions = $object->get_version_history();
  592 + if (count($versions) > 1)
  593 + {
  594 + // NOTE possibly may want to just throw a RuntimeException rather than this CMIS specific exception.
  595 + throw new ConstraintViolationException('This repository does not allow deleting of only the latest version.');
  596 + }
561 597 }
562 598  
563 599 // do not allow deletion of a checked out document - this is actually handled by the ktapi code,
... ... @@ -583,9 +619,9 @@ class CMISObjectService {
583 619 * Deletes an entire tree including all subfolders and other filed objects
584 620 *
585 621 * @param string $repositoryId
586   - * @param string $objectId
587   - * @param string $changeToken [optional]
588   - * @param boolean $unfileNonfolderObject [optional] - note that since KnowledgeTree does not allow unfiling this will be ignored
  622 + * @param string $folderId
  623 + * @param boolean $unfileObjects [optional] unfile/deletesinglefiles/delete - note that since KnowledgeTree does not
  624 + * allow unfiling this will be ignored
589 625 * @param boolean $continueOnFailure [optional] - note that since KnowledgeTree does not allow continue on failure this will be ignored
590 626 * @return array $failedToDelete A list of identifiers of objects in the folder tree that were not deleted.
591 627 */
... ... @@ -594,57 +630,52 @@ class CMISObjectService {
594 630 // โ€ข This is not transactional.
595 631 // โ€ข However, if DeleteSingleFiled is chosen and some objects fail to delete, then single-filed objects are either deleted or kept,
596 632 // never just unfiled. This is so that a user can call this command again to recover from the error by using the same tree.
597   - public function deleteTree($repositoryId, $objectId, $changeToken = null, $unfileNonfolderObject = 'delete', $continueOnFailure = false)
  633 + // NOTE when $continueOnFailure is false, the repository SHOULD abort this method when it fails to delete a single child- or
  634 + // descendant-object
  635 + public function deleteTree($repositoryId, $folderId, $unfileObjects = 'delete', $continueOnFailure = false)
598 636 {
599 637 // NOTE since we do not currently allow partial deletes this will always be empty
600 638 // (unless there is a failure at the requested folder level - what do we do then? exception or array of all objects?)
601 639 $failedToDelete = array();
602 640  
603 641 // determine object type and internal id
604   - $objectId = CMISUtil::decodeObjectId($objectId, $typeId);
  642 + $folderId = CMISUtil::decodeObjectId($folderId, $typeId);
605 643  
606   - // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository).
607   - $exists = true;
608   - if ($typeId == 'Folder') {
609   - $object = $this->ktapi->get_folder_by_id($objectId);
  644 + // throw updateConflictException if the operation is attempting to update an object that is no longer current
  645 + // (as determined by the repository)
  646 + if ($typeId == 'cmis:folder') {
  647 + $object = $this->ktapi->get_folder_by_id($folderId);
610 648 if (PEAR::isError($object)) {
611   - $exists = false;
  649 + throw new updateConflictException('Unable to delete the object as it cannot be found.');
612 650 }
613 651 }
614 652 // if not of type folder then we have a general problem, throw exception
615 653 else {
616 654 throw new RuntimeException('Cannot call deleteTree on a non-folder object.');
617 655 }
618   -
619   - if (!$exists) {
620   - throw new updateConflictException('Unable to delete the object as it cannot be found.');
621   - }
622 656  
623 657 // attempt to delete tree, throw RuntimeException if failed
624 658 // TODO add a default reason
625 659 // TODO add the electronic signature capability
626   - $result = $this->ktapi->delete_folder($objectId, $reason, $sig_username, $sig_password);
627   - // if there was an error performing the delete, throw exception
628   - // TODO list of objects which failed in $failedToDelete array;
629   - // since we do not delete the folder or any contents if anything cannot be deleted, this will contain the entire tree listing
630   - // NOTE once we do this we will need to deal with it externally as well, since we can no longer just catch an exception.
631   - if ($result['status_code'] == 1)
  660 + // TODO support of $continueOnFailure == false - this is not supported by the underlying code and so is left out for now
  661 + $result = $this->ktapi->delete_folder($folderId, $reason, $sig_username, $sig_password);
  662 + // if there was an error performing the delete, list objects not deleted
  663 + if ($result['status_code'] == 1)
632 664 {
633 665 // TODO consider sending back full properties on each object?
634 666 // Not sure yet what this output may be used for by a client, and the current specification (0.61c) says:
635 667 // "A list of identifiers of objects in the folder tree that were not deleted", so let's leave it returning just ids for now.
636   - $failedToDelete[] = CMISUtil::encodeObjectId('Folder', $objectId);
  668 + $failedToDelete[] = CMISUtil::encodeObjectId(FOLDER, $folderId);
637 669 $folderContents = $object->get_full_listing();
638 670 foreach($folderContents as $folderObject)
639 671 {
640   - if ($folderObject['item_type'] == 'F') $type = 'Folder';
641   - else if ($folderObject['item_type'] == 'D') $type = 'Document';
642   - // TODO deal with non-folder and non-document content
643   - else continue;
  672 + if ($folderObject['item_type'] == 'F') {
  673 + $type = 'cmis:folder';
  674 + }
  675 + else if ($folderObject['item_type'] == 'D') {
  676 + $type = 'cmis:document';
  677 + }
644 678  
645   - // TODO find out whether this is meant to be a hierarchical list or simply a list.
646   - // for now we are just returning the list in non-hierarchical form
647   - // (seeing as we don't really know how CMIS AtomPub is planning to deal with hierarchies at this time.)
648 679 $failedToDelete[] = CMISUtil::encodeObjectId($type, $folderObject['id']);
649 680 }
650 681 }
... ... @@ -652,14 +683,8 @@ class CMISObjectService {
652 683 return $failedToDelete;
653 684 }
654 685  
655   - // NOTE this function is presently incomplete and untested. Completion deferred to implementation of Checkout/Checkin
656   - // functionality
657   - // NOTE I am not sure yet when this function would ever be called - checkin would be able to update the content stream
658   - // already and the only easy method we have (via KTAPI as it stands) to update the content is on checkin anyway.
659   - // Additionally this function doesn't take a value for the versioning status (major/minor) and so cannot pass it
660   - // on to the ktapi checkin function.
661   - // I imagine this function may be called if we ever allow updating document content independent of checkin,
662   - // or if we change some of the underlying code and call direct to the document functions and not via KTAPI.
  686 + // NOTE this function is presently incomplete and untested. Completion deferred until Knowledgetree supports setting
  687 + // content streams independent of checkin (which may be necessary for proper client interaction with some clients)
663 688 /**
664 689 * Sets the content stream data for an existing document
665 690 *
... ... @@ -690,7 +715,7 @@ class CMISObjectService {
690 715 // Attempt to decode $documentId, use as is if not detected as encoded
691 716 $tmpObjectId = $documentId;
692 717 $tmpObjectId = CMISUtil::decodeObjectId($tmpObjectId, $tmpTypeId);
693   - if ($tmpTypeId != 'Unknown')
  718 + if ($tmpTypeId != 'unknown')
694 719 $documentId = $tmpObjectId;
695 720  
696 721 // TODO deal with other types except documents
... ... @@ -707,9 +732,8 @@ class CMISObjectService {
707 732 throw new StreamNotSupportedException('Content Streams are not allowed for this object type');
708 733 }
709 734  
710   - $csFileName = $CMISDocument->getProperty('ContentStreamFilename');
711   - if (!empty($csFileName) && (!$overwriteFlag))
712   - {
  735 + $csFileName = $CMISDocument->getProperty('contentStreamFilename');
  736 + if (!empty($csFileName) && (!$overwriteFlag)) {
713 737 throw new ContentAlreadyExistsException('Unable to overwrite existing content stream');
714 738 }
715 739  
... ... @@ -717,20 +741,19 @@ class CMISObjectService {
717 741 // update the document content from this temporary file as per usual
718 742 // TODO Use checkin_document_with_metadata instead if metadata content submitted || update metadata separately?
719 743 $response = $this->ktapi->checkin_document($documentId, $csFileName, 'CMIS setContentStream action', $tempfilename, false);
720   - if ($response['status_code'] != 0)
721   - {
  744 + if ($response['status_code'] != 0) {
722 745 throw new StorageException('Unable to update the content stream. ' . $response['message']);
723 746 }
724 747 // else
725 748 // {
726   -// $objectId = CMISUtil::encodeObjectId('Document', $response['results']['id']);
  749 +// $objectId = CMISUtil::encodeObjectId(DOCUMENT, $response['results']['id']);
727 750 // }
728 751  
729 752 @unlink($csFile);
730 753 // update the CMIS document object with the content stream information
731 754 // $CMISDocument->reload($document['result']['document_id']);
732 755  
733   - return $CMISDocument->getProperty('ObjectId');
  756 + return $CMISDocument->getProperty('objectId');
734 757 }
735 758  
736 759 }
... ...
lib/api/ktcmis/services/CMISRepositoryService.inc.php
... ... @@ -5,7 +5,7 @@
5 5 *
6 6 * KnowledgeTree Community Edition
7 7 * Document Management Made Simple
8   -* Copyright (C) 2008,2009 KnowledgeTree Inc.
  8 +* Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
9 9 *
10 10 *
11 11 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -33,8 +33,12 @@
33 33 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
34 34 * must display the words "Powered by KnowledgeTree" and retain the original
35 35 * copyright notice.
  36 +* Contributor( s): ______________________________________
  37 +*/
  38 +
  39 +/**
36 40 *
37   -* @copyright 2008-2009, KnowledgeTree Inc.
  41 +* @copyright 2008-2010, KnowledgeTree Inc.
38 42 * @license GNU General Public License version 3
39 43 * @author KnowledgeTree Team
40 44 * @package KTCMIS
... ... @@ -97,12 +101,16 @@ class CMISRepositoryService {
97 101 * @param boolean $hasMoreItems TRUE if there are more items to return than were requested
98 102 * @return array $objectTypes
99 103 */
100   - // NOTE this code may fit better within the Repository Class
101 104 // TODO return for specific type when $typeId is specified
102 105 // TODO other optional parameters
103   - function getTypes($repositoryId, $typeId = '', $returnPropertyDefinitions = false,
  106 + // This code is superseded by getTypeChildren and getTypeDescendants - when implementing those, check
  107 + // whether it is possible to entirely remove this function or if it is to remain and be shared by the
  108 + // other two functions (when no type is specified they will return base types [children] amd all types
  109 + // [descendants] respectively
  110 + public function getTypes($repositoryId, $typeId = '', $returnPropertyDefinitions = false,
104 111 $maxItems = 0, $skipCount = 0, &$hasMoreItems = false)
105   - {
  112 + {
  113 + /*
106 114 if ($typeId != '')
107 115 {
108 116 try {
... ... @@ -113,6 +121,7 @@ class CMISRepositoryService {
113 121 throw new InvalidArgumentException('Type ' . $typeId . ' is not supported');
114 122 }
115 123 }
  124 + */
116 125  
117 126 $repository = new CMISRepository($repositoryId);
118 127 $supportedTypes = $repository->getTypes();
... ... @@ -154,12 +163,12 @@ class CMISRepositoryService {
154 163 // NOTE this code may fit better in the Repository Class
155 164 function getTypeDefinition($repositoryId, $typeId)
156 165 {
  166 + $typeId = ucwords(str_replace('cmis:', '', $typeId));
157 167 $object = 'CMIS' . $typeId . 'Object';
158 168  
159 169 // check whether the object type exists, return error if not
160 170 // consider throwing an exception instead (see General Exceptions)
161   - if (!file_exists(CMIS_DIR . '/objecttypes/' . $object . '.inc.php'))
162   - {
  171 + if (!file_exists(CMIS_DIR . '/objecttypes/' . $object . '.inc.php')) {
163 172 throw new InvalidArgumentException('Type ' . $typeId . ' is not supported');
164 173 }
165 174  
... ... @@ -167,8 +176,11 @@ class CMISRepositoryService {
167 176  
168 177 require_once(CMIS_DIR . '/objecttypes/' . $object . '.inc.php');
169 178 $cmisObject = new $object;
  179 +
  180 + // NOTE The specification is ambigous here: it states that this function must return the type properties, but
  181 + // the atompub example shows the type attributes, not properties; since most properties are only populated
  182 + // on creation of an instance of an object-type, we choose to go with the attributes and not the properties
170 183 $typeDefinition['attributes'] = $cmisObject->getAttributes();
171   - $typeDefinition['properties'] = $cmisObject->getProperties();
172 184  
173 185 return $typeDefinition;
174 186 }
... ...
lib/api/ktcmis/services/CMISVersioningService.inc.php
... ... @@ -25,110 +25,71 @@ class CMISVersioningService {
25 25 }
26 26  
27 27 /**
28   - * Deletes all Document Objects in the specified Version Series, including the Private Working Copy if it exists
29   - *
30   - * @param string $repositoryId
31   - * @param string $versionSeriesId
32   - * @return boolean true if successful
33   - */
34   - // NOTE For KnowledgeTree the $versionSeriesId should be the latest version, if not it will be taken as implied.
35   - // Should we decide to implement the ability to delete individual versions,
36   - // then an exception may be thrown under certain circumstances (to be determined)
37   - // NOTE I am not really sure how this is going to be handled by CMIS clients.
38   - // Testing with CMISSpaces we have it sending the actual document id, not a version series id.
39   - // This may be due to the data sent back from our code, or it may just be how CMISSpaces does it.
40   - // There is a note in their source code about this.
41   - // Meantime we will try based on document id and adjust as needed later
42   - public function deleteAllVersions($repositoryId, $versionSeriesId)
43   - {
44   - // attempt to delete based on versionSeriesId as document/object id
45   - // determine object type and internal id
46   - $objectId = CMISUtil::decodeObjectId($versionSeriesId, $typeId);
47   -
48   - // if not a versionable object, throw exception
49   - // NOTE that we are assuming only documents are versionable at the moment
50   - if ($typeId != 'Document') {
51   - throw new RuntimeException('The object type is not versionable and cannot be deleted using deleteAllVersions.');
52   - }
53   -
54   - // try to delete
55   - // TODO add a default reason
56   - // TODO add the electronic signature capability
57   - $auth_sig = true;
58   - $result = $this->ktapi->delete_document($objectId, $reason, $auth_sig, $sig_username, $sig_password);
59   -
60   - // TODO delete any PWC which may exist (NOTE added 24 August 2009 - we did not have any PWC functionality when this function was originally created)
61   -
62   - // if there was an error performing the delete, throw exception
63   - if ($result['status_code'] == 1) {
64   - throw new RuntimeException('There was an error deleting the object: ' . $result['message']);
65   - }
66   -
67   - return true;
68   - }
69   -
70   - /**
71 28 * Checks out a document and creates the PWC (Private Working Copy) which will represent the checked out document
72 29 *
73 30 * @param string $repositoryId
74   - * @param string $documentId
75   - * @param string $changeToken [optional]
76   - * @return string $documentId The id of the PWC object
  31 + * @param string $objectId
  32 + * @return string $objectId The id of the PWC object
77 33 * @return boolean $contentCopied TRUE if contentStream is a copy of the document content stream, FALSE if contentStream not set
78 34 */
79   - // TODO exceptions:
80   - // รขโ‚ฌยข versioningException: The repository MAY throw this exception if the object is a non-current Document Version.
81 35 // NOTE since we need to return two values, we return one via argument by reference
82   - // since $documentId already exists in the argument list, that was chosen as the "return by reference" value
  36 + // since $objectId already exists in the argument list, that was chosen as the "return by reference" value
83 37 // TODO set up delivery of content stream? or is that up to the CMIS client?
84   - public function checkOut($repositoryId, &$documentId, $changeToken = '')
  38 + public function checkOut($repositoryId, &$objectId)
85 39 {
86 40 $contentCopied = false;
87   -
88   - $documentId = CMISUtil::decodeObjectId($documentId, $typeId);
  41 +
  42 + $objectId = CMISUtil::decodeObjectId($objectId, $typeId);
89 43  
90 44 // NOTE We are not planning on persisting the PWC beyond the current session, it will be re-created on access of the checked out document
91 45 // TODO consider persisting in the database? How will this relate to JSR if we are switching to that?
92 46 // NOTE within the current system it is assumed if a new document metadata version is created that this is the latest version of the document
93 47 // TODO see if there is an easy way to modify this, else we may not have an easy way to persist PWC objects
94   -
  48 +
95 49 // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository).
96 50 try {
97   - $pwc = new CMISDocumentObject($documentId, $this->ktapi);
  51 + $pwc = new CMISDocumentObject($objectId, $this->ktapi);
98 52 }
99 53 catch (exception $e) {
100 54 throw new UpdateConflictException($e->getMessage());
101 55 }
102   -
  56 +
103 57 // throw exception if the object is not versionable
104 58 if (!$pwc->getAttribute('versionable')) {
105 59 throw new ConstraintViolationException('This document is not versionable and may not be checked out');
106 60 }
107   -
  61 +
  62 + // check that this is the latest version
  63 + if ($pwc->getProperty('isLatestVersion') != true) {
  64 + throw new VersioningException('The document is not the latest version and cannot be checked out');
  65 + }
  66 +
108 67 // NOTE KTAPI as currently implemented does not give a direct response which indicates if the document is already checked out,
109 68 // as long as the same user is calling the checkout again, so should we add a check here specifically?
110 69  
111 70 // run checkout process - set $download = false (third function argument) as we want to return the document content via the contentStream
112   - $response = $this->ktapi->checkout_document($documentId, 'CMIS Checkout Action', false, $sig_username, $sig_password);
  71 + $response = $this->ktapi->checkout_document($objectId, 'CMIS Checkout Action', false, $sig_username, $sig_password);
113 72 // if there was an error, throw an exception
114 73 if ($response['status_code'] == 1) {
115 74 throw new StorageException($response['message']);
116   - };
117   -
  75 + }
  76 +
118 77 // if successful, set $contentCopied = true; unless contentStream is not set
119   - if ($pwc->getProperty('ContentStreamFilename') != '') $contentCopied = true;
120   - $documentId = CMISUtil::encodeObjectId('Document', $documentId);
121   -
  78 + if ($pwc->getProperty('contentStreamFilename') != '') {
  79 + $contentCopied = true;
  80 + }
  81 + $objectId = CMISUtil::encodeObjectId(DOCUMENT, $objectId);
  82 +
122 83 // mark document object as checked out
123   - $pwc->setProperty('IsVersionSeriesCheckedOut', true);
  84 + $pwc->setProperty('isVersionSeriesCheckedOut', true);
124 85 $userName = '';
125 86 $user = $this->ktapi->get_user();
126 87 if (!PEAR::isError($user)) {
127 88 $userName = $user->getName();
128 89 }
129   - $pwc->setProperty('VersionSeriesCheckedOutBy', $userName);
130   - $pwc->setProperty('VersionSeriesCheckedOutId', $documentId);
131   -
  90 + $pwc->setProperty('versionSeriesCheckedOutBy', $userName);
  91 + $pwc->setProperty('versionSeriesCheckedOutId', $objectId);
  92 +
132 93 return $contentCopied;
133 94 }
134 95  
... ... @@ -136,19 +97,18 @@ class CMISVersioningService {
136 97 * Reverses the effect of a checkout: I.E. deletes the PWC (Private Working Copy) and re-sets the status of the document to "not checked out"
137 98 *
138 99 * @param string $repositoryId
139   - * @param string $documentId
140   - * @param string $changeToken [optional]
  100 + * @param string $objectId
141 101 */
142 102 // TODO exceptions:
143 103 // รขโ‚ฌยข versioningException - The repository MAY throw this exception if the object is a non-current Document Version.
144   - public function cancelCheckOut($repositoryId, $documentId, $changeToken = '')
  104 + public function cancelCheckOut($repositoryId, $objectId)
145 105 {
146   - $documentId = CMISUtil::decodeObjectId($documentId, $typeId);
  106 + $objectId = CMISUtil::decodeObjectId($objectId, $typeId);
147 107  
148 108 /* re-generate PWC object */
149 109 // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository).
150 110 try {
151   - $pwc = new CMISDocumentObject($documentId, $this->ktapi);
  111 + $pwc = new CMISDocumentObject($objectId, $this->ktapi);
152 112 }
153 113 catch (exception $e) {
154 114 throw new UpdateConflictException($e->getMessage());
... ... @@ -159,10 +119,15 @@ class CMISVersioningService {
159 119 throw new ConstraintViolationException('This document is not versionable and may not be checked out');
160 120 }
161 121  
  122 + // check that this is the latest version
  123 + if ($pwc->getProperty('isLatestVersion') != true) {
  124 + throw new VersioningException('The document is not the latest version');
  125 + }
  126 +
162 127 // TODO delete PWC - since we are not persisting the PWC this is not necessary at the moment
163 128  
164 129 // cancel checkout
165   - $response = $this->ktapi->undo_document_checkout($documentId, 'CMIS Cancel Checkout Action', $sig_username, $sig_password);
  130 + $response = $this->ktapi->undo_document_checkout($objectId, 'CMIS Cancel Checkout Action', $sig_username, $sig_password);
166 131  
167 132 // if there was any error in cancelling the checkout
168 133 if ($response['status_code'] == 1) {
... ... @@ -174,23 +139,31 @@ class CMISVersioningService {
174 139 * Checks in a checked out document
175 140 *
176 141 * @param string $repositoryId
177   - * @param string $documentId
178   - * @param boolean $major
179   - * @param string $changeToken [optional]
  142 + * @param string $objectId
  143 + * @param boolean $major [optional] defaults to true
180 144 * @param array $properties [optional]
181 145 * @param contentStream $contentStream [optional]
182 146 * @param string $checkinComment [optional]
183   - * @return string $documentId
  147 + * @param array $policies
  148 + * @param array $addACEs
  149 + * @param array $removeACEs
  150 + * @return string $objectId
184 151 */
185   - // TODO Exceptions:
186   - // รขโ‚ฌยข versioningException - The repository MAY throw this exception if the object is a non-current Document Version
187   - public function checkIn($repositoryId, $documentId, $major, $contentStream = null, $changeToken = '', $properties = array(), $checkinComment = '')
  152 + // NOTE For repositories that do NOT support the optional โ€œcapabilityPWCUpdatableโ€ capability, the properties
  153 + // and contentStream input parameters MUST be provided on the checkIn method for updates to happen as part
  154 + // of checkIn.
  155 + // NOTE Only those properties whose values are different than the original value of the object need to be submitted.
  156 + // NOTE we are not actually doing anything with the properties at this time, only the content stream
  157 + // TODO filename changes and anything else supported in web interface, possibly additional supported by CMIS clients
  158 + public function checkIn($repositoryId, $objectId, $major = true, $properties = array(), $contentStream = null,
  159 + $checkinComment = '', $policies = array(), $addACEs = array(), $removeACEs = array())
188 160 {
189   - $documentId = CMISUtil::decodeObjectId($documentId, $typeId);
  161 +
  162 + $objectId = CMISUtil::decodeObjectId($objectId, $typeId);
190 163  
191 164 // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository).
192 165 try {
193   - $pwc = new CMISDocumentObject($documentId, $this->ktapi);
  166 + $pwc = new CMISDocumentObject($objectId, $this->ktapi);
194 167 }
195 168 catch (exception $e) {
196 169 throw new UpdateConflictException($e->getMessage());
... ... @@ -210,26 +183,33 @@ class CMISVersioningService {
210 183 throw new StorageException($e->getMessage());
211 184 }
212 185  
213   - if (($typeDefinition['attributes']['contentStreamAllowed'] == 'notAllowed') && !empty($contentStream)) {
  186 + // if content stream is required (capabilityPWCUpdatability == false) and no content stream is supplied,
  187 + // throw a ConstraintViolationException
  188 + if (($typeDefinition['attributes']['contentStreamAllowed'] == 'required') && is_null($contentStream)) {
  189 + throw new RuntimeException('This repository requires a content stream for document update on checkin. '
  190 + . 'Refusing to checkin an empty document');
  191 + }
  192 + else if (($typeDefinition['attributes']['contentStreamAllowed'] == 'notAllowed') && !empty($contentStream)) {
214 193 throw new StreamNotSupportedException('Content Streams are not supported');
215 194 }
216   -
  195 +
217 196 // check that this is the latest version
218   - if ($pwc->getProperty('IsLatestVersion') != true) {
  197 + if ($pwc->getProperty('isLatestVersion') != true) {
219 198 throw new VersioningException('The document is not the latest version and cannot be checked in');
220 199 }
221 200  
222 201 // now do the checkin
223 202 $tempfilename = CMISUtil::createTemporaryFile($contentStream);
224   - $response = $this->ktapi->checkin_document($documentId, $pwc->getProperty('ContentStreamFilename'), $reason, $tempfilename, $major,
  203 + $reason = 'CMIS object checkin';
  204 + $response = $this->ktapi->checkin_document($objectId, $pwc->getProperty('contentStreamFilename'), $reason, $tempfilename, $major,
225 205 $sig_username, $sig_password);
226   -
227   - // if there was any error in cancelling the checkout
  206 +
  207 + // if there was any error checking in
228 208 if ($response['status_code'] == 1) {
229 209 throw new RuntimeException('There was an error checking in the document: ' . $response['message']);
230 210 }
231 211  
232   - return CMISUtil::encodeObjectId(DOCUMENT, $documentId);
  212 + return CMISUtil::encodeObjectId(DOCUMENT, $objectId);
233 213 }
234 214  
235 215 }
... ...
lib/api/ktcmis/util/CMISUtil.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008,2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ... @@ -32,8 +32,12 @@
32 32 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
33 33 * must display the words "Powered by KnowledgeTree" and retain the original
34 34 * copyright notice.
  35 + * Contributor( s): ______________________________________
  36 + */
  37 +
  38 +/**
35 39 *
36   - * @copyright 2008-2009, KnowledgeTree Inc.
  40 + * @copyright 2008-2010, KnowledgeTree Inc.
37 41 * @license GNU General Public License version 3
38 42 * @author KnowledgeTree Team
39 43 * @package KTCMIS
... ... @@ -65,11 +69,13 @@ class CMISUtil {
65 69 {
66 70 case 'D':
67 71 case 'Document':
  72 + case 'cmis:document':
68 73 case DOCUMENT:
69 74 $encoded = 'D' . $objectId;
70 75 break;
71 76 case 'F':
72 77 case 'Folder':
  78 + case 'cmis:folder':
73 79 case FOLDER:
74 80 $encoded = 'F' . $objectId;
75 81 break;
... ... @@ -91,14 +97,14 @@ class CMISUtil {
91 97 * @param string &$typeId
92 98 * @return string $objectId
93 99 */
94   - static public function decodeObjectId($objectId, &$typeId = null)
  100 + static public function decodeObjectId($objectId, &$typeId = null, &$className = '')
95 101 {
96 102 if (!is_string($objectId))
97 103 {
98   - $typeId = 'Unknown';
  104 + $typeId = 'unknown';
99 105 return null;
100 106 }
101   -
  107 +
102 108 $typeId = null;
103 109  
104 110 // NOTE Not sure whether this really belongs here, but probably this is the safest and most reliable place
... ... @@ -117,7 +123,8 @@ class CMISUtil {
117 123 // method of doing this.
118 124 // meantime this minor hack will get things working for the existing system structure, as the root
119 125 // folder should always be id 1.
120   - $typeId = 'Folder';
  126 + $typeId = 'cmis:folder';
  127 + $className = 'Folder';
121 128 return '1';
122 129 }
123 130  
... ... @@ -128,13 +135,15 @@ class CMISUtil {
128 135 switch($type)
129 136 {
130 137 case 'D':
131   - $typeId = 'Document';
  138 + $typeId = 'cmis:document';
  139 + $className = 'Document';
132 140 break;
133 141 case 'F':
134   - $typeId = 'Folder';
  142 + $typeId = 'cmis:folder';
  143 + $className = 'Folder';
135 144 break;
136 145 default:
137   - $typeId = 'Unknown';
  146 + $typeId = 'unknown';
138 147 break;
139 148 }
140 149  
... ... @@ -172,20 +181,19 @@ class CMISUtil {
172 181 $CMISObject = new CMISFolderObject($object['id'], $ktapi, $repositoryURI);
173 182 break;
174 183 }
175   -
  184 +
176 185 $CMISArray[$count]['object'] = $CMISObject;
177   -
  186 +
178 187 // if sub-array
179   - if (count($object['items']) > 0)
180   - {
181   - $CMISArray[$count]['items'] = self::createChildObjectHierarchy($object['items'], $repositoryURI, $ktapi);
  188 + if (count($object['items']) > 0) {
  189 + $CMISArray[$count]['children'] = self::createChildObjectHierarchy($object['items'], $repositoryURI, $ktapi);
182 190 }
183 191 }
184 192 else
185 193 {
186 194 // NOTE why is this necessary? That's what you get for not commenting it at the time
187   - // TODO comment this properly
188   - $CMISArray[$count] = self::createChildObjectHierarchy($object, $repositoryURI, $ktapi);
  195 + // TODO comment this properly, once we know why it is happening
  196 + // $CMISArray[$count] = self::createChildObjectHierarchy($object, $repositoryURI, $ktapi);
189 197 }
190 198 }
191 199 }
... ... @@ -205,6 +213,7 @@ class CMISUtil {
205 213 * @return array $CMISArray
206 214 */
207 215 // NOTE this will have to change if we implement multi-filing
  216 + // NOTE this function probably serves no purpose, the parents are to be returned as a flat array
208 217 static public function createParentObjectHierarchy($input, $repositoryURI, &$ktapi)
209 218 {
210 219 $CMISArray = array();
... ... @@ -220,9 +229,8 @@ class CMISUtil {
220 229 $CMISElement['object'] = $CMISObject;
221 230  
222 231 // if more parent elements
223   - if (count($input) > 0)
224   - {
225   - $CMISElement['items'] = self::createParentObjectHierarchy($input, $repositoryURI, $ktapi);
  232 + if (count($input) > 0) {
  233 + $CMISElement['parents'] = self::createParentObjectHierarchy($input, $repositoryURI, $ktapi);
226 234 }
227 235  
228 236 $CMISArray[] = $CMISElement;
... ... @@ -239,20 +247,23 @@ class CMISUtil {
239 247 * though the output may well be different to what went into that function
240 248 *
241 249 * @param array $input // input hierarchy to decode
242   - * @param string $linkText // 'child' or 'parent' - indicates direction of hierarchy => descending or ascending
  250 + * @param string $linkText // 'children' or 'parents' - indicates direction of hierarchy => descending or ascending
243 251 * @return array $hierarchy
244 252 */
245   - static public function decodeObjectHierarchy($input, $linkText)
  253 + static public function decodeObjectHierarchy($input, $linkText = 'children')
246 254 {
247 255 $hierarchy = array();
248   -
  256 +
249 257 // first, run through the base array to get the initial children
250 258 foreach ($input as $key => $entry)
251 259 {
252 260 $object = $entry['object'];
253 261 $properties = $object->getProperties();
254   -
255 262 $hierarchy[$key] = self::createObjectPropertiesEntry($properties);
  263 +
  264 + if (isset($entry[$linkText]) && count($entry[$linkText])) {
  265 + $hierarchy[$key][$linkText] = self::decodeObjectHierarchy($entry[$linkText], $linkText);
  266 + }
256 267 }
257 268  
258 269 return $hierarchy;
... ... @@ -270,11 +281,11 @@ class CMISUtil {
270 281 static public function createObjectPropertiesEntry($properties)
271 282 {
272 283 $object = array();
273   -
  284 +
274 285 foreach(CMISPropertyCollection::$propertyTypes as $property => $type)
275 286 {
276   - // hack for Author property
277   - if ($property == 'Author') {
  287 + // author property does not work the same as the others
  288 + if ($property == 'author') {
278 289 $object[$property] = array('value' => $properties->getValue($property));
279 290 }
280 291 else {
... ... @@ -282,83 +293,6 @@ class CMISUtil {
282 293 }
283 294 }
284 295  
285   - /* old static method */
286   - /*
287   - $object['Author'] = array('value' => $properties->getValue('Author'));
288   -
289   - $object['properties']['BaseType'] = array('type' => $properties->getFieldType('BaseType'),
290   - 'value' => $properties->getValue('BaseType'));
291   -
292   - $object['properties']['Name'] = array('type' => $properties->getFieldType('Name'),
293   - 'value' => $properties->getValue('Name'));
294   -
295   - $object['properties']['ParentId'] = array('type' => $properties->getFieldType('ParentId'),
296   - 'value' => self::encodeObjectId('Folder',
297   - $properties->getValue('ParentId')));
298   -
299   - $object['properties']['Uri'] = array('type' => $properties->getFieldType('Uri'),
300   - 'value' => $properties->getValue('Uri'));
301   -
302   - // TODO ensure format of date is always correct
303   - $object['properties']['LastModificationDate'] = array('type' => $properties->getFieldType('LastModificationDate'),
304   - 'value' => $properties->getValue('LastModificationDate'));
305   -
306   - $object['properties']['CreatedBy'] = array('type' => $properties->getFieldType('CreatedBy'),
307   - 'value' => $properties->getValue('CreatedBy'));
308   -
309   - $object['properties']['AllowedChildObjectTypeIds'] = array('type' => $properties->getFieldType('AllowedChildObjectTypeIds'),
310   - 'value' => $properties->getValue('AllowedChildObjectTypeIds'));
311   -
312   - $object['properties']['CreationDate'] = array('type' => $properties->getFieldType('CreationDate'),
313   - 'value' => $properties->getValue('CreationDate'));
314   -
315   - $object['properties']['LastModifiedBy'] = array('type' => $properties->getFieldType('LastModifiedBy'),
316   - 'value' => $properties->getValue('LastModifiedBy'));
317   -
318   - $object['properties']['ChangeToken'] = array('type' => $properties->getFieldType('ChangeToken'),
319   - 'value' => $properties->getValue('ChangeToken'));
320   -
321   - $object['properties']['ObjectTypeId'] = array('type' => $properties->getFieldType('ObjectTypeId'),
322   - 'value' => $properties->getValue('ObjectTypeId'));
323   -
324   - $object['properties']['ObjectId'] = array('type' => $properties->getFieldType('ObjectId'),
325   - 'value' => $properties->getValue('ObjectId'));
326   -
327   - if (strtolower($properties->getValue('ObjectTypeId')) == 'document')
328   - {
329   - $object['properties']['ChangeToken'] = array('type' => $properties->getFieldType('ChangeToken'),
330   - 'value' => $properties->getValue('ChangeToken'));
331   - $contentStreamLength = $properties->getValue('ContentStreamLength');
332   - if (!empty($contentStreamLength))
333   - {
334   - $contentStreamLength = $properties->getValue('ContentStreamLength');
335   - $object['properties']['ContentStreamAllowed'] = array('type' => $properties->getFieldType('ContentStreamAllowed'),
336   - 'value' => $properties->getValue('ContentStreamAllowed'));
337   - $object['properties']['ContentStreamLength'] = array('type' => $properties->getFieldType('ContentStreamLength'),
338   - 'value' => $properties->getValue('ContentStreamLength'));
339   - $object['properties']['ContentStreamMimeType'] = array('type' => $properties->getFieldType('ContentStreamMimeType'),
340   - 'value' => $properties->getValue('ContentStreamMimeType'));
341   - $object['properties']['ContentStreamFilename'] = array('type' => $properties->getFieldType('ContentStreamFilename'),
342   - 'value' => $properties->getValue('ContentStreamFilename'));
343   - $object['properties']['ContentStreamUri'] = array('type' => $properties->getFieldType('ContentStreamUri'),
344   - 'value' => $properties->getValue('ContentStreamUri'));
345   - }
346   - }
347   - */
348   -
349   - /* what on earth was this for? */
350   - /*
351   - // if we have found a child/parent with one or more children/parents, recurse into the child/parent object
352   - if (count($entry['items']) > 0) {
353   - $object[$linkText] = self::decodeObjectHierarchy($entry['items'], $linkText);
354   - }
355   - // NOTE may need to set a null value here in case webservices don't like it unset
356   - // so we'll set it just in case...
357   - else {
358   - $object[$linkText] = null;
359   - }
360   - */
361   -
362 296 return $object;
363 297 }
364 298  
... ... @@ -367,8 +301,11 @@ class CMISUtil {
367 301 * via var_export (which returns a useable PHP string for creating the object from array content)
368 302 * and regular expressions to extract the array definitions and structure without the class specific code
369 303 *
370   - * NOTE this function is not reliable for objects which contain ktapi instances, as it appears there is a recursive reference
371   - * TODO attempt to deal with recursive references?
  304 + * NOTE this function is not reliable for objects which contain ktapi instances, as it appears there is a recursive reference;
  305 + * this will apply to any class which contains recursive references (which is bad practice and should not be done - the
  306 + * problem is with the object and not this code
  307 + *
  308 + * TODO attempt to deal with recursive references? - better to fix the objects in question, if possible
372 309 *
373 310 * @param object $data
374 311 * @return array $array
... ... @@ -378,12 +315,12 @@ class CMISUtil {
378 315 $array = array();
379 316  
380 317 $stringdata = var_export($data, true);
381   - // clean up ", )" - NOTE this may not be necessary
  318 + // clean up ", )" - NOTE this may not be necessary, but is included for safety
382 319 $stringdata = preg_replace('/, *\r?\n? *\)/', ')', $stringdata);
383 320  
384   - // NOTE is this while loop even needed?
385   - while (preg_match('/\b[\w]*::__set_state\(/', $stringdata, $matches))
386   - {
  321 + // NOTE is this while loop even needed, or can we just run a preg_replace without the while?
  322 + // TODO find out...
  323 + while (preg_match('/\b[\w]*::__set_state\(/', $stringdata, $matches)) {
387 324 $stringdata = preg_replace('/\b[\w]*::__set_state\(/', $matches[1], $stringdata);
388 325 }
389 326  
... ... @@ -407,18 +344,18 @@ class CMISUtil {
407 344 }
408 345  
409 346 // TODO more robust base64 encoding detection, if possible
410   -
  347 +
411 348 /**
412 349 * Checks the contentStream and ensures that it is a correct base64 string;
413 350 * This is purely for clients such as CMISSpaces breaking the content into
414   - * chunks before base64 encoding.
  351 + * chunks before base64 encoding each and this coming through as a single string containing multiple base64 chunks.
415 352 *
416 353 * If the stream is chunked, it is decoded in chunks and sent back as a single stream.
417 354 * If it is not chunked it is decoded as is and sent back as a single stream.
418 355 *
419 356 * NOTE there is an alternative version of this function called decodeChunkedContentStreamLong.
420 357 * that version checks line lengths, which should not be necessary.
421   - * this version merely splits on one or two "=" which is less complex and possibly faster (test this assumption)
  358 + * this version merely splits on one or two "=" which is less complex and appears to be faster
422 359 * (one or two "=" signs is the specified padding used for base64 encoding at the end of an encoded string, when needed)
423 360 *
424 361 * @param object $contentStream
... ... @@ -428,23 +365,23 @@ class CMISUtil {
428 365 {
429 366 // always trim content, just in case, as the AtomPub specification says content may be padded with whitespace at the start and end.
430 367 $contentStream = trim($contentStream);
431   -
  368 +
432 369 // check whether the content is encoded first, return as is if not
433 370 // Aโ€“Z, aโ€“z, 0โ€“9, +, /
434 371 // NOTE this makes the (fairly reasonable) assumption that text content contains at least one space or punctuation character.
435 372 // of course this may fail should something be sent in plain text such as a passwords file containing sha1 or md5 hashes only.
436 373 if (preg_match('/[^\w\/\+=\n]+/', $content)) return $contentStream;
437   -
  374 +
438 375 $decoded = '';
439   -
  376 +
440 377 // split the content stream on ={1,2}
441 378 $parts = preg_split('/(={1,2})/', $contentStream, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
442 379 foreach($parts as $part)
443   - {
  380 + {
444 381 if (preg_match('/={1,2}/', $part)) {
445 382 continue;
446 383 }
447   -
  384 +
448 385 // lookahead for delimiter, because we may need it back.
449 386 // NOTE that decoding appears to work fine without this, so this is just an "in case".
450 387 // NOTE that even with this it seems the present function works faster than the alternative below.
... ... @@ -453,14 +390,14 @@ class CMISUtil {
453 390 $part .= $parts[$key+1];
454 391 }
455 392 }
456   -
457   - // decode, append to output to be re-encoded
  393 +
  394 + // decode, append to output
458 395 $decoded .= base64_decode($part);
459 396 }
460 397  
461 398 return $decoded;
462 399 }
463   -
  400 +
464 401 /**
465 402 * Checks the contentStream and ensures that it is a correct base64 string;
466 403 * This is purely for clients such as CMISSpaces breaking the content into
... ... @@ -470,7 +407,7 @@ class CMISUtil {
470 407 * If it is not chunked it is decoded as is and sent back as a single stream.
471 408 *
472 409 * NOTE this function and the above need to be checked for efficiency.
473   - * The current one appears to be miles better (1/0/3 vs 14/4/57 on respective test files)
  410 + * The other one appears to be miles better (1/0/3 vs 14/4/57 on respective test files)
474 411 *
475 412 * @param object $contentStream
476 413 * @return string decoded
... ... @@ -479,13 +416,13 @@ class CMISUtil {
479 416 {
480 417 // always trim content, just in case, as the AtomPub specification says content may be padded with whitespace at the start and end.
481 418 $contentStream = trim($contentStream);
482   -
  419 +
483 420 // check whether the content is encoded first, return as is if not
484 421 // Aโ€“Z, aโ€“z, 0โ€“9, +, /
485 422 // NOTE this makes the (fairly reasonable) assumption that text content contains at least one space or punctuation character.
486 423 // of course this may fail should something be sent in plain text such as a passwords file containing sha1 or md5 hashes only.
487 424 if (preg_match('/[^\w\/\+=\n]+/', $content)) return $contentStream;
488   -
  425 +
489 426 // check the content stream for any lines of unusual length (except the last line, which can be any length)
490 427 $count = -1;
491 428 $length = 0;
... ... @@ -500,11 +437,11 @@ class CMISUtil {
500 437 foreach ($splitStream as $line)
501 438 {
502 439 $curlen = strlen($line);
503   -
  440 +
504 441 if ($length == 0) {
505 442 $length = $curlen;
506 443 }
507   -
  444 +
508 445 // if we find one we know that we must split the line here and end the previous base64 string
509 446 if ($curlen > $length)
510 447 {
... ... @@ -522,7 +459,7 @@ class CMISUtil {
522 459 }
523 460  
524 461 $decode[++$count] = $b64String . $lastChunk;
525   -
  462 +
526 463 $b64String = $nextChunk . "\n";
527 464 $length = strlen($nextChunk);
528 465  
... ... @@ -553,7 +490,7 @@ class CMISUtil {
553 490  
554 491 return $decoded;
555 492 }
556   -
  493 +
557 494 /**
558 495 * Function to check whether a specified object exists within the KnowledgeTree system
559 496 *
... ... @@ -565,14 +502,14 @@ class CMISUtil {
565 502 public function contentExists($typeId, $objectId, &$ktapi)
566 503 {
567 504 $exists = true;
568   - if ($typeId == 'Folder')
  505 + if ($typeId == 'cmis:folder')
569 506 {
570 507 $object = $ktapi->get_folder_by_id($objectId);
571 508 if (PEAR::isError($object)) {
572 509 $exists = false;
573 510 }
574 511 }
575   - else if ($typeId == 'Document')
  512 + else if ($typeId == 'cmis:document')
576 513 {
577 514 $object = $ktapi->get_document_by_id($objectId);
578 515 if (PEAR::isError($object)) {
... ... @@ -583,10 +520,10 @@ class CMISUtil {
583 520 else {
584 521 $exists = false;
585 522 }
586   -
  523 +
587 524 return $exists;
588 525 }
589   -
  526 +
590 527 /**
591 528 * Creates a temporary file
592 529 * Cleanup is the responsibility of the calling code
... ... @@ -598,22 +535,22 @@ class CMISUtil {
598 535 {
599 536 // if contentStream is empty, cannot create file
600 537 if (empty($contentStream)) return null;
601   -
  538 +
602 539 // TODO consider checking whether content is encoded (currently we expect encoded)
603 540 // TODO choose between this and the alternative decode function (see CMISUtil class)
604 541 // this will require some basic benchmarking
605 542 $contentStream = self::decodeChunkedContentStream($contentStream);
606   -
  543 +
607 544 // NOTE There is a function in CMISUtil to do this, written for the unit tests but since KTUploadManager exists
608 545 // and has more functionality which could come in useful at some point I decided to go with that instead
609 546 // (did not know this existed when I wrote the CMISUtil function)
610 547 $uploadManager = new KTUploadManager();
611 548 // assumes already decoded from base64, should use store_base64_file if not
612 549 $tempfilename = $uploadManager->store_file($contentStream, 'cmis_');
613   -
  550 +
614 551 return $tempfilename;
615 552 }
616   -
  553 +
617 554 /**
618 555 * attempts to fetch the folder id from a name
619 556 *
... ... @@ -627,28 +564,28 @@ class CMISUtil {
627 564 static public function getIdFromName($name, &$ktapi)
628 565 {
629 566 $folder = $ktapi->get_folder_by_name($name);
630   -
  567 +
631 568 return self::encodeObjectId(FOLDER, $folder->get_folderid());
632 569 }
633   -
  570 +
634 571 /**
635 572 * Checks for the root folder
636 573 *
637   - * @param unknown_type $repositoryId
638   - * @param unknown_type $folderId
639   - * @param unknown_type $ktapi
640   - * @return unknown
  574 + * @param string $repositoryId
  575 + * @param string $folderId
  576 + * @param object $ktapi
  577 + * @return boolean
641 578 */
642 579 static public function isRootFolder($repositoryId, $folderId, &$ktapi)
643 580 {
644 581 $repository = new CMISRepository($repositoryId);
645 582 $repositoryInfo = $repository->getRepositoryInfo();
646   -
  583 +
647 584 // NOTE this call is required to accomodate the definition of the root folder id in the config as required by the drupal module
648 585 // we should try to update the drupal module to not require this, but this way is just easier at the moment, and most of
649 586 // the code accomodates it without any serious hacks
650 587 $rootFolder = self::getIdFromName($repositoryInfo->getRootFolderId(), $ktapi);
651   -
  588 +
652 589 return $folderId == $rootFolder;
653 590 }
654 591  
... ...
lib/authentication/Authenticator.inc
... ... @@ -6,7 +6,7 @@
6 6 *
7 7 * KnowledgeTree Community Edition
8 8 * Document Management Made Simple
9   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  9 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
10 10 *
11 11 *
12 12 * This program is free software; you can redistribute it and/or modify it under
... ...
lib/authentication/DBAuthenticator.inc
... ... @@ -6,7 +6,7 @@
6 6 *
7 7 * KnowledgeTree Community Edition
8 8 * Document Management Made Simple
9   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  9 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
10 10 *
11 11 *
12 12 * This program is free software; you can redistribute it and/or modify it under
... ...
lib/authentication/authenticationprovider.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ...
lib/authentication/authenticationproviderregistry.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ...
lib/authentication/authenticationsource.inc.php
... ... @@ -4,7 +4,7 @@
4 4 *
5 5 * KnowledgeTree Community Edition
6 6 * Document Management Made Simple
7   - * Copyright (C) 2008, 2009 KnowledgeTree Inc.
  7 + * Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
8 8 *
9 9 *
10 10 * This program is free software; you can redistribute it and/or modify it under
... ...