'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(
'',
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 '' . esc_html( $label ) . ' ';
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' ) . ' ' . esc_html__( 'Remove', '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();
?>
';
}
/**
* SMTP field rows (shared with wizard).
*
* @param array $s Settings.
*/
public static function smtp_rows( array $s ) {
?>
$p ) : ?>
>
'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 '';
}
}
/**
* 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__( 'Date', '007aj-smtp-mailer' ) . ' ' . esc_html__( 'To', '007aj-smtp-mailer' ) . ' ' . esc_html__( 'Subject', '007aj-smtp-mailer' ) . ' ' . esc_html__( 'Status', '007aj-smtp-mailer' ) . ' ';
$rows = array( array( 'customer@example.com', __( 'Your order is confirmed', '007aj-smtp-mailer' ), __( 'Sent', '007aj-smtp-mailer' ) ), array( 'member@example.com', __( 'Password reset', '007aj-smtp-mailer' ), __( 'Sent', '007aj-smtp-mailer' ) ), array( 'info@example.com', __( 'New contact form message', '007aj-smtp-mailer' ), __( 'Failed', '007aj-smtp-mailer' ) ), array( 'buyer@example.com', __( 'Welcome!', '007aj-smtp-mailer' ), __( 'Sent', '007aj-smtp-mailer' ) ) );
foreach ( $rows as $r ) {
echo '2026-01-01 ' . esc_html( $r[0] ) . ' ' . esc_html( $r[1] ) . ' ' . esc_html( $r[2] ) . ' ';
}
echo '
';
}
/**
* 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 '' . 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' ) . ' ';
foreach ( $errors as $e ) {
$d = Diagnosis::explain( $e['message'] );
echo '' . 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 '
';
echo '';
}
echo '' . esc_html__( 'System', '007aj-smtp-mailer' ) . ' ';
$eng = Crypto::engine();
echo '' . esc_html__( 'Credential encryption', '007aj-smtp-mailer' ) . ' ' . esc_html( $eng ? $eng : __( 'Not available', '007aj-smtp-mailer' ) ) . ' ';
echo '' . esc_html__( 'Encryption key source', '007aj-smtp-mailer' ) . ' ' . esc_html( defined( 'AJSM_ENCRYPTION_KEY' ) ? 'AJSM_ENCRYPTION_KEY' : __( 'WordPress salts + site key', '007aj-smtp-mailer' ) ) . ' ';
echo '' . esc_html__( 'OpenSSL (for SSL/TLS connections)', '007aj-smtp-mailer' ) . ' ' . esc_html( extension_loaded( 'openssl' ) ? __( 'Yes', '007aj-smtp-mailer' ) : __( 'No', '007aj-smtp-mailer' ) ) . ' ';
echo '' . esc_html__( 'PHP mail() available', '007aj-smtp-mailer' ) . ' ' . esc_html( function_exists( 'mail' ) ? __( 'Yes', '007aj-smtp-mailer' ) : __( 'No', '007aj-smtp-mailer' ) ) . ' ';
echo '
';
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 '' . esc_html__( 'Feature', '007aj-smtp-mailer' ) . ' ' . esc_html__( 'Lite (free)', '007aj-smtp-mailer' ) . ' ' . esc_html__( 'Pro (paid)', '007aj-smtp-mailer' ) . ' ';
foreach ( $rows as $r ) {
echo '' . esc_html( $r[0] ) . ' ' . ( $r[1] ? ' ' : ' ' ) . ' ';
}
echo '
' . 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 ) . '
';
}
}