| @@ -160,8 +160,9 @@ | ||
| 160 | 160 | * load_textdomain( $domain, WPBC_PLUGIN_DIR . '/languages/' . $domain . '-' . $locale . '.mo' ); |
| 161 | 161 | */ |
| 162 | 162 | |
| 163 | 163 | $plugin_rel_path = WPBC_PLUGIN_DIRNAME . '/languages'; |
| 164 | + // phpcs:ignore PluginCheck.CodeAnalysis.DiscouragedFunctions.load_plugin_textdomainFound | |
| 164 | 165 | $is_mo_loaded = load_plugin_textdomain( $domain, false, $plugin_rel_path ); |
| 165 | 166 | } |
| 166 | 167 | |
| 167 | 168 | |
| @@ -215,23 +216,42 @@ | ||
| 215 | 216 | * @string $locale '' || 'en_US' || 'it_IT' |
| 216 | 217 | */ |
| 217 | 218 | function wpbc_load_country_list_file_php( $locale ){ // FixIn: 8.8.2.5. |
| 218 | 219 | |
| 219 | - if ( ! empty( $locale ) ) { | |
| 220 | - $locale_lang = strtolower( substr( $locale, 0, 2 ) ); | |
| 221 | - $locale_country = strtolower( substr( $locale, 3 ) ); | |
| 220 | + require_once WPBC_PLUGIN_DIR . '/core/lang/wpdev-country-list.php'; | |
| 222 | 221 | |
| 223 | - // FixIn: 8.9.4.12. | |
| 224 | - if ( ( $locale_lang !== 'en' ) && ( wpbc_is_file_exist( '/core/lang/wpdev-country-list-' . $locale . '.php' ) ) ) { | |
| 225 | - require_once WPBC_PLUGIN_DIR . '/core/lang/wpdev-country-list-' . $locale . '.php'; | |
| 226 | - } else { | |
| 227 | - require_once WPBC_PLUGIN_DIR . '/core/lang/wpdev-country-list.php'; | |
| 228 | - } | |
| 229 | - } else { | |
| 230 | - require_once WPBC_PLUGIN_DIR . '/core/lang/wpdev-country-list.php'; | |
| 222 | + do_action( 'wpbc_country_list_loaded' ); // FixIn: 8.9.4.9. | |
| 223 | +} | |
| 224 | + | |
| 225 | + | |
| 226 | +/** | |
| 227 | + * Validate a locale received from a request. | |
| 228 | + * | |
| 229 | + * Locale values are used request-wide and can later be rendered inside JavaScript and HTML attributes. Accept only | |
| 230 | + * ASCII locale identifiers, such as "en", "en_US", "de_DE_formal", or "en-US". Invalid values must be rejected | |
| 231 | + * instead of sanitized into a different value. // FixIn: 11.4.3.2. | |
| 232 | + * | |
| 233 | + * @param mixed $locale Locale value from the request. | |
| 234 | + * | |
| 235 | + * @return string|false Valid locale, or false when the value is invalid. | |
| 236 | + */ | |
| 237 | +function wpbc_validate_request_locale( $locale ) { | |
| 238 | + | |
| 239 | + if ( ! is_string( $locale ) ) { | |
| 240 | + return false; | |
| 231 | 241 | } |
| 232 | 242 | |
| 233 | - do_action( 'wpbc_country_list_loaded' ); // FixIn: 8.9.4.9. | |
| 243 | + $locale = wp_unslash( $locale ); | |
| 244 | + | |
| 245 | + if ( | |
| 246 | + ( '' === $locale ) | |
| 247 | + || ( strlen( $locale ) > 32 ) | |
| 248 | + || ( 1 !== preg_match( '/\A[A-Za-z0-9]+(?:[_-][A-Za-z0-9]+)*\z/D', $locale ) ) | |
| 249 | + ) { | |
| 250 | + return false; | |
| 251 | + } | |
| 252 | + | |
| 253 | + return $locale; | |
| 234 | 254 | } |
| 235 | 255 | |
| 236 | 256 | |
| 237 | 257 | /** |
| @@ -271,15 +291,15 @@ | ||
| 271 | 291 | |
| 272 | 292 | $wpbc_ajx_locale = false; |
| 273 | 293 | // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing |
| 274 | 294 | if ( isset( $_REQUEST['wpdev_active_locale'] ) ) { |
| 275 | - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.NonceVerification.Recommended | |
| 276 | - $wpbc_ajx_locale = sanitize_text_field( $_REQUEST['wpdev_active_locale'] ); | |
| 295 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 296 | + $wpbc_ajx_locale = wpbc_validate_request_locale( $_REQUEST['wpdev_active_locale'] ); | |
| 277 | 297 | } |
| 278 | 298 | // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing |
| 279 | 299 | if ( isset( $_REQUEST['wpbc_ajx_locale'] ) ) { |
| 280 | - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.NonceVerification.Recommended | |
| 281 | - $wpbc_ajx_locale = sanitize_text_field( $_REQUEST['wpbc_ajx_locale'] ); | |
| 300 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 301 | + $wpbc_ajx_locale = wpbc_validate_request_locale( $_REQUEST['wpbc_ajx_locale'] ); | |
| 282 | 302 | } |
| 283 | 303 | |
| 284 | 304 | // Reload locale ONLY in AJAX, and if `isset $_REQUEST['wpdev_active_locale'] |
| 285 | 305 | if ( |
| @@ -389,11 +409,11 @@ | ||
| 389 | 409 | |
| 390 | 410 | /** |
| 391 | 411 | * Translate content. Check for language sections -- [lang=xx_XX] shortcode. // FixIn: 10.0.0.46. |
| 392 | 412 | * |
| 393 | - * @param $content_orig | |
| 413 | + * @param mixed $content_orig Content containing optional language sections. | |
| 394 | 414 | * |
| 395 | - * @return string | |
| 415 | + * @return string Translated content, or an empty string for unsupported values. | |
| 396 | 416 | */ |
| 397 | 417 | function wpbc_lang( $content_orig ) { |
| 398 | 418 | return wpdev_check_for_active_language( $content_orig ); |
| 399 | 419 | } |
| @@ -401,23 +421,31 @@ | ||
| 401 | 421 | |
| 402 | 422 | /** |
| 403 | 423 | * Check plugin text for active language section -- [lang=xx_XX] shortcode |
| 404 | 424 | * |
| 405 | - * @param string $content_orig | |
| 406 | - * @return string | |
| 425 | + * @param mixed $content_orig Content containing optional language sections. | |
| 426 | + * @return string Translated content, or an empty string for unsupported values. | |
| 407 | 427 | * Usage: |
| 408 | 428 | * $text = wpbc_lang( $text ); |
| 409 | 429 | */ |
| 410 | -function wpdev_check_for_active_language( $content_orig ) { | |
| 430 | +function wpdev_check_for_active_language( $content_orig ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound | |
| 411 | 431 | |
| 412 | - $content = $content_orig; | |
| 432 | + if ( is_string( $content_orig ) ) { | |
| 433 | + $content = $content_orig; | |
| 434 | + } elseif ( is_scalar( $content_orig ) ) { | |
| 435 | + $content = (string) $content_orig; | |
| 436 | + } elseif ( is_object( $content_orig ) && method_exists( $content_orig, '__toString' ) ) { | |
| 437 | + $content = (string) $content_orig; | |
| 438 | + } else { | |
| 439 | + return ''; | |
| 440 | + } | |
| 413 | 441 | |
| 414 | - $languages = array(); | |
| 415 | - $content_ex = explode('[lang',$content); | |
| 442 | + $languages = array(); | |
| 443 | + $content_ex = explode( '[lang', $content ); | |
| 416 | 444 | |
| 417 | 445 | foreach ( $content_ex as $value ) { |
| 418 | 446 | |
| 419 | - if ( '=' == substr( $value, 0, 1 ) ) { | |
| 447 | + if ( '=' === substr( $value, 0, 1 ) ) { | |
| 420 | 448 | |
| 421 | 449 | $pos_s = strpos( $value, '=' ); |
| 422 | 450 | $pos_f = strpos( $value, ']' ); |
| 423 | 451 | $key = trim( substr( $value, ( $pos_s + 1 ), ( $pos_f - $pos_s - 1 ) ) ); |
| @@ -428,9 +456,9 @@ | ||
| 428 | 456 | $languages['default'] = $value; |
| 429 | 457 | } |
| 430 | 458 | } |
| 431 | 459 | |
| 432 | - $locale = wpbc_get_maybe_reloaded_booking_locale(); // $locale = 'fr_FR'; | |
| 460 | + $locale = wpbc_get_maybe_reloaded_booking_locale(); // $locale = 'fr_FR'. | |
| 433 | 461 | |
| 434 | 462 | if ( isset( $languages[ $locale ] ) ) { |
| 435 | 463 | $return_text = $languages[ $locale ]; |
| 436 | 464 | } else { |
| @@ -518,8 +546,9 @@ | ||
| 518 | 546 | } else { // WPML Version: 3.2 |
| 519 | 547 | |
| 520 | 548 | // Help info: do_action( 'wpml_register_single_string', string $context, string $name, string $value ) |
| 521 | 549 | // https://wpml.org/wpml-hook/wpml_register_string_for_translation/ |
| 550 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound | |
| 522 | 551 | do_action( 'wpml_register_single_string', 'Booking Calendar', 'wpbc-' . tag_escape( $translation_to_check ) , $translation_to_check ); |
| 523 | 552 | |
| 524 | 553 | |
| 525 | 554 | // Help info: apply_filters( 'wpml_translate_single_string', string $original_value, string $context, string $name, string $$language_code ) |
| @@ -525,8 +554,9 @@ | ||
| 525 | 554 | // Help info: apply_filters( 'wpml_translate_single_string', string $original_value, string $context, string $name, string $$language_code ) |
| 526 | 555 | // https://wpml.org/wpml-hook/wpml_translate_single_string/ |
| 527 | 556 | //$translation_to_check = apply_filters( 'wpml_translate_single_string', $translation_to_check, 'Booking Calendar', 'wpbc-' . tag_escape( $translation_to_check ) ); |
| 528 | 557 | $language_code = $locale; |
| 558 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound | |
| 529 | 559 | $translation_to_check = apply_filters( 'wpml_translate_single_string', $translation_to_check, 'Booking Calendar', 'wpbc-' . tag_escape( $translation_to_check ), $language_code ); |
| 530 | 560 | |
| 531 | 561 | } |
| 532 | 562 | } |
| @@ -741,13 +771,15 @@ | ||
| 741 | 771 | |
| 742 | 772 | /** |
| 743 | 773 | * Download translations from wpbookingcalendar.com, unpack it to the ../WPBC_PLUGIN_DIR/languages/' folder |
| 744 | 774 | * |
| 775 | + * @param WP_Upgrader_Skin|null $skin Optional authorized upgrader skin. | |
| 776 | + * | |
| 745 | 777 | * @return array|bool|string|WP_Error - result |
| 746 | 778 | */ |
| 747 | - function wpbc_translation_download_from_wpbc(){ | |
| 779 | + function wpbc_translation_download_from_wpbc( $skin = null ){ | |
| 748 | 780 | |
| 749 | - $my_upgrader = wpbc_get_translation_upgrader_obj(); | |
| 781 | + $my_upgrader = wpbc_get_translation_upgrader_obj( $skin ); | |
| 750 | 782 | |
| 751 | 783 | $result = $my_upgrader->run( array( |
| 752 | 784 | 'package' => 'https://wpbookingcalendar.com/download/languages/languages.zip', // Please always pass this. |
| 753 | 785 | 'destination' => WPBC_PLUGIN_DIR . '/languages/', // WPBC_PLUGIN_DIR . '/lang/', // ...and this. |
| @@ -764,11 +796,13 @@ | ||
| 764 | 796 | |
| 765 | 797 | /** |
| 766 | 798 | * Get translation Upgrader object |
| 767 | 799 | * |
| 800 | + * @param WP_Upgrader_Skin|null $skin Optional authorized upgrader skin. | |
| 801 | + * | |
| 768 | 802 | * @return WP_Upgrader obj |
| 769 | 803 | */ |
| 770 | - function wpbc_get_translation_upgrader_obj(){ | |
| 804 | + function wpbc_get_translation_upgrader_obj( $skin = null ){ | |
| 771 | 805 | |
| 772 | 806 | require_once ABSPATH . 'wp-admin/includes/file.php'; |
| 773 | 807 | require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
| 774 | 808 | require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; |
| @@ -774,11 +808,13 @@ | ||
| 774 | 808 | require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; |
| 775 | 809 | require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; |
| 776 | 810 | |
| 777 | 811 | require_once WPBC_PLUGIN_DIR . '/core/class/wpbc-class-upgrader-translation-skin.php'; |
| 778 | - $skin = new WPBC_Upgrader_Translation_Skin( | |
| 779 | - array( 'skip_header_footer' => true ) | |
| 780 | - ); | |
| 812 | + if ( ! ( $skin instanceof WP_Upgrader_Skin ) ) { | |
| 813 | + $skin = new WPBC_Upgrader_Translation_Skin( | |
| 814 | + array( 'skip_header_footer' => true ) | |
| 815 | + ); | |
| 816 | + } | |
| 781 | 817 | |
| 782 | 818 | $my_upgrader = new WP_Upgrader( $skin ); |
| 783 | 819 | |
| 784 | 820 | $my_upgrader->init(); // it's required for defining skin messages |
| @@ -808,9 +844,9 @@ | ||
| 808 | 844 | if ( ! is_admin() ) { |
| 809 | 845 | return $translations_arr; |
| 810 | 846 | } |
| 811 | 847 | |
| 812 | - require_once( ABSPATH . 'wp-admin/includes/translation-install.php' ); | |
| 848 | + require_once ABSPATH . 'wp-admin/includes/translation-install.php'; | |
| 813 | 849 | |
| 814 | 850 | $api = translations_api( 'plugins', array( |
| 815 | 851 | 'slug' => 'booking', |
| 816 | 852 | 'version' => WP_BK_VERSION_NUM, //'8.9.3', |
| @@ -1208,9 +1244,9 @@ | ||
| 1208 | 1244 | */ |
| 1209 | 1245 | function wpbc_get_available_language_locales_from_wp_org_api(){ |
| 1210 | 1246 | |
| 1211 | 1247 | // Get Language names for all Locales |
| 1212 | - require_once( ABSPATH . 'wp-admin/includes/translation-install.php' ); | |
| 1248 | + require_once ABSPATH . 'wp-admin/includes/translation-install.php'; | |
| 1213 | 1249 | /** |
| 1214 | 1250 | * Array( ["nl_NL"] => array ( language = "nl_NL" |
| 1215 | 1251 | version = "5.9" |
| 1216 | 1252 | updated = "2022-02-10 16:24:09" |
| @@ -1422,9 +1458,9 @@ | ||
| 1422 | 1458 | * Load translation POT file, and generate PHP file with all translations relative to plugin. |
| 1423 | 1459 | * Link: http://server.com/wp-admin/admin.php?page=wpbc-settings&system_info=show&pot=1#wpbc_general_settings_system_info_metabox |
| 1424 | 1460 | */ |
| 1425 | 1461 | function wpbc_pot_to_php() { |
| 1426 | - | |
| 1462 | + return; | |
| 1427 | 1463 | /* |
| 1428 | 1464 | * $shortcode = 'wpml'; |
| 1429 | 1465 | |
| 1430 | 1466 | // Find anything between [wpml] and [/wpml] shortcodes. Magic here: [\s\S]*? - fit to any text |