'Gmail / Google Workspace', 'microsoft' => 'Microsoft 365 / Outlook', 'sendgrid' => 'SendGrid', 'mailgun' => 'Mailgun', 'brevo' => 'Brevo', 'postmark' => 'Postmark', 'ses' => 'Amazon SES', 'smtp2go' => 'SMTP2GO', 'resend' => 'Resend', ); } /** * Register menus. */ public static function menu() { add_menu_page( __( '007AJ SMTP Mailer', '007aj-smtp-mailer' ), __( 'SMTP Mailer', '007aj-smtp-mailer' ), self::CAP, 'ajsm', array( __CLASS__, 'page_settings' ), 'dashicons-email-alt', 81 ); add_submenu_page( 'ajsm', __( 'Settings', '007aj-smtp-mailer' ), __( 'Settings', '007aj-smtp-mailer' ), self::CAP, 'ajsm', array( __CLASS__, 'page_settings' ) ); add_submenu_page( 'ajsm', __( 'Test Email', '007aj-smtp-mailer' ), __( 'Test Email', '007aj-smtp-mailer' ), self::CAP, 'ajsm-test', array( __CLASS__, 'page_test' ) ); if ( ! Plugin::is_pro() ) { add_submenu_page( 'ajsm', __( 'Email Log', '007aj-smtp-mailer' ), __( 'Email Log', '007aj-smtp-mailer' ), self::CAP, 'ajsm-log', array( __CLASS__, 'page_preview' ) ); add_submenu_page( 'ajsm', __( 'Reports', '007aj-smtp-mailer' ), __( 'Reports', '007aj-smtp-mailer' ), self::CAP, 'ajsm-reports', array( __CLASS__, 'page_preview' ) ); add_submenu_page( 'ajsm', __( 'Alerts', '007aj-smtp-mailer' ), __( 'Alerts', '007aj-smtp-mailer' ), self::CAP, 'ajsm-alerts', array( __CLASS__, 'page_preview' ) ); } do_action( 'ajsm_admin_menu' ); add_submenu_page( 'ajsm', __( 'Tools', '007aj-smtp-mailer' ), __( 'Tools', '007aj-smtp-mailer' ), self::CAP, 'ajsm-tools', array( __CLASS__, 'page_tools' ) ); add_submenu_page( 'ajsm', __( 'Documentation', '007aj-smtp-mailer' ), __( 'Documentation', '007aj-smtp-mailer' ), self::CAP, 'ajsm-docs', array( __CLASS__, 'page_docs' ) ); if ( ! Plugin::is_pro() ) { add_submenu_page( 'ajsm', __( 'Lite vs Paid', '007aj-smtp-mailer' ), __( 'Lite vs Paid', '007aj-smtp-mailer' ), self::CAP, 'ajsm-about', array( __CLASS__, 'page_about' ) ); } add_submenu_page( 'options.php', __( '007AJ SMTP Mailer Setup', '007aj-smtp-mailer' ), __( '007AJ SMTP Mailer Setup', '007aj-smtp-mailer' ), self::CAP, 'ajsm-setup', array( __CLASS__, 'page_wizard' ) ); } /** * Last submenu item: external upgrade link. */ public static function upgrade_link() { global $submenu; if ( Plugin::is_pro() || ! current_user_can( self::CAP ) ) { return; } add_submenu_page( 'ajsm', __( 'Upgrade', '007aj-smtp-mailer' ), '' . esc_html__( 'Upgrade', '007aj-smtp-mailer' ) . '', self::CAP, 'ajsm-upgrade', '__return_null' ); if ( isset( $submenu['ajsm'] ) ) { foreach ( $submenu['ajsm'] as $i => $item ) { if ( 'ajsm-upgrade' === $item[2] ) { $submenu['ajsm'][ $i ][2] = Plugin::upgrade_url( 'menu' ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- point the menu item at the external sales page. } } } } /** * Plugins-row links. * * @param array $links Links. * @return array */ public static function action_links( $links ) { $add = array( '' . esc_html__( 'Settings', '007aj-smtp-mailer' ) . '' ); if ( ! Plugin::is_pro() ) { $add[] = '' . esc_html__( 'Upgrade', '007aj-smtp-mailer' ) . ''; } return array_merge( $add, $links ); } /** * One-time redirect to the wizard. */ public static function maybe_redirect() { if ( ! get_transient( 'ajsm_activation_redirect' ) ) { return; } delete_transient( 'ajsm_activation_redirect' ); if ( wp_doing_ajax() || is_network_admin() || ! current_user_can( self::CAP ) || isset( $_GET['activate-multi'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only core flag. return; } wp_safe_redirect( admin_url( 'admin.php?page=ajsm-setup' ) ); exit; } /** * Current 007AJ SMTP Mailer page slug or ''. * * @return string */ private static function page() { $p = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- routing only. return 0 === strpos( $p, 'ajsm' ) ? $p : ''; } /** * Enqueue on own screens only. * * @param string $hook Hook suffix. */ public static function assets( $hook ) { if ( '' === self::page() ) { if ( 'plugins.php' !== $hook ) { return; } } wp_enqueue_style( 'ajsm-admin', AJSM_URL . 'assets/css/admin.css', array(), AJSM_VERSION ); if ( '' === self::page() ) { return; } wp_enqueue_script( 'ajsm-admin', AJSM_URL . 'assets/js/admin.js', array(), AJSM_VERSION, true ); $presets = array(); foreach ( Mailer::presets() as $k => $p ) { $presets[ $k ] = $p; } wp_localize_script( 'ajsm-admin', 'ajsmAdmin', array( 'ajax' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'ajsm_ajax' ), 'presets' => $presets, 'i18n' => array( 'sending' => __( 'Sending...', '007aj-smtp-mailer' ), 'sent' => __( 'Test email sent. Check the inbox (and spam folder).', '007aj-smtp-mailer' ), 'error' => __( 'Request failed. Reload the page and try again.', '007aj-smtp-mailer' ), 'saving' => __( 'Saving...', '007aj-smtp-mailer' ), ), ) ); if ( 'ajsm-docs' === self::page() ) { wp_enqueue_style( 'ajsm-docs', AJSM_URL . 'assets/css/docs.css', array(), AJSM_VERSION ); } } /** * Notices: own screens and Plugins screen, dismissible, one at a time. */ public static function notices() { if ( ! current_user_can( self::CAP ) ) { return; } $screen = get_current_screen(); $ok = '' !== self::page() || ( $screen && 'plugins' === $screen->id ); if ( ! $ok || 'ajsm-setup' === self::page() ) { return; } $msg = isset( $_GET['ajsm_msg'] ) ? sanitize_key( wp_unslash( $_GET['ajsm_msg'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- display only. if ( 'saved' === $msg ) { echo '

' . esc_html__( 'Settings saved.', '007aj-smtp-mailer' ) . '

'; return; } if ( 'failed' === $msg ) { echo '

' . esc_html__( 'Some settings could not be saved. Check that the PHP sodium or OpenSSL extension is available.', '007aj-smtp-mailer' ) . '

'; return; } if ( '' === Crypto::engine() ) { echo '

' . esc_html__( '007AJ SMTP Mailer needs the PHP sodium or OpenSSL extension to store passwords securely. Ask your host to enable one, or define the password in wp-config.php.', '007aj-smtp-mailer' ) . '

'; return; } $uid = get_current_user_id(); if ( ! get_option( 'ajsm_setup_done' ) && ! get_user_meta( $uid, 'ajsm_dismiss_setup', true ) ) { printf( '

%1$s %2$s

%4$s %6$s

', esc_html__( 'Finish setting up 007AJ SMTP Mailer.', '007aj-smtp-mailer' ), esc_html__( 'Connect a mailer so your site emails actually arrive.', '007aj-smtp-mailer' ), esc_url( admin_url( 'admin.php?page=ajsm-setup' ) ), esc_html__( 'Run the setup wizard', '007aj-smtp-mailer' ), esc_url( self::dismiss_url( 'setup' ) ), esc_html__( 'Dismiss', '007aj-smtp-mailer' ) ); } } /** * Dismiss URL. * * @param string $what Notice id. * @return string */ private static function dismiss_url( $what ) { return wp_nonce_url( admin_url( 'admin-post.php?action=ajsm_dismiss&what=' . $what ), 'ajsm_dismiss' ); } /** * Handle dismissal. */ public static function dismiss() { if ( ! current_user_can( self::CAP ) ) { wp_die( esc_html__( 'Sorry, you are not allowed to do that.', '007aj-smtp-mailer' ), 403 ); } check_admin_referer( 'ajsm_dismiss' ); $what = isset( $_GET['what'] ) ? sanitize_key( wp_unslash( $_GET['what'] ) ) : ''; if ( in_array( $what, array( 'setup', 'education' ), true ) ) { update_user_meta( get_current_user_id(), 'ajsm_dismiss_' . $what, 1 ); } $back = wp_get_referer(); wp_safe_redirect( $back ? $back : admin_url( 'admin.php?page=ajsm' ) ); exit; } /** * Gold badge. * * @return string */ private static function badge() { return '' . esc_html__( 'PAID', '007aj-smtp-mailer' ) . ''; } /** * Upsell modal markup (one per page). */ private static function modal() { if ( Plugin::is_pro() ) { return; } ?>

' . esc_html( $title ) . '

'; } /** * Read-only note when a constant is set. * * @param string $key Setting key. * @return string Attribute string. */ private static function lock_attr( $key ) { return Options::constant_for( $key ) ? ' disabled' : ''; } /** * Constant note. * * @param string $key Key. */ private static function const_note( $key ) { $c = Options::constant_for( $key ); if ( $c ) { /* translators: %s: constant name */ echo '

' . esc_html( sprintf( __( 'Defined in wp-config.php (%s).', '007aj-smtp-mailer' ), $c ) ) . '

'; } } /** * Password field (never shows the saved value). * * @param string $key Secret key. * @param string $label Label. */ public static function secret_field( $key, $label ) { $key = sanitize_key( $key ); echo ''; if ( Options::constant_for( $key ) ) { self::const_note( $key ); } else { $has = Options::has_secret( $key ); echo ''; if ( $has ) { echo '

' . esc_html__( 'Saved and encrypted. Leave blank to keep it, or type a new value to replace it.', '007aj-smtp-mailer' ) . '

'; } } echo ''; } /** * Settings page. */ public static function page_settings() { $s = Options::all(); self::header( __( '007AJ SMTP Mailer Settings', '007aj-smtp-mailer' ) ); self::education(); ?>

$label ) : ?> $label ) : ?>

'; } /** * SMTP field rows (shared with wizard). * * @param array $s Settings. */ public static function smtp_rows( array $s ) { ?>

> 'SSL', 'tls' => 'TLS (STARTTLS)', 'none' => __( 'None', '007aj-smtp-mailer' ) ) as $k => $l ) : ?>

> > >

>

__( 'If your main mailer fails, the email is sent again through a second mailer automatically.', '007aj-smtp-mailer' ), __( 'Smart routing', '007aj-smtp-mailer' ) => __( 'Send emails through different mailers based on the recipient, sender or subject.', '007aj-smtp-mailer' ), __( 'WordPress notification emails', '007aj-smtp-mailer' ) => __( 'Turn individual WordPress core emails on or off, such as new user, password change and auto-update emails.', '007aj-smtp-mailer' ), ); foreach ( $panels as $title => $text ) { echo '

' . esc_html( $title ) . ' ' . wp_kses_post( self::badge() ) . '

' . esc_html( $text ) . '

'; echo '

'; echo '

' . esc_html__( 'Unlock with 007AJ SMTP Mailer Pro', '007aj-smtp-mailer' ) . '

'; } } /** * Dismissible education card (after day 3). */ private static function education() { if ( Plugin::is_pro() || get_user_meta( get_current_user_id(), 'ajsm_dismiss_education', true ) ) { return; } $installed = (int) get_option( 'ajsm_installed', time() ); if ( time() - $installed < 3 * DAY_IN_SECONDS ) { return; } echo '
×

' . esc_html__( 'Get more from 007AJ SMTP Mailer', '007aj-smtp-mailer' ) . '

' . esc_html__( '007AJ SMTP Mailer Pro adds API mailers, a searchable email log with resend, a backup connection, smart routing, failure alerts and weekly summaries.', '007aj-smtp-mailer' ) . '

' . esc_html__( 'Learn more', '007aj-smtp-mailer' ) . '

'; } /** * Save settings. */ public static function save() { if ( ! current_user_can( self::CAP ) ) { wp_die( esc_html__( 'Sorry, you are not allowed to do that.', '007aj-smtp-mailer' ), 403 ); } check_admin_referer( 'ajsm_save' ); $raw = isset( $_POST['ajsm'] ) && is_array( $_POST['ajsm'] ) ? wp_unslash( $_POST['ajsm'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- each field sanitized in sanitize(). $ok = Options::update( self::sanitize( $raw ) ); $sec = isset( $_POST['ajsm_secret'] ) && is_array( $_POST['ajsm_secret'] ) ? wp_unslash( $_POST['ajsm_secret'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- secrets are stored verbatim after trim, then encrypted. $clr = isset( $_POST['ajsm_clear'] ) && is_array( $_POST['ajsm_clear'] ) ? array_map( 'absint', wp_unslash( $_POST['ajsm_clear'] ) ) : array(); $ok = self::save_secrets( $sec, $clr ) && $ok; wp_safe_redirect( admin_url( 'admin.php?page=ajsm&ajsm_msg=' . ( $ok ? 'saved' : 'failed' ) ) ); exit; } /** * Store secrets. * * @param array $sec New values. * @param array $clr Keys to clear. * @return bool */ public static function save_secrets( array $sec, array $clr ) { $ok = true; foreach ( Options::secret_keys() as $k ) { if ( Options::constant_for( $k ) ) { continue; } if ( ! empty( $clr[ $k ] ) ) { $ok = Options::set_secret( $k, '' ) && $ok; } elseif ( isset( $sec[ $k ] ) && is_string( $sec[ $k ] ) && '' !== trim( $sec[ $k ] ) ) { $ok = Options::set_secret( $k, trim( $sec[ $k ] ) ) && $ok; } } return $ok; } /** * Sanitize free settings; add-ons add theirs via filter. * * @param array $raw Raw input. * @return array */ public static function sanitize( array $raw ) { $c = array(); $mailer = isset( $raw['mailer'] ) ? sanitize_key( $raw['mailer'] ) : 'php'; $c['mailer'] = array_key_exists( $mailer, Mailer::mailers() ) ? $mailer : 'php'; $c['from_email'] = isset( $raw['from_email'] ) ? sanitize_email( $raw['from_email'] ) : ''; $c['from_name'] = isset( $raw['from_name'] ) ? sanitize_text_field( $raw['from_name'] ) : ''; $c['reply_to'] = isset( $raw['reply_to'] ) ? sanitize_email( $raw['reply_to'] ) : ''; $c['smtp_host'] = isset( $raw['smtp_host'] ) ? preg_replace( '/[^a-z0-9.\-\[\]:]/i', '', (string) $raw['smtp_host'] ) : ''; $port = isset( $raw['smtp_port'] ) ? absint( $raw['smtp_port'] ) : 465; $c['smtp_port'] = ( $port > 0 && $port < 65536 ) ? $port : 465; $enc = isset( $raw['smtp_encryption'] ) ? sanitize_key( $raw['smtp_encryption'] ) : 'ssl'; $c['smtp_encryption'] = in_array( $enc, array( 'ssl', 'tls', 'none' ), true ) ? $enc : 'ssl'; $c['smtp_user'] = isset( $raw['smtp_user'] ) ? sanitize_text_field( $raw['smtp_user'] ) : ''; foreach ( array( 'force_from_email', 'force_from_name', 'return_path', 'smtp_autotls', 'smtp_auth', 'uninstall_delete' ) as $b ) { $c[ $b ] = empty( $raw[ $b ] ) ? 0 : 1; } // Keep values that are locked by constants (their inputs are disabled and not posted). $saved = Options::saved(); foreach ( array_keys( $c ) as $k ) { if ( Options::constant_for( $k ) ) { $c[ $k ] = $saved[ $k ]; } } return (array) apply_filters( 'ajsm_sanitize_settings', $c, $raw ); } /** * Test page. */ public static function page_test() { self::header( __( 'Send a Test Email', '007aj-smtp-mailer' ) ); $labels = Mailer::mailers(); $active = Mailer::active(); ?>

'; } /** * AJAX: send test. */ public static function ajax_test() { check_ajax_referer( 'ajsm_ajax', 'nonce' ); if ( ! current_user_can( self::CAP ) ) { wp_send_json_error( array( 'message' => __( 'Not allowed.', '007aj-smtp-mailer' ) ), 403 ); } $to = isset( $_POST['to'] ) ? sanitize_email( wp_unslash( $_POST['to'] ) ) : ''; if ( ! is_email( $to ) ) { wp_send_json_error( array( 'message' => __( 'Enter a valid email address.', '007aj-smtp-mailer' ) ) ); } $html = ! isset( $_POST['html'] ) || '0' !== $_POST['html']; $r = Mailer::send_test( $to, $html ); if ( $r['ok'] ) { update_option( 'ajsm_last_test_ok', time(), false ); } wp_send_json_success( $r ); } /** * AJAX: wizard save. */ public static function ajax_wizard_save() { check_ajax_referer( 'ajsm_ajax', 'nonce' ); if ( ! current_user_can( self::CAP ) ) { wp_send_json_error( array( 'message' => __( 'Not allowed.', '007aj-smtp-mailer' ) ), 403 ); } $raw = isset( $_POST['ajsm'] ) && is_array( $_POST['ajsm'] ) ? wp_unslash( $_POST['ajsm'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- sanitized in sanitize(). $raw = array_merge( Options::saved(), array( 'force_from_email' => 1, 'smtp_auth' => 1, 'smtp_autotls' => 1, 'return_path' => 1, ), $raw ); $ok = Options::update( self::sanitize( $raw ) ); $sec = isset( $_POST['ajsm_secret'] ) && is_array( $_POST['ajsm_secret'] ) ? wp_unslash( $_POST['ajsm_secret'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- secret stored verbatim, encrypted. $ok = self::save_secrets( array_intersect_key( $sec, array( 'smtp_pass' => 1 ) ), array() ) && $ok; $int = isset( $_POST['interest'] ) && is_array( $_POST['interest'] ) ? array_map( 'sanitize_key', wp_unslash( $_POST['interest'] ) ) : array(); update_option( 'ajsm_wizard_interest', array_values( $int ), false ); if ( ! empty( $_POST['finish'] ) ) { update_option( 'ajsm_setup_done', time(), false ); } if ( ! $ok ) { wp_send_json_error( array( 'message' => __( 'Could not save. The PHP sodium or OpenSSL extension is required to store the password.', '007aj-smtp-mailer' ) ) ); } wp_send_json_success(); } /** * Wizard (plain JS steps). */ public static function page_wizard() { $s = Options::all(); $feat = array( 'log' => __( 'Detailed email log', '007aj-smtp-mailer' ), 'reports' => __( 'Sent/failed reports', '007aj-smtp-mailer' ), 'summary' => __( 'Weekly email summary', '007aj-smtp-mailer' ), 'alerts' => __( 'Instant failure alerts', '007aj-smtp-mailer' ), 'backup' => __( 'Backup connection', '007aj-smtp-mailer' ), 'routing' => __( 'Smart routing', '007aj-smtp-mailer' ), ); $exit = '' . esc_html__( 'Exit setup', '007aj-smtp-mailer' ) . ''; ?>

array( __( 'Email Log', '007aj-smtp-mailer' ), array( __( 'See every email your site sends, with status and the mailer used.', '007aj-smtp-mailer' ), __( 'Search, filter, view and resend any email.', '007aj-smtp-mailer' ), __( 'Export to CSV and set how long logs are kept.', '007aj-smtp-mailer' ) ) ), 'ajsm-reports' => array( __( 'Reports', '007aj-smtp-mailer' ), array( __( 'Sent and failed counts for each day.', '007aj-smtp-mailer' ), __( 'Spot delivery problems at a glance.', '007aj-smtp-mailer' ), __( 'Weekly summary email every Monday.', '007aj-smtp-mailer' ) ) ), 'ajsm-alerts' => array( __( 'Alerts', '007aj-smtp-mailer' ), array( __( 'Get notified the moment an email fails.', '007aj-smtp-mailer' ), __( 'Email, Slack, Discord, Microsoft Teams or any webhook.', '007aj-smtp-mailer' ), __( 'Throttled so you are never flooded.', '007aj-smtp-mailer' ) ) ), ); $d = isset( $data[ $p ] ) ? $data[ $p ] : $data['ajsm-log']; self::header( $d[0] ); echo '

' . esc_html( $d[0] ) . ' ' . wp_kses_post( self::badge() ) . '

' . esc_html__( 'Unlock with 007AJ SMTP Mailer Pro', '007aj-smtp-mailer' ) . '

'; } /** * Tools: recent errors. */ public static function page_tools() { self::header( __( 'Tools', '007aj-smtp-mailer' ) ); $errors = Options::errors(); echo '

' . esc_html__( 'Last 20 errors', '007aj-smtp-mailer' ) . '

'; if ( ! $errors ) { echo '

' . esc_html__( 'No errors recorded. Nice!', '007aj-smtp-mailer' ) . '

'; } else { echo ''; foreach ( $errors as $e ) { $d = Diagnosis::explain( $e['message'] ); echo ''; } echo '
' . esc_html__( 'Date', '007aj-smtp-mailer' ) . '' . esc_html__( 'Mailer', '007aj-smtp-mailer' ) . '' . esc_html__( 'To', '007aj-smtp-mailer' ) . '' . esc_html__( 'Subject', '007aj-smtp-mailer' ) . '' . esc_html__( 'Error', '007aj-smtp-mailer' ) . '' . esc_html__( 'What it means', '007aj-smtp-mailer' ) . '
' . esc_html( wp_date( 'Y-m-d H:i', (int) $e['time'] ) ) . '' . esc_html( $e['mailer'] ) . '' . esc_html( $e['to'] ) . '' . esc_html( $e['subject'] ) . '' . esc_html( $e['message'] ) . '' . esc_html( $d['title'] ) . '
'; echo '
'; wp_nonce_field( 'ajsm_clear_errors' ); submit_button( __( 'Clear errors', '007aj-smtp-mailer' ), 'secondary' ); echo '
'; } echo '

' . esc_html__( 'System', '007aj-smtp-mailer' ) . '

'; $eng = Crypto::engine(); echo ''; echo ''; echo ''; echo ''; echo '
' . esc_html__( 'Credential encryption', '007aj-smtp-mailer' ) . '' . esc_html( $eng ? $eng : __( 'Not available', '007aj-smtp-mailer' ) ) . '
' . esc_html__( 'Encryption key source', '007aj-smtp-mailer' ) . '' . esc_html( defined( 'AJSM_ENCRYPTION_KEY' ) ? 'AJSM_ENCRYPTION_KEY' : __( 'WordPress salts + site key', '007aj-smtp-mailer' ) ) . '
' . esc_html__( 'OpenSSL (for SSL/TLS connections)', '007aj-smtp-mailer' ) . '' . esc_html( extension_loaded( 'openssl' ) ? __( 'Yes', '007aj-smtp-mailer' ) : __( 'No', '007aj-smtp-mailer' ) ) . '
' . esc_html__( 'PHP mail() available', '007aj-smtp-mailer' ) . '' . esc_html( function_exists( 'mail' ) ? __( 'Yes', '007aj-smtp-mailer' ) : __( 'No', '007aj-smtp-mailer' ) ) . '
'; echo '

' . esc_html__( 'Run the setup wizard again', '007aj-smtp-mailer' ) . '

'; } /** * Clear errors. */ public static function clear_errors() { if ( ! current_user_can( self::CAP ) ) { wp_die( esc_html__( 'Sorry, you are not allowed to do that.', '007aj-smtp-mailer' ), 403 ); } check_admin_referer( 'ajsm_clear_errors' ); delete_option( Options::ERRORS ); wp_safe_redirect( admin_url( 'admin.php?page=ajsm-tools' ) ); exit; } /** * Lite vs Paid. */ public static function page_about() { self::header( __( '007AJ SMTP Mailer: Lite vs Paid', '007aj-smtp-mailer' ) ); $rows = array( array( __( 'Other SMTP with provider presets (Fastmail, Gmail, Outlook.com, Yahoo, Zoho, iCloud, Office 365, cPanel)', '007aj-smtp-mailer' ), 1 ), array( __( 'PHP mail fallback', '007aj-smtp-mailer' ), 1 ), array( __( 'From email/name with force options, Return-Path, Reply-To', '007aj-smtp-mailer' ), 1 ), array( __( 'Test email with plain-English diagnosis and debug transcript', '007aj-smtp-mailer' ), 1 ), array( __( 'Last 20 errors', '007aj-smtp-mailer' ), 1 ), array( __( 'Encrypted credentials and wp-config.php constants', '007aj-smtp-mailer' ), 1 ), array( __( 'Setup wizard', '007aj-smtp-mailer' ), 1 ), array( __( 'API mailers: Gmail/Google Workspace, Microsoft 365/Outlook, SendGrid, Mailgun, Brevo, Postmark, Amazon SES, SMTP2GO, Resend', '007aj-smtp-mailer' ), 0 ), array( __( 'Email log with search, view, resend, CSV export and retention', '007aj-smtp-mailer' ), 0 ), array( __( 'Backup connection (automatic failover)', '007aj-smtp-mailer' ), 0 ), array( __( 'Smart routing rules', '007aj-smtp-mailer' ), 0 ), array( __( 'Failure alerts: email, Slack, Discord, Teams, webhook', '007aj-smtp-mailer' ), 0 ), array( __( 'Weekly summary email', '007aj-smtp-mailer' ), 0 ), array( __( 'Turn WordPress notification emails on or off', '007aj-smtp-mailer' ), 0 ), array( __( 'Sent/failed stats by day', '007aj-smtp-mailer' ), 0 ), ); echo ''; foreach ( $rows as $r ) { echo ''; } echo '
' . esc_html__( 'Feature', '007aj-smtp-mailer' ) . '' . esc_html__( 'Lite (free)', '007aj-smtp-mailer' ) . '' . esc_html__( 'Pro (paid)', '007aj-smtp-mailer' ) . '
' . esc_html( $r[0] ) . '' . ( $r[1] ? '' : '' ) . '

' . esc_html__( 'Get 007AJ SMTP Mailer Pro', '007aj-smtp-mailer' ) . '

'; echo '

' . esc_html__( 'Pro is a separate add-on plugin. Lite keeps working exactly as it does now; nothing in Lite expires or is time-limited.', '007aj-smtp-mailer' ) . '

'; } /** * Documentation inside the dashboard. */ public static function page_docs() { self::header( __( 'Documentation', '007aj-smtp-mailer' ) ); $file = AJSM_DIR . 'docs/documentation.html'; $html = is_readable( $file ) ? (string) file_get_contents( $file ) : ''; // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- local bundled file. if ( preg_match( '#]*>(.*)#is', $html, $m ) ) { $html = $m[1]; } echo '
' . wp_kses_post( $html ) . '
'; } }