Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add panel for wp_mail() uses #773

Open
wants to merge 35 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
d54502c
save
crstauf Jun 16, 2023
4872ed3
save
crstauf Jun 16, 2023
4b8c36c
save
crstauf Jun 19, 2023
bc61920
save
crstauf Jun 19, 2023
9073c0b
Merge branch 'develop' into add-wp-mail
crstauf Jun 20, 2023
f8ed707
add return value
crstauf Jun 20, 2023
89ccc33
fix test errors
crstauf Jun 20, 2023
eb4815f
Merge branch 'develop' into add-wp-mail
crstauf Jun 21, 2023
110022a
fix code smells
crstauf Jun 21, 2023
f2d8da5
Merge branch 'develop' into add-wp-mail
crstauf Jun 28, 2023
98cd069
Merge branch 'develop' into add-wp-mail
crstauf Jul 4, 2023
cee7034
Merge branch 'develop' into add-wp-mail
crstauf Jul 5, 2023
16b8c7e
Merge branch 'develop' into add-wp-mail
crstauf Jul 10, 2023
caa883c
Merge branch 'develop' into add-wp-mail
crstauf Jul 27, 2023
496d00e
Merge branch 'develop' into add-wp-mail
crstauf Aug 2, 2023
0b1254f
Merge branch 'develop' into add-wp-mail
crstauf Aug 3, 2023
97fff38
Merge branch 'develop' into add-wp-mail
crstauf Aug 9, 2023
9137180
Merge branch 'develop' into add-wp-mail
crstauf Sep 11, 2023
e5ef1db
Merge branch 'develop' into add-wp-mail
crstauf Oct 17, 2023
fdae1f4
Merge branch 'develop' into add-wp-mail
crstauf Oct 20, 2023
fca6881
Merge branch 'develop' into add-wp-mail
crstauf Oct 30, 2023
67deab1
Merge branch 'develop' into add-wp-mail
crstauf Nov 6, 2023
b9e5957
Merge branch 'develop' into add-wp-mail
crstauf Nov 11, 2023
4c5d7c8
Merge branch 'develop' into add-wp-mail
crstauf Nov 13, 2023
2b589fa
Merge branch 'develop' into add-wp-mail
crstauf Dec 20, 2023
9894973
Merge branch 'develop' into add-wp-mail
crstauf Feb 15, 2024
cccf0d2
Merge branch 'develop' into add-wp-mail
crstauf May 25, 2024
0f6ec65
Merge branch 'develop' into add-wp-mail
crstauf Jul 27, 2024
15d573a
Merge branch 'develop' into add-wp-mail
crstauf Jul 27, 2024
c076883
Merge branch 'develop' into add-wp-mail
crstauf Aug 19, 2024
9ff7899
Merge branch 'develop' into add-wp-mail
crstauf Sep 25, 2024
5bc2562
Merge branch 'develop' into add-wp-mail
crstauf Nov 18, 2024
f985b3c
Merge branch 'develop' into add-wp-mail
crstauf Nov 27, 2024
38fd5e4
Merge branch 'develop' into add-wp-mail
crstauf Nov 29, 2024
4332cc5
Merge branch 'develop' into add-wp-mail
crstauf Jan 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
202 changes: 202 additions & 0 deletions collectors/emails.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
<?php declare(strict_types = 1);
/**
* Emails collector.
*
* @package query-monitor
*/

if ( ! defined( 'ABSPATH' ) ) {
exit;
}

/**
* @extends QM_DataCollector<QM_Data_Emails>
*/
class QM_Collector_Emails extends QM_DataCollector {

public $id = 'emails';

public function get_storage(): QM_Data {
return new QM_Data_Emails();
}

/**
* @return void
*/
public function set_up() {
parent::set_up();
add_filter( 'wp_mail', array( $this, 'filter_wp_mail' ), 9999 );
add_filter( 'pre_wp_mail', array( $this, 'filter_pre_wp_mail' ), 9999, 2 );
add_action( 'wp_mail_failed', array( $this, 'action_wp_mail_failed' ) );
}

/**
* @return void
*/
public function tear_down() {
remove_filter( 'wp_mail', array( $this, 'filter_wp_mail' ), 9999 );
remove_filter( 'pre_wp_mail', array( $this, 'filter_pre_wp_mail' ), 9999 );
remove_action( 'wp_mail_failed', array( $this, 'action_wp_mail_failed' ) );

parent::tear_down();
}

/**
* @return array<int, string>
*/
public function get_concerned_actions() {
return array(
'phpmailer_init',
'wp_mail_succeeded',
'wp_mail_failed',
);
}

/**
* @return array<int, string>
*/
public function get_concerned_filters() {
return array(
'pre_wp_mail',
'wp_mail',
'wp_mail_from',
'wp_mail_from_name',
'wp_mail_content_type',
'wp_mail_charset',
);
}

/**
* Other attributes of wp_mail() are changed,
* so use the attributes that aren't changed
* to generate identifying hash.
*
* @param array<string, string|array<int, string>> $atts
* @return string
*/
protected function hash( $atts ) {
$to = $atts['to'];

if ( ! is_array( $to ) ) {
$to = explode( ',', $to );
$to = array_map( 'trim', $to );
}

$data = array(
'to' => $to,
'subject' => $atts['subject'],
'message' => $atts['message'],
);

$datastring = json_encode( $data );

if ( ! is_string( $datastring ) ) {
$datastring = print_r( $data, true );
}

return wp_hash( $datastring );
}

/**
* @param array<string, string|array<int, string>> $atts
* @return array<string, string|array<int, string>>
*/
public function filter_wp_mail( $atts ) {
$atts = wp_parse_args( $atts, array(
'to' => array(),
'subject' => '',
'message' => '',
'headers' => array(),
'attachments' => array(),
) );

if ( ! is_array( $atts['to'] ) ) {
$atts['to'] = explode( ',', $atts['to'] );
}

if ( ! is_array( $atts['attachments'] ) ) {
$atts['attachments'] = explode( "\n", str_replace( "\r\n", "\n", $atts['attachments'] ) );
}

$hash = $this->hash( $atts );
$trace = new QM_Backtrace( array(
'ignore_hook' => array(
current_filter() => true,
),
) );

$this->data->emails[ $hash ] = array(
'atts' => $atts,
'error' => null,
'filtered_trace' => $trace->get_filtered_trace(),
);

return $atts;
}

/**
* @param null|bool $preempt
* @param array<string, string|array<int, string>> $atts
* @return null|bool
*/
public function filter_pre_wp_mail( $preempt, $atts ) {
if ( is_null( $preempt ) ) {
return null;
}

$hash = $this->hash( $atts );

$this->data->preempted[] = $hash;
$this->data->emails[ $hash ]['error'] = new WP_Error( 'pre_wp_mail', 'Preempted sending email.' );

return $preempt;
}

/**
* @param WP_Error $error
* @return void
*/
public function action_wp_mail_failed( $error ) {
$atts = $error->get_error_data( 'wp_mail_failed' );
$hash = $this->hash( $atts );

$this->data->failed[] = $hash;
$this->data->emails[ $hash ]['error'] = $error;
}

/**
* @return void
*/
public function process() {
$this->data->counts = array(
'preempted' => 0,
'failed' => 0,
'succeeded' => 0,
'total' => 0,
);

if ( ! is_array( $this->data->preempted ) ) {
$this->data->preempted = array();
}

if ( ! is_array( $this->data->failed ) ) {
$this->data->failed = array();
}

foreach ( $this->data->emails as $hash => $email ) {
$this->data->counts['total']++;

if ( in_array( $hash, $this->data->preempted ) ) {
$this->data->counts['preempted']++;
} else if ( in_array( $hash, $this->data->failed ) ) {
$this->data->counts['failed']++;
} else {
$this->data->counts['succeeded']++;
}
}
}

}

# Load early to catch early emails
QM_Collectors::add( new QM_Collector_Emails() );
28 changes: 28 additions & 0 deletions data/emails.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php declare(strict_types = 1);
/**
* Emails data transfer object.
*
* @package query-monitor
*/

class QM_Data_Emails extends QM_Data {
/**
* @var array<string, array<string, mixed>>
*/
public $emails;

/**
* @var array<int, string>
*/
public $preempted;

/**
* @var array<int, string>
*/
public $failed;

/**
* @var array<string, int>
*/
public $counts;
}
Loading