'daily', 'batch_size' => 50, 'check_images' => 1, 'check_external' => 1, 'check_internal' => 1, 'exclude_post_types' => array(), 'exclude_urls' => array(), 'digest_enabled' => 1, 'digest_recipient' => '', 'updates_optin' => 0, 'request_timeout' => 10, 'max_load' => 0, // 0 = auto (number of CPU cores). ); } /** * Returns all settings merged with defaults. * * @return array */ public static function all() { $saved = get_option( self::OPTION_KEY, array() ); if ( ! is_array( $saved ) ) { $saved = array(); } $settings = wp_parse_args( $saved, self::defaults() ); return $settings; } /** * Returns a single setting. * * @param string $key Setting key. * @return mixed */ public static function get( $key ) { $settings = self::all(); return isset( $settings[ $key ] ) ? $settings[ $key ] : null; } /** * Sanitizes settings submitted from the settings screen. * * @param array $input Raw input. * @return array Clean settings. */ public static function sanitize( $input ) { $defaults = self::defaults(); $clean = array(); if ( ! is_array( $input ) ) { return $defaults; } $frequency = isset( $input['scan_frequency'] ) ? sanitize_key( $input['scan_frequency'] ) : 'daily'; if ( ! in_array( $frequency, self::$frequencies, true ) ) { $frequency = 'daily'; } $clean['scan_frequency'] = $frequency; $batch_size = isset( $input['batch_size'] ) ? absint( $input['batch_size'] ) : $defaults['batch_size']; $clean['batch_size'] = max( 10, min( 200, $batch_size ) ); $clean['check_images'] = empty( $input['check_images'] ) ? 0 : 1; $clean['check_external'] = empty( $input['check_external'] ) ? 0 : 1; $clean['check_internal'] = empty( $input['check_internal'] ) ? 0 : 1; $clean['digest_enabled'] = empty( $input['digest_enabled'] ) ? 0 : 1; $recipient = isset( $input['digest_recipient'] ) ? sanitize_email( $input['digest_recipient'] ) : ''; $clean['digest_recipient'] = $recipient; // Product-updates co-consent: explicit, unchecked by default. Record // the opt-in only on the transition from unchecked to checked. $clean['updates_optin'] = empty( $input['updates_optin'] ) ? 0 : 1; $previous = get_option( self::OPTION_KEY, array() ); $was_opted = is_array( $previous ) && ! empty( $previous['updates_optin'] ); if ( $clean['updates_optin'] && ! $was_opted && class_exists( 'LGBF_Optin' ) ) { $optin_email = $recipient ? $recipient : get_option( 'admin_email' ); LGBF_Optin::record( $optin_email, 'digest_settings' ); } $timeout = isset( $input['request_timeout'] ) ? absint( $input['request_timeout'] ) : $defaults['request_timeout']; $clean['request_timeout'] = max( 3, min( 30, $timeout ) ); $clean['max_load'] = isset( $input['max_load'] ) ? min( 64, absint( $input['max_load'] ) ) : 0; $clean['exclude_post_types'] = array(); if ( ! empty( $input['exclude_post_types'] ) && is_array( $input['exclude_post_types'] ) ) { foreach ( $input['exclude_post_types'] as $post_type ) { $post_type = sanitize_key( $post_type ); if ( $post_type ) { $clean['exclude_post_types'][] = $post_type; } } } $clean['exclude_urls'] = array(); if ( isset( $input['exclude_urls'] ) ) { $raw_patterns = is_array( $input['exclude_urls'] ) ? $input['exclude_urls'] : explode( "\n", (string) $input['exclude_urls'] ); foreach ( $raw_patterns as $pattern ) { $pattern = trim( sanitize_text_field( $pattern ) ); if ( '' !== $pattern ) { $clean['exclude_urls'][] = $pattern; } } $clean['exclude_urls'] = array_slice( array_unique( $clean['exclude_urls'] ), 0, 200 ); } return $clean; } /** * Post types eligible for scanning (public, minus exclusions). * * @return string[] */ public static function scannable_post_types() { $post_types = get_post_types( array( 'public' => true ), 'names' ); unset( $post_types['attachment'] ); $excluded = self::get( 'exclude_post_types' ); if ( is_array( $excluded ) ) { $post_types = array_diff( $post_types, $excluded ); } return array_values( $post_types ); } /** * Digest recipient with fallback to the site admin email. * * @return string */ public static function digest_recipient() { $recipient = self::get( 'digest_recipient' ); return $recipient ? $recipient : get_option( 'admin_email' ); } }