PluginProbe
Booking Calendar / 11.4
Booking Calendar v11.4
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 10.11.4 10.12.0 All 200 releases
booking / core / admin / wpbc-sql.php

wpbc-sql.php in Booking Calendar 11.4, at core/admin/wpbc-sql.php

1,442 lines 73.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php /**
2 * @version 1.0
3 * @package Booking Calendar
4 * @category Data Engine for Booking Listing / Calendar Overview pages
5 * @author wpdevelop
6 *
7 * @web-site https://wpbookingcalendar.com/
8 * @email info@wpbookingcalendar.com
9 *
10 * @modified 2015-12-08
11 */
12
13 if ( ! defined( 'ABSPATH' ) ) exit; // Exit, if accessed directly
14
15
16 /** Trick here to overload default REQUST parameters before page is loading */
17 function wpbc_define_listing_page_parameters( $page_tag ) {
18
19 // $page_tag - here can be all defined in plugin menu pages
20 // So we need to check activated page. By default its inside of $_GET['page'],
21
22 // Execute it only for Booking Listing & Timeline admin pages.
23 //if ( ( isset( $_GET[ 'page' ] ) ) && ( $_GET[ 'page' ] == 'wpbc' ) ) {
24
25 if ( wpbc_is_bookings_page() ) { // We are inside of this page. Menu item selected.
26
27 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
28 $requested_tab = isset( $_REQUEST['tab'] ) ? sanitize_key( wp_unslash( $_REQUEST['tab'] ) ) : '';
29 if ( ( '' !== $requested_tab ) && ( ! in_array( $requested_tab, array( 'vm_booking_listing', 'vm_calendar' ), true ) ) ) { // FixIn: Add Booking lives as its own Bookings tab.
30 return;
31 }
32
33 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
34 if ( 'vm_booking_listing' === $requested_tab ) { //FixIn: 9.2.0
35 return;
36 }
37
38 $booking_default_view_mode = wpbc_get_default_saved_view_mode_for_wpbc_page();
39 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
40 if ( ! isset( $_REQUEST['tab'] ) ) {
41 $_REQUEST['tab'] = $booking_default_view_mode; // Set to REQUEST
42 }
43
44 // Get saved filters set, (if its not set in request yet), like "tab" & "view_mode" and overload $_REQUEST
45 wpbc_set_default_saved_params_to_request_for_booking_listing( 'default' );
46 }
47 }
48 // We are set 9 to execute earlier than hook in WPBC_Admin_Menus
49 add_action('wpbc_define_nav_tabs', 'wpbc_define_listing_page_parameters', 1 ); // This Hook fire in the class WPBC_Admin_Menus for showing page content of specific menu
50
51 ////////////////////////////////////////////////////////////////////////////////
52 // R e q u e s t S u p p o r t
53 ////////////////////////////////////////////////////////////////////////////////
54
55 /**
56 * Get here default View mode saved in a General Booking Settings page or From REQUEST view_mode
57 *
58 * @return string = 'vm_calendar' | 'vm_booking_listing'
59 */
60 function wpbc_get_default_saved_view_mode_for_wpbc_page() {
61
62 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
63 if ( ! isset( $_REQUEST['tab'] ) ) {
64 $booking_default_view_mode = get_bk_option( 'booking_listing_default_view_mode' );
65 } else {
66 $booking_default_view_mode = sanitize_text_field( wp_unslash( $_REQUEST['tab'] ) ); /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */ /* FixIn: sanitize_unslash */
67 }
68
69 // TODO:2023-05-20 remove it!!. 'vm_booking_listing';.
70 if ( ! in_array( $booking_default_view_mode, array( 'vm_calendar', 'vm_booking_listing' ), true ) ) {
71 $booking_default_view_mode = 'vm_booking_listing'; // FixIn: 9.2.1 // FixIn: 9.6.3.5.
72 }
73
74 $booking_default_view_mode = ( 'vm_listing' === $booking_default_view_mode ) ? 'vm_booking_listing' : $booking_default_view_mode; // FixIn: 9.6.3.5.
75
76 return $booking_default_view_mode; // 'vm_calendar' / 'vm_booking_listing'.
77 }
78
79
80 /**
81 * Get from SETTINGS (if its not set in request yet) the "tab" & "view_mode" and set to $_REQUEST
82 If we have the "saved" filter set so LOAD it and set to REQUEST, if REQUEST was not set previously
83 & skip "wh_booking_type" from the saved filter set
84 *
85 * @param string $filter_name - name of saved filter set. Currntly is using only one "Default"
86 */
87 function wpbc_set_default_saved_params_to_request_for_booking_listing( $filter_name ) {
88
89 // Exclude some parameters from the saved Default parameters - the values of these parameters are loading from General Booking Settings page or from the request.
90 $exclude_options_from_saved_params = array(
91 'tab', // Default.
92 'page', // From plugin.
93 'wh_booking_type', // Default.
94 'view_days_num', // Default.
95 'blank_field__this_field_only_for_formatting_buttons', // Skip this, this parameter for formating purpose in toolbar.
96 );
97
98 $wpdevbk_filter_params = array();
99
100 // Get here default View mode saved in a General Booking Settings page.
101 $booking_default_view_mode = wpbc_get_default_saved_view_mode_for_wpbc_page();
102 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
103 if ( ! isset( $_REQUEST['tab'] ) ) {
104 $wpdevbk_filter_params['tab'] = $booking_default_view_mode;
105 }
106 // 'vm_calendar' / 'vm_booking_listing' ;.
107 $_REQUEST['tab'] = $booking_default_view_mode;
108
109
110 // Get here default view_days_num.
111 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
112 if ( ! isset( $_REQUEST['view_days_num'] ) ) {
113 $booking_view_days_num = get_bk_option( 'booking_view_days_num' );
114 if ( false !== $booking_view_days_num ) {
115 $wpdevbk_filter_params['view_days_num'] = $booking_view_days_num; // '30'.
116 $_REQUEST['view_days_num'] = $booking_view_days_num;
117 } else {
118 $_REQUEST['view_days_num'] = '365';
119 }
120 }
121 }
122
123
124
125 /**
126 * Clean Request Parameters
127 *
128 */
129 function wpbc_check_request_paramters() { // FixIn: 6.2.1.4.
130
131 //debuge($_REQUEST);
132 $clean_params = array();
133
134 $clean_params['wh_booking_id'] = 'digit_or_csd';
135 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
136 if ( ( ! empty( $_REQUEST['wh_booking_type'] ) ) && ( 'lost' == $_REQUEST['wh_booking_type'] ) ) { // FixIn: 8.5.2.19.
137 $clean_params['wh_booking_type'] = 'checked_skip_it';
138 } else {
139 $clean_params['wh_booking_type'] = 'digit_or_csd';
140 }
141 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
142 if ( ( ! empty( $_REQUEST['booking_type'] ) ) && ( 'lost' == $_REQUEST['booking_type'] ) ) { // FixIn: 8.9.2.1.
143 $clean_params['booking_type'] = 'checked_skip_it';
144 } else {
145 $clean_params['booking_type'] = 'digit_or_csd';
146 }
147
148 $clean_params['wh_approved'] = 'digit_or_csd'; // '0' | '1' | ''
149
150 $clean_params['wh_booking_date'] = 'digit_or_date'; // number | date 2016-07-20
151 $clean_params['wh_booking_date2'] = 'digit_or_date'; // number | date 2016-07-20
152 $clean_params['wh_booking_datenext'] = 'd'; // '1' | '2' ....
153 $clean_params['wh_booking_dateprior'] = 'd'; // '1' | '2' ....
154 $clean_params['wh_booking_datefixeddates'] = 'digit_or_date'; // number | date 2016-07-20
155 $clean_params['wh_booking_date2fixeddates'] = 'digit_or_date'; // number | date 2016-07-20
156
157 $clean_params['wh_is_new'] = 'd'; // '1' | ''
158
159 $clean_params['wh_modification_date'] = 'digit_or_date'; // number | date 2016-07-20
160 $clean_params['wh_modification_date2'] = 'digit_or_date'; // number | date 2016-07-20
161 $clean_params['wh_modification_dateprior'] = 'd'; // '1' | '2' ....
162 $clean_params['wh_modification_datefixeddates'] = 'digit_or_date'; // number | date 2016-07-20
163 $clean_params['wh_modification_date2fixeddates']= 'digit_or_date'; // number | date 2016-07-20
164
165 $clean_params['wh_keyword'] = 's'; //string
166
167 $clean_params['wh_pay_statuscustom'] = 's'; //string !!! LIKE !!!
168 $clean_params['wh_pay_status'] = array('all', 'group_ok', 'group_unknown', 'group_pending', 'group_failed');
169
170 $clean_params['wh_cost'] = 'd'; // '1' | ''
171 $clean_params['wh_cost2'] = 'd'; // '1' | ''
172
173 $clean_params['or_sort'] = array('', 'sort_date', 'booking_type', 'cost', 'booking_id_asc', 'sort_date_asc', 'booking_type_asc', 'cost_asc');
174 $clean_params['wh_trash'] = array('0' , 'trash', 'any');
175
176
177 $clean_params['page_num'] = 'd'; // '' | '1' ... // does not exist in 6.2.1.4
178 $clean_params['page_items_count'] = 'd'; // '' | '1' ... // does not exist in 6.2.1.4
179 $clean_params['view_days_num'] = 'd'; // '' | '1' ... // does not exist in 6.2.1.4
180
181 // FixIn: 8.9.2.1.
182 $clean_params['scroll_start_date'] = 'digit_or_date';
183 $clean_params['scroll_day'] = 'd';
184 $clean_params['scroll_month'] = 'd';
185 $clean_params['limit_hours'] = 'digit_or_csd';
186 $clean_params['only_booked_resources'] = 'd';
187
188
189 foreach ( $clean_params as $request_key => $clean_type ) {
190
191 // elements only listed in array::
192 if ( is_array( $clean_type ) ) { // check only values from the list in this array
193
194 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
195 if ( ( isset( $_REQUEST[ $request_key ] ) ) && ( ! in_array( $_REQUEST[ $request_key ], $clean_type ) ) )
196 $clean_type = 's';
197 else
198 $clean_type = 'checked_skip_it';
199 }
200
201 switch ( $clean_type ) {
202
203 case 'checked_skip_it':
204
205 break;
206
207 case 'digit_or_date': // digit or comma separated digit
208 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
209 if ( isset( $_REQUEST[ $request_key ] ) ) {
210 $_REQUEST[ $request_key ] = wpbc_clean_digit_or_date( $_REQUEST[ $request_key ] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
211 }
212 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
213 if ( isset( $_GET[ $request_key ] ) ) {
214 $_GET[ $request_key ] = wpbc_clean_digit_or_date( $_GET[ $request_key ] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
215 }
216 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
217 if ( isset( $_POST[ $request_key ] ) ) {
218 $_POST[ $request_key ] = wpbc_clean_digit_or_date( $_POST[ $request_key ] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
219 }
220
221 break;
222
223 case 'digit_or_csd': // digit or comma separated digit
224 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
225 if ( isset( $_REQUEST[ $request_key ] ) ) {
226 $_REQUEST[ $request_key ] = wpbc_clean_digit_or_csd( $_REQUEST[ $request_key ] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
227 }
228 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
229 if ( isset( $_GET[ $request_key ] ) ) {
230 $_GET[ $request_key ] = wpbc_clean_digit_or_csd( $_GET[ $request_key ] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
231 }
232 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
233 if ( isset( $_POST[ $request_key ] ) ) {
234 $_POST[ $request_key ] = wpbc_clean_digit_or_csd( $_POST[ $request_key ] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
235 }
236
237 break;
238
239 case 's': // string
240 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
241 if ( isset( $_REQUEST[ $request_key ] ) ) {
242 $_REQUEST[ $request_key ] = wpbc_clean_like_string_for_db( $_REQUEST[ $request_key ] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
243 }
244 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
245 if ( isset( $_GET[ $request_key ] ) ) {
246 $_GET[ $request_key ] = wpbc_clean_like_string_for_db( $_GET[ $request_key ] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
247 }
248 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
249 if ( isset( $_POST[ $request_key ] ) ) {
250 $_POST[ $request_key ] = wpbc_clean_like_string_for_db( $_POST[ $request_key ] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
251 }
252
253 break;
254
255 case 'd': // digit
256 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
257 if ( ( isset( $_REQUEST[ $request_key ] ) ) && ( $_REQUEST[ $request_key ] !== '' ) ) {
258 $_REQUEST[ $request_key ] = intval( $_REQUEST[ $request_key ] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
259 }
260 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
261 if ( ( isset( $_GET[ $request_key ] ) ) && ( $_GET[ $request_key ] !== '' ) ) {
262 $_GET[ $request_key ] = intval( $_GET[ $request_key ] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
263 }
264 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
265 if ( ( isset( $_POST[ $request_key ] ) ) && ( $_POST[ $request_key ] !== '' ) ) {
266 $_POST[ $request_key ] = intval( $_POST[ $request_key ] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
267 }
268
269 break;
270
271 default:
272 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
273 if ( isset( $_REQUEST[ $request_key ] ) ) {
274 $_REQUEST[ $request_key ] = intval( $_REQUEST[ $request_key ] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
275 }
276 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
277 if ( isset( $_GET[ $request_key ] ) ) {
278 $_GET[ $request_key ] = intval( $_GET[ $request_key ] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
279 }
280 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
281 if ( isset( $_POST[ $request_key ] ) ) {
282 $_POST[ $request_key ] = intval( $_POST[ $request_key ] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
283 }
284 break;
285 }
286
287
288 }
289
290 //debuge($_REQUEST);
291 }
292
293
294 // FixIn: 9.6.3.5.
295
296 /**
297 * Get array of cleaned (limited number) paramas from REQUEST
298 *
299 * @return array
300 */
301 function wpbc_get_clean_paramas_from_request_for_timeline() {
302
303
304 // Reset
305 $start_year = gmdate("Y"); //2012
306 $start_month = gmdate("m"); //09
307 $start_day = 1;//date("d");//1; //31
308 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
309 if (! empty($_REQUEST['scroll_start_date'])) { // scroll_start_date=2013-07-01
310 $scroll_start_date = explode( '-', $_REQUEST['scroll_start_date'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
311
312 $start_year = $scroll_start_date[0]; //2012
313 $start_month = $scroll_start_date[1]; //09
314 $start_day = $scroll_start_date[2]; //date("d");//1; //31
315 }
316
317 $scroll_day = 0;
318 $scroll_month = 0;
319
320 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
321 if (isset($_REQUEST['view_days_num'])) $view_days_num = sanitize_text_field( wp_unslash( $_REQUEST['view_days_num'] ) ); /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */ /* FixIn: sanitize_unslash */
322 else $view_days_num = get_bk_option( 'booking_view_days_num');
323
324 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
325 if ((isset($_REQUEST['wh_booking_type'])) && ( strpos($_REQUEST['wh_booking_type'], ',') !== false ) )
326 $is_show_resources_matrix = true;
327 else $is_show_resources_matrix = false;
328
329 if ($is_show_resources_matrix) {
330
331 switch ($view_days_num) {
332
333 case '1':
334 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
335 if (empty($_REQUEST['scroll_start_date'])) $start_day = gmdate("d");
336 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
337 if (isset($_REQUEST['scroll_day'])) $scroll_day = sanitize_text_field( wp_unslash( $_REQUEST['scroll_day'] ) ); /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */ /* FixIn: sanitize_unslash */
338
339 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + intval( $scroll_day ) ), intval( $start_year ) );
340 $wh_booking_date = gmdate("Y-m-d", $real_date); // '2012-11-29';
341
342 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + intval( $scroll_day ) ), intval( $start_year ) );
343 $wh_booking_date2 = gmdate("Y-m-d", $real_date); // '2013-12-3';
344 break;
345
346 case '7':
347 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
348 if (empty($_REQUEST['scroll_start_date'])) $start_day = gmdate("d");
349 $start_week_day_num = gmdate("w");
350 $start_day_weeek = esc_js(get_bk_option( 'booking_start_day_weeek' )); //[0]:Sun .. [6]:Sut
351 if ($start_week_day_num != $start_day_weeek) {
352 for ($d_inc = 1; $d_inc < 8; $d_inc++) { // Just get week back
353 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) - intval( $d_inc ) ), intval( $start_year ) );
354 $start_week_day_num = gmdate("w", $real_date);
355 if ($start_week_day_num == $start_day_weeek) {
356 $start_day = gmdate("d", $real_date);
357 $start_year = gmdate("Y", $real_date);
358 $start_month = gmdate("m", $real_date);
359 $d_inc=9;
360 }
361 }
362 }
363
364 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
365 if (isset($_REQUEST['scroll_day'])) $scroll_day = sanitize_text_field( wp_unslash( $_REQUEST['scroll_day'] ) ); /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */ /* FixIn: sanitize_unslash */
366
367 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + intval( $scroll_day ) ), intval( $start_year ) );
368 $wh_booking_date = gmdate("Y-m-d", $real_date); // '2012-12-01';
369
370 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + 7 + intval( $scroll_day ) ), intval( $start_year ) );
371 $wh_booking_date2 = gmdate("Y-m-d", $real_date); // '2012-12-7';
372 break;
373
374 case '30':
375 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
376 if (isset($_REQUEST['scroll_month'])) $scroll_month = sanitize_text_field( wp_unslash( $_REQUEST['scroll_month'] ) ); /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */ /* FixIn: sanitize_unslash */
377
378 $real_date = mktime( 0, 0, 0, ( intval( $start_month ) + intval( $scroll_month ) ), intval( $start_day ), intval( $start_year ) );
379 $wh_booking_date = gmdate("Y-m-d", $real_date); // '2012-12-01';
380
381 $real_date = mktime( 0, 0, 0, ( intval( $start_month ) + 1 + intval( $scroll_month ) ), ( intval( $start_day ) - 1 ), intval( $start_year ) );
382 $wh_booking_date2 = gmdate("Y-m-d", $real_date); // '2012-12-31';
383 break;
384
385 case '60':
386 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
387 if (isset($_REQUEST['scroll_month'])) $scroll_month = sanitize_text_field( wp_unslash( $_REQUEST['scroll_month'] ) ); /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */ /* FixIn: sanitize_unslash */
388
389 $real_date = mktime( 0, 0, 0, ( intval( $start_month ) + intval( $scroll_month ) ), intval( $start_day ), intval( $start_year ) );
390 $wh_booking_date = gmdate("Y-m-d", $real_date); // '2012-12-01';
391
392 $real_date = mktime( 0, 0, 0, ( intval( $start_month ) + 2 + intval( $scroll_month ) ), ( intval( $start_day ) - 1 ), intval( $start_year ) );
393 $wh_booking_date2 = gmdate("Y-m-d", $real_date); // '2013-02-31';
394 break;
395
396 ////////////////////////////////////////////////////////////////////////////////
397 default: // 30 - default
398 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
399 if (isset($_REQUEST['scroll_month'])) $scroll_month = sanitize_text_field( wp_unslash( $_REQUEST['scroll_month'] ) ); /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */ /* FixIn: sanitize_unslash */
400
401 $real_date = mktime( 0, 0, 0, ( intval( $start_month ) + intval( $scroll_month ) ), intval( $start_day ), intval( $start_year ) );
402 $wh_booking_date = gmdate("Y-m-d", $real_date); // '2012-12-01';
403
404 $real_date = mktime( 0, 0, 0, ( intval( $start_month ) + 1 + intval( $scroll_month ) ), ( intval( $start_day ) - 1 ), intval( $start_year ) );
405 $wh_booking_date2 = gmdate("Y-m-d", $real_date); // '2012-12-31';
406 break;
407 }
408
409 } else { // Single resource
410
411 switch ($view_days_num) {
412 case '90':
413
414 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
415 if (empty($_REQUEST['scroll_start_date'])) $start_day = gmdate("d");
416 $start_week_day_num = gmdate("w");
417 $start_day_weeek = esc_js(get_bk_option( 'booking_start_day_weeek' )); //[0]:Sun .. [6]:Sut
418
419 if ($start_week_day_num != $start_day_weeek) {
420 for ($d_inc = 1; $d_inc < 8; $d_inc++) { // Just get week back
421 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) - intval( $d_inc ) ), intval( $start_year ) );
422 $start_week_day_num = gmdate("w", $real_date);
423 if ($start_week_day_num == $start_day_weeek) {
424 $start_day = gmdate("d", $real_date);
425 $start_year = gmdate("Y", $real_date);
426 $start_month = gmdate("m", $real_date);
427 $d_inc=9;
428 //break;
429 }
430 }
431 }
432
433 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
434 if (isset($_REQUEST['scroll_day'])) $scroll_day = sanitize_text_field( wp_unslash( $_REQUEST['scroll_day'] ) ); /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */ /* FixIn: sanitize_unslash */
435
436 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + intval( $scroll_day ) ), intval( $start_year ) );
437 $wh_booking_date = gmdate("Y-m-d", $real_date); // '2012-12-01';
438
439 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + 7 * 12 + 7 + intval( $scroll_day ) ), intval( $start_year ) );
440 $wh_booking_date2 = gmdate("Y-m-d", $real_date); // '2013-12-31';
441 break;
442
443 case '30':
444 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
445 if (empty($_REQUEST['scroll_start_date'])) $start_day = gmdate("d");
446
447 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
448 if (isset($_REQUEST['scroll_day'])) $scroll_day = sanitize_text_field( wp_unslash( $_REQUEST['scroll_day'] ) ); /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */ /* FixIn: sanitize_unslash */
449
450 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + intval( $scroll_day ) ), intval( $start_year ) );
451 $wh_booking_date = gmdate("Y-m-d", $real_date); // '2012-12-01';
452
453 $real_date = mktime( 0, 0, 0, intval( $start_month ), ( intval( $start_day ) + 31 + intval( $scroll_day ) ), intval( $start_year ) );
454 $wh_booking_date2 = gmdate("Y-m-d", $real_date); // '2013-12-31';
455 break;
456
457 default: // 365
458
459 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
460 if (isset($_REQUEST['scroll_month'])) $scroll_month = sanitize_text_field( wp_unslash( $_REQUEST['scroll_month'] ) ); /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */ /* FixIn: sanitize_unslash */
461 else $scroll_month = 0;
462
463 $real_date = mktime( 0, 0, 0, ( intval( $start_month ) + intval( $scroll_month ) ), intval( $start_day ), intval( $start_year ) );
464 $wh_booking_date = gmdate("Y-m-d", $real_date); // '2012-12-01';
465
466 $real_date = mktime( 0, 0, 0, ( intval( $start_month ) + intval( $scroll_month ) + 13 ), ( intval( $start_day ) - 1 ), intval( $start_year ) );
467 $wh_booking_date2 = gmdate("Y-m-d", $real_date); // '2013-12-31';
468
469 break;
470 }
471 }
472
473
474 $or_sort = '' ;
475
476 $args = array(
477 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
478 'wh_booking_type' => ( isset( $_REQUEST['wh_booking_type'] ) ) ? $_REQUEST['wh_booking_type'] : '',
479 'wh_approved' => '', // Any.
480 'wh_booking_id' => '', // Any.
481 'wh_is_new' => '', // (isset($_REQUEST['wh_is_new']))?$_REQUEST['wh_is_new']:'', ?.
482 'wh_pay_status' => 'all', // (isset($_REQUEST['wh_pay_status']))?$_REQUEST['wh_pay_status']:'', // ?.
483 'wh_keyword' => '', // (isset($_REQUEST['wh_keyword']))?$_REQUEST['wh_keyword']:'', // ?.
484 'wh_booking_date' => $wh_booking_date,
485 'wh_booking_date2' => $wh_booking_date2,
486 'wh_modification_date' => '3', // (isset($_REQUEST['wh_modification_date']))?$_REQUEST['wh_modification_date']:'', // ?
487 'wh_modification_date2' => '', // (isset($_REQUEST['wh_modification_date2']))?$_REQUEST['wh_modification_date2']:'', // ?
488 'wh_cost' => '', // (isset($_REQUEST['wh_cost']))?$_REQUEST['wh_cost']:'', // ?
489 'wh_cost2' => '', // (isset($_REQUEST['wh_cost2']))?$_REQUEST['wh_cost2']:'', // ?
490 'or_sort' => $or_sort,
491 'page_num' => '1',
492 'page_items_count' => '100000',
493 );
494
495 return $args;
496 }
497
498
499 /** Set initial $_REQUEST['view_days_num'] depend on from selected booking resources */
500 function wpbc_set_request_params_for_timeline() {
501
502 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
503 if ( ( isset( $_REQUEST['wh_booking_type'] ) ) && ( strpos( $_REQUEST['wh_booking_type'], ',' ) !== false ) ) {
504 $is_show_resources_matrix = true;
505 } else {
506 $is_show_resources_matrix = false;
507 }
508
509 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
510 if ( ! isset( $_REQUEST['view_days_num'] ) ) {
511 $_REQUEST['view_days_num'] = get_bk_option( 'booking_view_days_num' );
512 }
513
514 // We do not have the Year (365) and (90) view modes in the Matrix mode so we are set to the closest variant. And the same backward.
515 if ( ( $is_show_resources_matrix ) ) { // Switching from the Single to Matrix mode.
516 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
517 if ( isset( $_REQUEST['view_days_num'] ) && ( $_REQUEST['view_days_num'] == '365' ) ) {
518 $_REQUEST['view_days_num'] = 60;
519 }
520 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
521 if ( isset( $_REQUEST['view_days_num'] ) && ( $_REQUEST['view_days_num'] == '90' ) ) {
522 $_REQUEST['view_days_num'] = 7;
523 }
524 } else { // Switching from the Matrix to Single mode.
525 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
526 if ( isset( $_REQUEST['view_days_num'] ) && ( $_REQUEST['view_days_num'] == '60' ) ) {
527 $_REQUEST['view_days_num'] = 365;
528 }
529 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
530 if ( ( $_REQUEST['view_days_num'] == '7' ) || ( $_REQUEST['view_days_num'] == '1' ) ) {
531 $_REQUEST['view_days_num'] = 30;
532 }
533 }
534 }
535
536
537 /** Define default booking resource to $_GET request and check if user can be here in MU version. */
538 function wpbc_set_default_resource_to__get() {
539
540 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
541 if ( isset( $_GET['booking_type'] ) ) {
542
543 // Check if User can be here in MultiUser version for this booking resource (is this user owner of this resource or not).
544 if ( class_exists( 'wpdev_bk_multiuser' ) ) {
545
546 $default_booking_resource = sanitize_text_field( wp_unslash( $_GET['booking_type'] ) ); /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */ /* FixIn: sanitize_unslash */
547
548 // Check if this MU user activated or superadmin, otherwise show warning.
549 if ( ! wpbc_is_mu_user_can_be_here( 'activated_user' ) ) {
550 return false;
551 }
552
553 // Check if this MU user owner of this resource or superadmin, otherwise show warning.
554 if ( ! wpbc_is_mu_user_can_be_here( 'resource_owner', $default_booking_resource ) ) {
555 return false;
556 }
557 }
558 } else { // Set default booking resource to $_GET.
559
560 // Get ID of default booking resource, or return false (in case if user have no access to this resource and show some warnings).
561 $default_booking_resource = wpbc_get_default_resource();
562
563 if ( empty( $default_booking_resource ) ) {
564
565 return false; // User can not be here, Warnings have shown.
566
567 } else {
568
569 $_GET['booking_type'] = $default_booking_resource;
570 }
571
572 // Check if this resource parent and has some additional childs, if yes then assign $_ GET['parent_res'] = 1 only in case, if its for loading default booking resource.
573 make_bk_action( 'check_if_bk_res_parent_with_childs_set_parent_res', $default_booking_resource );
574 }
575
576 return true;
577 }
578
579
580 /**
581 * Get ID of default booking resource, or return false (in case if user have no access to this resource and show some warnings).
582 *
583 * @return boolean|int
584 */
585 function wpbc_get_default_resource() {
586
587 if ( ! class_exists( 'wpdev_bk_personal' ) ) {
588 return 1;
589 } // Free, i.e., default 1.
590
591 // Get assigned default booking resource from General Booking Settings page.
592 $default_booking_resource = get_bk_option( 'booking_default_booking_resource' ); // If empty, i.e., "" - its all resources - no default booking resource.
593
594 if ( empty( $default_booking_resource ) ) { // We do not have default resource.
595
596 // Get first resource in a list.
597 // If its MU, then for superadmin get first resource in a list OR if user DO NOT have resources get FIRST resource in LIST FROM ALL resources.
598 $default_booking_resource = get__default_type();
599 }
600
601 // MU.
602 if ( class_exists( 'wpdev_bk_multiuser' ) ) {
603
604 // Check if this MU user activated or superadmin, otherwise show warning.
605 if ( ! wpbc_is_mu_user_can_be_here( 'activated_user' ) ) {
606 return false;
607 }
608
609 // Check if this MU user owner of this resource or superadmin, otherwise show warning.
610 if ( ! wpbc_is_mu_user_can_be_here( 'resource_owner', $default_booking_resource ) ) {
611 return false;
612 }
613 }
614
615 return $default_booking_resource;
616 }
617
618
619 /** Get list of all booking resources.
620 *
621 * @return array (
622 [1] => Array (
623 [title] => Default [parent resource]
624 [attr] => Array (
625 [class] => wpbc_parent_resource
626 )
627 )
628 [5] => Array (
629 [title] => Default-1
630 [attr] => Array (
631 [class] => wpbc_child_resource
632 )
633 )
634 [6] => Array ( ...
635 */
636 function wpbc_get_all_booking_resources_list(){ //FixIn: 8.1.3.5.2
637
638 if ( ! class_exists( 'wpdev_bk_personal' ) ) {
639 return array();
640 }
641
642 $resources_cache = wpbc_br_cache(); // Get booking resources from cache
643
644 $resource_objects = $resources_cache->get_resources();
645 // $resource_objects = $resources_cache->get_single_parent_resources();
646
647 //$resource_options = $params['resources'];
648 $resource_options = array(); // FixIn: 8.2.1.12.
649
650 foreach ( $resource_objects as $br ) {
651
652 $br_option = array();
653 $br_option['title'] = wpbc_lang( $br['title'] );
654
655 if ( ( isset( $br['parent'] ) ) && ( $br['parent'] == 0 ) && ( isset( $br['count'] ) ) && ( $br['count'] > 1 ) ) {
656 $br_option['title'] .= ' [' . __( 'parent resource', 'booking' ) . ']';
657 }
658
659 $br_option['attr'] = array();
660 $br_option['attr']['class'] = 'wpbc_single_resource';
661 if ( isset( $br['parent'] ) ) {
662 if ( $br['parent'] == 0 ) {
663 if ( ( isset( $br['count'] ) ) && ( $br['count'] > 1 ) ) {
664 $br_option['attr']['class'] = 'wpbc_parent_resource';
665 }
666 } else {
667 $br_option['attr']['class'] = 'wpbc_child_resource';
668 }
669 }
670
671 $sufix = '';
672
673 $resource_options[ $br['id'] . $sufix ] = $br_option;
674
675 if ( $resource_options[ $br['id'] ]['attr']['class'] === 'wpbc_child_resource' ) {
676 $resource_options[ $br['id'] ]['title'] = ' &nbsp;&nbsp;&nbsp; ' . $resource_options[ $br['id'] ]['title'];
677 }
678 }
679
680 return $resource_options;
681 }
682
683 ////////////////////////////////////////////////////////////////////////////////
684 // S u p p o r t
685 ////////////////////////////////////////////////////////////////////////////////
686
687 /**
688 * Check if current WP user can be here
689 * Checking if the user activated, and booking resource belong to specific user
690 *
691 * @param string $check_condition 'activated_user' | 'resource_owner' | 'only_super_admin'
692 * @param string $booking_resource - Optional. ID of booking resource for 'resource_owner' condition
693 * @return boolean
694 */
695 function wpbc_is_mu_user_can_be_here( $check_condition, $booking_resource = '' ) {
696
697 $is_can = true;
698
699 if ( $check_condition == 'activated_user' )
700 $is_can = apply_bk_filter( 'multiuser_is_user_can_be_here', true, 'check_for_active_users' );
701
702 if ( $check_condition == 'only_super_admin' )
703 $is_can = apply_bk_filter( 'multiuser_is_user_can_be_here', true, 'only_super_admin' );
704
705 if ( $check_condition == 'resource_owner' )
706 $is_can = apply_bk_filter( 'multiuser_is_user_can_be_here', true, $booking_resource );
707
708 return $is_can;
709
710 }
711
712
713 ////////////////////////////////////////////////////////////////////////////////
714 // E n g i n e B o o k i n g L i s t i n g
715 ////////////////////////////////////////////////////////////////////////////////
716
717 /**
718 * E n g i n e for getting Bookings objects for Booking Listing pages
719 *
720 * @param array $args - Request paramters from filters
721 * @return array(
722 'bookings' => $bookings
723 , 'resources' => $booking_types
724 , 'bookings_count' => $bookings_count
725 , 'page_num' => $page_num
726 , 'count_per_page' => $page_items_count
727 );
728 */
729 function wpbc_get_bookings_objects( $args ){
730
731 global $wpdb;
732
733 // Initial variables //////////////////////////////////////////////////////
734
735 $sql_boking_listing = wpbc_get_sql_for_booking_listing( $args );
736 $sql_start_count = $sql_boking_listing[ 'sql_start_count' ];
737 $sql_start_select = $sql_boking_listing[ 'sql_start_select' ];
738 $sql = $sql_boking_listing[ 'sql' ];
739 $sql_where = $sql_boking_listing[ 'where' ];
740 $sql_order = $sql_boking_listing[ 'order' ];
741 $sql_limit = $sql_boking_listing[ 'limit' ];
742
743 $num_per_page_check = 10;
744 $defaults = array(
745 'wh_booking_type' => ''
746 , 'wh_approved' => ''
747 , 'wh_booking_id' => ''
748 , 'wh_is_new' => ''
749 , 'wh_pay_status' => ''
750 , 'wh_keyword' => ''
751 , 'wh_booking_date' => ''
752 , 'wh_booking_date2' => ''
753 , 'wh_modification_date' => ''
754 , 'wh_modification_date2' => ''
755 , 'wh_cost' => ''
756 , 'wh_cost2' => ''
757 , 'or_sort' => ''
758 , 'page_num' => '1'
759 , 'wh_trash' => '' // FixIn: 6.1.1.10.
760 , 'page_items_count' => ( ( empty( $num_per_page_check ) ) ? '10' : $num_per_page_check )
761 );
762
763 $r = wp_parse_args( $args, $defaults );
764
765 $r = apply_filters( 'wpbc_request_params_for_get_booking_obj', $r ); // FixIn: 7.0.1.41.
766
767 extract( $r, EXTR_SKIP );
768
769 $page_start = ( $page_num - 1 ) * $page_items_count;
770
771 //debuge( $sql_start_select . $sql . $sql_where . $sql_order . $sql_limit );
772
773 // -----------------------------------------------------------------------------------------------------------------
774 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
775 $bookings_res = $wpdb->get_results( $sql_start_select . $sql . $sql_where . $sql_order . $sql_limit ); // Get Bookings.
776
777 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
778 $bookings_count = $wpdb->get_results( $sql_start_count . $sql . $sql_where ); // Get Number of bookings.
779
780 $bookings_count = ( ( count( $bookings_count ) > 0 ) ? $bookings_count[0]->count : 0 );
781
782 $booking_types = apply_bk_filter( 'wpdebk_get_keyed_all_bk_resources', array() ); // Get Resources
783
784
785 // -----------------------------------------------------------------------------------------------------------------
786 $booking_id_list = array(); // ID list of ALL bookings
787 $bookings = array();
788 $short_days = array();
789 $short_days_type_id = array();
790
791 foreach ( $bookings_res as $booking ) {
792
793 if ( ! in_array( $booking->booking_id, $booking_id_list ) )
794 $booking_id_list[] = $booking->booking_id;
795
796 $bookings[$booking->booking_id] = $booking;
797 $bookings[$booking->booking_id]->dates = array();
798 $bookings[$booking->booking_id]->dates_short = array();
799
800 $bk_list_type = (isset( $booking->booking_type )) ? $booking->booking_type : '1';
801
802 if ( ( isset( $booking->sync_gid ) ) && (!empty( $booking->sync_gid )) ) {
803 $booking->form .= "~text^sync_gid{$booking->booking_type}^{$booking->sync_gid}";
804 }
805
806 $cont = wpbc__legacy__get_form_content_arr( $booking->form
807 , $bk_list_type
808 , ''
809 , array(
810 'booking_id' => $booking->booking_id
811 , 'resource_title' => (isset( $booking_types[$booking->booking_type] )) ? $booking_types[$booking->booking_type] : ''
812 )
813 );
814
815 $search = array( "'(<br[ ]?[/]?>)+'si", "'(<[/]?p[ ]?>)+'si"/*, "'(<[/]?div[ ]?>)+'si"*/ ); // FixIn: 8.8.1.6.
816 $replace = array( "&nbsp;&nbsp;", " &nbsp; ", " &nbsp; " );
817 $cont['content'] = preg_replace( $search, $replace, $cont['content'] );
818
819 $bookings[$booking->booking_id]->form_show = $cont['content'];
820 unset( $cont['content'] );
821 $bookings[$booking->booking_id]->form_data = $cont;
822 }
823 $booking_id_list = implode( ",", $booking_id_list );
824 $booking_id_list = wpbc_clean_like_string_for_db( $booking_id_list );
825
826 // -----------
827
828 if ( ! empty( $booking_id_list ) ) { // Get Dates for all our Bookings.
829 $sql = "SELECT *
830 FROM {$wpdb->prefix}bookingdates as dt
831 WHERE dt.booking_id in ( {$booking_id_list} ) ";
832
833 if ( class_exists( 'wpdev_bk_biz_l' ) ) {
834 $sql .= ' ORDER BY booking_id, type_id, booking_date ';
835 } else {
836 $sql .= ' ORDER BY booking_id, booking_date ';
837 }
838
839 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
840 $booking_dates = $wpdb->get_results( $sql );
841
842 } else {
843 $booking_dates = array();
844 }
845
846 // -------------
847
848 $last_booking_id = '';
849
850 foreach ( $booking_dates as $date ) { // Add Dates to Bookings array
851
852 $bookings[ $date->booking_id ]->dates[] = $date;
853
854 if ( $date->booking_id != $last_booking_id ) {
855 if ( !empty( $last_booking_id ) ) {
856 if ( $last_show_day != $dte ) {
857 $short_days[] = $dte;
858 $short_days_type_id[] = $last_day_id;
859 }
860
861 $bookings[$last_booking_id]->dates_short = $short_days;
862 $bookings[$last_booking_id]->dates_short_id = $short_days_type_id;
863 }
864 $last_day = '';
865 $last_day_id = '';
866 $last_show_day = '';
867 $short_days = array();
868 $short_days_type_id = array();
869 }
870
871 $last_booking_id = $date->booking_id;
872 $dte = $date->booking_date;
873
874 if ( empty( $last_day ) ) { // First date
875 $short_days[] = $dte;
876 $short_days_type_id[] = (isset( $date->type_id )) ? $date->type_id : '';
877 $last_show_day = $dte;
878 } else { // All other days
879 //if ( wpbc_is_next_day( $dte, $last_day ) ) {
880 $next_day_if__check_in__then__check_out = true;
881 if ( wpbc_is_less_than_next_day( $dte, $last_day, $next_day_if__check_in__then__check_out ) ) {
882 if ( $last_show_day != '-' ) {
883 $short_days[] = '-';
884 $short_days_type_id[] = '';
885 }
886 $last_show_day = '-';
887 } else {
888 if ( $last_show_day != $last_day ) {
889 $short_days[] = $last_day;
890 $short_days_type_id[] = $last_day_id;
891 }
892 $short_days[] = ',';
893 $short_days_type_id[] = '';
894 $short_days[] = $dte;
895 $short_days_type_id[] = (isset( $date->type_id )) ? $date->type_id : '';
896 $last_show_day = $dte;
897 }
898 }
899 $last_day = $dte;
900 $last_day_id = (isset( $date->type_id )) ? $date->type_id : '';
901 }
902
903 if ( isset( $dte ) )
904 if ( $last_show_day != $dte ) {
905 $short_days[] = $dte;
906 $short_days_type_id[] = (isset( $date->type_id )) ? $date->type_id : '';
907 }
908 if ( isset( $bookings[$last_booking_id] ) ) {
909 $bookings[$last_booking_id]->dates_short = $short_days;
910 $bookings[$last_booking_id]->dates_short_id = $short_days_type_id;
911 }
912
913 //debuge( 'Before filtering:', gmdate('Y-m-d', time() +86400 ), $_REQUEST, $bookings ) ;
914
915 // -----------------------------------------------------------------------------------------------------------------
916 // Filter some bookings
917 // -----------------------------------------------------------------------------------------------------------------
918 // Showing only bookings that starting or ending during "Today" ( Today check in/out )
919 if ( (isset( $args['wh_booking_date'] )) && ($args['wh_booking_date'] == '9') ) {
920
921 $today_mysql_format = date_i18n( 'Y-m-d', time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) + 0 * DAY_IN_SECONDS ); // Today day with gmt offset
922
923 foreach ( $bookings as $bc_id => $bc_value ) {
924
925 $check_in_date = $bc_value->dates_short[0];
926 $check_in_date = explode( ' ', $check_in_date );
927 $check_in_date = $check_in_date[0]; // 2014-02-25
928
929 if ( count( $bc_value->dates_short ) == 1 )
930 $check_out_date = $bc_value->dates_short[0];
931 else
932 $check_out_date = $bc_value->dates_short[2];
933 $check_out_date = explode( ' ', $check_out_date );
934 $check_out_date = $check_out_date[0]; // 2014-02-25
935
936 if ( ( $today_mysql_format != $check_in_date ) && ( $today_mysql_format != $check_out_date ) ) {
937 unset( $bookings[$bc_id] );
938 $bookings_count--;
939 }
940 }
941 }
942
943
944 // If we selected the Dates as "Check In - Today/Tommorow", then show only the bookings, where check in date is Today
945 if ( (isset( $args['wh_booking_date'] )) && ($args['wh_booking_date'] == '7') ) {
946 //$today_mysql_format = gmdate('Y-m-d');
947 //$today_mysql_format = gmdate('Y-m-d', time() +86400 ); // 1 Day = 24*60*60 = 86400
948 $today_mysql_format = date_i18n( 'Y-m-d', time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) + DAY_IN_SECONDS ); // Tommorow day with gmt offset
949 foreach ( $bookings as $bc_id => $bc_value ) {
950 $check_in_date = $bc_value->dates_short[0];
951 $check_in_date = explode( ' ', $check_in_date );
952 $check_in_date = $check_in_date[0]; // 2014-02-25
953 if ( $today_mysql_format != $check_in_date ) {
954 unset( $bookings[$bc_id] );
955 $bookings_count--;
956 }
957 }
958 }
959
960
961 // If we selected the Dates as "Check Out - Tomorow", then show only the bookings, where check out date is Tomorrow .
962 if ( ( isset( $args['wh_booking_date'] ) ) && ( 8 === intval( $args['wh_booking_date'] ) ) ) {
963
964 $tomorrow_mysql_format = date_i18n( 'Y-m-d', time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) + DAY_IN_SECONDS ); // Tommorow day with gmt offset.
965 foreach ( $bookings as $bc_id => $bc_value ) {
966 if ( count( $bc_value->dates_short ) === 1 ) {
967 $check_out_date = $bc_value->dates_short[0];
968 } else {
969 $check_out_date = $bc_value->dates_short[2];
970 }
971 $check_out_date = explode( ' ', $check_out_date );
972 $check_out_date = $check_out_date[0]; // 2014-02-25
973 if ( $tomorrow_mysql_format !== $check_out_date ) {
974 unset( $bookings[ $bc_id ] );
975 --$bookings_count;
976 }
977 }
978 }
979
980
981 $return_booking_structure = array(
982 'bookings' => $bookings,
983 'resources' => $booking_types,
984 'bookings_count' => $bookings_count,
985 'page_num' => $page_num,
986 'count_per_page' => $page_items_count,
987 );
988
989
990 return $return_booking_structure;
991 }
992
993
994 ////////////////////////////////////////////////////////////////////////////////
995 // S Q L
996 ////////////////////////////////////////////////////////////////////////////////
997
998 /**
999 * Get S Q L for bookings at Booking Listing page
1000 *
1001 * @param array $args - Request paramters from filters
1002 * @return array - Get array with SQL for getting bookings
1003 */
1004 function wpbc_get_sql_for_booking_listing( $args ){
1005
1006 global $wpdb;
1007
1008 $num_per_page_check = 10;
1009
1010 $defaults = array(
1011 'wh_booking_type' => ''
1012 , 'wh_approved' => ''
1013 , 'wh_booking_id' => ''
1014 , 'wh_is_new' => ''
1015 , 'wh_pay_status' => ''
1016 , 'wh_keyword' => ''
1017 , 'wh_booking_date' => ''
1018 , 'wh_booking_date2' => ''
1019 , 'wh_modification_date' => ''
1020 , 'wh_modification_date2' => ''
1021 , 'wh_cost' => ''
1022 , 'wh_cost2' => ''
1023 , 'or_sort' => ''
1024 , 'page_num' => '1'
1025 , 'wh_trash' => '' // FixIn: 6.1.1.10.
1026 , 'wh_sync_gid' => '' // '' | 'imported' | 'plugin' // FixIn: 8.8.3.19.
1027 , 'page_items_count' => $num_per_page_check
1028 );
1029 $r = wp_parse_args( $args, $defaults );
1030 extract( $r, EXTR_SKIP );
1031
1032 $page_start = ( $page_num - 1 ) * $page_items_count;
1033
1034
1035 $posible_sorts = array( 'booking_id_asc', 'sort_date', 'sort_date_asc', 'booking_type', 'booking_type_asc', 'cost', 'cost_asc' );
1036
1037 if ( ($or_sort == '') || ($or_sort == 'id') || ( !in_array( $or_sort, $posible_sorts ) ) )
1038 $or_sort = 'booking_id';
1039
1040
1041 ////////////////////////////////////////////////////////////////////////
1042 // S Q L
1043 ////////////////////////////////////////////////////////////////////////
1044 $sql_start_select = " SELECT * ";
1045 $sql_start_count = " SELECT COUNT(*) as count";
1046 $sql = " FROM {$wpdb->prefix}booking as bk"; // GET ONLY ROWS OF THE B o o k i n g s - So we can limit the requests
1047
1048 //debuge($wh_trash);
1049 //FixIn: 6.1.1.10 - check also below usage of {$trash_bookings}
1050 $trash_bookings = " AND bk.trash = 0 ";
1051 if ( isset( $wh_trash ) ) {
1052
1053 if ( $wh_trash == "trash" ) $trash_bookings = " AND bk.trash = 1 ";
1054 else if ( $wh_trash == "any" ) $trash_bookings = '';
1055 }
1056 //debuge($trash_bookings);
1057
1058 if ( empty( $wh_booking_id ) ) {
1059
1060 $sql_where = " WHERE " . // Date (single) connection (Its required for the correct Pages in SQL: LIMIT Keyword)
1061 " EXISTS (
1062 SELECT *
1063 FROM {$wpdb->prefix}bookingdates as dt
1064 WHERE bk.booking_id = dt.booking_id ";
1065
1066 if ( 'lost' == $wh_booking_type ) { // FixIn: 8.5.2.19.
1067
1068 $sql_where.= " AND bk.booking_type NOT IN ( SELECT DISTINCT booking_type_id FROM {$wpdb->prefix}bookingtypes ) ";
1069 $sql_where.= " ) ";
1070 $wh_booking_type = '';
1071
1072 } else {
1073
1074 if ( $wh_approved !== '' )
1075 $sql_where.= " AND approved = $wh_approved "; // Approved or Pending
1076
1077 $sql_where .= wpbc_set_sql_where_for_dates( $wh_booking_date, $wh_booking_date2 );
1078
1079 $sql_where.= " ) ";
1080
1081 $sql_where .= " {$trash_bookings} "; // FixIn: 6.1.1.10.
1082
1083 // FixIn: 8.8.3.19.
1084 if ( 'imported' === $wh_sync_gid ) {
1085 $sql_where .= " AND bk.sync_gid != '' ";
1086 }
1087 if ( 'plugin' === $wh_sync_gid ) {
1088 $sql_where .= " AND bk.sync_gid = '' ";
1089 }
1090
1091 if ( $wh_is_new !== '' )
1092 $sql_where .= " AND bk.is_new = " . $wh_is_new . " ";
1093
1094 $sql_where .= apply_bk_filter( 'get_bklist_sql_keyword', '', $wh_keyword ); // P
1095
1096 $sql_where .= wpbc_set_sql_where_for_modification_date( $wh_modification_date, $wh_modification_date2 );
1097
1098 $sql_where .= apply_bk_filter( 'get_bklist_sql_paystatus', '', $wh_pay_status ); // BS
1099 $sql_where .= apply_bk_filter( 'get_bklist_sql_cost', '', $wh_cost, $wh_cost2 ); // BS
1100
1101 $sql_where .= apply_bk_filter( 'get_bklist_sql_resources', '', $wh_booking_type, $wh_approved, $wh_booking_date, $wh_booking_date2 ); // P || BL
1102 }
1103
1104 } else {
1105
1106 // FixIn: 8.7.7.10.
1107 if ( strpos( $wh_booking_id, '<' ) !== false ) {
1108 $wh_booking_id = str_replace( '<', '', $wh_booking_id );
1109 $wh_booking_id = intval( $wh_booking_id );
1110 $sql_where = " WHERE bk.booking_id < " . $wh_booking_id . " ";
1111 }
1112
1113 else if ( strpos( $wh_booking_id, '>' ) !== false ) {
1114 $wh_booking_id = str_replace( '>', '', $wh_booking_id );
1115 $wh_booking_id = intval( $wh_booking_id );
1116 $sql_where = " WHERE bk.booking_id > " . $wh_booking_id . " ";
1117
1118 }
1119
1120 else if ( strpos( $wh_booking_id, ',' ) !== false ) {
1121 $sql_where = " WHERE bk.booking_id IN (" . $wh_booking_id . ") ";
1122
1123 } else {
1124 $sql_where = " WHERE bk.booking_id = " . $wh_booking_id . " ";
1125 }
1126
1127 // Check if searching booking is belonging to specific user in Booking Calendar MultiUser version
1128 $sql_where = apply_bk_filter('update_where_sql_for_getting_bookings_in_multiuser', $sql_where );
1129
1130 }
1131
1132 if ( strpos( $or_sort, '_asc' ) !== false ) { // Order
1133 $or_sort = str_replace( '_asc', '', $or_sort );
1134 $sql_order = " ORDER BY " . $or_sort . " ASC ";
1135 } else
1136 $sql_order = " ORDER BY " . $or_sort . " DESC ";
1137
1138
1139 $sql_limit = $wpdb->prepare( " LIMIT %d, %d ", $page_start, $page_items_count );
1140
1141 $return_res = array(
1142 'sql_start_count' => $sql_start_count
1143 , 'sql_start_select' => $sql_start_select
1144 , 'sql' => $sql
1145 , 'where' => $sql_where
1146 , 'order' => $sql_order
1147 , 'limit' => $sql_limit
1148 );
1149
1150 //debuge($return_res);
1151 return $return_res;
1152 }
1153
1154
1155 ////////////////////////////////////////////////////////////////////////////////
1156 // S Q L W H E R E
1157 ////////////////////////////////////////////////////////////////////////////////
1158
1159 /**
1160 * Get SQL W H E R E conditions for D a t e s of bookings
1161 *
1162 * @param string $wh_booking_date - Parameter from Booking Listing request (usually its number)
1163 * @param string $wh_booking_date2 - Parameter from Booking Listing request (usually its number)
1164 * @param string $pref - Optional. Prefix for table.
1165 * @return string - WHERE conditions for SQL
1166 */
1167 function wpbc_set_sql_where_for_dates( $wh_booking_date, $wh_booking_date2, $pref = 'dt.' ) {
1168
1169 $sql_where= '';
1170 if ($pref == 'dt.') { $and_pre = ' AND '; $and_suf = ''; }
1171 else { $and_pre = ''; $and_suf = ' AND '; }
1172
1173 // Actual
1174 if ( ( ( $wh_booking_date === '' ) && ( $wh_booking_date2 === '' ) ) || ($wh_booking_date === '0') ) {
1175 $sql_where = $and_pre."( ".$pref."booking_date >= (" . wpbc_sql_date_math_expr_explicit( "- INTERVAL '00:00:01' HOUR_SECOND", 'curdate' ) . ") ) ".$and_suf ; // FixIn: 8.5.2.14.
1176
1177 } else if ($wh_booking_date === '1') { // Today // FixIn: 7.1.2.8.
1178 $sql_where = $and_pre."( ".$pref."booking_date <= (" . wpbc_sql_date_math_expr_explicit( "+ INTERVAL '23:59:59' HOUR_SECOND", 'curdate' ) . ") ) ".$and_suf ;
1179 $sql_where .= $and_pre."( ".$pref."booking_date >= (" . wpbc_sql_date_math_expr_explicit( "- INTERVAL '00:00:01' HOUR_SECOND", 'curdate' ) . ") ) ".$and_suf ; // FixIn: 8.4.7.21.
1180
1181
1182 } else if ($wh_booking_date === '2') { // Previous
1183 $sql_where = $and_pre."( ".$pref."booking_date <= (" . wpbc_sql_date_math_expr_explicit( "- INTERVAL '00:00:01' HOUR_SECOND", 'curdate' ) . ") ) ".$and_suf ; // FixIn: 8.5.2.16.
1184
1185 } else if ($wh_booking_date === '3') { // All
1186 $sql_where = '';
1187
1188 } else if ($wh_booking_date === '4') { // Next
1189 $sql_where = $and_pre."( ".$pref."booking_date <= (" . wpbc_sql_date_math_expr_explicit( "+ INTERVAL ". $wh_booking_date2 . " DAY", 'curdate' ) . ") ) ".$and_suf ;
1190 // $sql_where .= $and_pre."( ".$pref."booking_date >= (" . wpbc_sql_date_math_expr_explicit( "- INTERVAL 1 DAY", 'curdate' ) . ") ) ".$and_suf ;
1191 $sql_where .= $and_pre."( ".$pref."booking_date > ( " . wpbc_sql_date_math_expr_explicit('', 'curdate') . " ) ) ".$and_suf ; // FixIn: 8.0.1.1.
1192
1193 } else if ($wh_booking_date === '5') { // Prior
1194 $wh_booking_date2 = str_replace('-', '', $wh_booking_date2);
1195 $sql_where = $and_pre."( ".$pref."booking_date >= (" . wpbc_sql_date_math_expr_explicit( "- INTERVAL ". $wh_booking_date2 . " DAY", 'curdate' ) . ") ) ".$and_suf ;
1196 $sql_where .= $and_pre."( ".$pref."booking_date <= (" . wpbc_sql_date_math_expr_explicit( "+ INTERVAL 1 DAY", 'curdate' ) . ") ) ".$and_suf ;
1197
1198 } else if ($wh_booking_date === '7') { // Check In date - Today/Tomorrow
1199 $sql_where = $and_pre."( ".$pref."booking_date <= ( " . wpbc_sql_date_math_expr_explicit( "+ INTERVAL '47:59:59' HOUR_SECOND", 'curdate' ) . " ) ) ".$and_suf ;
1200 $sql_where .= $and_pre."( ".$pref."booking_date >= (" . wpbc_sql_date_math_expr_explicit( "+ INTERVAL 1 DAY", 'curdate' ) . ") ) ".$and_suf ;
1201
1202 } else if ($wh_booking_date === '8') { // Check Out date - Tomorrow
1203 $sql_where = $and_pre."( ".$pref."booking_date <= ( " . wpbc_sql_date_math_expr_explicit( "+ INTERVAL '47:59:59' HOUR_SECOND", 'curdate' ) . " ) ) ".$and_suf ;
1204 $sql_where .= $and_pre."( ".$pref."booking_date >= (" . wpbc_sql_date_math_expr_explicit( "+ INTERVAL 1 DAY", 'curdate' ) . ") ) ".$and_suf ;
1205
1206 } else if ($wh_booking_date === '9') { // Today check in/out
1207 $sql_where = $and_pre."( ".$pref."booking_date <= (" . wpbc_sql_date_math_expr_explicit( "+ INTERVAL 1 DAY", 'curdate' ) . ") ) ".$and_suf ;
1208 $sql_where .= $and_pre."( ".$pref."booking_date >= (" . wpbc_sql_date_math_expr_explicit( "- INTERVAL 1 DAY", 'curdate' ) . ") ) ".$and_suf ;
1209
1210 } else { // Fixed
1211
1212 if ( $wh_booking_date !== '' )
1213 if ( strpos($wh_booking_date,':')===false ) // we are do not have the time in this date, so set it
1214 $sql_where.= $and_pre."( ".$pref."booking_date >= '" . $wh_booking_date . " 00:00:00' ) ".$and_suf;
1215 else $sql_where.= $and_pre."( ".$pref."booking_date >= '" . $wh_booking_date . "' ) ".$and_suf;
1216
1217 if ( $wh_booking_date2 !== '' )
1218 if ( strpos($wh_booking_date2,':')===false ) // we are do not have the time in this date, so set it
1219 $sql_where.= $and_pre."( ".$pref."booking_date <= '" . $wh_booking_date2 . " 23:59:59' ) ".$and_suf;
1220 else $sql_where.= $and_pre."( ".$pref."booking_date <= '" . $wh_booking_date2 . "' ) ".$and_suf;
1221 }
1222
1223 return $sql_where;
1224 }
1225
1226
1227 /**
1228 * Get SQL W H E R E conditions for M o d i f i c a t i o n D a t e of bookings
1229 *
1230 * @param type $wh_modification_date - Parameter from Booking Listing request (usually its number)
1231 * @param type $wh_modification_date2 - Parameter from Booking Listing request (usually its number)
1232 * @param string $pref - Optional. Prefix for table.
1233 * @return string - WHERE conditions for SQL
1234 */
1235 function wpbc_set_sql_where_for_modification_date( $wh_modification_date, $wh_modification_date2, $pref = 'bk.' ) {
1236
1237 $sql_where = '';
1238
1239 if ($pref == 'bk.') { $and_pre = ' AND '; $and_suf = ''; }
1240 else { $and_pre = ''; $and_suf = ' AND '; }
1241
1242 if ($wh_modification_date === '1') { // Today
1243 $sql_where = $and_pre."( ".$pref."modification_date <= (" . wpbc_sql_date_math_expr_explicit( "+ INTERVAL '23:59:59' HOUR_SECOND", 'curdate' ) . ") ) ".$and_suf ; // FixIn: 8.4.7.22.
1244 $sql_where .= $and_pre."( ".$pref."modification_date >= (" . wpbc_sql_date_math_expr_explicit( "- INTERVAL '00:00:01' HOUR_SECOND", 'curdate' ) . ") ) ".$and_suf ; // FixIn: 8.4.7.22.
1245
1246 } else if ($wh_modification_date === '3') { // All
1247 $sql_where = '';
1248
1249 } else if ($wh_modification_date === '5') { // Prior
1250 $wh_modification_date2 = str_replace('-', '', $wh_modification_date2);
1251 $sql_where = $and_pre."( ".$pref."modification_date >= (" . wpbc_sql_date_math_expr_explicit( "- INTERVAL ". $wh_modification_date2 . " DAY", 'curdate' ) . ") ) ".$and_suf ;
1252 $sql_where .= $and_pre."( ".$pref."modification_date <= (" . wpbc_sql_date_math_expr_explicit( "+ INTERVAL 1 DAY", 'curdate' ) . ") ) ".$and_suf ;
1253
1254 } else { // Fixed
1255
1256 if ( $wh_modification_date !== '' )
1257 $sql_where.= $and_pre."( ".$pref."modification_date >= '" . $wh_modification_date . "' ) ".$and_suf;
1258
1259 if ( $wh_modification_date2 !== '' )
1260 $sql_where.= $and_pre."( ".$pref."modification_date <= '" . $wh_modification_date2 . "' ) ".$and_suf;
1261 }
1262
1263 return $sql_where;
1264 }
1265
1266
1267 /**
1268 * Generate SQL-compatible datetime/date expression based on explicit base function and optional interval.
1269 *
1270 * @param string $mysql_expr - MySQL-style interval expression. Examples: "- INTERVAL '00:00:01' HOUR_SECOND", "+ INTERVAL 5 DAY", etc.
1271 * @param string $base_func - 'curdate'|'now' Either 'curdate' (default) for CURDATE() / date('now'), or 'now' for NOW() / datetime('now').
1272 *
1273 * @return string SQL expression (unquoted), adapted for MySQL or SQLite.
1274 *
1275 * Exmaples:
1276 * wpbc_sql_date_math_expr_explicit("- INTERVAL '00:00:01' HOUR_SECOND", 'curdate') | MySQL: CURDATE() - INTERVAL '00:00:01' HOUR_SECOND # SQLite: datetime('now', '-1 seconds') (auto-upgraded)
1277 * wpbc_sql_date_math_expr_explicit("+ INTERVAL 2 DAY", 'curdate') | MySQL: CURDATE() + INTERVAL 2 DAY # SQLite: date('now', '+2 days')
1278 * wpbc_sql_date_math_expr_explicit('', 'now'); | MySQL: NOW() # SQLite: datetime('now') |.
1279 * wpbc_sql_date_math_expr_explicit(); | MySQL: CURDATE() # SQLite: date('now')
1280 * wpbc_sql_date_math_expr_explicit("+ INTERVAL 30 MINUTE", 'curdate') | MySQL: CURDATE() + INTERVAL 30 MINUTE # SQLite: datetime('now', '+1800 seconds') (auto-upgraded)
1281 */
1282 function wpbc_sql_date_math_expr_explicit( $mysql_expr = '', $base_func = 'curdate' ) {
1283 global $wpdb;
1284
1285 $is_sqlite = ( get_class( $wpdb ) === 'WP_SQLite_DB' );
1286 $original_base_func = strtolower( $base_func );
1287 $base_func = $original_base_func;
1288
1289 // Fallback if invalid.
1290 if ( ! in_array( $base_func, array( 'curdate', 'now' ), true ) ) {
1291 $base_func = 'curdate';
1292 }
1293
1294 // Promote to datetime() if base is 'curdate' and delta is time-based.
1295 $has_time_delta = ( false !== stripos( $mysql_expr, 'HOUR' ) ||
1296 false !== stripos( $mysql_expr, 'MINUTE' ) ||
1297 false !== stripos( $mysql_expr, 'SECOND' ) ||
1298 false !== strpos( $mysql_expr, ':' ) );
1299
1300 if ( $is_sqlite && 'curdate' === $base_func && $has_time_delta ) {
1301 $base_func = 'now'; // auto-promote for SQLite.
1302 }
1303
1304 $mysql_base_func = ( 'curdate' === $base_func ) ? 'CURDATE()' : 'NOW()';
1305 $sqlite_base_func = ( 'curdate' === $base_func ) ? 'date' : 'datetime';
1306
1307 if ( empty( $mysql_expr ) ) {
1308 return $is_sqlite ? "{$sqlite_base_func}('now')" : $mysql_base_func;
1309 }
1310
1311 if ( ! $is_sqlite ) {
1312 return "{$mysql_base_func} {$mysql_expr}";
1313 }
1314
1315 $modifiers = wpbc__convert_mysql_interval_to_sqlite_modifiers( $mysql_expr );
1316
1317 // Fix: anchor to midnight if original func was 'curdate' with time math.
1318 if ( 'curdate' === $original_base_func && $has_time_delta ) {
1319 return "datetime('now','start of day'{$modifiers})";
1320 }
1321
1322 return "{$sqlite_base_func}('now'{$modifiers})";
1323 }
1324
1325
1326
1327 /**
1328 * Convert MySQL-style interval expression to SQLite-compatible modifier(s)
1329 *
1330 * @param string $expr - expression.
1331 *
1332 * @return string
1333 *
1334 * Supports:
1335 * - INTERVAL 5 DAY
1336 * - INTERVAL '00:00:01' HOUR_SECOND
1337 * - Multiple modifiers if needed (returns ', '+X unit', '+Y unit'...')
1338 */
1339 function wpbc__convert_mysql_interval_to_sqlite_modifiers( $expr ) {
1340
1341 $expr = trim( $expr );
1342
1343 if ( preg_match( '/([+-])?\s*INTERVAL\s+(\'?)([^\'\s]+)\2\s+([A-Z_]+)/i', $expr, $m ) ) {
1344 $sign = ( '-' === $m[1] ) ? '-' : '+';
1345 $value = $m[3];
1346 $type = strtoupper( $m[4] );
1347
1348 switch ( $type ) {
1349 case 'DAY':
1350 return ", '{$sign}{$value} days'";
1351
1352 case 'HOUR_SECOND':
1353 case 'SECOND':
1354 $seconds = 0;
1355 if ( strpos( $value, ':' ) !== false ) {
1356 $parts = array_map( 'intval', explode( ':', $value ) );
1357 if ( count( $parts ) === 3 ) {
1358 $seconds = $parts[0] * 3600 + $parts[1] * 60 + $parts[2];
1359 } elseif ( count( $parts ) === 2 ) {
1360 $seconds = $parts[0] * 60 + $parts[1];
1361 }
1362 } else {
1363 $seconds = intval( $value );
1364 }
1365
1366 return ", '{$sign}{$seconds} seconds'";
1367
1368 default:
1369 return ", '{$sign}{$value} " . strtolower( $type ) . "'";
1370 }
1371 }
1372
1373 return '';
1374 }
1375
1376 // FixIn: 10.14.9.1.
1377 /**
1378 * Sanitize and validate "dates_to_check" parameter.
1379 *
1380 * Accepts scalar or array, normalizes to array of 'Y-m-d' strings
1381 * that match /^\d{4}-\d{2}-\d{2}$/.
1382 *
1383 * @param mixed $dates_to_check Raw dates_to_check parameter.
1384 *
1385 * @return array Sanitized, validated dates.
1386 */
1387 function wpbc_sanitize_dates_to_check( $dates_to_check ) {
1388
1389 if ( ! is_array( $dates_to_check ) ) {
1390 $dates_to_check = array( $dates_to_check );
1391 }
1392
1393 $sanitized_dates = array();
1394
1395 foreach ( $dates_to_check as $maybe_date ) {
1396
1397 // Basic text cleanup.
1398 $maybe_date = sanitize_text_field( $maybe_date );
1399
1400 // Strict format: YYYY-MM-DD only.
1401 if ( preg_match( '/^\d{4}-\d{2}-\d{2}$/', $maybe_date ) ) {
1402 $sanitized_dates[] = $maybe_date;
1403 }
1404 }
1405
1406 return $sanitized_dates;
1407 }
1408
1409
1410 // FixIn: 10.14.17.1.
1411 /**
1412 * Sanitize and validate dates and times parameter.
1413 *
1414 * Accepts scalar or array, normalizes to array of 'Y-m-d H:i:s' strings
1415 * that match /^\d{4}-\d{2}-\d{2}$/.
1416 *
1417 * @param mixed $dates_to_check Raw dates_to_check parameter.
1418 *
1419 * @return array Sanitized, validated dates.
1420 */
1421 function wpbc_sanitize_date_ymdhis_to_check( $dates_to_check ) {
1422
1423 if ( ! is_array( $dates_to_check ) ) {
1424 $dates_to_check = array( $dates_to_check );
1425 }
1426
1427 $sanitized_dates = array();
1428
1429 foreach ( $dates_to_check as $maybe_date ) {
1430
1431 // Basic text cleanup.
1432 $maybe_date = sanitize_text_field( $maybe_date );
1433
1434 // Strict format: YYYY-MM-DD only.
1435 if ( preg_match( '/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $maybe_date ) ) {
1436 $sanitized_dates[] = $maybe_date;
1437 }
1438 }
1439
1440 return $sanitized_dates;
1441 }
1442