initial
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/*
|
||||
Plugin Name: Gravity Forms Akismet Add-On
|
||||
Plugin URI: https://gravityforms.com
|
||||
Description: Enhance Gravity Forms with advanced spam protection, powered by Akismet.
|
||||
Version: 1.1.0
|
||||
Requires at least: 6.5
|
||||
Requires PHP: 7.4
|
||||
Author: Gravity Forms
|
||||
Author URI: https://gravityforms.com
|
||||
License: GPL-3.0+
|
||||
Text Domain: gravityformsakismet
|
||||
Domain Path: /languages
|
||||
|
||||
------------------------------------------------------------------------
|
||||
Copyright 2020 - 2025 Rocketgenius Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see http://www.gnu.org/licenses.
|
||||
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || die();
|
||||
|
||||
// Defines the current version of the Gravity Forms Akismet Add-On.
|
||||
define( 'GF_AKISMET_VERSION', '1.1.0' );
|
||||
|
||||
// Defines the minimum version of Gravity Forms required to run Gravity Forms Akismet Add-On.
|
||||
define( 'GF_AKISMET_MIN_GF_VERSION', '2.8' );
|
||||
|
||||
// After Gravity Forms is loaded, load the Add-On.
|
||||
add_action( 'gform_loaded', array( 'GF_Akismet_Bootstrap', 'load_addon' ), 5 );
|
||||
|
||||
use Gravity_Forms\Gravity_Forms_Akismet\GF_Akismet;
|
||||
|
||||
/**
|
||||
* Loads the Gravity Forms Akismet Add-On.
|
||||
*
|
||||
* Includes the main class and registers it with GFAddOn.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
class GF_Akismet_Bootstrap {
|
||||
|
||||
/**
|
||||
* Loads the required files.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static function load_addon() {
|
||||
|
||||
// Requires the class file.
|
||||
require_once plugin_dir_path( __FILE__ ) . '/class-gf-akismet.php';
|
||||
|
||||
// Registers the class name with GFAddOn.
|
||||
GFAddOn::register( 'Gravity_Forms\Gravity_Forms_Akismet\GF_Akismet' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of the GF_Akismet class.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @return GF_Akismet|bool An instance of the GF_Akismet class
|
||||
*/
|
||||
function gf_akismet() {
|
||||
return class_exists( 'Gravity_Forms\Gravity_Forms_Akismet\GF_Akismet' ) ? GF_Akismet::get_instance() : false;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
### 1.1.0 | 2025-07-28
|
||||
- Updated to communicate directly with the Akismet API. No longer requires the Akismet plugin to be active and configured.
|
||||
- Fixed three PHP 8.2 creation of dynamic property deprecation notices that occur on form submission.
|
||||
|
||||
### 1.0 | 2021-07-07
|
||||
- All new!
|
||||
@@ -0,0 +1,926 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms_Akismet;
|
||||
|
||||
defined( 'ABSPATH' ) || die();
|
||||
|
||||
use GFForms;
|
||||
use GFAddOn;
|
||||
use GFCommon;
|
||||
use GFAPI;
|
||||
use GFFormsModel;
|
||||
use Akismet;
|
||||
use Gravity_Forms\Gravity_Forms_Akismet\Settings;
|
||||
|
||||
// Include the Gravity Forms Add-On Framework.
|
||||
GFForms::include_addon_framework();
|
||||
|
||||
/**
|
||||
* Gravity Forms Akismet Add-On.
|
||||
*
|
||||
* @since 1.0
|
||||
* @package GravityForms
|
||||
* @author Gravity Forms
|
||||
* @copyright Copyright (c) 2020-2021, Gravity Forms
|
||||
*/
|
||||
class GF_Akismet extends GFAddOn {
|
||||
|
||||
/**
|
||||
* Contains an instance of this class, if available.
|
||||
*
|
||||
* @since 1.0
|
||||
* @var GF_Akismet $_instance If available, contains an instance of this class
|
||||
*/
|
||||
private static $_instance = null;
|
||||
|
||||
/**
|
||||
* Defines the version of the Gravity Forms Akismet Add-On.
|
||||
*
|
||||
* @since 1.0
|
||||
* @var string $_version Contains the version.
|
||||
*/
|
||||
protected $_version = GF_AKISMET_VERSION;
|
||||
|
||||
/**
|
||||
* Defines the minimum Gravity Forms version required.
|
||||
*
|
||||
* @since 1.0
|
||||
* @var string $_min_gravityforms_version The minimum version required.
|
||||
*/
|
||||
protected $_min_gravityforms_version = GF_AKISMET_MIN_GF_VERSION;
|
||||
|
||||
/**
|
||||
* Defines the plugin slug.
|
||||
*
|
||||
* @since 1.0
|
||||
* @var string $_slug The slug used for this plugin.
|
||||
*/
|
||||
protected $_slug = 'gravityformsakismet';
|
||||
|
||||
/**
|
||||
* Defines the main plugin file.
|
||||
*
|
||||
* @since 1.0
|
||||
* @var string $_path The path to the main plugin file, relative to the plugins folder.
|
||||
*/
|
||||
protected $_path = 'gravityformsakismet/akismet.php';
|
||||
|
||||
/**
|
||||
* Defines the full path to this class file.
|
||||
*
|
||||
* @since 1.0
|
||||
* @var string $_full_path The full path.
|
||||
*/
|
||||
protected $_full_path = __FILE__;
|
||||
|
||||
/**
|
||||
* Defines the URL where this add-on can be found.
|
||||
*
|
||||
* @since 1.0
|
||||
* @var string The URL of the Add-On.
|
||||
*/
|
||||
protected $_url = 'https://gravityforms.com';
|
||||
|
||||
/**
|
||||
* Defines the title of this add-on.
|
||||
*
|
||||
* @since 1.0
|
||||
* @var string $_title The title of the add-on.
|
||||
*/
|
||||
protected $_title = 'Gravity Forms Akismet Add-On';
|
||||
|
||||
/**
|
||||
* Defines the short title of the add-on.
|
||||
*
|
||||
* @since 1.0
|
||||
* @var string $_short_title The short title.
|
||||
*/
|
||||
protected $_short_title = 'Akismet';
|
||||
|
||||
/**
|
||||
* Defines if Add-On should use Gravity Forms servers for update data.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access protected
|
||||
* @var bool
|
||||
*/
|
||||
protected $_enable_rg_autoupgrade = true;
|
||||
|
||||
/**
|
||||
* Defines the capabilities needed for the Gravity Forms Akismet Add-On
|
||||
*
|
||||
* @since 1.0
|
||||
* @access protected
|
||||
* @var array $_capabilities The capabilities needed for the Add-On
|
||||
*/
|
||||
protected $_capabilities = array(
|
||||
'gravityforms_akismet',
|
||||
'gravityforms_akismet_uninstall',
|
||||
);
|
||||
|
||||
/**
|
||||
* Defines the capability needed to access the Add-On settings page.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access protected
|
||||
* @var string $_capabilities_settings_page The capability needed to access the Add-On settings page.
|
||||
*/
|
||||
protected $_capabilities_settings_page = 'gravityforms_akismet';
|
||||
|
||||
/**
|
||||
* Defines the capability needed to access the Add-On form settings page.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access protected
|
||||
* @var string $_capabilities_form_settings The capability needed to access the Add-On form settings page.
|
||||
*/
|
||||
protected $_capabilities_form_settings = 'gravityforms_akismet';
|
||||
|
||||
/**
|
||||
* Defines the capability needed to uninstall the Add-On.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access protected
|
||||
* @var string $_capabilities_uninstall The capability needed to uninstall the Add-On.
|
||||
*/
|
||||
protected $_capabilities_uninstall = 'gravityforms_akismet_uninstall';
|
||||
|
||||
/**
|
||||
* Instance of the object responsible for mapping Gravity Forms fields to the Akismet array.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var Akismet_Fields_Filter
|
||||
*/
|
||||
private $akismet_fields_filter;
|
||||
|
||||
/**
|
||||
* Wrapper class for form settings.
|
||||
*
|
||||
* @since 1.0
|
||||
* @var Settings\Form_Settings
|
||||
*/
|
||||
private $form_settings;
|
||||
|
||||
/**
|
||||
* Instance of the Akismet API wrapper.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @var null|API
|
||||
*/
|
||||
private $api;
|
||||
|
||||
/**
|
||||
* Returns an instance of this class, and stores it in the $_instance property.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @return GF_Akismet $_instance An instance of the GF_Akismet class.
|
||||
*/
|
||||
public static function get_instance() {
|
||||
|
||||
if ( self::$_instance == null ) {
|
||||
self::$_instance = new GF_Akismet();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-initialize add-on services.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public function pre_init() {
|
||||
require_once __DIR__ . '/includes/class-akismet-fields-filter.php';
|
||||
require_once __DIR__ . '/includes/settings/class-form-settings.php';
|
||||
|
||||
$this->akismet_fields_filter = new Akismet_Fields_Filter( $this );
|
||||
$this->form_settings = new Settings\Form_Settings( $this );
|
||||
|
||||
$this->add_disable_core_filter();
|
||||
add_filter( 'gform_plugin_settings_fields', array( $this, 'remove_core_settings_field' ) );
|
||||
add_filter( 'gform_entry_is_spam', array( $this, 'is_entry_spam' ), 80, 3 );
|
||||
add_filter( 'gform_update_status', array( $this, 'entry_status_change' ), 1, 3 );
|
||||
add_filter( 'gform_form_tag', array( $this, 'add_akismet_inputs' ), 50, 2 );
|
||||
|
||||
parent::pre_init();
|
||||
}
|
||||
|
||||
// # FORM DISPLAY --------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Callback for gform_form_tag; adds the Akismet honeypot inputs to the form.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param string $form_tag The opening HTML form tag.
|
||||
* @param array $form The form currently being prepared for display.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function add_akismet_inputs( $form_tag, $form ) {
|
||||
remove_filter( 'gform_get_form_filter', array( 'Akismet', 'inject_custom_form_fields' ) );
|
||||
|
||||
if ( empty( $form_tag ) || ! $this->is_enabled_form( $form ) ) {
|
||||
return $form_tag;
|
||||
}
|
||||
|
||||
static $field_count = 0;
|
||||
++ $field_count;
|
||||
|
||||
$prefix = 'ak_';
|
||||
$value = mt_rand( 0, 250 );
|
||||
$script = GFCommon::get_inline_script_tag( sprintf( 'document.getElementById( "ak_js_%d" ).setAttribute( "value", ( new Date() ).getTime() );', $field_count ), false );
|
||||
|
||||
$form_tag .= <<<EOD
|
||||
<div style="display: none !important;" class="akismet-fields-container gf_invisible" data-prefix="{$prefix}">
|
||||
<label>Δ<textarea name="{$prefix}hp_textarea" cols="45" rows="8" maxlength="100"></textarea></label>
|
||||
<input type="hidden" id="{$prefix}js_{$field_count}" name="{$prefix}js" value="{$value}" />
|
||||
{$script}
|
||||
</div>
|
||||
EOD;
|
||||
|
||||
return $form_tag;
|
||||
}
|
||||
|
||||
// # ENTRY PROCESSING ----------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Callback for gform_entry_is_spam; performs the Akimset spam check.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param bool $is_spam Indicates if the submission has been flagged as spam.
|
||||
* @param array $form The form currently being processed.
|
||||
* @param array $entry The entry currently being processed.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_entry_spam( $is_spam, $form, $entry ) {
|
||||
remove_filter( 'gform_entry_is_spam', array( 'GFCommon', 'entry_is_spam_akismet' ), 90 );
|
||||
|
||||
$entry_id = (int) rgar( $entry, 'id' );
|
||||
if ( $is_spam ) {
|
||||
$this->log_debug( __METHOD__ . sprintf( '(): Entry #%d has already been marked as spam by another anti-spam solution.', $entry_id ) );
|
||||
|
||||
return $is_spam;
|
||||
}
|
||||
|
||||
if ( ! $this->is_enabled_form( $form ) ) {
|
||||
$this->log_debug( __METHOD__ . sprintf( '(): Not evaluating entry #%d; integration disabled for form #%d.', $entry_id, rgar( $form, 'id' ) ) );
|
||||
|
||||
return $is_spam;
|
||||
}
|
||||
|
||||
$fields = $this->get_akismet_fields( $form, $entry, 'submit' );
|
||||
if ( empty( $fields ) ) {
|
||||
$this->log_debug( __METHOD__ . sprintf( '(): No values to evaluate for entry #%d.', $entry_id ) );
|
||||
|
||||
return $is_spam;
|
||||
}
|
||||
|
||||
$this->initalize_api();
|
||||
$response = $this->api->spam_check( $fields );
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
$this->log_debug( __METHOD__ . sprintf( '(): Spam check failed for entry #%d; ', $entry_id ) . $response->get_error_message() );
|
||||
|
||||
return false;
|
||||
} elseif ( $response['body'] === 'true' ) {
|
||||
$this->log_debug( __METHOD__ . sprintf( '(): Entry #%d IS spam; ', $entry_id ) . print_r( $response, true ) );
|
||||
GFCommon::set_spam_filter( rgar( $form, 'id' ), $this->get_short_title(), '' );
|
||||
|
||||
return true;
|
||||
} elseif ( $response['body'] === 'false' ) {
|
||||
$this->log_debug( __METHOD__ . sprintf( '(): Entry #%d is NOT spam; ', $entry_id ) . print_r( $response, true ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->log_debug( __METHOD__ . sprintf( '(): Spam check failed for entry #%d; ', $entry_id ) . print_r( $response, true ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for gform_update_status; notifies Akismet that the entry has been manually marked as spam or ham.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param int $entry_id The ID of the entry the status changed for.
|
||||
* @param string $new_value The value value of the status property.
|
||||
* @param string $previous_value The previous value of the status property.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function entry_status_change( $entry_id, $new_value, $previous_value ) {
|
||||
$mark_as_spam = ( $new_value === 'spam' && $previous_value === 'active' );
|
||||
$mark_as_ham = ( $new_value === 'active' && $previous_value === 'spam' );
|
||||
|
||||
if ( ! $mark_as_spam && ! $mark_as_ham ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$entry = GFAPI::get_entry( $entry_id );
|
||||
if ( is_wp_error( $entry ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$form = GFAPI::get_form( rgar( $entry, 'form_id' ) );
|
||||
if ( ! $form ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! $this->is_enabled_form( $form ) ) {
|
||||
$this->log_debug( __METHOD__ . sprintf( '(): Not processing entry #%d; integration disabled for form #%d.', $entry_id, rgar( $form, 'id' ) ) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$action = $mark_as_spam ? 'spam' : 'ham';
|
||||
$fields = $this->get_akismet_fields( $form, $entry, $action );
|
||||
if ( empty( $fields ) ) {
|
||||
$this->log_debug( __METHOD__ . sprintf( '(): No values to evaluate for entry #%d.', $entry_id ) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->initalize_api();
|
||||
|
||||
if ( $mark_as_spam ) {
|
||||
$note = esc_html__( 'Akismet notified that the entry was marked as spam.', 'gravityformsakismet' );
|
||||
$response = $this->api->submit_spam( $fields );
|
||||
} else {
|
||||
$note = esc_html__( 'Akismet notified that the entry was marked as not spam.', 'gravityformsakismet' );
|
||||
$response = $this->api->submit_ham( $fields );
|
||||
}
|
||||
|
||||
$this->add_note( $entry_id, $note );
|
||||
$this->log_debug( __METHOD__ . sprintf( '(): Akismet notified that entry #%d was marked as %s; ', $entry_id, $action ) . print_r( $response, true ) );
|
||||
}
|
||||
|
||||
// # FORM SETTINGS -------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Define form settings fields.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param array $form The current form.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function form_settings_fields( $form ) {
|
||||
return $this->form_settings->get_fields( $form );
|
||||
}
|
||||
|
||||
/**
|
||||
* The settings page icon.
|
||||
*
|
||||
* @since 1.0
|
||||
* @return string
|
||||
*/
|
||||
public function get_menu_icon() {
|
||||
return 'gform-icon--akismet';
|
||||
}
|
||||
|
||||
// # PLUGIN SETTINGS -----------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the fields to be displayed on the Forms > Settings > Akismet page.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function plugin_settings_fields() {
|
||||
static $fields;
|
||||
|
||||
if ( ! $fields ) {
|
||||
require_once __DIR__ . '/includes/settings/class-plugin-settings.php';
|
||||
$fields = ( new Settings\Plugin_Settings( $this ) )->get_fields();
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Feedback callback for the API key field.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param string $api_key The value of the API key field.
|
||||
*
|
||||
* @return bool|null
|
||||
*/
|
||||
public function verify_api_key( $api_key ) {
|
||||
if ( empty( $api_key ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->initalize_api();
|
||||
$response = $this->api->verify_key( $api_key );
|
||||
if ( is_wp_error( $response ) ) {
|
||||
$this->log_error( __METHOD__ . '(): Unable to verify key; ' . $response->get_error_message() );
|
||||
|
||||
return false;
|
||||
} elseif ( $response['body'] === 'valid' ) {
|
||||
$this->log_debug( __METHOD__ . '(): Key is valid; ' . print_r( $response, true ) );
|
||||
|
||||
return true;
|
||||
} elseif ( $response['body'] === 'invalid' ) {
|
||||
$this->log_debug( __METHOD__ . '(): Key is invalid; ' . print_r( $response, true ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->log_debug( __METHOD__ . '(): Unable to verify key; ' . print_r( $response, true ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// # DISABLE OLD GF CORE -------------------------------------------------------------------------------------------
|
||||
// GF 2.9.11.2+: GFCommon::has_akismet() disables the core integration when the add-on is active and includes initalize_api().
|
||||
|
||||
/**
|
||||
* Helper to add the filter that aims to disable the core integration via the rg_gforms_enable_akismet option.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add_disable_core_filter() {
|
||||
if ( ! $this->is_akismet_plugin_active() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_filter( 'pre_option_rg_gforms_enable_akismet', array( $this, 'disable_core_option' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to remove the callback that filters the rg_gforms_enable_akismet option.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function remove_disable_core_filter() {
|
||||
remove_filter( 'pre_option_rg_gforms_enable_akismet', array( $this, 'disable_core_option' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the pre_option_rg_gforms_enable_akismet filter.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function disable_core_option() {
|
||||
if ( $this->is_akismet_plugin_active() ) {
|
||||
add_filter( 'gform_akismet_enabled', array( $this, 'disable_core_akismet_enabled' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
return '0';
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the core version of the gform_akismet_enabled filter.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param bool $enabled Indicates if the Akismet integration is enabled.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function disable_core_akismet_enabled( $enabled ) {
|
||||
remove_filter( 'gform_akismet_enabled', array( $this, 'disable_core_akismet_enabled' ), PHP_INT_MAX );
|
||||
|
||||
return $this->is_akismet_plugin_active() ? '0' : $enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for gform_plugin_settings_fields; removes the core toggle.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param array $fields The fields to be displayed on the Forms > Settings page.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function remove_core_settings_field( $fields ) {
|
||||
unset( $fields['akismet'] );
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
// # UPGRADE -------------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Populates the add-on settings.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param string $previous_version Empty or the previously installed version number.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function upgrade( $previous_version ) {
|
||||
if ( ! empty( $this->get_plugin_settings() ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->update_plugin_settings( array(
|
||||
'enabled' => $this->is_enabled_core(),
|
||||
'api_key' => $this->get_akismet_plugin_api_key(),
|
||||
) );
|
||||
}
|
||||
|
||||
// # HELPERS -------------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Initializes the API.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initalize_api() {
|
||||
if ( ! empty( $this->api ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/includes/class-api.php';
|
||||
$this->api = new API( $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the Akismet integration is enabled for the site on the Forms > Settings > Akismet page.
|
||||
*
|
||||
* @since 1.0
|
||||
* @since 1.1 Updated to use the add-on setting.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_enabled_global() {
|
||||
static $enabled = null;
|
||||
|
||||
if ( is_null( $enabled ) ) {
|
||||
$enabled = $this->get_plugin_setting( 'enabled' );
|
||||
}
|
||||
|
||||
return $enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the Akismet integration is enabled for the supplied form.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param array $form The current form.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_enabled_form( $form ) {
|
||||
static $status = array();
|
||||
$form_id = (int) rgar( $form, 'id', 0 );
|
||||
|
||||
if ( ! isset( $status[ $form_id ] ) ) {
|
||||
$enabled = $this->is_enabled_global();
|
||||
|
||||
if ( $enabled ) {
|
||||
$settings = $this->get_form_settings( $form );
|
||||
$enabled = empty( $settings ) || rgar( $settings, 'enabled' ) === '1';
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the Akismet integration to be enabled or disabled.
|
||||
*
|
||||
* @since 1.1 Copied over from GFCommon::akismet_enabled().
|
||||
*
|
||||
* @param bool $enabled Indicates if the Akismet integration is enabled.
|
||||
* @param int $form_id The ID of the form being processed.
|
||||
*/
|
||||
$status[ $form_id ] = (bool) gf_apply_filters( array( 'gform_akismet_enabled', $form_id ), $enabled, $form_id );
|
||||
}
|
||||
|
||||
return $status[ $form_id ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the core integration is enabled.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_enabled_core() {
|
||||
$this->remove_disable_core_filter();
|
||||
$enabled = get_option( 'rg_gforms_enable_akismet' );
|
||||
$this->add_disable_core_filter();
|
||||
|
||||
return $enabled === false || $enabled === '1';
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the Akismet plugin is active.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_akismet_plugin_active() {
|
||||
return class_exists( 'Akismet' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get the API key from the Akismet plugin.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_akismet_plugin_api_key() {
|
||||
if ( $this->is_akismet_plugin_active() ) {
|
||||
return (string) Akismet::get_api_key();
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data to be sent to Akismet.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param array $form The form which created the entry.
|
||||
* @param array $entry The entry being processed.
|
||||
* @param string $action The action triggering the Akismet request: submit, spam, or ham.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_akismet_fields( $form, $entry, $action ) {
|
||||
$form_id = (int) rgar( $form, 'id' );
|
||||
$this->log_debug( sprintf( '%s(): action: %s; form: %d; entry: %d.', __METHOD__, $action, $form_id, rgar( $entry, 'id' ) ) );
|
||||
|
||||
$settings = $this->get_form_settings( $form );
|
||||
|
||||
if ( empty( $settings ) ) {
|
||||
$this->log_debug( __METHOD__ . '(): Settings not configured; using defaults.' );
|
||||
$settings = $this->form_settings->get_default_settings( $form, $entry );
|
||||
}
|
||||
|
||||
$this->log_debug( __METHOD__ . '(): Settings => ' . print_r( $settings, true ) );
|
||||
|
||||
$fields = $this->akismet_fields_filter->get_fields( $settings, $form, $entry, $action );
|
||||
|
||||
$this->log_debug( __METHOD__ . '(): Values to be sent to Akismet => ' . print_r( $fields, true ) );
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
// # DEPRECATED ----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Callback method to the `minimum_requirements` override.
|
||||
*
|
||||
* This method ensures we have all of the minimum requirements needed run the add-on.
|
||||
*
|
||||
* @since 1.0
|
||||
* @depecated 1.1
|
||||
* @remove-in 1.2
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function check_minimum_requirements() {
|
||||
_deprecated_function( __METHOD__, '1.1' );
|
||||
|
||||
$meets_requirements = true;
|
||||
$errors = array();
|
||||
|
||||
if ( ! GFCommon::has_akismet() ) {
|
||||
$meets_requirements = false;
|
||||
$errors[] = esc_html__( 'The Akismet plugin is either inactive or not installed.', 'gravityformsakismet' );
|
||||
}
|
||||
|
||||
if ( ! $this->is_enabled_global() ) {
|
||||
$meets_requirements = false;
|
||||
$errors[] = esc_html__( 'To use this add-on, please visit the Forms -> Settings page to enable Akismet integration', 'gravityformsakismet' );
|
||||
}
|
||||
|
||||
return $meets_requirements
|
||||
? array( 'meets_requirements' => true )
|
||||
: array(
|
||||
'meets_requirements' => false,
|
||||
'errors' => $errors,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables Akismet based on the form settings.
|
||||
*
|
||||
* @since 1.0
|
||||
* @depecated 1.1
|
||||
* @remove-in 1.2
|
||||
*
|
||||
* @param bool $enabled Indicates if Akismet is enabled.
|
||||
* @param int $form_id The ID of the form being processed.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function filter_akismet_enabled( $enabled, $form_id ) {
|
||||
_deprecated_function( __METHOD__, '1.1' );
|
||||
|
||||
if ( ! $enabled ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! Akismet::get_api_key() ) {
|
||||
$this->log_debug( __METHOD__ . '(): Aborting; Akismet is not configured.' );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$form = GFAPI::get_form( $form_id );
|
||||
|
||||
if ( ! $form ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->is_enabled_form( $form );
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the default Akismet field mappings with the new mappings based on the form specific configuration.
|
||||
*
|
||||
* @since 1.0
|
||||
* @depecated 1.1
|
||||
* @remove-in 1.2
|
||||
*
|
||||
* @param array $akismet_fields The data passed from Akismet to Gravity Forms.
|
||||
* @param array $form The form which created the entry.
|
||||
* @param array $entry The form which created the entry.
|
||||
* @param string $action The action triggering the Akismet request: submit, spam, or ham.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function filter_akismet_fields( $akismet_fields, $form, $entry, $action ) {
|
||||
_deprecated_function( __METHOD__, '1.1' );
|
||||
|
||||
return $this->get_akismet_fields( $form, $entry, $action );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles any necessary processes after receiving a response from Akismet.
|
||||
*
|
||||
* @since 1.0
|
||||
* @depecated 1.1
|
||||
* @remove-in 1.2
|
||||
*
|
||||
* @param array|WP_Error $response HTTP response or WP_Error object.
|
||||
* @param string $context Context under which the hook is fired.
|
||||
* @param string $class HTTP transport used.
|
||||
* @param array $args HTTP request arguments.
|
||||
* @param string $url The request URL.
|
||||
*/
|
||||
public function handle_akismet_response( $response, $context, $class, $args, $url ) {
|
||||
_deprecated_function( __METHOD__, '1.1' );
|
||||
|
||||
if ( ! $this->is_akismet_response( $response, $args, $url ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->log_debug( __METHOD__ . '(): request body => ' . $args['body'] );
|
||||
|
||||
$response_body = wp_remote_retrieve_body( $response );
|
||||
|
||||
$this->log_debug(
|
||||
__METHOD__ . '(): response => '
|
||||
. print_r(
|
||||
array(
|
||||
wp_remote_retrieve_headers( $response ),
|
||||
$response_body,
|
||||
),
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
$this->maybe_mark_as_spam( $response_body );
|
||||
|
||||
remove_action( 'http_api_debug', array( $this, 'handle_akismet_response' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the current response being processed is for Akismet.
|
||||
*
|
||||
* @since 1.0
|
||||
* @depecated 1.1
|
||||
* @remove-in 1.2
|
||||
*
|
||||
* @param array|WP_Error $response The API response.
|
||||
* @param array $args HTTP request arguments.
|
||||
* @param string $url The request URL.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_akismet_response( $response, $args, $url ) {
|
||||
_deprecated_function( __METHOD__, '1.1' );
|
||||
|
||||
return (
|
||||
rgar( $args, 'method' ) === 'POST'
|
||||
&& stripos( $url, 'rest.akismet.com' ) !== false
|
||||
&& ! is_wp_error( $response )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the created_by merge tag.
|
||||
*
|
||||
* @since 1.0
|
||||
* @depecated 1.1
|
||||
* @remove-in 1.2
|
||||
*
|
||||
* @param string $text The current text in which merge tags are being replaced.
|
||||
* @param array $form The current form object.
|
||||
* @param array $entry The current entry object.
|
||||
* @param bool $url_encode Whether or not to encode any URLs found in the replaced value.
|
||||
* @param bool $esc_html Whether or not to encode HTML found in the replaced value.
|
||||
* @param bool $nl2br Whether or not to convert newlines to break tags.
|
||||
* @param string $format The format requested for the location the merge is being used. Possible values: html, text or url.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function filter_pre_replace_merge_tags( $text, $form, $entry, $url_encode, $esc_html, $nl2br, $format ) {
|
||||
_deprecated_function( __METHOD__, '1.1' );
|
||||
|
||||
if ( strpos( $text, '{' ) === false ) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
preg_match_all( '/{created_by:(.*?)}/', $text, $matches, PREG_SET_ORDER );
|
||||
|
||||
if ( empty( $matches ) ) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
$entry_creator = ! empty( $entry['created_by'] ) ? get_userdata( $entry['created_by'] ) : false;
|
||||
foreach ( $matches as $match ) {
|
||||
$full_tag = $match[0];
|
||||
$property = $match[1];
|
||||
|
||||
if ( $entry_creator && $property !== 'user_pass' ) {
|
||||
$value = $entry_creator->get( $property );
|
||||
$value = $url_encode ? urlencode( $value ) : $value;
|
||||
} else {
|
||||
$value = '';
|
||||
}
|
||||
|
||||
$text = str_replace( $full_tag, $value, $text );
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds additional actions for an entry if it needs to be marked as spam.
|
||||
*
|
||||
* @since 1.0
|
||||
* @depecated 1.1
|
||||
* @remove-in 1.2
|
||||
*
|
||||
* @param array $response_body HTTP response body.
|
||||
*/
|
||||
private function maybe_mark_as_spam( $response_body ) {
|
||||
_deprecated_function( __METHOD__, '1.1' );
|
||||
|
||||
if ( $response_body !== 'true' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_action( 'gform_entry_created', array( $this, 'add_marked_as_spam_note_to_entry' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a note to an entry at the time that it is marked as spam.
|
||||
*
|
||||
* @since 1.0
|
||||
* @depecated 1.1
|
||||
* @remove-in 1.2
|
||||
*
|
||||
* @param array $entry The entry data.
|
||||
*/
|
||||
public function add_marked_as_spam_note_to_entry( $entry ) {
|
||||
_deprecated_function( __METHOD__, '1.1' );
|
||||
|
||||
if ( rgar( $entry, 'status' ) !== 'spam' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->log_debug( __METHOD__ . '(): marking entry as spam.' );
|
||||
|
||||
$this->add_note( rgar( $entry, 'id' ), esc_html__( 'This entry has been marked as spam.', 'gravityformsakismet' ), 'success' );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,572 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms_Akismet;
|
||||
|
||||
use GFCommon;
|
||||
use GFFormsModel;
|
||||
use GF_Field;
|
||||
|
||||
/**
|
||||
* Class Akismet_Fields_Filter
|
||||
*
|
||||
* This class handles all of the logic for looking up and mapping Gravity Forms fields to their Akismet equivalents.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @see GF_Akismet::filter_akismet_fields()
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms_Akismet
|
||||
*/
|
||||
class Akismet_Fields_Filter {
|
||||
/**
|
||||
* Instance of the GF_Akismet add-on.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var GF_Akismet
|
||||
*/
|
||||
private $addon;
|
||||
|
||||
/**
|
||||
* Add-on settings.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* Array of required Akismet values that are missing from the form settings.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $missing_keys = array();
|
||||
|
||||
/**
|
||||
* IP address of the submission.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $ip;
|
||||
|
||||
/**
|
||||
* Fields prepared for Akismet.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $prepared_fields = array();
|
||||
|
||||
/**
|
||||
* The form being processed.
|
||||
*
|
||||
* @since 1.1 Previously a dynamic property.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $form;
|
||||
|
||||
/**
|
||||
* The entry being processed.
|
||||
*
|
||||
* @since 1.1 Previously a dynamic property.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $entry;
|
||||
|
||||
/**
|
||||
* The Akismet action.
|
||||
*
|
||||
* @since 1.1 Previously a dynamic property.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $action;
|
||||
|
||||
/**
|
||||
* Akismet_Fields_Filter constructor.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param GF_Akismet $addon Instance of the GF_Akismet add-on.
|
||||
*/
|
||||
public function __construct( $addon ) {
|
||||
$this->addon = $addon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hydrate this object with its provided data.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param array $settings The add-on settings.
|
||||
* @param array $form Gravity Forms form data.
|
||||
* @param array $entry Gravity Forms entry data.
|
||||
* @param string $action Akismet action.
|
||||
*/
|
||||
private function hydrate( $settings, $form, $entry, $action ) {
|
||||
$this->settings = $settings;
|
||||
$this->form = $form;
|
||||
$this->entry = $entry;
|
||||
$this->action = $action;
|
||||
$this->set_ip_address();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the IP address for this submission.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
private function set_ip_address() {
|
||||
$ip = $this->action === 'submit' && rgars( $this->form, 'personalData/preventIP' ) ? GFFormsModel::get_ip() : rgar( $this->entry, 'ip' );
|
||||
|
||||
if ( ! empty( $ip ) ) {
|
||||
$ip = preg_replace( '/[^0-9A-F:.]/i', '', $ip );
|
||||
}
|
||||
|
||||
$this->ip = $ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the array of data in the structure required by Akismet.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param array $settings The add-on settings.
|
||||
* @param array $form Gravity Forms form data.
|
||||
* @param array $entry Gravity Forms entry data.
|
||||
* @param string $action Akismet action.
|
||||
* @param array $akismet_fields Fields from the Akismet add-on. Set to optional because we don't actually use them.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_fields( $settings, $form, $entry, $action, $akismet_fields = array() ) {
|
||||
$this->hydrate( $settings, $form, $entry, $action );
|
||||
$fields = array_merge( $this->initialize_akismet_fields(), $this->initialize_additional_fields() );
|
||||
$form_id = (int) rgar( $form, 'id' );
|
||||
|
||||
if ( $this->addon->is_akismet_plugin_active() ) {
|
||||
// Removing the Akismet plugin callback because we already captured the same data.
|
||||
remove_filter( 'gform_akismet_fields', array( 'Akismet', 'prepare_custom_form_values' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the data to be sent to Akismet to be overridden.
|
||||
*
|
||||
* @since 1.1 Copied over from GFCommon::get_akismet_fields().
|
||||
*
|
||||
* @param array $fields The data to be sent to Akismet.
|
||||
* @param array $form The form which created the entry.
|
||||
* @param array $entry The entry being processed.
|
||||
* @param string $action The action triggering the Akismet request: submit, spam, or ham.
|
||||
*/
|
||||
$fields = gf_apply_filters( array( 'gform_akismet_fields', $form_id ), $fields, $form, $entry, $action );
|
||||
|
||||
if ( $this->is_fields_valid( $fields ) ) {
|
||||
$this->prepared_fields = $fields;
|
||||
}
|
||||
|
||||
return $this->prepared_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that at least one of the mapped fields or the fallbacks has a value for Akismet to evaluate.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param array $fields The data to be sent to Akismet.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_fields_valid( $fields ) {
|
||||
if ( empty( $fields ) || ! is_array( $fields ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ( $fields as $key => $value ) {
|
||||
if ( $key === 'comment_type' || ( ! str_starts_with( $key, 'comment_' ) && ! str_starts_with( $key, 'contact_form_field_' ) ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! rgblank( $value ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes additional data Akismet needs to make the most accurate analysis.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function initialize_additional_fields() {
|
||||
$fields = array(
|
||||
'comment_author_IP' => $this->ip,
|
||||
'user_ip' => $this->ip,
|
||||
'permalink' => rgar( $this->entry, 'source_url' ),
|
||||
'user_agent' => rgar( $this->entry, 'user_agent' ),
|
||||
'referrer' => $this->action === 'submit' ? rgar( $_SERVER, 'HTTP_REFERER' ) : '',
|
||||
'blog' => get_option( 'home' ),
|
||||
'blog_lang' => get_locale(),
|
||||
'blog_charset' => get_option( 'blog_charset' ),
|
||||
);
|
||||
|
||||
if ( $this->is_akismet_test_mode_enabled() || stripos( $fields['permalink'], 'gf_page=preview&id=' . rgar( $this->form, 'id' ) ) !== false ) {
|
||||
// Prevent test submissions training the Akismet filters.
|
||||
$fields['is_test'] = 'true';
|
||||
} elseif ( ! empty( $this->entry['created_by'] ) ) {
|
||||
// Akismet will return false for admins.
|
||||
$fields['user_role'] = $this->get_user_roles( $this->entry['created_by'] );
|
||||
}
|
||||
|
||||
if ( $this->action !== 'submit' ) {
|
||||
$fields['comment_date_gmt'] = rgar( $this->entry, 'date_created' );
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
$ak_inputs = array(
|
||||
'ak_hp_textarea',
|
||||
'ak_js',
|
||||
);
|
||||
|
||||
foreach ( $ak_inputs as $ak_input ) {
|
||||
$fields[ 'POST_' . $ak_input ] = rgpost( $ak_input );
|
||||
}
|
||||
|
||||
foreach ( $_SERVER as $key => $value ) {
|
||||
if ( ! is_string( $value ) || preg_match( '/^HTTP_COOKIE/', $key ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( preg_match( '/^(HTTP_|REMOTE_ADDR|REQUEST_URI|DOCUMENT_URI)/', $key ) ) {
|
||||
$fields["$key"] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes Akismet data for processing based on values from the from settings.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function initialize_akismet_fields() {
|
||||
$mapped_entry_data = $this->get_mapped_field_entry_data();
|
||||
$akismet_fields = $this->normalize_entry_data( $mapped_entry_data );
|
||||
|
||||
$this->set_missing_keys( $akismet_fields );
|
||||
|
||||
return $this->missing_keys
|
||||
? $this->populate_missing_fields_with_fallbacks( $this->form, $this->entry, $akismet_fields )
|
||||
: $akismet_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entry data mapped to the form settings.
|
||||
*
|
||||
* Iterates through the form settings to apply values from field data or merge tags, respectively.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_mapped_field_entry_data() {
|
||||
$akismet_fields = array(
|
||||
'comment_type' => 'gravity_form',
|
||||
);
|
||||
|
||||
foreach ( $this->get_form_settings_values() as $key => $value ) {
|
||||
$akismet_fields[ $key ] = $this->get_mapped_form_settings_value_from_entry( $value );
|
||||
}
|
||||
|
||||
return $akismet_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a value saved in the form settings into the actual value from the submitted form data.
|
||||
*
|
||||
* This method parses the field maps and text values from the form settings page in order to convert them
|
||||
* into their actual values from the form submission. Form settings values might be individual field IDs,
|
||||
* merge tags, or other field map types.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param string $form_settings_value The value saved to the form settings.
|
||||
*
|
||||
* @return array|mixed|string|null
|
||||
*/
|
||||
private function get_mapped_form_settings_value_from_entry( $form_settings_value ) {
|
||||
// Form setting is a merge tag.
|
||||
if ( 1 === GFCommon::has_merge_tag( $form_settings_value ) ) {
|
||||
return trim( GFCommon::replace_variables( $form_settings_value, $this->form, $this->entry, false, false, false, 'text' ) );
|
||||
}
|
||||
|
||||
// Form setting is either a GF_Field or something like an entry property.
|
||||
return $this->addon->get_field_value( $this->form, $this->entry, $form_settings_value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all of the values saved in the form settings.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_form_settings_values() {
|
||||
return array_filter(
|
||||
$this->settings,
|
||||
function( $key ) {
|
||||
return $key !== 'enabled';
|
||||
},
|
||||
ARRAY_FILTER_USE_KEY
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the raw field data into the Akismet structure.
|
||||
*
|
||||
* This method uses the data from the form settings fields and maps the first and last name values to the comment
|
||||
* author, if necessary.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param array $akismet_fields The Akismet field data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function normalize_entry_data( $akismet_fields ) {
|
||||
if (
|
||||
! empty( $akismet_fields['comment_author'] )
|
||||
|| ! isset( $akismet_fields['comment_author_first_name'], $akismet_fields['comment_author_last_name'] )
|
||||
) {
|
||||
return $akismet_fields;
|
||||
}
|
||||
|
||||
$normalized_fields = array_merge(
|
||||
$akismet_fields,
|
||||
array(
|
||||
'comment_author' => trim( "{$akismet_fields['comment_author_first_name']} {$akismet_fields['comment_author_last_name']}" ),
|
||||
)
|
||||
);
|
||||
|
||||
unset( $normalized_fields['comment_author_first_name'] );
|
||||
unset( $normalized_fields['comment_author_last_name'] );
|
||||
|
||||
return $normalized_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set missing keys on this object.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param array $akismet_fields Processed Akismet field data.
|
||||
*/
|
||||
private function set_missing_keys( $akismet_fields ) {
|
||||
$this->missing_keys = array_filter(
|
||||
array(
|
||||
'author' => empty( $akismet_fields['comment_author'] ),
|
||||
'email' => empty( $akismet_fields['comment_author_email'] ),
|
||||
'website' => empty( $akismet_fields['comment_author_url'] ),
|
||||
'content' => empty( $akismet_fields['comment_content'] ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the Akismet data is missing required fields and populates it with data from another matching field.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param array $form The form data.
|
||||
* @param array $entry The entry data.
|
||||
* @param array $akismet_fields The Akismet field data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function populate_missing_fields_with_fallbacks( $form, $entry, $akismet_fields ) {
|
||||
$gf_akismet_fields = $akismet_fields;
|
||||
|
||||
$process_types = $this->get_fallback_types_to_process();
|
||||
|
||||
if ( empty( $process_types ) ) {
|
||||
return $gf_akismet_fields;
|
||||
}
|
||||
|
||||
/** @var GF_Field $field */
|
||||
foreach ( $form['fields'] as $field ) {
|
||||
if ( empty( $this->missing_keys ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
$field_type = $field->get_input_type();
|
||||
|
||||
if ( $field->is_administrative() || ! in_array( $field_type, $process_types ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value = $field->get_value_export( $entry );
|
||||
if ( empty( $value ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isset( $this->missing_keys['author'] ) && $field_type === 'name' ) {
|
||||
$this->addon->log_debug( sprintf( '%s(): comment_author is empty; using value from field #%d.', __METHOD__, $field->id ) );
|
||||
$gf_akismet_fields['comment_author'] = $value;
|
||||
unset( $this->missing_keys['author'] );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isset( $this->missing_keys['email'] ) && $field_type === 'email' ) {
|
||||
$this->addon->log_debug( sprintf( '%s(): comment_author_email is empty; using value from field #%d.', __METHOD__, $field->id ) );
|
||||
$gf_akismet_fields['comment_author_email'] = $value;
|
||||
unset( $this->missing_keys['email'] );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isset( $this->missing_keys['website'] ) && $field_type === 'website' ) {
|
||||
$this->addon->log_debug( sprintf( '%s(): comment_author_url is empty; using value from field #%d.', __METHOD__, $field->id ) );
|
||||
$gf_akismet_fields['comment_author_url'] = $value;
|
||||
unset( $this->missing_keys['website'] );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! isset( $this->missing_keys['content'] ) || in_array( $value, $gf_akismet_fields ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$key = $this->get_key( $field );
|
||||
|
||||
$gf_akismet_fields[ $key ] = $value;
|
||||
}
|
||||
|
||||
return $gf_akismet_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a key from a field's ID and label.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param GF_Field $field The field object.
|
||||
*
|
||||
* @return string $key
|
||||
*/
|
||||
private function get_key( $field ) {
|
||||
$key = sprintf(
|
||||
'contact_form_field_%d_%s',
|
||||
$field->id,
|
||||
// Normalize the label into a slug. See https://github.com/Automattic/jetpack/blob/43fee1286315992b343dd91601d5afad6c0f0d0f/modules/contact-form/grunion-contact-form.php#L2588.
|
||||
trim( // Strip all leading/trailing dashes.
|
||||
preg_replace( // Normalize everything to a-z0-9_-.
|
||||
'/[^a-z0-9_]+/',
|
||||
'-',
|
||||
strtolower( GFFormsModel::get_label( $field, 0, false, false ) )
|
||||
),
|
||||
'-'
|
||||
)
|
||||
);
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines which field types are needed for fallback data to send to Akismet.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_fallback_types_to_process() {
|
||||
if ( rgar( $this->missing_keys, 'content' ) ) {
|
||||
return array(
|
||||
'address',
|
||||
'email',
|
||||
'hidden',
|
||||
'list',
|
||||
'name',
|
||||
'number',
|
||||
'phone',
|
||||
'post_content',
|
||||
'post_excerpt',
|
||||
'post_tags',
|
||||
'post_title',
|
||||
'text',
|
||||
'textarea',
|
||||
'website',
|
||||
);
|
||||
}
|
||||
|
||||
$process_types = array();
|
||||
|
||||
if ( rgar( $this->missing_keys, 'author' ) ) {
|
||||
$process_types[] = 'name';
|
||||
}
|
||||
|
||||
if ( rgar( $this->missing_keys, 'email' ) ) {
|
||||
$process_types[] = 'email';
|
||||
}
|
||||
|
||||
if ( rgar( $this->missing_keys, 'website' ) ) {
|
||||
$process_types[] = 'website';
|
||||
}
|
||||
|
||||
return $process_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if Akismet test mode is enabled.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_akismet_test_mode_enabled() {
|
||||
return defined( 'AKISMET_TEST_MODE' ) && AKISMET_TEST_MODE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a comma separated string of roles assigned to the user that created the entry.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param null|int|string $user_id Null or the ID of the user that created the entry.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_user_roles( $user_id ) {
|
||||
// Entry created by GFFormsModel::create_lead() uses string NULL when the $current_user global is empty.
|
||||
if ( empty( $user_id ) || $user_id === 'NULL' ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$user = get_userdata( $user_id );
|
||||
if ( empty( $user ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$roles = (array) $user->get( 'roles' );
|
||||
|
||||
if ( is_multisite() && is_super_admin( $user_id ) ) {
|
||||
$roles[] = 'super_admin';
|
||||
}
|
||||
|
||||
return implode( ',', $roles );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms_Akismet;
|
||||
|
||||
use WP_Error;
|
||||
|
||||
/**
|
||||
* Interacts with the Akismet REST API.
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
class API {
|
||||
|
||||
/**
|
||||
* The base Akismet API URL.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @var string $api_url
|
||||
*/
|
||||
protected $api_url = 'https://rest.akismet.com/1.1/';
|
||||
|
||||
/**
|
||||
* The API key.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @var null|GF_Akismet $add_on The current instance of the add-on.
|
||||
*/
|
||||
protected $add_on;
|
||||
|
||||
/**
|
||||
* Initializes an instance of this class.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param null|GF_Akismet $add_on The current instance of the add-on.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $add_on = null ) {
|
||||
$this->add_on = $add_on instanceof GF_Akismet ? $add_on : gf_akismet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the API request.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param string $path Request path.
|
||||
* @param array $args The query arguments or data for the request body.
|
||||
* @param string $method Request method. Defaults to POST.
|
||||
* @param int $expected_code The expected response code.
|
||||
*
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
private function make_request( $path, $args = array() ) {
|
||||
$request_url = $this->api_url . $path;
|
||||
|
||||
if ( empty( $args['api_key'] ) ) {
|
||||
$args['api_key'] = $this->add_on->get_plugin_setting( 'api_key' );
|
||||
}
|
||||
|
||||
if ( empty( $args['blog'] ) ) {
|
||||
$args['blog'] = home_url();
|
||||
}
|
||||
|
||||
$request_args = array(
|
||||
'method' => 'POST',
|
||||
'headers' => array(
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
),
|
||||
'user-agent' => sprintf( 'WordPress/%s | Gravity Forms Akismet Add-On/%s', rgar( $GLOBALS, 'wp_version' ), $this->add_on->get_version() ),
|
||||
'body' => http_build_query( $args ),
|
||||
);
|
||||
|
||||
$response = wp_remote_request( $request_url, $request_args );
|
||||
|
||||
return $this->get_simplified_response( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* If the request was successful, returns a simpler array containing just the response headers and body.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param array|WP_Error $response The request response.
|
||||
*
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
private function get_simplified_response( $response ) {
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
return array(
|
||||
'headers' => wp_remote_retrieve_headers( $response ),
|
||||
'body' => wp_remote_retrieve_body( $response ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contacts Akismet to verify the given API key is valid.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param string $api_key The API key.
|
||||
*
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
public function verify_key( $api_key ) {
|
||||
return $this->make_request( 'verify-key', array( 'api_key' => $api_key ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the given data to Akismet for analysis.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param array $data The data to be sent to Akismet.
|
||||
*
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
public function spam_check( $data ) {
|
||||
return $this->make_request( 'comment-check', $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the given data to Akismet, reporting it as spam.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param array $data The data to be sent to Akismet.
|
||||
*
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
public function submit_spam( $data ) {
|
||||
return $this->make_request( 'submit-spam', $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the given data to Akismet, reporting it as ham (not spam).
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param array $data The data to be sent to Akismet.
|
||||
*
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
public function submit_ham( $data ) {
|
||||
return $this->make_request( 'submit-ham', $data );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
<?php
|
||||
/**
|
||||
* Object responsible for organizing and constructing the form settings page.
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms_Akismet\Settings
|
||||
*/
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms_Akismet\Settings;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms_Akismet\GF_Akismet;
|
||||
use GFAPI;
|
||||
use GFFormsModel;
|
||||
|
||||
/**
|
||||
* Class Form_Settings
|
||||
*
|
||||
* @since 1.0
|
||||
* @package Gravity_Forms\Gravity_Forms_Akismet\Settings
|
||||
*/
|
||||
class Form_Settings {
|
||||
/**
|
||||
* Add-on instance.
|
||||
*
|
||||
* @var GF_Akismet
|
||||
*/
|
||||
private $addon;
|
||||
|
||||
/**
|
||||
* Plugin_Settings constructor.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param GF_Akismet $addon GF_Akismet instance.
|
||||
*/
|
||||
public function __construct( $addon ) {
|
||||
$this->addon = $addon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the form settings fields.
|
||||
*
|
||||
* @since 1.0
|
||||
* @see GF_Akismet::form_settings_fields()
|
||||
*
|
||||
* @param array $form The form data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_fields( $form ) {
|
||||
return array(
|
||||
array(
|
||||
'title' => esc_html__( 'Akismet Settings', 'gravityformsakismet' ),
|
||||
'fields' => array(
|
||||
$this->get_akismet_enabled_field(),
|
||||
array(
|
||||
'name' => 'comment_author_first_name',
|
||||
'label' => esc_html__( 'First Name', 'gravityformsakismet' ),
|
||||
'type' => 'field_select',
|
||||
'args' => array(
|
||||
'input_types' => array( 'name', 'text', 'hidden' ),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => 'comment_author_last_name',
|
||||
'label' => esc_html__( 'Last Name', 'gravityformsakismet' ),
|
||||
'type' => 'field_select',
|
||||
'args' => array(
|
||||
'input_types' => array( 'name', 'text', 'hidden' ),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => 'comment_author_email',
|
||||
'label' => esc_html__( 'Email', 'gravityformsakismet' ),
|
||||
'type' => 'field_select',
|
||||
'args' => array(
|
||||
'input_types' => array( 'email', 'text', 'hidden' ),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => 'comment_author_url',
|
||||
'label' => esc_html__( 'Website', 'gravityformsakismet' ),
|
||||
'type' => 'field_select',
|
||||
'args' => array(
|
||||
'input_types' => array( 'website', 'text', 'hidden' ),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => 'contact_form_subject',
|
||||
'label' => esc_html__( 'Subject', 'gravityformsakismet' ),
|
||||
'type' => 'text',
|
||||
'class' => 'medium merge-tag-support mt-position-right mt-hide_all_fields',
|
||||
'default_value' => '{form_title}',
|
||||
),
|
||||
array(
|
||||
'name' => 'comment_content',
|
||||
'label' => esc_html__( 'Content', 'gravityformsakismet' ),
|
||||
'type' => 'textarea',
|
||||
'class' => 'medium merge-tag-support mt-position-right',
|
||||
'default_value' => $this->get_default_merge_tag( $form, 'comment_content' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the field for controlling whether or not Gravity Forms Akismet is enabled for the given form.
|
||||
*
|
||||
* Newer versions of Gravity Forms use a toggle for this control, while earlier versions use a checkbox.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_akismet_enabled_field() {
|
||||
$field_name = 'enabled';
|
||||
$enabled_description = esc_html__( "Enable to protect this form's entries from spam using Akismet", 'gravityformsakismet' );
|
||||
|
||||
if ( ! $this->addon->is_gravityforms_supported( '2.5' ) ) {
|
||||
return array(
|
||||
'label' => esc_html__( 'Akismet enabled', 'gravityformsakismet' ),
|
||||
'description' => $enabled_description,
|
||||
'type' => 'checkbox',
|
||||
'name' => $field_name,
|
||||
'choices' => array(
|
||||
array(
|
||||
'label' => esc_html__( 'Enabled', 'gravityformsakismet' ),
|
||||
'name' => $field_name,
|
||||
'default_value' => '1',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return array(
|
||||
'label' => $enabled_description,
|
||||
'type' => 'toggle',
|
||||
'name' => $field_name,
|
||||
'default_value' => '1',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the defaults for the form settings fields.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param array $form The form data.
|
||||
* @param array $entry The entry data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_default_settings( $form, $entry ) {
|
||||
return array(
|
||||
'comment_author' => $this->get_default_merge_tag( $form, 'comment_author', $entry ),
|
||||
'comment_author_email' => $this->get_default_merge_tag( $form, 'comment_author_email', $entry ),
|
||||
'comment_author_url' => $this->get_default_merge_tag( $form, 'comment_author_url', $entry ),
|
||||
'contact_form_subject' => '{form_title}',
|
||||
'comment_content' => '', // Can be empty when using the contact_form_field_ keys.
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the merge tag to be used as the setting default value.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param array $form The current form.
|
||||
* @param string $name The field name.
|
||||
* @param null|array $entry Null when preparing the form settings or the entry currently being processed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_default_merge_tag( $form, $name, $entry = null ) {
|
||||
if ( $entry && empty( $entry['created_by'] ) ) {
|
||||
// Entry processing will loop through the fields so we don't need to do it here.
|
||||
return '';
|
||||
}
|
||||
|
||||
$mapping = rgar( $this->default_mappings(), $name );
|
||||
|
||||
// Using the created_by merge tag for forms where the user is logged in.
|
||||
if ( $entry || rgar( $form, 'requireLogin' ) ) {
|
||||
return $mapping['merge_tag'];
|
||||
}
|
||||
|
||||
$fields = GFAPI::get_fields_by_type( $form, $mapping['field_type'], true );
|
||||
|
||||
if ( empty( $fields ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( $name === 'comment_author' ) {
|
||||
$first_input_id = $fields[0]->id . '.3';
|
||||
$last_input_id = $fields[0]->id . '.6';
|
||||
|
||||
return sprintf( '{%s:%s} {%s:%s}', GFFormsModel::get_label( $fields[0], $first_input_id ), $first_input_id, GFFormsModel::get_label( $fields[0], $last_input_id ), $last_input_id );
|
||||
}
|
||||
|
||||
return sprintf( '{%s:%d}', GFFormsModel::get_label( $fields[0] ), $fields[0]->id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default mappings configuration for the Akismet settings.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function default_mappings() {
|
||||
return array(
|
||||
'comment_author' => array(
|
||||
'field_type' => array( 'name' ),
|
||||
'merge_tag' => '{created_by:first_name} {created_by:last_name}',
|
||||
),
|
||||
'comment_author_email' => array(
|
||||
'field_type' => array( 'email' ),
|
||||
'merge_tag' => '{created_by:user_email}',
|
||||
),
|
||||
'comment_author_url' => array(
|
||||
'field_type' => array( 'website' ),
|
||||
'merge_tag' => '{created_by:user_url}',
|
||||
),
|
||||
'comment_content' => array(
|
||||
'field_type' => array( 'paragraph', 'post_content' ),
|
||||
'merge_tag' => '',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms_Akismet\Settings;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms_Akismet\GF_Akismet;
|
||||
|
||||
/**
|
||||
* Defines the fields for the Forms > Settings > Akismet page.
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
class Plugin_Settings {
|
||||
|
||||
/**
|
||||
* The current instance of the add-on.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @var null|GF_Akismet
|
||||
*/
|
||||
private $add_on;
|
||||
|
||||
/**
|
||||
* Plugin_Settings constructor.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param GF_Akismet $add_on The current instance of the add-on.
|
||||
*/
|
||||
public function __construct( $add_on = null ) {
|
||||
$this->add_on = $add_on instanceof GF_Akismet ? $add_on : gf_akismet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fields to be displayed on the Forms > Settings > Akismet page.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function get_fields() {
|
||||
return array(
|
||||
array(
|
||||
'title' => esc_html__( 'Akismet Settings', 'gravityformsakismet' ),
|
||||
'description' => sprintf(
|
||||
'<p>%1$s <a href="https://akismet.com/pricing/" target="_blank" >%2$s<span class="screen-reader-text">%3$s</span> <span class="gform-icon gform-icon--external-link"></span></a>.</p>',
|
||||
esc_html__( "Protect your form entries from spam using Akismet. Don't have an Akismet account?", 'gravityformsakismet' ),
|
||||
esc_html__( 'Sign up here', 'gravityformsakismet' ),
|
||||
esc_html__( '(opens in a new tab)', 'gravityformsakismet' )
|
||||
),
|
||||
'fields' => array(
|
||||
array(
|
||||
'name' => 'enabled',
|
||||
'type' => 'toggle',
|
||||
'toggle_label' => esc_html__( 'Enable Akismet Integration', 'gravityformsakismet' ),
|
||||
'default_value' => true,
|
||||
'save_callback' => function ( $field, $value ) {
|
||||
// Keeping the legacy core setting in sync in case the add-on is deactivated.
|
||||
$this->add_on->remove_disable_core_filter();
|
||||
update_option( 'rg_gforms_enable_akismet', (bool) $value );
|
||||
$this->add_on->add_disable_core_filter();
|
||||
|
||||
return $value;
|
||||
},
|
||||
),
|
||||
array(
|
||||
'name' => 'api_key',
|
||||
'label' => esc_html__( 'API Key', 'gravityformsakismet' ),
|
||||
'type' => 'text',
|
||||
'default_value' => $this->add_on->get_akismet_plugin_api_key(),
|
||||
'required' => true,
|
||||
'description' => sprintf(
|
||||
'<p><a href="https://akismet.com/account/" target="_blank" >%1$s<span class="screen-reader-text">%2$s</span> <span class="gform-icon gform-icon--external-link"></span></a></p>',
|
||||
esc_html__( 'Click here to find your Akismet API Key', 'gravityformsakismet' ),
|
||||
esc_html__( '(opens in a new tab)', 'gravityformsakismet' )
|
||||
),
|
||||
'dependency' => array(
|
||||
'live' => true,
|
||||
'fields' => array(
|
||||
array(
|
||||
'field' => 'enabled',
|
||||
),
|
||||
),
|
||||
),
|
||||
'feedback_callback' => array( $this->add_on, 'verify_api_key' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
# Copyright (C) 2025 Gravity Forms
|
||||
# This file is distributed under the GPL-3.0+.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Gravity Forms Akismet Add-On 1.1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://gravityforms.com/support\n"
|
||||
"Last-Translator: Gravity Forms <support@gravityforms.com>\n"
|
||||
"Language-Team: Gravity Forms <support@gravityforms.com>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"POT-Creation-Date: 2025-07-28T13:58:59+00:00\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"X-Generator: WP-CLI 2.12.0\n"
|
||||
"X-Domain: gravityformsakismet\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
msgid "Gravity Forms Akismet Add-On"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin
|
||||
#. Author URI of the plugin
|
||||
msgid "https://gravityforms.com"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin
|
||||
msgid "Enhance Gravity Forms with advanced spam protection, powered by Akismet."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "Gravity Forms"
|
||||
msgstr ""
|
||||
|
||||
#: class-gf-akismet.php:354
|
||||
msgid "Akismet notified that the entry was marked as spam."
|
||||
msgstr ""
|
||||
|
||||
#: class-gf-akismet.php:357
|
||||
msgid "Akismet notified that the entry was marked as not spam."
|
||||
msgstr ""
|
||||
|
||||
#: class-gf-akismet.php:705
|
||||
msgid "The Akismet plugin is either inactive or not installed."
|
||||
msgstr ""
|
||||
|
||||
#: class-gf-akismet.php:710
|
||||
msgid "To use this add-on, please visit the Forms -> Settings page to enable Akismet integration"
|
||||
msgstr ""
|
||||
|
||||
#: class-gf-akismet.php:923
|
||||
msgid "This entry has been marked as spam."
|
||||
msgstr ""
|
||||
|
||||
#: includes/settings/class-form-settings.php:52
|
||||
#: includes/settings/class-plugin-settings.php:44
|
||||
msgid "Akismet Settings"
|
||||
msgstr ""
|
||||
|
||||
#: includes/settings/class-form-settings.php:57
|
||||
msgid "First Name"
|
||||
msgstr ""
|
||||
|
||||
#: includes/settings/class-form-settings.php:65
|
||||
msgid "Last Name"
|
||||
msgstr ""
|
||||
|
||||
#: includes/settings/class-form-settings.php:73
|
||||
msgid "Email"
|
||||
msgstr ""
|
||||
|
||||
#: includes/settings/class-form-settings.php:81
|
||||
msgid "Website"
|
||||
msgstr ""
|
||||
|
||||
#: includes/settings/class-form-settings.php:89
|
||||
msgid "Subject"
|
||||
msgstr ""
|
||||
|
||||
#: includes/settings/class-form-settings.php:96
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: includes/settings/class-form-settings.php:117
|
||||
msgid "Enable to protect this form's entries from spam using Akismet"
|
||||
msgstr ""
|
||||
|
||||
#: includes/settings/class-form-settings.php:121
|
||||
msgid "Akismet enabled"
|
||||
msgstr ""
|
||||
|
||||
#: includes/settings/class-form-settings.php:127
|
||||
msgid "Enabled"
|
||||
msgstr ""
|
||||
|
||||
#: includes/settings/class-plugin-settings.php:47
|
||||
msgid "Protect your form entries from spam using Akismet. Don't have an Akismet account?"
|
||||
msgstr ""
|
||||
|
||||
#: includes/settings/class-plugin-settings.php:48
|
||||
msgid "Sign up here"
|
||||
msgstr ""
|
||||
|
||||
#: includes/settings/class-plugin-settings.php:49
|
||||
#: includes/settings/class-plugin-settings.php:75
|
||||
msgid "(opens in a new tab)"
|
||||
msgstr ""
|
||||
|
||||
#: includes/settings/class-plugin-settings.php:55
|
||||
msgid "Enable Akismet Integration"
|
||||
msgstr ""
|
||||
|
||||
#: includes/settings/class-plugin-settings.php:68
|
||||
msgid "API Key"
|
||||
msgstr ""
|
||||
|
||||
#: includes/settings/class-plugin-settings.php:74
|
||||
msgid "Click here to find your Akismet API Key"
|
||||
msgstr ""
|
||||
Reference in New Issue
Block a user