Changed source root directory

This commit is contained in:
2026-03-05 16:30:11 +01:00
parent dc85447ee1
commit 538f85d7a2
5868 changed files with 749734 additions and 99 deletions

View File

@@ -0,0 +1,7 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
interface Postman_Notify {
public function send_message( $message );
}

View File

@@ -0,0 +1,29 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class PostmanMailNotify implements Postman_Notify {
public function send_message($message)
{
$notification_emails = PostmanNotifyOptions::getInstance()->get_notification_email();
/**
* Filters The Notification Emails
*
* @notification_emails String
*/
$notification_emails = apply_filters( 'post_smtp_notify_email', $notification_emails );
$domain = get_bloginfo( 'url' );
$notification_emails = explode( ',', $notification_emails );
//Lets start informing authorities ;')
foreach( $notification_emails as $to_email ) {
mail( $to_email, "{$domain}: " . __( 'Post SMTP email error', 'post-smtp' ), $message , '', "-f{$to_email}" );
}
}
}

View File

@@ -0,0 +1,88 @@
<?php
class PostmanNotifyOptions {
const DEFAULT_NOTIFICATION_SERVICE = 'default';
const NOTIFICATION_SERVICE = 'notification_service';
const NOTIFICATION_USE_CHROME = 'notification_use_chrome';
const NOTIFICATION_CHROME_UID = 'notification_chrome_uid';
const PUSHOVER_USER = 'pushover_user';
const PUSHOVER_TOKEN = 'pushover_token';
const SLACK_TOKEN = 'slack_token';
const NOTIFICATION_EMAIL = 'notification_email';
private $options;
private static $instance;
public static function getInstance()
{
if ( ! self::$instance ) {
self::$instance = new static;
}
return self::$instance;
}
private function __construct()
{
$this->options = get_option( 'postman_options' );
}
public function getNotificationService() {
if ( isset( $this->options [ self::NOTIFICATION_SERVICE ] ) ) {
return $this->options [ self::NOTIFICATION_SERVICE ];
} else {
return self::DEFAULT_NOTIFICATION_SERVICE;
}
}
public function getPushoverUser() {
if ( isset( $this->options [ self::PUSHOVER_USER ] ) ) {
return base64_decode( $this->options [ self::PUSHOVER_USER ] );
}
}
public function getPushoverToken() {
if ( isset( $this->options [ self::PUSHOVER_TOKEN ] ) ) {
return base64_decode( $this->options [ self::PUSHOVER_TOKEN ] );
}
}
public function getSlackToken() {
if ( isset( $this->options [ self::SLACK_TOKEN ] ) ) {
return base64_decode( $this->options [ self::SLACK_TOKEN ] );
}
}
public function useChromeExtension() {
if ( isset( $this->options [ self::NOTIFICATION_USE_CHROME ] ) ) {
return $this->options [ self::NOTIFICATION_USE_CHROME ];
}
}
public function getNotificationChromeUid() {
if ( isset( $this->options [ self::NOTIFICATION_CHROME_UID ] ) ) {
return base64_decode( $this->options [ self::NOTIFICATION_CHROME_UID ] );
}
}
/**
* Get Notification Email
*
* @since 2.4.0
* @version 1.0.0
*/
public function get_notification_email() {
if ( isset( $this->options[self::NOTIFICATION_EMAIL] ) ) {
return $this->options[self::NOTIFICATION_EMAIL];
}
return get_bloginfo( 'admin_email' );
}
}

View File

@@ -0,0 +1,34 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class PostmanPushoverNotify implements Postman_Notify {
public function send_message($message)
{
$options = PostmanNotifyOptions::getInstance();
$api_url = "https://api.pushover.net/1/messages.json";
$app_token = $options->getPushoverToken();
$user_key = $options->getPushoverUser();
$args = array(
'body' => array(
"token" => $app_token,
"user" => $user_key,
"message" => $message,
)
);
$result = wp_remote_post( $api_url, $args );
if ( is_wp_error($result) ) {
error_log( __CLASS__ . ': ' . $result->get_error_message() );
}
$body = json_decode( wp_remote_retrieve_body( $result ), true );
if ( $body['status'] == 0 ) {
error_log( __CLASS__ . ': ' . print_r( $body, true ) );
}
}
}

View File

@@ -0,0 +1,40 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class PostmanSlackNotify implements Postman_Notify {
public function send_message($message)
{
$options = PostmanNotifyOptions::getInstance();
$api_url = $options->getSlackToken();
$headers = array(
'content-type' => 'application/json'
);
$body = array(
'text' => $message
);
$args = array(
'headers' => $headers,
'body' => json_encode($body)
);
$result = wp_remote_post( $api_url, $args );
if ( is_wp_error($result) ) {
error_log( __CLASS__ . ': ' . $result->get_error_message() );
}
$code = wp_remote_retrieve_response_code( $result );
$message = wp_remote_retrieve_response_message( $result );
if ( $code != 200 && $message !== 'OK' ) {
error_log( __CLASS__ . ': ' . $message );
}
}
}

View File

@@ -0,0 +1,53 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class PostmanWebhookAlertsNotify implements Postman_Notify {
const WEBHOOK_OPTION = 'post_smtp_webhook_urls';
/**
* Broadcasts a message to the webhook
*
* @param string $message
*
* @return void
*
* @since 3.0.0
*/
public function send_message( $message ) {
$webhook_urls = get_option( self::WEBHOOK_OPTION );
foreach ( $webhook_urls as $webhook_url ) {
/**
* Filter to validate the webhook URL
*
* @param bool $validate
* @param string $webhook_url
*
* @since 3.0.0
*/
$validate = apply_filters( 'post_smtp_validate_webhook_url', true, $webhook_url );
if( !$validate || filter_var( $webhook_url, FILTER_VALIDATE_URL ) ) {
$response = wp_remote_post( $webhook_url, array(
'body' => json_encode( array(
'message' => $message
) ),
'headers' => array(
'Content-Type' => 'application/json'
)
) );
}
}
}
}

View File

@@ -0,0 +1,71 @@
(function( $ ) {
'use strict';
$( document ).ready( function() {
// Handle button click for all service-specific test notification buttons
$( document ).on( 'click', '.postman-send-test-notification', function( e ) {
e.preventDefault();
var $button = $( this );
var service = $button.data( 'service' );
if ( ! service || $button.prop( 'disabled' ) ) {
return;
}
// Get service-specific spinner and message elements
var $spinner = $( '#postman-test-notification-spinner-' + service );
var $message = $( '#postman-test-notification-message-' + service );
// Disable button and show spinner
$button.prop( 'disabled', true );
$spinner.css( 'display', 'inline-block' ).addClass( 'is-active' );
$message.empty();
// Send AJAX request
$.ajax( {
url: postmanTestNotification.ajaxUrl,
type: 'POST',
data: {
action: 'postman_send_test_notification',
nonce: postmanTestNotification.nonce,
service: service,
},
success: function( response ) {
$spinner.css( 'display', 'none' ).removeClass( 'is-active' );
$button.prop( 'disabled', false );
if ( response.success ) {
$message.html(
'<div class="notice notice-success is-dismissible"><p><span class="dashicons dashicons-yes-alt"></span> ' +
( response.data && response.data.message ? response.data.message : postmanTestNotification.strings.success ) +
'</p></div>'
);
} else {
var errorMessage = response.data && response.data.message ? response.data.message : postmanTestNotification.strings.error;
$message.html(
'<div class="notice notice-error is-dismissible"><p></span> ' +
errorMessage +
'</p></div>'
);
}
},
error: function( xhr, status, error ) {
$spinner.css( 'display', 'none' ).removeClass( 'is-active' );
$button.prop( 'disabled', false );
var errorMessage = postmanTestNotification.strings.error;
if ( xhr.status === 401 ) {
errorMessage = postmanTestNotification.strings.unauthorized;
}
$message.html(
'<div class="notice notice-error is-dismissible"><p></span> ' +
errorMessage +
'</p></div>'
);
},
} );
} );
} );
})( jQuery );

View File

@@ -0,0 +1,60 @@
<?php
class StatusSolution {
private $status;
public function __construct() {
add_filter( 'post_smtp_log_solution', array( $this, 'find_solution' ), 10, 4 );
}
public function find_solution( $solution, $status, $log, $message ) {
if ( empty( $status ) ) {
return 'All good, mail sent.';
}
$this->status = addslashes( $status );
$possible_solution = [];
if ( $this->strExists('timed out') ) {
$possible_solution[] = $this->make_clickable('https://postmansmtp.com/office365-smtp-connection-timed-out/');
} elseif ( $this->strExists('timeout') || $this->strExists('open socket' ) ) {
$possible_solution[] = 'Your hosting is blocking the connection, contact their support';
} elseif ( $this->strExists( 'DATA NOT ACCEPTED' ) || $this->strExists('Exception:SendAsDeniedException' ) ) {
$possible_solution[] = $this->make_clickable('https://postmansmtp.com/storedrv-submission-exceptionsendasdeniedexception-mapiexceptionsendasdenied/');
} elseif ( $this->strExists( 'Incorrect authentication data') ) {
$possible_solution[] = $this->make_clickable( 'https://postmansmtp.com/incorrect-authentication-data/' );
} elseif ( $this->strExists( 'Unrecognized authentication type' ) ) {
$possible_solution[] = 'Change "Authentication" type on plugin settings to "Login"';
} elseif ( $this->strExists( 'Error executing "SendRawEmail"' ) ) {
$possible_solution[] = 'Amazon SES - account permission error (review account configuration)';
} elseif ( $this->strExists( 'Please log in via your web browser and then try again' ) ) {
$possible_solution[] = $this->make_clickable( 'https://postmansmtp.com/gmail-gsuite-please-log-in-via-your-web-browser-and-then-try-again/' );
} elseif ( $this->strExists( 'Application-specific password required' ) ) {
$possible_solution[] = 'Two factor authentication is enabled, replace your password with app password.';
$possible_solution[] = $this->make_clickable( 'https://support.google.com/mail/?p=InvalidSecondFactor' );
} elseif ( $this->strExists( 'Username and Password not accepted' ) || $this->strExists( 'Authentication unsuccessful' ) ) {
$possible_solution[] = 'Check you credentials, wrong email or password.';
} elseif ( $this->strExists( 'ErrorSendAsDenied' ) ) {
$possible_solution[] = 'Give the configured account "Send As" permissions on the "From" mailbox (admin.office365.com).';
} elseif ( $this->strExists( 'ErrorParticipantDoesntHaveAnEmailAddress' ) ) {
$possible_solution[] = "Probably office 365 doesn't like shared mailbox in Reply-To field";
} else {
$possible_solution[] = 'Not found, check status column for more info.';
}
return ! empty( $possible_solution ) ? implode( '<br>', $possible_solution ) : '';
}
private function make_clickable($url) {
return '<a target="_blank" href="' . esc_url($url ) . '">' . esc_html__( 'Read here', 'post-smtp' ) . '</a>';
}
private function strExists( $value ) {
return strpos( strtolower( $this->status ), strtolower( addslashes( $value ) ) ) !== false;
}
}
new StatusSolution();

View File

@@ -0,0 +1,91 @@
<?php
if( !class_exists( 'Post_SMTP_MainWP_Child_Request' ) ):
class Post_SMTP_MainWP_Child_Request {
private $base_url = false;
/**
* Constructor
*
* @since 2.6.0
* @version 2.6.0
*/
public function __construct() {
$server = apply_filters( 'mainwp_child_get_encrypted_option', false, 'mainwp_child_server', false );
$server = str_replace( 'wp-admin/', '', $server );
if( $server ) {
$this->base_url = $server . 'wp-json/post-smtp-for-mainwp/v1/send-email';
}
}
/**
* Process email
*
* @param string|array $to Array or comma-separated list of email addresses to send message.
* @param string $subject Email subject
* @param string $message Message contents
* @param string|array $headers Optional. Additional headers.
* @param string|array $attachments Optional. Files to attach.
* @return bool Whether the email contents were sent successfully.
* @since 2.6.0
* @version 2.6.0
*/
public function process_email( $to, $subject, $message, $headers = '', $attachments = array() ) {
$body = array();
$pubkey = get_option( 'mainwp_child_pubkey' );
$pubkey = $pubkey ? md5( $pubkey ) : '';
$request_headers = array(
'Site-Id' => get_option( 'mainwp_child_siteid' ),
'API-Key' => $pubkey
);
//let's manage attachments
if( !empty( $attachments ) && $attachments ) {
$_attachments = $attachments;
$attachments = array();
foreach( $_attachments as $attachment ) {
$attachments[$attachment] = file_get_contents( $attachment );
}
}
$body = compact( 'to', 'subject', 'message', 'headers', 'attachments' );
$action_nonce = apply_filters( 'mainwp_child_create_action_nonce', false, 'post-smtp-send-mail' );
$ping_nonce = apply_filters( 'mainwp_child_get_ping_nonce', '' );
$this->base_url = "$this->base_url/?actionnonce={$action_nonce}&pingnonce={$ping_nonce}";
$response = wp_remote_post(
$this->base_url,
array(
'method' => 'POST',
'body' => $body,
'headers' => $request_headers
)
);
if( wp_remote_retrieve_body( $response ) ) {
return true;
}
}
}
endif;

View File

@@ -0,0 +1,32 @@
<?php
if( !function_exists( 'wp_mail' ) ):
/**
* Send an email | Override wp_mail function
*
* @param string|array $to Array or comma-separated list of email addresses to send message.
* @param string $subject Email subject
* @param string $message Message contents
* @param string|array $headers Optional. Additional headers.
* @param string|array $attachments Optional. Files to attach.
* @return bool Whether the email contents were sent successfully.
* @see wp_mail()
* @since 2.6.0
* @version 2.6.0
*/
function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() ) {
$request = new Post_SMTP_MainWP_Child_Request();
$response = $request->process_email( $to, $subject, $message, $headers, $attachments );
if( is_wp_error( $response ) ) {
return false;
}
return true;
}
endif;

View File

@@ -0,0 +1,128 @@
<?php
if( !class_exists( 'Post_SMTP_MainWP_Child' ) ):
class Post_SMTP_MainWP_Child {
private static $instance;
/**
* Get instance
*
* @return object
* @since 2.6.0
* @version 2.6.0
*/
public static function get_instance() {
if( !isset( self::$instance ) && !( self::$instance instanceof Post_SMTP_MainWP_Child ) ) {
self::$instance = new Post_SMTP_MainWP_Child();
}
return self::$instance;
}
/**
* Constructor
*
* @since 2.6.0
* @version 2.6.0
*/
public function __construct() {
$this->validate();
}
/**
* Validate
*
* @since 2.6.0
* @version 2.6.0
*/
public function validate() {
if( !function_exists( 'is_plugin_active' ) ) {
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
}
if( is_plugin_active( 'mainwp-child/mainwp-child.php' ) ) {
$this->init();
}
}
/**
* Init
*
* @since 2.6.0
* @version 2.6.0
*/
public function init() {
require_once 'rest-api/v1/class-psmwp-rest-api.php';
$post_smtp_enabled = get_option( 'post_smtp_use_from_main_site' );
if( $post_smtp_enabled ) {
add_filter( 'post_smtp_dashboard_notice', array( $this, 'update_notice' ) );
add_filter( 'post_smtp_declare_wp_mail', '__return_false' );
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
require_once 'classes/class-psmwp-request.php';
require_once 'psmwp-functions.php';
}
}
/**
* Enqueue Admin Scripts.
*
* @since 2.6.0
* @version 1.0.0
*/
public function enqueue_scripts() {
$css = '
.ps-config-bar .dashicons-dismiss {
display: none;
}';
wp_add_inline_style(
'postman_style',
$css
);
}
/**
* Update Dashboard Notice | Filter Callback
*
* @since 2.6.0
* @version 1.0.0
*/
public function update_notice() {
return array(
'error' => false,
'message' => __( 'Post SMTP is being used by MainWP Dashboard Site.', 'post-smtp' )
);
}
}
endif;

View File

@@ -0,0 +1,129 @@
<?php
if( !class_exists( 'PSMWP_Rest_API' ) ):
class PSMWP_Rest_API {
/**
* PSMWP_Rest_API constructor.
*
* @since 2.6.0
* @version 1.0.0
*/
public function __construct() {
add_action( 'rest_api_init', array( $this, 'register_routes' ) );
}
/**
* Register routes
*
* @since 2.6.0
* @version 1.0.0
*/
public function register_routes() {
register_rest_route( 'psmwp/v1', '/activate-from-mainwp', array(
'methods' => WP_REST_Server::CREATABLE,
'callback' => array( $this, 'activate_from_mainwp' ),
'permission_callback' => '__return_true',
) );
}
/**
* Activate from MainWP
*
* @since 2.6.0
* @version 1.0.0
*/
public function activate_from_mainwp( WP_REST_Request $request ) {
$params = $request->get_params();
$headers = $request->get_headers();
$api_key = empty( $request->get_header( 'api_key' ) ) ? '' : sanitize_text_field( $request->get_header( 'api_key' ) );
$action = $request->get_param( 'action' );
//Lets Validate :D
if( $this->validate( $api_key ) ) {
if( $action == 'enable_post_smtp' ) {
update_option( 'post_smtp_use_from_main_site', '1' );
}
if( $action == 'disable_post_smtp' ) {
delete_option( 'post_smtp_use_from_main_site' );
}
wp_send_json_success(
array(),
200
);
}
}
/**
* Validate request
*
* @since 2.6.0
* @version 1.0.0
*/
private function validate( $api_key ) {
if(
empty( $api_key )
) {
wp_send_json(
array(
'code' => 'incomplete_request',
'message' => 'Empty API-Key or Site-URL.'
),
404
);
}
$pubkey = get_option( 'mainwp_child_pubkey' );
$pubkey = $pubkey ? md5( $pubkey ) : '';
if( $pubkey != $api_key ) {
wp_send_json(
array(
'code' => 'incorrect_api_key',
'message' => 'Incorrect API Key.'
),
404
);
}
//Let's allow request
if(
$pubkey == $api_key
) {
return true;
}
}
}
new PSMWP_Rest_API();
endif;

View File

@@ -0,0 +1,17 @@
<?php
require_once 'includes/psmwp-init.php';
/**
* Load Post SMTP for MainWP Child
*
* @since 2.6.0
* @version 2.6.0
*/
function load_post_smtp_for_mainwp_child() {
Post_SMTP_MainWP_Child::get_instance();
}
load_post_smtp_for_mainwp_child();