| @@ -117,9 +117,9 @@ | ||
| 117 | 117 | } |
| 118 | 118 | } |
| 119 | 119 | |
| 120 | 120 | if ( ! function_exists( 'fs_enqueue_local_script' ) ) { |
| 121 | - function fs_enqueue_local_script( $handle, $path, $deps = array(), $ver = false, $in_footer = 'all' ) { | |
| 121 | + function fs_enqueue_local_script( $handle, $path, $deps = array(), $ver = false, $in_footer = true ) { | |
| 122 | 122 | wp_enqueue_script( $handle, fs_asset_url( WP_FS__DIR_JS . '/' . trim( $path, '/' ) ), $deps, $ver, $in_footer ); |
| 123 | 123 | } |
| 124 | 124 | } |
| 125 | 125 | |
| @@ -132,48 +132,103 @@ | ||
| 132 | 132 | #-------------------------------------------------------------------------------- |
| 133 | 133 | #region Request handlers. |
| 134 | 134 | #-------------------------------------------------------------------------------- |
| 135 | 135 | |
| 136 | - if ( ! function_exists( 'fs_request_get' ) ) { | |
| 136 | + if ( ! function_exists( 'fs_request_get_raw' ) ) { | |
| 137 | 137 | /** |
| 138 | - * A helper method to fetch GET/POST user input with an optional default value when the input is not set. | |
| 139 | - * @author Vova Feldman (@svovaf) | |
| 138 | + * A helper function to fetch GET/POST user input with an optional default value when the input is not set. | |
| 139 | + * This function does not do sanitization. It is up to the caller to properly sanitize and validate the input. | |
| 140 | 140 | * |
| 141 | + * The return of this function is always unslashed. | |
| 142 | + * | |
| 143 | + * @since 2.5.10 | |
| 144 | + * | |
| 141 | 145 | * @param string $key |
| 142 | 146 | * @param mixed $def |
| 143 | - * @param string|bool $type Since 1.2.1.7 - when set to 'get' will look for the value passed via querystring, when | |
| 144 | - * set to 'post' will look for the value passed via the POST request's body, otherwise, | |
| 145 | - * will check if the parameter was passed in any of the two. | |
| 147 | + * @param string|bool $type When set to 'get', it will look for the value passed via query string. When | |
| 148 | + * set to 'post', it will look for the value passed via the POST request's body. Otherwise, | |
| 149 | + * it will check if the parameter was passed using any of the mentioned two methods. | |
| 146 | 150 | * |
| 147 | 151 | * @return mixed |
| 148 | 152 | */ |
| 149 | - function fs_request_get( $key, $def = false, $type = false ) { | |
| 153 | + function fs_request_get_raw( $key, $def = false, $type = false ) { | |
| 150 | 154 | if ( is_string( $type ) ) { |
| 151 | 155 | $type = strtolower( $type ); |
| 152 | 156 | } |
| 153 | 157 | |
| 154 | 158 | /** |
| 155 | - * Note to WordPress.org Reviewers: | |
| 156 | - * This is a helper method to fetch GET/POST user input with an optional default value when the input is not set. The actual sanitization is done in the scope of the function's usage. | |
| 159 | + * Note to WordPress.org reviewers: | |
| 160 | + * This is a helper function to fetch GET/POST user input with an optional default value when the input is not set. The actual sanitization is done in the scope of the function's usage. | |
| 157 | 161 | */ |
| 158 | 162 | switch ( $type ) { |
| 159 | 163 | case 'post': |
| 164 | + // phpcs:ignore WordPress.Security.NonceVerification.Missing | |
| 160 | 165 | $value = isset( $_POST[ $key ] ) ? $_POST[ $key ] : $def; |
| 161 | 166 | break; |
| 162 | 167 | case 'get': |
| 168 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 163 | 169 | $value = isset( $_GET[ $key ] ) ? $_GET[ $key ] : $def; |
| 164 | 170 | break; |
| 165 | 171 | default: |
| 172 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 166 | 173 | $value = isset( $_REQUEST[ $key ] ) ? $_REQUEST[ $key ] : $def; |
| 167 | 174 | break; |
| 168 | 175 | } |
| 169 | 176 | |
| 170 | - return $value; | |
| 177 | + // Don't unslash if the value itself is empty (empty string, null, empty array etc). | |
| 178 | + return empty( $value ) ? $value : wp_unslash( $value ); | |
| 171 | 179 | } |
| 172 | 180 | } |
| 173 | 181 | |
| 182 | + if ( ! function_exists( 'fs_sanitize_input' ) ) { | |
| 183 | + /** | |
| 184 | + * Sanitizes input recursively (if an array). | |
| 185 | + * | |
| 186 | + * @param mixed $input | |
| 187 | + * | |
| 188 | + * @return mixed | |
| 189 | + * @uses sanitize_text_field() | |
| 190 | + * @since 2.5.10 | |
| 191 | + */ | |
| 192 | + function fs_sanitize_input( $input ) { | |
| 193 | + if ( is_array( $input ) ) { | |
| 194 | + foreach ( $input as $key => $value ) { | |
| 195 | + $input[ $key ] = fs_sanitize_input( $value ); | |
| 196 | + } | |
| 197 | + } else { | |
| 198 | + // Allow empty values to pass through as-is, like `null`, `''`, `0`, `'0'` etc. | |
| 199 | + $input = empty( $input ) ? $input : sanitize_text_field( $input ); | |
| 200 | + } | |
| 201 | + | |
| 202 | + return $input; | |
| 203 | + } | |
| 204 | + } | |
| 205 | + | |
| 206 | + if ( ! function_exists( 'fs_request_get' ) ) { | |
| 207 | + /** | |
| 208 | + * A helper method to fetch GET/POST user input with an optional default value when the input is not set. | |
| 209 | + * | |
| 210 | + * @author Vova Feldman (@svovaf) | |
| 211 | + * | |
| 212 | + * @note The return value is always sanitized with sanitize_text_field(). | |
| 213 | + * | |
| 214 | + * @param string $key | |
| 215 | + * @param mixed $def | |
| 216 | + * @param string|bool $type Since 1.2.1.7 - when set to 'get' will look for the value passed via querystring, when | |
| 217 | + * set to 'post' will look for the value passed via the POST request's body, otherwise, | |
| 218 | + * will check if the parameter was passed in any of the two. | |
| 219 | + * | |
| 220 | + * | |
| 221 | + * @return mixed | |
| 222 | + */ | |
| 223 | + function fs_request_get( $key, $def = false, $type = false ) { | |
| 224 | + return fs_sanitize_input( fs_request_get_raw( $key, $def, $type ) ); | |
| 225 | + } | |
| 226 | + } | |
| 227 | + | |
| 174 | 228 | if ( ! function_exists( 'fs_request_has' ) ) { |
| 175 | 229 | function fs_request_has( $key ) { |
| 230 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended | |
| 176 | 231 | return isset( $_REQUEST[ $key ] ); |
| 177 | 232 | } |
| 178 | 233 | } |
| 179 | 234 | |
| @@ -230,8 +285,9 @@ | ||
| 230 | 285 | } |
| 231 | 286 | |
| 232 | 287 | if ( ! function_exists( 'fs_get_action' ) ) { |
| 233 | 288 | function fs_get_action( $action_key = 'action' ) { |
| 289 | + // phpcs:disable WordPress.Security.NonceVerification.Recommended | |
| 234 | 290 | if ( ! empty( $_REQUEST[ $action_key ] ) && is_string( $_REQUEST[ $action_key ] ) ) { |
| 235 | 291 | return strtolower( $_REQUEST[ $action_key ] ); |
| 236 | 292 | } |
| 237 | 293 | |
| @@ -243,8 +299,9 @@ | ||
| 243 | 299 | } |
| 244 | 300 | } |
| 245 | 301 | |
| 246 | 302 | return false; |
| 303 | + // phpcs:enable WordPress.Security.NonceVerification.Recommended | |
| 247 | 304 | } |
| 248 | 305 | } |
| 249 | 306 | |
| 250 | 307 | if ( ! function_exists( 'fs_request_is_action' ) ) { |
| @@ -530,8 +587,35 @@ | ||
| 530 | 587 | return add_query_arg( $name, wp_create_nonce( $action ), $actionurl ); |
| 531 | 588 | } |
| 532 | 589 | } |
| 533 | 590 | |
| 591 | + if ( ! function_exists( 'fs_parse_url_params' ) ) { | |
| 592 | + /** | |
| 593 | + * Returns the query parameters of the given URL if there are any. | |
| 594 | + * | |
| 595 | + * @param string $url | |
| 596 | + * @param bool $html_entity_decode | |
| 597 | + * | |
| 598 | + * @return array<string, string> Key value pair where key represents the parameter name and value represents the parameter value. | |
| 599 | + */ | |
| 600 | + function fs_parse_url_params( $url, $html_entity_decode = false ) { | |
| 601 | + $query_str = parse_url( $url, PHP_URL_QUERY ); | |
| 602 | + $url_params = array(); | |
| 603 | + | |
| 604 | + if ( empty( $query_str ) ) { | |
| 605 | + return $url_params; | |
| 606 | + } | |
| 607 | + | |
| 608 | + if ( $html_entity_decode ) { | |
| 609 | + $query_str = html_entity_decode( $query_str ); | |
| 610 | + } | |
| 611 | + | |
| 612 | + parse_str( $query_str, $url_params ); | |
| 613 | + | |
| 614 | + return $url_params; | |
| 615 | + } | |
| 616 | + } | |
| 617 | + | |
| 534 | 618 | if ( ! function_exists( 'fs_starts_with' ) ) { |
| 535 | 619 | /** |
| 536 | 620 | * Check if string starts with. |
| 537 | 621 | * |
| @@ -755,9 +839,9 @@ | ||
| 755 | 839 | return 1; |
| 756 | 840 | } // If b has a priority and a does not, b wins. |
| 757 | 841 | elseif ( isset( $a['priority'] ) && ! isset( $b['priority'] ) ) { |
| 758 | 842 | return - 1; |
| 759 | - } // If neither has a priority or both priorities are equal its a tie. | |
| 843 | + } // If neither has a priority or both priorities are equal it's a tie. | |
| 760 | 844 | elseif ( ( ! isset( $a['priority'] ) && ! isset( $b['priority'] ) ) || $a['priority'] === $b['priority'] ) { |
| 761 | 845 | return 0; |
| 762 | 846 | } |
| 763 | 847 | |
| @@ -769,8 +853,14 @@ | ||
| 769 | 853 | #-------------------------------------------------------------------------------- |
| 770 | 854 | #region Localization |
| 771 | 855 | #-------------------------------------------------------------------------------- |
| 772 | 856 | |
| 857 | + global $fs_text_overrides; | |
| 858 | + | |
| 859 | + if ( ! isset( $fs_text_overrides ) ) { | |
| 860 | + $fs_text_overrides = array(); | |
| 861 | + } | |
| 862 | + | |
| 773 | 863 | if ( ! function_exists( 'fs_text' ) ) { |
| 774 | 864 | /** |
| 775 | 865 | * Retrieve a translated text by key. |
| 776 | 866 | * |
| @@ -781,14 +871,12 @@ | ||
| 781 | 871 | * @param string $slug |
| 782 | 872 | * |
| 783 | 873 | * @return string |
| 784 | 874 | * |
| 785 | - * @global $fs_text , $fs_text_overrides | |
| 875 | + * @global $fs_text_overrides | |
| 786 | 876 | */ |
| 787 | 877 | function fs_text( $key, $slug = 'freemius' ) { |
| 788 | - global $fs_text, | |
| 789 | - $fs_module_info_text, | |
| 790 | - $fs_text_overrides; | |
| 878 | + global $fs_text_overrides; | |
| 791 | 879 | |
| 792 | 880 | if ( isset( $fs_text_overrides[ $slug ] ) ) { |
| 793 | 881 | if ( isset( $fs_text_overrides[ $slug ][ $key ] ) ) { |
| 794 | 882 | return $fs_text_overrides[ $slug ][ $key ]; |
| @@ -799,24 +887,8 @@ | ||
| 799 | 887 | return $fs_text_overrides[ $slug ][ $lower_key ]; |
| 800 | 888 | } |
| 801 | 889 | } |
| 802 | 890 | |
| 803 | - if ( ! isset( $fs_text ) ) { | |
| 804 | - $dir = defined( 'WP_FS__DIR_INCLUDES' ) ? | |
| 805 | - WP_FS__DIR_INCLUDES : | |
| 806 | - dirname( __FILE__ ); | |
| 807 | - | |
| 808 | - require_once $dir . '/i18n.php'; | |
| 809 | - } | |
| 810 | - | |
| 811 | - if ( isset( $fs_text[ $key ] ) ) { | |
| 812 | - return $fs_text[ $key ]; | |
| 813 | - } | |
| 814 | - | |
| 815 | - if ( isset( $fs_module_info_text[ $key ] ) ) { | |
| 816 | - return $fs_module_info_text[ $key ]; | |
| 817 | - } | |
| 818 | - | |
| 819 | 891 | return $key; |
| 820 | 892 | } |
| 821 | 893 | |
| 822 | 894 | #region Private |
| @@ -1158,9 +1230,9 @@ | ||
| 1158 | 1230 | * @param string $context Context information for the translators. |
| 1159 | 1231 | * @param string $key String key for overrides. |
| 1160 | 1232 | * @param string $slug Module slug for overrides. |
| 1161 | 1233 | * |
| 1162 | - * @return string | |
| 1234 | + * @return void | |
| 1163 | 1235 | */ |
| 1164 | 1236 | function fs_esc_js_echo_x_inline( $text, $context, $key = '', $slug = 'freemius' ) { |
| 1165 | 1237 | echo esc_js( _fs_text_x_inline( $text, $context, $key, $slug ) ); |
| 1166 | 1238 | } |
| @@ -1348,9 +1420,9 @@ | ||
| 1348 | 1420 | */ |
| 1349 | 1421 | function fs_is_plugin_uninstall() { |
| 1350 | 1422 | return ( |
| 1351 | 1423 | defined( 'WP_UNINSTALL_PLUGIN' ) || |
| 1352 | - ( 0 < did_action( 'update_option_uninstall_plugins' ) ) | |
| 1424 | + ( 0 < did_action( 'pre_uninstall_plugin' ) ) | |
| 1353 | 1425 | ); |
| 1354 | 1426 | } |
| 1355 | 1427 | } |
| 1356 | 1428 | |
| @@ -1412,5 +1484,22 @@ | ||
| 1412 | 1484 | array( "fs_{$tag}_{$module_unique_affix}" ), |
| 1413 | 1485 | array_slice( $args, 2 ) ) |
| 1414 | 1486 | ); |
| 1415 | 1487 | } |
| 1416 | - } | |
| 1488 | + } | |
| 1489 | + | |
| 1490 | + if ( ! function_exists( 'fs_get_optional_constant' ) ) { | |
| 1491 | + /** | |
| 1492 | + * Gets the value of an optional constant. If the constant is not defined, the default value will be returned. | |
| 1493 | + * | |
| 1494 | + * @author Swashata Ghosh (@swashata) | |
| 1495 | + * @since 2.5.12.5 | |
| 1496 | + * | |
| 1497 | + * @param string $constant_name | |
| 1498 | + * @param mixed $default_value | |
| 1499 | + * | |
| 1500 | + * @return mixed | |
| 1501 | + */ | |
| 1502 | + function fs_get_optional_constant( $constant_name, $default_value = null ) { | |
| 1503 | + return defined( $constant_name ) ? constant( $constant_name ) : $default_value; | |
| 1504 | + } | |
| 1505 | + } | |