Merged in feature/117-dev-dev01 (pull request #8)

auto-patch  117-dev-dev01-2023-12-15T16_09_06

* auto-patch  117-dev-dev01-2023-12-15T16_09_06
This commit is contained in:
Tony Volpe
2023-12-15 16:10:57 +00:00
parent 0825f6bd5f
commit 3dc9eca989
1424 changed files with 28118 additions and 10097 deletions

View File

@@ -47,7 +47,7 @@ class AdminBarMenu {
if (
is_user_logged_in() &&
current_user_can( 'manage_options' )
current_user_can( wp_mail_smtp()->get_capability_manage_options() )
) {
$access = true;
}

View File

@@ -138,7 +138,7 @@ class Area {
return;
}
if ( ! current_user_can( 'manage_options' ) ) {
if ( ! current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
return;
}
@@ -177,6 +177,13 @@ class Area {
WP::ADMIN_NOTICE_ERROR
);
break;
case 'google_unsuccessful_oauth':
WP::add_admin_notice(
esc_html__( 'There was an error while processing the authentication request.', 'wp-mail-smtp' ),
WP::ADMIN_NOTICE_ERROR
);
break;
}
switch ( $success ) {
@@ -244,6 +251,17 @@ class Area {
return;
}
/*
* Don't display the notice if the user installed a plugin with a new "Email Test"
* location (starting from v3.9.0) and is not aware of the old one. Also, don't display
* the notice if the `wp_mail_smtp_initial_version` option is not set (it can happen if
* the plugin was activated network wise in the multisite installation and plugin
* activation hook was not performed on the subsite level).
*/
if ( version_compare( get_option( 'wp_mail_smtp_initial_version', '3.9.0' ), '3.9.0', '>=' ) ) {
return;
}
WP::add_admin_notice(
sprintf(
wp_kses(
@@ -285,7 +303,7 @@ class Area {
public function add_admin_options_page() {
// Options pages access capability.
$access_capability = 'manage_options';
$access_capability = wp_mail_smtp()->get_capability_manage_options();
$this->hook = add_menu_page(
esc_html__( 'WP Mail SMTP', 'wp-mail-smtp' ),
@@ -348,7 +366,7 @@ class Area {
add_menu_page(
esc_html__( 'WP Mail SMTP', 'wp-mail-smtp' ),
esc_html__( 'WP Mail SMTP', 'wp-mail-smtp' ),
'manage_options',
wp_mail_smtp()->get_capability_manage_options(),
self::SLUG,
[ $this, 'display_network_product_education_page' ],
'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiM5ZWEzYTgiIHdpZHRoPSI2NCIgaGVpZ2h0PSI2NCIgdmlld0JveD0iMCAwIDQzIDM0Ij48cGF0aCBkPSJNMC4wMDcsMy41ODVWMjAuNDIxcTAsMy41ODYsMy43NTEsMy41ODVMMjAsMjRWMTlIMzBWMTQuMDE0bDAuOTkxLTFMMzQsMTNWMy41ODVRMzQsMCwzMC4yNDksMEgzLjc1OFEwLjAwNywwLC4wMDcsMy41ODVoMFpNMy41MjQsNi4xNTdhMS40OSwxLjQ5LDAsMCwxLS41MDgtMC45MzUsMS41ODEsMS41ODEsMCwwLDEsLjI3NC0xLjIwOCwxLjQ0OSwxLjQ0OSwwLDAsMSwxLjA5NC0uNjYzLDEuNzU2LDEuNzU2LDAsMCwxLDEuMjUuMzEybDExLjQwOSw3LjcxNkwyOC4zNzQsMy42NjNhMS45NiwxLjk2LDAsMCwxLDEuMjg5LS4zMTIsMS41NDYsMS41NDYsMCwwLDEsMS4wOTQuNjYzLDEuNCwxLjQsMCwwLDEsLjI3MywxLjIwOCwxLjY3LDEuNjcsMCwwLDEtLjU0Ny45MzVMMTcuMDQzLDE3LjIyNVoiLz48cGF0aCBkPSJNMjIsMjhIMzJsLTAuMDA5LDQuNjI0YTEuMTI2LDEuMTI2LDAsMCwwLDEuOTIyLjhsOC4yNS04LjIzNmExLjEyNiwxLjEyNiwwLDAsMCwwLTEuNTk0bC04LjI1LTguMjQxYTEuMTI2LDEuMTI2LDAsMCwwLTEuOTIyLjh2NC44NjZMMjIsMjF2N1oiLz48L3N2Zz4=',
@@ -537,6 +555,10 @@ class Area {
esc_url( wp_mail_smtp()->get_utm_url( 'https://wpmailsmtp.com/docs/how-to-upgrade-wp-mail-smtp-to-pro-version/', [ 'medium' => 'plugin-settings', 'content' => 'Pro Mailer Popup - Already purchased' ] ) ),
esc_html__( 'Already purchased?', 'wp-mail-smtp' )
),
'gmail' => [
'one_click_setup_upgrade_title' => wp_kses( __( 'One-Click Setup for Google Mailer <br> is a Pro Feature', 'wp-mail-smtp' ), [ 'br' => [] ] ),
'one_click_setup_upgrade_content' => esc_html__( 'We\'re sorry, One-Click Setup for Google Mailer is not available on your plan. Please upgrade to the Pro plan to unlock all these awesome features.', 'wp-mail-smtp' ),
],
],
'all_mailers_supports' => wp_mail_smtp()->get_providers()->get_supports_all(),
'nonce' => wp_create_nonce( 'wp-mail-smtp-admin' ),
@@ -818,7 +840,10 @@ class Area {
*
* @param string $capability Email logs access capability.
*/
return apply_filters( 'wp_mail_smtp_admin_area_get_logs_access_capability', 'manage_options' );
return apply_filters(
'wp_mail_smtp_admin_area_get_logs_access_capability',
wp_mail_smtp()->get_capability_manage_options()
);
}
/**
@@ -1126,7 +1151,7 @@ class Area {
$data = [];
// Only admins can fire these ajax requests.
if ( ! current_user_can( 'manage_options' ) ) {
if ( ! current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
wp_send_json_error( $data );
}

View File

@@ -6,7 +6,6 @@ use WPMailSMTP\ConnectionInterface;
use WPMailSMTP\Debug;
use WPMailSMTP\Helpers\UI;
use WPMailSMTP\Options;
use WPMailSMTP\Providers\Gmail\Auth;
/**
* Class ConnectionSettings.
@@ -71,39 +70,14 @@ class ConnectionSettings {
<label for="wp-mail-smtp-setting-from_email"><?php esc_html_e( 'From Email', 'wp-mail-smtp' ); ?></label>
</div>
<div class="wp-mail-smtp-setting-field">
<?php if ( $mailer !== 'gmail' ) : ?>
<input name="wp-mail-smtp[mail][from_email]" type="email"
value="<?php echo esc_attr( $connection_options->get( 'mail', 'from_email' ) ); ?>"
id="wp-mail-smtp-setting-from_email" spellcheck="false"
placeholder="<?php echo esc_attr( wp_mail_smtp()->get_processor()->get_default_email() ); ?>"
<?php disabled( $connection_options->is_const_defined( 'mail', 'from_email' ) || ! empty( $disabled_email ) ); ?>
/>
<?php else : ?>
<?php
// Gmail mailer From Email selector.
$gmail_auth = new Auth( $this->connection );
$gmail_aliases = $gmail_auth->is_clients_saved() ? $gmail_auth->get_user_possible_send_from_addresses() : [];
?>
<input name="wp-mail-smtp[mail][from_email]" type="email"
value="<?php echo esc_attr( $connection_options->get( 'mail', 'from_email' ) ); ?>"
id="wp-mail-smtp-setting-from_email" spellcheck="false"
placeholder="<?php echo esc_attr( wp_mail_smtp()->get_processor()->get_default_email() ); ?>"
<?php disabled( $connection_options->is_const_defined( 'mail', 'from_email' ) || ! empty( $disabled_email ) ); ?>
/>
<?php if ( empty( $gmail_aliases ) ) : ?>
<select name="wp-mail-smtp[mail][from_email]" id="wp-mail-smtp-setting-from_email" disabled>
<option value="">
<?php esc_html_e( 'Please first authorize the Gmail mailer below', 'wp-mail-smtp' ); ?>
</option>
</select>
<?php else : ?>
<select name="wp-mail-smtp[mail][from_email]" id="wp-mail-smtp-setting-from_email">
<?php foreach ( $gmail_aliases as $gmail_email_address ) : ?>
<option value="<?php echo esc_attr( $gmail_email_address ); ?>" <?php selected( $connection_options->get( 'mail', 'from_email' ), $gmail_email_address ); ?>>
<?php echo esc_html( $gmail_email_address ); ?>
</option>
<?php endforeach; ?>
</select>
<?php endif; ?>
<?php endif; ?>
<?php if ( ! in_array( $mailer, [ 'gmail', 'zoho' ], true ) ) : ?>
<?php if ( ! in_array( $mailer, [ 'zoho' ], true ) ) : ?>
<p class="desc">
<?php esc_html_e( 'The email address that emails are sent from.', 'wp-mail-smtp' ); ?>
</p>
@@ -335,8 +309,6 @@ class ConnectionSettings {
*/
public function process( $data, $old_data ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.MaxExceeded, Generic.Metrics.CyclomaticComplexity.TooHigh
$connection_options = $this->connection->get_options();
// When checkbox is unchecked - it's not submitted at all, so we need to define its default false value.
if ( ! isset( $data['mail']['from_email_force'] ) ) {
$data['mail']['from_email_force'] = false;
@@ -372,21 +344,6 @@ class ConnectionSettings {
}
}
// Old and new Gmail client id/secret values are different - we need to invalidate tokens and scroll to Auth button.
if (
$this->connection->get_mailer_slug() === 'gmail' &&
! empty( $data['gmail']['client_id'] ) &&
! empty( $data['gmail']['client_secret'] ) &&
(
$connection_options->get( 'gmail', 'client_id' ) !== $data['gmail']['client_id'] ||
$connection_options->get( 'gmail', 'client_secret' ) !== $data['gmail']['client_secret']
)
) {
unset( $old_data['gmail'] );
$this->scroll_to = '#wp-mail-smtp-setting-row-gmail-authorize';
}
// Prevent redirect to setup wizard from settings page after successful auth.
if (
! empty( $data['mail']['mailer'] ) &&
@@ -395,7 +352,15 @@ class ConnectionSettings {
$data[ $data['mail']['mailer'] ]['is_setup_wizard_auth'] = false;
}
return $data;
/**
* Filters connection data.
*
* @since 3.11.0
*
* @param array $data Connection data.
* @param array $old_data Old connection data.
*/
return apply_filters( 'wp_mail_smtp_admin_connection_settings_process_data', $data, $old_data );
}
/**
@@ -416,24 +381,19 @@ class ConnectionSettings {
) {
// Save correct from email address if Gmail mailer is already configured.
if (
is_array( $data ) && in_array( $data['mail']['mailer'], [ 'gmail' ], true ) &&
! empty( $data['gmail']['client_id'] ) &&
! empty( $data['gmail']['client_secret'] )
) {
$gmail_auth = new Auth( $this->connection );
$gmail_aliases = $gmail_auth->is_clients_saved() ? $gmail_auth->get_user_possible_send_from_addresses() : [];
if ( $data['mail']['mailer'] === 'gmail' ) {
$gmail_auth = wp_mail_smtp()->get_providers()->get_auth( 'gmail', $this->connection );
$user_info = ! $gmail_auth->is_auth_required() ? $gmail_auth->get_user_info() : false;
if (
! empty( $gmail_aliases ) &&
isset( $gmail_aliases[0] ) &&
is_email( $gmail_aliases[0] ) !== false &&
! empty( $user_info['email'] ) &&
is_email( $user_info['email'] ) !== false &&
(
empty( $data['mail']['from_email'] ) ||
! in_array( $data['mail']['from_email'], $gmail_aliases, true )
$data['mail']['from_email'] !== $user_info['email']
)
) {
$data['mail']['from_email'] = $gmail_aliases[0];
$data['mail']['from_email'] = $user_info['email'];
$this->connection->get_options()->set( $data, false, false );
}

View File

@@ -58,7 +58,7 @@ class DashboardWidget {
public function init() {
// This widget should be displayed for certain high-level users only.
if ( ! current_user_can( 'manage_options' ) ) {
if ( ! current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
return;
}
@@ -181,7 +181,7 @@ class DashboardWidget {
check_admin_referer( 'wp_mail_smtp_' . static::SLUG . '_nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
if ( ! current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
wp_send_json_error();
}
@@ -202,7 +202,7 @@ class DashboardWidget {
check_admin_referer( 'wp_mail_smtp_' . static::SLUG . '_nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
if ( ! current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
wp_send_json_error();
}

View File

@@ -100,7 +100,7 @@ class DebugEvents {
wp_send_json_error( esc_html__( 'Access rejected.', 'wp-mail-smtp' ) );
}
if ( ! current_user_can( 'manage_options' ) ) {
if ( ! current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
wp_send_json_error( esc_html__( 'You don\'t have the capability to perform this action.', 'wp-mail-smtp' ) );
}
@@ -139,7 +139,7 @@ class DebugEvents {
wp_send_json_error( esc_html__( 'Access rejected.', 'wp-mail-smtp' ) );
}
if ( ! current_user_can( 'manage_options' ) ) {
if ( ! current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
wp_send_json_error( esc_html__( 'You don\'t have the capability to perform this action.', 'wp-mail-smtp' ) );
}

View File

@@ -558,7 +558,7 @@ class Table extends \WP_List_Table {
</div>
<?php
if ( current_user_can( 'manage_options' ) ) {
if ( current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
wp_nonce_field( 'wp_mail_smtp_debug_events', 'wp-mail-smtp-debug-events-nonce', false );
printf(
'<button id="wp-mail-smtp-delete-all-debug-events-button" type="button" class="button">%s</button>',

View File

@@ -92,7 +92,7 @@ class Education {
check_ajax_referer( 'wp-mail-smtp-admin', 'nonce' );
// Check for permissions.
if ( ! current_user_can( 'manage_options' ) ) {
if ( ! current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
wp_send_json_error();
}

View File

@@ -76,7 +76,7 @@ class Notifications {
$access = false;
if (
current_user_can( 'manage_options' ) &&
current_user_can( wp_mail_smtp()->get_capability_manage_options() ) &&
! Options::init()->get( 'general', 'am_notifications_hidden' )
) {
$access = true;
@@ -512,7 +512,7 @@ class Notifications {
check_ajax_referer( 'wp-mail-smtp-admin', 'nonce' );
// Check for access and required param.
if ( ! current_user_can( 'manage_options' ) || empty( $_POST['id'] ) ) {
if ( ! current_user_can( wp_mail_smtp()->get_capability_manage_options() ) || empty( $_POST['id'] ) ) {
wp_send_json_error();
}

View File

@@ -2,9 +2,10 @@
namespace WPMailSMTP\Admin\Pages;
use Plugin_Upgrader;
use WPMailSMTP\Admin\PageAbstract;
use WPMailSMTP\Admin\PluginsInstallSkin;
use WPMailSMTP\Admin\PluginsInstallUpgrader;
use WPMailSMTP\Helpers\Helpers;
/**
* About tab.
@@ -603,7 +604,14 @@ class AboutTab extends PageAbstract {
)
);
/*
* The `request_filesystem_credentials` function will output a credentials form in case of failure.
* We don't want that, since it will break AJAX response. So just hide output with a buffer.
*/
ob_start();
// phpcs:ignore WPForms.Formatting.EmptyLineAfterAssigmentVariables.AddEmptyLine
$creds = request_filesystem_credentials( $url, '', false, false, null );
ob_end_clean();
// Check for file system permissions.
if ( false === $creds ) {
@@ -617,8 +625,11 @@ class AboutTab extends PageAbstract {
// Do not allow WordPress to search/download translations, as this will break JS output.
remove_action( 'upgrader_process_complete', [ 'Language_Pack_Upgrader', 'async_upgrade' ], 20 );
// Import the plugin upgrader.
Helpers::include_plugin_upgrader();
// Create the plugin upgrader with our custom skin.
$installer = new PluginsInstallUpgrader( new PluginsInstallSkin() );
$installer = new Plugin_Upgrader( new PluginsInstallSkin() );
// Error check.
if ( ! method_exists( $installer, 'install' ) ) {

View File

@@ -6,7 +6,6 @@ use WPMailSMTP\Admin\ConnectionSettings;
use WPMailSMTP\Admin\PageAbstract;
use WPMailSMTP\Admin\SetupWizard;
use WPMailSMTP\Options;
use WPMailSMTP\Providers\Gmail\Auth;
use WPMailSMTP\WP;
/**

View File

@@ -2,13 +2,16 @@
namespace WPMailSMTP\Admin;
use Automatic_Upgrader_Skin;
/**
* WordPress class extended for on-the-fly plugin installations.
*
* @since 1.5.0
* @since 1.7.1 Removed feedback() method override to be compatible with PHP5.3+ and WP5.3.
* @since 3.11.0 Updated to extend Automatic_Upgrader_Skin.
*/
class PluginsInstallSkin extends \WP_Upgrader_Skin {
class PluginsInstallSkin extends Automatic_Upgrader_Skin {
/**
* Empty out the header of its HTML content and only check to see if it has

View File

@@ -2,6 +2,7 @@
namespace WPMailSMTP\Admin;
use Plugin_Upgrader;
use WPMailSMTP\Admin\Pages\TestTab;
use WPMailSMTP\Connect;
use WPMailSMTP\Helpers\Helpers;
@@ -81,7 +82,7 @@ class SetupWizard {
isset( $_GET['page'] ) && // phpcs:ignore WordPress.Security.NonceVerification.Recommended
Area::SLUG . '-setup-wizard' === $_GET['page'] && // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$this->should_setup_wizard_load() &&
current_user_can( 'manage_options' )
current_user_can( wp_mail_smtp()->get_capability_manage_options() )
)
) {
return;
@@ -97,6 +98,10 @@ class SetupWizard {
// Remove an action in the Gutenberg plugin ( not core Gutenberg ) which throws an error.
remove_action( 'admin_print_styles', 'gutenberg_block_editor_admin_print_styles' );
// Remove hooks for deprecated functions in WordPress 6.4.0.
remove_action( 'admin_print_styles', 'print_emoji_styles' );
remove_action( 'admin_head', 'wp_admin_bar_header' );
$this->load_setup_wizard();
}
@@ -155,7 +160,7 @@ class SetupWizard {
return;
}
add_submenu_page( '', '', '', 'manage_options', Area::SLUG . '-setup-wizard', '' );
add_submenu_page( '', '', '', wp_mail_smtp()->get_capability_manage_options(), Area::SLUG . '-setup-wizard', '' );
}
/**
@@ -543,7 +548,7 @@ class SetupWizard {
check_ajax_referer( 'wpms-admin-nonce', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
if ( ! current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
wp_send_json_error( esc_html__( 'You don\'t have permission to change options for this WP site!', 'wp-mail-smtp' ) );
}
@@ -561,7 +566,7 @@ class SetupWizard {
check_ajax_referer( 'wpms-admin-nonce', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
if ( ! current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
wp_send_json_error( esc_html__( 'You don\'t have permission to change options for this WP site!', 'wp-mail-smtp' ) );
}
@@ -583,7 +588,7 @@ class SetupWizard {
check_ajax_referer( 'wpms-admin-nonce', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
if ( ! current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
wp_send_json_error();
}
@@ -625,7 +630,7 @@ class SetupWizard {
check_ajax_referer( 'wpms-admin-nonce', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
if ( ! current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
wp_send_json_error( esc_html__( 'You don\'t have permission to change options for this WP site!', 'wp-mail-smtp' ) );
}
@@ -690,6 +695,7 @@ class SetupWizard {
*
* @since 2.6.0
* @since 3.10.0 Supply WPMS_AMAZONSES_DISPLAY_IDENTITIES constant value to control display of Amazon SES identity list.
* @since 3.11.0 Removed WPMS_AMAZONSES_DISPLAY_IDENTITIES constant handling.
*
* @return array
*/
@@ -710,10 +716,6 @@ class SetupWizard {
if ( $provider->get_slug() === 'gmail' ) {
$data['gmail']['redirect_uri'] = \WPMailSMTP\Providers\Gmail\Auth::get_oauth_redirect_url();
}
if ( $provider->get_slug() === 'amazonses' ) {
$data['amazonses']['display_identities'] = ! defined( 'WPMS_AMAZONSES_DISPLAY_IDENTITIES' ) || WPMS_AMAZONSES_DISPLAY_IDENTITIES === true;
}
}
return apply_filters( 'wp_mail_smtp_admin_setup_wizard_prepare_mailer_options', $data );
@@ -728,7 +730,7 @@ class SetupWizard {
check_ajax_referer( 'wpms-admin-nonce', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
if ( ! current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
wp_send_json_error();
}
@@ -738,7 +740,7 @@ class SetupWizard {
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$settings = isset( $_POST['settings'] ) ? wp_slash( json_decode( wp_unslash( $_POST['settings'] ), true ) ) : [];
if ( empty( $mailer ) || empty( $settings ) ) {
if ( empty( $mailer ) ) {
wp_send_json_error();
}
@@ -749,7 +751,7 @@ class SetupWizard {
switch ( $mailer ) {
case 'gmail':
$auth = new \WPMailSMTP\Providers\Gmail\Auth();
$auth = wp_mail_smtp()->get_providers()->get_auth( 'gmail' );
if ( $auth->is_clients_saved() && $auth->is_auth_required() ) {
$data['oauth_url'] = $auth->get_auth_url();
@@ -771,7 +773,7 @@ class SetupWizard {
check_ajax_referer( 'wpms-admin-nonce', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
if ( ! current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
wp_send_json_error();
}
@@ -784,20 +786,11 @@ class SetupWizard {
switch ( $mailer ) {
case 'gmail':
$auth = new \WPMailSMTP\Providers\Gmail\Auth();
$auth = wp_mail_smtp()->get_providers()->get_auth( 'gmail' );
if ( $auth->is_clients_saved() && ! $auth->is_auth_required() ) {
$user_info = $auth->get_user_info();
$data['connected_email'] = $user_info['email'];
$data['possible_send_from_addresses'] = array_map(
function( $value ) {
return [
'value' => $value,
'label' => $value,
];
},
$auth->get_user_possible_send_from_addresses()
);
$user_info = $auth->get_user_info();
$data['connected_email'] = $user_info['email'];
}
break;
}
@@ -810,11 +803,11 @@ class SetupWizard {
*
* @since 2.6.0
*/
public function remove_oauth_connection() {
public function remove_oauth_connection() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
check_ajax_referer( 'wpms-admin-nonce', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
if ( ! current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
wp_send_json_error();
}
@@ -827,10 +820,21 @@ class SetupWizard {
$options = Options::init();
$old_opt = $options->get_all_raw();
foreach ( $old_opt[ $mailer ] as $key => $value ) {
// Unset everything except Client ID, Client Secret and Domain (for Zoho).
if ( ! in_array( $key, array( 'domain', 'client_id', 'client_secret' ), true ) ) {
unset( $old_opt[ $mailer ][ $key ] );
/*
* Since Gmail mailer uses the same settings array for both the custom app and One-Click Setup,
* we need to make sure we don't remove the wrong settings.
*/
if ( $mailer === 'gmail' ) {
unset( $old_opt[ $mailer ]['access_token'] );
unset( $old_opt[ $mailer ]['refresh_token'] );
unset( $old_opt[ $mailer ]['user_details'] );
unset( $old_opt[ $mailer ]['auth_code'] );
} else {
foreach ( $old_opt[ $mailer ] as $key => $value ) {
// Unset everything except Client ID, Client Secret and Domain (for Zoho).
if ( ! in_array( $key, [ 'domain', 'client_id', 'client_secret' ], true ) ) {
unset( $old_opt[ $mailer ][ $key ] );
}
}
}
@@ -868,8 +872,16 @@ class SetupWizard {
wp_send_json_error( esc_html__( 'Could not install the plugin. Plugin is not whitelisted.', 'wp-mail-smtp' ) );
}
$url = esc_url_raw( WP::admin_url( 'admin.php?page=' . Area::SLUG . '-setup-wizard' ) );
$url = esc_url_raw( WP::admin_url( 'admin.php?page=' . Area::SLUG . '-setup-wizard' ) );
/*
* The `request_filesystem_credentials` function will output a credentials form in case of failure.
* We don't want that, since it will break AJAX response. So just hide output with a buffer.
*/
ob_start();
// phpcs:ignore WPForms.Formatting.EmptyLineAfterAssigmentVariables.AddEmptyLine
$creds = request_filesystem_credentials( $url, '', false, false, null );
ob_end_clean();
// Check for file system permissions.
if ( false === $creds ) {
@@ -883,8 +895,11 @@ class SetupWizard {
// Do not allow WordPress to search/download translations, as this will break JS output.
remove_action( 'upgrader_process_complete', [ 'Language_Pack_Upgrader', 'async_upgrade' ], 20 );
// Import the plugin upgrader.
Helpers::include_plugin_upgrader();
// Create the plugin upgrader with our custom skin.
$installer = new PluginsInstallUpgrader( new PluginsInstallSkin() );
$installer = new Plugin_Upgrader( new PluginsInstallSkin() );
// Error check.
if ( ! method_exists( $installer, 'install' ) || empty( $slug ) ) {

View File

@@ -2,9 +2,10 @@
namespace WPMailSMTP;
use Plugin_Upgrader;
use WP_Error;
use WPMailSMTP\Admin\PluginsInstallSkin;
use WPMailSMTP\Admin\PluginsInstallUpgrader;
use WPMailSMTP\Helpers\Helpers;
/**
* WP Mail SMTP Connect.
@@ -217,7 +218,14 @@ class Connect {
wp_send_json_success( esc_html__( 'Plugin installed & activated.', 'wp-mail-smtp' ) );
}
/*
* The `request_filesystem_credentials` function will output a credentials form in case of failure.
* We don't want that, since it will break AJAX response. So just hide output with a buffer.
*/
ob_start();
// phpcs:ignore WPForms.Formatting.EmptyLineAfterAssigmentVariables.AddEmptyLine
$creds = request_filesystem_credentials( $url, '', false, false, null );
ob_end_clean();
// Check for file system permissions.
$perm_error = esc_html__( 'There was an error while installing an upgrade. Please check file system permissions and try again. Also, you can download the plugin from wpmailsmtp.com and install it manually.', 'wp-mail-smtp' );
@@ -233,8 +241,11 @@ class Connect {
// Do not allow WordPress to search/download translations, as this will break JS output.
remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
// Import the plugin upgrader.
Helpers::include_plugin_upgrader();
// Create the plugin upgrader with our custom skin.
$installer = new PluginsInstallUpgrader( new PluginsInstallSkin() );
$installer = new Plugin_Upgrader( new PluginsInstallSkin() );
// Error check.
if ( ! method_exists( $installer, 'install' ) ) {

View File

@@ -175,7 +175,7 @@ class Core {
}
// Plugin admin area notices. Display to "admins" only.
if ( current_user_can( 'manage_options' ) ) {
if ( current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
add_action( 'admin_notices', array( '\WPMailSMTP\WP', 'display_admin_notices' ) );
add_action( 'admin_notices', array( $this, 'display_general_notices' ) );
@@ -609,7 +609,7 @@ class Core {
public function detect_conflicts() {
// Display only for those who can actually deactivate plugins.
if ( ! current_user_can( 'manage_options' ) ) {
if ( ! current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
return;
}
@@ -1346,4 +1346,23 @@ class Core {
return;
}
}
/**
* Get the default capability to manage everything for WP Mail SMTP.
*
* @since 3.11.0
*
* @return string
*/
public function get_capability_manage_options() {
/**
* Filters the default capability to manage everything for WP Mail SMTP.
*
* @since 3.11.0
*
* @param string $capability The default capability to manage everything for WP Mail SMTP.
*/
return apply_filters( 'wp_mail_smtp_core_get_capability_manage_options', 'manage_options' );
}
}

View File

@@ -37,7 +37,7 @@ class DBRepair {
isset( $_GET['create-missing-db-tables'] ) &&
$_GET['create-missing-db-tables'] === '1' &&
wp_mail_smtp()->get_admin()->is_admin_page() &&
current_user_can( 'manage_options' )
current_user_can( wp_mail_smtp()->get_capability_manage_options() )
) {
check_admin_referer( Area::SLUG . '-create-missing-db-tables' );
@@ -165,7 +165,7 @@ class DBRepair {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
isset( $_GET['check-db-tables'] ) && $_GET['check-db-tables'] === '1' &&
wp_mail_smtp()->get_admin()->is_admin_page() &&
current_user_can( 'manage_options' )
current_user_can( wp_mail_smtp()->get_capability_manage_options() )
) {
$missing_tables = $this->get_missing_tables();

View File

@@ -166,4 +166,60 @@ class Geo {
return $miles;
}
/**
* Get the user IP address.
*
* @since 3.11.0
*
* Code based on the:
* - WordPress method \WP_Community_Events::get_unsafe_client_ip
* - Cloudflare documentation https://support.cloudflare.com/hc/en-us/articles/206776727
*
* @return string
*/
public static function get_ip() {
$ip = '127.0.0.1';
$address_headers = [
'HTTP_TRUE_CLIENT_IP',
'HTTP_CF_CONNECTING_IP',
'HTTP_X_REAL_IP',
'HTTP_CLIENT_IP',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_FORWARDED',
'HTTP_X_CLUSTER_CLIENT_IP',
'HTTP_FORWARDED_FOR',
'HTTP_FORWARDED',
'REMOTE_ADDR',
];
foreach ( $address_headers as $header ) {
if ( empty( $_SERVER[ $header ] ) ) {
continue;
}
/*
* HTTP_X_FORWARDED_FOR can contain a chain of comma-separated addresses, with or without spaces.
* The first address is the original client. It can't be trusted for authenticity,
* but we don't need to for this purpose.
*/
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$address_chain = explode( ',', wp_unslash( $_SERVER[ $header ] ) );
$ip = filter_var( trim( $address_chain[0] ), FILTER_VALIDATE_IP );
break;
}
/**
* Filter detected IP address.
*
* @since 3.11.0
*
* @param string $ip IP address.
*/
return filter_var( apply_filters( 'wp_mail_smtp_geo_get_ip', $ip ), FILTER_VALIDATE_IP );
}
}

View File

@@ -153,4 +153,18 @@ class Helpers {
return 'WordPress/' . get_bloginfo( 'version' ) . '; ' . get_bloginfo( 'url' ) . '; WPMailSMTP/' . $license_type . '-' . WPMS_PLUGIN_VER;
}
/**
* Import Plugin_Upgrader class from core.
*
* @since 3.11.0
*/
public static function include_plugin_upgrader() {
/** \WP_Upgrader class */
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
/** \Plugin_Upgrader class */
require_once ABSPATH . 'wp-admin/includes/class-plugin-upgrader.php';
}
}

View File

@@ -46,6 +46,7 @@ class Options {
'pass',
],
'gmail' => [
'one_click_setup_enabled',
'client_id',
'client_secret',
],
@@ -232,7 +233,7 @@ class Options {
*/
public static function get_defaults() {
return [
$defaults = [
'mail' => [
'from_email' => get_option( 'admin_email' ),
'from_name' => get_bloginfo( 'name' ),
@@ -249,6 +250,15 @@ class Options {
SummaryReportEmail::SETTINGS_SLUG => ! is_multisite() ? false : true,
],
];
/**
* Filters the default options.
*
* @since 3.11.0
*
* @param array $defaults Default options.
*/
return apply_filters( 'wp_mail_smtp_options_get_defaults', $defaults );
}
/**

View File

@@ -2,6 +2,7 @@
namespace WPMailSMTP\Providers\Gmail;
use Exception;
use WPMailSMTP\Admin\Area;
use WPMailSMTP\Admin\ConnectionSettings;
use WPMailSMTP\Admin\DebugEvents\DebugEvents;
@@ -133,7 +134,7 @@ class Auth extends AuthAbstract {
) {
try {
$creds = $client->fetchAccessTokenWithAuthCode( $this->options['auth_code'] );
} catch ( \Exception $e ) {
} catch ( Exception $e ) {
$creds['error'] = $e->getMessage();
}
@@ -155,22 +156,19 @@ class Auth extends AuthAbstract {
$this->update_access_token( $client->getAccessToken() );
$this->update_refresh_token( $client->getRefreshToken() );
$this->update_user_details( $client );
/*
* We need to set the correct `from_email` address, to avoid the SPF and DKIM issue.
*/
$gmail_aliases = $this->is_clients_saved() ? $this->get_user_possible_send_from_addresses() : [];
$all_connection_options = $this->connection_options->get_all();
if (
! empty( $gmail_aliases ) &&
isset( $gmail_aliases[0] ) &&
is_email( $gmail_aliases[0] ) !== false &&
! in_array( $all_connection_options['mail']['from_email'], $gmail_aliases, true )
) {
$all_connection_options['mail']['from_email'] = $gmail_aliases[0];
$this->connection_options->set( $all_connection_options );
// Update the "from email" to the connected user's email.
if ( ! empty( $this->options['user_details']['email'] ) ) {
$this->connection_options->set(
[
'mail' => [
'from_email' => $this->options['user_details']['email'],
],
],
false,
false
);
}
}
@@ -188,7 +186,7 @@ class Auth extends AuthAbstract {
if ( ! empty( $refresh ) ) {
try {
$creds = $client->fetchAccessTokenWithRefreshToken( $refresh );
} catch ( \Exception $e ) {
} catch ( Exception $e ) {
$creds['error'] = $e->getMessage();
Debug::set(
'Mailer: Gmail' . "\r\n" .
@@ -341,23 +339,21 @@ class Auth extends AuthAbstract {
exit;
}
if ( $is_setup_wizard_auth ) {
Debug::clear();
Debug::clear();
$this->get_client( true );
$this->get_client( true );
$error = Debug::get_last();
$error = Debug::get_last();
if ( ! empty( $error ) ) {
wp_safe_redirect(
add_query_arg(
'error',
'google_unsuccessful_oauth',
$redirect_url
)
);
exit;
}
if ( ! empty( $error ) ) {
wp_safe_redirect(
add_query_arg(
'error',
'google_unsuccessful_oauth',
$redirect_url
)
);
exit;
}
wp_safe_redirect(
@@ -391,23 +387,62 @@ class Auth extends AuthAbstract {
}
/**
* Get user information (like email etc) that is associated with the current OAuth connection.
* Get and update user-related details (currently only email).
*
* @since 3.11.0
*
* @param Google_Client $client The Google Client object (optional).
*/
private function update_user_details( $client = false ) {
if ( $client === false ) {
$client = $this->get_client();
}
$gmail = new Gmail( $client );
try {
$email = $gmail->users->getProfile( 'me' )->getEmailAddress();
$user_details = [
'email' => $email,
];
// To save in DB.
$updated_settings = [
$this->mailer_slug => [
'user_details' => $user_details,
],
];
// To save in currently retrieved options array.
$this->options['user_details'] = $user_details;
$this->connection_options->set( $updated_settings, false, false );
} catch ( Exception $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
// Do nothing.
}
}
/**
* Get user information (currently only email) that is associated with the current OAuth connection.
*
* @since 1.5.0
* @since 3.11.0 Switched to DB stored value instead of API call.
*
* @return array
*/
public function get_user_info() {
$gmail = new Gmail( $this->get_client() );
try {
$email = $gmail->users->getProfile( 'me' )->getEmailAddress();
} catch ( \Exception $e ) {
$email = '';
/*
* We need to populate user data on the fly for old users who already performed
* authorization before we switched to DB stored value.
*/
if ( ! isset( $this->options['user_details'] ) && ! $this->is_auth_required() ) {
$this->update_user_details();
}
return array( 'email' => $email );
return $this->connection_options->get( $this->mailer_slug, 'user_details' );
}
/**
@@ -439,7 +474,7 @@ class Auth extends AuthAbstract {
);
// phpcs:enable
} catch ( \Exception $exception ) {
} catch ( Exception $exception ) {
DebugEvents::add_debug(
sprintf( /* Translators: %s the error message. */
esc_html__( 'An error occurred when trying to get Gmail aliases: %s' ),

View File

@@ -4,6 +4,7 @@ namespace WPMailSMTP\Providers\Gmail;
use WPMailSMTP\Admin\ConnectionSettings;
use WPMailSMTP\ConnectionInterface;
use WPMailSMTP\Helpers\UI;
use WPMailSMTP\Providers\OptionsAbstract;
/**
@@ -37,10 +38,9 @@ class Options extends OptionsAbstract {
'title' => esc_html__( 'Google / Gmail', 'wp-mail-smtp' ),
'description' => sprintf(
wp_kses( /* translators: %s - URL to our Gmail doc. */
__( 'Our Gmail mailer works with any Gmail or Google Workspace account via the Google API. You can send WordPress emails from your main email address or a Gmail alias, and it\'s more secure than connecting to Gmail using SMTP credentials. The setup steps are more technical than other options, so we created a detailed guide to walk you through the process.<br><br>To get started, read our <a href="%s" target="_blank" rel="noopener noreferrer">Gmail documentation</a>.', 'wp-mail-smtp' ),
__( 'Our Gmail mailer works with any Gmail or Google Workspace account via the Google API. You can send WordPress emails from your main email address or a Gmail alias, and it\'s more secure than connecting to Gmail using SMTP credentials. We now have a One-Click Setup, which simply asks you to authorize your Google account to use our app and takes care of everything for you. Alternatively, you can connect manually, which involves several steps that are more technical than other mailer options, so we created a detailed guide to walk you through the process.<br><br>To get started, read our <a href="%s" target="_blank" rel="noopener noreferrer">Gmail documentation</a>.', 'wp-mail-smtp' ),
[
'br' => [],
'b' => [],
'a' => [
'href' => [],
'rel' => [],
@@ -84,6 +84,28 @@ class Options extends OptionsAbstract {
}
?>
<?php if ( ! wp_mail_smtp()->is_pro() ) : ?>
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-one_click_setup_enabled-lite" class="wp-mail-smtp-setting-row">
<div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-one_click_setup_enabled-lite">
<?php esc_html_e( 'One-Click Setup', 'wp-mail-smtp' ); ?>
</label>
</div>
<div class="wp-mail-smtp-setting-field">
<?php
UI::toggle(
[
'id' => 'wp-mail-smtp-setting-' . esc_attr( $this->get_slug() ) . '-one_click_setup_enabled-lite',
]
);
?>
<p class="desc">
<?php esc_html_e( 'Provides a quick and easy way to connect to Google that doesn\'t require creating your own app.', 'wp-mail-smtp' ); ?>
</p>
</div>
</div>
<?php endif; ?>
<!-- Client ID -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-client_id"
class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-text wp-mail-smtp-clear">
@@ -242,7 +264,7 @@ class Options extends OptionsAbstract {
*/
public function process_provider_remove() {
if ( ! current_user_can( 'manage_options' ) ) {
if ( ! current_user_can( wp_mail_smtp()->get_capability_manage_options() ) ) {
return;
}
@@ -259,12 +281,10 @@ class Options extends OptionsAbstract {
$old_opt = $this->connection_options->get_all_raw();
foreach ( $old_opt[ $this->get_slug() ] as $key => $value ) {
// Unset everything except Client ID and Secret.
if ( ! in_array( $key, array( 'client_id', 'client_secret' ), true ) ) {
unset( $old_opt[ $this->get_slug() ][ $key ] );
}
}
unset( $old_opt[ $this->get_slug() ]['access_token'] );
unset( $old_opt[ $this->get_slug() ]['refresh_token'] );
unset( $old_opt[ $this->get_slug() ]['user_details'] );
unset( $old_opt[ $this->get_slug() ]['auth_code'] );
$this->connection_options->set( $old_opt );
}

View File

@@ -198,7 +198,7 @@ class Loader {
$entity = null;
}
return apply_filters( 'wp_mail_smtp_providers_loader_get_entity', $entity, $provider, $request );
return apply_filters( 'wp_mail_smtp_providers_loader_get_entity', $entity, $provider, $request, $args );
}
/**

View File

@@ -247,7 +247,8 @@ class Tasks {
*/
public static function is_scheduled( $hook ) {
if ( ! function_exists( 'as_has_scheduled_action' ) ) {
// If ActionScheduler wasn't loaded, then no tasks are scheduled.
if ( ! function_exists( 'as_next_scheduled_action' ) ) {
return null;
}
@@ -260,7 +261,12 @@ class Tasks {
}
// Action is not in the array, so it is not scheduled or belongs to another group.
return as_has_scheduled_action( $hook );
if ( function_exists( 'as_has_scheduled_action' ) ) {
// This function more performant than `as_next_scheduled_action`, but it is available only since AS 3.3.0.
return as_has_scheduled_action( $hook );
} else {
return as_next_scheduled_action( $hook ) !== false;
}
}
/**