PluginProbe ʕ •ᴥ•ʔ
LatePoint – Calendar Booking Plugin for Appointments and Events / trunk
LatePoint – Calendar Booking Plugin for Appointments and Events vtrunk
5.6.5 5.6.4 5.6.3 5.6.2 5.6.1 5.6.0 5.5.2 5.5.1 5.5.0 5.4.2 trunk 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.1.91 5.1.92 5.1.93 5.1.94 5.2.0 5.2.1 5.2.10 5.2.11 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1
latepoint / lib / controllers / bookings_controller.php
latepoint / lib / controllers Last commit date
activities_controller.php 1 month ago auth_controller.php 3 months ago booking_form_settings_controller.php 3 months ago bookings_controller.php 12 hours ago calendars_controller.php 3 months ago carts_controller.php 12 hours ago controller.php 3 months ago customer_cabinet_controller.php 2 months ago customers_controller.php 12 hours ago dashboard_controller.php 2 months ago default_agent_controller.php 3 months ago events_controller.php 3 months ago form_fields_controller.php 1 week ago integrations_controller.php 3 months ago invoices_controller.php 12 hours ago manage_booking_by_key_controller.php 3 months ago manage_order_by_key_controller.php 3 months ago notifications_controller.php 3 months ago orders_controller.php 12 hours ago pro_controller.php 2 weeks ago process_jobs_controller.php 3 months ago processes_controller.php 1 month ago razorpay_connect_controller.php 1 week ago search_controller.php 3 months ago services_controller.php 3 months ago settings_controller.php 2 months ago steps_controller.php 2 weeks ago stripe_connect_controller.php 1 week ago support_topics_controller.php 3 months ago todos_controller.php 3 months ago transactions_controller.php 12 hours ago wizard_controller.php 1 week ago
bookings_controller.php
623 lines
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit; // Exit if accessed directly.
4 }
5
6
7 if ( ! class_exists( 'OsBookingsController' ) ) :
8
9
10 class OsBookingsController extends OsController {
11
12 private $booking;
13
14 function __construct() {
15 parent::__construct();
16 $this->views_folder = LATEPOINT_VIEWS_ABSPATH . 'bookings/';
17 $this->vars['page_header'] = OsMenuHelper::get_menu_items_by_id( 'appointments' );
18 $this->vars['breadcrumbs'][] = array(
19 'label' => __( 'Appointments', 'latepoint' ),
20 'link' => OsRouterHelper::build_link( [ 'bookings', 'pending_approval' ] ),
21 );
22 }
23
24 public function view_booking_log() {
25 $booking_id = absint( $this->params['booking_id'] );
26 $booking = new OsBookingModel( $booking_id );
27 if ( ! OsRolesHelper::can_user_make_action_on_model_record( $booking, 'view' ) ) {
28 $this->access_not_allowed();
29 return;
30 }
31
32 $activities = new OsActivityModel();
33 $activities = $activities->where( [ 'booking_id' => $booking_id ] )->order_by( 'id desc' )->get_results_as_models();
34
35 $this->vars['booking'] = $booking;
36 $this->vars['activities'] = $activities;
37
38 $this->format_render( __FUNCTION__ );
39 }
40
41 public function grouped_bookings_quick_view() {
42 if ( ! isset( $this->params['booking_id'] ) ) {
43 return false;
44 }
45
46 $booking = new OsBookingModel( $this->params['booking_id'] );
47 if ( ! OsRolesHelper::can_user_make_action_on_model_record( $booking, 'view' ) ) {
48 $this->access_not_allowed();
49 return;
50 }
51 $this->vars['booking'] = $booking;
52
53 $group_bookings = new OsBookingModel();
54 $group_bookings = $group_bookings->where(
55 [
56 'start_time' => $booking->start_time,
57 'start_date' => $booking->start_date,
58 'service_id' => $booking->service_id,
59 'location_id' => $booking->location_id,
60 'agent_id' => $booking->agent_id,
61 ]
62 )->should_not_be_cancelled()->get_results_as_models();
63 $total_attendees = 0;
64 if ( $group_bookings ) {
65 foreach ( $group_bookings as $group_booking ) {
66 $total_attendees = $total_attendees + $group_booking->total_attendees;
67 }
68 }
69 $this->vars['total_attendees'] = $total_attendees;
70 $this->vars['group_bookings'] = $group_bookings;
71 $this->format_render( __FUNCTION__ );
72 }
73
74 public function pending_approval() {
75 $this->vars['page_header'] = __( 'Pending Appointments', 'latepoint' );
76 $this->vars['breadcrumbs'][] = array(
77 'label' => __( 'Pending Appointments', 'latepoint' ),
78 'link' => false,
79 );
80
81 $page_number = isset( $this->params['page_number'] ) ? $this->params['page_number'] : 1;
82 $per_page = OsSettingsHelper::get_number_of_records_per_page();
83 $offset = ( $page_number > 1 ) ? ( ( $page_number - 1 ) * $per_page ) : 0;
84
85 $bookings = new OsBookingModel();
86 $query_args = [ 'status' => OsBookingHelper::get_booking_statuses_for_pending_page() ];
87
88 $bookings->where( $query_args )->filter_allowed_records();
89
90 $count_total_bookings = clone $bookings;
91 $total_bookings = $count_total_bookings->count();
92
93 $this->vars['bookings'] = $bookings->set_limit( $per_page )->set_offset( $offset )->order_by( 'id desc' )->get_results_as_models();
94
95 $total_pages = ceil( $total_bookings / $per_page );
96
97 $this->vars['total_pages'] = $total_pages;
98 $this->vars['total_bookings'] = $total_bookings;
99 $this->vars['per_page'] = $per_page;
100 $this->vars['current_page_number'] = $page_number;
101
102 $this->vars['showing_from'] = ( ( $page_number - 1 ) * $per_page ) ? ( ( $page_number - 1 ) * $per_page ) : 1;
103 $this->vars['showing_to'] = min( $page_number * $per_page, $this->vars['total_bookings'] );
104
105 $this->format_render( __FUNCTION__ );
106 }
107
108 public function customize_table() {
109 $this->vars['selected_columns'] = OsSettingsHelper::get_selected_columns_for_bookings_table();
110 $this->vars['available_columns'] = OsSettingsHelper::get_available_columns_for_bookings_table();
111 $this->vars['ordered_columns'] = OsSettingsHelper::get_ordered_bookings_table_columns();
112
113 $this->format_render( __FUNCTION__ );
114 }
115
116 public function index() {
117
118 $this->vars['page_header'] = false;
119 $this->vars['breadcrumbs'][] = array(
120 'label' => __( 'All', 'latepoint' ),
121 'link' => false,
122 );
123
124 $page_number = isset( $this->params['page_number'] ) ? $this->params['page_number'] : 1;
125 $per_page = OsSettingsHelper::get_number_of_records_per_page();
126 $offset = ( $page_number > 1 ) ? ( ( $page_number - 1 ) * $per_page ) : 0;
127
128 $customer = new OsCustomerModel();
129
130 $bookings = new OsBookingModel();
131 $query_args = [];
132
133 $selected_columns = OsSettingsHelper::get_selected_columns_for_bookings_table();
134 $available_columns = OsSettingsHelper::get_available_columns_for_bookings_table();
135 $ordered_columns = OsSettingsHelper::get_ordered_bookings_table_columns();
136
137 $filter = $this->params['filter'] ?? false;
138
139 $order_by = [
140 'key' => 'booking_id',
141 'direction' => 'desc',
142 'column' => 'id',
143 ];
144
145 // TABLE SEARCH FILTERS
146 if ( $filter ) {
147 if ( ! empty( $filter['records_ordered_by_key'] ) && ! empty( $filter['records_ordered_by_direction'] ) ) {
148 if ( in_array( $filter['records_ordered_by_direction'], [ 'desc', 'asc' ] ) ) {
149 $order_by['direction'] = $filter['records_ordered_by_direction'];
150 }
151 $order_by['key'] = $filter['records_ordered_by_key'];
152 switch ( $filter['records_ordered_by_key'] ) {
153 case 'booking_id':
154 $order_by['column'] = 'id';
155 break;
156 case 'booking_start_datetime':
157 $order_by['column'] = 'start_datetime_utc';
158 break;
159 case 'booking_created_on':
160 $order_by['column'] = 'created_at';
161 break;
162 case 'booking_time_left':
163 $order_by['column'] = 'start_datetime_utc';
164 break;
165 }
166 }
167 if ( ! empty( $filter['service_id'] ) ) {
168 $query_args['service_id'] = $filter['service_id'];
169 }
170 if ( ! empty( $filter['agent_id'] ) ) {
171 $query_args['agent_id'] = $filter['agent_id'];
172 }
173 if ( ! empty( $filter['location_id'] ) ) {
174 $query_args['location_id'] = $filter['location_id'];
175 }
176 if ( ! empty( $filter['time_status'] ) ) {
177 switch ( $filter['time_status'] ) {
178 case 'now':
179 $query_args['start_datetime_utc <='] = OsTimeHelper::now_datetime_utc_in_db_format();
180 $query_args['end_datetime_utc >='] = OsTimeHelper::now_datetime_utc_in_db_format();
181 break;
182 case 'upcoming':
183 $query_args['start_datetime_utc >='] = OsTimeHelper::now_datetime_utc_in_db_format();
184 break;
185 case 'past':
186 $query_args['end_datetime_utc <='] = OsTimeHelper::now_datetime_utc_in_db_format();
187 break;
188 }
189 }
190 if ( ! empty( $filter['status'] ) ) {
191 $query_args[ LATEPOINT_TABLE_BOOKINGS . '.status' ] = $filter['status'];
192 }
193 if ( ! empty( $filter['payment_status'] ) ) {
194 $query_args[ LATEPOINT_TABLE_BOOKINGS . '.payment_status' ] = $filter['payment_status'];
195 }
196 if ( ! empty( $filter['id'] ) ) {
197 $query_args[ LATEPOINT_TABLE_BOOKINGS . '.id' ] = $filter['id'];
198 }
199 if ( ! empty( $filter['created_date_from'] ) && ! empty( $filter['created_date_to'] ) ) {
200 $query_args[ LATEPOINT_TABLE_BOOKINGS . '.created_at >=' ] = $filter['created_date_from'] . ' 00:00:00';
201 $query_args[ LATEPOINT_TABLE_BOOKINGS . '.created_at <=' ] = $filter['created_date_to'] . ' 23:59:59';
202 }
203 if ( ! empty( $filter['booking_date_from'] ) && ! empty( $filter['booking_date_to'] ) ) {
204 $query_args[ LATEPOINT_TABLE_BOOKINGS . '.start_date >=' ] = $filter['booking_date_from'];
205 $query_args[ LATEPOINT_TABLE_BOOKINGS . '.start_date <=' ] = $filter['booking_date_to'];
206 }
207
208 $selected_columns = OsSettingsHelper::get_selected_columns_for_bookings_table();
209 if ( ! empty( $filter['order'] ) ) {
210 $bookings->select( LATEPOINT_TABLE_BOOKINGS . '.*' );
211 $bookings->join( LATEPOINT_TABLE_ORDER_ITEMS, [ 'id' => LATEPOINT_TABLE_BOOKINGS . '.order_item_id' ] );
212 $bookings->join( LATEPOINT_TABLE_ORDERS, [ 'id' => LATEPOINT_TABLE_ORDER_ITEMS . '.order_id' ] );
213 if ( ! empty( $filter['order']['payment_status'] ) ) {
214 $bookings->select( LATEPOINT_TABLE_ORDERS . '.payment_status' );
215 $query_args[ LATEPOINT_TABLE_ORDERS . '.payment_status' ] = $filter['order']['payment_status'];
216 }
217 }
218 if ( ! empty( $filter['customer'] ) ) {
219 $bookings->select( LATEPOINT_TABLE_BOOKINGS . '.*' );
220 if ( ! empty( $filter['customer']['full_name'] ) ) {
221 $bookings->select( LATEPOINT_TABLE_CUSTOMERS . '.first_name, ' . LATEPOINT_TABLE_CUSTOMERS . '.last_name' );
222 $query_args[ 'concat_ws(" ", ' . LATEPOINT_TABLE_CUSTOMERS . '.first_name,' . LATEPOINT_TABLE_CUSTOMERS . '.last_name) LIKE' ] = '%' . $filter['customer']['full_name'] . '%';
223 $this->vars['customer_name_query'] = $filter['customer']['full_name'];
224 }
225 $bookings->join( LATEPOINT_TABLE_CUSTOMERS, [ 'id' => LATEPOINT_TABLE_BOOKINGS . '.customer_id' ] );
226
227
228 if ( ! empty( $selected_columns['customer'] ) ) {
229 $meta_filter = [];
230 foreach ( $selected_columns['customer'] as $customer_column_key ) {
231
232 if ( isset( $available_columns['customer'][ $customer_column_key ] ) && ! empty( $filter['customer'][ $customer_column_key ] ) ) {
233
234 if ( in_array( $customer_column_key, $customer->get_params_to_save() ) ) {
235 // native field
236 $bookings->select( LATEPOINT_TABLE_CUSTOMERS . '.' . $customer_column_key );
237 $query_args[ LATEPOINT_TABLE_CUSTOMERS . '.' . $customer_column_key . ' LIKE' ] = '%' . $filter['customer'][ $customer_column_key ] . '%';
238 } else {
239 // meta field
240 $meta_filter[ $customer_column_key ] = $filter['customer'][ $customer_column_key ];
241 }
242 }
243 }
244 if ( count( $meta_filter ) ) {
245 $customers_ids = OsMetaHelper::get_customers_by_filter( $meta_filter ) ?: [ - 1 ];
246 $query_args[ LATEPOINT_TABLE_CUSTOMERS . '.id IN' ] = $customers_ids;
247 }
248 }
249 }
250 // filters for custom selected columns, only related to booking fields
251 if ( ! empty( $selected_columns['booking'] ) ) {
252 foreach ( $selected_columns['booking'] as $booking_column_key ) {
253 if ( ! empty( $available_columns['booking'][ $booking_column_key ] ) && ! empty( $filter[ $booking_column_key ] ) ) {
254 $query_args[ $booking_column_key . ' LIKE' ] = '%' . $filter[ $booking_column_key ] . '%';
255 }
256 }
257 }
258 }
259
260 $this->vars['agents_list'] = OsAgentHelper::get_agents_list( true );
261 $this->vars['locations_list'] = OsLocationHelper::get_locations_list( true );
262 $this->vars['services_list'] = OsServiceHelper::get_services_list( true );
263
264 $this->vars['selected_columns'] = $selected_columns;
265 $this->vars['available_columns'] = $available_columns;
266 $this->vars['ordered_columns'] = $ordered_columns;
267
268 $this->vars['records_ordered_by_key'] = $order_by['key'];
269 $this->vars['records_ordered_by_direction'] = $order_by['direction'];
270
271 $this->vars['can_bulk_delete'] = OsRolesHelper::can_user_perform_model_action( 'OsBookingModel', 'delete' );
272
273 // OUTPUT CSV IF REQUESTED
274 if ( isset( $this->params['download'] ) && $this->params['download'] == 'csv' ) {
275 $csv_filename = 'all_bookings_' . OsUtilHelper::random_text() . '.csv';
276
277 header( 'Content-Type: text/csv' );
278 header( "Content-Disposition: attachment; filename={$csv_filename}" );
279
280 $labels_row = [
281 __( 'ID', 'latepoint' ),
282 __( 'Service', 'latepoint' ),
283 __( 'Start Date & Time', 'latepoint' ),
284 __( 'Duration', 'latepoint' ),
285 __( 'Customer', 'latepoint' ),
286 __( 'Customer Phone', 'latepoint' ),
287 __( 'Customer Email', 'latepoint' ),
288 __( 'Agent', 'latepoint' ),
289 __( 'Agent Phone', 'latepoint' ),
290 __( 'Agent Email', 'latepoint' ),
291 __( 'Status', 'latepoint' ),
292 __( 'Price', 'latepoint' ),
293 __( 'Booked On', 'latepoint' ),
294 ];
295
296
297 $bookings_data = [];
298 $bookings_data[] = $labels_row;
299
300
301 $bookings_arr = $bookings->where( $query_args )->filter_allowed_records()->order_by( $order_by['column'] . ' ' . $order_by['direction'] )->get_results_as_models();
302
303 if ( $bookings_arr ) {
304 foreach ( $bookings_arr as $booking ) {
305 $order_item = new OsOrderItemModel( $booking->order_item_id );
306 $values_row = [
307 $booking->id,
308 $booking->service->name,
309 $booking->nice_start_datetime,
310 $booking->get_total_duration(),
311 $booking->customer->full_name,
312 $booking->customer->phone,
313 $booking->customer->email,
314 $booking->agent->full_name,
315 $booking->agent->phone,
316 $booking->agent->email,
317 $booking->nice_status,
318 OsMoneyHelper::format_price( $order_item->get_total(), true, false ),
319 $booking->nice_created_at,
320 ];
321 $values_row = apply_filters( 'latepoint_booking_row_for_csv_export', $values_row, $booking, $this->params );
322 $bookings_data[] = $values_row;
323 }
324 }
325
326 $bookings_data = apply_filters( 'latepoint_bookings_data_for_csv_export', $bookings_data, $this->params );
327 OsCSVHelper::array_to_csv( $bookings_data );
328
329 return;
330 }
331
332 $query_args = OsRolesHelper::filter_allowed_records_from_arguments_or_filter( $query_args );
333 $bookings->where( $query_args )->filter_allowed_records();
334 $count_total_bookings = clone $bookings;
335 $total_bookings = $count_total_bookings->count();
336
337 $this->vars['bookings'] = $bookings->set_limit( $per_page )->set_offset( $offset )->order_by( $order_by['column'] . ' ' . $order_by['direction'] )->get_results_as_models();
338 $this->vars['total_bookings'] = $total_bookings;
339 $total_pages = ceil( $total_bookings / $per_page );
340
341 $this->vars['total_pages'] = $total_pages;
342 $this->vars['per_page'] = $per_page;
343 $this->vars['current_page_number'] = $page_number;
344 $this->vars['total_records'] = $total_bookings;
345
346 $this->vars['showing_from'] = ( ( $page_number - 1 ) * $per_page ) ? ( ( $page_number - 1 ) * $per_page ) : 1;
347 $this->vars['showing_to'] = min( $page_number * $per_page, $this->vars['total_bookings'] );
348
349 $this->format_render(
350 [
351 'json_view_name' => '_table_body',
352 'html_view_name' => __FUNCTION__,
353 ],
354 [],
355 [
356 'total_pages' => $total_pages,
357 'showing_from' => $this->vars['showing_from'],
358 'showing_to' => $this->vars['showing_to'],
359 'total_records' => $total_bookings,
360 ]
361 );
362 }
363
364 function quick_availability() {
365
366 $trigger_form_booking_id = $this->params['trigger_form_booking_id'];
367 $trigger_form_order_item_id = $this->params['trigger_form_order_item_id'];
368
369 $booking = OsOrdersHelper::create_booking_object_from_booking_data_form( $this->params['order_items'][ $trigger_form_order_item_id ]['bookings'][ $trigger_form_booking_id ] );
370
371 $calendar_start_date = isset( $this->params['start_date'] ) ? new OsWpDateTime( $this->params['start_date'] ) : new OsWpDateTime( $booking->start_date );
372 // show one more day before so the current selection does not look weird
373 if ( isset( $this->params['previous_days'] ) ) {
374 $calendar_end_date = clone $calendar_start_date;
375 $calendar_start_date->modify( '-60 days' );
376 } else {
377 if ( ! isset( $this->params['show_days_only'] ) ) {
378 $calendar_start_date->modify( '-1 day' );
379 }
380 $calendar_end_date = clone $calendar_start_date;
381 $calendar_end_date->modify( '+60 days' );
382 }
383
384 if ( OsAuthHelper::get_current_user()->is_single_record_allowed( 'agent' ) ) {
385 $booking->agent_id = OsRolesHelper::get_allowed_records( 'agent' )[0];
386 }
387
388 $work_periods = OsWorkPeriodsHelper::get_work_periods(
389 new \LatePoint\Misc\Filter(
390 [
391 'date_from' => $calendar_start_date->format( 'Y-m-d' ),
392 'date_to' => $calendar_end_date->format( 'Y-m-d' ),
393 'service_id' => $booking->service_id,
394 'agent_id' => $booking->agent_id,
395 'location_id' => $booking->location_id,
396 ]
397 )
398 );
399 $work_start_end = OsWorkPeriodsHelper::get_work_start_end_time( $work_periods );
400
401 $booking_request = \LatePoint\Misc\BookingRequest::create_from_booking_model( $booking );
402 $settings = [];
403 $settings['accessed_from_backend'] = true;
404 if ( ! $booking->is_new_record() ) {
405 $settings['exclude_booking_ids'] = [ $booking->id ];
406 }
407 $resources = OsResourceHelper::get_resources_grouped_by_day( $booking_request, $calendar_start_date, $calendar_end_date, $settings );
408 $work_boundaries = OsResourceHelper::get_work_boundaries_for_groups_of_resources( $resources );
409
410 $this->vars['trigger_form_booking_id'] = $trigger_form_booking_id;
411 $this->vars['trigger_form_order_item_id'] = $trigger_form_order_item_id;
412
413 $this->vars['booking'] = $booking;
414 $this->vars['work_boundaries'] = $work_boundaries;
415 $this->vars['show_days_only'] = isset( $this->params['show_days_only'] ) ? true : false;
416
417 $this->vars['timeblock_interval'] = $booking->service->get_timeblock_interval();
418 $this->vars['calendar_start_date'] = $calendar_start_date;
419 $this->vars['calendar_end_date'] = $calendar_end_date;
420 $this->vars['booking_request'] = $booking_request;
421 $this->vars['resources'] = $resources;
422
423 $agents = new OsAgentModel();
424 $this->vars['agents'] = $agents->filter_allowed_records()->get_results_as_models();
425
426 $this->format_render( __FUNCTION__ );
427 }
428
429
430 /**
431 * Maximum number of appointments accepted in a single bulk-delete request.
432 * Acts as a guard against accidental or malicious oversized payloads.
433 */
434 const BULK_DESTROY_MAX_IDS = 100;
435
436 /**
437 * Bulk-delete appointments by ID.
438 *
439 * Expects POST params:
440 * - _wpnonce: nonce for action 'bulk_destroy_bookings'.
441 * - ids: array of booking IDs (or comma-separated string).
442 *
443 * Verifies the user can delete bookings, validates input, then attempts to
444 * delete each ID after a per-record capability check. Fires the standard
445 * latepoint_booking_will_be_deleted / latepoint_booking_deleted hooks per
446 * successful deletion and logs activity.
447 *
448 * Responds with JSON containing status, message, deleted_ids, failed_ids,
449 * deleted_count and failed_count.
450 *
451 * @return void
452 */
453 public function bulk_destroy() {
454 $this->check_nonce( 'bulk_destroy_bookings' );
455
456 if ( ! OsRolesHelper::can_user_perform_model_action( 'OsBookingModel', 'delete' ) ) {
457 $this->send_json(
458 array(
459 'status' => LATEPOINT_STATUS_ERROR,
460 'message' => __( 'You do not have permission to delete appointments.', 'latepoint' ),
461 )
462 );
463 return;
464 }
465
466 $raw_ids = $this->params['ids'] ?? array();
467 if ( ! is_array( $raw_ids ) ) {
468 $raw_ids = explode( ',', (string) $raw_ids );
469 }
470
471 $ids = array();
472 foreach ( $raw_ids as $raw_id ) {
473 $id = absint( $raw_id );
474 if ( $id ) {
475 $ids[ $id ] = $id;
476 }
477 }
478
479 if ( empty( $ids ) ) {
480 $this->send_json(
481 array(
482 'status' => LATEPOINT_STATUS_ERROR,
483 'message' => __( 'No appointments selected.', 'latepoint' ),
484 )
485 );
486 return;
487 }
488
489 if ( count( $ids ) > self::BULK_DESTROY_MAX_IDS ) {
490 $this->send_json(
491 array(
492 'status' => LATEPOINT_STATUS_ERROR,
493 'message' => sprintf(
494 /* translators: %d: maximum number of appointments allowed in a single bulk action */
495 __( 'Too many appointments selected. Please delete in batches of %d or fewer.', 'latepoint' ),
496 self::BULK_DESTROY_MAX_IDS
497 ),
498 )
499 );
500 return;
501 }
502
503 ignore_user_abort( true );
504 if ( function_exists( 'set_time_limit' ) ) {
505 // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
506 @set_time_limit( 0 );
507 }
508
509 $deleted_ids = array();
510 $failed_ids = array();
511
512 foreach ( $ids as $id ) {
513 $booking = new OsBookingModel( $id );
514 if ( $booking->is_new_record() ) {
515 $failed_ids[] = $id;
516 continue;
517 }
518 if ( ! OsRolesHelper::can_user_make_action_on_model_record( $booking, 'delete' ) ) {
519 $failed_ids[] = $id;
520 continue;
521 }
522
523 /**
524 * Fires right before a booking is about to be deleted via bulk delete.
525 *
526 * @param {integer} $booking_id ID of the booking that will be deleted.
527 * @since 5.2.0
528 * @hook latepoint_booking_will_be_deleted
529 */
530 do_action( 'latepoint_booking_will_be_deleted', $id );
531
532 if ( $booking->delete() ) {
533 /**
534 * Fires right after a booking has been deleted via bulk delete.
535 *
536 * @param {integer} $booking_id ID of the booking that was deleted.
537 * @since 5.2.0
538 * @hook latepoint_booking_deleted
539 */
540 do_action( 'latepoint_booking_deleted', $id );
541 OsActivitiesHelper::log_booking_deleted( $booking );
542 $deleted_ids[] = $id;
543 } else {
544 $failed_ids[] = $id;
545 }
546 }
547
548 $deleted_count = count( $deleted_ids );
549 $failed_count = count( $failed_ids );
550
551 if ( $deleted_count && ! $failed_count ) {
552 $status = LATEPOINT_STATUS_SUCCESS;
553 $message = sprintf(
554 /* translators: %d: number of appointments deleted */
555 _n( '%d appointment deleted successfully.', '%d appointments deleted successfully.', $deleted_count, 'latepoint' ),
556 $deleted_count
557 );
558 } elseif ( $deleted_count && $failed_count ) {
559 $status = LATEPOINT_STATUS_SUCCESS;
560 $message = sprintf(
561 /* translators: 1: number of appointments deleted, 2: number of appointments that could not be deleted */
562 __( '%1$d appointment(s) deleted. %2$d could not be deleted.', 'latepoint' ),
563 $deleted_count,
564 $failed_count
565 );
566 } else {
567 $status = LATEPOINT_STATUS_ERROR;
568 $message = sprintf(
569 /* translators: %d: number of appointments that could not be deleted */
570 _n( '%d appointment could not be deleted.', '%d appointments could not be deleted.', $failed_count, 'latepoint' ),
571 $failed_count
572 );
573 }
574
575 $this->send_json(
576 array(
577 'status' => $status,
578 'message' => $message,
579 'deleted_ids' => $deleted_ids,
580 'failed_ids' => $failed_ids,
581 'deleted_count' => $deleted_count,
582 'failed_count' => $failed_count,
583 )
584 );
585 }
586
587
588 function change_status() {
589
590 if ( filter_var( $this->params['id'], FILTER_VALIDATE_INT ) ) {
591 $this->check_nonce( 'change_status_booking_' . $this->params['id'] );
592 $booking_id = $this->params['id'];
593 $new_status = $this->params['status'];
594 $booking = new OsBookingModel( $booking_id );
595 if ( ! OsRolesHelper::can_user_make_action_on_model_record( $booking, 'edit' ) ) {
596 exit;
597 }
598
599 if ( $booking->update_status( $new_status ) ) {
600 $status = LATEPOINT_STATUS_SUCCESS;
601 $response_html = __( 'Appointment Status Updated', 'latepoint' );
602 } else {
603 $status = LATEPOINT_STATUS_ERROR;
604 $response_html = __( 'Error Updating Booking Status!', 'latepoint' ) . ' ' . implode( ',', $booking->get_error_messages() );
605 }
606 } else {
607 $status = LATEPOINT_STATUS_ERROR;
608 $response_html = __( 'Error Updating Booking Status! Invalid ID', 'latepoint' );
609 }
610
611 if ( $this->get_return_format() == 'json' ) {
612 $this->send_json(
613 array(
614 'status' => $status,
615 'message' => $response_html,
616 )
617 );
618 }
619 }
620 }
621
622 endif;
623