| 1 |
<?php |
| 2 |
|
| 3 |
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly // FixIn: 9.8.0.4. |
| 4 |
|
| 5 |
// --------------------------------------------------------------------------------------------------------------------- |
| 6 |
// Main function for ajax_ WPBC_AJX_BOOKING__CREATE |
| 7 |
// --------------------------------------------------------------------------------------------------------------------- |
| 8 |
|
| 9 |
/** |
| 10 |
* Check CAPTCHA during Ajax request from booking form and if it's incorrect, then STOP execution and send request to show warning |
| 11 |
* |
| 12 |
* @param $request_params [ 'captcha_user_input'=> '...', 'captcha_chalange'=> '...'] |
| 13 |
* @param $is_from_admin_panel true | false |
| 14 |
* @param $original_ajx_search_params usually $_REQUEST[ $request_prefix ] |
| 15 |
* |
| 16 |
* @return void wp_send_json() TO front-end or skip and continue |
| 17 |
*/ |
| 18 |
function wpbc_captcha__in_ajx__check( $request_params, $is_from_admin_panel , $original_ajx_search_params ) { |
| 19 |
|
| 20 |
if ( |
| 21 |
( ( 'On' === get_bk_option( 'booking_is_use_captcha' ) ) || ( WPBC_NEW_FORM_BUILDER ) ) && |
| 22 |
( ! $is_from_admin_panel ) && |
| 23 |
( ( isset( $original_ajx_search_params['captcha_user_input'] ) ) && ( isset( $original_ajx_search_params['captcha_chalange'] ) ) ) |
| 24 |
) { |
| 25 |
|
| 26 |
if ( ! wpbc_captcha__simple__is_ansfer_correct( $request_params['captcha_user_input'], $request_params['captcha_chalange'] ) ) { |
| 27 |
|
| 28 |
$captcha_arr = wpbc_captcha__simple__generate_new(); |
| 29 |
|
| 30 |
$ajx_data_arr = array(); |
| 31 |
$ajx_data_arr['status'] = 'error'; |
| 32 |
$ajx_data_arr['status_error'] = 'captcha_simple_wrong'; |
| 33 |
$ajx_data_arr['captcha__simple'] = $captcha_arr; |
| 34 |
$ajx_data_arr['ajx_after_action_message'] = __( 'The code you entered is incorrect', 'booking' ); |
| 35 |
$ajx_data_arr['ajx_after_action_message_status'] = 'warning'; |
| 36 |
|
| 37 |
wp_send_json( |
| 38 |
array( |
| 39 |
'ajx_data' => $ajx_data_arr, |
| 40 |
'ajx_search_params' => $original_ajx_search_params, |
| 41 |
'ajx_cleaned_params' => $request_params, |
| 42 |
'resource_id' => $request_params['resource_id'], |
| 43 |
) |
| 44 |
); |
| 45 |
// After this page will die;. |
| 46 |
} |
| 47 |
} |
| 48 |
} |
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
// --------------------------------------------------------------------------------------------------------------------- |
| 53 |
// CAPTCHA Support |
| 54 |
// --------------------------------------------------------------------------------------------------------------------- |
| 55 |
|
| 56 |
/** |
| 57 |
* Is entered CAPTCHA correct ? |
| 58 |
* |
| 59 |
* @param string $captcha_user_input user entrance |
| 60 |
* @param string $captcha_chalange chalange |
| 61 |
* |
| 62 |
* @return bool |
| 63 |
*/ |
| 64 |
function wpbc_captcha__simple__is_ansfer_correct( $captcha_user_input, $captcha_chalange ) { |
| 65 |
|
| 66 |
if ( ( empty( $captcha_user_input ) ) || ( empty( $captcha_chalange ) ) ) { |
| 67 |
return false; |
| 68 |
} |
| 69 |
|
| 70 |
$captcha_instance = new wpdevReallySimpleCaptcha(); |
| 71 |
$correct = $captcha_instance->check( $captcha_chalange, $captcha_user_input ); |
| 72 |
|
| 73 |
return $correct; |
| 74 |
} |
| 75 |
|
| 76 |
|
| 77 |
/** |
| 78 |
* Generate new CAPTCHA image and return URL to this image and challenge code |
| 79 |
* |
| 80 |
* @return array [ |
| 81 |
'url' => $captcha_url, |
| 82 |
'challenge' => $captcha_challenge |
| 83 |
] |
| 84 |
*/ |
| 85 |
function wpbc_captcha__simple__generate_new() { |
| 86 |
|
| 87 |
$captcha_instance = new wpdevReallySimpleCaptcha(); |
| 88 |
|
| 89 |
// Clean up dead files older than 2 minutes |
| 90 |
$captcha_instance->cleanup( 2 ); // FixIn: 7.0.1.67. |
| 91 |
|
| 92 |
//$captcha_instance->img_size = array( 72, 24 ); |
| 93 |
/* Background color of CAPTCHA image. RGB color 0-255 */ |
| 94 |
//$captcha_instance->bg = array( 0, 0, 0 );//array( 255, 255, 255 ); |
| 95 |
/* Foreground (character) color of CAPTCHA image. RGB color 0-255 */ |
| 96 |
//$captcha_instance->fg = array( 255, 255, 255 );//array( 0, 0, 0 ); |
| 97 |
/* Coordinates for a text in an image. I don't know the meaning. Just adjust. */ |
| 98 |
//$captcha_instance->base = array( 6, 18 ); |
| 99 |
/* Font size */ |
| 100 |
//$captcha_instance->font_size = 14; |
| 101 |
/* Width of a character */ |
| 102 |
//$captcha_instance->font_char_width = 15; |
| 103 |
/* Image type. 'png', 'gif' or 'jpeg' */ |
| 104 |
//$captcha_instance->img_type = 'png'; |
| 105 |
|
| 106 |
|
| 107 |
$word = $captcha_instance->generate_random_word(); |
| 108 |
$prefix = wp_rand(); |
| 109 |
|
| 110 |
$captcha_instance->generate_image( $prefix, $word ); |
| 111 |
|
| 112 |
$filename = $prefix . '.png'; |
| 113 |
|
| 114 |
$captcha_url = WPBC_PLUGIN_URL . '/js/captcha/tmp/' . $filename; |
| 115 |
$captcha_challenge = substr( $filename, 0, strrpos( $filename, '.' ) ); |
| 116 |
|
| 117 |
return array( |
| 118 |
'url' => $captcha_url, |
| 119 |
'challenge' => $captcha_challenge |
| 120 |
); |
| 121 |
} |
| 122 |
|
| 123 |
|
| 124 |
/** |
| 125 |
* Generate initial HTML content for CAPTCHA in booking form |
| 126 |
* |
| 127 |
* @param $resource_id |
| 128 |
* |
| 129 |
* @return string|true |
| 130 |
*/ |
| 131 |
function wpbc_captcha__simple__generate_html_content( $resource_id ) { |
| 132 |
|
| 133 |
if ( true !== wpbc_captcha__simple__is_installed() ) { |
| 134 |
return wpbc_captcha__simple__is_installed(); |
| 135 |
} |
| 136 |
|
| 137 |
$captcha_arr = wpbc_captcha__simple__generate_new(); |
| 138 |
|
| 139 |
$captcha_url = $captcha_arr['url']; |
| 140 |
$captcha_challenge = $captcha_arr['challenge']; |
| 141 |
$html = '<span class="wpbc_text_captcha_container wpdev-form-control-wrap ">'; |
| 142 |
$html .= '<input autocomplete="off" type="hidden" name="wpdev_captcha_challenge_' . $resource_id . '" id="wpdev_captcha_challenge_' . $resource_id . '" value="' . $captcha_challenge . '" />'; |
| 143 |
$html .= '<input autocomplete="off" type="text" class="captachinput" value="" name="captcha_input' . $resource_id . '" id="captcha_input' . $resource_id . '" />'; |
| 144 |
// phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage |
| 145 |
$html .= '<img class="captcha_img" id="captcha_img' . $resource_id . '" alt="To show CAPTCHA, please deactivate cache plugin or exclude this page from caching or disable CAPTCHA at WP Booking Calendar - Settings General page in Form Options section." src="' . $captcha_url . '" />'; |
| 146 |
$html .= '</span>'; |
| 147 |
|
| 148 |
return $html; |
| 149 |
} |
| 150 |
|
| 151 |
|
| 152 |
/** |
| 153 |
* Check if captcha can work here |
| 154 |
* |
| 155 |
* @return string|true if true then can work, Otherwise return error message |
| 156 |
*/ |
| 157 |
function wpbc_captcha__simple__is_installed() { |
| 158 |
|
| 159 |
// FixIn: 8.8.3.5. |
| 160 |
if ( function_exists( 'gd_info' ) ) { |
| 161 |
|
| 162 |
return true; |
| 163 |
/* |
| 164 |
$gd_info = gd_info(); |
| 165 |
if ( isset( $gd_info['GD Version'] ) ) { |
| 166 |
$gd_info = $gd_info['GD Version']; |
| 167 |
} else { |
| 168 |
$gd_info = wp_json_encode( $gd_info ); |
| 169 |
} |
| 170 |
*/ |
| 171 |
} else { |
| 172 |
return '<strong>Error!</strong> CAPTCHA requires the GD library activated in your PHP configuration.' |
| 173 |
.'Please check more <a href="https://wpbookingcalendar.com/faq/captcha-showing-problems/">here</a>.'; |
| 174 |
} |
| 175 |
|
| 176 |
|
| 177 |
} |
| 178 |
|
| 179 |
|
| 180 |
/** |
| 181 |
* Decide if CAPTCHA can be shown for current request/context. |
| 182 |
* |
| 183 |
* Rules: |
| 184 |
* - Must be enabled in settings (booking_is_use_captcha = On) |
| 185 |
* - Must not be a WP Admin page, except plugin settings form page |
| 186 |
* |
| 187 |
* @return bool |
| 188 |
*/ |
| 189 |
function wpbc_booking_form_is_captcha_allowed_here() { |
| 190 |
|
| 191 |
if ( ( 'On' !== get_bk_option( 'booking_is_use_captcha' ) ) && ( ! WPBC_NEW_FORM_BUILDER ) ) { |
| 192 |
return false; |
| 193 |
} |
| 194 |
|
| 195 |
// In admin area we usually do not show CAPTCHA, except settings form page. |
| 196 |
// if ( is_admin() && ( ! wpbc_is_settings_form_page() ) ) { return false; } //. |
| 197 |
|
| 198 |
// old URI-based logic for edge cases, keep it as extra guard:. |
| 199 |
$server_request_uri = ( isset( $_SERVER['REQUEST_URI'] ) ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 200 |
|
| 201 |
// Optional legacy-style admin URI check. |
| 202 |
$admin_uri = ltrim( str_replace( get_site_url( null, '', 'admin' ), '', admin_url( 'admin.php?' ) ), '/' ); |
| 203 |
|
| 204 |
if ( ( '' !== $server_request_uri ) && ( false !== strpos( $server_request_uri, $admin_uri ) ) && ( ! wpbc_is_settings_form_page() ) ) { |
| 205 |
return false; |
| 206 |
} |
| 207 |
|
| 208 |
return true; |
| 209 |
} |
| 210 |
|
| 211 |
|
| 212 |
/** |
| 213 |
* Default CAPTCHA placeholder replacement for booking form HTML. |
| 214 |
* |
| 215 |
* Replaces [captcha] token with generated CAPTCHA markup (if enabled), |
| 216 |
* or removes the token when CAPTCHA is disabled/not allowed in current context. |
| 217 |
* |
| 218 |
* Add-ons can: |
| 219 |
* - Replace HTML entirely by filtering 'wpbc_booking_form_captcha_html' |
| 220 |
* - Or override this whole replacement by using a lower priority on |
| 221 |
* 'wpbc_booking_form_html__create_captha' / '__create_captcha' |
| 222 |
* |
| 223 |
* @param string $form_html Booking form HTML. |
| 224 |
* @param int $resource_id Booking resource ID. |
| 225 |
* |
| 226 |
* @return string |
| 227 |
*/ |
| 228 |
function wpbc_booking_form_html__create_captcha_default( $form_html, $resource_id ) { |
| 229 |
|
| 230 |
if ( false === strpos( $form_html, '[captcha]' ) ) { |
| 231 |
return $form_html; |
| 232 |
} |
| 233 |
|
| 234 |
$resource_id = (int) $resource_id; |
| 235 |
|
| 236 |
// If CAPTCHA is not allowed here, remove placeholder. |
| 237 |
if ( ! wpbc_booking_form_is_captcha_allowed_here() ) { |
| 238 |
return str_replace( '[captcha]', '', $form_html ); |
| 239 |
} |
| 240 |
|
| 241 |
/** |
| 242 |
* Filter: Provide CAPTCHA HTML for booking form. |
| 243 |
* |
| 244 |
* Return non-empty string to supply your own CAPTCHA markup (addons). |
| 245 |
* Return empty string to let WPBC fallback to the built-in simple CAPTCHA. |
| 246 |
* |
| 247 |
* @param string $captcha_html CAPTCHA HTML (empty by default). |
| 248 |
* @param int $resource_id Booking resource ID. |
| 249 |
* @param array $args Context args. |
| 250 |
*/ |
| 251 |
$captcha_html = apply_filters( 'wpbc_booking_form_captcha_html', '', $resource_id, |
| 252 |
array( |
| 253 |
'context' => 'booking_form', |
| 254 |
'placeholder' => '[captcha]', |
| 255 |
) |
| 256 |
); |
| 257 |
|
| 258 |
if ( '' === $captcha_html ) { |
| 259 |
// Core fallback (your existing generator). |
| 260 |
$captcha_html = wpbc_captcha__simple__generate_html_content( $resource_id ); |
| 261 |
} |
| 262 |
|
| 263 |
return str_replace( '[captcha]', $captcha_html, $form_html ); |
| 264 |
} |
| 265 |
add_filter( 'wpbc_booking_form_html__create_captcha', 'wpbc_booking_form_html__create_captcha_default', 10, 2 ); |
| 266 |
|
| 267 |
|
| 268 |
/** |
| 269 |
* How an add-on supplies a different CAPTCHA (example). |
| 270 |
* add_filter( 'wpbc_booking_form_captcha_html', 'my_addon_wpbc_captcha_html', 20, 3 ); |
| 271 |
* |
| 272 |
* |
| 273 |
* Provide custom CAPTCHA HTML (e.g., reCAPTCHA/hCaptcha). |
| 274 |
* |
| 275 |
* @param string $captcha_html Current HTML (empty by default). |
| 276 |
* @param int $resource_id Booking resource ID. |
| 277 |
* @param array $args Context args. |
| 278 |
* |
| 279 |
* @return string |
| 280 |
* |
| 281 |
* function my_addon_wpbc_captcha_html( $captcha_html, $resource_id, $args ) { |
| 282 |
* |
| 283 |
* // Only replace on booking form rendering context. |
| 284 |
* if ( empty( $args['context'] ) || ( 'booking_form' !== $args['context'] ) ) { |
| 285 |
* return $captcha_html; |
| 286 |
* } |
| 287 |
* |
| 288 |
* // Return your custom markup here. |
| 289 |
* return '<div class="my-addon-captcha">...</div>'; |
| 290 |
* } |
| 291 |
*/ |