diff --git a/config/dmsDefaults.php b/config/dmsDefaults.php
index e0033d7..d0c13e5 100644
--- a/config/dmsDefaults.php
+++ b/config/dmsDefaults.php
@@ -47,7 +47,7 @@ if (defined('DMS_DEFAULTS_INCLUDED'))
}
define('DMS_DEFAULTS_INCLUDED',1);
-define('LATEST_WEBSERVICE_VERSION',2);
+define('LATEST_WEBSERVICE_VERSION',3);
if (function_exists('apd_set_pprof_trace')) {
diff --git a/ktapi/KTAPIConstants.inc.php b/ktapi/KTAPIConstants.inc.php
index 29ef5ff..e0c7409 100644
--- a/ktapi/KTAPIConstants.inc.php
+++ b/ktapi/KTAPIConstants.inc.php
@@ -5,32 +5,32 @@
* KnowledgeTree Community Edition
* Document Management Made Simple
* Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
- *
- *
+ *
+ *
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 3 as published by the
* Free Software Foundation.
- *
+ *
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
- *
- * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
+ *
+ * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
* California 94120-7775, or email info@knowledgetree.com.
- *
+ *
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
- *
+ *
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
- * KnowledgeTree" logo and retain the original copyright notice. If the display of the
+ * KnowledgeTree" logo and retain the original copyright notice. If the display of the
* logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
- * must display the words "Powered by KnowledgeTree" and retain the original
+ * must display the words "Powered by KnowledgeTree" and retain the original
* copyright notice.
* Contributor( s): ______________________________________
*/
@@ -53,6 +53,7 @@ define('KTAPI_ERROR_SESSION_INVALID', 'The session could not be resolved.');
define('KTAPI_ERROR_PERMISSION_INVALID', 'The permission could not be resolved.');
define('KTAPI_ERROR_FOLDER_INVALID', 'The folder could not be resolved.');
define('KTAPI_ERROR_DOCUMENT_INVALID', 'The document could not be resolved.');
+define('KTAPI_ERROR_VERSION_INVALID', 'The document version could not be resolved.');
define('KTAPI_ERROR_USER_INVALID', 'The user could not be resolved.');
define('KTAPI_ERROR_KTAPI_INVALID', 'The ktapi could not be resolved.');
define('KTAPI_ERROR_INSUFFICIENT_PERMISSIONS', 'The user does not have sufficient permissions to access the resource.');
diff --git a/ktapi/KTAPIDocument.inc.php b/ktapi/KTAPIDocument.inc.php
index 148cf2b..5149704 100644
--- a/ktapi/KTAPIDocument.inc.php
+++ b/ktapi/KTAPIDocument.inc.php
@@ -91,16 +91,17 @@ class KTAPI_Document extends KTAPI_FolderItem
}
/**
- * This is used to get a document based on document id.
+ * This is used to get a document based on document id. Or a version of the document based on the metadata version id
*
* @author KnowledgeTree Team
* @static
* @access public
* @param KTAPI $ktapi The ktapi object
* @param int $documentid The document id
+ * @param int $iMetadataVersionId Optional. The metadata version id
* @return KTAPI_Document The document object
*/
- function &get(&$ktapi, $documentid)
+ function &get(&$ktapi, $documentid, $iMetadataVersionId = null)
{
assert(!is_null($ktapi));
assert(is_a($ktapi, 'KTAPI'));
@@ -108,7 +109,7 @@ class KTAPI_Document extends KTAPI_FolderItem
$documentid += 0;
- $document = &Document::get($documentid);
+ $document = &Document::get($documentid, $iMetadataVersionId);
if (is_null($document) || PEAR::isError($document))
{
return new KTAPI_Error(KTAPI_ERROR_DOCUMENT_INVALID,$document );
@@ -137,6 +138,30 @@ class KTAPI_Document extends KTAPI_FolderItem
}
/**
+ * This is used to get a document based on the document id and the metadata version
+ *
+ * @author KnowledgeTree Team
+ * @static
+ * @access public
+ * @param KTAPI $ktapi The ktapi object
+ * @param int $documentid The document id
+ * @param int $metadataVersion The metadata version (0,1,2)
+ * @return KTAPI_Document The document object
+ */
+ function &get_by_metadata_version(&$ktapi, $documentid, $metadataVersion)
+ {
+ // get the metadata version id
+ $iMetadataVersionId = Document::getMetadataVersionIdFromVersion($documentid, $metadataVersion);
+ if (is_null($iMetadataVersionId) || PEAR::isError($iMetadataVersionId))
+ {
+ return new KTAPI_Error(KTAPI_ERROR_VERSION_INVALID, $iMetadataVersionId );
+ }
+
+ // get the KTAPI_Document object
+ return self::get($ktapi, $documentid, $iMetadataVersionId);
+ }
+
+ /**
* Checks if a document has been deleted
*
* @author KnowledgeTree Team
@@ -2137,13 +2162,14 @@ class KTAPI_Document extends KTAPI_FolderItem
* @author KnowledgeTree Team
* @access public
*/
- function download()
+ function download($version = null)
{
$storage =& KTStorageManagerUtil::getSingleton();
$options = array();
+ $comment = (!is_null($version)) ? 'Document version '.$version.' downloaded' : 'Document downloaded';
$oDocumentTransaction = new DocumentTransaction($this->document, 'Document downloaded', 'ktcore.transactions.download', $aOptions);
- $oDocumentTransaction->create();
+ return $oDocumentTransaction->create();
}
/**
@@ -2241,6 +2267,17 @@ class KTAPI_Document extends KTAPI_FolderItem
}
/**
+ * Get the content version id using the document (content) version - major/minor version
+ *
+ * @param string $version
+ * @return int
+ */
+ function get_content_version_id_from_version($version)
+ {
+ return $this->document->getContentVersionIdFromVersion($version);
+ }
+
+ /**
* This expunges a document from the system.
*
*
diff --git a/ktapi/ktapi.inc.php b/ktapi/ktapi.inc.php
index 882600a..f8a6b96 100644
--- a/ktapi/ktapi.inc.php
+++ b/ktapi/ktapi.inc.php
@@ -870,6 +870,22 @@ class KTAPI
}
/**
+ * This returns a refererence to a document based on document id.
+ *
+ * @author KnowledgeTree Team
+ * @access public
+ * @param integer $documentid The document id
+ * @param integer $metadataVersion The metadata version of the document (not the id)
+ * @return object $document The KTAPI_Document object
+ */
+ public function &get_document_by_metadata_version($documentid, $metadataVersion)
+ {
+ // Get the document using the metadata version
+ $document = KTAPI_Document::get_by_metadata_version($this, $documentid, $metadataVersion);
+ return $document;
+ }
+
+ /**
* This returns a document type id based on the name or an error object.
*
* @author KnowledgeTree Team
diff --git a/ktwebservice/KTDownloadManager.inc.php b/ktwebservice/KTDownloadManager.inc.php
index 43beb07..5d32657 100644
--- a/ktwebservice/KTDownloadManager.inc.php
+++ b/ktwebservice/KTDownloadManager.inc.php
@@ -9,7 +9,7 @@
* KnowledgeTree Community Edition
* Document Management Made Simple
* Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
- *
+ *
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 3 as published by the
@@ -76,44 +76,41 @@ class KTDownloadManager
{
$this->session = $session;
}
-
+
/**
* This returns
*
* @access public
* @param KTAPI_Document $document
+ * @param int $content_version_id Optional. The id of the requested content version
* @return string
*/
- function allow_download($document, $content_version = null, $multipart = false) {
+ function allow_download($document, $content_version_id = null, $multipart = false) {
assert ( ! is_null ( $document ) );
-
- $content_version = 0;
+
$filesize = 0;
-
+
if ($document instanceof KTAPI_Document) {
$doc_id = $document->documentid;
- $content_version = $document->document->getContentVersionId ();
+ //$content_version_id = (is_numeric($content_version_id)) ? $content_version_id : $document->document->getContentVersionId();
$filesize = $document->document->getFileSize ();
} else if ($document instanceof Document || $document instanceof DocumentProxy) {
$doc_id = $document->getId ();
- $content_version = $document->getContentVersionId ();
+ //$content_version_id = (is_numeric($content_version_id)) ? $content_version_id : $document->getContentVersionId();
$filesize = $document->getFileSize ();
} else if (is_numeric ( $document )) {
$doc_id = $document;
} else
die ( 'gracefully' );
-
- //assert(is_a($document, 'KTAPI_Document'));
-
-
- $hash = sha1 ( "$doc_id $this->session $this->random" );
-
- $id = DBUtil::autoInsert ( 'download_files', array ('document_id' => $doc_id, 'session' => $this->session, 'download_date' => date ( 'Y-m-d H:i:s' ), 'content_version' => $content_version, 'filesize' => $filesize, 'hash' => $hash ), array ('noid' => true ) );
-
- return $multipart?$this->build_multipart_url( $hash, $doc_id ):$this->build_url ( $hash, $doc_id );
+
+ $hash = sha1 ( "$doc_id $content_version_id $this->session $this->random" );
+
+ $id = DBUtil::autoInsert ( 'download_files', array ('document_id' => $doc_id, 'session' => $this->session, 'download_date' => date ( 'Y-m-d H:i:s' ), 'content_version' => $content_version_id, 'filesize' => $filesize, 'hash' => $hash ), array ('noid' => true ) );
+
+ return $multipart ? $this->build_multipart_url( $hash, $doc_id ) : $this->build_url ( $hash, $doc_id );
}
-
-
+
+
/**
* This returns the url used to download a document.
*
@@ -125,21 +122,24 @@ class KTDownloadManager
function build_url($hash, $documentid) {
return $this->download_url . "?code=$hash&d=$documentid&u=$this->session";
}
-
+
function build_multipart_url($hash, $documentId) {
-// return '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@';
return $this->multipart_download_url . "?code=$hash&d=$documentId&u=$this->session";
}
-
/**
* This starts a download.
*
* @access public
+ *
+ * @param int $document_id
+ * @param string $hash
+ * @param string $apptype
+ * @return mixed
*/
- function download($document_id, $hash, $version = null, $apptype = 'ws')
+ function download($document_id, $hash, $apptype = 'ws')
{
- $sql = "SELECT 1 FROM download_files WHERE hash=? AND session=? AND document_id=?";
+ $sql = "SELECT content_version FROM download_files WHERE hash=? AND session=? AND document_id=?";
$rows = DBUtil::getResultArray(array($sql, array($hash, $this->session, $document_id)));
if (PEAR::isError($rows))
{
@@ -151,11 +151,14 @@ class KTDownloadManager
return new PEAR_Error('Invalid session.');
}
+ // Get the content version id
+ $content_version_id = $rows[0]['content_version'];
+
// If document is being downloaded by an external user bypass the session checking
$check = strstr($this->session, 'ktext_'.$document_id);
if($check == 0 && $check !== false){
// Use external download function
- return $this->download_ext($document_id, $hash, $version = null);
+ return $this->download_ext($document_id, $hash, $content_version_id);
}
$storage =& KTStorageManagerUtil::getSingleton();
@@ -173,11 +176,9 @@ class KTDownloadManager
return $document;
}
- if (!empty($version))
+ if (!empty($content_version_id))
{
- $version = KTDocumentContentVersion::get($version);
-
- $res = $storage->downloadVersion($document->document, $version);
+ $res = $storage->downloadVersion($document->document, $content_version_id);
}
else
{
@@ -193,8 +194,8 @@ class KTDownloadManager
return true;
}
-
- function download_ext($document_id, $hash, $version = null)
+
+ function download_ext($document_id, $hash, $content_version_id = null)
{
$storage =& KTStorageManagerUtil::getSingleton();
$document = Document::get($document_id);
@@ -203,11 +204,9 @@ class KTDownloadManager
return $document;
}
- if (!empty($version))
+ if (!empty($content_version_id))
{
- $version = KTDocumentContentVersion::get($version);
-
- $res = $storage->downloadVersion($document, $version);
+ $res = $storage->downloadVersion($document, $content_version_id);
}
else
{
@@ -237,4 +236,4 @@ class KTDownloadManager
DBUtil::runQuery($sql);
}
}
-?>
+?>
\ No newline at end of file
diff --git a/ktwebservice/download.php b/ktwebservice/download.php
index 05d413b..6965e84 100644
--- a/ktwebservice/download.php
+++ b/ktwebservice/download.php
@@ -7,7 +7,7 @@
* KnowledgeTree Community Edition
* Document Management Made Simple
* Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
- *
+ *
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 3 as published by the
@@ -73,7 +73,7 @@ require_once('KTDownloadManager.inc.php');
$download_manager = new KTDownloadManager();
$download_manager->set_session($session);
-$response = $download_manager->download($document_id, $hash, null, $apptype);
+$response = $download_manager->download($document_id, $hash, $apptype);
if (PEAR::isError($response))
{
$msg = urlencode($response->getMessage());
diff --git a/ktwebservice/webservice.php b/ktwebservice/webservice.php
index 70a9926..5445c04 100644
--- a/ktwebservice/webservice.php
+++ b/ktwebservice/webservice.php
@@ -60,8 +60,6 @@ if (defined('HAS_SEARCH_FUNCTIONALITY'))
require_once(KT_DIR . '/search2/search/search.inc.php');
}
-// TODO: allow downloading of metadata versions
-// TODO: allow downloading of document versions
// TODO: chunking search results
// TODO: add basic permissions management - add permissions to folder based on user/groups
// TODO: refactor!!! download manager, split this file into a few smaller ones, etc
@@ -72,7 +70,7 @@ if (defined('HAS_SEARCH_FUNCTIONALITY'))
// TODO: ktwsapi/php must be made compatible with v2/v3
// TODO: subscriptions/notifications
-// NOTE: some features are not implemented yet. most expected for v3. e.g. oem_document_no, custom_document_no, download($version)., get_metadata($version)
+// NOTE: some features are not implemented yet. most expected for v3. e.g. oem_document_no, custom_document_no
// Status Codes as defined in the specification.
@@ -97,7 +95,7 @@ define('KTWS_ERR_DB_PROBLEM', 99);
if (!defined('LATEST_WEBSERVICE_VERSION'))
{
- define('LATEST_WEBSERVICE_VERSION', 2);
+ define('LATEST_WEBSERVICE_VERSION', 3);
}
function bool2str($bool)
@@ -2944,12 +2942,13 @@ class KTWebService
*
* @param string $session_id
* @param int $document_id
+ * @param string $version The document (content) version - "major version" . "minor version"
* @return kt_response. status_code can be KTWS_ERR_INVALID_SESSION, KTWS_ERR_INVALID_DOCUMENT or KTWS_SUCCESS
*/
function download_document($session_id, $document_id, $version=null)
{
- $this->debug("download_document('$session_id',$document_id)");
+ $this->debug("download_document('$session_id',$document_id, '$version')");
$kt = &$this->get_ktapi($session_id );
if (is_array($kt))
@@ -2968,11 +2967,23 @@ class KTWebService
return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response);
}
- $result = $document->download();
+ $content_version_id = null;
+ if(!empty($version)){
+ // Get the content version id for the given document version
+ $content_version_id = $document->get_content_version_id_from_version($version);
+ if (PEAR::isError($content_version_id))
+ {
+ $response['message'] = $result->getMessage();
+ $this->debug("download_document - cannot get version $version - " . $result->getMessage(), $session_id);
+ return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response);
+ }
+ }
+
+ $result = $document->download($version);
if (PEAR::isError($result))
{
$response['message'] = $result->getMessage();
- $this->debug("download_document - cannot download - " . $result->getMessage(), $session_id);
+ $this->debug("download_document - cannot download (version $version) - " . $result->getMessage(), $session_id);
return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response);
}
@@ -2980,7 +2991,7 @@ class KTWebService
$download_manager = new KTDownloadManager();
$download_manager->set_session($session->session);
$download_manager->cleanup();
- $url = $download_manager->allow_download($document);
+ $url = $download_manager->allow_download($document, $content_version_id);
$response['status_code'] = KTWS_SUCCESS;
$response['message'] = $url;
@@ -3016,7 +3027,19 @@ class KTWebService
return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response);
}
- $result = $document->download();
+ $content_version_id = null;
+ if(!empty($version)){
+ // Get the content version id for the given document version
+ $content_version_id = $document->get_content_version_id_from_version($version);
+ if (PEAR::isError($content_version_id))
+ {
+ $response['message'] = $result->getMessage();
+ $this->debug("download_document - cannot get version $version - " . $result->getMessage(), $session_id);
+ return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response);
+ }
+ }
+
+ $result = $document->download($version);
if (PEAR::isError($result))
{
$response['message'] = $result->getMessage();
@@ -3024,24 +3047,33 @@ class KTWebService
return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response);
}
- $content='';
+ $content = '';
+ $oStorage =& KTStorageManagerUtil::getSingleton();
- $document = $document->document;
+ // for a specified version
+ if(is_numeric($content_version_id)){
+ $filename = $oStorage->temporaryFileForVersion($content_version_id);
- $oStorage =& KTStorageManagerUtil::getSingleton();
- $filename = $oStorage->temporaryFile($document);
-
- $fp=fopen($filename,'rb');
- if ($fp === false)
- {
+ if(!$filename){
$response['message'] = 'The file is not in the storage system. Please contact an administrator!';
- $this->debug("download_small_document - cannot write $filename", $session_id);
+ $this->debug("download_small_document - $filename cannot be found in the storage system", $session_id);
return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response);
- }
- $content = fread($fp, filesize($filename));
- fclose($fp);
- $content = base64_encode($content);
+ }
+ }else{
+ $document = $document->document;
+ $filename = $oStorage->temporaryFile($document);
+ }
+ $fp=fopen($filename,'rb');
+ if ($fp === false)
+ {
+ $response['message'] = 'The file is not in the storage system. Please contact an administrator!';
+ $this->debug("download_small_document - cannot read $filename", $session_id);
+ return new SOAP_Value('return',"{urn:$this->namespace}kt_response", $response);
+ }
+ $content = fread($fp, filesize($filename));
+ fclose($fp);
+ $content = base64_encode($content);
$response['status_code'] = KTWS_SUCCESS;
$response['message'] = $content;
@@ -3743,9 +3775,9 @@ class KTWebService
* @param int $document_id
* @return kt_metadata_response
*/
- function get_document_metadata($session_id,$document_id)
+ function get_document_metadata($session_id, $document_id, $version = null)
{
- $this->debug("get_document_metadata('$session_id',$document_id)");
+ $this->debug("get_document_metadata('$session_id',$document_id, $version)");
$kt = &$this->get_ktapi($session_id );
if (is_array($kt))
@@ -3755,7 +3787,12 @@ class KTWebService
$response = KTWebService::_status(KTWS_ERR_INVALID_DOCUMENT);
- $document = &$kt->get_document_by_id($document_id);
+ if(is_numeric($version)){
+ $document = &$kt->get_document_by_metadata_version($document_id, $version);
+ }else {
+ $document = &$kt->get_document_by_id($document_id);
+ }
+
if (PEAR::isError($document))
{
$response['message'] = $document->getMessage();
diff --git a/lib/documentmanagement/Document.inc b/lib/documentmanagement/Document.inc
index 82abff1..13c2cba 100644
--- a/lib/documentmanagement/Document.inc
+++ b/lib/documentmanagement/Document.inc
@@ -5,7 +5,7 @@
* KnowledgeTree Community Edition
* Document Management Made Simple
* Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
- *
+ *
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 3 as published by the
@@ -169,7 +169,7 @@ class Document {
function getStoragePath() { return $this->_oDocumentContentVersion->getStoragePath(); }
function setStoragePath($sNewValue) { $this->_oDocumentContentVersion->setStoragePath($sNewValue); }
-
+
/**
@@ -679,6 +679,50 @@ class Document {
}
// }}}
+ // {{{ getContentVersionIdFromVersion
+ function getContentVersionIdFromVersion($version)
+ {
+ $aVersion = explode('.', $version);
+ $major = $aVersion[0];
+ $minor = $aVersion[1];
+
+ $doc_id = $this->iId;
+
+ $query = "select id from document_content_version where document_id = $doc_id and major_version = $major and minor_version = $minor";
+
+ $result = DBUtil::getOneResultKey($query, 'id');
+
+ if(empty($result)){
+ return PEAR::raiseError("Requested content version, $version, does not exist.");
+ }
+
+ if(PEAR::isError($result)){
+ return $result;
+ }
+
+ return $result;
+ }
+ // }}}
+
+ // {{{ getMetadataVersionIdFromVersion
+ static function getMetadataVersionIdFromVersion($doc_id, $version)
+ {
+ $query = "select id from document_metadata_version where document_id = $doc_id and metadata_version = $version";
+
+ $result = DBUtil::getOneResultKey($query, 'id');
+
+ if(empty($result)){
+ return PEAR::raiseError("Requested metadata version, $version, does not exist.");
+ }
+
+ if(PEAR::isError($result)){
+ return $result;
+ }
+
+ return $result;
+ }
+ // }}}
+
// {{{ delete
function delete() {
$this->_oDocumentCore->setMetadataVersionId(null);
diff --git a/lib/documentmanagement/documentmetadataversion.inc.php b/lib/documentmanagement/documentmetadataversion.inc.php
index 2f9c766..e1079f8 100644
--- a/lib/documentmanagement/documentmetadataversion.inc.php
+++ b/lib/documentmanagement/documentmetadataversion.inc.php
@@ -5,32 +5,32 @@
* KnowledgeTree Community Edition
* Document Management Made Simple
* Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
- *
- *
+ *
+ *
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 3 as published by the
* Free Software Foundation.
- *
+ *
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
- *
- * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
+ *
+ * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
* California 94120-7775, or email info@knowledgetree.com.
- *
+ *
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
- *
+ *
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
- * KnowledgeTree" logo and retain the original copyright notice. If the display of the
+ * KnowledgeTree" logo and retain the original copyright notice. If the display of the
* logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
- * must display the words "Powered by KnowledgeTree" and retain the original
+ * must display the words "Powered by KnowledgeTree" and retain the original
* copyright notice.
* Contributor( s): ______________________________________
*
@@ -73,7 +73,7 @@ class KTDocumentMetadataVersion extends KTEntity {
var $iWorkflowStateId;
var $_aFieldToSelect;
-
+
public static $_versionFields = null;
// {{{ getters/setters
@@ -101,11 +101,11 @@ class KTDocumentMetadataVersion extends KTEntity {
function getWorkflowStateId() { return $this->iWorkflowStateId; }
function setWorkflowStateId($mValue) { $this->iWorkflowStateId = $mValue; }
// }}}
-
+
function __construct() {
$this->_aFieldToSelect = KTDocumentMetaDataVersion::getFieldsToSelect();
}
-
+
function getFieldsToSelect() {
if(self::$_versionFields == null) {
$sTable = KTUtil::getTableName('document_metadata_version');
@@ -116,24 +116,24 @@ class KTDocumentMetadataVersion extends KTEntity {
}
self::$_versionFields = $result;
}
- return self::$_versionFields;
+ return self::$_versionFields;
}
-
+
function getFieldType($dbType) {
/* Integer test */
if(strpos($dbType, "int") !== FALSE) {
return "i";
}
-
+
/* Time test */
if(strpos($dbType, "time") !== FALSE) {
return "d";
}
-
+
/* Default */
return "s";
}
-
+
function &createFromArray($aOptions) {
return KTEntityUtil::createFromArray('KTDocumentMetadataVersion', $aOptions);
@@ -163,7 +163,7 @@ class KTDocumentMetadataVersion extends KTEntity {
'document_id' => $iDocumentId,
), array(
'multi' => true,
- 'orderby' => 'version_created DESC',
+ 'orderby' => 'version_created DESC, metadata_version DESC',
));
}
diff --git a/lib/storage/ondiskhashedstoragemanager.inc.php b/lib/storage/ondiskhashedstoragemanager.inc.php
index 8e1b8eb..e980853 100644
--- a/lib/storage/ondiskhashedstoragemanager.inc.php
+++ b/lib/storage/ondiskhashedstoragemanager.inc.php
@@ -8,7 +8,7 @@
* KnowledgeTree Community Edition
* Document Management Made Simple
* Copyright (C) 2008, 2009, 2010 KnowledgeTree Inc.
- *
+ *
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 3 as published by the
@@ -176,6 +176,20 @@ class KTOnDiskHashedStorageManager extends KTStorageManager {
return sprintf("%s/%s", $oConfig->get('urls/documentRoot'), $this->getPath($oDocument));
}
+ function temporaryFileForVersion($iVersionId) {
+ $oConfig =& KTConfig::getSingleton();
+
+ // get path to the content version
+ $oContentVersion = KTDocumentContentVersion::get($iVersionId);
+ $sPath = sprintf("%s/%s", $oConfig->get('urls/documentRoot'), $this->getPath($oContentVersion));
+
+ // Ensure the file exists
+ if (file_exists($sPath)) {
+ return $sPath;
+ }
+ return false;
+ }
+
function freeTemporaryFile($sPath) {
// Storage uses file-on-filesystem for temporaryFile
return;
diff --git a/sql/mysql/install/structure.sql b/sql/mysql/install/structure.sql
index ff5db61..5883e56 100644
--- a/sql/mysql/install/structure.sql
+++ b/sql/mysql/install/structure.sql
@@ -633,8 +633,8 @@ CREATE TABLE `download_files` (
`session` varchar(100) NOT NULL,
`download_date` timestamp NULL default CURRENT_TIMESTAMP,
`downloaded` int(10) unsigned NOT NULL default '0',
- `filesize` int(10) unsigned NOT NULL,
- `content_version` int(10) unsigned NOT NULL,
+ `filesize` int(10) unsigned,
+ `content_version` int(10) unsigned,
`hash` varchar(100) NOT NULL,
PRIMARY KEY (`document_id`,`session`),
CONSTRAINT `download_files_ibfk_1` FOREIGN KEY (`document_id`) REFERENCES `documents` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
diff --git a/sql/mysql/upgrade/3.7.0.4/download_files.sql b/sql/mysql/upgrade/3.7.0.4/download_files.sql
new file mode 100644
index 0000000..ca50ef9
--- /dev/null
+++ b/sql/mysql/upgrade/3.7.0.4/download_files.sql
@@ -0,0 +1 @@
+ALTER TABLE download_files CHANGE COLUMN content_version content_version int(10) unsigned, CHANGE COLUMN filesize filesize int(10) unsigned;
\ No newline at end of file
diff --git a/tests/runtests.php b/tests/runtests.php
index 6e99b4f..39ab51e 100644
--- a/tests/runtests.php
+++ b/tests/runtests.php
@@ -36,12 +36,12 @@ class UnitTests extends TestSuite {
// if Electronic Signatures are NOT enabled for the API, new tests may not
// include the check which allows the tests to be bypassed when esignatures
// are not on, so if you have failures, check there first :)
- $this->addFile('api/testElectronicSignatures.php');
+// $this->addFile('api/testElectronicSignatures.php');
// Web Service tests
$this->addFile('webservices/testRest.php');
- $this->addFile('webservices/testSoap.php');
-
+ $this->addFile('webservices/testSoap.php');
+
// $this->addFile('SQLFile/test_sqlfile.php');
// $this->addFile('cache/testCache.php');
// $this->addFile('config/testConfig.php');
diff --git a/tests/webservices/testSoap.php b/tests/webservices/testSoap.php
index 855194a..6762d66 100644
--- a/tests/webservices/testSoap.php
+++ b/tests/webservices/testSoap.php
@@ -16,10 +16,14 @@ class SOAPTestCase extends KTUnitTestCase {
* @var string $rootUrl The root server url for the rest web service
*/
var $rootUrl;
-
+ var $uploads_dir;
+
public $client;
private $user;
private $pass;
+ private $content = 'New document for testing the soap webservice api';
+ private $content_update = 'Updated document for testing the soap webservice api';
+ private $reason = 'Running unit tests';
/**
* This method sets up the server url
@@ -31,6 +35,10 @@ class SOAPTestCase extends KTUnitTestCase {
$this->rootUrl = $url.'/ktwebservice/webservice.php?';
$this->user = isset($_GET['user']) ? $_GET['user'] : 'admin';
$this->pass = isset($_GET['pass']) ? $_GET['pass'] : 'admin';
+
+ // Login and authenticate
+ $this->connect();
+ $this->login('127.0.0.1');
}
/**
@@ -38,15 +46,17 @@ class SOAPTestCase extends KTUnitTestCase {
*/
public function tearDown()
{
+ // Logout
+ $this->logout();
}
- function connect()
+ private function connect()
{
$wsdl = $this->rootUrl . "wsdl";
$this->client = new SoapClient($wsdl);
}
- function login($ip = null)
+ private function login($ip = null)
{
$res = $this->client->__soapCall("login", array($this->user, $this->pass, $ip));
if($res->status_code != 0){
@@ -55,67 +65,210 @@ class SOAPTestCase extends KTUnitTestCase {
$this->session = $res->message;
}
+ private function logout()
+ {
+ $result = $this->client->__soapCall("logout", array($this->session));
+ if($result->status_code != 0){
+ return true;
+ }
+ }
- function getDocTypes()
+ private function getDocTypes()
{
$result = $this->client->__soapCall("get_document_types", array($this->session));
return $result->document_types;
}
- function search($expr)
+ private function search($expr)
{
$result = $this->client->__soapCall("search", array($this->session, $expr, ''));
return $result->hits;
}
- function getFolderDetail($folder, $parentId = 1)
+ private function getFolderDetail($folder, $parentId = 1)
{
$result = $this->client->__soapCall("get_folder_detail_by_name", array($this->session, $folder, $parentId));
return $result;
}
- function createFolder($parent_id, $folder)
+ private function createFolder($parent_id, $folder)
{
$result = $this->client->__soapCall("create_folder", array($this->session, $parent_id, $folder));
return $result;
}
- function deleteFolder($folder_id)
+ private function createFolderShortcut($target_folder_id, $source_folder_id)
{
- $result = $this->client->__soapCall("delete_folder", array($this->session, "$folder_id", 'Testing'));
+ $result = $this->client->__soapCall("create_folder_shortcut", array($this->session, $target_folder_id, $source_folder_id));
return $result;
}
- function logout()
+ private function deleteFolder($folder_id)
{
- $result = $this->client->__soapCall("logout", array($this->session));
- if($result->status_code != 0){
- return true;
- }
+ $result = $this->client->__soapCall("delete_folder", array($this->session, $folder_id, 'Testing'));
+ return $result;
+ }
+
+ private function getFolderShortcuts($folder_id)
+ {
+ $result = $this->client->__soapCall("get_folder_shortcuts", array($this->session, $folder_id));
+ return $result;
+ }
+
+ private function getDocumentVersionHistory($document_id)
+ {
+ $result = $this->client->__soapCall("get_document_version_history", array($this->session, $document_id));
+ return $result;
+ }
+
+ private function createDocument($folder_id, $title, $filename, $documenttype = 'Default')
+ {
+ global $default;
+ $uploads_dir = $default->uploadDirectory;
+
+ // create document in uploads folder
+ $tempfilename = tempnam($uploads_dir, 'myfile');
+ $fp = fopen($tempfilename, 'wt');
+ fwrite($fp, $this->content);
+ fclose($fp);
+
+ // call add document to upload into repo
+ $result = $this->client->__soapCall("add_document", array($this->session, $folder_id, $title, $filename, $documenttype, $tempfilename));
+ return $result;
+ }
+
+ private function createSmallDocument($folder_id, $title, $filename, $documenttype = 'Default')
+ {
+ global $default;
+ $uploads_dir = $default->uploadDirectory;
+
+ // create document in uploads folder
+ $base64 = base64_encode($this->content);
+
+ // call add document to upload into repo
+ $result = $this->client->__soapCall("add_small_document", array($this->session, $folder_id, $title, $filename, $documenttype, $base64));
+ return $result;
+ }
+
+ private function checkinDocument($document_id, $filename, $major_update = false)
+ {
+ global $default;
+ $uploads_dir = $default->uploadDirectory;
+
+ // create document in uploads folder
+ $tempfilename = tempnam($uploads_dir, 'myfile');
+ $fp = fopen($tempfilename, 'wt');
+ fwrite($fp, $this->content_update);
+ fclose($fp);
+
+ // call add document to upload into repo
+ $result = $this->client->__soapCall("checkin_document", array($this->session, $document_id, $filename, $this->reason, $tempfilename, $major_update));
+ return $result;
+ }
+
+ private function checkinSmallDocument($document_id, $filename, $major_update = false)
+ {
+ global $default;
+ $uploads_dir = $default->uploadDirectory;
+
+ // encode as base64
+ $base64 = base64_encode($this->content_update);
+
+ // call add document to upload into repo
+ $result = $this->client->__soapCall("checkin_small_document", array($this->session, $document_id, $filename, $this->reason, $base64, $major_update));
+ return $result;
}
-
- // now the test functions
-
+
+ private function checkoutDocument($document_id, $download = true)
+ {
+ $result = $this->client->__soapCall("checkout_document", array($this->session, $document_id, $this->reason, $download));
+ return $result;
+ }
+
+ private function checkoutSmallDocument($document_id, $download = true)
+ {
+ $result = $this->client->__soapCall("checkout_small_document", array($this->session, $document_id, $this->reason, $download));
+ return $result;
+ }
+
+ private function createDocumentShortcut($folder_id, $target_document_id)
+ {
+ $result = $this->client->__soapCall("create_document_shortcut", array($this->session, $folder_id, $target_document_id));
+ return $result;
+ }
+
+ private function getDocumentShortcuts($document_id)
+ {
+ $result = $this->client->__soapCall("get_document_shortcuts", array($this->session, $document_id));
+ return $result;
+ }
+
+ private function getFolderContents($folder_id, $depth=1, $what='DFS')
+ {
+ $result = $this->client->__soapCall("get_folder_contents", array($this->session, $folder_id, $depth, $what));
+ return $result;
+ }
+
+ private function getDocumentMetadata($document_id, $version = null)
+ {
+ $result = $this->client->__soapCall("get_document_metadata", array($this->session, $document_id, $version));
+ return $result;
+ }
+
+ private function updateDocumentMetadata($document_id, $metadata, $sysdata=null)
+ {
+ $result = $this->client->__soapCall("update_document_metadata", array($this->session, $document_id, $metadata, $sysdata));
+ return $result;
+ }
+
+ private function downloadDocument($document_id, $version = null)
+ {
+ $result = $this->client->__soapCall("download_document", array($this->session, $document_id, $version));
+ return $result;
+ }
+
+ private function downloadSmallDocument($document_id, $version = null)
+ {
+ $result = $this->client->__soapCall("download_small_document", array($this->session, $document_id, $version));
+ return $result;
+ }
+
+ private function doDownload($url)
+ {
+ $ch = curl_init($url);
+ curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch,CURLOPT_SSL_VERIFYHOST, false);
+ curl_setopt($ch,CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
+
+ $download = curl_exec($ch);
+ $status = curl_getinfo($ch,CURLINFO_HTTP_CODE);
+
+ $error = curl_errno($ch);
+
+ curl_close($ch);
+
+ return array('status' => $status, 'error' => $error, 'download' => $download);
+ }
+
+ /* *** now the test functions *** */
+
/**
* Tests finding of a folder or folder detail by name
* Runs the following sub-tests:
* . Folder Detail by Name in root folder (no duplicate names)
* . Folder Detail by Name in subfolder of root folder (no duplicate names)
* . Folder Detail by Name in subfolder of root folder (duplicate names)
- *
+ *
* NOTE there are less tests here because we cannot test the get_folder_by_name function since it does not exist within the web service code
*/
public function testGetFolderByName()
{
- // Login and authenticate
- $this->connect();
- $this->login('127.0.0.1');
-
// set up
$root_folder_id = array();
$sub_folder_id = array();
$folders[0][1] = 'Root Folder';
-
+
// Create a sub folder in the root folder
$parentId = 1;
$folderName = 'Test api sub-folder ONE';
@@ -124,7 +277,7 @@ class SOAPTestCase extends KTUnitTestCase {
$folders[$parentId][$response->id] = $folderName;
$this->assertEqual($response->status_code, 0);
$this->assertFalse(!empty($response->message));
-
+
// Create a second sub folder in the root folder
$parentId = 1;
$folderName = 'Test api sub-folder TWO';
@@ -133,7 +286,7 @@ class SOAPTestCase extends KTUnitTestCase {
$folders[$parentId][$response->id] = $folderName;
$this->assertEqual($response->status_code, 0);
$this->assertFalse(!empty($response->message));
-
+
// Create a sub folder in the first sub folder
$parentId = $root_folder_id[0];
$folderName = 'Test api sub-folder THREE';
@@ -142,7 +295,7 @@ class SOAPTestCase extends KTUnitTestCase {
$folders[$parentId][$response->id] = $folderName;
$this->assertEqual($response->status_code, 0);
$this->assertFalse(!empty($response->message));
-
+
// Create a sub folder within the first sub folder which shares a name with one of the root sub folders
$parentId = $sub_folder_id[0][0];
$folderName = 'Test api sub-folder TWO';
@@ -151,7 +304,7 @@ class SOAPTestCase extends KTUnitTestCase {
$folders[$parentId][$response->id] = $folderName;
$this->assertEqual($response->status_code, 0);
$this->assertFalse(!empty($response->message));
-
+
// Create a second sub folder in the first sub folder
$parentId = $root_folder_id[0];
$folderName = 'Test api sub-folder FOUR';
@@ -169,7 +322,7 @@ class SOAPTestCase extends KTUnitTestCase {
$folders[$parentId][$response->id] = $folderName;
$this->assertEqual($response->status_code, 0);
$this->assertFalse(!empty($response->message));
-
+
// Create a sub folder within the second sub folder which shares a name with a sub folder in the first sub folder
$parentId = $sub_folder_id[1][0];
$folderName = 'Test api sub-folder THREE';
@@ -180,7 +333,7 @@ class SOAPTestCase extends KTUnitTestCase {
$this->assertFalse(!empty($response->message));
// NOTE default parent is 1, so does not need to be declared when searching the root folder, but we use it elsewhere
-
+
// Fetching of root folder
$parentId = 0;
$folderName = 'Root Folder';
@@ -190,7 +343,7 @@ class SOAPTestCase extends KTUnitTestCase {
if (($response->status_code == 0)) {
$this->assertEqual($folders[$parentId][$response->id], $folderName);
}
-
+
// Folder Detail by Name in root folder (no duplicate names)
$parentId = 1;
$folderName = 'Test api sub-folder ONE';
@@ -201,7 +354,7 @@ class SOAPTestCase extends KTUnitTestCase {
if (($response->status_code == 0)) {
$this->assertEqual($folders[$parentId][$response->id], $folderName);
}
-
+
// Folder Detail by Name in sub folder of root folder (no duplicate names)
$parentId = $root_folder_id[0];
$folderName = 'Test api sub-folder FOUR';
@@ -211,7 +364,7 @@ class SOAPTestCase extends KTUnitTestCase {
if (($response->status_code == 0)) {
$this->assertEqual($folders[$parentId][$response->id], $folderName);
}
-
+
// Folder Detail by Name in root folder (duplicate names)
$parentId = 1;
$folderName = 'Test api sub-folder TWO';
@@ -221,7 +374,7 @@ class SOAPTestCase extends KTUnitTestCase {
if (($response->status_code == 0)) {
$this->assertEqual($folders[$parentId][$response->id], $folderName);
}
-
+
// Folder Detail by Name in sub folder of root folder (duplicate names)
$parentId = $root_folder_id[0];
$folderName = 'Test api sub-folder THREE';
@@ -231,7 +384,7 @@ class SOAPTestCase extends KTUnitTestCase {
if (($response->status_code == 0)) {
$this->assertEqual($folders[$parentId][$response->id], $folderName);
}
-
+
// Negative test with non duplicated folder - look for folder in location it does not exist
$parentId = $root_folder_id[0];
$folderName = 'Test api sub-folder ONE';
@@ -239,7 +392,7 @@ class SOAPTestCase extends KTUnitTestCase {
$this->assertNotEqual($response->status_code, 0);
$this->assertTrue(!empty($response->message));
$this->assertNotEqual($folders[$parentId][$response->id], $folderName);
-
+
// Negative test with duplicated folder - look for folder with incorrect parent id, result should not match expected folder
$parentId = 1;
$actualParentId = $sub_folder_id[0][0];
@@ -251,15 +404,511 @@ class SOAPTestCase extends KTUnitTestCase {
// but not the one we wanted
$expectedResponse = $this->getFolderDetail($folderName, $actualParentId);
$this->assertNotEqual($response->id, $expectedResponse->id);
-
+
// Clean up - delete all of the folders
foreach ($root_folder_id as $folder_id) {
$this->deleteFolder($folder_id);
}
-
- // Logout
- $this->logout();
}
+ /**
+ * Tests the creation of folders and folder shortcuts, getting the folder shortcut(s)
+ * WebService V3 and higher
+ */
+ public function testCreateFolderShortcut()
+ {
+ // if V3
+ if(LATEST_WEBSERVICE_VERSION < 3){
+ return ;
+ }
+
+ // Create folder 1
+ $result = $this->createFolder(1, 'Test Shortcut Container');
+ $this->assertEqual($result->status_code, 0, 'Create folder - '.$result->message);
+ $parentFolderId = $result->id;
+
+ // Create folder 2
+ $result = $this->createFolder(1, 'Test Shortcut Target');
+ $this->assertEqual($result->status_code, 0, 'Create folder - '.$result->message);
+ $targetFolderId = $result->id;
+
+ // Create folder 3
+ $result = $this->createFolder($targetFolderId, 'Test Shortcut Target 2');
+ $this->assertEqual($result->status_code, 0, 'Create folder - '.$result->message);
+ $target2FolderId = $result->id;
+
+ // Create shortcut in folder 1 targeting folder 2
+ $result = $this->createFolderShortcut($parentFolderId, $targetFolderId);
+ $this->assertEqual($result->status_code, 0, 'Create folder Shortcut - '.$result->message);
+
+ $shortcutId = $result->id;
+ $linkedFolderId = $result->linked_folder_id;
+ $this->assertTrue(is_numeric($shortcutId), 'Shortcut id should be numeric');
+ $this->assertTrue(is_numeric($linkedFolderId), 'Linked folder id should be numeric');
+ $this->assertEqual($linkedFolderId, $targetFolderId, 'Shortcut should contain link the target folder');
+
+ // Create shortcut in folder 1 targeting folder 3
+ $result = $this->createFolderShortcut($parentFolderId, $target2FolderId);
+ $this->assertEqual($result->status_code, 0, 'Create folder shortcut - '.$result->message);
+
+ $shortcut2Id = $result->id;
+ $linkedFolder2Id = $result->linked_folder_id;
+ $this->assertTrue(is_numeric($shortcut2Id), 'Shortcut id should be numeric');
+ $this->assertTrue(is_numeric($linkedFolder2Id), 'Linked folder id should be numeric');
+ $this->assertEqual($linkedFolder2Id, $target2FolderId, 'Shortcut should contain link the target folder');
+
+ // Get the folder shortcut details
+ $result = $this->getFolderShortcuts($targetFolderId);
+ $this->assertEqual($result->status_code, 0, 'Should return list of folder shortcuts - '.$result->message);
+
+ $shortcuts = $result[1];
+ foreach ($shortcuts as $item) {
+ $this->assertEqual($item->id, $shortcutId);
+ $this->assertEqual($item->linked_folder_id, $targetFolderId);
+ }
+
+ $result = $this->getFolderShortcuts($target2FolderId);
+ $this->assertEqual($result->status_code, 0, 'Should return list of folder shortcuts - '.$result->message);
+
+ $shortcuts2 = $result[1];
+ foreach ($shortcuts2 as $item) {
+ $this->assertEqual($item->id, $shortcut2Id);
+ $this->assertEqual($item->linked_folder_id, $target2FolderId);
+ }
+
+ // delete and cleanup
+ $this->deleteFolder($parentFolderId);
+ $this->deleteFolder($targetFolderId);
+ }
+
+ /**
+ * Tests the document upload and the creation and retrieval of document shortcuts
+ * WS V3
+ */
+ public function testCreateDocumentShortcut()
+ {
+ // if V3
+ if(LATEST_WEBSERVICE_VERSION < 3){
+ //$this->assertEqual(LATEST_WEBSERVICE_VERSION, 3, 'Webservice version is less than 3. Exiting test, functionality is V3 only');
+ return ;
+ }
+
+ // Create folder 1 containing the shortcut
+ $result = $this->createFolder(1, 'Test Shortcut Container');
+ $this->assertEqual($result->status_code, 0, 'Create folder - '.$result->message);
+ $parentFolderId = $result->id;
+
+ // Create folder 2 containing the document
+ $result = $this->createFolder(1, 'Test Shortcut Target');
+ $this->assertEqual($result->status_code, 0, 'Create folder - '.$result->message);
+ $targetFolderId = $result->id;
+
+ // Upload document to folder 2
+ $result = $this->createDocument($targetFolderId, 'Target Doc', 'target.txt');
+ $this->assertEqual($result->status_code, 0, 'Create document - '.$result->message);
+ $documentId = $result->document_id;
+ $this->assertTrue(is_numeric($documentId), 'Document id should be numeric');
+
+ // Create shortcut in folder 1, pointing to the document in folder 2
+ $result = $this->createDocumentShortcut($parentFolderId, $documentId);
+ $this->assertEqual($result->status_code, 0, 'Create document shortcut - '.$result->message);
+ $shortcutId = $result->document_id;
+ $linkedDocumentId = $result->linked_document_id;
+ $this->assertTrue(is_numeric($shortcutId), 'Shortcut id should be numeric');
+ $this->assertTrue(is_numeric($linkedDocumentId), 'Linked document id should be numeric');
+ $this->assertEqual($linkedDocumentId, $documentId, 'Shortcut should contain link to the target document');
+
+ // delete and cleanup
+ $this->deleteFolder($parentFolderId);
+ $this->deleteFolder($targetFolderId);
+ }
+
+ /**
+ * Tests document uploads, checkin / checkout, downloads and document version downloads (V3)
+ * Normal documents and small / base64 documents
+ */
+ public function testUploadDownloadDocument()
+ {
+ // Create folder containing the documents
+ $result = $this->createFolder(1, 'Test Container');
+ $this->assertEqual($result->status_code, 0, 'Create folder - '.$result->message);
+ $folderId = $result->id;
+
+ // Upload document to folder
+ $filename = 'test_doc.txt';
+ $result = $this->createDocument($folderId, 'Test Doc', $filename);
+ $this->assertEqual($result->status_code, 0, 'Create document - '.$result->message);
+ $documentId = $result->document_id;
+ $this->assertTrue(is_numeric($documentId), 'Document id should be numeric');
+
+ // Get the download url for the document
+ $result = $this->downloadDocument($documentId);
+ $this->assertEqual($result->status_code, 0, 'Get document download url - '.$result->message);
+ $url = $result->message;
+ $this->assertTrue(is_string($url), 'URL should be a string');
+ $this->assertTrue(strpos($url, 'http') !== false, 'URL should contain http');
+
+ // Download the document
+ $result = $this->doDownload($url);
+ $this->assertEqual($result['status'], 200, 'Status should be code 200 for success - '.$result['status']);
+ $this->assertEqual($result['error'], 0, 'Error code should be 0 for success - '.$result['error']);
+ $this->assertEqual($result['download'], $this->content, 'Document content should be the same as that uploaded');
+
+ // ----------
+
+ // Upload base64 document to folder
+ $filename2 = 'test_base64_doc.txt';
+ $result = $this->createSmallDocument($folderId, 'Test Base64 Doc', $filename2);
+ $this->assertEqual($result->status_code, 0, 'Create base64 document - '.$result->message);
+ $documentId2 = $result->document_id;
+ $this->assertTrue(is_numeric($documentId2), 'Document id should be numeric');
+
+ // Download base64 document
+ $result = $this->downloadSmallDocument($documentId2);
+ $this->assertEqual($result->status_code, 0, 'Download small document - '.$result->message);
+ $content = $result->message;
+ $this->assertTrue(is_string($content), 'Content should be a string');
+ $content = base64_decode($content);
+ $this->assertEqual($content, $this->content, 'Document content should be the same as that uploaded');
+
+ if(LATEST_WEBSERVICE_VERSION < 3){
+ // delete and cleanup
+ $this->deleteFolder($folderId);
+ return ;
+ }
+
+ /* *** V3 functions *** */
+
+ // Checkout first document
+ $result = $this->checkoutDocument($documentId);
+ $this->assertEqual($result->status_code, 0, 'Checkout document - '.$result->message);
+ $checkoutBy = $result->checked_out_by;
+ $checkoutDate = $result->checked_out_date;
+ $url = $result->message;
+ $this->assertFalse(is_null($checkoutDate), 'Checked out date should not be null / empty - '.$checkoutDate);
+ $this->assertEqual($checkoutBy, 'Administrator', 'Using the Administrative user, checked out user must match - '.$checkoutBy);
+ $this->assertTrue(is_string($url), 'Download URL should be a string');
+ $this->assertTrue(strpos($url, 'http') !== false, 'Download URL should contain http');
+
+ // Download the document
+ $result = $this->doDownload($url);
+ $content = $result['download'];
+ $this->assertEqual($result['status'], 200, 'Status should be code 200 for success - '.$result['status']);
+ $this->assertEqual($result['error'], 0, 'Error code should be 0 for success - '.$result['error']);
+ $this->assertEqual($result['download'], $this->content, 'Document content should be the same as that uploaded');
+
+ // ----------
+
+ // Checkin a new version
+ $result = $this->checkinDocument($documentId, $filename);
+ $this->assertEqual($result->status_code, 0, 'Checkin document - '.$result->message);
+ $checkoutBy = $result->checked_out_by;
+ $this->assertTrue(empty($checkoutBy) || $checkoutBy == 'n/a', 'Document should no longer be checked out by anyone - '.$checkoutBy);
+
+ // Download new version
+ $result = $this->downloadDocument($documentId);
+ $this->assertEqual($result->status_code, 0, 'Get checkedin document download url - '.$result->message);
+ $url = $result->message;
+
+ // Download the document
+ $result = $this->doDownload($url);
+ $this->assertEqual($result['download'], $this->content_update, 'Document content should be the same as the updated content');
+
+ // ----------
+
+ // Get previous versions of the document
+ $result = $this->getDocumentVersionHistory($documentId);
+ $this->assertEqual($result->status_code, 0, 'Get document version history - '.$result->message);
+ $history = $result->history;
+ $this->assertTrue(is_array($history), 'Version history should be an array');
+ $this->assertEqual(count($history), 2, 'Version history should contain 2 items / versions');
+
+ // Get the previous version number
+ $version = isset($history[1]) ? $history[1]->content_version : null;
+
+ // Download previous version
+ $result = $this->downloadDocument($documentId, $version);
+ $this->assertEqual($result->status_code, 0, "Get document download url for previous version ($version) - ".$result->message);
+ $url = $result->message;
+
+ // Download the document
+ $result = $this->doDownload($url);
+ $this->assertEqual($result['status'], 200, 'Status should be code 200 for success - '.$result['status']);
+ $this->assertEqual($result['error'], 0, 'Error code should be 0 for success - '.$result['error']);
+ $this->assertEqual($result['download'], $this->content, 'Document content should be the same as the original content of the initial upload');
+
+ // ----------
+
+ // Checkout base64 document
+ $result = $this->checkoutSmallDocument($documentId2);
+ $this->assertEqual($result->status_code, 0, 'Checkout base64 document - '.$result->message);
+ $checkoutBy = $result->checked_out_by;
+ $checkoutDate = $result->checked_out_date;
+ $content = $result->message;
+ $this->assertFalse(is_null($checkoutDate), 'Checked out date should not be null / empty - '.$checkoutDate);
+ $this->assertEqual($checkoutBy, 'Administrator', 'Using the Administrative user, checked out user must match - '.$checkoutBy);
+ $this->assertTrue(is_string($content), 'Base64 content should be a string');
+ $content = base64_decode($content);
+ $this->assertEqual($content, $this->content, 'Document content should be the same as that uploaded');
+
+ // ----------
+
+ // Checkin a new base64 version
+ $result = $this->checkinSmallDocument($documentId2, $filename2);
+ $this->assertEqual($result->status_code, 0, 'Checkin base64 document - '.$result->message);
+ $checkoutBy = $result->checked_out_by;
+ $this->assertTrue(empty($checkoutBy) || $checkoutBy == 'n/a', 'Document should no longer be checked out by anyone - '.$checkoutBy);
+
+ // Download new version
+ $result = $this->downloadSmallDocument($documentId2);
+ $this->assertEqual($result->status_code, 0, 'Download checkedin base64 document - '.$result->message);
+ $content = $result->message;
+ $this->assertTrue(is_string($content), 'Content should be a string');
+ $content = base64_decode($content);
+ $this->assertEqual($content, $this->content_update, 'Document content should be the same as the updated content');
+
+ // ----------
+
+ // Get previous versions of the base64 document
+ $result = $this->getDocumentVersionHistory($documentId2);
+ $this->assertEqual($result->status_code, 0, 'Get document version history - '.$result->message);
+ $history = $result->history;
+ $this->assertTrue(is_array($history), 'Version history should be an array');
+ $this->assertEqual(count($history), 2, 'Version history should contain 2 items / versions');
+
+ // Get the previous version number
+ $version = isset($history[1]) ? $history[1]->content_version : null;
+
+ // Download previous version
+ $result = $this->downloadSmallDocument($documentId2, $version);
+ $this->assertEqual($result->status_code, 0, "Download previous version ($version) - ".$result->message);
+ $content = $result->message;
+ $this->assertTrue(is_string($content), 'Content should be a string');
+ $content = base64_decode($content);
+ $this->assertEqual($content, $this->content, 'Document content should be the same as the original content of the initial upload');
+
+ // delete and cleanup
+ $this->deleteFolder($folderId);
+ }
+
+ /**
+ * Tests getting and updating document metadata
+ */
+ public function testDocumentMetadata()
+ {
+ // Create folder containing the documents
+ $result = $this->createFolder(1, 'Test Metadata Container');
+ $this->assertEqual($result->status_code, 0, 'Create folder - '.$result->message);
+ $folderId = $result->id;
+
+ // Upload document to folder
+ $filename = 'test_doc.txt';
+ $result = $this->createDocument($folderId, 'Test Doc', $filename);
+ $this->assertEqual($result->status_code, 0, 'Create document - '.$result->message);
+ $documentId = $result->document_id;
+ $this->assertTrue(is_numeric($documentId), 'Document id should be numeric');
+
+ // get document metadata
+ $result = $this->getDocumentMetadata($documentId);
+ $this->assertEqual($result->status_code, 0, 'Get document metadata - '.$result->message);
+ $metadata = $result->metadata;
+ $this->assertTrue(is_array($metadata), 'Returned document metadata should be an array of fieldsets');
+
+ // Add a new tag and a document author
+ foreach ($metadata as $fieldset){
+ $fields = $fieldset->fields;
+ switch($fieldset->fieldset){
+ case 'Tag Cloud':
+ $field_name = 'Tag';
+ $curr_val = 'n/a';
+ $new_val = 'unit test';
+ break;
+ case 'General information':
+ $field_name = 'Document Author';
+ $curr_val = 'n/a';
+ $new_val = 'Test Framework';
+ break;
+ }
+
+ foreach ($fields as $field){
+ if($field->name == $field_name){
+ $this->assertEqual($field->value, $curr_val, "The current value of the given field, $field_name, should be \"$curr_val\"");
+ // update the value
+ $field->value = $new_val;
+ }
+ if($field->value == 'n/a'){
+ $field->value = '';
+ }
+ }
+ }
+
+ // update metadata
+ $result = $this->updateDocumentMetadata($documentId, $metadata);
+
+ // get metadata - ensure it matches the updated metadata
+ $result = $this->getDocumentMetadata($documentId);
+ $this->assertEqual($result->status_code, 0, 'Get document metadata - '.$result->message);
+ $metadata = $result->metadata;
+ $this->assertTrue(is_array($metadata), 'Returned document metadata should be an array of fieldsets');
+
+ // Add a new tag and a document author
+ foreach ($metadata as $fieldset){
+ $fields = $fieldset->fields;
+ switch($fieldset->fieldset){
+ case 'Tag Cloud':
+ $field_name = 'Tag';
+ $curr_val = 'unit test';
+ break;
+ case 'General information':
+ $field_name = 'Document Author';
+ $curr_val = 'Test Framework';
+ break;
+ }
+
+ foreach ($fields as $field){
+ if($field->name == $field_name){
+ $this->assertEqual($field->value, $curr_val, "The current value of the given field, $field_name, should be the same as the updated value: \"$curr_val\"");
+ }
+ }
+ }
+
+ // Get previous versions of the document
+ $result = $this->getDocumentVersionHistory($documentId);
+ $this->assertEqual($result->status_code, 0, 'Get document version history - '.$result->message);
+ $history = $result->history;
+ $this->assertTrue(is_array($history), 'Version history should be an array');
+ $this->assertEqual(count($history), 2, 'Version history should contain 2 items / versions');
+
+ // Get the previous version number
+ $version = isset($history[1]) ? $history[1]->metadata_version : null;
+
+ // get document metadata for previous version
+ $result = $this->getDocumentMetadata($documentId, $version);
+ $this->assertEqual($result->status_code, 0, 'Get document metadata - '.$result->message);
+ $metadata = $result->metadata;
+ $this->assertTrue(is_array($metadata), 'Returned document metadata should be an array of fieldsets');
+
+ // Add a new tag and a document author
+ foreach ($metadata as $fieldset){
+ $fields = $fieldset->fields;
+ switch($fieldset->fieldset){
+ case 'Tag Cloud':
+ $field_name = 'Tag';
+ $curr_val = 'n/a';
+ break;
+ case 'General information':
+ $field_name = 'Document Author';
+ $curr_val = 'n/a';
+ break;
+ }
+
+ foreach ($fields as $field){
+ if($field->name == $field_name){
+ $this->assertEqual($field->value, $curr_val, "The current value of the given field, $field_name, should be the same as the previous version's value: \"$curr_val\"");
+ }
+ }
+ }
+
+ // delete and cleanup
+ $this->deleteFolder($folderId);
+ }
+
+ /**
+ * Test getting the contents of a folder
+ *
+ */
+ public function testGetFolderListing()
+ {
+ // create folder
+ $main_folder = 'Test Listing Container';
+ $result = $this->createFolder(1, $main_folder);
+ $this->assertEqual($result->status_code, 0, 'Create folder - '.$result->message);
+ $folderId = $result->id;
+
+ // create subfolder 1
+ $sub_folder_name = 'Subfolder One';
+ $result = $this->createFolder($folderId, $sub_folder_name);
+ $this->assertEqual($result->status_code, 0, 'Create subfolder 1 - '.$result->message);
+ $subFolderId1 = $result->id;
+
+ // create subfolder 2
+ $result = $this->createFolder($folderId, 'Subfolder Two');
+ $this->assertEqual($result->status_code, 0, 'Create subfolder 2 - '.$result->message);
+ $subFolderId2 = $result->id;
+
+ // create subfolder 3 under subfolder 1
+ $result = $this->createFolder($subFolderId1, 'Subfolder Three');
+ $this->assertEqual($result->status_code, 0, 'Create subfolder 3 under subfolder 1 - '.$result->message);
+ $subFolderId3 = $result->id;
+
+ // upload document into main folder
+ $filename = 'test_doc.txt';
+ $result = $this->createDocument($folderId, 'Test Doc', $filename);
+ $this->assertEqual($result->status_code, 0, 'Create document 1 in folder - '.$result->message);
+ $documentId = $result->document_id;
+ $this->assertTrue(is_numeric($documentId), 'Document id should be numeric');
+
+ // upload document 2 into main folder
+ $filename2 = 'test_doc2.txt';
+ $result = $this->createDocument($folderId, 'Test Doc 2', $filename2);
+ $this->assertEqual($result->status_code, 0, 'Create document 1 in folder - '.$result->message);
+ $documentId2 = $result->document_id;
+ $this->assertTrue(is_numeric($documentId2), 'Document id should be numeric');
+
+ // upload document 3 into subfolder 1
+ $filename3 = 'test_doc3.txt';
+ $result = $this->createDocument($subFolderId1, 'Test Doc 3', $filename3);
+ $this->assertEqual($result->status_code, 0, 'Create document 1 in sub folder 1 - '.$result->message);
+ $documentId3 = $result->document_id;
+ $this->assertTrue(is_numeric($documentId3), 'Document id should be numeric');
+
+ // Get folder listing for folder 1 - folders only, depth of 1
+ $result = $this->getFolderContents($folderId, 1, 'F');
+ $this->assertEqual($result->status_code, 0, 'Get subfolders in folder - '.$result->message);
+ $folder_name = $result->folder_name;
+ $sub_folders = $result->items;
+ $this->assertEqual($folder_name, $main_folder, 'Folder name is - '.$folder_name);
+ $this->assertTrue(is_array($sub_folders), 'There should be an array of subfolders');
+ $this->assertEqual(count($sub_folders), 2, 'There should be 2 subfolders');
+
+ // Get folder listing for folder 1 - folders and documents, infinite depth
+ $result = $this->getFolderContents($folderId, 5, 'FD');
+ $this->assertEqual($result->status_code, 0, 'Get all subfolders and documents under the folder - '.$result->message);
+ $items = $result->items;
+ $this->assertTrue(is_array($items), 'There should be an array of subfolders and documents');
+ $this->assertEqual(count($items), 4, 'There should be 2 subfolders and 2 documents in the immediate folder');
+
+ // Loop through items, find sub folder 1
+ $docs = 0;
+ $folders = 0;
+ foreach ($items as $item){
+ // increment count of item type
+ $folders = ($item->item_type == 'F') ? $folders + 1 : $folders;
+ $docs = ($item->item_type == 'D') ? $docs + 1 : $docs;
+
+ if($item->id == $subFolderId1){
+ $sub_items = $item->items;
+
+ $this->assertTrue(is_array($sub_items), 'Subfolder 1 should contain an array of contents');
+ $this->assertEqual(count($sub_items), 2, 'Subfolder 1 should contain a folder and document');
+
+ }
+ }
+
+ $this->assertEqual($folders, 2, 'There should be 2 folders');
+ $this->assertEqual($docs, 2, 'There should be 2 documents');
+
+ // Get folder listing for subfolder 1 - documents only, depth of 1
+ $result = $this->getFolderContents($subFolderId1, 1, 'D');
+ $this->assertEqual($result->status_code, 0, 'Get documents under subfolder 1 - '.$result->message);
+ $folder_name = $result->folder_name;
+ $items = $result->items;
+ $this->assertEqual($folder_name, $sub_folder_name, 'Subfolder name is - '.$folder_name);
+ $this->assertTrue(is_array($items), 'There should be an array of documents');
+ $this->assertEqual(count($items), 1, 'There should be 1 document');
+
+ // delete and cleanup
+ $this->deleteFolder($folderId);
+ }
}
?>
\ No newline at end of file