Commit 3c133975c9c9f1616e9550a7be5aa6c9c7c4adf3

Authored by kevin_fourie
1 parent 24b7e2c1

Merged in from DEV trunk...

Version bump to 3.5.2 beta2

WSA-89
"When calling add_document_with_metadata, notification for add and update are created."
Fixed. Not the best solution, but now we remove the duplicate message.

WSA-91
"error with move_document: Cannot assign object of type Dowco.KTWrapper.atlantic_kt.kt_response to an object of type Dowco.KTWrapper.atlantic_kt.kt_document_detail."
Fixed.

WSA-92
"get error when calling move_folder: An existing connection was forcibly closed by the remote host"
Fixed.

WSA-93
"Add integration/oem no so that integrators may associate a custom document reference"
Implemented.

Committed By: Conrad Vermeulen
Reviewed By: Megan Watson

WSA-91
"error with move_document: Cannot assign object of type Dowco.KTWrapper.atlantic_kt.kt_response to an object of type Dowco.KTWrapper.atlantic_kt.kt_document_detail."
Fixed.

Committed By: Conrad Vermeulen
Reviewed By: Megan Watson

WSA-76
"Update unit tests for document detail in web service"
Updated. Reinstating some tests
 

Committed By: Conrad Vermeulen
Reviewed By: Kevin Fourie

WSA-94
"Metadata update not reporting correct error messages when fieldsets/fields are specified that don't actually exist"
Fixed.

Committed By: Conrad Vermeulen
Reviewed By: Megan Watson

WSA-93
"Add integration/oem no so that integrators may associate a custom document reference"
Implemented.

Committed By: Conrad Vermeulen
Reviewed By: Megan Watson

WSA-92
"get error when calling move_folder: An existing connection was forcibly closed by the remote host"
Fixed.

Committed By: Conrad Vermeulen
Reviewed By: Megan Watson

WSA-93
"Add integration/oem no so that integrators may associate a custom document reference"
Implemented.

Committed By: Conrad Vermeulen
Reviewed By: Megan Watson

WSA-91
"error with move_document: Cannot assign object of type Dowco.KTWrapper.atlantic_kt.kt_response to an object of type Dowco.KTWrapper.atlantic_kt.kt_document_detail."
Fixed.

Committed By: Conrad Vermeulen
Reviewed By: Megan Watson

WSA-92
"get error when calling move_folder: An existing connection was forcibly closed by the remote host"
Fixed. Updated caching clearing mechanism.

Committed By: Conrad Vermeulen
Reviewed By: Megan Watson

KTS-2808
"HouseKeeper plugin produces 'Class 'KTPlugin' not found' error"
Fixed.

Committed By: Conrad Vermeulen
Reviewed By: Megan Watson

WSA-96
"Adding a document via web service should default to default document type if it does not exist. This is compatible with previous DWI operations"
Fixed.

Committed By: Conrad Vermeulen
Reviewed By: Megan Watson

KTC-267
"When subscribed to a folder: Document removal occurrences are listed twice in the 'Items that require your attention' dashlet on the Dashboard"
Fixed. Removed the function call.

Committed By:Yusuf Davids
Reviewed By:Kevin Fourie

KTC-301
"Generate PDF progress bar stays running long after the conversion has happened"
Fixed. Disabled the progress bar loader before converting to pdf.

Committed By:Yusuf Davids
Reviewed By:Kevin Fourie

git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/STABLE/trunk@7883 c91229c3-7414-0410-bfa2-8a42b809f60b
customerrorpage.php
1 -<?php  
2 -  
3 -if (array_key_exists('fatal', $_POST))  
4 -{  
5 - $posted = $_POST['fatal'];  
6 -  
7 -}  
8 -  
9 -if (array_key_exists('Error_MessageOne', $_POST) && array_key_exists('Error_MessageTwo', $_POST))  
10 -{  
11 - $sErrorMessage = $_POST['Error_MessageOne'].''.$_POST['Error_MessageTwo'];  
12 -  
13 -}  
14 -  
15 -session_start();  
16 -if (array_key_exists('sErrorMessage', $_SESSION))  
17 -{  
18 -$phperror = $_SESSION['sErrorMessage'];  
19 -}  
20 -  
21 -  
22 -  
23 -?>  
24 -  
25 -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html>  
26 - <head>  
27 - <title>Knowledgetree - Desklet</title>  
28 - <link rel="stylesheet" type="text/css" href="/resources/css/errors.css" />  
29 -  
30 - <script type="text/javascript">  
31 -  
32 -function Click()  
33 -{  
34 -var open = document.getElementById('exp');  
35 -open.style.display = 'block';  
36 -}  
37 -  
38 -</script>  
39 -  
40 - </head>  
41 - <body>  
42 -  
43 - <div id="error-container">  
44 -  
45 - <div id="acc-error">  
46 -  
47 -  
48 - <h1>Error!! - You have encountered a problem starting your document management system.</h1>  
49 - <p><h2>Please contact your systems administrator</h2></p>  
50 - <p>For more details, click here <img src="/resources/graphics/info.gif" style="cursor: pointer;" onclick="Click()" /><div id ="exp" style="display: none; "> <?php if(isset($sErrorMessage)){ echo $sErrorMessage; }else if(isset($posted)){ echo $posted; } else if($phperror){ echo $phperror; } ?></div></p>  
51 -  
52 - </div>  
53 - </div>  
54 -  
55 - </body> 1 +<?php
  2 +
  3 +if (array_key_exists('fatal', $_POST))
  4 +{
  5 + $posted = $_POST['fatal'];
  6 +
  7 +}
  8 +
  9 +if (array_key_exists('Error_MessageOne', $_POST) && array_key_exists('Error_MessageTwo', $_POST))
  10 +{
  11 + $sErrorMessage = $_POST['Error_MessageOne'].''.$_POST['Error_MessageTwo'];
  12 +
  13 +}
  14 +
  15 +session_start();
  16 +if (array_key_exists('sErrorMessage', $_SESSION))
  17 +{
  18 +$phperror = $_SESSION['sErrorMessage'];
  19 +}
  20 +
  21 +
  22 +
  23 +?>
  24 +
  25 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html>
  26 + <head>
  27 + <title>Knowledgetree - Desklet</title>
  28 + <link rel="stylesheet" type="text/css" href="/resources/css/errors.css" />
  29 +
  30 + <script type="text/javascript">
  31 +
  32 +function Click()
  33 +{
  34 +var open = document.getElementById('exp');
  35 +open.style.display = 'block';
  36 +var border = document.getElementById('error-container');
  37 +border.style.height = '250px';
  38 +}
  39 +
  40 +</script>
  41 +
  42 + </head>
  43 + <body>
  44 +
  45 + <div id="error-container">
  46 +
  47 + <div id="acc-error">
  48 +
  49 +
  50 + <h1>Error!! - You have encountered a problem starting your document management system.</h1>
  51 + <p><h2>Please contact your systems administrator</h2></p>
  52 + <p>For more details, click here <img src="/resources/graphics/info.gif" style="cursor: pointer;" onclick="Click()" /><div id ="exp" style="display: none; "> <?php if(isset($sErrorMessage)){ echo $sErrorMessage; }else if(isset($posted)){ echo $posted; } else if($phperror){ echo $phperror; } ?></div></p>
  53 +
  54 + </div>
  55 + </div>
  56 +
  57 + </body>
56 </html> 58 </html>
57 \ No newline at end of file 59 \ No newline at end of file
ktapi/KTAPIDocument.inc.php
@@ -180,6 +180,12 @@ class KTAPI_Document extends KTAPI_FolderItem @@ -180,6 +180,12 @@ class KTAPI_Document extends KTAPI_FolderItem
180 KTUploadManager::temporary_file_imported($tempfilename); 180 KTUploadManager::temporary_file_imported($tempfilename);
181 } 181 }
182 182
  183 + function removeUpdateNotification()
  184 + {
  185 + $sql = "DELETE FROM notifications WHERE data_int_1=$this->documentid AND data_str_1='ModifyDocument'";
  186 + DBUtil::runQuery($sql);
  187 + }
  188 +
183 /** 189 /**
184 * Link a document to another 190 * Link a document to another
185 * 191 *
@@ -276,7 +282,7 @@ class KTAPI_Document extends KTAPI_FolderItem @@ -276,7 +282,7 @@ class KTAPI_Document extends KTAPI_FolderItem
276 w.name as workflow, 282 w.name as workflow,
277 ws.name as workflow_state, 283 ws.name as workflow_state,
278 dlt.name as link_type, dtl.name as document_type, 284 dlt.name as link_type, dtl.name as document_type,
279 - dcv.major_version, dcv.minor_version 285 + dcv.major_version, dcv.minor_version, d.oem_no
280 FROM 286 FROM
281 document_link dl 287 document_link dl
282 INNER JOIN document_link_types dlt ON dl.link_type_id=dlt.id 288 INNER JOIN document_link_types dlt ON dl.link_type_id=dlt.id
@@ -312,12 +318,13 @@ class KTAPI_Document extends KTAPI_FolderItem @@ -312,12 +318,13 @@ class KTAPI_Document extends KTAPI_FolderItem
312 continue; 318 continue;
313 } 319 }
314 320
315 - 321 + $oem_no = $row['oem_no'];
  322 + if (empty($oem_no)) $oem_no = 'n/a';
316 323
317 $result[] = array( 324 $result[] = array(
318 'document_id'=>(int)$row['document_id'], 325 'document_id'=>(int)$row['document_id'],
319 'custom_document_no'=>'n/a', 326 'custom_document_no'=>'n/a',
320 - 'oem_document_no'=>'n/a', 327 + 'oem_document_no'=>$oem_no,
321 'title'=> $row['title'], 328 'title'=> $row['title'],
322 'document_type'=> $row['document_type'], 329 'document_type'=> $row['document_type'],
323 'version'=> (float) ($row['major_version'] . '.' . $row['minor_version']), 330 'version'=> (float) ($row['major_version'] . '.' . $row['minor_version']),
@@ -1008,9 +1015,9 @@ class KTAPI_Document extends KTAPI_FolderItem @@ -1008,9 +1015,9 @@ class KTAPI_Document extends KTAPI_FolderItem
1008 } 1015 }
1009 1016
1010 $fieldset = KTFieldset::getByName($fieldsetname); 1017 $fieldset = KTFieldset::getByName($fieldsetname);
1011 - if (is_null($fieldset) || PEAR::isError($fieldset)) 1018 + if (is_null($fieldset) || PEAR::isError($fieldset) || is_a($fieldset, 'KTEntityNoObjects'))
1012 { 1019 {
1013 - $default->log->debug("could not resolve fieldset: $fieldsetname"); 1020 + $default->log->debug("could not resolve fieldset: $fieldsetname for document id: $this->documentid");
1014 // exit graciously 1021 // exit graciously
1015 continue; 1022 continue;
1016 } 1023 }
@@ -1034,9 +1041,9 @@ class KTAPI_Document extends KTAPI_FolderItem @@ -1034,9 +1041,9 @@ class KTAPI_Document extends KTAPI_FolderItem
1034 } 1041 }
1035 1042
1036 $field = DocumentField::getByFieldsetAndName($fieldset, $fieldname); 1043 $field = DocumentField::getByFieldsetAndName($fieldset, $fieldname);
1037 - if (is_null($field) || PEAR::isError($fieldset)) 1044 + if (is_null($field) || PEAR::isError($field) || is_a($field, 'KTEntityNoObjects'))
1038 { 1045 {
1039 - $default->log->debug("could not resolve field: $fieldname"); 1046 + $default->log->debug("Could not resolve field: $fieldname on fieldset $fieldsetname for document id: $this->documentid");
1040 // exit graciously 1047 // exit graciously
1041 continue; 1048 continue;
1042 } 1049 }
@@ -1115,6 +1122,7 @@ class KTAPI_Document extends KTAPI_FolderItem @@ -1115,6 +1122,7 @@ class KTAPI_Document extends KTAPI_FolderItem
1115 $documents = array(); 1122 $documents = array();
1116 $document_content = array(); 1123 $document_content = array();
1117 $indexContent = null; 1124 $indexContent = null;
  1125 + $uniqueOemNo = false;
1118 1126
1119 foreach($sysdata as $rec) 1127 foreach($sysdata as $rec)
1120 { 1128 {
@@ -1135,6 +1143,13 @@ class KTAPI_Document extends KTAPI_FolderItem @@ -1135,6 +1143,13 @@ class KTAPI_Document extends KTAPI_FolderItem
1135 } 1143 }
1136 switch($name) 1144 switch($name)
1137 { 1145 {
  1146 + case 'unique_oem_document_no':
  1147 + $documents['oem_no'] = $value;
  1148 + $uniqueOemNo = true;
  1149 + break;
  1150 + case 'oem_document_no':
  1151 + $documents['oem_no'] = $value;
  1152 + break;
1138 case 'index_content': 1153 case 'index_content':
1139 $indexContent = $value; 1154 $indexContent = $value;
1140 break; 1155 break;
@@ -1218,10 +1233,8 @@ class KTAPI_Document extends KTAPI_FolderItem @@ -1218,10 +1233,8 @@ class KTAPI_Document extends KTAPI_FolderItem
1218 foreach($documents as $name=>$value) 1233 foreach($documents as $name=>$value)
1219 { 1234 {
1220 if ($i++ > 0) $sql .= ","; 1235 if ($i++ > 0) $sql .= ",";
1221 - if (is_numeric($value))  
1222 - $sql .= "$name=$value";  
1223 - else  
1224 - $sql .= "$name='$value'"; 1236 + $value = sanitizeForSQL($value);
  1237 + $sql .= "$name='$value'";
1225 } 1238 }
1226 $sql .= " WHERE id=$this->documentid"; 1239 $sql .= " WHERE id=$this->documentid";
1227 $result = DBUtil::runQuery($sql); 1240 $result = DBUtil::runQuery($sql);
@@ -1229,6 +1242,14 @@ class KTAPI_Document extends KTAPI_FolderItem @@ -1229,6 +1242,14 @@ class KTAPI_Document extends KTAPI_FolderItem
1229 { 1242 {
1230 return $result; 1243 return $result;
1231 } 1244 }
  1245 +
  1246 + if ($uniqueOemNo)
  1247 + {
  1248 + $oem_no = sanitizeForSQL($documents['oem_no']);
  1249 + $sql = "UPDATE documents SET oem_no=null WHERE oem_no = '$oem_no' AND id != $this->documentid";
  1250 + $result = DBUtil::runQuery($sql);
  1251 + }
  1252 +
1232 } 1253 }
1233 if (count($document_content) > 0) 1254 if (count($document_content) > 0)
1234 { 1255 {
@@ -1238,6 +1259,7 @@ class KTAPI_Document extends KTAPI_FolderItem @@ -1238,6 +1259,7 @@ class KTAPI_Document extends KTAPI_FolderItem
1238 foreach($document_content as $name=>$value) 1259 foreach($document_content as $name=>$value)
1239 { 1260 {
1240 if ($i++ > 0) $sql .= ","; 1261 if ($i++ > 0) $sql .= ",";
  1262 + $value = sanitizeForSQL($value);
1241 $sql .= "$name='$value'"; 1263 $sql .= "$name='$value'";
1242 } 1264 }
1243 $sql .= " WHERE id=$content_id"; 1265 $sql .= " WHERE id=$content_id";
@@ -1421,8 +1443,18 @@ class KTAPI_Document extends KTAPI_FolderItem @@ -1421,8 +1443,18 @@ class KTAPI_Document extends KTAPI_FolderItem
1421 // get the document id 1443 // get the document id
1422 $detail['document_id'] = (int) $document->getId(); 1444 $detail['document_id'] = (int) $document->getId();
1423 1445
  1446 + $oem_document_no = null;
  1447 + if ($wsversion >= 2)
  1448 + {
  1449 + $oem_document_no = $document->getOemNo();
  1450 + }
  1451 + if (empty($oem_document_no))
  1452 + {
  1453 + $oem_document_no = 'n/a';
  1454 + }
  1455 +
1424 $detail['custom_document_no'] = 'n/a'; 1456 $detail['custom_document_no'] = 'n/a';
1425 - $detail['oem_document_no'] = 'n/a'; 1457 + $detail['oem_document_no'] = $oem_document_no;
1426 1458
1427 // get the title 1459 // get the title
1428 $detail['title'] = $document->getName(); 1460 $detail['title'] = $document->getName();
ktapi/KTAPIFolder.inc.php
@@ -121,6 +121,7 @@ class KTAPI_Folder extends KTAPI_FolderItem @@ -121,6 +121,7 @@ class KTAPI_Folder extends KTAPI_FolderItem
121 */ 121 */
122 function get_detail() 122 function get_detail()
123 { 123 {
  124 + $this->clearCache();
124 $detail = array( 125 $detail = array(
125 'id'=>(int) $this->folderid, 126 'id'=>(int) $this->folderid,
126 'folder_name'=>$this->get_folder_name(), 127 'folder_name'=>$this->get_folder_name(),
@@ -131,6 +132,17 @@ class KTAPI_Folder extends KTAPI_FolderItem @@ -131,6 +132,17 @@ class KTAPI_Folder extends KTAPI_FolderItem
131 return $detail; 132 return $detail;
132 } 133 }
133 134
  135 + function clearCache()
  136 + {
  137 + // TODO: we should only clear the cache for the document we are working on
  138 + // this is a quick fix but not optimal!!
  139 +
  140 + $GLOBALS["_OBJECTCACHE"]['Folder'] = array();
  141 +
  142 + $this->folder = &Folder::get($this->folderid);
  143 + }
  144 +
  145 +
134 function get_parent_folder_id() 146 function get_parent_folder_id()
135 { 147 {
136 return (int) $this->folder->getParentID(); 148 return (int) $this->folder->getParentID();
@@ -479,13 +491,16 @@ class KTAPI_Folder extends KTAPI_FolderItem @@ -479,13 +491,16 @@ class KTAPI_Folder extends KTAPI_FolderItem
479 $docTypeId = $document->getDocumentTypeID(); 491 $docTypeId = $document->getDocumentTypeID();
480 $documentType = DocumentType::get($docTypeId); 492 $documentType = DocumentType::get($docTypeId);
481 493
  494 + $oemDocumentNo = $document->getOemNo();
  495 + if (empty($oemDocumentNo)) $oemDocumentNo = 'n/a';
  496 +
482 497
483 $contents[] = array( 498 $contents[] = array(
484 'id' => (int) $document->getId(), 499 'id' => (int) $document->getId(),
485 'item_type' => 'D', 500 'item_type' => 'D',
486 501
487 'custom_document_no'=>'n/a', 502 'custom_document_no'=>'n/a',
488 - 'oem_document_no'=>'n/a', 503 + 'oem_document_no'=>$oemDocumentNo,
489 504
490 'title' => $document->getName(), 505 'title' => $document->getName(),
491 'document_type'=>$documentType->getName(), 506 'document_type'=>$documentType->getName(),
@@ -581,7 +596,16 @@ class KTAPI_Folder extends KTAPI_FolderItem @@ -581,7 +596,16 @@ class KTAPI_Folder extends KTAPI_FolderItem
581 $documenttypeid = KTAPI::get_documenttypeid($documenttype); 596 $documenttypeid = KTAPI::get_documenttypeid($documenttype);
582 if (PEAR::isError($documenttypeid)) 597 if (PEAR::isError($documenttypeid))
583 { 598 {
584 - return new PEAR_Error('The document type could not be resolved or is disabled: ' . $documenttype); 599 + $config = KTCache::getSingleton();
  600 + $defaultToDefaultDocType = $config->get('webservice/useDefaultDocumentTypeIfInvalid',true);
  601 + if ($defaultToDefaultDocType)
  602 + {
  603 + $documenttypeid = KTAPI::get_documenttypeid('Default');
  604 + }
  605 + else
  606 + {
  607 + return new PEAR_Error('The document type could not be resolved or is disabled: ' . $documenttype);
  608 + }
585 } 609 }
586 610
587 611
ktapi/ktapi.inc.php
@@ -179,6 +179,36 @@ class KTAPI @@ -179,6 +179,36 @@ class KTAPI
179 return $user; 179 return $user;
180 } 180 }
181 181
  182 + /**
  183 + * Search for documents matching the oem_no.
  184 + *
  185 + * Note that oem_no is associated with a document and not with version of file (document content).
  186 + * oem_no is set on a document using document::update_sysdata().
  187 + *
  188 + * @param string $oem_no
  189 + * @param boolean idsOnly Defaults to true
  190 + * @return array
  191 + */
  192 + function get_documents_by_oem_no($oem_no, $idsOnly=true)
  193 + {
  194 + $sql = array("SELECT id FROM documents WHERE oem_no=?",$oem_no);
  195 + $rows = DBUtil::getResultArray($sql);
  196 + if (is_null($rows) || PEAR::isError($rows))
  197 + {
  198 + return new KTAPI_Error(KTAPI_ERROR_INTERNAL_ERROR, $rows);
  199 + }
  200 +
  201 + $result = array();
  202 + foreach($rows as $row)
  203 + {
  204 + $documentid = $row['id'];
  205 +
  206 + $result[] = $idsOnly?$documentid:KTAPI_Document::get($this, $documentid);
  207 + }
  208 +
  209 + return $result;
  210 + }
  211 +
182 /** 212 /**
183 * This returns a session object based on a session string. 213 * This returns a session object based on a session string.
184 * 214 *
ktwebservice/nunit/document_copy.cs
@@ -8,29 +8,29 @@ namespace MonoTests.KnowledgeTree @@ -8,29 +8,29 @@ namespace MonoTests.KnowledgeTree
8 8
9 [TestFixture] 9 [TestFixture]
10 public class DocumentCopyTest : KTTest 10 public class DocumentCopyTest : KTTest
11 - {  
12 - private int _folderId;  
13 - private Document _doc1; 11 + {
  12 + private int _folderId;
  13 + private Document _doc1;
14 14
15 15
16 [SetUp] 16 [SetUp]
17 public void SetUp() 17 public void SetUp()
18 - {  
19 - this._folderId = 1; 18 + {
  19 + this._folderId = 1;
20 20
21 this._doc1 = new Document(1, this._session, this._kt, this._verbose, false); 21 this._doc1 = new Document(1, this._session, this._kt, this._verbose, false);
22 - this._doc1.createFile(this._folderId);  
23 -  
24 -  
25 - 22 + this._doc1.createFile(this._folderId);
  23 +
  24 +
  25 +
26 } 26 }
27 27
28 [TearDown] 28 [TearDown]
29 public void TearDown() 29 public void TearDown()
30 { 30 {
31 - this._doc1.deleteFile(); 31 + this._doc1.deleteFile();
32 } 32 }
33 - 33 +
34 [Test] 34 [Test]
35 public void FindDocumentBeforeCopy() 35 public void FindDocumentBeforeCopy()
36 { 36 {
@@ -47,35 +47,38 @@ namespace MonoTests.KnowledgeTree @@ -47,35 +47,38 @@ namespace MonoTests.KnowledgeTree
47 { 47 {
48 System.Console.WriteLine("document not found. that is ok!"); 48 System.Console.WriteLine("document not found. that is ok!");
49 } 49 }
50 - }  
51 - 50 + }
  51 +
52 52
53 [Test] 53 [Test]
54 public void CopyTest() 54 public void CopyTest()
55 { 55 {
56 - kt_document_detail linkresp = this._kt.copy_document(this._session, this._doc1.docId, 1, "copy", "test123", "test123.txt");  
57 - Assert.AreEqual(0, linkresp.status_code);  
58 - Assert.AreEqual("test123.txt", linkresp.filename);  
59 - Assert.AreEqual("test123", linkresp.title); 56 + kt_folder_detail response2 = this._kt.create_folder(this._session, 1, "kt_unit_test_move");
  57 + Assert.AreEqual(0,response2.status_code);
  58 + int folderId = response2.id;
  59 +
  60 +
  61 + kt_document_detail linkresp = this._kt.copy_document(this._session, this._doc1.docId, folderId, "copy", "");
  62 + Assert.AreEqual(0, linkresp.status_code);
  63 + Assert.AreEqual("kt_unit_test1.txt", linkresp.filename);
  64 + Assert.AreEqual("kt unit test1", linkresp.title);
  65 +
60 66
61 -  
62 67
63 } 68 }
64 - 69 +
65 [Test] 70 [Test]
66 public void FindDocumentAfterCopy() 71 public void FindDocumentAfterCopy()
67 { 72 {
68 - String filename = "Root Folder/test123"; 73 + String filename = "Root Folder/kt unit test1";
69 if (this._verbose) System.Console.WriteLine("Finding document before add: " + filename); 74 if (this._verbose) System.Console.WriteLine("Finding document before add: " + filename);
70 kt_document_detail documentDetail = this._kt.get_document_detail_by_title(this._session, 1, filename, ""); 75 kt_document_detail documentDetail = this._kt.get_document_detail_by_title(this._session, 1, filename, "");
71 - Assert.AreEqual(0, documentDetail.status_code);  
72 -  
73 - if (this._verbose) System.Console.WriteLine("Found document - deleting");  
74 - kt_response response = this._kt.delete_document(this._session, documentDetail.document_id, "Delete - cleaning up before add");  
75 - Assert.AreEqual(0, response.status_code);  
76 -  
77 - }  
78 - 76 + Assert.AreEqual(0, documentDetail.status_code);
  77 +
  78 +
  79 +
  80 + }
  81 +
79 82
80 83
81 } 84 }
ktwebservice/nunit/document_detail.cs
@@ -108,7 +108,7 @@ namespace MonoTests.KnowledgeTree @@ -108,7 +108,7 @@ namespace MonoTests.KnowledgeTree
108 Assert.AreEqual(null, response.transitions); 108 Assert.AreEqual(null, response.transitions);
109 } 109 }
110 110
111 - //[Test] 111 + [Test]
112 public void GetDetailByTitleTest() 112 public void GetDetailByTitleTest()
113 { 113 {
114 kt_document_detail response = this._kt.get_document_detail_by_name(this._session, 1, "Root Folder/kt unit test1", "T",""); 114 kt_document_detail response = this._kt.get_document_detail_by_name(this._session, 1, "Root Folder/kt unit test1", "T","");
@@ -118,7 +118,7 @@ namespace MonoTests.KnowledgeTree @@ -118,7 +118,7 @@ namespace MonoTests.KnowledgeTree
118 } 118 }
119 119
120 120
121 - //[Test] 121 + [Test]
122 public void GetDetailByTitle2Test() 122 public void GetDetailByTitle2Test()
123 { 123 {
124 kt_document_detail response = this._kt.get_document_detail_by_title(this._session, 1, "Root Folder/kt unit test1", ""); 124 kt_document_detail response = this._kt.get_document_detail_by_title(this._session, 1, "Root Folder/kt unit test1", "");
@@ -127,7 +127,7 @@ namespace MonoTests.KnowledgeTree @@ -127,7 +127,7 @@ namespace MonoTests.KnowledgeTree
127 Assert.AreEqual(this._docId, response.document_id); 127 Assert.AreEqual(this._docId, response.document_id);
128 } 128 }
129 129
130 - //[Test] 130 + [Test]
131 public void GetDetailByFileTest() 131 public void GetDetailByFileTest()
132 { 132 {
133 kt_document_detail response = this._kt.get_document_detail_by_name(this._session, 1, "Root Folder/kt_unit_test1.txt", "F",""); 133 kt_document_detail response = this._kt.get_document_detail_by_name(this._session, 1, "Root Folder/kt_unit_test1.txt", "F","");
@@ -135,7 +135,7 @@ namespace MonoTests.KnowledgeTree @@ -135,7 +135,7 @@ namespace MonoTests.KnowledgeTree
135 Assert.AreEqual(0, response.status_code); 135 Assert.AreEqual(0, response.status_code);
136 Assert.AreEqual(this._docId, response.document_id); 136 Assert.AreEqual(this._docId, response.document_id);
137 } 137 }
138 - //[Test] 138 + [Test]
139 public void GetDetailByFile2Test() 139 public void GetDetailByFile2Test()
140 { 140 {
141 kt_document_detail response = this._kt.get_document_detail_by_filename(this._session, 1, "Root Folder/kt_unit_test1.txt", ""); 141 kt_document_detail response = this._kt.get_document_detail_by_filename(this._session, 1, "Root Folder/kt_unit_test1.txt", "");
@@ -144,7 +144,7 @@ namespace MonoTests.KnowledgeTree @@ -144,7 +144,7 @@ namespace MonoTests.KnowledgeTree
144 Assert.AreEqual(this._docId, response.document_id); 144 Assert.AreEqual(this._docId, response.document_id);
145 } 145 }
146 146
147 - //[Test] 147 + [Test]
148 public void GetDetailByUnknownNameTest() 148 public void GetDetailByUnknownNameTest()
149 { 149 {
150 kt_document_detail response = this._kt.get_document_detail_by_name(this._session, 1, "Root Folder/kt_unit_test1.ssssdasdasd", "F",""); 150 kt_document_detail response = this._kt.get_document_detail_by_name(this._session, 1, "Root Folder/kt_unit_test1.ssssdasdasd", "F","");
ktwebservice/nunit/document_metadata.cs
@@ -139,11 +139,41 @@ namespace MonoTests.KnowledgeTree @@ -139,11 +139,41 @@ namespace MonoTests.KnowledgeTree
139 139
140 Assert.AreEqual("Media Type", update_resp.metadata[1].fields[2].name); 140 Assert.AreEqual("Media Type", update_resp.metadata[1].fields[2].name);
141 Assert.AreEqual("Text'", update_resp.metadata[1].fields[2].value); 141 Assert.AreEqual("Text'", update_resp.metadata[1].fields[2].value);
  142 + }
142 143
  144 + [Test]
  145 + public void ProblemMetadataNoFieldSetTest()
  146 + {
  147 + kt_metadata_fieldset[] fs = new kt_metadata_fieldset[1];
  148 + fs[0] = new kt_metadata_fieldset();
  149 + fs[0].fieldset = "UnknownFieldset";
  150 + fs[0].fields = new kt_metadata_field[1];
  151 + fs[0].fields[0] = new kt_metadata_field();
  152 + fs[0].fields[0].name = "Document Author";
  153 + fs[0].fields[0].value = "Joe \\Soap";
143 154
144 - } 155 + kt_sysdata_item[] sysdata = new kt_sysdata_item[0];
  156 +
  157 + kt_document_detail update_resp = this._kt.update_document_metadata(this._session, this._docId, fs, sysdata);
  158 + Assert.AreEqual(0, update_resp.status_code);
  159 + }
145 160
  161 + [Test]
  162 + public void ProblemMetadataNoFieldTest()
  163 + {
  164 + kt_metadata_fieldset[] fs = new kt_metadata_fieldset[1];
  165 + fs[0] = new kt_metadata_fieldset();
  166 + fs[0].fieldset = "General information";
  167 + fs[0].fields = new kt_metadata_field[1];
  168 + fs[0].fields[0] = new kt_metadata_field();
  169 + fs[0].fields[0].name = "Document Owner";
  170 + fs[0].fields[0].value = "Joe \\Soap";
  171 +
  172 + kt_sysdata_item[] sysdata = new kt_sysdata_item[0];
146 173
  174 + kt_document_detail update_resp = this._kt.update_document_metadata(this._session, this._docId, fs, sysdata);
  175 + Assert.AreEqual(0, update_resp.status_code);
  176 + }
147 177
148 } 178 }
149 } 179 }
ktwebservice/nunit/document_move.cs 0 โ†’ 100644
  1 +using NUnit.Framework;
  2 +using System;
  3 +using System.IO;
  4 +
  5 +namespace MonoTests.KnowledgeTree
  6 +{
  7 +
  8 +
  9 + [TestFixture]
  10 + public class DocumentMoveTest : KTTest
  11 + {
  12 + private int _folderId;
  13 + private Document _doc1;
  14 +
  15 + private int _folderId2;
  16 +
  17 + [SetUp]
  18 + public void SetUp()
  19 + {
  20 + this._folderId = 1;
  21 +
  22 + this._doc1 = new Document(1, this._session, this._kt, this._verbose, false);
  23 + this._doc1.createFile(this._folderId);
  24 +
  25 +
  26 +
  27 + }
  28 +
  29 + [TearDown]
  30 + public void TearDown()
  31 + {
  32 + this._doc1.deleteFile();
  33 + }
  34 +
  35 + [Test]
  36 + public void FindDocumentBeforeMove()
  37 + {
  38 + String filename = "Root Folder/test123move";
  39 + if (this._verbose) System.Console.WriteLine("Finding document before add: " + filename);
  40 + kt_document_detail documentDetail = this._kt.get_document_detail_by_title(this._session, 1, filename, "");
  41 + if (0 == documentDetail.status_code)
  42 + {
  43 + if (this._verbose) System.Console.WriteLine("Found document - deleting");
  44 + kt_response response = this._kt.delete_document(this._session, documentDetail.document_id, "Delete - cleaning up before add");
  45 + Assert.AreEqual(0, response.status_code);
  46 + }
  47 + else if (this._verbose)
  48 + {
  49 + System.Console.WriteLine("document not found. that is ok!");
  50 + }
  51 +
  52 +
  53 + }
  54 +
  55 +
  56 + [Test]
  57 + public void MoveTest()
  58 + {
  59 + kt_folder_detail response2 = this._kt.create_folder(this._session, 1, "kt_unit_test_move");
  60 + Assert.AreEqual(0,response2.status_code);
  61 + int folderId = _folderId2 =response2.id;
  62 +
  63 + System.Console.WriteLine("The folder id is: " +folderId);
  64 +
  65 +
  66 + System.Console.WriteLine("The document id is: " +this._doc1.docId);
  67 +
  68 + kt_document_detail linkresp = this._kt.move_document(this._session, this._doc1.docId, folderId, "move ", "");
  69 + Assert.AreEqual(0, linkresp.status_code);
  70 + Assert.AreEqual("kt_unit_test1.txt", linkresp.filename);
  71 + Assert.AreEqual("kt unit test1", linkresp.title);
  72 + Assert.AreEqual(folderId, linkresp.folder_id);
  73 +
  74 +
  75 +
  76 + }
  77 +
  78 + [Test]
  79 + public void FindDocumentAfterMove()
  80 + {
  81 + String filename = "Root Folder/kt unit test1";
  82 + if (this._verbose) System.Console.WriteLine("Finding document before add: " + filename);
  83 + kt_document_detail documentDetail = this._kt.get_document_detail_by_title(this._session, 1, filename, "");
  84 + Assert.AreEqual(0, documentDetail.status_code);
  85 +
  86 +
  87 +
  88 + }
  89 +
  90 +
  91 +
  92 + }
  93 +}
ktwebservice/nunit/document_oem_no.cs 0 โ†’ 100644
  1 +using NUnit.Framework;
  2 +using System;
  3 +using System.IO;
  4 +
  5 +namespace MonoTests.KnowledgeTree
  6 +{
  7 + [TestFixture]
  8 + public class DocumentOemNoTest : KTTest
  9 + {
  10 + private int _docId;
  11 + private int _folderId;
  12 + private String _filename;
  13 + private String _content;
  14 +
  15 +
  16 + [SetUp]
  17 + public void SetUp()
  18 + {
  19 + this._filename = Helper.isUnix()?"/tmp/kt_unit_test1.txt":"c:\\kt_unit_test1.txt";
  20 +
  21 + String filename = "kt unit test1";
  22 +
  23 + this._content = "hello world!";
  24 +
  25 + Helper.writeFile(this._filename, this._content);
  26 +
  27 + this._folderId = 1;
  28 +
  29 + kt_document_detail response1 = this._kt.add_base64_document(this._session, this._folderId, filename, this._filename, "Default", Helper.ConvertFileToBase64Encoding(this._filename));
  30 +
  31 + if (this._verbose && response1.status_code != 0)
  32 + {
  33 + System.Console.WriteLine("Could not create file: " + this._filename);
  34 + }
  35 + this._docId = response1.document_id;
  36 + }
  37 +
  38 + [TearDown]
  39 + public void TearDown()
  40 + {
  41 +
  42 + Helper.deleteFile(this._filename);
  43 +
  44 + kt_response response = this._kt.delete_document(this._session, this._docId, "Delete - cleaning up");
  45 + if (this._verbose && response.status_code != 0)
  46 + {
  47 + System.Console.WriteLine("Could not delete file: " + this._filename);
  48 + }
  49 + }
  50 +
  51 + [Test]
  52 + public void UpdateOemNoMetadataTest()
  53 + {
  54 + kt_metadata_fieldset[] fs = new kt_metadata_fieldset[0];
  55 +
  56 + kt_sysdata_item[] sysdata = new kt_sysdata_item[1];
  57 + sysdata[0] = new kt_sysdata_item();
  58 + sysdata[0].name = "oem_document_no";
  59 + sysdata[0].value = "1234";
  60 +
  61 + kt_document_detail update_resp = this._kt.update_document_metadata(this._session, this._docId, fs, sysdata);
  62 + Assert.AreEqual(0, update_resp.status_code);
  63 +
  64 + Assert.AreEqual("1234", update_resp.oem_document_no);
  65 + }
  66 +
  67 + [Test]
  68 + public void UpdateUniqueOemNoMetadataTest()
  69 + {
  70 + kt_metadata_fieldset[] fs = new kt_metadata_fieldset[0];
  71 +
  72 + kt_sysdata_item[] sysdata = new kt_sysdata_item[1];
  73 + sysdata[0] = new kt_sysdata_item();
  74 + sysdata[0].name = "unique_oem_document_no";
  75 + sysdata[0].value = "1234";
  76 +
  77 + kt_document_detail update_resp = this._kt.update_document_metadata(this._session, this._docId, fs, sysdata);
  78 + Assert.AreEqual(0, update_resp.status_code);
  79 +
  80 + Assert.AreEqual("1234", update_resp.oem_document_no);
  81 +
  82 +
  83 + kt_document_collection_response response = this._kt.get_documents_by_oem_no(this._session, "1234", "");
  84 +
  85 + Assert.AreEqual(1, response.collection.Length);
  86 + Assert.AreEqual(this._docId, response.collection[0].document_id);
  87 + Assert.AreEqual("1234", response.collection[0].oem_document_no);
  88 +
  89 + }
  90 + }
  91 +}
ktwebservice/nunit/document_system_metadata.cs
@@ -32,7 +32,7 @@ namespace MonoTests.KnowledgeTree @@ -32,7 +32,7 @@ namespace MonoTests.KnowledgeTree
32 this._doc2.deleteFile(); 32 this._doc2.deleteFile();
33 } 33 }
34 34
35 -// [Test] 35 + [Test]
36 public void UpdateDocumentMetadataTest() 36 public void UpdateDocumentMetadataTest()
37 { 37 {
38 38
@@ -81,7 +81,7 @@ namespace MonoTests.KnowledgeTree @@ -81,7 +81,7 @@ namespace MonoTests.KnowledgeTree
81 Assert.AreEqual("2007-01-17 00:00:00", update_resp.created_date); 81 Assert.AreEqual("2007-01-17 00:00:00", update_resp.created_date);
82 } 82 }
83 83
84 -// [Test] 84 + [Test]
85 public void AddSmallDocumentWithMetadataTest() 85 public void AddSmallDocumentWithMetadataTest()
86 { 86 {
87 kt_metadata_fieldset[] fs = new kt_metadata_fieldset[1]; 87 kt_metadata_fieldset[] fs = new kt_metadata_fieldset[1];
@@ -125,7 +125,7 @@ namespace MonoTests.KnowledgeTree @@ -125,7 +125,7 @@ namespace MonoTests.KnowledgeTree
125 Assert.AreEqual("2007-01-17 00:00:00", update_resp.created_date); 125 Assert.AreEqual("2007-01-17 00:00:00", update_resp.created_date);
126 } 126 }
127 127
128 -// [Test] 128 + [Test]
129 public void CheckinSmallDocumentWithMetadataTest() 129 public void CheckinSmallDocumentWithMetadataTest()
130 { 130 {
131 kt_metadata_fieldset[] fs = new kt_metadata_fieldset[1]; 131 kt_metadata_fieldset[] fs = new kt_metadata_fieldset[1];
@@ -172,7 +172,7 @@ namespace MonoTests.KnowledgeTree @@ -172,7 +172,7 @@ namespace MonoTests.KnowledgeTree
172 Assert.AreEqual("Anonymous", update_resp.created_by); 172 Assert.AreEqual("Anonymous", update_resp.created_by);
173 Assert.AreEqual("2007-01-17 00:00:00", update_resp.created_date); 173 Assert.AreEqual("2007-01-17 00:00:00", update_resp.created_date);
174 } 174 }
175 - 175 +
176 [Test] 176 [Test]
177 public void AddDocumentWithMetadataTest() 177 public void AddDocumentWithMetadataTest()
178 { 178 {
@@ -190,7 +190,7 @@ namespace MonoTests.KnowledgeTree @@ -190,7 +190,7 @@ namespace MonoTests.KnowledgeTree
190 fs[0].fields[2].name = "Media Type"; 190 fs[0].fields[2].name = "Media Type";
191 fs[0].fields[2].value = "Text"; 191 fs[0].fields[2].value = "Text";
192 192
193 - kt_sysdata_item[] sysdata = new kt_sysdata_item[2]; 193 + kt_sysdata_item[] sysdata = new kt_sysdata_item[3];
194 sysdata[0] = new kt_sysdata_item(); 194 sysdata[0] = new kt_sysdata_item();
195 sysdata[0].name = "created_by"; 195 sysdata[0].name = "created_by";
196 sysdata[0].value = "Anonymous"; 196 sysdata[0].value = "Anonymous";
@@ -199,19 +199,29 @@ namespace MonoTests.KnowledgeTree @@ -199,19 +199,29 @@ namespace MonoTests.KnowledgeTree
199 sysdata[1].value = "2007-01-17"; 199 sysdata[1].value = "2007-01-17";
200 200
201 201
  202 + sysdata[2] = new kt_sysdata_item();
  203 + sysdata[2].name = "index_content";
  204 + sysdata[2].value = "happy happy. this is a test with hippos and rhinos under the sun. unbrellas are required to create shade when trees are not abound.";
  205 +
  206 +
202 207
203 this._doc2.local = true; 208 this._doc2.local = true;
204 this._doc2.createFile(this._folderId); 209 this._doc2.createFile(this._folderId);
205 210
206 - 211 +
  212 +
  213 + for (int i =0;i<2;i++)
  214 + {
207 FileUploader uploader = new FileUploader( ); 215 FileUploader uploader = new FileUploader( );
208 216
209 uploader.upload(this._session, this._doc2.filename); 217 uploader.upload(this._session, this._doc2.filename);
210 - 218 +
211 System.Console.WriteLine("uploaded: " + uploader.filename); 219 System.Console.WriteLine("uploaded: " + uploader.filename);
212 - kt_document_detail response1 = this._kt.add_document_with_metadata(this._session, this._folderId, this._doc2.title, this._doc2.filename, "Default", uploader.filename,fs, sysdata);  
213 220
214 - Assert.AreEqual(0, response1.status_code); 221 + kt_document_detail response1 = this._kt.add_document_with_metadata(this._session, this._folderId, this._doc2.title+i, this._doc2.filename+i, "Default", uploader.filename,fs, sysdata);
  222 +
  223 + Assert.AreEqual(0, response1.status_code);
  224 + }
215 } 225 }
216 226
217 [Test] 227 [Test]
@@ -246,8 +256,8 @@ namespace MonoTests.KnowledgeTree @@ -246,8 +256,8 @@ namespace MonoTests.KnowledgeTree
246 256
247 uploader.upload(this._session, this._doc1.filename); 257 uploader.upload(this._session, this._doc1.filename);
248 258
249 - kt_document_detail update_resp = this._kt.checkin_document(this._session, this._doc1.docId, this._doc1.filename, "unit test - doing checkin", uploader.filename, false);  
250 - Assert.AreEqual(0, update_resp.status_code); 259 + kt_document_detail update_resp = this._kt.checkin_document(this._session, this._doc1.docId, this._doc1.filename, "unit test - doing checkin", uploader.filename, false);
  260 + Assert.AreEqual(0, update_resp.status_code);
251 } 261 }
252 262
253 } 263 }
ktwebservice/nunit/folder.cs
@@ -49,6 +49,9 @@ namespace MonoTests.KnowledgeTree @@ -49,6 +49,9 @@ namespace MonoTests.KnowledgeTree
49 49
50 } 50 }
51 51
  52 +
  53 +
  54 +
52 [Test] 55 [Test]
53 public void GetFolderByName() 56 public void GetFolderByName()
54 { 57 {
@@ -122,6 +125,55 @@ namespace MonoTests.KnowledgeTree @@ -122,6 +125,55 @@ namespace MonoTests.KnowledgeTree
122 response = this._kt.create_folder(this._session, 1, "kt - unit - test"); 125 response = this._kt.create_folder(this._session, 1, "kt - unit - test");
123 Assert.AreEqual(0,response.status_code); 126 Assert.AreEqual(0,response.status_code);
124 Assert.AreEqual("kt - unit - test",response.folder_name); 127 Assert.AreEqual("kt - unit - test",response.folder_name);
  128 +
  129 + response = this._kt.get_folder_detail_by_name(this._session, "/kt ' unit \" test");
  130 + Assert.AreEqual(0,response.status_code);
  131 + Assert.AreEqual("kt ' unit \" test",response.folder_name);
125 } 132 }
  133 +
  134 + [Test]
  135 + public void CopyFolder()
  136 + {
  137 +
  138 + kt_folder_detail response = this._kt.create_folder(this._session, 1, "kt_unit_test2");
  139 + Assert.AreEqual(0,response.status_code);
  140 +
  141 + this._folder_id = response.id;
  142 +
  143 + response = this._kt.create_folder(this._session, 1, "subfolder");
  144 + Assert.AreEqual(0,response.status_code);
  145 +
  146 + this._subfolder_id = response.id;
  147 +
  148 +
  149 + response = this._kt.copy_folder(this._session, this._folder_id, this._subfolder_id, "copy reason");
  150 + Assert.AreEqual(0,response.status_code);
  151 + Assert.AreEqual(this._subfolder_id,response.parent_id);
  152 + Assert.AreEqual("kt_unit_test2",response.folder_name);
  153 +
  154 + }
  155 +
  156 + [Test]
  157 + public void MoveFolder()
  158 + {
  159 +
  160 + kt_folder_detail response = this._kt.create_folder(this._session, 1, "kt_unit_test3");
  161 + Assert.AreEqual(0,response.status_code);
  162 +
  163 + this._folder_id = response.id;
  164 +
  165 + response = this._kt.create_folder(this._session, 1, "subfolder3");
  166 + Assert.AreEqual(0,response.status_code);
  167 +
  168 + this._subfolder_id = response.id;
  169 +
  170 + response = this._kt.move_folder(this._session, this._folder_id, this._subfolder_id, "move reason");
  171 + Assert.AreEqual(0,response.status_code);
  172 + Assert.AreEqual(this._folder_id,response.id);
  173 + Assert.AreEqual(this._subfolder_id,response.parent_id);
  174 + Assert.AreEqual("kt_unit_test3",response.folder_name);
  175 + }
  176 +
  177 +
126 } 178 }
127 } 179 }
ktwebservice/nunit/helper.cs
@@ -4,7 +4,28 @@ using System.Net; @@ -4,7 +4,28 @@ using System.Net;
4 using System.IO; 4 using System.IO;
5 using System.Collections; 5 using System.Collections;
6 using System.Data; 6 using System.Data;
7 -using System.Data.Odbc; 7 +using System.Data.Odbc;
  8 +using System.Runtime.Remoting;
  9 +using System.Runtime.Remoting.Channels;
  10 +using System.Runtime.Remoting.Messaging;
  11 +using System.Runtime.Remoting.Activation;
  12 +using System.Runtime.Remoting.Services;
  13 +using System.Runtime.Serialization;
  14 +using System.Text.RegularExpressions;
  15 +using System.Web.Services.Protocols;
  16 +using System.Reflection;
  17 +using Interception;
  18 +using System.Web;
  19 +using System.Xml;
  20 +using System.Web.Services;
  21 +using System.Diagnostics;
  22 +using System.Runtime.CompilerServices;
  23 +using System.Web.Services.Description;
  24 +using System.Web.Services.Discovery;
  25 +using System.Xml.Serialization;
  26 +using System.Xml.Schema;
  27 +using System.Threading;
  28 +using System.Web.Services.Protocols;
8 29
9 namespace MonoTests.KnowledgeTree 30 namespace MonoTests.KnowledgeTree
10 { 31 {
@@ -18,7 +39,22 @@ namespace MonoTests.KnowledgeTree @@ -18,7 +39,22 @@ namespace MonoTests.KnowledgeTree
18 { 39 {
19 this.Url = Environment.GetEnvironmentVariable("KT_ROOT_URL") + "/ktwebservice/webservice.php"; 40 this.Url = Environment.GetEnvironmentVariable("KT_ROOT_URL") + "/ktwebservice/webservice.php";
20 } 41 }
21 - } 42 + }
  43 +
  44 + public class MySoapHttpClientProtocol : SoapHttpClientProtocol
  45 + {
  46 + public MySoapHttpClientProtocol() : base() {}
  47 +
  48 + public object [] ReceiveResponse (WebResponse response, SoapClientMessage message, SoapExtension[] extensions)
  49 + {
  50 +
  51 + StreamReader sr = new StreamReader(response.GetResponseStream());
  52 + String content = sr.ReadToEnd();
  53 + System.Console.WriteLine(content);
  54 +
  55 + return null;
  56 + }
  57 + }
22 58
23 public class KTTest 59 public class KTTest
24 { 60 {
@@ -33,8 +69,10 @@ namespace MonoTests.KnowledgeTree @@ -33,8 +69,10 @@ namespace MonoTests.KnowledgeTree
33 kt_response response = this._kt.login("admin","admin","127.0.0.1"); 69 kt_response response = this._kt.login("admin","admin","127.0.0.1");
34 this._session = response.message; 70 this._session = response.message;
35 this._verbose = false; 71 this._verbose = false;
36 - this.setupDb();  
37 - } 72 + this.setupDb();
  73 +
  74 + //System.Web.Services.Protocols.SoapHttpClientProtocol.ReceiveResponse
  75 + }
38 76
39 void setupDb() 77 void setupDb()
40 { 78 {
ktwebservice/nunit/makefile
1 -RESULTS= authentication.result document_detail.result document_contents.result document_history.result folder.result document_metadata.result document_add.result document_checkout.result document_type.result document_links.result document_owner.result document_rename.result document_workflow.result document_copy.result document_system_metadata.result query.result document_download.result 1 +RESULTS=folder.result document_metadata.result authentication.result document_contents.result document_detail.result document_history.result document_add.result document_checkout.result document_links.result document_owner.result document_rename.result document_workflow.result document_copy.result document_move.result document_system_metadata.result query.result document_download.result document_type.result document_oem_no.result
2 PROXY=KTproxy.cs 2 PROXY=KTproxy.cs
3 WSDL=ktdms.wsdl 3 WSDL=ktdms.wsdl
4 ROOT_URL=http://ktdms.trunk 4 ROOT_URL=http://ktdms.trunk
  5 +#ROOT_URL=http://192.168.1.111
5 WSDL_URL=${ROOT_URL}/ktwebservice/index.php?wsdl 6 WSDL_URL=${ROOT_URL}/ktwebservice/index.php?wsdl
6 7
7 all: ${RESULTS} 8 all: ${RESULTS}
8 9
9 results: clean-results ${RESULTS} 10 results: clean-results ${RESULTS}
10 11
11 -KTproxy.dll: KTproxy.cs helper.cs  
12 - mcs -r:System.Web.Services -r:System.Data.dll /target:library KTproxy.cs helper.cs 12 +KTproxy.dll: KTproxy.cs helper.cs
  13 + mcs -r:System.Web.Services -r:System.Data.dll /target:library KTproxy.cs intercept.cs helper.cs
13 14
14 KTproxy.cs: ktdms.wsdl 15 KTproxy.cs: ktdms.wsdl
15 wsdl -out:${PROXY} ${WSDL} 16 wsdl -out:${PROXY} ${WSDL}
@@ -23,7 +24,7 @@ clean: @@ -23,7 +24,7 @@ clean:
23 clean-results: 24 clean-results:
24 rm -f ${RESULTS} 25 rm -f ${RESULTS}
25 26
26 -%.dll: %.cs KTproxy.dll 27 +%.dll: %.cs KTproxy.dll
27 mcs -r:System.Web.Services -r:nunit.framework /r:KTproxy.dll -debug /target:library -out:$@ $< 28 mcs -r:System.Web.Services -r:nunit.framework /r:KTproxy.dll -debug /target:library -out:$@ $<
28 29
29 %.result: %.dll 30 %.result: %.dll
ktwebservice/webservice.php
@@ -69,6 +69,7 @@ if (defined(&#39;HAS_SEARCH_FUNCTIONALITY&#39;)) @@ -69,6 +69,7 @@ if (defined(&#39;HAS_SEARCH_FUNCTIONALITY&#39;))
69 // TODO: redo metadata encoding 69 // TODO: redo metadata encoding
70 // TODO: unit tests - metadata - test return values in selectin - list/tree 70 // TODO: unit tests - metadata - test return values in selectin - list/tree
71 // TODO: ktwsapi/php must be made compatible with v2/v3 71 // TODO: ktwsapi/php must be made compatible with v2/v3
  72 +// TODO: subscriptions/notifications
72 73
73 // NOTE: some features are not implemented yet. most expected for v3. e.g. oem_document_no, custom_document_no, download($version)., get_metadata($version) 74 // NOTE: some features are not implemented yet. most expected for v3. e.g. oem_document_no, custom_document_no, download($version)., get_metadata($version)
74 75
@@ -555,6 +556,34 @@ class KTWebService @@ -555,6 +556,34 @@ class KTWebService
555 ); 556 );
556 } 557 }
557 558
  559 + $this->__typedef["{urn:$this->namespace}kt_document_collection"] =
  560 + array(
  561 + array(
  562 + 'item' => "{urn:$this->namespace}kt_document_detail"
  563 + )
  564 + );
  565 +
  566 + $this->__typedef["{urn:$this->namespace}kt_document_collection_response"] =
  567 + array(
  568 + 'status_code' => 'int',
  569 + 'message' => 'string',
  570 + 'collection' => "{urn:$this->namespace}kt_document_collection"
  571 + );
  572 +
  573 + $this->__typedef["{urn:$this->namespace}kt_folder_collection"] =
  574 + array(
  575 + array(
  576 + 'item' => "{urn:$this->namespace}kt_folder_detail"
  577 + )
  578 + );
  579 +
  580 + $this->__typedef["{urn:$this->namespace}kt_folder_collection_response"] =
  581 + array(
  582 + 'status_code' => 'int',
  583 + 'message' => 'string',
  584 + 'collection' => "{urn:$this->namespace}kt_folder_collection"
  585 + );
  586 +
558 $this->__typedef["{urn:$this->namespace}kt_document_version_history"] = 587 $this->__typedef["{urn:$this->namespace}kt_document_version_history"] =
559 array( 588 array(
560 array( 589 array(
@@ -642,6 +671,12 @@ class KTWebService @@ -642,6 +671,12 @@ class KTWebService
642 $this->__dispatch_map['get_folder_detail']['in'] = array('session_id' => 'string', 'folder_id' => 'int', 'create'=>'boolean' ); 671 $this->__dispatch_map['get_folder_detail']['in'] = array('session_id' => 'string', 'folder_id' => 'int', 'create'=>'boolean' );
643 } 672 }
644 673
  674 + // get_documents_by_oem_no
  675 + $this->__dispatch_map['get_documents_by_oem_no'] =
  676 + array('in' => array('session_id' => 'string', 'oem_no' => 'string', 'detail' => 'string'),
  677 + 'out' => array('return' => "{urn:$this->namespace}kt_document_collection_response"),
  678 + );
  679 +
645 // get_folder_detail_by_name 680 // get_folder_detail_by_name
646 $this->__dispatch_map['get_folder_detail_by_name'] = 681 $this->__dispatch_map['get_folder_detail_by_name'] =
647 array('in' => array('session_id' => 'string', 'folder_name' => 'string' ), 682 array('in' => array('session_id' => 'string', 'folder_name' => 'string' ),
@@ -712,12 +747,23 @@ class KTWebService @@ -712,12 +747,23 @@ class KTWebService
712 'out' => array('return' => "{urn:$this->namespace}kt_response" ), 747 'out' => array('return' => "{urn:$this->namespace}kt_response" ),
713 ); 748 );
714 749
  750 + if ($this->version >= 2)
  751 + {
  752 + $this->__dispatch_map['copy_folder']['out'] = array('return' => "{urn:$this->namespace}kt_folder_detail" );
  753 + }
  754 +
715 // move_folder 755 // move_folder
716 $this->__dispatch_map['move_folder'] = 756 $this->__dispatch_map['move_folder'] =
717 array('in' => array('session_id'=>'string','source_id'=>'int','target_id'=>'int','reason' =>'string'), 757 array('in' => array('session_id'=>'string','source_id'=>'int','target_id'=>'int','reason' =>'string'),
718 'out' => array('return' => "{urn:$this->namespace}kt_response" ), 758 'out' => array('return' => "{urn:$this->namespace}kt_response" ),
719 ); 759 );
720 760
  761 + if ($this->version >= 2)
  762 + {
  763 + $this->__dispatch_map['move_folder']['out'] = array('return' => "{urn:$this->namespace}kt_folder_detail" );
  764 + }
  765 +
  766 +
721 // get_document_detail 767 // get_document_detail
722 $this->__dispatch_map['get_document_detail'] = array( 768 $this->__dispatch_map['get_document_detail'] = array(
723 'in' => array('session_id' => 'string', 'document_id' => 'int' ), 769 'in' => array('session_id' => 'string', 'document_id' => 'int' ),
@@ -914,7 +960,10 @@ class KTWebService @@ -914,7 +960,10 @@ class KTWebService
914 ); 960 );
915 if ($this->version >= 2) 961 if ($this->version >= 2)
916 { 962 {
917 - $this->__dispatch_map['copy_document']['out'] = array( 'return' => "{urn:$this->namespace}kt_document_detail" ); 963 + $this->__dispatch_map['copy_document'] =
  964 + array('in' => array('session_id'=>'string','document_id'=>'int','folder_id'=>'int','reason'=>'string', 'options'=>'string' ),
  965 + 'out' => array( 'return' => "{urn:$this->namespace}kt_document_detail" ),
  966 + );
918 } 967 }
919 968
920 // move_document 969 // move_document
@@ -924,7 +973,10 @@ class KTWebService @@ -924,7 +973,10 @@ class KTWebService
924 ); 973 );
925 if ($this->version >= 2) 974 if ($this->version >= 2)
926 { 975 {
927 - $this->__dispatch_map['move_document']['out'] = array( 'return' => "{urn:$this->namespace}kt_document_detail" ); 976 + $this->__dispatch_map['move_document'] =
  977 + array('in' => array('session_id'=>'string','document_id'=>'int','folder_id'=>'int','reason'=>'string', 'options'=>'string'),
  978 + 'out' => array( 'return' => "{urn:$this->namespace}kt_document_detail" ),
  979 + );
928 } 980 }
929 981
930 // rename_document_title 982 // rename_document_title
@@ -1493,9 +1545,15 @@ class KTWebService @@ -1493,9 +1545,15 @@ class KTWebService
1493 { 1545 {
1494 $this->debug("copy_folder('$session_id',$source_id,$target_id,'$reason')"); 1546 $this->debug("copy_folder('$session_id',$source_id,$target_id,'$reason')");
1495 $kt = &$this->get_ktapi($session_id ); 1547 $kt = &$this->get_ktapi($session_id );
  1548 +
  1549 + $responseType = 'kt_response';
  1550 + if ($this->version >= 2)
  1551 + {
  1552 + $responseType = 'kt_folder_detail';
  1553 + }
1496 if (is_array($kt)) 1554 if (is_array($kt))
1497 { 1555 {
1498 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $kt); 1556 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $kt);
1499 } 1557 }
1500 1558
1501 $response = KTWebService::_status(KTWS_ERR_INVALID_FOLDER); 1559 $response = KTWebService::_status(KTWS_ERR_INVALID_FOLDER);
@@ -1505,7 +1563,7 @@ class KTWebService @@ -1505,7 +1563,7 @@ class KTWebService
1505 { 1563 {
1506 $response['message'] = $src_folder->getMessage(); 1564 $response['message'] = $src_folder->getMessage();
1507 $this->debug("copy_folder - cannot get source folderid $source_id - " . $src_folder->getMessage(), $session_id); 1565 $this->debug("copy_folder - cannot get source folderid $source_id - " . $src_folder->getMessage(), $session_id);
1508 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response); 1566 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $response);
1509 } 1567 }
1510 1568
1511 $tgt_folder = &$kt->get_folder_by_id($target_id); 1569 $tgt_folder = &$kt->get_folder_by_id($target_id);
@@ -1514,7 +1572,7 @@ class KTWebService @@ -1514,7 +1572,7 @@ class KTWebService
1514 $response['message'] = $tgt_folder->getMessage(); 1572 $response['message'] = $tgt_folder->getMessage();
1515 $this->debug("copy_folder - cannot get target folderid $target_id - " . $tgt_folder->getMessage(), $session_id); 1573 $this->debug("copy_folder - cannot get target folderid $target_id - " . $tgt_folder->getMessage(), $session_id);
1516 1574
1517 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response); 1575 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $response);
1518 } 1576 }
1519 1577
1520 $result= $src_folder->copy($tgt_folder, $reason); 1578 $result= $src_folder->copy($tgt_folder, $reason);
@@ -1524,12 +1582,23 @@ class KTWebService @@ -1524,12 +1582,23 @@ class KTWebService
1524 $response['message'] = $result->getMessage(); 1582 $response['message'] = $result->getMessage();
1525 $this->debug("copy_folder - copy to target folder - " . $result->getMessage(), $session_id); 1583 $this->debug("copy_folder - copy to target folder - " . $result->getMessage(), $session_id);
1526 1584
1527 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response); 1585 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $response);
  1586 + }
  1587 +
  1588 + if ($this->version >=2)
  1589 + {
  1590 +
  1591 + $sourceName = $src_folder->get_folder_name();
  1592 + $targetPath = $tgt_folder->get_full_path();
  1593 +
  1594 + $response = $this->get_folder_detail_by_name($session_id, $targetPath . '/' . $sourceName);
  1595 +
  1596 + return $response;
1528 } 1597 }
1529 1598
1530 $response['status_code']= KTWS_SUCCESS; 1599 $response['status_code']= KTWS_SUCCESS;
1531 1600
1532 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response); 1601 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $response);
1533 } 1602 }
1534 1603
1535 /** 1604 /**
@@ -1545,9 +1614,14 @@ class KTWebService @@ -1545,9 +1614,14 @@ class KTWebService
1545 { 1614 {
1546 $this->debug("move_folder('$session_id',$source_id,$target_id,'$reason')"); 1615 $this->debug("move_folder('$session_id',$source_id,$target_id,'$reason')");
1547 $kt = &$this->get_ktapi($session_id ); 1616 $kt = &$this->get_ktapi($session_id );
  1617 + $responseType = 'kt_response';
  1618 + if ($this->version >= 2)
  1619 + {
  1620 + $responseType = 'kt_folder_detail';
  1621 + }
1548 if (is_array($kt)) 1622 if (is_array($kt))
1549 { 1623 {
1550 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $kt); 1624 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $kt);
1551 } 1625 }
1552 1626
1553 $response = KTWebService::_status(KTWS_ERR_INVALID_FOLDER); 1627 $response = KTWebService::_status(KTWS_ERR_INVALID_FOLDER);
@@ -1557,7 +1631,7 @@ class KTWebService @@ -1557,7 +1631,7 @@ class KTWebService
1557 { 1631 {
1558 $response['message'] = $src_folder->getMessage(); 1632 $response['message'] = $src_folder->getMessage();
1559 $this->debug("move_folder - cannot get source folder $source_id - " . $src_folder->getMessage(), $session_id); 1633 $this->debug("move_folder - cannot get source folder $source_id - " . $src_folder->getMessage(), $session_id);
1560 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response); 1634 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $response);
1561 } 1635 }
1562 1636
1563 $tgt_folder = &$kt->get_folder_by_id($target_id); 1637 $tgt_folder = &$kt->get_folder_by_id($target_id);
@@ -1565,7 +1639,7 @@ class KTWebService @@ -1565,7 +1639,7 @@ class KTWebService
1565 { 1639 {
1566 $response['message'] = $tgt_folder->getMessage(); 1640 $response['message'] = $tgt_folder->getMessage();
1567 $this->debug("move_folder - cannot get target folder $target_id - " . $tgt_folder->getMessage(), $session_id); 1641 $this->debug("move_folder - cannot get target folder $target_id - " . $tgt_folder->getMessage(), $session_id);
1568 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response); 1642 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $response);
1569 } 1643 }
1570 1644
1571 $result = $src_folder->move($tgt_folder, $reason); 1645 $result = $src_folder->move($tgt_folder, $reason);
@@ -1574,12 +1648,20 @@ class KTWebService @@ -1574,12 +1648,20 @@ class KTWebService
1574 $response['status_code'] = KTWS_ERR_PROBLEM; 1648 $response['status_code'] = KTWS_ERR_PROBLEM;
1575 $response['message'] = $result->getMessage(); 1649 $response['message'] = $result->getMessage();
1576 $this->debug("move_folder - cannot move folder - " . $result->getMessage(), $session_id); 1650 $this->debug("move_folder - cannot move folder - " . $result->getMessage(), $session_id);
1577 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response); 1651 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $response);
  1652 + }
  1653 +
  1654 + if ($this->version >=2)
  1655 + {
  1656 +
  1657 + $response = $this->get_folder_detail($session_id, $source_id);
  1658 +
  1659 + return $response;
1578 } 1660 }
1579 1661
1580 $response['status_code']= KTWS_SUCCESS; 1662 $response['status_code']= KTWS_SUCCESS;
1581 1663
1582 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response); 1664 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $response);
1583 } 1665 }
1584 1666
1585 /** 1667 /**
@@ -1908,6 +1990,11 @@ class KTWebService @@ -1908,6 +1990,11 @@ class KTWebService
1908 } 1990 }
1909 1991
1910 $document = $kt->get_document_by_id($document_id); 1992 $document = $kt->get_document_by_id($document_id);
  1993 + $result = $document->removeUpdateNotification();
  1994 + if (PEAR::isError($result))
  1995 + {
  1996 + // not much we can do, maybe just log!
  1997 + }
1911 $result = $document->mergeWithLastMetadataVersion(); 1998 $result = $document->mergeWithLastMetadataVersion();
1912 if (PEAR::isError($result)) 1999 if (PEAR::isError($result))
1913 { 2000 {
@@ -1942,6 +2029,13 @@ class KTWebService @@ -1942,6 +2029,13 @@ class KTWebService
1942 } 2029 }
1943 2030
1944 $document = $kt->get_document_by_id($document_id); 2031 $document = $kt->get_document_by_id($document_id);
  2032 + $result = $document->removeUpdateNotification();
  2033 + if (PEAR::isError($result))
  2034 + {
  2035 + // not much we can do, maybe just log!
  2036 + }
  2037 +
  2038 +
1945 $result = $document->mergeWithLastMetadataVersion(); 2039 $result = $document->mergeWithLastMetadataVersion();
1946 if (PEAR::isError($result)) 2040 if (PEAR::isError($result))
1947 { 2041 {
@@ -1951,6 +2045,45 @@ class KTWebService @@ -1951,6 +2045,45 @@ class KTWebService
1951 return $update_result; 2045 return $update_result;
1952 } 2046 }
1953 2047
  2048 +
  2049 + /**
  2050 + * Find documents matching the document oem (integration) no
  2051 + *
  2052 + * @param string $session_id
  2053 + * @param string $oem_no
  2054 + * @param string $detail
  2055 + * @return kt_document_collection_response
  2056 + */
  2057 + function get_documents_by_oem_no($session_id, $oem_no, $detail)
  2058 + {
  2059 + $this->debug("get_documents_by_oem_no('$session_id','$oem_no', '$detail')");
  2060 + $kt = &$this->get_ktapi($session_id );
  2061 + if (is_array($kt))
  2062 + {
  2063 + return new SOAP_Value('return',"{urn:$this->namespace}kt_document_collection_response", $kt);
  2064 + }
  2065 +
  2066 + $documents = $kt->get_documents_by_oem_no($oem_no);
  2067 +
  2068 + $collection = array();
  2069 + foreach($documents as $documentId)
  2070 + {
  2071 + $detail = $this->get_document_detail($session_id, $documentId, $detail);
  2072 + if ($detail->value['status_code'] != 0)
  2073 + {
  2074 + continue;
  2075 + }
  2076 + $collection[] = $detail->value;
  2077 + }
  2078 +
  2079 + $response=array();
  2080 + $response['status_code'] = KTWS_SUCCESS;
  2081 + $response['message'] = empty($collection)?_kt('No documents were found matching the specified document no'):'';
  2082 + $response['collection'] = new SOAP_Value('collection',"{urn:$this->namespace}kt_document_collection", $collection);
  2083 +
  2084 + return new SOAP_Value('return',"{urn:$this->namespace}kt_document_collection_response", $response);
  2085 + }
  2086 +
1954 /** 2087 /**
1955 * Adds a document to the repository. 2088 * Adds a document to the repository.
1956 * 2089 *
@@ -2088,6 +2221,11 @@ class KTWebService @@ -2088,6 +2221,11 @@ class KTWebService
2088 } 2221 }
2089 2222
2090 $document = $kt->get_document_by_id($document_id); 2223 $document = $kt->get_document_by_id($document_id);
  2224 + $result = $document->removeUpdateNotification();
  2225 + if (PEAR::isError($result))
  2226 + {
  2227 + // not much we can do, maybe just log!
  2228 + }
2091 $result = $document->mergeWithLastMetadataVersion(); 2229 $result = $document->mergeWithLastMetadataVersion();
2092 if (PEAR::isError($result)) 2230 if (PEAR::isError($result))
2093 { 2231 {
@@ -2121,6 +2259,11 @@ class KTWebService @@ -2121,6 +2259,11 @@ class KTWebService
2121 } 2259 }
2122 2260
2123 $document = $kt->get_document_by_id($document_id); 2261 $document = $kt->get_document_by_id($document_id);
  2262 + $result = $document->removeUpdateNotification();
  2263 + if (PEAR::isError($result))
  2264 + {
  2265 + // not much we can do, maybe just log!
  2266 + }
2124 $result = $document->mergeWithLastMetadataVersion(); 2267 $result = $document->mergeWithLastMetadataVersion();
2125 if (PEAR::isError($result)) 2268 if (PEAR::isError($result))
2126 { 2269 {
@@ -2583,14 +2726,19 @@ class KTWebService @@ -2583,14 +2726,19 @@ class KTWebService
2583 * @param string $newfilename 2726 * @param string $newfilename
2584 * @return kt_document_detail 2727 * @return kt_document_detail
2585 */ 2728 */
2586 - function copy_document($session_id,$document_id,$folder_id,$reason,$newtitle,$newfilename) 2729 + function copy_document($session_id,$document_id,$folder_id,$reason,$newtitle=null,$newfilename=null)
2587 { 2730 {
2588 $this->debug("copy_document('$session_id',$document_id,$folder_id,'$reason','$newtitle','$newfilename')"); 2731 $this->debug("copy_document('$session_id',$document_id,$folder_id,'$reason','$newtitle','$newfilename')");
2589 2732
  2733 + $responseType = 'kt_response';
  2734 + if ($this->version >= 2)
  2735 + {
  2736 + $responseType = 'kt_document_detail';
  2737 + }
2590 $kt = &$this->get_ktapi($session_id ); 2738 $kt = &$this->get_ktapi($session_id );
2591 if (is_array($kt)) 2739 if (is_array($kt))
2592 { 2740 {
2593 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $kt); 2741 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $kt);
2594 } 2742 }
2595 2743
2596 $response = KTWebService::_status(KTWS_ERR_INVALID_DOCUMENT); 2744 $response = KTWebService::_status(KTWS_ERR_INVALID_DOCUMENT);
@@ -2600,7 +2748,7 @@ class KTWebService @@ -2600,7 +2748,7 @@ class KTWebService
2600 { 2748 {
2601 $response['message'] = $document->getMessage(); 2749 $response['message'] = $document->getMessage();
2602 $this->debug("copy_document - cannot get documentid $document_id - " . $document->getMessage(), $session_id); 2750 $this->debug("copy_document - cannot get documentid $document_id - " . $document->getMessage(), $session_id);
2603 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response); 2751 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $response);
2604 } 2752 }
2605 2753
2606 $tgt_folder = &$kt->get_folder_by_id($folder_id); 2754 $tgt_folder = &$kt->get_folder_by_id($folder_id);
@@ -2609,7 +2757,7 @@ class KTWebService @@ -2609,7 +2757,7 @@ class KTWebService
2609 $response['status_code'] = KTWS_ERR_INVALID_FOLDER; 2757 $response['status_code'] = KTWS_ERR_INVALID_FOLDER;
2610 $response['message'] = $tgt_folder->getMessage(); 2758 $response['message'] = $tgt_folder->getMessage();
2611 $this->debug("copy_document - cannot get folderid $folder_id - " . $tgt_folder->getMessage(), $session_id); 2759 $this->debug("copy_document - cannot get folderid $folder_id - " . $tgt_folder->getMessage(), $session_id);
2612 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response); 2760 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $response);
2613 } 2761 }
2614 2762
2615 $result = $document->copy($tgt_folder, $reason, $newtitle, $newfilename); 2763 $result = $document->copy($tgt_folder, $reason, $newtitle, $newfilename);
@@ -2617,7 +2765,7 @@ class KTWebService @@ -2617,7 +2765,7 @@ class KTWebService
2617 { 2765 {
2618 $response['message'] = $result->getMessage(); 2766 $response['message'] = $result->getMessage();
2619 $this->debug("copy_document - cannot copy - " . $result->getMessage(), $session_id); 2767 $this->debug("copy_document - cannot copy - " . $result->getMessage(), $session_id);
2620 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response); 2768 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $response);
2621 } 2769 }
2622 $response['status_code'] = KTWS_SUCCESS; 2770 $response['status_code'] = KTWS_SUCCESS;
2623 if ($this->version >= 2) 2771 if ($this->version >= 2)
@@ -2626,7 +2774,7 @@ class KTWebService @@ -2626,7 +2774,7 @@ class KTWebService
2626 return $this->get_document_detail($session_id, $new_document_id, ''); 2774 return $this->get_document_detail($session_id, $new_document_id, '');
2627 } 2775 }
2628 2776
2629 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response); 2777 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $response);
2630 } 2778 }
2631 2779
2632 /** 2780 /**
@@ -2640,13 +2788,18 @@ class KTWebService @@ -2640,13 +2788,18 @@ class KTWebService
2640 * @param string $newfilename 2788 * @param string $newfilename
2641 * @return kt_response 2789 * @return kt_response
2642 */ 2790 */
2643 - function move_document($session_id,$document_id,$folder_id,$reason,$newtitle,$newfilename) 2791 + function move_document($session_id,$document_id,$folder_id,$reason,$newtitle=null,$newfilename=null)
2644 { 2792 {
2645 $this->debug("move_document('$session_id',$document_id,$folder_id,'$reason','$newtitle','$newfilename')"); 2793 $this->debug("move_document('$session_id',$document_id,$folder_id,'$reason','$newtitle','$newfilename')");
  2794 + $responseType = 'kt_response';
  2795 + if ($this->version >= 2)
  2796 + {
  2797 + $responseType = 'kt_document_detail';
  2798 + }
2646 $kt = &$this->get_ktapi($session_id ); 2799 $kt = &$this->get_ktapi($session_id );
2647 if (is_array($kt)) 2800 if (is_array($kt))
2648 { 2801 {
2649 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $kt); 2802 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $kt);
2650 } 2803 }
2651 2804
2652 $response = KTWebService::_status(KTWS_ERR_INVALID_DOCUMENT); 2805 $response = KTWebService::_status(KTWS_ERR_INVALID_DOCUMENT);
@@ -2656,16 +2809,20 @@ class KTWebService @@ -2656,16 +2809,20 @@ class KTWebService
2656 { 2809 {
2657 $response['message'] = $document->getMessage(); 2810 $response['message'] = $document->getMessage();
2658 $this->debug("move_document - cannot get documentid $document_id - " . $document->getMessage(), $session_id); 2811 $this->debug("move_document - cannot get documentid $document_id - " . $document->getMessage(), $session_id);
2659 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response); 2812 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $response);
2660 } 2813 }
2661 2814
  2815 + if ($document->ktapi_folder->folderid != $folder_id)
  2816 + {
  2817 + // we only have to do something if the source and target folders are different
  2818 +
2662 $tgt_folder = &$kt->get_folder_by_id($folder_id); 2819 $tgt_folder = &$kt->get_folder_by_id($folder_id);
2663 if (PEAR::isError($tgt_folder)) 2820 if (PEAR::isError($tgt_folder))
2664 { 2821 {
2665 $response['status_code'] = KTWS_ERR_INVALID_FOLDER; 2822 $response['status_code'] = KTWS_ERR_INVALID_FOLDER;
2666 $response['message'] = $tgt_folder->getMessage(); 2823 $response['message'] = $tgt_folder->getMessage();
2667 $this->debug("move_document - cannot get folderid $folder_id - " . $tgt_folder->getMessage(), $session_id); 2824 $this->debug("move_document - cannot get folderid $folder_id - " . $tgt_folder->getMessage(), $session_id);
2668 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response); 2825 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $response);
2669 } 2826 }
2670 2827
2671 $result = $document->move($tgt_folder, $reason, $newtitle, $newfilename); 2828 $result = $document->move($tgt_folder, $reason, $newtitle, $newfilename);
@@ -2673,11 +2830,17 @@ class KTWebService @@ -2673,11 +2830,17 @@ class KTWebService
2673 { 2830 {
2674 $response['message'] = $result->getMessage(); 2831 $response['message'] = $result->getMessage();
2675 $this->debug("move_document - cannot move - " . $result->getMessage(), $session_id); 2832 $this->debug("move_document - cannot move - " . $result->getMessage(), $session_id);
2676 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response); 2833 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $response);
  2834 + }
2677 } 2835 }
  2836 +
2678 $response['status_code'] = KTWS_SUCCESS; 2837 $response['status_code'] = KTWS_SUCCESS;
  2838 + if ($this->version >= 2)
  2839 + {
  2840 + return $this->get_document_detail($session_id, $document_id, '');
  2841 + }
2679 2842
2680 - return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response); 2843 + return new SOAP_Value('return',"{urn:$this->namespace}$responseType", $response);
2681 } 2844 }
2682 2845
2683 /** 2846 /**
lib/documentmanagement/Document.inc
@@ -5,32 +5,32 @@ @@ -5,32 +5,32 @@
5 * KnowledgeTree Open Source Edition 5 * KnowledgeTree Open Source Edition
6 * Document Management Made Simple 6 * Document Management Made Simple
7 * Copyright (C) 2004 - 2007 The Jam Warehouse Software (Pty) Limited 7 * Copyright (C) 2004 - 2007 The Jam Warehouse Software (Pty) Limited
8 - * 8 + *
9 * This program is free software; you can redistribute it and/or modify it under 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 10 * the terms of the GNU General Public License version 3 as published by the
11 * Free Software Foundation. 11 * Free Software Foundation.
12 - * 12 + *
13 * This program is distributed in the hope that it will be useful, but WITHOUT 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 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 15 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 * details. 16 * details.
17 - * 17 + *
18 * You should have received a copy of the GNU General Public License 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/>. 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 - * 20 + *
21 * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place, 21 * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place,
22 * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com. 22 * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com.
23 - * 23 + *
24 * The interactive user interfaces in modified source and object code versions 24 * The interactive user interfaces in modified source and object code versions
25 * of this program must display Appropriate Legal Notices, as required under 25 * of this program must display Appropriate Legal Notices, as required under
26 * Section 5 of the GNU General Public License version 3. 26 * Section 5 of the GNU General Public License version 3.
27 - * 27 + *
28 * In accordance with Section 7(b) of the GNU General Public License version 3, 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 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 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 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. 32 + * must display the words "Powered by KnowledgeTree" and retain the original
  33 + * copyright notice.
34 * Contributor( s): ______________________________________ 34 * Contributor( s): ______________________________________
35 */ 35 */
36 36
@@ -107,6 +107,8 @@ class Document { @@ -107,6 +107,8 @@ class Document {
107 function getRestoreFolderPath() { return $this->_oDocumentCore->getRestoreFolderPath(); } 107 function getRestoreFolderPath() { return $this->_oDocumentCore->getRestoreFolderPath(); }
108 function setRestoreFolderPath($sValue) { $this->_oDocumentCore->setRestoreFolderPath($sValue); } 108 function setRestoreFolderPath($sValue) { $this->_oDocumentCore->setRestoreFolderPath($sValue); }
109 109
  110 + function getOemNo() { return $this->_oDocumentCore->getOemNo(); }
  111 +
110 112
111 // Document Metadata Items 113 // Document Metadata Items
112 114
@@ -610,6 +612,7 @@ class Document { @@ -610,6 +612,7 @@ class Document {
610 612
611 function clearAllCaches() { 613 function clearAllCaches() {
612 614
  615 + $GLOBALS["_OBJECTCACHE"]['Document'] = array();
613 KTEntityUtil::clearAllCaches('KTDocumentCore'); 616 KTEntityUtil::clearAllCaches('KTDocumentCore');
614 KTEntityUtil::clearAllCaches('KTDocumentContentVersion'); 617 KTEntityUtil::clearAllCaches('KTDocumentContentVersion');
615 KTEntityUtil::clearAllCaches('KTDocumentMetadataVersion'); 618 KTEntityUtil::clearAllCaches('KTDocumentMetadataVersion');
lib/documentmanagement/documentcore.inc.php
@@ -82,6 +82,8 @@ class KTDocumentCore extends KTEntity { @@ -82,6 +82,8 @@ class KTDocumentCore extends KTEntity {
82 82
83 var $dCheckedOut; 83 var $dCheckedOut;
84 84
  85 + var $sOemNo;
  86 +
85 var $_aFieldToSelect = array( 87 var $_aFieldToSelect = array(
86 "iId" => "id", 88 "iId" => "id",
87 89
@@ -114,10 +116,11 @@ class KTDocumentCore extends KTEntity { @@ -114,10 +116,11 @@ class KTDocumentCore extends KTEntity {
114 'iRestoreFolderId' => 'restore_folder_id', 116 'iRestoreFolderId' => 'restore_folder_id',
115 'sRestoreFolderPath' => 'restore_folder_path', 117 'sRestoreFolderPath' => 'restore_folder_path',
116 118
117 - 'dCheckedOut'=>'checkedout' 119 + 'dCheckedOut'=>'checkedout',
  120 + 'sOemNo'=>'oem_no'
118 ); 121 );
119 122
120 - function KTDocument() { 123 + function KTDocumentCore() {
121 } 124 }
122 125
123 // {{{ getters/setters 126 // {{{ getters/setters
@@ -133,6 +136,8 @@ class KTDocumentCore extends KTEntity { @@ -133,6 +136,8 @@ class KTDocumentCore extends KTEntity {
133 function getCheckedOutDate() { return $this->dCheckedOut; } 136 function getCheckedOutDate() { return $this->dCheckedOut; }
134 function setCheckedOutDate($dNewValue) { $this->dCheckedOut = $dNewValue; } 137 function setCheckedOutDate($dNewValue) { $this->dCheckedOut = $dNewValue; }
135 138
  139 + function getOemNo() { return $this->sOemNo; }
  140 +
136 function getFolderId() { return $this->iFolderId; } 141 function getFolderId() { return $this->iFolderId; }
137 function setFolderId($iNewValue) { $this->iFolderId = $iNewValue; } 142 function setFolderId($iNewValue) { $this->iFolderId = $iNewValue; }
138 143
lib/documentmanagement/documentmetadataversion.inc.php
@@ -5,32 +5,32 @@ @@ -5,32 +5,32 @@
5 * KnowledgeTree Open Source Edition 5 * KnowledgeTree Open Source Edition
6 * Document Management Made Simple 6 * Document Management Made Simple
7 * Copyright (C) 2004 - 2007 The Jam Warehouse Software (Pty) Limited 7 * Copyright (C) 2004 - 2007 The Jam Warehouse Software (Pty) Limited
8 - * 8 + *
9 * This program is free software; you can redistribute it and/or modify it under 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 10 * the terms of the GNU General Public License version 3 as published by the
11 * Free Software Foundation. 11 * Free Software Foundation.
12 - * 12 + *
13 * This program is distributed in the hope that it will be useful, but WITHOUT 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 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 15 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 * details. 16 * details.
17 - * 17 + *
18 * You should have received a copy of the GNU General Public License 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/>. 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 - * 20 + *
21 * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place, 21 * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place,
22 * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com. 22 * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com.
23 - * 23 + *
24 * The interactive user interfaces in modified source and object code versions 24 * The interactive user interfaces in modified source and object code versions
25 * of this program must display Appropriate Legal Notices, as required under 25 * of this program must display Appropriate Legal Notices, as required under
26 * Section 5 of the GNU General Public License version 3. 26 * Section 5 of the GNU General Public License version 3.
27 - * 27 + *
28 * In accordance with Section 7(b) of the GNU General Public License version 3, 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 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 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 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. 32 + * must display the words "Powered by KnowledgeTree" and retain the original
  33 + * copyright notice.
34 * Contributor( s): ______________________________________ 34 * Contributor( s): ______________________________________
35 * 35 *
36 */ 36 */
@@ -103,9 +103,9 @@ class KTDocumentMetadataVersion extends KTEntity { @@ -103,9 +103,9 @@ class KTDocumentMetadataVersion extends KTEntity {
103 function getDocumentTypeId() { return $this->iDocumentTypeId; } 103 function getDocumentTypeId() { return $this->iDocumentTypeId; }
104 function setDocumentTypeId($iNewValue) { $this->iDocumentTypeId = $iNewValue; } 104 function setDocumentTypeId($iNewValue) { $this->iDocumentTypeId = $iNewValue; }
105 function getName() { return sanitizeForSQLtoHTML($this->sName); } 105 function getName() { return sanitizeForSQLtoHTML($this->sName); }
106 - function setName($sNewValue) { $this->sName = sanitizeForSQL($sNewValue); } 106 + function setName($sNewValue) { $this->sName = $sNewValue; }
107 function getDescription() { return sanitizeForSQLtoHTML($this->sDescription); } 107 function getDescription() { return sanitizeForSQLtoHTML($this->sDescription); }
108 - function setDescription($sNewValue) { $this->sDescription = sanitizeForSQL($sNewValue); } 108 + function setDescription($sNewValue) { $this->sDescription = $sNewValue; }
109 function getStatusId() { return $this->iStatusId; } 109 function getStatusId() { return $this->iStatusId; }
110 function setStatusId($iNewValue) { $this->iStatusId = $iNewValue; } 110 function setStatusId($iNewValue) { $this->iStatusId = $iNewValue; }
111 function getVersionCreated() { return $this->dVersionCreated; } 111 function getVersionCreated() { return $this->dVersionCreated; }
lib/foldermanagement/Folder.inc
@@ -494,6 +494,7 @@ class Folder extends KTEntity { @@ -494,6 +494,7 @@ class Folder extends KTEntity {
494 } 494 }
495 495
496 function clearAllCaches() { 496 function clearAllCaches() {
  497 + $GLOBALS["_OBJECTCACHE"]['Folder'] = array();
497 return KTEntityUtil::clearAllCaches('Folder'); 498 return KTEntityUtil::clearAllCaches('Folder');
498 } 499 }
499 500
lib/help/helpreplacement.inc.php
@@ -5,32 +5,32 @@ @@ -5,32 +5,32 @@
5 * KnowledgeTree Open Source Edition 5 * KnowledgeTree Open Source Edition
6 * Document Management Made Simple 6 * Document Management Made Simple
7 * Copyright (C) 2004 - 2007 The Jam Warehouse Software (Pty) Limited 7 * Copyright (C) 2004 - 2007 The Jam Warehouse Software (Pty) Limited
8 - * 8 + *
9 * This program is free software; you can redistribute it and/or modify it under 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 10 * the terms of the GNU General Public License version 3 as published by the
11 * Free Software Foundation. 11 * Free Software Foundation.
12 - * 12 + *
13 * This program is distributed in the hope that it will be useful, but WITHOUT 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 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 15 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 * details. 16 * details.
17 - * 17 + *
18 * You should have received a copy of the GNU General Public License 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/>. 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 - * 20 + *
21 * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place, 21 * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place,
22 * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com. 22 * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com.
23 - * 23 + *
24 * The interactive user interfaces in modified source and object code versions 24 * The interactive user interfaces in modified source and object code versions
25 * of this program must display Appropriate Legal Notices, as required under 25 * of this program must display Appropriate Legal Notices, as required under
26 * Section 5 of the GNU General Public License version 3. 26 * Section 5 of the GNU General Public License version 3.
27 - * 27 + *
28 * In accordance with Section 7(b) of the GNU General Public License version 3, 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 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 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 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. 32 + * must display the words "Powered by KnowledgeTree" and retain the original
  33 + * copyright notice.
34 * Contributor( s): ______________________________________ 34 * Contributor( s): ______________________________________
35 * 35 *
36 */ 36 */
@@ -61,9 +61,9 @@ class KTHelpReplacement extends KTEntity { @@ -61,9 +61,9 @@ class KTHelpReplacement extends KTEntity {
61 function getDescription() { return sanitizeForSQLtoHTML($this->sDescription); } 61 function getDescription() { return sanitizeForSQLtoHTML($this->sDescription); }
62 function getTitle() { return sanitizeForSQLtoHTML($this->sTitle); } 62 function getTitle() { return sanitizeForSQLtoHTML($this->sTitle); }
63 function setID($iId) { $this->iId = $iId; } 63 function setID($iId) { $this->iId = $iId; }
64 - function setName($sName) { $this->sName = sanitizeForSQL($sName); }  
65 - function setDescription($sDescription) { $this->sDescription = sanitizeForSQL($sDescription); }  
66 - function setTitle($sTitle) { $this->sTitle= sanitizeForSQL($sTitle); } 64 + function setName($sName) { $this->sName = $sName; }
  65 + function setDescription($sDescription) { $this->sDescription = $sDescription; }
  66 + function setTitle($sTitle) { $this->sTitle= $sTitle; }
67 67
68 function _table () { 68 function _table () {
69 global $default; 69 global $default;
lib/import/zipimportstorage.inc.php
@@ -7,71 +7,140 @@ @@ -7,71 +7,140 @@
7 * KnowledgeTree Open Source Edition 7 * KnowledgeTree Open Source Edition
8 * Document Management Made Simple 8 * Document Management Made Simple
9 * Copyright (C) 2004 - 2007 The Jam Warehouse Software (Pty) Limited 9 * Copyright (C) 2004 - 2007 The Jam Warehouse Software (Pty) Limited
10 - * 10 + *
11 * This program is free software; you can redistribute it and/or modify it under 11 * This program is free software; you can redistribute it and/or modify it under
12 * the terms of the GNU General Public License version 3 as published by the 12 * the terms of the GNU General Public License version 3 as published by the
13 * Free Software Foundation. 13 * Free Software Foundation.
14 - * 14 + *
15 * This program is distributed in the hope that it will be useful, but WITHOUT 15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 17 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
18 * details. 18 * details.
19 - * 19 + *
20 * You should have received a copy of the GNU General Public License 20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>. 21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 - * 22 + *
23 * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place, 23 * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place,
24 * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com. 24 * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com.
25 - * 25 + *
26 * The interactive user interfaces in modified source and object code versions 26 * The interactive user interfaces in modified source and object code versions
27 * of this program must display Appropriate Legal Notices, as required under 27 * of this program must display Appropriate Legal Notices, as required under
28 * Section 5 of the GNU General Public License version 3. 28 * Section 5 of the GNU General Public License version 3.
29 - * 29 + *
30 * In accordance with Section 7(b) of the GNU General Public License version 3, 30 * In accordance with Section 7(b) of the GNU General Public License version 3,
31 * these Appropriate Legal Notices must retain the display of the "Powered by 31 * these Appropriate Legal Notices must retain the display of the "Powered by
32 - * KnowledgeTree" logo and retain the original copyright notice. If the display of the 32 + * KnowledgeTree" logo and retain the original copyright notice. If the display of the
33 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices 33 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
34 - * must display the words "Powered by KnowledgeTree" and retain the original  
35 - * copyright notice. 34 + * must display the words "Powered by KnowledgeTree" and retain the original
  35 + * copyright notice.
36 * Contributor( s): ______________________________________ 36 * Contributor( s): ______________________________________
37 */ 37 */
38 38
39 require_once(KT_LIB_DIR . '/filelike/fsfilelike.inc.php'); 39 require_once(KT_LIB_DIR . '/filelike/fsfilelike.inc.php');
40 require_once(KT_LIB_DIR . '/import/fsimportstorage.inc.php'); 40 require_once(KT_LIB_DIR . '/import/fsimportstorage.inc.php');
41 41
  42 +require_once('File/Archive.php');
  43 +
42 class KTZipImportStorage extends KTFSImportStorage { 44 class KTZipImportStorage extends KTFSImportStorage {
43 - function KTZipImportStorage($sZipPath) {  
44 - $this->sZipPath = $sZipPath; 45 +
  46 + /**
  47 + * The archive extension.
  48 + * @var string
  49 + */
  50 + var $sExtension = 'zip';
  51 +
  52 + var $sZipPath = '';
  53 +
  54 + var $sBasePath = '';
  55 +
  56 + var $aFile = array();
  57 +
  58 + var $allowed_extensions = array('tgz', 'tar', 'gz', 'gzip', 'zip', 'deb', 'ar');
  59 +
  60 + function KTZipImportStorage($sFilesName) {
  61 + $this->aFile = $_FILES[$sFilesName];
  62 + $this->sZipPath = $this->aFile['tmp_name'];
  63 +
  64 + // Check the bzip2 lib functions are available
  65 + if(function_exists('bzopen')){
  66 + $this->allowed_extensions = array_merge($this->allowed_extensions, array('bz2', 'bzip2', 'tbz'));
  67 + }
  68 + }
  69 +
  70 + function CheckFormat(){
  71 + // Get the file extension
  72 + $aFilename = explode('.', $this->aFile['name']);
  73 + $cnt = count($aFilename);
  74 + $sExtension = $aFilename[$cnt - 1];
  75 +
  76 + // check if its in the list of supported extensions
  77 + if(!in_array($sExtension, $this->allowed_extensions)){
  78 + return false;
  79 + }
  80 +
  81 + $this->sExtension = (!empty($sExtension)) ? $sExtension : 'zip';
  82 +
  83 + // Check if the archive is a .tar.gz or .tar.bz, etc
  84 + if($cnt > 2){
  85 + if($aFilename[$cnt-2] == 'tar'){
  86 + switch($this->sExtension){
  87 + case 'gz':
  88 + $this->sExtension = 'tgz';
  89 + break;
  90 + case 'bz2':
  91 + $this->sExtension = 'tbz';
  92 + break;
  93 + }
  94 + }
  95 + }
  96 +
  97 + return true;
  98 + }
  99 +
  100 + function getFormats(){
  101 + return implode(', ', $this->allowed_extensions);
45 } 102 }
46 103
47 function init() { 104 function init() {
48 $oKTConfig =& KTConfig::getSingleton(); 105 $oKTConfig =& KTConfig::getSingleton();
49 - $sBasedir = $oKTConfig->get("urls/tmpDirectory");  
50 -  
51 - $sTmpPath = tempnam($sBasedir, 'zipimportstorage'); 106 + $sBasedir = $oKTConfig->get("urls/tmpDirectory");
  107 +
  108 + $sTmpPath = tempnam($sBasedir, 'archiveimportstorage');
52 if ($sTmpPath === false) { 109 if ($sTmpPath === false) {
53 - return PEAR::raiseError(_kt("Could not create temporary directory for zip storage")); 110 + return PEAR::raiseError(_kt("Could not create temporary directory for archive storage"));
54 } 111 }
55 if (!file_exists($this->sZipPath)) { 112 if (!file_exists($this->sZipPath)) {
56 - return PEAR::raiseError(_kt("Zip file given does not exist")); 113 + return PEAR::raiseError(_kt("Archive file given does not exist"));
57 } 114 }
58 unlink($sTmpPath); 115 unlink($sTmpPath);
59 mkdir($sTmpPath, 0700); 116 mkdir($sTmpPath, 0700);
60 $this->sBasePath = $sTmpPath; 117 $this->sBasePath = $sTmpPath;
61 - $sUnzipCommand = KTUtil::findCommand("import/unzip", "unzip");  
62 - if (empty($sUnzipCommand)) {  
63 - return PEAR::raiseError(_kt("unzip command not found on system"));  
64 - }  
65 - $aArgs = array(  
66 - $sUnzipCommand,  
67 - "-q", "-n",  
68 - "-d", $sTmpPath,  
69 - $this->sZipPath,  
70 - );  
71 - $aRes = KTUtil::pexec($aArgs);  
72 -  
73 - if ($aRes['ret'] !== 0) {  
74 - return PEAR::raiseError(_kt("Could not retrieve contents from zip storage")); 118 +
  119 + // File Archive doesn't unzip properly so sticking to the original unzip functionality
  120 + if($this->sExtension == 'zip'){
  121 + // ** Original zip functionality
  122 + $sUnzipCommand = KTUtil::findCommand("import/unzip", "unzip");
  123 + if (empty($sUnzipCommand)) {
  124 + return PEAR::raiseError(_kt("unzip command not found on system"));
  125 + }
  126 + $aArgs = array(
  127 + $sUnzipCommand,
  128 + "-q", "-n",
  129 + "-d", $sTmpPath,
  130 + $this->sZipPath,
  131 + );
  132 + $aRes = KTUtil::pexec($aArgs);
  133 +
  134 + if ($aRes['ret'] !== 0) {
  135 + return PEAR::raiseError(_kt("Could not retrieve contents from zip storage"));
  136 + }
  137 + }else{
  138 + File_Archive::extract(
  139 + File_Archive::readArchive(
  140 + $this->sExtension, File_Archive::readUploadedFile('file')
  141 + ),
  142 + $dst = $sTmpPath
  143 + );
75 } 144 }
76 } 145 }
77 146
@@ -83,4 +152,4 @@ class KTZipImportStorage extends KTFSImportStorage { @@ -83,4 +152,4 @@ class KTZipImportStorage extends KTFSImportStorage {
83 } 152 }
84 } 153 }
85 154
86 -?> 155 -?>
  156 +?>
87 \ No newline at end of file 157 \ No newline at end of file
lib/permissions/permissionutil.inc.php
@@ -647,6 +647,9 @@ class KTPermissionUtil { @@ -647,6 +647,9 @@ class KTPermissionUtil {
647 */ 647 */
648 function inheritPermissionObject(&$oDocumentOrFolder, $aOptions = null) { 648 function inheritPermissionObject(&$oDocumentOrFolder, $aOptions = null) {
649 global $default; 649 global $default;
  650 +
  651 + $oDocumentOrFolder->cacheGlobal=array();
  652 +
650 $bEvenIfNotOwner = KTUtil::arrayGet($aOptions, 'evenifnotowner'); 653 $bEvenIfNotOwner = KTUtil::arrayGet($aOptions, 'evenifnotowner');
651 if (empty($bEvenIfNotOwner) && !KTPermissionUtil::isPermissionOwner($oDocumentOrFolder)) { 654 if (empty($bEvenIfNotOwner) && !KTPermissionUtil::isPermissionOwner($oDocumentOrFolder)) {
652 return PEAR::raiseError(_kt("Document or Folder doesn't own its permission object")); 655 return PEAR::raiseError(_kt("Document or Folder doesn't own its permission object"));
plugins/housekeeper/HouseKeeperPlugin.php
@@ -35,6 +35,9 @@ @@ -35,6 +35,9 @@
35 * Contributor( s): ______________________________________ 35 * Contributor( s): ______________________________________
36 */ 36 */
37 37
  38 +require_once(KT_LIB_DIR . '/plugins/plugin.inc.php');
  39 +require_once(KT_LIB_DIR . '/plugins/pluginregistry.inc.php');
  40 +
38 class HouseKeeperPlugin extends KTPlugin 41 class HouseKeeperPlugin extends KTPlugin
39 { 42 {
40 var $autoRegister = true; 43 var $autoRegister = true;
@@ -49,8 +52,16 @@ class HouseKeeperPlugin extends KTPlugin @@ -49,8 +52,16 @@ class HouseKeeperPlugin extends KTPlugin
49 $this->sFriendlyName = _kt('Housekeeper'); 52 $this->sFriendlyName = _kt('Housekeeper');
50 53
51 $config = KTConfig::getSingleton(); 54 $config = KTConfig::getSingleton();
52 - $tempDir = $config->get('urls/tmpDirectory');  
53 $cacheDir = $config->get('cache/cacheDirectory'); 55 $cacheDir = $config->get('cache/cacheDirectory');
  56 + $cacheFile = $cacheDir . '/houseKeeper.folders';
  57 +
  58 + if (is_file($cacheFile))
  59 + {
  60 + $this->folders = unserialize(file_get_contents($cacheFile));
  61 + return;
  62 + }
  63 +
  64 + $tempDir = $config->get('urls/tmpDirectory');
54 $logDir = $config->get('urls/logDirectory'); 65 $logDir = $config->get('urls/logDirectory');
55 $docsDir = $config->get('urls/documentRoot'); 66 $docsDir = $config->get('urls/documentRoot');
56 67
@@ -107,8 +118,13 @@ class HouseKeeperPlugin extends KTPlugin @@ -107,8 +118,13 @@ class HouseKeeperPlugin extends KTPlugin
107 'pattern'=>'', 118 'pattern'=>'',
108 'canClean'=>false 119 'canClean'=>false
109 ); 120 );
  121 +
  122 + // lets only cache this once it has been resolved!
  123 + file_put_contents($cacheFile, serialize($this->folders));
110 } 124 }
111 125
  126 +
  127 +
112 } 128 }
113 129
114 function getDirectories() 130 function getDirectories()
plugins/ktcore/folder/BulkUpload.php
@@ -115,16 +115,6 @@ class KTBulkUploadFolderAction extends KTFolderAction { @@ -115,16 +115,6 @@ class KTBulkUploadFolderAction extends KTFolderAction {
115 unset($aErrorOptions['message']); 115 unset($aErrorOptions['message']);
116 $aFile = $this->oValidator->validateFile($_FILES['file'], $aErrorOptions); 116 $aFile = $this->oValidator->validateFile($_FILES['file'], $aErrorOptions);
117 117
118 - // Ensure file is a zip file  
119 - $sMime = $aFile['type'];  
120 - $pos = strpos($sMime, 'x-zip-compressed');  
121 - $pos2 = strpos($sMime, 'application/zip');  
122 - if($pos === false && $pos2 === false){  
123 - $this->addErrorMessage(_kt("Bulk Upload failed: File is not a zip file."));  
124 - controllerRedirect("browse", 'fFolderId=' . $this->oFolder->getID());  
125 - exit(0);  
126 - }  
127 -  
128 $matches = array(); 118 $matches = array();
129 $aFields = array(); 119 $aFields = array();
130 foreach ($_REQUEST as $k => $v) { 120 foreach ($_REQUEST as $k => $v) {
@@ -138,7 +128,14 @@ class KTBulkUploadFolderAction extends KTFolderAction { @@ -138,7 +128,14 @@ class KTBulkUploadFolderAction extends KTFolderAction {
138 'metadata' => $aFields, 128 'metadata' => $aFields,
139 ); 129 );
140 130
141 - $fs =& new KTZipImportStorage($aFile['tmp_name']); 131 + $fs =& new KTZipImportStorage('file');
  132 + if(!$fs->CheckFormat()){
  133 + $sFormats = $fs->getFormats();
  134 + $this->addErrorMessage(_kt("Bulk Upload failed. Archive is not an accepted format. Accepted formats are: ".$sFormats));
  135 + controllerRedirect("browse", 'fFolderId=' . $this->oFolder->getID());
  136 + exit;
  137 + }
  138 +
142 $bm =& new KTBulkImportManager($this->oFolder, $fs, $this->oUser, $aOptions); 139 $bm =& new KTBulkImportManager($this->oFolder, $fs, $this->oUser, $aOptions);
143 $this->startTransaction(); 140 $this->startTransaction();
144 $res = $bm->import(); 141 $res = $bm->import();
@@ -152,3 +149,4 @@ class KTBulkUploadFolderAction extends KTFolderAction { @@ -152,3 +149,4 @@ class KTBulkUploadFolderAction extends KTFolderAction {
152 exit(0); 149 exit(0);
153 } 150 }
154 } 151 }
  152 +?>
155 \ No newline at end of file 153 \ No newline at end of file
plugins/ktstandard/KTSubscriptions.php
@@ -267,7 +267,7 @@ class KTDeleteSubscriptionTrigger { @@ -267,7 +267,7 @@ class KTDeleteSubscriptionTrigger {
267 // fire subscription alerts for the checked in document 267 // fire subscription alerts for the checked in document
268 $oSubscriptionEvent = new SubscriptionEvent(); 268 $oSubscriptionEvent = new SubscriptionEvent();
269 $oFolder = Folder::get($oDocument->getFolderID()); 269 $oFolder = Folder::get($oDocument->getFolderID());
270 - $oSubscriptionEvent->RemoveDocument($oDocument, $oFolder); 270 + // $oSubscriptionEvent->RemoveDocument($oDocument, $oFolder);
271 } 271 }
272 } 272 }
273 // }}} 273 // }}}
resources/css/errors.css
1 div#error-container { 1 div#error-container {
2 - width: 500px; 2 + border:1px solid gray;
3 color: #555; 3 color: #555;
4 font-size: 11px; 4 font-size: 11px;
5 font-family: Verdana, Arial, sans-serif; 5 font-family: Verdana, Arial, sans-serif;
  6 + margin:2em auto;
  7 + padding:10px;
  8 + width:470px;
6 } 9 }
7 div#error-container div { 10 div#error-container div {
8 - height: 140px; 11 + height: 150px;
9 } 12 }
10 div#error-container h1 { 13 div#error-container h1 {
11 font-weight: lighter; 14 font-weight: lighter;
resources/js/loader.js
@@ -30,8 +30,10 @@ window.onload = function() @@ -30,8 +30,10 @@ window.onload = function()
30 } 30 }
31 31
32 window.onsubmit = function(){ 32 window.onsubmit = function(){
33 - var myElem = document.getElementById("modalDiv");  
34 - myElem.style.display = "block"; 33 + if(typeof disable_loader == "undefined"){
  34 + var myElem = document.getElementById("modalDiv");
  35 + myElem.style.display = "block";
  36 + }
35 } 37 }
36 function Loader() 38 function Loader()
37 { 39 {
search2/indexing/indexerCore.inc.php
@@ -74,6 +74,7 @@ class QueryResultItem @@ -74,6 +74,7 @@ class QueryResultItem
74 protected $documentType; 74 protected $documentType;
75 protected $mimeIconPath; 75 protected $mimeIconPath;
76 protected $mimeDisplay; 76 protected $mimeDisplay;
  77 + protected $oemDocumentNo;
77 78
78 public function __construct($document_id, $rank=null, $title=null, $text=null) 79 public function __construct($document_id, $rank=null, $title=null, $text=null)
79 { 80 {
@@ -108,7 +109,7 @@ class QueryResultItem @@ -108,7 +109,7 @@ class QueryResultItem
108 dcv.minor_version, dcv.filename, cou.name as checkoutuser, w.human_name as workflow, ws.human_name as workflowstate, 109 dcv.minor_version, dcv.filename, cou.name as checkoutuser, w.human_name as workflow, ws.human_name as workflowstate,
109 mt.mimetypes as mimetype, md.mime_doc as mimedoc, d.checkedout, mbu.name as modifiedbyuser, d.modified, 110 mt.mimetypes as mimetype, md.mime_doc as mimedoc, d.checkedout, mbu.name as modifiedbyuser, d.modified,
110 cbu.name as createdbyuser, ou.name as owneruser, d.immutable, d.status_id, d.created,dcv.storage_path, dtl.name as document_type, 111 cbu.name as createdbyuser, ou.name as owneruser, d.immutable, d.status_id, d.created,dcv.storage_path, dtl.name as document_type,
111 - mt.icon_path as mime_icon_path, mt.friendly_name as mime_display 112 + mt.icon_path as mime_icon_path, mt.friendly_name as mime_display, d.oem_no
112 FROM 113 FROM
113 documents d 114 documents d
114 INNER JOIN document_metadata_version dmv ON d.metadata_version_id = dmv.id 115 INNER JOIN document_metadata_version dmv ON d.metadata_version_id = dmv.id
@@ -168,6 +169,9 @@ class QueryResultItem @@ -168,6 +169,9 @@ class QueryResultItem
168 $this->workflow = $result['workflow']; 169 $this->workflow = $result['workflow'];
169 $this->workflowState = $result['workflowstate']; 170 $this->workflowState = $result['workflowstate'];
170 171
  172 + $this->oemDocumentNo = $result['oem_no'];
  173 + if (empty($this->oemDocumentNo)) $this->oemDocumentNo = 'n/a';
  174 +
171 if (is_null($result['name'])) 175 if (is_null($result['name']))
172 { 176 {
173 $this->fullpath = '(orphaned)'; 177 $this->fullpath = '(orphaned)';
@@ -202,6 +206,7 @@ class QueryResultItem @@ -202,6 +206,7 @@ class QueryResultItem
202 case 'Version': return (string) $this->version; 206 case 'Version': return (string) $this->version;
203 case 'Filename': return (string)$this->filename; 207 case 'Filename': return (string)$this->filename;
204 case 'FolderId': return (int)$this->folderId; 208 case 'FolderId': return (int)$this->folderId;
  209 + case 'OemDocumentNo': return (string) $this->oemDocumentNo;
205 case 'Document': 210 case 'Document':
206 if (is_null($this->document)) 211 if (is_null($this->document))
207 { 212 {
search2/search/fields/DocumentOemNoField.inc.php 0 โ†’ 100644
  1 +<?php
  2 +
  3 +/**
  4 + * $Id:$
  5 + *
  6 + * KnowledgeTree Open Source Edition
  7 + * Document Management Made Simple
  8 + * Copyright (C) 2004 - 2007 The Jam Warehouse Software (Pty) Limited
  9 + *
  10 + * This program is free software; you can redistribute it and/or modify it under
  11 + * the terms of the GNU General Public License version 3 as published by the
  12 + * Free Software Foundation.
  13 + *
  14 + * This program is distributed in the hope that it will be useful, but WITHOUT
  15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  17 + * details.
  18 + *
  19 + * You should have received a copy of the GNU General Public License
  20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21 + *
  22 + * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place,
  23 + * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com.
  24 + *
  25 + * The interactive user interfaces in modified source and object code versions
  26 + * of this program must display Appropriate Legal Notices, as required under
  27 + * Section 5 of the GNU General Public License version 3.
  28 + *
  29 + * In accordance with Section 7(b) of the GNU General Public License version 3,
  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
  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
  34 + * copyright notice.
  35 + * Contributor( s): ______________________________________
  36 + *
  37 + */
  38 +
  39 +class DocumentOemNoField extends DBFieldExpr
  40 +{
  41 + public function __construct()
  42 + {
  43 + parent::__construct('oem_no', 'documents', _kt('Integration Id'));
  44 + $this->setAlias('IntegrationId');
  45 + }
  46 +
  47 + public function getInputRequirements()
  48 + {
  49 + return array('value'=>array('type'=>FieldInputType::INT ));
  50 + }
  51 +
  52 + public function is_valid()
  53 + {
  54 + return DefaultOpCollection::validateParent($this, DefaultOpCollection::$is);
  55 + }
  56 +}
  57 +
  58 +?>
0 \ No newline at end of file 59 \ No newline at end of file
search2/search/search.inc.php
@@ -556,7 +556,7 @@ function processSearchExpression($query) @@ -556,7 +556,7 @@ function processSearchExpression($query)
556 'document_id' => (int) $hit->DocumentID, 556 'document_id' => (int) $hit->DocumentID,
557 557
558 'custom_document_no' => 'n/a', 558 'custom_document_no' => 'n/a',
559 - 'oem_document_no' => 'n/a', 559 + 'oem_document_no' => (string) $hit->OemDocumentNo,
560 560
561 'relevance' => (float) $hit->Rank, 561 'relevance' => (float) $hit->Rank,
562 'text' => (string) $noText?'':$hit->Text, 562 'text' => (string) $noText?'':$hit->Text,
sql/mysql/install/structure.sql
@@ -557,6 +557,7 @@ CREATE TABLE `documents` ( @@ -557,6 +557,7 @@ CREATE TABLE `documents` (
557 `restore_folder_id` int(11) default NULL, 557 `restore_folder_id` int(11) default NULL,
558 `restore_folder_path` text, 558 `restore_folder_path` text,
559 `checkedout` datetime default NULL, 559 `checkedout` datetime default NULL,
  560 + `oem_no` varchar(255) default NULL,
560 PRIMARY KEY (`id`), 561 PRIMARY KEY (`id`),
561 KEY `creator_id` (`creator_id`), 562 KEY `creator_id` (`creator_id`),
562 KEY `folder_id` (`folder_id`), 563 KEY `folder_id` (`folder_id`),
@@ -571,6 +572,7 @@ CREATE TABLE `documents` ( @@ -571,6 +572,7 @@ CREATE TABLE `documents` (
571 KEY `full_path` (`full_path`(255)), 572 KEY `full_path` (`full_path`(255)),
572 KEY `immutable` (`immutable`), 573 KEY `immutable` (`immutable`),
573 KEY `checkedout` (`checkedout`), 574 KEY `checkedout` (`checkedout`),
  575 + KEY `oem_no` (`oem_no`),
574 CONSTRAINT `documents_ibfk_1` FOREIGN KEY (`creator_id`) REFERENCES `users` (`id`) ON DELETE SET NULL ON UPDATE SET NULL, 576 CONSTRAINT `documents_ibfk_1` FOREIGN KEY (`creator_id`) REFERENCES `users` (`id`) ON DELETE SET NULL ON UPDATE SET NULL,
575 CONSTRAINT `documents_ibfk_2` FOREIGN KEY (`folder_id`) REFERENCES `folders` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, 577 CONSTRAINT `documents_ibfk_2` FOREIGN KEY (`folder_id`) REFERENCES `folders` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
576 CONSTRAINT `documents_ibfk_3` FOREIGN KEY (`checked_out_user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL ON UPDATE SET NULL, 578 CONSTRAINT `documents_ibfk_3` FOREIGN KEY (`checked_out_user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL ON UPDATE SET NULL,
sql/mysql/upgrade/3.5.2/oem_no.sql 0 โ†’ 100644
  1 +ALTER TABLE documents ADD oem_no varchar(255) NULL, ADD INDEX (oem_no);
0 \ No newline at end of file 2 \ No newline at end of file
templates/ktstandard/PDFPlugin/PDFPlugin.smarty
  1 +{literal}
  2 +<script type="text/javascript">
  3 + var disable_loader = true;
  4 +</script>
  5 +{/literal}
  6 +
1 <h2><img src="{if $config->get("ui/morphEnabled") == '1'}{$rootUrl}/skins/kts_{$config->get("ui/morphTo")}/title_bullet.png{else}{$rootUrl}/resources/graphics/title_bullet.png{/if}"/>{i18n}Generate PDF of{/i18n}:<br />{$context->oDocument->getName()|sanitize}</h2> 7 <h2><img src="{if $config->get("ui/morphEnabled") == '1'}{$rootUrl}/skins/kts_{$config->get("ui/morphTo")}/title_bullet.png{else}{$rootUrl}/resources/graphics/title_bullet.png{/if}"/>{i18n}Generate PDF of{/i18n}:<br />{$context->oDocument->getName()|sanitize}</h2>
2 8
3 {$form->render()} 9 {$form->render()}
thirdparty/pear/File/Archive.php 0 โ†’ 100644
  1 +<?php
  2 +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3 +
  4 +/**
  5 + * Factory to access the most common File_Archive features
  6 + * It uses lazy include, so you dont have to include the files from
  7 + * File/Archive/* directories
  8 + *
  9 + * PHP versions 4 and 5
  10 + *
  11 + * This library is free software; you can redistribute it and/or
  12 + * modify it under the terms of the GNU Lesser General Public
  13 + * License as published by the Free Software Foundation; either
  14 + * version 2.1 of the License, or (at your option) any later version.
  15 + *
  16 + * This library is distributed in the hope that it will be useful,
  17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19 + * Lesser General Public License for more details.
  20 + *
  21 + * You should have received a copy of the GNU Lesser General Public
  22 + * License along with this library; if not, write to the Free Software
  23 + * Foundation, Inc., 59 Temple Place, Suite 330,Boston,MA 02111-1307 USA
  24 + *
  25 + * @category File Formats
  26 + * @package File_Archive
  27 + * @author Vincent Lascaux <vincentlascaux@php.net>
  28 + * @copyright 1997-2005 The PHP Group
  29 + * @license http://www.gnu.org/copyleft/lesser.html LGPL
  30 + * @version CVS: $Id: Archive.php,v 1.85 2005/08/16 08:48:59 vincentlascaux Exp $
  31 + * @link http://pear.php.net/package/File_Archive
  32 + */
  33 +
  34 +/**
  35 + * To have access to PEAR::isError and PEAR::raiseError
  36 + * We should probably use lazy include and remove this inclusion...
  37 + */
  38 +require_once "PEAR.php";
  39 +
  40 +function File_Archive_cleanCache($file, $group)
  41 +{
  42 + $file = split('_', $file);
  43 + if (count($file) != 3) {
  44 + return false; //not a File_Archive file, keep it
  45 + }
  46 +
  47 + $name = $file[2];
  48 + $name = urldecode($name);
  49 +
  50 + $group = $file[1];
  51 +
  52 + //clean the cache only for files in File_Archive groups
  53 + return substr($group, 0, 11) == 'FileArchive' &&
  54 + !file_exists($name); //and only if the related file no longer exists
  55 +}
  56 +
  57 +/**
  58 + * Factory to access the most common File_Archive features
  59 + * It uses lazy include, so you dont have to include the files from
  60 + * File/Archive/* directories
  61 + */
  62 +class File_Archive
  63 +{
  64 + function& _option($name)
  65 + {
  66 + static $container = array(
  67 + 'zipCompressionLevel' => 9,
  68 + 'gzCompressionLevel' => 9,
  69 + 'tmpDirectory' => '.',
  70 + 'cache' => null,
  71 + 'appendRemoveDuplicates' => false,
  72 + 'blockSize' => 65536,
  73 + 'cacheCondition' => false
  74 + );
  75 + return $container[$name];
  76 + }
  77 + /**
  78 + * Sets an option that will be used by default by all readers or writers
  79 + * Option names are case sensitive
  80 + * Currently, the following options are used:
  81 + *
  82 + * "cache"
  83 + * Instance of a Cache_Lite object used to cache some compressed
  84 + * data to speed up future compressions of files
  85 + * Default: null (no cache used)
  86 + *
  87 + * "zipCompressionLevel"
  88 + * Value between 0 and 9 specifying the default compression level used
  89 + * by Zip writers (0 no compression, 9 highest compression)
  90 + * Default: 9
  91 + *
  92 + * "gzCompressionLevel"
  93 + * Value between 0 and 9 specifying the default compression level used
  94 + * by Gz writers (0 no compression, 9 highest compression)
  95 + * Default: 9
  96 + *
  97 + * "tmpDirectory"
  98 + * Directory where the temporary files generated by File_Archive will
  99 + * be created
  100 + * Default: '.'
  101 + *
  102 + * "appendRemoveDuplicates"
  103 + * If set to true, the appender created will by default remove the
  104 + * file present in the archive when adding a new one. This will slow the
  105 + * appending of files to archives
  106 + * Default: false
  107 + *
  108 + * "blockSize"
  109 + * To transfer data from a reader to a writer, some chunks a read from the
  110 + * source and written to the writer. This parameter controls the size of the
  111 + * chunks
  112 + * Default: 64kB
  113 + *
  114 + * "cacheCondition"
  115 + * This parameter specifies when a cache should be used. When the cache is
  116 + * used, the data of the reader is saved in a temporary file for future access.
  117 + * The cached reader will be read only once, even if you read it several times.
  118 + * This can be usefull to read compressed files or downloaded files (from http or ftp)
  119 + * The possible values for this option are
  120 + * - false: never use cache
  121 + * - a regexp: A cache will be used if the specified URL matches the regexp
  122 + * preg_match is used
  123 + * Default: false
  124 + * Example: '/^(http|ftp):\/\//' will cache all files downloaded via http or ftp
  125 + *
  126 + */
  127 + function setOption($name, $value)
  128 + {
  129 + $option =& File_Archive::_option($name);
  130 + $option = $value;
  131 + if ($name == 'cache' && $value !== null) {
  132 + //TODO: ask to Cache_Lite to allow that
  133 + $value->_fileNameProtection = false;
  134 + }
  135 + }
  136 +
  137 + /**
  138 + * Retrieve the value of an option
  139 + */
  140 + function getOption($name)
  141 + {
  142 + return File_Archive::_option($name);
  143 + }
  144 +
  145 + /**
  146 + * Create a reader to read the URL $URL.
  147 + * If the URL is a directory, it will recursively read that directory.
  148 + * If $uncompressionLevel is not null, the archives (files with extension
  149 + * tar, zip, gz or tgz) will be considered as directories (up to a depth of
  150 + * $uncompressionLevel if $uncompressionLevel > 0). The reader will only
  151 + * read files with a directory depth of $directoryDepth. It reader will
  152 + * replace the given URL ($URL) with $symbolic in the public filenames
  153 + * The default symbolic name is the last filename in the URL (or '' for
  154 + * directories)
  155 + *
  156 + * Examples:
  157 + * Considere the following file system
  158 + * <pre>
  159 + * a.txt
  160 + * b.tar (archive that contains the following files)
  161 + * c.txt
  162 + * d.tgz (archive that contains the following files)
  163 + * e.txt
  164 + * dir1/
  165 + * f.txt
  166 + * dir2/
  167 + * g.txt
  168 + * dir3/
  169 + * h.tar (archive that contains the following files)
  170 + * i.txt
  171 + * </pre>
  172 + *
  173 + * read('.') will return a reader that gives access to following
  174 + * files (recursively read current dir):
  175 + * <pre>
  176 + * a.txt
  177 + * b.tar
  178 + * dir2/g.txt
  179 + * dir2/dir3/h.tar
  180 + * </pre>
  181 + *
  182 + * read('.', 'myBaseDir') will return the following reader:
  183 + * <pre>
  184 + * myBaseDir/a.txt
  185 + * myBaseDir/b.tar
  186 + * myBaseDir/dir2/g.txt
  187 + * myBaseDir/dir2/dir3/h.tar
  188 + * </pre>
  189 + *
  190 + * read('.', '', -1) will return the following reader (uncompress
  191 + * everything)
  192 + * <pre>
  193 + * a.txt
  194 + * b.tar/c.txt
  195 + * b.tar/d.tgz/e.txt
  196 + * b.tar/d.tgz/dir1/f.txt
  197 + * dir2/g.txt
  198 + * dir2/dir3/h.tar/i.txt
  199 + * </pre>
  200 + *
  201 + * read('.', '', 1) will uncompress only one level (so d.tgz will
  202 + * not be uncompressed):
  203 + * <pre>
  204 + * a.txt
  205 + * b.tar/c.txt
  206 + * b.tar/d.tgz
  207 + * dir2/g.txt
  208 + * dir2/dir3/h.tar/i.txt
  209 + * </pre>
  210 + *
  211 + * read('.', '', 0, 0) will not recurse into subdirectories
  212 + * <pre>
  213 + * a.txt
  214 + * b.tar
  215 + * </pre>
  216 + *
  217 + * read('.', '', 0, 1) will recurse only one level in
  218 + * subdirectories
  219 + * <pre>
  220 + * a.txt
  221 + * b.tar
  222 + * dir2/g.txt
  223 + * </pre>
  224 + *
  225 + * read('.', '', -1, 2) will uncompress everything and recurse in
  226 + * only 2 levels in subdirectories or archives
  227 + * <pre>
  228 + * a.txt
  229 + * b.tar/c.txt
  230 + * b.tar/d.tgz/e.txt
  231 + * dir2/g.txt
  232 + * </pre>
  233 + *
  234 + * The recursion level is determined by the real path, not the symbolic one.
  235 + * So read('.', 'myBaseDir', -1, 2) will result to the same files:
  236 + * <pre>
  237 + * myBaseDir/a.txt
  238 + * myBaseDir/b.tar/c.txt
  239 + * myBaseDir/b.tar/d.tgz/e.txt (accepted because the real depth is 2)
  240 + * myBaseDir/dir2/g.txt
  241 + * </pre>
  242 + *
  243 + * Use readSource to do the same thing, reading from a specified reader instead of
  244 + * reading from the system files
  245 + *
  246 + * To read a single file, you can do read('a.txt', 'public_name.txt')
  247 + * If no public name is provided, the default one is the name of the file
  248 + * read('dir2/g.txt') contains the single file named 'g.txt'
  249 + * read('b.tar/c.txt') contains the single file named 'c.txt'
  250 + *
  251 + * Note: This function uncompress files reading their extension
  252 + * The compressed files must have a tar, zip, gz or tgz extension
  253 + * Since it is impossible for some URLs to use is_dir or is_file, this
  254 + * function may not work with
  255 + * URLs containing folders which name ends with such an extension
  256 + */
  257 + function readSource(&$source, $URL, $symbolic = null,
  258 + $uncompression = 0, $directoryDepth = -1)
  259 + {
  260 + return File_Archive::_readSource($source, $URL, $reachable, $baseDir,
  261 + $symbolic, $uncompression, $directoryDepth);
  262 + }
  263 +
  264 + /**
  265 + * This function performs exactly as readSource, but with two additional parameters
  266 + * ($reachable and $baseDir) that will be set so that $reachable."/".$baseDir == $URL
  267 + * and $reachable can be reached (in case of error)
  268 + *
  269 + * @access private
  270 + */
  271 + function _readSource(&$toConvert, $URL, &$reachable, &$baseDir, $symbolic = null,
  272 + $uncompression = 0, $directoryDepth = -1)
  273 + {
  274 + $source =& File_Archive::_convertToReader($toConvert);
  275 + if (PEAR::isError($source)) {
  276 + return $source;
  277 + }
  278 + if (is_array($URL)) {
  279 + $converted = array();
  280 + foreach($URL as $key => $foo) {
  281 + $converted[] =& File_Archive::_convertToReader($URL[$key]);
  282 + }
  283 + return File_Archive::readMulti($converted);
  284 + }
  285 +
  286 + //No need to uncompress more than $directoryDepth
  287 + //That's not perfect, and some archives will still be uncompressed just
  288 + //to be filtered out :(
  289 + if ($directoryDepth >= 0) {
  290 + $uncompressionLevel = min($uncompression, $directoryDepth);
  291 + } else {
  292 + $uncompressionLevel = $uncompression;
  293 + }
  294 +
  295 + require_once 'File/Archive/Reader.php';
  296 + $std = File_Archive_Reader::getStandardURL($URL);
  297 +
  298 + //Modify the symbolic name if necessary
  299 + $slashPos = strrpos($std, '/');
  300 + if ($symbolic === null) {
  301 + if ($slashPos === false) {
  302 + $realSymbolic = $std;
  303 + } else {
  304 + $realSymbolic = substr($std, $slashPos+1);
  305 + }
  306 + } else {
  307 + $realSymbolic = $symbolic;
  308 + }
  309 + if ($slashPos !== false) {
  310 + $baseFile = substr($std, 0, $slashPos+1);
  311 + $lastFile = substr($std, $slashPos+1);
  312 + } else {
  313 + $baseFile = '';
  314 + $lastFile = $std;
  315 + }
  316 +
  317 + if (strpos($lastFile, '*')!==false ||
  318 + strpos($lastFile, '?')!==false) {
  319 + //We have to build a regexp here
  320 + $regexp = str_replace(
  321 + array('\*', '\?'),
  322 + array('[^/]*', '[^/]'),
  323 + preg_quote($lastFile)
  324 + );
  325 + $result = File_Archive::_readSource($source, $baseFile,
  326 + $reachable, $baseDir, null, 0, -1);
  327 + return File_Archive::filter(
  328 + File_Archive::predEreg('^'.$regexp.'$'),
  329 + $result
  330 + );
  331 + }
  332 +
  333 + //If the URL can be interpreted as a directory, and we are reading from the file system
  334 + if ((empty($URL) || is_dir($URL)) && $source === null) {
  335 + require_once "File/Archive/Reader/Directory.php";
  336 + require_once "File/Archive/Reader/ChangeName.php";
  337 +
  338 + if ($uncompressionLevel != 0) {
  339 + require_once "File/Archive/Reader/Uncompress.php";
  340 + $result = new File_Archive_Reader_Uncompress(
  341 + new File_Archive_Reader_Directory($std, '', $directoryDepth),
  342 + $uncompressionLevel
  343 + );
  344 + } else {
  345 + $result = new File_Archive_Reader_Directory($std, '', $directoryDepth);
  346 + }
  347 +
  348 + if ($directoryDepth >= 0) {
  349 + require_once 'File/Archive/Reader/Filter.php';
  350 + require_once 'File/Archive/Predicate/MaxDepth.php';
  351 +
  352 + $tmp =& File_Archive::filter(
  353 + new File_Archive_Predicate_MaxDepth($directoryDepth),
  354 + $result
  355 + );
  356 + unset($result);
  357 + $result =& $tmp;
  358 + }
  359 + if (!empty($realSymbolic)) {
  360 + if ($symbolic === null) {
  361 + $realSymbolic = '';
  362 + }
  363 + $tmp =& new File_Archive_Reader_AddBaseName(
  364 + $realSymbolic,
  365 + $result
  366 + );
  367 + unset($result);
  368 + $result =& $tmp;
  369 + }
  370 +
  371 + //If the URL can be interpreted as a file, and we are reading from the file system
  372 + } else if (is_file($URL) && substr($URL, -1)!='/' && $source === null) {
  373 + require_once "File/Archive/Reader/File.php";
  374 + $result = new File_Archive_Reader_File($URL, $realSymbolic);
  375 +
  376 + //Else, we will have to build a complex reader
  377 + } else {
  378 + require_once "File/Archive/Reader/File.php";
  379 +
  380 + $realPath = $std;
  381 +
  382 + // Try to find a file with a known extension in the path (
  383 + // (to manage URLs like archive.tar/directory/file)
  384 + $pos = 0;
  385 + do {
  386 + if ($pos+1<strlen($realPath)) {
  387 + $pos = strpos($realPath, '/', $pos+1);
  388 + } else {
  389 + $pos = false;
  390 + }
  391 + if ($pos === false) {
  392 + $pos = strlen($realPath);
  393 + }
  394 +
  395 + $file = substr($realPath, 0, $pos);
  396 + $baseDir = substr($realPath, $pos+1);
  397 + $dotPos = strrpos($file, '.');
  398 + $extension = '';
  399 + if ($dotPos !== false) {
  400 + $extension = substr($file, $dotPos+1);
  401 + }
  402 + } while ($pos < strlen($realPath) &&
  403 + (!File_Archive::isKnownExtension($extension) ||
  404 + (is_dir($file) && $source==null)));
  405 +
  406 + $reachable = $file;
  407 +
  408 + //If we are reading from the file system
  409 + if ($source === null) {
  410 + //Create a file reader
  411 + $result = new File_Archive_Reader_File($file);
  412 + } else {
  413 + //Select in the source the file $file
  414 +
  415 + require_once "File/Archive/Reader/Select.php";
  416 + $result = new File_Archive_Reader_Select($file, $source);
  417 + }
  418 +
  419 + require_once "File/Archive/Reader/Uncompress.php";
  420 + $tmp = new File_Archive_Reader_Uncompress($result, $uncompressionLevel);
  421 + unset($result);
  422 + $result = $tmp;
  423 +
  424 + //Select the requested folder in the uncompress reader
  425 + $isDir = $result->setBaseDir($std);
  426 + if (PEAR::isError($isDir)) {
  427 + return $isDir;
  428 + }
  429 + if ($isDir && $symbolic==null) {
  430 + //Default symbolic name for directories is empty
  431 + $realSymbolic = '';
  432 + }
  433 +
  434 + if ($directoryDepth >= 0) {
  435 + //Limit the maximum depth if necessary
  436 + require_once "File/Archive/Predicate/MaxDepth.php";
  437 +
  438 + $tmp = new File_Archive_Reader_Filter(
  439 + new File_Archive_Predicate(
  440 + $directoryDepth +
  441 + substr_count(substr($std, $pos+1), '/')
  442 + ),
  443 + $result
  444 + );
  445 + unset($result);
  446 + $result =& $tmp;
  447 + }
  448 +
  449 + if ($std != $realSymbolic) {
  450 + require_once "File/Archive/Reader/ChangeName.php";
  451 +
  452 + //Change the base name to the symbolic one if necessary
  453 + $tmp = new File_Archive_Reader_ChangeBaseName(
  454 + $std,
  455 + $realSymbolic,
  456 + $result
  457 + );
  458 + unset($result);
  459 + $result =& $tmp;
  460 + }
  461 + }
  462 +
  463 + $cacheCondition = File_Archive::getOption('cacheCondition');
  464 + if ($cacheCondition !== false &&
  465 + preg_match($cacheCondition, $URL)) {
  466 + $tmp =& File_Archive::cache($result);
  467 + unset($result);
  468 + $result =& $tmp;
  469 + }
  470 +
  471 + return $result;
  472 + }
  473 + function read($URL, $symbolic = null,
  474 + $uncompression = 0, $directoryDepth = -1)
  475 + {
  476 + $source = null;
  477 + return File_Archive::readSource($source, $URL, $symbolic, $uncompression, $directoryDepth);
  478 + }
  479 +
  480 + /**
  481 + * Create a file reader on an uploaded file. The reader will read
  482 + * $_FILES[$name]['tmp_name'] and will have $_FILES[$name]['name']
  483 + * as a symbolic filename.
  484 + *
  485 + * A PEAR error is returned if one of the following happen
  486 + * - $_FILES[$name] is not set
  487 + * - $_FILES[$name]['error'] is not 0
  488 + * - is_uploaded_file returns false
  489 + *
  490 + * @param string $name Index of the file in the $_FILES array
  491 + * @return File_Archive_Reader File reader on the uploaded file
  492 + */
  493 + function readUploadedFile($name)
  494 + {
  495 + if (!isset($_FILES[$name])) {
  496 + return PEAR::raiseError("File $name has not been uploaded");
  497 + }
  498 + switch ($_FILES[$name]['error']) {
  499 + case 0:
  500 + //No error
  501 + break;
  502 + case 1:
  503 + return PEAR::raiseError(
  504 + "The upload size limit didn't allow to upload file ".
  505 + $_FILES[$name]['name']
  506 + );
  507 + case 2:
  508 + return PEAR::raiseError(
  509 + "The form size limit didn't allow to upload file ".
  510 + $_FILES[$name]['name']
  511 + );
  512 + case 3:
  513 + return PEAR::raiseError(
  514 + "The file was not entirely uploaded"
  515 + );
  516 + case 4:
  517 + return PEAR::raiseError(
  518 + "The uploaded file is empty"
  519 + );
  520 + default:
  521 + return PEAR::raiseError(
  522 + "Unknown error ".$_FILES[$name]['error']." in file upload. ".
  523 + "Please, report a bug"
  524 + );
  525 + }
  526 + if (!is_uploaded_file($_FILES[$name]['tmp_name'])) {
  527 + return PEAR::raiseError("The file is not an uploaded file");
  528 + }
  529 +
  530 + require_once "File/Archive/Reader/File.php";
  531 + return new File_Archive_Reader_File(
  532 + $_FILES[$name]['tmp_name'],
  533 + $_FILES[$name]['name'],
  534 + $_FILES[$name]['type']
  535 + );
  536 + }
  537 +
  538 + /**
  539 + * Adds a cache layer above the specified reader
  540 + * The data of the reader is saved in a temporary file for future access.
  541 + * The cached reader will be read only once, even if you read it several times.
  542 + * This can be usefull to read compressed files or downloaded files (from http or ftp)
  543 + *
  544 + * @param mixed $toConvert The reader to cache
  545 + * It can be a File_Archive_Reader or a string, which will be converted using the
  546 + * read function
  547 + */
  548 + function cache(&$toConvert)
  549 + {
  550 + $source =& File_Archive::_convertToReader($toConvert);
  551 + if (PEAR::isError($source)) {
  552 + return $source;
  553 + }
  554 +
  555 + require_once 'File/Archive/Reader/Cache.php';
  556 + return new File_Archive_Reader_Cache($source);
  557 + }
  558 +
  559 + /**
  560 + * Try to interpret the object as a reader
  561 + * Strings are converted to readers using File_Archive::read
  562 + * Arrays are converted to readers using File_Archive::readMulti
  563 + *
  564 + * @access private
  565 + */
  566 + function &_convertToReader(&$source)
  567 + {
  568 + if (is_string($source)) {
  569 + $cacheCondition = File_Archive::getOption('cacheCondition');
  570 + if ($cacheCondition !== false &&
  571 + preg_match($cacheCondition, $source)) {
  572 + return File_Archive::cache(File_Archive::read($source));
  573 + } else {
  574 + return File_Archive::read($source);
  575 + }
  576 + } else if (is_array($source)) {
  577 + return File_Archive::readMulti($source);
  578 + } else {
  579 + return $source;
  580 + }
  581 + }
  582 +
  583 + /**
  584 + * Try to interpret the object as a writer
  585 + * Strings are converted to writers using File_Archive::appender
  586 + * Arrays are converted to writers using a multi writer
  587 + *
  588 + * @access private
  589 + */
  590 + function &_convertToWriter(&$dest)
  591 + {
  592 + if (is_string($dest)) {
  593 + return File_Archive::appender($dest);
  594 + } else if (is_array($dest)) {
  595 + require_once 'File/Archive/Writer/Multi.php';
  596 + $writer = new File_Archive_Writer_Multi();
  597 + foreach($dest as $key => $foo) {
  598 + $writer->addWriter($dest[$key]);
  599 + }
  600 + } else {
  601 + return $dest;
  602 + }
  603 + }
  604 +
  605 + /**
  606 + * Check if a file with a specific extension can be read as an archive
  607 + * with File_Archive::read*
  608 + * This function is case sensitive.
  609 + *
  610 + * @param string $extension the checked extension
  611 + * @return bool whether this file can be understood reading its extension
  612 + * Currently, supported extensions are tar, zip, gz, tgz, tbz, bz2,
  613 + * bzip2, ar, deb
  614 + */
  615 + function isKnownExtension($extension)
  616 + {
  617 + return $extension == 'tar' ||
  618 + $extension == 'zip' ||
  619 + $extension == 'gz' ||
  620 + $extension == 'tgz' ||
  621 + $extension == 'tbz' ||
  622 + $extension == 'bz2' ||
  623 + $extension == 'bzip2' ||
  624 + $extension == 'ar' ||
  625 + $extension == 'deb' /* ||
  626 + $extension == 'cab' ||
  627 + $extension == 'rar' */;
  628 + }
  629 +
  630 + /**
  631 + * Create a reader that will read the single file source $source as
  632 + * a specific archive
  633 + *
  634 + * @param string $extension determines the kind of archive $source contains
  635 + * $extension is case sensitive
  636 + * @param File_Archive_Reader $source stores the archive
  637 + * @param bool $sourceOpened specifies if the archive is already opened
  638 + * if false, next will be called on source
  639 + * Closing the returned archive will close $source iif $sourceOpened
  640 + * is true
  641 + * @return A File_Archive_Reader that uncompresses the archive contained in
  642 + * $source interpreting it as a $extension archive
  643 + * If $extension is not handled return false
  644 + */
  645 + function readArchive($extension, &$toConvert, $sourceOpened = false)
  646 + {
  647 + $source =& File_Archive::_convertToReader($toConvert);
  648 + if (PEAR::isError($source)) {
  649 + return $source;
  650 + }
  651 +
  652 + switch($extension) {
  653 + case 'tgz':
  654 + return File_Archive::readArchive('tar',
  655 + File_Archive::readArchive('gz', $source, $sourceOpened)
  656 + );
  657 + case 'tbz':
  658 + return File_Archive::readArchive('tar',
  659 + File_Archive::readArchive('bz2', $source, $sourceOpened)
  660 + );
  661 + case 'tar':
  662 + require_once 'File/Archive/Reader/Tar.php';
  663 + return new File_Archive_Reader_Tar($source, $sourceOpened);
  664 +
  665 + case 'gz':
  666 + case 'gzip':
  667 + require_once 'File/Archive/Reader/Gzip.php';
  668 + return new File_Archive_Reader_Gzip($source, $sourceOpened);
  669 +
  670 + case 'zip':
  671 + require_once 'File/Archive/Reader/Zip.php';
  672 + return new File_Archive_Reader_Zip($source, $sourceOpened);
  673 +
  674 + case 'bz2':
  675 + case 'bzip2':
  676 + require_once 'File/Archive/Reader/Bzip2.php';
  677 + return new File_Archive_Reader_Bzip2($source, $sourceOpened);
  678 +
  679 + case 'deb':
  680 + case 'ar':
  681 + require_once 'File/Archive/Reader/Ar.php';
  682 + return new File_Archive_Reader_Ar($source, $sourceOpened);
  683 +
  684 +/* case 'cab':
  685 + require_once 'File/Archive/Reader/Cab.php';
  686 + return new File_Archive_Reader_Cab($source, $sourceOpened);
  687 +
  688 +
  689 + case 'rar':
  690 + require_once "File/Archive/Reader/Rar.php";
  691 + return new File_Archive_Reader_Rar($source, $sourceOpened); */
  692 +
  693 + default:
  694 + return false;
  695 + }
  696 + }
  697 +
  698 + /**
  699 + * Contains only one file with data read from a memory buffer
  700 + *
  701 + * @param string $memory content of the file
  702 + * @param string $filename public name of the file
  703 + * @param array $stat statistics of the file. Index 7 (size) will be
  704 + * overwritten to match the size of $memory
  705 + * @param string $mime mime type of the file. Default will determine the
  706 + * mime type thanks to the extension of $filename
  707 + * @see File_Archive_Reader_Memory
  708 + */
  709 + function readMemory($memory, $filename, $stat=array(), $mime=null)
  710 + {
  711 + require_once "File/Archive/Reader/Memory.php";
  712 + return new File_Archive_Reader_Memory($memory, $filename, $stat, $mime);
  713 + }
  714 +
  715 + /**
  716 + * Contains several other sources. Take care the sources don't have several
  717 + * files with the same filename. The sources are given as a parameter, or
  718 + * can be added thanks to the reader addSource method
  719 + *
  720 + * @param array $sources Array of strings or readers that will be added to
  721 + * the multi reader. If the parameter is a string, a reader will be
  722 + * built thanks to the read function
  723 + * @see File_Archive_Reader_Multi, File_Archive::read()
  724 + */
  725 + function readMulti($sources = array())
  726 + {
  727 + require_once "File/Archive/Reader/Multi.php";
  728 + $result = new File_Archive_Reader_Multi();
  729 + foreach ($sources as $index => $foo) {
  730 + $s =& File_Archive::_convertToReader($sources[$index]);
  731 + if (PEAR::isError($s)) {
  732 + return $s;
  733 + } else {
  734 + $result->addSource($s);
  735 + }
  736 + }
  737 + return $result;
  738 + }
  739 + /**
  740 + * Make the files of a source appear as one large file whose content is the
  741 + * concatenation of the content of all the files
  742 + *
  743 + * @param File_Archive_Reader $source The source whose files must be
  744 + * concatened
  745 + * @param string $filename name of the only file of the created reader
  746 + * @param array $stat statistics of the file. Index 7 (size) will be
  747 + * overwritten to match the total size of the files
  748 + * @param string $mime mime type of the file. Default will determine the
  749 + * mime type thanks to the extension of $filename
  750 + * @see File_Archive_Reader_Concat
  751 + */
  752 + function readConcat(&$toConvert, $filename, $stat=array(), $mime=null)
  753 + {
  754 + $source =& File_Archive::_convertToReader($toConvert);
  755 + if (PEAR::isError($source)) {
  756 + return $source;
  757 + }
  758 +
  759 + require_once "File/Archive/Reader/Concat.php";
  760 + return new File_Archive_Reader_Concat($source, $filename, $stat, $mime);
  761 + }
  762 +
  763 + /**
  764 + * Removes from a source the files that do not follow a given predicat
  765 + *
  766 + * @param File_Archive_Predicate $predicate Only the files for which
  767 + * $predicate->isTrue() will be kept
  768 + * @param File_Archive_Reader $source Source that will be filtered
  769 + * @see File_Archive_Reader_Filter
  770 + */
  771 + function filter($predicate, &$toConvert)
  772 + {
  773 + $source =& File_Archive::_convertToReader($toConvert);
  774 + if (PEAR::isError($source)) {
  775 + return $source;
  776 + }
  777 +
  778 + require_once "File/Archive/Reader/Filter.php";
  779 + return new File_Archive_Reader_Filter($predicate, $source);
  780 + }
  781 + /**
  782 + * Predicate that always evaluate to true
  783 + *
  784 + * @see File_Archive_Predicate_True
  785 + */
  786 + function predTrue()
  787 + {
  788 + require_once "File/Archive/Predicate/True.php";
  789 + return new File_Archive_Predicate_True();
  790 + }
  791 + /**
  792 + * Predicate that always evaluate to false
  793 + *
  794 + * @see File_Archive_Predicate_False
  795 + */
  796 + function predFalse()
  797 + {
  798 + require_once "File/Archive/Predicate/False.php";
  799 + return new File_Archive_Predicate_False();
  800 + }
  801 + /**
  802 + * Predicate that evaluates to the logical AND of the parameters
  803 + * You can add other predicates thanks to the
  804 + * File_Archive_Predicate_And::addPredicate() function
  805 + *
  806 + * @param File_Archive_Predicate (any number of them)
  807 + * @see File_Archive_Predicate_And
  808 + */
  809 + function predAnd()
  810 + {
  811 + require_once "File/Archive/Predicate/And.php";
  812 + $pred = new File_Archive_Predicate_And();
  813 + $args = func_get_args();
  814 + foreach ($args as $p) {
  815 + $pred->addPredicate($p);
  816 + }
  817 + return $pred;
  818 + }
  819 + /**
  820 + * Predicate that evaluates to the logical OR of the parameters
  821 + * You can add other predicates thanks to the
  822 + * File_Archive_Predicate_Or::addPredicate() function
  823 + *
  824 + * @param File_Archive_Predicate (any number of them)
  825 + * @see File_Archive_Predicate_Or
  826 + */
  827 + function predOr()
  828 + {
  829 + require_once "File/Archive/Predicate/Or.php";
  830 + $pred = new File_Archive_Predicate_Or();
  831 + $args = func_get_args();
  832 + foreach ($args as $p) {
  833 + $pred->addPredicate($p);
  834 + }
  835 + return $pred;
  836 + }
  837 + /**
  838 + * Negate a predicate
  839 + *
  840 + * @param File_Archive_Predicate $pred Predicate to negate
  841 + * @see File_Archive_Predicate_Not
  842 + */
  843 + function predNot($pred)
  844 + {
  845 + require_once "File/Archive/Predicate/Not.php";
  846 + return new File_Archive_Predicate_Not($pred);
  847 + }
  848 + /**
  849 + * Evaluates to true iif the file is larger than a given size
  850 + *
  851 + * @param int $size the minimal size of the files (in Bytes)
  852 + * @see File_Archive_Predicate_MinSize
  853 + */
  854 + function predMinSize($size)
  855 + {
  856 + require_once "File/Archive/Predicate/MinSize.php";
  857 + return new File_Archive_Predicate_MinSize($size);
  858 + }
  859 + /**
  860 + * Evaluates to true iif the file has been modified after a given time
  861 + *
  862 + * @param int $time Unix timestamp of the minimal modification time of the
  863 + * files
  864 + * @see File_Archive_Predicate_MinTime
  865 + */
  866 + function predMinTime($time)
  867 + {
  868 + require_once "File/Archive/Predicate/MinTime.php";
  869 + return new File_Archive_Predicate_MinTime($time);
  870 + }
  871 + /**
  872 + * Evaluates to true iif the file has less that a given number of
  873 + * directories in its path
  874 + *
  875 + * @param int $depth Maximal number of directories in path of the files
  876 + * @see File_Archive_Predicate_MaxDepth
  877 + */
  878 + function predMaxDepth($depth)
  879 + {
  880 + require_once "File/Archive/Predicate/MaxDepth.php";
  881 + return new File_Archive_Predicate_MaxDepth($depth);
  882 + }
  883 + /**
  884 + * Evaluates to true iif the extension of the file is in a given list
  885 + *
  886 + * @param array or string $list List or comma separated string of possible
  887 + * extension of the files
  888 + * @see File_Archive_Predicate_Extension
  889 + */
  890 + function predExtension($list)
  891 + {
  892 + require_once "File/Archive/Predicate/Extension.php";
  893 + return new File_Archive_Predicate_Extension($list);
  894 + }
  895 + /**
  896 + * Evaluates to true iif the MIME type of the file is in a given list
  897 + *
  898 + * @param array or string $list List or comma separated string of possible
  899 + * MIME types of the files. You may enter wildcards like "image/*" to
  900 + * select all the MIME in class image
  901 + * @see File_Archive_Predicate_MIME, MIME_Type::isWildcard()
  902 + */
  903 + function predMIME($list)
  904 + {
  905 + require_once "File/Archive/Predicate/MIME.php";
  906 + return new File_Archive_Predicate_MIME($list);
  907 + }
  908 + /**
  909 + * Evaluates to true iif the name of the file follow a given regular
  910 + * expression
  911 + *
  912 + * @param string $ereg regular expression that the filename must follow
  913 + * @see File_Archive_Predicate_Ereg, ereg()
  914 + */
  915 + function predEreg($ereg)
  916 + {
  917 + require_once "File/Archive/Predicate/Ereg.php";
  918 + return new File_Archive_Predicate_Ereg($ereg);
  919 + }
  920 + /**
  921 + * Evaluates to true iif the name of the file follow a given regular
  922 + * expression (case insensitive version)
  923 + *
  924 + * @param string $ereg regular expression that the filename must follow
  925 + * @see File_Archive_Predicate_Eregi, eregi
  926 + */
  927 + function predEregi($ereg)
  928 + {
  929 + require_once "File/Archive/Predicate/Eregi.php";
  930 + return new File_Archive_Predicate_Eregi($ereg);
  931 + }
  932 + /**
  933 + * Evaluates to true only after a given number of evaluations
  934 + * This can be used to select files by index since the evaluation is done
  935 + * once per file
  936 + *
  937 + * @param array The indexes for which the returned predicate will return true
  938 + * are the keys of the array
  939 + * The predicate will return true if isset($indexes[$pos])
  940 + */
  941 + function predIndex($indexes)
  942 + {
  943 + require_once "File/Archive/Predicate/Index.php";
  944 + return new File_Archive_Predicate_Index($indexes);
  945 + }
  946 + /**
  947 + * Custom predicate built by supplying a string expression
  948 + *
  949 + * Here are different ways to create a predicate that keeps only files
  950 + * with names shorter than 100 chars
  951 + * <sample>
  952 + * File_Archive::predCustom("return strlen($name)<100;")
  953 + * File_Archive::predCustom("strlen($name)<100;")
  954 + * File_Archive::predCustom("strlen($name)<100")
  955 + * File_Archive::predCustom("strlen($source->getFilename())<100")
  956 + * </sample>
  957 + *
  958 + * @param string $expression String containing an expression that evaluates
  959 + * to a boolean. If the expression doesn't contain a return
  960 + * statement, it will be added at the begining of the expression
  961 + * A ';' will be added at the end of the expression so that you don't
  962 + * have to write it. You may use the $name variable to refer to the
  963 + * current filename (with path...), $time for the modification time
  964 + * (unix timestamp), $size for the size of the file in bytes, $mime
  965 + * for the MIME type of the file
  966 + * @see File_Archive_Predicate_Custom
  967 + */
  968 + function predCustom($expression)
  969 + {
  970 + require_once "File/Archive/Predicate/Custom.php";
  971 + return new File_Archive_Predicate_Custom($expression);
  972 + }
  973 +
  974 + /**
  975 + * Send the files as a mail attachment
  976 + *
  977 + * @param Mail $mail Object used to send mail (see Mail::factory)
  978 + * @param array or String $to An array or a string with comma separated
  979 + * recipients
  980 + * @param array $headers The headers that will be passed to the Mail_mime
  981 + * object
  982 + * @param string $message Text body of the mail
  983 + * @see File_Archive_Writer_Mail
  984 + */
  985 + function toMail($to, $headers, $message, $mail = null)
  986 + {
  987 + require_once "File/Archive/Writer/Mail.php";
  988 + return new File_Archive_Writer_Mail($to, $headers, $message, $mail);
  989 + }
  990 + /**
  991 + * Write the files on the hard drive
  992 + *
  993 + * @param string $baseDir if specified, the files will be created in that
  994 + * directory. If they don't exist, the directories will automatically
  995 + * be created
  996 + * @see File_Archive_Writer_Files
  997 + */
  998 + function toFiles($baseDir = "")
  999 + {
  1000 + require_once "File/Archive/Writer/Files.php";
  1001 + return new File_Archive_Writer_Files($baseDir);
  1002 + }
  1003 + /**
  1004 + * Send the content of the files to a memory buffer
  1005 + *
  1006 + * toMemory returns a writer where the data will be written.
  1007 + * In this case, the data is accessible using the getData member
  1008 + *
  1009 + * toVariable returns a writer that will write into the given
  1010 + * variable
  1011 + *
  1012 + * @param out $data if specified, the data will be written to this buffer
  1013 + * Else, you can retrieve the buffer with the
  1014 + * File_Archive_Writer_Memory::getData() function
  1015 + * @see File_Archive_Writer_Memory
  1016 + */
  1017 + function toMemory()
  1018 + {
  1019 + $v = '';
  1020 + return File_Archive::toVariable($v);
  1021 + }
  1022 + function toVariable(&$v)
  1023 + {
  1024 + require_once "File/Archive/Writer/Memory.php";
  1025 + return new File_Archive_Writer_Memory($v);
  1026 + }
  1027 + /**
  1028 + * Duplicate the writing operation on two writers
  1029 + *
  1030 + * @param File_Archive_Writer $a, $b writers where data will be duplicated
  1031 + * @see File_Archive_Writer_Multi
  1032 + */
  1033 + function toMulti(&$aC, &$bC)
  1034 + {
  1035 + $a =& File_Archive::_convertToWriter($aC);
  1036 + $b =& File_Archive::_convertToWriter($bC);
  1037 +
  1038 + if (PEAR::isError($a)) {
  1039 + return $a;
  1040 + }
  1041 + if (PEAR::isError($b)) {
  1042 + return $b;
  1043 + }
  1044 +
  1045 + require_once "File/Archive/Writer/Multi.php";
  1046 + $writer = new File_Archive_Writer_Multi();
  1047 + $writer->addWriter($a);
  1048 + $writer->addWriter($b);
  1049 + return $writer;
  1050 + }
  1051 + /**
  1052 + * Send the content of the files to the standard output (so to the client
  1053 + * for a website)
  1054 + *
  1055 + * @param bool $sendHeaders If true some headers will be sent to force the
  1056 + * download of the file. Default value is true
  1057 + * @see File_Archive_Writer_Output
  1058 + */
  1059 + function toOutput($sendHeaders = true)
  1060 + {
  1061 + require_once "File/Archive/Writer/Output.php";
  1062 + return new File_Archive_Writer_Output($sendHeaders);
  1063 + }
  1064 + /**
  1065 + * Compress the data to a tar, gz, tar/gz or zip format
  1066 + *
  1067 + * @param string $filename name of the archive file
  1068 + * @param File_Archive_Writer $innerWriter writer where the archive will be
  1069 + * written
  1070 + * @param string $type can be one of tgz, tbz, tar, zip, gz, gzip, bz2,
  1071 + * bzip2 (default is the extension of $filename) or any composition
  1072 + * of them (for example tar.gz or tar.bz2). The case of this
  1073 + * parameter is not important.
  1074 + * @param array $stat Statistics of the archive (see stat function)
  1075 + * @param bool $autoClose If set to true, $innerWriter will be closed when
  1076 + * the returned archive is close. Default value is true.
  1077 + */
  1078 + function toArchive($filename, &$toConvert, $type = null,
  1079 + $stat = array(), $autoClose = true)
  1080 + {
  1081 + $innerWriter =& File_Archive::_convertToWriter($toConvert);
  1082 + if (PEAR::isError($innerWriter)) {
  1083 + return $innerWriter;
  1084 + }
  1085 + $shortcuts = array("tgz" , "tbz" );
  1086 + $reals = array("tar.gz", "tar.bz2");
  1087 +
  1088 + if ($type === null) {
  1089 + $extensions = strtolower($filename);
  1090 + } else {
  1091 + $extensions = strtolower($type);
  1092 + }
  1093 + $extensions = explode('.', str_replace($shortcuts, $reals, $extensions));
  1094 + if ($innerWriter !== null) {
  1095 + $writer =& $innerWriter;
  1096 + } else {
  1097 + $writer = File_Archive::toFiles();
  1098 + }
  1099 + $nbCompressions = 0;
  1100 + $currentFilename = $filename;
  1101 + while (($extension = array_pop($extensions)) !== null) {
  1102 + unset($next);
  1103 + switch($extension) {
  1104 + case "tar":
  1105 + require_once "File/Archive/Writer/Tar.php";
  1106 + $next = new File_Archive_Writer_Tar(
  1107 + $currentFilename, $writer, $stat, $autoClose
  1108 + );
  1109 + unset($writer); $writer =& $next;
  1110 + break;
  1111 + case "zip":
  1112 + require_once "File/Archive/Writer/Zip.php";
  1113 + $next = new File_Archive_Writer_Zip(
  1114 + $currentFilename, $writer, $stat, $autoClose
  1115 + );
  1116 + unset($writer); $writer =& $next;
  1117 + break;
  1118 + case "gz":
  1119 + case "gzip":
  1120 + require_once "File/Archive/Writer/Gzip.php";
  1121 + $next = new File_Archive_Writer_Gzip(
  1122 + $currentFilename, $writer, $stat, $autoClose
  1123 + );
  1124 + unset($writer); $writer =& $next;
  1125 + break;
  1126 + case "bz2":
  1127 + case "bzip2":
  1128 + require_once "File/Archive/Writer/Bzip2.php";
  1129 + $next = new File_Archive_Writer_Bzip2(
  1130 + $currentFilename, $writer, $stat, $autoClose
  1131 + );
  1132 + unset($writer); $writer =& $next;
  1133 + break;
  1134 + case "deb":
  1135 + case "ar":
  1136 + require_once "File/Archive/Writer/Ar.php";
  1137 + $next = new File_Archive_Writer_Ar(
  1138 + $currentFilename, $writer, $stat, $autoClose
  1139 + );
  1140 + unset($writer); $writer =& $next;
  1141 + break;
  1142 + default:
  1143 + if ($type !== null || $nbCompressions == 0) {
  1144 + return PEAR::raiseError("Archive $extension unknown");
  1145 + }
  1146 + break;
  1147 + }
  1148 + $nbCompressions ++;
  1149 + $autoClose = true;
  1150 + $currentFilename = implode(".", $extensions);
  1151 + }
  1152 + return $writer;
  1153 + }
  1154 +
  1155 +
  1156 + /**
  1157 + * File_Archive::extract($source, $dest) is equivalent to $source->extract($dest)
  1158 + * If $source is a PEAR error, the error will be returned
  1159 + * It is thus easier to use this function than $source->extract, since it reduces the number of
  1160 + * error checking and doesn't force you to define a variable $source
  1161 + *
  1162 + * You may use strings as source and dest. In that case the source is automatically
  1163 + * converted to a reader using File_Archive::read and the dest is converted to a
  1164 + * writer using File_Archive::appender
  1165 + * Since PHP doesn't allow to pass literal strings by ref, you will have to use temporary
  1166 + * variables.
  1167 + * File_Archive::extract($src = 'archive.zip/', $dest = 'dir') will extract the archive to 'dir'
  1168 + * It is the same as
  1169 + * File_Archive::extract(
  1170 + * File_Archive::read('archive.zip/'),
  1171 + * File_Archive::appender('dir')
  1172 + * );
  1173 + * You may use any variable in the extract function ($from/$to, $a/$b...).
  1174 + *
  1175 + * @param File_Archive_Reader $source The source that will be read
  1176 + * @param File_Archive_Writer $dest Where to copy $source files
  1177 + * @param bool $autoClose if true (default), $dest will be closed after the extraction
  1178 + * @param int $bufferSize Size of the buffer to use to move data from the reader to the buffer
  1179 + * If $bufferSize <= 0 (default), the blockSize option is used
  1180 + * You shouldn't need to change that
  1181 + * @return null or a PEAR error if an error occured
  1182 + */
  1183 + function extract(&$sourceToConvert, &$destToConvert, $autoClose = true, $bufferSize = 0)
  1184 + {
  1185 + $source =& File_Archive::_convertToReader($sourceToConvert);
  1186 + if (PEAR::isError($source)) {
  1187 + return $source;
  1188 + }
  1189 + $dest =& File_Archive::_convertToWriter($destToConvert);
  1190 + return $source->extract($dest, $autoClose, $bufferSize);
  1191 + }
  1192 +
  1193 + /**
  1194 + * Create a writer that can be used to append files to an archive inside a source
  1195 + * If the archive can't be found in the source, it will be created
  1196 + * If source is set to null, File_Archive::toFiles will be assumed
  1197 + * If type is set to null, the type of the archive will be determined looking at
  1198 + * the extension in the URL
  1199 + * stat is the array of stat (returned by stat() PHP function of Reader getStat())
  1200 + * to use if the archive must be created
  1201 + *
  1202 + * This function allows to create or append data to nested archives. Only one
  1203 + * archive will be created and if your creation requires creating several nested
  1204 + * archives, a PEAR error will be returned
  1205 + *
  1206 + * After this call, $source will be closed and should not be used until the
  1207 + * returned writer is closed.
  1208 + *
  1209 + * @param File_Archive_Reader $source A reader where some files will be appended
  1210 + * @param string $URL URL to reach the archive in the source.
  1211 + * if $URL is null, a writer to append files to the $source reader will
  1212 + * be returned
  1213 + * @param bool $unique If true, the duplicate files will be deleted on close
  1214 + * Default is false (and setting it to true may have some performance
  1215 + * consequences)
  1216 + * @param string $type Extension of the archive (or null to use the one in the URL)
  1217 + * @param array $stat Used only if archive is created, array of stat as returned
  1218 + * by PHP stat function or Reader getStat function: stats of the archive)
  1219 + * Time (index 9) will be overwritten to current time
  1220 + * @return File_Archive_Writer a writer that you can use to append files to the reader
  1221 + */
  1222 + function appenderFromSource(&$toConvert, $URL = null, $unique = null,
  1223 + $type = null, $stat = array())
  1224 + {
  1225 + $source =& File_Archive::_convertToReader($toConvert);
  1226 + if (PEAR::isError($source)) {
  1227 + return $source;
  1228 + }
  1229 + if ($unique == null) {
  1230 + $unique = File_Archive::getOption("appendRemoveDuplicates");
  1231 + }
  1232 +
  1233 + //Do not report the fact that the archive does not exist as an error
  1234 + PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
  1235 +
  1236 + if ($URL === null) {
  1237 + $result =& $source;
  1238 + } else {
  1239 + if ($type === null) {
  1240 + $result = File_Archive::_readSource($source, $URL.'/', $reachable, $baseDir);
  1241 + } else {
  1242 + $result = File_Archive::readArchive(
  1243 + $type,
  1244 + File_Archive::_readSource($source, $URL, $reachable, $baseDir)
  1245 + );
  1246 + }
  1247 + }
  1248 +
  1249 + PEAR::popErrorHandling();
  1250 +
  1251 + if (!PEAR::isError($result)) {
  1252 + if ($unique) {
  1253 + require_once "File/Archive/Writer/UniqueAppender.php";
  1254 + return new File_Archive_Writer_UniqueAppender($result);
  1255 + } else {
  1256 + return $result->makeAppendWriter();
  1257 + }
  1258 + }
  1259 +
  1260 + //The source can't be found and has to be created
  1261 + $stat[9] = $stat['mtime'] = time();
  1262 +
  1263 + if (empty($baseDir)) {
  1264 + if ($source !== null) {
  1265 + $writer =& $source->makeWriter();
  1266 + } else {
  1267 + $writer =& File_Archive::toFiles();
  1268 + }
  1269 + if (PEAR::isError($writer)) {
  1270 + return $writer;
  1271 + }
  1272 +
  1273 + PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
  1274 + $result = File_Archive::toArchive($reachable, $writer, $type);
  1275 + PEAR::popErrorHandling();
  1276 +
  1277 + if (PEAR::isError($result)) {
  1278 + $result = File_Archive::toFiles($reachable);
  1279 + }
  1280 + } else {
  1281 + $reachedSource = File_Archive::readSource($source, $reachable);
  1282 + if (PEAR::isError($reachedSource)) {
  1283 + return $reachedSource;
  1284 + }
  1285 + $writer = $reachedSource->makeWriter();
  1286 + if (PEAR::isError($writer)) {
  1287 + return $writer;
  1288 + }
  1289 +
  1290 + PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
  1291 + $result = File_Archive::toArchive($baseDir, $writer, $type);
  1292 + PEAR::popErrorHandling();
  1293 +
  1294 + if (PEAR::isError($result)) {
  1295 + require_once "File/Archive/Writer/AddBaseName.php";
  1296 + $result = new File_Archive_Writer_AddBaseName(
  1297 + $baseDir, $writer);
  1298 + if (PEAR::isError($result)) {
  1299 + return $result;
  1300 + }
  1301 + }
  1302 + }
  1303 + return $result;
  1304 + }
  1305 +
  1306 + /**
  1307 + * Create a writer that allows appending new files to an existing archive
  1308 + * This function actes as appendToSource with source being the system files
  1309 + * $URL can't be null here
  1310 + *
  1311 + * @param File_Archive_Reader $source A reader where some files will be appended
  1312 + * @return File_Archive_Writer a writer that you can use to append files to the reader
  1313 + */
  1314 + function appender($URL, $unique = null, $type = null, $stat = array())
  1315 + {
  1316 + $source = null;
  1317 + return File_Archive::appenderFromSource($source, $URL, $unique, $type, $stat);
  1318 + }
  1319 +
  1320 + /**
  1321 + * Remove the files that follow a given predicate from the source
  1322 + * If URL is null, the files will be removed from the source directly
  1323 + * Else, URL must link to a source from which the files will be removed
  1324 + *
  1325 + * @param File_Archive_Predicate $pred The files that follow the predicate
  1326 + * (for which $pred->isTrue($source) is true) will be erased
  1327 + * @param File_Archive_Reader $source A reader that contains the files to remove
  1328 + */
  1329 + function removeFromSource(&$pred, &$toConvert, $URL = null)
  1330 + {
  1331 + $source =& File_Archive::_convertToReader($toConvert);
  1332 + if (PEAR::isError($source)) {
  1333 + return $source;
  1334 + }
  1335 + if ($URL === null) {
  1336 + $result = &$source;
  1337 + } else {
  1338 + if (substr($URL, -1) !== '/') {
  1339 + $URL .= '/';
  1340 + }
  1341 + $result = File_Archive::readSource($source, $URL);
  1342 + }
  1343 +
  1344 + $writer = $result->makeWriterRemoveFiles($pred);
  1345 + if (PEAR::isError($writer)) {
  1346 + return $writer;
  1347 + }
  1348 + $writer->close();
  1349 + }
  1350 +
  1351 + /**
  1352 + * Remove the files that follow a given predicate from the archive specified
  1353 + * in $URL
  1354 + *
  1355 + * @param $URL URL of the archive where some files must be removed
  1356 + */
  1357 + function remove($pred, $URL)
  1358 + {
  1359 + $source = null;
  1360 + return File_Archive::removeFromSource($pred, $source, $URL);
  1361 + }
  1362 +
  1363 + /**
  1364 + * Remove duplicates from a source, keeping the most recent one (or the one that has highest pos in
  1365 + * the archive if the files have same date or no date specified)
  1366 + *
  1367 + * @param File_Archive_Reader a reader that may contain duplicates
  1368 + */
  1369 + function removeDuplicatesFromSource(&$toConvert, $URL = null)
  1370 + {
  1371 + $source =& File_Archive::_convertToReader($toConvert);
  1372 + if (PEAR::isError($source)) {
  1373 + return $source;
  1374 + }
  1375 + if ($URL !== null && substr($URL, -1) != '/') {
  1376 + $URL .= '/';
  1377 + }
  1378 +
  1379 + if ($source === null) {
  1380 + $source = File_Archive::read($URL);
  1381 + }
  1382 +
  1383 + require_once "File/Archive/Predicate/Duplicate.php";
  1384 + $pred = new File_Archive_Predicate_Duplicate($source);
  1385 + $source->close();
  1386 + return File_Archive::removeFromSource(
  1387 + $pred,
  1388 + $source,
  1389 + null
  1390 + );
  1391 + }
  1392 +
  1393 + /**
  1394 + * Remove duplicates from the archive specified in the URL
  1395 + */
  1396 + function removeDuplicates($URL)
  1397 + {
  1398 + $source = null;
  1399 + return File_Archive::removeDuplicatesFromSource($source, $URL);
  1400 + }
  1401 +}
  1402 +
  1403 +?>
0 \ No newline at end of file 1404 \ No newline at end of file