Skip to content

Commit

Permalink
Merge pull request #1694 from Automattic/trunk
Browse files Browse the repository at this point in the history
Alpha release Nov 06
  • Loading branch information
dkoo authored Nov 6, 2024
2 parents c4854bc + d3f1f37 commit 531ec36
Show file tree
Hide file tree
Showing 18 changed files with 196 additions and 130 deletions.
2 changes: 1 addition & 1 deletion includes/class-newspack-newsletters-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ private static function render_lists_table() {
/>
</td>
<td class="name">
<label for="<?php echo esc_attr( $checkbox_id ); ?>"><?php echo esc_html( $list['name'] ); ?></strong>
<label for="<?php echo esc_attr( $checkbox_id ); ?>"><?php echo esc_html( $list['remote_name'] ); ?></strong>
<br/>
<small>
<?php echo esc_html( $list['type_label'] ); ?>
Expand Down
1 change: 1 addition & 0 deletions includes/class-subscription-list.php
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ public function to_array() {
'type_label' => $this->get_type_label(),
'edit_link' => $this->get_edit_link(),
'active' => $this->is_active(),
'remote_name' => $this->get_remote_name(),
];
}
}
25 changes: 17 additions & 8 deletions includes/class-subscription-lists.php
Original file line number Diff line number Diff line change
Expand Up @@ -466,8 +466,18 @@ public static function get_or_create_remote_list( $list ) {
$subscriber_count = ! empty( $list['member_count'] ) ? (int) $list['member_count'] : 0; // Tags have member_count instead of subscriber_count.
$saved_list = Subscription_List::from_public_id( $list['id'] );
if ( $saved_list ) {
// Update remote name, in case it's changed in the ESP.
$saved_list->set_remote_name( $list['title'] );

$has_customized_title = $saved_list->get_title() !== $saved_list->get_remote_name();

if ( $list['title'] !== $saved_list->get_remote_name() ) {
// The remote name has changed, let's update it locally.
$saved_list->set_remote_name( $list['title'] );

// Only update the title if it was not customized by the user.
if ( ! $has_customized_title ) {
$saved_list->update( [ 'title' => $list['title'] ] );
}
}

// Update subscriber count, if available.
if ( 0 > $subscriber_count ) {
Expand Down Expand Up @@ -551,11 +561,11 @@ public static function update_lists( $lists ) {
$existing_ids = [];

foreach ( $lists as $list ) {
if ( Subscription_List::is_local_public_id( $list['id'] ) ) {
// Local lists will be fetched here.
$stored_list = Subscription_List::from_public_id( $list['id'] );
} else {
// Remote lists will be either fetched or created here.

$stored_list = Subscription_List::from_public_id( $list['id'] );

// If a remote list was not found, create one.
if ( ! $stored_list instanceof Subscription_List && ! Subscription_List::is_local_public_id( $list['id'] ) ) {
$stored_list = self::get_or_create_remote_list( $list );
}

Expand All @@ -564,7 +574,6 @@ public static function update_lists( $lists ) {
}

$existing_ids[] = $stored_list->get_id();

$stored_list->update( $list );

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1050,7 +1050,7 @@ public function sync( $post ) {
'p[' . $send_list_id . ']' => 1,
'fromemail' => $from_email,
'fromname' => $from_name,
'subject' => $post->post_title,
'subject' => html_entity_decode( $post->post_title ),
],
$message_data
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -490,8 +490,8 @@ public function format_campaign_args( $post_id ) {
}

$args = [
'Subject' => get_the_title( $post_id ),
'Name' => get_the_title( $post_id ) . ' ' . gmdate( 'h:i:s A' ), // Name must be unique.
'Subject' => html_entity_decode( get_the_title( $post_id ) ),
'Name' => html_entity_decode( get_the_title( $post_id ) ) . ' ' . gmdate( 'h:i:s A' ), // Name must be unique.
'FromName' => get_post_meta( $post_id, 'senderName', true ),
'FromEmail' => get_post_meta( $post_id, 'senderEmail', true ),
'ReplyTo' => get_post_meta( $post_id, 'senderEmail', true ),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ public function sender( $post_id, $from_name, $reply_to ) {
$activity = [
'format_type' => 5,
'email_content' => $content,
'subject' => $post->post_title,
'subject' => html_entity_decode( $post->post_title ),
'contact_list_ids' => $campaign->activity->contact_list_ids,
'from_name' => $from_name,
'from_email' => $reply_to,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -618,14 +618,15 @@ public function retrieve( $post_id ) {
* @return array|WP_Error List of subscription lists or error.
*/
public function get_lists( $audiences_only = false ) {
$lists = Newspack_Newsletters_Mailchimp_Cached_Data::get_lists();
if ( $audiences_only || is_wp_error( $lists ) ) {
return $lists;
$audiences = Newspack_Newsletters_Mailchimp_Cached_Data::get_lists();
if ( $audiences_only || is_wp_error( $audiences ) ) {
return $audiences;
}
$lists = [];

// In addition to Audiences, we also automatically fetch all groups and tags and offer them as Subscription Lists.
// Build the final list inside the loop so groups are added after the list they belong to and we can then represent the hierarchy in the UI.
foreach ( $lists as $list ) {
foreach ( $audiences as $list ) {

$lists[] = $list;
$all_categories = Newspack_Newsletters_Mailchimp_Cached_Data::get_interest_categories( $list['id'] );
Expand Down Expand Up @@ -958,18 +959,6 @@ public function test( $post_id, $emails ) {
);
}
try {

$sync_result = $this->sync( get_post( $post_id ) );
if ( ! $sync_result ) {
return new WP_Error(
'newspack_newsletters_mailchimp_error',
__( 'Unable to synchronize with Mailchimp.', 'newspack-newsletters' )
);
}
if ( is_wp_error( $sync_result ) ) {
return $sync_result;
}

$mc = new Mailchimp( $this->api_key() );
$payload = [
'test_emails' => $emails,
Expand Down Expand Up @@ -1015,7 +1004,7 @@ public function get_sync_payload( $post ) {
'type' => 'regular',
'content_type' => 'template',
'settings' => [
'subject_line' => $post->post_title,
'subject_line' => html_entity_decode( $post->post_title ),
'title' => $this->get_campaign_name( $post ),
],
];
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.10.4",
"@wordpress/browserslist-config": "^6.10.0",
"@wordpress/browserslist-config": "^6.11.0",
"eslint": "^8.57.0",
"lint-staged": "^15.2.10",
"newspack-scripts": "^5.5.2",
Expand Down
7 changes: 4 additions & 3 deletions src/components/send-button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ import { get } from 'lodash';
* Internal dependencies
*/
import { getServiceProvider } from '../../service-providers';
import { refreshEmailHtml, validateNewsletter } from '../../newsletter-editor/utils';
import { validateNewsletter } from '../../newsletter-editor/utils';
import { useNewsletterData } from '../../newsletter-editor/store';
import { refreshEmailHtml } from '../../editor/mjml';
import './style.scss';

function PreviewHTML() {
Expand Down Expand Up @@ -298,7 +299,7 @@ export default compose( [
}

return (
<Fragment>
<div style={{ display: 'flex' }}>
<PreviewHTMLButton />
<Button
className="editor-post-publish-button"
Expand Down Expand Up @@ -366,7 +367,7 @@ export default compose( [
</div>
</Modal>
) }
</Fragment>
</div>
);
}
);
112 changes: 66 additions & 46 deletions src/editor/mjml/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,52 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import apiFetch from '@wordpress/api-fetch';
import { useSelect, useDispatch } from '@wordpress/data';
import { useEffect, useRef, useState } from '@wordpress/element';
import { refreshEmailHtml } from '../../newsletter-editor/utils';
import { useEffect } from '@wordpress/element';
import { usePrevious } from '../../newsletter-editor/utils';

/**
* Internal dependencies
*/
import { fetchNewsletterData, fetchSyncErrors, updateNewsletterDataError } from '../../newsletter-editor/store';
import { getServiceProvider } from '../../service-providers';
import {
fetchNewsletterData,
fetchSyncErrors,
updateIsRefreshingHtml,
} from '../../newsletter-editor/store';

/**
* Custom hook for fetching the prior value of a prop.
* External dependencies
*/
import mjml2html from 'mjml-browser';

/**
* Refresh the email-compliant HTML for a post.
*
* @param {*} value The prop to track.
* @return {*} The prior value of the prop.
* @param {number} postId The current post ID.
* @param {string} postTitle The current post title.
* @param {string} postContent The current post content.
* @return {Promise<string>} The refreshed email HTML.
*/
const usePrevProp = value => {
const ref = useRef();
useEffect( () => {
ref.current = value;
}, [ value ] );
return ref.current;
export const refreshEmailHtml = async ( postId, postTitle, postContent ) => {
const mjml = await apiFetch( {
path: `/newspack-newsletters/v1/post-mjml`,
method: 'POST',
data: {
post_id: postId,
title: postTitle,
content: postContent,
},
} );

// Once received MJML markup, convert it to email-compliant HTML and save as post meta.
const { html } = mjml2html( mjml, { keepComments: false, minify: true } );
return html;
};

function MJML() {
const [ isRefreshingHTML, setIsRefreshingHTML ] = useState( false );
const {
saveSucceeded,
isPublishing,
Expand Down Expand Up @@ -68,7 +87,7 @@ function MJML() {
isAutosaveLocked: isPostAutosavingLocked(),
};
} );

const { createNotice } = useDispatch( 'core/notices' );
const { lockPostAutosaving, lockPostSaving, unlockPostSaving, editPost } = useDispatch(
'core/editor'
);
Expand All @@ -82,7 +101,7 @@ function MJML() {
}, [ isAutosaveLocked ] );

// After the post is successfully saved, refresh the email HTML.
const wasSaving = usePrevProp( isSaving );
const wasSaving = usePrevious( isSaving );
const { name: serviceProviderName } = getServiceProvider();
const { supported_esps: supportedESPs } = newspack_email_editor_data || [];
const isSupportedESP = serviceProviderName && 'manual' !== serviceProviderName && supportedESPs?.includes( serviceProviderName );
Expand All @@ -93,42 +112,43 @@ function MJML() {
! isSaving &&
! isAutosaving &&
! isPublishing &&
! isRefreshingHTML &&
! isSent &&
saveSucceeded
) {
setIsRefreshingHTML( true );
lockPostSaving( 'newspack-newsletters-refresh-html' );
refreshEmailHtml( postId, postTitle, postContent )
.then( refreshedHtml => {
updateMetaValue( newspack_email_editor_data.email_html_meta, refreshedHtml );
return apiFetch( {
data: { meta: { [ newspack_email_editor_data.email_html_meta ]: refreshedHtml } },
method: 'POST',
path: `/wp/v2/${ postType }/${ postId }`,
} );
} ).then( () => {
// Rehydrate ESP newsletter data after completing sync.
if ( isSupportedESP ) {
return fetchNewsletterData( postId );
}
return true;
} ).then ( () => {
// Check for sync errors after refreshing the HTML.
if ( isSupportedESP ) {
return fetchSyncErrors( postId );
}
return true;
} )
.catch( e => {
updateNewsletterDataError( e );
} )
.finally( () => {
unlockPostSaving( 'newspack-newsletters-refresh-html' );
setIsRefreshingHTML( false );
} );
refreshHtml();
}
}, [ isSaving, isAutosaving ] );

const refreshHtml = async () => {
try {
lockPostSaving( 'newspack-newsletters-refresh-html' );
if ( isSupportedESP ) {
updateIsRefreshingHtml( true );
}
const refreshedHtml = await refreshEmailHtml( postId, postTitle, postContent );
updateMetaValue( newspack_email_editor_data.email_html_meta, refreshedHtml );

// Save the refreshed HTML to post meta.
await apiFetch( {
data: { meta: { [ newspack_email_editor_data.email_html_meta ]: refreshedHtml } },
method: 'POST',
path: `/wp/v2/${ postType }/${ postId }`,
} );

// Rehydrate ESP newsletter data after completing sync.
if ( isSupportedESP ) {
await fetchNewsletterData( postId );
await fetchSyncErrors( postId );
updateIsRefreshingHtml( false );
}
unlockPostSaving( 'newspack-newsletters-refresh-html' );
} catch ( e ) {
createNotice( 'error', e?.message || __( 'Error refreshing email HTML.', 'newspack-newsletters' ), {
id: 'newspack-newsletters-mjml-error',
isDismissible: true,
} );
}
}
}

export default MJML;
2 changes: 1 addition & 1 deletion src/newsletter-editor/editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ const Editor = compose( [
const publishButton = document.getElementsByClassName(
'editor-post-publish-button__button'
)[ 0 ];
publishButton.parentNode.insertBefore( publishEl, publishButton );
publishButton.parentNode.insertBefore( publishEl, publishButton.nextSibling );
}, [] );

// Set color palette option.
Expand Down
2 changes: 1 addition & 1 deletion src/newsletter-editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ function NewsletterEdit( { apiFetchWithErrorHandling, setInFlightForAsync, inFli
// Handle error messages from retrieve/sync requests with connected ESP.
useEffect( () => {
if ( newsletterDataError ) {
createNotice( 'error', newsletterDataError?.message || __( 'Error communicating with service provider.', 'newspack-newseltters' ), {
createNotice( 'error', newsletterDataError?.message || __( 'Error communicating with service provider.', 'newspack-newsletters' ), {
id: 'newspack-newsletters-newsletter-data-error',
isDismissible: true,
} );
Expand Down
Loading

0 comments on commit 531ec36

Please sign in to comment.