Added Gravity Forms Addon

This commit is contained in:
Cooper Dalrymple
2026-06-05 17:44:26 -05:00
parent 7da66983a9
commit 15a89a140f
9 changed files with 210 additions and 32 deletions
+8 -20
View File
@@ -20,9 +20,6 @@ defined('ABSPATH') || exit;
abstract class Location {
use Singleton;
public const ERROR_EMPTY_TOKEN = 'empty_captcha_token';
public const ERROR_INVALID_CAPTCHA = 'invalid_captcha_result';
protected string $name;
protected function __construct(string $name) {
@@ -54,31 +51,22 @@ abstract class Location {
Widget::render();
}
public function process(WP_Error $errors):void {
if (!Settings::is_connected()) return;
$token = Widget::get_token();
if (empty($token)) {
$errors->add(self::ERROR_EMPTY_TOKEN, Plugin::__('<strong>Error:</strong> Please complete CAPTCHA verification.'));
return;
}
if (!API::verify($token)) {
$errors->add(self::ERROR_INVALID_CAPTCHA, Plugin::__('<strong>Error:</strong> Your answer was incorrect - please try again.'));
return;
}
public function process(WP_Error|null $errors = null):void {
API::process(Widget::get_token(), $errors);
}
protected function print_errors(WP_Error $errors):void {
if (!$errors->has_errors()) return;
ob_start();
echo '<ul>';
$messages = [];
foreach ($errors->get_error_codes() as $code) {
foreach ($errors->get_error_messages($code) as $message) {
echo '<li>' . wp_kses($message, ['strong']) . '</li>';
$messages[] = $message;
}
}
echo '</ul>';
ob_start();
echo '<ul><li>' . implode('</li><li>', $messages) . '</li></ul>';
wp_die(ob_get_clean());
}
+18
View File
@@ -10,12 +10,17 @@
namespace Ogre\Captcha;
use Ogre\Captcha as Plugin;
use Ogre\Captcha\Settings;
use WP_Error;
defined('ABSPATH') || exit;
final class API {
public const ERROR_EMPTY_TOKEN = 'empty_captcha_token';
public const ERROR_INVALID_CAPTCHA = 'invalid_captcha_result';
private static function transaction(string $url, array $data):array|string|bool {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POSTFIELDS, wp_json_encode($data));
@@ -52,4 +57,17 @@ final class API {
return is_bool($result) ? $result : false;
}
public static function process(string $token, WP_Error|null $errors = null): WP_Error {
if (is_null($errors)) $errors = new WP_Error();
if (!Settings::is_connected()) return $errors;
if (empty($token)) {
$errors->add(self::ERROR_EMPTY_TOKEN, Plugin::__('Please complete CAPTCHA verification.'));
} else if (!API::verify($token)) {
$errors->add(self::ERROR_INVALID_CAPTCHA, Plugin::__('Your answer was incorrect - please try again.'));
}
return $errors;
}
}
+10
View File
@@ -44,6 +44,16 @@ final class Settings {
return $data;
}
private static function set(string $key, $value = null):void {
$data = self::get();
if (is_null($value) && isset($data[$key])) {
unset($data[$key]);
} else {
$data[$key] = $value;
}
update_option(Plugin::get_id(), $data);
}
private static function is_checked(string $name, string $value):bool {
return in_array($value, (array) self::get($name));
}
+142
View File
@@ -0,0 +1,142 @@
<?php
/**
* @package ogre-captcha
* @author cleverogre
* @copyright 2026 CleverOgre
* @license GLP-3.0-or-later
* @version 1.1.0
* @since 1.1.0
*/
namespace Ogre\Captcha\GravityForms;
use Ogre\Singleton;
use Ogre\Captcha as Plugin;
use GFForms;
use GFAddOn;
use Ogre\Captcha\API;
use Ogre\Captcha\Settings;
use Ogre\Captcha\Widget;
defined('ABSPATH') || exit;
GFForms::include_addon_framework();
final class Addon extends GFAddOn {
use Singleton;
protected $_min_gravityforms_version = '2.6.3.2';
public static function get_instance(): Addon {
return self::instance();
}
public function pre_init() {
$this->_version = Plugin::get_version();
$this->_slug = Plugin::get_id();
$this->_path = sprintf(
'%1$s/%1$s.php',
Plugin::get_id()
);
$this->_full_path = Plugin::get_file();
$this->_title = sprintf(
Plugin::__('%s Add-On'),
Plugin::get_title()
);
$this->_short_title = Plugin::get_title();
}
public function init() {
add_filter('gform_submit_button', [$this, 'submit_button'], 10, 2);
add_filter('gform_validation', [$this, 'validation'], 10, 2);
}
public function get_menu_icon() {
return 'gform-icon--lock';
}
public function plugin_settings_fields() {
return [
[
'title' => esc_html(sprintf(
Plugin::__('%s Settings'),
Plugin::get_title()
)),
'description' => sprintf(
Plugin::__('Looking to configure your CAPTCHA connection? You can find the settings on <a href="%s">this page</a>.'),
esc_url(Settings::get_url())
),
'fields' => [
[
'label' => sprintf(
Plugin::esc_html__('Enable %s'),
Plugin::get_title()
),
'type' => 'checkbox',
'name' => 'enabled',
'choices' => [
[
'label' => Plugin::esc_html__('Enable CAPTCHA on all forms by default.'),
'name' => 'enabled',
]
]
]
]
]
];
}
public function form_settings_fields($form) {
return [
[
'title' => esc_html(sprintf(
Plugin::__('%s Settings'),
Plugin::get_title()
)),
'fields' => [
[
'type' => 'checkbox',
'name' => 'disabled',
'choices' => [
[
'label' => Plugin::esc_html__('Disable CAPTCHA for this form.'),
'name' => 'disabled',
]
]
]
]
]
];
}
public function is_enabled(array|null $form = null): bool {
$plugin_enabled = (bool) $this->get_plugin_setting('enabled');
if (is_null($form) || !$plugin_enabled) return $plugin_enabled;
$form_settings = $this->get_form_settings($form);
$form_disabled = (bool) rgar($form_settings, 'disabled');
return !$form_disabled;
}
public function submit_button(string $button_input, array $form): string {
if (!Settings::is_connected() || !$this->is_enabled($form)) return $button_input;
ob_start();
Widget::render();
return ob_get_clean() . $button_input;
}
public function validation(array $validation_result, string $context): array {
if ($context != 'form-submit') return $validation_result;
if (!Settings::is_connected() || !$this->is_enabled(rgar($validation_result, 'form'))) return $validation_result;
$errors = API::process(Widget::get_token());
if ($errors->has_errors()) {
$validation_result['is_valid'] = false;
}
// TODO: Mark as spam (optional)
return $validation_result;
}
}
+3 -2
View File
@@ -10,6 +10,7 @@
namespace Ogre\Captcha\Location;
use Ogre\Captcha\API;
use Override;
use Ogre\Captcha\Location;
use Ogre\Captcha\Settings;
@@ -42,8 +43,8 @@ final class LoginPage extends Location {
return array_merge(
$shake_error_codes,
[
self::ERROR_EMPTY_TOKEN,
self::ERROR_INVALID_CAPTCHA,
API::ERROR_EMPTY_TOKEN,
API::ERROR_INVALID_CAPTCHA,
]
);
}