Skip to content

Commit

Permalink
Merge branch 'release/2.2.6'
Browse files Browse the repository at this point in the history
  • Loading branch information
remcotolsma committed Mar 13, 2018
2 parents b516747 + 5b13648 commit 18292ee
Show file tree
Hide file tree
Showing 48 changed files with 1,066 additions and 755 deletions.
47 changes: 47 additions & 0 deletions change_log.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,50 @@
------------------------------------------------------------------------------------------------------------------
Version 2.2.6
- Added security enhancements.
- Added a message in the plugins page to remind users to take a backup of the database and update all Gravity Forms add-ons before updating to 2.3.
- Added GPL to plugin header.
- Added the gform_field_groups_form_editor filter.
- Added the "gform_recaptcha_callback" JS filter allowing a custom callback function to be executed when the user successfully submits the captcha.
- Added the "gform_form_not_found_message" filter allowing the form not found message to be overridden. Credit: Naomi C. Bush.
- Added the theme to the system report.
- Added the locale to the system report.
- Added the "gform_validation_error_form_editor" JS filter allowing the form editor validation error to be overridden.
- Added the "gform_field_choice_selected_type_form_editor" JS filter allowing the choice selected input type to be overridden.

- Updated field creation to set visibility to visible.
- Updated Plugin URI and Author URI to use https.
- Updated the minimum version of WordPress required for support to 4.8.
- Updated remote message caching so that it gets cleared when user navigates to System Status page.

- Fixed a PHP warning when no values have been submitted to a multiple column List field.
- Fixed incorrect field CSS class when field visibility is set to visible.
- Fixed issue where input-specific conditional logic on the next button was not evaluated correctly.
- Fixed product quantity calculation not evalulating conditional logic.
- Fixed a JavaScript error which occurred when clicking cancel for a file being uploaded via the multi-file enabled file upload field.
- Fixed a rare infinite loop issue where the new and previous value comparison is always different for pricing fields.
- Fixed an issue where a calculation result could return INF which would prevent the Save and Continue feature successfully saving the incomplete submission.
- Fixed the payment date not being formatted to the local timezone in the entry export.
- Fixed multi-select type Post Category fields created with GF2.2+ not saving the entry value correctly.
- Fixed a JavaScript error on form display when the "Disable the visual editor when writing" setting is enabled for the current user and the "Use the Rich Text Editor" setting is enabled on a Paragraph or Post Body field.
- Fixed dynamic population of administrative Date and Time fields.
- Fixed PHP notice during submission with WordPress 4.8.3+ when the no duplicates setting was enabled on a field.
- Fixed GFCommon::is_valid_email_list() returning false when commas were followed by a space.
- Fixed the $form_id passed to the gform_custom_merge_tags filter for new forms and when getting the merge tags for calculation fields.
- Fixed the placeholder attribute not being added when the field or input placeholder is set to 0.
- Fixed notices on WP 4.8.3 while performing entry searches with certain field filters.
- Fixed entry exports from the Forms > Import/Export page not using the field admin labels since v2.2.5.
- Fixed a PHP notice related to a file upload field logging statement.
- Fixed JavaScript errors preventing conditional logic settings being displayed for new or duplicate confirmations with the Hebrew translation.
- Fixed the Multi Select field not using the choice isSelected property when determining which choices are selected on display.
- Fixed required Number field with a min range setting of 1 passing validation when a value of 0 is submitted.
- Fixed an issue during post creation where the value from multi-select type custom fields, created with GF2.2+, were not processed correctly.
- Fixed an issue on some sites where a outdated version of the active_plugins option could be used when updating the option so the plugin loads first.

- AF: Fixed a PHP warning when using the args property of the field_select setting.
- AF: Fixed "callback" property being output as a settings field attribute.
- AF: Fixed the payment_gateway entry meta item not being set for some add-ons when using the gform_post_payment_completed hook.
- AF: Add GFAddOn::get_capabilities() to get registered capabilities.

------------------------------------------------------------------------------------------------------------------
Version 2.2.5
- Updated form view recording so that IP isn't included.
Expand Down
63 changes: 53 additions & 10 deletions common.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public static function recursive_add_index_file( $dir ) {
}

// ignores all errors
set_error_handler( create_function( '', 'return 0;' ), E_ALL );
set_error_handler( '__return_false', E_ALL );

//creates an empty index.html file
if ( $f = fopen( $dir . '/index.html', 'w' ) ) {
Expand Down Expand Up @@ -369,8 +369,11 @@ public static function is_valid_email_list( $email_list ) {
return false;
}

// Trim values.
$emails = array_map( 'trim', $emails );

foreach ( $emails as $email ) {
if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
if ( ! self::is_valid_email( $email ) ) {
return false;
}
}
Expand Down Expand Up @@ -589,7 +592,8 @@ public static function get_merge_tags( $fields, $element_id, $hide_all_fields =
$other_group[] = array( 'tag' => '{user:user_email}', 'label' => esc_html__( 'User Email', 'gravityforms' ) );
$other_group[] = array( 'tag' => '{user:user_login}', 'label' => esc_html__( 'User Login', 'gravityforms' ) );

$form_id = isset( $fields[0] ) ? $fields[0]->formId : 0;
$form_id = isset( $fields[0] ) ? $fields[0]->formId : rgget( 'id' );
$form_id = absint( $form_id );

$custom_group = apply_filters( 'gform_custom_merge_tags', array(), $form_id, $fields, $element_id );

Expand Down Expand Up @@ -765,7 +769,9 @@ public static function insert_calculation_variables( $fields, $element_id, $onch
</optgroup>

<?php
$form_id = isset( $forms[0] ) ? $fields[0]->formId : 0;
$form_id = isset( $fields[0] ) ? $fields[0]->formId : rgget( 'id' );
$form_id = absint( $form_id );

$custom_merge_tags = apply_filters( 'gform_custom_merge_tags', array(), $form_id, $fields, $element_id );

if ( is_array( $custom_merge_tags ) && ! empty( $custom_merge_tags ) ) {
Expand Down Expand Up @@ -2446,9 +2452,19 @@ public static function get_key_info( $key ) {

public static function get_version_info( $cache = true ) {

$version_info = get_transient( 'gform_update_info' );
$version_info = get_option( 'gform_version_info' );
if ( ! $cache ) {
$version_info = null;
} else {

// Checking cache expiration
$cache_duration = DAY_IN_SECONDS; // 24 hours.
$cache_timestamp = $version_info && isset( $version_info['timestamp'] ) ? $version_info['timestamp'] : 0;

// Is cache expired ?
if ( $cache_timestamp + $cache_duration < time() ) {
$version_info = null;
}
}

if ( is_wp_error( $version_info ) || isset( $version_info['headers'] ) ) {
Expand Down Expand Up @@ -2481,8 +2497,10 @@ public static function get_version_info( $cache = true ) {
}
}

$version_info['timestamp'] = time();

// Caching response.
set_transient( 'gform_update_info', $version_info, 86400 ); //caching for 24 hours
update_option( 'gform_version_info', $version_info ); //caching version info
}

return $version_info;
Expand Down Expand Up @@ -2928,7 +2946,7 @@ public static function get_select_choices( $field, $value = '', $support_placeho
$field_value .= '|' . $price;
}

if ( ! isset( $_GET['gf_token'] ) && empty( $_POST ) && rgblank( $value ) && rgget('view') != 'entry' ) {
if ( ! isset( $_GET['gf_token'] ) && empty( $_POST ) && self::is_empty_array( $value ) && rgget('view') != 'entry' ) {
$selected = rgar( $choice, 'isSelected' ) ? "selected='selected'" : '';
} else {
if ( is_array( $value ) ) {
Expand Down Expand Up @@ -3189,7 +3207,9 @@ public static function get_field_input( $field, $value = '', $lead_id = 0, $form
break;

case 'adminonly_hidden' :
if ( ! is_array( $field->inputs ) ) {
$inputs = $field->get_entry_inputs();

if ( ! is_array( $inputs ) ) {
if ( is_array( $value ) ) {
$value = json_encode( $value );
}
Expand All @@ -3199,7 +3219,7 @@ public static function get_field_input( $field, $value = '', $lead_id = 0, $form


$fields = '';
foreach ( $field->inputs as $input ) {
foreach ( $inputs as $input ) {
$fields .= sprintf( "<input name='input_%s' class='gform_hidden' type='hidden' value='%s'/>", $input['id'], esc_attr( rgar( $value, strval( $input['id'] ) ) ) );
}

Expand Down Expand Up @@ -4177,7 +4197,7 @@ public static function calculate( $field, $form, $lead ) {

$result = apply_filters( 'gform_calculation_result', $result, $formula, $field, $form, $lead );

if ( ! $result || ! is_numeric( $result ) || is_nan( $result ) ) {
if ( ! $result || ! is_numeric( $result ) || ! is_finite( $result ) ) {
GFCommon::log_debug( __METHOD__ . '(): No result or non-numeric result. Returning zero instead.' );
$result = 0;
}
Expand Down Expand Up @@ -5823,3 +5843,26 @@ public function get_var( $query = null, $x = 0, $y = 0 ) {
return parent::get_var( $query );
}
}

/**
* Late static binding for dynamic function calls.
*
* Provides compatibility with PHP 7.2 (create_function deprecated) and 5.2.
* So whenever the need for `create_function` arises, use this instead.
*/
class GF_Late_Static_Binding {
private $args = array();

public function __construct( $args ) {
$this->args = wp_parse_args( $args, array(
'form_id' => 0,
) );
}

/**
* Binding for GFFormDisplay::footer_init_scripts
*/
public function GFFormDisplay_footer_init_scripts() {
return GFFormDisplay::footer_init_scripts( $this->args['form_id'] );
}
}
10 changes: 7 additions & 3 deletions export.php
Original file line number Diff line number Diff line change
Expand Up @@ -753,9 +753,13 @@ public static function start_export( $form, $offset = 0, $export_id = '' ) {
foreach ( $fields as $field_id ) {
switch ( $field_id ) {
case 'date_created' :
$lead_gmt_time = mysql2date( 'G', $lead['date_created'] );
$lead_local_time = GFCommon::get_local_timestamp( $lead_gmt_time );
$value = date_i18n( 'Y-m-d H:i:s', $lead_local_time, true );
case 'payment_date' :
$value = $lead[ $field_id ];
if ( $value ) {
$lead_gmt_time = mysql2date( 'G', $value );
$lead_local_time = GFCommon::get_local_timestamp( $lead_gmt_time );
$value = date_i18n( 'Y-m-d H:i:s', $lead_local_time, true );
}
break;
default :
$field = RGFormsModel::get_field( $form, $field_id );
Expand Down
7 changes: 7 additions & 0 deletions form_detail.php
Original file line number Diff line number Diff line change
Expand Up @@ -2573,6 +2573,13 @@ public static function get_field_groups() {
'value' => GFCommon::get_field_type_title( 'creditcard' )
);
}

/**
* Modify the field groups before fields are added
*
* @param array $field_groups The field groups, including group name, label and fields.
*/
$field_groups = apply_filters( 'gform_field_groups_form_editor', $field_groups );

// Remove array keys from field groups array.
$field_groups = array_values( $field_groups );
Expand Down
35 changes: 23 additions & 12 deletions form_display.php
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ private static function upload_files( $form, $files ) {
}

if ( empty( $_FILES[ $input_name ]['name'] ) ) {
GFCommon::log_debug( "GFFormDisplay::upload_files(): Skipping field because " . $_FILES[ $input_name ]['name'] . " could not be found: {$field->label}({$field->id} - {$field->type})." );
GFCommon::log_debug( "GFFormDisplay::upload_files(): Skipping field because a file could not be found: {$field->label}({$field->id} - {$field->type})." );
continue;
}

Expand Down Expand Up @@ -793,7 +793,7 @@ public static function get_form( $form_id, $display_title = true, $display_descr
}
}
} elseif ( ! current_user_can( 'administrator' ) && ! $view_counter_disabled ) {
RGFormsModel::insert_form_view( $form_id, $_SERVER['REMOTE_ADDR'] );
RGFormsModel::insert_form_view( $form_id );
}
}

Expand All @@ -805,7 +805,15 @@ public static function get_form( $form_id, $display_title = true, $display_descr
$form = gf_apply_filters( array( 'gform_pre_render', $form_id ), $form, $ajax, $field_values );

if ( $form == null ) {
return '<p class="gform_not_found">' . esc_html__( 'Oops! We could not locate your form.', 'gravityforms' ) . '</p>';
/**
* Filter the form not found message that will be displayed
*
* @since
*
* @param string The default form not found message
* @param int|string $form_id The ID of the form we tried to retrieve
*/
return apply_filters( 'gform_form_not_found_message', '<p class="gform_not_found">' . esc_html__( 'Oops! We could not locate your form.', 'gravityforms' ) . '</p>', $form_id );
}

$has_pages = self::has_pages( $form );
Expand Down Expand Up @@ -1081,8 +1089,9 @@ public static function get_form( $form_id, $display_title = true, $display_descr
self::register_form_init_scripts( $form, $field_values, $ajax );

if ( apply_filters( 'gform_init_scripts_footer', false ) ) {
add_action( 'wp_footer', create_function( '', 'GFFormDisplay::footer_init_scripts(' . $form['id'] . ');' ), 20 );
add_action( 'gform_preview_footer', create_function( '', 'GFFormDisplay::footer_init_scripts(' . $form['id'] . ');' ) );
$callback = array( new GF_Late_Static_Binding( array( 'form_id' => $form['id'] ) ), 'GFFormDisplay_footer_init_scripts' );
add_action( 'wp_footer', $callback, 20 );
add_action( 'gform_preview_footer', $callback );
} else {
$form_string .= self::get_form_init_scripts( $form );
$form_string .= "<script type='text/javascript'>" . apply_filters( 'gform_cdata_open', '' ) . " jQuery(document).ready(function(){jQuery(document).trigger('gform_post_render', [{$form_id}, {$current_page}]) } ); " . apply_filters( 'gform_cdata_close', '' ) . '</script>';
Expand Down Expand Up @@ -2443,17 +2452,19 @@ public static function get_placeholders_init_script( $form ) {
}

public static function get_counter_init_script( $form ) {

$script = '';

/** @var GF_Field $field */
foreach ( $form['fields'] as $field ) {

$max_length = $field->maxLength;
$input_id = "input_{$form['id']}_{$field->id}";

if ( ! empty( $max_length ) && ! $field->is_administrative() ) {
$truncate = $field->useRichTextEditor === true ? 'false' : 'true' ;
$tinymce_style = $field->useRichTextEditor === true ? ' ginput_counter_tinymce' : '' ;
$error_style = $field->useRichTextEditor === true ? ' ginput_counter_error' : '' ;
$rte_enabled = $field instanceof GF_Field_Textarea && $field->is_rich_edit_enabled();
$truncate = $rte_enabled ? 'false' : 'true';
$tinymce_style = $rte_enabled ? ' ginput_counter_tinymce' : '';
$error_style = $rte_enabled ? ' ginput_counter_error' : '';

$field_script =
"jQuery('#{$input_id}').textareaCount(" .
Expand Down Expand Up @@ -2530,7 +2541,7 @@ public static function get_calculations_init_script( $form ) {
return '';
}

$script = 'new GFCalc(' . $form['id'] . ', ' . GFCommon::json_encode( $formula_fields ) . ');';
$script = 'if( typeof window.gf_global["gfcalc"] == "undefined" ) { window.gf_global["gfcalc"] = {}; } window.gf_global["gfcalc"][' . $form['id'] . '] = new GFCalc(' . $form['id'] . ', ' . GFCommon::json_encode( $formula_fields ) . ');';

return $script;
}
Expand Down Expand Up @@ -2771,7 +2782,7 @@ public static function get_conditional_logic_fields( $form, $fieldId ) {
//adding fields with next button logic
if ( ! empty( $field->nextButton['conditionalLogic'] ) ) {
foreach ( $field->nextButton['conditionalLogic']['rules'] as $rule ) {
if ( $rule['fieldId'] == $fieldId && ! in_array( $fieldId, $fields ) ) {
if ( intval( $rule['fieldId'] ) == $fieldId && ! in_array( $fieldId, $fields ) ) {
$fields[] = floatval( $field->id );
break;
}
Expand Down Expand Up @@ -2848,7 +2859,7 @@ public static function get_field( $field, $value = '', $force_frontend_label = f

$error_class = $field->failed_validation ? 'gfield_error' : '';
$admin_only_class = $field->visibility == 'administrative' ? 'field_admin_only' : ''; // maintain for backwards compat
$visibility_class = sprintf( 'gfield_visibility_%s', $field->visibility );
$visibility_class = sprintf( 'gfield_visibility_%s', ( $field->visibility ? $field->visibility : 'visible' ) );
$selectable_class = $is_admin ? 'selectable' : '';
$hidden_class = in_array( $input_type, array( 'hidden', 'hiddenproduct' ) ) ? 'gform_hidden' : '';

Expand Down
20 changes: 10 additions & 10 deletions form_settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -1262,9 +1262,9 @@ public static function confirmations_edit_page( $form_id, $confirmation_id ) {

<?php if ( $is_duplicate ) :?>
$('#confirmation_conditional_logic_container').pointer({
content : '<h3><?php _e( 'Important', 'gravityforms' ) ?></h3><p><?php _e( 'Ensure that the conditional logic for this confirmation is different from all the other confirmations for this form and then press save to create the new confirmation.', 'gravityforms' ) ?></p>',
position : {
edge : 'bottom', // arrow direction
content: <?php echo json_encode( sprintf( '<h3>%s</h3><p>%s</p>', __( 'Important', 'gravityforms' ), __( 'Ensure that the conditional logic for this confirmation is different from all the other confirmations for this form and then press save to create the new confirmation.', 'gravityforms' ) ) ); ?>,
position: {
edge: 'bottom', // arrow direction
align: 'center' // vertical alignment
},
pointerWidth: 300
Expand All @@ -1273,16 +1273,16 @@ public static function confirmations_edit_page( $form_id, $confirmation_id ) {
});


gform.addFilter("gform_merge_tags", "MaybeAddSaveMergeTags");
function MaybeAddSaveMergeTags(mergeTags, elementId, hideAllFields, excludeFieldTypes, isPrepop, option){
gform.addFilter('gform_merge_tags', 'MaybeAddSaveMergeTags');
function MaybeAddSaveMergeTags(mergeTags, elementId, hideAllFields, excludeFieldTypes, isPrepop, option) {
var event = confirmation.event;
if ( event == 'form_saved' || event == 'form_save_email_sent' ) {
mergeTags["other"].tags.push({ tag: '{save_link}', label: '<?php _e( 'Save &amp; Continue Link', 'gravityforms' ) ?>' });
mergeTags["other"].tags.push({ tag: '{save_token}', label: '<?php _e( 'Save &amp; Continue Token', 'gravityforms' ) ?>' });
if ( event === 'form_saved' || event === 'form_save_email_sent' ) {
mergeTags['other'].tags.push({ tag: '{save_link}', label: <?php echo json_encode( __( 'Save &amp; Continue Link', 'gravityforms' ) ) ?> });
mergeTags['other'].tags.push({ tag: '{save_token}', label: <?php echo json_encode( __( 'Save &amp; Continue Token', 'gravityforms' ) ) ?> });
}

if( event == 'form_saved' ) {
mergeTags["other"].tags.push({ tag: '{save_email_input}', label: '<?php _e( 'Save &amp; Continue Email Input', 'gravityforms' ) ?>' });
if ( event === 'form_saved' ) {
mergeTags['other'].tags.push({ tag: '{save_email_input}', label: <?php echo json_encode( __( 'Save &amp; Continue Email Input', 'gravityforms' ) ) ?> });
}

return mergeTags;
Expand Down
Loading

0 comments on commit 18292ee

Please sign in to comment.