This commit is contained in:
Patrick Zeitz 2024-08-23 13:56:21 +02:00
parent 1dc57a582e
commit a895343e0a

View file

@ -1,155 +1,139 @@
<?php defined('BASEPATH') or exit('No direct script access allowed'); <?php defined('BASEPATH') or exit('No direct script access allowed');
/* ----------------------------------------------------------------------------
* Easy!Appointments - Online Appointment Scheduler
*
* @package EasyAppointments
* @author A.Tselegidis <alextselegidis@gmail.com>
* @copyright Copyright (c) Alex Tselegidis
* @license https://opensource.org/licenses/GPL-3.0 - GPLv3
* @link https://easyappointments.org
* @since v1.0.0
* ---------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------- use Google\Service\Calendar\Event;
* Easy!Appointments - Online Appointment Scheduler
*
* @package EasyAppointments
* @author A.Tselegidis <alextselegidis@gmail.com>
* @copyright Copyright (c) Alex Tselegidis
* @license https://opensource.org/licenses/GPL-3.0 - GPLv3
* @link https://easyappointments.org
* @since v1.0.0
* ---------------------------------------------------------------------------- */
use Google\Service\Calendar\Event;
use Google\Service\Calendar\Events; use Google\Service\Calendar\Events;
/** /**
* Google sync library. * Google sync library.
* *
* Handles Google Calendar API related functionality. * Handles Google Calendar API related functionality.
* *
* @package Libraries * @package Libraries
*/ */
class Google_sync class Google_sync
{ {
/** /**
* @var EA_Controller|CI_Controller * @var EA_Controller|CI_Controller
*/ */
protected EA_Controller|CI_Controller $CI; protected EA_Controller|CI_Controller $CI;
/**
/** * @var Google_Client
* @var Google_Client */
*/
protected Google_Client $client; protected Google_Client $client;
/**
/** * @var Google_Service_Calendar
* @var Google_Service_Calendar */
*/
protected Google_Service_Calendar $service; protected Google_Service_Calendar $service;
/**
/** * Google_sync constructor.
* Google_sync constructor. *
* * This method initializes the Google client class and the Calendar service class so that they can be used by the
* This method initializes the Google client class and the Calendar service class so that they can be used by the * other methods.
* other methods. */
*/ public function __construct()
public function __construct() {
{
$this->CI = &get_instance(); $this->CI = &get_instance();
$this->CI->load->model('appointments_model');
$this->CI->load->model('appointments_model'); $this->CI->load->model('customers_model');
$this->CI->load->model('customers_model'); $this->CI->load->model('providers_model');
$this->CI->load->model('providers_model');
$this->CI->load->model('services_model'); $this->CI->load->model('services_model');
$this->initialize_clients();
}
/**
* Initialize the client, so that existing execution errors are not passed from one provider to another.
*/
public function initialize_clients(): void
{
$http = new GuzzleHttp\Client([
'verify' => false,
]);
$this->client = new Google_Client();
$this->client->setHttpClient($http);
$this->client->setApplicationName('Easy!Appointments');
$this->client->setClientId(config('google_client_id'));
$this->client->setClientSecret(config('google_client_secret'));
$this->client->setRedirectUri(site_url('google/oauth_callback'));
$this->client->setPrompt('consent');
$this->client->setAccessType('offline');
$this->client->addScope([Google_Service_Calendar::CALENDAR]);
$this->service = new Google_Service_Calendar($this->client);
}
/**
* Get Google OAuth authorization url.
*
* This url must be used to redirect the user to the Google user consent page,
* where the user grants access to his data for the Easy!Appointments app.
*/
public function get_auth_url(): string
{
// The "max_auth_age" is needed because the user needs to always log in and not use an existing session.
return $this->client->createAuthUrl() . '&max_auth_age=0';
}
/**
* Authenticate the Google API usage.
*
* When the user grants consent for his data usage, Google is going to redirect the browser back to the given
* redirect URL. There an authentication code is provided. Using this code, we can authenticate the API usage and
* store the token information to the database.
*
* @param string $code
*
* @return array
*
* @throws Exception
*/
public function authenticate(string $code): array
{
$response = $this->client->fetchAccessTokenWithAuthCode($code);
if (isset($response['error'])) {
throw new RuntimeException(
'Google Authentication Error (' . $response['error'] . '): ' . $response['error_description'],
);
}
return $response;
}
/**
* Refresh the Google Client access token.
*
* This method must be executed every time we need to make actions on a provider's Google Calendar account. A new
* token is necessary and the only way to get it is to use the stored refresh token that was provided when the
* provider granted consent to Easy!Appointments for use his Google Calendar account.
*
* @param string $refresh_token The provider's refresh token. This value is stored in the database and used every
* time we need to make actions to his Google Calendar account.
*/
public function refresh_token(string $refresh_token): void
{
$this->initialize_clients(); $this->initialize_clients();
$this->client->refreshToken($refresh_token);
} }
/**
/** * Initialize the client, so that existing execution errors are not passed from one provider to another.
* Add an appointment record to its providers Google Calendar account. */
* public function initialize_clients(): void
* This method checks whether the appointment's provider has enabled the Google Sync utility of Easy!Appointments {
* and the stored access token is still valid. If yes, the selected appointment record is going to be added to the $http = new GuzzleHttp\Client([
* Google Calendar account. 'verify' => false,
* ]);
* @param array $appointment Appointment data. $this->client = new Google_Client();
* @param array $provider Provider data. $this->client->setHttpClient($http);
* @param array $service Service data. $this->client->setApplicationName('Easy!Appointments');
* @param array $customer Customer data. $this->client->setClientId(config('google_client_id'));
* @param array $settings Required settings. $this->client->setClientSecret(config('google_client_secret'));
* $this->client->setRedirectUri(site_url('google/oauth_callback'));
* @return Event Returns the Google_Event class object. $this->client->setPrompt('consent');
* $this->client->setAccessType('offline');
* @throws Exception $this->client->addScope([Google_Service_Calendar::CALENDAR]);
*/ $this->service = new Google_Service_Calendar($this->client);
}
/**
* Get Google OAuth authorization url.
*
* This url must be used to redirect the user to the Google user consent page,
* where the user grants access to his data for the Easy!Appointments app.
*/
public function get_auth_url(): string
{
// The "max_auth_age" is needed because the user needs to always log in and not use an existing session.
return $this->client->createAuthUrl() . '&max_auth_age=0';
}
/**
* Authenticate the Google API usage.
*
* When the user grants consent for his data usage, Google is going to redirect the browser back to the given
* redirect URL. There an authentication code is provided. Using this code, we can authenticate the API usage and
* store the token information to the database.
*
* @param string $code
*
* @return array
*
* @throws Exception
*/
public function authenticate(string $code): array
{
$response = $this->client->fetchAccessTokenWithAuthCode($code);
if (isset($response['error'])) {
throw new RuntimeException(
'Google Authentication Error (' . $response['error'] . '): ' . $response['error_description'],
);
}
return $response;
}
/**
* Refresh the Google Client access token.
*
* This method must be executed every time we need to make actions on a provider's Google Calendar account. A new
* token is necessary and the only way to get it is to use the stored refresh token that was provided when the
* provider granted consent to Easy!Appointments for use his Google Calendar account.
*
* @param string $refresh_token The provider's refresh token. This value is stored in the database and used every
* time we need to make actions to his Google Calendar account.
*/
public function refresh_token(string $refresh_token): void
{
$this->initialize_clients();
$this->client->refreshToken($refresh_token);
}
/**
* Add an appointment record to its providers Google Calendar account.
*
* This method checks whether the appointment's provider has enabled the Google Sync utility of Easy!Appointments
* and the stored access token is still valid. If yes, the selected appointment record is going to be added to the
* Google Calendar account.
*
* @param array $appointment Appointment data.
* @param array $provider Provider data.
* @param array $service Service data.
* @param array $customer Customer data.
* @param array $settings Required settings.
*
* @return Event Returns the Google_Event class object.
*
* @throws Exception
*/
public function add_appointment( public function add_appointment(
array $appointment, array $appointment,
array $provider, array $provider,
@ -161,33 +145,26 @@ class Google_sync
$event->setSummary(!empty($service) ? $service['name'] : 'Unavailable'); $event->setSummary(!empty($service) ? $service['name'] : 'Unavailable');
$event->setDescription($appointment['notes']); $event->setDescription($appointment['notes']);
$event->setLocation($appointment['location'] ?? $settings['company_name']); $event->setLocation($appointment['location'] ?? $settings['company_name']);
$timezone = new DateTimeZone($provider['timezone']); $timezone = new DateTimeZone($provider['timezone']);
$start = new Google_Service_Calendar_EventDateTime(); $start = new Google_Service_Calendar_EventDateTime();
$start->setDateTime( $start->setDateTime(
(new DateTime($appointment['start_datetime'], $timezone))->format(DateTimeInterface::RFC3339), (new DateTime($appointment['start_datetime'], $timezone))->format(DateTimeInterface::RFC3339),
); );
$event->setStart($start); $event->setStart($start);
$end = new Google_Service_Calendar_EventDateTime(); $end = new Google_Service_Calendar_EventDateTime();
$end->setDateTime((new DateTime($appointment['end_datetime'], $timezone))->format(DateTimeInterface::RFC3339)); $end->setDateTime((new DateTime($appointment['end_datetime'], $timezone))->format(DateTimeInterface::RFC3339));
$event->setEnd($end); $event->setEnd($end);
$event->attendees = []; $event->attendees = [];
$event_provider = new Google_Service_Calendar_EventAttendee(); $event_provider = new Google_Service_Calendar_EventAttendee();
$event_provider->setDisplayName($provider['first_name'] . ' ' . $provider['last_name']); $event_provider->setDisplayName($provider['first_name'] . ' ' . $provider['last_name']);
$event_provider->setEmail($provider['email']); $event_provider->setEmail($provider['email']);
$event->attendees[] = $event_provider; $event->attendees[] = $event_provider;
if (!empty($customer['first_name']) && !empty($customer['last_name']) && !empty($customer['email'])) { if (!empty($customer['first_name']) && !empty($customer['last_name']) && !empty($customer['email'])) {
$event_customer = new Google_Service_Calendar_EventAttendee(); $event_customer = new Google_Service_Calendar_EventAttendee();
$event_customer->setDisplayName($customer['first_name'] . ' ' . $customer['last_name']); $event_customer->setDisplayName($customer['first_name'] . ' ' . $customer['last_name']);
$event_customer->setEmail($customer['email']); $event_customer->setEmail($customer['email']);
$event->attendees[] = $event_customer; $event->attendees[] = $event_customer;
} }
// Add Google Meet link // Add Google Meet link
$conferenceData = new Google_Service_Calendar_ConferenceData(); $conferenceData = new Google_Service_Calendar_ConferenceData();
$createRequest = new Google_Service_Calendar_CreateConferenceRequest(); $createRequest = new Google_Service_Calendar_CreateConferenceRequest();
@ -197,7 +174,6 @@ class Google_sync
$createRequest->setConferenceSolutionKey($solutionKey); $createRequest->setConferenceSolutionKey($solutionKey);
$conferenceData->setCreateRequest($createRequest); $conferenceData->setCreateRequest($createRequest);
$event->setConferenceData($conferenceData); $event->setConferenceData($conferenceData);
// Add the new event to the Google Calendar. // Add the new event to the Google Calendar.
return $this->service->events->insert( return $this->service->events->insert(
$provider['settings']['google_calendar'], $provider['settings']['google_calendar'],
@ -205,24 +181,22 @@ class Google_sync
['conferenceDataVersion' => 1] ['conferenceDataVersion' => 1]
); );
} }
/**
* Update an existing appointment that is already synced with Google Calendar.
/** *
* Update an existing appointment that is already synced with Google Calendar. * This method updates the Google Calendar event item that is connected with the provided appointment record of
* * Easy!Appointments.
* This method updates the Google Calendar event item that is connected with the provided appointment record of *
* Easy!Appointments. * @param array $appointment Appointment data.
* * @param array $provider Provider data.
* @param array $appointment Appointment data. * @param array $service Service data.
* @param array $provider Provider data. * @param array $customer Customer data.
* @param array $service Service data. * @parma array $settings Required settings.
* @param array $customer Customer data. *
* @parma array $settings Required settings. * @return Event Returns the Google_Service_Calendar_Event class object.
* *
* @return Event Returns the Google_Service_Calendar_Event class object. * @throws Exception
* */
* @throws Exception
*/
public function update_appointment( public function update_appointment(
array $appointment, array $appointment,
array $provider, array $provider,
@ -234,37 +208,29 @@ class Google_sync
$provider['settings']['google_calendar'], $provider['settings']['google_calendar'],
$appointment['id_google_calendar'], $appointment['id_google_calendar'],
); );
$event->setSummary($service['name']); $event->setSummary($service['name']);
$event->setDescription($appointment['notes']); $event->setDescription($appointment['notes']);
$event->setLocation($appointment['location'] ?? $settings['company_name']); $event->setLocation($appointment['location'] ?? $settings['company_name']);
$timezone = new DateTimeZone($provider['timezone']); $timezone = new DateTimeZone($provider['timezone']);
$start = new Google_Service_Calendar_EventDateTime(); $start = new Google_Service_Calendar_EventDateTime();
$start->setDateTime( $start->setDateTime(
(new DateTime($appointment['start_datetime'], $timezone))->format(DateTimeInterface::RFC3339), (new DateTime($appointment['start_datetime'], $timezone))->format(DateTimeInterface::RFC3339),
); );
$event->setStart($start); $event->setStart($start);
$end = new Google_Service_Calendar_EventDateTime(); $end = new Google_Service_Calendar_EventDateTime();
$end->setDateTime((new DateTime($appointment['end_datetime'], $timezone))->format(DateTimeInterface::RFC3339)); $end->setDateTime((new DateTime($appointment['end_datetime'], $timezone))->format(DateTimeInterface::RFC3339));
$event->setEnd($end); $event->setEnd($end);
$event->attendees = []; $event->attendees = [];
$event_provider = new Google_Service_Calendar_EventAttendee(); $event_provider = new Google_Service_Calendar_EventAttendee();
$event_provider->setDisplayName($provider['first_name'] . ' ' . $provider['last_name']); $event_provider->setDisplayName($provider['first_name'] . ' ' . $provider['last_name']);
$event_provider->setEmail($provider['email']); $event_provider->setEmail($provider['email']);
$event->attendees[] = $event_provider; $event->attendees[] = $event_provider;
if (!empty($customer['first_name']) && !empty($customer['last_name']) && !empty($customer['email'])) { if (!empty($customer['first_name']) && !empty($customer['last_name']) && !empty($customer['email'])) {
$event_customer = new Google_Service_Calendar_EventAttendee(); $event_customer = new Google_Service_Calendar_EventAttendee();
$event_customer->setDisplayName($customer['first_name'] . ' ' . $customer['last_name']); $event_customer->setDisplayName($customer['first_name'] . ' ' . $customer['last_name']);
$event_customer->setEmail($customer['email']); $event_customer->setEmail($customer['email']);
$event->attendees[] = $event_customer; $event->attendees[] = $event_customer;
} }
// Add or update Google Meet link // Add or update Google Meet link
if (!$event->getConferenceData()) { if (!$event->getConferenceData()) {
$conferenceData = new Google_Service_Calendar_ConferenceData(); $conferenceData = new Google_Service_Calendar_ConferenceData();
@ -276,7 +242,6 @@ class Google_sync
$conferenceData->setCreateRequest($createRequest); $conferenceData->setCreateRequest($createRequest);
$event->setConferenceData($conferenceData); $event->setConferenceData($conferenceData);
} }
return $this->service->events->update( return $this->service->events->update(
$provider['settings']['google_calendar'], $provider['settings']['google_calendar'],
$event->getId(), $event->getId(),
@ -284,213 +249,177 @@ class Google_sync
['conferenceDataVersion' => 1] ['conferenceDataVersion' => 1]
); );
} }
/**
/** * Delete an existing appointment from Google Calendar.
* Delete an existing appointment from Google Calendar. *
* * @param array $provider Provider data.
* @param array $provider Provider data. * @param string $google_event_id The Google Calendar event ID to be removed.
* @param string $google_event_id The Google Calendar event ID to be removed. */
*/ public function delete_appointment(array $provider, string $google_event_id): void
public function delete_appointment(array $provider, string $google_event_id): void {
{ $this->service->events->delete($provider['settings']['google_calendar'], $google_event_id);
$this->service->events->delete($provider['settings']['google_calendar'], $google_event_id);
} }
/**
/** * Add unavailability period event to Google Calendar.
* Add unavailability period event to Google Calendar. *
* * @param array $provider Provider data.
* @param array $provider Provider data. * @param array $unavailability Unavailable data.
* @param array $unavailability Unavailable data. *
* * @return Google_Service_Calendar_Event Returns the Google event.
* @return Google_Service_Calendar_Event Returns the Google event. *
* * @throws Exception
* @throws Exception */
*/ public function add_unavailability(array $provider, array $unavailability): Google_Service_Calendar_Event
public function add_unavailability(array $provider, array $unavailability): Google_Service_Calendar_Event {
{ $event = new Google_Service_Calendar_Event();
$event = new Google_Service_Calendar_Event(); $event->setSummary('Unavailable');
$event->setSummary('Unavailable');
$event->setDescription($unavailability['notes']); $event->setDescription($unavailability['notes']);
$timezone = new DateTimeZone($provider['timezone']); $timezone = new DateTimeZone($provider['timezone']);
$start = new Google_Service_Calendar_EventDateTime();
$start = new Google_Service_Calendar_EventDateTime(); $start->setDateTime(
$start->setDateTime( (new DateTime($unavailability['start_datetime'], $timezone))->format(DateTimeInterface::RFC3339),
(new DateTime($unavailability['start_datetime'], $timezone))->format(DateTimeInterface::RFC3339),
);
$event->setStart($start);
$end = new Google_Service_Calendar_EventDateTime();
$end->setDateTime(
(new DateTime($unavailability['end_datetime'], $timezone))->format(DateTimeInterface::RFC3339),
);
$event->setEnd($end);
// Add the new event to the Google Calendar.
return $this->service->events->insert($provider['settings']['google_calendar'], $event);
}
/**
* Update Google Calendar unavailability period event.
*
* @param array $provider Provider data.
* @param array $unavailability Unavailability data.
*
* @return Google_Service_Calendar_Event Returns the Google_Service_Calendar_Event object.
*
* @throws Exception
*/
public function update_unavailability(array $provider, array $unavailability): Google_Service_Calendar_Event
{
$event = $this->service->events->get(
$provider['settings']['google_calendar'],
$unavailability['id_google_calendar'],
); );
$event->setSummary('Unavailable');
$event->setDescription($unavailability['notes']);
$timezone = new DateTimeZone($provider['timezone']);
$start = new Google_Service_Calendar_EventDateTime();
$start->setDateTime(
(new DateTime($unavailability['start_datetime'], $timezone))->format(DateTimeInterface::RFC3339),
);
$event->setStart($start); $event->setStart($start);
$end = new Google_Service_Calendar_EventDateTime();
$end = new Google_Service_Calendar_EventDateTime(); $end->setDateTime(
$end->setDateTime( (new DateTime($unavailability['end_datetime'], $timezone))->format(DateTimeInterface::RFC3339),
(new DateTime($unavailability['end_datetime'], $timezone))->format(DateTimeInterface::RFC3339), );
);
$event->setEnd($end); $event->setEnd($end);
// Add the new event to the Google Calendar.
return $this->service->events->update($provider['settings']['google_calendar'], $event->getId(), $event); return $this->service->events->insert($provider['settings']['google_calendar'], $event);
} }
/**
/** * Update Google Calendar unavailability period event.
* Delete unavailability period event from Google Calendar. *
* * @param array $provider Provider data.
* @param array $provider Provider data. * @param array $unavailability Unavailability data.
* @param string $google_event_id Google Calendar event ID to be removed. *
*/ * @return Google_Service_Calendar_Event Returns the Google_Service_Calendar_Event object.
public function delete_unavailability(array $provider, string $google_event_id): void *
{ * @throws Exception
$this->service->events->delete($provider['settings']['google_calendar'], $google_event_id); */
public function update_unavailability(array $provider, array $unavailability): Google_Service_Calendar_Event
{
$event = $this->service->events->get(
$provider['settings']['google_calendar'],
$unavailability['id_google_calendar'],
);
$event->setSummary('Unavailable');
$event->setDescription($unavailability['notes']);
$timezone = new DateTimeZone($provider['timezone']);
$start = new Google_Service_Calendar_EventDateTime();
$start->setDateTime(
(new DateTime($unavailability['start_datetime'], $timezone))->format(DateTimeInterface::RFC3339),
);
$event->setStart($start);
$end = new Google_Service_Calendar_EventDateTime();
$end->setDateTime(
(new DateTime($unavailability['end_datetime'], $timezone))->format(DateTimeInterface::RFC3339),
);
$event->setEnd($end);
return $this->service->events->update($provider['settings']['google_calendar'], $event->getId(), $event);
} }
/**
/** * Delete unavailability period event from Google Calendar.
* Get a Google Calendar event. *
* * @param array $provider Provider data.
* @param array $provider Provider data. * @param string $google_event_id Google Calendar event ID to be removed.
* @param string $google_event_id Google Calendar event ID. */
* public function delete_unavailability(array $provider, string $google_event_id): void
* @return Event Returns the Google Calendar event. {
*/ $this->service->events->delete($provider['settings']['google_calendar'], $google_event_id);
public function get_event(array $provider, string $google_event_id): Event
{
return $this->service->events->get($provider['settings']['google_calendar'], $google_event_id);
} }
/**
/** * Get a Google Calendar event.
* Get all the events between the sync period. *
* * @param array $provider Provider data.
* @param string $google_calendar The name of the Google Calendar to be used. * @param string $google_event_id Google Calendar event ID.
* @param string $start The start date of sync period. *
* @param string $end The end date of sync period. * @return Event Returns the Google Calendar event.
* */
* @return Events Returns a collection of events. public function get_event(array $provider, string $google_event_id): Event
*/ {
public function get_sync_events(string $google_calendar, string $start, string $end): Events return $this->service->events->get($provider['settings']['google_calendar'], $google_event_id);
{ }
$params = [ /**
'timeMin' => date(DateTimeInterface::RFC3339, $start), * Get all the events between the sync period.
'timeMax' => date(DateTimeInterface::RFC3339, $end), *
'singleEvents' => true, * @param string $google_calendar The name of the Google Calendar to be used.
* @param string $start The start date of sync period.
* @param string $end The end date of sync period.
*
* @return Events Returns a collection of events.
*/
public function get_sync_events(string $google_calendar, string $start, string $end): Events
{
$params = [
'timeMin' => date(DateTimeInterface::RFC3339, $start),
'timeMax' => date(DateTimeInterface::RFC3339, $end),
'singleEvents' => true,
]; ];
return $this->service->events->listEvents($google_calendar, $params);
return $this->service->events->listEvents($google_calendar, $params);
} }
/**
/** * Return available Google Calendars for specific user.
* Return available Google Calendars for specific user. *
* * The given user's token must already exist in db in order to get access to his
* The given user's token must already exist in db in order to get access to his * Google Calendar account.
* Google Calendar account. *
* * @return array Returns an array with the available calendars.
* @return array Returns an array with the available calendars. */
*/ public function get_google_calendars(): array
public function get_google_calendars(): array {
{
$calendar_list = $this->service->calendarList->listCalendarList(); $calendar_list = $this->service->calendarList->listCalendarList();
$calendars = []; $calendars = [];
foreach ($calendar_list->getItems() as $google_calendar) {
foreach ($calendar_list->getItems() as $google_calendar) { if ($google_calendar->getAccessRole() === 'reader') {
if ($google_calendar->getAccessRole() === 'reader') { continue;
continue;
} }
$calendars[] = [
$calendars[] = [ 'id' => $google_calendar->getId(),
'id' => $google_calendar->getId(), 'summary' => $google_calendar->getSummary(),
'summary' => $google_calendar->getSummary(), ];
];
} }
return $calendars;
return $calendars;
} }
/**
/** * Get the Add-To-Google-URL, that can be used by anyone to quickly add the event to Google Calendar (no API needed).
* Get the Add-To-Google-URL, that can be used by anyone to quickly add the event to Google Calendar (no API needed). *
* * @param int $appointment_id
* @param int $appointment_id *
* * @return string
* @return string *
* * @throws Exception
* @throws Exception */
*/ public function get_add_to_google_url(int $appointment_id): string
public function get_add_to_google_url(int $appointment_id): string {
{
$appointment = $this->CI->appointments_model->find($appointment_id); $appointment = $this->CI->appointments_model->find($appointment_id);
$service = $this->CI->services_model->find($appointment['id_services']); $service = $this->CI->services_model->find($appointment['id_services']);
$provider = $this->CI->providers_model->find($appointment['id_users_provider']); $provider = $this->CI->providers_model->find($appointment['id_users_provider']);
$customer = $this->CI->customers_model->find($appointment['id_users_customer']); $customer = $this->CI->customers_model->find($appointment['id_users_customer']);
$provider_timezone_instance = new DateTimeZone($provider['timezone']); $provider_timezone_instance = new DateTimeZone($provider['timezone']);
$utc_timezone_instance = new DateTimeZone('UTC'); $utc_timezone_instance = new DateTimeZone('UTC');
$appointment_start_instance = new DateTime($appointment['start_datetime'], $provider_timezone_instance); $appointment_start_instance = new DateTime($appointment['start_datetime'], $provider_timezone_instance);
$appointment_start_instance->setTimezone($utc_timezone_instance); $appointment_start_instance->setTimezone($utc_timezone_instance);
$appointment_end_instance = new DateTime($appointment['end_datetime'], $provider_timezone_instance); $appointment_end_instance = new DateTime($appointment['end_datetime'], $provider_timezone_instance);
$appointment_end_instance->setTimezone($utc_timezone_instance); $appointment_end_instance->setTimezone($utc_timezone_instance);
$add = [$provider['email']]; $add = [$provider['email']];
if (!empty($customer['email'])) {
if (!empty($customer['email'])) { $add[] = $customer['email'];
$add[] = $customer['email'];
} }
$add_to_google_url_params = [
$add_to_google_url_params = [ 'action' => 'TEMPLATE',
'action' => 'TEMPLATE', 'text' => $service['name'],
'text' => $service['name'], 'dates' =>
'dates' => $appointment_start_instance->format('Ymd\THis\Z') .
$appointment_start_instance->format('Ymd\THis\Z') . '/' .
'/' . $appointment_end_instance->format('Ymd\THis\Z'),
$appointment_end_instance->format('Ymd\THis\Z'), 'location' => setting('company_name'),
'location' => setting('company_name'), 'details' => 'View/Change Appointment: ' . site_url('appointments/index/' . $appointment['hash']),
'details' => 'View/Change Appointment: ' . site_url('appointments/index/' . $appointment['hash']), 'add' => implode(', ', $add),
'add' => implode(', ', $add),
]; ];
return 'https://calendar.google.com/calendar/render?' . http_build_query($add_to_google_url_params);
return 'https://calendar.google.com/calendar/render?' . http_build_query($add_to_google_url_params);
} }
/** /**
* Get the Google Meet link from an event. * Get the Google Meet link from an event.
* *