private function _update_appointment_locations($worker_id, $old_location_id, $location_id)
 {
     global $wpdb, $appointments;
     if ($old_location_id == $location_id) {
         return false;
     }
     $res = $wpdb->update($appointments->app_table, array('location' => $location_id), array('location' => $old_location_id, 'worker' => $worker_id), '%s', '%s');
     if ($res) {
         appointments_clear_appointment_cache();
     }
 }
 /**
  * Make checks on submitted fields and save appointment
  * @return json object
  */
 function post_confirmation()
 {
     global $appointments;
     if (!$appointments->check_spam()) {
         die(json_encode(array("error" => apply_filters('app_spam_message', __('You have already applied for an appointment. Please wait until you hear from us.', 'appointments')))));
     }
     global $wpdb, $current_user;
     $values = explode(":", $_POST["value"]);
     $location = $values[0];
     $service = $values[1];
     $worker = $values[2];
     $start = $values[3];
     $end = $values[4];
     $post_id = $values[5];
     if (is_user_logged_in()) {
         $user_id = $current_user->ID;
         $userdata = get_userdata($current_user->ID);
         $user_email = $userdata->email;
         $user_name = $userdata->display_name;
         if (!$user_name) {
             $first_name = get_user_meta($worker, 'first_name', true);
             $last_name = get_user_meta($worker, 'last_name', true);
             $user_name = $first_name . " " . $last_name;
         }
         if ("" == trim($user_name)) {
             $user_name = $userdata->user_login;
         }
     } else {
         $user_id = 0;
         $user_email = '';
         $user_name = '';
     }
     // A little trick to pass correct lsw variables to the get_price, is_busy and get_capacity functions
     $_REQUEST["app_location_id"] = $location;
     $_REQUEST["app_service_id"] = $service;
     $_REQUEST["app_provider_id"] = $worker;
     $appointments->get_lsw();
     // Default status
     $status = 'pending';
     if ('yes' != $appointments->options["payment_required"] && isset($appointments->options["auto_confirm"]) && 'yes' == $appointments->options["auto_confirm"]) {
         $status = 'confirmed';
     }
     // We may have 2 prices now: 1) Service full price, 2) Amount that will be paid to Paypal
     $price = $appointments->get_price();
     $price = apply_filters('app_post_confirmation_price', $price, $service, $worker, $start, $end);
     $paypal_price = $appointments->get_price(true);
     $paypal_price = apply_filters('app_post_confirmation_paypal_price', $paypal_price, $service, $worker, $start, $end);
     // Break here - is the appointment free and, if so, shall we auto-confirm?
     if (!(double) $price && !(double) $paypal_price && 'pending' === $status && "yes" === $appointments->options["payment_required"] && (!empty($appointments->options["auto_confirm"]) && "yes" === $appointments->options["auto_confirm"])) {
         $status = defined('APP_CONFIRMATION_ALLOW_FREE_AUTOCONFIRM') && APP_CONFIRMATION_ALLOW_FREE_AUTOCONFIRM ? 'confirmed' : $status;
     }
     $name = !empty($_POST['app_name']) ? sanitize_text_field($_POST["app_name"]) : $user_name;
     $name_check = apply_filters("app_name_check", true, $name);
     if (!$name_check) {
         $appointments->json_die('name');
     }
     $email = !empty($_POST['app_email']) && is_email($_POST['app_email']) ? $_POST['app_email'] : $user_email;
     if ($appointments->options["ask_email"] && !is_email($email)) {
         $appointments->json_die('email');
     }
     $phone = !empty($_POST['app_phone']) ? sanitize_text_field($_POST["app_phone"]) : '';
     $phone_check = apply_filters("app_phone_check", true, $phone);
     if (!$phone_check) {
         $appointments->json_die('phone');
     }
     $address = !empty($_POST['app_address']) ? sanitize_text_field($_POST["app_address"]) : '';
     $address_check = apply_filters("app_address_check", true, $address);
     if (!$address_check) {
         $appointments->json_die('address');
     }
     $city = !empty($_POST['app_city']) ? sanitize_text_field($_POST["app_city"]) : '';
     $city_check = apply_filters("app_city_check", true, $city);
     if (!$city_check) {
         $appointments->json_die('city');
     }
     $note = !empty($_POST['app_note']) ? sanitize_text_field($_POST["app_note"]) : '';
     $gcal = !empty($_POST['app_gcal']) ? $_POST['app_gcal'] : '';
     do_action('app-additional_fields-validate');
     // It may be required to add additional data here
     $note = apply_filters('app_note_field', $note);
     $service_result = $appointments->get_service($service);
     $duration = false;
     if ($service_result !== null) {
         $duration = $service_result->duration;
     }
     if (!$duration) {
         $duration = $appointments->get_min_time();
     }
     // In minutes
     $duration = apply_filters('app_post_confirmation_duration', $duration, $service, $worker, $user_id);
     if ($appointments->is_busy($start, $start + $duration * 60, $appointments->get_capacity())) {
         die(json_encode(array("error" => apply_filters('app_booked_message', __('We are sorry, but this time slot is no longer available. Please refresh the page and try another time slot. Thank you.', 'appointments')))));
     }
     $status = apply_filters('app_post_confirmation_status', $status, $price, $service, $worker, $user_id);
     $result = $wpdb->insert($appointments->app_table, array('created' => date("Y-m-d H:i:s", $appointments->local_time), 'user' => $user_id, 'name' => $name, 'email' => $email, 'phone' => $phone, 'address' => $address, 'city' => $city, 'location' => $location, 'service' => $service, 'worker' => $worker, 'price' => $price, 'status' => $status, 'start' => date("Y-m-d H:i:s", $start), 'end' => date("Y-m-d H:i:s", $start + $duration * 60), 'note' => $note));
     appointments_clear_appointment_cache();
     if (!$result) {
         die(json_encode(array("error" => __('Appointment could not be saved. Please contact website admin.', 'appointments'))));
     }
     // A new appointment is accepted, so clear cache
     $insert_id = $wpdb->insert_id;
     // Save insert ID
     $appointments->flush_cache();
     $appointments->save_cookie($insert_id, $name, $email, $phone, $address, $city, $gcal);
     do_action('app_new_appointment', $insert_id);
     // Send confirmation for pending, payment not required cases, if selected so
     if ('yes' != $appointments->options["payment_required"] && isset($appointments->options["send_notification"]) && 'yes' == $appointments->options["send_notification"] && 'pending' == $status) {
         $appointments->send_notification($insert_id);
     }
     // Send confirmation if we forced it
     if ('confirmed' == $status && isset($appointments->options["send_confirmation"]) && 'yes' == $appointments->options["send_confirmation"]) {
         $appointments->send_confirmation($insert_id);
     }
     // Add to GCal API
     if (is_object($appointments->gcal_api) && $appointments->gcal_api->is_syncable_status($status)) {
         $appointments->gcal_api->insert($insert_id);
     }
     // GCal button
     if (isset($appointments->options["gcal"]) && 'yes' == $appointments->options["gcal"] && $gcal) {
         $gcal_url = $appointments->gcal($service, $start, $start + $duration * 60, false, $address, $city);
     } else {
         $gcal_url = '';
     }
     $additional = array('mp' => 0, 'variation' => null);
     $additional = apply_filters('app-appointment-appointment_created', $additional, $insert_id, $post_id, $service, $worker, $start, $end);
     $mp = isset($additional['mp']) ? $additional['mp'] : 0;
     $variation = isset($additional['variation']) ? $additional['variation'] : 0;
     $gcal_same_window = !empty($appointments->options["gcal_same_window"]) ? 1 : 0;
     if (isset($appointments->options["payment_required"]) && 'yes' == $appointments->options["payment_required"]) {
         die(json_encode(array("cell" => $_POST["value"], "app_id" => $insert_id, "refresh" => 0, "price" => $paypal_price, "service_name" => stripslashes($service_result->name), 'gcal_url' => $gcal_url, 'gcal_same_window' => $gcal_same_window, 'mp' => $mp, 'variation' => $variation)));
     } else {
         $result = array("cell" => $_POST["value"], "app_id" => $insert_id, "refresh" => 1, 'gcal_url' => $gcal_url, 'gcal_same_window' => $gcal_same_window);
         wp_send_json($result);
     }
 }
/**
 * Delete an appointment forever
 *
 * @param $app_id
 *
 * @return bool|false|int
 */
function appointments_delete_appointment($app_id)
{
    global $wpdb;
    $app = appointments_get_appointment($app_id);
    if (!$app) {
        return false;
    }
    $table = appointments_get_table('appointments');
    $result = $wpdb->query($wpdb->prepare("DELETE FROM {$table} WHERE ID = %d", $app_id));
    appointments_clear_appointment_cache($app_id);
    return (bool) $result;
}
 /**
  * Deletes a worker's database records in case he is deleted
  * @since 1.0.4
  */
 function delete_user($ID)
 {
     if (!$ID) {
         return;
     }
     global $wpdb;
     $r1 = appointments_delete_worker($ID);
     // Also modify app table
     $r2 = $wpdb->update($this->app_table, array('worker' => 0), array('worker' => $ID));
     if ($r1 || $r2) {
         appointments_clear_appointment_cache();
         $this->flush_cache();
     }
 }