' . esc_html__( 'Number of articles to display (1-6). Default: 3.', 'peptide-repo-core' ) . '
'; } /** * Sanitize the related articles limit to 1-6. * * @param mixed $value Raw input. * @return int */ public static function sanitize_limit( $value ): int { return min( 6, max( 1, (int) $value ) ); } // ── Verification ───────────────────────────────────────────────────── /** * Register Verification settings. * * @return void */ private static function register_verification_section(): void { register_setting( self::OPTION_GROUP, self::SCAN_CADENCE, array( 'type' => 'string', 'default' => 'weekly', 'sanitize_callback' => array( __CLASS__, 'sanitize_cadence' ), ) ); register_setting( self::OPTION_GROUP, self::DEFAULT_THRESHOLD, array( 'type' => 'integer', 'default' => 180, 'sanitize_callback' => 'absint', ) ); register_setting( self::OPTION_GROUP, self::HIGH_VELOCITY_THRESHOLD, array( 'type' => 'integer', 'default' => 60, 'sanitize_callback' => 'absint', ) ); register_setting( self::OPTION_GROUP, self::VERIFICATION_EMAIL, array( 'type' => 'string', 'default' => '', 'sanitize_callback' => array( __CLASS__, 'sanitize_emails' ), ) ); add_settings_section( 'pr_core_verification', __( 'Verification', 'peptide-repo-core' ), array( __CLASS__, 'render_verification_section' ), self::OPTION_GROUP ); add_settings_field( self::SCAN_CADENCE, __( 'Scan cadence', 'peptide-repo-core' ), array( __CLASS__, 'render_cadence_field' ), self::OPTION_GROUP, 'pr_core_verification' ); add_settings_field( self::DEFAULT_THRESHOLD, __( 'Default staleness threshold (days)', 'peptide-repo-core' ), array( __CLASS__, 'render_threshold_field' ), self::OPTION_GROUP, 'pr_core_verification' ); add_settings_field( self::HIGH_VELOCITY_THRESHOLD, __( 'High-velocity threshold (days)', 'peptide-repo-core' ), array( __CLASS__, 'render_high_velocity_field' ), self::OPTION_GROUP, 'pr_core_verification' ); add_settings_field( self::VERIFICATION_EMAIL, __( 'Notification email(s)', 'peptide-repo-core' ), array( __CLASS__, 'render_email_field' ), self::OPTION_GROUP, 'pr_core_verification' ); } /** @return void */ public static function render_verification_section(): void { echo '' . esc_html__( 'Configure automatic staleness scanning and digest notifications.', 'peptide-repo-core' ) . '
'; } /** @return void */ public static function render_cadence_field(): void { $current = get_option( self::SCAN_CADENCE, 'weekly' ); echo ''; } /** @return void */ public static function render_threshold_field(): void { printf( '', esc_attr( self::DEFAULT_THRESHOLD ), absint( get_option( self::DEFAULT_THRESHOLD, 180 ) ) ); } /** @return void */ public static function render_high_velocity_field(): void { printf( '', esc_attr( self::HIGH_VELOCITY_THRESHOLD ), absint( get_option( self::HIGH_VELOCITY_THRESHOLD, 60 ) ) ); } /** @return void */ public static function render_email_field(): void { printf( '', esc_attr( self::VERIFICATION_EMAIL ), esc_attr( (string) get_option( self::VERIFICATION_EMAIL, '' ) ) ); echo '' . esc_html__( 'Comma-separated. Leave blank to disable email digests.', 'peptide-repo-core' ) . '
'; } /** * Sanitize cadence to allowed WP-cron recurrence values. * * @param string $value Raw input. * @return string */ public static function sanitize_cadence( string $value ): string { return in_array( $value, array( 'daily', 'weekly', 'monthly' ), true ) ? $value : 'weekly'; } /** * Sanitize comma-separated email list, keeping only valid addresses. * * @param string $value Raw input. * @return string */ public static function sanitize_emails( string $value ): string { if ( '' === $value ) { return ''; } $valid = array_filter( array_map( 'trim', explode( ',', $value ) ), 'is_email' ); return implode( ', ', $valid ); } /** * Reschedule the verification cron when cadence changes. * * Fires on: update_option_pr_core_scan_cadence. * * @param mixed $old_value Previous option value. * @param mixed $new_value New option value. * @return void */ public static function reschedule_cron( $old_value, $new_value ): void { if ( $old_value === $new_value ) { return; } wp_clear_scheduled_hook( 'pr_core_verification_scan' ); wp_schedule_event( time(), (string) $new_value, 'pr_core_verification_scan' ); } }