2020-10-21 21:37:47 +03:00
|
|
|
<?php defined('BASEPATH') or exit('No direct script access allowed');
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------------
|
2022-01-18 15:05:42 +03:00
|
|
|
* Easy!Appointments - Online Appointment Scheduler
|
2020-10-21 21:37:47 +03:00
|
|
|
*
|
|
|
|
* @package EasyAppointments
|
|
|
|
* @author A.Tselegidis <alextselegidis@gmail.com>
|
2021-12-18 19:43:45 +03:00
|
|
|
* @copyright Copyright (c) Alex Tselegidis
|
|
|
|
* @license https://opensource.org/licenses/GPL-3.0 - GPLv3
|
|
|
|
* @link https://easyappointments.org
|
2020-10-21 21:37:47 +03:00
|
|
|
* @since v1.4.0
|
|
|
|
* ---------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
/**
|
2021-11-06 18:21:27 +03:00
|
|
|
* Synchronization library.
|
2020-10-21 21:37:47 +03:00
|
|
|
*
|
2021-10-28 15:00:40 +03:00
|
|
|
* Handles external calendar synchronization functionality.
|
|
|
|
*
|
|
|
|
* @package Libraries
|
2020-10-21 21:37:47 +03:00
|
|
|
*/
|
2023-11-29 12:24:09 +03:00
|
|
|
class Synchronization
|
|
|
|
{
|
2020-10-21 21:37:47 +03:00
|
|
|
/**
|
2023-03-13 11:06:18 +03:00
|
|
|
* @var EA_Controller|CI_Controller
|
2020-10-21 21:37:47 +03:00
|
|
|
*/
|
2023-03-13 11:06:18 +03:00
|
|
|
protected EA_Controller|CI_Controller $CI;
|
2020-10-21 21:37:47 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Synchronization constructor.
|
|
|
|
*/
|
|
|
|
public function __construct()
|
|
|
|
{
|
2023-11-29 12:24:09 +03:00
|
|
|
$this->CI = &get_instance();
|
2021-10-28 15:00:40 +03:00
|
|
|
|
2020-10-21 21:37:47 +03:00
|
|
|
$this->CI->load->model('providers_model');
|
|
|
|
$this->CI->load->model('appointments_model');
|
2021-10-28 15:00:40 +03:00
|
|
|
|
2020-10-21 21:37:47 +03:00
|
|
|
$this->CI->load->library('google_sync');
|
2024-05-12 19:07:46 +03:00
|
|
|
$this->CI->load->library('caldav_sync');
|
2020-10-21 21:37:47 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Synchronize changes made to the appointment with external calendars.
|
|
|
|
*
|
|
|
|
* @param array $appointment Appointment record.
|
|
|
|
* @param array $service Service record.
|
|
|
|
* @param array $provider Provider record.
|
|
|
|
* @param array $customer Customer record.
|
|
|
|
* @param array $settings Required settings for the notification content.
|
|
|
|
*/
|
2023-11-29 12:24:09 +03:00
|
|
|
public function sync_appointment_saved(
|
|
|
|
array $appointment,
|
|
|
|
array $service,
|
|
|
|
array $provider,
|
|
|
|
array $customer,
|
2023-12-22 13:35:41 +03:00
|
|
|
array $settings,
|
2023-11-29 12:24:09 +03:00
|
|
|
): void {
|
|
|
|
try {
|
2024-05-12 15:24:58 +03:00
|
|
|
// Google
|
2022-06-19 20:05:45 +03:00
|
|
|
|
2024-05-12 15:24:58 +03:00
|
|
|
if ($provider['settings']['google_sync']) {
|
|
|
|
if (empty($provider['settings']['google_token'])) {
|
|
|
|
throw new RuntimeException('No google token available for the provider: ' . $provider['id']);
|
|
|
|
}
|
|
|
|
|
|
|
|
$google_token = json_decode($provider['settings']['google_token'], true);
|
2022-06-19 20:05:45 +03:00
|
|
|
|
2024-05-12 15:24:58 +03:00
|
|
|
$this->CI->google_sync->refresh_token($google_token['refresh_token']);
|
2022-06-19 20:05:45 +03:00
|
|
|
|
2024-05-12 15:24:58 +03:00
|
|
|
if (empty($appointment['id_google_calendar'])) {
|
|
|
|
$google_event = $this->CI->google_sync->add_appointment(
|
|
|
|
$appointment,
|
|
|
|
$provider,
|
|
|
|
$service,
|
|
|
|
$customer,
|
|
|
|
$settings,
|
|
|
|
);
|
|
|
|
|
|
|
|
$appointment['id_google_calendar'] = $google_event->getId();
|
|
|
|
|
|
|
|
$this->CI->appointments_model->save($appointment);
|
|
|
|
} else {
|
|
|
|
$this->CI->google_sync->update_appointment($appointment, $provider, $service, $customer, $settings);
|
|
|
|
}
|
|
|
|
}
|
2022-06-19 20:05:45 +03:00
|
|
|
|
2024-05-12 15:24:58 +03:00
|
|
|
// CalDAV
|
|
|
|
|
|
|
|
if ($provider['settings']['caldav_sync']) {
|
|
|
|
$appointment['id_caldav_calendar'] = $this->CI->caldav_sync->save_appointment(
|
2022-06-19 20:05:45 +03:00
|
|
|
$appointment,
|
2022-06-20 12:09:56 +03:00
|
|
|
$service,
|
2024-05-12 15:24:58 +03:00
|
|
|
$provider,
|
2022-06-19 20:05:45 +03:00
|
|
|
$customer,
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->CI->appointments_model->save($appointment);
|
|
|
|
}
|
2023-11-29 12:24:09 +03:00
|
|
|
} catch (Throwable $e) {
|
|
|
|
log_message(
|
|
|
|
'error',
|
|
|
|
'Synchronization - Could not sync confirmation details of appointment (' .
|
|
|
|
($appointment['id'] ?? '-') .
|
|
|
|
') : ' .
|
2023-12-22 13:35:41 +03:00
|
|
|
$e->getMessage(),
|
2023-11-29 12:24:09 +03:00
|
|
|
);
|
2024-05-12 15:24:58 +03:00
|
|
|
|
|
|
|
log_message('error', $e->getTraceAsString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Synchronize removal of an appointment with external calendars.
|
|
|
|
*
|
|
|
|
* @param array $appointment Appointment record.
|
|
|
|
* @param array $provider Provider record.
|
|
|
|
*/
|
|
|
|
public function sync_appointment_deleted(array $appointment, array $provider): void
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
// Google
|
|
|
|
|
|
|
|
if ($provider['settings']['google_sync'] && !empty($appointment['id_google_calendar'])) {
|
|
|
|
if (empty($provider['settings']['google_token'])) {
|
|
|
|
throw new RuntimeException('No google token available for the provider: ' . $provider['id']);
|
|
|
|
}
|
|
|
|
|
|
|
|
$google_token = json_decode($provider['settings']['google_token'], true);
|
|
|
|
|
|
|
|
$this->CI->google_sync->refresh_token($google_token['refresh_token']);
|
|
|
|
|
|
|
|
$this->CI->google_sync->delete_appointment($provider, $appointment['id_google_calendar']);
|
|
|
|
}
|
|
|
|
|
|
|
|
// CalDAV
|
|
|
|
|
|
|
|
if ($provider['settings']['caldav_sync'] && !empty($appointment['id_caldav_calendar'])) {
|
|
|
|
$this->CI->caldav_sync->delete_event($provider, $appointment['id_caldav_calendar']);
|
|
|
|
}
|
|
|
|
} catch (Throwable $e) {
|
|
|
|
log_message(
|
|
|
|
'error',
|
|
|
|
'Synchronization - Could not sync cancellation details of appointment (' .
|
|
|
|
($appointment['id'] ?? '-') .
|
|
|
|
') : ' .
|
|
|
|
$e->getMessage(),
|
|
|
|
);
|
2022-06-19 20:05:45 +03:00
|
|
|
log_message('error', $e->getTraceAsString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Synchronize changes made to the unavailability with external calendars.
|
|
|
|
*
|
|
|
|
* @param array $unavailability Unavailability record.
|
|
|
|
* @param array $provider Provider record.
|
|
|
|
*/
|
2023-03-13 11:06:18 +03:00
|
|
|
public function sync_unavailability_saved(array $unavailability, array $provider): void
|
2022-06-19 20:05:45 +03:00
|
|
|
{
|
2023-11-29 12:24:09 +03:00
|
|
|
try {
|
2024-05-12 15:24:58 +03:00
|
|
|
// Google
|
2022-06-19 20:05:45 +03:00
|
|
|
|
2024-05-12 15:24:58 +03:00
|
|
|
if ($provider['settings']['google_sync']) {
|
|
|
|
if (empty($provider['settings']['google_token'])) {
|
|
|
|
throw new RuntimeException('No google token available for the provider: ' . $provider['id']);
|
|
|
|
}
|
|
|
|
|
|
|
|
$google_token = json_decode($provider['settings']['google_token'], true);
|
|
|
|
|
|
|
|
$this->CI->google_sync->refresh_token($google_token['refresh_token']);
|
2022-06-19 20:05:45 +03:00
|
|
|
|
2024-05-12 15:24:58 +03:00
|
|
|
if (empty($unavailability['id_google_calendar'])) {
|
|
|
|
$google_event = $this->CI->google_sync->add_unavailability($provider, $unavailability);
|
2022-06-19 20:05:45 +03:00
|
|
|
|
2024-05-12 15:24:58 +03:00
|
|
|
$unavailability['id_google_calendar'] = $google_event->getId();
|
|
|
|
|
|
|
|
$this->CI->unavailabilities_model->save($unavailability);
|
|
|
|
} else {
|
|
|
|
$this->CI->google_sync->update_unavailability($provider, $unavailability);
|
|
|
|
}
|
|
|
|
}
|
2022-06-19 20:05:45 +03:00
|
|
|
|
2024-05-12 15:24:58 +03:00
|
|
|
// CalDAV
|
2022-06-19 20:05:45 +03:00
|
|
|
|
2024-05-12 15:24:58 +03:00
|
|
|
if ($provider['settings']['caldav_sync']) {
|
|
|
|
$unavailability['id_caldav_calendar'] = $this->CI->caldav_sync->save_unavailability(
|
|
|
|
$unavailability,
|
|
|
|
$provider,
|
|
|
|
);
|
2022-06-19 20:05:45 +03:00
|
|
|
|
|
|
|
$this->CI->unavailabilities_model->save($unavailability);
|
|
|
|
}
|
2023-11-29 12:24:09 +03:00
|
|
|
} catch (Throwable $e) {
|
|
|
|
log_message(
|
|
|
|
'error',
|
|
|
|
'Synchronization - Could not sync cancellation details of unavailability (' .
|
|
|
|
($appointment['id'] ?? '-') .
|
|
|
|
') : ' .
|
2023-12-22 13:35:41 +03:00
|
|
|
$e->getMessage(),
|
2023-11-29 12:24:09 +03:00
|
|
|
);
|
2022-06-19 20:05:45 +03:00
|
|
|
log_message('error', $e->getTraceAsString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Synchronize removal of an unavailability with external calendars.
|
|
|
|
*
|
|
|
|
* @param array $unavailability Unavailability record.
|
|
|
|
* @param array $provider Provider record.
|
|
|
|
*/
|
2023-03-13 11:06:18 +03:00
|
|
|
public function sync_unavailability_deleted(array $unavailability, array $provider): void
|
2022-06-19 20:05:45 +03:00
|
|
|
{
|
2023-11-29 12:24:09 +03:00
|
|
|
try {
|
2024-05-12 15:24:58 +03:00
|
|
|
// Google
|
2022-06-19 20:05:45 +03:00
|
|
|
|
2024-05-12 15:24:58 +03:00
|
|
|
if ($provider['settings']['google_sync'] && !empty($unavailability['id_google_calendar'])) {
|
|
|
|
if (empty($provider['settings']['google_token'])) {
|
|
|
|
throw new RuntimeException('No google token available for the provider: ' . $provider['id']);
|
|
|
|
}
|
|
|
|
|
|
|
|
$google_token = json_decode($provider['settings']['google_token'], true);
|
2022-06-19 20:05:45 +03:00
|
|
|
|
2024-05-12 15:24:58 +03:00
|
|
|
$this->CI->google_sync->refresh_token($google_token['refresh_token']);
|
2022-06-19 20:05:45 +03:00
|
|
|
|
2024-05-12 15:24:58 +03:00
|
|
|
$this->CI->google_sync->delete_unavailability($provider, $unavailability['id_google_calendar']);
|
|
|
|
}
|
|
|
|
|
|
|
|
// CalDAV
|
2022-06-19 20:05:45 +03:00
|
|
|
|
2024-05-12 15:24:58 +03:00
|
|
|
if ($provider['settings']['caldav_sync'] && !empty($unavailability['id_caldav_calendar'])) {
|
|
|
|
$this->CI->caldav_sync->delete_event($provider, $unavailability['id_caldav_calendar']);
|
|
|
|
}
|
2023-11-29 12:24:09 +03:00
|
|
|
} catch (Throwable $e) {
|
|
|
|
log_message(
|
|
|
|
'error',
|
|
|
|
'Synchronization - Could not sync cancellation details of unavailability (' .
|
|
|
|
($appointment['id'] ?? '-') .
|
|
|
|
') : ' .
|
2023-12-22 13:35:41 +03:00
|
|
|
$e->getMessage(),
|
2023-11-29 12:24:09 +03:00
|
|
|
);
|
2022-06-19 20:05:45 +03:00
|
|
|
log_message('error', $e->getTraceAsString());
|
2020-10-21 21:37:47 +03:00
|
|
|
}
|
|
|
|
}
|
2022-07-26 16:43:37 +03:00
|
|
|
|
|
|
|
/**
|
2024-05-12 15:24:58 +03:00
|
|
|
* Make sure a synced appointment is removed from Google/CalDAV Calendar, if its provider is changed.
|
2023-11-29 12:24:09 +03:00
|
|
|
*
|
2022-07-26 16:43:37 +03:00
|
|
|
* @throws Exception
|
|
|
|
*/
|
2023-03-13 11:06:18 +03:00
|
|
|
public function remove_appointment_on_provider_change($appointment_id): void
|
2022-07-26 16:43:37 +03:00
|
|
|
{
|
2023-03-13 11:06:18 +03:00
|
|
|
$existing_appointment = $this->CI->appointments_model->find($appointment_id);
|
2022-07-26 16:43:37 +03:00
|
|
|
|
|
|
|
$existing_google_id = $existing_appointment['id_google_calendar'];
|
2024-05-12 15:24:58 +03:00
|
|
|
$existing_caldav_id = $existing_appointment['id_caldav_calendar'];
|
2022-07-26 16:43:37 +03:00
|
|
|
|
|
|
|
$existing_provider_id = $existing_appointment['id_users_provider'];
|
|
|
|
|
2023-11-29 12:24:09 +03:00
|
|
|
if (
|
2024-05-12 15:24:58 +03:00
|
|
|
(!empty($existing_google_id) || !empty($existing_caldav_id)) &&
|
2023-11-29 12:24:09 +03:00
|
|
|
(int) $existing_provider_id !== (int) $existing_appointment['id_users_provider']
|
|
|
|
) {
|
2023-03-13 11:06:18 +03:00
|
|
|
$existing_provider = $this->CI->providers_model->find($existing_provider_id);
|
2022-07-26 16:43:37 +03:00
|
|
|
|
2024-05-12 15:24:58 +03:00
|
|
|
if ($existing_provider['settings']['google_sync'] || $existing_provider['settings']['caldav_sync']) {
|
2022-07-26 16:43:37 +03:00
|
|
|
$this->sync_appointment_deleted($existing_appointment, $existing_provider);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-10-21 21:37:47 +03:00
|
|
|
}
|