/** * Do replacements. * * @param $text * @param string $type * * @return string */ public function replace($text, $type = 'email') { // Company logo as <img> tag. $company_logo = ''; if (get_option('ab_settings_company_logo_url') != '') { $company_logo = sprintf('<img src="%s" alt="%s" />', esc_attr(get_option('ab_settings_company_logo_url')), esc_attr(get_option('ab_settings_company_name'))); } // Staff photo as <img> tag. $staff_photo = ''; if ($this->data['staff_photo'] != '') { $staff_photo = sprintf('<img src="%s" alt="%s" />', esc_attr($this->get('staff_photo')), esc_attr($this->get('staff_name'))); } // Cancel appointment URL and <a> tag. $cancel_appointment_url = admin_url('admin-ajax.php') . '?action=ab_cancel_appointment&token=' . $this->get('appointment_token'); $cancel_appointment = sprintf('<a href="%1$s">%1$s</a>', $cancel_appointment_url); // Codes. $codes = array('[[APPOINTMENT_TIME]]' => AB_DateTimeUtils::formatTime($this->get('appointment_datetime')), '[[APPOINTMENT_DATE]]' => AB_DateTimeUtils::formatDate($this->get('appointment_datetime')), '[[CUSTOM_FIELDS]]' => $this->get('custom_fields'), '[[CUSTOM_FIELDS_2C]]' => $this->get('custom_fields_2c'), '[[CLIENT_NAME]]' => $this->get('client_name'), '[[CLIENT_PHONE]]' => $this->get('client_phone'), '[[CLIENT_EMAIL]]' => $this->get('client_email'), '[[SERVICE_NAME]]' => $this->get('service_name'), '[[SERVICE_PRICE]]' => AB_Utils::formatPrice($this->get('service_price')), '[[STAFF_EMAIL]]' => $this->get('staff_email'), '[[STAFF_NAME]]' => $this->get('staff_name'), '[[STAFF_PHONE]]' => $this->get('staff_phone'), '[[STAFF_PHOTO]]' => $staff_photo, '[[CANCEL_APPOINTMENT]]' => $cancel_appointment, '[[CANCEL_APPOINTMENT_URL]]' => $cancel_appointment_url, '[[CATEGORY_NAME]]' => $this->get('category_name'), '[[COMPANY_ADDRESS]]' => $type == 'email' ? nl2br(get_option('ab_settings_company_address')) : get_option('ab_settings_company_address'), '[[COMPANY_LOGO]]' => $company_logo, '[[COMPANY_NAME]]' => get_option('ab_settings_company_name'), '[[COMPANY_PHONE]]' => get_option('ab_settings_company_phone'), '[[COMPANY_WEBSITE]]' => get_option('ab_settings_company_website'), '[[NEXT_DAY_AGENDA]]' => $this->get('next_day_agenda'), '[[TOMORROW_DATE]]' => date_i18n(get_option('date_format'), strtotime($this->get('appointment_datetime'))), '[[TOTAL_PRICE]]' => AB_Utils::formatPrice($this->get('service_price') * $this->get('number_of_persons')), '[[NUMBER_OF_PERSONS]]' => $this->get('number_of_persons'), '[[SITE_ADDRESS]]' => $this->get('site_address'), '[[NEW_USERNAME]]' => $this->get('new_username'), '[[NEW_PASSWORD]]' => $this->get('new_password')); return strtr($text, $codes); }
/** * Constructor. * * @param array $options */ public function __construct(array $options = array()) { // Handle widget options. $options = array_merge(array('use_empty' => true, 'empty_value' => null, 'exclude_last_slot' => false), $options); // Insert empty value if required. if ($options['use_empty']) { $this->values[null] = $options['empty_value']; } $ts_length = AB_BookingConfiguration::getTimeSlotLength(); $time_start = AB_StaffScheduleItem::WORKING_START_TIME; $time_end = AB_StaffScheduleItem::WORKING_END_TIME; if ($options['exclude_last_slot']) { $time_end -= $ts_length; } // Run the loop. while ($time_start <= $time_end) { $this->values[AB_DateTimeUtils::buildTimeString($time_start)] = AB_DateTimeUtils::formatTime($time_start); $time_start += $ts_length; } }
/** * @param string $field_name * @param bool $is_start * @return string */ public function renderField($field_name = 'ab_settings_monday', $is_start = true) { $ts_length = AB_BookingConfiguration::getTimeSlotLength(); $time_output = AB_StaffScheduleItem::WORKING_START_TIME; $time_end = AB_StaffScheduleItem::WORKING_END_TIME; $option_name = $field_name . ($is_start ? '_start' : '_end'); $class_name = $is_start ? 'select_start' : 'select_end'; $selected_value = get_option($option_name); $output = "<select class='form-control ab-auto-w {$class_name}' name={$option_name}>"; if ($is_start) { $output .= "<option value=''>" . __('OFF', 'bookly') . "</option>"; $time_end -= $ts_length; } while ($time_output <= $time_end) { $value = AB_DateTimeUtils::buildTimeString($time_output, false); $op_name = AB_DateTimeUtils::formatTime($time_output); $output .= "<option value='{$value}'" . selected($value, $selected_value, false) . ">{$op_name}</option>"; $time_output += $ts_length; } $output .= '</select>'; return $output; }
esc_attr_e(get_option('ab_appearance_text_label_finish_by'), 'ab'); ?> " class="ab_editable" id="ab-text-label-finish_by" data-type="text" data-pk="1"><?php esc_html_e(get_option('ab_appearance_text_label_finish_by'), 'ab'); ?> </label> <div> <select class="select-list ab-select-time-to"> <?php for ($i = 28800; $i <= 64800; $i += 3600) { ?> <option<?php selected($i == 64800); ?> ><?php echo AB_DateTimeUtils::formatTime($i); ?> </option> <?php } ?> </select> </div> </div> </div> </div> <div class="ab-row-fluid ab-nav-steps last-row ab-clear"> <button class="ab-right ab-mobile-prev-step ab-btn ab-none ladda-button"> <span><?php _e('Back', 'bookly'); ?>
/** * Render info text into a variable. * * @param string $text * @param AB_UserBookingData $userData * @param int $preset_price * * @return string */ private function _prepareInfoText($text, $userData, $preset_price = null) { if (empty($this->replacement)) { $service = $userData->getService(); $category_name = $service->getCategoryName(); $staff_name = $userData->getStaffName(); $price = $preset_price === null ? $userData->getServicePrice() : $preset_price; $number_of_persons = $userData->get('number_of_persons'); $service_date = AB_DateTimeUtils::formatDate($userData->get('appointment_datetime')); if (get_option('ab_settings_use_client_time_zone')) { $service_time = AB_DateTimeUtils::formatTime(AB_DateTimeUtils::applyTimeZoneOffset($userData->get('appointment_datetime'), $userData->get('time_zone_offset'))); } else { $service_time = AB_DateTimeUtils::formatTime($userData->get('appointment_datetime')); } $this->replacement = array('[[STAFF_NAME]]' => '<b>' . $staff_name . '</b>', '[[SERVICE_NAME]]' => '<b>' . $service->get('title') . '</b>', '[[CATEGORY_NAME]]' => '<b>' . $category_name . '</b>', '[[NUMBER_OF_PERSONS]]' => '<b>' . $number_of_persons . '</b>', '[[SERVICE_TIME]]' => '<b>' . $service_time . '</b>', '[[SERVICE_DATE]]' => '<b>' . $service_date . '</b>', '[[SERVICE_PRICE]]' => '<b>' . AB_Utils::formatPrice($price) . '</b>', '[[TOTAL_PRICE]]' => '<b>' . AB_Utils::formatPrice($price * $number_of_persons) . '</b>', '[[LOGIN_FORM]]' => get_current_user_id() == 0 ? $this->render('_login_form', array(), false) : ''); } return strtr(nl2br($text), $this->replacement); }
/** * Get item data for cart. * * @param $other_data * @param $cart_item * * @return array */ function getItemData($other_data, $cart_item) { if (isset($cart_item['bookly'])) { $info_name = get_option('ab_woocommerce_cart_info_name'); $info_value = get_option('ab_woocommerce_cart_info_value'); $staff = new AB_Staff(); $staff->load($cart_item['bookly']['staff_ids'][0]); $service = new AB_Service(); $service->load($cart_item['bookly']['service_id']); $info_value = strtr($info_value, array('[[APPOINTMENT_TIME]]' => AB_DateTimeUtils::formatTime($cart_item['bookly']['appointment_datetime']), '[[APPOINTMENT_DATE]]' => AB_DateTimeUtils::formatDate($cart_item['bookly']['appointment_datetime']), '[[CATEGORY_NAME]]' => $service->getCategoryName(), '[[SERVICE_NAME]]' => $service->getTitle(), '[[SERVICE_PRICE]]' => $service->get('price'), '[[STAFF_NAME]]' => $staff->get('full_name'))); $other_data[] = array('name' => $info_name, 'value' => $info_value); } return $other_data; }
/** * Get SMS list. * * @param null $start_date * @param null $end_date * @return array|mixed */ public function getSmsList($start_date = null, $end_date = null) { if ($this->token) { $response = $this->sendGetRequest(self::GET_SMS_LIST, array('start_date' => $start_date, 'end_date' => $end_date)); if ($response) { array_walk($response->list, function (&$item) { $date_time = AB_DateTimeUtils::UTCToWPTimeZone($item->datetime); $item->date = AB_DateTimeUtils::formatDate($date_time); $item->time = AB_DateTimeUtils::formatTime($date_time); $item->message = nl2br($item->message); $item->phone = '+' . $item->phone; $item->charge = rtrim($item->charge, '0'); switch ($item->status) { case 1: case 10: $item->status = __('Queued', 'bookly'); $item->charge = '$' . $item->charge; break; case 2: case 16: $item->status = __('Error', 'bookly'); $item->charge = ''; break; case 3: $item->status = __('Out of credit', 'bookly'); $item->charge = ''; break; case 4: $item->status = __('Country out of service', 'bookly'); $item->charge = ''; break; case 11: $item->status = __('Sending', 'bookly'); $item->charge = '$' . $item->charge; break; case 12: $item->status = __('Sent', 'bookly'); $item->charge = '$' . $item->charge; break; case 13: $item->status = __('Delivered', 'bookly'); $item->charge = '$' . $item->charge; break; case 14: $item->status = __('Failed', 'bookly'); $item->charge = '$' . $item->charge; break; case 15: $item->status = __('Undelivered', 'bookly'); $item->charge = '$' . $item->charge; break; default: $item->status = __('Error', 'bookly'); $item->charge = ''; } }); return $response; } } return array(); }
<span style="display: <?php echo $display; ?> "> <?php _e('breaks:', 'bookly'); ?> </span> </td> <td class="breaks-list-content"> <?php foreach ($breaks_list as $break_interval) { ?> <?php $formatted_interval_start = AB_DateTimeUtils::formatTime($break_interval['start_time']); $formatted_interval_end = AB_DateTimeUtils::formatTime($break_interval['end_time']); $formatted_interval = $formatted_interval_start . ' - ' . $formatted_interval_end; if (isset($default_breaks)) { $default_breaks['breaks'][] = array('start_time' => $break_interval['start_time'], 'end_time' => $break_interval['end_time'], 'staff_schedule_item_id' => $break_interval['staff_schedule_item_id']); } $breakStart = new AB_TimeChoiceWidget(array('use_empty' => false)); $break_start_choices = $breakStart->render('', $break_interval['start_time'], array('class' => 'break-start form-control')); $breakEnd = new AB_TimeChoiceWidget(array('use_empty' => false)); $break_end_choices = $breakEnd->render('', $break_interval['end_time'], array('class' => 'break-end form-control')); $this->render('_break', array('staff_schedule_item_break_id' => $break_interval['id'], 'formatted_interval' => $formatted_interval, 'break_start_choices' => $break_start_choices, 'break_end_choices' => $break_end_choices)); ?> <?php } ?> </td> </tr>
<?php foreach ($columns as $column) { ?> <?php switch ($column) { case 'date': ?> <td class="ab-column-date"><?php echo AB_DateTimeUtils::formatDate($a['start_date']); ?> </td><?php break; case 'time': ?> <td class="ab-column-time"><?php echo AB_DateTimeUtils::formatTime($a['start_date']); ?> </td><?php break; case 'price': ?> <td class="ab-column-price"><?php echo AB_Utils::formatPrice($a['price']); ?> </td><?php break; case 'cancel': ?> <td class="ab-column-cancel"> <?php if ($a['start_date'] > current_time('mysql')) {
/** * Get data needed for appointment form initialisation. */ public function executeGetDataForAppointmentForm() { $result = array('staff' => array(), 'customers' => array(), 'custom_fields' => array(), 'time' => array(), 'time_interval' => get_option('ab_settings_time_slot_length') * 60); // Staff list. $staff_members = AB_Utils::isCurrentUserAdmin() ? AB_Staff::query()->sortBy('position')->find() : AB_Staff::query()->where('wp_user_id', get_current_user_id())->find(); /** @var AB_Staff $staff_member */ foreach ($staff_members as $staff_member) { $services = array(); foreach ($staff_member->getStaffServices() as $staff_service) { $services[] = array('id' => $staff_service->service->get('id'), 'title' => sprintf('%s (%s)', $staff_service->service->get('title'), AB_Service::durationToString($staff_service->service->get('duration'))), 'duration' => $staff_service->service->get('duration'), 'capacity' => $staff_service->get('capacity')); } $result['staff'][] = array('id' => $staff_member->get('id'), 'full_name' => $staff_member->get('full_name'), 'services' => $services); } // Customers list. foreach (AB_Customer::query()->sortBy('name')->find() as $customer) { $name = $customer->get('name'); if ($customer->get('email') != '' || $customer->get('phone') != '') { $name .= ' (' . trim($customer->get('email') . ', ' . $customer->get('phone'), ', ') . ')'; } $result['customers'][] = array('id' => $customer->get('id'), 'name' => $name, 'custom_fields' => array(), 'number_of_persons' => 1); } // Time list. $ts_length = AB_BookingConfiguration::getTimeSlotLength(); $time_start = AB_StaffScheduleItem::WORKING_START_TIME; $time_end = AB_StaffScheduleItem::WORKING_END_TIME; // Run the loop. while ($time_start <= $time_end) { $result['time'][] = array('value' => AB_DateTimeUtils::buildTimeString($time_start, false), 'title' => AB_DateTimeUtils::formatTime($time_start)); $time_start += $ts_length; } wp_send_json($result); }
public function executeStaffScheduleHandleBreak() { $start_time = $this->getParameter('start_time'); $end_time = $this->getParameter('end_time'); $working_start = $this->getParameter('working_start'); $working_end = $this->getParameter('working_end'); if (strtotime(date('Y-m-d ' . $start_time)) >= strtotime(date('Y-m-d ' . $end_time))) { wp_send_json(array('success' => false, 'error_msg' => __('The start time must be less than the end one', 'bookly'))); } $staffScheduleItem = new AB_StaffScheduleItem(); $staffScheduleItem->load($this->getParameter('staff_schedule_item_id')); $break_id = $this->getParameter('break_id', 0); $in_working_time = $working_start <= $start_time && $start_time <= $working_end && $working_start <= $end_time && $end_time <= $working_end; if (!$in_working_time || !$staffScheduleItem->isBreakIntervalAvailable($start_time, $end_time, $break_id)) { wp_send_json(array('success' => false, 'error_msg' => __('The requested interval is not available', 'bookly'))); } $formatted_interval_start = AB_DateTimeUtils::formatTime($start_time); $formatted_interval_end = AB_DateTimeUtils::formatTime($end_time); $formatted_interval = $formatted_interval_start . ' - ' . $formatted_interval_end; if ($break_id) { $break = new AB_ScheduleItemBreak(); $break->load($break_id); $break->set('start_time', $start_time); $break->set('end_time', $end_time); $break->save(); wp_send_json(array('success' => true, 'new_interval' => $formatted_interval)); } else { $this->form = new AB_StaffScheduleItemBreakForm(); $this->form->bind($this->getPostParameters()); $staffScheduleItemBreak = $this->form->save(); if ($staffScheduleItemBreak) { $breakStart = new AB_TimeChoiceWidget(array('use_empty' => false)); $break_start_choices = $breakStart->render('', $start_time, array('class' => 'break-start', 'data-default_value' => AB_StaffScheduleItem::WORKING_START_TIME)); $breakEnd = new AB_TimeChoiceWidget(array('use_empty' => false)); $break_end_choices = $breakEnd->render('', $end_time, array('class' => 'break-end', 'data-default_value' => date('H:i:s', strtotime(AB_StaffScheduleItem::WORKING_START_TIME . ' + 1 hour')))); wp_send_json(array('success' => true, 'item_content' => $this->render('_break', array('staff_schedule_item_break_id' => $staffScheduleItemBreak->get('id'), 'formatted_interval' => $formatted_interval, 'break_start_choices' => $break_start_choices, 'break_end_choices' => $break_end_choices), false))); } else { wp_send_json(array('success' => false, 'error_msg' => __('Error adding the break interval', 'bookly'))); } } }
/** * Fetches ids of the available days + the available time range * For the 1st step of the booking wizard * * @return array */ public function fetchAvailableWorkDaysAndTime() { /** @var WP_Locale $wp_locale */ global $wp_locale; $schedule_items = AB_StaffScheduleItem::query('ssi')->select('GROUP_CONCAT( DISTINCT ssi.day_index ORDER BY ssi.day_index ) AS available_day_ids, SUBSTRING_INDEX(MIN(ssi.start_time), \':\', 2) AS min_start_time, SUBSTRING_INDEX(MAX(ssi.end_time), \':\', 2) AS max_end_time')->whereNot('ssi.start_time', null)->fetchArray(); $data = current($schedule_items); $result = array('available_days' => array(), 'time_range' => array()); if ($data['available_day_ids']) { $wp_week_start_day = (int) get_option('start_of_week'); $available_day_ids = explode(',', $data['available_day_ids']); $week_days = array_values($wp_locale->weekday_abbrev); if ($wp_week_start_day >= $available_day_ids[0]) { $list_start = array_slice($week_days, $wp_week_start_day, 7, TRUE); $list_end = array_slice($week_days, 0, $wp_week_start_day, TRUE); $week_days = $list_start + $list_end; } foreach ($week_days as $day_id => $day_name) { if (in_array($day_id + 1, $available_day_ids)) { $result['available_days'][$day_id + 1] = $day_name; } } } if ($data['min_start_time'] && $data['max_end_time']) { $start_timestamp = strtotime(sprintf("1970-01-01 %s", $data['min_start_time'])); $end_timestamp = strtotime(sprintf("1970-01-01 %s", $data['max_end_time'])); $now_timestamp = $start_timestamp; $now_timestamp_print = $start_timestamp; $end_timestamp_print = $end_timestamp; if ($this->client_timezone_offset !== false) { $now_timestamp_print -= ($this->client_timezone_offset + get_option('gmt_offset')) * 3600; $end_timestamp_print -= ($this->client_timezone_offset + get_option('gmt_offset')) * 3600; } while ($now_timestamp <= $end_timestamp) { $result['time_range'][AB_DateTimeUtils::buildTimeString($now_timestamp, false)] = AB_DateTimeUtils::formatTime($now_timestamp_print); // The next value will be rounded to integer number of hours, i.e. e.g. 8:00, 9:00, 10:00 and so on. $now_timestamp = $this->roundTime($now_timestamp + 30 * 60); $now_timestamp_print = $this->roundTime($now_timestamp_print + 30 * 60); } // The last value should always be the end time. $result['time_range'][AB_DateTimeUtils::buildTimeString($end_timestamp, false)] = AB_DateTimeUtils::formatTime($end_timestamp_print); } return $result; }