Skip to content

Commit

Permalink
Merge pull request #51 from hametuha/bugfix/save-before-sending
Browse files Browse the repository at this point in the history
Bugfix/save before sending
  • Loading branch information
fumikito authored Dec 31, 2024
2 parents a9fd753 + 081ff36 commit 53b3edf
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 5 deletions.
100 changes: 100 additions & 0 deletions app/Hametuha/Hamail/API/Helper/RecipientsList.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php

namespace Hametuha\Hamail\API\Helper;


use Hametuha\Hamail\Pattern\Singleton;

/**
* Recipients list in CSV format.
*/
class RecipientsList extends Singleton {

/**
* {@inheritDoc}
*/
protected function init() {
add_action( 'rest_api_init', [ $this, 'rest_api_init' ] );
}

/**
* Register REST API
*
* @return void
*/
public function rest_api_init() {
register_rest_route( 'hamail/v1', '/recipients/(?P<post_id>\d+)', [
[
'methods' => 'GET',
'args' => [
'post_id' => [
'required' => true,
'type' => 'integer',
'validate_callback' => function ( $param ) {
$post = get_post( $param );
return ( $post && 'hamail' === $post->post_type );
},
],
],
'permission_callback' => [ $this, 'permission_callback' ],
'callback' => [ $this, 'callback' ],
],
] );
}

/**
* Handle REST API.
*
* @param \WP_REST_Request $request
* @return void|\WP_Error
*/
public function callback( $request ) {
$post = get_post( $request->get_param( 'post_id' ) );
$recipients = hamail_get_message_recipients( $post );
if ( empty( $recipients ) ) {
return new \WP_Error( 'hamail_invalid_email', __( 'No recipients are listed in this post.', 'hamail' ) );
}
// Send HTTP headers.
header( 'Content-Type: text/csv; charset=utf-8' );
header( sprintf( 'Content-Disposition: attachment; filename="recipients-%d-%s.csv"', $post->ID, date_i18n( 'YmdHis' ) ) );
// User stream for CSV.
$output = new \SplFileObject( 'php://output', 'w' );
// Write header.
$output->fputcsv( [ 'Email', 'Name', 'User ID', 'Role', 'User Exists' ] );
// Write recipients.
foreach ( $recipients as $id_or_email ) {
$user = null;
if ( is_numeric( $id_or_email ) ) {
$user = get_userdata( $id_or_email );
} else {
$user_id = email_exists( $id_or_email );
if ( $user_id ) {
$user = get_userdata( $user_id );
}
}
if ( $user ) {
// User exists.
$output->fputcsv( [ $user->user_email, $user->display_name, $id_or_email, implode( '/', $user->roles ), 'True' ] );
} else {
if ( is_numeric( $id_or_email ) ) {
// This is ID, but no user found.
$output->fputcsv( [ '', '', $id_or_email, '', 'False' ] );
} else {
// This is email, and user not found.
$output->fputcsv( [ $id_or_email, '', '0', '', 'False' ] );
}
}
}
exit;
}

/**
* Permission callback.
*
* @param \WP_REST_Request $request
* @return bool
*/
public function permission_callback( $request ) {
return current_user_can( 'edit_post', $request->get_param( 'post_id' ) );
}
}
52 changes: 52 additions & 0 deletions app/Hametuha/Hamail/API/TransactionMails.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Hametuha\Hamail\API;


use Hametuha\Hamail\API\Helper\RecipientsList;
use Hametuha\Hamail\API\Helper\UserFilter;
use Hametuha\Hamail\Pattern\Singleton;
use Hametuha\Hamail\Service\TemplateSelector;
Expand All @@ -23,12 +24,15 @@ protected function init() {
// Initialize template selector.
TemplateSelector::get_instance();
UserFilter::get_instance();
RecipientsList::get_instance();
add_action( 'add_meta_boxes', [ $this, 'add_meta_boxes' ] );
add_action( 'init', [ $this, 'register_mail_post_type' ] );
// Save post meta.
add_action( 'save_post_hamail', [ $this, 'save_post_id' ], 10, 2 );
// Save post and send mail.
add_action( 'save_post_hamail', [ $this, 'save_post_and_send_mail' ], 11, 2 );
// Scheduled post.
add_action( 'transition_post_status', [ $this, 'send_email_for_scheduled_post' ], 20, 3 );
}

/**
Expand Down Expand Up @@ -114,6 +118,30 @@ public function save_post_and_send_mail( $post_id, $post ) {
}
}

/**
* Send email for scheduled post.
*
* @see wp_publish_post()
* @param string $new_status
* @param string $old_status
* @param \WP_Post $post
*/
public function send_email_for_scheduled_post( $new_status, $old_status, $post ) {
if ( 'hamail' !== $post->post_type ) {
return;
}
if ( 'publish' !== $new_status || 'future' !== $old_status ) {
// This is not scheduled post publication.
return;
}
if ( hamail_is_sent( $post ) ) {
// Don't know why, but this post is already sent.
return;
}
// Send mail.
hamail_send_message( $post );
}

/**
* Change "Publish" button's label.
*
Expand Down Expand Up @@ -221,6 +249,14 @@ public function recipients_meta_box( $post ) {
</p>
<?php endif; ?>


<p style="text-align: right;">
<a href="<?php echo esc_url( wp_nonce_url( rest_url( 'hamail/v1/recipients/' . $post->ID ), 'wp_rest' ) ); ?>"
class="button" target="_blank" rel="noopener noreferrer">
<?php esc_html_e( 'Check Recipients in CSV', 'hamail' ); ?>
</a>
</p>

<div class="hamail-address">
<div class="hamail-address-group">
<h4 class="hamail-address-title"><?php esc_html_e( 'Filter Users', 'hamail' ); ?></h4>
Expand Down Expand Up @@ -354,6 +390,22 @@ public function status_meta_box( $post ) {
) )
?>
</p>
<p>
<label for="hamail-message-ids"><?php esc_html_e( 'Message ID', 'hamail' ); ?></label>
<?php
$message_ids = array_filter( (array) get_post_meta( $post->ID, '_hamail_message_ids', true ) );
printf(
'<textarea id="hamail-message-ids" name="hamail_message_ids" rows="3" class="widefat" readonly placeholder="%s">%s</textarea>',
esc_attr__( 'No message ID', 'hamail' ),
esc_textarea( implode( "\n", $message_ids ) )
);
?>
<span class="description">
<?php
printf( 'Message IDs are set if the message is actually sent via SendGrid. This works for filtering activity logs.' );
?>
</span>
</p>
<?php else : ?>
<?php wp_nonce_field( 'hamail_as_admin', '_hamailadminnonce', false ); ?>
<p class="description">
Expand Down
20 changes: 20 additions & 0 deletions app/Hametuha/Hamail/Commands/HamailCommands.php
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,26 @@ public function test_message( $args ) {
}
}

/**
* Get message activities
*
* @synopsis <message_id>
* @param array $args
* @return void
*/
public function activities( $args ) {
list( $message_id ) = $args;
$client = hamail_client();
$response = $client->client->messages()->_( $message_id )->get();
if ( '200' !== $response->statusCode() ) {
$body = json_decode( $response->body(), true );
\WP_CLI::error( implode( "\n", array_map( function ( $error ) {
return $error['message'];
}, $body['errors'] ) ) );
}
var_dump( $response );
}

/**
* Getter.
*
Expand Down
18 changes: 14 additions & 4 deletions functions/mail.php
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ function hamail_get_recipients_data( $recipients, $subject = '', $body = '' ) {
* @param array $attachments
* @param int $asm_id If set, unsubscribe group will be this.
*
* @return bool|WP_Error
* @return true|string[]|WP_Error If API returns message IDs, return array of message IDs. If error, return WP_Error. Else true.
*/
function hamail_simple_mail( $recipients, $subject, $body, $additional_headers = [], $attachments = [], $asm_id = 0 ) {
// Parse recipients.
Expand Down Expand Up @@ -451,6 +451,7 @@ function hamail_simple_mail( $recipients, $subject, $body, $additional_headers =
$errors = new WP_Error();
$slots_total = 0;
$sent_total = 0;
$message_ids = [];
foreach ( $recipients_slots as $index => $recipients_group ) {
try {
// Create mail instance.
Expand Down Expand Up @@ -518,6 +519,11 @@ function hamail_simple_mail( $recipients, $subject, $body, $additional_headers =
// Get response.
$code = $response->statusCode();
if ( preg_match( '#2[\d]{2}#u', $code ) ) {
// Status 2x2, so this is OK. Save message ID for post.
$message_id = $response->headers( true )['X-Message-Id'] ?? '';
if ( $message_id ) {
$message_ids[] = $message_id;
}
continue;
} else {
$error = json_decode( $response->body() );
Expand All @@ -533,18 +539,18 @@ function hamail_simple_mail( $recipients, $subject, $body, $additional_headers =
}
$errors_messages = $errors->get_error_messages();
if ( empty( $errors_messages ) ) {
return true;
return $message_ids ?: true;
} else {
return $errors;
}
}

/**
* Get recipients.
* Get recipients of specified mail.
*
* @param null|int|WP_Post $post
*
* @return array ID or email.
* @return array<int, int|string> ID or email.
*/
function hamail_get_message_recipients( $post = null ) {
$post = get_post( $post );
Expand Down Expand Up @@ -671,6 +677,10 @@ function hamail_send_message( $post = null, $force = false ) {
}
return $result;
} else {
// If result is array, these are message IDs.
if ( is_array( $result ) ) {
update_post_meta( $post->ID, '_hamail_message_ids', $result );
}
update_post_meta( $post->ID, '_hamail_sent', current_time( 'mysql' ) );
return true;
}
Expand Down
25 changes: 24 additions & 1 deletion src/js/hamail-sender.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
/*!
* Hametuha user selector
*
* @deps hamail-incsearch, wp-api-fetch
* @deps hamail-incsearch, wp-api-fetch, wp-i18n, wp-hooks
*/

const $ = jQuery;
const { ItemsController } = wp.hamail;
const { apiFetch } = wp;
const { addFilter } = wp.hooks;
const { __ } = wp.i18n;

$( document ).ready( function() {
// User selector.
Expand Down Expand Up @@ -83,3 +85,24 @@ $( document ).ready( function() {
$( 'input[name="hamail_roles[]"]' ).on( 'click', updateUserFilterCount );
$( 'input[name^="hamail_user_filters"]' ).on( 'click', updateUserFilterCount );
} );

// Add filter to override text.
// https://developer.wordpress.org/block-editor/reference-guides/filters/i18n-filters/
addFilter( 'i18n.gettext_default', 'hamail/override-editor-label', ( translation, text ) => {
switch ( text ) {
case 'Publish':
return __( 'Send', 'hamail' );
case 'Schedule':
return __( 'Schedule', 'hamail' );
case 'Excerpt':
return __( 'Pre-header Text', 'hamail' );
case 'Add an excerpt…':
return __( 'Add pre-header text', 'hamail' );
case 'Edit excerpt':
return __( 'Edit pre-header text', 'hamail' );
case 'Learn more about manual excerpts':
return __( 'Excerpt is used for pre-header text in email.', 'hamail' );
default:
return translation;
}
} );

0 comments on commit 53b3edf

Please sign in to comment.