Skip to content

Instantly share code, notes, and snippets.

@westonruter
Last active February 20, 2022 11:29
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save westonruter/3501016b0d44af45d878067b1856e023 to your computer and use it in GitHub Desktop.
Save westonruter/3501016b0d44af45d878067b1856e023 to your computer and use it in GitHub Desktop.
Initial support for forms provided by Contact Form 7 when used with the official AMP plugin
<?php
/**
* Plugin Name: AMP Contact Form 7 Support
*
* @package AMP_Contact_Form_7
* @author Weston Ruter, Google
* @license GPL-2.0-or-later
* @copyright 2019 Google Inc.
*
* @wordpress-plugin
* Plugin Name: AMP Contact Form 7 Support
* Description: Ensure that success/error messages are displayed when submitting forms provided by Contact Form 7 on AMP pages generated by the <a href="https://wordpress.org/plugins/amp/">official AMP plugin</a>.
* Plugin URI: https://gist.github.com/westonruter/3501016b0d44af45d878067b1856e023
* Version: 0.3.0
* Author: Weston Ruter, Google
* Author URI: https://weston.ruter.net/
* License: GNU General Public License v2 (or later)
* License URI: http://www.gnu.org/licenses/gpl-2.0.html
* Gist Plugin URI: https://gist.github.com/westonruter/3501016b0d44af45d878067b1856e023
*/
namespace AMP_Contact_Form_7;
/**
* Determine whether the current page is AMP.
*
* @return bool Whether it is an AMP endpoint.
*/
function is_amp_endpoint() {
return function_exists( 'is_amp_endpoint' ) && \is_amp_endpoint();
}
/**
* Dequeue scripts on AMP responses.
*
* @see \wpcf7_do_enqueue_scripts()
*/
function dequeue_scripts_on_amp_responses() {
if ( is_amp_endpoint() ) {
wp_dequeue_script( 'contact-form-7' );
}
}
add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\dequeue_scripts_on_amp_responses', 20 );
/**
* Filter whether novalidate attribute is used on the form.
*
* @param bool $novalidate Use form novalidate.
* @return bool Whether to use novalidate.
*/
function filter_form_novalidate( $novalidate ) {
if ( is_amp_endpoint() ) {
$novalidate = false;
}
return $novalidate;
}
add_filter( 'wpcf7_form_novalidate', __NAMESPACE__ . '\filter_form_novalidate' );
/**
* Replace aria-required="true" with required on AMP pages, since client-side jQuery validation will not work in AMP.
*
* @param string $elements Form elements.
* @return string Filtered form elements.
*/
function filter_form_elements_for_required( $elements ) {
if ( is_amp_endpoint() ) {
$elements = str_replace( 'aria-required="true"', 'required', $elements );
}
return $elements;
}
add_filter( 'wpcf7_form_elements', __NAMESPACE__ . '\filter_form_elements_for_required' );
/**
* Handle submission.
*
* @param \WPCF7_ContactForm $contact_form Contact Form.
* @param array $result Result.
*/
function handle_submit( $contact_form, $result ) {
if ( ! is_amp_endpoint() ) {
return;
}
unset( $contact_form );
if ( ! function_exists( 'wp_is_json_request' ) ) {
_doing_it_wrong( __FUNCTION__, 'Please update to WordPress 5.0', '0.1' );
return;
}
if ( wp_is_json_request() ) {
$success = 'mail_sent' === $result['status'];
$response = array(
'message' => $result['message'],
);
// @todo Add full support for verify-xhr.
if ( ! empty( $result['invalid_fields'] ) ) {
foreach ( $result['invalid_fields'] as $name => $invalid_field ) {
$response['verifyErrors'][] = array(
'name' => $name,
'message' => $invalid_field['reason'],
);
}
}
wp_send_json(
$response,
$success ? 200 : 400
);
}
}
add_action( 'wpcf7_submit', __NAMESPACE__ . '\handle_submit', 11, 2 );
/**
* Add RECAPTCHA support.
*/
function maybe_add_recaptcha_support() {
if ( ! class_exists( '\WPCF7_RECAPTCHA' ) ) {
return;
}
$service = \WPCF7_RECAPTCHA::get_instance();
if ( ! $service->is_active() ) {
return;
}
add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\handle_recaptcha_scripts_on_amp_responses', 20 );
add_filter( 'wpcf7_form_hidden_fields', __NAMESPACE__ . '\filter_recaptcha_hidden_fields', 200, 1 );
add_filter( 'wpcf7_form_elements', __NAMESPACE__ . '\filter_form_elements_for_recaptcha' );
}
add_action( 'wpcf7_init', __NAMESPACE__ . '\maybe_add_recaptcha_support' );
/**
* Dequeue RECAPTCHA scripts on AMP pages and add amp-recaptcha-input script.
*
* @see \wpcf7_do_enqueue_scripts()
*/
function handle_recaptcha_scripts_on_amp_responses() {
if ( is_amp_endpoint() ) {
wp_dequeue_script( 'google-recaptcha' );
wp_dequeue_script( 'wpcf7-recaptcha' );
wp_enqueue_script( 'amp-recaptcha-input', 'https://cdn.ampproject.org/v0/amp-recaptcha-input-0.1.js' );
}
}
/**
* Remove hidden field for recaptcha on AMP pages.
*
* @param array $fields Form hidden fields.
* @return array Filtered form hidden fields.
*/
function filter_recaptcha_hidden_fields( $fields ) {
if ( is_amp_endpoint() ) {
unset( $fields['_wpcf7_recaptcha_response'] );
}
return $fields;
}
/**
* Add amp-recaptcha-input on AMP pages.
*
* @param string $elements Form elements.
* @return string Filtered form elements.
*/
function filter_form_elements_for_recaptcha( $elements ) {
if ( ! is_amp_endpoint() ) {
return $elements;
}
$actions = apply_filters( 'wpcf7_recaptcha_actions', array(
'homepage' => 'homepage',
'contactform' => 'contactform',
) );
if ( ! isset( $actions['contactform'] ) ) {
return $elements;
}
$service = \WPCF7_RECAPTCHA::get_instance();
return sprintf(
'<amp-recaptcha-input layout="nodisplay" name="_wpcf7_recaptcha_response" data-sitekey="%s" data-action="%s"></amp-recaptcha-input>',
esc_attr( $service->get_sitekey() ),
esc_attr( $actions['contactform'] )
) . $elements;
}
@Invader444
Copy link

Invader444 commented Jan 11, 2021

Also, for anyone coming here, be aware that after creating a v3 recaptcha site token, you need to go back into its settings to enable its use via AMP! That option is not on the initial setup page and is currently (at the time of writing) disabled by default. Tripped me up at first :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment