AlkantarClanX12

Your IP : 216.73.217.24


Current Path : /www/capitalgmcbuickregina_830/public/wp-content/plugins/wp-cerber/includes/
Upload File :
Current File : /www/capitalgmcbuickregina_830/public/wp-content/plugins/wp-cerber/includes/CRB_Messaging.php

<?php

use PHPMailer\PHPMailer\PHPMailer;

/**
 * Handles outbound messages, including security alerts, reports,
 * system notifications, and user-facing messages such as 2FA codes.
 *
 * Builds message content based on message type, applies channel policies and
 * rate limits, and delivers messages via supported transports (email, Pushbullet).
 * Also manages email delivery details such as SMTP configuration, fallback to
 * default wp_mail(), deferred sending, and error handling.
 *
 * This class acts as a single entry point for sending all outgoing messages.
 */
final class CRB_Messaging {

	const SEND_ISSUE_CODE = 'email_send_error';

	private static ?self $instance = null;
	private bool $smpt_enabled = false;
	private bool $no_smtp = false; // If true, it temporarily disables using the WP Cerber's SMTP settings
	private ?PHPMailer $mailer = null; // Last used mailer
	private array $email_args = array(); // Holds email parameters in case of postponed sending
	private bool $error = false; // If an error occurred while sending

	private static function instance() : self {
		if ( self::$instance === null ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Sends outbound messages via configured delivery channels.
	 *
	 * Sends administrative notifications, reports, and user-facing messages
	 * (including 2FA codes) via enabled delivery channels, applying rate limits
	 * and channel policies.
	 *
	 * Replacement for cerber_send_message().
	 *
	 * @param string $msg_type Message type identifier.
	 * @param array $msg_parts Message content parts and optional variants.
	 * @param array $channels Delivery channels to use.
	 * @param bool $ignore Whether to ignore global rate limits.
	 * @param array $args Additional context and message parameters.
	 *
	 * @return array|false List of recipients on success, false on failure.
	 *
	 * @since 9.6.16
	 */
	public static function send( $msg_type, $msg_parts = array(), $channels = array(), $ignore = false, $args = array() ) {
		return self::instance()->send_message( $msg_type, $msg_parts, $channels, $ignore, $args );
	}

	/**
	 * Sends outbound messages via configured delivery channels.
	 *
	 * Builds message content based on message type, applies channel selection and
	 * rate limits, and dispatches delivery via supported transports.
	 *
	 * @param string $msg_type Message type identifier.
	 * @param array $msg_parts Message content parts and optional variants.
	 * @param array $channels Delivery channels to use.
	 * @param bool $ignore Whether to ignore global rate limits.
	 * @param array $args Additional context and message parameters.
	 *
	 * @return array|false List of recipients on success, false on failure.
	 *
	 * @since 9.5.5.1
	 */
	private function send_message( $msg_type, $msg_parts = array(), $channels = array(), $ignore = false, $args = array() ) {

		$msg_type = $msg_type ?: 'generic';

		$sb = $msg_parts['subj'] ?? '';
		$msg = $msg_parts['text'] ?? '';
		$msg_masked = $msg_parts['text_masked'] ?? '';
		$more = $msg_parts['more'] ?? '';
		$ip = $msg_parts['ip'] ?? '';

		$channels = array_merge( CRB_CHANNELS, $channels );

		if ( ! array_filter( $channels ) ) {
			return false;
		}

		if ( ! $ignore
		     && ! is_admin()
		     && in_array( $msg_type, array( 'lockout', 'send_alert' ) ) ) {

			$channels = $this->check_limits( $channels );

			if ( ! array_filter( $channels ) ) {
				return false;
			}
		}

		$html_mode = false;
		$blogname = crb_get_blogname_decoded();

		if ( ! in_array( $msg_type, array( '2fa', 'new_version' ) ) ) {
			$subj = '[' . $blogname . '] WP Cerber: ' . $sb;
		}
		else {
			$subj = '[' . $blogname . '] ' . $sb;
		}

		$body = '';
		$body_masked = '';

		if ( is_array( $msg ) ) {
			$msg = implode( "\n\n", $msg ) . "\n\n";
		}

		if ( is_array( $msg_masked ) ) {
			$msg_masked = implode( "\n\n", $msg_masked ) . "\n\n";
		}

		$last = null;

		switch ( $msg_type ) {
			case 'citadel_mode':
				$max = cerber_db_get_var( 'SELECT MAX(stamp) FROM ' . CERBER_LOG_TABLE . ' WHERE  activity = ' . CRB_EV_LFL );
				if ( $max ) {
					$last_date = cerber_date( $max, false );
					$last = cerber_db_get_row( 'SELECT * FROM ' . CERBER_LOG_TABLE . ' WHERE stamp = ' . $max . ' AND activity = ' . CRB_EV_LFL, MYSQL_FETCH_OBJECT );
				}

				if ( ! $last ) { // workaround for the empty log table
					$last = new stdClass();
					$last->ip = CERBER_NO_REMOTE_IP;
					$last->user_login = 'test';
				}

				$subj .= __( 'Citadel mode is active', 'wp-cerber' );

				/* translators: %1$d is the number of failed login attempts, %2$d is the time period in minutes. */
				$body = sprintf( __( 'Citadel mode has been activated after %1$d failed login attempts in %2$d minutes.', 'wp-cerber' ), crb_get_settings( 'cilimit' ), crb_get_settings( 'ciperiod' ) ) . "\n\n";
				/* translators: %1$s is the date and time, %2$s is the IP address, %3$s is the username. */
				$body .= sprintf( __( 'Last failed attempt was at %1$s from IP %2$s using username: %3$s.', 'wp-cerber' ), $last_date, $last->ip, $last->user_login ) . "\n\n";

				/* translators: %s is the URL to view activity in the Dashboard. */
				$more = sprintf( __( 'View activity in the Dashboard: %s', 'wp-cerber' ), cerber_admin_link( 'activity', array(), false, false ) ) . "\n\n";
				break;
			case 'lockout':
				$max = cerber_db_get_var( 'SELECT MAX(stamp) FROM ' . CERBER_LOG_TABLE . ' WHERE  activity IN (' . CRB_EV_IPL . ',' . CRB_EV_NEL . ')' );

				if ( $max ) {
					$last_date = cerber_date( $max, false );
					$last = cerber_db_get_row( 'SELECT * FROM ' . CERBER_LOG_TABLE . ' WHERE stamp = ' . $max . ' AND activity IN (' . CRB_EV_IPL . ',' . CRB_EV_NEL . ')', MYSQL_FETCH_OBJECT );
				}
				else {
					$last_date = '';

					// workaround for the empty log table
					$last = new stdClass();
					$last->ip = CERBER_NO_REMOTE_IP;
					$last->user_login = 'test';
				}

				$active = crb_get_locked_out_num();

				if ( $last->ip && ( $block = crb_get_lockout( $last->ip ) ) ) {
					$reason = $block->reason;
				}
				else {
					$reason = __( 'unspecified', 'wp-cerber' );
				}

				/* translators: %d is the number of active lockouts. */
				$subj .= sprintf( __( 'Number of lockouts is increasing (%d)', 'wp-cerber' ), $active );

				/* translators: %d is the number of active lockouts. */
				$body = sprintf( __( 'Number of active lockouts at the moment: %d', 'wp-cerber' ), $active ) . "\n\n";

				if ( $last_date ) {
					/* translators: %1$s is the IP address with hostname, %2$s is the date and time of the lockout. */
					$body .= sprintf( __( 'Last security action: IP address %1$s was locked out at %2$s', 'wp-cerber' ), $last->ip . ' (' . @gethostbyaddr( $last->ip ) . ')', $last_date ) . "\n\n";
					/* translators: %s is the lockout reason. */
					$body .= sprintf( __( 'Reason: %s', 'wp-cerber' ), strip_tags( $reason ) ) . "\n\n";
				}

				/* translators: %s is the URL to view activity for the IP. */
				$more = sprintf( __( 'View activity for this IP: %s', 'wp-cerber' ), cerber_admin_link( 'activity', array(), false, false ) . '&filter_ip=' . $last->ip ) . "\n\n";
				/* translators: %s is the URL to view all lockouts. */
				$more .= sprintf( __( 'View all lockouts: %s', 'wp-cerber' ), cerber_admin_link( 'lockouts', array(), false, false ) ) . "\n\n";

				/* translators: %s is the URL to learn more about alerting. */
				$more .= sprintf( __( 'Learn more about advanced alerting in WP Cerber: %s', 'wp-cerber' ), 'https://wpcerber.com/wordpress-notifications-made-easy/' );
				break;
			case 'new_version':
				$body = $msg . "\n\n";
				/* translators: %s is the website name. */
				$more = sprintf( __( 'Website: %s', 'wp-cerber' ), $blogname );
				break;
			case 'shutdown':
				$d = __( 'The WP Cerber Security plugin has been deactivated', 'wp-cerber' );
				$subj = '[' . $blogname . '] ' . $d;
				$body .= "\n" . $d . "\n\n";
				if ( ! is_user_logged_in() ) {
					$u = __( 'Unknown', 'wp-cerber' );
				}
				else {
					$user = wp_get_current_user();
					$u = $user->display_name;
				}
				/* translators: %s is the website name. */
				$body .= sprintf( __( 'Website: %s', 'wp-cerber' ), $blogname ) . "\n";

				/* translators: %s is the user name. */
				$more = sprintf( __( 'By the user: %s', 'wp-cerber' ), $u ) . "\n";
				/* translators: %s is the IP address. */
				$more .= sprintf( __( 'From the IP address: %s', 'wp-cerber' ), cerber_get_remote_ip() ) . "\n";

				$ip_rdap = CRB_RDAP_Client::get_parsed_ip_info( $ip );

				if ( ! crb_is_wp_error( $ip_rdap ) && ! empty( $ip_rdap->country ) ) {
					/* translators: %s is the country name. */
					$more .= sprintf( __( 'From the country: %s', 'wp-cerber' ), crb_get_country_name( $ip_rdap->country ) );
				}

				break;
			case 'plugin_activated':
				$subj = '[' . $blogname . '] ' . __( 'The WP Cerber Security plugin is now active', 'wp-cerber' );
				$body = "\n" . __( 'WP Cerber is now active and has started protecting your site', 'wp-cerber' ) . "\n\n";
				$body .= __( 'Getting Started Guide', 'wp-cerber' ) . "\n\n";
				$body .= 'https://wpcerber.com/getting-started/' . "\n\n";
				$body .= 'Is your website under Cloudflare? You have to enable a crucial WP Cerber setting.' . "\n\n";
				$body .= 'https://wpcerber.com/cloudflare-and-wordpress-cerber/' . "\n\n";
				$body .= 'Be in touch with the developer.' . "\n\n";
				$body .= 'Follow Cerber on X: https://twitter.com/wpcerber' . "\n\n";
				$body .= "Subscribe to Cerber's newsletter: https://wpcerber.com/subscribe-newsletter/" . "\n\n";
				break;
			case 'newlurl':
				$subj .= __( 'New Custom login URL', 'wp-cerber' );
				$body .= $msg;
				break;
			case 'send_alert':
				$body = __( 'A new activity has occurred', 'wp-cerber' ) . "\n\n";
				$body_masked = $body;
				$body .= $msg;
				$body_masked .= $msg_masked;
				break;
			case 'report':
				list ( $title, $body ) = cerber_generate_email_report( $args );
				$subj .= $title;
				$link = cerber_admin_link( 'notifications', array(), false, false );
				$body .= '<br/>' . __( 'To change reporting settings visit', 'wp-cerber' ) . ' <a href="' . $link . '">' . $link . '</a>';
				$body .= $msg;
				$html_mode = true;
				break;
			case 'scan':
				$subj .= __( 'Scanner Report', 'wp-cerber' );
				$body = $msg;

				$link = cerber_admin_link( 'scan_main', array(), false, false );
				$body .= '<p>' . __( 'To view full report, navigate to:', 'wp-cerber' ) . ' <a href="' . $link . '">' . $link . '</a></p>';

				$link = cerber_admin_link( 'scan_schedule', array(), false, false );
				$body .= '<br/>' . __( 'To modify your reporting settings, navigate to:', 'wp-cerber' ) . ' <a href="' . $link . '">' . $link . '</a>';

				$html_mode = true;
				break;
			case 'generic':
			case '2fa':
			default:
				$body = $msg;
				break;
		}

		$to_list = array();
		$to = '';

		if ( $channels['email'] ) {
			$to_list = crb_build_email_recipients( $msg_type, $args );
			$to = implode( ', ', $to_list );
		}

		$body_filtered = apply_filters( 'cerber_notify_body', $body, array(
			'type'    => $msg_type,
			'IP'      => $ip,
			'to'      => $to,
			'subject' => $subj
		) );

		if ( $body_filtered && is_string( $body_filtered ) ) {
			$body = $body_filtered;
		}

		if ( ! $body ) {
			//return new WP_Error( 'notifications', 'No text of the message provided.' );
			return false;
		}

		$footer = '';
		$mf = crb_get_settings( 'email_format' );

		if ( ( 1 > $mf )
		     && ! in_array( $msg_type, array( 'shutdown', 'generic', '2fa' ) )
		     && $lolink = cerber_get_custom_login_url() ) {

			$lourl = urldecode( $lolink );

			if ( $html_mode ) {
				$lourl = '<a href="' . $lolink . '">' . $lourl . '</a>';
			}

			/* translators: %s is the custom login page URL. */
			$footer .= "\n\n" . sprintf( __( 'Your login page: %s', 'wp-cerber' ), $lourl );

		}

		if ( ( 1 > $mf )
		     && $msg_type == 'report'
		     && $date = lab_lab( 1 ) ) {
			/* translators: %s is the license expiration date. */
			$footer .= "\n\n" . sprintf( __( 'Your license is valid until %s', 'wp-cerber' ), $date );
		}

		if ( $msg_type != '2fa' ) {
			/* translators: %s is the plugin name and version. */
			$footer .= "\n\n\n" . sprintf( __( 'This message was created by %s', 'wp-cerber' ), 'WP Cerber Security ' . ( lab_lab() ? 'Professional ' : '' ) . ( 1 > $mf ? CERBER_VER : '' ) );
			/* translators: %s is the date. */
			$footer .= "\n" . sprintf( __( 'Date: %s', 'wp-cerber' ), cerber_date( time(), false ) );
			$footer .= "\n" . 'https://wpcerber.com';
		}

		// Everything is prepared, let's send it out

		$results = array();
		$recipients = array();
		$success = false;

		$go = 'pushbullet';
		if ( $channels[ $go ] && ! $html_mode ) {
			$body_go = ( $msg_type == 'send_alert' && crb_get_settings( 'pb_mask' ) ) ? $body_masked : $body;
			$res = cerber_pb_send( $subj, $body_go, $more, $footer );
			if ( $res && ! crb_is_wp_error( $res ) ) {
				$results[ $go ] = true;
				$recipients[ $go ] = cerber_pb_get_active();
				$success = true;
			}
		}

		$go = 'email';
		if ( $channels[ $go ] ) {
			$body_go = ( $msg_type == 'send_alert' && crb_get_settings( 'email_mask' ) ) ? $body_masked : $body;
			if ( $results[ $go ] = $this->send_email( $msg_type, $html_mode, $to_list, $subj, $body_go, $more, $footer, $ip ) ) {
				$recipients[ $go ] = $to;
				$success = true;
			}
		}

		if ( ! $success ) {

			return false;
		}

		$sent = cerber_get_set( '_cerber_last_send' );

		if ( ! is_array( $sent ) ) {
			$sent = array();
		}

		foreach ( $results as $channel_id => $result ) {
			$sent[ $channel_id ] = ( $result ) ? time() : 0;
		}

		cerber_update_set( '_cerber_last_send', $sent );

		return $recipients;
	}

	/**
	 * Sends emails. Acts as a go_send_email() wrapper.
	 *
	 * @see self::go_send_email()
	 *
	 * @param string $type
	 * @param bool $html_mode
	 * @param array $to_list
	 * @param string $subj
	 * @param string $body
	 * @param string $more
	 * @param string $footer
	 * @param string $ip
	 *
	 * @return bool
	 *
	 * @since 9.5.5.1
	 */
	private function send_email( $type, $html_mode, $to_list, $subj, $body, $more, $footer, $ip ) {

		if ( function_exists( 'wp_mail' ) ) {
			return $this->go_send_email( $type, $html_mode, $to_list, $subj, $body, $more, $footer, $ip );
		}

		// Here wp_mail() is not yet defined
		// We postpone sending to the moment when we expect it is defined

		$this->email_args[] = func_get_args();

		add_action( 'plugins_loaded', array( $this, 'launch_send_email' ) );

		// If 'plugins_loaded' is not invoked - e.g. HTTP redirection occurred before
		register_shutdown_function( [ $this, 'launch_send_email' ] );

		// We have to return the result of sending, but at this pont, we have no idea how the postponed sending will end
		// We hope it will be OK.
		return true;
	}

	/**
	 * Sends emails if sending was postponed due to wp_mail() is not defined
	 *
	 * @return void
	 *
	 * @since 9.5.5.1
	 */
	public function launch_send_email() {

		if ( ! $this->email_args ) {
			return;
		}

		foreach ( $this->email_args as $item ) {
			$this->go_send_email( ...$item );
		}

		$this->email_args = array();
	}

	/**
	 * Sends email
	 *
	 * @param string $type
	 * @param bool $html_mode
	 * @param array $to_list
	 * @param string $subj
	 * @param string $body
	 * @param string $more
	 * @param string $footer
	 * @param string $ip
	 *
	 * @return bool
	 *
	 * @since 8.9.6.1
	 */
	private function go_send_email( $type, $html_mode, $to_list, $subj, $body, $more, $footer, $ip ) {

		$this->error = false;
		add_action( 'wp_mail_failed', array( $this, 'process_email_errors' ) );

		if ( $html_mode ) {
			add_filter( 'wp_mail_content_type', 'cerber_enable_html' );
			$footer = str_replace( "\n", '<br/>', $footer );
		}

		if ( crb_get_settings( 'email_format' ) < 2 ) {
			$body .= $more;
		}

		$this->enable_smtp();

		$result = false;
		$to = implode( ', ', $to_list );

		if ( $to_list && $subj && $body ) {

			$lang = crb_get_bloginfo( 'language' );

			if ( $type == 'report') {

				$result = true;

				foreach ( $to_list as $email ) {

					$lastus = '';

					if ( ( $user = get_user_by( 'email', $email ) )
					     && $last = crb_get_last_user_login( $user->ID ) ) {

						$last_ip = crb_get_settings( 'email_mask' ) ? crb_mask_ip( $last['ip'] ) : $last['ip'];

						/* translators: Here the first placeholder %s is a date of the last user login and the second placeholder %s is the user's IP address. */
						$lastus = sprintf( __( 'Your last sign-in was at %1$s from the IP address %2$s', 'wp-cerber' ), cerber_date( $last['ts'], false ), $last_ip );

						if ( $country = crb_get_country_name( $last['cn'] ) ) {
							$lastus .= ' (' . $country . ')';
						}

						if ( $html_mode ) {
							$lastus = '<br/><br/>' . $lastus;
						}
						else {
							$lastus = "\n\n" . $lastus;
						}
					}

					$body = '<html lang="' . $lang . '">' . $body . $lastus . $footer . '</html>';

					if ( ! $this->transmit_email( $email, $subj, $body ) ) {
						$result = false;
					}
				}
			}
			else {

				$result = true;
				$body = $body . $footer;

				if ( $html_mode ) {
					$body = '<html lang="' . $lang . '">' . $body . '</html>';
				}

				foreach ( $to_list as $email ) {
					if ( ! $this->transmit_email( $email, $subj, $body ) ) {
						$result = false;
					}
				}
			}
		}

		$this->disable_smtp();

		remove_filter('wp_mail_content_type', 'cerber_enable_html');

		remove_action( 'wp_mail_failed', array( $this, 'process_email_errors' ) );

		$params = array( 'type' => $type, 'IP' => $ip, 'to' => $to, 'subject' => $subj );

		if ( $result ) {
			do_action( 'cerber_notify_sent', $body, $params );

			if ( ! $this->error ) { // Delete error occurred during a previous sending only
				CRB_Issues::delete_item( self::SEND_ISSUE_CODE);
			}
		}
		else {
			do_action( 'cerber_notify_fail', $body, $params );
		}

		return $result;
	}

	/**
	 * Send out one email message.
	 * If SMTP sending has failed, use generic wp_mail() without SMTP.
	 *
	 * @param string|string[] $email
	 * @param string $subj
	 * @param string $body
	 *
	 * @return bool
	 *
	 * @since 9.5.5.1
	 */
	private function transmit_email( $email, $subj, $body ) {

		crb_load_dependencies( 'wp_mail' );  // It's crucial in some configurations

		if ( ( ! $result = wp_mail( $email, $subj, $body ) )
		     && $this->smpt_enabled ) {

			$this->no_smtp = true;

			if ( ! $result = wp_mail( $email, $subj, $body ) ) {
				$this->no_smtp = false;
			}
		}

		return $result;
	}

	/**
	 * @param PHPMailer $pm
	 *
	 * @return void
	 *
	 * @since 8.9.6.3
	 */
	public function set_smtp_credentials( $pm ) {
		if ( ! lab_lab()
		     || $this->no_smtp ) {
			return;
		}

		$config = crb_get_settings();

		$pm->isSMTP();
		$pm->SMTPAuth = true;
		$pm->Timeout = 5;
		$pm->Host = $config['smtp_host'];
		$pm->Port = $config['smtp_port'];
		$pm->Username = $config['smtp_user'];
		$pm->Password = $config['smtp_pwd'];

		// For better deliverability we use "smtp_user"
		$pm->From = ( $config['smtp_from'] ) ?: $config['smtp_user'];

		if ( $config['smtp_from_name'] ) {
			$pm->FromName = $config['smtp_from_name'];
		}

		if ( $config['smtp_encr'] ) {
			$pm->SMTPSecure = $config['smtp_encr'];
		}

		$this->save_mailer( array( &$pm ) );

	}

	/**
	 * Set up hooks to configure PHPMailer if SMTP configured
	 *
	 * @return void
	 *
	 * @since 9.5.5.1
	 */
	private function enable_smtp() {
		if ( ! $this->smpt_enabled = (bool) crb_get_settings( 'use_smtp' ) ) {
			return;
		}

		add_action( 'phpmailer_init', array( $this, 'set_smtp_credentials' ) );
	}

	/**
	 * Remove our hooks
	 *
	 * @return void
	 *
	 * @since 9.5.5.1
	 */
	private function disable_smtp() {
		if ( ! $this->smpt_enabled ) {
			return;
		}

		remove_action( 'phpmailer_init', array( $this, 'set_smtp_credentials' ) );

		// Warn the website admin if the wp_mail() function is redefined somewhere or/and our SMTP settings were not used

		if ( is_admin() && crb_get_query_params( 'cerber_admin_do' ) ) {
			$mailer = $this->mailer;

			if ( ! ( $mailer instanceof PHPMailer )
			     || $mailer->Host != crb_get_settings( 'smtp_host' )
			     || $mailer->Port != crb_get_settings( 'smtp_port' )
			     || $mailer->Username != crb_get_settings( 'smtp_user' ) ) {
				cerber_admin_notice( "Warning: The WP Cerber SMTP settings were not used while sending email. They can be altered by another plugin." );
				$alien = true;
			}
			else {
				$alien = false;
			}

			if ( $alien && $mailer->Host ) {
				cerber_admin_notice( 'Warning: The email was sent using the host ' . $mailer->Host . ' and the user ' . $mailer->Username );
			}
		}
	}

	/**
	 * Saves and provides access to last used PHPMailer configuration
	 *
	 * @param PHPMailer $pm
	 *
	 * @return PHPMailer|null
	 *
	 * @since 8.9.6.4
	 */
	private function save_mailer( $pm = null ) {

		if ( isset( $pm[0] ) ) {
			$this->mailer = $pm[0];
		}

		return $this->mailer;
	}

	/**
	 * A wp_mail() error handler
	 *
	 * @param WP_Error $error
	 *
	 * @return void
	 *
	 * @since 9.5.5.1
	 */
	public function process_email_errors( $error ) {

		$this->error = true;

		if ( ! $error instanceof WP_Error ) {
			return;
		}

		$mailer_data = $error->get_error_data();
		if ( ! is_array( $mailer_data ) ) {
			$mailer_data = array();
		}

		$exception_code = $mailer_data['phpmailer_exception_code'] ?? '';

		if ( is_admin() && crb_get_query_params( 'cerber_admin_do' ) ) {
			cerber_admin_notice( strip_tags( $error->get_error_message() ) . ' (' . $exception_code . ')' );

			return;
		}

		$to = $mailer_data['to'] ?? array();
		if ( ! is_array( $to ) ) {
			$to = array( $to );
		}

		$smtp_host = '';
		$smtp_user = '';
		if ( $this->mailer instanceof PHPMailer ) {
			$smtp_host = (string) $this->mailer->Host;
			$smtp_user = (string) $this->mailer->Username;
		}

		$context_data = array(
			'format_version' => 1,
			'ts'             => time(),
			'remote_ip'      => cerber_get_remote_ip(),
			'error_message'  => strip_tags( $error->get_error_message() ),
			'exception_code' => $exception_code,
			'smtp_host'      => $smtp_host,
			'smtp_user'      => $smtp_user,
			'to'             => $to,
			'subject'        => (string) ( $mailer_data['subject'] ?? '' ),
		);

		CRB_Issues::add( self::SEND_ISSUE_CODE,	__( 'An error occurred while sending email. Security alerts and reports may not reach you. Check email notification settings and recipient addresses.', 'wp-cerber' ),
			array(
				'type'    => CRB_Issues::TYPE_EVENT,
				'context' => array(
					'mailer_data' => $context_data,
				),
			)
		);

	}


	/**
	 * Check sending limits and disable channels if it's needed
	 *
	 * @param array $channels
	 *
	 * @return array
	 *
	 * @since 8.9.6.1
	 *
	 */
	private function check_limits( $channels ) {
		static $ref = array( 'email' => 'emailrate', 'pushbullet' => 'pbrate' );

		if ( ! lab_lab() ) {
			$ref ['pushbullet'] = 'emailrate';
		}

		$limits = array_filter( array_intersect_key( crb_get_settings(), array_flip( $ref ) ) );

		if ( ! $limits ) {
			return $channels;
		}

		$sent = cerber_get_set( '_cerber_last_send' );

		if ( empty( $sent ) ) {
			return $channels;
		}

		foreach ( $ref as $channel_id => $key ) {
			$rate = absint( $limits[ $key ] ?? 0 );
			if ( $rate && ( $sent[ $channel_id ] ?? 0 ) > ( time() - 3600 / $rate ) ) {
				$channels[ $channel_id ] = 0; // Do not send
			}
		}

		return $channels;
	}
}

Home - Capital GMC Buick Regina

No data

Welcome to Capital GMC BUICK – REGINA

Thank you for choosing Capital GMC Buick | Regina, your premier certified Buick and GMC dealership proudly serving drivers in Regina and the surrounding communities. Whether you’re searching for a brand-new Buick or GMC vehicle or a meticulously inspected pre-owned model, we have a diverse selection to match your needs and lifestyle.

Beyond our impressive inventory, we offer a seamless and stress-free financing experience through our well-connected finance centre, where our team of experts is dedicated to securing the best loan or lease options for you, quickly, transparently, and hassle-free.

But our commitment to you doesn’t stop at the sale. Our state-of-the-art service centre is staffed with skilled Buick and GMC technicians who use the latest equipment and genuine OEM parts to keep your vehicle running at its best. From routine maintenance to complex repairs, we’ve got you covered.

Experience top-tier customer service, quality vehicles, and expert care, all in one place. Visit Capital GMC Buick | Regina today or call us at 306-205-8072 with any questions. We’re here to help!

Ask a Question