MailProbe) and the two notices. * * @package MailProbe */ defined( 'ABSPATH' ) || exit; /** * Settings page and notices. */ class MailProbe_Admin { /** * Slug of the settings page. */ const PAGE = 'mailprobe'; /** * Where an account and its API key are created. */ const SIGNUP_URL = 'https://mailprobe.dev/login/'; /** * Where credits are bought. */ const PRICING_URL = 'https://mailprobe.dev/pricing/'; /** * The plugin's support forum on WordPress.org. */ const SUPPORT_URL = 'https://wordpress.org/support/plugin/mailprobe/'; /** * Where a review of the plugin is left on WordPress.org. */ const REVIEW_URL = 'https://wordpress.org/support/plugin/mailprobe/reviews/#new-post'; /** * Hooks. */ public static function hooks() { add_action( 'admin_menu', array( __CLASS__, 'menu' ) ); add_action( 'admin_init', array( __CLASS__, 'register' ) ); add_action( 'admin_notices', array( __CLASS__, 'notices' ) ); add_action( 'admin_post_mailprobe_dismiss', array( __CLASS__, 'dismiss' ) ); add_filter( 'plugin_action_links_' . plugin_basename( MAILPROBE_FILE ), array( __CLASS__, 'action_links' ) ); } /** * Settings > MailProbe. */ public static function menu() { add_options_page( 'MailProbe', 'MailProbe', 'manage_options', self::PAGE, array( __CLASS__, 'render' ) ); } /** * The setting, its sanitizer, and the text suggested for the privacy policy. */ public static function register() { register_setting( self::PAGE, MailProbe::OPTION, array( 'type' => 'array', 'sanitize_callback' => array( __CLASS__, 'sanitize' ), 'default' => MailProbe::defaults(), ) ); if ( function_exists( 'wp_add_privacy_policy_content' ) ) { wp_add_privacy_policy_content( 'MailProbe', wp_kses_post( wpautop( sprintf( /* translators: %s: URL of the MailProbe privacy policy. */ __( 'When a visitor creates an account or places an order, this site sends the email address entered to MailProbe (mailprobe.dev), a service of Iris Digital hosted in France, to check that the address can receive emails. MailProbe checks the address in real time and does not store it once the check is done. MailProbe privacy policy: %s', 'mailprobe' ), 'https://mailprobe.dev/privacy/' ) ) ) ); } } /** * "Settings" next to "Deactivate" on the plugins screen. * * @param array $links The links. * @return array */ public static function action_links( $links ) { array_unshift( $links, sprintf( '%s', esc_url( self::page_url() ), esc_html__( 'Settings', 'mailprobe' ) ) ); return $links; } /** * URL of the settings page. * * @return string */ private static function page_url() { return admin_url( 'options-general.php?page=' . self::PAGE ); } /** * Cleans what the form sends. An empty key field keeps the saved key; a new key * is tried against the API before it replaces the old one. * * @param mixed $input The submitted values. * @return array */ public static function sanitize( $input ) { // WordPress runs the sanitizer twice on the first save of an option (once // through update_option, once more through add_option): the key would be // tried twice and the message shown twice. static $done = array(); $signature = md5( wp_json_encode( $input ) ); if ( isset( $done[ $signature ] ) ) { return $done[ $signature ]; } $done[ $signature ] = self::sanitize_once( $input ); return $done[ $signature ]; } /** * The sanitizer itself. * * @param mixed $input The submitted values. * @return array */ private static function sanitize_once( $input ) { $input = is_array( $input ) ? $input : array(); $previous = MailProbe::settings(); $clean = array( 'api_key' => $previous['api_key'], 'block_invalid' => ! empty( $input['block_invalid'] ), 'block_disposable' => ! empty( $input['block_disposable'] ), 'block_role' => ! empty( $input['block_role'] ), 'check_orders' => ! empty( $input['check_orders'] ), ); if ( ! empty( $input['remove_key'] ) ) { $clean['api_key'] = ''; MailProbe::clear_alert(); return $clean; } $key = isset( $input['api_key'] ) ? trim( sanitize_text_field( $input['api_key'] ) ) : ''; if ( '' === $key || $key === $previous['api_key'] ) { return $clean; } if ( 0 !== strpos( $key, 'mp_live_' ) ) { add_settings_error( MailProbe::OPTION, 'mailprobe_key_format', __( 'A MailProbe API key starts with mp_live_. The previous key was kept.', 'mailprobe' ) ); return $clean; } $credits = ( new MailProbe_Client( $key ) )->credits(); if ( is_wp_error( $credits ) && 'mailprobe_unauthorized' === $credits->get_error_code() ) { add_settings_error( MailProbe::OPTION, 'mailprobe_key_refused', __( 'MailProbe refused this API key. The previous key was kept.', 'mailprobe' ) ); return $clean; } $clean['api_key'] = $key; MailProbe::clear_alert(); if ( is_wp_error( $credits ) ) { /* translators: %s: the error. */ add_settings_error( MailProbe::OPTION, 'mailprobe_key_unchecked', sprintf( __( 'The key is saved, but it could not be tried: %s', 'mailprobe' ), $credits->get_error_message() ), 'warning' ); } else { /* translators: %s: number of credits. */ add_settings_error( MailProbe::OPTION, 'mailprobe_key_ok', sprintf( _n( 'Connected to MailProbe: %s credit left.', 'Connected to MailProbe: %s credits left.', $credits, 'mailprobe' ), number_format_i18n( $credits ) ), 'success' ); } return $clean; } /** * The settings page. */ public static function render() { if ( ! current_user_can( 'manage_options' ) ) { return; } $settings = MailProbe::settings(); $stats = MailProbe::stats(); $name = MailProbe::OPTION; $from_wp_config = MailProbe::key_from_constant(); ?>
%3$s · %5$s', esc_html__( 'MailProbe on WordPress.org:', 'mailprobe' ), esc_url( self::SUPPORT_URL ), esc_html__( 'support forum', 'mailprobe' ), esc_url( self::REVIEW_URL ), esc_html__( 'leave a review', 'mailprobe' ) ); ?>
' . esc_html( $credits->get_error_message() ) . '
'; return; } echo '' . wp_kses( sprintf( /* translators: 1: number of credits, 2: pricing URL. */ _n( 'Connected: %1$s credit left. Buy credits', 'Connected: %1$s credits left. Buy credits', $credits, 'mailprobe' ), number_format_i18n( $credits ), esc_url( self::PRICING_URL ) ), array( 'a' => array( 'href' => true, 'target' => true, 'rel' => true, ), ) ) . '
'; } /** * Two notices, for administrators only: a key is missing (plugins screen only), * or the checks stopped (no credits, key refused) until someone acts. */ public static function notices() { if ( ! current_user_can( 'manage_options' ) ) { return; } $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null; $id = $screen ? $screen->id : ''; if ( ! MailProbe::connected() ) { if ( 'plugins' === $id ) { printf( '%s %s
'; if ( 'mailprobe_no_credits' === $alert['code'] ) { echo esc_html__( 'MailProbe has no credits left: registrations and orders are no longer checked.', 'mailprobe' ) . ' ' . esc_html__( 'Buy credits', 'mailprobe' ) . ''; } else { echo esc_html__( 'MailProbe refused the API key: registrations and orders are no longer checked.', 'mailprobe' ) . ' ' . esc_html__( 'Check the key', 'mailprobe' ) . ''; } echo ' · ' . esc_html__( 'Dismiss', 'mailprobe' ) . '