diff --git a/ktapi/KTAPIAcl.inc.php b/ktapi/KTAPIAcl.inc.php
index cc776bd..fe80661 100644
--- a/ktapi/KTAPIAcl.inc.php
+++ b/ktapi/KTAPIAcl.inc.php
@@ -1719,7 +1719,7 @@ final class KTAPI_RoleAllocation extends KTAPI_AllocationBase
$roleAllocation = RoleAllocation::getAllocationsForFolderAndRole($objectId, $roleId);
- $res = $oRoleAllocation->delete();
+ $res = $roleAllocation->delete();
if (PEAR::isError($res))
{
return $res;
diff --git a/ktapi/KTAPIBulkActions.inc.php b/ktapi/KTAPIBulkActions.inc.php
index 65c2bee..349f469 100644
--- a/ktapi/KTAPIBulkActions.inc.php
+++ b/ktapi/KTAPIBulkActions.inc.php
@@ -63,7 +63,7 @@ class KTAPI_BulkActions
* @access public
* @param KTAPI $ktapi Instance of the KTAPI object
*/
- function __construct(&$ktapi)
+ public function __construct(&$ktapi)
{
$this->ktapi = $ktapi;
}
diff --git a/ktapi/KTAPIDocument.inc.php b/ktapi/KTAPIDocument.inc.php
index ca42950..7b7d7da 100644
--- a/ktapi/KTAPIDocument.inc.php
+++ b/ktapi/KTAPIDocument.inc.php
@@ -2438,7 +2438,7 @@ class KTAPI_Document extends KTAPI_FolderItem
$config = KTConfig::getSingleton();
$allowAttachment = $config->get('email/allowAttachment', false);
- $allowEmailAddresses = $oConfig->get('email/allowEmailAddresses', false);
+ $allowEmailAddresses = $config->get('email/allowEmailAddresses', false);
$emailErrors = array();
$userEmails = array();
diff --git a/ktapi/KTAPIFolder.inc.php b/ktapi/KTAPIFolder.inc.php
index 1daf537..4cb3415 100644
--- a/ktapi/KTAPIFolder.inc.php
+++ b/ktapi/KTAPIFolder.inc.php
@@ -1031,6 +1031,15 @@ class KTAPI_Folder extends KTAPI_FolderItem
DBUtil::rollback();
return new KTAPI_Error(KTAPI_ERROR_INTERNAL_ERROR, $result);
}
+
+ // regenerate internal folder object
+ $res = $this->updateObject();
+
+ if (PEAR::isError($res))
+ {
+ DBUtil::rollback();
+ return new KTAPI_Error(KTAPI_ERROR_INTERNAL_ERROR, $result);
+ }
DBUtil::commit();
}
@@ -1132,6 +1141,20 @@ class KTAPI_Folder extends KTAPI_FolderItem
return $this->folder;
}
+ /**
+ * Updates the Folder object
+ */
+ private function updateObject()
+ {
+ $folder = &Folder::get($this->folderid);
+ if (is_null($folder) || PEAR::isError($folder))
+ {
+ return new KTAPI_Error(KTAPI_ERROR_FOLDER_INVALID, $folder);
+ }
+
+ $this->folder = $folder;
+ }
+
/**
* Get the role allocation for the folder
*
diff --git a/ktapi/ktapi.inc.php b/ktapi/ktapi.inc.php
index 34d6050..9346042 100644
--- a/ktapi/ktapi.inc.php
+++ b/ktapi/ktapi.inc.php
@@ -288,6 +288,39 @@ class KTAPI
);
}
+
+ /**
+ * Returns folder permissions
+ *
+ * @access public
+ * @param string
+ * @param int
+ *
+ */
+ public function get_document_permissions($username, $document_id) {
+ if (is_null($this->session))
+ {
+ return array(
+ "status_code" => 1,
+ "message" => "Your session is not active"
+ );
+ }
+ /* We need to create a new instance of KTAPI to get another user */
+ $user_ktapi = new KTAPI();
+ $user_ktapi->start_system_session($username);
+
+ $document = KTAPI_Document::get($user_ktapi, $document_id);
+
+ $permissions = $document->getPermissionAllocation();
+
+ $user_ktapi->session_logout();
+
+ return array(
+ "status_code" => 0,
+ "results" => $permissions->permissions
+ );
+
+ }
/**
* Add folder permission
@@ -1137,8 +1170,646 @@ class KTAPI
return $subscriptions;
}
+ /**
+ * Perform a bulk action on a list of folders and documents
+ * Available actions are copy, move, delete, archive, checkout, undo_checkout and immute.
+ *
+ *
+ * $ktapi = new KTAPI();
+ * $session = $ktapi->start_system_session();
+ *
+ * $items = array();
+ * $items['documents'][] = $document_id;
+ * $items['folders'][] = $folder_id;
+ *
+ * $response = $ktapi->performBulkAction('move', $items, 'Reason for moving', $target_folder_id);
+ * if($response['status_code'] != 0) return 'ERROR';
+ *
+ *
+ *
+ * @author KnowledgeTree Team
+ * @access public
+ * @param string $action The action to be performed
+ * @param array $items A list of id's and item type in the format array('documents' => array(1,6), 'folders' => array(3,4))
+ * @param string $reason The reason for performing the action - only immute does not require a reason.
+ * @param integer $target_folder_id The id of the target folder if required - copy and move require this.
+ * @return array The response array. On success response['results'] will be empty | contain an array of failed items.
+ */
+ public function performBulkAction($action, $items, $reason = '', $target_folder_id = null)
+ {
+ $response['status_code'] = 1;
+
+ if(!is_array($items)){
+ $response['message'] = _kt("The list of id's must be an array of format array('documents' => array(1,2), 'folders' => array(2,3)). Received: {$items}");
+ return $response;
+ }
+
+ if(empty($items)){
+ $response['message'] = _kt('No items found to perform the action on.');
+ return $response;
+ }
+
+ if(!is_string($action)){
+ $response['message'] = _kt("The bulk action to perform must be a string. Received: {$action}");
+ return $response;
+ }
+
+ // Check that the action exists in the bulk actions class
+ $bulkActions = new ReflectionClass('KTAPI_BulkActions');
+ $methods = $bulkActions->getMethods();
+
+ $exists = false;
+ foreach ($methods as $method){
+ if($method->getName() == $action){
+ $actionMethod = $method;
+ $exists = true;
+ break;
+ }
+ }
+
+ if(!$exists) {
+ $response['message'] = _kt("The requested action has not been implemented: {$action}");
+ return $response;
+ }
+
+ // Create the document and folder objects
+ $objects = array();
+ if(isset($items['folders'])){
+ foreach($items['folders'] as $item) {
+ $folder = $this->get_folder_by_id($item);
+ $objects[] = $folder;
+ }
+ }
+
+ if(isset($items['documents'])){
+ foreach($items['documents'] as $item) {
+ $document = $this->get_document_by_id($item);
+ $objects[] = $document;
+ }
+ }
+
+ if(empty($objects)){
+ $response['message'] = _kt('No folder or document items found to perform the action on.');
+ return $response;
+ }
+
+ // perform the action
+ $ktapi_bulkactions = new KTAPI_BulkActions($this);
+
+ // Get target folder object if required
+ if(in_array($action, array('move', 'copy'))){
+ if(!is_int($target_folder_id) || empty($target_folder_id)){
+ $response['message'] = _kt('No target folder has been specified.');
+ return $response;
+ }
+ $target = $this->get_folder_by_id($target_folder_id);
+
+ // call the action
+ $result = $ktapi_bulkactions->$action($objects, $target, $reason);
+ }else if($action == 'immute'){
+ // call the action
+ $result = $ktapi_bulkactions->$action($objects);
+ }else {
+ // call the action
+ $result = $ktapi_bulkactions->$action($objects, $reason);
+ }
+
+ if(PEAR::isError($result)) {
+ $response['message'] = _kt("The bulk action failed: {$result->getMessage()}");
+ return $response;
+ }
+
+ // if failed items are returned - flatten the objects
+ if(is_array($result)){
+ if(isset($result['docs'])){
+ foreach ($result['docs'] as $key => $item){
+ $result['docs'][$key]['object'] = $item['object']->get_detail();
+ }
+ }
+ if(isset($result['folders'])){
+ foreach ($result['folders'] as $key => $item){
+ $result['folders'][$key]['object'] = $item['object']->get_detail();
+ }
+ }
+ }
+
+ // For a successful action
+ $response['status_code'] = 0;
+ $response['results'] = $result;
+ return $response;
+ }
+
+ /* *** ACL Roles and Role_Allocation *** */
+
+ /**
+ * Get a list of available roles
+ *
+ * @author KnowledgeTree Team
+ * @access public
+ * @param string $filter The beginning letter(s) of the role being searched for
+ * @return array Response.
+ */
+ public function get_roles($filter = null)
+ {
+ $response['status_code'] = 1;
+
+ // check the filter
+ if(!empty($filter)) {
+ if(!is_string($filter)){
+ $response['message'] = _kt('Filter should be a string.');
+ return $response;
+ }
+
+ // escape filter string - prevent sql injection
+ $filter = addslashes($filter);
+ $filter = "name like '{$filter}%'";
+ }
+
+ $listing = KTAPI_Role::getList($filter);
+
+ if(PEAR::isError($listing)){
+ $response['message'] = $listing->getMessage();
+ return $response;
+ }
+
+ // flatten role objects
+ $roles = array();
+ foreach ($listing as $ktapi_roll) {
+ $roles[] = array(
+ 'id' => $ktapi_roll->getId(),
+ 'name' => $ktapi_roll->getName(),
+ );
+ }
+
+ $response['status_code'] = 0;
+ $response['results'] = $roles;
+ return $response;
+ }
+
+ /**
+ * Get a role using its id
+ *
+ * @author KnowledgeTree Team
+ * @access public
+ * @param integer $role_id The id of the role
+ * @return array Response
+ */
+ public function get_role_by_id($role_id)
+ {
+ $response['status_code'] = 1;
+ if(!is_numeric($role_id)){
+ $response['message'] = _kt('Role id must be numeric.');
+ return $response;
+
+ }
+
+ $role = KTAPI_Role::getById($role_id);
+
+ if(PEAR::isError($role)) {
+ $response['message'] = $role->getMessage();
+ return $response;
+ }
+
+ $response['status_code'] = 0;
+ $response['results'] = array(
+ 'id' => $role->getId(),
+ 'name' => $role->getName()
+ );
+
+ return $response;
+ }
+
+ /**
+ * Get a role based on its name
+ *
+ * @author KnowledgeTree Team
+ * @access public
+ * @param string $role_name The name of the role
+ * @return array Response
+ */
+ public function get_role_by_name($role_name)
+ {
+ $response['status_code'] = 1;
+ if(!is_string($role_name)){
+ $response['message'] = _kt('Role name must be a string.');
+ return $response;
+
+ }
+
+ $role = KTAPI_Role::getByName($role_name);
+
+ if(PEAR::isError($role)) {
+ $response['message'] = $role->getMessage();
+ return $response;
+ }
+
+ $response['status_code'] = 0;
+ $response['results'] = array(
+ 'id' => $role->getId(),
+ 'name' => $role->getName()
+ );
+
+ return $response;
+ }
+
+ /**
+ * Get the list of role allocations on a folder
+ *
+ * @author KnowledgeTree Team
+ * @access public
+ * @param integar $folder_id The id of the folder
+ * @return array Response
+ */
+ public function get_role_allocation_for_folder($folder_id)
+ {
+ $response['status_code'] = 1;
+ if(!is_numeric($folder_id)){
+ $response['message'] = _kt('Folder id must be numeric.');
+ return $response;
+
+ }
+
+ $folder = $this->get_folder_by_id($folder_id);
+
+ if(PEAR::isError($folder)) {
+ $response['message'] = $folder->getMessage();
+ return $response;
+ }
+
+ $role_allocation = $folder->getRoleAllocation();
+
+ // flatten object
+ $membership = $role_allocation->getMembership();
+
+ $response['status_code'] = 0;
+ $response['results'] = $membership;
+ return $response;
+ }
+
+ /**
+ * Add a user to a role on a folder
+ *
+ * @author KnowledgeTree Team
+ * @access public
+ * @param integer $folder_id The folder id
+ * @param integer $role_id The id of the role being modified
+ * @param integer $user_id The id of the user to be added
+ * @return array Response
+ */
+ public function add_user_to_role_on_folder($folder_id, $role_id, $user_id)
+ {
+ $response['status_code'] = 1;
+ if(!is_numeric($user_id)){
+ $response['message'] = _kt('User id must be numeric.');
+ return $response;
+ }
+ $member['users'][] = $user_id;
+
+ return $this->add_members_to_role_on_folder($folder_id, $role_id, $member);
+ }
+
+ /**
+ * Add a group to a role on a folder
+ *
+ * @author KnowledgeTree Team
+ * @access public
+ * @param integer $folder_id The folder id
+ * @param integer $role_id The id of the role being modified
+ * @param integer $group_id The id of the group to be added
+ * @return array Response
+ */
+ public function add_group_to_role_on_folder($folder_id, $role_id, $group_id)
+ {
+ $response['status_code'] = 1;
+ if(!is_numeric($group_id)){
+ $response['message'] = _kt('Group id must be numeric.');
+ return $response;
+ }
+ $member['groups'][] = $group_id;
+
+ return $this->add_members_to_role_on_folder($folder_id, $role_id, $member);
+ }
+
+ /**
+ * Remove a user from a role on a folder
+ *
+ * @author KnowledgeTree Team
+ * @access public
+ * @param integer $folder_id The folder id
+ * @param integer $role_id The id of the role being modified
+ * @param integer $user_id The id of the user to be removed
+ * @return array Response
+ */
+ public function remove_user_from_role_on_folder($folder_id, $role_id, $user_id)
+ {
+ $response['status_code'] = 1;
+ if(!is_numeric($user_id)){
+ $response['message'] = _kt('User id must be numeric.');
+ return $response;
+ }
+ $member['users'][] = $user_id;
+
+ return $this->remove_members_from_role_on_folder($folder_id, $role_id, $member);
+ }
+
+ /**
+ * Remove a group from a role on a folder
+ *
+ * @author KnowledgeTree Team
+ * @access public
+ * @param integer $folder_id The folder id
+ * @param integer $role_id The id of the role being modified
+ * @param integer $group_id The id of the group to be removied
+ * @return array Response
+ */
+ public function remove_group_from_role_on_folder($folder_id, $role_id, $group_id)
+ {
+ $response['status_code'] = 1;
+ if(!is_numeric($group_id)){
+ $response['message'] = _kt('Group id must be numeric.');
+ return $response;
+ }
+ $member['groups'][] = $group_id;
+
+ return $this->remove_members_from_role_on_folder($folder_id, $role_id, $member);
+ }
+
+ /**
+ * Remove members (user, group) from a role on a folder
+ *
+ * @author KnowledgeTree Team
+ * @access public
+ * @param integer $folder_id The folder id
+ * @param integer $role_id The id of the role being modified
+ * @param array $members The list of id's of members to be removed - array('users' => array(1,2), 'groups' => array(2,4))
+ * @return array Response
+ */
+ public function remove_members_from_role_on_folder($folder_id, $role_id, $members)
+ {
+ return $this->update_members_on_role_on_folder($folder_id, $role_id, $members, 'remove');
+ }
+
+ /**
+ * Add members (user, group) to a role on a folder
+ *
+ * @author KnowledgeTree Team
+ * @access public
+ * @param integer $folder_id The folder id
+ * @param integer $role_id The id of the role being modified
+ * @param array $members The list of id's of members to be added - array('users' => array(1,2), 'groups' => array(2,4))
+ * @return array Response
+ */
+ public function add_members_to_role_on_folder($folder_id, $role_id, $members)
+ {
+ return $this->update_members_on_role_on_folder($folder_id, $role_id, $members, 'add');
+ }
+
+ /**
+ * Add / remove members (user, group) to / from a role on a folder
+ *
+ * @author KnowledgeTree Team
+ * @access private
+ * @param integer $folder_id The folder id
+ * @param integer $role_id The id of the role being modified
+ * @param array $members The list of id's of members to be updated - array('users' => array(1,2), 'groups' => array(2,4))
+ * @param string $update The type of modification - add | remove
+ * @return array Response
+ */
+ private function update_members_on_role_on_folder($folder_id, $role_id, $members, $update = 'add')
+ {
+ // Check input information
+ $response['status_code'] = 1;
+ if(!is_numeric($folder_id)){
+ $response['message'] = _kt('Folder id must be numeric.');
+ return $response;
+ }
+
+ if(!is_numeric($role_id)){
+ $response['message'] = _kt('Role id must be numeric.');
+ return $response;
+ }
+
+ if(!is_array($members)){
+ $response['message'] = _kt("The list of members must be in the format: array('users' => array(1,2), 'groups' => array(2,4)).')");
+ return $response;
+ }
+
+ if(!isset($members['users']) && !isset($members['groups'])){
+ $response['message'] = _kt("The list of members must be in the format: array('users' => array(1,2), 'groups' => array(2,4)).')");
+ return $response;
+ }
+
+ // Get folder and role objects
+ $folder = $this->get_folder_by_id($folder_id);
+ if(PEAR::isError($folder)) {
+ $response['message'] = $folder->getMessage();
+ return $response;
+ }
+
+ $role = KTAPI_Role::getById($role_id);
+ if(PEAR::isError($role)) {
+ $response['message'] = $role->getMessage();
+ return $response;
+ }
+
+ // Get the role allocation for the folder
+ $role_allocation = $folder->getRoleAllocation();
+
+ // Get member objects and add them to the role
+ // Users
+ if(isset($members['users'])){
+
+ foreach($members['users'] as $user_id){
+ // Get the user object
+ $member = KTAPI_User::getById($user_id);
+
+ if(PEAR::isError($member)) {
+ $response['message'] = $member->getMessage();
+ return $response;
+ }
+
+ // Add to / remove from the role
+ $role_allocation->$update($role, $member);
+ }
+ }
+
+ // Groups
+ if(isset($members['groups'])){
+
+ foreach($members['groups'] as $group_id){
+ // Get the group object
+ $member = KTAPI_Group::getById($group_id);
+
+ if(PEAR::isError($member)) {
+ $response['message'] = $member->getMessage();
+ return $response;
+ }
+
+ // Add to / remove from the role
+ $role_allocation->$update($role, $member);
+ }
+ }
+
+ // Save the new allocations
+ $role_allocation->save();
+
+ $response['status_code'] = 0;
+ return $response;
+ }
+
+ /**
+ * Check if a user or group is allocated to a role on the folder
+ *
+ * @author KnowledgeTree Team
+ * @access public
+ * @param integer $folder_id The folder id
+ * @param integer $role_id The id of the role being checked
+ * @param integer $member_id The id of the user or group
+ * @param string $member_type user | group
+ * @return array Response
+ */
+ public function is_member_in_role_on_folder($folder_id, $role_id, $member_id, $member_type = 'user')
+ {
+ $response['status_code'] = 1;
+
+ // Get folder and role objects
+ $folder = $this->get_folder_by_id($folder_id);
+ if(PEAR::isError($folder)) {
+ $response['message'] = $folder->getMessage();
+ return $response;
+ }
+
+ $role = KTAPI_Role::getById($role_id);
+ if(PEAR::isError($role)) {
+ $response['message'] = $role->getMessage();
+ return $response;
+ }
+
+ // get the member object
+ switch($member_type){
+ case 'user':
+ $member = KTAPI_User::getById($member_id);
+ break;
+ case 'group':
+ $member = KTAPI_Group::getById($member_id);
+ break;
+ default:
+ $response['message'] = _kt('Unrecognised member type. Must be group or user.');
+ return $response;
+ }
+
+ if(PEAR::isError($member)) {
+ $response['message'] = $member->getMessage();
+ return $response;
+ }
+
+ // Get the role allocation for the folder
+ $role_allocation = $folder->getRoleAllocation();
+ $check = $role_allocation->doesRoleHaveMember($role, $member);
+ $result = ($check) ? 'YES' : 'NO';
+
+ $response['status_code'] = 0;
+ $response['results'] = $result;
+ return $response;
+ }
+
+ /**
+ * Removes all members (users, groups) from all roles or from the specified role on the folder
+ *
+ * @author KnowledgeTree Team
+ * @access public
+ * @param integer $folder_id The folder id
+ * @param integer $role_id Optional. The id of the role being reset.
+ * @return array Response
+ */
+ public function remove_all_role_allocation_from_folder($folder_id, $role_id = null)
+ {
+ $response['status_code'] = 1;
+
+ // Get folder and role objects
+ $folder = $this->get_folder_by_id($folder_id);
+ if(PEAR::isError($folder)) {
+ $response['message'] = $folder->getMessage();
+ return $response;
+ }
+
+ $role = null;
+ if(!empty($role_id)){
+ $role = KTAPI_Role::getById($role_id);
+ if(PEAR::isError($role)) {
+ $response['message'] = $role->getMessage();
+ return $response;
+ }
+ }
+
+ // Get the role allocation for the folder
+ $role_allocation = $folder->getRoleAllocation();
+ $role_allocation->removeAll($role);
+ $role_allocation->save();
+
+ $response['status_code'] = 0;
+ $response['results'] = $result;
+ return $response;
+ }
+
+ /**
+ * Overrides the parents role allocation
+ *
+ * @author KnowledgeTree Team
+ * @access public
+ * @param integer $folder_id The folder id
+ * @return array Response
+ */
+ public function override_role_allocation_on_folder($folder_id)
+ {
+ $response['status_code'] = 1;
+
+ // Get folder object
+ $folder = $this->get_folder_by_id($folder_id);
+ if(PEAR::isError($folder)) {
+ $response['message'] = $folder->getMessage();
+ return $response;
+ }
+
+ // Get the role allocation for the folder
+ $role_allocation = $folder->getRoleAllocation();
+ $result = $role_allocation->overrideAllocation();
+
+ $response['status_code'] = 0;
+ $response['results'] = $result;
+ return $response;
+ }
+
+ /**
+ * Inherits the role allocation from the parent
+ *
+ * @author KnowledgeTree Team
+ * @access public
+ * @param integer $folder_id The folder id
+ * @return array Response
+ */
+ public function inherit_role_allocation_on_folder($folder_id)
+ {
+ $response['status_code'] = 1;
+
+ // Get folder object
+ $folder = $this->get_folder_by_id($folder_id);
+ if(PEAR::isError($folder)) {
+ $response['message'] = $folder->getMessage();
+ return $response;
+ }
+
+ // Get the role allocation for the folder
+ $role_allocation = $folder->getRoleAllocation();
+ $result = $role_allocation->inheritAllocation();
+
+ $response['status_code'] = 0;
+ $response['results'] = $result;
+ return $response;
+ }
+
- /* *** Refactored web services functions *** */
+ /* *** Refactored web services functions *** */
/**
diff --git a/ktwebservice/KTWebService.php b/ktwebservice/KTWebService.php
index 7d1df33..d65a19a 100644
--- a/ktwebservice/KTWebService.php
+++ b/ktwebservice/KTWebService.php
@@ -118,6 +118,7 @@ class JsonEncoder extends EncoderBase
*/
public function encode($input)
{
+ $input = array('response' => $input);
return json_encode($input);
}
}
@@ -150,11 +151,12 @@ class XmlEncoder extends EncoderBase
return false;
}
- $xml = ''."\n";
- $xml .= ''."\n";
+ $xml = ''."\n";
+ $xml .= ''."\n";
+// $xml .= ''."\n";
$xml .= XmlEncoder::createXmlFromArray($input);
-
+ $xml .= ''."\n";
return $xml;
}
@@ -171,6 +173,10 @@ class XmlEncoder extends EncoderBase
$xml = '';
foreach ($input as $key => $value) {
+ if(is_numeric($key)){
+ $key = 'item';
+ }
+
if(is_array($value)){
$value = XmlEncoder::createXmlFromArray($value);
}
@@ -383,6 +389,13 @@ class Response extends ResponseBase
// instantiate KTAPI and invoke method
$ktapi = $this->get_ktapi($session_id);
+
+ if(PEAR::isError($ktapi)){
+ $this->error = 'API could not be authenticated: '.$ktapi->getMessage();
+ $this->error_code = 404;
+ return false;
+ }
+
$result = $reflectMethod->invokeArgs($ktapi, $orderedParams);
return $result;
@@ -409,10 +422,10 @@ class Response extends ResponseBase
if(!empty($session_id)){
$session = $kt->get_active_session($session_id, null);
- if ( PEAR::isError($session))
+ if (PEAR::isError($session))
{
// return error / exception
- return false;
+ return $session;
}
}
$this->ktapi = $kt;
@@ -477,6 +490,18 @@ class Response extends ResponseBase
*/
protected function _post($args)
{
+ $result = $this->callMethod($args);
+
+ // if an error occurred, initiate the error response
+ if($result === false){
+ return false;
+ }
+
+ $result = $this->flattenInput($result);
+
+ $encoder = EncoderBase::getEncoder($this->responseType);
+ $this->output = $encoder->encode($result);
+ $this->headers = $encoder->getHeaders();
}
/**
@@ -489,6 +514,18 @@ class Response extends ResponseBase
*/
protected function _put($args)
{
+ $result = $this->callMethod($args);
+
+ // if an error occurred, initiate the error response
+ if($result === false){
+ return false;
+ }
+
+ $result = $this->flattenInput($result);
+
+ $encoder = EncoderBase::getEncoder($this->responseType);
+ $this->output = $encoder->encode($result);
+ $this->headers = $encoder->getHeaders();
}
/**
@@ -501,6 +538,18 @@ class Response extends ResponseBase
*/
protected function _delete($args)
{
+ $result = $this->callMethod($args);
+
+ // if an error occurred, initiate the error response
+ if($result === false){
+ return false;
+ }
+
+ $result = $this->flattenInput($result);
+
+ $encoder = EncoderBase::getEncoder($this->responseType);
+ $this->output = $encoder->encode($result);
+ $this->headers = $encoder->getHeaders();
}
/**
@@ -512,9 +561,12 @@ class Response extends ResponseBase
public function output()
{
if(!empty($this->error)){
+ $response = array('message' => $this->error, 'status_code' => 1);
+ $encoder = EncoderBase::getEncoder($this->responseType);
+ $this->output = $encoder->encode($response);
+ $this->headers = $encoder->getHeaders();
+
$this->_respondError($this->error_code);
- echo $this->error;
- exit;
}
$this->_respond($this->output, $this->headers);
diff --git a/ktwebservice/webservice.php b/ktwebservice/webservice.php
index 585145c..bc70e67 100644
--- a/ktwebservice/webservice.php
+++ b/ktwebservice/webservice.php
@@ -1455,7 +1455,7 @@ class KTWebService
}
$folder = $kt->get_folder_by_id($folder_id);
- if(PEAR::isError($document)){
+ if(PEAR::isError($folder)){
$response=array(
'status_code'=>KTWS_ERR_INVALID_FOLDER,
'message'=>$folder->getMessage()
@@ -1699,7 +1699,7 @@ class KTWebService
}
$source_document = &$kt->get_document_by_id($source_document_id);
- if (PEAR::isError($source_folder))
+ if (PEAR::isError($source_document))
{
$response = KTWebService::_status(KTWS_ERR_INVALID_DOCUMENT,$source_document);
@@ -2454,7 +2454,7 @@ class KTWebService
if (PEAR::isError($tempfilename))
{
$reason = $tempfilename->getMessage();
- $response = KTWebService::_status(KTWS_ERR_INVALID_DOCUMENT,'Cannot write to temp file: ' + $tempfilename . ". Reason: $reason");
+ $response = KTWebService::_status(KTWS_ERR_INVALID_DOCUMENT,'Cannot write to temp file: ' . $tempfilename . ". Reason: $reason");
$this->debug("add_small_document - cannot write $tempfilename. Reason: $reason", $session_id);
return new SOAP_Value('return',"{urn:$this->namespace}kt_document_detail", $response);
@@ -2639,7 +2639,7 @@ class KTWebService
if (PEAR::isError($tempfilename))
{
$reason = $tempfilename->getMessage();
- $response = KTWebService::_status(KTWS_ERR_INVALID_DOCUMENT,'Cannot write to temp file: ' + $tempfilename . ". Reason: $reason");
+ $response = KTWebService::_status(KTWS_ERR_INVALID_DOCUMENT,'Cannot write to temp file: ' . $tempfilename . ". Reason: $reason");
$this->debug("checkin_small_document - cannot write $tempfilename. Reason: $reason", $session_id);
return new SOAP_Value('return',"{urn:$this->namespace}kt_document_detail", $response);
diff --git a/lib/documentmanagement/documentutil.inc.php b/lib/documentmanagement/documentutil.inc.php
index 2556283..834379a 100644
--- a/lib/documentmanagement/documentutil.inc.php
+++ b/lib/documentmanagement/documentutil.inc.php
@@ -995,6 +995,9 @@ $sourceDocument->getName(),
return PEAR::raiseError(_kt('There was a problem deleting the document from storage.'));
}
+ // get the user object
+ $oUser = User::get($_SESSION['userID']);
+
//delete all shortcuts linking to this document
$aSymlinks = $oDocument->getSymbolicLinks();
foreach($aSymlinks as $aSymlink){
@@ -1005,7 +1008,7 @@ $sourceDocument->getName(),
//send an email to the owner of the shortcut
if($oOwnerUser->getEmail()!=null && $oOwnerUser->getEmailNotification() == true){
- $emailTemplate = new EmailTemplate("kt3/notifications/notification.SymbolicLinkDeleted",array('user_name'=>$this->oUser->getName(),
+ $emailTemplate = new EmailTemplate("kt3/notifications/notification.SymbolicLinkDeleted",array('user_name'=>$oUser->getName(),
'url'=>KTUtil::ktLink(KTBrowseUtil::getUrlForDocument($oShortcutDocument)),
'title' =>$oShortcutDocument->getName()));
$email = new EmailAlert($oOwnerUser->getEmail(),_kt("KnowledgeTree Notification"),$emailTemplate->getBody());
diff --git a/lib/foldermanagement/Folder.inc b/lib/foldermanagement/Folder.inc
index c92740b..6fffd95 100644
--- a/lib/foldermanagement/Folder.inc
+++ b/lib/foldermanagement/Folder.inc
@@ -130,6 +130,11 @@ class Folder extends KTEntity {
//now load fields from the folder this folder is linking to, if any.
if($this->isSymbolicLink()){
$oLinkedFolder = $this->getLinkedFolder();
+
+ if(PEAR::isError($oLinkedFolder)){
+ return PEAR::raiseError(_kt("Linked folder can't be found: ") . $oLinkedFolder->getMessage());
+ }
+
$this->sName = $oLinkedFolder->getName();
$this->sDescription = $oLinkedFolder->getDescription();
}
diff --git a/lib/foldermanagement/folderutil.inc.php b/lib/foldermanagement/folderutil.inc.php
index ac24b33..91c961f 100644
--- a/lib/foldermanagement/folderutil.inc.php
+++ b/lib/foldermanagement/folderutil.inc.php
@@ -241,12 +241,13 @@ class KTFolderUtil {
// First, deal with SQL, as it, at least, is guaranteed to be atomic
$table = "folders";
- if ($oFolder->getId() == 1) {
+ if ($oFolder->getId() == 1 || $oFolder->getParentID() == 1) {
$sOldPath = $oFolder->getName();
$sNewPath = $sNewName;
} else {
$sOldPath = $oFolder->getFullPath();
- $sNewPath = dirname($oFolder->getFullPath()) . '/' . $sNewName;
+ $sNewPathDir = !empty($sOldPath) ? dirname($sOldPath) . '/' : '';
+ $sNewPath = $sNewPathDir . $sNewName;
}
$sQuery = "UPDATE $table SET full_path = CONCAT(?, SUBSTRING(full_path FROM ?)) WHERE full_path LIKE ? OR full_path = ?";
@@ -400,7 +401,7 @@ class KTFolderUtil {
foreach($aFolderIds as $iFolder){
$oFolder = Folder::get($iFolder);
$aLinks = $oFolder->getSymbolicLinks();
- array_merge($aSymlinks, $aLinks);
+ $aSymlinks = array_merge($aSymlinks, $aLinks);
}
// documents all cleared.
@@ -423,11 +424,14 @@ class KTFolderUtil {
$linkIds = implode(',', $links);
$query = "DELETE FROM folders WHERE id IN ($linkIds)";
+ DBUtil::runQuery($query);
}
+ /*
foreach($aSymlinks as $aSymlink){
KTFolderUtil::deleteSymbolicLink($aSymlink['id']);
}
+ */
// purge caches
KTEntityUtil::clearAllCaches('Folder');
diff --git a/tests/api/testAcl.php b/tests/api/testAcl.php
index 273aeb0..f2298fd 100644
--- a/tests/api/testAcl.php
+++ b/tests/api/testAcl.php
@@ -9,6 +9,7 @@ class APIAclTestCase extends KTUnitTestCase {
*/
var $ktapi;
var $session;
+ var $root;
/**
* Setup the session
@@ -17,6 +18,7 @@ class APIAclTestCase extends KTUnitTestCase {
function setUp() {
$this->ktapi = new KTAPI();
$this->session = $this->ktapi->start_system_session();
+ $this->root = $this->ktapi->get_root_folder();
}
/**
@@ -27,6 +29,140 @@ class APIAclTestCase extends KTUnitTestCase {
$this->session->logout();
}
+
+ /* *** Testing KTAPI ACL functions *** */
+
+ /**
+ * Testing get list of roles
+ */
+ function testGetRoles()
+ {
+ $list = $this->ktapi->get_roles();
+
+ $this->assertEqual($list['status_code'], 0);
+ $this->assertTrue(!empty($list['results']));
+
+ // filter roles - should return the "Everyone" role
+ $list = $this->ktapi->get_roles('Ever');
+
+ $this->assertEqual($list['status_code'], 0);
+ $this->assertTrue(!empty($list['results']));
+ $this->assertEqual(count($list['results']), 1);
+ $this->assertEqual($list['results'][0]['name'], 'Everyone');
+ }
+
+ /**
+ * Testing get role by id and name
+ */
+ function testGetRole()
+ {
+ // get by id -2 - should return system role Owner
+ $role = $this->ktapi->get_role_by_id(-2);
+
+ $this->assertEqual($role['status_code'], 0);
+ $this->assertTrue(!empty($role['results']));
+ $this->assertEqual($role['results']['name'], 'Owner');
+
+ // get by name Authenticated
+ $role = $this->ktapi->get_role_by_name('Authenticated Users');
+
+ $this->assertEqual($role['status_code'], 0);
+ $this->assertTrue(!empty($role['results']));
+ $this->assertEqual($role['results']['name'], 'Authenticated Users');
+ $this->assertEqual($role['results']['id'], -4);
+ }
+
+ /**
+ * Test role allocation on folders
+ */
+ function testAllocatingMembersToRoles()
+ {
+ $folder = $this->ktapi->get_folder_by_name('test123');
+ if(!$folder instanceof KTAPI_Folder){
+ $folder = $this->root->add_folder('test123');
+ }
+ $folder_id = $folder->get_folderid();
+
+ $allocation = $this->ktapi->get_role_allocation_for_folder($folder_id);
+ $this->assertEqual($allocation['status_code'], 0);
+ $this->assertTrue(empty($allocation['results']));
+
+ // add a user to a role
+ $role_id = 2; // Publisher
+ $user_id = 1; // Admin
+ $result = $this->ktapi->add_user_to_role_on_folder($folder_id, $role_id, $user_id);
+ $this->assertEqual($result['status_code'], 0);
+
+ $allocation = $this->ktapi->get_role_allocation_for_folder($folder_id);
+ $this->assertEqual($allocation['status_code'], 0);
+ $this->assertTrue(isset($allocation['results']['Publisher']));
+ $this->assertEqual($allocation['results']['Publisher']['user'][1], 'Administrator');
+
+ // test check on members in the role
+ $check = $this->ktapi->is_member_in_role_on_folder($folder_id, $role_id, $user_id, 'user');
+ $this->assertEqual($check['status_code'], 0);
+ $this->assertEqual($check['results'], 'YES');
+
+ // remove user from a role
+ $result = $this->ktapi->remove_user_from_role_on_folder($folder_id, $role_id, $user_id);
+ $this->assertEqual($result['status_code'], 0);
+
+ $allocation = $this->ktapi->get_role_allocation_for_folder($folder_id);
+ $this->assertEqual($allocation['status_code'], 0);
+ $this->assertFalse(isset($allocation['results']['Publisher']));
+
+ // clean up
+ $folder->delete('Testing API');
+ }
+
+ /**
+ * Test inherit and override role allocation and remove all allocations
+ */
+ function testRoleAllocationInheritance()
+ {
+ $folder = $this->ktapi->get_folder_by_name('test123');
+ if(!$folder instanceof KTAPI_Folder){
+ $folder = $this->root->add_folder('test123');
+ }
+ $folder_id = $folder->get_folderid();
+
+ $allocation = $this->ktapi->get_role_allocation_for_folder($folder_id);
+ $this->assertEqual($allocation['status_code'], 0);
+
+ // Override
+ $result = $this->ktapi->override_role_allocation_on_folder($folder_id);
+ $this->assertEqual($result['status_code'], 0);
+
+ $role_id = 2; // Publisher
+ $user_id = 1; // Admin
+ $group_id = 1; // System Administrators
+ $members = array('users' => array($user_id), 'groups' => array($group_id));
+
+ $result = $this->ktapi->add_members_to_role_on_folder($folder_id, $role_id, $members);
+ $this->assertEqual($result['status_code'], 0);
+
+ $check = $this->ktapi->is_member_in_role_on_folder($folder_id, $role_id, $user_id, 'user');
+ $this->assertEqual($check['status_code'], 0);
+ $this->assertEqual($check['results'], 'YES');
+
+ // Remove all
+ $result = $this->ktapi->remove_all_role_allocation_from_folder($folder_id, $role_id);
+ $this->assertEqual($result['status_code'], 0);
+
+ $check = $this->ktapi->is_member_in_role_on_folder($folder_id, $role_id, $group_id, 'group');
+ $this->assertEqual($check['status_code'], 0);
+ $this->assertEqual($check['results'], 'NO');
+
+ // Inherit
+ $result = $this->ktapi->inherit_role_allocation_on_folder($folder_id);
+ $this->assertEqual($result['status_code'], 0);
+
+ // clean up
+ $folder->delete('Testing API');
+ }
+
+ /* *** Testing ACL classes *** */
+
/**
*
* Test KTAPI_User getList(), getById(), getByName, getByUsername()
diff --git a/tests/api/testApi.php b/tests/api/testApi.php
index 19e84f6..1d6f2ef 100644
--- a/tests/api/testApi.php
+++ b/tests/api/testApi.php
@@ -449,8 +449,186 @@ class APITestCase extends KTUnitTestCase {
$document->expunge();
}
- function createRandomFile($content = 'this is some text') {
- $temp = tempnam(dirname(__FILE__), 'myfile');
+ /* *** Test webservice functions *** */
+
+ /**
+ * Testing folder creation and deletion, add document, get folder contents, folder detail
+ * Folder shortcuts and actions
+ */
+ public function testFolderApiFunctions()
+ {
+ // check for a negative result
+ $result = $this->ktapi->create_folder(0, 'New test error api folder');
+ $this->assertNotEqual($result['status_code'], 0);
+
+ // Create a folder
+ $result1 = $this->ktapi->create_folder(1, 'New test api folder');
+ $folder_id = $result1['results']['id'];
+
+ $this->assertEqual($result1['status_code'], 0);
+ $this->assertTrue($result1['results']['parent_id'] == 1);
+
+ // Create a sub folder
+ $result2 = $this->ktapi->create_folder($folder_id, 'New test api sub-folder');
+ $folder_id2 = $result2['results']['id'];
+ $this->assertEqual($result2['status_code'], 0);
+
+ // Add a document
+ global $default;
+ $dir = $default->uploadDirectory;
+ $tempfilename = $this->createRandomFile('some text', $dir);
+ $doc = $this->ktapi->add_document($folder_id, 'New API test doc', 'testdoc1.txt', 'Default', $tempfilename);
+
+ $this->assertEqual($doc['status_code'], 0);
+ $this->assertEqual($doc['results']['title'], 'New API test doc');
+
+ // Get folder 1 contents
+ $contents = $this->ktapi->get_folder_contents($folder_id, $depth=1, $what='DFS');
+ $this->assertEqual($contents['status_code'], 0);
+ $this->assertEqual(count($contents['results']['items']), 2);
+
+ $detail = $this->ktapi->get_folder_detail($folder_id2);
+ $this->assertEqual($detail['status_code'], 0);
+ $this->assertTrue($detail['results']['parent_id'] == $folder_id);
+
+ // Create a shortcut to the subfolder from the root folder
+ $shortcut = $this->ktapi->create_folder_shortcut(1, $folder_id2);
+ $this->assertEqual($shortcut['status_code'], 0);
+ $this->assertEqual($shortcut['results']['folder_name'], 'New test api sub-folder');
+ $this->assertEqual($shortcut['results']['parent_id'], 1);
+
+ $shortcut_list = $this->ktapi->get_folder_shortcuts($folder_id2);
+ $this->assertEqual($shortcut['status_code'], 0);
+ $this->assertEqual(count($shortcut_list['results']), 1);
+
+ // Rename the folder
+ $renamed = $this->ktapi->rename_folder($folder_id, 'Renamed test folder');
+ $this->assertEqual($renamed['status_code'], 0);
+
+ $renamed_detail = $this->ktapi->get_folder_detail_by_name('Renamed test folder');
+ $this->assertEqual($renamed_detail['status_code'], 0);
+ $this->assertEqual($renamed_detail['results']['id'], $folder_id);
+
+// $this->ktapi->copy_folder($source_id, $target_id, $reason);
+// $this->ktapi->move_folder($source_id, $target_id, $reason);
+
+
+ // Clean up - delete the folder
+ $this->ktapi->delete_folder($folder_id, 'Testing API');
+ $detail2 = $this->ktapi->get_folder_detail($folder_id);
+ $this->assertNotEqual($detail2['status_code'], 0);
+ }
+
+ /**
+ * Testing document get, update, actions, delete, shortcuts and detail
+ */
+ public function testDocumentApiFunctions()
+ {
+ // Create a folder
+ $result1 = $this->ktapi->create_folder(1, 'New test api folder');
+ $folder_id = $result1['results']['id'];
+ $this->assertEqual($result1['status_code'], 0);
+
+ // Create a sub folder
+ $result2 = $this->ktapi->create_folder($folder_id, 'New test api sub-folder');
+ $folder_id2 = $result2['results']['id'];
+ $this->assertEqual($result2['status_code'], 0);
+
+ // Add a document
+ global $default;
+ $dir = $default->uploadDirectory;
+ $tempfilename = $this->createRandomFile('some text', $dir);
+ $doc = $this->ktapi->add_document($folder_id, 'New API test doc', 'testdoc1.txt', 'Default', $tempfilename);
+
+ $doc_id = $doc['results']['document_id'];
+ $this->assertEqual($doc['status_code'], 0);
+
+ // Get document detail
+ $detail = $this->ktapi->get_document_detail($doc_id);//, 'MLTVH');
+ $this->assertEqual($detail['status_code'], 0);
+ $this->assertEqual($detail['results']['document_type'], 'Default');
+ $this->assertEqual($detail['results']['folder_id'], $folder_id);
+
+ // Get document detail - filename
+ $detail2 = $this->ktapi->get_document_detail_by_filename($folder_id, 'testdoc1.txt');
+ $this->assertEqual($detail2['status_code'], 0);
+ $this->assertEqual($detail2['results']['title'], 'New API test doc');
+
+ // Get document detail - title
+ $detail3 = $this->ktapi->get_document_detail_by_title($folder_id, 'New API test doc');
+ $this->assertEqual($detail3['status_code'], 0);
+ $this->assertEqual($detail3['results']['filename'], 'testdoc1.txt');
+
+ // Get document detail - name
+ $detail4 = $this->ktapi->get_document_detail_by_name($folder_id, 'New API test doc');
+ $this->assertEqual($detail4['status_code'], 0);
+ $this->assertEqual($detail4['results']['title'], 'New API test doc');
+
+ // Checkout the document
+ $result1 = $this->ktapi->checkout_document($doc_id, 'Testing API', true);
+ $this->assertEqual($result1['status_code'], 0);
+ $this->assertTrue(!empty($result1['results']));
+
+ // Checkin the document
+ $dir = $default->uploadDirectory;
+ $tempfilename = $this->createRandomFile('some text', $dir);
+ $result2 = $this->ktapi->checkin_document($doc_id, 'testdoc1.txt', 'Testing API', $tempfilename, false);
+
+ $this->assertEqual($result2['status_code'], 0);
+ $this->assertEqual($result2['results']['document_id'], $doc_id);
+
+ // Create document shortcut
+ $shortcut = $this->ktapi->create_document_shortcut(1, $doc_id);
+ $this->assertEqual($shortcut['status_code'], 0);
+ $this->assertEqual($shortcut['results']['title'], 'New API test doc');
+ $this->assertEqual($shortcut['results']['folder_id'], $folder_id);
+
+ // Delete the document
+ $result3 = $this->ktapi->delete_document($doc_id, 'Testing API');
+ $this->assertEqual($result3['status_code'], 0);
+
+ // Clean up - delete the folder
+ $this->ktapi->delete_folder($folder_id, 'Testing API');
+ $detail2 = $this->ktapi->get_folder_detail($folder_id);
+ $this->assertNotEqual($detail2['status_code'], 0);
+ }
+
+ /**
+ * Helper function to create a document
+ */
+ function createDocument($title, $filename, $folder = null)
+ {
+ if(is_null($folder)){
+ $folder = $this->root;
+ }
+
+ // Create a new document
+ $randomFile = $this->createRandomFile();
+ $this->assertTrue(is_file($randomFile));
+
+ $document = $folder->add_document($title, $filename, 'Default', $randomFile);
+ $this->assertNotError($document);
+
+ @unlink($randomFile);
+ if(PEAR::isError($document)) return false;
+
+ return $document;
+ }
+
+ /**
+ * Helper function to delete docs
+ */
+ function deleteDocument($document)
+ {
+ $document->delete('Testing API');
+ $document->expunge();
+ }
+
+ function createRandomFile($content = 'this is some text', $uploadDir = null) {
+ if(is_null($uploadDir)){
+ $uploadDir = dirname(__FILE__);
+ }
+ $temp = tempnam($uploadDir, 'myfile');
$fp = fopen($temp, 'wt');
fwrite($fp, $content);
fclose($fp);
diff --git a/tests/api/testBulkActions.php b/tests/api/testBulkActions.php
index a4bbf61..aab8e90 100644
--- a/tests/api/testBulkActions.php
+++ b/tests/api/testBulkActions.php
@@ -48,6 +48,147 @@ class APIBulkActionsTestCase extends KTUnitTestCase {
$this->session->logout();
}
+ /* *** Test KTAPI functions *** */
+
+ /**
+ * Testing the bulk actions - copy, move, delete
+ */
+ public function testApiBulkCopyMoveDelete()
+ {
+ // Create folder and documents
+ $doc1 = $this->createDocument('Test Doc One', 'testdoc1.txt');
+ $doc2 = $this->createDocument('Test Doc Two', 'testdoc2.txt');
+ $folder1 = $this->root->add_folder("New test folder");
+ $this->assertNotError($newFolder);
+ if(PEAR::isError($newFolder)) return;
+
+ $doc4 = $this->createDocument('Test Doc Four', 'testdoc4.txt', $folder1);
+
+ $target_folder = $this->root->add_folder("New target folder");
+ $this->assertNotError($target_folder);
+ if(PEAR::isError($target_folder)) return;
+ $target_folder_id = $target_folder->get_folderid();
+
+ $aItems = array();
+ $aItems['documents'][] = $doc1->get_documentid();
+ $aItems['documents'][] = $doc2->get_documentid();
+ $aItems['folders'][] = $folder1->get_folderid();
+
+ // Call bulk action - copy
+ $response = $this->ktapi->performBulkAction('copy', $aItems, 'Testing API', $target_folder_id);
+
+ $this->assertEqual($response['status_code'], 0);
+ $this->assertTrue(empty($response['results']));
+
+ // Test move action - delete and recreate target folder
+ $target_folder->delete('Testing API');
+
+ $target_folder = $this->root->add_folder("New target folder");
+ $this->assertNotError($target_folder);
+ if(PEAR::isError($target_folder)) return;
+ $target_folder_id = $target_folder->get_folderid();
+
+ $response = $this->ktapi->performBulkAction('move', $aItems, 'Testing API', $target_folder_id);
+
+ $this->assertEqual($response['status_code'], 0);
+ $this->assertTrue(empty($response['results']));
+
+ $response = $this->ktapi->performBulkAction('delete', $aItems, 'Testing API');
+
+ $this->assertEqual($response['status_code'], 0);
+ $this->assertTrue(empty($response['results']));
+
+ // Delete and expunge documents and folder
+ $target_folder->delete('Testing API');
+ }
+
+ /**
+ * Testing the bulk actions - checkout and cancel check out
+ */
+ public function testApiBulkCheckout()
+ {
+ // Create folder and documents
+ $doc1 = $this->createDocument('Test Doc One', 'testdoc1.txt');
+ $doc2 = $this->createDocument('Test Doc Two', 'testdoc2.txt');
+ $folder1 = $this->root->add_folder("New test folder");
+ $this->assertNotError($newFolder);
+ if(PEAR::isError($newFolder)) return;
+
+ $doc4 = $this->createDocument('Test Doc Four', 'testdoc4.txt', $folder1);
+
+ $doc1_id = $doc1->get_documentid();
+ $doc2_id = $doc2->get_documentid();
+
+ $aItems = array();
+ $aItems['documents'][] = $doc1_id;
+ $aItems['documents'][] = $doc2_id;
+ $aItems['folders'][] = $folder1->get_folderid();
+
+ // Call bulk action - checkout
+ $response = $this->ktapi->performBulkAction('checkout', $aItems, 'Testing API');
+
+ $this->assertEqual($response['status_code'], 0);
+ $this->assertTrue(empty($response['results']));
+
+ // update document object
+ $doc1 = $this->ktapi->get_document_by_id($doc1_id);
+ $this->assertTrue($doc1->is_checked_out());
+
+ // cancel the checkout
+ $response = $this->ktapi->performBulkAction('undo_checkout', $aItems, 'Testing API');
+
+ $this->assertEqual($response['status_code'], 0);
+ $this->assertTrue(empty($response['results']));
+
+ // delete items
+ $response = $this->ktapi->performBulkAction('delete', $aItems, 'Testing API');
+ $this->assertEqual($response['status_code'], 0);
+ }
+
+ /**
+ * Testing the bulk actions - checkout and cancel check out
+ */
+ public function testApiBulkImmute()
+ {
+ // Create folder and documents
+ $doc1 = $this->createDocument('Test Doc One', 'testdoc1.txt');
+ $doc2 = $this->createDocument('Test Doc Two', 'testdoc2.txt');
+ $folder1 = $this->root->add_folder("New test folder");
+ $this->assertNotError($newFolder);
+ if(PEAR::isError($newFolder)) return;
+
+ $doc4 = $this->createDocument('Test Doc Four', 'testdoc4.txt', $folder1);
+
+ $doc1_id = $doc1->get_documentid();
+ $doc2_id = $doc2->get_documentid();
+
+ $aItems = array();
+ $aItems['documents'][] = $doc1_id;
+ $aItems['documents'][] = $doc2_id;
+ $aItems['folders'][] = $folder1->get_folderid();
+
+ // Call bulk action - checkout
+ $response = $this->ktapi->performBulkAction('immute', $aItems);
+
+ $this->assertEqual($response['status_code'], 0);
+ $this->assertTrue(empty($response['results']));
+
+ // update document object
+ $doc1 = $this->ktapi->get_document_by_id($doc1_id);
+ $this->assertTrue($doc1->isImmutable());
+
+ // remove immutability for deletion
+ $doc1->unimmute();
+ $doc2->unimmute();
+ $doc4->unimmute();
+
+ // delete items
+ $response = $this->ktapi->performBulkAction('delete', $aItems, 'Testing API');
+ $this->assertEqual($response['status_code'], 0);
+ }
+
+ /* *** Test Bulk actions class *** */
+
/**
* Test the bulk copy functionality
*/
@@ -182,6 +323,9 @@ class APIBulkActionsTestCase extends KTUnitTestCase {
$this->assertTrue($doc1->is_checked_out());
$this->assertTrue($doc2->is_checked_out());
$this->assertTrue($doc3->is_checked_out());
+
+ // refresh the doc4 document object to reflect changes
+ $doc4 = KTAPI_Document::get($this->ktapi, $doc4->get_documentid());
$this->assertTrue($doc4->is_checked_out());
$res = $this->bulk->undo_checkout($aItems, 'Testing bulk undo / cancel checkout');
@@ -191,6 +335,9 @@ class APIBulkActionsTestCase extends KTUnitTestCase {
$this->assertFalse($doc1->is_checked_out());
$this->assertFalse($doc2->is_checked_out());
$this->assertFalse($doc3->is_checked_out());
+
+ // refresh the doc4 document object to reflect changes
+ $doc4 = KTAPI_Document::get($this->ktapi, $doc4->get_documentid());
$this->assertFalse($doc4->is_checked_out());
// Delete and expunge documents and folder
@@ -226,6 +373,9 @@ class APIBulkActionsTestCase extends KTUnitTestCase {
$this->assertTrue($doc1->isImmutable());
$this->assertTrue($doc2->isImmutable());
$this->assertTrue($doc3->isImmutable());
+
+ // refresh the doc4 document object to reflect changes
+ $doc4 = KTAPI_Document::get($this->ktapi, $doc4->get_documentid());
$this->assertTrue($doc4->isImmutable());
// remove immutability for deletion
@@ -268,6 +418,9 @@ class APIBulkActionsTestCase extends KTUnitTestCase {
$this->assertTrue($doc1->is_deleted());
$this->assertTrue($doc2->is_deleted());
$this->assertTrue($doc3->is_deleted());
+
+ // refresh the doc4 document object to reflect changes
+ $doc4 = KTAPI_Document::get($this->ktapi, $doc4->get_documentid());
$this->assertTrue($doc4->is_deleted());
// Check folder has been deleted
@@ -305,6 +458,9 @@ class APIBulkActionsTestCase extends KTUnitTestCase {
$document1 = $doc1->getObject();
$this->assertTrue($document1->getStatusID() == 4);
+
+ // refresh the doc4 document object to reflect changes
+ $doc4 = KTAPI_Document::get($this->ktapi, $doc4->get_documentid());
$document4 = $doc4->getObject();
$this->assertTrue($document4->getStatusID() == 4);
diff --git a/tests/webservices/testRest.php b/tests/webservices/testRest.php
new file mode 100644
index 0000000..8261613
--- /dev/null
+++ b/tests/webservices/testRest.php
@@ -0,0 +1,297 @@
+rootUrl = $url.'/ktwebservice/KTWebService.php?';
+ }
+
+ /**
+ * This method is a placeholder
+ */
+ public function tearDown()
+ {
+ }
+
+ /**
+ * Test login
+ */
+ public function testLogin()
+ {
+ // Login and authenticate
+ $url = $this->rootUrl.'method=login&password=admin&username=admin';
+ $response = $this->call($url);
+ $response = $response['response'];
+ $session_id = $response['results'];
+
+ $this->assertEqual($response['status_code'], 0);
+ $this->assertTrue(!empty($response['results']));
+
+ // Logout
+ $url = $this->rootUrl.'method=logout&session_id='.$session_id;
+ $response = $this->call($url);
+ $response = $response['response'];
+
+ $this->assertEqual($response['status_code'], 0);
+ }
+
+ /**
+ * Test the successful running of a method
+ */
+ public function testFolderDetails()
+ {
+ // Login and authenticate
+ $url = $this->rootUrl.'method=login&password=admin&username=admin';
+ $response = $this->call($url);
+ $response = $response['response'];
+
+ $this->assertEqual($response['status_code'], 0);
+ $session_id = $response['results'];
+
+ $url = $this->rootUrl.'method=get_folder_detail&session_id='.$session_id.'&folder_id=1';
+ $response = $this->call($url);
+ $response = $response['response'];
+
+ $this->assertEqual($response['status_code'], 0);
+ $this->assertTrue(!empty($response['results']));
+ $this->assertEqual($response['results']['folder_name'], 'Root Folder');
+ $this->assertEqual($response['results']['permissions'], 'RWA');
+
+ // Logout
+ $url = $this->rootUrl.'method=logout&session_id='.$session_id;
+ $response = $this->call($url);
+ $response = $response['response'];
+
+ $this->assertEqual($response['status_code'], 0);
+ }
+
+ /**
+ * Test incorrect authentication and no authentication
+ */
+ public function testAuthenticationError()
+ {
+ // Incorrect password
+ $url = $this->rootUrl.'method=login&password=random&username=admin';
+ $response = $this->call($url);
+ $response = $response['response'];
+
+ $this->assertNotEqual($response['status_code'], 0);
+ $this->assertTrue(empty($response['results']));
+ $this->assertTrue(!empty($response['message']));
+
+ // No session set up - use a random session id
+ $url = $this->rootUrl.'method=get_folder_detail&session_id=09sfirandom3828492&folder_id=1';
+ $response = $this->call($url);
+ $response = $response['response'];
+
+ $this->assertNotEqual($response['status_code'], 0);
+ $this->assertTrue(empty($response['results']));
+ $this->assertTrue(!empty($response['message']));
+ }
+
+ /**
+ * Test incorrect method error and the error response on incorrect parameters
+ */
+ public function testMethodErrors()
+ {
+ $url = $this->rootUrl.'method=incorrect_method¶meter=something';
+ $response = $this->call($url);
+ $response = $response['response'];
+
+ $this->assertNotEqual($response['status_code'], 0);
+ $this->assertTrue(empty($response['results']));
+ $this->assertTrue(!empty($response['message']));
+
+ $url = $this->rootUrl.'method=get_folder_detail¶meter=something';
+ $response = $this->call($url);
+ $response = $response['response'];
+
+ $this->assertNotEqual($response['status_code'], 0);
+ $this->assertTrue(empty($response['results']));
+ $this->assertTrue(!empty($response['message']));
+ }
+
+ /**
+ * Convert xml into an array structure
+ *
+ * @param unknown_type $contents
+ * @param unknown_type $get_attributes
+ * @param unknown_type $priority
+ * @return unknown
+ */
+ private function xml2array($contents, $get_attributes = 1, $priority = 'tag')
+ {
+ if (!function_exists('xml_parser_create'))
+ {
+ return array ();
+ }
+ $parser = xml_parser_create('');
+
+ xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
+ xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
+ xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
+ xml_parse_into_struct($parser, trim($contents), $xml_values);
+ xml_parser_free($parser);
+
+ if (!$xml_values)
+ return; //Hmm...
+
+ $xml_array = array ();
+ $parents = array ();
+ $opened_tags = array ();
+ $arr = array ();
+ $current = & $xml_array;
+ $repeated_tag_index = array ();
+ foreach ($xml_values as $data)
+ {
+ unset ($attributes, $value);
+ extract($data);
+ $result = array ();
+ $attributes_data = array ();
+ if (isset ($value))
+ {
+ if ($priority == 'tag')
+ $result = $value;
+ else
+ $result['value'] = $value;
+ }
+ if (isset ($attributes) and $get_attributes)
+ {
+ foreach ($attributes as $attr => $val)
+ {
+ if ($priority == 'tag')
+ $attributes_data[$attr] = $val;
+ else
+ $result['attr'][$attr] = $val; //Set all the attributes in a array called 'attr'
+ }
+ }
+ if ($type == "open")
+ {
+ $parent[$level -1] = & $current;
+ if (!is_array($current) or (!in_array($tag, array_keys($current))))
+ {
+ $current[$tag] = $result;
+ if ($attributes_data)
+ $current[$tag . '_attr'] = $attributes_data;
+ $repeated_tag_index[$tag . '_' . $level] = 1;
+ $current = & $current[$tag];
+ }
+ else
+ {
+ if (isset ($current[$tag][0]))
+ {
+ $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
+ $repeated_tag_index[$tag . '_' . $level]++;
+ }
+ else
+ {
+ $current[$tag] = array (
+ $current[$tag],
+ $result
+ );
+ $repeated_tag_index[$tag . '_' . $level] = 2;
+ if (isset ($current[$tag . '_attr']))
+ {
+ $current[$tag]['0_attr'] = $current[$tag . '_attr'];
+ unset ($current[$tag . '_attr']);
+ }
+ }
+ $last_item_index = $repeated_tag_index[$tag . '_' . $level] - 1;
+ $current = & $current[$tag][$last_item_index];
+ }
+ }
+ elseif ($type == "complete")
+ {
+ if (!isset ($current[$tag]))
+ {
+ $current[$tag] = $result;
+ $repeated_tag_index[$tag . '_' . $level] = 1;
+ if ($priority == 'tag' and $attributes_data)
+ $current[$tag . '_attr'] = $attributes_data;
+ }
+ else
+ {
+ if (isset ($current[$tag][0]) and is_array($current[$tag]))
+ {
+ $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
+ if ($priority == 'tag' and $get_attributes and $attributes_data)
+ {
+ $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
+ }
+ $repeated_tag_index[$tag . '_' . $level]++;
+ }
+ else
+ {
+ $current[$tag] = array (
+ $current[$tag],
+ $result
+ );
+ $repeated_tag_index[$tag . '_' . $level] = 1;
+ if ($priority == 'tag' and $get_attributes)
+ {
+ if (isset ($current[$tag . '_attr']))
+ {
+ $current[$tag]['0_attr'] = $current[$tag . '_attr'];
+ unset ($current[$tag . '_attr']);
+ }
+ if ($attributes_data)
+ {
+ $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
+ }
+ }
+ $repeated_tag_index[$tag . '_' . $level]++; //0 and 1 index is already taken
+ }
+ }
+ }
+ elseif ($type == 'close')
+ {
+ $current = & $parent[$level -1];
+ }
+ }
+ return ($xml_array);
+ }
+
+ /**
+ * Use curl to run the webservice function
+ *
+ * @param unknown_type $url
+ * @return unknown
+ */
+ private function call($url) {
+ $c = curl_init($url);
+ curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
+ $xml = curl_exec($c);
+ curl_close($c);
+
+ $xmlArray = $this->xml2array($xml);
+ return $xmlArray;
+ }
+}
+?>
\ No newline at end of file