updated plugin WP Mail SMTP
version 2.1.1
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 871 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1 @@
|
||||
<svg aria-hidden="true" data-prefix="fas" data-icon="check-circle" class="svg-inline--fa fa-check-circle fa-w-16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#2ecc71" d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"/></svg>
|
After Width: | Height: | Size: 560 B |
@ -0,0 +1 @@
|
||||
<svg aria-hidden="true" data-prefix="far" data-icon="exclamation-circle" class="svg-inline--fa fa-exclamation-circle fa-w-16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#e74c3c" d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm42-104c0 23.159-18.841 42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42zm-81.37-211.401l6.8 136c.319 6.387 5.591 11.401 11.985 11.401h41.17c6.394 0 11.666-5.014 11.985-11.401l6.8-136c.343-6.854-5.122-12.599-11.985-12.599h-54.77c-6.863 0-12.328 5.745-11.985 12.599z"/></svg>
|
After Width: | Height: | Size: 724 B |
@ -0,0 +1 @@
|
||||
<svg aria-hidden="true" data-prefix="fas" data-icon="exclamation-circle" class="svg-inline--fa fa-exclamation-circle fa-w-16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#f1c40f" d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"/></svg>
|
After Width: | Height: | Size: 598 B |
@ -168,6 +168,7 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || ( function( document, w
|
||||
} );
|
||||
|
||||
app.triggerExitNotice();
|
||||
app.beforeSaveChecks();
|
||||
},
|
||||
|
||||
education: {
|
||||
@ -178,6 +179,7 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || ( function( document, w
|
||||
escapeKey: true,
|
||||
animationBounce: 1,
|
||||
theme: 'modern',
|
||||
type: 'blue',
|
||||
animateFromElement: false,
|
||||
draggable: false,
|
||||
closeIcon: true,
|
||||
@ -263,6 +265,54 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || ( function( document, w
|
||||
$( 'form', $settingPages ).on( 'submit', function() {
|
||||
app.pluginSettingsChanged = false;
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Perform any checks before the settings are saved.
|
||||
*
|
||||
* Checks:
|
||||
* - warn users if they try to save the settings with the default (PHP) mailer selected.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
beforeSaveChecks: function() {
|
||||
|
||||
$( 'form', app.pageHolder ).on( 'submit', function() {
|
||||
if ( $( '.wp-mail-smtp-mailer input:checked', app.pageHolder ).val() === 'mail' ) {
|
||||
var $thisForm = $( this );
|
||||
|
||||
$.alert( {
|
||||
backgroundDismiss: false,
|
||||
escapeKey: false,
|
||||
animationBounce: 1,
|
||||
theme: 'modern',
|
||||
type: 'orange',
|
||||
animateFromElement: false,
|
||||
draggable: false,
|
||||
closeIcon: false,
|
||||
useBootstrap: false,
|
||||
icon: '"></i><img src="' + wp_mail_smtp.plugin_url + '/assets/images/font-awesome/exclamation-circle-solid-orange.svg" style="width: 40px; height: 40px;" alt="' + wp_mail_smtp.default_mailer_notice.icon_alt + '"><i class="',
|
||||
title: wp_mail_smtp.default_mailer_notice.title,
|
||||
content: wp_mail_smtp.default_mailer_notice.content,
|
||||
boxWidth: '550px',
|
||||
buttons: {
|
||||
confirm: {
|
||||
text: wp_mail_smtp.default_mailer_notice.save_button,
|
||||
btnClass: 'btn-confirm',
|
||||
keys: [ 'enter' ],
|
||||
action: function() {
|
||||
$thisForm.off( 'submit' ).submit();
|
||||
}
|
||||
},
|
||||
cancel: {
|
||||
text: wp_mail_smtp.default_mailer_notice.cancel_button,
|
||||
},
|
||||
}
|
||||
} );
|
||||
|
||||
return false;
|
||||
}
|
||||
} );
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -3,7 +3,7 @@ Contributors: wpforms, jaredatch, smub, slaFFik
|
||||
Tags: smtp, wp mail smtp, wordpress smtp, gmail smtp, sendgrid smtp, mailgun smtp, mail, mailer, phpmailer, wp_mail, email, mailgun, sengrid, gmail, pepipost, sendinblue, wp smtp
|
||||
Requires at least: 4.9
|
||||
Tested up to: 5.4
|
||||
Stable tag: 2.0.1
|
||||
Stable tag: 2.1.1
|
||||
Requires PHP: 5.5.0
|
||||
|
||||
The most popular WordPress SMTP and PHP Mailer plugin. Trusted by over 1 million sites.
|
||||
@ -62,7 +62,7 @@ SMTP.com is a recommended transactional email service.
|
||||
|
||||
With over 22 years of email delivery expertise, SMTP.com has been around for almost as long as email itself. They are known among internet providers as one of the most reliable senders on the internet.
|
||||
|
||||
Their easy integration process lets you start sending emails in minutes and benefit from years of experience. SMTP.com provides users 10,000 free emails the first 30 days.
|
||||
Their easy integration process lets you start sending emails in minutes and benefit from years of experience. SMTP.com provides users 50,000 free emails the first 30 days.
|
||||
|
||||
Read our <a href="https://wpmailsmtp.com/docs/how-to-set-up-the-smtp-com-mailer-in-wp-mail-smtp" rel="friend">SMTP.com documentation</a> for more details.
|
||||
|
||||
@ -229,6 +229,24 @@ By all means please contact us to discuss features or options you'd like to see
|
||||
|
||||
== Changelog ==
|
||||
|
||||
= 2.1.1 - 2020-06-08 =
|
||||
* Changed: Remove current automatic default reply-to address and add WP filter `wp_mail_smtp_processor_set_default_reply_to` for setting default reply-to addresses.
|
||||
* Changed: Improve description for several options with links to an article about how to properly use constants.
|
||||
* Fixed: PHP parse error connected to Monolog library on PHP versions < 7.x.
|
||||
|
||||
= 2.1.0 - 2020-06-04 =
|
||||
* Added: Async/scheduled tasks management support.
|
||||
* Added: New warning notification for selecting the "Default (none)" mailer and saving the plugin settings.
|
||||
* Changed: Set the original From Email as Reply-To address if it was overwritten by the Force From Email option.
|
||||
* Changed: The Force From Email option is now enabled by default, for new plugin installs.
|
||||
* Changed: Reply-To header is now set when not provided, equals to From Name/Email.
|
||||
* Fixed: Display a non-empty PHPMailer error when some non-SMTP mailers generate errors.
|
||||
* Fixed: Display a more accurate message, when the "channel - not found" error is triggered by SMTP.com API.
|
||||
* Fixed: Save and display debug errors for the "Other SMTP" mailer.
|
||||
* Fixed: Improve the debug details for the "Invalid address (setFrom)" error in the Email Test tab.
|
||||
* Fixed: Improve the debug details for SMTP CA verification fail, Gmail Guzzle requirements, and Gmail invalid grant errors.
|
||||
* Fixed: Improve the uninstall cleanup procedure.
|
||||
|
||||
= 2.0.1 - 2020-05-07 =
|
||||
* Changed: Improved description of the "Do Not Send" plugin option.
|
||||
* Fixed: Due to Pepipost API changes we now convert new lines so they are preserved in plain text emails.
|
||||
|
@ -13,20 +13,26 @@ use WPMailSMTP\Options;
|
||||
class Area {
|
||||
|
||||
/**
|
||||
* Slug of the admin area page.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @var string Slug of the admin area page.
|
||||
* @var string
|
||||
*/
|
||||
const SLUG = 'wp-mail-smtp';
|
||||
|
||||
/**
|
||||
* Admin page unique hook.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @var string Admin page unique hook.
|
||||
* @var string
|
||||
*/
|
||||
public $hook;
|
||||
|
||||
/**
|
||||
* List of admin area pages.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @var PageAbstract[]
|
||||
@ -34,11 +40,13 @@ class Area {
|
||||
private $pages;
|
||||
|
||||
/**
|
||||
* List of official registered pages.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*
|
||||
* @var array List of official registered pages.
|
||||
* @var array
|
||||
*/
|
||||
public static $pages_registered = array( 'general', 'logs', 'about' );
|
||||
public static $pages_registered = [ 'general', 'logs', 'about' ];
|
||||
|
||||
/**
|
||||
* Area constructor.
|
||||
@ -46,6 +54,7 @@ class Area {
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
$this->hooks();
|
||||
}
|
||||
|
||||
@ -57,34 +66,39 @@ class Area {
|
||||
protected function hooks() {
|
||||
|
||||
// Add the Settings link to a plugin on Plugins page.
|
||||
add_filter( 'plugin_action_links_' . plugin_basename( WPMS_PLUGIN_FILE ), array( $this, 'add_plugin_action_link' ), 10, 1 );
|
||||
add_filter( 'plugin_action_links_' . plugin_basename( WPMS_PLUGIN_FILE ), [ $this, 'add_plugin_action_link' ], 10, 1 );
|
||||
|
||||
// Add the options page.
|
||||
add_action( 'admin_menu', array( $this, 'add_admin_options_page' ) );
|
||||
add_action( 'admin_menu', [ $this, 'add_admin_options_page' ] );
|
||||
|
||||
// Register on load Email Log admin menu hook.
|
||||
add_action( 'load-wp-mail-smtp_page_wp-mail-smtp-logs', [ $this, 'maybe_redirect_email_log_menu_to_email_log_settings_tab' ] );
|
||||
|
||||
// Admin footer text.
|
||||
add_filter( 'admin_footer_text', array( $this, 'get_admin_footer' ), 1, 2 );
|
||||
add_filter( 'admin_footer_text', [ $this, 'get_admin_footer' ], 1, 2 );
|
||||
|
||||
// Enqueue admin area scripts and styles.
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
|
||||
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
|
||||
|
||||
// Process the admin page forms actions.
|
||||
add_action( 'admin_init', array( $this, 'process_actions' ) );
|
||||
add_action( 'admin_init', [ $this, 'process_actions' ] );
|
||||
|
||||
// Display custom notices based on the error/success codes.
|
||||
add_action( 'admin_init', array( $this, 'display_custom_auth_notices' ) );
|
||||
add_action( 'admin_init', [ $this, 'display_custom_auth_notices' ] );
|
||||
|
||||
// Display notice instructing the user to complete plugin setup.
|
||||
add_action( 'admin_init', array( $this, 'display_setup_notice' ) );
|
||||
add_action( 'admin_init', [ $this, 'display_setup_notice' ] );
|
||||
|
||||
// Outputs the plugin admin header.
|
||||
add_action( 'in_admin_header', array( $this, 'display_admin_header' ), 100 );
|
||||
add_action( 'in_admin_header', [ $this, 'display_admin_header' ], 100 );
|
||||
|
||||
// Hide all unrelated to the plugin notices on the plugin admin pages.
|
||||
add_action( 'admin_print_scripts', array( $this, 'hide_unrelated_notices' ) );
|
||||
add_action( 'admin_print_scripts', [ $this, 'hide_unrelated_notices' ] );
|
||||
|
||||
// Process all AJAX requests.
|
||||
add_action( 'wp_ajax_wp_mail_smtp_ajax', array( $this, 'process_ajax' ) );
|
||||
add_action( 'wp_ajax_wp_mail_smtp_ajax', [ $this, 'process_ajax' ] );
|
||||
|
||||
( new Review() )->hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,8 +121,7 @@ class Area {
|
||||
|
||||
switch ( $error ) {
|
||||
case 'google_access_denied':
|
||||
WP::add_admin_notice(
|
||||
/* translators: %s - error code, returned by Google API. */
|
||||
WP::add_admin_notice( /* translators: %s - error code, returned by Google API. */
|
||||
sprintf( esc_html__( 'There was an error while processing the authentication request: %s. Please try again.', 'wp-mail-smtp' ), '<code>' . $error . '</code>' ),
|
||||
WP::ADMIN_NOTICE_ERROR
|
||||
);
|
||||
@ -169,15 +182,14 @@ class Area {
|
||||
// Display notice informing user further action is needed.
|
||||
WP::add_admin_notice(
|
||||
sprintf(
|
||||
wp_kses(
|
||||
/* translators: %s - Mailer anchor link. */
|
||||
wp_kses( /* translators: %s - Mailer anchor link. */
|
||||
__( 'Thanks for using WP Mail SMTP! To complete the plugin setup and start sending emails, <strong>please select and configure your <a href="%s">Mailer</a></strong>.', 'wp-mail-smtp' ),
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
),
|
||||
'strong' => array(),
|
||||
)
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
],
|
||||
'strong' => [],
|
||||
]
|
||||
),
|
||||
wp_mail_smtp()->get_admin()->get_admin_page_url( self::SLUG . '#wp-mail-smtp-setting-row-mailer' )
|
||||
),
|
||||
@ -232,6 +244,26 @@ class Area {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect the "Email Log" WP menu link to the "Email Log" setting tab for lite version of the plugin.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public function maybe_redirect_email_log_menu_to_email_log_settings_tab() {
|
||||
|
||||
/**
|
||||
* The Email Logs object to be used for loading the Email Log page.
|
||||
*
|
||||
* @var \WPMailSMTP\Admin\PageAbstract $logs
|
||||
*/
|
||||
$logs = $this->generate_display_logs_object();
|
||||
|
||||
if ( $logs instanceof \WPMailSMTP\Admin\Pages\Logs ) {
|
||||
wp_safe_redirect( $logs->get_link() );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue admin area scripts and styles.
|
||||
*
|
||||
@ -269,6 +301,19 @@ class Area {
|
||||
array(
|
||||
'text_provider_remove' => esc_html__( 'Are you sure you want to reset the current provider connection? You will need to immediately create a new one to be able to send emails.', 'wp-mail-smtp' ),
|
||||
'text_settings_not_saved' => esc_html__( 'Changes that you made to the settings are not saved!', 'wp-mail-smtp' ),
|
||||
'default_mailer_notice' => array(
|
||||
'title' => esc_html__( 'Heads up!', 'wp-mail-smtp' ),
|
||||
'content' => wp_kses(
|
||||
__( '<p>The Default (PHP) mailer is currently selected, but is not recommended because in most cases it does not resolve email delivery issues.</p><p>Please consider selecting and configuring one of the other mailers.</p>', 'wp-mail-smtp' ),
|
||||
array(
|
||||
'p' => true,
|
||||
)
|
||||
),
|
||||
'save_button' => esc_html__( 'Save Settings', 'wp-mail-smtp' ),
|
||||
'cancel_button' => esc_html__( 'Cancel', 'wp-mail-smtp' ),
|
||||
'icon_alt' => esc_html__( 'Warning icon', 'wp-mail-smtp' ),
|
||||
),
|
||||
'plugin_url' => wp_mail_smtp()->plugin_url,
|
||||
'education' => array(
|
||||
'upgrade_icon_lock' => '<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="lock" class="svg-inline--fa fa-lock fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zm-104 0H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z"></path></svg>',
|
||||
'upgrade_title' => esc_html__( '%name% is a PRO Feature', 'wp-mail-smtp' ),
|
||||
@ -469,9 +514,12 @@ class Area {
|
||||
break;
|
||||
|
||||
case self::SLUG . '-logs':
|
||||
$logs_class = apply_filters( 'wp_mail_smtp_admin_display_get_logs_fqcn', '\WPMailSMTP\Admin\Pages\Logs' );
|
||||
/** @var \WPMailSMTP\Admin\PageAbstract $logs */
|
||||
$logs = new $logs_class();
|
||||
/**
|
||||
* The Email Logs object to be used for loading the Email Log page.
|
||||
*
|
||||
* @var \WPMailSMTP\Admin\PageAbstract $logs
|
||||
*/
|
||||
$logs = $this->generate_display_logs_object();
|
||||
|
||||
$is_archive = wp_mail_smtp()->is_pro() && wp_mail_smtp()->pro->get_logs()->is_archive();
|
||||
?>
|
||||
@ -500,6 +548,20 @@ class Area {
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the appropriate Email Log page object used for displaying the Email Log page.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @return \WPMailSMTP\Admin\PageAbstract
|
||||
*/
|
||||
public function generate_display_logs_object() {
|
||||
|
||||
$logs_class = apply_filters( 'wp_mail_smtp_admin_display_get_logs_fqcn', \WPMailSMTP\Admin\Pages\Logs::class );
|
||||
|
||||
return new $logs_class();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display General page tabs.
|
||||
*
|
||||
|
@ -36,43 +36,56 @@ class ControlTab extends PageAbstract {
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @since 2.1.0 Replaced images with SVGs.
|
||||
*/
|
||||
public function display() {
|
||||
|
||||
$features = array(
|
||||
array(
|
||||
'image' => 'comments.png',
|
||||
$features = [
|
||||
[
|
||||
'svg' => '<svg xmlns="http://www.w3.org/2000/svg" focusable="false" viewBox="0 0 64 64"><path class="st0" d="M39.1,35.5H18l-9.2,6.9c-0.5,0.4-1.2,0.3-1.5-0.2c-0.1-0.2-0.2-0.4-0.2-0.6v-6c-3.9,0-7.1-3.2-7.1-7.1V10.7c0-3.9,3.2-7.1,7.1-7.1h32c3.9,0,7.1,3.2,7.1,7.1v17.8C46.2,32.4,43,35.5,39.1,35.5C39.1,35.5,39.1,35.5,39.1,35.5z"/><path class="st1" d="M64,28.4v17.8c0,3.9-3.2,7.1-7.1,7.1h-3.6v6c0,0.6-0.5,1.1-1.1,1.1c-0.2,0-0.5-0.1-0.6-0.2l-9.2-6.9h-14c-3.9,0-7.1-3.2-7.1-7.1v-7.1h17.8c5.9,0,10.7-4.8,10.7-10.7v-7.1h7.1C60.8,21.3,64,24.5,64,28.4z"/></svg>',
|
||||
'title' => esc_html__( 'Comment Notifications', 'wp-mail-smtp' ),
|
||||
'desc' => esc_html__( 'Manage emails sent when comments are published or awaiting moderation.', 'wp-mail-smtp' ),
|
||||
),
|
||||
array(
|
||||
'image' => 'admin.png',
|
||||
],
|
||||
[
|
||||
'svg' => '<svg xmlns="http://www.w3.org/2000/svg" focusable="false" viewBox="0 0 64 64"><path class="st0" d="M63.6 45.2l-2.6-1.5c0.3-1.4 0.3-2.9 0-4.3l2.6-1.5c0.3-0.2 0.4-0.5 0.3-0.9 -0.7-2.1-1.8-4.1-3.3-5.7 -0.2-0.3-0.6-0.3-0.9-0.1l-2.6 1.5c-1.1-0.9-2.3-1.7-3.7-2.1v-3c0-0.3-0.2-0.6-0.6-0.7 -2.2-0.5-4.4-0.5-6.6 0 -0.3 0.1-0.6 0.4-0.6 0.7v3c-1.4 0.5-2.6 1.2-3.7 2.1l-2.6-1.5c-0.3-0.2-0.7-0.1-0.9 0.1C37 33 35.9 35 35.2 37.1c-0.1 0.3 0 0.7 0.3 0.9l2.6 1.5c-0.3 1.4-0.3 2.9 0 4.3l-2.6 1.5c-0.3 0.2-0.4 0.5-0.3 0.9 0.7 2.1 1.8 4.1 3.3 5.7 0.2 0.3 0.6 0.3 0.9 0.1l2.6-1.5c1.1 0.9 2.3 1.7 3.7 2.1v3c0 0.3 0.2 0.6 0.6 0.7 2.2 0.5 4.4 0.5 6.6 0 0.3-0.1 0.6-0.4 0.6-0.7v-3c1.4-0.5 2.6-1.2 3.7-2.1l2.6 1.5c0.3 0.2 0.7 0.1 0.9-0.1 1.5-1.6 2.7-3.6 3.3-5.7C64.1 45.7 63.9 45.4 63.6 45.2zM49.6 46.5c-2.7 0-4.9-2.2-4.9-4.9s2.2-4.9 4.9-4.9c2.7 0 4.9 2.2 4.9 4.9S52.3 46.5 49.6 46.5z"/><path class="st1" d="M42.5 55.6v-0.9c-0.2-0.1-0.5-0.3-0.7-0.4l-0.8 0.5c-1.6 0.9-3.6 0.6-4.9-0.7 -1.8-2-3.2-4.4-4-7 -0.6-1.8 0.2-3.7 1.8-4.6l0.8-0.5c0-0.3 0-0.5 0-0.8L34 40.8c-1.6-0.9-2.3-2.8-1.8-4.6 0.1-0.3 0.2-0.6 0.3-0.9 -0.4 0-0.8-0.1-1.1-0.1h-1.7c-4.6 2.1-10 2.1-14.6 0h-1.7C6 35.2 0 41.2 0 48.6v4.2c0 2.7 2.2 4.8 4.8 4.8l0 0H40c1 0 1.9-0.3 2.7-0.9C42.6 56.4 42.5 56 42.5 55.6zM22.4 32c7.1 0 12.8-5.7 12.8-12.8S29.5 6.4 22.4 6.4 9.6 12.1 9.6 19.2 15.3 32 22.4 32z"/></svg>',
|
||||
'title' => esc_html__( 'Site Admin Email Change Notifications', 'wp-mail-smtp' ),
|
||||
'desc' => esc_html__( 'Manage emails sent when site admin\'s account has been changed.', 'wp-mail-smtp' ),
|
||||
),
|
||||
array(
|
||||
'image' => 'users.png',
|
||||
],
|
||||
[
|
||||
'svg' => '<svg xmlns="http://www.w3.org/2000/svg" focusable="false" viewBox="0 0 64 64"><path class="st0" d="M9.6 28.8c3.5 0 6.4-2.9 6.4-6.4S13.1 16 9.6 16s-6.4 2.9-6.4 6.4S6.1 28.8 9.6 28.8zM57.6 32h-6.4c-1.7 0-3.3 0.7-4.5 1.9 4.1 2.2 6.9 6.3 7.5 10.9h6.6c1.8 0 3.2-1.4 3.2-3.2v-3.2C64 34.9 61.1 32 57.6 32zM6.4 32C2.9 32 0 34.9 0 38.4v3.2c0 1.8 1.4 3.2 3.2 3.2h6.6c0.6-4.6 3.4-8.7 7.5-10.9 -1.2-1.2-2.8-1.9-4.5-1.9H6.4zM54.4 28.8c3.5 0 6.4-2.9 6.4-6.4S57.9 16 54.4 16 48 18.9 48 22.4 50.9 28.8 54.4 28.8z"/><path class="st1" d="M39.7 35.2h-0.8c-2.1 1-4.5 1.6-6.8 1.6 -2.5 0-4.8-0.6-6.9-1.6h-0.8c-6.4 0-11.5 5.2-11.5 11.5v2.9c0 2.7 2.1 4.8 4.8 4.8h28.8c2.6 0 4.8-2.2 4.8-4.8v-2.9C51.2 40.4 46 35.2 39.7 35.2zM32 32c6.2 0 11.2-5 11.2-11.2S38.2 9.6 32 9.6s-11.2 5-11.2 11.2C20.8 27 25.8 32 32 32L32 32z"/></svg>',
|
||||
'title' => esc_html__( 'User Change Notifications', 'wp-mail-smtp' ),
|
||||
'desc' => esc_html__( 'Limit emails triggered by password changed/reset, email changed, and more.', 'wp-mail-smtp' ),
|
||||
),
|
||||
array(
|
||||
'image' => 'personal.png',
|
||||
],
|
||||
[
|
||||
'svg' => '<svg xmlns="http://www.w3.org/2000/svg" focusable="false" viewBox="0 0 64 64"><path class="st0" d="M35.9 52.6L32 60l-3.9-7.4L30 44l-2.2-4.5c2.8 0.6 5.7 0.6 8.5 0L34 44 35.9 52.6zM32 35.9c8.8 0 16-7.1 16-15.9 -0.9 0.2-1.9 0.4-3 0.5v0.8c0 0-0.8 0.4-0.9 0.8 -0.5 1.6-1 3.3-2.2 4.5 -1.4 1.3-6.5 3-8.7-3.4 -0.4-1.1-2.1-1.1-2.5 0 -2.3 6.8-7.6 4.4-8.7 3.4 -1.3-1.2-1.7-2.9-2.2-4.5 -0.1-0.3-0.9-0.8-0.9-0.8v-0.8c-1.1-0.2-2.1-0.3-3-0.5C16 28.8 23.2 35.9 32 35.9z"/><path class="st1" d="M19 20.5v0.8c0 0 0.8 0.5 0.9 0.8 0.5 1.6 1 3.3 2.2 4.5 1.1 1 6.4 3.4 8.7-3.4 0.4-1.1 2.1-1.1 2.5 0 2.2 6.4 7.3 4.7 8.7 3.4 1.3-1.2 1.7-2.9 2.2-4.5 0.1-0.4 0.9-0.8 0.9-0.8v-0.8c6.6-1 11-2.7 11-4.6 0-1.7-3.4-3.3-8.8-4.3 -1.2-4-3.3-8-5-10.1C41 0 39-0.4 37.2 0.4l-3.5 1.7c-1.1 0.6-2.5 0.6-3.6 0l-3.5-1.7C25-0.4 23 0 21.8 1.5c-1.7 2.1-3.8 6.1-5 10.1 -5.4 1-8.8 2.5-8.8 4.3C8 17.8 12.3 19.6 19 20.5zM52 38.5l3-7.8c0.4-1-0.1-2.2-1.2-2.6 -0.2-0.1-0.5-0.1-0.7-0.1h-4L32 60 14.9 27.9H11c-1.1 0-2 0.9-2 2 0 0.3 0.1 0.5 0.2 0.8l3.2 7.5c-5.2 3-8.4 8.5-8.4 14.5V58c0 3.3 2.7 6 6 6l0 0H54c3.3 0 6-2.7 6-6l0 0v-5.2C60.1 46.9 57 41.5 52 38.5L52 38.5z"/></svg>',
|
||||
'title' => esc_html__( 'Personal Data Requests Notifications', 'wp-mail-smtp' ),
|
||||
'desc' => esc_html__( 'Control emails for data requests and data removal actions.', 'wp-mail-smtp' ),
|
||||
),
|
||||
array(
|
||||
'image' => 'update.png',
|
||||
],
|
||||
[
|
||||
'svg' => '<svg xmlns="http://www.w3.org/2000/svg" focusable="false" viewBox="0 0 64 64"><path class="st0" d="M0 57.6V40.3c0-1.7 1.4-3.1 3.1-3.1h17.3c2.8 0 4.1 3.3 2.2 5.3l-5.4 5.4c4 3.8 9.3 5.9 14.8 5.8 10 0 18.6-6.9 21-16.4 0.2-0.7 0.8-1.2 1.5-1.2h7.4c0.9 0 1.5 0.7 1.5 1.5 0 0.1 0 0.2 0 0.3C60.7 52.8 47.6 64 32 64c-8.2 0-16.2-3.2-22.1-8.9l-4.6 4.6C3.3 61.7 0 60.3 0 57.6z"/><path class="st1" d="M0.6 26C3.3 11.2 16.4 0 32 0c8.2 0 16.2 3.2 22.1 8.9l4.6-4.6C60.7 2.3 64 3.7 64 6.5v17.3c0 1.7-1.4 3.1-3.1 3.1H43.6c-2.8 0-4.1-3.3-2.2-5.3l5.4-5.4c-4-3.8-9.3-5.9-14.8-5.8 -10 0-18.6 6.9-21 16.4 -0.2 0.7-0.8 1.2-1.5 1.2H2.1c-0.9 0-1.5-0.7-1.5-1.5C0.5 26.2 0.5 26.1 0.6 26z"/></svg>',
|
||||
'title' => esc_html__( 'Automatic Update Notifications', 'wp-mail-smtp' ),
|
||||
'desc' => esc_html__( 'Manage emails sent by the core automatic update process.', 'wp-mail-smtp' ),
|
||||
),
|
||||
array(
|
||||
'image' => 'user_new.png',
|
||||
],
|
||||
[
|
||||
'svg' => '<svg xmlns="http://www.w3.org/2000/svg" focusable="false" viewBox="0 0 64 64"><path class="st0" d="M64 28.8V32c0 0.9-0.7 1.6-1.6 1.6H56V40c0 0.9-0.7 1.6-1.6 1.6h-3.2c-0.9 0-1.6-0.7-1.6-1.6v-6.4h-6.4c-0.9 0-1.6-0.7-1.6-1.6v-3.2c0-0.9 0.7-1.6 1.6-1.6h6.4v-6.4c0-0.9 0.7-1.6 1.6-1.6h3.2c0.9 0 1.6 0.7 1.6 1.6v6.4h6.4C63.3 27.2 64 27.9 64 28.8z"/><path class="st1" d="M22.4 32c7.1 0 12.8-5.7 12.8-12.8S29.5 6.4 22.4 6.4 9.6 12.1 9.6 19.2 15.3 32 22.4 32zM31.4 35.2h-1.7c-4.6 2.1-9.9 2.1-14.6 0h-1.7C6 35.2 0 41.2 0 48.6v4.2c0 2.7 2.2 4.8 4.8 4.8l0 0H40c2.7 0 4.8-2.1 4.8-4.8l0 0v-4.2C44.8 41.2 38.8 35.2 31.4 35.2z"/></svg>',
|
||||
'title' => esc_html__( 'New User Notifications', 'wp-mail-smtp' ),
|
||||
'desc' => esc_html__( 'Toggle emails sent to both user and site administrator about new user accounts.', 'wp-mail-smtp' ),
|
||||
),
|
||||
],
|
||||
];
|
||||
|
||||
)
|
||||
$allowed_svg_html = [
|
||||
'svg' => [
|
||||
'xmlns' => [],
|
||||
'focusable' => [],
|
||||
'viewbox' => [],
|
||||
],
|
||||
'path' => [
|
||||
'class' => [],
|
||||
'd' => [],
|
||||
],
|
||||
];
|
||||
?>
|
||||
|
||||
<div class="wp-mail-smtp-page-upsell">
|
||||
@ -88,7 +101,7 @@ class ControlTab extends PageAbstract {
|
||||
<?php foreach ( $features as $feature ) : ?>
|
||||
<div class="wp-mail-smtp-page-upsell-feature">
|
||||
<div class="wp-mail-smtp-page-upsell-feature-image">
|
||||
<img src="<?php echo esc_url( wp_mail_smtp()->assets_url . '/images/control/' . $feature['image'] ); ?>" alt="">
|
||||
<?php echo wp_kses( $feature['svg'], $allowed_svg_html ); ?>
|
||||
</div>
|
||||
<div class="wp-mail-smtp-page-upsell-feature-content">
|
||||
<h4><?php echo esc_html( $feature['title'] ); ?></h4>
|
||||
|
@ -7,13 +7,17 @@ use WPMailSMTP\Admin\PageAbstract;
|
||||
|
||||
/**
|
||||
* Class Logs
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
class Logs extends PageAbstract {
|
||||
|
||||
/**
|
||||
* Slug of a page.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*
|
||||
* @var string Slug of a page.
|
||||
* @var string
|
||||
*/
|
||||
protected $slug = 'logs';
|
||||
|
||||
@ -21,65 +25,45 @@ class Logs extends PageAbstract {
|
||||
* Get the page/tab link.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @since 2.1.0 Changed the URL to point to the email log settings tab.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_link() {
|
||||
|
||||
return add_query_arg(
|
||||
'page',
|
||||
Area::SLUG . '-' . $this->slug,
|
||||
admin_url( 'admin.php' )
|
||||
'tab',
|
||||
$this->slug,
|
||||
admin_url( 'admin.php?page=' . Area::SLUG )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* Link label of a tab.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_label() {
|
||||
return esc_html__( 'Email Log', 'wp-mail-smtp' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* Title of a tab.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_title() {
|
||||
return $this->get_label();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* Tab content.
|
||||
*
|
||||
* @since 2.1.0 Moved the display content to the email log settings tab.
|
||||
*/
|
||||
public function display() {
|
||||
?>
|
||||
|
||||
<div class="wp-mail-smtp-page-title">
|
||||
<h1 class="page-title">
|
||||
<?php echo esc_html( $this->get_label() ); ?>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="wp-mail-smtp-page-upsell">
|
||||
<h2><?php esc_html_e( 'Unlock Email Logging', 'wp-mail-smtp' ); ?></h2>
|
||||
|
||||
<h3>
|
||||
<?php esc_html_e( 'Keep track of every email sent from your WordPress site with email logging.
', 'wp-mail-smtp' ); ?><br>
|
||||
<?php esc_html_e( 'Troubleshoot sending issues, recover lost emails, and more!', 'wp-mail-smtp' ); ?>
|
||||
</h3>
|
||||
|
||||
<div class="wp-mail-smtp-page-upsell-images">
|
||||
<img src="<?php echo esc_url( wp_mail_smtp()->assets_url . '/images/logs/archive.png' ); ?>" alt="<?php esc_attr_e( 'Logs Archive Page Screenshot', 'wp-mail-smtp' ); ?>">
|
||||
<img src="<?php echo esc_url( wp_mail_smtp()->assets_url . '/images/logs/single.png' ); ?>" alt="<?php esc_attr_e( 'Logs Single Page Screenshot', 'wp-mail-smtp' ); ?>">
|
||||
</div>
|
||||
|
||||
<div class="wp-mail-smtp-page-upsell-button">
|
||||
<a href="https://wpmailsmtp.com/lite-upgrade/?discount=LITEUPGRADE&utm_source=WordPress&utm_medium=logs&utm_campaign=liteplugin" class="wp-mail-smtp-btn wp-mail-smtp-btn-lg wp-mail-smtp-btn-orange wp-mail-smtp-upgrade-modal" target="_blank" rel="noopener noreferrer">
|
||||
<?php esc_html_e( 'Upgrade to WP Mail SMTP Pro', 'wp-mail-smtp' ); ?>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
public function display() {}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace WPMailSMTP\Admin\Pages;
|
||||
|
||||
use WPMailSMTP\Admin\Area;
|
||||
use WPMailSMTP\Admin\PageAbstract;
|
||||
|
||||
/**
|
||||
@ -42,23 +41,36 @@ class LogsTab extends PageAbstract {
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom URL for this tab, redirects to Email Log page.
|
||||
*
|
||||
* @since 1.6.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_link() {
|
||||
|
||||
return wp_mail_smtp()->get_admin()->get_admin_page_url( Area::SLUG . '-' . $this->slug );
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used as we are simply redirecting users.
|
||||
* Display the upsell content for the Email Log feature.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @since 2.1.0 Moved the display content from the email log page (WP admin menu "Email Log" page).
|
||||
*/
|
||||
public function display() {
|
||||
?>
|
||||
|
||||
<div class="wp-mail-smtp-page-upsell">
|
||||
<h2><?php esc_html_e( 'Unlock Email Logging', 'wp-mail-smtp' ); ?></h2>
|
||||
|
||||
<h3>
|
||||
<?php esc_html_e( 'Keep track of every email sent from your WordPress site with email logging.
', 'wp-mail-smtp' ); ?><br>
|
||||
<?php esc_html_e( 'Troubleshoot sending issues, recover lost emails, and more!', 'wp-mail-smtp' ); ?>
|
||||
</h3>
|
||||
|
||||
<div class="wp-mail-smtp-page-upsell-images">
|
||||
<img src="<?php echo esc_url( wp_mail_smtp()->assets_url . '/images/logs/archive.png' ); ?>" alt="<?php esc_attr_e( 'Logs Archive Page Screenshot', 'wp-mail-smtp' ); ?>">
|
||||
<img src="<?php echo esc_url( wp_mail_smtp()->assets_url . '/images/logs/single.png' ); ?>" alt="<?php esc_attr_e( 'Logs Single Page Screenshot', 'wp-mail-smtp' ); ?>">
|
||||
</div>
|
||||
|
||||
<div class="wp-mail-smtp-page-upsell-button">
|
||||
<a href="https://wpmailsmtp.com/lite-upgrade/?discount=LITEUPGRADE&utm_source=WordPress&utm_medium=logs&utm_campaign=liteplugin" class="wp-mail-smtp-btn wp-mail-smtp-btn-lg wp-mail-smtp-btn-orange wp-mail-smtp-upgrade-modal" target="_blank" rel="noopener noreferrer">
|
||||
<?php esc_html_e( 'Upgrade to WP Mail SMTP Pro', 'wp-mail-smtp' ); ?>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,19 +88,22 @@ class MiscTab extends PageAbstract {
|
||||
'<code>wp-config.php</code>'
|
||||
);
|
||||
} else {
|
||||
printf( /* translators: %s - file to put that constant in. */
|
||||
esc_html__( 'If you want to enable this option using constants, put the lines below to your %s file:', 'wp-mail-smtp' ),
|
||||
'<code>wp-config.php</code>'
|
||||
printf(
|
||||
wp_kses( /* translators: %s - The URL to the constants support article. */
|
||||
__( 'Please read this <a href="%s" target="_blank" rel="noopener noreferrer">support article</a> if you want to enable this option using constants.', 'wp-mail-smtp' ),
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
'rel' => [],
|
||||
],
|
||||
]
|
||||
),
|
||||
'https://wpmailsmtp.com/docs/how-to-secure-smtp-settings-by-using-constants/'
|
||||
);
|
||||
}
|
||||
?>
|
||||
</p>
|
||||
<?php if ( ! $options->is_const_defined( 'general', 'do_not_send' ) ) : ?>
|
||||
<pre>
|
||||
define( 'WPMS_ON', true );
|
||||
define( 'WPMS_DO_NOT_SEND', true );
|
||||
</pre>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -98,12 +98,12 @@ class TestTab extends PageAbstract {
|
||||
$disabled = '';
|
||||
$help_text = '';
|
||||
|
||||
if (
|
||||
! wp_mail_smtp()->get_providers()->get_mailer(
|
||||
$mailer = wp_mail_smtp()->get_providers()->get_mailer(
|
||||
Options::init()->get( 'mail', 'mailer' ),
|
||||
wp_mail_smtp()->get_processor()->get_phpmailer()
|
||||
)->is_mailer_complete()
|
||||
) {
|
||||
);
|
||||
|
||||
if ( ! $mailer || ! $mailer->is_mailer_complete() ) {
|
||||
$btn = 'wp-mail-smtp-btn-red';
|
||||
$disabled = 'disabled';
|
||||
|
||||
@ -435,6 +435,18 @@ Lead Developer, WP Mail SMTP';
|
||||
$mailer_text .= $mailer->get_debug_info();
|
||||
}
|
||||
|
||||
$phpmailer_error = $phpmailer->ErrorInfo; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||
|
||||
// Append any PHPMailer errors to the mailer debug (except SMTP mailer, which has the full error output below).
|
||||
if (
|
||||
! empty( $phpmailer_error ) &&
|
||||
! $options->is_mailer_smtp()
|
||||
) {
|
||||
$mailer_text .= '<br><br><strong>PHPMailer Debug:</strong><br>' .
|
||||
wp_strip_all_tags( $phpmailer_error ) .
|
||||
'<br>';
|
||||
}
|
||||
|
||||
/*
|
||||
* General Debug.
|
||||
*/
|
||||
@ -486,137 +498,163 @@ Lead Developer, WP Mail SMTP';
|
||||
$smtp_port = $options->get( 'smtp', 'port' );
|
||||
$smtp_encryption = $options->get( 'smtp', 'encryption' );
|
||||
|
||||
$details = array(
|
||||
$details = [
|
||||
// [any] - cURL error 60/77.
|
||||
array(
|
||||
[
|
||||
'mailer' => 'any',
|
||||
'errors' => array(
|
||||
array( 'cURL error 60' ),
|
||||
array( 'cURL error 77' ),
|
||||
),
|
||||
'description' => array(
|
||||
'errors' => [
|
||||
[ 'cURL error 60' ],
|
||||
[ 'cURL error 77' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'SSL certificate issue.', 'wp-mail-smtp' ) . '</strong>',
|
||||
esc_html__( 'This means your web server cannot reliably make secure connections (make requests to HTTPS sites).', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Typically this error is returned when web server is not configured properly.', 'wp-mail-smtp' ),
|
||||
),
|
||||
'steps' => array(
|
||||
],
|
||||
'steps' => [
|
||||
esc_html__( 'Contact your web hosting provider and inform them your site has an issue with SSL certificates.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'The exact error you can provide them is in the Error log, available at the bottom of this page.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Ask them to resolve the issue then try again.', 'wp-mail-smtp' ),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
// [any] - cURL error 6/7.
|
||||
array(
|
||||
[
|
||||
'mailer' => 'any',
|
||||
'errors' => array(
|
||||
array( 'cURL error 6' ),
|
||||
array( 'cURL error 7' ),
|
||||
),
|
||||
'description' => array(
|
||||
'errors' => [
|
||||
[ 'cURL error 6' ],
|
||||
[ 'cURL error 7' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'Could not connect to host.', 'wp-mail-smtp' ) . '</strong>',
|
||||
! empty( $smtp_host )
|
||||
? sprintf(
|
||||
/* translators: %s - SMTP host address. */
|
||||
? sprintf( /* translators: %s - SMTP host address. */
|
||||
esc_html__( 'This means your web server was unable to connect to %s.', 'wp-mail-smtp' ),
|
||||
$smtp_host
|
||||
)
|
||||
: esc_html__( 'This means your web server was unable to connect to the host server.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Typically this error is returned your web server is blocking the connections or the SMTP host denying the request.', 'wp-mail-smtp' ),
|
||||
),
|
||||
'steps' => array(
|
||||
sprintf(
|
||||
/* translators: %s - SMTP host address. */
|
||||
],
|
||||
'steps' => [
|
||||
sprintf( /* translators: %s - SMTP host address. */
|
||||
esc_html__( 'Contact your web hosting provider and ask them to verify your server can connect to %s. Additionally, ask them if a firewall or security policy may be preventing the connection.', 'wp-mail-smtp' ),
|
||||
$smtp_host
|
||||
),
|
||||
esc_html__( 'If using "Other SMTP" Mailer, triple check your SMTP settings including host address, email, and password.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'If using "Other SMTP" Mailer, contact your SMTP host to confirm they are accepting outside connections with the settings you have configured (address, username, port, security, etc).', 'wp-mail-smtp' ),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
// [any] - cURL error XX (other).
|
||||
array(
|
||||
[
|
||||
'mailer' => 'any',
|
||||
'errors' => array(
|
||||
array( 'cURL error' ),
|
||||
),
|
||||
'description' => array(
|
||||
'errors' => [
|
||||
[ 'cURL error' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'Could not connect to your host.', 'wp-mail-smtp' ) . '</strong>',
|
||||
! empty( $smtp_host )
|
||||
? sprintf(
|
||||
/* translators: %s - SMTP host address. */
|
||||
? sprintf( /* translators: %s - SMTP host address. */
|
||||
esc_html__( 'This means your web server was unable to connect to %s.', 'wp-mail-smtp' ),
|
||||
$smtp_host
|
||||
)
|
||||
: esc_html__( 'This means your web server was unable to connect to the host server.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Typically this error is returned when web server is not configured properly.', 'wp-mail-smtp' ),
|
||||
),
|
||||
'steps' => array(
|
||||
],
|
||||
'steps' => [
|
||||
esc_html__( 'Contact your web hosting provider and inform them you are having issues making outbound connections.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'The exact error you can provide them is in the Error log, available at the bottom of this page.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Ask them to resolve the issue then try again.', 'wp-mail-smtp' ),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
// [smtp] - SMTP Error: Count not authenticate.
|
||||
array(
|
||||
[
|
||||
'mailer' => 'smtp',
|
||||
'errors' => array(
|
||||
array( 'SMTP Error: Could not authenticate.' ),
|
||||
),
|
||||
'description' => array(
|
||||
'errors' => [
|
||||
[ 'SMTP Error: Could not authenticate.' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'Could not authenticate your SMTP account.', 'wp-mail-smtp' ) . '</strong>',
|
||||
esc_html__( 'This means we were able to connect to your SMTP host, but were not able to proceed using the email/password in the settings.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Typically this error is returned when the email or password is not correct or is not what the SMTP host is expecting.', 'wp-mail-smtp' ),
|
||||
),
|
||||
'steps' => array(
|
||||
],
|
||||
'steps' => [
|
||||
esc_html__( 'Triple check your SMTP settings including host address, email, and password. If you have recently reset your password you will need to update the settings.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Contact your SMTP host to confirm you are using the correct username and password.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Verify with your SMTP host that your account has permissions to send emails using outside connections.', 'wp-mail-smtp' ),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
// [smtp] - Sending bulk email, hitting rate limit.
|
||||
array(
|
||||
[
|
||||
'mailer' => 'smtp',
|
||||
'errors' => array(
|
||||
array( 'We do not authorize the use of this system to transport unsolicited' ),
|
||||
),
|
||||
'description' => array(
|
||||
'errors' => [
|
||||
[ 'We do not authorize the use of this system to transport unsolicited' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'Error due to unsolicited and/or bulk e-mail.', 'wp-mail-smtp' ) . '</strong>',
|
||||
esc_html__( 'This means the connection to your SMTP host was made successfully, but the host rejected the email.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Typically this error is returned when you are sending too many e-mails or e-mails that have been identified as spam.', 'wp-mail-smtp' ),
|
||||
),
|
||||
'steps' => array(
|
||||
],
|
||||
'steps' => [
|
||||
esc_html__( 'Check the emails that are sending are sending individually. Example: email is not sending to 30 recipients. You can install any WordPress e-mail logging plugin to do that.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Contact your SMTP host to ask about sending/rate limits.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Verify with them your SMTP account is in good standing and your account has not been flagged.', 'wp-mail-smtp' ),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
// [smtp] - Unauthenticated senders not allowed.
|
||||
array(
|
||||
[
|
||||
'mailer' => 'smtp',
|
||||
'errors' => array(
|
||||
array( 'Unauthenticated senders not allowed' ),
|
||||
),
|
||||
'description' => array(
|
||||
'errors' => [
|
||||
[ 'Unauthenticated senders not allowed' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'Unauthenticated senders are not allowed.', 'wp-mail-smtp' ) . '</strong>',
|
||||
esc_html__( 'This means the connection to your SMTP host was made successfully, but you should enable Authentication and provide correct Username and Password.', 'wp-mail-smtp' ),
|
||||
),
|
||||
'steps' => array(
|
||||
],
|
||||
'steps' => [
|
||||
esc_html__( 'Go to WP Mail SMTP plugin Settings page.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Enable Authentication', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Enter correct SMTP Username (usually this is an email address) and Password in the appropriate fields.', 'wp-mail-smtp' ),
|
||||
),
|
||||
),
|
||||
// [smtp] - SMTP connect() failed.
|
||||
array(
|
||||
],
|
||||
],
|
||||
// [smtp] - certificate verify failed.
|
||||
// Has to be defined before "SMTP connect() failed" error, since this is a more specific error,
|
||||
// which contains the "SMTP connect() failed" error message as well.
|
||||
[
|
||||
'mailer' => 'smtp',
|
||||
'errors' => array(
|
||||
array( 'SMTP connect() failed' ),
|
||||
'errors' => [
|
||||
[ 'certificate verify failed' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'Misconfigured server certificate.', 'wp-mail-smtp' ) . '</strong>',
|
||||
esc_html__( 'This means OpenSSL on your server isn\'t able to verify the host certificate.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'There are a few reasons why this is happening. It could be that the host certificate is misconfigured, or this server\'s OpenSSL is using an outdated CA bundle.', 'wp-mail-smtp' ),
|
||||
],
|
||||
'steps' => [
|
||||
esc_html__( 'Verify that the host\'s SSL certificate is valid.', 'wp-mail-smtp' ),
|
||||
sprintf(
|
||||
wp_kses( /* translators: %s - URL to the PHP openssl manual */
|
||||
__( 'Contact your hosting support, show them the "full Error Log for debugging" below and share this <a href="%s" target="_blank" rel="noopener noreferrer">link</a> with them.', 'wp-mail-smtp' ),
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
'rel' => [],
|
||||
],
|
||||
]
|
||||
),
|
||||
'description' => array(
|
||||
'https://www.php.net/manual/en/migration56.openssl.php'
|
||||
),
|
||||
],
|
||||
],
|
||||
// [smtp] - SMTP connect() failed.
|
||||
[
|
||||
'mailer' => 'smtp',
|
||||
'errors' => [
|
||||
[ 'SMTP connect() failed' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'Could not connect to the SMTP host.', 'wp-mail-smtp' ) . '</strong>',
|
||||
! empty( $smtp_host )
|
||||
? sprintf(
|
||||
/* translators: %s - SMTP host address. */
|
||||
? sprintf( /* translators: %s - SMTP host address. */
|
||||
esc_html__( 'This means your web server was unable to connect to %s.', 'wp-mail-smtp' ),
|
||||
$smtp_host
|
||||
)
|
||||
@ -625,22 +663,21 @@ Lead Developer, WP Mail SMTP';
|
||||
'-' . esc_html__( 'SMTP settings are incorrect (wrong port, security setting, incorrect host).', 'wp-mail-smtp' ) . '<br>' .
|
||||
'-' . esc_html__( 'Your web server is blocking the connection.', 'wp-mail-smtp' ) . '<br>' .
|
||||
'-' . esc_html__( 'Your SMTP host is rejecting the connection.', 'wp-mail-smtp' ),
|
||||
),
|
||||
'steps' => array(
|
||||
],
|
||||
'steps' => [
|
||||
esc_html__( 'Triple check your SMTP settings including host address, email, and password, port, and security.', 'wp-mail-smtp' ),
|
||||
sprintf(
|
||||
wp_kses(
|
||||
/* translators: %1$s - SMTP host address, %2$s - SMTP port, %3$s - SMTP encryption. */
|
||||
wp_kses( /* translators: %1$s - SMTP host address, %2$s - SMTP port, %3$s - SMTP encryption. */
|
||||
__( 'Contact your web hosting provider and ask them to verify your server can connect to %1$s on port %2$s using %3$s encryption. Additionally, ask them if a firewall or security policy may be preventing the connection - many shared hosts block certain ports.<br><strong>Note: this is the most common cause of this issue.</strong>', 'wp-mail-smtp' ),
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'rel' => array(),
|
||||
'target' => array(),
|
||||
),
|
||||
'strong' => array(),
|
||||
'br' => array(),
|
||||
)
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'rel' => [],
|
||||
'target' => [],
|
||||
],
|
||||
'strong' => [],
|
||||
'br' => [],
|
||||
]
|
||||
),
|
||||
$smtp_host,
|
||||
$smtp_port,
|
||||
@ -648,281 +685,332 @@ Lead Developer, WP Mail SMTP';
|
||||
),
|
||||
esc_html__( 'Contact your SMTP host to confirm you are using the correct username and password.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Verify with your SMTP host that your account has permissions to send emails using outside connections.', 'wp-mail-smtp' ),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
// [mailgun] - Please activate your Mailgun account.
|
||||
array(
|
||||
[
|
||||
'mailer' => 'mailgun',
|
||||
'errors' => array(
|
||||
array( 'Please activate your Mailgun account' ),
|
||||
),
|
||||
'description' => array(
|
||||
'errors' => [
|
||||
[ 'Please activate your Mailgun account' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'Mailgun failed.', 'wp-mail-smtp' ) . '</strong>',
|
||||
esc_html__( 'It seems that you forgot to activate your Mailgun account.', 'wp-mail-smtp' ),
|
||||
),
|
||||
'steps' => array(
|
||||
],
|
||||
'steps' => [
|
||||
esc_html__( 'Check your inbox you used to create a Mailgun account. Click the activation link in an email from Mailgun.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'If you do not see activation email, go to your Mailgun control panel and resend the activation email.', 'wp-mail-smtp' ),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
// [mailgun] - Forbidden.
|
||||
array(
|
||||
[
|
||||
'mailer' => 'mailgun',
|
||||
'errors' => array(
|
||||
array( 'Forbidden' ),
|
||||
),
|
||||
'description' => array(
|
||||
'errors' => [
|
||||
[ 'Forbidden' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'Mailgun failed.', 'wp-mail-smtp' ) . '</strong>',
|
||||
esc_html__( 'Typically this error is because there is an issue with your Mailgun settings, in many cases the API key.', 'wp-mail-smtp' ),
|
||||
),
|
||||
'steps' => array(
|
||||
],
|
||||
'steps' => [
|
||||
esc_html__( 'Verify your API key is correct.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Go to your Mailgun account and view your API key.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Note that the API key includes the "key" prefix, so make sure that it is in the WP Mail SMTP Mailgun API setting.', 'wp-mail-smtp' ),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
// [mailgun] - Free accounts are for test purposes only.
|
||||
array(
|
||||
[
|
||||
'mailer' => 'mailgun',
|
||||
'errors' => array(
|
||||
array( 'Free accounts are for test purposes only' ),
|
||||
),
|
||||
'description' => array(
|
||||
'errors' => [
|
||||
[ 'Free accounts are for test purposes only' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'Mailgun failed.', 'wp-mail-smtp' ) . '</strong>',
|
||||
esc_html__( 'Your Mailgun account does not have access to send emails.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Typically this error is because you have not set up and/or complete domain name verification for your Mailgun account.', 'wp-mail-smtp' ),
|
||||
),
|
||||
'steps' => array(
|
||||
],
|
||||
'steps' => [
|
||||
sprintf(
|
||||
wp_kses(
|
||||
/* translators: %s - Mailgun documentation URL. */
|
||||
wp_kses( /* translators: %s - Mailgun documentation URL. */
|
||||
__( 'Go to our how-to guide for setting up <a href="%s" target="_blank" rel="noopener noreferrer">Mailgun with WP Mail SMTP</a>.', 'wp-mail-smtp' ),
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'rel' => array(),
|
||||
'target' => array(),
|
||||
),
|
||||
)
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'rel' => [],
|
||||
'target' => [],
|
||||
],
|
||||
]
|
||||
),
|
||||
'https://wpmailsmtp.com/docs/how-to-set-up-the-mailgun-mailer-in-wp-mail-smtp/'
|
||||
),
|
||||
esc_html__( 'Complete the steps in section "2. Verify Your Domain".', 'wp-mail-smtp' ),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
// [gmail] - 401: Login Required.
|
||||
array(
|
||||
[
|
||||
'mailer' => 'gmail',
|
||||
'errors' => array(
|
||||
array( '401', 'Login Required' ),
|
||||
),
|
||||
'description' => array(
|
||||
'errors' => [
|
||||
[ '401', 'Login Required' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'Google API Error.', 'wp-mail-smtp' ) . '</strong>',
|
||||
esc_html__( 'You have not properly configured Gmail mailer.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Make sure that you have clicked the "Allow plugin to send emails using your Google account" button under Gmail settings.', 'wp-mail-smtp' ),
|
||||
),
|
||||
'steps' => array(
|
||||
],
|
||||
'steps' => [
|
||||
esc_html__( 'Go to plugin Settings page and click the "Allow plugin to send emails using your Google account" button.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'After the click you should be redirected to a Gmail authorization screen, where you will be asked a permission to send emails on your behalf.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Please click "Agree", if you see that button. If not - you will need to enable less secure apps first:', 'wp-mail-smtp' )
|
||||
. '<ul>'
|
||||
. '<li>' .
|
||||
sprintf(
|
||||
wp_kses(
|
||||
/* translators: %s - Google support article URL. */
|
||||
wp_kses( /* translators: %s - Google support article URL. */
|
||||
__( 'if you are using regular Gmail account, please <a href="%s" target="_blank" rel="noopener noreferrer">read this article</a> to proceed.', 'wp-mail-smtp' ),
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'target' => array(),
|
||||
'rel' => array(),
|
||||
),
|
||||
)
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
'rel' => [],
|
||||
],
|
||||
]
|
||||
),
|
||||
'https://support.google.com/accounts/answer/6010255?hl=en'
|
||||
)
|
||||
. '</li>'
|
||||
. '<li>' .
|
||||
sprintf(
|
||||
wp_kses(
|
||||
/* translators: %s - Google support article URL. */
|
||||
wp_kses( /* translators: %s - Google support article URL. */
|
||||
__( 'if you are using G Suite, please <a href="%s" target="_blank" rel="noopener noreferrer">read this article</a> to proceed.', 'wp-mail-smtp' ),
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'target' => array(),
|
||||
'rel' => array(),
|
||||
),
|
||||
)
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
'rel' => [],
|
||||
],
|
||||
]
|
||||
),
|
||||
'https://support.google.com/cloudidentity/answer/6260879?hl=en'
|
||||
)
|
||||
. '</li>'
|
||||
. '</ul>',
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
// [gmail] - 400: Recipient address required.
|
||||
array(
|
||||
[
|
||||
'mailer' => 'gmail',
|
||||
'errors' => array(
|
||||
array( '400', 'Recipient address required' ),
|
||||
),
|
||||
'description' => array(
|
||||
'errors' => [
|
||||
[ '400', 'Recipient address required' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'Google API Error.', 'wp-mail-smtp' ) . '</strong>',
|
||||
esc_html__( 'Typically this error is because address the email was sent to is invalid or was empty.', 'wp-mail-smtp' ),
|
||||
),
|
||||
'steps' => array(
|
||||
],
|
||||
'steps' => [
|
||||
esc_html__( 'Check the "Send To" email address used and confirm it is a valid email and was not empty.', 'wp-mail-smtp' ),
|
||||
sprintf(
|
||||
/* translators: 1 - correct email address example. 2 - incorrect email address example. */
|
||||
sprintf( /* translators: 1 - correct email address example. 2 - incorrect email address example. */
|
||||
esc_html__( 'It should be something like this: %1$s. These are incorrect values: %2$s.', 'wp-mail-smtp' ),
|
||||
'<code>info@example.com</code>',
|
||||
'<code>info@localhost</code>, <code>info@192.168.1.1</code>'
|
||||
),
|
||||
esc_html__( 'Make sure that the generated email has a TO header, useful when you are responsible for email creation.', 'wp-mail-smtp' ),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
// [gmail] - Token has been expired or revoked.
|
||||
array(
|
||||
[
|
||||
'mailer' => 'gmail',
|
||||
'errors' => array(
|
||||
array( 'invalid_grant', 'Token has been expired or revoked' ),
|
||||
),
|
||||
'description' => array(
|
||||
'errors' => [
|
||||
[ 'invalid_grant', 'Token has been expired or revoked' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'Google API Error.', 'wp-mail-smtp' ) . '</strong>',
|
||||
esc_html__( 'Unfortunately, this error can be due to many different reasons.', 'wp-mail-smtp' ),
|
||||
),
|
||||
'steps' => array(
|
||||
],
|
||||
'steps' => [
|
||||
sprintf(
|
||||
wp_kses(
|
||||
/* translators: %s - Blog article URL. */
|
||||
wp_kses( /* translators: %s - Blog article URL. */
|
||||
__( 'Please <a href="%s" target="_blank" rel="noopener noreferrer">read this article</a> to learn more about what can cause this error and how it can be resolved.', 'wp-mail-smtp' ),
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'target' => array(),
|
||||
'rel' => array(),
|
||||
),
|
||||
)
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
'rel' => [],
|
||||
],
|
||||
]
|
||||
),
|
||||
'https://blog.timekit.io/google-oauth-invalid-grant-nightmare-and-how-to-fix-it-9f4efaf1da35'
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
// [gmail] - Code was already redeemed.
|
||||
array(
|
||||
[
|
||||
'mailer' => 'gmail',
|
||||
'errors' => array(
|
||||
array( 'invalid_grant', 'Code was already redeemed' ),
|
||||
),
|
||||
'description' => array(
|
||||
'errors' => [
|
||||
[ 'invalid_grant', 'Code was already redeemed' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'Google API Error.', 'wp-mail-smtp' ) . '</strong>',
|
||||
esc_html__( 'Authentication code that Google returned to you has already been used on your previous auth attempt.', 'wp-mail-smtp' ),
|
||||
),
|
||||
'steps' => array(
|
||||
],
|
||||
'steps' => [
|
||||
esc_html__( 'Make sure that you are not trying to manually clean up the plugin options to retry the "Allow..." step.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Reinstall the plugin with clean plugin data turned on on Misc page. This will remove all the plugin options and you will be safe to retry.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Make sure there is no aggressive caching on site admin area pages or try to clean cache between attempts.', 'wp-mail-smtp' ),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
// [gmail] - 400: Mail service not enabled.
|
||||
array(
|
||||
[
|
||||
'mailer' => 'gmail',
|
||||
'errors' => array(
|
||||
array( '400', 'Mail service not enabled' ),
|
||||
),
|
||||
'description' => array(
|
||||
'errors' => [
|
||||
[ '400', 'Mail service not enabled' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'Google API Error.', 'wp-mail-smtp' ) . '</strong>',
|
||||
esc_html__( 'There are various reasons for that, please review the steps below.', 'wp-mail-smtp' ),
|
||||
),
|
||||
'steps' => array(
|
||||
],
|
||||
'steps' => [
|
||||
sprintf(
|
||||
wp_kses(
|
||||
/* translators: %s - Google G Suite Admin area URL. */
|
||||
wp_kses( /* translators: %s - Google G Suite Admin area URL. */
|
||||
__( 'Make sure that your G Suite trial period has not expired. You can check the status <a href="%s" target="_blank" rel="noopener noreferrer">here</a>.', 'wp-mail-smtp' ),
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'rel' => array(),
|
||||
'target' => array(),
|
||||
),
|
||||
)
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'rel' => [],
|
||||
'target' => [],
|
||||
],
|
||||
]
|
||||
),
|
||||
'https://admin.google.com'
|
||||
),
|
||||
sprintf(
|
||||
wp_kses(
|
||||
/* translators: %s - Google G Suite Admin area URL. */
|
||||
wp_kses( /* translators: %s - Google G Suite Admin area URL. */
|
||||
__( 'Make sure that Gmail app in your G Suite is actually enabled. You can check that in Apps list in <a href="%s" target="_blank" rel="noopener noreferrer">G Suite Admin</a> area.', 'wp-mail-smtp' ),
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'rel' => array(),
|
||||
'target' => array(),
|
||||
),
|
||||
)
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'rel' => [],
|
||||
'target' => [],
|
||||
],
|
||||
]
|
||||
),
|
||||
'https://admin.google.com'
|
||||
),
|
||||
sprintf(
|
||||
wp_kses(
|
||||
/* translators: %s - Google Developers Console URL. */
|
||||
wp_kses( /* translators: %s - Google Developers Console URL. */
|
||||
__( 'Make sure that you have Gmail API enabled, and you can do that <a href="%s" target="_blank" rel="noopener noreferrer">here</a>.', 'wp-mail-smtp' ),
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'rel' => array(),
|
||||
'target' => array(),
|
||||
),
|
||||
)
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'rel' => [],
|
||||
'target' => [],
|
||||
],
|
||||
]
|
||||
),
|
||||
'https://console.developers.google.com/'
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
// [gmail] - 403: Project X is not found and cannot be used for API calls.
|
||||
array(
|
||||
[
|
||||
'mailer' => 'gmail',
|
||||
'errors' => array(
|
||||
array( '403', 'is not found and cannot be used for API calls' ),
|
||||
),
|
||||
'description' => array(
|
||||
'errors' => [
|
||||
[ '403', 'is not found and cannot be used for API calls' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'Google API Error.', 'wp-mail-smtp' ) . '</strong>',
|
||||
),
|
||||
'steps' => array(
|
||||
],
|
||||
'steps' => [
|
||||
esc_html__( 'Make sure that the used Client ID/Secret correspond to a proper project that has Gmail API enabled.', 'wp-mail-smtp' ),
|
||||
sprintf(
|
||||
wp_kses(
|
||||
/* translators: %s - Gmail documentation URL. */
|
||||
wp_kses( /* translators: %s - Gmail documentation URL. */
|
||||
esc_html__( 'Please follow our <a href="%s" target="_blank" rel="noopener noreferrer">Gmail tutorial</a> to be sure that all the correct project and data is applied.', 'wp-mail-smtp' ),
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'rel' => array(),
|
||||
'target' => array(),
|
||||
),
|
||||
)
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'rel' => [],
|
||||
'target' => [],
|
||||
],
|
||||
]
|
||||
),
|
||||
'https://wpmailsmtp.com/docs/how-to-set-up-the-gmail-mailer-in-wp-mail-smtp/'
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
// [gmail] - The OAuth client was disabled.
|
||||
array(
|
||||
[
|
||||
'mailer' => 'gmail',
|
||||
'errors' => array(
|
||||
array( 'disabled_client', 'The OAuth client was disabled' ),
|
||||
),
|
||||
'description' => array(
|
||||
'errors' => [
|
||||
[ 'disabled_client', 'The OAuth client was disabled' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'Google API Error.', 'wp-mail-smtp' ) . '</strong>',
|
||||
esc_html__( 'You may have added a new API to a project', 'wp-mail-smtp' ),
|
||||
),
|
||||
'steps' => array(
|
||||
],
|
||||
'steps' => [
|
||||
esc_html__( 'Make sure that the used Client ID/Secret correspond to a proper project that has Gmail API enabled.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Try to use a separate project for your emails, so the project has only 1 Gmail API in it enabled. You will need to remove the old project and create a new one from scratch.', 'wp-mail-smtp' ),
|
||||
),
|
||||
),
|
||||
);
|
||||
],
|
||||
],
|
||||
// [SMTP.com] - The "channel - not found" issue.
|
||||
[
|
||||
'mailer' => 'smtpcom',
|
||||
'errors' => [
|
||||
[ 'channel - not found' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'SMTP.com API Error.', 'wp-mail-smtp' ) . '</strong>',
|
||||
esc_html__( 'Your Sender Name option is incorrect.', 'wp-mail-smtp' ),
|
||||
],
|
||||
'steps' => [
|
||||
esc_html__( 'Please make sure you entered an accurate Sender Name in WP Mail SMTP plugin settings.', 'wp-mail-smtp' ),
|
||||
],
|
||||
],
|
||||
// [gmail] - GuzzleHttp requires cURL, the allow_url_fopen ini setting, or a custom HTTP handler.
|
||||
[
|
||||
'mailer' => 'gmail',
|
||||
'errors' => [
|
||||
[ 'GuzzleHttp requires cURL, the allow_url_fopen ini setting, or a custom HTTP handler' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'GuzzleHttp requirements.', 'wp-mail-smtp' ) . '</strong>',
|
||||
esc_html__( 'GuzzleHttp requires cURL, the allow_url_fopen ini setting, or a custom HTTP handler.', 'wp-mail-smtp' ),
|
||||
],
|
||||
'steps' => [
|
||||
esc_html__( 'Edit your php.ini file on your hosting server.', 'wp-mail-smtp' ),
|
||||
esc_html__( '(Recommended) Enable PHP extension: cURL, by adding "extension=curl" to the php.ini file (without the quotation marks) OR', 'wp-mail-smtp' ),
|
||||
esc_html__( '(If cURL can\'t be enabled on your hosting server) Enable PHP setting: allow_url_fopen, by adding "allow_url_fopen = On" to the php.ini file (without the quotation marks)', 'wp-mail-smtp' ),
|
||||
esc_html__( 'If you don\'t know how to do the above we strongly suggest contacting your hosting support and provide them the "full Error Log for debugging" below and these steps. They should be able to fix this issue for you.', 'wp-mail-smtp' ),
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* [any] - PHP 7.4.x and PCRE library issues.
|
||||
*
|
||||
* @see https://wordpress.org/support/topic/cant-send-emails-using-php-7-4/
|
||||
*/
|
||||
if (
|
||||
version_compare( phpversion(), '7.4', '>=' ) &&
|
||||
defined( 'PCRE_VERSION' ) &&
|
||||
version_compare( PCRE_VERSION, '10.0', '>' ) &&
|
||||
version_compare( PCRE_VERSION, '10.32', '<=' )
|
||||
) {
|
||||
$details[] = [
|
||||
'mailer' => 'any',
|
||||
'errors' => [
|
||||
[ 'Invalid address: (setFrom)' ],
|
||||
],
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'PCRE library issue', 'wp-mail-smtp' ) . '</strong>',
|
||||
esc_html__( 'It looks like your server is running PHP version 7.4.x with an outdated PCRE library (libpcre2) that has a known issue with email address validation.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'There is a known issue with PHP version 7.4.x, when using libpcre2 library version lower than 10.33.', 'wp-mail-smtp' ),
|
||||
],
|
||||
'steps' => [
|
||||
esc_html__( 'Contact your web hosting provider and inform them you are having issues with libpcre2 library on PHP 7.4.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'They should be able to resolve this issue for you.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'For a quick fix, until your web hosting resolves this, you can downgrade to PHP version 7.3 on your server.', 'wp-mail-smtp' ),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
// Error detection logic.
|
||||
foreach ( $details as $data ) {
|
||||
@ -953,27 +1041,27 @@ Lead Developer, WP Mail SMTP';
|
||||
}
|
||||
|
||||
// Return defaults.
|
||||
return array(
|
||||
'description' => array(
|
||||
return [
|
||||
'description' => [
|
||||
'<strong>' . esc_html__( 'An issue was detected.', 'wp-mail-smtp' ) . '</strong>',
|
||||
esc_html__( 'This means your test email was unable to be sent.', 'wp-mail-smtp' ),
|
||||
esc_html__( 'Typically this error is returned for one of the following reasons:', 'wp-mail-smtp' ),
|
||||
'- ' . esc_html__( 'Plugin settings are incorrect (wrong SMTP settings, invalid Mailer configuration, etc).', 'wp-mail-smtp' ) . '<br>' .
|
||||
'- ' . esc_html__( 'Your web server is blocking the connection.', 'wp-mail-smtp' ) . '<br>' .
|
||||
'- ' . esc_html__( 'Your host is rejecting the connection.', 'wp-mail-smtp' ),
|
||||
),
|
||||
'steps' => array(
|
||||
],
|
||||
'steps' => [
|
||||
esc_html__( 'Triple check the plugin settings, consider reconfiguring to make sure everything is correct (eg bad copy and paste).', 'wp-mail-smtp' ),
|
||||
wp_kses(
|
||||
__( 'Contact your web hosting provider and ask them to verify your server can make outside connections. Additionally, ask them if a firewall or security policy may be preventing the connection - many shared hosts block certain ports.<br><strong>Note: this is the most common cause of this issue.</strong>', 'wp-mail-smtp' ),
|
||||
array(
|
||||
'strong' => array(),
|
||||
'br' => array(),
|
||||
)
|
||||
[
|
||||
'strong' => [],
|
||||
'br' => [],
|
||||
]
|
||||
),
|
||||
esc_html__( 'Try using a different mailer.', 'wp-mail-smtp' ),
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
203
wp-content/plugins/wp-mail-smtp/src/Admin/Review.php
Normal file
@ -0,0 +1,203 @@
|
||||
<?php
|
||||
|
||||
namespace WPMailSMTP\Admin;
|
||||
|
||||
use WPMailSMTP\Options;
|
||||
|
||||
/**
|
||||
* Class for admin notice requesting plugin review.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
class Review {
|
||||
|
||||
/**
|
||||
* The name of the WP option for the review notice data.
|
||||
*
|
||||
* Data attributes:
|
||||
* - time
|
||||
* - dismissed
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
const NOTICE_OPTION = 'wp_mail_smtp_review_notice';
|
||||
|
||||
/**
|
||||
* Days the plugin waits before displaying a review request.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
const WAIT_PERIOD = 14;
|
||||
|
||||
/**
|
||||
* Initialize hooks.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public function hooks() {
|
||||
|
||||
add_action( 'admin_notices', array( $this, 'review_request' ) );
|
||||
add_action( 'wp_ajax_wp_mail_smtp_review_dismiss', array( $this, 'review_dismiss' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add admin notices as needed for reviews.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public function review_request() {
|
||||
|
||||
// Only consider showing the review request to admin users.
|
||||
if ( ! is_super_admin() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify that we can do a check for reviews.
|
||||
$review = get_option( self::NOTICE_OPTION );
|
||||
$time = time();
|
||||
$load = false;
|
||||
|
||||
if ( empty( $review ) ) {
|
||||
$review = [
|
||||
'time' => $time,
|
||||
'dismissed' => false,
|
||||
];
|
||||
update_option( self::NOTICE_OPTION, $review );
|
||||
} else {
|
||||
// Check if it has been dismissed or not.
|
||||
if ( isset( $review['dismissed'] ) && ! $review['dismissed'] ) {
|
||||
$load = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If we cannot load, return early.
|
||||
if ( ! $load ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->review();
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe show review request.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
private function review() {
|
||||
|
||||
// Get the currently selected mailer.
|
||||
$mailer = Options::init()->get( 'mail', 'mailer' );
|
||||
|
||||
// Skip if the default mailer is selected.
|
||||
if ( $mailer === 'mail' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch when plugin was initially activated.
|
||||
$activated = get_option( 'wp_mail_smtp_activated_time' );
|
||||
|
||||
// Skip if the plugin activated time is not set.
|
||||
if ( empty( $activated ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if mailer setup is complete.
|
||||
$mailer_setup_complete = wp_mail_smtp()
|
||||
->get_providers()
|
||||
->get_mailer( $mailer, wp_mail_smtp()->get_processor()->get_phpmailer() )
|
||||
->is_mailer_complete();
|
||||
|
||||
// Skip if the mailer is not set or the plugin is active for less then a defined number of days.
|
||||
if ( ! $mailer_setup_complete || ( $activated + ( DAY_IN_SECONDS * self::WAIT_PERIOD ) ) > time() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We have a candidate! Output a review message.
|
||||
?>
|
||||
<div class="notice notice-info is-dismissible wp-mail-smtp-review-notice">
|
||||
<div class="wp-mail-smtp-review-step wp-mail-smtp-review-step-1">
|
||||
<p><?php esc_html_e( 'Are you enjoying WP Mail SMTP?', 'wp-mail-smtp' ); ?></p>
|
||||
<p>
|
||||
<a href="#" class="wp-mail-smtp-review-switch-step" data-step="3"><?php esc_html_e( 'Yes', 'wp-mail-smtp' ); ?></a><br />
|
||||
<a href="#" class="wp-mail-smtp-review-switch-step" data-step="2"><?php esc_html_e( 'Not Really', 'wp-mail-smtp' ); ?></a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="wp-mail-smtp-review-step wp-mail-smtp-review-step-2" style="display: none">
|
||||
<p><?php esc_html_e( 'We\'re sorry to hear you aren\'t enjoying WP Mail SMTP. We would love a chance to improve. Could you take a minute and let us know what we can do better?', 'wp-mail-smtp' ); ?></p>
|
||||
<p>
|
||||
<a href="https://wpmailsmtp.com/plugin-feedback/" class="wp-mail-smtp-dismiss-review-notice wp-mail-smtp-review-out" target="_blank" rel="noopener noreferrer">
|
||||
<?php esc_html_e( 'Give Feedback', 'wp-mail-smtp' ); ?>
|
||||
</a><br>
|
||||
<a href="#" class="wp-mail-smtp-dismiss-review-notice" target="_blank" rel="noopener noreferrer">
|
||||
<?php esc_html_e( 'No thanks', 'wp-mail-smtp' ); ?>
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="wp-mail-smtp-review-step wp-mail-smtp-review-step-3" style="display: none">
|
||||
<p><?php esc_html_e( 'That’s awesome! Could you please do me a BIG favor and give it a 5-star rating on WordPress to help us spread the word and boost our motivation?', 'wp-mail-smtp' ); ?></p>
|
||||
<p><strong><?php echo wp_kses( __( '~ Jared Atchison<br>Lead Developer, WP Mail SMTP', 'wp-mail-smtp' ), [ 'br' => [] ] ); ?></strong></p>
|
||||
<p>
|
||||
<a href="https://wordpress.org/support/plugin/wp-mail-smtp/reviews/?filter=5#new-post" class="wp-mail-smtp-dismiss-review-notice wp-mail-smtp-review-out" target="_blank" rel="noopener noreferrer">
|
||||
<?php esc_html_e( 'Ok, you deserve it', 'wp-mail-smtp' ); ?>
|
||||
</a><br>
|
||||
<a href="#" class="wp-mail-smtp-dismiss-review-notice" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Nope, maybe later', 'wp-mail-smtp' ); ?></a><br>
|
||||
<a href="#" class="wp-mail-smtp-dismiss-review-notice" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'I already did', 'wp-mail-smtp' ); ?></a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
jQuery( document ).ready( function ( $ ) {
|
||||
$( document ).on( 'click', '.wp-mail-smtp-dismiss-review-notice, .wp-mail-smtp-review-notice button', function( e ) {
|
||||
if ( ! $( this ).hasClass( 'wp-mail-smtp-review-out' ) ) {
|
||||
e.preventDefault();
|
||||
}
|
||||
$.post( ajaxurl, { action: 'wp_mail_smtp_review_dismiss' } );
|
||||
$( '.wp-mail-smtp-review-notice' ).remove();
|
||||
} );
|
||||
|
||||
$( document ).on( 'click', '.wp-mail-smtp-review-switch-step', function( e ) {
|
||||
e.preventDefault();
|
||||
var target = parseInt( $( this ).attr( 'data-step' ), 10 );
|
||||
|
||||
if ( target ) {
|
||||
var $notice = $( this ).closest( '.wp-mail-smtp-review-notice' );
|
||||
var $review_step = $notice.find( '.wp-mail-smtp-review-step-' + target );
|
||||
|
||||
if ( $review_step.length > 0 ) {
|
||||
$notice.find( '.wp-mail-smtp-review-step:visible' ).fadeOut( function() {
|
||||
$review_step.fadeIn();
|
||||
} );
|
||||
}
|
||||
}
|
||||
} );
|
||||
} );
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismiss the review admin notice.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public function review_dismiss() {
|
||||
|
||||
$review = get_option( self::NOTICE_OPTION, [] );
|
||||
$review['time'] = time();
|
||||
$review['dismissed'] = true;
|
||||
update_option( self::NOTICE_OPTION, $review );
|
||||
|
||||
if ( is_super_admin() && is_multisite() ) {
|
||||
$site_list = get_sites();
|
||||
foreach ( (array) $site_list as $site ) {
|
||||
switch_to_blog( $site->blog_id );
|
||||
|
||||
update_option( self::NOTICE_OPTION, $review );
|
||||
|
||||
restore_current_blog();
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json_success();
|
||||
}
|
||||
}
|
@ -95,6 +95,9 @@ class Core {
|
||||
*/
|
||||
public function hooks() {
|
||||
|
||||
// Action Scheduler requires a special early loading procedure.
|
||||
add_action( 'plugins_loaded', array( $this, 'load_action_scheduler' ), -10 );
|
||||
|
||||
// Activation hook.
|
||||
register_activation_hook( WPMS_PLUGIN_FILE, array( $this, 'activate' ) );
|
||||
|
||||
@ -107,6 +110,9 @@ class Core {
|
||||
|
||||
add_action( 'init', array( $this, 'init' ) );
|
||||
|
||||
// Initialize Action Scheduler tasks.
|
||||
add_action( 'init', array( $this, 'get_tasks' ), 5 );
|
||||
|
||||
add_action( 'plugins_loaded', array( $this, 'get_pro' ) );
|
||||
}
|
||||
|
||||
@ -188,6 +194,25 @@ class Core {
|
||||
return $this->pro;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get/Load the Tasks code of the plugin.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @return \WPMailSMTP\Tasks\Tasks
|
||||
*/
|
||||
public function get_tasks() {
|
||||
|
||||
static $tasks;
|
||||
|
||||
if ( ! isset( $tasks ) ) {
|
||||
$tasks = apply_filters( 'wp_mail_smtp_core_get_tasks', new Tasks\Tasks() );
|
||||
$tasks->init();
|
||||
}
|
||||
|
||||
return $tasks;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows to overwrite certain core WP functions, because it's fired:
|
||||
* - after `muplugins_loaded` hook,
|
||||
@ -573,6 +598,13 @@ class Core {
|
||||
|
||||
// Save default options, only once.
|
||||
Options::init()->set( Options::get_defaults(), true );
|
||||
|
||||
/**
|
||||
* Store the timestamp of first plugin activation.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
add_option( 'wp_mail_smtp_activated_time', time(), '', false );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -689,4 +721,16 @@ class Core {
|
||||
|
||||
return (bool) apply_filters( 'wp_mail_smtp_is_white_labeled', false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Require the action scheduler in an early plugins_loaded hook (-10).
|
||||
*
|
||||
* @see https://actionscheduler.org/usage/#load-order
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public function load_action_scheduler() {
|
||||
|
||||
require_once $this->plugin_path . '/vendor/woocommerce/action-scheduler/action-scheduler.php';
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +89,15 @@ class MailCatcher extends \PHPMailer {
|
||||
} catch ( \phpmailerException $e ) {
|
||||
$this->mailHeader = '';
|
||||
$this->setError( $e->getMessage() );
|
||||
|
||||
// Set the debug error, but not for default PHP mailer.
|
||||
if ( $mail_mailer !== 'mail' ) {
|
||||
Debug::set(
|
||||
'Mailer: ' . esc_html( wp_mail_smtp()->get_providers()->get_options( $mail_mailer )->get_title() ) . PHP_EOL .
|
||||
$e->getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
if ( $this->exceptions ) {
|
||||
throw $e;
|
||||
}
|
||||
|
@ -2,13 +2,39 @@
|
||||
|
||||
namespace WPMailSMTP;
|
||||
|
||||
use WPMailSMTP\Tasks\Meta;
|
||||
|
||||
/**
|
||||
* Class Migration helps migrate all plugin options saved into DB to a new storage location.
|
||||
* Class Migration helps migrate plugin options, DB tables and more.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @since 1.0.0 Migrate all plugin options saved from separate WP options into one.
|
||||
* @since 2.1.0 Major overhaul of this class to use DB migrations (or any other migrations per version).
|
||||
*/
|
||||
class Migration {
|
||||
|
||||
/**
|
||||
* Version of the latest migration.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
const VERSION = 2;
|
||||
|
||||
/**
|
||||
* Option key where we save the current migration version.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
const OPTION_NAME = 'wp_mail_smtp_migration_version';
|
||||
|
||||
/**
|
||||
* Current migration version, received from self::OPTION_NAME WP option
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $cur_ver;
|
||||
|
||||
/**
|
||||
* All old values for pre 1.0 version of a plugin.
|
||||
*
|
||||
@ -56,9 +82,108 @@ class Migration {
|
||||
* Migration constructor.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @since 2.1.0 Redefined constructor - major overhaul.
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
$this->cur_ver = self::get_cur_version();
|
||||
|
||||
$this->maybe_migrate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Static on purpose, to get current migration version without __construct() and validation.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function get_cur_version() {
|
||||
|
||||
return (int) get_option( self::OPTION_NAME, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the migration if needed.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
protected function maybe_migrate() {
|
||||
|
||||
if ( ! is_admin() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( version_compare( $this->cur_ver, self::VERSION, '<' ) ) {
|
||||
$this->run( self::VERSION );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actual migration launcher.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param int $version The version of migration to run.
|
||||
*/
|
||||
protected function run( $version ) {
|
||||
|
||||
$function_version = (int) $version;
|
||||
|
||||
if ( method_exists( $this, 'migrate_to_' . $function_version ) ) {
|
||||
$this->{'migrate_to_' . $function_version}();
|
||||
} else {
|
||||
$message = sprintf( /* translators: %1$s - WP Mail SMTP, %2$s - error message. */
|
||||
esc_html__( 'There was an error while upgrading the database. Please contact %1$s support with this information: %2$s.', 'wp-mail-smtp' ),
|
||||
'<strong>WP Mail SMTP</strong>',
|
||||
'<code>migration from v' . self::get_cur_version() . ' to v' . self::VERSION . ' failed. Plugin version: v' . WPMS_PLUGIN_VER . '</code>'
|
||||
);
|
||||
|
||||
WP::add_admin_notice( $message, WP::ADMIN_NOTICE_ERROR );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update migration version in options table.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param int $version Migration version.
|
||||
*/
|
||||
protected function update_db_ver( $version ) {
|
||||
|
||||
if ( empty( $version ) ) {
|
||||
$version = self::VERSION;
|
||||
}
|
||||
|
||||
// Autoload it, because this value is checked all the time
|
||||
// and no need to request it separately from all autoloaded options.
|
||||
update_option( self::OPTION_NAME, $version, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent running the same migration twice.
|
||||
* Run migration only when required.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string $version The version of migration to check for potential execution.
|
||||
*/
|
||||
protected function maybe_required_older_migrations( $version ) {
|
||||
|
||||
if ( version_compare( $this->cur_ver, $version, '<' ) ) {
|
||||
$this->run( $version );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migration from 0.x to 1.0.0.
|
||||
* Move separate plugin WP options to one main plugin WP option setting.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
private function migrate_to_1() {
|
||||
|
||||
if ( $this->is_migrated() ) {
|
||||
return;
|
||||
}
|
||||
@ -68,8 +193,27 @@ class Migration {
|
||||
|
||||
Options::init()->set( $this->new_values, true );
|
||||
|
||||
// Removing all old options will be enabled some time in the future.
|
||||
// $this->clean_deprecated_data();
|
||||
$this->update_db_ver( 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Migration from 1.x to 2.1.0.
|
||||
* Create Tasks\Meta table, if it does not exist.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
private function migrate_to_2() {
|
||||
|
||||
$this->maybe_required_older_migrations( 1 );
|
||||
|
||||
$meta = new Meta();
|
||||
|
||||
// Create the table if it doesn't exist.
|
||||
if ( $meta && ! $meta->table_exists() ) {
|
||||
$meta->create_table();
|
||||
}
|
||||
|
||||
$this->update_db_ver( 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -19,21 +19,22 @@ class Options {
|
||||
* @since 1.4.0 Added Mailgun:region.
|
||||
* @since 1.5.0 Added Outlook/AmazonSES.
|
||||
* @since 1.8.0 Added Pepipost API.
|
||||
* @since 2.0.0 Added SMTP.com API.
|
||||
*
|
||||
* @since
|
||||
*
|
||||
* @var array Map of all the default options of the plugin.
|
||||
*/
|
||||
private static $map = array(
|
||||
'mail' => array(
|
||||
private static $map = [
|
||||
'mail' => [
|
||||
'from_name',
|
||||
'from_email',
|
||||
'mailer',
|
||||
'return_path',
|
||||
'from_name_force',
|
||||
'from_email_force',
|
||||
),
|
||||
'smtp' => array(
|
||||
],
|
||||
'smtp' => [
|
||||
'host',
|
||||
'port',
|
||||
'encryption',
|
||||
@ -41,62 +42,64 @@ class Options {
|
||||
'auth',
|
||||
'user',
|
||||
'pass',
|
||||
),
|
||||
'gmail' => array(
|
||||
],
|
||||
'gmail' => [
|
||||
'client_id',
|
||||
'client_secret',
|
||||
),
|
||||
'outlook' => array(
|
||||
],
|
||||
'outlook' => [
|
||||
'client_id',
|
||||
'client_secret',
|
||||
),
|
||||
'amazonses' => array(
|
||||
],
|
||||
'amazonses' => [
|
||||
'client_id',
|
||||
'client_secret',
|
||||
'region',
|
||||
'emails_pending',
|
||||
),
|
||||
'mailgun' => array(
|
||||
],
|
||||
'mailgun' => [
|
||||
'api_key',
|
||||
'domain',
|
||||
'region',
|
||||
),
|
||||
'sendgrid' => array(
|
||||
],
|
||||
'sendgrid' => [
|
||||
'api_key',
|
||||
),
|
||||
'smtpcom' => array(
|
||||
],
|
||||
'smtpcom' => [
|
||||
'api_key',
|
||||
'channel',
|
||||
),
|
||||
'sendinblue' => array(
|
||||
],
|
||||
'sendinblue' => [
|
||||
'api_key',
|
||||
),
|
||||
'pepipostapi' => array(
|
||||
],
|
||||
'pepipostapi' => [
|
||||
'api_key',
|
||||
),
|
||||
'pepipost' => array(
|
||||
],
|
||||
'pepipost' => [
|
||||
'host',
|
||||
'port',
|
||||
'encryption',
|
||||
'auth',
|
||||
'user',
|
||||
'pass',
|
||||
),
|
||||
'license' => array(
|
||||
],
|
||||
'license' => [
|
||||
'key',
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* That's where plugin options are saved in wp_options table.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.0.0
|
||||
*/
|
||||
const META_KEY = 'wp_mail_smtp';
|
||||
|
||||
/**
|
||||
* All the plugin options.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_options = array();
|
||||
@ -141,6 +144,7 @@ class Options {
|
||||
* Default options that are saved on plugin activation.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @since 2.1.0 Set the Force from email to "on" by default.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@ -152,7 +156,7 @@ class Options {
|
||||
'from_name' => get_bloginfo( 'name' ),
|
||||
'mailer' => 'mail',
|
||||
'return_path' => false,
|
||||
'from_email_force' => false,
|
||||
'from_email_force' => true,
|
||||
'from_name_force' => false,
|
||||
),
|
||||
'smtp' => array(
|
||||
|
@ -9,6 +9,18 @@ namespace WPMailSMTP;
|
||||
*/
|
||||
class Processor {
|
||||
|
||||
/**
|
||||
* This attribute will hold the "original" WP from email address passed to the wp_mail_from filter,
|
||||
* that is not equal to the default email address.
|
||||
*
|
||||
* It should hold an email address set via the wp_mail_from filter, before we might overwrite it.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $wp_mail_from;
|
||||
|
||||
/**
|
||||
* Processor constructor.
|
||||
*
|
||||
@ -81,6 +93,11 @@ class Processor {
|
||||
$phpmailer->SMTPAutoTLS = false;
|
||||
}
|
||||
|
||||
// Check if original WP from email can be set as the reply_to attribute.
|
||||
if ( $this->allow_setting_original_from_email_to_reply_to( $phpmailer->getReplyToAddresses(), $mailer ) ) {
|
||||
$phpmailer->addReplyTo( $this->wp_mail_from );
|
||||
}
|
||||
|
||||
// If we're sending via SMTP, set the host.
|
||||
if ( 'smtp' === $mailer ) {
|
||||
// Set the other options.
|
||||
@ -104,12 +121,62 @@ class Processor {
|
||||
$phpmailer->Password = $options->get( $mailer, 'pass' );
|
||||
}
|
||||
|
||||
// Maybe set default reply-to header.
|
||||
$this->set_default_reply_to( $phpmailer );
|
||||
|
||||
// You can add your own options here.
|
||||
// See the phpmailer documentation for more info: https://github.com/PHPMailer/PHPMailer/tree/5.2-stable.
|
||||
/** @noinspection PhpUnusedLocalVariableInspection It's passed by reference. */
|
||||
$phpmailer = apply_filters( 'wp_mail_smtp_custom_options', $phpmailer );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if it's allowed to set the original WP from email to the reply_to field.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param array $reply_to Array of currently set reply to emails.
|
||||
* @param string $mailer The slug of current mailer.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function allow_setting_original_from_email_to_reply_to( $reply_to, $mailer ) {
|
||||
|
||||
$options = new Options();
|
||||
$forced = $options->get( 'mail', 'from_email_force' );
|
||||
$from_email = $options->get( 'mail', 'from_email' );
|
||||
|
||||
if ( ! empty( $reply_to ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( in_array( $mailer, array( 'gmail', 'outlook' ), true ) ) {
|
||||
$forced = true;
|
||||
|
||||
switch ( $mailer ) {
|
||||
case 'gmail':
|
||||
$sender = wp_mail_smtp()->get_providers()->get_auth( 'gmail' )->get_user_info();
|
||||
break;
|
||||
|
||||
case 'outlook':
|
||||
$sender = $options->get( 'outlook', 'user_details' );
|
||||
break;
|
||||
}
|
||||
|
||||
$from_email = ! empty( $sender['email'] ) ? $sender['email'] : '';
|
||||
}
|
||||
|
||||
if (
|
||||
empty( $this->wp_mail_from ) ||
|
||||
$from_email === $this->wp_mail_from ||
|
||||
! $forced
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will be called every time 'smtp' and 'mail' mailers will be used to send emails.
|
||||
*
|
||||
@ -157,6 +224,11 @@ class Processor {
|
||||
$from_email = $options->get( 'mail', 'from_email' );
|
||||
$def_email = $this->get_default_email();
|
||||
|
||||
// Save the "original" set WP email from address for later use.
|
||||
if ( $wp_email !== $def_email ) {
|
||||
$this->wp_mail_from = $wp_email;
|
||||
}
|
||||
|
||||
// Return FROM EMAIL if forced in settings.
|
||||
if ( $forced & ! empty( $from_email ) ) {
|
||||
return $from_email;
|
||||
@ -250,4 +322,34 @@ class Processor {
|
||||
|
||||
return $phpmailer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default reply_to header, if:
|
||||
* - no other reply_to headers are already set and,
|
||||
* - the default reply_to address filter `wp_mail_smtp_processor_default_reply_to_addresses` is configured.
|
||||
*
|
||||
* @since 2.1.1
|
||||
*
|
||||
* @param \PHPMailer $phpmailer The PHPMailer object.
|
||||
*/
|
||||
private function set_default_reply_to( $phpmailer ) {
|
||||
|
||||
if ( ! empty( $phpmailer->getReplyToAddresses() ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$default_reply_to_emails = apply_filters( 'wp_mail_smtp_processor_set_default_reply_to', '' );
|
||||
|
||||
if ( empty( $default_reply_to_emails ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( explode( ',', $default_reply_to_emails ) as $email ) {
|
||||
$email = trim( $email );
|
||||
|
||||
if ( filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
|
||||
$phpmailer->addReplyTo( $email );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,26 +92,28 @@ class Mailer extends MailerAbstract {
|
||||
$this->phpmailer->Sender = $gmail_creds['email'];
|
||||
}
|
||||
|
||||
try {
|
||||
// Prepare a message for sending.
|
||||
$this->phpmailer->preSend();
|
||||
|
||||
// Get the raw MIME email using MailCatcher data.
|
||||
// We need here to make base64URL-safe string.
|
||||
$base64 = str_replace(
|
||||
array( '+', '/', '=' ),
|
||||
array( '-', '_', '' ),
|
||||
base64_encode( $this->phpmailer->getSentMIMEMessage() )
|
||||
[ '+', '/', '=' ],
|
||||
[ '-', '_', '' ],
|
||||
base64_encode( $this->phpmailer->getSentMIMEMessage() ) //phpcs:ignore
|
||||
);
|
||||
|
||||
$message->setRaw( $base64 );
|
||||
|
||||
$service = new \Google_Service_Gmail( $auth->get_client() );
|
||||
|
||||
try {
|
||||
$response = $service->users_messages->send( 'me', $message );
|
||||
|
||||
$this->process_response( $response );
|
||||
} catch ( \Exception $e ) {
|
||||
Debug::set(
|
||||
'Mailer: Gmail' . "\r\n" .
|
||||
$e->getMessage()
|
||||
$this->process_exception_message( $e->getMessage() )
|
||||
);
|
||||
|
||||
return;
|
||||
@ -124,7 +126,7 @@ class Mailer extends MailerAbstract {
|
||||
* @since 1.0.0
|
||||
* @since 1.5.0 Added action "wp_mail_smtp_providers_gmail_mailer_process_response" with $response.
|
||||
*
|
||||
* @param \Google_Service_Gmail_Message $response
|
||||
* @param \Google_Service_Gmail_Message $response Instance of Gmail response.
|
||||
*/
|
||||
protected function process_response( $response ) {
|
||||
|
||||
@ -160,7 +162,12 @@ class Mailer extends MailerAbstract {
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* 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() {
|
||||
|
||||
@ -200,7 +207,11 @@ class Mailer extends MailerAbstract {
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* Whether the mailer has all its settings correctly set up and saved.
|
||||
*
|
||||
* @since 1.4.0
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_mailer_complete() {
|
||||
|
||||
@ -219,4 +230,75 @@ class Mailer extends MailerAbstract {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the exception message and append additional explanation to it.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param mixed $message A string or an object with strings.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function process_exception_message( $message ) {
|
||||
|
||||
// Transform the passed message to a string.
|
||||
if ( ! is_string( $message ) ) {
|
||||
$message = wp_json_encode( $message );
|
||||
} else {
|
||||
$message = wp_strip_all_tags( $message, false );
|
||||
}
|
||||
|
||||
// Define known errors, that we will scan the message with.
|
||||
$known_errors = array(
|
||||
array(
|
||||
'errors' => array(
|
||||
'invalid_grant',
|
||||
),
|
||||
'explanation' => esc_html__( 'Please re-grant Google app permissions!', 'wp-mail-smtp' ) . ' ' . PHP_EOL .
|
||||
esc_html__( 'Go to WP Mail SMTP plugin settings page. Click the “Remove Connection” button.', 'wp-mail-smtp' ) . ' ' . PHP_EOL .
|
||||
esc_html__( 'Then click the “Allow plugin to send emails using your Google account” button and re-enable access.', 'wp-mail-smtp' ),
|
||||
),
|
||||
);
|
||||
|
||||
// Check if we get a match and append the explanation to the original message.
|
||||
foreach ( $known_errors as $error ) {
|
||||
foreach ( $error['errors'] as $error_fragment ) {
|
||||
if ( false !== strpos( $message, $error_fragment ) ) {
|
||||
return $message . PHP_EOL . $error['explanation'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we get no match we return the original message (as a string).
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default email addresses for the reply to email parameter.
|
||||
*
|
||||
* @deprecated 2.1.1
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @since 2.1.1 Not used anymore.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function default_reply_to_addresses() {
|
||||
|
||||
_deprecated_function( __CLASS__ . '::' . __METHOD__, '2.1.1 of WP Mail SMTP plugin' );
|
||||
|
||||
$gmail_creds = ( new Auth() )->get_user_info();
|
||||
|
||||
if ( empty( $gmail_creds['email'] ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
$gmail_creds['email'] => [
|
||||
$gmail_creds['email'],
|
||||
'',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -132,8 +132,8 @@ class Loader {
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param string $provider
|
||||
* @param MailCatcher $phpmailer
|
||||
* @param string $provider The provider name.
|
||||
* @param MailCatcher|\PHPMailer $phpmailer The MailCatcher object.
|
||||
*
|
||||
* @return MailerAbstract|null
|
||||
*/
|
||||
|
@ -414,4 +414,54 @@ abstract class MailerAbstract implements MailerInterface {
|
||||
|
||||
return implode( '<br>', $smtp_text );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the email addresses for the reply to email parameter.
|
||||
*
|
||||
* @deprecated 2.1.1
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @since 2.1.1 Not used anymore.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_reply_to_addresses() {
|
||||
|
||||
_deprecated_function( __CLASS__ . '::' . __METHOD__, '2.1.1 of WP Mail SMTP plugin' );
|
||||
|
||||
$reply_to = $this->phpmailer->getReplyToAddresses();
|
||||
|
||||
// Return the passed reply to addresses, if defined.
|
||||
if ( ! empty( $reply_to ) ) {
|
||||
return $reply_to;
|
||||
}
|
||||
|
||||
// Return the default reply to addresses.
|
||||
return apply_filters(
|
||||
'wp_mail_smtp_providers_mailer_default_reply_to_addresses',
|
||||
$this->default_reply_to_addresses()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default email addresses for the reply to email parameter.
|
||||
*
|
||||
* @deprecated 2.1.1
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @since 2.1.1 Not used anymore.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function default_reply_to_addresses() {
|
||||
|
||||
_deprecated_function( __CLASS__ . '::' . __METHOD__, '2.1.1 of WP Mail SMTP plugin' );
|
||||
|
||||
return [
|
||||
$this->phpmailer->From => [
|
||||
$this->phpmailer->From,
|
||||
$this->phpmailer->FromName,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -344,20 +344,12 @@ abstract class OptionsAbstract implements OptionsInterface {
|
||||
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-pass" spellcheck="false" autocomplete="new-password"
|
||||
/>
|
||||
<p class="desc">
|
||||
<?php esc_html_e( 'The password is stored in plain text. We highly recommend you set up your password in your WordPress configuration file for improved security.', 'wp-mail-smtp' ); ?>
|
||||
<?php esc_html_e( 'The password will be stored in plain text. For improved security, we highly recommend using your site\'s WordPress configuration file to set your password.', 'wp-mail-smtp' ); ?>
|
||||
<br>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s - wp-config.php. */
|
||||
esc_html__( 'To do this add the lines below to your %s file:', 'wp-mail-smtp' ),
|
||||
'<code>wp-config.php</code>'
|
||||
);
|
||||
?>
|
||||
<a href="https://wpmailsmtp.com/docs/how-to-secure-smtp-settings-by-using-constants/" target="_blank" rel="noopener noreferrer">
|
||||
<strong><?php esc_html_e( 'Learn More', 'wp-mail-smtp' ); ?></strong>
|
||||
</a>
|
||||
</p>
|
||||
<pre>
|
||||
define( 'WPMS_ON', true );
|
||||
define( 'WPMS_SMTP_PASS', 'your_password' );
|
||||
</pre>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
@ -440,13 +432,21 @@ abstract class OptionsAbstract implements OptionsInterface {
|
||||
<blockquote>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s - Provider name. */
|
||||
esc_html__( '%s requires a SSL certificate on a site to work and does not support your current installation. Please contact your host and request a SSL certificate or install a free one, like Let\'s Encrypt.', 'wp-mail-smtp' ),
|
||||
wp_kses( /* translators: %s - Provider name */
|
||||
__( '%s requires an SSL certificate, and so is not currently compatible with your site. Please contact your host to request a SSL certificate, or check out <a href="https://www.wpbeginner.com/wp-tutorials/how-to-add-ssl-and-https-in-wordpress/" target="_blank">WPBeginner\'s tutorial on how to set up SSL</a>.', 'wp-mail-smtp' ),
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
],
|
||||
]
|
||||
),
|
||||
esc_html( $this->get_title() )
|
||||
);
|
||||
?>
|
||||
<br>
|
||||
<?php esc_html_e( 'Meanwhile you can switch to some other mailers.', 'wp-mail-smtp' ); ?>
|
||||
<br>
|
||||
<?php esc_html_e( 'If you\'d prefer not to set up SSL, or need an SMTP solution in the meantime, please select a different mailer option.', 'wp-mail-smtp' ); ?>
|
||||
</blockquote>
|
||||
|
||||
<?php
|
||||
|
@ -38,7 +38,7 @@ class Options extends OptionsAbstract {
|
||||
|
||||
$description = sprintf(
|
||||
wp_kses( /* translators: %s - URL to smtp.com site. */
|
||||
__( '<strong><a href="%s" target="_blank" rel="noopener noreferrer">SMTP.com</a> is a recommended transactional email service.</strong> With over 22 years of email delivery expertise, SMTP.com has been around for almost as long as email itself. They are known among internet providers as one of the most reliable senders on the internet. Their easy integration process lets you start sending emails in minutes and benefit from years of experience. SMTP.com provides users 10,000 free emails the first 30 days.', 'wp-mail-smtp' ),
|
||||
__( '<strong><a href="%s" target="_blank" rel="noopener noreferrer">SMTP.com</a> is a recommended transactional email service.</strong> With a 22 years of track record of reliable email delivery, SMTP.com is a premiere solution for WordPress developers and website owners. SMTP.com has been around for almost as long as email itself. Their super simple integration interface makes it easy to get started while a powerful API and robust documentation make it a preferred choice among developers. Start a 30-day free trial with 50,000 emails.', 'wp-mail-smtp' ),
|
||||
$allowed_kses_html
|
||||
),
|
||||
'https://wpmailsmtp.com/go/smtp/'
|
||||
|
527
wp-content/plugins/wp-mail-smtp/src/Tasks/Meta.php
Normal file
@ -0,0 +1,527 @@
|
||||
<?php
|
||||
|
||||
namespace WPMailSMTP\Tasks;
|
||||
|
||||
/**
|
||||
* Class Meta helps to manage the tasks meta information
|
||||
* between Action Scheduler and WP Mail SMTP hooks arguments.
|
||||
* We can't pass arguments longer than >191 chars in JSON to AS,
|
||||
* so we need to store them somewhere (and clean from time to time).
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
class Meta {
|
||||
|
||||
/**
|
||||
* Database table name.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $table_name;
|
||||
|
||||
/**
|
||||
* Database version.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $version;
|
||||
|
||||
/**
|
||||
* Primary key (unique field) for the database table.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $primary_key = 'id';
|
||||
|
||||
/**
|
||||
* Database type identifier.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'tasks_meta';
|
||||
|
||||
/**
|
||||
* Primary class constructor.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
$this->table_name = self::get_table_name();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DB table name.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_table_name() {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
return $wpdb->prefix . 'wpmailsmtp_tasks_meta';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table columns.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public function get_columns() {
|
||||
|
||||
return array(
|
||||
'id' => '%d',
|
||||
'action' => '%s',
|
||||
'data' => '%s',
|
||||
'date' => '%s',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default column values.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_column_defaults() {
|
||||
|
||||
return array(
|
||||
'action' => '',
|
||||
'data' => '',
|
||||
'date' => gmdate( 'Y-m-d H:i:s' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a row from the database based on a given row ID.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param int $row_id Row ID.
|
||||
*
|
||||
* @return null|object
|
||||
*/
|
||||
private function get_from_db( $row_id ) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
return $wpdb->get_row(
|
||||
$wpdb->prepare(
|
||||
"SELECT * FROM {$this->table_name} WHERE {$this->primary_key} = %s LIMIT 1;", // phpcs:ignore
|
||||
$row_id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a row based on column and row ID.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string $column Column name.
|
||||
* @param int|string $row_id Row ID.
|
||||
*
|
||||
* @return object|null|bool Database query result, object or null on failure.
|
||||
*/
|
||||
public function get_by( $column, $row_id ) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
if ( empty( $row_id ) || ! array_key_exists( $column, $this->get_columns() ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
return $wpdb->get_row(
|
||||
$wpdb->prepare(
|
||||
"SELECT * FROM $this->table_name WHERE $column = '%s' LIMIT 1;", // phpcs:ignore
|
||||
$row_id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a value based on column name and row ID.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string $column Column name.
|
||||
* @param int|string $row_id Row ID.
|
||||
*
|
||||
* @return string|null Database query result (as string), or null on failure.
|
||||
*/
|
||||
public function get_column( $column, $row_id ) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
if ( empty( $row_id ) || ! array_key_exists( $column, $this->get_columns() ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
return $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT $column FROM $this->table_name WHERE $this->primary_key = '%s' LIMIT 1;", // phpcs:ignore
|
||||
$row_id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve one column value based on another given column and matching value.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string $column Column name.
|
||||
* @param string $column_where Column to match against in the WHERE clause.
|
||||
* @param string $column_value Value to match to the column in the WHERE clause.
|
||||
*
|
||||
* @return string|null Database query result (as string), or null on failure.
|
||||
*/
|
||||
public function get_column_by( $column, $column_where, $column_value ) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
if ( empty( $column ) || empty( $column_where ) || empty( $column_value ) || ! array_key_exists( $column, $this->get_columns() ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
return $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT $column FROM $this->table_name WHERE $column_where = %s LIMIT 1;", // phpcs:ignore
|
||||
$column_value
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a new record into the database.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param array $data Column data.
|
||||
* @param string $type Optional. Data type context.
|
||||
*
|
||||
* @return int ID for the newly inserted record. 0 otherwise.
|
||||
*/
|
||||
private function add_to_db( $data, $type = '' ) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
// Set default values.
|
||||
$data = wp_parse_args( $data, $this->get_column_defaults() );
|
||||
|
||||
do_action( 'wp_mail_smtp_pre_insert_' . $type, $data );
|
||||
|
||||
// Initialise column format array.
|
||||
$column_formats = $this->get_columns();
|
||||
|
||||
// Force fields to lower case.
|
||||
$data = array_change_key_case( $data );
|
||||
|
||||
// White list columns.
|
||||
$data = array_intersect_key( $data, $column_formats );
|
||||
|
||||
// Reorder $column_formats to match the order of columns given in $data.
|
||||
$data_keys = array_keys( $data );
|
||||
$column_formats = array_merge( array_flip( $data_keys ), $column_formats );
|
||||
|
||||
$wpdb->insert( $this->table_name, $data, $column_formats );
|
||||
|
||||
do_action( 'wp_mail_smtp_post_insert_' . $type, $wpdb->insert_id, $data );
|
||||
|
||||
return $wpdb->insert_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an existing record in the database.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param int|string $row_id Row ID for the record being updated.
|
||||
* @param array $data Optional. Array of columns and associated data to update. Default empty array.
|
||||
* @param string $where Optional. Column to match against in the WHERE clause. If empty, $primary_key
|
||||
* will be used. Default empty.
|
||||
* @param string $type Optional. Data type context, e.g. 'affiliate', 'creative', etc. Default empty.
|
||||
*
|
||||
* @return bool False if the record could not be updated, true otherwise.
|
||||
*/
|
||||
public function update( $row_id, $data = array(), $where = '', $type = '' ) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
// Row ID must be a positive integer.
|
||||
$row_id = absint( $row_id );
|
||||
|
||||
if ( empty( $row_id ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $where ) ) {
|
||||
$where = $this->primary_key;
|
||||
}
|
||||
|
||||
do_action( 'wp_mail_smtp_pre_update_' . $type, $data );
|
||||
|
||||
// Initialise column format array.
|
||||
$column_formats = $this->get_columns();
|
||||
|
||||
// Force fields to lower case.
|
||||
$data = array_change_key_case( $data );
|
||||
|
||||
// White list columns.
|
||||
$data = array_intersect_key( $data, $column_formats );
|
||||
|
||||
// Reorder $column_formats to match the order of columns given in $data.
|
||||
$data_keys = array_keys( $data );
|
||||
$column_formats = array_merge( array_flip( $data_keys ), $column_formats );
|
||||
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
if ( false === $wpdb->update( $this->table_name, $data, array( $where => $row_id ), $column_formats ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
do_action( 'wp_mail_smtp_post_update_' . $type, $data );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a record from the database.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param int|string $row_id Row ID.
|
||||
*
|
||||
* @return bool False if the record could not be deleted, true otherwise.
|
||||
*/
|
||||
public function delete( $row_id = 0 ) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
// Row ID must be positive integer.
|
||||
$row_id = absint( $row_id );
|
||||
|
||||
if ( empty( $row_id ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
do_action( 'wp_mail_smtp_pre_delete', $row_id );
|
||||
do_action( 'wp_mail_smtp_pre_delete_' . $this->type, $row_id );
|
||||
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
if ( false === $wpdb->query( $wpdb->prepare( "DELETE FROM {$this->table_name} WHERE {$this->primary_key} = %d", $row_id ) ) ) { // phpcs:ignore
|
||||
return false;
|
||||
}
|
||||
|
||||
do_action( 'wp_mail_smtp_post_delete', $row_id );
|
||||
do_action( 'wp_mail_smtp_post_delete_' . $this->type, $row_id );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a record from the database by column.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string $column Column name.
|
||||
* @param int|string $column_value Column value.
|
||||
*
|
||||
* @return bool False if the record could not be deleted, true otherwise.
|
||||
*/
|
||||
public function delete_by( $column, $column_value ) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
if ( empty( $column ) || empty( $column_value ) || ! array_key_exists( $column, $this->get_columns() ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
do_action( 'wp_mail_smtp_pre_delete', $column_value );
|
||||
do_action( 'wp_mail_smtp_pre_delete_' . $this->type, $column_value );
|
||||
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
if ( false === $wpdb->query( $wpdb->prepare( "DELETE FROM {$this->table_name} WHERE $column = %s", $column_value ) ) ) { // phpcs:ignore
|
||||
return false;
|
||||
}
|
||||
|
||||
do_action( 'wp_mail_smtp_post_delete', $column_value );
|
||||
do_action( 'wp_mail_smtp_post_delete_' . $this->type, $column_value );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given table exists.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string $table The table name. Defaults to the child class table name.
|
||||
*
|
||||
* @return string|null If the table name exists.
|
||||
*/
|
||||
public function table_exists( $table = '' ) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
if ( ! empty( $table ) ) {
|
||||
$table = sanitize_text_field( $table );
|
||||
} else {
|
||||
$table = $this->table_name;
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
return $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) ) === $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create custom entry meta database table.
|
||||
* Used in migration.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public function create_table() {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
|
||||
$charset_collate = '';
|
||||
|
||||
if ( ! empty( $wpdb->charset ) ) {
|
||||
$charset_collate .= "DEFAULT CHARACTER SET {$wpdb->charset}";
|
||||
}
|
||||
if ( ! empty( $wpdb->collate ) ) {
|
||||
$charset_collate .= " COLLATE {$wpdb->collate}";
|
||||
}
|
||||
|
||||
$sql = "CREATE TABLE {$this->table_name} (
|
||||
id bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
action varchar(255) NOT NULL,
|
||||
data longtext NOT NULL,
|
||||
date datetime NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) {$charset_collate};";
|
||||
|
||||
dbDelta( $sql );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove queue records for a defined period of time in the past.
|
||||
* Calling this method will remove queue records that are older than $period seconds.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string $action Action that should be cleaned up.
|
||||
* @param int $interval Number of seconds from now.
|
||||
*
|
||||
* @return int Number of removed tasks meta records.
|
||||
*/
|
||||
public function clean_by( $action, $interval ) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
if ( empty( $action ) || empty( $interval ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$table = self::get_table_name();
|
||||
$action = sanitize_key( $action );
|
||||
$date = gmdate( 'Y-m-d H:i:s', time() - (int) $interval );
|
||||
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
return (int) $wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM `$table` WHERE action = %s AND date < %s", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
$action,
|
||||
$date
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a new record into the database.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param array $data Column data.
|
||||
* @param string $type Optional. Data type context.
|
||||
*
|
||||
* @return int ID for the newly inserted record. 0 otherwise.
|
||||
*/
|
||||
public function add( $data, $type = '' ) {
|
||||
|
||||
if ( empty( $data['action'] ) || ! is_string( $data['action'] ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$data['action'] = sanitize_key( $data['action'] );
|
||||
|
||||
if ( isset( $data['data'] ) ) {
|
||||
$string = wp_json_encode( $data['data'] );
|
||||
|
||||
if ( $string === false ) {
|
||||
$string = '';
|
||||
}
|
||||
|
||||
/*
|
||||
* We are encoding the string representation of all the data
|
||||
* to make sure that nothing can harm the database.
|
||||
* This is not an encryption, and we need this data later as is,
|
||||
* so we are using one of the fastest way to do that.
|
||||
* This data is removed from DB on a daily basis.
|
||||
*/
|
||||
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
|
||||
$data['data'] = base64_encode( $string );
|
||||
}
|
||||
|
||||
if ( empty( $type ) ) {
|
||||
$type = $this->type;
|
||||
}
|
||||
|
||||
return $this->add_to_db( $data, $type );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a row from the database based on a given row ID.
|
||||
*
|
||||
* @since 2.1.0}
|
||||
*
|
||||
* @param int $meta_id Meta ID.
|
||||
*
|
||||
* @return null|object
|
||||
*/
|
||||
public function get( $meta_id ) {
|
||||
|
||||
$meta = $this->get_from_db( $meta_id );
|
||||
|
||||
if ( empty( $meta ) || empty( $meta->data ) ) {
|
||||
return $meta;
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
|
||||
$decoded = base64_decode( $meta->data );
|
||||
|
||||
if ( $decoded === false || ! is_string( $decoded ) ) {
|
||||
$meta->data = '';
|
||||
} else {
|
||||
$meta->data = json_decode( $decoded, true );
|
||||
}
|
||||
|
||||
return $meta;
|
||||
}
|
||||
}
|
304
wp-content/plugins/wp-mail-smtp/src/Tasks/Task.php
Normal file
@ -0,0 +1,304 @@
|
||||
<?php
|
||||
|
||||
namespace WPMailSMTP\Tasks;
|
||||
|
||||
/**
|
||||
* Class Task.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
class Task {
|
||||
|
||||
/**
|
||||
* This task is async (runs asap).
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
const TYPE_ASYNC = 'async';
|
||||
|
||||
/**
|
||||
* This task is a recurring.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
const TYPE_RECURRING = 'scheduled';
|
||||
|
||||
/**
|
||||
* This task is run once.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
const TYPE_ONCE = 'once';
|
||||
|
||||
/**
|
||||
* Type of the task.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $type;
|
||||
|
||||
/**
|
||||
* Action that will be used as a hook.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $action;
|
||||
|
||||
/**
|
||||
* Task meta ID.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $meta_id;
|
||||
|
||||
/**
|
||||
* All the params that should be passed to the hook.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $params;
|
||||
|
||||
/**
|
||||
* When the first instance of the job will run.
|
||||
* Used for ONCE ane RECURRING tasks.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $timestamp;
|
||||
|
||||
/**
|
||||
* How long to wait between runs.
|
||||
* Used for RECURRING tasks.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $interval;
|
||||
|
||||
/**
|
||||
* Task constructor.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string $action Action of the task.
|
||||
*
|
||||
* @throws \InvalidArgumentException When action is not a string.
|
||||
* @throws \UnexpectedValueException When action is empty.
|
||||
*/
|
||||
public function __construct( $action ) {
|
||||
|
||||
if ( ! is_string( $action ) ) {
|
||||
throw new \InvalidArgumentException( 'Task action should be a string.' );
|
||||
}
|
||||
|
||||
$this->action = sanitize_key( $action );
|
||||
|
||||
if ( empty( $this->action ) ) {
|
||||
throw new \UnexpectedValueException( 'Task action cannot be empty.' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the type of the task as async.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @return Task
|
||||
*/
|
||||
public function async() {
|
||||
|
||||
$this->type = self::TYPE_ASYNC;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the type of the task as recurring.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param int $timestamp When the first instance of the job will run.
|
||||
* @param int $interval How long to wait between runs.
|
||||
*
|
||||
* @return Task
|
||||
*/
|
||||
public function recurring( $timestamp, $interval ) {
|
||||
|
||||
$this->type = self::TYPE_RECURRING;
|
||||
$this->timestamp = (int) $timestamp;
|
||||
$this->interval = (int) $interval;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the type of the task as one-time.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param int $timestamp When the first instance of the job will run.
|
||||
*
|
||||
* @return Task
|
||||
*/
|
||||
public function once( $timestamp ) {
|
||||
|
||||
$this->type = self::TYPE_ONCE;
|
||||
$this->timestamp = (int) $timestamp;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass any number of params that should be saved to Meta table.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @return Task
|
||||
*/
|
||||
public function params() {
|
||||
|
||||
$this->params = func_get_args();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the action.
|
||||
* Should be the final call in a chain.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @return null|string Action ID.
|
||||
*/
|
||||
public function register() {
|
||||
|
||||
$action_id = null;
|
||||
|
||||
// No processing if ActionScheduler is not usable.
|
||||
if ( ! wp_mail_smtp()->get_tasks()->is_usable() ) {
|
||||
return $action_id;
|
||||
}
|
||||
|
||||
// Save data to tasks meta table.
|
||||
$task_meta = new Meta();
|
||||
$this->meta_id = $task_meta->add(
|
||||
[
|
||||
'action' => $this->action,
|
||||
'data' => $this->params,
|
||||
]
|
||||
);
|
||||
|
||||
if ( empty( $this->meta_id ) ) {
|
||||
return $action_id;
|
||||
}
|
||||
|
||||
switch ( $this->type ) {
|
||||
case self::TYPE_ASYNC:
|
||||
$action_id = $this->register_async();
|
||||
break;
|
||||
|
||||
case self::TYPE_RECURRING:
|
||||
$action_id = $this->register_recurring();
|
||||
break;
|
||||
|
||||
case self::TYPE_ONCE:
|
||||
$action_id = $this->register_once();
|
||||
break;
|
||||
}
|
||||
|
||||
return $action_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the async task.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @return null|string Action ID.
|
||||
*/
|
||||
protected function register_async() {
|
||||
|
||||
if ( ! function_exists( 'as_enqueue_async_action' ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return as_enqueue_async_action(
|
||||
$this->action,
|
||||
[ 'tasks_meta_id' => $this->meta_id ],
|
||||
Tasks::GROUP
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the recurring task.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @return null|string Action ID.
|
||||
*/
|
||||
protected function register_recurring() {
|
||||
|
||||
if ( ! function_exists( 'as_schedule_recurring_action' ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return as_schedule_recurring_action(
|
||||
$this->timestamp,
|
||||
$this->interval,
|
||||
$this->action,
|
||||
[ 'tasks_meta_id' => $this->meta_id ],
|
||||
Tasks::GROUP
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the one-time task.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @return null|string Action ID.
|
||||
*/
|
||||
protected function register_once() {
|
||||
|
||||
if ( ! function_exists( 'as_schedule_single_action' ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return as_schedule_single_action(
|
||||
$this->timestamp,
|
||||
$this->action,
|
||||
[ 'tasks_meta_id' => $this->meta_id ],
|
||||
Tasks::GROUP
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel all occurrences of this task.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @return null|bool|string Null if no matching action found,
|
||||
* false if AS library is missing,
|
||||
* string of the scheduled action ID if a scheduled action was found and unscheduled.
|
||||
*/
|
||||
public function cancel() {
|
||||
|
||||
// Exit if AS function does not exist.
|
||||
if ( ! function_exists( 'as_unschedule_all_actions' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return as_unschedule_all_actions( $this->action );
|
||||
}
|
||||
}
|
150
wp-content/plugins/wp-mail-smtp/src/Tasks/Tasks.php
Normal file
@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
namespace WPMailSMTP\Tasks;
|
||||
|
||||
/**
|
||||
* Class Tasks manages the tasks queue and provides API to work with it.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
class Tasks {
|
||||
|
||||
/**
|
||||
* Group that will be assigned to all actions.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
const GROUP = 'wp_mail_smtp';
|
||||
|
||||
/**
|
||||
* Perform certain things on class init.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
// Register tasks.
|
||||
foreach ( $this->get_tasks() as $task ) {
|
||||
if ( ! is_subclass_of( $task, '\WPMailSMTP\Tasks\Task' ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$new_task = new $task();
|
||||
|
||||
// Run the init method, if a task has one defined.
|
||||
if ( method_exists( $new_task, 'init' ) ) {
|
||||
$new_task->init();
|
||||
}
|
||||
}
|
||||
|
||||
add_action( 'admin_menu', array( $this, 'admin_hide_as_menu' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of default scheduled tasks.
|
||||
* Tasks, that are fired under certain specific circumstances
|
||||
* (like sending emails) are not listed here.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @return Task[] List of tasks classes.
|
||||
*/
|
||||
public function get_tasks() {
|
||||
|
||||
return apply_filters( 'wp_mail_smtp_tasks_get_tasks', array() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide Action Scheduler admin area when not in debug mode.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public function admin_hide_as_menu() {
|
||||
|
||||
// Filter to redefine that WP Mail SMTP hides Tools > Action Scheduler menu item.
|
||||
if ( apply_filters( 'wp_mail_smtp_tasks_admin_hide_as_menu', true ) ) {
|
||||
remove_submenu_page( 'tools.php', 'action-scheduler' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new task.
|
||||
* Used for "inline" tasks, that require additional information
|
||||
* from the plugin runtime before they can be scheduled.
|
||||
*
|
||||
* Example:
|
||||
* wp_mail_smtp()->get( 'tasks' )
|
||||
* ->create( 'i_am_the_dude' )
|
||||
* ->async()
|
||||
* ->params( 'The Big Lebowski', 1998 )
|
||||
* ->register();
|
||||
*
|
||||
* This `i_am_the_dude` action will be later processed as:
|
||||
* add_action( 'i_am_the_dude', 'thats_what_you_call_me' );
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string $action Action that will be used as a hook.
|
||||
*
|
||||
* @return \WPMailSMTP\Tasks\Task
|
||||
*/
|
||||
public function create( $action ) {
|
||||
|
||||
return new Task( $action );
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel all the AS actions for a group.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string $group Group to cancel all actions for.
|
||||
*/
|
||||
public function cancel_all( $group = '' ) {
|
||||
|
||||
if ( empty( $group ) ) {
|
||||
$group = self::GROUP;
|
||||
} else {
|
||||
$group = sanitize_key( $group );
|
||||
}
|
||||
|
||||
if ( class_exists( 'ActionScheduler_DBStore' ) ) {
|
||||
\ActionScheduler_DBStore::instance()->cancel_actions_by_group( $group );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether ActionScheduler thinks that it has migrated or not.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_usable() {
|
||||
|
||||
// No tasks if ActionScheduler wasn't loaded.
|
||||
if ( ! class_exists( 'ActionScheduler_DataController' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return \ActionScheduler_DataController::is_migration_complete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether task has been scheduled and is pending.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string $hook Hook to check for.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_scheduled( $hook ) {
|
||||
|
||||
if ( ! function_exists( 'as_next_scheduled_action' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return as_next_scheduled_action( $hook );
|
||||
}
|
||||
}
|
@ -18,24 +18,32 @@ class WP {
|
||||
*/
|
||||
protected static $admin_notices = array();
|
||||
/**
|
||||
* CSS class for a success notice.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const ADMIN_NOTICE_SUCCESS = 'notice-success';
|
||||
/**
|
||||
* CSS class for an error notice.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const ADMIN_NOTICE_ERROR = 'notice-error';
|
||||
/**
|
||||
* CSS class for an info notice.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const ADMIN_NOTICE_INFO = 'notice-info';
|
||||
/**
|
||||
* CSS class for a warning notice.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @var string
|
||||
@ -43,7 +51,7 @@ class WP {
|
||||
const ADMIN_NOTICE_WARNING = 'notice-warning';
|
||||
|
||||
/**
|
||||
* True is WP is processing an AJAX call.
|
||||
* True if WP is processing an AJAX call.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
@ -103,7 +111,7 @@ class WP {
|
||||
|
||||
<div class="notice wp-mail-smtp-notice <?php echo esc_attr( $notice['class'] ); ?> notice <?php echo esc_attr( $dismissible ); ?>">
|
||||
<p>
|
||||
<?php echo $notice['message']; ?>
|
||||
<?php echo wp_kses_post( $notice['message'] ); ?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -160,7 +168,7 @@ class WP {
|
||||
*
|
||||
* @since 1.5.0
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $string String we want to test if it's json.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@ -178,8 +186,7 @@ class WP {
|
||||
*/
|
||||
public static function datetime_format() {
|
||||
|
||||
return sprintf(
|
||||
/* translators: %1$s - date, \a\t - specially escaped "at", %2$s - time. */
|
||||
return sprintf( /* translators: %1$s - date, \a\t - specially escaped "at", %2$s - time. */
|
||||
esc_html__( '%1$s \a\t %2$s', 'wp-mail-smtp' ),
|
||||
get_option( 'date_format' ),
|
||||
get_option( 'time_format' )
|
||||
@ -199,14 +206,14 @@ class WP {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize the value, similar to sanitize_text_field(), but a bit differently.
|
||||
* Sanitize the value, similar to `sanitize_text_field()`, but a bit differently.
|
||||
* It preserves `<` and `>` for non-HTML tags.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $value String we want to sanitize.
|
||||
*
|
||||
* @return mixed|string|string[]|null
|
||||
* @return string
|
||||
*/
|
||||
public static function sanitize_value( $value ) {
|
||||
|
||||
|
@ -20,15 +20,10 @@ if ( empty( $settings['general']['uninstall'] ) ) {
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove options.
|
||||
* Remove Legacy options.
|
||||
*/
|
||||
$options = array(
|
||||
'wp_mail_smtp_initial_version',
|
||||
'wp_mail_smtp_version',
|
||||
'wp_mail_smtp_debug',
|
||||
'wp_mail_smtp',
|
||||
'_amn_smtp_last_checked',
|
||||
// Legacy options.
|
||||
'pepipost_ssl',
|
||||
'pepipost_port',
|
||||
'pepipost_pass',
|
||||
@ -43,13 +38,26 @@ $options = array(
|
||||
'mailer',
|
||||
'mail_from_name',
|
||||
'mail_from',
|
||||
'wp_mail_smtp_am_notifications_hidden',
|
||||
);
|
||||
|
||||
foreach ( $options as $option ) {
|
||||
delete_option( $option );
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
|
||||
// Delete plugin settings.
|
||||
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE 'wp\_mail\_smtp%'" );
|
||||
|
||||
// Delete plugin user meta.
|
||||
$wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key LIKE 'wp\_mail\_smtp\_%'" );
|
||||
|
||||
// Remove any transients we've left behind.
|
||||
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE '\_transient\_wp\_mail\_smtp\_%'" );
|
||||
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE '\_site\_transient\_wp\_mail\_smtp\_%'" );
|
||||
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE '\_transient\_timeout\_wp\_mail\_smtp\_%'" );
|
||||
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE '\_site\_transient\_timeout\_wp\_mail\_smtp\_%'" );
|
||||
|
||||
/*
|
||||
* Remove product announcements.
|
||||
*/
|
||||
@ -70,11 +78,22 @@ if ( ! empty( $announcements ) ) {
|
||||
/*
|
||||
* Logs for Pro plugin only.
|
||||
*/
|
||||
if ( function_exists( 'wp_mail_smtp' ) && wp_mail_smtp()->is_pro() ) {
|
||||
// DB version.
|
||||
delete_option( 'wp_mail_smtp_logs_db_version' );
|
||||
if (
|
||||
function_exists( 'wp_mail_smtp' ) &&
|
||||
is_readable( wp_mail_smtp()->plugin_path . '/src/Pro/Pro.php' )
|
||||
) {
|
||||
// DB table.
|
||||
global $wpdb;
|
||||
$table = \WPMailSMTP\Pro\Emails\Logs\Logs::get_table_name();
|
||||
$wpdb->query( "DROP TABLE $table;" ); // phpcs:ignore
|
||||
$logs_table = \WPMailSMTP\Pro\Emails\Logs\Logs::get_table_name();
|
||||
$wpdb->query( "DROP TABLE IF EXISTS $logs_table;" ); // phpcs:ignore WordPress.DB
|
||||
}
|
||||
|
||||
/*
|
||||
* Drop all Action Scheduler data.
|
||||
*/
|
||||
require_once dirname( __FILE__ ) . '/vendor/woocommerce/action-scheduler/action-scheduler.php';
|
||||
|
||||
// Unschedule all plugin ActionScheduler actions.
|
||||
( new \WPMailSMTP\Tasks\Tasks() )->cancel_all();
|
||||
|
||||
$meta_table = \WPMailSMTP\Tasks\Meta::get_table_name();
|
||||
$wpdb->query( "DROP TABLE IF EXISTS $meta_table;" ); // phpcs:ignore WordPress.DB
|
||||
|
@ -9,6 +9,9 @@ return array(
|
||||
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
|
||||
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
|
||||
'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
|
||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
|
||||
'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
|
||||
);
|
||||
|
@ -8,6 +8,9 @@ $baseDir = dirname($vendorDir);
|
||||
return array(
|
||||
'phpseclib\\' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'),
|
||||
'WPMailSMTP\\' => array($baseDir . '/src'),
|
||||
'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'),
|
||||
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
|
||||
'Symfony\\Polyfill\\Intl\\Idn\\' => array($vendorDir . '/symfony/polyfill-intl-idn'),
|
||||
'SendinBlue\\Client\\' => array($vendorDir . '/sendinblue/api-v3-sdk/lib'),
|
||||
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
|
||||
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
|
||||
|
@ -10,6 +10,9 @@ class ComposerStaticInit72f613a3d0c2cc77892490951b6e5352
|
||||
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||
'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
|
||||
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
|
||||
'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',
|
||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
|
||||
'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
|
||||
);
|
||||
@ -25,6 +28,9 @@ class ComposerStaticInit72f613a3d0c2cc77892490951b6e5352
|
||||
),
|
||||
'S' =>
|
||||
array (
|
||||
'Symfony\\Polyfill\\Php72\\' => 23,
|
||||
'Symfony\\Polyfill\\Mbstring\\' => 26,
|
||||
'Symfony\\Polyfill\\Intl\\Idn\\' => 26,
|
||||
'SendinBlue\\Client\\' => 18,
|
||||
),
|
||||
'P' =>
|
||||
@ -63,6 +69,18 @@ class ComposerStaticInit72f613a3d0c2cc77892490951b6e5352
|
||||
array (
|
||||
0 => __DIR__ . '/../..' . '/src',
|
||||
),
|
||||
'Symfony\\Polyfill\\Php72\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/polyfill-php72',
|
||||
),
|
||||
'Symfony\\Polyfill\\Mbstring\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
|
||||
),
|
||||
'Symfony\\Polyfill\\Intl\\Idn\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/polyfill-intl-idn',
|
||||
),
|
||||
'SendinBlue\\Client\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/sendinblue/api-v3-sdk/lib',
|
||||
|
@ -19,8 +19,7 @@
|
||||
* Service definition for Gmail (v1).
|
||||
*
|
||||
* <p>
|
||||
* The Gmail API lets you view and manage Gmail mailbox data like threads,
|
||||
* messages, and labels.</p>
|
||||
* Access Gmail mailboxes including sending user email.</p>
|
||||
*
|
||||
* <p>
|
||||
* For more information about this service, see the API
|
||||
@ -98,8 +97,8 @@ class Google_Service_Gmail extends Google_Service
|
||||
{
|
||||
parent::__construct($client);
|
||||
$this->rootUrl = $rootUrl ?: 'https://www.googleapis.com/';
|
||||
$this->servicePath = '';
|
||||
$this->batchPath = 'batch';
|
||||
$this->servicePath = 'gmail/v1/users/';
|
||||
$this->batchPath = 'batch/gmail/v1';
|
||||
$this->version = 'v1';
|
||||
$this->serviceName = 'gmail';
|
||||
|
||||
@ -110,7 +109,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
array(
|
||||
'methods' => array(
|
||||
'getProfile' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/profile',
|
||||
'path' => '{userId}/profile',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -120,7 +119,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'stop' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/stop',
|
||||
'path' => '{userId}/stop',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -130,7 +129,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'watch' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/watch',
|
||||
'path' => '{userId}/watch',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -150,7 +149,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
array(
|
||||
'methods' => array(
|
||||
'create' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/drafts',
|
||||
'path' => '{userId}/drafts',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -160,7 +159,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'delete' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/drafts/{id}',
|
||||
'path' => '{userId}/drafts/{id}',
|
||||
'httpMethod' => 'DELETE',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -175,7 +174,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'get' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/drafts/{id}',
|
||||
'path' => '{userId}/drafts/{id}',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -194,7 +193,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'list' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/drafts',
|
||||
'path' => '{userId}/drafts',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -206,6 +205,10 @@ class Google_Service_Gmail extends Google_Service
|
||||
'location' => 'query',
|
||||
'type' => 'boolean',
|
||||
),
|
||||
'maxResults' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'integer',
|
||||
),
|
||||
'pageToken' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
@ -214,13 +217,9 @@ class Google_Service_Gmail extends Google_Service
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
),
|
||||
'maxResults' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'integer',
|
||||
),
|
||||
),
|
||||
),'send' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/drafts/send',
|
||||
'path' => '{userId}/drafts/send',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -230,7 +229,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'update' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/drafts/{id}',
|
||||
'path' => '{userId}/drafts/{id}',
|
||||
'httpMethod' => 'PUT',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -255,7 +254,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
array(
|
||||
'methods' => array(
|
||||
'list' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/history',
|
||||
'path' => '{userId}/history',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -263,9 +262,10 @@ class Google_Service_Gmail extends Google_Service
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
),
|
||||
'pageToken' => array(
|
||||
'historyTypes' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
'repeated' => true,
|
||||
),
|
||||
'labelId' => array(
|
||||
'location' => 'query',
|
||||
@ -275,10 +275,9 @@ class Google_Service_Gmail extends Google_Service
|
||||
'location' => 'query',
|
||||
'type' => 'integer',
|
||||
),
|
||||
'historyTypes' => array(
|
||||
'pageToken' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
'repeated' => true,
|
||||
),
|
||||
'startHistoryId' => array(
|
||||
'location' => 'query',
|
||||
@ -296,7 +295,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
array(
|
||||
'methods' => array(
|
||||
'create' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/labels',
|
||||
'path' => '{userId}/labels',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -306,7 +305,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'delete' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/labels/{id}',
|
||||
'path' => '{userId}/labels/{id}',
|
||||
'httpMethod' => 'DELETE',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -321,7 +320,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'get' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/labels/{id}',
|
||||
'path' => '{userId}/labels/{id}',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -336,7 +335,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'list' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/labels',
|
||||
'path' => '{userId}/labels',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -346,7 +345,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'patch' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/labels/{id}',
|
||||
'path' => '{userId}/labels/{id}',
|
||||
'httpMethod' => 'PATCH',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -361,7 +360,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'update' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/labels/{id}',
|
||||
'path' => '{userId}/labels/{id}',
|
||||
'httpMethod' => 'PUT',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -386,7 +385,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
array(
|
||||
'methods' => array(
|
||||
'batchDelete' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/messages/batchDelete',
|
||||
'path' => '{userId}/messages/batchDelete',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -396,7 +395,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'batchModify' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/messages/batchModify',
|
||||
'path' => '{userId}/messages/batchModify',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -406,7 +405,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'delete' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/messages/{id}',
|
||||
'path' => '{userId}/messages/{id}',
|
||||
'httpMethod' => 'DELETE',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -421,7 +420,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'get' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/messages/{id}',
|
||||
'path' => '{userId}/messages/{id}',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -434,18 +433,18 @@ class Google_Service_Gmail extends Google_Service
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
),
|
||||
'format' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
),
|
||||
'metadataHeaders' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
'repeated' => true,
|
||||
),
|
||||
'format' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
),'import' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/messages/import',
|
||||
'path' => '{userId}/messages/import',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -453,7 +452,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
),
|
||||
'processForCalendar' => array(
|
||||
'deleted' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'boolean',
|
||||
),
|
||||
@ -465,13 +464,13 @@ class Google_Service_Gmail extends Google_Service
|
||||
'location' => 'query',
|
||||
'type' => 'boolean',
|
||||
),
|
||||
'deleted' => array(
|
||||
'processForCalendar' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'boolean',
|
||||
),
|
||||
),
|
||||
),'insert' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/messages',
|
||||
'path' => '{userId}/messages',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -479,17 +478,17 @@ class Google_Service_Gmail extends Google_Service
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
),
|
||||
'internalDateSource' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
),
|
||||
'deleted' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'boolean',
|
||||
),
|
||||
'internalDateSource' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
),'list' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/messages',
|
||||
'path' => '{userId}/messages',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -501,26 +500,26 @@ class Google_Service_Gmail extends Google_Service
|
||||
'location' => 'query',
|
||||
'type' => 'boolean',
|
||||
),
|
||||
'pageToken' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
),
|
||||
'labelIds' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
'repeated' => true,
|
||||
),
|
||||
'q' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
),
|
||||
'maxResults' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'integer',
|
||||
),
|
||||
'pageToken' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
),
|
||||
'q' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
),'modify' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/messages/{id}/modify',
|
||||
'path' => '{userId}/messages/{id}/modify',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -535,7 +534,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'send' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/messages/send',
|
||||
'path' => '{userId}/messages/send',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -545,7 +544,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'trash' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/messages/{id}/trash',
|
||||
'path' => '{userId}/messages/{id}/trash',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -560,7 +559,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'untrash' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/messages/{id}/untrash',
|
||||
'path' => '{userId}/messages/{id}/untrash',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -585,7 +584,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
array(
|
||||
'methods' => array(
|
||||
'get' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/messages/{messageId}/attachments/{id}',
|
||||
'path' => '{userId}/messages/{messageId}/attachments/{id}',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -615,7 +614,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
array(
|
||||
'methods' => array(
|
||||
'getAutoForwarding' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/autoForwarding',
|
||||
'path' => '{userId}/settings/autoForwarding',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -625,7 +624,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'getImap' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/imap',
|
||||
'path' => '{userId}/settings/imap',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -635,7 +634,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'getLanguage' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/language',
|
||||
'path' => '{userId}/settings/language',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -645,7 +644,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'getPop' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/pop',
|
||||
'path' => '{userId}/settings/pop',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -655,7 +654,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'getVacation' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/vacation',
|
||||
'path' => '{userId}/settings/vacation',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -665,7 +664,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'updateAutoForwarding' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/autoForwarding',
|
||||
'path' => '{userId}/settings/autoForwarding',
|
||||
'httpMethod' => 'PUT',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -675,7 +674,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'updateImap' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/imap',
|
||||
'path' => '{userId}/settings/imap',
|
||||
'httpMethod' => 'PUT',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -685,7 +684,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'updateLanguage' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/language',
|
||||
'path' => '{userId}/settings/language',
|
||||
'httpMethod' => 'PUT',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -695,7 +694,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'updatePop' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/pop',
|
||||
'path' => '{userId}/settings/pop',
|
||||
'httpMethod' => 'PUT',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -705,7 +704,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'updateVacation' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/vacation',
|
||||
'path' => '{userId}/settings/vacation',
|
||||
'httpMethod' => 'PUT',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -725,7 +724,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
array(
|
||||
'methods' => array(
|
||||
'create' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/delegates',
|
||||
'path' => '{userId}/settings/delegates',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -735,7 +734,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'delete' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/delegates/{delegateEmail}',
|
||||
'path' => '{userId}/settings/delegates/{delegateEmail}',
|
||||
'httpMethod' => 'DELETE',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -750,7 +749,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'get' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/delegates/{delegateEmail}',
|
||||
'path' => '{userId}/settings/delegates/{delegateEmail}',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -765,7 +764,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'list' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/delegates',
|
||||
'path' => '{userId}/settings/delegates',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -785,7 +784,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
array(
|
||||
'methods' => array(
|
||||
'create' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/filters',
|
||||
'path' => '{userId}/settings/filters',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -795,7 +794,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'delete' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/filters/{id}',
|
||||
'path' => '{userId}/settings/filters/{id}',
|
||||
'httpMethod' => 'DELETE',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -810,7 +809,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'get' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/filters/{id}',
|
||||
'path' => '{userId}/settings/filters/{id}',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -825,7 +824,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'list' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/filters',
|
||||
'path' => '{userId}/settings/filters',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -845,7 +844,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
array(
|
||||
'methods' => array(
|
||||
'create' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/forwardingAddresses',
|
||||
'path' => '{userId}/settings/forwardingAddresses',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -855,7 +854,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'delete' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/forwardingAddresses/{forwardingEmail}',
|
||||
'path' => '{userId}/settings/forwardingAddresses/{forwardingEmail}',
|
||||
'httpMethod' => 'DELETE',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -870,7 +869,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'get' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/forwardingAddresses/{forwardingEmail}',
|
||||
'path' => '{userId}/settings/forwardingAddresses/{forwardingEmail}',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -885,7 +884,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'list' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/forwardingAddresses',
|
||||
'path' => '{userId}/settings/forwardingAddresses',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -905,7 +904,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
array(
|
||||
'methods' => array(
|
||||
'create' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/sendAs',
|
||||
'path' => '{userId}/settings/sendAs',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -915,7 +914,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'delete' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}',
|
||||
'path' => '{userId}/settings/sendAs/{sendAsEmail}',
|
||||
'httpMethod' => 'DELETE',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -930,7 +929,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'get' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}',
|
||||
'path' => '{userId}/settings/sendAs/{sendAsEmail}',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -945,7 +944,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'list' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/sendAs',
|
||||
'path' => '{userId}/settings/sendAs',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -955,7 +954,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'patch' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}',
|
||||
'path' => '{userId}/settings/sendAs/{sendAsEmail}',
|
||||
'httpMethod' => 'PATCH',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -970,7 +969,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'update' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}',
|
||||
'path' => '{userId}/settings/sendAs/{sendAsEmail}',
|
||||
'httpMethod' => 'PUT',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -985,7 +984,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'verify' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/verify',
|
||||
'path' => '{userId}/settings/sendAs/{sendAsEmail}/verify',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -1010,7 +1009,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
array(
|
||||
'methods' => array(
|
||||
'delete' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}',
|
||||
'path' => '{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}',
|
||||
'httpMethod' => 'DELETE',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -1030,7 +1029,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'get' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}',
|
||||
'path' => '{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -1050,7 +1049,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'insert' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo',
|
||||
'path' => '{userId}/settings/sendAs/{sendAsEmail}/smimeInfo',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -1065,7 +1064,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'list' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo',
|
||||
'path' => '{userId}/settings/sendAs/{sendAsEmail}/smimeInfo',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -1080,7 +1079,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'setDefault' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}/setDefault',
|
||||
'path' => '{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}/setDefault',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -1110,7 +1109,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
array(
|
||||
'methods' => array(
|
||||
'delete' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/threads/{id}',
|
||||
'path' => '{userId}/threads/{id}',
|
||||
'httpMethod' => 'DELETE',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -1125,7 +1124,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'get' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/threads/{id}',
|
||||
'path' => '{userId}/threads/{id}',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -1138,18 +1137,18 @@ class Google_Service_Gmail extends Google_Service
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
),
|
||||
'format' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
),
|
||||
'metadataHeaders' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
'repeated' => true,
|
||||
),
|
||||
'format' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
),'list' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/threads',
|
||||
'path' => '{userId}/threads',
|
||||
'httpMethod' => 'GET',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -1157,30 +1156,30 @@ class Google_Service_Gmail extends Google_Service
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
),
|
||||
'pageToken' => array(
|
||||
'includeSpamTrash' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
'type' => 'boolean',
|
||||
),
|
||||
'labelIds' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
'repeated' => true,
|
||||
),
|
||||
'q' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
),
|
||||
'maxResults' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'integer',
|
||||
),
|
||||
'includeSpamTrash' => array(
|
||||
'pageToken' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'boolean',
|
||||
'type' => 'string',
|
||||
),
|
||||
'q' => array(
|
||||
'location' => 'query',
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
),'modify' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/threads/{id}/modify',
|
||||
'path' => '{userId}/threads/{id}/modify',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -1195,7 +1194,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'trash' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/threads/{id}/trash',
|
||||
'path' => '{userId}/threads/{id}/trash',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
@ -1210,7 +1209,7 @@ class Google_Service_Gmail extends Google_Service
|
||||
),
|
||||
),
|
||||
),'untrash' => array(
|
||||
'path' => 'gmail/v1/users/{userId}/threads/{id}/untrash',
|
||||
'path' => '{userId}/threads/{id}/untrash',
|
||||
'httpMethod' => 'POST',
|
||||
'parameters' => array(
|
||||
'userId' => array(
|
||||
|
@ -81,12 +81,12 @@ class Google_Service_Gmail_Resource_UsersDrafts extends Google_Service_Resource
|
||||
*
|
||||
* @opt_param bool includeSpamTrash Include drafts from SPAM and TRASH in the
|
||||
* results.
|
||||
* @opt_param string maxResults Maximum number of drafts to return.
|
||||
* @opt_param string pageToken Page token to retrieve a specific page of results
|
||||
* in the list.
|
||||
* @opt_param string q Only return draft messages matching the specified query.
|
||||
* Supports the same query format as the Gmail search box. For example,
|
||||
* "from:someuser@example.com rfc822msgid: is:unread".
|
||||
* @opt_param string maxResults Maximum number of drafts to return.
|
||||
* @return Google_Service_Gmail_ListDraftsResponse
|
||||
*/
|
||||
public function listUsersDrafts($userId, $optParams = array())
|
||||
|
@ -34,11 +34,11 @@ class Google_Service_Gmail_Resource_UsersHistory extends Google_Service_Resource
|
||||
* used to indicate the authenticated user.
|
||||
* @param array $optParams Optional parameters.
|
||||
*
|
||||
* @opt_param string pageToken Page token to retrieve a specific page of results
|
||||
* in the list.
|
||||
* @opt_param string historyTypes History types to be returned by the function
|
||||
* @opt_param string labelId Only return messages with a label matching the ID.
|
||||
* @opt_param string maxResults The maximum number of history records to return.
|
||||
* @opt_param string historyTypes History types to be returned by the function
|
||||
* @opt_param string pageToken Page token to retrieve a specific page of results
|
||||
* in the list.
|
||||
* @opt_param string startHistoryId Required. Returns history records after the
|
||||
* specified startHistoryId. The supplied startHistoryId should be obtained from
|
||||
* the historyId of a message, thread, or previous list response. History IDs
|
||||
|
@ -85,7 +85,8 @@ class Google_Service_Gmail_Resource_UsersLabels extends Google_Service_Resource
|
||||
return $this->call('list', array($params), "Google_Service_Gmail_ListLabelsResponse");
|
||||
}
|
||||
/**
|
||||
* Patch the specified label. (labels.patch)
|
||||
* Updates the specified label. This method supports patch semantics.
|
||||
* (labels.patch)
|
||||
*
|
||||
* @param string $userId The user's email address. The special value me can be
|
||||
* used to indicate the authenticated user.
|
||||
|
@ -77,9 +77,9 @@ class Google_Service_Gmail_Resource_UsersMessages extends Google_Service_Resourc
|
||||
* @param string $id The ID of the message to retrieve.
|
||||
* @param array $optParams Optional parameters.
|
||||
*
|
||||
* @opt_param string format The format to return the message in.
|
||||
* @opt_param string metadataHeaders When given and format is METADATA, only
|
||||
* include headers specified.
|
||||
* @opt_param string format The format to return the message in.
|
||||
* @return Google_Service_Gmail_Message
|
||||
*/
|
||||
public function get($userId, $id, $optParams = array())
|
||||
@ -98,15 +98,15 @@ class Google_Service_Gmail_Resource_UsersMessages extends Google_Service_Resourc
|
||||
* @param Google_Service_Gmail_Message $postBody
|
||||
* @param array $optParams Optional parameters.
|
||||
*
|
||||
* @opt_param bool processForCalendar Process calendar invites in the email and
|
||||
* add any extracted meetings to the Google Calendar for this user.
|
||||
* @opt_param bool deleted Mark the email as permanently deleted (not TRASH) and
|
||||
* only visible in Google Vault to a Vault administrator. Only used for G Suite
|
||||
* accounts.
|
||||
* @opt_param string internalDateSource Source for Gmail's internal date of the
|
||||
* message.
|
||||
* @opt_param bool neverMarkSpam Ignore the Gmail spam classifier decision and
|
||||
* never mark this email as SPAM in the mailbox.
|
||||
* @opt_param bool deleted Mark the email as permanently deleted (not TRASH) and
|
||||
* only visible in Google Vault to a Vault administrator. Only used for G Suite
|
||||
* accounts.
|
||||
* @opt_param bool processForCalendar Process calendar invites in the email and
|
||||
* add any extracted meetings to the Google Calendar for this user.
|
||||
* @return Google_Service_Gmail_Message
|
||||
*/
|
||||
public function import($userId, Google_Service_Gmail_Message $postBody, $optParams = array())
|
||||
@ -125,11 +125,11 @@ class Google_Service_Gmail_Resource_UsersMessages extends Google_Service_Resourc
|
||||
* @param Google_Service_Gmail_Message $postBody
|
||||
* @param array $optParams Optional parameters.
|
||||
*
|
||||
* @opt_param string internalDateSource Source for Gmail's internal date of the
|
||||
* message.
|
||||
* @opt_param bool deleted Mark the email as permanently deleted (not TRASH) and
|
||||
* only visible in Google Vault to a Vault administrator. Only used for G Suite
|
||||
* accounts.
|
||||
* @opt_param string internalDateSource Source for Gmail's internal date of the
|
||||
* message.
|
||||
* @return Google_Service_Gmail_Message
|
||||
*/
|
||||
public function insert($userId, Google_Service_Gmail_Message $postBody, $optParams = array())
|
||||
@ -147,16 +147,15 @@ class Google_Service_Gmail_Resource_UsersMessages extends Google_Service_Resourc
|
||||
*
|
||||
* @opt_param bool includeSpamTrash Include messages from SPAM and TRASH in the
|
||||
* results.
|
||||
* @opt_param string pageToken Page token to retrieve a specific page of results
|
||||
* in the list.
|
||||
* @opt_param string labelIds Only return messages with labels that match all of
|
||||
* the specified label IDs.
|
||||
* @opt_param string maxResults Maximum number of messages to return.
|
||||
* @opt_param string pageToken Page token to retrieve a specific page of results
|
||||
* in the list.
|
||||
* @opt_param string q Only return messages matching the specified query.
|
||||
* Supports the same query format as the Gmail search box. For example,
|
||||
* "from:someuser@example.com rfc822msgid:somemsgid@example.com is:unread".
|
||||
* Parameter cannot be used when accessing the api using the gmail.metadata
|
||||
* scope.
|
||||
* @opt_param string maxResults Maximum number of messages to return.
|
||||
* "from:someuser@example.com rfc822msgid: is:unread". Parameter cannot be used
|
||||
* when accessing the api using the gmail.metadata scope.
|
||||
* @return Google_Service_Gmail_ListMessagesResponse
|
||||
*/
|
||||
public function listUsersMessages($userId, $optParams = array())
|
||||
|
@ -27,8 +27,8 @@ class Google_Service_Gmail_Resource_UsersSettingsDelegates extends Google_Servic
|
||||
{
|
||||
/**
|
||||
* Adds a delegate with its verification status set directly to accepted,
|
||||
* without sending any verification email. The delegate user must be a member
|
||||
* of the same G Suite organization as the delegator user.
|
||||
* without sending any verification email. The delegate user must be a member of
|
||||
* the same G Suite organization as the delegator user.
|
||||
*
|
||||
* Gmail imposes limitations on the number of delegates and delegators each user
|
||||
* in a G Suite organization can have. These limits depend on your organization,
|
||||
|
@ -31,8 +31,8 @@ class Google_Service_Gmail_Resource_UsersSettingsSendAs extends Google_Service_R
|
||||
* before creating the alias. If ownership verification is required for the
|
||||
* alias, a message will be sent to the email address and the resource's
|
||||
* verification status will be set to pending; otherwise, the resource will be
|
||||
* created with verification status set to accepted. If a signature is
|
||||
* provided, Gmail will sanitize the HTML before saving it with the alias.
|
||||
* created with verification status set to accepted. If a signature is provided,
|
||||
* Gmail will sanitize the HTML before saving it with the alias.
|
||||
*
|
||||
* This method is only available to service account clients that have been
|
||||
* delegated domain-wide authority. (sendAs.create)
|
||||
@ -100,7 +100,12 @@ class Google_Service_Gmail_Resource_UsersSettingsSendAs extends Google_Service_R
|
||||
return $this->call('list', array($params), "Google_Service_Gmail_ListSendAsResponse");
|
||||
}
|
||||
/**
|
||||
* Patch the specified send-as alias. (sendAs.patch)
|
||||
* Updates a send-as alias. If a signature is provided, Gmail will sanitize the
|
||||
* HTML before saving it with the alias.
|
||||
*
|
||||
* Addresses other than the primary address for the account can only be updated
|
||||
* by service account clients that have been delegated domain-wide authority.
|
||||
* This method supports patch semantics. (sendAs.patch)
|
||||
*
|
||||
* @param string $userId User's email address. The special value "me" can be
|
||||
* used to indicate the authenticated user.
|
||||
|
@ -48,9 +48,9 @@ class Google_Service_Gmail_Resource_UsersThreads extends Google_Service_Resource
|
||||
* @param string $id The ID of the thread to retrieve.
|
||||
* @param array $optParams Optional parameters.
|
||||
*
|
||||
* @opt_param string format The format to return the messages in.
|
||||
* @opt_param string metadataHeaders When given and format is METADATA, only
|
||||
* include headers specified.
|
||||
* @opt_param string format The format to return the messages in.
|
||||
* @return Google_Service_Gmail_Thread
|
||||
*/
|
||||
public function get($userId, $id, $optParams = array())
|
||||
@ -66,17 +66,17 @@ class Google_Service_Gmail_Resource_UsersThreads extends Google_Service_Resource
|
||||
* used to indicate the authenticated user.
|
||||
* @param array $optParams Optional parameters.
|
||||
*
|
||||
* @opt_param string pageToken Page token to retrieve a specific page of results
|
||||
* in the list.
|
||||
* @opt_param bool includeSpamTrash Include threads from SPAM and TRASH in the
|
||||
* results.
|
||||
* @opt_param string labelIds Only return threads with labels that match all of
|
||||
* the specified label IDs.
|
||||
* @opt_param string maxResults Maximum number of threads to return.
|
||||
* @opt_param string pageToken Page token to retrieve a specific page of results
|
||||
* in the list.
|
||||
* @opt_param string q Only return threads matching the specified query.
|
||||
* Supports the same query format as the Gmail search box. For example,
|
||||
* "from:someuser@example.com rfc822msgid: is:unread". Parameter cannot be used
|
||||
* when accessing the api using the gmail.metadata scope.
|
||||
* @opt_param string maxResults Maximum number of threads to return.
|
||||
* @opt_param bool includeSpamTrash Include threads from SPAM and TRASH in the
|
||||
* results.
|
||||
* @return Google_Service_Gmail_ListThreadsResponse
|
||||
*/
|
||||
public function listUsersThreads($userId, $optParams = array())
|
||||
|
@ -82,22 +82,19 @@ class AccessToken
|
||||
* accepted. By default, the id token must have been issued to this OAuth2 client.
|
||||
*
|
||||
* @param string $token The JSON Web Token to be verified.
|
||||
* @param array $options [optional] {
|
||||
* Configuration options.
|
||||
*
|
||||
* @type string $audience The indended recipient of the token.
|
||||
* @type string $issuer The intended issuer of the token.
|
||||
* @type string $certsLocation The location (remote or local) from which
|
||||
* @param array $options [optional] Configuration options.
|
||||
* @param string $options.audience The indended recipient of the token.
|
||||
* @param string $options.issuer The intended issuer of the token.
|
||||
* @param string $options.cacheKey The cache key of the cached certs. Defaults to
|
||||
* the sha1 of $certsLocation if provided, otherwise is set to
|
||||
* "federated_signon_certs_v3".
|
||||
* @param string $options.certsLocation The location (remote or local) from which
|
||||
* to retrieve certificates, if not cached. This value should only be
|
||||
* provided in limited circumstances in which you are sure of the
|
||||
* behavior.
|
||||
* @type string $cacheKey The cache key of the cached certs. Defaults to
|
||||
* the sha1 of $certsLocation if provided, otherwise is set to
|
||||
* "federated_signon_certs_v3".
|
||||
* @type bool $throwException Whether the function should throw an
|
||||
* @param bool $options.throwException Whether the function should throw an
|
||||
* exception if the verification fails. This is useful for
|
||||
* determining the reason verification failed.
|
||||
* }
|
||||
* @return array|bool the token payload, if successful, or false if not.
|
||||
* @throws InvalidArgumentException If certs could not be retrieved from a local file.
|
||||
* @throws InvalidArgumentException If received certs are in an invalid format.
|
||||
@ -129,7 +126,8 @@ class AccessToken
|
||||
$alg = $this->determineAlg($certs);
|
||||
if (!in_array($alg, ['RS256', 'ES256'])) {
|
||||
throw new InvalidArgumentException(
|
||||
'unrecognized "alg" in certs, expected ES256 or RS256');
|
||||
'unrecognized "alg" in certs, expected ES256 or RS256'
|
||||
);
|
||||
}
|
||||
try {
|
||||
if ($alg == 'RS256') {
|
||||
@ -188,11 +186,9 @@ class AccessToken
|
||||
* @param array $certs Certificate array according to the JWK spec (see
|
||||
* https://tools.ietf.org/html/rfc7517).
|
||||
* @param string|null $audience If set, returns false if the provided
|
||||
* audience does not match the "aud" claim on
|
||||
* the JWT.
|
||||
* audience does not match the "aud" claim on the JWT.
|
||||
* @param string|null $issuer If set, returns false if the provided
|
||||
* issuer does not match the "iss" claim on
|
||||
* the JWT.
|
||||
* issuer does not match the "iss" claim on the JWT.
|
||||
* @return array|bool the token payload, if successful, or false if not.
|
||||
*/
|
||||
private function verifyEs256($token, array $certs, $audience = null, $issuer = null)
|
||||
@ -230,11 +226,9 @@ class AccessToken
|
||||
* @param array $certs Certificate array according to the JWK spec (see
|
||||
* https://tools.ietf.org/html/rfc7517).
|
||||
* @param string|null $audience If set, returns false if the provided
|
||||
* audience does not match the "aud" claim on
|
||||
* the JWT.
|
||||
* audience does not match the "aud" claim on the JWT.
|
||||
* @param string|null $issuer If set, returns false if the provided
|
||||
* issuer does not match the "iss" claim on
|
||||
* the JWT.
|
||||
* issuer does not match the "iss" claim on the JWT.
|
||||
* @return array|bool the token payload, if successful, or false if not.
|
||||
*/
|
||||
private function verifyRs256($token, array $certs, $audience = null, $issuer = null)
|
||||
@ -325,6 +319,7 @@ class AccessToken
|
||||
* are PEM encoded certificates.
|
||||
*
|
||||
* @param string $location The location from which to retrieve certs.
|
||||
* @param string $cacheKey The key under which to cache the retrieved certs.
|
||||
* @param array $options [optional] Configuration options.
|
||||
* @return array
|
||||
* @throws InvalidArgumentException If received certs are in an invalid format.
|
||||
|
@ -46,6 +46,7 @@ use Psr\Cache\CacheItemPoolInterface;
|
||||
*
|
||||
* This allows it to be used as follows with GuzzleHttp\Client:
|
||||
*
|
||||
* ```
|
||||
* use Google\Auth\ApplicationDefaultCredentials;
|
||||
* use GuzzleHttp\Client;
|
||||
* use GuzzleHttp\HandlerStack;
|
||||
@ -63,6 +64,7 @@ use Psr\Cache\CacheItemPoolInterface;
|
||||
* ]);
|
||||
*
|
||||
* $res = $client->get('myproject/taskqueues/myqueue');
|
||||
* ```
|
||||
*/
|
||||
class ApplicationDefaultCredentials
|
||||
{
|
||||
@ -77,10 +79,9 @@ class ApplicationDefaultCredentials
|
||||
* either as an Array or as a space-delimited String.
|
||||
* @param callable $httpHandler callback which delivers psr7 request
|
||||
* @param array $cacheConfig configuration for the cache when it's present
|
||||
* @param CacheItemPoolInterface $cache an implementation of CacheItemPoolInterface
|
||||
*
|
||||
* @param CacheItemPoolInterface $cache A cache implementation, may be
|
||||
* provided if you have one already available for use.
|
||||
* @return AuthTokenSubscriber
|
||||
*
|
||||
* @throws DomainException if no implementation can be obtained.
|
||||
*/
|
||||
public static function getSubscriber(
|
||||
@ -105,10 +106,9 @@ class ApplicationDefaultCredentials
|
||||
* either as an Array or as a space-delimited String.
|
||||
* @param callable $httpHandler callback which delivers psr7 request
|
||||
* @param array $cacheConfig configuration for the cache when it's present
|
||||
* @param CacheItemPoolInterface $cache
|
||||
*
|
||||
* @param CacheItemPoolInterface $cache A cache implementation, may be
|
||||
* provided if you have one already available for use.
|
||||
* @return AuthTokenMiddleware
|
||||
*
|
||||
* @throws DomainException if no implementation can be obtained.
|
||||
*/
|
||||
public static function getMiddleware(
|
||||
@ -134,17 +134,20 @@ class ApplicationDefaultCredentials
|
||||
* either as an Array or as a space-delimited String.
|
||||
* @param callable $httpHandler callback which delivers psr7 request
|
||||
* @param array $cacheConfig configuration for the cache when it's present
|
||||
* @param CacheItemPoolInterface $cache
|
||||
* @param CacheItemPoolInterface $cache A cache implementation, may be
|
||||
* provided if you have one already available for use.
|
||||
* @param string $quotaProject specifies a project to bill for access
|
||||
* charges associated with the request.
|
||||
*
|
||||
* @return CredentialsLoader
|
||||
*
|
||||
* @throws DomainException if no implementation can be obtained.
|
||||
*/
|
||||
public static function getCredentials(
|
||||
$scope = null,
|
||||
callable $httpHandler = null,
|
||||
array $cacheConfig = null,
|
||||
CacheItemPoolInterface $cache = null
|
||||
CacheItemPoolInterface $cache = null,
|
||||
$quotaProject = null
|
||||
) {
|
||||
$creds = null;
|
||||
$jsonKey = CredentialsLoader::fromEnv()
|
||||
@ -160,11 +163,12 @@ class ApplicationDefaultCredentials
|
||||
}
|
||||
|
||||
if (!is_null($jsonKey)) {
|
||||
$jsonKey['quota_project'] = $quotaProject;
|
||||
$creds = CredentialsLoader::makeCredentials($scope, $jsonKey);
|
||||
} elseif (AppIdentityCredentials::onAppEngine() && !GCECredentials::onAppEngineFlexible()) {
|
||||
$creds = new AppIdentityCredentials($scope);
|
||||
} elseif (GCECredentials::onGce($httpHandler)) {
|
||||
$creds = new GCECredentials(null, $scope);
|
||||
$creds = new GCECredentials(null, $scope, null, $quotaProject);
|
||||
}
|
||||
|
||||
if (is_null($creds)) {
|
||||
@ -187,10 +191,9 @@ class ApplicationDefaultCredentials
|
||||
* @param string $targetAudience The audience for the ID token.
|
||||
* @param callable $httpHandler callback which delivers psr7 request
|
||||
* @param array $cacheConfig configuration for the cache when it's present
|
||||
* @param CacheItemPoolInterface $cache
|
||||
*
|
||||
* @param CacheItemPoolInterface $cache A cache implementation, may be
|
||||
* provided if you have one already available for use.
|
||||
* @return AuthTokenMiddleware
|
||||
*
|
||||
* @throws DomainException if no implementation can be obtained.
|
||||
*/
|
||||
public static function getIdTokenMiddleware(
|
||||
@ -198,7 +201,6 @@ class ApplicationDefaultCredentials
|
||||
callable $httpHandler = null,
|
||||
array $cacheConfig = null,
|
||||
CacheItemPoolInterface $cache = null
|
||||
|
||||
) {
|
||||
$creds = self::getIdTokenCredentials($targetAudience, $httpHandler, $cacheConfig, $cache);
|
||||
|
||||
@ -213,10 +215,9 @@ class ApplicationDefaultCredentials
|
||||
* @param string $targetAudience The audience for the ID token.
|
||||
* @param callable $httpHandler callback which delivers psr7 request
|
||||
* @param array $cacheConfig configuration for the cache when it's present
|
||||
* @param CacheItemPoolInterface $cache
|
||||
*
|
||||
* @param CacheItemPoolInterface $cache A cache implementation, may be
|
||||
* provided if you have one already available for use.
|
||||
* @return CredentialsLoader
|
||||
*
|
||||
* @throws DomainException if no implementation can be obtained.
|
||||
* @throws InvalidArgumentException if JSON "type" key is invalid
|
||||
*/
|
||||
|
@ -62,22 +62,22 @@ class SysVCacheItemPool implements CacheItemPoolInterface
|
||||
/**
|
||||
* Create a SystemV shared memory based CacheItemPool.
|
||||
*
|
||||
* @param array $options [optional] {
|
||||
* Configuration options.
|
||||
*
|
||||
* @type int $variableKey The variable key for getting the data from
|
||||
* @param array $options [optional] Configuration options.
|
||||
* @param int $options.variableKey The variable key for getting the data from
|
||||
* the shared memory. **Defaults to** 1.
|
||||
* @type string $proj The project identifier for ftok. This needs to
|
||||
* @param $options.proj string The project identifier for ftok. This needs to
|
||||
* be a one character string. **Defaults to** 'A'.
|
||||
* @type int $memsize The memory size in bytes for shm_attach.
|
||||
* @param $options.memsize int The memory size in bytes for shm_attach.
|
||||
* **Defaults to** 10000.
|
||||
* @type int $perm The permission for shm_attach. **Defaults to** 0600.
|
||||
* @param $options.perm int The permission for shm_attach. **Defaults to**
|
||||
* 0600.
|
||||
*/
|
||||
public function __construct($options = [])
|
||||
{
|
||||
if (! extension_loaded('sysvshm')) {
|
||||
throw new \RuntimeException(
|
||||
'sysvshm extension is required to use this ItemPool');
|
||||
'sysvshm extension is required to use this ItemPool'
|
||||
);
|
||||
}
|
||||
$this->options = $options + [
|
||||
'variableKey' => self::VAR_KEY,
|
||||
@ -90,9 +90,6 @@ class SysVCacheItemPool implements CacheItemPoolInterface
|
||||
$this->sysvKey = ftok(__FILE__, $this->options['proj']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getItem($key)
|
||||
{
|
||||
$this->loadItems();
|
||||
|
@ -90,7 +90,7 @@ class AppIdentityCredentials extends CredentialsLoader implements
|
||||
* SERVER_SOFTWARE environment variable (prod) or the APPENGINE_RUNTIME
|
||||
* environment variable (dev).
|
||||
*
|
||||
* @return true if this an App Engine Instance, false otherwise
|
||||
* @return bool true if this an App Engine Instance, false otherwise
|
||||
*/
|
||||
public static function onAppEngine()
|
||||
{
|
||||
@ -115,7 +115,6 @@ class AppIdentityCredentials extends CredentialsLoader implements
|
||||
* the GuzzleHttp\ClientInterface instance passed in will not be used.
|
||||
*
|
||||
* @param callable $httpHandler callback which delivers psr7 request
|
||||
*
|
||||
* @return array A set of auth related metadata, containing the following
|
||||
* keys:
|
||||
* - access_token (string)
|
||||
|
@ -18,6 +18,7 @@
|
||||
namespace Google\Auth\Credentials;
|
||||
|
||||
use Google\Auth\CredentialsLoader;
|
||||
use Google\Auth\GetQuotaProjectInterface;
|
||||
use Google\Auth\HttpHandler\HttpClientCache;
|
||||
use Google\Auth\HttpHandler\HttpHandlerFactory;
|
||||
use Google\Auth\Iam;
|
||||
@ -55,9 +56,12 @@ use InvalidArgumentException;
|
||||
*/
|
||||
class GCECredentials extends CredentialsLoader implements
|
||||
SignBlobInterface,
|
||||
ProjectIdProviderInterface
|
||||
ProjectIdProviderInterface,
|
||||
GetQuotaProjectInterface
|
||||
{
|
||||
// phpcs:disable
|
||||
const cacheKey = 'GOOGLE_AUTH_PHP_GCE';
|
||||
// phpcs:enable
|
||||
|
||||
/**
|
||||
* The metadata IP address on appengine instances.
|
||||
@ -149,19 +153,27 @@ class GCECredentials extends CredentialsLoader implements
|
||||
*/
|
||||
private $targetAudience;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $quotaProject;
|
||||
|
||||
/**
|
||||
* @param Iam $iam [optional] An IAM instance.
|
||||
* @param string|array $scope [optional] the scope of the access request,
|
||||
* expressed either as an array or as a space-delimited string.
|
||||
* @param string $targetAudience [optional] The audience for the ID token.
|
||||
* @param string $quotaProject [optional] Specifies a project to bill for access
|
||||
* charges associated with the request.
|
||||
*/
|
||||
public function __construct(Iam $iam = null, $scope = null, $targetAudience = null)
|
||||
public function __construct(Iam $iam = null, $scope = null, $targetAudience = null, $quotaProject = null)
|
||||
{
|
||||
$this->iam = $iam;
|
||||
|
||||
if ($scope && $targetAudience) {
|
||||
throw new InvalidArgumentException(
|
||||
'Scope and targetAudience cannot both be supplied');
|
||||
'Scope and targetAudience cannot both be supplied'
|
||||
);
|
||||
}
|
||||
|
||||
$tokenUri = self::getTokenUri();
|
||||
@ -174,7 +186,8 @@ class GCECredentials extends CredentialsLoader implements
|
||||
|
||||
$tokenUri = $tokenUri . '?scopes='. $scope;
|
||||
} elseif ($targetAudience) {
|
||||
$tokenUri = sprintf('http://%s/computeMetadata/%s?audience=%s',
|
||||
$tokenUri = sprintf(
|
||||
'http://%s/computeMetadata/%s?audience=%s',
|
||||
self::METADATA_IP,
|
||||
self::ID_TOKEN_URI_PATH,
|
||||
$targetAudience
|
||||
@ -183,6 +196,7 @@ class GCECredentials extends CredentialsLoader implements
|
||||
}
|
||||
|
||||
$this->tokenUri = $tokenUri;
|
||||
$this->quotaProject = $quotaProject;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -225,7 +239,7 @@ class GCECredentials extends CredentialsLoader implements
|
||||
* Determines if this an App Engine Flexible instance, by accessing the
|
||||
* GAE_INSTANCE environment variable.
|
||||
*
|
||||
* @return true if this an App Engine Flexible Instance, false otherwise
|
||||
* @return bool true if this an App Engine Flexible Instance, false otherwise
|
||||
*/
|
||||
public static function onAppEngineFlexible()
|
||||
{
|
||||
@ -456,4 +470,14 @@ class GCECredentials extends CredentialsLoader implements
|
||||
|
||||
return (string) $resp->getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the quota project used for this API request
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getQuotaProject()
|
||||
{
|
||||
return $this->quotaProject;
|
||||
}
|
||||
}
|
||||
|
@ -43,11 +43,13 @@ class IAMCredentials
|
||||
{
|
||||
if (!is_string($selector)) {
|
||||
throw new \InvalidArgumentException(
|
||||
'selector must be a string');
|
||||
'selector must be a string'
|
||||
);
|
||||
}
|
||||
if (!is_string($token)) {
|
||||
throw new \InvalidArgumentException(
|
||||
'token must be a string');
|
||||
'token must be a string'
|
||||
);
|
||||
}
|
||||
|
||||
$this->selector = $selector;
|
||||
|
@ -112,18 +112,21 @@ class ServiceAccountCredentials extends CredentialsLoader implements
|
||||
}
|
||||
if (!array_key_exists('client_email', $jsonKey)) {
|
||||
throw new \InvalidArgumentException(
|
||||
'json key is missing the client_email field');
|
||||
'json key is missing the client_email field'
|
||||
);
|
||||
}
|
||||
if (!array_key_exists('private_key', $jsonKey)) {
|
||||
throw new \InvalidArgumentException(
|
||||
'json key is missing the private_key field');
|
||||
'json key is missing the private_key field'
|
||||
);
|
||||
}
|
||||
if (array_key_exists('quota_project', $jsonKey)) {
|
||||
$this->quotaProject = (string) $jsonKey['quota_project'];
|
||||
}
|
||||
if ($scope && $targetAudience) {
|
||||
throw new InvalidArgumentException(
|
||||
'Scope and targetAudience cannot both be supplied');
|
||||
'Scope and targetAudience cannot both be supplied'
|
||||
);
|
||||
}
|
||||
$additionalClaims = [];
|
||||
if ($targetAudience) {
|
||||
@ -199,7 +202,6 @@ class ServiceAccountCredentials extends CredentialsLoader implements
|
||||
* @param array $metadata metadata hashmap
|
||||
* @param string $authUri optional auth uri
|
||||
* @param callable $httpHandler callback which delivers psr7 request
|
||||
*
|
||||
* @return array updated metadata hashmap
|
||||
*/
|
||||
public function updateMetadata(
|
||||
|
@ -71,11 +71,13 @@ class ServiceAccountJwtAccessCredentials extends CredentialsLoader implements
|
||||
}
|
||||
if (!array_key_exists('client_email', $jsonKey)) {
|
||||
throw new \InvalidArgumentException(
|
||||
'json key is missing the client_email field');
|
||||
'json key is missing the client_email field'
|
||||
);
|
||||
}
|
||||
if (!array_key_exists('private_key', $jsonKey)) {
|
||||
throw new \InvalidArgumentException(
|
||||
'json key is missing the private_key field');
|
||||
'json key is missing the private_key field'
|
||||
);
|
||||
}
|
||||
if (array_key_exists('quota_project', $jsonKey)) {
|
||||
$this->quotaProject = (string) $jsonKey['quota_project'];
|
||||
@ -98,7 +100,6 @@ class ServiceAccountJwtAccessCredentials extends CredentialsLoader implements
|
||||
* @param array $metadata metadata hashmap
|
||||
* @param string $authUri optional auth uri
|
||||
* @param callable $httpHandler callback which delivers psr7 request
|
||||
*
|
||||
* @return array updated metadata hashmap
|
||||
*/
|
||||
public function updateMetadata(
|
||||
|
@ -74,15 +74,18 @@ class UserRefreshCredentials extends CredentialsLoader implements GetQuotaProjec
|
||||
}
|
||||
if (!array_key_exists('client_id', $jsonKey)) {
|
||||
throw new \InvalidArgumentException(
|
||||
'json key is missing the client_id field');
|
||||
'json key is missing the client_id field'
|
||||
);
|
||||
}
|
||||
if (!array_key_exists('client_secret', $jsonKey)) {
|
||||
throw new \InvalidArgumentException(
|
||||
'json key is missing the client_secret field');
|
||||
'json key is missing the client_secret field'
|
||||
);
|
||||
}
|
||||
if (!array_key_exists('refresh_token', $jsonKey)) {
|
||||
throw new \InvalidArgumentException(
|
||||
'json key is missing the refresh_token field');
|
||||
'json key is missing the refresh_token field'
|
||||
);
|
||||
}
|
||||
$this->auth = new OAuth2([
|
||||
'clientId' => $jsonKey['client_id'],
|
||||
@ -109,7 +112,8 @@ class UserRefreshCredentials extends CredentialsLoader implements GetQuotaProjec
|
||||
. 'To disable this warning, set '
|
||||
. self::SUPPRESS_CLOUD_SDK_CREDS_WARNING_ENV
|
||||
. ' environment variable to "true".',
|
||||
E_USER_WARNING);
|
||||
E_USER_WARNING
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ abstract class CredentialsLoader implements FetchAuthTokenInterface
|
||||
* variable GOOGLE_APPLICATION_CREDENTIALS. Return null if
|
||||
* GOOGLE_APPLICATION_CREDENTIALS is not specified.
|
||||
*
|
||||
* @return array JSON key | null
|
||||
* @return array|null JSON key | null
|
||||
*/
|
||||
public static function fromEnv()
|
||||
{
|
||||
@ -81,12 +81,13 @@ abstract class CredentialsLoader implements FetchAuthTokenInterface
|
||||
* Load a JSON key from a well known path.
|
||||
*
|
||||
* The well known path is OS dependent:
|
||||
* - windows: %APPDATA%/gcloud/application_default_credentials.json
|
||||
* - others: $HOME/.config/gcloud/application_default_credentials.json
|
||||
*
|
||||
* If the file does not exists, this returns null.
|
||||
* * windows: %APPDATA%/gcloud/application_default_credentials.json
|
||||
* * others: $HOME/.config/gcloud/application_default_credentials.json
|
||||
*
|
||||
* @return array JSON key | null
|
||||
* If the file does not exist, this returns null.
|
||||
*
|
||||
* @return array|null JSON key | null
|
||||
*/
|
||||
public static function fromWellKnownFile()
|
||||
{
|
||||
@ -110,7 +111,6 @@ abstract class CredentialsLoader implements FetchAuthTokenInterface
|
||||
* @param string|array $scope the scope of the access request, expressed
|
||||
* either as an Array or as a space-delimited String.
|
||||
* @param array $jsonKey the JSON credentials.
|
||||
*
|
||||
* @return ServiceAccountCredentials|UserRefreshCredentials
|
||||
*/
|
||||
public static function makeCredentials($scope, array $jsonKey)
|
||||
@ -134,10 +134,9 @@ abstract class CredentialsLoader implements FetchAuthTokenInterface
|
||||
* Create an authorized HTTP Client from an instance of FetchAuthTokenInterface.
|
||||
*
|
||||
* @param FetchAuthTokenInterface $fetcher is used to fetch the auth token
|
||||
* @param array $httpClientOptoins (optional) Array of request options to apply.
|
||||
* @param array $httpClientOptions (optional) Array of request options to apply.
|
||||
* @param callable $httpHandler (optional) http client to fetch the token.
|
||||
* @param callable $tokenCallback (optional) function to be called when a new token is fetched.
|
||||
*
|
||||
* @return \GuzzleHttp\Client
|
||||
*/
|
||||
public static function makeHttpClient(
|
||||
@ -203,7 +202,6 @@ abstract class CredentialsLoader implements FetchAuthTokenInterface
|
||||
* @param array $metadata metadata hashmap
|
||||
* @param string $authUri optional auth uri
|
||||
* @param callable $httpHandler callback which delivers psr7 request
|
||||
*
|
||||
* @return array updated metadata hashmap
|
||||
*/
|
||||
public function updateMetadata(
|
||||
|
@ -46,6 +46,11 @@ class FetchAuthTokenCache implements
|
||||
*/
|
||||
private $cache;
|
||||
|
||||
/**
|
||||
* @param FetchAuthTokenInterface $fetcher A credentials fetcher
|
||||
* @param array $cacheConfig Configuration for the cache
|
||||
* @param CacheItemPoolInterface $cache
|
||||
*/
|
||||
public function __construct(
|
||||
FetchAuthTokenInterface $fetcher,
|
||||
array $cacheConfig = null,
|
||||
@ -66,9 +71,7 @@ class FetchAuthTokenCache implements
|
||||
* from the supplied fetcher.
|
||||
*
|
||||
* @param callable $httpHandler callback which delivers psr7 request
|
||||
*
|
||||
* @return array the response
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function fetchAuthToken(callable $httpHandler = null)
|
||||
@ -125,7 +128,7 @@ class FetchAuthTokenCache implements
|
||||
* Sign a blob using the fetcher.
|
||||
*
|
||||
* @param string $stringToSign The string to sign.
|
||||
* @param bool $forceOpenssl Require use of OpenSSL for local signing. Does
|
||||
* @param bool $forceOpenSsl Require use of OpenSSL for local signing. Does
|
||||
* not apply to signing done using external services. **Defaults to**
|
||||
* `false`.
|
||||
* @return string The resulting signature.
|
||||
|
@ -26,7 +26,6 @@ interface FetchAuthTokenInterface
|
||||
* Fetches the auth tokens based on the current state.
|
||||
*
|
||||
* @param callable $httpHandler callback which delivers psr7 request
|
||||
*
|
||||
* @return array a hash of auth tokens
|
||||
*/
|
||||
public function fetchAuthToken(callable $httpHandler = null);
|
||||
|
@ -45,7 +45,6 @@ class Guzzle5HttpHandler
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param array $options
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function __invoke(RequestInterface $request, array $options = [])
|
||||
@ -62,7 +61,6 @@ class Guzzle5HttpHandler
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param array $options
|
||||
*
|
||||
* @return Promise
|
||||
*/
|
||||
public function async(RequestInterface $request, array $options = [])
|
||||
|
@ -26,7 +26,6 @@ class Guzzle6HttpHandler
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param array $options
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function __invoke(RequestInterface $request, array $options = [])
|
||||
@ -40,7 +39,7 @@ class Guzzle6HttpHandler
|
||||
* @param RequestInterface $request
|
||||
* @param array $options
|
||||
*
|
||||
* @return \GuzzleHttp\Promise\Promise
|
||||
* @return \GuzzleHttp\Promise\PromiseInterface
|
||||
*/
|
||||
public function async(RequestInterface $request, array $options = [])
|
||||
{
|
||||
|
@ -89,7 +89,6 @@ class AuthTokenMiddleware
|
||||
* $res = $client->get('myproject/taskqueues/myqueue');
|
||||
*
|
||||
* @param callable $handler
|
||||
*
|
||||
* @return \Closure
|
||||
*/
|
||||
public function __invoke(callable $handler)
|
||||
|
@ -76,7 +76,8 @@ class ScopedAccessTokenMiddleware
|
||||
$this->tokenFunc = $tokenFunc;
|
||||
if (!(is_string($scopes) || is_array($scopes))) {
|
||||
throw new \InvalidArgumentException(
|
||||
'wants scope should be string or array');
|
||||
'wants scope should be string or array'
|
||||
);
|
||||
}
|
||||
$this->scopes = $scopes;
|
||||
|
||||
@ -119,7 +120,6 @@ class ScopedAccessTokenMiddleware
|
||||
* $res = $client->get('myproject/taskqueues/myqueue');
|
||||
*
|
||||
* @param callable $handler
|
||||
*
|
||||
* @return \Closure
|
||||
*/
|
||||
public function __invoke(callable $handler)
|
||||
|
@ -71,7 +71,6 @@ class SimpleMiddleware
|
||||
* $res = $client->get('drive/v2/rest');
|
||||
*
|
||||
* @param callable $handler
|
||||
*
|
||||
* @return \Closure
|
||||
*/
|
||||
public function __invoke(callable $handler)
|
||||
|
@ -120,7 +120,7 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
* The scope of the access request, expressed either as an Array or as a
|
||||
* space-delimited string.
|
||||
*
|
||||
* @var string
|
||||
* @var array
|
||||
*/
|
||||
private $scope;
|
||||
|
||||
@ -175,6 +175,13 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
*/
|
||||
private $signingKey;
|
||||
|
||||
/**
|
||||
* The signing key id when using assertion profile. Param kid in jwt header
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $signingKeyId;
|
||||
|
||||
/**
|
||||
* The signing algorithm when using an assertion profile.
|
||||
*
|
||||
@ -294,6 +301,9 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
* - signingKey
|
||||
* Signing key when using assertion profile
|
||||
*
|
||||
* - signingKeyId
|
||||
* Signing key id when using assertion profile
|
||||
*
|
||||
* - refreshToken
|
||||
* The refresh token associated with the access token
|
||||
* to be refreshed.
|
||||
@ -327,6 +337,7 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
'sub' => null,
|
||||
'audience' => null,
|
||||
'signingKey' => null,
|
||||
'signingKeyId' => null,
|
||||
'signingAlgorithm' => null,
|
||||
'scope' => null,
|
||||
'additionalClaims' => [],
|
||||
@ -345,6 +356,7 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
$this->setExpiry($opts['expiry']);
|
||||
$this->setAudience($opts['audience']);
|
||||
$this->setSigningKey($opts['signingKey']);
|
||||
$this->setSigningKeyId($opts['signingKeyId']);
|
||||
$this->setSigningAlgorithm($opts['signingAlgorithm']);
|
||||
$this->setScope($opts['scope']);
|
||||
$this->setExtensionParams($opts['extensionParams']);
|
||||
@ -359,11 +371,21 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
* - if present, but invalid, raises DomainException.
|
||||
* - otherwise returns the payload in the idtoken as a PHP object.
|
||||
*
|
||||
* if $publicKey is null, the key is decoded without being verified.
|
||||
* The behavior of this method varies depending on the version of
|
||||
* `firebase/php-jwt` you are using. In versions lower than 3.0.0, if
|
||||
* `$publicKey` is null, the key is decoded without being verified. In
|
||||
* newer versions, if a public key is not given, this method will throw an
|
||||
* `\InvalidArgumentException`.
|
||||
*
|
||||
* @param string $publicKey The public key to use to authenticate the token
|
||||
* @param array $allowed_algs List of supported verification algorithms
|
||||
*
|
||||
* @throws \DomainException if the token is missing an audience.
|
||||
* @throws \DomainException if the audience does not match the one set in
|
||||
* the OAuth2 class instance.
|
||||
* @throws \UnexpectedValueException If the token is invalid
|
||||
* @throws SignatureInvalidException If the signature is invalid.
|
||||
* @throws BeforeValidException If the token is not yet valid.
|
||||
* @throws ExpiredException If the token has expired.
|
||||
* @return null|object
|
||||
*/
|
||||
public function verifyIdToken($publicKey = null, $allowed_algs = array())
|
||||
@ -388,7 +410,6 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
* Obtains the encoded jwt from the instance data.
|
||||
*
|
||||
* @param array $config array optional configuration parameters
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toJwt(array $config = [])
|
||||
@ -424,8 +445,12 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
}
|
||||
$assertion += $this->getAdditionalClaims();
|
||||
|
||||
return $this->jwtEncode($assertion, $this->getSigningKey(),
|
||||
$this->getSigningAlgorithm());
|
||||
return $this->jwtEncode(
|
||||
$assertion,
|
||||
$this->getSigningKey(),
|
||||
$this->getSigningAlgorithm(),
|
||||
$this->getSigningKeyId()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -490,7 +515,6 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
* Fetches the auth tokens based on the current state.
|
||||
*
|
||||
* @param callable $httpHandler callback which delivers psr7 request
|
||||
*
|
||||
* @return array the response
|
||||
*/
|
||||
public function fetchAuthToken(callable $httpHandler = null)
|
||||
@ -515,10 +539,6 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
*/
|
||||
public function getCacheKey()
|
||||
{
|
||||
if (is_string($this->scope)) {
|
||||
return $this->scope;
|
||||
}
|
||||
|
||||
if (is_array($this->scope)) {
|
||||
return implode(':', $this->scope);
|
||||
}
|
||||
@ -531,9 +551,7 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
* Parses the fetched tokens.
|
||||
*
|
||||
* @param ResponseInterface $resp the response.
|
||||
*
|
||||
* @return array the tokens parsed from the response body.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function parseTokenResponse(ResponseInterface $resp)
|
||||
@ -559,12 +577,14 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
/**
|
||||
* Updates an OAuth 2.0 client.
|
||||
*
|
||||
* @example
|
||||
* client.updateToken([
|
||||
* Example:
|
||||
* ```
|
||||
* $oauth->updateToken([
|
||||
* 'refresh_token' => 'n4E9O119d',
|
||||
* 'access_token' => 'FJQbwq9',
|
||||
* 'expires_in' => 3600
|
||||
* ])
|
||||
* ]);
|
||||
* ```
|
||||
*
|
||||
* @param array $config
|
||||
* The configuration parameters related to the token.
|
||||
@ -621,16 +641,15 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
* Builds the authorization Uri that the user should be redirected to.
|
||||
*
|
||||
* @param array $config configuration options that customize the return url
|
||||
*
|
||||
* @return UriInterface the authorization Url.
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function buildFullAuthorizationUri(array $config = [])
|
||||
{
|
||||
if (is_null($this->getAuthorizationUri())) {
|
||||
throw new InvalidArgumentException(
|
||||
'requires an authorizationUri to have been set');
|
||||
'requires an authorizationUri to have been set'
|
||||
);
|
||||
}
|
||||
|
||||
$params = array_merge([
|
||||
@ -645,14 +664,16 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
// Validate the auth_params
|
||||
if (is_null($params['client_id'])) {
|
||||
throw new InvalidArgumentException(
|
||||
'missing the required client identifier');
|
||||
'missing the required client identifier'
|
||||
);
|
||||
}
|
||||
if (is_null($params['redirect_uri'])) {
|
||||
throw new InvalidArgumentException('missing the required redirect URI');
|
||||
}
|
||||
if (!empty($params['prompt']) && !empty($params['approval_prompt'])) {
|
||||
throw new InvalidArgumentException(
|
||||
'prompt and approval_prompt are mutually exclusive');
|
||||
'prompt and approval_prompt are mutually exclusive'
|
||||
);
|
||||
}
|
||||
|
||||
// Construct the uri object; return it if it is valid.
|
||||
@ -665,7 +686,8 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
|
||||
if ($result->getScheme() != 'https') {
|
||||
throw new InvalidArgumentException(
|
||||
'Authorization endpoint must be protected by TLS');
|
||||
'Authorization endpoint must be protected by TLS'
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
@ -743,7 +765,8 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
// @see https://developers.google.com/identity/sign-in/web/server-side-flow
|
||||
if ('postmessage' !== (string)$uri) {
|
||||
throw new InvalidArgumentException(
|
||||
'Redirect URI must be absolute');
|
||||
'Redirect URI must be absolute'
|
||||
);
|
||||
}
|
||||
}
|
||||
$this->redirectUri = (string)$uri;
|
||||
@ -768,7 +791,6 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
* a space-delimited String.
|
||||
*
|
||||
* @param string|array $scope
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setScope($scope)
|
||||
@ -782,13 +804,15 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
$pos = strpos($s, ' ');
|
||||
if ($pos !== false) {
|
||||
throw new InvalidArgumentException(
|
||||
'array scope values should not contain spaces');
|
||||
'array scope values should not contain spaces'
|
||||
);
|
||||
}
|
||||
}
|
||||
$this->scope = $scope;
|
||||
} else {
|
||||
throw new InvalidArgumentException(
|
||||
'scopes should be a string or array of strings');
|
||||
'scopes should be a string or array of strings'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -828,7 +852,6 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
* Sets the current grant type.
|
||||
*
|
||||
* @param $grantType
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setGrantType($grantType)
|
||||
@ -839,7 +862,8 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
// validate URI
|
||||
if (!$this->isAbsoluteUri($grantType)) {
|
||||
throw new InvalidArgumentException(
|
||||
'invalid grant type');
|
||||
'invalid grant type'
|
||||
);
|
||||
}
|
||||
$this->grantType = (string)$grantType;
|
||||
}
|
||||
@ -1031,6 +1055,26 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
$this->signingKey = $signingKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the signing key id when using an assertion profile.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSigningKeyId()
|
||||
{
|
||||
return $this->signingKeyId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the signing key id when using an assertion profile.
|
||||
*
|
||||
* @param string $signingKeyId
|
||||
*/
|
||||
public function setSigningKeyId($signingKeyId)
|
||||
{
|
||||
$this->signingKeyId = $signingKeyId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the signing algorithm when using an assertion profile.
|
||||
*
|
||||
@ -1287,7 +1331,6 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
* @todo handle uri as array
|
||||
*
|
||||
* @param string $uri
|
||||
*
|
||||
* @return null|UriInterface
|
||||
*/
|
||||
private function coerceUri($uri)
|
||||
@ -1303,7 +1346,6 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
* @param string $idToken
|
||||
* @param string|array|null $publicKey
|
||||
* @param array $allowedAlgs
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
private function jwtDecode($idToken, $publicKey, $allowedAlgs)
|
||||
@ -1315,14 +1357,18 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
return \JWT::decode($idToken, $publicKey, $allowedAlgs);
|
||||
}
|
||||
|
||||
private function jwtEncode($assertion, $signingKey, $signingAlgorithm)
|
||||
private function jwtEncode($assertion, $signingKey, $signingAlgorithm, $signingKeyId = null)
|
||||
{
|
||||
if (class_exists('Firebase\JWT\JWT')) {
|
||||
return \Firebase\JWT\JWT::encode($assertion, $signingKey,
|
||||
$signingAlgorithm);
|
||||
return \Firebase\JWT\JWT::encode(
|
||||
$assertion,
|
||||
$signingKey,
|
||||
$signingAlgorithm,
|
||||
$signingKeyId
|
||||
);
|
||||
}
|
||||
|
||||
return \JWT::encode($assertion, $signingKey, $signingAlgorithm);
|
||||
return \JWT::encode($assertion, $signingKey, $signingAlgorithm, $signingKeyId);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1330,7 +1376,6 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
* (RFC 3986).
|
||||
*
|
||||
* @param string $uri
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isAbsoluteUri($uri)
|
||||
@ -1342,7 +1387,6 @@ class OAuth2 implements FetchAuthTokenInterface
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function addClientCredentials(&$params)
|
||||
|
@ -79,6 +79,8 @@ class AuthTokenSubscriber implements SubscriberInterface
|
||||
/**
|
||||
* Updates the request with an Authorization header when auth is 'fetched_auth_token'.
|
||||
*
|
||||
* Example:
|
||||
* ```
|
||||
* use GuzzleHttp\Client;
|
||||
* use Google\Auth\OAuth2;
|
||||
* use Google\Auth\Subscriber\AuthTokenSubscriber;
|
||||
@ -94,6 +96,7 @@ class AuthTokenSubscriber implements SubscriberInterface
|
||||
* $client->getEmitter()->attach($subscriber);
|
||||
*
|
||||
* $res = $client->get('myproject/taskqueues/myqueue');
|
||||
* ```
|
||||
*
|
||||
* @param BeforeEvent $event
|
||||
*/
|
||||
|
@ -78,7 +78,8 @@ class ScopedAccessTokenSubscriber implements SubscriberInterface
|
||||
$this->tokenFunc = $tokenFunc;
|
||||
if (!(is_string($scopes) || is_array($scopes))) {
|
||||
throw new \InvalidArgumentException(
|
||||
'wants scope should be string or array');
|
||||
'wants scope should be string or array'
|
||||
);
|
||||
}
|
||||
$this->scopes = $scopes;
|
||||
|
||||
@ -102,9 +103,10 @@ class ScopedAccessTokenSubscriber implements SubscriberInterface
|
||||
/**
|
||||
* Updates the request with an Authorization header when auth is 'scoped'.
|
||||
*
|
||||
* E.g this could be used to authenticate using the AppEngine
|
||||
* AppIdentityService.
|
||||
* E.g this could be used to authenticate using the AppEngine AppIdentityService.
|
||||
*
|
||||
* Example:
|
||||
* ```
|
||||
* use google\appengine\api\app_identity\AppIdentityService;
|
||||
* use Google\Auth\Subscriber\ScopedAccessTokenSubscriber;
|
||||
* use GuzzleHttp\Client;
|
||||
@ -124,6 +126,7 @@ class ScopedAccessTokenSubscriber implements SubscriberInterface
|
||||
* $client->getEmitter()->attach($subscriber);
|
||||
*
|
||||
* $res = $client->get('myproject/taskqueues/myqueue');
|
||||
* ```
|
||||
*
|
||||
* @param BeforeEvent $event
|
||||
*/
|
||||
|
@ -62,6 +62,8 @@ class SimpleSubscriber implements SubscriberInterface
|
||||
/**
|
||||
* Updates the request query with the developer key if auth is set to simple.
|
||||
*
|
||||
* Example:
|
||||
* ```
|
||||
* use Google\Auth\Subscriber\SimpleSubscriber;
|
||||
* use GuzzleHttp\Client;
|
||||
*
|
||||
@ -75,6 +77,7 @@ class SimpleSubscriber implements SubscriberInterface
|
||||
* $client->getEmitter()->attach($subscriber);
|
||||
*
|
||||
* $res = $client->get('drive/v2/rest');
|
||||
* ```
|
||||
*
|
||||
* @param BeforeEvent $event
|
||||
*/
|
||||
|
@ -2,11 +2,12 @@
|
||||
namespace GuzzleHttp;
|
||||
|
||||
use GuzzleHttp\Cookie\CookieJar;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Promise;
|
||||
use GuzzleHttp\Psr7;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
|
||||
/**
|
||||
* @method ResponseInterface get(string|UriInterface $uri, array $options = [])
|
||||
@ -46,9 +47,8 @@ class Client implements ClientInterface
|
||||
* wire. The function is called with a Psr7\Http\Message\RequestInterface
|
||||
* and array of transfer options, and must return a
|
||||
* GuzzleHttp\Promise\PromiseInterface that is fulfilled with a
|
||||
* Psr7\Http\Message\ResponseInterface on success. "handler" is a
|
||||
* constructor only option that cannot be overridden in per/request
|
||||
* options. If no handler is provided, a default handler will be created
|
||||
* Psr7\Http\Message\ResponseInterface on success.
|
||||
* If no handler is provided, a default handler will be created
|
||||
* that enables all of the request options below by attaching all of the
|
||||
* default middleware to the handler.
|
||||
* - base_uri: (string|UriInterface) Base URI of the client that is merged
|
||||
@ -75,6 +75,12 @@ class Client implements ClientInterface
|
||||
$this->configureDefaults($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param array $args
|
||||
*
|
||||
* @return Promise\PromiseInterface
|
||||
*/
|
||||
public function __call($method, $args)
|
||||
{
|
||||
if (count($args) < 1) {
|
||||
@ -89,6 +95,14 @@ class Client implements ClientInterface
|
||||
: $this->request($method, $uri, $opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously send an HTTP request.
|
||||
*
|
||||
* @param array $options Request options to apply to the given
|
||||
* request and to the transfer. See \GuzzleHttp\RequestOptions.
|
||||
*
|
||||
* @return Promise\PromiseInterface
|
||||
*/
|
||||
public function sendAsync(RequestInterface $request, array $options = [])
|
||||
{
|
||||
// Merge the base URI into the request URI if needed.
|
||||
@ -100,12 +114,35 @@ class Client implements ClientInterface
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an HTTP request.
|
||||
*
|
||||
* @param array $options Request options to apply to the given
|
||||
* request and to the transfer. See \GuzzleHttp\RequestOptions.
|
||||
*
|
||||
* @return ResponseInterface
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function send(RequestInterface $request, array $options = [])
|
||||
{
|
||||
$options[RequestOptions::SYNCHRONOUS] = true;
|
||||
return $this->sendAsync($request, $options)->wait();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and send an asynchronous HTTP request.
|
||||
*
|
||||
* Use an absolute path to override the base path of the client, or a
|
||||
* relative path to append to the base path of the client. The URL can
|
||||
* contain the query string as well. Use an array to provide a URL
|
||||
* template and additional variables to use in the URL template expansion.
|
||||
*
|
||||
* @param string $method HTTP method
|
||||
* @param string|UriInterface $uri URI object or string.
|
||||
* @param array $options Request options to apply. See \GuzzleHttp\RequestOptions.
|
||||
*
|
||||
* @return Promise\PromiseInterface
|
||||
*/
|
||||
public function requestAsync($method, $uri = '', array $options = [])
|
||||
{
|
||||
$options = $this->prepareDefaults($options);
|
||||
@ -125,12 +162,37 @@ class Client implements ClientInterface
|
||||
return $this->transfer($request, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and send an HTTP request.
|
||||
*
|
||||
* Use an absolute path to override the base path of the client, or a
|
||||
* relative path to append to the base path of the client. The URL can
|
||||
* contain the query string as well.
|
||||
*
|
||||
* @param string $method HTTP method.
|
||||
* @param string|UriInterface $uri URI object or string.
|
||||
* @param array $options Request options to apply. See \GuzzleHttp\RequestOptions.
|
||||
*
|
||||
* @return ResponseInterface
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function request($method, $uri = '', array $options = [])
|
||||
{
|
||||
$options[RequestOptions::SYNCHRONOUS] = true;
|
||||
return $this->requestAsync($method, $uri, $options)->wait();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a client configuration option.
|
||||
*
|
||||
* These options include default request options of the client, a "handler"
|
||||
* (if utilized by the concrete client), and a "base_uri" if utilized by
|
||||
* the concrete client.
|
||||
*
|
||||
* @param string|null $option The config option to retrieve.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getConfig($option = null)
|
||||
{
|
||||
return $option === null
|
||||
@ -138,6 +200,11 @@ class Client implements ClientInterface
|
||||
: (isset($this->config[$option]) ? $this->config[$option] : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $uri
|
||||
*
|
||||
* @return UriInterface
|
||||
*/
|
||||
private function buildUri($uri, array $config)
|
||||
{
|
||||
// for BC we accept null which would otherwise fail in uri_for
|
||||
@ -147,6 +214,11 @@ class Client implements ClientInterface
|
||||
$uri = Psr7\UriResolver::resolve(Psr7\uri_for($config['base_uri']), $uri);
|
||||
}
|
||||
|
||||
if (isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) {
|
||||
$idnOptions = ($config['idn_conversion'] === true) ? IDNA_DEFAULT : $config['idn_conversion'];
|
||||
$uri = Utils::idnUriConvert($uri, $idnOptions);
|
||||
}
|
||||
|
||||
return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri;
|
||||
}
|
||||
|
||||
@ -154,6 +226,7 @@ class Client implements ClientInterface
|
||||
* Configures the default options for a client.
|
||||
*
|
||||
* @param array $config
|
||||
* @return void
|
||||
*/
|
||||
private function configureDefaults(array $config)
|
||||
{
|
||||
@ -162,7 +235,8 @@ class Client implements ClientInterface
|
||||
'http_errors' => true,
|
||||
'decode_content' => true,
|
||||
'verify' => true,
|
||||
'cookies' => false
|
||||
'cookies' => false,
|
||||
'idn_conversion' => true,
|
||||
];
|
||||
|
||||
// Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set.
|
||||
@ -170,7 +244,7 @@ class Client implements ClientInterface
|
||||
// We can only trust the HTTP_PROXY environment variable in a CLI
|
||||
// process due to the fact that PHP has no reliable mechanism to
|
||||
// get environment variables that start with "HTTP_".
|
||||
if (php_sapi_name() == 'cli' && getenv('HTTP_PROXY')) {
|
||||
if (php_sapi_name() === 'cli' && getenv('HTTP_PROXY')) {
|
||||
$defaults['proxy']['http'] = getenv('HTTP_PROXY');
|
||||
}
|
||||
|
||||
@ -225,7 +299,7 @@ class Client implements ClientInterface
|
||||
if (array_key_exists('headers', $options)) {
|
||||
// Allows default headers to be unset.
|
||||
if ($options['headers'] === null) {
|
||||
$defaults['_conditional'] = null;
|
||||
$defaults['_conditional'] = [];
|
||||
unset($options['headers']);
|
||||
} elseif (!is_array($options['headers'])) {
|
||||
throw new \InvalidArgumentException('headers must be an array');
|
||||
@ -251,8 +325,7 @@ class Client implements ClientInterface
|
||||
* The URI of the request is not modified and the request options are used
|
||||
* as-is without merging in default options.
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param array $options
|
||||
* @param array $options See \GuzzleHttp\RequestOptions.
|
||||
*
|
||||
* @return Promise\PromiseInterface
|
||||
*/
|
||||
@ -271,6 +344,7 @@ class Client implements ClientInterface
|
||||
}
|
||||
|
||||
$request = $this->applyOptions($request, $options);
|
||||
/** @var HandlerStack $handler */
|
||||
$handler = $options['handler'];
|
||||
|
||||
try {
|
||||
@ -411,6 +485,11 @@ class Client implements ClientInterface
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw Exception with pre-set message.
|
||||
* @return void
|
||||
* @throws \InvalidArgumentException Invalid body.
|
||||
*/
|
||||
private function invalidBody()
|
||||
{
|
||||
throw new \InvalidArgumentException('Passing in the "body" request '
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
namespace GuzzleHttp;
|
||||
|
||||
use GuzzleHttp\Promise\PromiseInterface;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Promise\PromiseInterface;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
@ -12,7 +12,10 @@ use Psr\Http\Message\UriInterface;
|
||||
*/
|
||||
interface ClientInterface
|
||||
{
|
||||
const VERSION = '6.4.1';
|
||||
/**
|
||||
* @deprecated Will be removed in Guzzle 7.0.0
|
||||
*/
|
||||
const VERSION = '6.5.4';
|
||||
|
||||
/**
|
||||
* Send an HTTP request.
|
||||
|
@ -94,8 +94,8 @@ class CookieJar implements CookieJarInterface
|
||||
*/
|
||||
public function getCookieByName($name)
|
||||
{
|
||||
// don't allow a null name
|
||||
if ($name === null) {
|
||||
// don't allow a non string name
|
||||
if ($name === null || !is_scalar($name)) {
|
||||
return null;
|
||||
}
|
||||
foreach ($this->cookies as $cookie) {
|
||||
@ -103,6 +103,8 @@ class CookieJar implements CookieJarInterface
|
||||
return $cookie;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function toArray()
|
||||
|
@ -58,9 +58,9 @@ interface CookieJarInterface extends \Countable, \IteratorAggregate
|
||||
* arguments, then the cookie with the specified name, path and domain is
|
||||
* removed.
|
||||
*
|
||||
* @param string $domain Clears cookies matching a domain
|
||||
* @param string $path Clears cookies matching a domain and path
|
||||
* @param string $name Clears cookies matching a domain, path, and name
|
||||
* @param string|null $domain Clears cookies matching a domain
|
||||
* @param string|null $path Clears cookies matching a domain and path
|
||||
* @param string|null $name Clears cookies matching a domain, path, and name
|
||||
*
|
||||
* @return CookieJarInterface
|
||||
*/
|
||||
|
@ -1,9 +1,9 @@
|
||||
<?php
|
||||
namespace GuzzleHttp\Exception;
|
||||
|
||||
use GuzzleHttp\Promise\PromiseInterface;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use GuzzleHttp\Promise\PromiseInterface;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
|
||||
/**
|
||||
@ -14,7 +14,7 @@ class RequestException extends TransferException
|
||||
/** @var RequestInterface */
|
||||
private $request;
|
||||
|
||||
/** @var ResponseInterface */
|
||||
/** @var ResponseInterface|null */
|
||||
private $response;
|
||||
|
||||
/** @var array */
|
||||
@ -124,42 +124,17 @@ class RequestException extends TransferException
|
||||
*/
|
||||
public static function getResponseBodySummary(ResponseInterface $response)
|
||||
{
|
||||
$body = $response->getBody();
|
||||
|
||||
if (!$body->isSeekable() || !$body->isReadable()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$size = $body->getSize();
|
||||
|
||||
if ($size === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$summary = $body->read(120);
|
||||
$body->rewind();
|
||||
|
||||
if ($size > 120) {
|
||||
$summary .= ' (truncated...)';
|
||||
}
|
||||
|
||||
// Matches any printable character, including unicode characters:
|
||||
// letters, marks, numbers, punctuation, spacing, and separators.
|
||||
if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/', $summary)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $summary;
|
||||
return \GuzzleHttp\Psr7\get_message_body_summary($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obfuscates URI if there is an username and a password present
|
||||
* Obfuscates URI if there is a username and a password present
|
||||
*
|
||||
* @param UriInterface $uri
|
||||
*
|
||||
* @return UriInterface
|
||||
*/
|
||||
private static function obfuscateUri($uri)
|
||||
private static function obfuscateUri(UriInterface $uri)
|
||||
{
|
||||
$userInfo = $uri->getUserInfo();
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
namespace GuzzleHttp\Handler;
|
||||
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use GuzzleHttp\Exception\ConnectException;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use GuzzleHttp\Promise\FulfilledPromise;
|
||||
use GuzzleHttp\Psr7;
|
||||
use GuzzleHttp\Psr7\LazyOpenStream;
|
||||
@ -454,11 +454,16 @@ class CurlFactory implements CurlFactoryInterface
|
||||
}
|
||||
|
||||
if (isset($options['ssl_key'])) {
|
||||
$sslKey = $options['ssl_key'];
|
||||
if (is_array($sslKey)) {
|
||||
$conf[CURLOPT_SSLKEYPASSWD] = $sslKey[1];
|
||||
$sslKey = $sslKey[0];
|
||||
if (is_array($options['ssl_key'])) {
|
||||
if (count($options['ssl_key']) === 2) {
|
||||
list($sslKey, $conf[CURLOPT_SSLKEYPASSWD]) = $options['ssl_key'];
|
||||
} else {
|
||||
list($sslKey) = $options['ssl_key'];
|
||||
}
|
||||
}
|
||||
|
||||
$sslKey = isset($sslKey) ? $sslKey: $options['ssl_key'];
|
||||
|
||||
if (!file_exists($sslKey)) {
|
||||
throw new \InvalidArgumentException(
|
||||
"SSL private key not found: {$sslKey}"
|
||||
|
@ -3,7 +3,7 @@ namespace GuzzleHttp\Handler;
|
||||
|
||||
use GuzzleHttp\Promise as P;
|
||||
use GuzzleHttp\Promise\Promise;
|
||||
use GuzzleHttp\Psr7;
|
||||
use GuzzleHttp\Utils;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
|
||||
/**
|
||||
@ -23,6 +23,7 @@ class CurlMultiHandler
|
||||
private $active;
|
||||
private $handles = [];
|
||||
private $delays = [];
|
||||
private $options = [];
|
||||
|
||||
/**
|
||||
* This handler accepts the following options:
|
||||
@ -30,6 +31,8 @@ class CurlMultiHandler
|
||||
* - handle_factory: An optional factory used to create curl handles
|
||||
* - select_timeout: Optional timeout (in seconds) to block before timing
|
||||
* out while selecting curl handles. Defaults to 1 second.
|
||||
* - options: An associative array of CURLMOPT_* options and
|
||||
* corresponding values for curl_multi_setopt()
|
||||
*
|
||||
* @param array $options
|
||||
*/
|
||||
@ -45,12 +48,23 @@ class CurlMultiHandler
|
||||
} else {
|
||||
$this->selectTimeout = 1;
|
||||
}
|
||||
|
||||
$this->options = isset($options['options']) ? $options['options'] : [];
|
||||
}
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
if ($name === '_mh') {
|
||||
return $this->_mh = curl_multi_init();
|
||||
$this->_mh = curl_multi_init();
|
||||
|
||||
foreach ($this->options as $option => $value) {
|
||||
// A warning is raised in case of a wrong option.
|
||||
curl_multi_setopt($this->_mh, $option, $value);
|
||||
}
|
||||
|
||||
// Further calls to _mh will return the value directly, without entering the
|
||||
// __get() method at all.
|
||||
return $this->_mh;
|
||||
}
|
||||
|
||||
throw new \BadMethodCallException();
|
||||
@ -88,7 +102,7 @@ class CurlMultiHandler
|
||||
{
|
||||
// Add any delayed handles if needed.
|
||||
if ($this->delays) {
|
||||
$currentTime = \GuzzleHttp\_current_time();
|
||||
$currentTime = Utils::currentTime();
|
||||
foreach ($this->delays as $id => $delay) {
|
||||
if ($currentTime >= $delay) {
|
||||
unset($this->delays[$id]);
|
||||
@ -140,7 +154,7 @@ class CurlMultiHandler
|
||||
if (empty($easy->options['delay'])) {
|
||||
curl_multi_add_handle($this->_mh, $easy->handle);
|
||||
} else {
|
||||
$this->delays[$id] = \GuzzleHttp\_current_time() + ($easy->options['delay'] / 1000);
|
||||
$this->delays[$id] = Utils::currentTime() + ($easy->options['delay'] / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@ -192,7 +206,7 @@ class CurlMultiHandler
|
||||
|
||||
private function timeToNext()
|
||||
{
|
||||
$currentTime = \GuzzleHttp\_current_time();
|
||||
$currentTime = Utils::currentTime();
|
||||
$nextTime = PHP_INT_MAX;
|
||||
foreach ($this->delays as $time) {
|
||||
if ($time < $nextTime) {
|
||||
|
@ -66,7 +66,7 @@ class MockHandler implements \Countable
|
||||
throw new \OutOfBoundsException('Mock queue is empty');
|
||||
}
|
||||
|
||||
if (isset($options['delay'])) {
|
||||
if (isset($options['delay']) && is_numeric($options['delay'])) {
|
||||
usleep($options['delay'] * 1000);
|
||||
}
|
||||
|
||||
@ -175,6 +175,11 @@ class MockHandler implements \Countable
|
||||
return count($this->queue);
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->queue = [];
|
||||
}
|
||||
|
||||
private function invokeStats(
|
||||
RequestInterface $request,
|
||||
array $options,
|
||||
|
@ -1,12 +1,13 @@
|
||||
<?php
|
||||
namespace GuzzleHttp\Handler;
|
||||
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use GuzzleHttp\Exception\ConnectException;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use GuzzleHttp\Promise\FulfilledPromise;
|
||||
use GuzzleHttp\Promise\PromiseInterface;
|
||||
use GuzzleHttp\Psr7;
|
||||
use GuzzleHttp\TransferStats;
|
||||
use GuzzleHttp\Utils;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
@ -33,7 +34,7 @@ class StreamHandler
|
||||
usleep($options['delay'] * 1000);
|
||||
}
|
||||
|
||||
$startTime = isset($options['on_stats']) ? \GuzzleHttp\_current_time() : null;
|
||||
$startTime = isset($options['on_stats']) ? Utils::currentTime() : null;
|
||||
|
||||
try {
|
||||
// Does not support the expect header.
|
||||
@ -82,7 +83,7 @@ class StreamHandler
|
||||
$stats = new TransferStats(
|
||||
$request,
|
||||
$response,
|
||||
\GuzzleHttp\_current_time() - $startTime,
|
||||
Utils::currentTime() - $startTime,
|
||||
$error,
|
||||
[]
|
||||
);
|
||||
|
@ -1,7 +1,9 @@
|
||||
<?php
|
||||
namespace GuzzleHttp;
|
||||
|
||||
use GuzzleHttp\Promise\PromiseInterface;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Creates a composed Guzzle handler function by stacking middlewares on top of
|
||||
@ -9,7 +11,7 @@ use Psr\Http\Message\RequestInterface;
|
||||
*/
|
||||
class HandlerStack
|
||||
{
|
||||
/** @var callable */
|
||||
/** @var callable|null */
|
||||
private $handler;
|
||||
|
||||
/** @var array */
|
||||
@ -59,6 +61,8 @@ class HandlerStack
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param array $options
|
||||
*
|
||||
* @return ResponseInterface|PromiseInterface
|
||||
*/
|
||||
public function __invoke(RequestInterface $request, array $options)
|
||||
{
|
||||
|
@ -168,6 +168,11 @@ class MessageFormatter
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get headers from message as string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function headers(MessageInterface $message)
|
||||
{
|
||||
$result = '';
|
||||
|
@ -1,9 +1,10 @@
|
||||
<?php
|
||||
namespace GuzzleHttp;
|
||||
|
||||
use GuzzleHttp\Promise\EachPromise;
|
||||
use GuzzleHttp\Promise\PromiseInterface;
|
||||
use GuzzleHttp\Promise\PromisorInterface;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use GuzzleHttp\Promise\EachPromise;
|
||||
|
||||
/**
|
||||
* Sends an iterator of requests concurrently using a capped pool size.
|
||||
@ -69,6 +70,11 @@ class Pool implements PromisorInterface
|
||||
$this->each = new EachPromise($requests(), $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get promise
|
||||
*
|
||||
* @return PromiseInterface
|
||||
*/
|
||||
public function promise()
|
||||
{
|
||||
return $this->each->promise();
|
||||
@ -106,6 +112,11 @@ class Pool implements PromisorInterface
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute callback(s)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function cmpCallback(array &$options, $name, array &$results)
|
||||
{
|
||||
if (!isset($options[$name])) {
|
||||
|
@ -66,6 +66,11 @@ class PrepareBodyMiddleware
|
||||
return $fn(Psr7\modify_request($request, $modify), $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add expect header
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addExpectHeader(
|
||||
RequestInterface $request,
|
||||
array $options,
|
||||
|
@ -13,7 +13,7 @@ use Psr\Http\Message\UriInterface;
|
||||
* Request redirect middleware.
|
||||
*
|
||||
* Apply this middleware like other middleware using
|
||||
* {@see GuzzleHttp\Middleware::redirect()}.
|
||||
* {@see \GuzzleHttp\Middleware::redirect()}.
|
||||
*/
|
||||
class RedirectMiddleware
|
||||
{
|
||||
@ -76,7 +76,7 @@ class RedirectMiddleware
|
||||
/**
|
||||
* @param RequestInterface $request
|
||||
* @param array $options
|
||||
* @param ResponseInterface|PromiseInterface $response
|
||||
* @param ResponseInterface $response
|
||||
*
|
||||
* @return ResponseInterface|PromiseInterface
|
||||
*/
|
||||
@ -118,6 +118,11 @@ class RedirectMiddleware
|
||||
return $promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable tracking on promise.
|
||||
*
|
||||
* @return PromiseInterface
|
||||
*/
|
||||
private function withTracking(PromiseInterface $promise, $uri, $statusCode)
|
||||
{
|
||||
return $promise->then(
|
||||
@ -135,6 +140,13 @@ class RedirectMiddleware
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for too many redirects
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws TooManyRedirectsException Too many redirects.
|
||||
*/
|
||||
private function guardMax(RequestInterface $request, array &$options)
|
||||
{
|
||||
$current = isset($options['__redirect_count'])
|
||||
@ -172,13 +184,19 @@ class RedirectMiddleware
|
||||
// would do.
|
||||
$statusCode = $response->getStatusCode();
|
||||
if ($statusCode == 303 ||
|
||||
($statusCode <= 302 && $request->getBody() && !$options['allow_redirects']['strict'])
|
||||
($statusCode <= 302 && !$options['allow_redirects']['strict'])
|
||||
) {
|
||||
$modify['method'] = 'GET';
|
||||
$modify['body'] = '';
|
||||
}
|
||||
|
||||
$modify['uri'] = $this->redirectUri($request, $response, $protocols);
|
||||
$uri = $this->redirectUri($request, $response, $protocols);
|
||||
if (isset($options['idn_conversion']) && ($options['idn_conversion'] !== false)) {
|
||||
$idnOptions = ($options['idn_conversion'] === true) ? IDNA_DEFAULT : $options['idn_conversion'];
|
||||
$uri = Utils::idnUriConvert($uri, $idnOptions);
|
||||
}
|
||||
|
||||
$modify['uri'] = $uri;
|
||||
Psr7\rewind_body($request);
|
||||
|
||||
// Add the Referer header if it is told to do so and only
|
||||
|
@ -132,6 +132,14 @@ final class RequestOptions
|
||||
*/
|
||||
const HTTP_ERRORS = 'http_errors';
|
||||
|
||||
/**
|
||||
* idn: (bool|int, default=true) A combination of IDNA_* constants for
|
||||
* idn_to_ascii() PHP's function (see "options" parameter). Set to false to
|
||||
* disable IDN support completely, or to true to use the default
|
||||
* configuration (IDNA_DEFAULT constant).
|
||||
*/
|
||||
const IDN_CONVERSION = 'idn_conversion';
|
||||
|
||||
/**
|
||||
* json: (mixed) Adds JSON data to a request. The provided value is JSON
|
||||
* encoded and a Content-Type header of application/json will be added to
|
||||
|
@ -47,11 +47,11 @@ class RetryMiddleware
|
||||
*
|
||||
* @param int $retries
|
||||
*
|
||||
* @return int
|
||||
* @return int milliseconds.
|
||||
*/
|
||||
public static function exponentialDelay($retries)
|
||||
{
|
||||
return (int) pow(2, $retries - 1);
|
||||
return (int) pow(2, $retries - 1) * 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,6 +74,11 @@ class RetryMiddleware
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute fulfilled closure
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function onFulfilled(RequestInterface $req, array $options)
|
||||
{
|
||||
return function ($value) use ($req, $options) {
|
||||
@ -90,6 +95,11 @@ class RetryMiddleware
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute rejected closure
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
private function onRejected(RequestInterface $req, array $options)
|
||||
{
|
||||
return function ($reason) use ($req, $options) {
|
||||
@ -106,6 +116,9 @@ class RetryMiddleware
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return self
|
||||
*/
|
||||
private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null)
|
||||
{
|
||||
$options['delay'] = call_user_func($this->delay, ++$options['retries'], $response);
|
||||
|
@ -19,7 +19,7 @@ final class TransferStats
|
||||
|
||||
/**
|
||||
* @param RequestInterface $request Request that was sent.
|
||||
* @param ResponseInterface $response Response received (if any)
|
||||
* @param ResponseInterface|null $response Response received (if any)
|
||||
* @param float|null $transferTime Total handler transfer time.
|
||||
* @param mixed $handlerErrorData Handler error data.
|
||||
* @param array $handlerStats Handler specific stats.
|
||||
@ -93,7 +93,7 @@ final class TransferStats
|
||||
/**
|
||||
* Get the estimated time the request was being transferred by the handler.
|
||||
*
|
||||
* @return float Time in seconds.
|
||||
* @return float|null Time in seconds.
|
||||
*/
|
||||
public function getTransferTime()
|
||||
{
|
||||
|
89
wp-content/plugins/wp-mail-smtp/vendor/guzzlehttp/guzzle/src/Utils.php
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
namespace GuzzleHttp;
|
||||
|
||||
use GuzzleHttp\Exception\InvalidArgumentException;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
use Symfony\Polyfill\Intl\Idn\Idn;
|
||||
|
||||
final class Utils
|
||||
{
|
||||
/**
|
||||
* Wrapper for the hrtime() or microtime() functions
|
||||
* (depending on the PHP version, one of the two is used)
|
||||
*
|
||||
* @return float|mixed UNIX timestamp
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function currentTime()
|
||||
{
|
||||
return function_exists('hrtime') ? hrtime(true) / 1e9 : microtime(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $options
|
||||
*
|
||||
* @return UriInterface
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function idnUriConvert(UriInterface $uri, $options = 0)
|
||||
{
|
||||
if ($uri->getHost()) {
|
||||
$asciiHost = self::idnToAsci($uri->getHost(), $options, $info);
|
||||
if ($asciiHost === false) {
|
||||
$errorBitSet = isset($info['errors']) ? $info['errors'] : 0;
|
||||
|
||||
$errorConstants = array_filter(array_keys(get_defined_constants()), function ($name) {
|
||||
return substr($name, 0, 11) === 'IDNA_ERROR_';
|
||||
});
|
||||
|
||||
$errors = [];
|
||||
foreach ($errorConstants as $errorConstant) {
|
||||
if ($errorBitSet & constant($errorConstant)) {
|
||||
$errors[] = $errorConstant;
|
||||
}
|
||||
}
|
||||
|
||||
$errorMessage = 'IDN conversion failed';
|
||||
if ($errors) {
|
||||
$errorMessage .= ' (errors: ' . implode(', ', $errors) . ')';
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException($errorMessage);
|
||||
} else {
|
||||
if ($uri->getHost() !== $asciiHost) {
|
||||
// Replace URI only if the ASCII version is different
|
||||
$uri = $uri->withHost($asciiHost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $domain
|
||||
* @param int $options
|
||||
* @param array $info
|
||||
*
|
||||
* @return string|false
|
||||
*/
|
||||
private static function idnToAsci($domain, $options, &$info = [])
|
||||
{
|
||||
if (\preg_match('%^[ -~]+$%', $domain) === 1) {
|
||||
return $domain;
|
||||
}
|
||||
|
||||
if (\extension_loaded('intl') && defined('INTL_IDNA_VARIANT_UTS46')) {
|
||||
return \idn_to_ascii($domain, $options, INTL_IDNA_VARIANT_UTS46, $info);
|
||||
}
|
||||
|
||||
/*
|
||||
* The Idn class is marked as @internal. We've locked the version to
|
||||
* symfony/polyfill-intl-idn to avoid issues in the future.
|
||||
*/
|
||||
return Idn::idn_to_ascii($domain, $options, Idn::INTL_IDNA_VARIANT_UTS46, $info);
|
||||
}
|
||||
}
|
@ -56,7 +56,7 @@ function describe_type($input)
|
||||
/**
|
||||
* Parses an array of header lines into an associative array of headers.
|
||||
*
|
||||
* @param array $lines Header lines array of strings in the following
|
||||
* @param iterable $lines Header lines array of strings in the following
|
||||
* format: "Name: Value"
|
||||
* @return array
|
||||
*/
|
||||
@ -97,8 +97,8 @@ function debug_resource($value = null)
|
||||
*
|
||||
* The returned handler is not wrapped by any default middlewares.
|
||||
*
|
||||
* @throws \RuntimeException if no viable Handler is available.
|
||||
* @return callable Returns the best handler for the given system.
|
||||
* @throws \RuntimeException if no viable Handler is available.
|
||||
*/
|
||||
function choose_handler()
|
||||
{
|
||||
@ -332,15 +332,3 @@ function json_encode($value, $options = 0, $depth = 512)
|
||||
|
||||
return $json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for the hrtime() or microtime() functions
|
||||
* (depending on the PHP version, one of the two is used)
|
||||
*
|
||||
* @return float|mixed UNIX timestamp
|
||||
* @internal
|
||||
*/
|
||||
function _current_time()
|
||||
{
|
||||
return function_exists('hrtime') ? hrtime(true) / 1e9 : microtime(true);
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ namespace Monolog;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
use Monolog\Handler\AbstractHandler;
|
||||
use Monolog\Registry;
|
||||
|
||||
/**
|
||||
* Monolog error handler
|
||||
|
@ -142,8 +142,12 @@ class NormalizerFormatter implements FormatterInterface
|
||||
$data['faultactor'] = $e->faultactor;
|
||||
}
|
||||
|
||||
if (isset($e->detail) && (is_string($e->detail) || is_object($e->detail) || is_array($e->detail))) {
|
||||
$data['detail'] = is_string($e->detail) ? $e->detail : reset($e->detail);
|
||||
if (isset($e->detail)) {
|
||||
if (is_string($e->detail)) {
|
||||
$data['detail'] = $e->detail;
|
||||
} elseif (is_object($e->detail) || is_array($e->detail)) {
|
||||
$data['detail'] = $this->toJson($e->detail, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ abstract class AbstractHandler implements HandlerInterface, ResettableInterface
|
||||
protected $processors = array();
|
||||
|
||||
/**
|
||||
* @param int $level The minimum logging level at which this handler will be triggered
|
||||
* @param int|string $level The minimum logging level at which this handler will be triggered
|
||||
* @param bool $bubble Whether the messages that are handled can bubble up the stack or not
|
||||
*/
|
||||
public function __construct($level = Logger::DEBUG, $bubble = true)
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Monolog\Handler;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\Utils;
|
||||
|
||||
/**
|
||||
* Stores logs to files that are rotated every day and a limited number of files are kept.
|
||||
@ -45,7 +46,7 @@ class RotatingFileHandler extends StreamHandler
|
||||
*/
|
||||
public function __construct($filename, $maxFiles = 0, $level = Logger::DEBUG, $bubble = true, $filePermission = null, $useLocking = false)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
$this->filename = Utils::canonicalizePath($filename);
|
||||
$this->maxFiles = (int) $maxFiles;
|
||||
$this->nextRotation = new \DateTime('tomorrow');
|
||||
$this->filenameFormat = '{filename}-{date}';
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Monolog\Handler;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\Utils;
|
||||
|
||||
/**
|
||||
* Stores to any stream resource
|
||||
@ -45,7 +46,7 @@ class StreamHandler extends AbstractProcessingHandler
|
||||
if (is_resource($stream)) {
|
||||
$this->stream = $stream;
|
||||
} elseif (is_string($stream)) {
|
||||
$this->url = $stream;
|
||||
$this->url = Utils::canonicalizePath($stream);
|
||||
} else {
|
||||
throw new \InvalidArgumentException('A stream must either be a resource or a string.');
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ class GitProcessor implements ProcessorInterface
|
||||
}
|
||||
|
||||
$branches = `git branch -v --no-abbrev`;
|
||||
if (preg_match('{^\* (.+?)\s+([a-f0-9]{40})(?:\s|$)}m', $branches, $matches)) {
|
||||
if ($branches && preg_match('{^\* (.+?)\s+([a-f0-9]{40})(?:\s|$)}m', $branches, $matches)) {
|
||||
return self::$cache = array(
|
||||
'branch' => $matches[1],
|
||||
'commit' => $matches[2],
|
||||
|
@ -23,6 +23,36 @@ class Utils
|
||||
return 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure if a relative path is passed in it is turned into an absolute path
|
||||
*
|
||||
* @param string $streamUrl stream URL or path without protocol
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function canonicalizePath($streamUrl)
|
||||
{
|
||||
$prefix = '';
|
||||
if ('file://' === substr($streamUrl, 0, 7)) {
|
||||
$streamUrl = substr($streamUrl, 7);
|
||||
$prefix = 'file://';
|
||||
}
|
||||
|
||||
// other type of stream, not supported
|
||||
if (false !== strpos($streamUrl, '://')) {
|
||||
return $streamUrl;
|
||||
}
|
||||
|
||||
// already absolute
|
||||
if (substr($streamUrl, 0, 1) === '/' || substr($streamUrl, 1, 1) === ':' || substr($streamUrl, 0, 2) === '\\\\') {
|
||||
return $prefix.$streamUrl;
|
||||
}
|
||||
|
||||
$streamUrl = getcwd() . '/' . $streamUrl;
|
||||
|
||||
return $prefix.$streamUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the JSON representation of a value
|
||||
*
|
||||
|
287
wp-content/plugins/wp-mail-smtp/vendor/symfony/polyfill-intl-idn/Idn.php
vendored
Normal file
@ -0,0 +1,287 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 TrueServer B.V.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is furnished
|
||||
* to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* Originally forked from
|
||||
* https://github.com/true/php-punycode/blob/v2.1.1/src/Punycode.php
|
||||
*/
|
||||
|
||||
namespace Symfony\Polyfill\Intl\Idn;
|
||||
|
||||
/**
|
||||
* Partial intl implementation in pure PHP.
|
||||
*
|
||||
* Implemented:
|
||||
* - idn_to_ascii - Convert domain name to IDNA ASCII form
|
||||
* - idn_to_utf8 - Convert domain name from IDNA ASCII to Unicode
|
||||
*
|
||||
* @author Renan Gonçalves <renan.saddam@gmail.com>
|
||||
* @author Sebastian Kroczek <sk@xbug.de>
|
||||
* @author Dmitry Lukashin <dmitry@lukashin.ru>
|
||||
* @author Laurent Bassin <laurent@bassin.info>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class Idn
|
||||
{
|
||||
const INTL_IDNA_VARIANT_2003 = 0;
|
||||
const INTL_IDNA_VARIANT_UTS46 = 1;
|
||||
|
||||
private static $encodeTable = array(
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
|
||||
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
|
||||
'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
);
|
||||
|
||||
private static $decodeTable = array(
|
||||
'a' => 0, 'b' => 1, 'c' => 2, 'd' => 3, 'e' => 4, 'f' => 5,
|
||||
'g' => 6, 'h' => 7, 'i' => 8, 'j' => 9, 'k' => 10, 'l' => 11,
|
||||
'm' => 12, 'n' => 13, 'o' => 14, 'p' => 15, 'q' => 16, 'r' => 17,
|
||||
's' => 18, 't' => 19, 'u' => 20, 'v' => 21, 'w' => 22, 'x' => 23,
|
||||
'y' => 24, 'z' => 25, '0' => 26, '1' => 27, '2' => 28, '3' => 29,
|
||||
'4' => 30, '5' => 31, '6' => 32, '7' => 33, '8' => 34, '9' => 35,
|
||||
);
|
||||
|
||||
public static function idn_to_ascii($domain, $options, $variant, &$idna_info = array())
|
||||
{
|
||||
if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) {
|
||||
@trigger_error('idn_to_ascii(): INTL_IDNA_VARIANT_2003 is deprecated', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (self::INTL_IDNA_VARIANT_UTS46 === $variant) {
|
||||
$domain = mb_strtolower($domain, 'utf-8');
|
||||
}
|
||||
|
||||
$parts = explode('.', $domain);
|
||||
|
||||
foreach ($parts as $i => &$part) {
|
||||
if ('' === $part && \count($parts) > 1 + $i) {
|
||||
return false;
|
||||
}
|
||||
if (false === $part = self::encodePart($part)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$output = implode('.', $parts);
|
||||
|
||||
$idna_info = array(
|
||||
'result' => \strlen($output) > 255 ? false : $output,
|
||||
'isTransitionalDifferent' => false,
|
||||
'errors' => 0,
|
||||
);
|
||||
|
||||
return $idna_info['result'];
|
||||
}
|
||||
|
||||
public static function idn_to_utf8($domain, $options, $variant, &$idna_info = array())
|
||||
{
|
||||
if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) {
|
||||
@trigger_error('idn_to_utf8(): INTL_IDNA_VARIANT_2003 is deprecated', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$parts = explode('.', $domain);
|
||||
|
||||
foreach ($parts as &$part) {
|
||||
$length = \strlen($part);
|
||||
if ($length < 1 || 63 < $length) {
|
||||
continue;
|
||||
}
|
||||
if (0 !== strpos($part, 'xn--')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$part = substr($part, 4);
|
||||
$part = self::decodePart($part);
|
||||
}
|
||||
|
||||
$output = implode('.', $parts);
|
||||
|
||||
$idna_info = array(
|
||||
'result' => \strlen($output) > 255 ? false : $output,
|
||||
'isTransitionalDifferent' => false,
|
||||
'errors' => 0,
|
||||
);
|
||||
|
||||
return $idna_info['result'];
|
||||
}
|
||||
|
||||
private static function encodePart($input)
|
||||
{
|
||||
if (\substr($input, 0, 1) === '-' || \substr($input, -1) === '-') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$codePoints = self::listCodePoints($input);
|
||||
|
||||
$n = 128;
|
||||
$bias = 72;
|
||||
$delta = 0;
|
||||
$h = $b = \count($codePoints['basic']);
|
||||
|
||||
$output = '';
|
||||
foreach ($codePoints['basic'] as $code) {
|
||||
$output .= mb_chr($code, 'utf-8');
|
||||
}
|
||||
if ($input === $output) {
|
||||
return $output;
|
||||
}
|
||||
if ($b > 0) {
|
||||
$output .= '-';
|
||||
}
|
||||
|
||||
$codePoints['nonBasic'] = array_unique($codePoints['nonBasic']);
|
||||
sort($codePoints['nonBasic']);
|
||||
|
||||
$i = 0;
|
||||
$length = mb_strlen($input, 'utf-8');
|
||||
while ($h < $length) {
|
||||
$m = $codePoints['nonBasic'][$i++];
|
||||
$delta += ($m - $n) * ($h + 1);
|
||||
$n = $m;
|
||||
|
||||
foreach ($codePoints['all'] as $c) {
|
||||
if ($c < $n || $c < 128) {
|
||||
++$delta;
|
||||
}
|
||||
if ($c === $n) {
|
||||
$q = $delta;
|
||||
for ($k = 36;; $k += 36) {
|
||||
$t = self::calculateThreshold($k, $bias);
|
||||
if ($q < $t) {
|
||||
break;
|
||||
}
|
||||
|
||||
$code = $t + (($q - $t) % (36 - $t));
|
||||
$output .= self::$encodeTable[$code];
|
||||
|
||||
$q = ($q - $t) / (36 - $t);
|
||||
}
|
||||
|
||||
$output .= self::$encodeTable[$q];
|
||||
$bias = self::adapt($delta, $h + 1, ($h === $b));
|
||||
$delta = 0;
|
||||
++$h;
|
||||
}
|
||||
}
|
||||
|
||||
++$delta;
|
||||
++$n;
|
||||
}
|
||||
|
||||
$output = 'xn--'.$output;
|
||||
|
||||
return \strlen($output) < 1 || 63 < \strlen($output) ? false : strtolower($output);
|
||||
}
|
||||
|
||||
private static function listCodePoints($input)
|
||||
{
|
||||
$codePoints = array(
|
||||
'all' => array(),
|
||||
'basic' => array(),
|
||||
'nonBasic' => array(),
|
||||
);
|
||||
|
||||
$length = mb_strlen($input, 'utf-8');
|
||||
for ($i = 0; $i < $length; ++$i) {
|
||||
$char = mb_substr($input, $i, 1, 'utf-8');
|
||||
$code = mb_ord($char, 'utf-8');
|
||||
if ($code < 128) {
|
||||
$codePoints['all'][] = $codePoints['basic'][] = $code;
|
||||
} else {
|
||||
$codePoints['all'][] = $codePoints['nonBasic'][] = $code;
|
||||
}
|
||||
}
|
||||
|
||||
return $codePoints;
|
||||
}
|
||||
|
||||
private static function calculateThreshold($k, $bias)
|
||||
{
|
||||
if ($k <= $bias + 1) {
|
||||
return 1;
|
||||
}
|
||||
if ($k >= $bias + 26) {
|
||||
return 26;
|
||||
}
|
||||
|
||||
return $k - $bias;
|
||||
}
|
||||
|
||||
private static function adapt($delta, $numPoints, $firstTime)
|
||||
{
|
||||
$delta = (int) ($firstTime ? $delta / 700 : $delta / 2);
|
||||
$delta += (int) ($delta / $numPoints);
|
||||
|
||||
$k = 0;
|
||||
while ($delta > 35 * 13) {
|
||||
$delta = (int) ($delta / 35);
|
||||
$k = $k + 36;
|
||||
}
|
||||
|
||||
return $k + (int) (36 * $delta / ($delta + 38));
|
||||
}
|
||||
|
||||
private static function decodePart($input)
|
||||
{
|
||||
$n = 128;
|
||||
$i = 0;
|
||||
$bias = 72;
|
||||
$output = '';
|
||||
|
||||
$pos = strrpos($input, '-');
|
||||
if (false !== $pos) {
|
||||
$output = substr($input, 0, $pos++);
|
||||
} else {
|
||||
$pos = 0;
|
||||
}
|
||||
|
||||
$outputLength = \strlen($output);
|
||||
$inputLength = \strlen($input);
|
||||
|
||||
while ($pos < $inputLength) {
|
||||
$oldi = $i;
|
||||
$w = 1;
|
||||
|
||||
for ($k = 36;; $k += 36) {
|
||||
$digit = self::$decodeTable[$input[$pos++]];
|
||||
$i += $digit * $w;
|
||||
$t = self::calculateThreshold($k, $bias);
|
||||
|
||||
if ($digit < $t) {
|
||||
break;
|
||||
}
|
||||
|
||||
$w *= 36 - $t;
|
||||
}
|
||||
|
||||
$bias = self::adapt($i - $oldi, ++$outputLength, 0 === $oldi);
|
||||
$n = $n + (int) ($i / $outputLength);
|
||||
$i = $i % $outputLength;
|
||||
$output = mb_substr($output, 0, $i, 'utf-8').mb_chr($n, 'utf-8').mb_substr($output, $i, $outputLength - 1, 'utf-8');
|
||||
|
||||
++$i;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
19
wp-content/plugins/wp-mail-smtp/vendor/symfony/polyfill-intl-idn/LICENSE
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2018-2019 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
141
wp-content/plugins/wp-mail-smtp/vendor/symfony/polyfill-intl-idn/bootstrap.php
vendored
Normal file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Symfony\Polyfill\Intl\Idn as p;
|
||||
|
||||
if (extension_loaded('intl')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!defined('U_IDNA_PROHIBITED_ERROR')) {
|
||||
define('U_IDNA_PROHIBITED_ERROR', 66560);
|
||||
}
|
||||
if (!defined('U_IDNA_ERROR_START')) {
|
||||
define('U_IDNA_ERROR_START', 66560);
|
||||
}
|
||||
if (!defined('U_IDNA_UNASSIGNED_ERROR')) {
|
||||
define('U_IDNA_UNASSIGNED_ERROR', 66561);
|
||||
}
|
||||
if (!defined('U_IDNA_CHECK_BIDI_ERROR')) {
|
||||
define('U_IDNA_CHECK_BIDI_ERROR', 66562);
|
||||
}
|
||||
if (!defined('U_IDNA_STD3_ASCII_RULES_ERROR')) {
|
||||
define('U_IDNA_STD3_ASCII_RULES_ERROR', 66563);
|
||||
}
|
||||
if (!defined('U_IDNA_ACE_PREFIX_ERROR')) {
|
||||
define('U_IDNA_ACE_PREFIX_ERROR', 66564);
|
||||
}
|
||||
if (!defined('U_IDNA_VERIFICATION_ERROR')) {
|
||||
define('U_IDNA_VERIFICATION_ERROR', 66565);
|
||||
}
|
||||
if (!defined('U_IDNA_LABEL_TOO_LONG_ERROR')) {
|
||||
define('U_IDNA_LABEL_TOO_LONG_ERROR', 66566);
|
||||
}
|
||||
if (!defined('U_IDNA_ZERO_LENGTH_LABEL_ERROR')) {
|
||||
define('U_IDNA_ZERO_LENGTH_LABEL_ERROR', 66567);
|
||||
}
|
||||
if (!defined('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR')) {
|
||||
define('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR', 66568);
|
||||
}
|
||||
if (!defined('U_IDNA_ERROR_LIMIT')) {
|
||||
define('U_IDNA_ERROR_LIMIT', 66569);
|
||||
}
|
||||
if (!defined('U_STRINGPREP_PROHIBITED_ERROR')) {
|
||||
define('U_STRINGPREP_PROHIBITED_ERROR', 66560);
|
||||
}
|
||||
if (!defined('U_STRINGPREP_UNASSIGNED_ERROR')) {
|
||||
define('U_STRINGPREP_UNASSIGNED_ERROR', 66561);
|
||||
}
|
||||
if (!defined('U_STRINGPREP_CHECK_BIDI_ERROR')) {
|
||||
define('U_STRINGPREP_CHECK_BIDI_ERROR', 66562);
|
||||
}
|
||||
if (!defined('IDNA_DEFAULT')) {
|
||||
define('IDNA_DEFAULT', 0);
|
||||
}
|
||||
if (!defined('IDNA_ALLOW_UNASSIGNED')) {
|
||||
define('IDNA_ALLOW_UNASSIGNED', 1);
|
||||
}
|
||||
if (!defined('IDNA_USE_STD3_RULES')) {
|
||||
define('IDNA_USE_STD3_RULES', 2);
|
||||
}
|
||||
if (!defined('IDNA_CHECK_BIDI')) {
|
||||
define('IDNA_CHECK_BIDI', 4);
|
||||
}
|
||||
if (!defined('IDNA_CHECK_CONTEXTJ')) {
|
||||
define('IDNA_CHECK_CONTEXTJ', 8);
|
||||
}
|
||||
if (!defined('IDNA_NONTRANSITIONAL_TO_ASCII')) {
|
||||
define('IDNA_NONTRANSITIONAL_TO_ASCII', 16);
|
||||
}
|
||||
if (!defined('IDNA_NONTRANSITIONAL_TO_UNICODE')) {
|
||||
define('IDNA_NONTRANSITIONAL_TO_UNICODE', 32);
|
||||
}
|
||||
if (!defined('INTL_IDNA_VARIANT_2003')) {
|
||||
define('INTL_IDNA_VARIANT_2003', 0);
|
||||
}
|
||||
if (!defined('INTL_IDNA_VARIANT_UTS46')) {
|
||||
define('INTL_IDNA_VARIANT_UTS46', 1);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_EMPTY_LABEL')) {
|
||||
define('IDNA_ERROR_EMPTY_LABEL', 1);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_LABEL_TOO_LONG')) {
|
||||
define('IDNA_ERROR_LABEL_TOO_LONG', 2);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_DOMAIN_NAME_TOO_LONG')) {
|
||||
define('IDNA_ERROR_DOMAIN_NAME_TOO_LONG', 4);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_LEADING_HYPHEN')) {
|
||||
define('IDNA_ERROR_LEADING_HYPHEN', 8);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_TRAILING_HYPHEN')) {
|
||||
define('IDNA_ERROR_TRAILING_HYPHEN', 16);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_HYPHEN_3_4')) {
|
||||
define('IDNA_ERROR_HYPHEN_3_4', 32);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_LEADING_COMBINING_MARK')) {
|
||||
define('IDNA_ERROR_LEADING_COMBINING_MARK', 64);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_DISALLOWED')) {
|
||||
define('IDNA_ERROR_DISALLOWED', 128);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_PUNYCODE')) {
|
||||
define('IDNA_ERROR_PUNYCODE', 256);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_LABEL_HAS_DOT')) {
|
||||
define('IDNA_ERROR_LABEL_HAS_DOT', 512);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_INVALID_ACE_LABEL')) {
|
||||
define('IDNA_ERROR_INVALID_ACE_LABEL', 1024);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_BIDI')) {
|
||||
define('IDNA_ERROR_BIDI', 2048);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_CONTEXTJ')) {
|
||||
define('IDNA_ERROR_CONTEXTJ', 4096);
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID < 70400) {
|
||||
if (!function_exists('idn_to_ascii')) {
|
||||
function idn_to_ascii($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_2003, &$idna_info = array()) { return p\Idn::idn_to_ascii($domain, $options, $variant, $idna_info); }
|
||||
}
|
||||
if (!function_exists('idn_to_utf8')) {
|
||||
function idn_to_utf8($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_2003, &$idna_info = array()) { return p\Idn::idn_to_utf8($domain, $options, $variant, $idna_info); }
|
||||
}
|
||||
} else {
|
||||
if (!function_exists('idn_to_ascii')) {
|
||||
function idn_to_ascii($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = array()) { return p\Idn::idn_to_ascii($domain, $options, $variant, $idna_info); }
|
||||
}
|
||||
if (!function_exists('idn_to_utf8')) {
|
||||
function idn_to_utf8($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = array()) { return p\Idn::idn_to_utf8($domain, $options, $variant, $idna_info); }
|
||||
}
|
||||
}
|
19
wp-content/plugins/wp-mail-smtp/vendor/symfony/polyfill-mbstring/LICENSE
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2015-2019 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
847
wp-content/plugins/wp-mail-smtp/vendor/symfony/polyfill-mbstring/Mbstring.php
vendored
Normal file
@ -0,0 +1,847 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Polyfill\Mbstring;
|
||||
|
||||
/**
|
||||
* Partial mbstring implementation in PHP, iconv based, UTF-8 centric.
|
||||
*
|
||||
* Implemented:
|
||||
* - mb_chr - Returns a specific character from its Unicode code point
|
||||
* - mb_convert_encoding - Convert character encoding
|
||||
* - mb_convert_variables - Convert character code in variable(s)
|
||||
* - mb_decode_mimeheader - Decode string in MIME header field
|
||||
* - mb_encode_mimeheader - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED
|
||||
* - mb_decode_numericentity - Decode HTML numeric string reference to character
|
||||
* - mb_encode_numericentity - Encode character to HTML numeric string reference
|
||||
* - mb_convert_case - Perform case folding on a string
|
||||
* - mb_detect_encoding - Detect character encoding
|
||||
* - mb_get_info - Get internal settings of mbstring
|
||||
* - mb_http_input - Detect HTTP input character encoding
|
||||
* - mb_http_output - Set/Get HTTP output character encoding
|
||||
* - mb_internal_encoding - Set/Get internal character encoding
|
||||
* - mb_list_encodings - Returns an array of all supported encodings
|
||||
* - mb_ord - Returns the Unicode code point of a character
|
||||
* - mb_output_handler - Callback function converts character encoding in output buffer
|
||||
* - mb_scrub - Replaces ill-formed byte sequences with substitute characters
|
||||
* - mb_strlen - Get string length
|
||||
* - mb_strpos - Find position of first occurrence of string in a string
|
||||
* - mb_strrpos - Find position of last occurrence of a string in a string
|
||||
* - mb_str_split - Convert a string to an array
|
||||
* - mb_strtolower - Make a string lowercase
|
||||
* - mb_strtoupper - Make a string uppercase
|
||||
* - mb_substitute_character - Set/Get substitution character
|
||||
* - mb_substr - Get part of string
|
||||
* - mb_stripos - Finds position of first occurrence of a string within another, case insensitive
|
||||
* - mb_stristr - Finds first occurrence of a string within another, case insensitive
|
||||
* - mb_strrchr - Finds the last occurrence of a character in a string within another
|
||||
* - mb_strrichr - Finds the last occurrence of a character in a string within another, case insensitive
|
||||
* - mb_strripos - Finds position of last occurrence of a string within another, case insensitive
|
||||
* - mb_strstr - Finds first occurrence of a string within another
|
||||
* - mb_strwidth - Return width of string
|
||||
* - mb_substr_count - Count the number of substring occurrences
|
||||
*
|
||||
* Not implemented:
|
||||
* - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more)
|
||||
* - mb_ereg_* - Regular expression with multibyte support
|
||||
* - mb_parse_str - Parse GET/POST/COOKIE data and set global variable
|
||||
* - mb_preferred_mime_name - Get MIME charset string
|
||||
* - mb_regex_encoding - Returns current encoding for multibyte regex as string
|
||||
* - mb_regex_set_options - Set/Get the default options for mbregex functions
|
||||
* - mb_send_mail - Send encoded mail
|
||||
* - mb_split - Split multibyte string using regular expression
|
||||
* - mb_strcut - Get part of string
|
||||
* - mb_strimwidth - Get truncated string with specified width
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class Mbstring
|
||||
{
|
||||
const MB_CASE_FOLD = PHP_INT_MAX;
|
||||
|
||||
private static $encodingList = array('ASCII', 'UTF-8');
|
||||
private static $language = 'neutral';
|
||||
private static $internalEncoding = 'UTF-8';
|
||||
private static $caseFold = array(
|
||||
array('µ', 'ſ', "\xCD\x85", 'ς', "\xCF\x90", "\xCF\x91", "\xCF\x95", "\xCF\x96", "\xCF\xB0", "\xCF\xB1", "\xCF\xB5", "\xE1\xBA\x9B", "\xE1\xBE\xBE"),
|
||||
array('μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "\xE1\xB9\xA1", 'ι'),
|
||||
);
|
||||
|
||||
public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
|
||||
{
|
||||
if (\is_array($fromEncoding) || false !== strpos($fromEncoding, ',')) {
|
||||
$fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
|
||||
} else {
|
||||
$fromEncoding = self::getEncoding($fromEncoding);
|
||||
}
|
||||
|
||||
$toEncoding = self::getEncoding($toEncoding);
|
||||
|
||||
if ('BASE64' === $fromEncoding) {
|
||||
$s = base64_decode($s);
|
||||
$fromEncoding = $toEncoding;
|
||||
}
|
||||
|
||||
if ('BASE64' === $toEncoding) {
|
||||
return base64_encode($s);
|
||||
}
|
||||
|
||||
if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) {
|
||||
if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) {
|
||||
$fromEncoding = 'Windows-1252';
|
||||
}
|
||||
if ('UTF-8' !== $fromEncoding) {
|
||||
$s = iconv($fromEncoding, 'UTF-8//IGNORE', $s);
|
||||
}
|
||||
|
||||
return preg_replace_callback('/[\x80-\xFF]+/', array(__CLASS__, 'html_encoding_callback'), $s);
|
||||
}
|
||||
|
||||
if ('HTML-ENTITIES' === $fromEncoding) {
|
||||
$s = html_entity_decode($s, ENT_COMPAT, 'UTF-8');
|
||||
$fromEncoding = 'UTF-8';
|
||||
}
|
||||
|
||||
return iconv($fromEncoding, $toEncoding.'//IGNORE', $s);
|
||||
}
|
||||
|
||||
public static function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null)
|
||||
{
|
||||
$vars = array(&$a, &$b, &$c, &$d, &$e, &$f);
|
||||
|
||||
$ok = true;
|
||||
array_walk_recursive($vars, function (&$v) use (&$ok, $toEncoding, $fromEncoding) {
|
||||
if (false === $v = Mbstring::mb_convert_encoding($v, $toEncoding, $fromEncoding)) {
|
||||
$ok = false;
|
||||
}
|
||||
});
|
||||
|
||||
return $ok ? $fromEncoding : false;
|
||||
}
|
||||
|
||||
public static function mb_decode_mimeheader($s)
|
||||
{
|
||||
return iconv_mime_decode($s, 2, self::$internalEncoding);
|
||||
}
|
||||
|
||||
public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null)
|
||||
{
|
||||
trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', E_USER_WARNING);
|
||||
}
|
||||
|
||||
public static function mb_decode_numericentity($s, $convmap, $encoding = null)
|
||||
{
|
||||
if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) {
|
||||
trigger_error('mb_decode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', E_USER_WARNING);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!\is_array($convmap) || !$convmap) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null !== $encoding && !\is_scalar($encoding)) {
|
||||
trigger_error('mb_decode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', E_USER_WARNING);
|
||||
|
||||
return ''; // Instead of null (cf. mb_encode_numericentity).
|
||||
}
|
||||
|
||||
$s = (string) $s;
|
||||
if ('' === $s) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$encoding = self::getEncoding($encoding);
|
||||
|
||||
if ('UTF-8' === $encoding) {
|
||||
$encoding = null;
|
||||
if (!preg_match('//u', $s)) {
|
||||
$s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
|
||||
}
|
||||
} else {
|
||||
$s = iconv($encoding, 'UTF-8//IGNORE', $s);
|
||||
}
|
||||
|
||||
$cnt = floor(\count($convmap) / 4) * 4;
|
||||
|
||||
for ($i = 0; $i < $cnt; $i += 4) {
|
||||
// collector_decode_htmlnumericentity ignores $convmap[$i + 3]
|
||||
$convmap[$i] += $convmap[$i + 2];
|
||||
$convmap[$i + 1] += $convmap[$i + 2];
|
||||
}
|
||||
|
||||
$s = preg_replace_callback('/&#(?:0*([0-9]+)|x0*([0-9a-fA-F]+))(?!&);?/', function (array $m) use ($cnt, $convmap) {
|
||||
$c = isset($m[2]) ? (int) hexdec($m[2]) : $m[1];
|
||||
for ($i = 0; $i < $cnt; $i += 4) {
|
||||
if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) {
|
||||
return Mbstring::mb_chr($c - $convmap[$i + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
return $m[0];
|
||||
}, $s);
|
||||
|
||||
if (null === $encoding) {
|
||||
return $s;
|
||||
}
|
||||
|
||||
return iconv('UTF-8', $encoding.'//IGNORE', $s);
|
||||
}
|
||||
|
||||
public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false)
|
||||
{
|
||||
if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) {
|
||||
trigger_error('mb_encode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', E_USER_WARNING);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!\is_array($convmap) || !$convmap) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null !== $encoding && !\is_scalar($encoding)) {
|
||||
trigger_error('mb_encode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', E_USER_WARNING);
|
||||
|
||||
return null; // Instead of '' (cf. mb_decode_numericentity).
|
||||
}
|
||||
|
||||
if (null !== $is_hex && !\is_scalar($is_hex)) {
|
||||
trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, '.\gettype($s).' given', E_USER_WARNING);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$s = (string) $s;
|
||||
if ('' === $s) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$encoding = self::getEncoding($encoding);
|
||||
|
||||
if ('UTF-8' === $encoding) {
|
||||
$encoding = null;
|
||||
if (!preg_match('//u', $s)) {
|
||||
$s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
|
||||
}
|
||||
} else {
|
||||
$s = iconv($encoding, 'UTF-8//IGNORE', $s);
|
||||
}
|
||||
|
||||
static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
|
||||
|
||||
$cnt = floor(\count($convmap) / 4) * 4;
|
||||
$i = 0;
|
||||
$len = \strlen($s);
|
||||
$result = '';
|
||||
|
||||
while ($i < $len) {
|
||||
$ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
|
||||
$uchr = substr($s, $i, $ulen);
|
||||
$i += $ulen;
|
||||
$c = self::mb_ord($uchr);
|
||||
|
||||
for ($j = 0; $j < $cnt; $j += 4) {
|
||||
if ($c >= $convmap[$j] && $c <= $convmap[$j + 1]) {
|
||||
$cOffset = ($c + $convmap[$j + 2]) & $convmap[$j + 3];
|
||||
$result .= $is_hex ? sprintf('&#x%X;', $cOffset) : '&#'.$cOffset.';';
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
$result .= $uchr;
|
||||
}
|
||||
|
||||
if (null === $encoding) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return iconv('UTF-8', $encoding.'//IGNORE', $result);
|
||||
}
|
||||
|
||||
public static function mb_convert_case($s, $mode, $encoding = null)
|
||||
{
|
||||
$s = (string) $s;
|
||||
if ('' === $s) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$encoding = self::getEncoding($encoding);
|
||||
|
||||
if ('UTF-8' === $encoding) {
|
||||
$encoding = null;
|
||||
if (!preg_match('//u', $s)) {
|
||||
$s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
|
||||
}
|
||||
} else {
|
||||
$s = iconv($encoding, 'UTF-8//IGNORE', $s);
|
||||
}
|
||||
|
||||
if (MB_CASE_TITLE == $mode) {
|
||||
static $titleRegexp = null;
|
||||
if (null === $titleRegexp) {
|
||||
$titleRegexp = self::getData('titleCaseRegexp');
|
||||
}
|
||||
$s = preg_replace_callback($titleRegexp, array(__CLASS__, 'title_case'), $s);
|
||||
} else {
|
||||
if (MB_CASE_UPPER == $mode) {
|
||||
static $upper = null;
|
||||
if (null === $upper) {
|
||||
$upper = self::getData('upperCase');
|
||||
}
|
||||
$map = $upper;
|
||||
} else {
|
||||
if (self::MB_CASE_FOLD === $mode) {
|
||||
$s = str_replace(self::$caseFold[0], self::$caseFold[1], $s);
|
||||
}
|
||||
|
||||
static $lower = null;
|
||||
if (null === $lower) {
|
||||
$lower = self::getData('lowerCase');
|
||||
}
|
||||
$map = $lower;
|
||||
}
|
||||
|
||||
static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
|
||||
|
||||
$i = 0;
|
||||
$len = \strlen($s);
|
||||
|
||||
while ($i < $len) {
|
||||
$ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
|
||||
$uchr = substr($s, $i, $ulen);
|
||||
$i += $ulen;
|
||||
|
||||
if (isset($map[$uchr])) {
|
||||
$uchr = $map[$uchr];
|
||||
$nlen = \strlen($uchr);
|
||||
|
||||
if ($nlen == $ulen) {
|
||||
$nlen = $i;
|
||||
do {
|
||||
$s[--$nlen] = $uchr[--$ulen];
|
||||
} while ($ulen);
|
||||
} else {
|
||||
$s = substr_replace($s, $uchr, $i - $ulen, $ulen);
|
||||
$len += $nlen - $ulen;
|
||||
$i += $nlen - $ulen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null === $encoding) {
|
||||
return $s;
|
||||
}
|
||||
|
||||
return iconv('UTF-8', $encoding.'//IGNORE', $s);
|
||||
}
|
||||
|
||||
public static function mb_internal_encoding($encoding = null)
|
||||
{
|
||||
if (null === $encoding) {
|
||||
return self::$internalEncoding;
|
||||
}
|
||||
|
||||
$encoding = self::getEncoding($encoding);
|
||||
|
||||
if ('UTF-8' === $encoding || false !== @iconv($encoding, $encoding, ' ')) {
|
||||
self::$internalEncoding = $encoding;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function mb_language($lang = null)
|
||||
{
|
||||
if (null === $lang) {
|
||||
return self::$language;
|
||||
}
|
||||
|
||||
switch ($lang = strtolower($lang)) {
|
||||
case 'uni':
|
||||
case 'neutral':
|
||||
self::$language = $lang;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function mb_list_encodings()
|
||||
{
|
||||
return array('UTF-8');
|
||||
}
|
||||
|
||||
public static function mb_encoding_aliases($encoding)
|
||||
{
|
||||
switch (strtoupper($encoding)) {
|
||||
case 'UTF8':
|
||||
case 'UTF-8':
|
||||
return array('utf8');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function mb_check_encoding($var = null, $encoding = null)
|
||||
{
|
||||
if (null === $encoding) {
|
||||
if (null === $var) {
|
||||
return false;
|
||||
}
|
||||
$encoding = self::$internalEncoding;
|
||||
}
|
||||
|
||||
return self::mb_detect_encoding($var, array($encoding)) || false !== @iconv($encoding, $encoding, $var);
|
||||
}
|
||||
|
||||
public static function mb_detect_encoding($str, $encodingList = null, $strict = false)
|
||||
{
|
||||
if (null === $encodingList) {
|
||||
$encodingList = self::$encodingList;
|
||||
} else {
|
||||
if (!\is_array($encodingList)) {
|
||||
$encodingList = array_map('trim', explode(',', $encodingList));
|
||||
}
|
||||
$encodingList = array_map('strtoupper', $encodingList);
|
||||
}
|
||||
|
||||
foreach ($encodingList as $enc) {
|
||||
switch ($enc) {
|
||||
case 'ASCII':
|
||||
if (!preg_match('/[\x80-\xFF]/', $str)) {
|
||||
return $enc;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'UTF8':
|
||||
case 'UTF-8':
|
||||
if (preg_match('//u', $str)) {
|
||||
return 'UTF-8';
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (0 === strncmp($enc, 'ISO-8859-', 9)) {
|
||||
return $enc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function mb_detect_order($encodingList = null)
|
||||
{
|
||||
if (null === $encodingList) {
|
||||
return self::$encodingList;
|
||||
}
|
||||
|
||||
if (!\is_array($encodingList)) {
|
||||
$encodingList = array_map('trim', explode(',', $encodingList));
|
||||
}
|
||||
$encodingList = array_map('strtoupper', $encodingList);
|
||||
|
||||
foreach ($encodingList as $enc) {
|
||||
switch ($enc) {
|
||||
default:
|
||||
if (strncmp($enc, 'ISO-8859-', 9)) {
|
||||
return false;
|
||||
}
|
||||
// no break
|
||||
case 'ASCII':
|
||||
case 'UTF8':
|
||||
case 'UTF-8':
|
||||
}
|
||||
}
|
||||
|
||||
self::$encodingList = $encodingList;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function mb_strlen($s, $encoding = null)
|
||||
{
|
||||
$encoding = self::getEncoding($encoding);
|
||||
if ('CP850' === $encoding || 'ASCII' === $encoding) {
|
||||
return \strlen($s);
|
||||
}
|
||||
|
||||
return @iconv_strlen($s, $encoding);
|
||||
}
|
||||
|
||||
public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null)
|
||||
{
|
||||
$encoding = self::getEncoding($encoding);
|
||||
if ('CP850' === $encoding || 'ASCII' === $encoding) {
|
||||
return strpos($haystack, $needle, $offset);
|
||||
}
|
||||
|
||||
$needle = (string) $needle;
|
||||
if ('' === $needle) {
|
||||
trigger_error(__METHOD__.': Empty delimiter', E_USER_WARNING);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return iconv_strpos($haystack, $needle, $offset, $encoding);
|
||||
}
|
||||
|
||||
public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null)
|
||||
{
|
||||
$encoding = self::getEncoding($encoding);
|
||||
if ('CP850' === $encoding || 'ASCII' === $encoding) {
|
||||
return strrpos($haystack, $needle, $offset);
|
||||
}
|
||||
|
||||
if ($offset != (int) $offset) {
|
||||
$offset = 0;
|
||||
} elseif ($offset = (int) $offset) {
|
||||
if ($offset < 0) {
|
||||
if (0 > $offset += self::mb_strlen($needle)) {
|
||||
$haystack = self::mb_substr($haystack, 0, $offset, $encoding);
|
||||
}
|
||||
$offset = 0;
|
||||
} else {
|
||||
$haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding);
|
||||
}
|
||||
}
|
||||
|
||||
$pos = iconv_strrpos($haystack, $needle, $encoding);
|
||||
|
||||
return false !== $pos ? $offset + $pos : false;
|
||||
}
|
||||
|
||||
public static function mb_str_split($string, $split_length = 1, $encoding = null)
|
||||
{
|
||||
if (null !== $string && !\is_scalar($string) && !(\is_object($string) && \method_exists($string, '__toString'))) {
|
||||
trigger_error('mb_str_split() expects parameter 1 to be string, '.\gettype($string).' given', E_USER_WARNING);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (1 > $split_length = (int) $split_length) {
|
||||
trigger_error('The length of each segment must be greater than zero', E_USER_WARNING);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null === $encoding) {
|
||||
$encoding = mb_internal_encoding();
|
||||
}
|
||||
|
||||
if ('UTF-8' === $encoding = self::getEncoding($encoding)) {
|
||||
$rx = '/(';
|
||||
while (65535 < $split_length) {
|
||||
$rx .= '.{65535}';
|
||||
$split_length -= 65535;
|
||||
}
|
||||
$rx .= '.{'.$split_length.'})/us';
|
||||
|
||||
return preg_split($rx, $string, null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
||||
}
|
||||
|
||||
$result = array();
|
||||
$length = mb_strlen($string, $encoding);
|
||||
|
||||
for ($i = 0; $i < $length; $i += $split_length) {
|
||||
$result[] = mb_substr($string, $i, $split_length, $encoding);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function mb_strtolower($s, $encoding = null)
|
||||
{
|
||||
return self::mb_convert_case($s, MB_CASE_LOWER, $encoding);
|
||||
}
|
||||
|
||||
public static function mb_strtoupper($s, $encoding = null)
|
||||
{
|
||||
return self::mb_convert_case($s, MB_CASE_UPPER, $encoding);
|
||||
}
|
||||
|
||||
public static function mb_substitute_character($c = null)
|
||||
{
|
||||
if (0 === strcasecmp($c, 'none')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return null !== $c ? false : 'none';
|
||||
}
|
||||
|
||||
public static function mb_substr($s, $start, $length = null, $encoding = null)
|
||||
{
|
||||
$encoding = self::getEncoding($encoding);
|
||||
if ('CP850' === $encoding || 'ASCII' === $encoding) {
|
||||
return (string) substr($s, $start, null === $length ? 2147483647 : $length);
|
||||
}
|
||||
|
||||
if ($start < 0) {
|
||||
$start = iconv_strlen($s, $encoding) + $start;
|
||||
if ($start < 0) {
|
||||
$start = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (null === $length) {
|
||||
$length = 2147483647;
|
||||
} elseif ($length < 0) {
|
||||
$length = iconv_strlen($s, $encoding) + $length - $start;
|
||||
if ($length < 0) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
return (string) iconv_substr($s, $start, $length, $encoding);
|
||||
}
|
||||
|
||||
public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null)
|
||||
{
|
||||
$haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
|
||||
$needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
|
||||
|
||||
return self::mb_strpos($haystack, $needle, $offset, $encoding);
|
||||
}
|
||||
|
||||
public static function mb_stristr($haystack, $needle, $part = false, $encoding = null)
|
||||
{
|
||||
$pos = self::mb_stripos($haystack, $needle, 0, $encoding);
|
||||
|
||||
return self::getSubpart($pos, $part, $haystack, $encoding);
|
||||
}
|
||||
|
||||
public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null)
|
||||
{
|
||||
$encoding = self::getEncoding($encoding);
|
||||
if ('CP850' === $encoding || 'ASCII' === $encoding) {
|
||||
return strrchr($haystack, $needle, $part);
|
||||
}
|
||||
$needle = self::mb_substr($needle, 0, 1, $encoding);
|
||||
$pos = iconv_strrpos($haystack, $needle, $encoding);
|
||||
|
||||
return self::getSubpart($pos, $part, $haystack, $encoding);
|
||||
}
|
||||
|
||||
public static function mb_strrichr($haystack, $needle, $part = false, $encoding = null)
|
||||
{
|
||||
$needle = self::mb_substr($needle, 0, 1, $encoding);
|
||||
$pos = self::mb_strripos($haystack, $needle, $encoding);
|
||||
|
||||
return self::getSubpart($pos, $part, $haystack, $encoding);
|
||||
}
|
||||
|
||||
public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null)
|
||||
{
|
||||
$haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
|
||||
$needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
|
||||
|
||||
return self::mb_strrpos($haystack, $needle, $offset, $encoding);
|
||||
}
|
||||
|
||||
public static function mb_strstr($haystack, $needle, $part = false, $encoding = null)
|
||||
{
|
||||
$pos = strpos($haystack, $needle);
|
||||
if (false === $pos) {
|
||||
return false;
|
||||
}
|
||||
if ($part) {
|
||||
return substr($haystack, 0, $pos);
|
||||
}
|
||||
|
||||
return substr($haystack, $pos);
|
||||
}
|
||||
|
||||
public static function mb_get_info($type = 'all')
|
||||
{
|
||||
$info = array(
|
||||
'internal_encoding' => self::$internalEncoding,
|
||||
'http_output' => 'pass',
|
||||
'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)',
|
||||
'func_overload' => 0,
|
||||
'func_overload_list' => 'no overload',
|
||||
'mail_charset' => 'UTF-8',
|
||||
'mail_header_encoding' => 'BASE64',
|
||||
'mail_body_encoding' => 'BASE64',
|
||||
'illegal_chars' => 0,
|
||||
'encoding_translation' => 'Off',
|
||||
'language' => self::$language,
|
||||
'detect_order' => self::$encodingList,
|
||||
'substitute_character' => 'none',
|
||||
'strict_detection' => 'Off',
|
||||
);
|
||||
|
||||
if ('all' === $type) {
|
||||
return $info;
|
||||
}
|
||||
if (isset($info[$type])) {
|
||||
return $info[$type];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function mb_http_input($type = '')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function mb_http_output($encoding = null)
|
||||
{
|
||||
return null !== $encoding ? 'pass' === $encoding : 'pass';
|
||||
}
|
||||
|
||||
public static function mb_strwidth($s, $encoding = null)
|
||||
{
|
||||
$encoding = self::getEncoding($encoding);
|
||||
|
||||
if ('UTF-8' !== $encoding) {
|
||||
$s = iconv($encoding, 'UTF-8//IGNORE', $s);
|
||||
}
|
||||
|
||||
$s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide);
|
||||
|
||||
return ($wide << 1) + iconv_strlen($s, 'UTF-8');
|
||||
}
|
||||
|
||||
public static function mb_substr_count($haystack, $needle, $encoding = null)
|
||||
{
|
||||
return substr_count($haystack, $needle);
|
||||
}
|
||||
|
||||
public static function mb_output_handler($contents, $status)
|
||||
{
|
||||
return $contents;
|
||||
}
|
||||
|
||||
public static function mb_chr($code, $encoding = null)
|
||||
{
|
||||
if (0x80 > $code %= 0x200000) {
|
||||
$s = \chr($code);
|
||||
} elseif (0x800 > $code) {
|
||||
$s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F);
|
||||
} elseif (0x10000 > $code) {
|
||||
$s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
|
||||
} else {
|
||||
$s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
|
||||
}
|
||||
|
||||
if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
|
||||
$s = mb_convert_encoding($s, $encoding, 'UTF-8');
|
||||
}
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
public static function mb_ord($s, $encoding = null)
|
||||
{
|
||||
if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
|
||||
$s = mb_convert_encoding($s, 'UTF-8', $encoding);
|
||||
}
|
||||
|
||||
if (1 === \strlen($s)) {
|
||||
return \ord($s);
|
||||
}
|
||||
|
||||
$code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0;
|
||||
if (0xF0 <= $code) {
|
||||
return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80;
|
||||
}
|
||||
if (0xE0 <= $code) {
|
||||
return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80;
|
||||
}
|
||||
if (0xC0 <= $code) {
|
||||
return (($code - 0xC0) << 6) + $s[2] - 0x80;
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
private static function getSubpart($pos, $part, $haystack, $encoding)
|
||||
{
|
||||
if (false === $pos) {
|
||||
return false;
|
||||
}
|
||||
if ($part) {
|
||||
return self::mb_substr($haystack, 0, $pos, $encoding);
|
||||
}
|
||||
|
||||
return self::mb_substr($haystack, $pos, null, $encoding);
|
||||
}
|
||||
|
||||
private static function html_encoding_callback(array $m)
|
||||
{
|
||||
$i = 1;
|
||||
$entities = '';
|
||||
$m = unpack('C*', htmlentities($m[0], ENT_COMPAT, 'UTF-8'));
|
||||
|
||||
while (isset($m[$i])) {
|
||||
if (0x80 > $m[$i]) {
|
||||
$entities .= \chr($m[$i++]);
|
||||
continue;
|
||||
}
|
||||
if (0xF0 <= $m[$i]) {
|
||||
$c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
|
||||
} elseif (0xE0 <= $m[$i]) {
|
||||
$c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
|
||||
} else {
|
||||
$c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80;
|
||||
}
|
||||
|
||||
$entities .= '&#'.$c.';';
|
||||
}
|
||||
|
||||
return $entities;
|
||||
}
|
||||
|
||||
private static function title_case(array $s)
|
||||
{
|
||||
return self::mb_convert_case($s[1], MB_CASE_UPPER, 'UTF-8').self::mb_convert_case($s[2], MB_CASE_LOWER, 'UTF-8');
|
||||
}
|
||||
|
||||
private static function getData($file)
|
||||
{
|
||||
if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) {
|
||||
return require $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function getEncoding($encoding)
|
||||
{
|
||||
if (null === $encoding) {
|
||||
return self::$internalEncoding;
|
||||
}
|
||||
|
||||
if ('UTF-8' === $encoding) {
|
||||
return 'UTF-8';
|
||||
}
|
||||
|
||||
$encoding = strtoupper($encoding);
|
||||
|
||||
if ('8BIT' === $encoding || 'BINARY' === $encoding) {
|
||||
return 'CP850';
|
||||
}
|
||||
|
||||
if ('UTF8' === $encoding) {
|
||||
return 'UTF-8';
|
||||
}
|
||||
|
||||
return $encoding;
|
||||
}
|
||||
}
|