settings = $settings; $this->mailer = $mailer; add_action( 'admin_menu', array( $this, 'register_menu' ) ); add_action( 'admin_post_wpcev_save_settings', array( $this, 'handle_save' ) ); add_action( 'admin_post_wpcev_send_test_email', array( $this, 'handle_test_email' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) ); add_filter( 'plugin_action_links_' . WPCEV_PLUGIN_BASENAME, array( $this, 'plugin_action_links' ) ); } public function register_menu() { add_options_page( __( 'Email Verify', 'wpcoretools-email-verify' ), __( 'Email Verify', 'wpcoretools-email-verify' ), 'manage_options', self::PAGE_SLUG, array( $this, 'render_page' ) ); } public function plugin_action_links( $links ) { $url = admin_url( 'options-general.php?page=' . self::PAGE_SLUG ); array_unshift( $links, '' . esc_html__( 'Settings', 'wpcoretools-email-verify' ) . '' ); return $links; } public function enqueue_assets( $hook ) { $is_settings = ( 'settings_page_' . self::PAGE_SLUG === $hook ); $is_wizard = ( WPCEV_Wizard::SCREEN_ID === $hook ); $is_verifications = ( 'users_page_' . WPCEV_Verifications_Page::PAGE_SLUG === $hook ); // WP main dashboard: only load CSS for users who can see our widget. $is_dashboard = ( 'index.php' === $hook && current_user_can( 'manage_options' ) ); // Users list: the status badges of the Verified column. $is_users = ( 'users.php' === $hook && current_user_can( 'list_users' ) ); if ( ! $is_settings && ! $is_wizard && ! $is_dashboard && ! $is_verifications && ! $is_users ) { return; } // Use file mtime as part of the cache key so CSS edits between // releases bust the browser cache reliably (otherwise WPCEV_VERSION // stays "1.0.0" through every rebuild and admins keep seeing a // stale stylesheet). $css_path = WPCEV_PLUGIN_DIR . 'assets/css/admin.css'; $ver = is_readable( $css_path ) ? WPCEV_VERSION . '.' . filemtime( $css_path ) : WPCEV_VERSION; wp_enqueue_style( 'wpcev-admin', WPCEV_PLUGIN_URL . 'assets/css/admin.css', array(), $ver ); } public function handle_save() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have permission to do this.', 'wpcoretools-email-verify' ) ); } check_admin_referer( 'wpcev_save_settings' ); // $_POST['wpcev'] is a structured array; per-field sanitization happens in // WPCEV_Settings::sanitize(), called by ->save(). Sanitizing the raw array // here would corrupt nested values before that schema-aware step. // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $raw = isset( $_POST['wpcev'] ) && is_array( $_POST['wpcev'] ) ? wp_unslash( $_POST['wpcev'] ) : array(); $clean = $this->settings->save( $raw, true ); // Auto-delete just switched on (or its event went missing): make sure the // daily event exists. The handler itself does nothing while the setting is off. if ( ! empty( $clean['auto_delete_unverified'] ) ) { WPCEV_Purge::schedule(); } wp_safe_redirect( add_query_arg( array( 'page' => self::PAGE_SLUG, 'updated' => 1, ), admin_url( 'options-general.php' ) ) ); exit; } public function handle_test_email() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have permission to do this.', 'wpcoretools-email-verify' ) ); } check_admin_referer( 'wpcev_send_test_email' ); $user = wp_get_current_user(); $res = $this->mailer->send_test( $user->ID, $user->user_email ); wp_safe_redirect( add_query_arg( array( 'page' => self::PAGE_SLUG, 'wpcev_test' => $res, ), admin_url( 'options-general.php' ) ) ); exit; } public function render_page() { if ( ! current_user_can( 'manage_options' ) ) { return; } // phpcs:disable WordPress.Security.NonceVerification.Recommended -- read-only flags from our own redirects. $saved = ! empty( $_GET['updated'] ); $wizard_ok = ! empty( $_GET['wpcev_done'] ); $test_state = isset( $_GET['wpcev_test'] ) ? sanitize_key( wp_unslash( $_GET['wpcev_test'] ) ) : ''; $current_tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : 'dashboard'; // phpcs:enable WordPress.Security.NonceVerification.Recommended $valid_tabs = array( 'dashboard', 'settings', 'tools', 'fail-log' ); if ( ! in_array( $current_tab, $valid_tabs, true ) ) { $current_tab = 'dashboard'; } ?>
user_email ) ); ?>
render_companion_callout(); ?>
' . esc_html__( 'Failure log cleared.', 'wpcoretools-email-verify' ) . '
'; } $failures = WPCEV_Stats::get_failures(); ?> purge ? wpcev()->purge : new WPCEV_Purge( $this->settings, wpcev()->tokens ); $wizard_url = function_exists( 'menu_page_url' ) ? menu_page_url( WPCEV_Wizard::PAGE_SLUG, false ) : admin_url( 'admin.php?page=' . WPCEV_Wizard::PAGE_SLUG ); // phpcs:disable WordPress.Security.NonceVerification.Recommended -- read-only flags from our own redirects. $scanned = ! empty( $_GET['wpcev_scanned'] ); $purged_count = isset( $_GET['wpcev_purged'] ) ? (int) $_GET['wpcev_purged'] : -1; $unverified_all_count = isset( $_GET['wpcev_unverified_all'] ) ? (int) $_GET['wpcev_unverified_all'] : -1; // phpcs:enable WordPress.Security.NonceVerification.Recommended $auto_delete_on = (bool) $this->settings->get( 'auto_delete_unverified' ); $threshold_days = (int) $this->settings->get( 'auto_delete_after_days', 30 ); $next_cron = wp_next_scheduled( WPCEV_Purge::CRON_HOOK ); $eligible = $purge->eligible_count(); $grandfathered = $purge->grandfathered_count(); ?>
| — — | |
| () | |
|
WPCEV_Purge::BATCH_SIZE ) : ?>
|
|
|
|
' . wp_kses( WPCEV_Conflicts::format_detail( $issue['detail'] ), array( 'br' => array() ) ) . '