Add gravity flow demo

This commit is contained in:
Almira Krdzic
2018-06-28 10:02:07 +02:00
parent 1b5076bf2f
commit 12a5066018
1106 changed files with 317603 additions and 4720 deletions

View File

@@ -0,0 +1,22 @@
<?php
namespace WPMailSMTP\Providers;
/**
* Class AuthAbstract.
*
* @since 1.0.0
*/
abstract class AuthAbstract implements AuthInterface {
/**
* Get the url, that users will be redirected back to finish the OAuth process.
*
* @since 1.0.0
*
* @return string
*/
public static function get_plugin_auth_url() {
return add_query_arg( 'tab', 'auth', wp_mail_smtp()->get_admin()->get_admin_page_url() );
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace WPMailSMTP\Providers;
/**
* Interface AuthInterface.
*
* @since 1.0.0
*/
interface AuthInterface {
/**
* Do something for this Auth implementation.
*
* @since 1.0.0
*/
public function process();
}

View File

@@ -0,0 +1,321 @@
<?php
namespace WPMailSMTP\Providers\Gmail;
use WPMailSMTP\Debug;
use WPMailSMTP\Options as PluginOptions;
use WPMailSMTP\Providers\AuthAbstract;
/**
* Class Auth to request access and refresh tokens.
*
* @since 1.0.0
*/
class Auth extends AuthAbstract {
/**
* Gmail options.
*
* @var array
*/
private $gmail;
/**
* @var \Google_Client
*/
private $client;
/**
* @var string
*/
private $mailer;
/**
* Auth constructor.
*
* @since 1.0.0
*/
public function __construct() {
$options = new PluginOptions();
$this->mailer = $options->get( 'mail', 'mailer' );
if ( $this->mailer !== 'gmail' ) {
return;
}
$this->gmail = $options->get_group( $this->mailer );
if ( $this->is_clients_saved() ) {
$this->include_google_lib();
$this->client = $this->get_client();
}
}
/**
* Use the composer autoloader to include the Google Library and all its dependencies.
*
* @since 1.0.0
*/
protected function include_google_lib() {
require wp_mail_smtp()->plugin_path . '/vendor/autoload.php';
}
/**
* Init and get the Google Client object.
*
* @since 1.0.0
*/
public function get_client() {
// Doesn't load client twice + gives ability to overwrite.
if ( ! empty( $this->client ) ) {
return $this->client;
}
$client = new \Google_Client(
array(
'client_id' => $this->gmail['client_id'],
'client_secret' => $this->gmail['client_secret'],
'redirect_uris' => array(
Auth::get_plugin_auth_url(),
),
)
);
$client->setAccessType( 'offline' );
$client->setApprovalPrompt( 'force' );
$client->setIncludeGrantedScopes( true );
// We request only the sending capability, as it's what we only need to do.
$client->setScopes( array( \Google_Service_Gmail::GMAIL_SEND ) );
$client->setRedirectUri( self::get_plugin_auth_url() );
if (
empty( $this->gmail['access_token'] ) &&
! empty( $this->gmail['auth_code'] )
) {
try {
$creds = $client->fetchAccessTokenWithAuthCode( $this->gmail['auth_code'] );
} catch ( \Exception $e ) {
$creds['error'] = $e->getMessage();
Debug::set( $e->getMessage() );
}
// Bail if we have an error.
if ( ! empty( $creds['error'] ) ) {
// TODO: save this error to display to a user later.
return $client;
}
$this->update_access_token( $client->getAccessToken() );
$this->update_refresh_token( $client->getRefreshToken() );
}
if ( ! empty( $this->gmail['access_token'] ) ) {
$client->setAccessToken( $this->gmail['access_token'] );
}
// Refresh the token if it's expired.
if ( $client->isAccessTokenExpired() ) {
$refresh = $client->getRefreshToken();
if ( empty( $refresh ) && isset( $this->gmail['refresh_token'] ) ) {
$refresh = $this->gmail['refresh_token'];
}
if ( ! empty( $refresh ) ) {
try {
$creds = $client->fetchAccessTokenWithRefreshToken( $refresh );
} catch ( \Exception $e ) {
$creds['error'] = $e->getMessage();
Debug::set( $e->getMessage() );
}
// Bail if we have an error.
if ( ! empty( $creds['error'] ) ) {
return $client;
}
$this->update_access_token( $client->getAccessToken() );
$this->update_refresh_token( $client->getRefreshToken() );
}
}
return $client;
}
/**
* Get the auth code from the $_GET and save it.
* Redirect user back to settings with an error message, if failed.
*
* @since 1.0.0
*/
public function process() {
// We can't process without saved client_id/secret.
if ( ! $this->is_clients_saved() ) {
Debug::set( 'There was an error while processing the Google authentication request. Please make sure that you have Client ID and Client Secret both valid and saved.' );
wp_redirect(
add_query_arg(
'error',
'google_no_clients',
wp_mail_smtp()->get_admin()->get_admin_page_url()
)
);
exit;
}
$code = '';
$scope = '';
$error = '';
if ( isset( $_GET['error'] ) ) {
$error = sanitize_key( $_GET['error'] );
}
// In case of any error: display a message to a user.
if ( ! empty( $error ) ) {
wp_redirect(
add_query_arg(
'error',
'google_' . $error,
wp_mail_smtp()->get_admin()->get_admin_page_url()
)
);
exit;
}
if ( isset( $_GET['code'] ) ) {
$code = $_GET['code'];
}
if ( isset( $_GET['scope'] ) ) {
$scope = urldecode( $_GET['scope'] );
}
// Let's try to get the access token.
if (
! empty( $code ) &&
(
$scope === ( \Google_Service_Gmail::GMAIL_SEND . ' ' . \Google_Service_Gmail::MAIL_GOOGLE_COM ) ||
$scope === \Google_Service_Gmail::GMAIL_SEND
)
) {
// Save the auth code. So \Google_Client can reuse it to retrieve the access token.
$this->update_auth_code( $code );
} else {
wp_redirect(
add_query_arg(
'error',
'google_no_code_scope',
wp_mail_smtp()->get_admin()->get_admin_page_url()
)
);
exit;
}
wp_redirect(
add_query_arg(
'success',
'google_site_linked',
wp_mail_smtp()->get_admin()->get_admin_page_url()
)
);
exit;
}
/**
* Update access token in our DB.
*
* @since 1.0.0
*
* @param array $token
*/
protected function update_access_token( $token ) {
$options = new PluginOptions();
$all = $options->get_all();
$all[ $this->mailer ]['access_token'] = $token;
$this->gmail['access_token'] = $token;
$options->set( $all );
}
/**
* Update refresh token in our DB.
*
* @since 1.0.0
*
* @param array $token
*/
protected function update_refresh_token( $token ) {
$options = new PluginOptions();
$all = $options->get_all();
$all[ $this->mailer ]['refresh_token'] = $token;
$this->gmail['refresh_token'] = $token;
$options->set( $all );
}
/**
* Update auth code in our DB.
*
* @since 1.0.0
*
* @param string $code
*/
protected function update_auth_code( $code ) {
$options = new PluginOptions();
$all = $options->get_all();
$all[ $this->mailer ]['auth_code'] = $code;
$this->gmail['auth_code'] = $code;
$options->set( $all );
}
/**
* Get the auth URL used to proceed to Google to request access to send emails.
*
* @since 1.0.0
*
* @return string
*/
public function get_google_auth_url() {
if (
! empty( $this->client ) &&
class_exists( 'Google_Client', false ) &&
$this->client instanceof \Google_Client
) {
return filter_var( $this->client->createAuthUrl(), FILTER_SANITIZE_URL );
}
return '';
}
/**
* Whether user saved Client ID and Client Secret or not.
* Both options are required.
*
* @since 1.0.0
*
* @return bool
*/
public function is_clients_saved() {
return ! empty( $this->gmail['client_id'] ) && ! empty( $this->gmail['client_secret'] );
}
/**
* Whether we have an access and refresh tokens or not.
*
* @since 1.0.0
*
* @return bool
*/
public function is_auth_required() {
return empty( $this->gmail['access_token'] ) || empty( $this->gmail['refresh_token'] );
}
}

View File

@@ -0,0 +1,168 @@
<?php
namespace WPMailSMTP\Providers\Gmail;
use WPMailSMTP\Debug;
use WPMailSMTP\MailCatcher;
use WPMailSMTP\Providers\MailerAbstract;
/**
* Class Mailer.
*
* @since 1.0.0
*/
class Mailer extends MailerAbstract {
/**
* URL to make an API request to.
* Not used for Gmail, as we are using its API.
*
* @var string
*/
protected $url = 'https://www.googleapis.com/upload/gmail/v1/users/userId/messages/send';
/**
* Gmail custom Auth library.
*
* @var Auth
*/
protected $auth;
/**
* Gmail message.
*
* @var \Google_Service_Gmail_Message
*/
protected $message;
/**
* Mailer constructor.
*
* @since 1.0.0
*
* @param \WPMailSMTP\MailCatcher $phpmailer
*/
public function __construct( $phpmailer ) {
parent::__construct( $phpmailer );
if ( ! $this->is_php_compatible() ) {
return;
}
// Include the Google library.
require wp_mail_smtp()->plugin_path . '/vendor/autoload.php';
$this->auth = new Auth();
$this->message = new \Google_Service_Gmail_Message();
}
/**
* Re-use the MailCatcher class methods and properties.
*
* @since 1.2.0
*
* @param \WPMailSMTP\MailCatcher $phpmailer
*/
public function process_phpmailer( $phpmailer ) {
// Make sure that we have access to MailCatcher class methods.
if (
! $phpmailer instanceof MailCatcher &&
! $phpmailer instanceof \PHPMailer
) {
return;
}
$this->phpmailer = $phpmailer;
}
/**
* Use Google API Services to send emails.
*
* @since 1.0.0
*/
public function send() {
// Get the raw MIME email using \MailCatcher data.
$base64 = base64_encode( $this->phpmailer->getSentMIMEMessage() );
$base64 = str_replace( array( '+', '/', '=' ), array( '-', '_', '' ), $base64 ); // url safe.
$this->message->setRaw( $base64 );
$service = new \Google_Service_Gmail( $this->auth->get_client() );
try {
$response = $service->users_messages->send( 'me', $this->message );
$this->process_response( $response );
} catch ( \Exception $e ) {
Debug::set( 'Error while sending via Gmail mailer: ' . $e->getMessage() );
return;
}
}
/**
* Save response from the API to use it later.
*
* @since 1.0.0
*
* @param \Google_Service_Gmail_Message $response
*/
protected function process_response( $response ) {
$this->response = $response;
}
/**
* Check whether the email was sent.
*
* @since 1.0.0
*
* @return bool
*/
public function is_email_sent() {
$is_sent = false;
if ( method_exists( $this->response, 'getId' ) ) {
$message_id = $this->response->getId();
if ( ! empty( $message_id ) ) {
return true;
}
}
return $is_sent;
}
/**
* @inheritdoc
*/
public function get_debug_info() {
$gmail_text = array();
$options = new \WPMailSMTP\Options();
$gmail = $options->get_group( 'gmail' );
$gmail_text[] = '<strong>Client ID/Secret:</strong> ' . ( ! empty( $gmail['client_id'] ) && ! empty( $gmail['client_secret'] ) ? 'Yes' : 'No' );
$gmail_text[] = '<strong>Auth Code:</strong> ' . ( ! empty( $gmail['auth_code'] ) ? 'Yes' : 'No' );
$gmail_text[] = '<strong>Access Token:</strong> ' . ( ! empty( $gmail['access_token'] ) ? 'Yes' : 'No' );
$gmail_text[] = '<br><strong>Server:</strong>';
$gmail_text[] = '<strong>OpenSSL:</strong> ' . ( extension_loaded( 'openssl' ) ? 'Yes' : 'No' );
$gmail_text[] = '<strong>PHP.allow_url_fopen:</strong> ' . ( ini_get( 'allow_url_fopen' ) ? 'Yes' : 'No' );
$gmail_text[] = '<strong>PHP.stream_socket_client():</strong> ' . ( function_exists( 'stream_socket_client' ) ? 'Yes' : 'No' );
$gmail_text[] = '<strong>PHP.fsockopen():</strong> ' . ( function_exists( 'fsockopen' ) ? 'Yes' : 'No' );
$gmail_text[] = '<strong>PHP.curl_version():</strong> ' . ( function_exists( 'curl_version' ) ? 'Yes' : 'No' );
if ( function_exists( 'apache_get_modules' ) ) {
$modules = apache_get_modules();
$gmail_text[] = '<strong>Apache.mod_security:</strong> ' . ( in_array( 'mod_security', $modules, true ) || in_array( 'mod_security2', $modules, true ) ? 'Yes' : 'No' );
}
if ( function_exists( 'selinux_is_enabled' ) ) {
$gmail_text[] = '<strong>OS.SELinux:</strong> ' . ( selinux_is_enabled() ? 'Yes' : 'No' );
}
if ( function_exists( 'grsecurity_is_enabled' ) ) {
$gmail_text[] = '<strong>OS.grsecurity:</strong> ' . ( grsecurity_is_enabled() ? 'Yes' : 'No' );
}
return implode( '<br>', $gmail_text );
}
}

View File

@@ -0,0 +1,131 @@
<?php
namespace WPMailSMTP\Providers\Gmail;
use WPMailSMTP\Providers\OptionsAbstract;
/**
* Class Option.
*
* @since 1.0.0
*/
class Options extends OptionsAbstract {
/**
* Mailgun constructor.
*
* @since 1.0.0
*/
public function __construct() {
parent::__construct(
array(
'logo_url' => wp_mail_smtp()->plugin_url . '/assets/images/gmail.png',
'slug' => 'gmail',
'title' => esc_html__( 'Gmail', 'wp-mail-smtp' ),
'description' => sprintf(
wp_kses(
/* translators: %1$s - opening link tag; %2$s - closing link tag. */
__( 'Send emails using your Gmail or G Suite (formerly Google Apps) account, all while keeping your login credentials safe. Other Google SMTP methods require enabling less secure apps in your account and entering your password. However, this integration uses the Google API to improve email delivery issues while keeping your site secure.<br><br>Read our %1$sGmail documentation%2$s to learn how to configure Gmail or G Suite.', 'wp-mail-smtp' ),
array(
'br' => array(),
'a' => array(
'href' => array(),
'rel' => array(),
'target' => array(),
),
)
),
'<a href="https://wpforms.com/how-to-securely-send-wordpress-emails-using-gmail-smtp/" target="_blank" rel="noopener noreferrer">',
'</a>'
),
'php' => '5.5',
)
);
}
/**
* @inheritdoc
*/
public function display_options() {
// Do not display options if PHP version is not correct.
if ( ! $this->is_php_correct() ) {
$this->display_php_warning();
return;
}
?>
<!-- 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">
<div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-client_id"><?php esc_html_e( 'Client ID', 'wp-mail-smtp' ); ?></label>
</div>
<div class="wp-mail-smtp-setting-field">
<input name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][client_id]" type="text"
value="<?php echo esc_attr( $this->options->get( $this->get_slug(), 'client_id' ) ); ?>"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'client_id' ) ? 'disabled' : ''; ?>
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-client_id" spellcheck="false"
/>
</div>
</div>
<!-- Client Secret -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-client_secret" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-text wp-mail-smtp-clear">
<div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-client_secret"><?php esc_html_e( 'Client Secret', 'wp-mail-smtp' ); ?></label>
</div>
<div class="wp-mail-smtp-setting-field">
<input name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][client_secret]" type="text"
value="<?php echo esc_attr( $this->options->get( $this->get_slug(), 'client_secret' ) ); ?>"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'client_secret' ) ? 'disabled' : ''; ?>
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-client_secret" spellcheck="false"
/>
</div>
</div>
<!-- Authorized redirect URI -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-client_redirect" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-text wp-mail-smtp-clear">
<div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-client_redirect"><?php esc_html_e( 'Authorized redirect URI', 'wp-mail-smtp' ); ?></label>
</div>
<div class="wp-mail-smtp-setting-field">
<input type="text" readonly="readonly"
value="<?php echo esc_attr( Auth::get_plugin_auth_url() ); ?>"
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-client_redirect"
/>
<button type="button" class="wp-mail-smtp-btn wp-mail-smtp-btn-md wp-mail-smtp-btn-light-grey wp-mail-smtp-setting-copy"
title="<?php esc_attr_e( 'Copy URL to clipboard', 'wp-mail-smtp' ); ?>"
data-source_id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-client_redirect">
<span class="dashicons dashicons-admin-page"></span>
</button>
<p class="desc">
<?php esc_html_e( 'This is the path on your site that you will be redirected to after you have authenticated with Google.', 'wp-mail-smtp' ); ?>
<br>
<?php esc_html_e( 'You need to copy this URL into "Authorized redirect URIs" field for you web application on Google APIs site for your project there.', 'wp-mail-smtp' ); ?>
</p>
</div>
</div>
<!-- Auth users button -->
<?php $auth = new Auth(); ?>
<?php if ( $auth->is_clients_saved() && $auth->is_auth_required() ) : ?>
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-authorize" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-text wp-mail-smtp-clear">
<div class="wp-mail-smtp-setting-label">
<label><?php esc_html_e( 'Authorize', 'wp-mail-smtp' ); ?></label>
</div>
<div class="wp-mail-smtp-setting-field">
<a href="<?php echo esc_url( $auth->get_google_auth_url() ); ?>" class="wp-mail-smtp-btn wp-mail-smtp-btn-md wp-mail-smtp-btn-orange">
<?php esc_html_e( 'Allow plugin to send emails using your Google account', 'wp-mail-smtp' ); ?>
</a>
<p class="desc">
<?php esc_html_e( 'Click the button above to confirm authorization.', 'wp-mail-smtp' ); ?>
</p>
</div>
</div>
<?php endif; ?>
<?php
}
}

View File

@@ -0,0 +1,188 @@
<?php
namespace WPMailSMTP\Providers;
use WPMailSMTP\Debug;
use WPMailSMTP\MailCatcher;
use WPMailSMTP\Options;
/**
* Class Loader.
*
* @since 1.0.0
*/
class Loader {
/**
* Key is the mailer option, value is the path to its classes.
*
* @var array
*/
protected $providers = array(
'mail' => 'WPMailSMTP\Providers\Mail\\',
'gmail' => 'WPMailSMTP\Providers\Gmail\\',
'mailgun' => 'WPMailSMTP\Providers\Mailgun\\',
'sendgrid' => 'WPMailSMTP\Providers\Sendgrid\\',
'pepipost' => 'WPMailSMTP\Providers\Pepipost\\',
'smtp' => 'WPMailSMTP\Providers\SMTP\\',
);
/**
* @var \WPMailSMTP\MailCatcher
*/
private $phpmailer;
/**
* Get all the supported providers.
*
* @since 1.0.0
*
* @return array
*/
public function get_providers() {
if ( ! Options::init()->is_pepipost_active() ) {
unset( $this->providers['pepipost'] );
}
return apply_filters( 'wp_mail_smtp_providers_loader_get_providers', $this->providers );
}
/**
* Get a single provider FQN-path based on its name.
*
* @since 1.0.0
*
* @param string $provider
*
* @return array
*/
public function get_provider_path( $provider ) {
$provider = sanitize_key( $provider );
return apply_filters(
'wp_mail_smtp_providers_loader_get_provider_path',
isset( $this->providers[ $provider ] ) ? $this->providers[ $provider ] : null,
$provider
);
}
/**
* Get the provider options, if exists.
*
* @since 1.0.0
*
* @param string $provider
*
* @return \WPMailSMTP\Providers\OptionsAbstract|null
*/
public function get_options( $provider ) {
return $this->get_entity( $provider, 'Options' );
}
/**
* Get all options of all providers.
*
* @since 1.0.0
*
* @return \WPMailSMTP\Providers\OptionsAbstract[]
*/
public function get_options_all() {
$options = array();
foreach ( $this->get_providers() as $provider => $path ) {
$option = $this->get_options( $provider );
if ( ! $option instanceof OptionsAbstract ) {
continue;
}
$slug = $option->get_slug();
$title = $option->get_title();
if ( empty( $title ) || empty( $slug ) ) {
continue;
}
$options[] = $option;
}
return apply_filters( 'wp_mail_smtp_providers_loader_get_providers_all', $options );
}
/**
* Get the provider mailer, if exists.
*
* @since 1.0.0
*
* @param string $provider
* @param MailCatcher $phpmailer
*
* @return \WPMailSMTP\Providers\MailerAbstract|null
*/
public function get_mailer( $provider, $phpmailer ) {
if (
$phpmailer instanceof MailCatcher ||
$phpmailer instanceof \PHPMailer
) {
$this->phpmailer = $phpmailer;
}
return $this->get_entity( $provider, 'Mailer' );
}
/**
* Get the provider auth, if exists.
*
* @param string $provider
*
* @return \WPMailSMTP\Providers\AuthAbstract|null
*/
public function get_auth( $provider ) {
return $this->get_entity( $provider, 'Auth' );
}
/**
* Get a generic entity based on the request.
*
* @uses ReflectionClass
*
* @since 1.0.0
*
* @param string $provider
* @param string $request
*
* @return null
*/
protected function get_entity( $provider, $request ) {
$provider = sanitize_key( $provider );
$request = sanitize_text_field( $request );
$path = $this->get_provider_path( $provider );
$entity = null;
if ( empty( $path ) ) {
return $entity;
}
try {
$reflection = new \ReflectionClass( $path . $request );
if ( file_exists( $reflection->getFileName() ) ) {
$class = $path . $request;
if ( $this->phpmailer ) {
$entity = new $class( $this->phpmailer );
} else {
$entity = new $class();
}
}
} catch ( \Exception $e ) {
Debug::set( "There was a problem while retrieving {$request} for {$provider}: {$e->getMessage()}" );
$entity = null;
}
return apply_filters( 'wp_mail_smtp_providers_loader_get_entity', $entity, $provider, $request );
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace WPMailSMTP\Providers\Mail;
use WPMailSMTP\Providers\MailerAbstract;
/**
* Class Mailer inherits everything from parent abstract class.
* This file is required for a proper work of Loader and \ReflectionClass.
*
* @package WPMailSMTP\Providers\Mail
*/
class Mailer extends MailerAbstract {
/**
* @inheritdoc
*/
public function get_debug_info() {
$mail_text = array();
$mail_text[] = '<br><strong>Server:</strong>';
$disabled_functions = ini_get( 'disable_functions' );
$disabled = (array) explode( ',', trim( $disabled_functions ) );
$mail_text[] = '<strong>PHP.mail():</strong> ' . ( in_array( 'mail', $disabled, true ) || ! function_exists( 'mail' ) ? 'No' : 'Yes' );
if ( function_exists( 'apache_get_modules' ) ) {
$modules = apache_get_modules();
$mail_text[] = '<strong>Apache.mod_security:</strong> ' . ( in_array( 'mod_security', $modules, true ) || in_array( 'mod_security2', $modules, true ) ? 'Yes' : 'No' );
}
if ( function_exists( 'selinux_is_enabled' ) ) {
$mail_text[] = '<strong>OS.SELinux:</strong> ' . ( selinux_is_enabled() ? 'Yes' : 'No' );
}
if ( function_exists( 'grsecurity_is_enabled' ) ) {
$mail_text[] = '<strong>OS.grsecurity:</strong> ' . ( grsecurity_is_enabled() ? 'Yes' : 'No' );
}
return implode( '<br>', $mail_text );
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace WPMailSMTP\Providers\Mail;
use WPMailSMTP\Providers\OptionsAbstract;
/**
* Class Option.
*
* @since 1.0.0
*/
class Options extends OptionsAbstract {
/**
* Mail constructor.
*
* @since 1.0.0
*/
public function __construct() {
parent::__construct(
array(
'logo_url' => wp_mail_smtp()->plugin_url . '/assets/images/php.png',
'slug' => 'mail',
'title' => esc_html__( 'Default (none)', 'wp-mail-smtp' ),
)
);
}
/**
* @inheritdoc
*/
public function display_options() {
?>
<blockquote>
<?php esc_html_e( 'You currently have the native WordPress option selected. Please select any other Mailer option above to continue the setup.', 'wp-mail-smtp' ); ?>
</blockquote>
<?php
}
}

View File

@@ -0,0 +1,372 @@
<?php
namespace WPMailSMTP\Providers;
use WPMailSMTP\Debug;
use WPMailSMTP\MailCatcher;
use WPMailSMTP\Options;
/**
* Class MailerAbstract.
*
* @since 1.0.0
*/
abstract class MailerAbstract implements MailerInterface {
/**
* Which response code from HTTP provider is considered to be successful?
*
* @var int
*/
protected $email_sent_code = 200;
/**
* @var Options
*/
protected $options;
/**
* @var MailCatcher
*/
protected $phpmailer;
/**
* @var string
*/
protected $mailer = '';
/**
* URL to make an API request to.
*
* @var string
*/
protected $url = '';
/**
* @var array
*/
protected $headers = array();
/**
* @var array
*/
protected $body = array();
/**
* @var mixed
*/
protected $response = array();
/**
* Mailer constructor.
*
* @since 1.0.0
*
* @param MailCatcher $phpmailer
*/
public function __construct( MailCatcher $phpmailer ) {
$this->options = new Options();
$this->mailer = $this->options->get( 'mail', 'mailer' );
// Only non-SMTP mailers need URL.
if ( ! $this->options->is_mailer_smtp() && empty( $this->url ) ) {
return;
}
$this->process_phpmailer( $phpmailer );
}
/**
* Re-use the MailCatcher class methods and properties.
*
* @since 1.0.0
*
* @param MailCatcher $phpmailer
*/
public function process_phpmailer( $phpmailer ) {
// Make sure that we have access to MailCatcher class methods.
if (
! $phpmailer instanceof MailCatcher &&
! $phpmailer instanceof \PHPMailer
) {
return;
}
$this->phpmailer = $phpmailer;
// Prevent working with those methods, as they are not needed for SMTP-like mailers.
if ( $this->options->is_mailer_smtp() ) {
return;
}
$this->set_headers( $this->phpmailer->getCustomHeaders() );
$this->set_from( $this->phpmailer->From, $this->phpmailer->FromName );
$this->set_recipients(
array(
'to' => $this->phpmailer->getToAddresses(),
'cc' => $this->phpmailer->getCcAddresses(),
'bcc' => $this->phpmailer->getBccAddresses(),
)
);
$this->set_subject( $this->phpmailer->Subject );
$this->set_content(
array(
'html' => $this->phpmailer->Body,
'text' => $this->phpmailer->AltBody,
)
);
$this->set_return_path( $this->phpmailer->From );
$this->set_reply_to( $this->phpmailer->getReplyToAddresses() );
/*
* In some cases we will need to modify the internal structure
* of the body content, if attachments are present.
* So lets make this call the last one.
*/
$this->set_attachments( $this->phpmailer->getAttachments() );
}
/**
* @inheritdoc
*/
public function set_subject( $subject ) {
$this->set_body_param(
array(
'subject' => $subject,
)
);
}
/**
* Set the request params, that goes to the body of the HTTP request.
*
* @since 1.0.0
*
* @param array $param Key=>value of what should be sent to a 3rd party API.
*
* @internal param array $params
*/
protected function set_body_param( $param ) {
$this->body = Options::array_merge_recursive( $this->body, $param );
}
/**
* @inheritdoc
*/
public function set_headers( $headers ) {
foreach ( $headers as $header ) {
$name = isset( $header[0] ) ? $header[0] : false;
$value = isset( $header[1] ) ? $header[1] : false;
if ( empty( $name ) || empty( $value ) ) {
continue;
}
$this->set_header( $name, $value );
}
}
/**
* @inheritdoc
*/
public function set_header( $name, $value ) {
$process_value = function ( $value ) {
// Remove HTML tags.
$filtered = wp_strip_all_tags( $value, false );
// Remove multi-lines/tabs.
$filtered = preg_replace( '/[\r\n\t ]+/', ' ', $filtered );
// Remove whitespaces.
$filtered = trim( $filtered );
// Remove octets.
$found = false;
while ( preg_match( '/%[a-f0-9]{2}/i', $filtered, $match ) ) {
$filtered = str_replace( $match[0], '', $filtered );
$found = true;
}
if ( $found ) {
// Strip out the whitespace that may now exist after removing the octets.
$filtered = trim( preg_replace( '/ +/', ' ', $filtered ) );
}
return $filtered;
};
$name = sanitize_text_field( $name );
if ( empty( $name ) ) {
return;
}
$value = $process_value( $value );
$this->headers[ $name ] = $value;
}
/**
* @inheritdoc
*/
public function get_body() {
return apply_filters( 'wp_mail_smtp_providers_mailer_get_body', $this->body );
}
/**
* @inheritdoc
*/
public function get_headers() {
return apply_filters( 'wp_mail_smtp_providers_mailer_get_headers', $this->headers );
}
/**
* @inheritdoc
*/
public function send() {
$params = Options::array_merge_recursive( $this->get_default_params(), array(
'headers' => $this->get_headers(),
'body' => $this->get_body(),
) );
$response = wp_safe_remote_post( $this->url, $params );
$this->process_response( $response );
}
/**
* We might need to do something after the email was sent to the API.
* In this method we preprocess the response from the API.
*
* @since 1.0.0
*
* @param array|\WP_Error $response
*/
protected function process_response( $response ) {
if ( is_wp_error( $response ) ) {
// Save the error text.
$errors = $response->get_error_messages();
foreach ( $errors as $error ) {
Debug::set( $error );
}
return;
}
if ( isset( $response['body'] ) && $this->is_json( $response['body'] ) ) {
$response['body'] = \json_decode( $response['body'] );
}
$this->response = $response;
}
/**
* Get the default params, required for wp_safe_remote_post().
*
* @since 1.0.0
*
* @return array
*/
protected function get_default_params() {
return apply_filters( 'wp_mail_smtp_providers_mailer_get_default_params', array(
'timeout' => 15,
'httpversion' => '1.1',
'blocking' => true,
) );
}
/**
* @inheritdoc
*/
public function is_email_sent() {
$is_sent = false;
if ( wp_remote_retrieve_response_code( $this->response ) === $this->email_sent_code ) {
$is_sent = true;
} else {
$error = $this->get_response_error();
if ( ! empty( $error ) ) {
Debug::set( $error );
}
}
return apply_filters( 'wp_mail_smtp_providers_mailer_is_email_sent', $is_sent );
}
/**
* Should be overwritten when appropriate.
*
* @since 1.2.0
*
* @return string
*/
protected function get_response_error() {
return '';
}
/**
* @inheritdoc
*/
public function is_php_compatible() {
$options = wp_mail_smtp()->get_providers()->get_options( $this->mailer );
return version_compare( phpversion(), $options->get_php_version(), '>=' );
}
/**
* Check whether the string is a JSON or not.
*
* @since 1.0.0
*
* @param string $string
*
* @return bool
*/
protected function is_json( $string ) {
return is_string( $string ) && is_array( json_decode( $string, true ) ) && ( json_last_error() === JSON_ERROR_NONE ) ? true : false;
}
/**
* This method is relevant to SMTP and Pepipost.
* All other custom mailers should override it with own information.
*
* @since 1.2.0
*
* @return string
*/
public function get_debug_info() {
global $phpmailer;
$smtp_text = array();
// Mail mailer has nothing to return.
if ( $this->options->is_mailer_smtp() ) {
$smtp_text[] = '<strong>ErrorInfo:</strong> ' . make_clickable( wp_strip_all_tags( $phpmailer->ErrorInfo ) );
$smtp_text[] = '<strong>Host:</strong> ' . $phpmailer->Host;
$smtp_text[] = '<strong>Port:</strong> ' . $phpmailer->Port;
$smtp_text[] = '<strong>SMTPSecure:</strong> ' . Debug::pvar( $phpmailer->SMTPSecure );
$smtp_text[] = '<strong>SMTPAutoTLS:</strong> ' . Debug::pvar( $phpmailer->SMTPAutoTLS );
$smtp_text[] = '<strong>SMTPAuth:</strong> ' . Debug::pvar( $phpmailer->SMTPAuth );
if ( ! empty( $phpmailer->SMTPOptions ) ) {
$smtp_text[] = '<strong>SMTPOptions:</strong> <code>' . json_encode( $phpmailer->SMTPOptions ) . '</code>';
}
}
$smtp_text[] = '<br><strong>Server:</strong>';
$smtp_text[] = '<strong>OpenSSL:</strong> ' . ( extension_loaded( 'openssl' ) ? 'Yes' : 'No' );
if ( function_exists( 'apache_get_modules' ) ) {
$modules = apache_get_modules();
$smtp_text[] = '<strong>Apache.mod_security:</strong> ' . ( in_array( 'mod_security', $modules, true ) || in_array( 'mod_security2', $modules, true ) ? 'Yes' : 'No' );
}
if ( function_exists( 'selinux_is_enabled' ) ) {
$smtp_text[] = '<strong>OS.SELinux:</strong> ' . ( selinux_is_enabled() ? 'Yes' : 'No' );
}
if ( function_exists( 'grsecurity_is_enabled' ) ) {
$smtp_text[] = '<strong>OS.grsecurity:</strong> ' . ( grsecurity_is_enabled() ? 'Yes' : 'No' );
}
return implode( '<br>', $smtp_text );
}
}

View File

@@ -0,0 +1,74 @@
<?php
namespace WPMailSMTP\Providers;
/**
* Interface MailerInterface.
*
* @since 1.0.0
*/
interface MailerInterface {
/**
* Send the email.
*
* @since 1.0.0
*/
public function send();
/**
* Whether the email is sent or not.
* We basically check the response code from a request to provider.
* Might not be 100% correct, not guarantees that email is delivered.
*
* @since 1.0.0
*
* @return bool
*/
public function is_email_sent();
/**
* Whether the mailer supports the current PHP version or not.
*
* @since 1.0.0
*
* @return bool
*/
public function is_php_compatible();
/**
* Get the email body.
*
* @since 1.0.0
*
* @return string|array
*/
public function get_body();
/**
* Get the email headers.
*
* @since 1.0.0
*
* @return array
*/
public function get_headers();
/**
* Get an array of all debug information relevant to the mailer.
*
* @since 1.2.0
*
* @return array
*/
public function get_debug_info();
/**
* Re-use the MailCatcher class methods and properties.
*
* @since 1.2.0
*
* @param \WPMailSMTP\MailCatcher $phpmailer
*/
public function process_phpmailer( $phpmailer );
}

View File

@@ -0,0 +1,344 @@
<?php
namespace WPMailSMTP\Providers\Mailgun;
use WPMailSMTP\Providers\MailerAbstract;
/**
* Class Mailer.
*
* @since 1.0.0
*/
class Mailer extends MailerAbstract {
/**
* Which response code from HTTP provider is considered to be successful?
*
* @var int
*/
protected $email_sent_code = 200;
/**
* URL to make an API request to.
*
* @var string
*/
protected $url = 'https://api.mailgun.net/v3/';
/**
* @inheritdoc
*/
public function __construct( $phpmailer ) {
// We want to prefill everything from \WPMailSMTP\MailCatcher class, which extends \PHPMailer.
parent::__construct( $phpmailer );
/*
* Append the url with a domain,
* to avoid passing the domain name as a query parameter with all requests.
*/
$this->url .= sanitize_text_field( $this->options->get( $this->mailer, 'domain' ) . '/messages' );
$this->set_header( 'Authorization', 'Basic ' . base64_encode( 'api:' . $this->options->get( $this->mailer, 'api_key' ) ) );
}
/**
* @inheritdoc
*/
public function set_from( $email, $name = '' ) {
if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
return;
}
if ( ! empty( $name ) ) {
$this->set_body_param(
array(
'from' => $name . ' <' . $email . '>',
)
);
} else {
$this->set_body_param(
array(
'from' => $email,
)
);
}
}
/**
* @inheritdoc
*/
public function set_recipients( $recipients ) {
if ( empty( $recipients ) ) {
return;
}
$default = array( 'to', 'cc', 'bcc' );
foreach ( $recipients as $kind => $emails ) {
if (
! in_array( $kind, $default, true ) ||
empty( $emails ) ||
! is_array( $emails )
) {
continue;
}
$data = array();
foreach ( $emails as $email ) {
$addr = isset( $email[0] ) ? $email[0] : false;
$name = isset( $email[1] ) ? $email[1] : false;
if ( ! filter_var( $addr, FILTER_VALIDATE_EMAIL ) ) {
continue;
}
if ( ! empty( $name ) ) {
$data[] = $name . ' <' . $addr . '>';
} else {
$data[] = $addr;
}
}
if ( ! empty( $data ) ) {
$this->set_body_param(
array(
$kind => implode( ', ', $data ),
)
);
}
}
}
/**
* @inheritdoc
*/
public function set_content( $content ) {
if ( is_array( $content ) ) {
$default = array( 'text', 'html' );
foreach ( $content as $type => $mail ) {
if (
! in_array( $type, $default, true ) ||
empty( $mail )
) {
continue;
}
$this->set_body_param(
array(
$type => $mail,
)
);
}
} else {
$type = 'text';
if ( $this->phpmailer->ContentType === 'text/html' ) {
$type = 'html';
}
if ( ! empty( $content ) ) {
$this->set_body_param(
array(
$type => $content,
)
);
}
}
}
/**
* It's the last one, so we can modify the whole body.
*
* @since 1.0.0
*
* @param array $attachments
*/
public function set_attachments( $attachments ) {
if ( empty( $attachments ) ) {
return;
}
$payload = '';
$data = array();
foreach ( $attachments as $attachment ) {
$file = false;
/*
* We are not using WP_Filesystem API as we can't reliably work with it.
* It is not always available, same as credentials for FTP.
*/
try {
if ( is_file( $attachment[0] ) && is_readable( $attachment[0] ) ) {
$file = file_get_contents( $attachment[0] );
}
} catch ( \Exception $e ) {
$file = false;
}
if ( $file === false ) {
continue;
}
$data[] = array(
'content' => $file,
'name' => $attachment[1],
);
}
if ( ! empty( $data ) ) {
// First, generate a boundary for the multipart message.
$boundary = base_convert( uniqid( 'boundary', true ), 10, 36 );
// Iterate through pre-built params and build a payload.
foreach ( $this->body as $key => $value ) {
if ( is_array( $value ) ) {
foreach ( $value as $child_key => $child_value ) {
$payload .= '--' . $boundary;
$payload .= "\r\n";
$payload .= 'Content-Disposition: form-data; name="' . $key . "\"\r\n\r\n";
$payload .= $child_value;
$payload .= "\r\n";
}
} else {
$payload .= '--' . $boundary;
$payload .= "\r\n";
$payload .= 'Content-Disposition: form-data; name="' . $key . '"' . "\r\n\r\n";
$payload .= $value;
$payload .= "\r\n";
}
}
// Now iterate through our attachments, and add them too.
foreach ( $data as $key => $attachment ) {
$payload .= '--' . $boundary;
$payload .= "\r\n";
$payload .= 'Content-Disposition: form-data; name="attachment[' . $key . ']"; filename="' . $attachment['name'] . '"' . "\r\n\r\n";
$payload .= $attachment['content'];
$payload .= "\r\n";
}
$payload .= '--' . $boundary . '--';
// Redefine the body the "dirty way".
$this->body = $payload;
$this->set_header( 'Content-Type', 'multipart/form-data; boundary=' . $boundary );
}
}
/**
* @inheritdoc
*/
public function set_reply_to( $reply_to ) {
if ( empty( $reply_to ) ) {
return;
}
$data = array();
foreach ( $reply_to as $key => $emails ) {
if (
empty( $emails ) ||
! is_array( $emails )
) {
continue;
}
$addr = isset( $emails[0] ) ? $emails[0] : false;
$name = isset( $emails[1] ) ? $emails[1] : false;
if ( ! filter_var( $addr, FILTER_VALIDATE_EMAIL ) ) {
continue;
}
if ( ! empty( $name ) ) {
$data[] = $name . ' <' . $addr . '>';
} else {
$data[] = $addr;
}
}
if ( ! empty( $data ) ) {
$this->set_body_param(
array(
'h:Reply-To' => implode( ',', $data ),
)
);
}
}
/**
* @inheritdoc
*/
public function set_return_path( $email ) {
if (
$this->options->get( 'mail', 'return_path' ) !== true ||
! filter_var( $email, FILTER_VALIDATE_EMAIL )
) {
return;
}
$this->set_body_param(
array(
'sender' => $email,
)
);
}
/**
* Get a Mailgun-specific response with a helpful error.
*
* @since 1.2.0
*
* @return string
*/
protected function get_response_error() {
$body = (array) wp_remote_retrieve_body( $this->response );
$error_text = array();
if ( ! empty( $body['message'] ) ) {
if ( is_string( $body['message'] ) ) {
$error_text[] = $body['message'];
} else {
$error_text[] = \json_encode( $body['message'] );
}
} elseif ( ! empty( $body[0] ) ) {
if ( is_string( $body[0] ) ) {
$error_text[] = $body[0];
} else {
$error_text[] = \json_encode( $body[0] );
}
}
return implode( '<br>', array_map( 'esc_textarea', $error_text ) );
}
/**
* @inheritdoc
*/
public function get_debug_info() {
$mg_text = array();
$options = new \WPMailSMTP\Options();
$mailgun = $options->get_group( 'mailgun' );
$mg_text[] = '<strong>Api Key / Domain:</strong> ' . ( ! empty( $mailgun['api_key'] ) && ! empty( $mailgun['domain'] ) ? 'Yes' : 'No' );
return implode( '<br>', $mg_text );
}
}

View File

@@ -0,0 +1,106 @@
<?php
namespace WPMailSMTP\Providers\Mailgun;
use WPMailSMTP\Providers\OptionsAbstract;
/**
* Class Option.
*
* @since 1.0.0
*/
class Options extends OptionsAbstract {
/**
* Mailgun constructor.
*
* @since 1.0.0
*/
public function __construct() {
parent::__construct(
array(
'logo_url' => wp_mail_smtp()->plugin_url . '/assets/images/mailgun.png',
'slug' => 'mailgun',
'title' => esc_html__( 'Mailgun', 'wp-mail-smtp' ),
'description' => sprintf(
wp_kses(
/* translators: %1$s - opening link tag; %2$s - closing link tag; %3$s - opening link tag; %4$s - closing link tag. */
__( '%1$sMailgun%2$s is one of the leading transactional email services trusted by over 10,000 website and application developers. They provide users 10,000 free emails per month.<br><br>Read our %3$sMailgun documentation%4$s to learn how to configure Mailgun and improve your email deliverability.', 'wp-mail-smtp' ),
array(
'br' => array(),
'a' => array(
'href' => array(),
'rel' => array(),
'target' => array(),
),
)
),
'<a href="https://www.mailgun.com" target="_blank" rel="noopener noreferrer">',
'</a>',
'<a href="https://wpforms.com/how-to-send-wordpress-emails-with-mailgun/" target="_blank" rel="noopener noreferrer">',
'</a>'
),
)
);
}
/**
* @inheritdoc
*/
public function display_options() {
?>
<!-- API Key -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-api_key" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-text wp-mail-smtp-clear">
<div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-api_key"><?php esc_html_e( 'Private API Key', 'wp-mail-smtp' ); ?></label>
</div>
<div class="wp-mail-smtp-setting-field">
<input name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][api_key]" type="text"
value="<?php echo esc_attr( $this->options->get( $this->get_slug(), 'api_key' ) ); ?>"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'api_key' ) ? 'disabled' : ''; ?>
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-api_key" spellcheck="false"
/>
<p class="desc">
<?php
printf(
/* translators: %s - API key link. */
esc_html__( 'Follow this link to get an API Key from Mailgun: %s.', 'wp-mail-smtp' ),
'<a href="https://app.mailgun.com/app/account/security" target="_blank" rel="noopener noreferrer">' .
esc_html__( 'Get a Private API Key', 'wp-mail-smtp' ) .
'</a>'
);
?>
</p>
</div>
</div>
<!-- Domain -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-domain" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-text wp-mail-smtp-clear">
<div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-domain"><?php esc_html_e( 'Domain Name', 'wp-mail-smtp' ); ?></label>
</div>
<div class="wp-mail-smtp-setting-field">
<input name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][domain]" type="text"
value="<?php echo esc_attr( $this->options->get( $this->get_slug(), 'domain' ) ); ?>"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'domain' ) ? 'disabled' : ''; ?>
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-domain" spellcheck="false"
/>
<p class="desc">
<?php
printf(
/* translators: %s - Domain Name link. */
esc_html__( 'Follow this link to get a Domain Name from Mailgun: %s.', 'wp-mail-smtp' ),
'<a href="https://app.mailgun.com/app/domains" target="_blank" rel="noopener noreferrer">' .
esc_html__( 'Get a Domain Name', 'wp-mail-smtp' ) .
'</a>'
);
?>
</p>
</div>
</div>
<?php
}
}

View File

@@ -0,0 +1,312 @@
<?php
namespace WPMailSMTP\Providers;
use WPMailSMTP\Options;
/**
* Abstract Class ProviderAbstract to contain common providers functionality.
*
* @since 1.0.0
*/
abstract class OptionsAbstract implements OptionsInterface {
/**
* @var string
*/
private $logo_url = '';
/**
* @var string
*/
private $slug = '';
/**
* @var string
*/
private $title = '';
/**
* @var string
*/
private $description = '';
/**
* @var string
*/
private $php = WPMS_PHP_VER;
/**
* @var Options
*/
protected $options;
/**
* ProviderAbstract constructor.
*
* @since 1.0.0
*
* @param array $params
*/
public function __construct( $params ) {
if (
empty( $params['slug'] ) ||
empty( $params['title'] )
) {
return;
}
$this->slug = sanitize_key( $params['slug'] );
$this->title = sanitize_text_field( $params['title'] );
if ( ! empty( $params['description'] ) ) {
$this->description = wp_kses( $params['description'],
array(
'br' => array(),
'a' => array(
'href' => array(),
'rel' => array(),
'target' => array(),
),
)
);
}
if ( ! empty( $params['php'] ) ) {
$this->php = sanitize_text_field( $params['php'] );
}
if ( ! empty( $params['logo_url'] ) ) {
$this->logo_url = esc_url_raw( $params['logo_url'] );
}
$this->options = new Options();
}
/**
* @inheritdoc
*/
public function get_logo_url() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_logo_url', $this->logo_url, $this );
}
/**
* @inheritdoc
*/
public function get_slug() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_slug', $this->slug, $this );
}
/**
* @inheritdoc
*/
public function get_title() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_title', $this->title, $this );
}
/**
* @inheritdoc
*/
public function get_description() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_description', $this->description, $this );
}
/**
* @inheritdoc
*/
public function get_php_version() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_php_version', $this->php, $this );
}
/**
* @inheritdoc
*/
public function display_options() {
?>
<!-- SMTP Host -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-host" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-text wp-mail-smtp-clear">
<div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-host"><?php esc_html_e( 'SMTP Host', 'wp-mail-smtp' ); ?></label>
</div>
<div class="wp-mail-smtp-setting-field">
<input name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][host]" type="text"
value="<?php echo esc_attr( $this->options->get( $this->get_slug(), 'host' ) ); ?>"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'host' ) ? 'disabled' : ''; ?>
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-host" spellcheck="false"
/>
</div>
</div>
<!-- SMTP Port -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-port" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-number wp-mail-smtp-clear">
<div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-port"><?php esc_html_e( 'SMTP Port', 'wp-mail-smtp' ); ?></label>
</div>
<div class="wp-mail-smtp-setting-field">
<input name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][port]" type="number"
value="<?php echo esc_attr( $this->options->get( $this->get_slug(), 'port' ) ); ?>"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'port' ) ? 'disabled' : ''; ?>
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-port" class="small-text" spellcheck="false"
/>
</div>
</div>
<!-- SMTP Encryption -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-encryption" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-radio wp-mail-smtp-clear">
<div class="wp-mail-smtp-setting-label">
<label><?php esc_html_e( 'Encryption', 'wp-mail-smtp' ); ?></label>
</div>
<div class="wp-mail-smtp-setting-field">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-enc-none">
<input type="radio" id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-enc-none"
name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][encryption]" value="none"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'encryption' ) ? 'disabled' : ''; ?>
<?php checked( 'none', $this->options->get( $this->get_slug(), 'encryption' ) ); ?>
/>
<?php esc_html_e( 'None', 'wp-mail-smtp' ); ?>
</label>
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-enc-ssl">
<input type="radio" id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-enc-ssl"
name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][encryption]" value="ssl"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'encryption' ) ? 'disabled' : ''; ?>
<?php checked( 'ssl', $this->options->get( $this->get_slug(), 'encryption' ) ); ?>
/>
<?php esc_html_e( 'SSL', 'wp-mail-smtp' ); ?>
</label>
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-enc-tls">
<input type="radio" id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-enc-tls"
name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][encryption]" value="tls"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'encryption' ) ? 'disabled' : ''; ?>
<?php checked( 'tls', $this->options->get( $this->get_slug(), 'encryption' ) ); ?>
/>
<?php esc_html_e( 'TLS', 'wp-mail-smtp' ); ?>
</label>
<p class="desc">
<?php esc_html_e( 'For most servers TLS is the recommended option. If your SMTP provider offers both SSL and TLS options, we recommend using TLS.', 'wp-mail-smtp' ); ?>
</p>
</div>
</div>
<!-- PHPMailer SMTPAutoTLS -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-autotls" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-checkbox-toggle wp-mail-smtp-clear <?php echo $this->options->is_const_defined( $this->get_slug(), 'encryption' ) || 'tls' === $this->options->get( $this->get_slug(), 'encryption' ) ? 'inactive' : ''; ?>">
<div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-autotls"><?php esc_html_e( 'Auto TLS', 'wp-mail-smtp' ); ?></label>
</div>
<div class="wp-mail-smtp-setting-field">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-autotls">
<input type="checkbox" id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-autotls"
name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][autotls]" value="yes"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'autotls' ) ? 'disabled' : ''; ?>
<?php checked( true, (bool) $this->options->get( $this->get_slug(), 'autotls' ) ); ?>
/>
<span class="wp-mail-smtp-setting-toggle-switch"></span>
<span class="wp-mail-smtp-setting-toggle-checked-label"><?php esc_html_e( 'On', 'wp-mail-smtp' ); ?></span>
<span class="wp-mail-smtp-setting-toggle-unchecked-label"><?php esc_html_e( 'Off', 'wp-mail-smtp' ); ?></span>
</label>
<p class="desc">
<?php esc_html_e( 'By default TLS encryption is automatically used if the server supports it, which is recommended. In some cases, due to server misconfigurations, this can cause issues and may need to be disabled.', 'wp-mail-smtp' ); ?>
</p>
</div>
</div>
<!-- SMTP Authentication -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-auth" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-checkbox-toggle wp-mail-smtp-clear">
<div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-auth"><?php esc_html_e( 'Authentication', 'wp-mail-smtp' ); ?></label>
</div>
<div class="wp-mail-smtp-setting-field">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-auth">
<input type="checkbox" id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-auth"
name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][auth]" value="yes"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'auth' ) ? 'disabled' : ''; ?>
<?php checked( true, (bool) $this->options->get( $this->get_slug(), 'auth' ) ); ?>
/>
<span class="wp-mail-smtp-setting-toggle-switch"></span>
<span class="wp-mail-smtp-setting-toggle-checked-label"><?php esc_html_e( 'On', 'wp-mail-smtp' ); ?></span>
<span class="wp-mail-smtp-setting-toggle-unchecked-label"><?php esc_html_e( 'Off', 'wp-mail-smtp' ); ?></span>
</label>
</div>
</div>
<!-- SMTP Username -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-user" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-text wp-mail-smtp-clear <?php echo ! $this->options->is_const_defined( $this->get_slug(), 'auth' ) && ! $this->options->get( $this->get_slug(), 'auth' ) ? 'inactive' : ''; ?>">
<div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-user"><?php esc_html_e( 'SMTP Username', 'wp-mail-smtp' ); ?></label>
</div>
<div class="wp-mail-smtp-setting-field">
<input name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][user]" type="text"
value="<?php echo esc_attr( $this->options->get( $this->get_slug(), 'user' ) ); ?>"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'user' ) ? 'disabled' : ''; ?>
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-user" spellcheck="false" autocomplete="off"
/>
</div>
</div>
<!-- SMTP Password -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-pass" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-password wp-mail-smtp-clear <?php echo ! $this->options->is_const_defined( $this->get_slug(), 'auth' ) && ! $this->options->get( $this->get_slug(), 'auth' ) ? 'inactive' : ''; ?>">
<div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-pass"><?php esc_html_e( 'SMTP Password', 'wp-mail-smtp' ); ?></label>
</div>
<div class="wp-mail-smtp-setting-field">
<?php if ( $this->options->is_const_defined( $this->get_slug(), 'pass' ) ) : ?>
<input type="text" value="*************" disabled id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-pass"/>
<?php else : ?>
<input name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][pass]" type="password"
value="<?php echo esc_attr( $this->options->get( $this->get_slug(), 'pass' ) ); ?>"
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-pass" spellcheck="false" autocomplete="off"
/>
<p class="desc">
<?php
printf(
/* translators: %s - wp-config.php. */
esc_html__( 'The password is stored in plain text. We highly recommend you setup your password in your WordPress configuration file for improved security; to do this add the lines below to your %s file.', 'wp-mail-smtp' ),
'<code>wp-config.php</code>'
);
?>
</p>
<pre>
define( 'WPMS_ON', true );
define( 'WPMS_SMTP_PASS', 'your_password' );
</pre>
<?php endif; ?>
</div>
</div>
<?php
}
/**
* Check whether we can use this provider based on the PHP version.
* Valid for those, that use SDK.
*
* @return bool
*/
protected function is_php_correct() {
return version_compare( phpversion(), $this->php, '>=' );
}
/**
* Display a helpful message to those users, that are using an outdated version of PHP,
* which is not supported by the currently selected Provider.
*/
protected function display_php_warning() {
?>
<blockquote>
<?php
printf(
/* translators: %1$s - Provider name; %2$s - PHP version required by Provider; %3$s - current PHP version. */
esc_html__( '%1$s requires PHP %2$s to work and does not support your current PHP version %3$s. Please contact your host and request a PHP upgrade to the latest one.', 'wp-mail-smtp' ),
$this->title,
$this->php,
phpversion()
)
?>
<br>
<?php esc_html_e( 'Meanwhile you can switch to the "Other SMTP" Mailer option.', 'wp-mail-smtp' ); ?>
</blockquote>
<?php
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace WPMailSMTP\Providers;
/**
* Interface ProviderInterface, shared between all current and future providers.
* Defines required methods across all providers.
*
* @since 1.0.0
*/
interface OptionsInterface {
/**
* Get the mailer provider slug.
*
* @since 1.0.0
*
* @return string
*/
public function get_slug();
/**
* Get the mailer provider title (or name).
*
* @since 1.0.0
*
* @return string
*/
public function get_title();
/**
* Get the mailer provider description.
*
* @since 1.0.0
*
* @return string
*/
public function get_description();
/**
* Get the mailer provider minimum PHP version.
*
* @since 1.0.0
*
* @return string
*/
public function get_php_version();
/**
* Get the mailer provider logo URL.
*
* @since 1.0.0
*
* @return string
*/
public function get_logo_url();
/**
* Output the mailer provider options.
*
* @since 1.0.0
*/
public function display_options();
}

View File

@@ -0,0 +1,15 @@
<?php
namespace WPMailSMTP\Providers\Pepipost;
use WPMailSMTP\Providers\MailerAbstract;
/**
* Class Mailer inherits everything from parent abstract class.
* This file is required for a proper work of Loader and \ReflectionClass.
*
* @package WPMailSMTP\Providers\Pepipost
*/
class Mailer extends MailerAbstract {
}

View File

@@ -0,0 +1,29 @@
<?php
namespace WPMailSMTP\Providers\Pepipost;
use WPMailSMTP\Providers\OptionsAbstract;
/**
* Class Options.
*
* @since 1.0.0
*/
class Options extends OptionsAbstract {
/**
* Pepipost constructor.
*
* @since 1.0.0
*/
public function __construct() {
parent::__construct(
array(
'logo_url' => wp_mail_smtp()->plugin_url . '/assets/images/pepipost.png',
'slug' => 'pepipost',
'title' => esc_html__( 'Pepipost', 'wp-mail-smtp' ),
)
);
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace WPMailSMTP\Providers\SMTP;
use WPMailSMTP\Providers\MailerAbstract;
/**
* Class Mailer inherits everything from parent abstract class.
* This file is required for a proper work of Loader and \ReflectionClass.
*
* @package WPMailSMTP\Providers\SMTP
*/
class Mailer extends MailerAbstract {
}

View File

@@ -0,0 +1,45 @@
<?php
namespace WPMailSMTP\Providers\SMTP;
use WPMailSMTP\Providers\OptionsAbstract;
/**
* Class SMTP.
*
* @since 1.0.0
*/
class Options extends OptionsAbstract {
/**
* SMTP constructor.
*
* @since 1.0.0
*/
public function __construct() {
parent::__construct(
array(
'logo_url' => wp_mail_smtp()->plugin_url . '/assets/images/smtp.png',
'slug' => 'smtp',
'title' => esc_html__( 'Other SMTP', 'wp-mail-smtp' ),
/* translators: %1$s - opening link tag; %2$s - closing link tag. */
'description' => sprintf(
wp_kses(
__( 'Use the SMTP details provided by your hosting provider or email service.<br><br>To see recommended settings for the popular services as well as troubleshooting tips, check out our %1$sSMTP documentation%2$s.', 'wp-mail-smtp' ),
array(
'br' => array(),
'a' => array(
'href' => array(),
'rel' => array(),
'target' => array(),
),
)
),
'<a href="https://wpforms.com/docs/how-to-set-up-smtp-using-the-wp-mail-smtp-plugin/" target="_blank" rel="noopener noreferrer">',
'</a>'
),
)
);
}
}

View File

@@ -0,0 +1,344 @@
<?php
namespace WPMailSMTP\Providers\Sendgrid;
use WPMailSMTP\Providers\MailerAbstract;
/**
* Class Mailer.
*
* @since 1.0.0
*/
class Mailer extends MailerAbstract {
/**
* Which response code from HTTP provider is considered to be successful?
*
* @var int
*/
protected $email_sent_code = 202;
/**
* URL to make an API request to.
*
* @var string
*/
protected $url = 'https://api.sendgrid.com/v3/mail/send';
/**
* Mailer constructor.
*
* @since 1.0.0
*
* @param \WPMailSMTP\MailCatcher $phpmailer
*/
public function __construct( $phpmailer ) {
// We want to prefill everything from \WPMailSMTP\MailCatcher class, which extends \PHPMailer.
parent::__construct( $phpmailer );
$this->set_header( 'Authorization', 'Bearer ' . $this->options->get( $this->mailer, 'api_key' ) );
$this->set_header( 'content-type', 'application/json' );
}
/**
* Redefine the way email body is returned.
* By default we are sending an array of data.
* SendGrid requires a JSON, so we encode the body.
*
* @since 1.0.0
*/
public function get_body() {
$body = parent::get_body();
return wp_json_encode( $body );
}
/**
* @inheritdoc
*/
public function set_from( $email, $name = '' ) {
if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
return;
}
$from['email'] = $email;
if ( ! empty( $name ) ) {
$from['name'] = $name;
}
$this->set_body_param(
array(
'from' => $from,
)
);
}
/**
* @inheritdoc
*/
public function set_recipients( $recipients ) {
if ( empty( $recipients ) ) {
return;
}
// Allow for now only these recipient types.
$default = array( 'to', 'cc', 'bcc' );
$data = array();
foreach ( $recipients as $type => $emails ) {
if (
! in_array( $type, $default, true ) ||
empty( $emails ) ||
! is_array( $emails )
) {
continue;
}
$data[ $type ] = array();
// Iterate over all emails for each type.
// There might be multiple cc/to/bcc emails.
foreach ( $emails as $email ) {
$holder = array();
$addr = isset( $email[0] ) ? $email[0] : false;
$name = isset( $email[1] ) ? $email[1] : false;
if ( ! filter_var( $addr, FILTER_VALIDATE_EMAIL ) ) {
continue;
}
$holder['email'] = $addr;
if ( ! empty( $name ) ) {
$holder['name'] = $name;
}
array_push( $data[ $type ], $holder );
}
}
if ( ! empty( $data ) ) {
$this->set_body_param(
array(
'personalizations' => array( $data ),
)
);
}
}
/**
* @inheritdoc
*/
public function set_content( $content ) {
if ( empty( $content ) ) {
return;
}
if ( is_array( $content ) ) {
$default = array( 'text', 'html' );
$data = array();
foreach ( $content as $type => $body ) {
if (
! in_array( $type, $default, true ) ||
empty( $body )
) {
continue;
}
$content_type = 'text/plain';
$content_value = $body;
if ( $type === 'html' ) {
$content_type = 'text/html';
}
$data[] = array(
'type' => $content_type,
'value' => $content_value,
);
}
$this->set_body_param(
array(
'content' => $data,
)
);
} else {
$data['type'] = 'text/plain';
$data['value'] = $content;
if ( $this->phpmailer->ContentType === 'text/html' ) {
$data['type'] = 'text/html';
}
$this->set_body_param(
array(
'content' => array( $data ),
)
);
}
}
/**
* SendGrid accepts an array of files content in body, so we will include all files and send.
* Doesn't handle exceeding the limits etc, as this is done and reported be SendGrid API.
*
* @since 1.0.0
*
* @param array $attachments
*/
public function set_attachments( $attachments ) {
if ( empty( $attachments ) ) {
return;
}
$data = array();
foreach ( $attachments as $attachment ) {
$file = false;
/*
* We are not using WP_Filesystem API as we can't reliably work with it.
* It is not always available, same as credentials for FTP.
*/
try {
if ( is_file( $attachment[0] ) && is_readable( $attachment[0] ) ) {
$file = file_get_contents( $attachment[0] );
}
}
catch ( \Exception $e ) {
$file = false;
}
if ( $file === false ) {
continue;
}
$data[] = array(
'content' => base64_encode( $file ),
'type' => $attachment[4],
'filename' => $attachment[1],
'disposition' => $attachment[6],
);
}
if ( ! empty( $data ) ) {
$this->set_body_param(
array(
'attachments' => $data,
)
);
}
}
/**
* @inheritdoc
*/
public function set_reply_to( $reply_to ) {
if ( empty( $reply_to ) ) {
return;
}
$data = array();
foreach ( $reply_to as $key => $emails ) {
if (
empty( $emails ) ||
! is_array( $emails )
) {
continue;
}
$addr = isset( $emails[0] ) ? $emails[0] : false;
$name = isset( $emails[1] ) ? $emails[1] : false;
if ( ! filter_var( $addr, FILTER_VALIDATE_EMAIL ) ) {
continue;
}
$data['email'] = $addr;
if ( ! empty( $name ) ) {
$data['name'] = $name;
}
break;
}
if ( ! empty( $data ) ) {
$this->set_body_param(
array(
'reply_to' => $data,
)
);
}
}
/**
* SendGrid doesn't support sender or return_path params.
* So we do nothing.
*
* @since 1.0.0
*
* @param string $email
*/
public function set_return_path( $email ) {
}
/**
* Get a SendGrid-specific response with a helpful error.
*
* @since 1.2.0
*
* @return string
*/
protected function get_response_error() {
$body = (array) wp_remote_retrieve_body( $this->response );
$error_text = array();
if ( ! empty( $body['errors'] ) ) {
foreach ( $body['errors'] as $error ) {
if ( property_exists( $error, 'message' ) ) {
// Prepare additional information from SendGrid API.
$extra = '';
if ( property_exists( $error, 'field' ) && ! empty( $error->field ) ) {
$extra .= $error->field . '; ';
}
if ( property_exists( $error, 'help' ) && ! empty( $error->help ) ) {
$extra .= $error->help;
}
// Assign both the main message and perhaps extra information, if exists.
$error_text[] = $error->message . ( ! empty( $extra ) ? ' - ' . $extra : '' );
}
}
}
return implode( '<br>', array_map( 'esc_textarea', $error_text ) );
}
/**
* @inheritdoc
*/
public function get_debug_info() {
$mg_text = array();
$options = new \WPMailSMTP\Options();
$mailgun = $options->get_group( 'sendgrid' );
$mg_text[] = '<strong>Api Key:</strong> ' . ( ! empty( $mailgun['api_key'] ) ? 'Yes' : 'No' );
return implode( '<br>', $mg_text );
}
}

View File

@@ -0,0 +1,89 @@
<?php
namespace WPMailSMTP\Providers\Sendgrid;
use WPMailSMTP\Providers\OptionsAbstract;
/**
* Class Option.
*
* @since 1.0.0
*/
class Options extends OptionsAbstract {
/**
* Options constructor.
*
* @since 1.0.0
*/
public function __construct() {
parent::__construct(
array(
'logo_url' => wp_mail_smtp()->plugin_url . '/assets/images/sendgrid.png',
'slug' => 'sendgrid',
'title' => esc_html__( 'SendGrid', 'wp-mail-smtp' ),
'description' => sprintf(
wp_kses(
/* translators: %1$s - opening link tag; %2$s - closing link tag; %3$s - opening link tag; %4$s - closing link tag. */
__( '%1$sSendGrid%2$s is one of the leading transactional email services, sending over 35 billion emails every month. They provide users 100 free emails per month.<br><br>Read our %3$sSendGrid documentation%4$s to learn how to set up SendGrid and improve your email deliverability.', 'wp-mail-smtp' ),
array(
'br' => array(),
'a' => array(
'href' => array(),
'rel' => array(),
'target' => array(),
),
)
),
'<a href="https://sendgrid.com" target="_blank" rel="noopener noreferrer">',
'</a>',
'<a href="https://wpforms.com/fix-wordpress-email-notifications-with-sendgrid/" target="_blank" rel="noopener noreferrer">',
'</a>'
),
)
);
}
/**
* @inheritdoc
*/
public function display_options() {
?>
<!-- API Key -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-api_key" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-text wp-mail-smtp-clear">
<div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-api_key"><?php esc_html_e( 'API Key', 'wp-mail-smtp' ); ?></label>
</div>
<div class="wp-mail-smtp-setting-field">
<input name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][api_key]" type="text"
value="<?php echo esc_attr( $this->options->get( $this->get_slug(), 'api_key' ) ); ?>"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'api_key' ) ? 'disabled' : ''; ?>
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-api_key" spellcheck="false"
/>
<p class="desc">
<?php
printf(
/* translators: %s - API key link. */
esc_html__( 'Follow this link to get an API Key from SendGrid: %s.', 'wp-mail-smtp' ),
'<a href="https://app.sendgrid.com/settings/api_keys" target="_blank" rel="noopener noreferrer">' .
esc_html__( 'Create API Key', 'wp-mail-smtp' ) .
'</a>'
);
?>
<br/>
<?php
printf(
/* translators: %s - SendGrid access level. */
esc_html__( 'To send emails you will need only a %s access level for this API key.', 'wp-mail-smtp' ),
'<code>Mail Send</code>'
);
?>
</p>
</div>
</div>
<?php
}
}