/** * [AJAX] Installs Easy!Appointments on the server. * * @param array $_POST['admin'] Contains the initial admin user data. The App needs at * least one admin user to work. * @param array $_POST['company'] Contains the basic company data. */ public function ajax_install() { try { if (is_ea_installed()) { return; } // Create E!A database structure. $file_contents = file_get_contents(BASEPATH . 'assets/sql/structure.sql'); $sql_queries = explode(';', $file_contents); array_pop($sql_queries); foreach ($sql_queries as $query) { $this->db->query($query); } // Insert admin $this->load->model('admins_model'); $admin = json_decode($_POST['admin'], true); $admin['settings']['username'] = $admin['username']; $admin['settings']['password'] = $admin['password']; unset($admin['username'], $admin['password']); $admin['id'] = $this->admins_model->add($admin); $this->load->library('session'); $this->session->set_userdata('user_id', $admin['id']); $this->session->set_userdata('user_email', $admin['email']); $this->session->set_userdata('role_slug', DB_SLUG_ADMIN); $this->session->set_userdata('username', $admin['settings']['username']); // Save company settings $this->load->model('settings_model'); $company = json_decode($_POST['company'], true); $this->settings_model->set_setting('company_name', $company['company_name']); $this->settings_model->set_setting('company_email', $company['company_email']); $this->settings_model->set_setting('company_link', $company['company_link']); echo json_encode(AJAX_SUCCESS); } catch (Exception $exc) { echo json_encode(array('exceptions' => array(exceptionToJavaScript($exc)))); } }
/** * Installs Easy!Appointments on server. * * @param array $_POST['admin'] Contains the initial admin user data. System needs at least * one admin user to work. * @param array $_POST['company'] Contains the basic company data. */ public function ajax_install() { try { // Create E!A database structure. $file_contents = file_get_contents($this->config->item('base_url') . 'assets/sql/structure.sql'); $sql_queries = explode(';', $file_contents); array_pop($sql_queries); foreach ($sql_queries as $query) { $this->db->query($query); } // Insert admin $this->load->model('admins_model'); $admin = json_decode($_POST['admin'], true); $admin['settings']['username'] = $admin['username']; $admin['settings']['password'] = $admin['password']; unset($admin['username'], $admin['password']); $admin['id'] = $this->admins_model->add($admin); $this->load->library('session'); $this->session->set_userdata('user_id', $admin['id']); $this->session->set_userdata('user_email', $admin['email']); $this->session->set_userdata('role_slug', DB_SLUG_ADMIN); $this->session->set_userdata('username', $admin['settings']['username']); // Save company settings $this->load->model('settings_model'); $company = json_decode($_POST['company'], true); $this->settings_model->set_setting('company_name', $company['company_name']); $this->settings_model->set_setting('company_email', $company['company_email']); $this->settings_model->set_setting('company_link', $company['company_link']); // Try to send a notification email for the new installation. // IMPORTANT: THIS WILL ONLY BE USED TO TRACK THE INSTALLATION NUMBER AND // NO PERSONAL DATA WILL BE USED FOR OTHER CAUSE. try { $this->load->library('notifications'); $this->notifications->send_new_installation($company['company_name'], $company['company_email'], $company['company_link']); } catch (Exception $exc) { // Well, I guess we'll never know ... } echo json_encode(AJAX_SUCCESS); } catch (Exception $exc) { echo json_encode(array('exceptions' => array(exceptionToJavaScript($exc)))); } }
/** * This method will update the installation to the latest available * version in the server. IMPORTANT: The code files must exist in the * server, this method will not fetch any new files but will update * the database schema. * * This method can be used either by loading the page in the browser * or by an ajax request. But it will answer with json encoded data. */ public function update() { try { if (!$this->hasPrivileges(PRIV_SYSTEM_SETTINGS, TRUE)) { throw new Exception('You do not have the required privileges for this task!'); } $this->load->library('migration'); if (!$this->migration->current()) { throw new Exception($this->migration->error_string()); } echo json_encode(AJAX_SUCCESS); } catch (Exception $exc) { echo json_encode(array('exceptions' => array(exceptionToJavaScript($exc)))); } }
function add_appointment_post() { $customer_data = empty($this->post('first_name') || $this->post('last_name') || $this->post('email') || $this->post('phone_number')) ? FALSE : TRUE; $appointment_data = empty($this->post('service') || $this->post('provider') || $this->post('start_datetime') || $this->post('end_datetime')) ? FALSE : TRUE; try { $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'); // :: SAVE CUSTOMER CHANGES TO DATABASE if ($customer_data) { //$customer = json_decode(stripcslashes($_POST['customer_data']), true); $customer = array('id' => $this->post('id'), 'first_name' => $this->post('first_name'), 'last_name' => $this->post('last_name'), 'email' => $this->post('email'), 'phone_number' => $this->post('phone_number'), 'address' => $this->post('address'), 'city' => $this->post('city'), 'zip_code' => $this->post('zip_code'), 'notes' => $this->post('notes')); $customer['id'] = $this->customers_model->add($customer); //$this->response(array('success' => 'Customer saved successfully!'), 200); // 200 being the HTTP response code } // :: SAVE APPOINTMENT CHANGES TO DATABASE if ($appointment_data) { //$appointment = json_decode(stripcslashes($_POST['appointment_data']), true); $appointment = array('id_services' => $this->post('service'), 'id_users_provider' => $this->post('provider'), 'start_datetime' => $this->post('start_datetime'), 'end_datetime' => $this->post('end_datetime'), 'id_users_customer' => $customer['id']); $appointment['id'] = $this->appointments_model->add($appointment); $this->response(array('success' => 'Appointment saved successfully!'), 200); // 200 being the HTTP response code } /* $appointment = $this->appointments_model->get_row($appointment['id']); $provider = $this->providers_model->get_row($appointment['id_users_provider']); $customer = $this->customers_model->get_row($appointment['id_users_customer']); $service = $this->services_model->get_row($appointment['id_services']); $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 APPOINTMENT CHANGES WITH GOOGLE CALENDAR /* try { $google_sync = $this->providers_model->get_setting('google_sync', $appointment['id_users_provider']); if ($google_sync == TRUE) { $google_token = json_decode($this->providers_model->get_setting('google_token', $appointment['id_users_provider'])); $this->load->library('Google_Sync'); $this->google_sync->refresh_token($google_token->refresh_token); 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); // Store google calendar id. } else { $this->google_sync->update_appointment($appointment, $provider, $service, $customer, $company_settings); } } } catch(Exception $exc) { $warnings[] = exceptionToJavaScript($exc); } */ // :: SEND EMAIL NOTIFICATIONS TO PROVIDER AND CUSTOMER /* try { $this->load->library('Notifications'); $send_provider = $this->providers_model ->get_setting('notifications', $provider['id']); if (!$manage_mode) { $customer_title = $this->lang->line('appointment_booked'); $customer_message = $this->lang->line('thank_your_for_appointment'); $customer_link = $this->config->item('base_url') . 'appointments/index/' . $appointment['hash']; $provider_title = $this->lang->line('appointment_added_to_your_plan'); $provider_message = $this->lang->line('appointment_link_description'); $provider_link = $this->config->item('base_url') . 'backend/index/' . $appointment['hash']; } else { $customer_title = $this->lang->line('appointment_changes_saved'); $customer_message = ''; $customer_link = $this->config->item('base_url') . 'appointments/index/' . $appointment['hash']; $provider_title = $this->lang->line('appointment_details_changed'); $provider_message = ''; $provider_link = $this->config->item('base_url') . 'backend/index/' . $appointment['hash']; } $this->notifications->send_appointment_details($appointment, $provider, $service, $customer, $company_settings, $customer_title, $customer_message, $customer_link, $customer['email']); if ($send_provider == TRUE) { $this->notifications->send_appointment_details($appointment, $provider, $service, $customer, $company_settings, $provider_title, $provider_message, $provider_link, $provider['email']); } } catch(Exception $exc) { $warnings[] = exceptionToJavaScript($exc); } if (!isset($warnings)) { echo json_encode(AJAX_SUCCESS); } else { echo json_encode(array( 'warnings' => $warnings )); } */ } catch (Exception $exc) { echo json_encode(array('exceptions' => array(exceptionToJavaScript($exc)))); } }
/** * [AJAX] Register the appointment to the database. * * @return string Returns a JSON string with the appointment database ID. */ public function ajax_register_appointment() { try { $post_data = $_POST['post_data']; // alias $post_data['manage_mode'] = filter_var($post_data['manage_mode'], FILTER_VALIDATE_BOOLEAN); $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'); // Validate the CAPTCHA string. if ($this->settings_model->get_setting('require_captcha') === '1' && $this->session->userdata('captcha_phrase') !== $_POST['captcha']) { echo json_encode(array('captcha_verification' => FALSE, 'expected_phrase' => $this->session->userdata('captcha_phrase'))); return; } // Check appointment availability. if (!$this->check_datetime_availability()) { throw new Exception($this->lang->line('requested_hour_is_unavailable')); } $appointment = $_POST['post_data']['appointment']; $customer = $_POST['post_data']['customer']; if ($this->customers_model->exists($customer)) { $customer['id'] = $this->customers_model->find_record_id($customer); } $customer_id = $this->customers_model->add($customer); $appointment['id_users_customer'] = $customer_id; $appointment['is_unavailable'] = (int) $appointment['is_unavailable']; // needs to be type casted $appointment['id'] = $this->appointments_model->add($appointment); $appointment['hash'] = $this->appointments_model->get_value('hash', $appointment['id']); $provider = $this->providers_model->get_row($appointment['id_users_provider']); $service = $this->services_model->get_row($appointment['id_services']); $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')); // :: SYNCHRONIZE APPOINTMENT WITH PROVIDER'S GOOGLE CALENDAR // The provider must have previously granted access to his google calendar account // in order to sync the appointment. try { $google_sync = filter_var($this->providers_model->get_setting('google_sync', $appointment['id_users_provider']), FILTER_VALIDATE_BOOLEAN); if ($google_sync == TRUE) { $google_token = json_decode($this->providers_model->get_setting('google_token', $appointment['id_users_provider'])); $this->load->library('google_sync'); $this->google_sync->refresh_token($google_token->refresh_token); if ($post_data['manage_mode'] === FALSE) { // Add appointment to Google Calendar. $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); } else { // Update appointment to Google Calendar. $appointment['id_google_calendar'] = $this->appointments_model->get_value('id_google_calendar', $appointment['id']); $this->google_sync->update_appointment($appointment, $provider, $service, $customer, $company_settings); } } } catch (Exception $exc) { log_message('error', $exc->getMessage()); log_message('error', $exc->getTraceAsString()); } // :: SEND NOTIFICATION EMAILS TO BOTH CUSTOMER AND PROVIDER try { $this->load->library('Notifications'); if ($post_data['manage_mode'] == FALSE) { $customer_title = $this->lang->line('appointment_booked'); $customer_message = $this->lang->line('thank_you_for_appointment'); $customer_link = $this->config->item('base_url') . '/index.php/appointments/index/' . $appointment['hash']; $provider_title = $this->lang->line('appointment_added_to_your_plan'); $provider_message = $this->lang->line('appointment_link_description'); $provider_link = $this->config->item('base_url') . '/index.php/backend/index/' . $appointment['hash']; } else { $customer_title = $this->lang->line('appointment_changes_saved'); $customer_message = ''; $customer_link = $this->config->item('base_url') . '/index.php/appointments/index/' . $appointment['hash']; $provider_title = $this->lang->line('appointment_details_changed'); $provider_message = ''; $provider_link = $this->config->item('base_url') . '/index.php/backend/index/' . $appointment['hash']; } $send_customer = filter_var($this->settings_model->get_setting('customer_notifications'), FILTER_VALIDATE_BOOLEAN); if ($send_customer == TRUE) { $this->notifications->send_appointment_details($appointment, $provider, $service, $customer, $company_settings, $customer_title, $customer_message, $customer_link, $customer['email']); } $send_provider = filter_var($this->providers_model->get_setting('notifications', $provider['id']), FILTER_VALIDATE_BOOLEAN); if ($send_provider == TRUE) { $this->notifications->send_appointment_details($appointment, $provider, $service, $customer, $company_settings, $provider_title, $provider_message, $provider_link, $provider['email']); } } catch (Exception $exc) { log_message('error', $exc->getMessage()); log_message('error', $exc->getTraceAsString()); } echo json_encode(array('appointment_id' => $appointment['id'])); } catch (Exception $exc) { echo json_encode(array('exceptions' => array(exceptionToJavaScript($exc)))); } }
/** * Regenerate a new password for the current user, only if the username and * email address given corresond to an existing user in db. * * @param string $_POST['username'] * @param string $_POST['email'] */ public function ajax_forgot_password() { try { if (!isset($_POST['username']) || !isset($_POST['email'])) { throw new Exception('You must enter a valid username and email address in ' . 'order to get a new password!'); } $this->load->model('user_model'); $this->load->model('settings_model'); $new_password = $this->user_model->regenerate_password($_POST['username'], $_POST['email']); if ($new_password != FALSE) { $this->load->library('notifications'); $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')); $this->notifications->send_password($new_password, $_POST['email'], $company_settings); } echo $new_password != FALSE ? json_encode(AJAX_SUCCESS) : json_encode(AJAX_FAILURE); } catch (Exception $exc) { echo json_encode(array('exceptions' => array(exceptionToJavaScript($exc)))); } }
/** * 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. */ public function sync($provider_id = NULL) { try { // The user must be logged in. $this->load->library('session'); if ($this->session->userdata('user_id') == FALSE) { return; } 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']); $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) { if ($appointment['is_unavailable'] == FALSE) { $service = $this->services_model->get_row($appointment['id_services']); $customer = $this->customers_model->get_row($appointment['id_users_customer']); } else { $service = NULL; $customer = NULL; } // If current appointment not synced yet, 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 } else { // Appointment is synced with google calendar. try { $google_event = $this->google_sync->get_event($provider, $appointment['id_google_calendar']); if ($google_event->status == 'cancelled') { throw new Exception('Event is cancelled, remove the record from Easy!Appointments.'); } // If gcal event is different from e!a appointment then update e!a record. $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); } } catch (Exception $exc) { // Appointment not found on gcal, delete from e!a. $this->appointments_model->delete($appointment['id']); $appointment['id_google_calendar'] = NULL; } } } // :: ADD GCAL EVENTS THAT ARE NOT PRESENT ON E!A $google_calendar = $provider['settings']['google_calendar']; $events = $this->google_sync->get_sync_events($google_calendar, $start, $end); foreach ($events->getItems() as $event) { $results = $this->appointments_model->get_batch(array('id_google_calendar' => $event->getId())); if (count($results) == 0) { // Record doesn't exist in E!A, so add the event now. $appointment = array('start_datetime' => date('Y-m-d H:i:s', strtotime($event->start->getDateTime())), 'end_datetime' => date('Y-m-d H:i:s', strtotime($event->end->getDateTime())), 'is_unavailable' => TRUE, 'notes' => $event->getSummary() . ' ' . $event->getDescription(), 'id_users_provider' => $provider_id, 'id_google_calendar' => $event->getId(), 'id_users_customer' => NULL, 'id_services' => NULL); $this->appointments_model->add($appointment); } } echo json_encode(AJAX_SUCCESS); } catch (Exception $exc) { echo json_encode(array('exceptions' => array(exceptionToJavaScript($exc)))); } }
/** * Select a specific google calendar for a provider. * * All the appointments will be synced with this particular calendar. * * @param numeric $_POST['provider_id'] Provider record id. * @param string $_POST['calendar_id'] Google calendar's id. */ public function ajax_select_google_calendar() { try { if ($this->privileges[PRIV_USERS]['edit'] == FALSE && $this->session->userdata('user_id') != $_POST['provider_id']) { throw new Exception('You do not have the required privileges for this task.'); } $this->load->model('providers_model'); $result = $this->providers_model->set_setting('google_calendar', $_POST['calendar_id'], $_POST['provider_id']); echo json_encode($result ? AJAX_SUCCESS : AJAX_FAILURE); } catch (Exception $exc) { echo json_encode(array('exceptions' => array(exceptionToJavaScript($exc)))); } }