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);
+ });
}
-
};