Skip to content

Commit a8387b1

Browse files
author
Gravity Forms
committed
Updates to 2.9.12
1 parent 4f01829 commit a8387b1

File tree

10 files changed

+315
-259
lines changed

10 files changed

+315
-259
lines changed

change_log.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
1+
### 2.9.12 | 2025-07-10
2+
- Added merge tags on the "Send To: Enter Email" notification setting. Credit: The GravityKit Team.
3+
- Updated the legacy Akismet spam check during form submission to run via the [`gform_entry_is_spam`](https://docs.gravityforms.com/gform_entry_is_spam/) filter in preparation for version 1.1.0 of the Akismet add-on.
4+
- Fixed rendering of calculated product in form editor when quantity is disabled.
5+
- Fixed an issue where the recent forms list used by the form switcher is not updated when the admin toolbar menu is disabled.
6+
- Fixed an issue in reCAPTCHA that prevents the form from being submitted when the reCAPTCHA API keys are invalid on the settings page.
7+
- Removed the mock-data endpoint from production environments.
8+
19
### 2.9.11 | 2025-06-26
2-
- Added a h1 to all admin pages to improve accessibility.
10+
- Added a top-level heading to all admin pages to improve accessibility.
311
- Fixed undefined variable error when the filter [gform_toolbar_menu](https://docs.gravityforms.com/gform_toolbar_menu/) returns an empty array.
412
- Fixed handling of notification addressing where comma-separation of merge tags includes spaces.
513
- Updated links in the admin to indicate when they open in a new window for improved accessibility.

common.php

Lines changed: 59 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4577,30 +4577,25 @@ public static function is_spam_entry( $entry, $form ) {
45774577
self::timer_start( __METHOD__ );
45784578
$is_spam = false;
45794579

4580-
if ( self::akismet_enabled( $form_id ) ) {
4581-
$is_spam = self::is_akismet_spam( $form, $entry );
4582-
self::log_debug( __METHOD__ . '(): Result from Akismet: ' . json_encode( $is_spam ) );
4583-
if ( $is_spam ) {
4584-
self::set_spam_filter( $form_id, __( 'Akismet Spam Filter', 'gravityforms' ), '' );
4585-
}
4580+
$akismet_callback = array( __CLASS__, 'entry_is_spam_akismet' );
4581+
if ( has_filter( 'gform_entry_is_spam', $akismet_callback ) === false ) {
4582+
add_filter( 'gform_entry_is_spam', $akismet_callback, 90, 3 );
45864583
}
45874584

4588-
$gform_entry_is_spam_args = array( 'gform_entry_is_spam', $form_id );
4589-
if ( gf_has_filter( $gform_entry_is_spam_args ) ) {
4590-
GFCommon::log_debug( __METHOD__ . '(): Executing functions hooked to gform_entry_is_spam.' );
4591-
/**
4592-
* Allows submissions to be flagged as spam by custom methods.
4593-
*
4594-
* @since 1.8.17
4595-
* @since 2.4.17 Moved from GFFormDisplay::handle_submission().
4596-
*
4597-
* @param bool $is_spam Indicates if the submission has been flagged as spam.
4598-
* @param array $form The form currently being processed.
4599-
* @param array $entry The entry currently being processed.
4600-
*/
4601-
$is_spam = gf_apply_filters( $gform_entry_is_spam_args, $is_spam, $form, $entry );
4602-
self::log_debug( __METHOD__ . '(): Result from gform_entry_is_spam filter: ' . json_encode( $is_spam ) );
4603-
}
4585+
GFCommon::log_debug( __METHOD__ . '(): Executing functions hooked to gform_entry_is_spam.' );
4586+
4587+
/**
4588+
* Allows submissions to be flagged as spam by custom methods.
4589+
*
4590+
* @since 1.8.17
4591+
* @since 2.4.17 Moved from GFFormDisplay::handle_submission().
4592+
*
4593+
* @param bool $is_spam Indicates if the submission has been flagged as spam.
4594+
* @param array $form The form currently being processed.
4595+
* @param array $entry The entry currently being processed.
4596+
*/
4597+
$is_spam = gf_apply_filters( array( 'gform_entry_is_spam', $form_id ), $is_spam, $form, $entry );
4598+
self::log_debug( __METHOD__ . '(): Result from gform_entry_is_spam filter: ' . json_encode( $is_spam ) );
46044599

46054600
if ( $use_cache ) {
46064601
GFFormDisplay::$submission[ $form_id ]['is_spam'] = $is_spam;
@@ -4643,7 +4638,49 @@ public static function spam_enabled( $form_id ) {
46434638
return $spam_enabled;
46444639
}
46454640

4641+
/**
4642+
* Callback for gform_entry_is_spam; performs the Akimset spam check.
4643+
*
4644+
* @since 2.9.12 Moved to a filter callback from GFCommon::is_spam_entry().
4645+
*
4646+
* @param bool $is_spam Indicates if the submission has been flagged as spam.
4647+
* @param array $form The form currently being processed.
4648+
* @param array $entry The entry currently being processed.
4649+
*
4650+
* @return bool
4651+
*/
4652+
public static function entry_is_spam_akismet( $is_spam, $form, $entry ) {
4653+
if ( $is_spam ) {
4654+
return $is_spam;
4655+
}
4656+
4657+
$form_id = (int) rgar( $form, 'id' );
4658+
if ( ! self::akismet_enabled( $form_id ) ) {
4659+
return $is_spam;
4660+
}
4661+
4662+
$is_spam = self::is_akismet_spam( $form, $entry );
4663+
self::log_debug( __METHOD__ . '(): Result from Akismet: ' . json_encode( $is_spam ) );
4664+
if ( $is_spam ) {
4665+
self::set_spam_filter( $form_id, __( 'Akismet Spam Filter', 'gravityforms' ), '' );
4666+
}
4667+
4668+
return $is_spam;
4669+
}
4670+
4671+
/**
4672+
* Determines if the Akismet integration is available.
4673+
*
4674+
* @since unknown
4675+
* @since 2.9.12 Disable the integration when the Akismet Add-On (that communicates directly with the Akismet API) is active.
4676+
*
4677+
* @return bool
4678+
*/
46464679
public static function has_akismet() {
4680+
if ( function_exists( 'gf_akismet' ) && method_exists( gf_akismet(), 'initalize_api' ) ) {
4681+
return false;
4682+
}
4683+
46474684
$akismet_exists = function_exists( 'akismet_http_post' ) || method_exists( 'Akismet', 'http_post' );
46484685

46494686
return $akismet_exists;

forms_model.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8197,15 +8197,12 @@ public static function is_valid_operator( $operator ) {
81978197
* Update the recent forms list for the current user when a form is edited or trashed.
81988198
*
81998199
* @since 2.0.7.14
8200+
* @since 2.9.12 Removed the dependency on the admin toolbar being enabled.
82008201
*
82018202
* @param int $form_id The ID of the current form.
82028203
* @param bool $trashed Indicates if the form was trashed. Default is false, form was opened for editing.
82038204
*/
82048205
public static function update_recent_forms( $form_id, $trashed = false ) {
8205-
if ( ! get_option( 'gform_enable_toolbar_menu' ) ) {
8206-
return;
8207-
}
8208-
82098206
$current_user_id = get_current_user_id();
82108207
$recent_form_ids = self::get_recent_forms( $current_user_id );
82118208

gravityforms.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Plugin Name: Gravity Forms
44
Plugin URI: https://gravityforms.com
55
Description: Easily create web forms and manage form entries within the WordPress admin.
6-
Version: 2.9.11
6+
Version: 2.9.12
77
Requires at least: 6.5
88
Requires PHP: 7.4
99
Author: Gravity Forms
@@ -257,7 +257,7 @@ class GFForms {
257257
*
258258
* @var string $version The version number.
259259
*/
260-
public static $version = '2.9.11';
260+
public static $version = '2.9.12';
261261

262262
/**
263263
* Handles background upgrade tasks.

includes/config/class-gf-config-service-provider.php

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,16 @@ public function init( GF_Service_Container $container ) {
146146
});
147147

148148
add_action( 'rest_api_init', function () use ( $container, $self ) {
149-
register_rest_route( 'gravityforms/v2', '/tests/mock-data', array(
150-
'methods' => 'GET',
151-
'callback' => array( $self, 'config_mocks_endpoint' ),
152-
'permission_callback' => function () {
153-
return true;
154-
},
155-
) );
149+
// check if we are in a test environment, if so register the mock data endpoint.
150+
if ( defined( 'GF_SCRIPT_DEBUG' ) && GF_SCRIPT_DEBUG ) {
151+
register_rest_route( 'gravityforms/v2', '/tests/mock-data', array(
152+
'methods' => 'GET',
153+
'callback' => array( $self, 'config_mocks_endpoint' ),
154+
'permission_callback' => function () {
155+
return true;
156+
},
157+
) );
158+
}
156159
} );
157160

158161
// Add global config data to admin and theme.

includes/fields/class-gf-field-calculation.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public function get_field_input( $form, $value = '', $entry = null ) {
7979

8080
if ( $is_entry_detail || $is_form_editor ) {
8181
$style = $this->disableQuantity ? "style='display:none;'" : '';
82-
$quantity_field = " <label for='ginput_quantity_{$form_id}_{$this->id}' class='ginput_quantity_label gform-field-label' {$style}>{$product_quantity_sub_label}</label> <input type='number' name='input_{$id}.3' value='{$quantity}' id='ginput_quantity_{$form_id}_{$this->id}' class='ginput_quantity' size='10' min='0' {$disabled_text} />";
82+
$quantity_field = " <label for='ginput_quantity_{$form_id}_{$this->id}' class='ginput_quantity_label gform-field-label' {$style}>{$product_quantity_sub_label}</label> <input type='number' name='input_{$id}.3' value='{$quantity}' id='ginput_quantity_{$form_id}_{$this->id}' class='ginput_quantity' size='10' min='0' {$disabled_text} {$style} />";
8383
} elseif ( ! $this->disableQuantity ) {
8484
$tabindex = $this->get_tabindex();
8585
$describedby_extra_id = array();

js/gravityforms.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2395,9 +2395,13 @@ gform.recaptcha = {
23952395
jQuery( '.ginput_recaptcha:not(.gform-initialized)' ).each( function() {
23962396
let $elem = jQuery( this ),
23972397
parameters = {
2398-
'sitekey': $elem.data( 'sitekey' ),
2399-
'theme': $elem.data( 'theme' ),
2400-
'tabindex': $elem.data( 'tabindex' )
2398+
'sitekey': $elem.data( 'sitekey' ),
2399+
'theme': $elem.data( 'theme' ),
2400+
'tabindex': $elem.data( 'tabindex' ),
2401+
'error-callback': () => {
2402+
console.error( 'Gravity Forms: There was an error initializing reCAPTCHA v2. Please ensure your reCAPTCHA API keys are valid.' );
2403+
$elem.attr( 'data-recaptcha-error', '1' );
2404+
}
24012405
};
24022406

24032407
if ( $elem.data( 'stoken' ) ) {
@@ -2494,6 +2498,12 @@ gform.recaptcha = {
24942498
*/
24952499
executeRecaptcha: async function( widgetId, form ) {
24962500

2501+
// If there was an error loading recaptcha, just abort and let the submission fail validation.
2502+
const recaptcha = gform.utils.getNode( '.ginput_recaptcha', form, true );
2503+
if ( recaptcha.getAttribute( 'data-recaptcha-error' ) === '1' ) {
2504+
return;
2505+
}
2506+
24972507
// Executes recaptcha.
24982508
window.grecaptcha.execute( widgetId );
24992509

js/gravityforms.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)