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 REST API endpoint to replace AJAX callback #33

Merged
merged 23 commits into from
Sep 12, 2019
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
23913eb
Add additional autotweet meta util functions
johnwatkins0 Aug 11, 2019
582c3ea
Convert metadata functions to autotweet versions
johnwatkins0 Aug 11, 2019
0c119bc
Create REST route and convert WP AJAX to WP REST
johnwatkins0 Aug 11, 2019
be98d1b
Meta key case consistency
johnwatkins0 Aug 11, 2019
f1c741f
Convert consts back to vars in untranspiled JS file
johnwatkins0 Aug 11, 2019
1676cd9
Remove curly brace use syntax for PHP5.6 compatability
johnwatkins0 Aug 11, 2019
3021245
Merge branch 'feature/webpack-build-process' into feature/rest-endpoint
johnwatkins0 Aug 11, 2019
35b27d8
Variable name fix
johnwatkins0 Aug 11, 2019
4a45475
Function name fix
johnwatkins0 Aug 11, 2019
f78fe06
In JS, check for boolean instead of 'true'
johnwatkins0 Aug 11, 2019
c0510ff
Legacy JS - eplace jquery ajax with apiFetch
johnwatkins0 Aug 20, 2019
2e422bb
Replace direct access of with filter_input
johnwatkins0 Aug 20, 2019
dafbba7
Restore meta keys to previous forms for backward compatibility
johnwatkins0 Aug 20, 2019
a3f1de9
Add REST sanitize/validate CBs and refactor meta saving
johnwatkins0 Aug 21, 2019
16f1e25
Improve error handling in legacy JS
johnwatkins0 Aug 21, 2019
eb075f8
Remove debug code
johnwatkins0 Aug 23, 2019
51b7cf0
Merge branch 'feature/rest-endpoint' of https://github.com/10up/10up-…
Aug 26, 2019
b7d0f8c
improve rest response message
Aug 26, 2019
1ee6551
Switch JS concatenation to template literal
johnwatkins0 Aug 27, 2019
f230945
Docblock formatting fixes
johnwatkins0 Aug 27, 2019
d19badf
Cast checked boolean values in comparison
johnwatkins0 Aug 27, 2019
8248745
Remove no-longer-used nonce field
johnwatkins0 Aug 27, 2019
d0f0541
Update failing integratino test
johnwatkins0 Aug 27, 2019
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
152 changes: 81 additions & 71 deletions assets/js/admin-auto_tweet.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,93 +3,105 @@
*
* @todo soooo much dependency :facepalm:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of this file's changeset is ESLint.

*/
(function ($) {
( function( $ ) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intentionally not removing the jQuery dependency for this PR.

'use strict';

var $tweetPost = $('#tenup-auto-tweet-enable'),
$icon = $('#tenup-auto-tweet-icon'),
$postTitle = $('input[name="post_title"]'),
$tweetText = $('#tenup-auto-tweet-text'),
$editLink = $('#tenup-auto-tweet-edit'),
$editBody = $('#tenup-auto-tweet-override-body'),
$hideLink = $('.cancel-tweet-text'),
counterWrap = document.getElementById('tenup-auto-tweet-counter-wrap'),
var $tweetPost = $( '#tenup-auto-tweet-enable' ),
$icon = $( '#tenup-auto-tweet-icon' ),
$tweetText = $( '#tenup-auto-tweet-text' ),
$editLink = $( '#tenup-auto-tweet-edit' ),
$editBody = $( '#tenup-auto-tweet-override-body' ),
$hideLink = $( '.cancel-tweet-text' ),
errorMessageContainer = document.getElementById( 'tenup-autotweet-error-message' ),
counterWrap = document.getElementById( 'tenup-auto-tweet-counter-wrap' ),
limit = 280;


// Add enabled class if checked
if ($tweetPost.prop('checked')) {
$icon.addClass('enabled')
if ( $tweetPost.prop( 'checked' ) ) {
$icon.addClass( 'enabled' );
}

// Event handlers.
$tweetPost.on('click', handleRequest );
$tweetText.change(handleRequest);
$editLink.on('click', function() {
$tweetPost.on( 'click', handleRequest );
$tweetText.change( handleRequest );
$editLink.on( 'click', function() {
$editBody.slideToggle();
updateRemainingField();
$(this).hide();
})
$tweetText.on('keyup', function() {
$( this ).hide();
} );
$tweetText.on( 'keyup', function() {
updateRemainingField();
})
$hideLink.on('click', function(e) {
} );
$hideLink.on( 'click', function( e ) {
e.preventDefault();
$('#tenup-auto-tweet-override-body').slideToggle();
$( '#tenup-auto-tweet-override-body' ).slideToggle();
$editLink.show();
});
} );

// Runs on page load to auto-enable posts to be tweeted
window.onload = function(event) {
if ( '' === adminTUAT.currentStatus ) {
handleRequest(event, true)
window.onload = function( event ) {
if ( '' === adminAutotweet.currentStatus ) {
handleRequest( event, true );
}
}
};

/**
* AJAX handler
* @param event
* Callback for failed requests.
*/
function handleRequest(event, status = $tweetPost.prop('checked') ) {
function onRequestFail( error ) {
var errorText = '';
if ( 'statusText' in error && 'status' in error ) {
errorText = adminAutotweet.errorText + ' ' + error.status + ': ' + error.statusText;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can use a template literal:

Suggested change
errorText = adminAutotweet.errorText + ' ' + error.status + ': ' + error.statusText;
errorText = `${ adminAutotweet.errorText } ${ error.status }: ${ error.statusText }`;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adamsilverstein This JS isn't transpiled -- is browser support an issue if we use a template literal? https://caniuse.com/#feat=template-literals

} else {
errorText = adminAutotweet.unkonwnErrorText;
}

// Process AJAX action.
$.ajax(ajaxurl, {
'data': {
'action': 'tenup_auto_tweet',
'checked': status,
'value': $tweetPost.val(),
'nonce': adminTUAT.nonce,
'post_id': adminTUAT.postId,
'text': $tweetText.val(),
'type': event.type
},
'beforeSend': pendingStatus(),
'dataType': 'json',
'success': function (response) {
errorMessageContainer.innerText = errorText;

// If successful
if (response.success) {
$icon.removeClass( 'pending' );
$tweetPost.prop( 'checked', false );
}

// Remove the pending and enabled/disabled classes depending on AJAX response
$icon.removeClass('pending');
if ('true' === response.data.enabled) {
$icon.toggleClass('enabled');
$tweetPost.prop('checked', true);
} else {
$icon.toggleClass('disabled');
$tweetPost.prop('checked', false);
}
/**
* AJAX handler
* @param event
*/
function handleRequest( event, status = $tweetPost.prop( 'checked' ) ) {
var data = {};
data[adminAutotweet.enableAutotweetKey] = status;
data[adminAutotweet.tweetBodyKey] = $tweetText.val();

wp.apiFetch(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

excellent!

{
url: adminAutotweet.restUrl,
data: data,
method: 'POST',
parse: false // We'll check the response for errors.
}
).then(
function( response ) {
if ( ! response.ok ) {
throw response;
}

// Something went wrong with the AJAX request. Remove the class and uncheck the box.
return response.json();
}
)
.then(
function( data ) {
errorMessageContainer.innerText = '';

$icon.removeClass( 'pending' );
if ( data.enabled ) {
$icon.toggleClass( 'enabled' );
$tweetPost.prop( 'checked', true );
} else {
$icon.removeClass('pending');
$tweetPost.prop('checked', false);
$icon.toggleClass( 'disabled' );
$tweetPost.prop( 'checked', false );
}

}

});
};
).catch( onRequestFail );

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may want to look for errors in the then handler as well, we should do some testing around different errors: eg network error, blocked request (rest disabled) etc. See https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch

}

/**
* Updates the counter
Expand All @@ -100,21 +112,19 @@
$( counterWrap ).text( count );

// Toggle the .over-limit class.
if (limit < count) {
counterWrap.classList.add('over-limit');

} else if (counterWrap.classList.contains('over-limit')) {
counterWrap.classList.remove('over-limit');
if ( limit < count ) {
counterWrap.classList.add( 'over-limit' );
} else if ( counterWrap.classList.contains( 'over-limit' ) ) {
counterWrap.classList.remove( 'over-limit' );
}
}

/**
* Helper for toggling classes to indicate something is happening.
*/
function pendingStatus() {
$icon.toggleClass('pending');
$icon.removeClass('enabled');
$icon.removeClass('disabled');
$icon.toggleClass( 'pending' );
$icon.removeClass( 'enabled' );
$icon.removeClass( 'disabled' );
}

})(jQuery);
} )( jQuery );
57 changes: 50 additions & 7 deletions includes/admin/assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@

namespace TenUp\AutoTweet\Admin\Assets;

use function TenUp\Auto_Tweet\Utils\get_autotweet_meta;
adamsilverstein marked this conversation as resolved.
Show resolved Hide resolved
use function TenUp\Auto_Tweet\Utils\opted_into_autotweet;
use const TenUp\Auto_Tweet\Core\Post_Meta\META_PREFIX;
use const TenUp\Auto_Tweet\Core\Post_Meta\TWEET_KEY;
use const TenUp\Auto_Tweet\Core\Post_Meta\ENABLE_AUTOTWEET_KEY;
use const TenUp\Auto_Tweet\Core\Post_Meta\TWEET_BODY_KEY;
use function TenUp\AutoTweet\REST\post_autotweet_meta_rest_route;

/**
* The handle used in registering plugin assets.
Expand Down Expand Up @@ -47,11 +49,40 @@ function maybe_enqueue_classic_editor_assets( $hook ) {
return;
}

$api_fetch_handle = 'wp-api-fetch';
if ( ! wp_script_is( $api_fetch_handle, 'registered' ) ) {
wp_register_script(
$api_fetch_handle,
trailingslashit( TUAT_URL ) . 'dist/api-fetch.js',
[],
'3.4.0',
true
);

wp_add_inline_script(
$api_fetch_handle,
sprintf(
'wp.apiFetch.use( wp.apiFetch.createNonceMiddleware( "%s" ) );',
( wp_installing() && ! is_multisite() ) ? '' : wp_create_nonce( 'wp_rest' )
),
'after'
);

wp_add_inline_script(
$api_fetch_handle,
sprintf(
'wp.apiFetch.use( wp.apiFetch.createRootURLMiddleware( "%s" ) );',
esc_url_raw( get_rest_url() )
),
'after'
);
}

$handle = 'admin_tenup-auto-tweet';
wp_enqueue_script(
$handle,
trailingslashit( TUAT_URL ) . 'assets/js/admin-auto_tweet.js',
[ 'jquery' ],
[ 'jquery', 'wp-api-fetch' ],
TUAT_VERSION,
true
);
Expand Down Expand Up @@ -94,11 +125,23 @@ function enqueue_editor_assets() {
* @param string $handle Handle of the JS script intended to consume the data.
*/
function localize_data( $handle = SCRIPT_HANDLE ) {
$post_id = intval( get_the_ID() );

if ( empty( $post_id ) ) {
$post_id = intval(
filter_input( INPUT_GET, 'post', FILTER_SANITIZE_NUMBER_INT ) // Filter removes all characters except digits.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

);
}

$localization = [
'nonce' => wp_create_nonce( 'admin_tenup-auto-tweet' ),
'postId' => get_the_ID() ? get_the_ID() : ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : 0 ), // phpcs:ignore WordPress.Security.NonceVerification.Recommended
'currentStatus' => get_post_meta( get_the_ID(), META_PREFIX . '_' . TWEET_KEY, true ),
'enabled' => get_autotweet_meta( $post_id, ENABLE_AUTOTWEET_KEY ),
'enableAutotweetKey' => ENABLE_AUTOTWEET_KEY,
'errorText' => __( 'Error', 'autotweet' ),
'nonce' => wp_create_nonce( 'wp_rest' ),
'restUrl' => rest_url( post_autotweet_meta_rest_route( $post_id ) ),
'tweetBodyKey' => TWEET_BODY_KEY,
'unknownErrorText' => __( 'An unknown error occurred', 'autotweet' ),
];

wp_localize_script( $handle, 'adminTUAT', $localization );
wp_localize_script( $handle, 'adminAutotweet', $localization );
}
Loading