PluginProbe
Booking Calendar / 11.8.1
Booking Calendar v11.8.1
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 10.11.2 10.11.3 All 202 releases
booking / includes / _front_end / date-hints.php

date-hints.php in Booking Calendar 11.8.1, at includes/_front_end/date-hints.php

300 lines 9.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Front-end date hints for Booking Calendar Free.
4 *
5 * This small layer supports lightweight date-selection hints without loading the
6 * Business Medium cost-calculation pipeline. Business Medium and higher keep
7 * using their existing implementation.
8 *
9 * @package Booking Calendar
10 */
11
12 if ( ! defined( 'ABSPATH' ) ) {
13 exit;
14 }
15
16 // FixIn: 10.15.6.2.
17
18 /**
19 * Free date hints runtime.
20 */
21 class WPBC_Free_Date_Hints {
22
23 /**
24 * Register hooks.
25 *
26 * @return void
27 */
28 public static function init() {
29
30 add_bk_filter( 'wpbc_update_bookingform_content__after_load', array( __CLASS__, 'replace_hints_in_form' ) );
31 add_filter( 'wpbc_booking_form_content__after_load', array( __CLASS__, 'replace_hints_in_form' ), 10, 3 );
32
33 add_bk_action( 'wpdev_ajax_show_cost', array( __CLASS__, 'ajax_show_hints' ) );
34
35 add_action( 'wpbc_enqueue_js_files', array( __CLASS__, 'enqueue_js' ), 10, 1 );
36 }
37
38 /**
39 * Is this Free implementation active?
40 *
41 * @return bool
42 */
43 private static function is_active() {
44
45 return ! class_exists( 'wpdev_bk_biz_m' );
46 }
47
48 /**
49 * Hint definitions supported by this Free module.
50 *
51 * Add future date/time hint shortcodes here.
52 *
53 * @return array
54 */
55 private static function get_hint_definitions() {
56
57 return array(
58 'check_in_date_hint' => array(
59 'default' => '...',
60 ),
61 'check_out_date_hint' => array(
62 'default' => '...',
63 ),
64 'selected_dates_hint' => array(
65 'default' => '...',
66 ),
67 'days_number_hint' => array(
68 'default' => '...',
69 ),
70 'start_time_hint' => array(
71 'default' => '...',
72 ),
73 'end_time_hint' => array(
74 'default' => '...',
75 ),
76 );
77 }
78
79 /**
80 * Enqueue front-end JS.
81 *
82 * @param string $where_to_load Loading context.
83 *
84 * @return void
85 */
86 public static function enqueue_js( $where_to_load ) {
87
88 if ( ! self::is_active() ) {
89 return;
90 }
91
92 if ( ! in_array( $where_to_load, array( 'client', 'both' ), true ) ) {
93 return;
94 }
95
96 wp_enqueue_script(
97 'wpbc-free-date-hints',
98 wpbc_plugin_url( '/js/wpbc-free-date-hints.js' ),
99 array( 'jquery', 'wpbc_capacity' ),
100 WP_BK_VERSION_NUM,
101 array( 'in_footer' => WPBC_JS_IN_FOOTER )
102 );
103 }
104
105 /**
106 * Replace supported hint shortcodes in booking form markup.
107 *
108 * @param string $form_content Booking form markup.
109 * @param int $resource_id Booking resource ID.
110 * @param string $form_slug Booking form slug.
111 *
112 * @return string
113 */
114 public static function replace_hints_in_form( $form_content, $resource_id = 1, $form_slug = 'standard' ) {
115
116 if ( ! self::is_active() ) {
117 return $form_content;
118 }
119
120 $resource_id = (int) $resource_id;
121
122 foreach ( self::get_hint_definitions() as $hint_name => $hint_params ) {
123 $form_content = self::replace_single_hint_shortcode(
124 $form_content,
125 array(
126 'shortcode' => '[' . $hint_name . ']',
127 'span_class' => $hint_name . '_tip' . $resource_id,
128 'span_value' => $hint_params['default'],
129 'input_name' => $hint_name . $resource_id,
130 'input_data' => $hint_params['default'],
131 )
132 );
133 }
134
135 return $form_content;
136 }
137
138 /**
139 * Replace one hint shortcode, preserving support for repeated usage.
140 *
141 * The first occurrence receives a stable ID and hidden input; additional
142 * occurrences receive the same class, matching the Pro hint convention.
143 *
144 * @param string $form_content Booking form markup.
145 * @param array $params Replacement params.
146 *
147 * @return string
148 */
149 private static function replace_single_hint_shortcode( $form_content, $params ) {
150
151 $shortcode = str_replace( array( '[', ']' ), '', $params['shortcode'] );
152 $pattern = '/\[' . preg_quote( $shortcode, '/' ) . '\]/';
153
154 $first_html = '<span class="wpbc_field_hint wpbc_free_date_hint" id="' . esc_attr( $params['span_class'] ) . '">' . esc_html( $params['span_value'] ) . '</span>' .
155 '<input class="wpbc_field_hint wpbc_free_date_hint" id="' . esc_attr( $params['input_name'] ) . '" name="' . esc_attr( $params['input_name'] ) . '" value="' . esc_attr( $params['input_data'] ) . '" style="display:none;" type="text" />';
156
157 $form_content = preg_replace( $pattern, $first_html, $form_content, 1 );
158
159 $other_html = '<span class="wpbc_field_hint wpbc_free_date_hint ' . esc_attr( $params['span_class'] ) . '">' . esc_html( $params['span_value'] ) . '</span>';
160
161 return str_replace( '[' . $shortcode . ']', $other_html, $form_content );
162 }
163
164 /**
165 * AJAX responder for Free date hints.
166 *
167 * @return void
168 */
169 public static function ajax_show_hints() {
170
171 if ( ! self::is_active() ) {
172 return;
173 }
174
175 $default_resource_id = 1;
176 if ( class_exists( 'WPBC_FE_Attr_Postprocessor' ) && method_exists( 'WPBC_FE_Attr_Postprocessor', 'get_default_booking_resource_id' ) ) {
177 $default_resource_id = WPBC_FE_Attr_Postprocessor::get_default_booking_resource_id();
178 }
179
180 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
181 $resource_id = isset( $_POST['bk_type'] ) ? intval( $_POST['bk_type'] ) : $default_resource_id;
182
183 make_bk_action( 'check_multiuser_params_for_client_side', $resource_id );
184
185 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
186 $selected_dates = isset( $_POST['all_dates'] ) ? sanitize_text_field( wp_unslash( $_POST['all_dates'] ) ) : '';
187
188 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
189 $form_data = isset( $_POST['form'] ) ? sanitize_text_field( wp_unslash( $_POST['form'] ) ) : '';
190
191 $hints = self::calculate_hints( $selected_dates, $resource_id, $form_data );
192
193 self::print_update_script( $resource_id, $hints );
194 }
195
196 /**
197 * Calculate supported hint values.
198 *
199 * @param string $selected_dates Selected dates in dd.mm.yyyy CSV/range format.
200 * @param int $resource_id Booking resource ID.
201 * @param string $form_data Serialized booking form data.
202 *
203 * @return array
204 */
205 private static function calculate_hints( $selected_dates, $resource_id, $form_data ) {
206
207 $hints = array();
208 foreach ( self::get_hint_definitions() as $hint_name => $hint_params ) {
209 $hints[ $hint_name ] = $hint_params['default'];
210 }
211
212 $selected_dates = trim( (string) $selected_dates );
213 if ( '' === $selected_dates || false !== strpos( $selected_dates, '13.01.2981' ) ) {
214 return $hints;
215 }
216
217 $dates_in_diff_formats = wpbc_get_dates_in_diff_formats( $selected_dates, $resource_id, $form_data );
218 if ( empty( $dates_in_diff_formats['array'] ) || ! is_array( $dates_in_diff_formats['array'] ) ) {
219 return $hints;
220 }
221
222 $only_dates = array_values( array_unique( array_filter( $dates_in_diff_formats['array'] ) ) );
223 if ( empty( $only_dates ) ) {
224 return $hints;
225 }
226
227 $selected_dates_localized = array();
228 $only_full_days = array();
229
230 foreach ( $only_dates as $day ) {
231 $only_full_days[] = $day . ' 00:00:00';
232 $selected_dates_localized[] = wpbc_get_dates_comma_string_localized( $day . ' 00:00:00' );
233 }
234
235 $hints['check_in_date_hint'] = wpbc_get_dates_comma_string_localized( $only_full_days[0] );
236 $hints['check_out_date_hint'] = wpbc_get_dates_comma_string_localized( $only_full_days[ count( $only_full_days ) - 1 ] );
237 $hints['selected_dates_hint'] = implode( ', ', $selected_dates_localized );
238 $hints['days_number_hint'] = (string) count( $selected_dates_localized );
239
240 $start_time = $dates_in_diff_formats['start_time'];
241 $end_time = $dates_in_diff_formats['end_time'];
242
243 if ( ( ! isset( $start_time[0] ) ) || ( '' === $start_time[0] ) ) {
244 $start_time[0] = '00';
245 }
246 if ( ( ! isset( $start_time[1] ) ) || ( '' === $start_time[1] ) ) {
247 $start_time[1] = '00';
248 }
249 if ( ( ! isset( $start_time[2] ) ) || ( '' === $start_time[2] ) ) {
250 $start_time[2] = '00';
251 }
252 if ( ( ! isset( $end_time[0] ) ) || ( '' === $end_time[0] ) ) {
253 $end_time[0] = '00';
254 }
255 if ( ( ! isset( $end_time[1] ) ) || ( '' === $end_time[1] ) ) {
256 $end_time[1] = '00';
257 }
258 if ( ( ! isset( $end_time[2] ) ) || ( '' === $end_time[2] ) ) {
259 $end_time[2] = '00';
260 }
261
262 $hints['start_time_hint'] = wpbc_time_localized( implode( ':', $start_time ) );
263 $hints['end_time_hint'] = wpbc_time_localized( implode( ':', $end_time ) );
264
265 return $hints;
266 }
267
268 /**
269 * Print JavaScript that applies calculated hint values.
270 *
271 * @param int $resource_id Booking resource ID.
272 * @param array $hints Calculated hint values.
273 *
274 * @return void
275 */
276 private static function print_update_script( $resource_id, $hints ) {
277
278 ?>
279 <script type="text/javascript">
280 (function ( w, $ ) {
281 var resourceId = <?php echo wp_json_encode( (int) $resource_id ); ?>;
282 var hints = <?php echo wp_json_encode( $hints ); ?>;
283
284 if ( w.wpbc_free_date_hints__apply ) {
285 w.wpbc_free_date_hints__apply( resourceId, hints );
286 return;
287 }
288
289 $.each( hints, function ( hintName, hintValue ) {
290 $( '#' + hintName + '_tip' + resourceId + ',.' + hintName + '_tip' + resourceId ).html( hintValue );
291 $( '#' + hintName + resourceId ).val( $( '<div />' ).html( hintValue ).text() );
292 } );
293 })( window, jQuery );
294 </script>
295 <?php
296 }
297 }
298
299 WPBC_Free_Date_Hints::init();
300