load->library('Google_Sync'); header('Location: ' . $this->google_sync->get_auth_url()); } /** * Callback method for the Google Calendar API authorization process. * * Once the user grants consent with his Google Calendar data usage, the Google * OAuth service will redirect him back in this page. Here we are going to store * the refresh token, because this is what will be used to generate access tokens * in the future. * * IMPORTANT! Because it is necessary to authorize the application * using the web server flow (see official documentation of OAuth), every * Easy!Appointments installation should use its own calendar api key. So in every * api console account, the "http://path-to-e!a/google/oauth_callback" should be * included in an allowed redirect url. */ public function oauth_callback() { if (isset($_GET['code'])) { $this->load->library('Google_Sync'); $token = $this->google_sync->authenticate($_GET['code']); // Store the token into the database for future reference. if (!isset($_SESSION)) { @session_start(); } if (isset($_SESSION['oauth_provider_id'])) { $this->load->model('providers_model'); $this->providers_model->set_setting('google_sync', TRUE, $_SESSION['oauth_provider_id']); $this->providers_model->set_setting('google_token', $token, $_SESSION['oauth_provider_id']); } else { echo '

Sync provider id not specified!

'; } } else { echo '

Authorization Failed!

'; } } /** * Complete synchronization of appointments between Google Calendar and Easy!Appointments. * * This method will completely sync the appointments of a provider with his Google Calendar * account. The sync period needs to be relatively small, because a lot of API calls might * be necessary and this will lead to consuming the Google limit for the Calendar API usage. * * @param numeric $provider_id Provider record to be synced. * * @task This method must be executed only by the system and noone else outside. It is a big security issue. */ public function sync($provider_id = NULL) { try { if ($provider_id === NULL) { throw new Exception('Provider id not specified.'); } $this->load->model('appointments_model'); $this->load->model('providers_model'); $this->load->model('services_model'); $this->load->model('customers_model'); $this->load->model('settings_model'); $provider = $this->providers_model->get_row($provider_id); // Check whether the selected provider has google sync enabled. $google_sync = $this->providers_model->get_setting('google_sync', $provider['id']); if (!$google_sync) { throw new Exception('The selected provider has not the google synchronization ' . 'setting enabled.'); } $google_token = json_decode($this->providers_model->get_setting('google_token', $provider['id'])); $this->load->library('google_sync'); $this->google_sync->refresh_token($google_token->refresh_token); // Fetch provider's appointments that belong to the sync time period. $sync_past_days = $this->providers_model->get_setting('sync_past_days', $provider['id']); $sync_future_days = $this->providers_model->get_setting('sync_future_days', $provider['id']); $start = strtotime('-' . $sync_past_days . ' days', strtotime(date('Y-m-d'))); $end = strtotime('+' . $sync_future_days . ' days', strtotime(date('Y-m-d'))); $where_clause = array( 'start_datetime >=' => date('Y-m-d H:i:s', $start), 'end_datetime <=' => date('Y-m-d H:i:s', $end), 'id_users_provider' => $provider['id'], 'is_unavailable' => FALSE ); $appointments = $this->appointments_model->get_batch($where_clause); $company_settings = array( 'company_name' => $this->settings_model->get_setting('company_name'), 'company_link' => $this->settings_model->get_setting('company_link'), 'company_email' => $this->settings_model->get_setting('company_email') ); // Sync each appointment with Google Calendar by following the project's sync // protocol (see documentation). foreach($appointments as $appointment) { $service = $this->services_model->get_row($appointment['id_services']); $customer = $this->customers_model->get_row($appointment['id_users_customer']); // :: APPOINTMENT WITH NO GCAL_ID -> ADD TO GCAL if ($appointment['id_google_calendar'] == NULL) { $google_event = $this->google_sync->add_appointment($appointment, $provider, $service, $customer, $company_settings); $appointment['id_google_calendar'] = $google_event->id; $this->appointments_model->add($appointment); // save gcal id } // :: SYNCED APPOINTMENT NOT FOUND ON GCAL -> DELETE E!A RECORD if ($appointment['id_google_calendar'] != NULL) { try { $google_event = $this->google_sync->get_event($appointment['id_google_calendar']); } catch(Exception $exc) { $this->appointments_model->delete($appointment['id']); $appointment['id_google_calendar'] = NULL; // Do not proceed with the rest sync actions. } } // :: SYNCED APPOINTMENT DIFFERENT FROM GCAL EVENT -> UPDATE E!A RECORD if ($appointment['id_google_calendar'] != NULL) { $is_different = FALSE; $appt_start = strtotime($appointment['start_datetime']); $appt_end = strtotime($appointment['end_datetime']); $event_start = strtotime($google_event->getStart()->getDateTime()); $event_end = strtotime($google_event->getEnd()->getDateTime()); if ($appt_start != $event_start || $appt_end != $event_end) { $is_different = TRUE; } if ($is_different) { $appointment['start_datetime'] = date('Y-m-d H:i:s', $event_start); $appointment['end_datetime'] = date('Y-m-d H:i:s', $event_end); $this->appointments_model->add($appointment); } } // @task :: GCAL EVENT NOT FOUND ON E!A -> ADD EVENT TO E!A } // @task Sync unavailable periods with Google Calendar echo json_encode('SUCCESS'); } catch(Exception $exc) { echo json_encode(array( 'exceptions' => array($exc) )); } } } /* End of file google.php */ /* Location: ./application/controllers/google.php */