更新到 5.2 后第一次 SVN 提交。

yuchenghu@hawebs.net



git-svn-id: https://svn.code.sf.net/p/hawebs/svn@544 a2543c7e-f6e9-4f8a-8bff-1ffc34733512
This commit is contained in:
YuCheng Hu
2010-08-21 17:30:12 +00:00
parent 342a9e415e
commit 841d2ae3bf
33 changed files with 2209 additions and 0 deletions
@@ -0,0 +1,13 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
function GetRelatedList($module,$relatedmodule,$focus,$query,$button,$returnset,$id='',$edit_val='',$del_val='') {
return array( 'query' => $query );
}
@@ -0,0 +1,56 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
class Mobile_API_Request {
private $valuemap;
private $rawvaluemap;
private $defaultmap = array();
function __construct($values, $rawvalues = array()) {
$this->valuemap = $values;
$this->rawvaluemap = $rawvalues;
}
function get($key, $defvalue = '') {
if(isset($this->valuemap[$key])) {
return $this->valuemap[$key];
}
if($defvalue === '' && isset($this->defaultmap[$key])) {
$defvalue = $this->defaultmap[$key];
}
return $defvalue;
}
function has($key) {
return isset($this->valuemap[$key]);
}
function getRaw($key, $defvalue = '') {
if (isset($this->rawvaluemap[$key])) {
return $this->rawvaluemap[$key];
}
return $this->get($key, $defvalue);
}
function set($key, $newvalue) {
$this->valuemap[$key]= $newvalue;
}
function setDefault($key, $defvalue) {
$this->defaultmap[$key] = $defvalue;
}
function getOperation() {
return $this->get('_operation');
}
function getSession() {
return $this->get('_session');
}
}
@@ -0,0 +1,62 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/../../../include/Zend/Json.php';
class Mobile_API_Response {
private $error = NULL;
private $result = NULL;
function setError($code, $message) {
$error = array('code' => $code, 'message' => $message);
$this->error = $error;
}
function getError() {
return $this->error;
}
function hasError() {
return !is_null($this->error);
}
function setResult($result) {
$this->result = $result;
}
function getResult() {
return $this->result;
}
function addToResult($key, $value) {
$this->result[$key] = $value;
}
function prepareResponse() {
$response = array();
if($this->result === NULL) {
$response['success'] = false;
$response['error'] = $this->error;
} else {
$response['success'] = true;
$response['result'] = $this->result;
}
return $response;
}
function emitJSON() {
return Zend_Json::encode($this->prepareResponse());
}
function emitHTML() {
if($this->result === NULL) return (is_string($this->error))? $this->error : var_export($this->error, true);
return $this->result;
}
}
@@ -0,0 +1,43 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/../../../include/HTTP_Session/Session.php';
class Mobile_API_Session {
function __construct() {
}
static function destroy($sessionid = false) {
HTTP_Session_Destroy($sessionid);
}
static function init($sessionid = false) {
if(empty($sessionid)) {
HTTP_Session::start(null, null);
$sessionid = HTTP_Session::id();
} else {
HTTP_Session::start(null, $sessionid);
}
if(HTTP_Session::isIdle() || HTTP_Session::isExpired()) {
return false;
}
return $sessionid;
}
static function get($key, $defvalue = '') {
return HTTP_Session::get($key, $defvalue);
}
static function set($key, $value) {
HTTP_Session::set($key, $value);
}
}
@@ -0,0 +1,59 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/SaveRecord.php';
class Mobile_WS_AddRecordComment extends Mobile_WS_SaveRecord {
function saveCommentToHelpDesk($commentcontent, $record, $user) {
global $current_user;
$current_user = $user;
$targetModule = 'HelpDesk';
$recordComponents = vtws_getIdComponents($record);
$focus = CRMEntity::getInstance('HelpDesk');
$focus->retrieve_entity_info($recordComponents[1], $targetModule);
$focus->id = $recordComponents[1];
$focus->mode = 'edit';
$focus->column_fields['comments'] = $commentcontent;
$focus->save($targetModule);
return false;
}
function process(Mobile_API_Request $request) {
$values = Zend_Json::decode($request->get('values'));
$relatedTo = $values['related_to'];
$commentContent = $values['commentcontent'];
$user = $this->getActiveUser();
$targetModule = '';
if (!empty($relatedTo) && Mobile_WS_Utils::detectModulenameFromRecordId($relatedTo) == 'HelpDesk') {
$targetModule = 'HelpDesk';
} else {
$targetModule = 'ModComments';
}
$response = false;
if ($targetModule == 'HelpDesk') {
$response = $this->saveCommentToHelpDesk($commentContent, $relatedTo, $user);
} else {
if (vtlib_isModuleActive($targetModule)) {
$request->set('module', $targetModule);
$values['assigned_user_id'] = sprintf('%sx%s', Mobile_WS_Utils::getEntityModuleWSId('Users'), $user->id);
$request->set('values', Zend_Json::encode($values) );
$response = parent::process($request);
}
}
return $response;
}
}
@@ -0,0 +1,50 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once 'include/Webservices/Query.php';
include_once dirname(__FILE__) . '/FetchAllAlerts.php';
class Mobile_WS_AlertDetailsWithMessage extends Mobile_WS_FetchAllAlerts {
function process(Mobile_API_Request $request) {
global $current_user;
$response = new Mobile_API_Response();
$alertid = $request->get('alertid');
$current_user = $this->getActiveUser();
$alert = $this->getAlertDetails($alertid);
if(empty($alert)) {
$response->setError(1401, 'Alert not found');
} else {
$result = array();
$result['alert'] = $this->getAlertDetails($alertid);
$response->setResult($result);
}
return $response;
}
function getAlertDetails($alertid) {
$alertModel = Mobile_WS_AlertModel::modelWithId($alertid);
$alert = false;
if($alertModel) {
$alert = $alertModel->serializeToSend();
$alertModel->setUser($this->getActiveUser());
$alert['message'] = $alertModel->message();
}
return $alert;
}
}
@@ -0,0 +1,52 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once 'include/Webservices/Utils.php';
include_once 'modules/Mobile/Mobile.php';
include_once dirname(__FILE__) . '/Utils.php';
class Mobile_WS_Controller {
function requireLogin() {
return true;
}
private $activeUser = false;
public function initActiveUser($user) {
$this->activeUser = $user;
}
protected function setActiveUser($user) {
$this->sessionSet('_authenticated_user_id', $user->id);
$this->initActiveUser($user);
}
protected function getActiveUser() {
if($this->activeUser === false) {
$userid = $this->sessionGet('_authenticated_user_id');
if(!empty($userid)) {
$this->activeUser = CRMEntity::getInstance('Users');
$this->activeUser->retrieveCurrentUserInfoFromFile($userid);
}
}
return $this->activeUser;
}
function hasActiveUser() {
$user = $this->getActiveUser();
return ($user !== false);
}
function sessionGet($key, $defvaule = '') {
return Mobile_API_Session::get($key, $defvalue);
}
function sessionSet($key, $value) {
Mobile_API_Session::set($key, $value);
}
}
@@ -0,0 +1,42 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once 'include/Webservices/Delete.php';
class Mobile_WS_DeleteRecords extends Mobile_WS_Controller {
function process(Mobile_API_Request $request) {
global $current_user;
$current_user = $this->getActiveUser();
$records = $request->get('records');
if (empty($records)) {
$records = array($request->get('record'));
} else {
$records = Zend_Json::decode($records);
}
$deleted = array();
foreach($records as $record) {
try {
vtws_delete($record, $current_user);
$result = true;
} catch(Exception $e) {
$result = false;
}
$deleted[$record] = $result;
}
$response = new Mobile_API_Response();
$response->setResult(array('deleted' => $deleted));
return $response;
}
}
@@ -0,0 +1,26 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once 'include/Webservices/DescribeObject.php';
class Mobile_WS_Describe extends Mobile_WS_Controller {
function process(Mobile_API_Request $request) {
$current_user = $this->getActiveUser();
$module = $request->get('module');
$describeInfo = vtws_describe($module, $current_user);
Mobile_WS_Utils::fixDescribeFieldInfo($module, $describeInfo);
$response = new Mobile_API_Response();
$response->setResult(array('describe' => $describeInfo));
return $response;
}
}
@@ -0,0 +1,35 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/models/Alert.php';
class Mobile_WS_FetchAllAlerts extends Mobile_WS_Controller {
function process(Mobile_API_Request $request) {
$response = new Mobile_API_Response();
$current_user = $this->getActiveUser();
$result = array();
$result['alerts'] = $this->getAlertDetails();
$response->setResult($result);
return $response;
}
function getAlertDetails() {
$alertModels = Mobile_WS_AlertModel::models();
$alerts = array();
foreach($alertModels as $alertModel) {
$alerts[] = $alertModel->serializeToSend();;
}
return $alerts;
}
}
@@ -0,0 +1,79 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
class Mobile_WS_FetchModuleFilters extends Mobile_WS_Controller {
function process(Mobile_API_Request $request) {
$response = new Mobile_API_Response();
$module = $request->get('module');
$current_user = $this->getActiveUser();
$result = array();
$filters = $this->getModuleFilters($module, $current_user);
$yours = array();
$others= array();
if(!empty($filters)) {
foreach($filters as $filter) {
if($filter['userName'] == $current_user->column_fields['user_name']) {
$yours[] = $filter;
} else {
$others[]= $filter;
}
}
}
$result['filters'] = array('yours' => $yours, 'others' => $others);
$response->setResult($result);
return $response;
}
protected function getModuleFilters($moduleName, $user) {
$filters = array();
global $adb;
$sql = "SELECT vtiger_customview.*, vtiger_users.user_name FROM vtiger_customview
INNER JOIN vtiger_users ON vtiger_customview.userid = vtiger_users.id WHERE vtiger_customview.entitytype=?";
$parameters = array($moduleName);
if(!is_admin($user)) {
require('user_privileges/user_privileges_'.$user->id.'.php');
$sql .= " AND (vtiger_customview.status=0 or vtiger_customview.userid = ? or vtiger_customview.status = 3 or vtiger_customview.userid IN
(SELECT vtiger_user2role.userid FROM vtiger_user2role INNER JOIN vtiger_users on vtiger_users.id=vtiger_user2role.userid
INNER JOIN vtiger_role on vtiger_role.roleid=vtiger_user2role.roleid WHERE vtiger_role.parentrole LIKE '".$current_user_parent_role_seq."::%'))";
array_push($parameters, $current_user->id);
}
$result = $adb->pquery($sql, $parameters);
if($result && $adb->num_rows($result)) {
while($resultrow = $adb->fetch_array($result)) {
$filters[] = $this->prepareFilterDetailUsingResultRow($resultrow);
}
}
return $filters;
}
protected function prepareFilterDetailUsingResultRow($resultrow) {
$filter = array();
$filter['cvid'] = $resultrow['cvid'];
$filter['viewname'] = decode_html($resultrow['viewname']);
$filter['setdefault'] = $resultrow['setdefault'];
$filter['setmetrics'] = $resultrow['setmetrics'];
$filter['moduleName'] = decode_html($resultrow['entitytype']);
$filter['status'] = decode_html($resultrow['status']);
$filter['userName'] = decode_html($resultrow['user_name']);
return $filter;
}
}
@@ -0,0 +1,76 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once 'include/Webservices/Retrieve.php';
class Mobile_WS_FetchRecord extends Mobile_WS_Controller {
private $module = false;
protected $resolvedValueCache = array();
protected function detectModuleName($recordid) {
if($this->module === false) {
$this->module = Mobile_WS_Utils::detectModulenameFromRecordId($recordid);
}
return $this->module;
}
protected function processRetrieve(Mobile_API_Request $request) {
$current_user = $this->getActiveUser();
$recordid = $request->get('record');
$record = vtws_retrieve($recordid, $current_user);
return $record;
}
function process(Mobile_API_Request $request) {
$current_user = $this->getActiveUser();
$record = $this->processRetrieve($request);
$this->resolveRecordValues($record, $current_user);
$response = new Mobile_API_Response();
$response->setResult(array('record' => $record));
return $response;
}
function resolveRecordValues(&$record, $user, $ignoreUnsetFields=false) {
if(empty($record)) return $record;
$fieldnamesToResolve = Mobile_WS_Utils::detectFieldnamesToResolve(
$this->detectModuleName($record['id']) );
if(!empty($fieldnamesToResolve)) {
foreach($fieldnamesToResolve as $resolveFieldname) {
if ($ignoreUnsetFields === false || isset($record[$resolveFieldname])) {
$fieldvalueid = $record[$resolveFieldname];
$fieldvalue = $this->fetchRecordLabelForId($fieldvalueid, $user);
$record[$resolveFieldname] = array('value' => $fieldvalueid, 'label'=>$fieldvalue);
}
}
}
}
function fetchRecordLabelForId($id, $user) {
$value = null;
if (isset($this->resolvedValueCache[$id])) {
$value = $this->resolvedValueCache[$id];
} else if(!empty($id)) {
$value = trim(vtws_getName($id, $user));
$this->resolvedValueCache[$id] = $value;
} else {
$value = $id;
}
return $value;
}
}
@@ -0,0 +1,169 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once 'include/Webservices/Retrieve.php';
include_once dirname(__FILE__) . '/FetchRecord.php';
include_once 'include/Webservices/DescribeObject.php';
class Mobile_WS_FetchRecordWithGrouping extends Mobile_WS_FetchRecord {
private $_cachedDescribeInfo = false;
private $_cachedDescribeFieldInfo = false;
protected function cacheDescribeInfo($describeInfo) {
$this->_cachedDescribeInfo = $describeInfo;
$this->_cachedDescribeFieldInfo = array();
if(!empty($describeInfo['fields'])) {
foreach($describeInfo['fields'] as $describeFieldInfo) {
$this->_cachedDescribeFieldInfo[$describeFieldInfo['name']] = $describeFieldInfo;
}
}
}
protected function cachedDescribeInfo() {
return $this->_cachedDescribeInfo;
}
protected function cachedDescribeFieldInfo($fieldname) {
if ($this->_cachedDescribeFieldInfo !== false) {
if(isset($this->_cachedDescribeFieldInfo[$fieldname])) {
return $this->_cachedDescribeFieldInfo[$fieldname];
}
}
return false;
}
protected function cachedEntityFieldnames($module) {
$describeInfo = $this->cachedDescribeInfo();
$labelFields = $describeInfo['labelFields'];
switch($module) {
case 'HelpDesk': $labelFields = 'ticket_title'; break;
case 'Documents': $labelFields = 'notes_title'; break;
}
return explode(',', $labelFields);
}
protected function isTemplateRecordRequest(Mobile_API_Request $request) {
$recordid = $request->get('record');
return (preg_match("/([0-9]+)x0/", $recordid));
}
protected function processRetrieve(Mobile_API_Request $request) {
$recordid = $request->get('record');
// Create a template record for use
if ($this->isTemplateRecordRequest($request)) {
$current_user = $this->getActiveUser();
$module = $this->detectModuleName($recordid);
$describeInfo = vtws_describe($module, $current_user);
Mobile_WS_Utils::fixDescribeFieldInfo($module, $describeInfo);
$this->cacheDescribeInfo($describeInfo);
$templateRecord = array();
foreach($describeInfo['fields'] as $describeField) {
$templateFieldValue = '';
if (isset($describeField['type']) && isset($describeField['type']['defaultValue'])) {
$templateFieldValue = $describeField['type']['defaultValue'];
} else if (isset($describeField['default'])) {
$templateFieldValue = $describeField['default'];
}
$templateRecord[$describeField['name']] = $templateFieldValue;
}
if (isset($templateRecord['assigned_user_id'])) {
$templateRecord['assigned_user_id'] = sprintf("%sx%s", Mobile_WS_Utils::getEntityModuleWSId('Users'), $current_user->id);
}
// Reset the record id
$templateRecord['id'] = $recordid;
return $templateRecord;
}
// Or else delgate the action to parent
return parent::processRetrieve($request);
}
function process(Mobile_API_Request $request) {
$response = parent::process($request);
return $this->processWithGrouping($request, $response);
}
protected function processWithGrouping(Mobile_API_Request $request, $response) {
$isTemplateRecord = $this->isTemplateRecordRequest($request);
$result = $response->getResult();
$resultRecord = $result['record'];
$module = $this->detectModuleName($resultRecord['id']);
$modifiedRecord = $this->transformRecordWithGrouping($resultRecord, $module, $isTemplateRecord);
$response->setResult(array('record' => $modifiedRecord));
return $response;
}
protected function transformRecordWithGrouping($resultRecord, $module, $isTemplateRecord=false) {
$current_user = $this->getActiveUser();
$moduleFieldGroups = Mobile_WS_Utils::gatherModuleFieldGroupInfo($module);
$modifiedResult = array();
$blocks = array(); $labelFields = false;
foreach($moduleFieldGroups as $blocklabel => $fieldgroups) {
$fields = array();
foreach($fieldgroups as $fieldname => $fieldinfo) {
// Pickup field if its part of the result
if(isset($resultRecord[$fieldname])) {
$field = array(
'name' => $fieldname,
'value' => $resultRecord[$fieldname],
'label' => $fieldinfo['label'],
'uitype'=> $fieldinfo['uitype']
);
// Template record requested send more details if available
if ($isTemplateRecord) {
$describeFieldInfo = $this->cachedDescribeFieldInfo($fieldname);
foreach($describeFieldInfo as $k=>$v) {
if (isset($field[$k])) continue;
$field[$k] = $v;
}
// Entity fieldnames
$labelFields = $this->cachedEntityFieldnames($module);
}
// Fix the assigned to uitype
if ($field['uitype'] == '53') {
$field['type']['defaultValue'] = array('value' => "19x{$current_user->id}", 'label' => $current_user->column_fields['last_name']);
} else if($field['uitype'] == '117') {
$field['type']['defaultValue'] = $field['value'];
}
// END
$fields[] = $field;
}
}
$blocks[] = array( 'label' => $blocklabel, 'fields' => $fields );
}
$sections = array();
$moduleFieldGroupKeys = array_keys($moduleFieldGroups);
foreach($moduleFieldGroupKeys as $blocklabel) {
// Eliminate empty blocks
if(isset($groups[$blocklabel]) && !empty($groups[$blocklabel])) {
$sections[] = array( 'label' => $blocklabel, 'count' => count($groups[$blocklabel]) );
}
}
$modifiedResult = array('blocks' => $blocks, 'id' => $resultRecord['id']);
if($labelFields) $modifiedResult['labelFields'] = $labelFields;
return $modifiedResult;
}
}
@@ -0,0 +1,91 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once 'include/Webservices/Query.php';
include_once dirname(__FILE__) . '/FetchRecordWithGrouping.php';
include_once dirname(__FILE__) . '/models/Alert.php';
class Mobile_WS_FetchRecordsWithGrouping extends Mobile_WS_FetchRecordWithGrouping {
function process(Mobile_API_Request $request) {
$response = new Mobile_API_Response();
$current_user = $this->getActiveUser();
$module = $request->get('module');
$moduleWSID = Mobile_WS_Utils::getEntityModuleWSId($module);
if (empty($module)) {
$response->setError(1501, "Module not specified.");
return $response;
}
$records = array();
// Fetch the request parameters
$idlist = $request->get('ids');
$alertid = $request->get('alertid');
// List of ids specified?
if (!empty($idlist)) {
$idlist = Zend_Json::decode($idlist);
$records = $this->fetchRecordsWithId($module, $idlist, $current_user);
}
// Alert id specified?
else if (!empty($alertid)) {
$alert = Mobile_WS_AlertModel::modelWithId($alertid);
if ($alert === false) {
$response->setError(1404, "Alert not found.");
$records = false;
}
$alert->setUser($current_user);
$records = $this->fetchAlertRecords($module, $alert);
}
if ($records !== false) {
$response->setResult(array('records' => $records));
}
return $response;
}
function fetchRecordsWithId($module, $idlist, $user) {
if (empty($idlist)) return array();
$wsresult = vtws_query(sprintf("SELECT * FROM {$module} WHERE id IN ('%s');", implode("','", $idlist)), $user);
if (!empty($wsresult)) {
$resolvedRecords = array();
foreach($wsresult as $record) {
$this->resolveRecordValues($record, $user);
$resolvedRecords[] = $this->transformRecordWithGrouping($record, $module, false);
}
}
return $resolvedRecords;
}
function fetchAlertRecords($module, $alert) {
global $adb;
// Initialize global variable: ($alert->query() could indirectly depend if its using Module API as its base)
global $current_user;
if (!isset($current_user)) $current_user = $alert->getUser();
$moduleWSID = Mobile_WS_Utils::getEntityModuleWSId($module);
$alertResult = $adb->pquery($alert->query(), $alert->queryParameters());
$fetchIds = array();
while($resultrow = $adb->fetch_array($alertResult)) {
$fetchIds[] = "{$moduleWSID}x" . $resultrow['crmid'];
}
return $this->fetchRecordsWithId($module, $fetchIds, $alert->getUser());
}
}
@@ -0,0 +1,57 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/FetchModuleFilters.php';
include_once 'modules/CustomView/CustomView.php';
class Mobile_WS_FilterDetailsWithCount extends Mobile_WS_FetchModuleFilters {
function process(Mobile_API_Request $request) {
global $current_user;
$response = new Mobile_API_Response();
$filterid = $request->get('filterid');
$current_user = $this->getActiveUser();
$result = array();
$result['filter'] = $this->getModuleFilterDetails($filterid);
$response->setResult($result);
return $response;
}
protected function getModuleFilterDetails($filterid) {
global $adb;
$result = $adb->pquery("SELECT * FROM vtiger_customview WHERE cvid=?", array($filterid));
if ($result && $adb->num_rows($result)) {
$resultrow = $adb->fetch_array($result);
$module = $resultrow['entitytype'];
$view = new CustomView($module);
$viewid = $resultrow['cvid'];
$view->getCustomViewByCvid($viewid);
$viewQuery = $view->getModifiedCvListQuery($viewid, getListQuery($module), $module);
$countResult = $adb->pquery(mkCountQuery($viewQuery), array());
$count = 0;
if($countResult && $adb->num_rows($countResult)) {
$count = $adb->query_result($countResult, 0, 'count');
}
$filter = $this->prepareFilterDetailUsingResultRow($resultrow);
$filter['userName'] = getUserName($resultrow['userid']);
$filter['count'] = $count;
return $filter;
}
}
}
@@ -0,0 +1,188 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/models/Alert.php';
include_once dirname(__FILE__) . '/models/SearchFilter.php';
include_once dirname(__FILE__) . '/models/Paging.php';
class Mobile_WS_ListModuleRecords extends Mobile_WS_Controller {
function isCalendarModule($module) {
return ($module == 'Events' || $module == 'Calendar');
}
function getSearchFilterModel($module, $search) {
return Mobile_WS_SearchFilterModel::modelWithCriterias($module, Zend_JSON::decode($search));
}
function getPagingModel(Mobile_API_Request $request) {
$page = $request->get('page', 0);
return Mobile_WS_PagingModel::modelWithPageStart($page);
}
function process(Mobile_API_Request $request) {
return $this->processSearchRecordLabel($request);
}
function processSearchRecordLabel(Mobile_API_Request $request) {
global $current_user; // Few core API assumes this variable availability
$current_user = $this->getActiveUser();
$module = $request->get('module');
$alertid = $request->get('alertid');
$filterid = $request->get('filterid');
$search = $request->get('search');
$filterOrAlertInstance = false;
if(!empty($alertid)) {
$filterOrAlertInstance = Mobile_WS_AlertModel::modelWithId($alertid);
}
else if(!empty($filterid)) {
$filterOrAlertInstance = Mobile_WS_FilterModel::modelWithId($module, $filterid);
}
else if(!empty($search)) {
$filterOrAlertInstance = $this->getSearchFilterModel($module, $search);
}
if($filterOrAlertInstance && strcmp($module, $filterOrAlertInstance->moduleName)) {
$response = new Mobile_API_Response();
$response->setError(1001, 'Mistached module information.');
return $response;
}
// Initialize with more information
if($filterOrAlertInstance) {
$filterOrAlertInstance->setUser($current_user);
}
// Paging model
$pagingModel = $this->getPagingModel($request);
if($this->isCalendarModule($module)) {
return $this->processSearchRecordLabelForCalendar($request, $pagingModel);
}
$records = $this->fetchRecordLabelsForModule($module, $current_user, array(), $filterOrAlertInstance, $pagingModel);
$modifiedRecords = array();
foreach($records as $record) {
if ($record instanceof SqlResultIteratorRow) {
$record = $record->data;
// Remove all integer indexed mappings
for($index = count($record); $index > -1; --$index) {
if(isset($record[$index])) {
unset($record[$index]);
}
}
}
$recordid = $record['id'];
unset($record['id']);
$eventstart = '';
if($this->isCalendarModule($module)) {
$eventstart = $record['date_start'];
unset($record['date_start']);
}
$values = array_values($record);
$label = implode(' ', $values);
$modifiedRecord = array('id' => $recordid, 'label'=>$label);
if(!empty($eventstart)) {
$modifiedRecord['eventstart'] = $eventstart;
}
$modifiedRecords[] = $modifiedRecord;
}
$response = new Mobile_API_Response();
$response->setResult(array('records'=>$modifiedRecords, 'module'=>$module));
return $response;
}
function processSearchRecordLabelForCalendar(Mobile_API_Request $request, $pagingModel = false) {
$current_user = $this->getActiveUser();
// Fetch both Calendar (Todo) and Event information
$moreMetaFields = array('date_start', 'time_start', 'activitytype', 'location');
$eventsRecords = $this->fetchRecordLabelsForModule('Events', $current_user, $moreMetaFields, false, $pagingModel);
$calendarRecords=$this->fetchRecordLabelsForModule('Calendar', $current_user, $moreMetaFields, false, $pagingModel);
// Merge the Calendar & Events information
$records = array_merge($eventsRecords, $calendarRecords);
$modifiedRecords = array();
foreach($records as $record) {
$modifiedRecord = array();
$modifiedRecord['id'] = $record['id']; unset($record['id']);
$modifiedRecord['eventstartdate'] = $record['date_start']; unset($record['date_start']);
$modifiedRecord['eventstarttime'] = $record['time_start']; unset($record['time_start']);
$modifiedRecord['eventtype'] = $record['activitytype']; unset($record['activitytype']);
$modifiedRecord['eventlocation'] = $record['location']; unset($record['location']);
$modifiedRecord['label'] = implode(' ',array_values($record));
$modifiedRecords[] = $modifiedRecord;
}
$response = new Mobile_API_Response();
$response->setResult(array('records' =>$modifiedRecords, 'module'=>'Calendar'));
return $response;
}
function fetchRecordLabelsForModule($module, $user, $morefields=array(), $filterOrAlertInstance=false, $pagingModel = false) {
if($this->isCalendarModule($module)) {
$fieldnames = Mobile_WS_Utils::getEntityFieldnames('Calendar');
} else {
$fieldnames = Mobile_WS_Utils::getEntityFieldnames($module);
}
if(!empty($morefields)) {
foreach($morefields as $fieldname) $fieldnames[] = $fieldname;
}
if($filterOrAlertInstance === false) {
$filterOrAlertInstance = Mobile_WS_SearchFilterModel::modelWithCriterias($module);
$filterOrAlertInstance->setUser($user);
}
return $this->queryToSelectFilteredRecords($module, $fieldnames, $filterOrAlertInstance, $pagingModel);
}
function queryToSelectFilteredRecords($module, $fieldnames, $filterOrAlertInstance, $pagingModel) {
if ($filterOrAlertInstance instanceof Mobile_WS_SearchFilterModel) {
return $filterOrAlertInstance->execute($fieldnames, $pagingModel);
}
global $adb;
$moduleWSId = Mobile_WS_Utils::getEntityModuleWSId($module);
$columnByFieldNames = Mobile_WS_Utils::getModuleColumnTableByFieldNames($module, $fieldnames);
// Build select clause similar to Webservice query
$selectColumnClause = "CONCAT('{$moduleWSId}','x',vtiger_crmentity.crmid) as id,";
foreach($columnByFieldNames as $fieldname=>$fieldinfo) {
$selectColumnClause .= sprintf("%s.%s as %s,", $fieldinfo['table'],$fieldinfo['column'],$fieldname);
}
$selectColumnClause = rtrim($selectColumnClause, ',');
$query = $filterOrAlertInstance->query();
$query = preg_replace("/SELECT.*FROM(.*)/i", "SELECT $selectColumnClause FROM $1", $query);
if ($pagingModel !== false) {
$query .= sprintf(" LIMIT %s, %s", $pagingModel->currentCount(), $pagingModel->limit());
}
$prequeryResult = $adb->pquery($query, $filterOrAlertInstance->queryParameters());
return new SqlResultIterator($adb, $prequeryResult);
}
}
@@ -0,0 +1,62 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
class Mobile_WS_Login extends Mobile_WS_Controller {
function requireLogin() {
return false;
}
function process(Mobile_API_Request $request) {
$response = new Mobile_API_Response();
$username = $request->get('username');
$password = $request->get('password');
$current_user = CRMEntity::getInstance('Users');
$current_user->column_fields['user_name'] = $username;
if(vtlib_isModuleActive('Mobile') === false) {
$response->setError(1501, 'Service not available');
return $response;
}
if(!$current_user->doLogin($password)) {
$response->setError(1210, 'Authentication Failed');
} else {
// Start session now
$sessionid = Mobile_API_Session::init();
if($sessionid === false) {
echo "Session init failed $sessionid\n";
}
$current_user->id = $current_user->retrieve_user_id($username);
$this->setActiveUser($current_user);
$result = array();
$result['login'] = array(
'userid' => $current_user->id,
'session'=> $sessionid,
'vtiger_version' => Mobile_WS_Utils::getVtigerVersion(),
'mobile_module_version' => Mobile_WS_Utils::getVersion()
);
$response->setResult($result);
$this->postProcess($response);
}
return $response;
}
function postProcess(Mobile_API_Response $response) {
return $response;
}
}
@@ -0,0 +1,50 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/Login.php';
class Mobile_WS_LoginAndFetchModules extends Mobile_WS_Login {
function postProcess(Mobile_API_Response $response) {
$current_user = $this->getActiveUser();
if ($current_user) {
$result = $response->getResult();
$result['modules'] = $this->getListing($current_user);
$response->setResult($result);
}
}
function getListing($user) {
$modulewsids = Mobile_WS_Utils::getEntityModuleWSIds();
// Disallow modules
unset($modulewsids['Users']);
// Calendar & Events module will be merged
unset($modulewsids['Events']);
$listresult = vtws_listtypes($user);
$listing = array();
foreach($listresult['types'] as $index => $modulename) {
if(!isset($modulewsids[$modulename])) continue;
$listing[] = array(
'id' => $modulewsids[$modulename],
'name' => $modulename,
'isEntity' => $listresult['information'][$modulename]['isEntity'],
'label' => $listresult['information'][$modulename]['label'],
'singular' => $listresult['information'][$modulename]['singular'],
);
}
return $listing;
}
}
@@ -0,0 +1,61 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/FetchRecordWithGrouping.php';
include_once 'include/Webservices/Query.php';
class Mobile_WS_Query extends Mobile_WS_FetchRecordWithGrouping {
function processQueryResultRecord(&$record, $user) {
$this->resolveRecordValues($record, $user);
return $record;
}
function process(Mobile_API_Request $request) {
$current_user = $this->getActiveUser();
$query = $request->get('query');
$nextPage = 0;
$queryResult = false;
if (preg_match("/(.*) LIMIT[^;]+;/i", $query)) {
$queryResult = vtws_query($query, $current_user);
} else {
// Implicit limit and paging
$query = rtrim($query, ";");
$currentPage = intval($request->get('page', 0));
$FETCH_LIMIT = Mobile::config('API_RECORD_FETCH_LIMIT');
$startLimit = $currentPage * $FETCH_LIMIT;
$queryWithLimit = sprintf("%s LIMIT %u,%u;", $query, $startLimit, ($FETCH_LIMIT+1));
$queryResult = vtws_query($queryWithLimit, $current_user);
// Determine paging
$hasNextPage = (count($queryResult) > $FETCH_LIMIT);
if ($hasNextPage) {
array_pop($queryResult); // Avoid sending next page record now
$nextPage = $currentPage + 1;
}
}
$records = array();
if (!empty($queryResult)) {
foreach($queryResult as $recordValues) {
$records[] = $this->processQueryResultRecord($recordValues, $current_user);
}
}
$result = array('records' => $records, 'nextPage' => $nextPage );
$response = new Mobile_API_Response();
$response->setResult($result);
return $response;
}
}
@@ -0,0 +1,35 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/Query.php';
include_once 'include/Webservices/Query.php';
class Mobile_WS_QueryWithGrouping extends Mobile_WS_Query {
private $queryModule;
function processQueryResultRecord($record, $user) {
parent::processQueryResultRecord($record, $user);
if ($this->cachedDescribeInfo() === false) {
$describeInfo = vtws_describe($this->queryModule, $user);
$this->cacheDescribeInfo($describeInfo);
}
$transformedRecord = $this->transformRecordWithGrouping($record, $this->queryModule);
// Update entity fieldnames
$transformedRecord['labelFields'] = $this->cachedEntityFieldnames($this->queryModule);
return $transformedRecord;
}
function process(Mobile_API_Request $request) {
$this->queryModule = $request->get('module');
return parent::process($request);
}
}
@@ -0,0 +1,79 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/QueryWithGrouping.php';
class Mobile_WS_RelatedRecordsWithGrouping extends Mobile_WS_QueryWithGrouping {
function process(Mobile_API_Request $request) {
global $current_user, $adb, $currentModule;
$current_user = $this->getActiveUser();
$response = new Mobile_API_Response();
$record = $request->get('record');
$relatedmodule = $request->get('relatedmodule');
$currentPage = $request->get('page', 0);
// Input validation
if (empty($record)) {
$response->setError(1001, 'Record id is empty');
return $response;
}
$recordid = vtws_getIdComponents($record);
$recordid = $recordid[1];
$module = Mobile_WS_Utils::detectModulenameFromRecordId($record);
// Initialize global variable
$currentModule = $module;
$functionHandler = Mobile_WS_Utils::getRelatedFunctionHandler($module, $relatedmodule);
if ($functionHandler) {
$sourceFocus = CRMEntity::getInstance($module);
$relationResult = call_user_func_array( array($sourceFocus, $functionHandler), array($recordid, getTabid($module), getTabid($relatedmodule)) );
$query = $relationResult['query'];
$querySEtype = "vtiger_crmentity.setype as setype";
if ($relatedmodule == 'Calendar') {
$querySEtype = "vtiger_activity.activitytype as setype";
}
$query = sprintf("SELECT vtiger_crmentity.crmid, $querySEtype %s", substr($query, stripos($query, 'FROM')));
$queryResult = $adb->query($query);
// Gather resolved record id's
$relatedRecords = array();
while($row = $adb->fetch_array($queryResult)) {
$targetSEtype = $row['setype'];
if ($relatedmodule == 'Calendar') {
if ($row['setype'] != 'Task' && $row['setype'] != 'Emails') {
$targetSEtype = 'Events';
} else {
$targetSEtype = $relatedmodule;
}
}
$relatedRecords[] = sprintf("%sx%s", Mobile_WS_Utils::getEntityModuleWSId($targetSEtype), $row['crmid']);
}
// Perform query to get record information with grouping
$wsquery = sprintf("SELECT * FROM %s WHERE id IN ('%s');", $relatedmodule, implode("','", $relatedRecords));
$newRequest = new Mobile_API_Request();
$newRequest->set('module', $relatedmodule);
$newRequest->set('query', $wsquery);
$newRequest->set('page', $currentPage);
$response = parent::process($newRequest);
}
return $response;
}
}
@@ -0,0 +1,82 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/FetchRecordWithGrouping.php';
include_once 'include/Webservices/Create.php';
include_once 'include/Webservices/Update.php';
class Mobile_WS_SaveRecord extends Mobile_WS_FetchRecordWithGrouping {
protected $recordValues = false;
// Avoid retrieve and return the value obtained after Create or Update
protected function processRetrieve(Mobile_API_Request $request) {
return $this->recordValues;
}
function process(Mobile_API_Request $request) {
global $current_user; // Required for vtws_update API
$current_user = $this->getActiveUser();
$module = $request->get('module');
$recordid = $request->get('record');
$valuesJSONString = $request->get('values');
$values = "";
if(!empty($valuesJSONString)) {
$values = Zend_Json::decode($valuesJSONString);
}
$response = new Mobile_API_Response();
if (empty($values)) {
$response->setError(1501, "Values cannot be empty!");
return $response;
}
try {
// Retrieve or Initalize
if (!empty($recordid) && !$this->isTemplateRecordRequest($request)) {
$this->recordValues = vtws_retrieve($recordid, $current_user);
} else {
$this->recordValues = array();
}
// Set the modified values
foreach($values as $name => $value) {
$this->recordValues[$name] = $value;
}
// Update or Create
if (isset($this->recordValues['id'])) {
$this->recordValues = vtws_update($this->recordValues, $current_user);
} else {
// Set right target module name for Calendar/Event record
if ($module == 'Calendar') {
if (!empty($this->recordValues['eventstatus'])) {
$module = 'Events';
}
}
$this->recordValues = vtws_create($module, $this->recordValues, $current_user);
}
// Update the record id
$request->set('record', $this->recordValues['id']);
// Gather response with full details
$response = parent::process($request);
} catch(Exception $e) {
$response->setError($e->getCode(), $e->getMessage());
}
return $response;
}
}
@@ -0,0 +1,172 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/SaveRecord.php';
include_once 'include/Webservices/Query.php';
class Mobile_WS_SyncModuleRecords extends Mobile_WS_SaveRecord {
static $SYNC_MODE_PUBLIC = "PUBLIC";
static $SYNC_MODE_PRIVATE = "PRIVATE";
function isModePrivate(Mobile_API_Request $request, $defmode="PRIVATE") {
return (strcasecmp($request->get('mode', $defmode), self::$SYNC_MODE_PRIVATE) === 0);
}
function process(Mobile_API_Request $request) {
$current_user = $this->getActiveUser();
$current_user_wsid = sprintf("%sx%s", Mobile_WS_Utils::getEntityModuleWSId("Users"), $current_user->id);
$module = $request->get('module');
$lastSyncTime = $request->get('syncToken', 0);
$currentPage = intval($request->get('page', 0));
$isPrivateMode = $this->isModePrivate($request);
$FETCH_LIMIT = Mobile::config('API_RECORD_FETCH_LIMIT');
$startLimit = $currentPage * $FETCH_LIMIT;
// Keep track of sync-token for futher reference
$maxSyncTime = $lastSyncTime;
$describeInfo = vtws_describe($module, $current_user);
$this->cacheDescribeInfo($describeInfo);
$hasAssignedToField = false;
foreach ($describeInfo['fields'] as $fieldinfo) {
if ($fieldinfo['name'] == 'assigned_user_id') {
$hasAssignedToField = true;
break;
}
}
/////////////////////////////
// MODIFIED RECORDS TRACKING
/////////////////////////////
if (empty($lastSyncTime)) {
// No previous state information available? Lookup records recently modified
if ($hasAssignedToField && $isPrivateMode) {
$queryActive = sprintf("SELECT * FROM %s WHERE assigned_user_id = '%s' ORDER BY modifiedtime DESC", $module, $current_user_wsid);
} else {
$queryActive = sprintf("SELECT * FROM %s ORDER BY modifiedtime DESC", $module);
}
} else {
// Attempt to lookup records from previous state
if ($hasAssignedToField && $isPrivateMode) {
$queryActive = sprintf("SELECT * FROM %s WHERE assigned_user_id = '%s' AND modifiedtime > '%s'", $module, $current_user_wsid, date("Y-m-d H:i:s", $lastSyncTime));
} else {
$queryActive = sprintf("SELECT * FROM %s WHERE modifiedtime > '%s'", $module, date("Y-m-d H:i:s", $lastSyncTime));
}
}
// Try to fetch record with paging (one extra record fetch is attempted to determine presence of next page)
$activeQuery = sprintf("%s LIMIT %u,%u;", $queryActive, $startLimit, ($FETCH_LIMIT+1));
$activeResult = vtws_query( $activeQuery, $current_user );
// Special case handling merge Events records
if ($module == 'Calendar') {
$activeResult2 = vtws_query(str_replace('Calendar', 'Events', $activeQuery), $current_user);
if (!empty($activeResult2)) $activeResult = array_merge($activeResult, $activeResult2);
$FETCH_LIMIT *= 2;
}
// Determine paging
$hasNextPage = (count($activeResult) > $FETCH_LIMIT);
$nextPage = 0;
if ($hasNextPage) {
array_pop($activeResult); // Avoid sending next page record now
$nextPage = $currentPage + 1;
}
// Resolved record details
$resolvedModifiedRecords = array();
$resolvedDeletedRecords = array();
if (!empty($activeResult)) {
foreach($activeResult as $recordValues) {
$this->resolveRecordValues($recordValues, $current_user);
$transformedRecord = $this->transformRecordWithGrouping($recordValues, $module);
// Update entity fieldnames
$transformedRecord['labelFields'] = $this->cachedEntityFieldnames($module);
$resolvedModifiedRecords[] = $transformedRecord;
$modifiedTimeInSeconds = strtotime($recordValues['modifiedtime']);
if ($maxSyncTime < $modifiedTimeInSeconds) {
$maxSyncTime = $modifiedTimeInSeconds;
}
}
}
////////////////////////////
// DELETED RECORDS TRACKING
////////////////////////////
// Only when there is previous state information and is first page
if (!empty($lastSyncTime) && $currentPage === 0) {
global $adb;
$queryDeletedParameters = array($module, date('Y-m-d H:i:s', $lastSyncTime));
$andsmowneridequal = "";
if ($hasAssignedToField) {
if ($isPrivateMode) {
$queryDeletedParameters[] = $current_user->id;
$andsmowneridequal = " AND vtiger_crmentity.smownerid=?";
} else {
$andsmowneridequal = Mobile_WS_Utils::querySecurityFromSuffix($module, $current_user);
}
}
// Since Calendar and Events are merged
if ($module == 'Calendar') {
$queryDeleted = $adb->pquery("SELECT activityid as crmid, activitytype as setype FROM vtiger_activity
INNER JOIN vtiger_crmentity ON vtiger_activity.activityid=vtiger_crmentity.crmid
AND vtiger_crmentity.deleted=1 AND vtiger_crmentity.setype=? AND vtiger_crmentity.modifiedtime > ?
LEFT JOIN vtiger_users ON vtiger_users.id = vtiger_crmentity.smownerid
LEFT JOIN vtiger_groups ON vtiger_groups.groupid = vtiger_crmentity.smownerid WHERE 1=1 $andsmowneridequal ",
$queryDeletedParameters);
} else {
$queryDeleted = $adb->pquery("SELECT crmid, modifiedtime, setype FROM vtiger_crmentity
LEFT JOIN vtiger_users ON vtiger_users.id = vtiger_crmentity.smownerid
LEFT JOIN vtiger_groups ON vtiger_groups.groupid = vtiger_crmentity.smownerid
WHERE vtiger_crmentity.deleted=1 AND vtiger_crmentity.setype=? AND vtiger_crmentity.modifiedtime > ? $andsmowneridequal", $queryDeletedParameters);
}
while($row = $adb->fetch_array($queryDeleted)) {
$recordModule = $row['setype'];
if ($module == 'Calendar') {
if ($row['setype'] != 'Task' && $row['setype'] != 'Emails') {
$recordModule = 'Events';
} else {
$recordModule = $module;
}
}
$resolvedDeletedRecords[] = sprintf("%sx%s", Mobile_WS_Utils::getEntityModuleWSId($recordModule), $row['crmid']);
$modifiedTimeInSeconds = strtotime($row['modifiedtime']);
if ($maxSyncTime < $modifiedTimeInSeconds) {
$maxSyncTime = $modifiedTimeInSeconds;
}
}
}
$result = array(
'nextSyncToken' => $maxSyncTime,
'deleted' => $resolvedDeletedRecords,
'updated' => $resolvedModifiedRecords,
'nextPage'=> $nextPage, // Applies only to retrieve updated record details
);
$response = new Mobile_API_Response();
$response->setResult( array( 'sync' => $result) );
return $response;
}
}
@@ -0,0 +1,100 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
abstract class Mobile_WS_AlertModel {
var $alertid; // Unique id refering the instance
var $name; // Name of the alert - should be unique to make it easy on client side
var $moduleName; // If alert is targeting module record count, this should be set along with $recordsLinked
var $refreshRate;// Recommended lookup rate in SECONDS
var $description;// Describe the purpose of alert to client
var $recordsLinked;// TRUE if message is based on records of module, FALSE otherwise
protected $user;
function __construct() {
$this->recordsLinked = true;
}
function setUser($userInstance) {
$this->user = $userInstance;
}
function getUser() {
return $this->user;
}
function serializeToSend() {
$category = $this->moduleName;
if (empty($category)) {
$category = "General";
}
return array(
'alertid' => (string)$this->alertid,
'name' => $this->name,
'category' => $category,
'refreshRate'=> $this->refreshRate,
'description'=> $this->description,
'recordsLinked'=> $this->recordsLinked
);
}
abstract function query();
abstract function queryParameters();
function message() {
return (string) $this->executeCount();
}
/*function execute() {
global $adb;
$result = $adb->pquery($this->query(), $this->queryParameters());
return $result;
}*/
function executeCount() {
global $adb;
$result = $adb->pquery($this->countQuery(), $this->queryParameters());
return $adb->query_result($result, 0, 'count');
}
// Function provided to enable sub-classes to over-ride in case required
protected function countQuery() {
return mkCountQuery($this->query());
}
static function models() {
global $adb;
$models = array();
$handlerResult = $adb->pquery("SELECT * FROM vtiger_mobile_alerts WHERE deleted = 0", array());
if ($adb->num_rows($handlerResult)) {
while ($handlerRow = $adb->fetch_array($handlerResult)) {
$handlerPath = $handlerRow['handler_path'];
if (file_exists($handlerPath)) {
checkFileAccess($handlerPath);
include_once $handlerPath;
$alertModel = new $handlerRow['handler_class'];
$alertModel->alertid = $handlerRow['id'];
$models[] = $alertModel;
}
}
}
return $models;
}
static function modelWithId($alertid) {
$models = self::models();
foreach($models as $model) {
if ($model->alertid == $alertid) return $model;
}
return false;
}
}
@@ -0,0 +1,47 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once 'modules/CustomView/CustomView.php';
class Mobile_WS_FilterModel {
var $filterid, $moduleName;
var $user;
protected $customView;
function __construct($moduleName) {
$this->moduleName = $moduleName;
$this->customView = new CustomView($moduleName);
}
function setUser($userInstance) {
$this->user = $userInstance;
}
function getUser() {
return $this->user;
}
function query() {
$listquery = getListQuery($this->moduleName);
$query = $this->customView->getModifiedCvListQuery($this->filterid,$listquery,$this->moduleName);
return $query;
}
function queryParameters() {
return false;
}
static function modelWithId($moduleName, $filterid) {
$model = new Mobile_WS_FilterModel($moduleName);
$model->filterid = $filterid;
return $model;
}
}
@@ -0,0 +1,71 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
class Mobile_WS_PagingModel {
var $_start;
var $_limit;
var $_page;
function __construct() {
$this->_limit = Mobile::config('API_RECORD_FETCH_LIMIT', 20);
}
function start() {
return $this->_start;
}
function limit() {
return $this->_limit;
}
function currentCount() {
return ($this->current() * $this->limit());
}
function current() {
return $this->_page;
}
function next() {
return ($this->current()+1);
}
function previous() {
return ($this->current() < 1? 0 : ($this->current()-1));
}
function hasNext($countOnPage) {
return ($countOnPage >= $this->limit());
}
function hasPrevious() {
return ($this->start() != 0);
}
function initStart($page) {
if(empty($page)) $page = 0;
$this->_page = $page;
if($page < 1) $this->_start = 0;
else $this->_start = ($page * $this->_limit);
}
function setLimit($limit) {
$this->_limit = $limit;
}
static function modelWithPageStart($start) {
$instance = new self();
$instance->initStart($start);
return $instance;
}
}
?>
@@ -0,0 +1,58 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once 'include/Webservices/Query.php';
include_once dirname(__FILE__) . '/Filter.php';
class Mobile_WS_SearchFilterModel extends Mobile_WS_FilterModel {
protected $criterias;
function __construct($moduleName) {
$this->moduleName = $moduleName;
}
function query() {
return false;
}
function queryParameters() {
return false;
}
function setCriterias($criterias) {
$this->criterias = $criterias;
}
function execute($fieldnames, $pagingModel = false) {
$selectClause = sprintf("SELECT %s", implode(',', $fieldnames));
$fromClause = sprintf("FROM %s", $this->moduleName);
$whereClause = "";
$orderClause = "";
$groupClause = "";
$limitClause = $pagingModel? " LIMIT {$pagingModel->currentCount()},{$pagingModel->limit()}" : "" ;
if (!empty($this->criterias)) {
$_sortCriteria = $this->criterias['_sort'];
if(!empty($_sortCriteria)) {
$orderClause = $_sortCriteria;
}
}
$query = sprintf("%s %s %s %s %s %s;", $selectClause, $fromClause, $whereClause, $orderClause, $groupClause, $limitClause);
return vtws_query($query, $this->getUser());
}
static function modelWithCriterias($moduleName, $criterias = false) {
$model = new Mobile_WS_SearchFilterModel($moduleName);
$model->setCriterias($criterias);
return $model;
}
}
@@ -0,0 +1,27 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/PendingTicketsOfMine.php';
/** Idle Ticket Alert */
class Mobile_WS_AlertModel_IdleTicketsOfMine extends Mobile_WS_AlertModel_PendingTicketsOfMine {
function __construct() {
parent::__construct();
$this->name = 'Idle Ticket Alert';
$this->moduleName = 'HelpDesk';
$this->refreshRate= 1 * (60 * 60); // 1 hour
$this->description='Alert sent when ticket has not been updated in 24 hours';
}
function query() {
$sql = parent::query();
$sql .= " AND DATEDIFF(CURDATE(), vtiger_crmentity.modifiedtime) > 1";
return $sql;
}
}
@@ -0,0 +1,37 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/PendingTicketsOfMine.php';
/** New Ticket */
class Mobile_WS_AlertModel_NewTicketOfMine extends Mobile_WS_AlertModel_PendingTicketsOfMine {
function __construct() {
parent::__construct();
$this->name = 'New Ticket Alert';
$this->moduleName = 'HelpDesk';
$this->refreshRate= 1 * (60 * 60); // 1 hour
$this->description='Alert sent when a ticket is assigned to you';
}
function query() {
$sql = parent::query();
$sql .= " ORDER BY crmid DESC LIMIT 1";
return $sql;
}
function countQuery() {
return str_replace("ORDER BY crmid DESC", "", $this->query());
}
function executeCount() {
global $adb;
$result = $adb->pquery($this->countQuery(), $this->queryParameters());
return $adb->num_rows($result);
}
}
@@ -0,0 +1,33 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/../Alert.php';
/** Pending Ticket Alert */
class Mobile_WS_AlertModel_PendingTicketsOfMine extends Mobile_WS_AlertModel {
function __construct() {
parent::__construct();
$this->name = 'Pending Ticket Alert';
$this->moduleName = 'HelpDesk';
$this->refreshRate= 1 * (24* 60 * 60); // 1 day
$this->description='Alert sent when ticket assigned is not yet closed';
}
function query() {
$sql = "SELECT crmid FROM vtiger_troubletickets INNER JOIN
vtiger_crmentity ON vtiger_crmentity.crmid=vtiger_troubletickets.ticketid
WHERE vtiger_crmentity.deleted=0 AND vtiger_crmentity.smownerid=? AND
vtiger_troubletickets.status <> 'Closed'";
return $sql;
}
function queryParameters() {
return array($this->getUser()->id);
}
}
@@ -0,0 +1,33 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/../Alert.php';
/** Upcoming Opportunity */
class Mobile_WS_AlertModel_PotentialsDueIn5Days extends Mobile_WS_AlertModel {
function __construct() {
parent::__construct();
$this->name = 'Upcoming Opportunity';
$this->moduleName = 'Potentials';
$this->refreshRate= 1 * (24 * 60 * 60); // 1 day
$this->description='Alert sent when Potential Close Date is due before 5 days or less';
}
function query() {
$sql = Mobile_WS_Utils::getModuleListQuery('Potentials',
"vtiger_potential.sales_stage not like 'Closed%' AND
DATEDIFF(vtiger_potential.closingdate, CURDATE()) <= 5"
);
return preg_replace("/^SELECT count\(\*\) as count(.*)/i", "SELECT crmid $1", mkCountQuery($sql));
}
function queryParameters() {
return array();
}
}
@@ -0,0 +1,38 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/../Alert.php';
/** Server time sample alert */
class Mobile_WS_AlertModel_ServerTimeSampleAlert extends Mobile_WS_AlertModel {
function __construct() {
// Mandatory call to parent constructor
parent::__construct();
$this->name = 'Server Time Alert';
$this->description='Alert to get server time information';
$this->refreshRate= 1; // 1 second
$this->recordsLinked = FALSE;
// There is no module records linked with message.
// If set to true $this->moduleName needs to be set.
}
function message() {
return date('Y-m-d H:i:s');
}
/** Override base class methods */
function query() {
return false;
}
function queryParameters() {
return false;
}
}
@@ -0,0 +1,126 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
/**********************************************************************
* Expose the extensions added over webservice API
*/
function mobile_ws_fetchAllAlerts($user) {
$request = new Mobile_API_Request();
return Mobile_WS_API::process($request, $user, 'Mobile_WS_FetchAllAlerts', 'ws/FetchAllAlerts.php');
}
function mobile_ws_alertDetailsWithMessage($alertid, $user) {
$request = new Mobile_API_Request();
$request->set('alertid', $alertid);
return Mobile_WS_API::process($request, $user, 'Mobile_WS_AlertDetailsWithMessage', 'ws/AlertDetailsWithMessage.php');
}
function mobile_ws_fetchModuleFilters($module, $user) {
$request = new Mobile_API_Request();
$request->set('module', $module);
return Mobile_WS_API::process($request, $user, 'Mobile_WS_FetchModuleFilters', 'ws/FetchModuleFilters.php');
}
function mobile_ws_fetchRecord($record, $user) {
$request = new Mobile_API_Request();
$request->set('record', $record);
return Mobile_WS_API::process($request, $user, 'Mobile_WS_FetchRecord', 'ws/FetchRecord.php');
}
function mobile_ws_fetchRecordWithGrouping($record, $user) {
$request = new Mobile_API_Request();
$request->set('record', $record);
return Mobile_WS_API::process($request, $user, 'Mobile_WS_FetchRecordWithGrouping', 'ws/FetchRecordWithGrouping.php');
}
function mobile_ws_filterDetailsWithCount($filterid, $user) {
$request = new Mobile_API_Request();
$request->set('filterid', $filterid);
return Mobile_WS_API::process($request, $user, 'Mobile_WS_FilterDetailsWithCount', 'ws/FilterDetailsWithCount.php');
}
function mobile_ws_listModuleRecords($elements, $user) {
$request = new Mobile_API_Request($elements); // elements can have key (module, alertid, filterid, search, page)
return Mobile_WS_API::process($request, $user, 'Mobile_WS_ListModuleRecords', 'ws/ListModuleRecords.php');
}
function mobile_ws_saveRecord($module, $record, $values, $user) {
$request = new Mobile_API_Request($values);
$request->set('module', $module);
$request->set('record', $record);
return Mobile_WS_API::process($request, $user, 'Mobile_WS_SaveRecord', 'ws/SaveRecord.php');
}
function mobile_ws_syncModuleRecords($module, $syncToken, $page, $user) {
$request = new Mobile_API_Request();
$request->set('module', $module);
$request->set('syncToken', $syncToken);
$request->set('page', $page);
return Mobile_WS_API::process($request, $user, 'Mobile_WS_SyncModuleRecords', 'ws/SyncModuleRecords.php');
}
function mobile_ws_query($module, $query, $page, $user) {
$request = new Mobile_API_Request();
$request->set('module', $module);
$request->set('query', $query);
$request->set('page', $page);
return Mobile_WS_API::process($request, $user, 'Mobile_WS_Query', 'ws/Query.php');
}
function mobile_ws_queryWithGrouping($module, $query, $page, $user) {
$request = new Mobile_API_Request();
$request->set('module', $module);
$request->set('query', $query);
$request->set('page', $page);
return Mobile_WS_API::process($request, $user, 'Mobile_WS_QueryWithGrouping', 'ws/QueryWithGrouping.php');
}
/**********************************************************************/
/**
* Mobile WS API Controller
*/
include_once dirname(__FILE__) . '/Request.php';
include_once dirname(__FILE__) . '/Response.php';
include_once dirname(__FILE__) . '/Session.php';
include_once dirname(__FILE__) . '/ws/Controller.php';
class Mobile_WS_API {
private $controller;
function initController($className, $handlerPath, $user) {
include_once dirname(__FILE__) . "/$handlerPath";
$this->controller = new $className();
Mobile_API_Session::init(session_id());
$this->controller->initActiveUser($user);
return $this->controller;
}
function getController() {
return $this->controller;
}
static function process(Mobile_API_Request $request, $user, $className, $handlerPath) {
if(vtlib_isModuleActive('Mobile') === false) {
throw new WebServiceException('1501', 'Service not available');
}
$wsapiController = new self();
$response = $wsapiController->initController($className, $handlerPath, $user)->process($request);
if($response->hasError()) {
$error = $response->getError();
throw new WebServiceException($error['code'], $error['message']);
}
return $response->getResult();
}
}