| @@ -1,11 +1,15 @@ | ||
| 1 | 1 | <?php |
| 2 | + | |
| 3 | +use Give\Log\Log; | |
| 4 | +use Give\Framework\Database\DB; | |
| 5 | +use Give\Log\ValueObjects\LogType; | |
| 2 | 6 | /** |
| 3 | 7 | * Front-end Filters |
| 4 | 8 | * |
| 5 | 9 | * @package Give |
| 6 | 10 | * @subpackage Functions |
| 7 | - * @copyright Copyright (c) 2016, WordImpress | |
| 11 | + * @copyright Copyright (c) 2016, GiveWP | |
| 8 | 12 | * @license https://opensource.org/licenses/gpl-license GNU Public License |
| 9 | 13 | * @since 1.0 |
| 10 | 14 | */ |
| 11 | 15 | |
| @@ -80,11 +84,13 @@ | ||
| 80 | 84 | * |
| 81 | 85 | * @return bool|mixed |
| 82 | 86 | */ |
| 83 | 87 | function give_akismet( $spam ) { |
| 88 | + // Build args array. | |
| 89 | + $args = []; | |
| 84 | 90 | |
| 85 | 91 | // Bail out, If spam. |
| 86 | - if ( $spam ) { | |
| 92 | + if ( $spam || ! give_is_setting_enabled( give_get_option( 'akismet_spam_protection' ) ) ) { | |
| 87 | 93 | return $spam; |
| 88 | 94 | } |
| 89 | 95 | |
| 90 | 96 | // Bail out, if Akismet key not exist. |
| @@ -91,23 +97,36 @@ | ||
| 91 | 97 | if ( ! give_check_akismet_key() ) { |
| 92 | 98 | return false; |
| 93 | 99 | } |
| 94 | 100 | |
| 95 | - // Build args array. | |
| 96 | - $args = array(); | |
| 101 | + $args['comment_author_email'] = isset( $_POST['give_email'] ) ? sanitize_email( $_POST['give_email'] ) : false; | |
| 97 | 102 | |
| 98 | - $args['comment_author'] = isset( $_POST['give_first'] ) ? give_clean( $_POST['give_first'] ) : ''; | |
| 99 | - $args['comment_author_email'] = isset( $_POST['give_email'] ) ? sanitize_email( $_POST['give_email'] ) : false; | |
| 100 | - $args['blog'] = get_option( 'home' ); | |
| 101 | - $args['blog_lang'] = get_locale(); | |
| 102 | - $args['blog_charset'] = get_option( 'blog_charset' ); | |
| 103 | - $args['user_ip'] = $_SERVER['REMOTE_ADDR']; | |
| 104 | - $args['user_agent'] = $_SERVER['HTTP_USER_AGENT']; | |
| 105 | - $args['referrer'] = $_SERVER['HTTP_REFERER']; | |
| 106 | - $args['comment_type'] = 'contact-form'; | |
| 103 | + /** | |
| 104 | + * Filter list of whitelisted emails | |
| 105 | + * | |
| 106 | + * @since 2.5.14 | |
| 107 | + * | |
| 108 | + * @param array | |
| 109 | + */ | |
| 110 | + $whitelist_emails = apply_filters( 'give_akismet_whitelist_emails', give_akismet_get_whitelisted_emails() ); | |
| 107 | 111 | |
| 108 | - $form_id = isset( $_POST['give-form-id'] ) ? absint( $_POST['give-form-id'] ) : 0; | |
| 112 | + // Whitelist emails. | |
| 113 | + if ( in_array( $args['comment_author_email'], (array) $whitelist_emails, true ) ) { | |
| 114 | + return false; | |
| 115 | + } | |
| 109 | 116 | |
| 117 | + $args['comment_author'] = isset( $_POST['give_first'] ) ? give_clean( $_POST['give_first'] ) : ''; | |
| 118 | + $args['blog'] = get_option( 'home' ); | |
| 119 | + $args['blog_lang'] = get_locale(); | |
| 120 | + $args['blog_charset'] = get_option( 'blog_charset' ); | |
| 121 | + $args['user_ip'] = $_SERVER['REMOTE_ADDR']; | |
| 122 | + $args['user_agent'] = $_SERVER['HTTP_USER_AGENT']; | |
| 123 | + $args['referrer'] = $_SERVER['HTTP_REFERER']; | |
| 124 | + $args['comment_type'] = 'contact-form'; | |
| 125 | + | |
| 126 | + $form_id = isset( $_POST['give-form-id'] ) ? absint( $_POST['give-form-id'] ) : 0; | |
| 127 | + $donor_last_name = ! empty( $_POST['give_last'] ) ? ' ' . give_clean( $_POST['give_last'] ) : ''; | |
| 128 | + | |
| 110 | 129 | // Pass Donor comment if enabled. |
| 111 | 130 | if ( give_is_donor_comment_field_enabled( $form_id ) ) { |
| 112 | 131 | $give_comment = isset( $_POST['give_comment'] ) ? give_clean( $_POST['give_comment'] ) : ''; |
| 113 | 132 | |
| @@ -113,18 +132,48 @@ | ||
| 113 | 132 | |
| 114 | 133 | $args['comment_content'] = $give_comment; |
| 115 | 134 | } |
| 116 | 135 | |
| 117 | - $ignore = array( 'HTTP_COOKIE', 'HTTP_COOKIE2', 'PHP_AUTH_PW' ); | |
| 136 | + $ignore = [ 'HTTP_COOKIE', 'HTTP_COOKIE2', 'PHP_AUTH_PW' ]; | |
| 118 | 137 | |
| 119 | 138 | foreach ( $_SERVER as $key => $value ) { |
| 120 | - if ( ! in_array( $key, (array) $ignore ) ) { | |
| 121 | - $args["$key"] = $value; | |
| 139 | + if ( ! in_array( $key, $ignore, true ) ) { | |
| 140 | + $args[ $key ] = $value; | |
| 122 | 141 | } |
| 123 | 142 | } |
| 124 | 143 | |
| 144 | + $response = give_akismet_spam_check_post( $args ); | |
| 145 | + $spam = 'true' === $response[1]; | |
| 146 | + | |
| 147 | + // Log spam information. | |
| 148 | + if ( $spam && ! give_akismet_is_email_logged( $args['comment_author_email'] ) ) { | |
| 149 | + | |
| 150 | + $title = sprintf( | |
| 151 | + 'This donor\'s email (%1$s%2$s - %3$s) has been flagged as SPAM', | |
| 152 | + $args['comment_author'], | |
| 153 | + $donor_last_name, | |
| 154 | + $args['comment_author_email'] | |
| 155 | + ); | |
| 156 | + | |
| 157 | + $message = sprintf( | |
| 158 | + '<p><strong>%1$s</strong><pre>%2$s</pre></p><strong>%3$s</strong><pre>%4$s</pre><p>', | |
| 159 | + __( 'Request', 'give' ), | |
| 160 | + print_r( $args, true ), | |
| 161 | + __( 'Response', 'give' ), | |
| 162 | + print_r( $response, true ) | |
| 163 | + ); | |
| 164 | + | |
| 165 | + $context = [ | |
| 166 | + 'donor_email' => $args['comment_author_email'], | |
| 167 | + 'filter' => 'akismet', | |
| 168 | + 'message' => $message, | |
| 169 | + ]; | |
| 170 | + | |
| 171 | + Log::spam( $title, $context ); | |
| 172 | + } | |
| 173 | + | |
| 125 | 174 | // It will return Akismet spam detect API response. |
| 126 | - return give_akismet_spam_check( $args ); | |
| 175 | + return $spam; | |
| 127 | 176 | |
| 128 | 177 | } |
| 129 | 178 | |
| 130 | 179 | add_filter( 'give_spam', 'give_akismet' ); |
| @@ -136,9 +185,9 @@ | ||
| 136 | 185 | * |
| 137 | 186 | * @return bool |
| 138 | 187 | */ |
| 139 | 188 | function give_check_akismet_key() { |
| 140 | - if ( is_callable( array( 'Akismet', 'get_api_key' ) ) ) { // Akismet v3.0+ | |
| 189 | + if ( is_callable( [ 'Akismet', 'get_api_key' ] ) ) { // Akismet v3.0+ | |
| 141 | 190 | return (bool) Akismet::get_api_key(); |
| 142 | 191 | } |
| 143 | 192 | |
| 144 | 193 | if ( function_exists( 'akismet_get_key' ) ) { |
| @@ -150,37 +199,87 @@ | ||
| 150 | 199 | |
| 151 | 200 | /** |
| 152 | 201 | * Detect spam through Akismet Comment API. |
| 153 | 202 | * |
| 203 | + * @param array $args | |
| 204 | + * | |
| 205 | + * @return bool|mixed | |
| 154 | 206 | * @since 1.8.14 |
| 207 | + * @since 2.3.15 Refactor function to use give_akismet_spam_check_post | |
| 208 | + */ | |
| 209 | +function give_akismet_spam_check( $args ) { | |
| 210 | + $response = give_akismet_spam_check_post( $args ); | |
| 211 | + | |
| 212 | + // It's spam if response status is true. | |
| 213 | + $spam = 'true' === $response[1]; | |
| 214 | + | |
| 215 | + // Allow developer to modified Akismet spam detection response. | |
| 216 | + return apply_filters( 'give_akismet_spam_check', $spam, $args ); | |
| 217 | +} | |
| 218 | + | |
| 219 | +/** | |
| 220 | + * Detect spam through Akismet Comment API. | |
| 155 | 221 | * |
| 222 | + * @since 2.5.13 | |
| 223 | + * | |
| 156 | 224 | * @param array $args |
| 157 | 225 | * |
| 158 | - * @return bool|mixed | |
| 226 | + * @return array | |
| 159 | 227 | */ |
| 160 | -function give_akismet_spam_check( $args ) { | |
| 228 | +function give_akismet_spam_check_post( $args ) { | |
| 161 | 229 | global $akismet_api_host, $akismet_api_port; |
| 162 | 230 | |
| 163 | - $spam = false; | |
| 164 | 231 | $query_string = http_build_query( $args ); |
| 165 | 232 | |
| 166 | - if ( is_callable( array( 'Akismet', 'http_post' ) ) ) { // Akismet v3.0+ | |
| 233 | + if ( is_callable( [ 'Akismet', 'http_post' ] ) ) { // Akismet v3.0+ | |
| 167 | 234 | $response = Akismet::http_post( $query_string, 'comment-check' ); |
| 168 | 235 | } else { |
| 169 | - $response = akismet_http_post( $query_string, $akismet_api_host, | |
| 170 | - '/1.1/comment-check', $akismet_api_port ); | |
| 236 | + $response = akismet_http_post( | |
| 237 | + $query_string, | |
| 238 | + $akismet_api_host, | |
| 239 | + '/1.1/comment-check', | |
| 240 | + $akismet_api_port | |
| 241 | + ); | |
| 171 | 242 | } |
| 172 | 243 | |
| 173 | - // It's spam if response status is true. | |
| 174 | - if ( 'true' === $response[1] ) { | |
| 175 | - $spam = true; | |
| 176 | - } | |
| 244 | + return $response; | |
| 245 | +} | |
| 177 | 246 | |
| 178 | - // Allow developer to modified Akismet spam detection response. | |
| 179 | - return apply_filters( 'give_akismet_spam_check', $spam, $args ); | |
| 247 | + | |
| 248 | +/** | |
| 249 | + * Check if email already logged or not | |
| 250 | + * | |
| 251 | + * @param $email | |
| 252 | + * | |
| 253 | + * @return bool | |
| 254 | + * @since 2.5.13 | |
| 255 | + */ | |
| 256 | +function give_akismet_is_email_logged( $email ) { | |
| 257 | + global $wpdb; | |
| 258 | + | |
| 259 | + return (bool) DB::get_var( | |
| 260 | + DB::prepare( | |
| 261 | + "SELECT COUNT(id) FROM {$wpdb->give_log} WHERE log_type = %s AND data LIKE '%s';", | |
| 262 | + LogType::SPAM, | |
| 263 | + '%' . esc_sql( $email ) . '%' | |
| 264 | + ) | |
| 265 | + ); | |
| 180 | 266 | } |
| 181 | 267 | |
| 182 | 268 | /** |
| 269 | + * Get list of whitelisted emails. | |
| 270 | + * | |
| 271 | + * @return array | |
| 272 | + * @since 2.5.13 | |
| 273 | + */ | |
| 274 | +function give_akismet_get_whitelisted_emails() { | |
| 275 | + return give_get_option( | |
| 276 | + 'akismet_whitelisted_email_addresses', | |
| 277 | + get_bloginfo( 'admin_email' ) | |
| 278 | + ); | |
| 279 | +} | |
| 280 | + | |
| 281 | +/** | |
| 183 | 282 | * Add support of RIAL code for backward compatibility. |
| 184 | 283 | * Note: for internal use only |
| 185 | 284 | * |
| 186 | 285 | * @since 1.8.17 |
| @@ -189,16 +288,16 @@ | ||
| 189 | 288 | * |
| 190 | 289 | * @return array |
| 191 | 290 | */ |
| 192 | 291 | function give_bc_v1817_iranian_currency_code( $currencies ) { |
| 193 | - if ( ! give_has_upgrade_completed( 'v1817_update_donation_iranian_currency_code' ) ) { | |
| 194 | - $currencies['RIAL'] = $currencies['IRR']; | |
| 195 | - } | |
| 292 | + $currencies['RIAL'] = $currencies['IRR']; | |
| 196 | 293 | |
| 197 | 294 | return $currencies; |
| 198 | 295 | } |
| 199 | 296 | |
| 200 | -add_filter( 'give_currencies', 'give_bc_v1817_iranian_currency_code', 0 ); | |
| 297 | +if ( ! give_has_upgrade_completed( 'v1817_update_donation_iranian_currency_code' ) ) { | |
| 298 | + add_filter( 'give_currencies', 'give_bc_v1817_iranian_currency_code', 0 ); | |
| 299 | +} | |
| 201 | 300 | |
| 202 | 301 | |
| 203 | 302 | /** |
| 204 | 303 | * Format right to left supported currency amount. |
| @@ -233,8 +332,9 @@ | ||
| 233 | 332 | |
| 234 | 333 | /** |
| 235 | 334 | * Validate active gateway value before returning result. |
| 236 | 335 | * |
| 336 | + * @since 4.9.0 rename function - PHP 8 compatibility | |
| 237 | 337 | * @since 2.1.0 |
| 238 | 338 | * |
| 239 | 339 | * @param $value |
| 240 | 340 | * |
| @@ -239,17 +339,17 @@ | ||
| 239 | 339 | * @param $value |
| 240 | 340 | * |
| 241 | 341 | * @return array |
| 242 | 342 | */ |
| 243 | -function __give_validate_active_gateways( $value ) { | |
| 244 | - $gateways = array_keys( give_get_payment_gateways() ); | |
| 245 | - $active_gateways = is_array( $value ) ? array_keys( $value ) : array(); | |
| 343 | +function give_validate_active_gateways( $value ) { | |
| 344 | + $gateways = array_keys( give_get_payment_gateways() ); | |
| 345 | + $active_gateways = is_array( $value ) ? array_keys( $value ) : []; | |
| 246 | 346 | |
| 247 | 347 | // Remove deactivated payment gateways. |
| 248 | - if( ! empty( $active_gateways ) ) { | |
| 348 | + if ( ! empty( $active_gateways ) ) { | |
| 249 | 349 | foreach ( $active_gateways as $index => $gateway_id ) { |
| 250 | - if( ! in_array( $gateway_id, $gateways ) ) { | |
| 251 | - unset( $value[$gateway_id] ); | |
| 350 | + if ( ! in_array( $gateway_id, $gateways ) ) { | |
| 351 | + unset( $value[ $gateway_id ] ); | |
| 252 | 352 | } |
| 253 | 353 | } |
| 254 | 354 | } |
| 255 | 355 | |
| @@ -258,13 +358,16 @@ | ||
| 258 | 358 | * Filter the default active gateway |
| 259 | 359 | * |
| 260 | 360 | * @since 2.1.0 |
| 261 | 361 | */ |
| 262 | - $value = apply_filters( 'give_default_active_gateways', array( | |
| 263 | - 'manual' => 1, | |
| 264 | - ) ); | |
| 362 | + $value = apply_filters( | |
| 363 | + 'give_default_active_gateways', | |
| 364 | + [ | |
| 365 | + 'manual' => 1, | |
| 366 | + ] | |
| 367 | + ); | |
| 265 | 368 | } |
| 266 | 369 | |
| 267 | 370 | return $value; |
| 268 | 371 | } |
| 269 | 372 | |
| 270 | -add_filter( 'give_get_option_gateways', '__give_validate_active_gateways', 10, 1 ); | |
| 373 | +add_filter( 'give_get_option_gateways', 'give_validate_active_gateways', 10, 1 ); | |