PluginProbe
Booking Calendar / 11.7
Booking Calendar v11.7
11.9 11.8.4 11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 All 205 releases
booking / includes / page-catalog-booking-resources / ajax / booking-resource-details.php

booking-resource-details.php in Booking Calendar 11.7, at includes/page-catalog-booking-resources/ajax/booking-resource-details.php

120 lines 4.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Lazy read-only details endpoint for the independent Resources catalog.
4 *
5 * @package Booking Calendar
6 * @since 11.6.0
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * Send a normalized lazy-details error response.
15 *
16 * @param int $request_id Client details-request sequence.
17 * @param WP_Error $error Safe error without internal diagnostics.
18 * @param int $status HTTP response status.
19 * @param bool $retryable Whether retrying may succeed.
20 *
21 * @return void Terminates the AJAX request with JSON.
22 */
23 function wpbc_catalog_booking_resource_send_details_error( $request_id, $error, $status, $retryable = false ) {
24 wp_send_json(
25 array(
26 'success' => false,
27 'schema_version' => 1,
28 'catalog_id' => 'catalog_booking_resources',
29 'request_id' => max( 0, absint( $request_id ) ),
30 'error' => array(
31 'code' => sanitize_key( $error->get_error_code() ),
32 'message' => sanitize_text_field( $error->get_error_message() ),
33 'retryable' => (bool) $retryable,
34 ),
35 ),
36 absint( $status )
37 );
38 }
39
40 /**
41 * Return a positive scalar integer from the details payload.
42 *
43 * @param array $request_values Untrusted request values.
44 * @param string $request_key Allow-listed request key.
45 * @param bool $allow_zero Whether zero is valid.
46 *
47 * @return int|false Normalized integer or false for malformed input.
48 */
49 function wpbc_catalog_booking_resource_get_details_integer( $request_values, $request_key, $allow_zero = false ) {
50 if ( ! is_array( $request_values ) || ! isset( $request_values[ $request_key ] ) || ! is_scalar( $request_values[ $request_key ] ) ) {
51 return false;
52 }
53 $raw_integer = (string) $request_values[ $request_key ];
54 if ( ! preg_match( '/^\d+$/', $raw_integer ) ) {
55 return false;
56 }
57 $integer = (int) $raw_integer;
58
59 return $allow_zero || 0 < $integer ? $integer : false;
60 }
61
62 /**
63 * Serve authorized normalized details for one Resource.
64 *
65 * Authorization is repeated at the transport and repository boundaries. The
66 * endpoint performs no SQL and returns no HTML; the browser renders the DTO
67 * through the registered Resource details WP template.
68 *
69 * @return void Terminates the AJAX request with JSON.
70 */
71 function wpbc_catalog_booking_resource_ajax_details() {
72 $configuration = WPBC_UI_Catalog_Registry::get_instance()->get_configuration( 'catalog_booking_resources' );
73 if ( empty( $configuration ) ) {
74 wpbc_catalog_booking_resource_send_details_error( 0, new WP_Error( 'wpbc_catalog_booking_resource_details_unavailable', __( 'The Booking Resource details are unavailable.', 'booking' ) ), 503, true );
75 }
76
77 // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Verified immediately below using the registered nonce action.
78 $request_values = is_array( $_POST ) ? wp_unslash( $_POST ) : array();
79 $request_id = wpbc_catalog_booking_resource_get_details_integer( $request_values, 'request_id', true );
80 $request_id = false === $request_id ? 0 : $request_id;
81 if ( false === check_ajax_referer( $configuration['nonce_name'], 'nonce', false ) ) {
82 wpbc_catalog_booking_resource_send_details_error( $request_id, new WP_Error( 'wpbc_catalog_booking_resource_details_invalid_nonce', __( 'Security check failed.', 'booking' ) ), 403 );
83 }
84 if ( ! current_user_can( wpbc_catalog_booking_resources_get_manage_capability() ) ) {
85 wpbc_catalog_booking_resource_send_details_error( $request_id, new WP_Error( 'wpbc_catalog_booking_resource_details_forbidden', __( 'You do not have permission to view Booking Resource details.', 'booking' ) ), 403 );
86 }
87
88 $resource_id = wpbc_catalog_booking_resource_get_details_integer( $request_values, 'resource_id' );
89 if ( false === $resource_id ) {
90 wpbc_catalog_booking_resource_send_details_error( $request_id, new WP_Error( 'wpbc_catalog_booking_resource_details_invalid_request', __( 'The Booking Resource details request is invalid.', 'booking' ) ), 400 );
91 }
92
93 $repository = new WPBC_Catalog_Booking_Resources_Repository();
94 $resource = $repository->get_resource_details( $resource_id );
95 if ( is_wp_error( $resource ) ) {
96 wpbc_catalog_booking_resource_send_details_error( $request_id, $resource, 500, true );
97 }
98 if ( null === $resource ) {
99 wpbc_catalog_booking_resource_send_details_error( $request_id, new WP_Error( 'wpbc_catalog_booking_resource_details_not_found', __( 'The Booking Resource is unavailable or you do not have permission to view it.', 'booking' ) ), 404 );
100 }
101
102 $details = ( new WPBC_Catalog_Booking_Resource_Details_DTO() )->create( $resource );
103 if ( is_wp_error( $details ) ) {
104 wpbc_catalog_booking_resource_send_details_error( $request_id, $details, 500 );
105 }
106
107 wp_send_json(
108 array(
109 'success' => true,
110 'schema_version' => 1,
111 'catalog_id' => 'catalog_booking_resources',
112 'request_id' => $request_id,
113 'resource_id' => $resource_id,
114 'details' => $details,
115 ),
116 200
117 );
118 }
119 add_action( 'wp_ajax_WPBC_AJX_CATALOG_BOOKING_RESOURCE_DETAILS', 'wpbc_catalog_booking_resource_ajax_details' );
120