/** * @param AB_Notification $notification */ public function processNotification(AB_Notification $notification) { /** @var $wpdb wpdb */ global $wpdb; $date = new DateTime(); switch ($notification->get('type')) { case 'staff_agenda': if ($date->format('H') >= 18) { $rows = $wpdb->get_results('SELECT `a`.*, `c`.`name` AS `customer_name`, `s`.`title` AS `service_title`, `st`.`email` AS `staff_email`, `st`.`phone` AS `staff_phone`, `st`.`full_name` AS `staff_name` FROM `' . AB_CustomerAppointment::getTableName() . '` `ca` LEFT JOIN `' . AB_Appointment::getTableName() . '` `a` ON `a`.`id` = `ca`.`appointment_id` LEFT JOIN `' . AB_Customer::getTableName() . '` `c` ON `c`.`id` = `ca`.`customer_id` LEFT JOIN `' . AB_Service::getTableName() . '` `s` ON `s`.`id` = `a`.`service_id` LEFT JOIN `' . AB_Staff::getTableName() . '` `st` ON `st`.`id` = `a`.`staff_id` LEFT JOIN `' . AB_StaffService::getTableName() . '` `ss` ON `ss`.`staff_id` = `a`.`staff_id` AND `ss`.`service_id` = `a`.`service_id` WHERE DATE(DATE_ADD("' . $this->mysql_now . '", INTERVAL 1 DAY)) = DATE(`a`.`start_date`) AND NOT EXISTS ( SELECT * FROM `' . AB_SentNotification::getTableName() . '` `sn` WHERE DATE(`sn`.`created`) = DATE("' . $this->mysql_now . '") AND `sn`.`gateway` = "' . $notification->get('gateway') . '" AND `sn`.`type` = "staff_agenda" AND `sn`.`staff_id` = `a`.`staff_id` )'); if ($rows) { $appointments = array(); foreach ($rows as $row) { $appointments[$row->staff_id][] = $row; } foreach ($appointments as $staff_id => $collection) { $sent = false; $staff_email = null; $staff_phone = null; $table = $notification->get('gateway') == 'email' ? '<table>%s</table>' : '%s'; $tr = $notification->get('gateway') == 'email' ? '<tr><td>%s</td><td>%s</td><td>%s</td></tr>' : "%s %s %s\n"; $agenda = ''; foreach ($collection as $appointment) { $startDate = new DateTime($appointment->start_date); $endDate = new DateTime($appointment->end_date); $agenda .= sprintf($tr, $startDate->format('H:i') . '-' . $endDate->format('H:i'), $appointment->service_title, $appointment->customer_name); $staff_email = $appointment->staff_email; $staff_phone = $appointment->staff_phone; } $agenda = sprintf($table, $agenda); if ($staff_email || $staff_phone) { $replacement = new AB_NotificationCodes(); $replacement->set('next_day_agenda', $agenda); $replacement->set('appointment_datetime', $appointment->start_date); $replacement->set('staff_name', $appointment->staff_name); if ($notification->get('gateway') == 'email' && $staff_email) { $message = $replacement->replace($notification->get('message')); $subject = $replacement->replace($notification->get('subject')); // Send email. $sent = wp_mail($staff_email, $subject, wpautop($message), AB_Utils::getEmailHeaders()); } else { if ($notification->get('gateway') == 'sms' && $staff_phone) { $message = $replacement->replace($notification->get('message'), $notification->get('gateway')); // Send sms. $sent = $this->sms->sendSms($staff_phone, $message); } } } if ($sent) { $sent_notification = new AB_SentNotification(); $sent_notification->set('staff_id', $staff_id); $sent_notification->set('gateway', $notification->get('gateway')); $sent_notification->set('type', 'staff_agenda'); $sent_notification->set('created', $date->format('Y-m-d H:i:s')); $sent_notification->save(); } } } } break; case 'client_follow_up': if ($date->format('H') >= 21) { $rows = $wpdb->get_results('SELECT `a`.*, `ca`.* FROM `' . AB_CustomerAppointment::getTableName() . '` `ca` LEFT JOIN `' . AB_Appointment::getTableName() . '` `a` ON `a`.`id` = `ca`.`appointment_id` WHERE DATE("' . $this->mysql_now . '") = DATE(`a`.`start_date`) AND NOT EXISTS ( SELECT * FROM `' . AB_SentNotification::getTableName() . '` `sn` WHERE DATE(`sn`.`created`) = DATE("' . $this->mysql_now . '") AND `sn`.`gateway` = "' . $notification->get('gateway') . '" AND `sn`.`type` = "client_follow_up" AND `sn`.`customer_appointment_id` = `ca`.`id` )', ARRAY_A); if ($rows) { foreach ($rows as $row) { $customer_appointment = new AB_CustomerAppointment(); $customer_appointment->load($row['id']); if (AB_NotificationSender::sendFromCron(AB_NotificationSender::CRON_FOLLOW_UP_EMAIL, $notification, $customer_appointment)) { $sent_notification = new AB_SentNotification(); $sent_notification->set('customer_appointment_id', $customer_appointment->get('id')); $sent_notification->set('gateway', $notification->get('gateway')); $sent_notification->set('type', 'client_follow_up'); $sent_notification->set('created', $date->format('Y-m-d H:i:s')); $sent_notification->save(); } } } } break; case 'client_reminder': if ($date->format('H') >= 18) { $rows = $wpdb->get_results('SELECT `ca`.`id` FROM `' . AB_CustomerAppointment::getTableName() . '` `ca` LEFT JOIN `' . AB_Appointment::getTableName() . '` `a` ON `a`.`id` = `ca`.`appointment_id` WHERE DATE(DATE_ADD("' . $this->mysql_now . '", INTERVAL 1 DAY)) = DATE(`a`.`start_date`) AND NOT EXISTS ( SELECT * FROM `' . AB_SentNotification::getTableName() . '` `sn` WHERE DATE(`sn`.`created`) = DATE("' . $this->mysql_now . '") AND `sn`.`gateway` = "' . $notification->get('gateway') . '" AND `sn`.`type` = "client_reminder" AND `sn`.`customer_appointment_id` = `ca`.`id` )', ARRAY_A); if ($rows) { foreach ($rows as $row) { $customer_appointment = new AB_CustomerAppointment(); $customer_appointment->load($row['id']); if (AB_NotificationSender::sendFromCron(AB_NotificationSender::CRON_NEXT_DAY_APPOINTMENT, $notification, $customer_appointment)) { $sent_notification = new AB_SentNotification(); $sent_notification->set('customer_appointment_id', $customer_appointment->get('id')); $sent_notification->set('gateway', $notification->get('gateway')); $sent_notification->set('type', 'client_reminder'); $sent_notification->set('created', $date->format('Y-m-d H:i:s')); $sent_notification->save(); } } } } break; } }
/** * Save all data and create appointment. * * @return AB_Appointment */ public function save() { $user_id = get_current_user_id(); $customer = new AB_Customer(); if ($user_id) { // Try to find customer by WP user ID. $customer->loadBy(array('wp_user_id' => $user_id)); } if (!$customer->isLoaded()) { // If customer with such name & e-mail exists, append new booking to him, otherwise - create new customer $customer->loadBy(array('name' => $this->get('name'), 'email' => $this->get('email'))); } $customer->set('name', $this->get('name')); $customer->set('email', $this->get('email')); $customer->set('phone', $this->get('phone')); if (get_option('ab_settings_create_account', 0) && !$customer->get('wp_user_id')) { // Create WP user and link it to customer. $customer->setWPUser($user_id ?: null); } $customer->save(); $this->customer_id = $customer->get('id'); $service = $this->getService(); /** * Get appointment, with same params. * If it is -> create connection to this appointment, * otherwise create appointment and connect customer to new appointment */ $appointment = new AB_Appointment(); $appointment->loadBy(array('staff_id' => $this->getStaffId(), 'service_id' => $this->get('service_id'), 'start_date' => $this->get('appointment_datetime'))); if ($appointment->isLoaded() == false) { $appointment->set('staff_id', $this->getStaffId()); $appointment->set('service_id', $this->get('service_id')); $appointment->set('start_date', $this->get('appointment_datetime')); $endDate = new DateTime($this->get('appointment_datetime')); $di = "+ {$service->get('duration')} sec"; $endDate->modify($di); $appointment->set('end_date', $endDate->format('Y-m-d H:i:s')); $appointment->save(); } $customer_appointment = new AB_CustomerAppointment(); $customer_appointment->loadBy(array('customer_id' => $customer->get('id'), 'appointment_id' => $appointment->get('id'))); if ($customer_appointment->isLoaded()) { // Add number of persons to existing booking. $customer_appointment->set('number_of_persons', $customer_appointment->get('number_of_persons') + $this->get('number_of_persons')); } else { $customer_appointment->set('customer_id', $customer->get('id')); $customer_appointment->set('appointment_id', $appointment->get('id')); $customer_appointment->set('number_of_persons', $this->get('number_of_persons')); } $customer_appointment->set('custom_fields', $this->get('custom_fields')); $customer_appointment->set('time_zone_offset', $this->get('time_zone_offset')); $coupon = $this->getCoupon(); if ($coupon) { $customer_appointment->set('coupon_code', $coupon->get('code')); $customer_appointment->set('coupon_discount', $coupon->get('discount')); $customer_appointment->set('coupon_deduction', $coupon->get('deduction')); $coupon->claim(); $coupon->save(); } $customer_appointment->save(); // Create fake payment record for 100% discount coupons. if ($coupon && $coupon->get('discount') == '100') { $payment = new AB_Payment(); $payment->set('total', '0.00'); $payment->set('type', 'coupon'); $payment->set('created', current_time('mysql')); $payment->set('customer_appointment_id', $customer_appointment->get('id')); $payment->save(); } // Google Calendar. $appointment->handleGoogleCalendar(); // Send email notifications. AB_NotificationSender::send(AB_NotificationSender::INSTANT_NEW_APPOINTMENT, $customer_appointment); return $appointment; }
/** * Cancel Appointment using token. */ public function executeCancelAppointment() { $customer_appointment = new AB_CustomerAppointment(); if ($customer_appointment->loadBy(array('token' => $this->getParameter('token')))) { // Send email. AB_NotificationSender::send(AB_NotificationSender::INSTANT_CANCELLED_APPOINTMENT, $customer_appointment); $customer_appointment->delete(); $appointment = new AB_Appointment(); $appointment->load($customer_appointment->get('appointment_id')); // Delete appointment, if there aren't customers. $count = AB_CustomerAppointment::query('ca')->where('ca.appointment_id', $customer_appointment->get('appointment_id'))->count(); if (!$count) { $appointment->delete(); } else { $appointment->handleGoogleCalendar(); } if ($this->url = get_option('ab_settings_cancel_page_url')) { wp_redirect($this->url); $this->render('cancel_appointment'); exit(0); } } $this->url = home_url(); if (isset($_SERVER['HTTP_REFERER'])) { if (parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) == parse_url($this->url, PHP_URL_HOST)) { // Redirect back if user came from our site. $this->url = $_SERVER['HTTP_REFERER']; } } wp_redirect($this->url); $this->render('cancel_appointment'); exit(0); }
/** * Send email to $mail_to. * * @param AB_Notification $notification * @param AB_NotificationCodes $codes * @param string $mail_to * @param string $phone * @return bool */ private static function _send(AB_Notification $notification, AB_NotificationCodes $codes, $mail_to, $phone = '') { $result = false; if ($notification->get('gateway') == 'email') { $message = $codes->replace($notification->get('message')); // Send email to recipient. $subject = $codes->replace($notification->get('subject')); $result = wp_mail($mail_to, $subject, wpautop($message), AB_Utils::getEmailHeaders()); // Send copy to administrators. if ($notification->get('copy')) { $admin_emails = AB_Utils::getAdminEmails(); if (!empty($admin_emails)) { wp_mail($admin_emails, $subject, wpautop($message), AB_Utils::getEmailHeaders()); } } } elseif ($notification->get('gateway') == 'sms') { $message = $codes->replace($notification->get('message'), 'sms'); if (self::$sms_authorized === null) { self::$sms = new AB_SMS(); self::$sms_authorized = self::$sms->loadProfile(); } if (self::$sms_authorized) { if ($phone != '') { $result = self::$sms->sendSms($phone, $message); } if ($notification->get('copy')) { if ($administrator_phone = get_option('ab_sms_administrator_phone', '') != '') { self::$sms->sendSms($administrator_phone, $message); } } } } return $result; }
/** * Save appointment form (for both create and edit). */ public function executeSaveAppointmentForm() { $response = array('success' => false); $start_date = date('Y-m-d H:i:s', strtotime($this->getParameter('start_date'))); $end_date = date('Y-m-d H:i:s', strtotime($this->getParameter('end_date'))); $staff_id = $this->getParameter('staff_id'); $service_id = $this->getParameter('service_id'); $appointment_id = $this->getParameter('id', 0); $customers = json_decode($this->getParameter('customers', '[]'), true); $staff_service = new AB_StaffService(); $staff_service->loadBy(array('staff_id' => $staff_id, 'service_id' => $service_id)); // Check for errors. if (!$service_id) { $response['errors']['service_required'] = true; } if (empty($customers)) { $response['errors']['customers_required'] = true; } if (!$this->dateIntervalIsAvailableForAppointment($start_date, $end_date, $staff_id, $appointment_id)) { $response['errors']['date_interval_not_available'] = true; } $number_of_persons = 0; foreach ($customers as $customer) { $number_of_persons += $customer['number_of_persons']; } if ($number_of_persons > $staff_service->get('capacity')) { $response['errors']['overflow_capacity'] = __('The number of customers should be not more than ', 'bookly') . $staff_service->get('capacity'); } if (!$this->getParameter('start_date')) { $response['errors']['time_interval'] = __('Start time must not be empty', 'bookly'); } elseif (!$this->getParameter('end_date')) { $response['errors']['time_interval'] = __('End time must not be empty', 'bookly'); } elseif ($start_date == $end_date) { $response['errors']['time_interval'] = __('End time must not be equal to start time', 'bookly'); } // If no errors then try to save the appointment. if (!isset($response['errors'])) { $appointment = new AB_Appointment(); if ($appointment_id) { // Edit. $appointment->load($appointment_id); } $appointment->set('start_date', $start_date); $appointment->set('end_date', $end_date); $appointment->set('staff_id', $staff_id); $appointment->set('service_id', $service_id); if ($appointment->save() !== false) { // Save customers. $appointment->setCustomers($customers); // Google Calendar. $appointment->handleGoogleCalendar(); if ($this->getParameter('email_notification') === 'true') { foreach ($appointment->getCustomerAppointments() as $ca) { AB_NotificationSender::send(AB_NotificationSender::INSTANT_NEW_APPOINTMENT, $ca); } } $startDate = new DateTime($appointment->get('start_date')); $endDate = new DateTime($appointment->get('end_date')); $desc = array(); if ($staff_service->get('capacity') == 1) { $customer_appointments = $appointment->getCustomerAppointments(); if (!empty($customer_appointments)) { $ca = $customer_appointments[0]->customer; foreach (array('name', 'phone', 'email') as $data_entry) { $entry_value = $ca->get($data_entry); if ($entry_value) { $desc[] = '<div class="fc-employee">' . esc_html($entry_value) . '</div>'; } } foreach ($customer_appointments[0]->getCustomFields() as $custom_field) { $desc[] = '<div class="fc-notes">' . wp_strip_all_tags($custom_field['label']) . ': ' . esc_html($custom_field['value']) . '</div>'; } } } else { $signed_up = 0; foreach ($appointment->getCustomerAppointments() as $ca) { $signed_up += $ca->get('number_of_persons'); } $desc[] = '<div class="fc-notes">' . __('Signed up', 'bookly') . ' ' . $signed_up . '</div>'; $desc[] = '<div class="fc-notes">' . __('Capacity', 'bookly') . ' ' . $staff_service->get('capacity') . '</div>'; } $service = new AB_Service(); $service->load($service_id); $response['success'] = true; $response['data'] = array('id' => (int) $appointment->get('id'), 'start' => $startDate->format('Y-m-d H:i:s'), 'end' => $endDate->format('Y-m-d H:i:s'), 'desc' => implode('', $desc), 'title' => $service->get('title') ? $service->get('title') : __('Untitled', 'bookly'), 'color' => $service->get('color'), 'staffId' => $appointment->get('staff_id')); } else { $response['errors'] = array('db' => __('Could not save appointment in database.', 'bookly')); } } wp_send_json($response); }
/** * Create new WP user and send email notification. * * @return bool|int */ private function _createWPUser() { // Generate unique username. $i = 1; $base = $this->get('name') != '' ? sanitize_user($this->get('name')) : 'client'; $username = $base; while (username_exists($username)) { $username = $base . $i; ++$i; } // Generate password. $password = wp_generate_password(6, true); // Create user. $user_id = wp_create_user($username, $password, $this->get('email')); if (!$user_id instanceof WP_Error) { // Set the role $user = new WP_User($user_id); $user->set_role('subscriber'); // Send email notification. AB_NotificationSender::sendEmailForNewUser($this, $username, $password); return $user_id; } return false; }