Last active
March 20, 2019 05:29
-
-
Save westonruter/3b61ffcfbc1b528b1135ac7cc065eaa2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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