PluginProbe
Booking Calendar / 11.8.4
Booking Calendar v11.8.4
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 10.11 All 204 releases
booking / includes / booking-appointment / booking-appointment__pricing.php

booking-appointment__pricing.php in Booking Calendar 11.8.4, at includes/booking-appointment/booking-appointment__pricing.php

154 lines 6.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Appointment integration with the established Booking Calendar cost engine.
4 *
5 * @package Booking Calendar
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit;
10 }
11
12 /**
13 * Add a verified public Appointment selection to live cost-calculation params.
14 *
15 * The browser sends the same signed Service/Provider context used by final
16 * submission. Invalid or unrelated requests remain normal resource bookings.
17 *
18 * @param array<string,mixed> $params Existing cost-calculation parameters.
19 *
20 * @return array<string,mixed> Filtered parameters.
21 */
22 function wpbc_booking_appointment_filter_cost_params( $params ) {
23 if ( ! wpbc_appointment_services_is_pricing_available() || ! is_array( $params ) || ! empty( $params['service_id'] ) ) {
24 return $params;
25 }
26
27 // phpcs:disable WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended
28 $service_id = isset( $_POST['appointment_service_id'] ) ? absint( $_POST['appointment_service_id'] ) : 0;
29 $context_token = isset( $_POST['appointment_context_token'] ) ? sanitize_text_field( wp_unslash( $_POST['appointment_context_token'] ) ) : '';
30 // phpcs:enable WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended
31 $resource_id = ! empty( $params['resource_id'] ) ? absint( $params['resource_id'] ) : 0;
32 if ( ! $service_id || ! $resource_id || ! $context_token || ! function_exists( 'wpbc_booking_appointment_validate_submission_context' ) ) {
33 return $params;
34 }
35
36 $context_check = wpbc_booking_appointment_validate_submission_context( $context_token, $service_id, $resource_id );
37 if ( is_wp_error( $context_check ) ) {
38 return $params;
39 }
40
41 $params['service_id'] = $service_id;
42
43 return $params;
44 }
45 add_filter( 'wpbc_booking_cost_calculation_params', 'wpbc_booking_appointment_filter_cost_params', 10, 1 );
46
47 /**
48 * Resolve the immutable or current effective Service for one cost calculation.
49 *
50 * A saved booking snapshot wins so later Service edits cannot rewrite a
51 * historical payment. Before save, the active Service/Provider assignment is
52 * resolved from the database and includes a nullable Provider cost override.
53 *
54 * @param array<string,mixed> $params Cost-calculation parameters.
55 *
56 * @return array<string,mixed>|null Effective Service data, or null.
57 */
58 function wpbc_booking_appointment_get_cost_service( $params ) {
59 static $cache = array();
60
61 if ( ! wpbc_appointment_services_is_pricing_available() || ! function_exists( 'wpbc_appointment_services_repository' ) ) {
62 return null;
63 }
64
65 $booking_id = ! empty( $params['booking_id'] ) ? absint( $params['booking_id'] ) : 0;
66 if ( $booking_id ) {
67 $cache_key = 'booking:' . $booking_id;
68 if ( array_key_exists( $cache_key, $cache ) ) {
69 return $cache[ $cache_key ];
70 }
71 $snapshot = wpbc_appointment_services_repository()->get_appointment_snapshot( $booking_id );
72 if ( $snapshot && isset( $snapshot['base_cost'] ) && is_numeric( $snapshot['base_cost'] ) ) {
73 $cache[ $cache_key ] = $snapshot;
74 return $cache[ $cache_key ];
75 }
76 }
77
78 $service_id = ! empty( $params['service_id'] ) ? absint( $params['service_id'] ) : 0;
79 $resource_id = ! empty( $params['resource_id'] ) ? absint( $params['resource_id'] ) : 0;
80 if ( ! $service_id || ! $resource_id ) {
81 return null;
82 }
83
84 $cache_key = 'selection:' . $service_id . ':' . $resource_id;
85 if ( array_key_exists( $cache_key, $cache ) ) {
86 return $cache[ $cache_key ];
87 }
88 $service = wpbc_appointment_services_repository()->find_active_for_resource( $service_id, $resource_id );
89 $cache[ $cache_key ] = is_wp_error( $service ) ? null : $service;
90
91 return $cache[ $cache_key ];
92 }
93
94 /**
95 * Replace only the calculated resource base total with the effective Service.
96 *
97 * Existing advanced costs, coupons, deposits, taxes, and gateways continue
98 * after this hook in their established order. Non-Appointment calculations
99 * are returned byte-for-byte unchanged.
100 *
101 * @param float|int|string $base_total Calculated resource base total.
102 * @param array<string,mixed> $params Cost-calculation parameters.
103 *
104 * @return float|int|string Effective Appointment base total or original value.
105 */
106 function wpbc_booking_appointment_filter_base_cost_total( $base_total, $params ) {
107 if ( ! wpbc_appointment_services_is_pricing_available() ) {
108 return $base_total;
109 }
110
111 $service = wpbc_booking_appointment_get_cost_service( is_array( $params ) ? $params : array() );
112 if ( ! $service || ! isset( $service['base_cost'] ) || ! is_numeric( $service['base_cost'] ) ) {
113 return $base_total;
114 }
115
116 $service_cost = (float) $service['base_cost'];
117
118 return apply_filters( 'wpbc_booking_appointment_base_cost', $service_cost, $service, $params, $base_total );
119 }
120 add_filter( 'wpbc_booking_cost_base_total', 'wpbc_booking_appointment_filter_base_cost_total', 10, 2 );
121
122 /**
123 * Format a Service price using the active Booking Calendar currency settings.
124 *
125 * Editions below Business Small do not expose the required pricing engine, so
126 * they do not present a price that cannot enter the cost/payment pipeline.
127 *
128 * @param float|int|string $cost Numeric Service price.
129 * @param int $resource_id Provider resource ID.
130 *
131 * @return string Formatted price, or an empty string when pricing is absent.
132 */
133 function wpbc_booking_appointment_format_service_cost( $cost, $resource_id = 0 ) {
134 if ( ! wpbc_appointment_services_is_pricing_available() || ! function_exists( 'wpbc_get_cost_with_currency_for_user' ) || ! is_numeric( $cost ) ) {
135 return '';
136 }
137
138 return (string) wpbc_get_cost_with_currency_for_user( (float) $cost, absint( $resource_id ) );
139 }
140
141 /**
142 * Return the formatted Service price as plain text for escaped UI labels.
143 *
144 * @param float|int|string $cost Numeric Service price.
145 * @param int $resource_id Provider resource ID.
146 *
147 * @return string Plain-text price.
148 */
149 function wpbc_booking_appointment_format_service_cost_text( $cost, $resource_id = 0 ) {
150 $formatted = wpbc_booking_appointment_format_service_cost( $cost, $resource_id );
151
152 return trim( html_entity_decode( wp_strip_all_tags( $formatted ), ENT_QUOTES, get_bloginfo( 'charset' ) ) );
153 }
154