*/ public static function defaults() { return array( 'remove_data_on_uninstall' => false, 'retention_days' => 0, // 0 = keep entries forever. 'time_trap' => 3, // Seconds a human needs at least. 'rate_limit' => 20, // Submits per hour per visitor; 0 = off. 'blocklist_words' => '', 'blocklist_emails' => '', 'blocklist_domains' => '', 'captcha' => 'none', 'captcha_site_key' => '', 'captcha_secret' => '', 'recaptcha_threshold' => '0.5', 'proxy_header' => '', ); } /** * Clean the core keys. * * @param array $in Posted. * @param array $old Saved. * @return array */ public static function sanitize_core( array $in, array $old ) { $d = self::defaults(); $captcha = isset( $in['captcha'] ) && in_array( $in['captcha'], self::CAPTCHAS, true ) ? (string) $in['captcha'] : 'none'; $site = isset( $in['captcha_site_key'] ) ? preg_replace( '/[^A-Za-z0-9_\-]/', '', (string) $in['captcha_site_key'] ) : ''; $secret = isset( $in['captcha_secret'] ) ? preg_replace( '/[^A-Za-z0-9_\-]/', '', (string) $in['captcha_secret'] ) : ''; if ( '' === $secret && isset( $old['captcha_secret'] ) && ! empty( $in['captcha_secret_keep'] ) ) { $secret = (string) $old['captcha_secret']; // The field is shown empty; empty + keep = unchanged. } if ( 'none' !== $captcha && ( '' === $site || '' === $secret ) ) { add_settings_error( Options::SETTINGS, 'llforms_captcha', __( 'The captcha needs both keys. It was switched off until both are filled in.', 'laserlead-forms' ) ); $captcha = 'none'; } $threshold = isset( $in['recaptcha_threshold'] ) && is_numeric( $in['recaptcha_threshold'] ) ? max( 0.1, min( 0.9, (float) $in['recaptcha_threshold'] ) ) : (float) $d['recaptcha_threshold']; return array( 'remove_data_on_uninstall' => ! empty( $in['remove_data_on_uninstall'] ), 'retention_days' => isset( $in['retention_days'] ) ? max( 0, min( 3650, (int) $in['retention_days'] ) ) : 0, 'time_trap' => isset( $in['time_trap'] ) ? max( 0, min( 60, (int) $in['time_trap'] ) ) : $d['time_trap'], 'rate_limit' => isset( $in['rate_limit'] ) ? max( 0, min( 1000, (int) $in['rate_limit'] ) ) : $d['rate_limit'], 'blocklist_words' => self::lines( isset( $in['blocklist_words'] ) ? $in['blocklist_words'] : '' ), 'blocklist_emails' => self::lines( isset( $in['blocklist_emails'] ) ? $in['blocklist_emails'] : '' ), 'blocklist_domains' => self::lines( isset( $in['blocklist_domains'] ) ? $in['blocklist_domains'] : '' ), 'captcha' => $captcha, 'captcha_site_key' => $site, 'captcha_secret' => $secret, 'recaptcha_threshold' => (string) round( $threshold, 1 ), 'proxy_header' => isset( $in['proxy_header'] ) && in_array( $in['proxy_header'], self::PROXY_HEADERS, true ) ? (string) $in['proxy_header'] : '', ); } /** * One entry per line, trimmed, de-duplicated, capped. * * @param mixed $raw Raw textarea. * @return string */ private static function lines( $raw ) { $out = array(); foreach ( preg_split( '/\r\n|\r|\n/', sanitize_textarea_field( (string) $raw ) ) as $l ) { $l = trim( $l ); if ( '' !== $l && ! in_array( $l, $out, true ) ) { $out[] = mb_substr( $l, 0, 200 ); } } return implode( "\n", array_slice( $out, 0, 1000 ) ); } /** * A blocklist as an array. * * @param string $key blocklist_words|blocklist_emails|blocklist_domains. * @return string[] */ public static function list_of( $key ) { $s = Options::settings(); $v = isset( $s[ $key ] ) ? (string) $s[ $key ] : ''; return '' === $v ? array() : explode( "\n", $v ); } }