Added Gravity Forms Addon
This commit is contained in:
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user