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
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://getcomposer.org/schema.json",
"name": "cleverogre/ogre-captcha",
"version": "1.0.1",
"version": "1.1.0",
"title": "Ogre CAPTCHA",
"description": "Protect your site with CAPTCHA",
"author": "CleverOgre",
Generated
+4 -4
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "1daff9d4452a2ff8f159fea23468a225",
"content-hash": "49f5e6f919f33ce6a3edc2992620a64a",
"packages": [
{
"name": "cleverogre/plugin-framework",
@@ -59,7 +59,7 @@
"source": {
"type": "git",
"url": "git@git.cleverogre.com:cleverogre/plugin-update-checker.git",
"reference": "010b7cf90b5df60d6d98256d48594ae423b951b7"
"reference": "b05c3dd4cf01f45544358671018dd5b5851cd079"
},
"require": {
"composer/installers": "~1.0",
@@ -69,7 +69,7 @@
"default-branch": true,
"type": "wordpress-plugin",
"extra": {
"installer-name": "update-plugin-checker"
"installer-name": "plugin-update-checker"
},
"license": [
"MIT"
@@ -90,7 +90,7 @@
"theme updates",
"wordpress"
],
"time": "2026-06-05T20:17:06+00:00"
"time": "2026-06-05T22:05:11+00:00"
},
{
"name": "cleverogre/updatepulse-updater",
+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,
]
);
}
+23 -4
View File
@@ -6,14 +6,14 @@
* @author cleverogre
* @copyright 2026 CleverOgre
* @license GLP-3.0-or-later
* @version 1.0.1
* @version 1.1.0
* @since 1.0.0
*
* @wordpress-plugin
* Plugin Name: Ogre CAPTCHA
* Plugin URI: https://git.cleverogre.com/cleverogre/ogre-captcha/
* Description: Protect your site with CAPTCHA
* Version: 1.0.1
* Version: 1.1.0
* Requires at least: 6.0
* Requires PHP: 8.2
* Author: CleverOgre
@@ -33,6 +33,9 @@
namespace Ogre;
use Ogre\Captcha\Settings;
use Ogre\Captcha\GravityForms\Addon;
use GFAddOn;
use Override;
defined('ABSPATH') || exit;
@@ -44,6 +47,10 @@ final class Captcha extends Plugin {
return is_plugin_active('woocommerce/woocommerce.php');
}
public static function is_gravityforms_active():bool {
return is_plugin_active('gravityforms/gravityforms.php');
}
protected function __construct() {
parent::__construct();
@@ -59,18 +66,22 @@ final class Captcha extends Plugin {
'inc/location/class-post-password-form.php',
'inc/location/class-registration-page.php',
]);
add_action('plugins_loaded', [$this, 'load_woocommerce'], 9, 0);
}
#[Override]
protected function enable():void {
parent::enable();
add_filter('plugin_action_links_' . self::get_basename(), [$this, 'action_links']);
add_action('plugins_loaded', [$this, 'load_woocommerce'], 2, 0);
add_action('gform_loaded', [$this, 'load_gravityforms'], 5, 0);
}
#[Override]
protected function disable():void {
parent::disable();
remove_filter('plugin_action_links_' . self::get_basename(), [$this, 'action_links']);
remove_action('plugins_loaded', [$this, 'load_woocommerce'], 2);
remove_action('gform_loaded', [$this, 'load_gravityforms'], 5);
}
public function action_links(array $links):array {
@@ -95,6 +106,14 @@ final class Captcha extends Plugin {
]);
}
public function load_gravityforms():void {
if (!self::is_gravityforms_active() || !method_exists('GFForms', 'include_addon_framework')) return;
require_once('inc/gravityforms/class-addon.php');
GFAddOn::register(Addon::class);
}
}
Captcha::instance();
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://www.schemastore.org/package.json",
"name": "cleverogre/ogre-captcha",
"version": "1.0.1",
"version": "1.1.0",
"title": "Ogre CAPTCHA",
"description": "Protect your site with CAPTCHA",
"author": "CleverOgre",