晋太元中,武陵人捕鱼为业。缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷。渔人甚异之,复前行,欲穷其林。 林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田、美池、桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。 见渔人,乃大惊,问所从来。具答之。便要还家,设酒杀鸡作食。村中闻有此人,咸来问讯。自云先世避秦时乱,率妻子邑人来此绝境,不复出焉,遂与外人间隔。问今是何世,乃不知有汉,无论魏晋。此人一一为具言所闻,皆叹惋。余人各复延至其家,皆出酒食。停数日,辞去。此中人语云:“不足为外人道也。”(间隔 一作:隔绝) 既出,得其船,便扶向路,处处志之。及郡下,诣太守,说如此。太守即遣人随其往,寻向所志,遂迷,不复得路。 南阳刘子骥,高尚士也,闻之,欣然规往。未果,寻病终。后遂无问津者。
|
Server : Apache System : Linux srv.rainic.com 4.18.0-553.47.1.el8_10.x86_64 #1 SMP Wed Apr 2 05:45:37 EDT 2025 x86_64 User : rainic ( 1014) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/akaindir/public_html/crm/modules/WSAPP/Handlers/ |
Upload File : |
<?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.
* *********************************************************************************** */
require_once 'modules/WSAPP/WSAPP.php';
require_once 'include/Webservices/Utils.php';
require_once 'include/database/PearDatabase.php';
require_once 'include/Webservices/GetUpdates.php';
require_once 'include/utils/CommonUtils.php';
require_once 'modules/WSAPP/Utils.php';
require_once 'include/Webservices/Update.php';
require_once 'include/Webservices/Revise.php';
require_once 'modules/WSAPP/Handlers/SyncHandler.php';
class vtigerCRMHandler extends SyncHandler {
private $assignToChangedRecords;
protected $clientSyncType = 'user';
public function __construct($appkey) {
$this->key = $appkey;
$this->assignToChangedRecords = array();
}
public function get($module, $token, $user) {
$syncModule = $module;
$this->user = $user;
$syncModule = $module;
$syncType = 'user';
if (!$this->isClientUserSyncType()) {
if($this->isClientUserAndGroupSyncType()){
$syncType = 'userandgroup';
}else{
$syncType = 'application';
}
}
$result = vtws_sync($token, $syncModule, $syncType, $this->user);
$result['updated'] = $this->translateTheReferenceFieldIdsToName($result['updated'], $syncModule, $user);
return $this->nativeToSyncFormat($result);
}
public function put($recordDetails, $user) {
global $current_user;
$current_user = $user;
$this->user = $user;
$recordDetails = $this->syncToNativeFormat($recordDetails);
$createdRecords = $recordDetails['created'];
$updatedRecords = $recordDetails['updated'];
$deletedRecords = $recordDetails['deleted'];
$updateDuplicateRecords = array();
if (count($createdRecords) > 0) {
$createdRecords = $this->translateReferenceFieldNamesToIds($createdRecords, $user);
$createdRecords = $this->fillNonExistingMandatoryPicklistValues($createdRecords);
$createdRecords = $this->fillMandatoryFields($createdRecords, $user);
}
foreach ($createdRecords as $index => $record) {
try {
$createdRecords[$index] = vtws_create($record['module'], $record, $this->user);
} catch (DuplicateException $e) {
$skipped = true;
$duplicateRecordIds = $e->getDuplicateRecordIds();
$duplicatesResult = $this->triggerSyncActionForDuplicate($record, $duplicateRecordIds);
if ($duplicatesResult) {
$updateDuplicateRecords[$index] = $duplicatesResult;
$skipped = false;
}
if ($skipped) {
$recordDetails['skipped'][] = array('record' => $createdRecords[$index],
'messageidentifier' => '',
'message' => $e->getMessage());
}
unset($createdRecords[$index]);
continue;
} catch (Exception $e) {
$recordDetails['skipped'][] = array('record' => $createdRecords[$index],
'messageidentifier' => '',
'message' => $e->getMessage());
unset($createdRecords[$index]);
continue;
}
}
if (count($updatedRecords) > 0) {
$updatedRecords = $this->translateReferenceFieldNamesToIds($updatedRecords, $user);
}
$crmIds = array();
foreach ($updatedRecords as $index => $record) {
$webserviceRecordId = $record["id"];
$recordIdComp = vtws_getIdComponents($webserviceRecordId);
$crmIds[] = $recordIdComp[1];
}
$assignedRecordIds = array();
if ($this->isClientUserSyncType()|| $this->isClientUserAndGroupSyncType()) {
$assignedRecordIds = wsapp_checkIfRecordsAssignToUser($crmIds, $this->user->id);
// To check if the record assigned to group
if($this->isClientUserAndGroupSyncType()){
$groupIds = $this->getGroupIds($this->user->id);
foreach ($groupIds as $group) {
$groupRecordId = wsapp_checkIfRecordsAssignToUser($crmIds, $group);
$assignedRecordIds = array_merge($assignedRecordIds, $groupRecordId);
}
}
// End
}
foreach ($updatedRecords as $index => $record) {
$webserviceRecordId = $record["id"];
$recordIdComp = vtws_getIdComponents($webserviceRecordId);
try {
if (in_array($recordIdComp[1], $assignedRecordIds)) {
$updatedRecords[$index] = vtws_revise($record, $this->user);
} else if (!$this->isClientUserSyncType()) {
$updatedRecords[$index] = vtws_revise($record, $this->user);
} else {
$this->assignToChangedRecords[$index] = $record;
}
} catch (DuplicateException $e) {
$skipped = true;
$duplicateRecordIds = $e->getDuplicateRecordIds();
$duplicatesResult = $this->triggerSyncActionForDuplicate($record, $duplicateRecordIds);
if ($duplicatesResult) {
$updateDuplicateRecords[$index] = $duplicatesResult;
$skipped = false;
}
if ($skipped) {
$recordDetails['skipped'][] = array('record' => $updatedRecords[$index],
'messageidentifier' => '',
'message' => $e->getMessage());
}
unset($updatedRecords[$index]);
continue;
} catch (Exception $e) {
$recordDetails['skipped'][] = array('record' => $updatedRecords[$index],
'messageidentifier' => '',
'message' => $e->getMessage());
unset($updatedRecords[$index]);
continue;
}
}
foreach ($updateDuplicateRecords as $index => $record) {
$updatedRecords[$index] = $record;
}
$hasDeleteAccess = null;
$deletedCrmIds = array();
foreach ($deletedRecords as $index => $record) {
$webserviceRecordId = $record;
$recordIdComp = vtws_getIdComponents($webserviceRecordId);
$deletedCrmIds[] = $recordIdComp[1];
}
$assignedDeletedRecordIds = wsapp_checkIfRecordsAssignToUser($deletedCrmIds, $this->user->id);
// To get record id's assigned to group of the current user
if($this->isClientUserAndGroupSyncType()){
foreach ($groupIds as $group) {
$groupRecordId = wsapp_checkIfRecordsAssignToUser($deletedCrmIds, $group);
$assignedDeletedRecordIds = array_merge($assignedDeletedRecordIds, $groupRecordId);
}
}
// End
foreach ($deletedRecords as $index => $record) {
$idComp = vtws_getIdComponents($record);
if (empty($hasDeleteAccess)) {
$handler = vtws_getModuleHandlerFromId($idComp[0], $this->user);
$meta = $handler->getMeta();
$hasDeleteAccess = $meta->hasDeleteAccess();
}
if ($hasDeleteAccess) {
if (in_array($idComp[1], $assignedDeletedRecordIds)) {
try {
vtws_delete($record, $this->user);
} catch (Exception $e) {
$recordDetails['skipped'][] = array('record' => $deletedRecords[$index],
'messageidentifier' => '',
'message' => $e->getMessage());
unset($deletedRecords[$index]);
continue;
}
}
}
}
$recordDetails['created'] = $createdRecords;
$recordDetails['updated'] = $updatedRecords;
$recordDetails['deleted'] = $deletedRecords;
return $this->nativeToSyncFormat($recordDetails);
}
public function nativeToSyncFormat($element) {
return $element;
}
public function syncToNativeFormat($element) {
$syncCreatedRecords = $element['created'];
$nativeCreatedRecords = array();
foreach ($syncCreatedRecords as $index => $createRecord) {
if (empty($createRecord['assigned_user_id'])) {
$createRecord['assigned_user_id'] = vtws_getWebserviceEntityId("Users", $this->user->id);
}
$nativeCreatedRecords[$index] = $createRecord;
}
$element['created'] = $nativeCreatedRecords;
return $element;
}
public function map($element, $user) {
return $element;
}
public function translateReferenceFieldNamesToIds($entityRecords, $user) {
$entityRecordList = array();
foreach ($entityRecords as $index => $record) {
$entityRecordList[$record['module']][$index] = $record;
}
foreach ($entityRecordList as $module => $records) {
$handler = vtws_getModuleHandlerFromName($module, $user);
$meta = $handler->getMeta();
$referenceFieldDetails = $meta->getReferenceFieldDetails();
foreach ($referenceFieldDetails as $referenceFieldName => $referenceModuleDetails) {
$recordReferenceFieldNames = array();
foreach ($records as $index => $recordDetails) {
if (!empty($recordDetails[$referenceFieldName])) {
$recordReferenceFieldNames[] = $recordDetails[$referenceFieldName];
}
}
$entityNameIds = wsapp_getRecordEntityNameIds(array_values($recordReferenceFieldNames), $referenceModuleDetails, $user);
foreach ($records as $index => $recordInfo) {
if(array_key_exists($referenceFieldName, $recordInfo)){
$array = explode('x',$record[$referenceFieldName]);
if(is_numeric($array[0]) && is_numeric($array[1])){
$recordInfo[$referenceFieldName] = $recordInfo[$referenceFieldName];
}elseif (!empty($entityNameIds[strtolower($recordInfo[$referenceFieldName])])) {
$recordInfo[$referenceFieldName] = $entityNameIds[strtolower($recordInfo[$referenceFieldName])];
} else {
$recordInfo[$referenceFieldName] = "";
}
}
$records[$index] = $recordInfo;
}
}
$entityRecordList[$module] = $records;
}
$crmRecords = array();
foreach ($entityRecordList as $module => $entityRecords) {
foreach ($entityRecords as $index => $record) {
$crmRecords[$index] = $record;
}
}
return $crmRecords;
}
public function translateTheReferenceFieldIdsToName($records, $module, $user) {
$db = PearDatabase::getInstance();
global $current_user;
$current_user = $user;
$handler = vtws_getModuleHandlerFromName($module, $user);
$meta = $handler->getMeta();
$referenceFieldDetails = $meta->getReferenceFieldDetails();
foreach ($referenceFieldDetails as $referenceFieldName => $referenceModuleDetails) {
$referenceFieldIds = array();
$referenceModuleIds = array();
$referenceIdsName = array();
foreach ($records as $recordDetails) {
$referenceWsId = $recordDetails[$referenceFieldName];
if (!empty($referenceWsId)) {
$referenceIdComp = vtws_getIdComponents($referenceWsId);
$webserviceObject = VtigerWebserviceObject::fromId($db, $referenceIdComp[0]);
if ($webserviceObject->getEntityName() == 'Currency') {
continue;
}
$referenceModuleIds[$webserviceObject->getEntityName()][] = $referenceIdComp[1];
$referenceFieldIds[] = $referenceIdComp[1];
}
}
foreach ($referenceModuleIds as $referenceModule => $idLists) {
$nameList = getEntityName($referenceModule, $idLists);
foreach ($nameList as $key => $value)
$referenceIdsName[$key] = $value;
}
$recordCount = count($records);
for ($i = 0; $i < $recordCount; $i++) {
$record = $records[$i];
if (!empty($record[$referenceFieldName])) {
$wsId = vtws_getIdComponents($record[$referenceFieldName]);
$record[$referenceFieldName] = decode_html($referenceIdsName[$wsId[1]]);
}
$records[$i] = $record;
}
}
return $records;
}
public function getAssignToChangedRecords() {
return $this->assignToChangedRecords;
}
public function fillNonExistingMandatoryPicklistValues($recordList) {
//Meta is cached to eliminate overhead of doing the query every time to get the meta details(retrieveMeta)
$modulesMetaCache = array();
foreach ($recordList as $index => $recordDetails) {
if (!array_key_exists($recordDetails['module'], $modulesMetaCache)) {
$handler = vtws_getModuleHandlerFromName($recordDetails['module'], $this->user);
$meta = $handler->getMeta();
$modulesMetaCache[$recordDetails['module']] = $meta;
}
$moduleMeta = $modulesMetaCache[$recordDetails['module']];
$mandatoryFieldsList = $meta->getMandatoryFields();
$moduleFields = $meta->getModuleFields();
foreach ($mandatoryFieldsList as $fieldName) {
$fieldInstance = $moduleFields[$fieldName];
if (empty($recordDetails[$fieldName]) &&
($fieldInstance->getFieldDataType() == "multipicklist" || $fieldInstance->getFieldDataType() == "picklist")) {
if($fieldInstance->hasDefault() && trim($fieldInstance->getDefault())) {
$defaultValue = decode_html($fieldInstance->getDefault());
} else {
$pickListDetails = $fieldInstance->getPicklistDetails($webserviceField);
$defaultValue = $pickListDetails[0]['value'];
}
$recordDetails[$fieldName] = $defaultValue;
}
}
$recordList[$index] = $recordDetails;
}
return $recordList;
}
/**
* Function to fillMandatory fields in vtiger with given values
* @param type $recordLists
* @param type $user
* @return type
*/
public function fillMandatoryFields($recordLists, $user) {
$transformedRecords = array();
foreach ($recordLists as $index => $record) {
$handler = vtws_getModuleHandlerFromName($record['module'], $user);
$meta = $handler->getMeta();
$fields = $meta->getModuleFields();
$mandatoryFields = $meta->getMandatoryFields();
$ownerFields = $meta->getOwnerFields();
foreach ($mandatoryFields as $fieldName) {
// ignore owner fields
if (in_array($fieldName, $ownerFields)) {
continue;
}
$fieldInstance = $fields[$fieldName];
$currentFieldValue = $record[$fieldName];
if (!empty($currentFieldValue)) {
continue;
}
$fieldDataType = $fieldInstance->getFieldDataType();
$defaultValue = $fieldInstance->getDefault();
$value = '';
switch ($fieldDataType) {
case 'date':
$value = $defaultValue;
if (empty($defaultValue)) {
$dateObject = new DateTime();
$value = $dateObject->format('Y-m-d');
}
break;
case 'time' :
$value = '00:00:00';
if(!empty($defaultValue)) {
$value = $defaultValue;
}
break;
case 'text':
$value = '?????';
if (!empty($defaultValue)) {
$value = $defaultValue;
}
break;
case 'phone':
$value = '?????';
if (!empty($defaultValue)) {
$value = $defaultValue;
}
break;
case 'boolean':
$value = false;
if (!empty($defaultValue)) {
$value = $defaultValue;
}
break;
case 'email':
$value = '?????';
if (!empty($defaultValue)) {
$value = $defaultValue;
}
break;
case 'string':
$value = '?????';
if (!empty($defaultValue)) {
$value = $defaultValue;
}
break;
case 'url':
$value = '?????';
if (!empty($defaultValue)) {
$value = $defaultValue;
}
break;
case 'integer':
$value = 0;
if (!empty($defaultValue)) {
$value = $defaultValue;
}
break;
case 'double':
$value = 00.00;
if (!empty($defaultValue)) {
$value = $defaultValue;
}
break;
case 'currency':
$value = 0.00;
if (!empty($defaultValue)) {
$value = $defaultValue;
}
break;
case 'skype':
$value = '?????';
if (!empty($defaultValue)) {
$value = $defaultValue;
}
break;
}
$record[$fieldName] = $value;
}
// New field added to show Record Source
if(!isset($record['source'])){
$record['source'] = Vtiger_Cache::get('WSAPP', 'appName');
}
$transformedRecords[$index] = $record;
}
return $transformedRecords;
}
public function setClientSyncType($syncType = 'user') {
$this->clientSyncType = $syncType;
return $this;
}
public function isClientUserSyncType() {
return ($this->clientSyncType == 'user') ? true : false;
}
public function isClientUserAndGroupSyncType() {
return ($this->clientSyncType == 'userandgroup') ? true : false;
}
public function triggerSyncActionForDuplicate($recordData, $duplicateRecordIds) {
$db = PearDatabase::getInstance();
$result = array();
$user = $this->user;
$moduleName = $recordData['module'];
$moduleModel = Vtiger_Module_Model::getInstance($moduleName);
if ($moduleModel && $moduleModel->isSyncable) {
$webSeviceModuleModel = VtigerWebserviceObject::fromName($db, $moduleName);
$moduleId = $webSeviceModuleModel->getEntityId();
$recordId = $recordData['id'];
$recordIdComponents = vtws_getIdComponents($recordId);
if (count($recordIdComponents) == 2 && in_array($moduleId, $recordIdComponents)) {
return array();
}
$elemId = reset($duplicateRecordIds);
$recordId = vtws_getId($moduleId, $elemId);
try {
$vtigerRecordData = vtws_retrieve($recordId, $user);
} catch (Exception $e) {
return $result;
}
global $skipDuplicateCheck;
$skipDuplicateCheck = true;
switch ($moduleModel->syncActionForDuplicate) {
case 1 : //Prefer latest record
$finalRecordData = $vtigerRecordData;
if ($recordData['modifiedtime'] > $vtigerRecordData['modifiedtime']) {
$finalRecordData = $recordData;
$finalRecordData['id'] = $recordId;
$finalRecordData = vtws_revise($finalRecordData, $user);
}
$result = $finalRecordData;
break;
// case 3 : //Prefer Vtiger Record
// $result = $vtigerRecordData;
// break;
case 4 : //Prefer external record
$recordData['id'] = $recordId;
foreach ($recordData as $fieldName => $fieldValue) {
if (!$fieldValue) {
unset($recordData[$fieldName]);
}
}
$result = vtws_revise($recordData, $user);
break;
case 2 : //Prefer internal record
default : $result = array();
break;
}
$skipDuplicateCheck = false;
}
return $result;
}
}
?>