File "WP.php"
Full Path: /home/rrterraplen/public_html/wp-content-20241221212636/plugins/wp-mail-smtp/src/WP.php
File size: 18.84 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace WPMailSMTP;
use WPMailSMTP\Helpers\Helpers;
/**
* Class WP provides WordPress shortcuts.
*
* @since 1.0.0
*/
class WP {
/**
* The "queue" of notices.
*
* @since 1.0.0
*
* @var array
*/
protected static $admin_notices = [];
/**
* 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
*/
const ADMIN_NOTICE_WARNING = 'notice-warning';
/**
* Cross-platform line break.
*
* @since 3.4.0
*
* @var string
*/
const EOL = "\r\n";
/**
* True if WP is processing an AJAX call.
*
* @since 1.0.0
*
* @return bool
*/
public static function is_doing_ajax() {
if ( function_exists( 'wp_doing_ajax' ) ) {
return wp_doing_ajax();
}
return ( defined( 'DOING_AJAX' ) && DOING_AJAX );
}
/**
* True if I am in the Admin Panel, not doing AJAX.
*
* @since 1.0.0
*
* @return bool
*/
public static function in_wp_admin() {
return ( is_admin() && ! self::is_doing_ajax() );
}
/**
* Add a notice to the "queue of notices".
*
* @since 1.0.0
* @since 1.5.0 Added `$is_dismissible` param.
*
* @param string $message Message text (HTML is OK).
* @param string $class Display class (severity).
* @param bool $is_dismissible Whether the message should be dismissible.
*/
public static function add_admin_notice( $message, $class = self::ADMIN_NOTICE_INFO, $is_dismissible = true ) {
self::$admin_notices[] = array(
'message' => $message,
'class' => $class,
'is_dismissible' => (bool) $is_dismissible,
);
}
/**
* Display all notices.
*
* @since 1.0.0
* @since 1.5.0 Allow the notice to be dismissible, remove the id attribute, which is not unique.
*/
public static function display_admin_notices() {
foreach ( (array) self::$admin_notices as $notice ) :
$dismissible = $notice['is_dismissible'] ? 'is-dismissible' : '';
?>
<div class="notice wp-mail-smtp-notice <?php echo esc_attr( $notice['class'] ); ?> notice <?php echo esc_attr( $dismissible ); ?>">
<p>
<?php echo wp_kses_post( $notice['message'] ); ?>
</p>
</div>
<?php
endforeach;
}
/**
* Check whether WP_DEBUG is active.
*
* @since 1.0.0
*
* @return bool
*/
public static function is_debug() {
return defined( 'WP_DEBUG' ) && WP_DEBUG;
}
/**
* Shortcut to global $wpdb.
*
* @since 1.0.0
*
* @return \wpdb
*/
public static function wpdb() {
global $wpdb;
return $wpdb;
}
/**
* Get the postfix for assets files - ".min" or empty.
* ".min" if in production mode.
*
* @since 1.0.0
*
* @return string
*/
public static function asset_min() {
$min = '.min';
if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) {
$min = '';
}
return $min;
}
/**
* Check whether the string is a JSON or not.
*
* @since 1.5.0
*
* @param string $string String we want to test if it's json.
*
* @return bool
*/
public static function is_json( $string ) {
return is_string( $string ) && is_array( json_decode( $string, true ) ) && ( json_last_error() === JSON_ERROR_NONE ) ? true : false;
}
/**
* Get the full date format as per WP options.
*
* @since 1.5.0
*
* @return string
*/
public static function datetime_format() {
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' )
);
}
/**
* Get the full date form as per MySQL format.
*
* @since 1.5.0
*
* @return string
*/
public static function datetime_mysql_format() {
return 'Y-m-d H:i:s';
}
/**
* 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 String we want to sanitize.
*
* @return string
*/
public static function sanitize_value( $value ) {
// Remove HTML tags.
$filtered = wp_strip_all_tags( $value, false );
// Remove multi-lines/tabs.
$filtered = preg_replace( '/[\r\n\t ]+/', ' ', $filtered );
// Remove whitespaces.
$filtered = trim( $filtered );
// Remove octets.
$found = false;
while ( preg_match( '/%[a-f0-9]{2}/i', $filtered, $match ) ) {
$filtered = str_replace( $match[0], '', $filtered );
$found = true;
}
if ( $found ) {
// Strip out the whitespace that may now exist after removing the octets.
$filtered = trim( preg_replace( '/ +/', ' ', $filtered ) );
}
return $filtered;
}
/**
* Get default email address.
*
* This is the same code as used in WP core for getting the default email address.
*
* @see https://github.com/WordPress/WordPress/blob/master/wp-includes/pluggable.php#L332
*
* @since 2.2.0
* @since 2.3.0 In WP 5.5 the core code changed and is now using `network_home_url`.
*
* @return string
*/
public static function get_default_email() {
if ( version_compare( get_bloginfo( 'version' ), '5.5-alpha', '<' ) ) {
$sitename = ! empty( $_SERVER['SERVER_NAME'] ) ?
strtolower( sanitize_text_field( wp_unslash( $_SERVER['SERVER_NAME'] ) ) ) :
wp_parse_url( get_home_url( get_current_blog_id() ), PHP_URL_HOST );
} else {
$sitename = wp_parse_url( network_home_url(), PHP_URL_HOST );
}
if ( 'www.' === substr( $sitename, 0, 4 ) ) {
$sitename = substr( $sitename, 4 );
}
return 'wordpress@' . $sitename;
}
/**
* Wrapper for the WP `admin_url` method that should be used in the plugin.
*
* We can filter into it, to maybe call `network_admin_url` for multisite support.
*
* @since 2.2.0
*
* @param string $path Optional path relative to the admin URL.
* @param string $scheme The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl().
* 'http' or 'https' can be passed to force those schemes.
*
* @return string Admin URL link with optional path appended.
*/
public static function admin_url( $path = '', $scheme = 'admin' ) {
return apply_filters( 'wp_mail_smtp_admin_url', \admin_url( $path, $scheme ), $path, $scheme );
}
/**
* Check if the global plugin option in a multisite should be used.
* If the global plugin option "multisite" is set and true.
*
* @since 2.2.0
*
* @return bool
*/
public static function use_global_plugin_settings() {
if ( ! is_multisite() ) {
return false;
}
$main_site_options = get_blog_option( get_main_site_id(), Options::META_KEY, [] );
return ! empty( $main_site_options['general']['network_wide'] );
}
/**
* Returns Jed-formatted localization data.
* This code was taken from a function removed from WP core: `wp_get_jed_locale_data`.
*
* @since 2.6.0
*
* @param string $domain Translation domain.
*
* @return array
*/
public static function get_jed_locale_data( $domain ) {
$translations = get_translations_for_domain( $domain );
$locale = array(
'' => array(
'domain' => $domain,
'lang' => is_admin() && function_exists( 'get_user_locale' ) ? get_user_locale() : get_locale(),
),
);
if ( ! empty( $translations->headers['Plural-Forms'] ) ) {
$locale['']['plural_forms'] = $translations->headers['Plural-Forms'];
}
foreach ( $translations->entries as $entry ) {
$locale[ $entry->singular ] = $entry->translations;
}
return $locale;
}
/**
* Check if plugins is activated.
* Replacement for is_plugin_active function as it works only in admin area
*
* @since 2.8.0
*
* @param string $plugin_slug Plugin slug.
*
* @return bool
*/
public static function is_plugin_activated( $plugin_slug ) {
static $active_plugins;
if ( ! isset( $active_plugins ) ) {
$active_plugins = (array) get_option( 'active_plugins', [] );
if ( is_multisite() ) {
$active_plugins = array_merge( $active_plugins, get_site_option( 'active_sitewide_plugins', [] ) );
}
}
return ( in_array( $plugin_slug, $active_plugins, true ) || array_key_exists( $plugin_slug, $active_plugins ) );
}
/**
* Get the ISO 639-2 Language Code from user/site locale.
*
* @see http://www.loc.gov/standards/iso639-2/php/code_list.php
*
* @since 2.8.0
*
* @return string
*/
public static function get_language_code() {
$default_lang = 'en';
$locale = get_user_locale();
if ( ! empty( $locale ) ) {
$lang = explode( '_', $locale );
if ( ! empty( $lang ) && is_array( $lang ) ) {
$default_lang = strtolower( $lang[0] );
}
}
return $default_lang;
}
/**
* Get the certain date of a specified day in a specified format.
*
* @since 2.8.0
*
* @param string $period Supported values: start, end.
* @param string $timestamp Default is the current timestamp, if left empty.
* @param string $format Default is a MySQL format.
* @param bool $use_gmt_offset Use GTM offset.
*
* @return string
*/
public static function get_day_period_date( $period, $timestamp = '', $format = 'Y-m-d H:i:s', $use_gmt_offset = false ) {
$date = '';
if ( empty( $timestamp ) ) {
$timestamp = time();
}
$offset_sec = $use_gmt_offset ? get_option( 'gmt_offset' ) * 3600 : 0;
switch ( $period ) {
case 'start_of_day':
$date = gmdate( $format, strtotime( 'today', $timestamp ) - $offset_sec );
break;
case 'end_of_day':
$date = gmdate( $format, strtotime( 'tomorrow', $timestamp ) - 1 - $offset_sec );
break;
}
return $date;
}
/**
* Returns extracted domain from email address.
*
* @since 2.8.0
*
* @param string $email Email address.
*
* @return string
*/
public static function get_email_domain( $email ) {
return substr( strrchr( $email, '@' ), 1 );
}
/**
* Wrapper for set_time_limit to see if it is enabled.
*
* @since 2.8.0
*
* @param int $limit Time limit.
*/
public static function set_time_limit( $limit = 0 ) {
if ( function_exists( 'set_time_limit' ) && false === strpos( ini_get( 'disable_functions' ), 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) { // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.safe_modeDeprecatedRemoved
@set_time_limit( $limit ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
}
}
/**
* Recursive arguments parsing.
*
* @since 2.8.0
*
* @param array $args Arguments.
* @param array $defaults Defaults.
*
* @return array
*/
public static function parse_args_r( &$args, $defaults ) {
$args = (array) $args;
$defaults = (array) $defaults;
$r = $defaults;
foreach ( $args as $k => &$v ) {
if ( is_array( $v ) && isset( $r[ $k ] ) ) {
$r[ $k ] = self::parse_args_r( $v, $r[ $k ] );
} else {
$r[ $k ] = $v;
}
}
return $r;
}
/**
* True if WP is processing plugin related AJAX call.
*
* @since 3.0.0
*
* @return bool
*/
public static function is_doing_self_ajax() {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$action = isset( $_REQUEST['action'] ) ? sanitize_key( $_REQUEST['action'] ) : false;
return self::is_doing_ajax() && $action && substr( $action, 0, 12 ) === 'wp_mail_smtp';
}
/**
* Get the name of the plugin/theme/wp-core that initiated the desired function call.
*
* @since 3.0.0
*
* @param string $file_path The absolute path of a file that that called the desired function.
*
* @return string
*/
public static function get_initiator_name( $file_path ) {
return self::get_initiator( $file_path )['name'];
}
/**
* Get the info of the plugin/theme/wp-core function.
*
* @since 3.5.0
*
* @param string $file_path The absolute path of the function location.
*
* @return array
*/
public static function get_initiator( $file_path ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
$cache_key = 'wp_mail_smtp_initiators_data';
// Mainly we have several initiators and we can cache them for better performance.
$initiators_cache = get_transient( $cache_key );
$initiators_cache = is_array( $initiators_cache ) ? $initiators_cache : [];
if ( isset( $initiators_cache[ $file_path ] ) ) {
return $initiators_cache[ $file_path ];
}
$initiator = self::get_initiator_plugin( $file_path );
// Change the initiator name if the email was sent from the reloaded method in the email controls.
if (
! empty( $initiator ) &&
strpos( str_replace( '\\', '/', $file_path ), 'src/Pro/Emails/Control/Reload.php' )
) {
$initiator['name'] = sprintf( /* translators: %s - plugin name. */
esc_html__( 'WP Core (%s)', 'wp-mail-smtp' ),
$initiator['name']
);
}
if ( empty( $initiator ) ) {
$initiator = self::get_initiator_plugin( $file_path, true );
}
if ( empty( $initiator ) ) {
$initiator = self::get_initiator_theme( $file_path );
}
if ( empty( $initiator ) ) {
$initiator = self::get_initiator_wp_core( $file_path );
}
if ( empty( $initiator ) ) {
$initiator = [];
$initiator['name'] = esc_html__( 'N/A', 'wp-mail-smtp' );
$initiator['slug'] = '';
$initiator['type'] = 'unknown';
}
$initiators_cache[ $file_path ] = $initiator;
set_transient( $cache_key, $initiators_cache, HOUR_IN_SECONDS );
return $initiator;
}
/**
* Get the initiator's data, if it's a plugin (or mu plugin).
*
* @since 3.0.0
*
* @param string $file_path The absolute path of a file.
* @param bool $check_mu_plugin Whether to check for mu plugins or not.
*
* @return false|array
*/
private static function get_initiator_plugin( $file_path, $check_mu_plugin = false ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh, Generic.Metrics.CyclomaticComplexity.MaxExceeded
$constant = empty( $check_mu_plugin ) ? 'WP_PLUGIN_DIR' : 'WPMU_PLUGIN_DIR';
if ( ! defined( $constant ) ) {
return false;
}
$root = basename( constant( $constant ) );
$separator = defined( 'DIRECTORY_SEPARATOR' ) ? '\\' . DIRECTORY_SEPARATOR : '\/';
preg_match( "/$separator$root$separator(.[^$separator]+)($separator|\.php)/", $file_path, $result );
if ( ! empty( $result[1] ) ) {
if ( ! function_exists( 'get_plugins' ) ) {
include ABSPATH . '/wp-admin/includes/plugin.php';
}
$all_plugins = empty( $check_mu_plugin ) ? get_plugins() : get_mu_plugins();
$plugin_slug = $result[1];
foreach ( $all_plugins as $plugin => $plugin_data ) {
if (
1 === preg_match( "/^$plugin_slug(\/|\.php)/", $plugin ) &&
isset( $plugin_data['Name'] )
) {
return [
'name' => $plugin_data['Name'],
'slug' => $plugin,
'type' => $check_mu_plugin ? 'mu-plugin' : 'plugin',
];
}
}
return [
'name' => $result[1],
'slug' => '',
'type' => $check_mu_plugin ? 'mu-plugin' : 'plugin',
];
}
return false;
}
/**
* Get the initiator's data, if it's a theme.
*
* @since 3.0.0
*
* @param string $file_path The absolute path of a file.
*
* @return false|array
*/
private static function get_initiator_theme( $file_path ) {
if ( ! defined( 'WP_CONTENT_DIR' ) ) {
return false;
}
$root = basename( WP_CONTENT_DIR );
$separator = defined( 'DIRECTORY_SEPARATOR' ) ? '\\' . DIRECTORY_SEPARATOR : '\/';
preg_match( "/$separator$root{$separator}themes{$separator}(.[^$separator]+)/", $file_path, $result );
if ( ! empty( $result[1] ) ) {
$theme = wp_get_theme( $result[1] );
return [
'name' => method_exists( $theme, 'get' ) ? $theme->get( 'Name' ) : $result[1],
'slug' => $result[1],
'type' => 'theme',
];
}
return false;
}
/**
* Return WP Core if the file path is from WP Core (wp-admin or wp-includes folders).
*
* @since 3.1.0
*
* @param string $file_path The absolute path of a file.
*
* @return false|array
*/
private static function get_initiator_wp_core( $file_path ) {
if ( ! defined( 'ABSPATH' ) ) {
return false;
}
$wp_includes = defined( 'WPINC' ) ? trailingslashit( ABSPATH . WPINC ) : false;
$wp_admin = trailingslashit( ABSPATH . 'wp-admin' );
if (
strpos( $file_path, $wp_includes ) === 0 ||
strpos( $file_path, $wp_admin ) === 0
) {
return [
'name' => esc_html__( 'WP Core', 'wp-mail-smtp' ),
'slug' => 'wp-core',
'type' => 'wp-core',
];
}
return false;
}
/**
* Retrieves the timezone from site settings as a `DateTimeZone` object.
*
* Timezone can be based on a PHP timezone string or a ±HH:MM offset.
*
* We use `wp_timezone()` when it's available (WP 5.3+),
* otherwise fallback to the same code, copy-pasted.
*
* @since 3.0.2
*
* @return \DateTimeZone Timezone object.
*/
public static function wp_timezone() {
if ( function_exists( 'wp_timezone' ) ) {
return wp_timezone();
}
return new \DateTimeZone( self::wp_timezone_string() );
}
/**
* Retrieves the timezone from site settings as a string.
*
* Uses the `timezone_string` option to get a proper timezone if available,
* otherwise falls back to an offset.
*
* We use `wp_timezone_string()` when it's available (WP 5.3+),
* otherwise fallback to the same code, copy-pasted.
*
* @since 3.0.2
*
* @return string PHP timezone string or a ±HH:MM offset.
*/
public static function wp_timezone_string() {
if ( function_exists( 'wp_timezone_string' ) ) {
return wp_timezone_string();
}
$timezone_string = get_option( 'timezone_string' );
if ( $timezone_string ) {
return $timezone_string;
}
$offset = (float) get_option( 'gmt_offset' );
$hours = (int) $offset;
$minutes = ( $offset - $hours );
$sign = ( $offset < 0 ) ? '-' : '+';
$abs_hour = abs( $hours );
$abs_mins = abs( $minutes * 60 );
$tz_offset = sprintf( '%s%02d:%02d', $sign, $abs_hour, $abs_mins );
return $tz_offset;
}
/**
* Get wp remote response error message.
*
* @since 3.4.0
*
* @param array $response Response array.
*/
public static function wp_remote_get_response_error_message( $response ) {
if ( is_wp_error( $response ) ) {
return '';
}
$body = wp_remote_retrieve_body( $response );
$message = wp_remote_retrieve_response_message( $response );
$code = wp_remote_retrieve_response_code( $response );
$description = '';
if ( ! empty( $body ) ) {
$description = is_string( $body ) ? $body : wp_json_encode( $body );
}
return Helpers::format_error_message( $message, $code, $description );
}
/**
* Clean variables using sanitize_text_field. Arrays are cleaned recursively.
* Non-string values are ignored.
*
* @since 3.7.0
*
* @param string|array $var Data to sanitize.
*
* @return string|array
*/
public static function sanitize_text( $var ) {
if ( is_array( $var ) ) {
return array_map( [ __CLASS__, 'sanitize_text' ], $var );
} else {
return is_string( $var ) ? sanitize_text_field( $var ) : $var;
}
}
}