*/ private static $defaults = array( 'enabled' => false, 'batch_size' => 10, 'max_per_connection' => 50, ); /** * Plugin display name. * * @var string */ public $name; /** * Plugin slug. * * @var string */ public $slug; /** * Menu title. * * @var string */ public $menu_title; /** * Get singleton instance. * * @return Plugin */ public static function get_instance() { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } /** * Initialize plugin (called on newsletter_loaded hook). * * @return void */ public static function instance_init() { $instance = self::get_instance(); $instance->init(); } /** * Constructor. */ private function __construct() { parent::__construct( 'robotstxt-smtp-newsletter', ROBOTSTXT_SMTP_NEWSLETTER_VERSION, ROBOTSTXT_SMTP_NEWSLETTER_PATH ); $this->name = 'SMTP (by ROBOTSTXT)'; $this->slug = 'robotstxt-smtp-newsletter'; $this->menu_title = 'SMTP (by ROBOTSTXT)'; } /** * Setup options. * * Overrides parent to use our custom option name. * * @return void */ public function setup_options() { if ( $this->options ) { return; } // Load our options using our custom option name (not newsletter_ prefix). $this->options = get_option( 'robotstxt_smtp_newsletter_options', array() ); $this->options = wp_parse_args( $this->options, self::$defaults ); } /** * Initialize plugin hooks. * * Overrides parent init() method. * * @return void */ public function init() { parent::init(); // Load text domain. add_action( 'init', array( $this, 'load_textdomain' ) ); // Register settings (but not menu - parent handles that). if ( is_admin() ) { require_once ROBOTSTXT_SMTP_NEWSLETTER_PATH . 'admin/class-settings-page.php'; add_action( 'admin_init', array( 'Robotstxt_SMTP_Newsletter\Admin\Settings_Page', 'register_settings_static' ) ); } } /** * Load plugin text domain for translations. * * @return void */ public function load_textdomain() { load_plugin_textdomain( 'robotstxt-smtp-newsletter', false, dirname( plugin_basename( ROBOTSTXT_SMTP_NEWSLETTER_FILE ) ) . '/languages' ); } /** * Get the mailer instance. * * This method is called by the parent class to get the mailer * that should be registered with Newsletter. * * @return \NewsletterMailer */ public function get_mailer() { // Get our settings and map to Newsletter's expected format. $settings = $this->get_settings(); $smtp_settings = $this->get_smtp_settings(); // Calculate optimal speed (emails per hour) based on rate limits. $speed = $this->calculate_optimal_speed( $smtp_settings ); // Newsletter expects 'turbo' for batch_size and 'speed' for emails/hour. $mailer_options = array( 'turbo' => $settings['batch_size'] ?? 10, 'speed' => $speed, 'max_per_connection' => $settings['max_per_connection'] ?? 50, ); // Detect if Amazon SES is active. if ( $this->is_amazon_ses_active() ) { require_once ROBOTSTXT_SMTP_NEWSLETTER_PATH . 'includes/class-amazonses-mailer.php'; return new AmazonSES_Mailer( $mailer_options ); } else { require_once ROBOTSTXT_SMTP_NEWSLETTER_PATH . 'includes/class-smtp-mailer.php'; return new SMTP_Mailer( $mailer_options ); } } /** * Calculate optimal speed (emails per hour) based on rate limits. * * @param array $smtp_settings SMTP settings with rate limits. * * @return int Emails per hour. */ private function calculate_optimal_speed( $smtp_settings ) { // Get rate limits from ROBOTSTXT SMTP settings. $rate_per_hour = absint( $smtp_settings['rate_limit_per_hour'] ?? 0 ); // If hourly limit is set, use it (with 90% safety margin). if ( $rate_per_hour > 0 ) { return (int) floor( $rate_per_hour * 0.9 ); } // If no hourly limit, calculate from per-second limit. $rate_per_second = absint( $smtp_settings['rate_limit_per_second'] ?? 0 ); if ( $rate_per_second > 0 ) { return (int) floor( $rate_per_second * 3600 * 0.9 ); } // If no limits set, use a conservative default based on delivery method. $is_ses = $this->is_amazon_ses_active(); return $is_ses ? 1000 : 500; } /** * Check if Amazon SES integration is active. * * @return bool */ private function is_amazon_ses_active() { if ( ! class_exists( '\Robotstxt_SMTP\Plugin' ) ) { return false; } return \Robotstxt_SMTP\Plugin::is_amazon_ses_integration_active(); } /** * Get plugin settings with defaults. * * @return array */ public function get_settings() { $options = get_option( 'robotstxt_smtp_newsletter_options', array() ); return wp_parse_args( $options, self::$defaults ); } /** * Get SMTP settings from robotstxt-smtp plugin. * * @return array */ public function get_smtp_settings() { if ( ! class_exists( '\Robotstxt_SMTP\Plugin' ) || ! class_exists( '\Robotstxt_SMTP\Admin\Settings_Page' ) ) { return array(); } // Check if network mode is enabled. $scope = get_site_option( 'robotstxt_smtp_configuration_scope', 'site' ); if ( 'network' === $scope ) { $settings = get_site_option( 'robotstxt_smtp_network_options', array() ); } else { $settings = get_option( 'robotstxt_smtp_options', array() ); } return $settings; } }