diff --git a/README.md b/README.md index 891bba6f..5e9a0256 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ perform the following steps in order to install the system on your server: * Make sure that your server has Apache, PHP and MySQL installed. * Create a new database (or use an existing). * Copy the "easyappointments" source folder on your server. -* Edit the "configuration.php" file and set your server properties. +* Rename the "config-sample.php" file to "config.php" and set your server properties. * Open your browser on the Easy!Appointments URL and follow the installation guide. * That's it! You can now use Easy!Appointments at your will. diff --git a/rsc/db/sample-data.sql b/rsc/db/sample-data.sql index 14d517ff..57bc76c7 100644 --- a/rsc/db/sample-data.sql +++ b/rsc/db/sample-data.sql @@ -21,7 +21,8 @@ INSERT INTO `ea_settings` (`id`, `name`, `value`) VALUES (2, 'book_advance_timeout', '30'), (3, 'company_name', 'ABC Company'), (4, 'company_email', 'info@abc-company.ea'), -(5, 'company_link', 'http://www.abc-company.ea'); +(5, 'company_link', 'http://www.abc-company.ea'), +(6, 'google_analytics_code', ''); -- -- Dumping data for table `ea_roles` diff --git a/src/application/controllers/appointments.php b/src/application/controllers/appointments.php index 0772477b..3f475430 100755 --- a/src/application/controllers/appointments.php +++ b/src/application/controllers/appointments.php @@ -216,6 +216,40 @@ class Appointments extends CI_Controller { $this->load->view('appointments/message', $view); } + /** + * GET an specific appointment book and redirect to the success screen. + * + * @param int $appointment_id Contains the id of the appointment to retrieve. + */ + public function book_success($appointment_id) { + //if the appointment id doesn't exist or zero redirect to index + if(!$appointment_id){ + redirect('appointments'); + } + $this->load->model('appointments_model'); + $this->load->model('providers_model'); + $this->load->model('services_model'); + $this->load->model('settings_model'); + //retrieve the data needed in the view + $appointment = $this->appointments_model->get_row($appointment_id); + $provider = $this->providers_model->get_row($appointment['id_users_provider']); + $service = $this->services_model->get_row($appointment['id_services']); + $company_name = $this->settings_model->get_setting('company_name'); + //get the exceptions + $exceptions = $this->session->flashdata('book_success'); + // :: LOAD THE BOOK SUCCESS VIEW + $view = array( + 'appointment_data' => $appointment, + 'provider_data' => $provider, + 'service_data' => $service, + 'company_name' => $company_name, + ); + if($exceptions){ + $view['exceptions'] = $exceptions; + } + $this->load->view('appointments/book_success', $view); + } + /** * [AJAX] Get the available appointment hours for the given date. * @@ -316,223 +350,6 @@ class Appointments extends CI_Controller { } } - /** - * Check whether the provider is still available in the selected appointment date. - * - * It might be times where two or more customers select the same appointment date and time. - * This shouldn't be allowed to happen, so one of the two customers will eventually get the - * prefered date and the other one will have to choose for another date. Use this method - * just before the customer confirms the appointment details. If the selected date was taken - * in the mean time, the customer must be prompted to select another time for his appointment. - * - * @param int $_POST['id_users_provider'] The selected provider's record id. - * @param int $_POST['id_services'] The selected service's record id. - * @param string $_POST['start_datetime'] This is a mysql formed string. - * @return bool Returns whether the selected datetime is still available. - */ - public function ajax_check_datetime_availability() { - try { - $this->load->model('services_model'); - - $service_duration = $this->services_model->get_value('duration', $_POST['id_services']); - - $exclude_appointments = (isset($_POST['exclude_appointment_id'])) - ? array($_POST['exclude_appointment_id']) : array(); - - $available_periods = $this->get_provider_available_time_periods( - $_POST['id_users_provider'], $_POST['start_datetime'], $exclude_appointments); - - $is_still_available = FALSE; - - foreach($available_periods as $period) { - $appt_start = new DateTime($_POST['start_datetime']); - $appt_start = $appt_start->format('H:i'); - - $appt_end = new DateTime($_POST['start_datetime']); - $appt_end->add(new DateInterval('PT' . $service_duration . 'M')); - $appt_end = $appt_end->format('H:i'); - - $period_start = date('H:i', strtotime($period['start'])); - $period_end = date('H:i', strtotime($period['end'])); - - if ($period_start <= $appt_start && $period_end >= $appt_end) { - $is_still_available = TRUE; - break; - } - } - - echo json_encode($is_still_available); - - } catch(Exception $exc) { - echo json_encode(array( - 'exceptions' => array(exceptionToJavaScript($exc)) - )); - } - } - - /** - * Get an array containing the free time periods (start - end) of a selected date. - * - * This method is very important because there are many cases where the system needs to - * know when a provider is avaible for an appointment. This method will return an array - * that belongs to the selected date and contains values that have the start and the end - * time of an available time period. - * - * @param numeric $provider_id The provider's record id. - * @param string $selected_date The date to be checked (MySQL formatted string). - * @param array $exclude_appointments This array contains the ids of the appointments that - * will not be taken into consideration when the available time periods are calculated. - * @return array Returns an array with the available time periods of the provider. - */ - private function get_provider_available_time_periods($provider_id, $selected_date, - $exclude_appointments = array()) { - $this->load->model('appointments_model'); - $this->load->model('providers_model'); - - // Get the provider's working plan and reserved appointments. - $working_plan = json_decode($this->providers_model->get_setting('working_plan', $provider_id), true); - - $where_clause = array( - //'DATE(start_datetime)' => date('Y-m-d', strtotime($selected_date)), - 'id_users_provider' => $provider_id - ); - - $reserved_appointments = $this->appointments_model->get_batch($where_clause); - - // Sometimes it might be necessary to not take into account some appointment records - // in order to display what the providers' available time periods would be without them. - foreach ($exclude_appointments as $excluded_id) { - foreach ($reserved_appointments as $index => $reserved) { - if ($reserved['id'] == $excluded_id) { - unset($reserved_appointments[$index]); - } - } - } - - // Find the empty spaces on the plan. The first split between the plan is due to - // a break (if exist). After that every reserved appointment is considered to be - // a taken space in the plan. - $selected_date_working_plan = $working_plan[strtolower(date('l', strtotime($selected_date)))]; - $available_periods_with_breaks = array(); - - if (isset($selected_date_working_plan['breaks'])) { - if (count($selected_date_working_plan['breaks'])) { - foreach($selected_date_working_plan['breaks'] as $index=>$break) { - // Split the working plan to available time periods that do not - // contain the breaks in them. - $last_break_index = $index - 1; - - if (count($available_periods_with_breaks) === 0) { - $start_hour = $selected_date_working_plan['start']; - $end_hour = $break['start']; - } else { - $start_hour = $selected_date_working_plan['breaks'][$last_break_index]['end']; - $end_hour = $break['start']; - } - - $available_periods_with_breaks[] = array( - 'start' => $start_hour, - 'end' => $end_hour - ); - } - - // Add the period from the last break to the end of the day. - $available_periods_with_breaks[] = array( - 'start' => $selected_date_working_plan['breaks'][$index]['end'], - 'end' => $selected_date_working_plan['end'] - ); - } else { - $available_periods_with_breaks[] = array( - 'start' => $selected_date_working_plan['start'], - 'end' => $selected_date_working_plan['end'] - ); - } - } - - // Break the empty periods with the reserved appointments. - $available_periods_with_appointments = $available_periods_with_breaks; - - foreach($reserved_appointments as $appointment) { - foreach($available_periods_with_appointments as $index => &$period) { - - $a_start = strtotime($appointment['start_datetime']); - $a_end = strtotime($appointment['end_datetime']); - $p_start = strtotime($selected_date . ' ' . $period['start']); - $p_end = strtotime($selected_date . ' ' .$period['end']); - - if ($a_start <= $p_start && $a_end <= $p_end && $a_end <= $p_start) { - // The appointment does not belong in this time period, so we - // will not change anything. - } else if ($a_start <= $p_start && $a_end <= $p_end && $a_end >= $p_start) { - // The appointment starts before the period and finishes somewhere inside. - // We will need to break this period and leave the available part. - $period['start'] = date('H:i', $a_end); - - } else if ($a_start >= $p_start && $a_end <= $p_end) { - // The appointment is inside the time period, so we will split the period - // into two new others. - unset($available_periods_with_appointments[$index]); - $available_periods_with_appointments[] = array( - 'start' => date('H:i', $p_start), - 'end' => date('H:i', $a_start) - ); - $available_periods_with_appointments[] = array( - 'start' => date('H:i', $a_end), - 'end' => date('H:i', $p_end) - ); - - } else if ($a_start >= $p_start && $a_end >= $p_start && $a_start <= $p_end) { - // The appointment starts in the period and finishes out of it. We will - // need to remove the time that is taken from the appointment. - $period['end'] = date('H:i', $a_start); - - } else if ($a_start >= $p_start && $a_end >= $p_end && $a_start >= $p_end) { - // The appointment does not belong in the period so do not change anything. - } else if ($a_start <= $p_start && $a_end >= $p_end && $a_start <= $p_end) { - // The appointment is bigger than the period, so this period needs to be - // removed. - unset($available_periods_with_appointments[$index]); - } - } - } - - return array_values($available_periods_with_appointments); - } - - /** - * GET an specific appointment book and redirect to the success screen. - * - * @param int $appointment_id Contains the id of the appointment to retrieve. - */ - public function book_success($appointment_id) { - //if the appointment id doesn't exist or zero redirect to index - if(!$appointment_id){ - redirect('appointments'); - } - $this->load->model('appointments_model'); - $this->load->model('providers_model'); - $this->load->model('services_model'); - $this->load->model('settings_model'); - //retrieve the data needed in the view - $appointment = $this->appointments_model->get_row($appointment_id); - $provider = $this->providers_model->get_row($appointment['id_users_provider']); - $service = $this->services_model->get_row($appointment['id_services']); - $company_name = $this->settings_model->get_setting('company_name'); - //get the exceptions - $exceptions = $this->session->flashdata('book_success'); - // :: LOAD THE BOOK SUCCESS VIEW - $view = array( - 'appointment_data' => $appointment, - 'provider_data' => $provider, - 'service_data' => $service, - 'company_name' => $company_name, - ); - if($exceptions){ - $view['exceptions'] = $exceptions; - } - $this->load->view('appointments/book_success', $view); - } - /** * [AJAX] Register the appointment to the database. */ @@ -546,6 +363,11 @@ class Appointments extends CI_Controller { throw new Exception($this->lang->line('captcha_is_wrong')); } + // Check appointment availability. + if (!$this->check_datetime_availability()) { + throw new Exception($this->lang->line('requested_hour_is_unavailable')); + } + $appointment = $post_data['appointment']; $customer = $post_data['customer']; @@ -660,6 +482,183 @@ class Appointments extends CI_Controller { )); } } + + /** + * Check whether the provider is still available in the selected appointment date. + * + * It might be times where two or more customers select the same appointment date and time. + * This shouldn't be allowed to happen, so one of the two customers will eventually get the + * prefered date and the other one will have to choose for another date. Use this method + * just before the customer confirms the appointment details. If the selected date was taken + * in the mean time, the customer must be prompted to select another time for his appointment. + * + * @return bool Returns whether the selected datetime is still available. + */ + private function check_datetime_availability() { + $this->load->model('services_model'); + + $appointment = $_POST['post_data']['appointment']; + + $service_duration = $this->services_model->get_value('duration', $appointment['id_services']); + + $exclude_appointments = (isset($appointment['appointment_id'])) + ? array($appointment['appointment_id']) : array(); + + $available_periods = $this->get_provider_available_time_periods( + $appointment['id_users_provider'], date('Y-m-d', strtotime($appointment['start_datetime'])), + $exclude_appointments); + + $is_still_available = FALSE; + + foreach($available_periods as $period) { + $appt_start = new DateTime($appointment['start_datetime']); + $appt_start = $appt_start->format('H:i'); + + $appt_end = new DateTime($appointment['start_datetime']); + $appt_end->add(new DateInterval('PT' . $service_duration . 'M')); + $appt_end = $appt_end->format('H:i'); + + $period_start = date('H:i', strtotime($period['start'])); + $period_end = date('H:i', strtotime($period['end'])); + + if ($period_start <= $appt_start && $period_end >= $appt_end) { + $is_still_available = TRUE; + break; + } + } + + return $is_still_available; + } + + /** + * Get an array containing the free time periods (start - end) of a selected date. + * + * This method is very important because there are many cases where the system needs to + * know when a provider is avaible for an appointment. This method will return an array + * that belongs to the selected date and contains values that have the start and the end + * time of an available time period. + * + * @param numeric $provider_id The provider's record id. + * @param string $selected_date The date to be checked (MySQL formatted string). + * @param array $exclude_appointments This array contains the ids of the appointments that + * will not be taken into consideration when the available time periods are calculated. + * @return array Returns an array with the available time periods of the provider. + */ + private function get_provider_available_time_periods($provider_id, $selected_date, + $exclude_appointments = array()) { + $this->load->model('appointments_model'); + $this->load->model('providers_model'); + + // Get the provider's working plan and reserved appointments. + $working_plan = json_decode($this->providers_model + ->get_setting('working_plan', $provider_id), true); + + $where_clause = array( + 'DATE(start_datetime)' => date('Y-m-d', strtotime($selected_date)), + 'id_users_provider' => $provider_id + ); + + $reserved_appointments = $this->appointments_model->get_batch($where_clause); + + // Sometimes it might be necessary to not take into account some appointment records + // in order to display what the providers' available time periods would be without them. + foreach ($exclude_appointments as $excluded_id) { + foreach ($reserved_appointments as $index => $reserved) { + if ($reserved['id'] == $excluded_id) { + unset($reserved_appointments[$index]); + } + } + } + + // Find the empty spaces on the plan. The first split between the plan is due to + // a break (if exist). After that every reserved appointment is considered to be + // a taken space in the plan. + $selected_date_working_plan = $working_plan[strtolower(date('l', strtotime($selected_date)))]; + $available_periods_with_breaks = array(); + + if (isset($selected_date_working_plan['breaks'])) { + if (count($selected_date_working_plan['breaks'])) { + foreach($selected_date_working_plan['breaks'] as $index=>$break) { + // Split the working plan to available time periods that do not + // contain the breaks in them. + $last_break_index = $index - 1; + + if (count($available_periods_with_breaks) === 0) { + $start_hour = $selected_date_working_plan['start']; + $end_hour = $break['start']; + } else { + $start_hour = $selected_date_working_plan['breaks'][$last_break_index]['end']; + $end_hour = $break['start']; + } + + $available_periods_with_breaks[] = array( + 'start' => $start_hour, + 'end' => $end_hour + ); + } + + // Add the period from the last break to the end of the day. + $available_periods_with_breaks[] = array( + 'start' => $selected_date_working_plan['breaks'][$index]['end'], + 'end' => $selected_date_working_plan['end'] + ); + } else { + $available_periods_with_breaks[] = array( + 'start' => $selected_date_working_plan['start'], + 'end' => $selected_date_working_plan['end'] + ); + } + } + + // Break the empty periods with the reserved appointments. + $available_periods_with_appointments = $available_periods_with_breaks; + + foreach($reserved_appointments as $appointment) { + foreach($available_periods_with_appointments as $index => &$period) { + + $a_start = strtotime($appointment['start_datetime']); + $a_end = strtotime($appointment['end_datetime']); + $p_start = strtotime($selected_date . ' ' . $period['start']); + $p_end = strtotime($selected_date . ' ' .$period['end']); + + if ($a_start <= $p_start && $a_end <= $p_end && $a_end <= $p_start) { + // The appointment does not belong in this time period, so we + // will not change anything. + } else if ($a_start <= $p_start && $a_end <= $p_end && $a_end >= $p_start) { + // The appointment starts before the period and finishes somewhere inside. + // We will need to break this period and leave the available part. + $period['start'] = date('H:i', $a_end); + + } else if ($a_start >= $p_start && $a_end <= $p_end) { + // The appointment is inside the time period, so we will split the period + // into two new others. + unset($available_periods_with_appointments[$index]); + $available_periods_with_appointments[] = array( + 'start' => date('H:i', $p_start), + 'end' => date('H:i', $a_start) + ); + $available_periods_with_appointments[] = array( + 'start' => date('H:i', $a_end), + 'end' => date('H:i', $p_end) + ); + + } else if ($a_start >= $p_start && $a_end >= $p_start && $a_start <= $p_end) { + // The appointment starts in the period and finishes out of it. We will + // need to remove the time that is taken from the appointment. + $period['end'] = date('H:i', $a_start); + + } else if ($a_start >= $p_start && $a_end >= $p_end && $a_start >= $p_end) { + // The appointment does not belong in the period so do not change anything. + } else if ($a_start <= $p_start && $a_end >= $p_end && $a_start <= $p_end) { + // The appointment is bigger than the period, so this period needs to be + // removed. + unset($available_periods_with_appointments[$index]); + } + } + } + + return array_values($available_periods_with_appointments); + } } /* End of file appointments.php */ diff --git a/src/application/controllers/backend_api.php b/src/application/controllers/backend_api.php index 81da191f..ad7268a1 100644 --- a/src/application/controllers/backend_api.php +++ b/src/application/controllers/backend_api.php @@ -2,29 +2,29 @@ /* ---------------------------------------------------------------------------- * Easy!Appointments - Open Source Web Scheduler - * + * * @package EasyAppointments * @author A.Tselegidis * @copyright Copyright (c) 2013 - 2015, Alex Tselegidis - * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 + * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 * @link http://easyappointments.org * @since v1.0.0 * ---------------------------------------------------------------------------- */ /** - * Backend API Controller + * Backend API Controller * * Contains all the backend AJAX callbacks. - * + * * @package Controllers */ class Backend_api extends CI_Controller { private $privileges; - + public function __construct() { parent::__construct(); - - // All the methods in this class must be accessible through a POST request. + + // All the methods in this class must be accessible through a POST request. if (strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST') { $this->security->csrf_show_error(); } @@ -32,8 +32,8 @@ class Backend_api extends CI_Controller { $this->load->library('session'); $this->load->model('roles_model'); $this->privileges = $this->roles_model->get_privileges($this->session->userdata('role_slug')); - - // Set user's selected language. + + // Set user's selected language. if ($this->session->userdata('language')) { $this->config->set_item('language', $this->session->userdata('language')); $this->lang->load('translations', $this->session->userdata('language')); @@ -41,14 +41,14 @@ class Backend_api extends CI_Controller { $this->lang->load('translations', $this->config->item('language')); // default } } - + /** * [AJAX] Get the registered appointments for the given date period and record. - * - * This method returns the database appointments and unavailable periods for the - * user selected date period and record type (provider or service). - * - * @param {numeric} $_POST['record_id'] Selected record id. + * + * This method returns the database appointments and unavailable periods for the + * user selected date period and record type (provider or service). + * + * @param {numeric} $_POST['record_id'] Selected record id. * @param {string} $_POST['filter_type'] Could be either FILTER_TYPE_PROVIDER or FILTER_TYPE_SERVICE. * @param {string} $_POST['start_date'] The user selected start date. * @param {string} $_POST['end_date'] The user selected end date. @@ -58,18 +58,23 @@ class Backend_api extends CI_Controller { if ($this->privileges[PRIV_APPOINTMENTS]['view'] == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + + if (!isset($_POST['filter_type'])) { + echo json_encode(array( 'appointments' => array())); + return; + } + $this->load->model('appointments_model'); $this->load->model('providers_model'); $this->load->model('services_model'); $this->load->model('customers_model'); - + if ($_POST['filter_type'] == FILTER_TYPE_PROVIDER) { $where_id = 'id_users_provider'; - } else { + } else { $where_id = 'id_services'; - } - + } + // Get appointments $where_clause = array( $where_id => $_POST['record_id'], @@ -77,7 +82,7 @@ class Backend_api extends CI_Controller { //'end_datetime <=' => $_POST['end_date'], 'is_unavailable' => FALSE ); - + $response['appointments'] = $this->appointments_model->get_batch($where_clause); foreach($response['appointments'] as &$appointment) { @@ -85,7 +90,7 @@ class Backend_api extends CI_Controller { $appointment['service'] = $this->services_model->get_row($appointment['id_services']); $appointment['customer'] = $this->customers_model->get_row($appointment['id_users_customer']); } - + // Get unavailable periods (only for provider). if ($_POST['filter_type'] == FILTER_TYPE_PROVIDER) { $where_clause = array( @@ -94,26 +99,26 @@ class Backend_api extends CI_Controller { //'end_datetime <=' => $_POST['end_date'], 'is_unavailable' => TRUE ); - + $response['unavailables'] = $this->appointments_model->get_batch($where_clause); } - + echo json_encode($response); - + } catch(Exception $exc) { echo json_encode(array( 'exceptions' => array(exceptionToJavaScript($exc)) )); } } - + /** * [AJAX] Save appointment changes that are made from the backend calendar * page. - * - * @param array $_POST['appointment_data'] (OPTIONAL) Array with the + * + * @param array $_POST['appointment_data'] (OPTIONAL) Array with the * appointment data. - * @param array $_POST['customer_data'] (OPTIONAL) Array with the customer + * @param array $_POST['customer_data'] (OPTIONAL) Array with the customer * data. */ public function ajax_save_appointment() { @@ -123,122 +128,122 @@ class Backend_api extends CI_Controller { $this->load->model('services_model'); $this->load->model('customers_model'); $this->load->model('settings_model'); - + // :: SAVE CUSTOMER CHANGES TO DATABASE if (isset($_POST['customer_data'])) { $customer = json_decode(stripcslashes($_POST['customer_data']), true); - - $REQUIRED_PRIV = (!isset($customer['id'])) - ? $this->privileges[PRIV_CUSTOMERS]['add'] + + $REQUIRED_PRIV = (!isset($customer['id'])) + ? $this->privileges[PRIV_CUSTOMERS]['add'] : $this->privileges[PRIV_CUSTOMERS]['edit']; if ($REQUIRED_PRIV == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $customer['id'] = $this->customers_model->add($customer); } - + // :: SAVE APPOINTMENT CHANGES TO DATABASE if (isset($_POST['appointment_data'])) { $appointment = json_decode(stripcslashes($_POST['appointment_data']), true); - - $REQUIRED_PRIV = (!isset($appointment['id'])) - ? $this->privileges[PRIV_APPOINTMENTS]['add'] + + $REQUIRED_PRIV = (!isset($appointment['id'])) + ? $this->privileges[PRIV_APPOINTMENTS]['add'] : $this->privileges[PRIV_APPOINTMENTS]['edit']; if ($REQUIRED_PRIV == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $manage_mode = isset($appointment['id']); - // If the appointment does not contain the customer record id, then it + // If the appointment does not contain the customer record id, then it // means that is is going to be inserted. Get the customer's record id. if (!isset($appointment['id_users_customer'])) { $appointment['id_users_customer'] = $customer['id']; } - + $appointment['id'] = $this->appointments_model->add($appointment); } - + $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', + $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', + $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, + $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, + $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_you_for_appointment'); - $customer_link = $this->config->item('base_url') . '/index.php/appointments/index/' + $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/' + $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/' + $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/' + $provider_link = $this->config->item('base_url') . '/index.php/backend/index/' . $appointment['hash']; } - + $this->notifications->send_appointment_details($appointment, $provider, - $service, $customer, $company_settings, $customer_title, + $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, + $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 { @@ -252,27 +257,27 @@ class Backend_api extends CI_Controller { )); } } - + /** * [AJAX] Delete appointment from the database. - * - * This method deletes an existing appointment from the database. Once this + * + * This method deletes an existing appointment from the database. Once this * action is finished it cannot be undone. Notification emails are send to both - * provider and customer and the delete action is executed to the Google Calendar + * provider and customer and the delete action is executed to the Google Calendar * account of the provider, if the "google_sync" setting is enabled. - * + * * @param int $_POST['appointment_id'] The appointment id to be deleted. */ - public function ajax_delete_appointment() { + public function ajax_delete_appointment() { try { if ($this->privileges[PRIV_APPOINTMENTS]['delete'] == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + if (!isset($_POST['appointment_id'])) { throw new Exception('No appointment id provided.'); } - + // :: STORE APPOINTMENT DATA FOR LATER USE IN THIS METHOD $this->load->model('appointments_model'); $this->load->model('providers_model'); @@ -290,10 +295,10 @@ class Backend_api extends CI_Controller { 'company_email' => $this->settings_model->get_setting('company_email'), 'company_link' => $this->settings_model->get_setting('company_link') ); - + // :: DELETE APPOINTMENT RECORD FROM DATABASE $this->appointments_model->delete($_POST['appointment_id']); - + // :: SYNC DELETE WITH GOOGLE CALENDAR if ($appointment['id_google_calendar'] != NULL) { try { @@ -305,32 +310,32 @@ class Backend_api extends CI_Controller { $this->load->library('Google_Sync'); $this->google_sync->refresh_token($google_token->refresh_token); $this->google_sync->delete_appointment($provider, $appointment['id_google_calendar']); - } + } } catch(Exception $exc) { $warnings[] = exceptionToJavaScript($exc); } } - + // :: SEND NOTIFICATION EMAILS TO PROVIDER AND CUSTOMER try { $this->load->library('Notifications'); - + $send_provider = $this->providers_model ->get_setting('notifications', $provider['id']); - + if ($send_provider == TRUE) { - $this->notifications->send_delete_appointment($appointment, $provider, + $this->notifications->send_delete_appointment($appointment, $provider, $service, $customer, $company_settings, $provider['email'], $_POST['delete_reason']); } - + $this->notifications->send_delete_appointment($appointment, $provider, $service, $customer, $company_settings, $customer['email'], $_POST['delete_reason']); } catch(Exception $exc) { $warnings[] = exceptionToJavaScript($exc); } - + // :: SEND RESPONSE TO CLIENT BROWSER if (!isset($warnings)) { echo json_encode(AJAX_SUCCESS); // Everything executed successfully. @@ -345,45 +350,45 @@ class Backend_api extends CI_Controller { )); } } - + /** * [AJAX] Disable a providers sync setting. - * - * This method deletes the "google_sync" and "google_token" settings from the - * database. After that the provider's appointments will be no longer synced + * + * This method deletes the "google_sync" and "google_token" settings from the + * database. After that the provider's appointments will be no longer synced * with google calendar. - * + * * @param string $_POST['provider_id'] The selected provider record id. */ public function ajax_disable_provider_sync() { - try { - if (!isset($_POST['provider_id'])) + try { + if (!isset($_POST['provider_id'])) throw new Exception('Provider id not specified.'); - - + + 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'); $this->load->model('appointments_model'); $this->providers_model->set_setting('google_sync', FALSE, $_POST['provider_id']); $this->providers_model->set_setting('google_token', NULL, $_POST['provider_id']); $this->appointments_model->clear_google_sync_ids($_POST['provider_id']); - + echo json_encode(AJAX_SUCCESS); - + } catch(Exception $exc) { echo json_encode(array( 'exceptions' => array(exceptionToJavaScript($exc)) )); } } - + /** * [AJAX] Filter the customer records with the given key string. - * + * * @param string $_POST['key'] The filter key string * @return array Returns the search results. */ @@ -392,87 +397,87 @@ class Backend_api extends CI_Controller { if ($this->privileges[PRIV_CUSTOMERS]['view'] == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $this->load->model('appointments_model'); $this->load->model('services_model'); $this->load->model('providers_model'); $this->load->model('customers_model'); - - $key = $this->db->escape_str($_POST['key']); - - $where_clause = - '(first_name LIKE "%' . $key . '%" OR ' . - 'last_name LIKE "%' . $key . '%" OR ' . - 'email LIKE "%' . $key . '%" OR ' . + + $key = $this->db->escape_str($_POST['key']); + + $where_clause = + '(first_name LIKE "%' . $key . '%" OR ' . + 'last_name LIKE "%' . $key . '%" OR ' . + 'email LIKE "%' . $key . '%" OR ' . 'phone_number LIKE "%' . $key . '%" OR ' . 'address LIKE "%' . $key . '%" OR ' . 'city LIKE "%' . $key . '%" OR ' . - 'zip_code LIKE "%' . $key . '%")'; - + 'zip_code LIKE "%' . $key . '%")'; + $customers = $this->customers_model->get_batch($where_clause); - + foreach($customers as &$customer) { $appointments = $this->appointments_model ->get_batch(array('id_users_customer' => $customer['id'])); - + foreach($appointments as &$appointment) { $appointment['service'] = $this->services_model ->get_row($appointment['id_services']); $appointment['provider'] = $this->providers_model ->get_row($appointment['id_users_provider']); } - + $customer['appointments'] = $appointments; } - + echo json_encode($customers); - + } catch(Exception $exc) { echo json_encode(array( 'exceptions' => array(exceptionToJavaScript($exc)) )); } } - + /** * [AJAX] Insert of update unavailable time period to database. - * - * @param array $_POST['unavailable'] JSON encoded array that contains the unavailable + * + * @param array $_POST['unavailable'] JSON encoded array that contains the unavailable * period data. */ public function ajax_save_unavailable() { try { // Check privileges $unavailable = json_decode($_POST['unavailable'], true); - - $REQUIRED_PRIV = (!isset($unavailable['id'])) - ? $this->privileges[PRIV_APPOINTMENTS]['add'] + + $REQUIRED_PRIV = (!isset($unavailable['id'])) + ? $this->privileges[PRIV_APPOINTMENTS]['add'] : $this->privileges[PRIV_APPOINTMENTS]['edit']; if ($REQUIRED_PRIV == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $this->load->model('appointments_model'); $this->load->model('providers_model'); - + $provider = $this->providers_model->get_row($unavailable['id_users_provider']); - + // Add appointment - $unavailable['id'] = $this->appointments_model->add_unavailable($unavailable); + $unavailable['id'] = $this->appointments_model->add_unavailable($unavailable); $unavailable = $this->appointments_model->get_row($unavailable['id']); // fetch all inserted data - + // Google Sync try { - $google_sync = $this->providers_model->get_setting('google_sync', + $google_sync = $this->providers_model->get_setting('google_sync', $unavailable['id_users_provider']); - + if ($google_sync) { $google_token = json_decode($this->providers_model->get_setting('google_token', $unavailable['id_users_provider'])); - + $this->load->library('google_sync'); $this->google_sync->refresh_token($google_token->refresh_token); - + if ($unavailable['id_google_calendar'] == NULL) { $google_event = $this->google_sync->add_unavailable($provider, $unavailable); $unavailable['id_google_calendar'] = $google_event->id; @@ -484,7 +489,7 @@ class Backend_api extends CI_Controller { } catch(Exception $exc) { $warnings[] = $exc; } - + if (isset($warnings)) { echo json_encode(array( 'warnings' => $warnings @@ -492,17 +497,17 @@ class Backend_api extends CI_Controller { } else { echo json_encode(AJAX_SUCCESS); } - - } catch(Exception $exc) { + + } catch(Exception $exc) { echo json_encode(array( 'exceptions' => array(exceptionToJavaScript($exc)) )); } } - + /** * [AJAX] Delete an unavailable time period from database. - * + * * @param numeric $_POST['unavailable_id'] Record id to be deleted. */ public function ajax_delete_unavailable() { @@ -510,16 +515,16 @@ class Backend_api extends CI_Controller { if ($this->privileges[PRIV_APPOINTMENTS]['delete'] == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $this->load->model('appointments_model'); $this->load->model('providers_model'); - + $unavailable = $this->appointments_model->get_row($_POST['unavailable_id']); $provider = $this->providers_model->get_row($unavailable['id_users_provider']); - - // Delete unavailable + + // Delete unavailable $this->appointments_model->delete_unavailable($unavailable['id']); - + // Google Sync try { $google_sync = $this->providers_model->get_setting('google_sync', $provider['id']); @@ -532,7 +537,7 @@ class Backend_api extends CI_Controller { } catch(Exception $exc) { $warnings[] = $exc; } - + if (isset($warnings)) { echo json_encode(array( 'warnings' => $warnings @@ -540,31 +545,31 @@ class Backend_api extends CI_Controller { } else { echo json_encode(AJAX_SUCCESS); } - + } catch(Exception $exc) { echo json_encode(array( 'exceptions' => array(exceptionToJavaScript($exc)) )); } } - + /** * [AJAX] Save (insert or update) a customer record. - * + * * @param array $_POST['customer'] JSON encoded array that contains the customer's data. */ public function ajax_save_customer() { try { $this->load->model('customers_model'); $customer = json_decode($_POST['customer'], true); - - $REQUIRED_PRIV = (!isset($customer['id'])) - ? $this->privileges[PRIV_CUSTOMERS]['add'] + + $REQUIRED_PRIV = (!isset($customer['id'])) + ? $this->privileges[PRIV_CUSTOMERS]['add'] : $this->privileges[PRIV_CUSTOMERS]['edit']; if ($REQUIRED_PRIV == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $customer_id = $this->customers_model->add($customer); echo json_encode(array( 'status' => AJAX_SUCCESS, @@ -576,10 +581,10 @@ class Backend_api extends CI_Controller { )); } } - + /** * [AJAX] Delete customer from database. - * + * * @param numeric $_POST['customer_id'] Customer record id to be deleted. */ public function ajax_delete_customer() { @@ -587,7 +592,7 @@ class Backend_api extends CI_Controller { if ($this->privileges[PRIV_CUSTOMERS]['delete'] == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $this->load->model('customers_model'); $this->customers_model->delete($_POST['customer_id']); echo json_encode(AJAX_SUCCESS); @@ -597,24 +602,24 @@ class Backend_api extends CI_Controller { )); } } - + /** * [AJAX] Save (insert or update) service record. - * + * * @param array $_POST['service'] Contains the service data (json encoded). */ public function ajax_save_service() { try { $this->load->model('services_model'); $service = json_decode($_POST['service'], true); - - $REQUIRED_PRIV = (!isset($service['id'])) - ? $this->privileges[PRIV_SERVICES]['add'] + + $REQUIRED_PRIV = (!isset($service['id'])) + ? $this->privileges[PRIV_SERVICES]['add'] : $this->privileges[PRIV_SERVICES]['edit']; if ($REQUIRED_PRIV == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $service_id =$this->services_model->add($service); echo json_encode(array( 'status' => AJAX_SUCCESS, @@ -626,10 +631,10 @@ class Backend_api extends CI_Controller { )); } } - + /** * [AJAX] Delete service record from database. - * + * * @param numeric $_POST['service_id'] Record id to be deleted. */ public function ajax_delete_service() { @@ -637,7 +642,7 @@ class Backend_api extends CI_Controller { if ($this->privileges[PRIV_SERVICES]['delete'] == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $this->load->model('services_model'); $result = $this->services_model->delete($_POST['service_id']); echo ($result) ? json_encode(AJAX_SUCCESS) : json_encode(AJAX_FAILURE); @@ -647,10 +652,10 @@ class Backend_api extends CI_Controller { )); } } - + /** * [AJAX] Filter service records by given key string. - * + * * @param string $_POST['key'] Key string used to filter the records. * @return array Returns a json encoded array back to client. */ @@ -659,11 +664,11 @@ class Backend_api extends CI_Controller { if ($this->privileges[PRIV_SERVICES]['view'] == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $this->load->model('services_model'); - $key = $this->db->escape_str($_POST['key']); - $where = - '(name LIKE "%' . $key . '%" OR duration LIKE "%' . $key . '%" OR ' . + $key = $this->db->escape_str($_POST['key']); + $where = + '(name LIKE "%' . $key . '%" OR duration LIKE "%' . $key . '%" OR ' . 'price LIKE "%' . $key . '%" OR currency LIKE "%' . $key . '%" OR ' . 'description LIKE "%' . $key . '%")'; $services = $this->services_model->get_batch($where); @@ -674,10 +679,10 @@ class Backend_api extends CI_Controller { )); } } - + /** * [AJAX] Save (insert or update) category record. - * + * * @param array $_POST['category'] Json encoded array with the category data. If an id * value is provided then the category is going to be udpated instead of inserted. */ @@ -685,14 +690,14 @@ class Backend_api extends CI_Controller { try { $this->load->model('services_model'); $category = json_decode($_POST['category'], true); - - $REQUIRED_PRIV = (!isset($category['id'])) - ? $this->privileges[PRIV_SERVICES]['add'] + + $REQUIRED_PRIV = (!isset($category['id'])) + ? $this->privileges[PRIV_SERVICES]['add'] : $this->privileges[PRIV_SERVICES]['edit']; if ($REQUIRED_PRIV == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $category_id = $this->services_model->add_category($category); echo json_encode(array( 'status' => AJAX_SUCCESS, @@ -704,10 +709,10 @@ class Backend_api extends CI_Controller { )); } } - + /** * [AJAX] Delete category record from database. - * + * * @param numeric $_POST['category_id'] Record id to be deleted. */ public function ajax_delete_service_category() { @@ -715,7 +720,7 @@ class Backend_api extends CI_Controller { if ($this->privileges[PRIV_SERVICES]['delete'] == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $this->load->model('services_model'); $result = $this->services_model->delete_category($_POST['category_id']); echo ($result) ? json_encode(AJAX_SUCCESS) : json_encode(AJAX_FAILURE); @@ -725,10 +730,10 @@ class Backend_api extends CI_Controller { )); } } - + /** * [AJAX] Filter services categories with key string. - * + * * @param string $_POST['key'] The key string used to filter the records. * @return array Returns a json encoded array back to client with the category records. */ @@ -737,9 +742,9 @@ class Backend_api extends CI_Controller { if ($this->privileges[PRIV_SERVICES]['view'] == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $this->load->model('services_model'); - $key = $this->db->escape_str($_POST['key']); + $key = $this->db->escape_str($_POST['key']); $where = '(name LIKE "%' . $key . '%" OR description LIKE "%' . $key . '%")'; $categories = $this->services_model->get_all_categories($where); echo json_encode($categories); @@ -749,10 +754,10 @@ class Backend_api extends CI_Controller { )); } } - + /** * [AJAX] Filter admin records with string key. - * + * * @param string $_POST['key'] The key string used to filter the records. * @return array Returns a json encoded array back to client with the admin records. */ @@ -761,12 +766,12 @@ class Backend_api extends CI_Controller { if ($this->privileges[PRIV_USERS]['view'] == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $this->load->model('admins_model'); - $key = $this->db->escape_str($_POST['key']); - $where = - '(first_name LIKE "%' . $key . '%" OR last_name LIKE "%' . $key . '%" ' . - 'OR email LIKE "%' . $key . '%" OR mobile_number LIKE "%' . $key . '%" ' . + $key = $this->db->escape_str($_POST['key']); + $where = + '(first_name LIKE "%' . $key . '%" OR last_name LIKE "%' . $key . '%" ' . + 'OR email LIKE "%' . $key . '%" OR mobile_number LIKE "%' . $key . '%" ' . 'OR phone_number LIKE "%' . $key . '%" OR address LIKE "%' . $key . '%" ' . 'OR city LIKE "%' . $key . '%" OR state LIKE "%' . $key . '%" ' . 'OR zip_code LIKE "%' . $key . '%" OR notes LIKE "%' . $key . '%")'; @@ -778,34 +783,34 @@ class Backend_api extends CI_Controller { )); } } - + /** * [AJAX] Save (insert or update) admin record into database. - * + * * @param array $_POST['admin'] A json encoded array that contains the admin data. If an 'id' * value is provided then the record is going to be updated. - * @return array Returns an array with the operation status and the record id that was + * @return array Returns an array with the operation status and the record id that was * saved into the database. */ public function ajax_save_admin() { try { $this->load->model('admins_model'); $admin = json_decode($_POST['admin'], true); - - $REQUIRED_PRIV = (!isset($admin['id'])) - ? $this->privileges[PRIV_USERS]['add'] + + $REQUIRED_PRIV = (!isset($admin['id'])) + ? $this->privileges[PRIV_USERS]['add'] : $this->privileges[PRIV_USERS]['edit']; if ($REQUIRED_PRIV == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $admin_id = $this->admins_model->add($admin); - + $response = array( 'status' => AJAX_SUCCESS, - 'id' => $admin_id + 'id' => $admin_id ); - + echo json_encode($response); } catch(Exception $exc) { echo json_encode(array( @@ -813,10 +818,10 @@ class Backend_api extends CI_Controller { )); } } - + /** * [AJAX] Delete an admin record from the database. - * + * * @param numeric $_POST['admin_id'] The id of the record to be deleted. * @return string Returns the operation result constant (AJAX_SUCESS or AJAX_FAILURE). */ @@ -825,7 +830,7 @@ class Backend_api extends CI_Controller { if ($this->privileges[PRIV_USERS]['delete'] == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $this->load->model('admins_model'); $result = $this->admins_model->delete($_POST['admin_id']); echo ($result) ? json_encode(AJAX_SUCCESS) : json_encode(AJAX_FAILURE); @@ -835,10 +840,10 @@ class Backend_api extends CI_Controller { )); } } - + /** * [AJAX] Filter provider records with string key. - * + * * @param string $_POST['key'] The key string used to filter the records. * @return array Returns a json encoded array back to client with the provider records. */ @@ -847,12 +852,12 @@ class Backend_api extends CI_Controller { if ($this->privileges[PRIV_USERS]['view'] == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $this->load->model('providers_model'); - $key = $this->db->escape_str($_POST['key']); - $where = - '(first_name LIKE "%' . $key . '%" OR last_name LIKE "%' . $key . '%" ' . - 'OR email LIKE "%' . $key . '%" OR mobile_number LIKE "%' . $key . '%" ' . + $key = $this->db->escape_str($_POST['key']); + $where = + '(first_name LIKE "%' . $key . '%" OR last_name LIKE "%' . $key . '%" ' . + 'OR email LIKE "%' . $key . '%" OR mobile_number LIKE "%' . $key . '%" ' . 'OR phone_number LIKE "%' . $key . '%" OR address LIKE "%' . $key . '%" ' . 'OR city LIKE "%' . $key . '%" OR state LIKE "%' . $key . '%" ' . 'OR zip_code LIKE "%' . $key . '%" OR notes LIKE "%' . $key . '%")'; @@ -864,50 +869,50 @@ class Backend_api extends CI_Controller { )); } } - + /** * [AJAX] Save (insert or update) a provider record into database. - * + * * @param array $_POST['provider'] A json encoded array that contains the provider data. If an 'id' * value is provided then the record is going to be updated. - * @return string Returns the success contant 'AJAX_SUCCESS' so javascript knows that + * @return string Returns the success contant 'AJAX_SUCCESS' so javascript knows that * everything completed successfully. */ public function ajax_save_provider() { try { $this->load->model('providers_model'); $provider = json_decode($_POST['provider'], true); - - $REQUIRED_PRIV = (!isset($provider['id'])) - ? $this->privileges[PRIV_USERS]['add'] + + $REQUIRED_PRIV = (!isset($provider['id'])) + ? $this->privileges[PRIV_USERS]['add'] : $this->privileges[PRIV_USERS]['edit']; if ($REQUIRED_PRIV == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + if (!isset($provider['settings']['working_plan'])) { $this->load->model('settings_model'); $provider['settings']['working_plan'] = $this->settings_model ->get_setting('company_working_plan'); } - + $provider_id = $this->providers_model->add($provider); - + echo json_encode(array( 'status' => AJAX_SUCCESS, 'id' => $provider_id )); - + } catch(Exception $exc) { echo json_encode(array( 'exceptions' => array(exceptionToJavaScript($exc)) )); } } - + /** * [AJAX] Delete a provider record from the database. - * + * * @param numeric $_POST['provider_id'] The id of the record to be deleted. * @return string Returns the operation result constant (AJAX_SUCESS or AJAX_FAILURE). */ @@ -916,7 +921,7 @@ class Backend_api extends CI_Controller { if ($this->privileges[PRIV_USERS]['delete'] == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $this->load->model('providers_model'); $result = $this->providers_model->delete($_POST['provider_id']); echo ($result) ? json_encode(AJAX_SUCCESS) : json_encode(AJAX_FAILURE); @@ -926,10 +931,10 @@ class Backend_api extends CI_Controller { )); } } - + /** * [AJAX] Filter secretary records with string key. - * + * * @param string $_POST['key'] The key string used to filter the records. * @return array Returns a json encoded array back to client with the secretary records. */ @@ -938,12 +943,12 @@ class Backend_api extends CI_Controller { if ($this->privileges[PRIV_USERS]['view'] == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $this->load->model('secretaries_model'); - $key = $this->db->escape_str($_POST['key']); - $where = - '(first_name LIKE "%' . $key . '%" OR last_name LIKE "%' . $key . '%" ' . - 'OR email LIKE "%' . $key . '%" OR mobile_number LIKE "%' . $key . '%" ' . + $key = $this->db->escape_str($_POST['key']); + $where = + '(first_name LIKE "%' . $key . '%" OR last_name LIKE "%' . $key . '%" ' . + 'OR email LIKE "%' . $key . '%" OR mobile_number LIKE "%' . $key . '%" ' . 'OR phone_number LIKE "%' . $key . '%" OR address LIKE "%' . $key . '%" ' . 'OR city LIKE "%' . $key . '%" OR state LIKE "%' . $key . '%" ' . 'OR zip_code LIKE "%' . $key . '%" OR notes LIKE "%' . $key . '%")'; @@ -955,29 +960,29 @@ class Backend_api extends CI_Controller { )); } } - + /** * [AJAX] Save (insert or update) a secretary record into database. - * - * @param array $_POST['secretary'] A json encoded array that contains the secretary data. + * + * @param array $_POST['secretary'] A json encoded array that contains the secretary data. * If an 'id' value is provided then the record is going to be updated. - * @return string Returns the success contant 'AJAX_SUCCESS' so javascript knows that + * @return string Returns the success contant 'AJAX_SUCCESS' so javascript knows that * everything completed successfully. */ public function ajax_save_secretary() { try { $this->load->model('secretaries_model'); $secretary = json_decode($_POST['secretary'], true); - - $REQUIRED_PRIV = (!isset($secretary['id'])) + + $REQUIRED_PRIV = (!isset($secretary['id'])) ? $this->privileges[PRIV_USERS]['add'] : $this->privileges[PRIV_USERS]['edit']; if ($REQUIRED_PRIV == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $secretary_id = $this->secretaries_model->add($secretary); - + echo json_encode(array( 'status' => AJAX_SUCCESS, 'id' => $secretary_id @@ -988,10 +993,10 @@ class Backend_api extends CI_Controller { )); } } - + /** * [AJAX] Delete a secretary record from the database. - * + * * @param numeric $_POST['secretary_id'] The id of the record to be deleted. * @return string Returns the operation result constant (AJAX_SUCESS or AJAX_FAILURE). */ @@ -1000,7 +1005,7 @@ class Backend_api extends CI_Controller { if ($this->privileges[PRIV_USERS]['delete'] == FALSE) { throw new Exception('You do not have the required privileges for this task.'); } - + $this->load->model('secretaries_model'); $result = $this->secretaries_model->delete($_POST['secretary_id']); echo ($result) ? json_encode(AJAX_SUCCESS) : json_encode(AJAX_FAILURE); @@ -1010,13 +1015,13 @@ class Backend_api extends CI_Controller { )); } } - + /** * [AJAX] Save a setting or multiple settings in the database. - * - * This method is used to store settings in the database. It can be either system + * + * This method is used to store settings in the database. It can be either system * or user settings, one or many. Use the $_POST variables accordingly. - * + * * @param array $_POST['settings'] Contains an array with settings. * @param bool $_POST['type'] Determines the settings type, can be either SETTINGS_SYSTEM * or SETTINGS_USER. @@ -1037,7 +1042,7 @@ class Backend_api extends CI_Controller { $this->load->model('user_model'); $this->user_model->save_settings(json_decode($_POST['settings'], true)); } - + echo json_encode(AJAX_SUCCESS); } catch(Exception $exc) { echo json_encode(array( @@ -1045,16 +1050,16 @@ class Backend_api extends CI_Controller { )); } } - + /** - * [AJAX] This method checks whether the username already exists in the database. - * + * [AJAX] This method checks whether the username already exists in the database. + * * @param string $_POST['username'] Record's username to validate. * @param bool $_POST['record_exists'] Whether the record already exists in database. */ public function ajax_validate_username() { - try { - // We will only use the function in the admins_model because it is sufficient + try { + // We will only use the function in the admins_model because it is sufficient // for the rest user types for now (providers, secretaries). $this->load->model('admins_model'); $is_valid = $this->admins_model->validate_username($_POST['username'], $_POST['user_id']); @@ -1065,13 +1070,13 @@ class Backend_api extends CI_Controller { )); } } - + /** * [AJAX] Change system language for current user. - * + * * The language setting is stored in session data and retrieved every time the user * visits any of the system pages. - * + * * @param string $_POST['language'] Selected language name. */ public function ajax_change_language() { @@ -1082,7 +1087,7 @@ class Backend_api extends CI_Controller { if ($lang == $_POST['language']) { $found = true; break; - } + } } if (!$found) @@ -1092,21 +1097,21 @@ class Backend_api extends CI_Controller { $this->config->set_item('language', $_POST['language']); echo json_encode(AJAX_SUCCESS); - + } catch(Exception $exc) { echo json_encode(array( 'exceptions' => array(exceptionToJavaScript($exc)) - )); + )); } } - + /** - * This method will return a list of the available google calendars. - * - * The user will need to select a specific calendar from this list to sync his - * appointments with. Google access must be already granted for the specific + * This method will return a list of the available google calendars. + * + * The user will need to select a specific calendar from this list to sync his + * appointments with. Google access must be already granted for the specific * provider. - * + * * @param string $_POST['provider_id'] Provider record id. */ public function ajax_get_google_calendars() { @@ -1117,7 +1122,7 @@ class Backend_api extends CI_Controller { if (!isset($_POST['provider_id'])) throw new Exception('Provider id is required in order to fetch the google calendars.'); - // Check if selected provider has sync enabled. + // Check if selected provider has sync enabled. $google_sync = $this->providers_model->get_setting('google_sync', $_POST['provider_id']); if ($google_sync) { $google_token = json_decode($this->providers_model->get_setting('google_token', $_POST['provider_id'])); @@ -1133,12 +1138,12 @@ class Backend_api extends CI_Controller { )); } } - + /** - * Select a specific google calendar for a provider. - * + * 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. */ @@ -1148,11 +1153,11 @@ class Backend_api extends CI_Controller { && $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)) @@ -1162,4 +1167,4 @@ class Backend_api extends CI_Controller { } /* End of file backend_api.php */ -/* Location: ./application/controllers/backend_api.php */ \ No newline at end of file +/* Location: ./application/controllers/backend_api.php */ diff --git a/src/application/controllers/installation.php b/src/application/controllers/installation.php index 51b9051e..efe4f1e6 100644 --- a/src/application/controllers/installation.php +++ b/src/application/controllers/installation.php @@ -26,6 +26,15 @@ class Installation extends CI_Controller { public function __construct() { parent::__construct(); $this->load->helper('installation'); + $this->load->library('session'); + + // Set user's selected language. + if ($this->session->userdata('language')) { + $this->config->set_item('language', $this->session->userdata('language')); + $this->lang->load('translations', $this->session->userdata('language')); + } else { + $this->lang->load('translations', $this->config->item('language')); // default + } } @@ -57,7 +66,15 @@ class Installation extends CI_Controller { } // Create E!A database structure. - $file_contents = file_get_contents(BASEPATH . 'assets/sql/structure.sql'); + $file_contents = file_get_contents(dirname(BASEPATH) . '/assets/sql/structure.sql'); + $sql_queries = explode(';', $file_contents); + array_pop($sql_queries); + foreach($sql_queries as $query) { + $this->db->query($query); + } + + // Insert default E!A entries into the database. + $file_contents = file_get_contents(dirname(BASEPATH) . '/assets/sql/data.sql'); $sql_queries = explode(';', $file_contents); array_pop($sql_queries); foreach($sql_queries as $query) { @@ -93,9 +110,6 @@ class Installation extends CI_Controller { )); } } - - - } /* End of file installation.php */ diff --git a/src/application/language/chinese/translations_lang.php b/src/application/language/chinese/translations_lang.php index c3c889e5..36ac04b5 100644 --- a/src/application/language/chinese/translations_lang.php +++ b/src/application/language/chinese/translations_lang.php @@ -265,3 +265,5 @@ $lang['oops_something_went_wrong'] = '不好!出了一些问题!'; $lang['could_not_add_to_google_calendar'] = '您的预约不能添加到谷歌日历.'; $lang['ea_update_success'] = '预约系统已经成功更新!'; $lang['captcha_is_wrong'] = 'CAPTCHA verification failed, please try again.'; +$lang['any_provider'] = 'Any Provider'; +$lang['requested_hour_is_unavailable'] = 'The requested appointment is unfornately not available. Please select a different hour for your appointment.'; diff --git a/src/application/language/danish/translations_lang.php b/src/application/language/danish/translations_lang.php index 5fbee9ec..a20a31dc 100644 --- a/src/application/language/danish/translations_lang.php +++ b/src/application/language/danish/translations_lang.php @@ -265,3 +265,5 @@ $lang['oops_something_went_wrong'] = 'Oops! Noget gik galt!'; $lang['could_not_add_to_google_calendar'] = 'Din tid kunne ikke tilføjes din Google kalender konto'; $lang['ea_update_success'] = 'Easy!Appointments er blevet opdateret.'; $lang['captcha_is_wrong'] = 'CAPTCHA verification failed, please try again.'; +$lang['any_provider'] = 'Any Provider'; +$lang['requested_hour_is_unavailable'] = 'The requested appointment is unfornately not available. Please select a different hour for your appointment.'; diff --git a/src/application/language/dutch/translations_lang.php b/src/application/language/dutch/translations_lang.php index 59a7ff2c..ab088e94 100644 --- a/src/application/language/dutch/translations_lang.php +++ b/src/application/language/dutch/translations_lang.php @@ -265,3 +265,5 @@ $lang['oops_something_went_wrong'] ='Oeps! Er is iets misgegaan!'; $lang['could_not_add_to_google_calendar'] ='Uw afspraak kon niet toegevoegd worden aan het Google Agenda-account.'; $lang['ea_update_success'] ='Easy!Appointments is succesvol bijgewerkt!'; $lang['captcha_is_wrong'] = 'CAPTCHA verification failed, please try again.'; +$lang['any_provider'] = 'Any Provider'; +$lang['requested_hour_is_unavailable'] = 'The requested appointment is unfornately not available. Please select a different hour for your appointment.'; diff --git a/src/application/language/english/translations_lang.php b/src/application/language/english/translations_lang.php index 694a8e54..86e2e336 100644 --- a/src/application/language/english/translations_lang.php +++ b/src/application/language/english/translations_lang.php @@ -265,3 +265,5 @@ $lang['oops_something_went_wrong'] = 'Oops! Something Went Wrong!'; $lang['could_not_add_to_google_calendar'] = 'Your appointment could not be added to your Google Calendar account.'; $lang['ea_update_success'] = 'Easy!Appointments has been successfully updated!'; $lang['captcha_is_wrong'] = 'CAPTCHA verification failed, please try again.'; +$lang['any_provider'] = 'Any Provider'; +$lang['requested_hour_is_unavailable'] = 'The requested appointment is unfornately not available. Please select a different hour for your appointment.'; diff --git a/src/application/language/finnish/translations_lang.php b/src/application/language/finnish/translations_lang.php index b8e3459a..81930baa 100644 --- a/src/application/language/finnish/translations_lang.php +++ b/src/application/language/finnish/translations_lang.php @@ -265,3 +265,5 @@ $lang['oops_something_went_wrong'] = 'Oho! Jotain meni pieleen!'; $lang['could_not_add_to_google_calendar'] = 'Varaustasi ei pystytty lisäämään Google-kalenteri tiliisi.'; $lang['ea_update_success'] = 'Easy!Appointments päivitettiin onnistuneesti!'; $lang['captcha_is_wrong'] = 'CAPTCHA verification failed, please try again.'; +$lang['any_provider'] = 'Any Provider'; +$lang['requested_hour_is_unavailable'] = 'The requested appointment is unfornately not available. Please select a different hour for your appointment.'; diff --git a/src/application/language/french/translations_lang.php b/src/application/language/french/translations_lang.php index ee62143d..7ea2d2ae 100644 --- a/src/application/language/french/translations_lang.php +++ b/src/application/language/french/translations_lang.php @@ -265,3 +265,5 @@ $lang['oops_something_went_wrong'] = 'Oops! Une erreur s\'est produite !'; $lang['could_not_add_to_google_calendar'] = 'Votre rendez-vous ne peux pas être ajoutée à votre compte calendrier Google.'; $lang['ea_update_success'] = 'Easy!Appointments à été mis à jour avec succès !'; $lang['captcha_is_wrong'] = 'CAPTCHA verification failed, please try again.'; +$lang['any_provider'] = 'Any Provider'; +$lang['requested_hour_is_unavailable'] = 'The requested appointment is unfornately not available. Please select a different hour for your appointment.'; diff --git a/src/application/language/german/translations_lang.php b/src/application/language/german/translations_lang.php index bfe33fc3..03957e7d 100644 --- a/src/application/language/german/translations_lang.php +++ b/src/application/language/german/translations_lang.php @@ -265,3 +265,5 @@ $lang['oops_something_went_wrong'] = 'Oops! Etwas ist schiefgelaufen!'; $lang['could_not_add_to_google_calendar'] = 'Ihr Termin konnte nicht in den Google-Kalender-Konto hinzugefügt werden.'; $lang['ea_update_success'] = 'Easy!Appointments wurde erfolgreich aktualisiert!'; $lang['captcha_is_wrong'] = 'CAPTCHA Überprüfung fehlgeschlagen, bitte versuchen Sie es wieder.'; +$lang['any_provider'] = 'Jeder Anbieter'; +$lang['requested_hour_is_unavailable'] = 'The requested appointment is unfornately not available. Please select a different hour for your appointment.'; diff --git a/src/application/language/greek/translations_lang.php b/src/application/language/greek/translations_lang.php index 60c4cdf2..5f757aff 100644 --- a/src/application/language/greek/translations_lang.php +++ b/src/application/language/greek/translations_lang.php @@ -265,3 +265,5 @@ $lang['oops_something_went_wrong'] = 'Ώχ! Κάτι πήγε στραβά!'; $lang['could_not_add_to_google_calendar'] = 'Το ραντεβού σας δεν μπόρεσε να προστεθεί στον λογαριασμό σας στο Google Calendar.'; $lang['ea_update_success'] = 'Το Easy!Appointments ενημερώθηκε με επιτυχία!'; $lang['captcha_is_wrong'] = 'Η επαλήθευση του CAPTCHA απέτυχε, παρακαλώ δοκιμάστε πάλι.'; +$lang['any_provider'] = 'Οποιοσδήποτε Πάροχος'; +$lang['requested_hour_is_unavailable'] = 'Το απαιτούμενο ραντεβού δεν είναι δυστυχώς διαθέσιμο. Παρακαλώ επιλέξτε κάποια άλλη ώρα για το ραντεβού σας.'; diff --git a/src/application/language/hungarian/translations_lang.php b/src/application/language/hungarian/translations_lang.php index 6d9242a2..b03b88e6 100644 --- a/src/application/language/hungarian/translations_lang.php +++ b/src/application/language/hungarian/translations_lang.php @@ -265,3 +265,5 @@ $lang['oops_something_went_wrong'] = 'Hoppá! Valami balul sült el!'; $lang['could_not_add_to_google_calendar'] = 'Az időpontot nem tudtuk hozzá adni a Google naptáradhoz.'; $lang['ea_update_success'] = 'Foglalj időpontot a ...'; $lang['captcha_is_wrong'] = 'CAPTCHA verification failed, please try again.'; +$lang['any_provider'] = 'Any Provider'; +$lang['requested_hour_is_unavailable'] = 'The requested appointment is unfornately not available. Please select a different hour for your appointment.'; diff --git a/src/application/language/italian/translations_lang.php b/src/application/language/italian/translations_lang.php index 7f6d3551..4ce164df 100644 --- a/src/application/language/italian/translations_lang.php +++ b/src/application/language/italian/translations_lang.php @@ -271,3 +271,5 @@ $lang['oops_something_went_wrong'] = 'Oops! Qualcosa è andato storto!'; $lang['could_not_add_to_google_calendar'] = 'Il tuo appuntamento potrebbe non essere stato aggiunto al tuo account Google Calendar.'; $lang['ea_update_success'] = 'Easy!Appointments è stato aggiornato con successo!'; $lang['captcha_is_wrong'] = 'CAPTCHA verification failed, please try again.'; +$lang['any_provider'] = 'Any Provider'; +$lang['requested_hour_is_unavailable'] = 'The requested appointment is unfornately not available. Please select a different hour for your appointment.'; diff --git a/src/application/language/japanese/translations_lang.php b/src/application/language/japanese/translations_lang.php index e5783af3..6025302e 100644 --- a/src/application/language/japanese/translations_lang.php +++ b/src/application/language/japanese/translations_lang.php @@ -265,3 +265,5 @@ $lang['oops_something_went_wrong'] = 'おっと、なにか が うまく 行っ $lang['could_not_add_to_google_calendar'] = 'あなたの予約をGoogleカレンダーに 追加することができませんでした。'; $lang['ea_update_success'] = 'Easy!Appointments の アップデートが成功しました。'; $lang['captcha_is_wrong'] = 'CAPTCHA verification failed, please try again.'; +$lang['any_provider'] = 'Any Provider'; +$lang['requested_hour_is_unavailable'] = 'The requested appointment is unfornately not available. Please select a different hour for your appointment.'; diff --git a/src/application/language/luxembourgish/translations_lang.php b/src/application/language/luxembourgish/translations_lang.php index dfadee55..12e27d8b 100644 --- a/src/application/language/luxembourgish/translations_lang.php +++ b/src/application/language/luxembourgish/translations_lang.php @@ -265,3 +265,5 @@ $lang['oops_something_went_wrong'] = 'Oops! Et ass eppes schif gaang!'; $lang['could_not_add_to_google_calendar'] = 'Ären Termäin konnt nët am Google Kalenner bäigesat ginn.'; $lang['ea_update_success'] = 'Easy!Appointments gouf erfollegräich aktualiséiert!'; $lang['captcha_is_wrong'] = 'CAPTCHA verification failed, please try again.'; +$lang['any_provider'] = 'Any Provider'; +$lang['requested_hour_is_unavailable'] = 'The requested appointment is unfornately not available. Please select a different hour for your appointment.'; diff --git a/src/application/language/polish/translations_lang.php b/src/application/language/polish/translations_lang.php index 5d1d2840..838872ae 100644 --- a/src/application/language/polish/translations_lang.php +++ b/src/application/language/polish/translations_lang.php @@ -265,3 +265,5 @@ $lang['oops_something_went_wrong'] = 'Ojj! Coś poszło nie tak!'; $lang['could_not_add_to_google_calendar'] = 'Nie można dodać wizyty do Twojego Kalendarza Google'; $lang['ea_update_success'] = 'Easy!Appointment zaktualizowany pomyślnie'; $lang['captcha_is_wrong'] = 'CAPTCHA verification failed, please try again.'; +$lang['any_provider'] = 'Any Provider'; +$lang['requested_hour_is_unavailable'] = 'The requested appointment is unfornately not available. Please select a different hour for your appointment.'; diff --git a/src/application/language/portuguese-br/translations_lang.php b/src/application/language/portuguese-br/translations_lang.php index 931adef0..9d4ff6dd 100644 --- a/src/application/language/portuguese-br/translations_lang.php +++ b/src/application/language/portuguese-br/translations_lang.php @@ -265,3 +265,5 @@ $lang['oops_something_went_wrong'] = 'Ops! Algo deu errado!'; $lang['could_not_add_to_google_calendar'] = 'Não foi possível adicionar à sua conta do Google Calendar.'; $lang['ea_update_success'] = 'Easy!Appointments foi atualizado com sucesso!'; $lang['captcha_is_wrong'] = 'CAPTCHA verification failed, please try again.'; +$lang['any_provider'] = 'Any Provider'; +$lang['requested_hour_is_unavailable'] = 'The requested appointment is unfornately not available. Please select a different hour for your appointment.'; diff --git a/src/application/language/portuguese/translations_lang.php b/src/application/language/portuguese/translations_lang.php index 6dd7e1fa..5d5ca1a4 100644 --- a/src/application/language/portuguese/translations_lang.php +++ b/src/application/language/portuguese/translations_lang.php @@ -265,3 +265,5 @@ $lang['oops_something_went_wrong'] = 'Ops! Algo deu errado!'; $lang['could_not_add_to_google_calendar'] = 'Sua nomeação não pode ser adicionado à sua conta do Google Calendar.'; $lang['ea_update_success'] = 'Nomeações fáceis! Foi atualizado com sucesso!'; $lang['captcha_is_wrong'] = 'CAPTCHA verification failed, please try again.'; +$lang['any_provider'] = 'Any Provider'; +$lang['requested_hour_is_unavailable'] = 'The requested appointment is unfornately not available. Please select a different hour for your appointment.'; diff --git a/src/application/language/romanian/translations_lang.php b/src/application/language/romanian/translations_lang.php index 38bbd9c0..e8e88b1b 100644 --- a/src/application/language/romanian/translations_lang.php +++ b/src/application/language/romanian/translations_lang.php @@ -271,3 +271,5 @@ $lang['oops_something_went_wrong'] = 'Oops! Ceva nu a funtionat corect!'; $lang['could_not_add_to_google_calendar'] = 'Întâlnirea nu a putut fi adaugata în Calendarul Google.'; $lang['ea_update_success'] = 'Easy!Appointments a fost actualizat!'; $lang['captcha_is_wrong'] = 'CAPTCHA verification failed, please try again.'; +$lang['any_provider'] = 'Any Provider'; +$lang['requested_hour_is_unavailable'] = 'The requested appointment is unfornately not available. Please select a different hour for your appointment.'; diff --git a/src/application/language/russian/translations_lang.php b/src/application/language/russian/translations_lang.php index 33d043e5..f70a1115 100644 --- a/src/application/language/russian/translations_lang.php +++ b/src/application/language/russian/translations_lang.php @@ -265,3 +265,5 @@ $lang['oops_something_went_wrong'] = 'Сорри! Возникла неопре $lang['could_not_add_to_google_calendar'] = 'Ваше событие не было добавлено в указанный Google-календарь.'; $lang['ea_update_success'] = 'Готово! Успешно обновлено!'; $lang['captcha_is_wrong'] = 'CAPTCHA verification failed, please try again.'; +$lang['any_provider'] = 'Any Provider'; +$lang['requested_hour_is_unavailable'] = 'The requested appointment is unfornately not available. Please select a different hour for your appointment.'; diff --git a/src/application/language/slovak/translations_lang.php b/src/application/language/slovak/translations_lang.php index c14f87b8..2f857e7e 100644 --- a/src/application/language/slovak/translations_lang.php +++ b/src/application/language/slovak/translations_lang.php @@ -265,3 +265,5 @@ $lang['oops_something_went_wrong'] = 'Úups! Niečo sa pokazilo!'; $lang['could_not_add_to_google_calendar'] = 'Vaše rezervácie nemoholi byť pridané do vášho účtu služby Google Kalendár.'; $lang['ea_update_success'] = 'Easy!Appointments bolo úspešne aktualizované!'; $lang['captcha_is_wrong'] = 'CAPTCHA verification failed, please try again.'; +$lang['any_provider'] = 'Any Provider'; +$lang['requested_hour_is_unavailable'] = 'The requested appointment is unfornately not available. Please select a different hour for your appointment.'; diff --git a/src/application/language/spanish/translations_lang.php b/src/application/language/spanish/translations_lang.php index 6a7888c9..6ad47fbd 100644 --- a/src/application/language/spanish/translations_lang.php +++ b/src/application/language/spanish/translations_lang.php @@ -265,3 +265,5 @@ $lang['oops_something_went_wrong'] ='¡Ups! ¡Algo ha salido mal!'; $lang['could_not_add_to_google_calendar'] = 'No se ha podido agregar el turno a su cuenta de Google Calendar.'; $lang['ea_update_success'] = 'Easy!Appointments ha sido actualizado exitosamente'; $lang['captcha_is_wrong'] = 'CAPTCHA verification failed, please try again.'; +$lang['any_provider'] = 'Any Provider'; +$lang['requested_hour_is_unavailable'] = 'The requested appointment is unfornately not available. Please select a different hour for your appointment.'; diff --git a/src/application/language/turkish/translations_lang.php b/src/application/language/turkish/translations_lang.php index cd374d79..331d0f4c 100644 --- a/src/application/language/turkish/translations_lang.php +++ b/src/application/language/turkish/translations_lang.php @@ -265,3 +265,5 @@ $lang['oops_something_went_wrong'] = 'Oops! Bir Sorun Oluştu!'; $lang['could_not_add_to_google_calendar'] = 'Randevunuz Google Takvim hesabınıza eklenemedi.'; $lang['ea_update_success'] = 'Easy!Appointments başarı ile güncellendi!'; $lang['captcha_is_wrong'] = 'CAPTCHA verification failed, please try again.'; +$lang['any_provider'] = 'Any Provider'; +$lang['requested_hour_is_unavailable'] = 'The requested appointment is unfornately not available. Please select a different hour for your appointment.'; diff --git a/src/application/views/appointments/book.php b/src/application/views/appointments/book.php index ce6f4b12..09b7dcef 100644 --- a/src/application/views/appointments/book.php +++ b/src/application/views/appointments/book.php @@ -406,6 +406,12 @@ config->item('language')); ?> + | + session->userdata('user_id')): ?> + + lang->line('backend_section'); ?> + + @@ -421,7 +427,6 @@ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); - ga('create', '', 'auto'); ga('send', 'pageview'); diff --git a/src/application/views/backend/footer.php b/src/application/views/backend/footer.php index ca8df4f5..f89111fc 100644 --- a/src/application/views/backend/footer.php +++ b/src/application/views/backend/footer.php @@ -1,31 +1,35 @@ - - - - - - \ No newline at end of file + + + + + + diff --git a/src/application/views/general/installation.php b/src/application/views/general/installation.php index e3d69647..a70c0284 100644 --- a/src/application/views/general/installation.php +++ b/src/application/views/general/installation.php @@ -13,6 +13,9 @@ + +