晋太元中,武陵人捕鱼为业。缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷。渔人甚异之,复前行,欲穷其林。 林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田、美池、桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。 见渔人,乃大惊,问所从来。具答之。便要还家,设酒杀鸡作食。村中闻有此人,咸来问讯。自云先世避秦时乱,率妻子邑人来此绝境,不复出焉,遂与外人间隔。问今是何世,乃不知有汉,无论魏晋。此人一一为具言所闻,皆叹惋。余人各复延至其家,皆出酒食。停数日,辞去。此中人语云:“不足为外人道也。”(间隔 一作:隔绝) 既出,得其船,便扶向路,处处志之。及郡下,诣太守,说如此。太守即遣人随其往,寻向所志,遂迷,不复得路。 南阳刘子骥,高尚士也,闻之,欣然规往。未果,寻病终。后遂无问津者。
|
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 : /proc/thread-self/root/home/akaindir/public_html/crm/modules/Google/connectors/ |
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.
* *********************************************************************************** */
vimport('~~/modules/WSAPP/synclib/connectors/TargetConnector.php');
vimport('~~/libraries/google-api-php-client/src/Google/Client.php');
vimport('~~/libraries/google-api-php-client/src/Google/Service/Calendar.php');
Class Google_Calendar_Connector extends WSAPP_TargetConnector {
const maxBatchRequestCount = 50;
protected $apiConnection;
protected $totalRecords;
protected $maxResults = 100;
protected $createdRecords;
protected $client;
protected $service;
protected $eventCalendarFieldMappingTableName = 'vtiger_google_event_calendar_mapping';
protected $calendars;
public function __construct($oauth2Connection) {
$this->apiConnection = $oauth2Connection;
$this->client = new Google_Client();
$this->client->setClientId($oauth2Connection->getClientId());
$this->client->setClientSecret($oauth2Connection->getClientSecret());
$this->client->setRedirectUri($oauth2Connection->getRedirectUri());
$this->client->setScopes($oauth2Connection->getScope());
$this->client->setAccessType($oauth2Connection->getAccessType());
$this->client->setApprovalPrompt($oauth2Connection->getApprovalPrompt());
try {
$this->client->setAccesstoken($oauth2Connection->getAccessToken());
} catch(Exception $e) {} //suppressing invalid access-token exception
$this->service = new Google_Service_Calendar($this->client);
}
public function getName() {
return 'GoogleCalendar';
}
public function emailLookUp($emailIds) {
$db = PearDatabase::getInstance();
$sql = 'SELECT crmid FROM vtiger_emailslookup WHERE setype = "Contacts" AND value IN (' . generateQuestionMarks($emailIds) . ')';
$result = $db->pquery($sql,$emailIds);
$crmIds = array();
for($i=0;$i<$db->num_rows($result);$i++) {
$crmIds[] = $db->query_result($result,$i,'crmid');
}
return $crmIds;
}
/**
* Tarsform Google Records to Vtiger Records
* @param <array> $targetRecords
* @return <array> tranformed Google Records
*/
public function transformToSourceRecord($targetRecords, $user = false) {
$entity = array();
$calendarArray = array();
foreach ($targetRecords as $googleRecord) {
if ($googleRecord->getMode() != WSAPP_SyncRecordModel::WSAPP_DELETE_MODE) {
if(!$user)
$user = Users_Record_Model::getCurrentUserModel();
$entity = Vtiger_Functions::getMandatoryReferenceFields('Events');
$entity['assigned_user_id'] = vtws_getWebserviceEntityId('Users', $user->id);
$entity['subject'] = $googleRecord->getSubject();
$entity['date_start'] = $googleRecord->getStartDate($user);
$entity['location'] = $googleRecord->getWhere();
$entity['time_start'] = $googleRecord->getStartTimeUTC($user);
$entity['due_date'] = $googleRecord->getEndDate($user);
$entity['time_end'] = $googleRecord->getEndTimeUTC($user);
$entity['eventstatus'] = "Planned";
$entity['activitytype'] = "Meeting";
$entity['description'] = $googleRecord->getDescription();
$entity['duration_hours'] = '00:00';
$entity['visibility'] = $googleRecord->getVisibility($user);
if (empty($entity['subject'])) {
$entity['subject'] = 'Google Event';
}
$attendees = $googleRecord->getAttendees();
$entity['contactidlist'] = '';
if(count($attendees)) {
$contactIds = $this->emailLookUp($attendees);
if(count($contactIds)) {
$entity['contactidlist'] = implode(';', $contactIds);
}
}
}
$calendar = $this->getSynchronizeController()->getSourceRecordModel($entity);
$calendar = $this->performBasicTransformations($googleRecord, $calendar);
$calendar = $this->performBasicTransformationsToSourceRecords($calendar, $googleRecord);
$calendarArray[] = $calendar;
}
return $calendarArray;
}
/**
* Pull the events from google
* @param <object> $SyncState
* @return <array> google Records
*/
public function pull($SyncState, $user = false) {
try {
return $this->getCalendar($SyncState, $user);
} catch (Exception $e) {
return array();
}
}
/**
* Function to convert datetime to RFC 3339 timestamp
* @param <String> $date
* @return <DateTime>
*/
function googleFormat($date) {
$datTime = new DateTime($date);
$timeZone = new DateTimeZone('UTC');
$datTime->setTimezone($timeZone);
$googleFormat = $datTime->format('Y-m-d\TH:i:s\Z');
return $googleFormat;
}
/**
* Pull the events from google
* @param <object> $SyncState
* @return <array> google Records
*/
public function getCalendar($SyncState, $user = false) {
if($this->apiConnection->isTokenExpired()) {
$this->apiConnection->refreshToken();
$this->client->setAccessToken($this->apiConnection->getAccessToken());
$this->service = new Google_Service_Calendar($this->client);
}
$query = array(
'maxResults' => $this->maxResults,
'orderBy' => 'updated',
'singleEvents' => true,
);
if (Google_Utils_Helper::getSyncTime('Calendar', $user)) {
$query['updatedMin'] = $this->googleFormat(Google_Utils_Helper::getSyncTime('Calendar', $user));
//shows deleted by default
}
$calendarId = Google_Utils_Helper::getSelectedCalendarForUser($user);
if(!isset($this->calendars)) {
$this->calendars = $this->pullCalendars(true);
}
if(!in_array($calendarId, $this->calendars)) {
$calendarId = 'primary';
}
try {
$feed = $this->service->events->listEvents($calendarId,$query);
} catch (Exception $e) {
if($e->getCode() == 410) {
$query['showDeleted'] = false;
$feed = $this->service->events->listEvents($calendarId,$query);
}
}
$calendarRecords = array();
if($feed) {
$calendarRecords = $feed->getItems();
if($feed->getNextPageToken()) $this->totalRecords = $this->maxResults + 1;
}
if (count($calendarRecords) > 0) {
$maxModifiedTime = date('Y-m-d H:i:s', strtotime(Google_Contacts_Model::vtigerFormat(end($calendarRecords)->getUpdated())) + 1);
}
$googleRecords = array();
$googleEventIds = array();
foreach ($calendarRecords as $i => $calendar) {
$recordModel = Google_Calendar_Model::getInstanceFromValues(array('entity' => $calendar));
$deleted = false;
if ($calendar->getStatus() == 'cancelled') {
$deleted = true;
}
if (!$deleted) {
$recordModel->setType($this->getSynchronizeController()->getSourceType())->setMode(WSAPP_SyncRecordModel::WSAPP_UPDATE_MODE);
} else {
$recordModel->setType($this->getSynchronizeController()->getSourceType())->setMode(WSAPP_SyncRecordModel::WSAPP_DELETE_MODE);
}
$googleRecords[$calendar->getId()] = $recordModel;
$googleEventIds[] = $calendar->getId();
}
$this->createdRecords = count($googleRecords);
if (isset($maxModifiedTime)) {
Google_Utils_Helper::updateSyncTime('Calendar', $maxModifiedTime, $user);
} else {
Google_Utils_Helper::updateSyncTime('Calendar', false, $user);
}
if(count($googleEventIds)) {
$this->putGoogleEventCalendarMap($googleEventIds, $calendarId, $user);
}
return $googleRecords;
}
protected function putGoogleEventCalendarMap($event_ids, $calendar_id, $user) {
if(is_array($event_ids) && count($event_ids)) {
$db = PearDatabase::getInstance();
$user_id = $user->getId();
$sql = 'INSERT INTO vtiger_google_event_calendar_mapping (event_id, calendar_id, user_id) VALUES ';
$sqlParams = array();
foreach($event_ids as $event_id) {
$sql .= '(?, ?, ?),';
$sqlParams[] = $event_id;
$sqlParams[] = $calendar_id;
$sqlParams[] = $user_id;
}
$sql = substr_replace($sql, "", -1);
$db->pquery('DELETE FROM vtiger_google_event_calendar_mapping WHERE event_id IN ('.generateQuestionMarks($event_ids).')',$event_ids);
$db->pquery($sql,$sqlParams);
}
}
protected function getGoogleEventCalendarMap($user) {
$db = PearDatabase::getInstance();
$map = array();
$sql = 'SELECT event_id, calendar_id FROM vtiger_google_event_calendar_mapping WHERE user_id = ?';
$res = $db->pquery($sql, array($user->getId()));
$num_of_rows = $db->num_rows($res);
for($i=0;$i<$num_of_rows;$i++) {
$event_id = $db->query_result($res, $i, 'event_id');
$calendar_id = $db->query_result($res, $i, 'calendar_id');
$map[$event_id] = $calendar_id;
}
return $map;
}
/**
* Push the vtiger records to google
* @param <array> $records vtiger records to be pushed to google
* @return <array> pushed records
*/
public function push($records,$user) {
//TODO : use batch requests
$calendarId = Google_Utils_Helper::getSelectedCalendarForUser($user);
if(!isset($this->calendars)) {
try {
$this->calendars = $this->pullCalendars(true);
} catch (Exception $e) {
return $records;
}
}
if(!in_array($calendarId, $this->calendars)) {
$calendarId = 'primary';
}
$eventCalendarMap = $this->getGoogleEventCalendarMap($user);
$newEventIds = array();
foreach ($records as $record) {
$entity = $record->get('entity');
$eventCalendarId = 'primary';
if($this->apiConnection->isTokenExpired()) {
$this->apiConnection->refreshToken();
$this->client->setAccessToken($this->apiConnection->getAccessToken());
$this->service = new Google_Service_Calendar($this->client);
}
try {
if ($record->getMode() == WSAPP_SyncRecordModel::WSAPP_UPDATE_MODE) {
if(array_key_exists($entity->getId(), $eventCalendarMap)) {
$eventCalendarId = $eventCalendarMap[$entity->getId()];
}
$newEntity = $this->service->events->update($eventCalendarId,$entity->getId(),$entity);
$record->set('entity', $newEntity);
} else if ($record->getMode() == WSAPP_SyncRecordModel::WSAPP_DELETE_MODE) {
$record->set('entity', $entity);
if(array_key_exists($entity->getId(), $eventCalendarMap)) {
$eventCalendarId = $eventCalendarMap[$entity->getId()];
}
$newEntity = $this->service->events->delete($eventCalendarId,$entity->getId());
} else {
$newEntity = $this->service->events->insert($calendarId,$entity);
$newEventIds[] = $newEntity->getId();
$record->set('entity', $newEntity);
}
} catch (Exception $e) {
continue;
}
}
if(count($newEventIds)) {
$this->putGoogleEventCalendarMap($newEventIds, $calendarId, $user);
}
return $records;
}
/**
* Tarsform Vtiger Records to Google Records
* @param <array> $vtEvents
* @return <array> tranformed vtiger Records
*/
public function transformToTargetRecord($vtEvents, $user) {
$records = array();
foreach ($vtEvents as $vtEvent) {
$newEvent = new Google_Service_Calendar_Event();
if ($vtEvent->getMode() == WSAPP_SyncRecordModel::WSAPP_DELETE_MODE) {
$newEvent->setId($vtEvent->get('_id'));
} elseif($vtEvent->getMode() == WSAPP_SyncRecordModel::WSAPP_UPDATE_MODE && $vtEvent->get('_id')) {
if($this->apiConnection->isTokenExpired()) {
$this->apiConnection->refreshToken();
try {
$this->client->setAccessToken($this->apiConnection->getAccessToken());
} catch(Exception $e) {}//suppressing invalid access-token exception if access revoked
$this->service = new Google_Service_Calendar($this->client);
}
try {
$calendarId = 'primary';
$eventCalendarMap = $this->getGoogleEventCalendarMap($user);
if(array_key_exists($vtEvent->get('_id'), $eventCalendarMap)) {
$calendarId = $eventCalendarMap[$vtEvent->get('_id')];
}
$newEvent = $this->service->events->get($calendarId, $vtEvent->get('_id'));
} catch (Exception $e) {
continue;
}
}
$newEvent->setSummary($vtEvent->get('subject'));
$newEvent->setLocation($vtEvent->get('location'));
$newEvent->setDescription($vtEvent->get('description'));
$newEvent->setVisibility(strtolower($vtEvent->get('visibility')));
$startDate = $vtEvent->get('date_start');
$startTime = $vtEvent->get('time_start');
$endDate = $vtEvent->get('due_date');
$endTime = $vtEvent->get('time_end');
if (empty($endTime)) {
$endTime = "00:00";
}
$start = new Google_Service_Calendar_EventDateTime();
$start->setDateTime($this->googleFormat($startDate . ' ' . $startTime));
$newEvent->setStart($start);
$end = new Google_Service_Calendar_EventDateTime();
$end->setDateTime($this->googleFormat($endDate. ' ' .$endTime));
$newEvent->setEnd($end);
/**
* Commenting out adding attendees in google
//attendees
$googleAttendees = array();
$newEvent->setAttendees($googleAttendees);
$attendees = $vtEvent->get('attendees');
if(isset($attendees)) {
foreach($attendees as $attendee) {
if(!empty($attendee['email'])) {
$eventAttendee = new Google_Service_Calendar_EventAttendee();
$eventAttendee->setEmail($attendee['email']);
$googleAttendees[] = $eventAttendee;
}
}
if(count($googleAttendees)) $newEvent->setAttendees($googleAttendees);
}
*/
$recordModel = Google_Calendar_Model::getInstanceFromValues(array('entity' => $newEvent));
$recordModel->setType($this->getSynchronizeController()->getSourceType())->setMode($vtEvent->getMode())->setSyncIdentificationKey($vtEvent->get('_syncidentificationkey'));
$recordModel = $this->performBasicTransformations($vtEvent, $recordModel);
$recordModel = $this->performBasicTransformationsToTargetRecords($recordModel, $vtEvent);
$records[] = $recordModel;
}
return $records;
}
/**
* returns if more records exits or not
* @return <boolean> true or false
*/
public function moreRecordsExits() {
return ($this->totalRecords - $this->createdRecords > 0) ? true : false;
}
public function pullCalendars($list=false) {
$calendarList = $this->service->calendarList->listCalendarList();
$allCalendarsItems = array();
while(true) {
$calendarItems = $calendarList->getItems();
if(is_array($calendarItems))
$allCalendarsItems = array_merge($allCalendarsItems, $calendarItems);
$pageToken = $calendarList->getNextPageToken();
if ($pageToken) {
$optParams = array('pageToken' => $pageToken);
$calendarList = $this->service->calendarList->listCalendarList($optParams);
} else {
break;
}
}
$calendars = array();
if($list) {
foreach($allCalendarsItems as $calendarItem) {
if(!$calendarItem->getPrimary())
$calendars[] = $calendarItem->getId();
else
$calendars[] = 'primary';
}
return $calendars;
}
foreach($allCalendarsItems as $calendarItem) {
$calendars[] = array(
'id' => $calendarItem->getId(),
'summary' => $calendarItem->getSummary(),
'primary' => $calendarItem->getPrimary()
);
}
return $calendars;
}
}
?>