Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save westonruter/3b61ffcfbc1b528b1135ac7cc065eaa2 to your computer and use it in GitHub Desktop.
Save westonruter/3b61ffcfbc1b528b1135ac7cc065eaa2 to your computer and use it in GitHub Desktop.
<?php
/**
* Plugin Name: Jetpack Subscriptions Widget AMP Workaround (and Ajax Enhancements)
* Description: Fix issue with form submission in AMP not including the name of clicked submit button. Also make use of Ajax to show the success/failure of the submission.
* Plugin URI: https://wordpress.org/support/topic/amp-jetpack-subscribe-button-stopped-working/
* Author Name: Weston Ruter
* Author URI: https://weston.ruter.net/
* Version: 1.0
* License: GPLv2 or later
*/
/*
* Ensure that \Jetpack_Subscriptions::widget_submit() will run at the template_redirect action.
* See https://github.com/Automattic/jetpack/blob/e3986c699471dbb1dab42bdeac2041b8c979514c/modules/subscriptions.php#L84
*/
if ( isset( $_SERVER['REQUEST_METHOD'] ) && 'POST' === $_SERVER['REQUEST_METHOD'] && isset( $_REQUEST['action'] ) && 'subscribe' === $_REQUEST['action'] ) {
$_REQUEST['jetpack_subscriptions_widget'] = true;
}
// -----------THE REST OF THIS PLUGIN IS OPTIONAL------------------
/*
* The following code is used to implement Ajax-based submission of the subscription form.
* Instead of the page reloading to display the success/failure of the subscription, the
* success/error response will be displayed at the top of the form.
* This should really be factored into the Jetpack plugin generally.
*/
add_action(
'jetpack_subscriptions_form_submission',
/**
* Intercept the redirect after the subscription form submission request to instead return with JSON response.
*
* Most of the code in this function comes from Jetpack_Subscriptions_Widget::render_widget_status_messages().
*
* @see \Jetpack_Subscriptions_Widget::render_widget_status_messages()
* @param string $result Result code.
*/
function( $result ) {
if ( ! function_exists( 'get_jetpack_blog_subscriptions_widget_classname' ) ) {
return;
}
global $wp_widget_factory;
if ( ! isset( $wp_widget_factory->widgets[ get_jetpack_blog_subscriptions_widget_classname() ] ) ) {
return;
}
// Determine the success message for the widget.
$success_message = '';
/**
* Subscriptions widget instance (object).
*
* @var Jetpack_Subscriptions_Widget $widget_object
*/
$widget_object = $wp_widget_factory->widgets[ get_jetpack_blog_subscriptions_widget_classname() ];
$widget_number = 0;
if ( isset( $_REQUEST['redirect_fragment'] ) ) {
$widget_number = intval( preg_replace( '/^.+?-(?=\d+$)/', '', $_REQUEST['redirect_fragment'] ) );
}
if ( $widget_number ) {
$instances = $widget_object->get_settings();
if ( isset( $instances[ $widget_number ]['success_message'] ) ) {
$success_message = $instances[ $widget_number ]['success_message'];
}
}
$error = null;
$success = null;
switch ( $result ) {
case 'invalid_email' :
$error = sprintf( '<p class="error">%s</p>', esc_html__( 'The email you entered was invalid. Please check and try again.', 'jetpack' ) );
break;
case 'opted_out' :
$error = sprintf(
'<p class="error">%s</p>',
sprintf(
__( 'The email address has opted out of subscription emails. <br /> You can manage your preferences at <a href="%1$s" title="%2$s" target="_blank">subscribe.wordpress.com</a>', 'jetpack' ),
'https://subscribe.wordpress.com/',
__( 'Manage your email preferences.', 'jetpack' )
)
);
break;
case 'already' :
$error = sprintf(
'<p class="error">%s</p>',
sprintf(
__( 'You have already subscribed to this site. Please check your inbox. <br /> You can manage your preferences at <a href="%1$s" title="%2$s" target="_blank">subscribe.wordpress.com</a>', 'jetpack' ),
'https://subscribe.wordpress.com/',
__( 'Manage your email preferences.', 'jetpack' )
)
);
break;
case 'success' :
$success = sprintf( '<p class="success">%s</p>', wpautop( str_replace( '[total-subscribers]', number_format_i18n( $widget_object::fetch_subscriber_count()['value'] ), $success_message ) ) );
break;
default :
$error = sprintf( '<p class="error">%s</p>', esc_html__( 'There was an error when subscribing. Please try again.', 'jetpack' ) );
break;
}
wp_send_json( compact( 'success', 'error' ), $success ? 200 : 400 );
},
PHP_INT_MAX
);
// Add sanitizer for injecting the success/error response containers to the subscription form.
add_filter(
'amp_content_sanitizers',
function ( $sanitizers ) {
class AMP_Jetpack_Subscriptions_Form_Response_Container_Injector extends AMP_Base_Sanitizer {
function sanitize() {
$xpath = new DOMXPath( $this->dom );
/**
* @var DOMElement $form
*/
foreach ( $xpath->query( '//form[ starts-with( @id, "subscribe-blog-blog_subscription" ) ]' ) as $form ) {
$form->insertBefore( $this->create_message_container( 'error' ), $form->firstChild );
$form->insertBefore( $this->create_message_container( 'success' ), $form->firstChild );
}
}
function create_message_container( $type ) {
$div = $this->dom->createElement( 'div' );
$template = $this->dom->createElement( 'template' );
$mustache = $this->dom->createTextNode( '{{{' . $type . '}}}' );
$div->setAttribute( 'submit-' . $type, '' );
$template->setAttribute( 'type', 'amp-mustache' );
$template->appendChild( $mustache );
$div->appendChild( $template );
return $div;
}
}
$sanitizers = array_merge(
array(
'AMP_Jetpack_Subscriptions_Form_Response_Container_Injector' => array(),
),
$sanitizers
);
return $sanitizers;
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment