diff --git a/src/application/controllers/appointments.php b/src/application/controllers/appointments.php index 6b010466..0772477b 100755 --- a/src/application/controllers/appointments.php +++ b/src/application/controllers/appointments.php @@ -34,11 +34,6 @@ class Appointments extends CI_Controller { } else { $this->lang->load('translations', $this->config->item('language')); // default } - - // Create a new captcha builder instance and store it to the session vars. - if ($this->session->userdata('captcha_builder') === FALSE) { - $this->session->userdata('captcha_builder', new Gregwar\Captcha\CaptchaBuilder()); - } } /** @@ -543,11 +538,23 @@ class Appointments extends CI_Controller { */ public function ajax_register_appointment() { try { - $view = array(); - $post_data = json_decode($_POST['post_data'], true); + + $post_data = $_POST['post_data']; // alias + + // Validate the CAPTCHA string. + if ($this->session->userdata('captcha_phrase') !== $_POST['captcha']) { + throw new Exception($this->lang->line('captcha_is_wrong')); + } + $appointment = $post_data['appointment']; $customer = $post_data['customer']; + $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'); + if ($this->customers_model->exists($customer)) $customer['id'] = $this->customers_model->find_record_id($customer); @@ -643,7 +650,9 @@ class Appointments extends CI_Controller { log_message('error', $exc->getTraceAsString()); } - echo AJAX_SUCCESS; + echo json_encode(array( + 'appointment_id' => $appointment['id'] + )); } catch(Exception $exc) { echo json_encode(array( diff --git a/src/application/controllers/captcha.php b/src/application/controllers/captcha.php new file mode 100644 index 00000000..01941b0d --- /dev/null +++ b/src/application/controllers/captcha.php @@ -0,0 +1,41 @@ + + * @copyright Copyright (c) 2013 - 2015, Alex Tselegidis + * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 + * @link http://easyappointments.org + * @since v1.0.0 + * ---------------------------------------------------------------------------- */ + +/** + * Captcha Controller + * + * @package Controllers + */ +class Captcha extends CI_Controller { + + /** + * Class Constructor + */ + public function __construct() { + parent::__construct(); + $this->load->library('session'); + } + + /** + * Make a request to this method to get a captcha image. + */ + public function index() { + header('Content-type: image/jpeg'); + $builder = new Gregwar\Captcha\CaptchaBuilder; + $builder->build()->output(); + $this->session->set_userdata('captcha_phrase', $builder->getPhrase()); + } +} + +/* End of file appointments.php */ +/* Location: ./application/controllers/appointments.php */ diff --git a/src/application/language/chinese/translations_lang.php b/src/application/language/chinese/translations_lang.php index 1b2f75ea..c3c889e5 100644 --- a/src/application/language/chinese/translations_lang.php +++ b/src/application/language/chinese/translations_lang.php @@ -1,266 +1,267 @@ -
+
+
+

+ Captcha + +

+ + +
+
@@ -400,6 +410,7 @@
+ diff --git a/src/assets/css/frontend.css b/src/assets/css/frontend.css index c30d51fb..498d05c5 100644 --- a/src/assets/css/frontend.css +++ b/src/assets/css/frontend.css @@ -181,6 +181,23 @@ body { margin-bottom: 25px; } +#book-appointment-wizard .captcha-title { + float: left; + margin-right: 20px; + margin-top: 7px; +} + +#book-appointment-wizard .captcha-image { + float: right; + margin-bottom: 20px; +} + +#book-appointment-wizard .captcha-text { + width: 100%; + margin-bottom: 20px; +} + + /* BOOK SUCCESS & MESSAGE ------------------------------------------------------------------------- */ #message-frame, diff --git a/src/assets/js/frontend_book.js b/src/assets/js/frontend_book.js index 106c1985..029a6c4d 100644 --- a/src/assets/js/frontend_book.js +++ b/src/assets/js/frontend_book.js @@ -285,7 +285,7 @@ var FrontendBook = { } if (response === true) { - $('#book-appointment-form').submit(); + FrontendBook.registerAppointment(); } else { GeneralFunctions.displayMessageBox('Appointment Hour Taken', 'Unfortunately ' + 'the selected appointment hour is not available anymore. Please select ' @@ -294,6 +294,13 @@ var FrontendBook = { } }, 'json').fail(GeneralFunctions.ajaxFailureHandler); }); + + /** + * Event: Refresh captcha image. + */ + $('.captcha-title small').click(function(event) { + $('.captcha-image').attr('src', GlobalVariables.baseUrl + '/index.php/captcha?' + Date.now()); + }); }, /** @@ -612,7 +619,56 @@ var FrontendBook = { } else { $div.hide(); } + }, + /** + * Register an appointment to the database. + * + * This method will make an ajax call to the appointments controller that will register + * the appointment to the database. + */ + registerAppointment: function() { + if ($('.captcha-text').val() === '') { + $('.captcha-text').css('border', '1px solid red'); + return; + } + + var formData = jQuery.parseJSON($('input[name="post_data"]').val()); + + var postData = { + 'csrfToken': GlobalVariables.csrfToken, + 'post_data': formData, + 'captcha': $('.captcha-text').val() + }; + + if (GlobalVariables.manageMode) { + postData.exclude_appointment_id = GlobalVariables.appointmentData.id; + } + + var postUrl = GlobalVariables.baseUrl + '/index.php/appointments/ajax_register_appointment'; + + $.ajax({ + url: postUrl, + method: 'post', + data: postData, + dataType: 'json' + }) + .done(function(response) { + if (response.exceptions) { + response.exceptions = GeneralFunctions.parseExceptions(response.exceptions); + GeneralFunctions.displayMessageBox('Unexpected Issues', 'Unfortunately ' + + 'the check appointment time availability could not be completed. ' + + 'The following issues occurred:'); + $('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions)); + $('.captcha-title small').trigger('click'); + return false; + } + + window.location.replace(GlobalVariables.baseUrl + '/index.php/appointments/book_success'); + }) + .fail(function(jqxhr, textStatus, errorThrown) { + $('.captcha-title small').trigger('click'); + GeneralFunctions.ajaxFailureHandler(jqxhr, textStatus, errorThrown); + }); } - };