array(), 'themes' => array(), ); /** * Default class constructor * * @param string $table_name - The name of the table to use for the listing. * * @since 3.0.0 */ public function __construct( string $table_name = '' ) { $class = Common_Table::class; Common_Table::init( WP_Mail_Entity::get_table_name() ); self::$table = $class; parent::__construct( array( 'plural' => WP_Mail_Entity::get_table_name(), // Plural value used for labels and the objects being listed. 'singular' => WP_Mail_Entity::get_table_name(), // Singular label for an object being listed, e.g. 'post'. 'ajax' => false, // If true, the parent class will call the _js_vars() method in the footer. ) ); } /** * Inits class hooks. That is called every time - not in some specific environment set. * * @return void * * @since 3.0.0 */ public static function init() { \add_action( 'admin_post_' . self::NEW_ACTION, array( WP_Mail_View::class, 'new_mail' ) ); \add_action( 'admin_post_' . self::SITE_ID_FILTER_ACTION, array( WP_Mail_View::class, 'site_id_filter_action' ) ); \add_action( 'admin_post_' . self::PLUGIN_FILTER_ACTION, array( WP_Mail_View::class, 'plugin_filter_action' ) ); \add_action( 'admin_post_resend_email', array( __CLASS__, 'handle_resend_email' ) ); \add_action( 'admin_notices', array( __CLASS__, 'display_resend_notice' ) ); \add_filter( 'advan_cron_hooks', array( __CLASS__, 'add_cron_job' ) ); } /** * Adds a cron job for truncating the records in the requests table * * @param array $crons - The array with all the crons associated with the plugin. * * @return array * * @since 3.0.0 */ public static function add_cron_job( $crons ) { if ( -1 !== (int) Settings::get_option( 'advana_mail_logging_clear' ) ) { $crons[ ADVAN_PREFIX . 'mail_logging_clear' ] = array( 'time' => Settings::get_option( 'advana_mail_logging_clear' ), 'hook' => array( __CLASS__, 'truncate_wp_mail_table' ), 'args' => array(), ); } return $crons; } /** * Truncates the requests table from CRON job * * @return void * * @since 3.0.0 */ public static function truncate_wp_mail_table() { Common_Table::truncate_table( null, WP_Mail_Entity::get_table_name() ); } /** * Handles the email resend action * * @return void * * @since 4.8.0 */ public static function handle_resend_email() { // Check user capabilities. if ( ! \current_user_can( 'manage_options' ) ) { \wp_die( \esc_html__( 'You do not have permission to resend emails.', '0-day-analytics' ) ); } // Get mail ID. $mail_id = isset( $_GET['mail_id'] ) ? \absint( $_GET['mail_id'] ) : 0; // Verify nonce. if ( ! isset( $_GET['_wpnonce'] ) || ! \wp_verify_nonce( \sanitize_text_field( \wp_unslash( $_GET['_wpnonce'] ) ), 'resend_email_' . $mail_id ) ) { \wp_die( \esc_html__( 'Security check failed.', '0-day-analytics' ) ); } if ( ! $mail_id ) { \wp_die( \esc_html__( 'Invalid email ID.', '0-day-analytics' ) ); } // Load email data. $email = WP_Mail_Entity::load( 'id=%d', array( $mail_id ) ); if ( ! $email ) { \wp_die( \esc_html__( 'Email not found.', '0-day-analytics' ) ); } // Check if email can be resent. if ( isset( $email['can_resend'] ) && 0 === (int) $email['can_resend'] ) { \wp_die( \esc_html__( 'This email cannot be resent (it may contain time-sensitive information like password resets or verification codes).', '0-day-analytics' ) ); } // Prepare email parameters. $to = $email['email_to']; $subject = $email['subject']; $message = $email['message']; // Reconstruct headers. $headers = array(); // Add From header if we have plugin context. if ( ! empty( $email['plugin_slug'] ) ) { $headers[] = 'From: ' . \get_bloginfo( 'name' ) . ' <' . \get_option( 'admin_email' ) . '>'; } // Add CC if present. if ( ! empty( $email['email_cc'] ) ) { $headers[] = 'CC: ' . $email['email_cc']; } // Add BCC if present. if ( ! empty( $email['email_bcc'] ) ) { $headers[] = 'BCC: ' . $email['email_bcc']; } // Add Reply-To if present. if ( ! empty( $email['email_reply_to'] ) ) { $headers[] = 'Reply-To: ' . $email['email_reply_to']; } // Add Content-Type if HTML. if ( ! empty( $email['is_html'] ) && 1 === (int) $email['is_html'] ) { $headers[] = 'Content-Type: text/html; charset=UTF-8'; } // Parse attachments from JSON. $attachments = array(); if ( ! empty( $email['attachments'] ) ) { $attachments_data = \json_decode( $email['attachments'], true ); if ( \is_array( $attachments_data ) ) { foreach ( $attachments_data as $attachment ) { // Handle different attachment formats. if ( \is_string( $attachment ) && \file_exists( $attachment ) ) { $attachments[] = $attachment; } elseif ( \is_array( $attachment ) && isset( $attachment['path'] ) && \file_exists( $attachment['path'] ) ) { $attachments[] = $attachment['path']; } } } } // Attempt to resend the email. $result = \wp_mail( $to, $subject, $message, $headers, $attachments ); // Redirect back with status. $redirect_url = \add_query_arg( array( 'page' => self::WP_MAIL_MENU_SLUG, 'resend_status' => $result ? 'success' : 'failed', 'resent_mail_id' => $mail_id, ), \admin_url( 'admin.php' ) ); \wp_safe_redirect( $redirect_url ); exit; } /** * Displays admin notice after email resend attempt * * @return void * * @since 4.8.0 */ public static function display_resend_notice() { // Only show on mail list page. if ( ! isset( $_GET['page'] ) || self::WP_MAIL_MENU_SLUG !== $_GET['page'] ) { return; } if ( ! isset( $_GET['resend_status'] ) ) { return; } $status = \sanitize_text_field( \wp_unslash( $_GET['resend_status'] ) ); $mail_id = isset( $_GET['resent_mail_id'] ) ? \absint( $_GET['resent_mail_id'] ) : 0; if ( 'success' === $status ) { echo '
'; echo \esc_html( \sprintf( \__( 'Email #%d has been successfully resent.', '0-day-analytics' ), $mail_id ) ); echo '
'; echo \esc_html( \sprintf( \__( 'Failed to resend email #%d. Please check your mail configuration.', '0-day-analytics' ), $mail_id ) ); echo '
tag.
if ( empty( $item[ $column_name ] ) ) {
return '';
}
return '' . \esc_html( $item[ $column_name ] ) . '';
case 'backtrace_segment':
$source_link = '';
$query_array = array(
'_wpnonce' => \wp_create_nonce( 'source-view' ),
'action' => 'log_source_view',
);
$source = \json_decode( $item['backtrace_segment'], true );
if ( isset( $source['file'] ) ) {
$item['error_file'] = $source['file'];
if ( isset( $source['line'] ) ) {
$item['error_line'] = $source['line'];
}
}
unset( $source );
if ( isset( $item['error_file'] ) && ! empty( $item['error_file'] ) ) {
$query_array['error_file'] = $item['error_file'];
if ( isset( $item['error_line'] ) && ! empty( $item['error_line'] ) ) {
$query_array['error_line'] = $item['error_line'];
}
$query_array['TB_iframe'] = 'true';
$view_url = \esc_url_raw(
\add_query_arg( $query_array, \admin_url( 'admin-ajax.php' ) )
);
$title = __( 'Viewing: ', '0-day-analytics' ) . $item['error_file'];
$source_link = '';
}
if ( isset( $item['error_file'] ) ) {
$plugins_dir_basename = basename( \WP_PLUGIN_DIR );
if ( false !== \mb_strpos( $item['error_file'], $plugins_dir_basename . \DIRECTORY_SEPARATOR ) ) {
$split_plugin = explode( \DIRECTORY_SEPARATOR, $item['error_file'] );
$next = false;
$plugin_base = '';
foreach ( $split_plugin as $part ) {
if ( $next ) {
$plugin_base = $part;
break;
}
if ( $plugins_dir_basename === $part ) {
$next = true;
}
}
if ( isset( $plugin_base ) && ! empty( $plugin_base ) ) {
$item['plugin'] = Plugin_Theme_Helper::get_plugin_from_path( $plugin_base );
if ( isset( $item['plugin'] ) && ! empty( $item['plugin'] ) ) {
return __( 'Plugin: ', '0-day-analytics' ) . '' . \esc_html( $item['plugin']['Name'] ) . '
' . \__( 'Current version: ', '0-day-analytics' ) . \esc_html( $item['plugin']['Version'] ) . $source_link;
}
}
}
$theme = Plugin_Theme_Helper::get_theme_from_file_path( $item['error_file'] );
if ( $theme ) {
$name = $theme->get( 'Name' );
$version = $theme->get( 'Version' );
$version = ( ! empty( $version ) ) ? '
' . __( 'Current version: ', '0-day-analytics' ) . \esc_html( $version ) : '
' . __( 'Unknown version', '0-day-analytics' );
$name = ( ( ! empty( $name ) ) ? \esc_html( $name ) : __( 'Unknown theme', '0-day-analytics' ) ) . $version;
$parent = $theme->parent(); // ( 'parent_theme' );
if ( $parent ) {
$parent = $theme->parent()->get( 'Name' );
$parent_version = $theme->parent()->get( 'Version' );
$parent_version = ( ! empty( $parent_version ) ) ? \esc_html( $parent_version ) : __( 'Unknown version', '0-day-analytics' );
$parent = ( ! empty( $parent ) ) ? '' . __( 'Parent theme: ', '0-day-analytics' ) . \esc_html( $parent ) . '
' . __( 'Parent Current Version: ', '0-day-analytics' ) . $parent_version . '' : '';
}
$name .= (string) $parent;
return __( 'Theme: ', '0-day-analytics' ) . '' . ( $name ) . '' . $source_link;
}
if ( false !== \mb_strpos( $item['error_file'], ABSPATH . WPINC . \DIRECTORY_SEPARATOR ) ) {
return ' ' . __( 'WP Core', '0-day-analytics' ) . $source_link;
}
$admin_path = str_replace( \get_home_url( 1 ) . '/', ABSPATH, \network_admin_url() );
if ( false !== \mb_strpos( $item['error_file'], $admin_path ) ) {
return ' ' . __( 'WP Admin Core', '0-day-analytics' ) . $source_link;
} else {
return ' ' . __( 'Source', '0-day-analytics' ) . $source_link;
}
}
return '';
case 'email_category':
if ( empty( $item['email_category'] ) ) {
return 'general';
}
$colors = array(
'order' => '#4CAF50',
'user' => '#2196F3',
'system' => '#FF5722',
'marketing' => '#9C27B0',
'notification' => '#FF9800',
'transactional' => '#00BCD4',
'general' => '#999',
);
$color = isset( $colors[ $item['email_category'] ] ) ? $colors[ $item['email_category'] ] : '#999';
return '' . \esc_html( $item['email_category'] ) . '';
case 'message_size':
case 'total_size':
case 'attachment_total_size':
if ( empty( $item[ $column_name ] ) || 0 === (int) $item[ $column_name ] ) {
return '';
}
return \esc_html( \size_format( (int) $item[ $column_name ], 2 ) );
case 'attachment_count':
if ( empty( $item['attachment_count'] ) || 0 === (int) $item['attachment_count'] ) {
return '';
}
$count = (int) $item['attachment_count'];
$size = ! empty( $item['attachment_total_size'] ) ? ' (' . \size_format( (int) $item['attachment_total_size'], 2 ) . ')' : '';
return ' ' . \esc_html( $count . $size );
case 'delivery_time':
if ( empty( $item['delivery_time'] ) || 0.0 === (float) $item['delivery_time'] ) {
return '';
}
$ms = round( (float) $item['delivery_time'] * 1000, 2 );
return \esc_html( $ms . ' ms' );
case 'can_resend':
if ( isset( $item['can_resend'] ) && 1 === (int) $item['can_resend'] ) {
return '';
}
return '';
case 'is_html':
$icon = ( $item['is_html'] ) ? 'saved' : 'minus';
return '';
case 'attachments':
if ( ! \is_string( $item['attachments'] ) ) {
return esc_html__( 'No', '0-day-analytics' );
}
$item['attachments'] = json_decode( $item['attachments'], true );
if ( isset( $item['attachments'] ) && ! empty( $item['attachments'] ) && is_array( $item['attachments'] ) ) {
$item['attachments'] = array_map(
function ( $attachment ) {
if ( ! isset( $attachment['id'] ) || -1 === $attachment['id'] ) {
$attachment['note'] = __( 'Attachment not in media library', '0-day-analytics' );
if ( empty( $attachment['src'] ) ) {
$attachment['src'] = 'data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%201024%201024%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill%3D%22currentColor%22%20d%3D%22M832%20384H576V128H192v768h640V384zm-26.496-64L640%20154.496V320h165.504zM160%2064h480l256%20256v608a32%2032%200%200%201-32%2032H160a32%2032%200%200%201-32-32V96a32%2032%200%200%201%2032-32zm160%20448h384v64H320v-64zm0-192h160v64H320v-64zm0%20384h384v64H320v-64z%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E';
}
return $attachment;
}
if ( empty( $attachment['alt'] ) ) {
$attachment['alt'] = $attachment['url'];
}
if ( empty( $attachment['src'] ) ) {
$attachment['src'] = 'data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%201024%201024%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill%3D%22currentColor%22%20d%3D%22M832%20384H576V128H192v768h640V384zm-26.496-64L640%20154.496V320h165.504zM160%2064h480l256%20256v608a32%2032%200%200%201-32%2032H160a32%2032%200%200%201-32-32V96a32%2032%200%200%201%2032-32zm160%20448h384v64H320v-64zm0-192h160v64H320v-64zm0%20384h384v64H320v-64z%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E';
}
return $attachment;
},
$item['attachments']
);
// $item['attachments'] = array_column( $item['attachments'], 'url' );
// $item['attachments'] = WP_Mail_Log::array_to_string(
// $item['attachments'],
// ' | '
// );
} else {
$item['attachments'] = null;
}
if ( empty( $item['attachments'] ) ) {
return esc_html__( 'No', '0-day-analytics' );
} else {
\ob_start();
?>
_args['plural'] );
$delete_url =
\add_query_arg(
array(
'action' => 'delete',
'advan_' . self::$table::get_name() => $item['id'],
self::SEARCH_INPUT => self::escaped_search_input(),
'_wpnonce' => $query_args_view_data['_wpnonce'],
)
);
$actions['delete'] = '' . \esc_html__( 'Delete', '0-day-analytics' ) . '';
// Add resend action if email can be resent.
if ( isset( $item['can_resend'] ) && 1 === (int) $item['can_resend'] ) {
$resend_url = \add_query_arg(
array(
'action' => 'resend_email',
'mail_id' => $item['id'],
'_wpnonce' => \wp_create_nonce( 'resend_email_' . $item['id'] ),
),
\admin_url( 'admin-post.php' )
);
$actions['resend'] = '' . \esc_html__( 'Resend', '0-day-analytics' ) . '';
}
$actions['details'] = '' . \esc_html__( 'Details', '0-day-analytics' ) . '';
$data = '';
if ( 0 === (int) $item['status'] ) {
$data = '' . __( 'Error occurred:', '0-day-analytics' ) . '
' . \esc_html( (string) $item['error'] ) . '';
}
$time_format = 'g:i a';
$item['date_added'] = (int) $item['time'];
$mail_datetime_utc = \gmdate( 'Y-m-d H:i:s', $item['date_added'] );
$timezone_local = \wp_timezone();
$mail_local = \get_date_from_gmt( $mail_datetime_utc, 'Y-m-d' );
$today_local = ( new \DateTimeImmutable( 'now', $timezone_local ) )->format( 'Y-m-d' );
$tomorrow_local = ( new \DateTimeImmutable( 'tomorrow', $timezone_local ) )->format( 'Y-m-d' );
$yesterday_local = ( new \DateTimeImmutable( 'yesterday', $timezone_local ) )->format( 'Y-m-d' );
// If the offset of the date of the event is different from the offset of the site, add a marker.
if ( \get_date_from_gmt( $mail_datetime_utc, 'P' ) !== get_date_from_gmt( 'now', 'P' ) ) {
$time_format .= ' (P)';
}
$mail_time_local = \get_date_from_gmt( $mail_datetime_utc, $time_format );
if ( $mail_local === $today_local ) {
$date = sprintf(
/* translators: %s: Time */
__( 'Today at %s', '0-day-analytics' ),
$mail_time_local,
);
} elseif ( $mail_local === $tomorrow_local ) {
$date = sprintf(
/* translators: %s: Time */
__( 'Tomorrow at %s', '0-day-analytics' ),
$mail_time_local,
);
} elseif ( $mail_local === $yesterday_local ) {
$date = sprintf(
/* translators: %s: Time */
__( 'Yesterday at %s', '0-day-analytics' ),
$mail_time_local,
);
} else {
$date = sprintf(
/* translators: 1: Date, 2: Time */
__( '%1$s at %2$s', '0-day-analytics' ),
\get_date_from_gmt( $mail_datetime_utc, 'F jS' ),
$mail_time_local,
);
}
$time = sprintf(
'',
\esc_attr( gmdate( 'c', $item['date_added'] ) ),
\esc_html( $date )
);
$until = $item['date_added'] - time();
if ( $until < 0 ) {
$ago = sprintf(
/* translators: %s: Time period, for example "8 minutes" */
__( '%s ago', '0-day-analytics' ),
WP_Helper::interval( abs( $until ) )
);
return sprintf(
' %s
%s',
esc_html( $ago ),
$time,
) . $this->row_actions( $actions ) . $data;
} elseif ( 0 === $until ) {
$in = __( 'Now', '0-day-analytics' );
} else {
$in = sprintf(
/* translators: %s: Time period, for example "8 minutes" */
__( 'In %s', '0-day-analytics' ),
WP_Helper::interval( $until ),
);
}
return sprintf(
' %s
%s',
\esc_html( $in ),
$time,
) . $this->row_actions( $actions ) . $data;
case 'blog_id':
if ( WP_Helper::is_multisite() && 1 !== (int) $item['blog_id'] ) {
$site = \get_site( (int) $item['blog_id'] );
if ( $site ) {
$blog_details = \get_blog_details( array( 'blog_id' => $item['blog_id'] ) );
$name = ( $blog_details ) ? $blog_details->blogname : \sprintf( /* translators: %s: Site ID */ __( 'Site %s', '0-day-analytics' ), (int) $item['blog_id'] );
$details = \sprintf(
/* translators: 1: Site ID, 2: Site domain, 3: Site path */
__( 'Site ID: %1$s, Domain: %2$s, Path: %3$s', '0-day-analytics' ),
(int) $site->blog_id,
$site->domain,
$site->path
);
return '' . \esc_html( $name ) . '';
} else {
return \esc_html__( 'Unknown or deleted site', '0-day-analytics' );
}
} elseif ( WP_Helper::is_multisite() && 1 === (int) $item['blog_id'] ) {
return \esc_html__( 'Main Site', '0-day-analytics' );
}
}
}
/**
* Get value for checkbox column.
*
* The special 'cb' column
*
* @param object $item - A row's data.
*
* @return string Text to be placed inside the column < td > .
*
* @since 3.0.0
*/
protected function column_cb( $item ) {
return sprintf(
'',
\esc_attr( self::$table::get_name() . '_' . $item['id'] ),
sprintf(
// translators: The column name.
__( 'Select %s', '0-day-analytics' ),
'id'
),
\esc_attr( self::$table::get_name() ),
\esc_attr( (string) $item['id'] )
);
}
/**
* Process actions triggered by the user
*
* @since 1.0.0
*/
public function handle_table_actions() {
/**
* Note: Table bulk_actions can be identified by checking $_REQUEST['action'] and $_REQUEST['action2']
*
* Action - is set if checkbox from top-most select-all is set, otherwise returns -1
* Action2 - is set if checkbox the bottom-most select-all checkbox is set, otherwise returns -1
*/
if ( \is_user_logged_in() && \current_user_can( 'manage_options' ) ) {
// check for individual row actions.
$the_table_action = $this->current_action();
// check for table bulk actions.
if ( ( isset( $_REQUEST['action'] ) && 'delete' === $_REQUEST['action'] ) || ( isset( $_REQUEST['action2'] ) && 'delete' === $_REQUEST['action2'] ) ) {
WP_Helper::verify_admin_nonce( 'bulk-' . $this->_args['plural'] );
if ( isset( $_REQUEST[ 'advan_' . self::$table::get_name() ] ) ) {
foreach ( (array) $_REQUEST[ 'advan_' . self::$table::get_name() ] as $id ) {
self::$table::delete_by_id( (int) $id );
}
}
$redirect =
\remove_query_arg(
array( 'delete', '_wpnonce', 'advan_' . self::$table::get_name(), 'action' ),
\add_query_arg(
array(
self::SEARCH_INPUT => self::escaped_search_input(),
'paged' => (int) ( $_REQUEST['paged'] ?? 1 ),
'page' => self::WP_MAIL_MENU_SLUG,
'show_table' => self::$table::get_name(),
),
\admin_url( 'admin.php' )
)
);
\wp_safe_redirect( $redirect );
exit;
}
}
}
/**
* View a license information.
*
* @since 1.0.0
*
* @param int $table_id - Record ID.
*/
public function page_view_data( $table_id ) {
// Edit_Data::set_table( $this->table );
// Edit_Data::edit_record( $table_id );
}
/**
* Table navigation.
*
* @param string $which - Position of the nav.
*
* @since 1.1.0
*/
public function extra_tablenav( $which ) {
// Plugin filter dropdown (mirrors Requests list behavior).
if ( isset( $_REQUEST['plugin'] ) && ! empty( $_REQUEST['plugin'] ) ) {
if ( -1 === (int) $_REQUEST['plugin'] ) {
$plugin = -1;
} else {
$plugin = \sanitize_text_field( \wp_unslash( $_REQUEST['plugin'] ) );
}
} else {
$plugin = 0;
}
?>
items ) > 0 ) {
?>
|
|
|
|
|
'', // to display the checkbox.
);
self::$admin_columns = \array_merge( $table_columns, $screen_options, $columns );
}
return self::$admin_columns;
}
/**
* Retrieves mail body by given record ID.
*
* @param \WP_REST_Request $request - The request object.
*
* @return \WP_REST_Response|\WP_Error|string
*
* @since 3.0.0
*/
public static function get_mail_body_api( \WP_REST_Request $request ) {
// Basic capability check to protect sensitive mail content. Adjust capability if plugin defines custom caps.
if ( ! \current_user_can( 'manage_options' ) ) {
return new \WP_Error(
'insufficient_permissions',
__( 'You do not have permission to view this resource.', '0-day-analytics' ),
array( 'status' => 403 )
);
}
$id = abs( (int) $request->get_param( 'id' ) );
$record = WP_Mail_Entity::load( 'id=%d', array( $id ) );
$message = '
' . \esc_html__( 'Mail Content', '0-day-analytics' ) . '
';
if ( is_array( $record ) && ! empty( $record ) ) {
if ( isset( $record['is_html'] ) && (bool) $record['is_html'] ) {
$message .= WP_Mail_Log::filter_html( $record['message'] );
} else {
$message .= \nl2br( $record['message'] );
}
$attachments = '';
$record['attachments'] = json_decode( (string) $record['attachments'], true );
if ( isset( $record['attachments'] ) && ! empty( $record['attachments'] ) && is_array( $record['attachments'] ) ) {
$record['attachments'] = array_map(
function ( $attachment ) {
if ( ! isset( $attachment['id'] ) || -1 === $attachment['id'] ) {
$attachment['note'] = __( 'Attachment not in media library', '0-day-analytics' );
if ( empty( $attachment['src'] ) ) {
$attachment['src'] = 'data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%201024%201024%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill%3D%22currentColor%22%20d%3D%22M832%20384H576V128H192v768h640V384zm-26.496-64L640%20154.496V320h165.504zM160%2064h480l256%20256v608a32%2032%200%200%201-32%2032H160a32%2032%200%200%201-32-32V96a32%2032%200%200%201%2032-32zm160%20448h384v64H320v-64zm0-192h160v64H320v-64zm0%20384h384v64H320v-64z%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E';
}
return $attachment;
}
if ( empty( $attachment['alt'] ) ) {
$attachment['alt'] = $attachment['url'];
}
if ( empty( $attachment['src'] ) ) {
$attachment['src'] = 'data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%201024%201024%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill%3D%22currentColor%22%20d%3D%22M832%20384H576V128H192v768h640V384zm-26.496-64L640%20154.496V320h165.504zM160%2064h480l256%20256v608a32%2032%200%200%201-32%2032H160a32%2032%200%200%201-32-32V96a32%2032%200%200%201%2032-32zm160%20448h384v64H320v-64zm0-192h160v64H320v-64zm0%20384h384v64H320v-64z%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E';
}
return $attachment;
},
$record['attachments']
);
} else {
$record['attachments'] = null;
}
if ( ! empty( $record['attachments'] ) ) {
\ob_start();
?>
';
return \rest_ensure_response(
array(
'success' => true,
'mail_body' => $message,
'email_to' => $record['email_to'],
'email_from' => $record['email_from'],
'email_cc' => $record['email_cc'] ?? '',
'email_bcc' => $record['email_bcc'] ?? '',
'email_reply_to' => $record['email_reply_to'] ?? '',
'subject' => $record['subject'],
'email_category' => $record['email_category'] ?? 'general',
'additional_headers' => $record['additional_headers'] ?? \esc_html__( 'No additional headers', '0-day-analytics' ),
'message_size' => $record['message_size'] ?? 0,
'message_size_formatted' => ! empty( $record['message_size'] ) ? \size_format( (int) $record['message_size'] ) : '',
'total_size' => $record['total_size'] ?? 0,
'total_size_formatted' => ! empty( $record['total_size'] ) ? \size_format( (int) $record['total_size'] ) : '',
'attachment_count' => $record['attachment_count'] ?? 0,
'attachment_total_size' => $record['attachment_total_size'] ?? 0,
'attachment_total_size_formatted' => ! empty( $record['attachment_total_size'] ) ? \size_format( (int) $record['attachment_total_size'] ) : '',
'delivery_time' => $record['delivery_time'] ?? 0,
'can_resend' => $record['can_resend'] ?? 0,
'attachments' => $attachments,
)
);
} else {
return new \WP_Error(
'empty_mail_record',
__( 'No record found.', '0-day-analytics' ),
array( 'status' => 400 )
);
}
}
/**
* Display the list of hook types.
*
* @return array
*
* @since 3.5.0
*/
public function get_views() {
$views = array();
$hooks_type = ( $_REQUEST['mail_type'] ) ?? ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$hooks_type = \sanitize_text_field( \wp_unslash( $hooks_type ) );
$types = array(
'successful' => __( 'Successful', '0-day-analytics' ),
'unsuccessful' => __( 'Unsuccessful', '0-day-analytics' ),
'html' => __( 'HTML', '0-day-analytics' ),
'text' => __( 'Text', '0-day-analytics' ),
'attachments' => __( 'With attachments', '0-day-analytics' ),
// 'url' => __( 'URL events', '0-day-analytics' ),
);
$url = \add_query_arg(
array(
'page' => self::WP_MAIL_MENU_SLUG,
'mail_type' => 'all',
),
\admin_url( 'admin.php' )
);
$all_mails = $this->fetch_table_data( array( 'all' => true ) );
$views['all'] = sprintf(
'%3$s (%4$s)',
\esc_url( $url ),
'all' === $hooks_type ? ' class="current"' : '',
\esc_html__( 'All mails (no filters)', '0-day-analytics' ),
\esc_html( \number_format_i18n( count( $all_mails ) ) )
);
$filtered = self::get_filtered_mails( $all_mails );
foreach ( $types as $key => $type ) {
if ( ! isset( $filtered[ $key ] ) ) {
continue;
}
$count = count( $filtered[ $key ] );
if ( ! $count ) {
continue;
}
$url = \add_query_arg(
array(
'page' => self::WP_MAIL_MENU_SLUG,
self::SEARCH_INPUT => self::escaped_search_input(),
'mail_type' => $key,
),
\admin_url( 'admin.php' )
);
$views[ $key ] = sprintf(
'%3$s (%4$s)',
\esc_url( $url ),
$hooks_type === $key ? ' class="current"' : '',
\esc_html( $type ),
\esc_html( \number_format_i18n( $count ) )
);
}
return $views;
}
/**
* Returns mails filtered by various parameters
*
* @param array $mails The list of all events.
* @return array> Array of filtered events keyed by filter name.
*
* @since 3.3.1
*/
public static function get_filtered_mails( array $mails ) {
$filtered['successful'] = array_filter(
$mails,
function ( $mail ) {
return ( 1 === (int) $mail['status'] );
}
);
$filtered['unsuccessful'] = array_filter(
$mails,
function ( $mail ) {
return ( 0 === (int) $mail['status'] );
}
);
$filtered['html'] = array_filter(
$mails,
function ( $mail ) {
return ( 1 === (int) $mail['is_html'] );
}
);
$filtered['text'] = array_filter(
$mails,
function ( $mail ) {
return ( 0 === (int) $mail['is_html'] );
}
);
$filtered['attachments'] = array_filter(
$mails,
function ( $mail ) {
return ( '[]' !== $mail['attachments'] );
// $mail['attachments'] = json_decode( $mail['attachments'], true );
// return (
// ( isset( $mail['attachments'] ) && ! empty( $mail['attachments'] ) && is_array( $mail['attachments'] ) ) );
}
);
return $filtered;
}
}
}