Skip to content

Commit

Permalink
Adding hCaptcha to Jetpack admin.
Browse files Browse the repository at this point in the history
  • Loading branch information
kagg-design committed Oct 26, 2024
1 parent 57ac700 commit a7f1d27
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 45 deletions.
3 changes: 1 addition & 2 deletions .tests/php/integration/AAAMainTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
use HCaptcha\Divi\EmailOptin;
use HCaptcha\DownloadManager\DownloadManager;
use HCaptcha\FluentForm\Form;
use HCaptcha\Jetpack\JetpackForm;
use HCaptcha\Main;
use HCaptcha\ElementorPro\HCaptchaHandler;
use HCaptcha\Migrations\Migrations;
Expand Down Expand Up @@ -1505,7 +1504,7 @@ public function dp_test_load_modules(): array {
'Jetpack' => [
[ 'jetpack_status', 'contact' ],
'jetpack/jetpack.php',
JetpackForm::class,
\HCaptcha\Jetpack\Form::class,
],
'Kadence Form' => [
[ 'kadence_status', 'form' ],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
<?php
/**
* JetpackBaseTest class file.
* BaseTest class file.
*
* @package HCaptcha\Tests
*/

namespace HCaptcha\Tests\Integration\Jetpack;

use HCaptcha\Jetpack\JetpackForm;
use HCaptcha\Jetpack\Form;
use HCaptcha\Tests\Integration\HCaptchaWPTestCase;
use ReflectionException;
use tad\FunctionMocker\FunctionMocker;
use WP_Error;

/**
* Class JetpackBaseTest.
* Class BaseTest.
*
* @group jetpack
*/
class JetpackBaseTest extends HCaptchaWPTestCase {
class BaseTest extends HCaptchaWPTestCase {

/**
* Tear down test.
Expand All @@ -35,15 +35,15 @@ public function tearDown(): void {
* Test constructor and init_hooks.
*/
public function test_init_hooks(): void {
$subject = new JetpackForm();
$subject = new Form();

self::assertSame(
10,
has_filter( 'jetpack_contact_form_html', [ $subject, 'add_captcha' ] )
has_filter( 'jetpack_contact_form_html', [ $subject, 'add_hcaptcha' ] )
);
self::assertSame(
0,
has_filter( 'widget_text', [ $subject, 'add_captcha' ] )
has_filter( 'widget_text', [ $subject, 'add_hcaptcha' ] )
);

self::assertSame(
Expand All @@ -67,7 +67,7 @@ public function test_init_hooks(): void {
public function test_jetpack_verify(): void {
$this->prepare_hcaptcha_get_verify_message( 'hcaptcha_jetpack_nonce', 'hcaptcha_jetpack' );

$subject = new JetpackForm();
$subject = new Form();

self::assertFalse( $subject->verify() );
self::assertTrue( $subject->verify( true ) );
Expand All @@ -84,7 +84,7 @@ public function test_jetpack_verify_not_verified(): void {

$this->prepare_hcaptcha_get_verify_message( 'hcaptcha_jetpack_nonce', 'hcaptcha_jetpack', false );

$subject = new JetpackForm();
$subject = new Form();

self::assertEquals( $error, $subject->verify() );
self::assertNull( $this->get_protected_property( $subject, 'error_form_hash' ) );
Expand Down Expand Up @@ -113,7 +113,7 @@ public function test_error_message(): void {
],
];

$subject = new JetpackForm();
$subject = new Form();

self::assertSame( $hcaptcha_content, $subject->error_message( $hcaptcha_content ) );

Expand Down Expand Up @@ -163,7 +163,7 @@ static function ( $name ) {
CSS;
$expected = "<style>\n$expected\n</style>\n";

$subject = new JetpackForm();
$subject = new Form();

ob_start();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
<?php
/**
* JetpackFormTest class file.
* FormTest class file.
*
* @package HCaptcha\Tests
*/

namespace HCaptcha\Tests\Integration\Jetpack;

use HCaptcha\Jetpack\JetpackForm;
use HCaptcha\Jetpack\Form;
use HCaptcha\Tests\Integration\HCaptchaWPTestCase;

/**
* Class JetpackFormTest.
* Class FormTest.
*
* @group jetpack
*/
class JetpackFormTest extends HCaptchaWPTestCase {
class FormTest extends HCaptchaWPTestCase {

/**
* Test add_captcha().
Expand All @@ -26,9 +26,9 @@ class JetpackFormTest extends HCaptchaWPTestCase {
* @dataProvider dp_test_add_captcha
*/
public function test_add_captcha( string $content, string $expected ): void {
$subject = new JetpackForm();
$subject = new Form();

self::assertSame( $expected, $subject->add_captcha( $content ) );
self::assertSame( $expected, $subject->add_hcaptcha( $content ) );
}

/**
Expand Down
21 changes: 21 additions & 0 deletions assets/js/admin-jetpack.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* global HCaptchaJetpackObject */

wp.hooks.addFilter(
'hcaptcha.formSelector',
'hcaptcha',
( formSelector ) => {
return formSelector + ', div.jetpack-contact-form';
}
);

document.addEventListener( 'hCaptchaBeforeBindEvents', function() {
const buttons = [ ...document.querySelectorAll( '.wp-block .jetpack-contact-form .wp-block-jetpack-button' ) ];

buttons.map( ( button ) => {
const newElement = document.createElement( 'div' );
newElement.innerHTML = HCaptchaJetpackObject.hCaptcha;
button.parentNode.insertBefore( newElement, button );

return button;
} );
} );
1 change: 1 addition & 0 deletions src/js/hcaptcha/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ window.hCaptchaSubmit = () => {

window.hCaptchaOnLoad = () => {
function hCaptchaOnLoad() {
document.dispatchEvent( new CustomEvent( 'hCaptchaBeforeBindEvents' ) );
window.hCaptchaBindEvents();
document.dispatchEvent( new CustomEvent( 'hCaptchaLoaded' ) );
}
Expand Down
132 changes: 126 additions & 6 deletions src/php/Jetpack/JetpackBase.php → src/php/Jetpack/Base.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php
/**
* Jetpack class file.
* Base class file.
*
* @package hcaptcha-wp
*/
Expand All @@ -11,9 +11,9 @@
use WP_Error;

/**
* Class Jetpack
* Class Base
*/
abstract class JetpackBase {
abstract class Base {

/**
* Nonce action.
Expand All @@ -25,6 +25,16 @@ abstract class JetpackBase {
*/
protected const NAME = 'hcaptcha_jetpack_nonce';

/**
* Admin script handle.
*/
private const ADMIN_HANDLE = 'admin-jetpack';

/**
* Admin script object.
*/
private const OBJECT = 'HCaptchaJetpackObject';

/**
* Error message.
*
Expand Down Expand Up @@ -53,17 +63,19 @@ public function __construct() {
*/
private function init_hooks(): void {
// This filter works for a Jetpack classic and block form on a page or in a template.
add_filter( 'jetpack_contact_form_html', [ $this, 'add_captcha' ] );
add_filter( 'jetpack_contact_form_html', [ $this, 'add_hcaptcha' ] );

// This filter works for a Jetpack form in a classic widget.
add_filter( 'widget_text', [ $this, 'add_captcha' ], 0 );
add_filter( 'widget_text', [ $this, 'add_hcaptcha' ], 0 );

add_filter( 'widget_text', 'shortcode_unautop' );
add_filter( 'widget_text', 'do_shortcode' );

add_filter( 'jetpack_contact_form_is_spam', [ $this, 'verify' ], 100, 2 );

add_action( 'wp_head', [ $this, 'print_inline_styles' ] );
add_action( 'hcap_print_hcaptcha_scripts', [ $this, 'print_hcaptcha_scripts' ] );
add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] );
}

/**
Expand All @@ -73,7 +85,7 @@ private function init_hooks(): void {
*
* @return string
*/
abstract public function add_captcha( $content ): string;
abstract public function add_hcaptcha( $content ): string;

/**
* Verify hCaptcha answer from the Jetpack Contact Form.
Expand Down Expand Up @@ -135,6 +147,76 @@ public function error_message( $hcaptcha = '', array $atts = [] ) {
return $hcaptcha . $message;
}

/**
* Print hCaptcha script when editing a page with Jetpack form.
*
* @param bool|mixed $status Current print status.
*
* @return bool
*/
public function print_hcaptcha_scripts( $status ): bool {
$status = (bool) $status;

if ( ! function_exists( 'get_current_screen' ) ) {
// @codeCoverageIgnoreStart
return $status;
// @codeCoverageIgnoreEnd
}

$pagenow = $GLOBALS['pagenow'] ?? '';

if ( 'post.php' !== $pagenow ) {
return $status;
}

// phpcs:disable WordPress.Security.NonceVerification.Recommended
$post_id = isset( $_GET['post'] ) ? (int) $_GET['post'] : 0;
$action = isset( $_GET['action'] ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : '';
// phpcs:enable WordPress.Security.NonceVerification.Recommended

if ( ! $post_id || 'edit' !== $action ) {
return $status;
}

$post = get_post( $post_id );
$content = $post->post_content ?? '';

if ( false === strpos( $content, '<!-- wp:jetpack/contact-form -->' ) ) {
return $status;
}

return true;
}

/**
* Enqueue script in admin.
*
* @return void
*/
public function admin_enqueue_scripts(): void {
if ( ! $this->is_jetpack_post_page() ) {
return;
}

$min = hcap_min_suffix();

wp_enqueue_script(
self::ADMIN_HANDLE,
constant( 'HCAPTCHA_URL' ) . "/assets/js/admin-jetpack$min.js",
[ 'hcaptcha' ],
constant( 'HCAPTCHA_VERSION' ),
true
);

wp_localize_script(
self::ADMIN_HANDLE,
self::OBJECT,
[
'hCaptcha' => $this->get_hcaptcha( $this->get_args() ),
]
);
}

/**
* Print inline styles.
*
Expand All @@ -152,6 +234,24 @@ public function print_inline_styles(): void {
HCaptcha::css_display( $css );
}

/**
* Get hCaptcha arguments.
*
* @param string $hash Form hash.
*
* @return array
*/
protected function get_args( string $hash = '' ): array {
return [
'action' => self::ACTION,
'name' => self::NAME,
'id' => [
'source' => HCaptcha::get_class_source( __CLASS__ ),
'form_id' => 'contact' . $hash,
],
];
}

/**
* Get form hash.
*
Expand All @@ -165,6 +265,17 @@ protected function get_form_hash( string $form ): string {
: '';
}

/**
* Get hCaptcha.
*
* @param array $args The hCaptcha arguments.
*
* @return string
*/
protected function get_hcaptcha( array $args ): string {
return '<div class="grunion-field-wrap">' . HCaptcha::form( $args ) . '</div>';
}

/**
* Get form hash.
*
Expand All @@ -177,4 +288,13 @@ private function get_submitted_form_hash(): ?string {
: null;
// phpcs:enable WordPress.Security.NonceVerification.Missing
}

/**
* Check if the current page is a post page containing a Jetpack form.
*
* @return bool
*/
private function is_jetpack_post_page(): bool {
return true;
}
}
Loading

0 comments on commit a7f1d27

Please sign in to comment.