Skip to content

Instantly share code, notes, and snippets.

@spivurno
Last active September 16, 2021 13:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save spivurno/4fb1d71a69771fe9e5f6 to your computer and use it in GitHub Desktop.
Save spivurno/4fb1d71a69771fe9e5f6 to your computer and use it in GitHub Desktop.
Gravity Wiz // Gravity Forms // Require Unique Values Between Fields
<?php
/**
* WARNING! THIS SNIPPET MAY BE OUTDATED.
* The latest version of this snippet can be found in the Gravity Wiz Snippet Library:
* https://github.com/gravitywiz/snippet-library/blob/master/gravity-forms/gw-require-unique-values.php
*/
/**
* Gravity Wiz // Gravity Forms // Require Unique Values Between Fields
*
* Allows you to require two or more fields on the same form to be different from each other. For example, if you are
* collecting a personal phone number and an emergency contact phone number, this functionality can be used to ensure
* that the same number is not used for both fields.
*
* @version 1.6
* @author David Smith <david@gravitywiz.com>
* @license GPL-2.0+
* @link https://gravitywiz.com/gravity-forms-require-unique-values-for-different-fields/
*/
class GW_Require_Unique_Values {
public function __construct( $args = array() ) {
// set our default arguments, parse against the provided arguments, and store for use throughout the class
$this->_args = wp_parse_args( $args, array(
'form_id' => false,
'field_ids' => false,
'validation_message' => __( 'Please enter a unique value.' ),
'validate_all_fields' => false,
'mode' => 'collective' // 'collective' or 'individual' (experimental)
) );
$this->_args['master_field_id'] = array_shift( $this->_args['field_ids'] );
// do version check in the init to make sure if GF is going to be loaded, it is already loaded
add_action( 'init', array( $this, 'init' ) );
}
public function init() {
// make sure we're running the required minimum version of Gravity Forms
if( ! property_exists( 'GFCommon', 'version' ) || ! version_compare( GFCommon::$version, '1.9', '>=' ) ) {
return;
}
add_filter( sprintf( 'gform_field_validation_%s', $this->_args['form_id'] ), array( $this, 'validate' ), 10, 4 );
}
public function validate( $result, $value, $form, $field ) {
if( ! $this->is_applicable_field( $field ) ) {
return $result;
}
$value = $this->get_filtered_value( $field );
if( empty( $value ) ) {
return $result;
}
if( $this->_args['mode'] === 'individual' ) {
$groups = $this->get_group_values( $form, $field->id, false );
$is_unique = true;
foreach( $value as $target ) {
foreach( $groups as $group ) {
if( in_array( $target, $group ) ) {
$is_unique = false;
break 2;
}
}
}
} else {
$values = $this->get_group_values( $form, $field->id );
$is_unique = ! in_array( $this->get_value_hash( $value ), $values );
}
if ( $result['is_valid'] && ! $is_unique ) {
$result['is_valid'] = false;
$result['message'] = $this->_args['validation_message'];
}
return $result;
}
public function get_group_values( $form, $exclude_field_id, $do_hash = true ) {
$field_ids = $this->_args['field_ids'];
$field_ids[] = $this->_args['master_field_id'];
$values = array();
foreach( $field_ids as $field_id ) {
if( $field_id == $exclude_field_id ) {
continue;
}
$field = GFFormsModel::get_field( $form, $field_id );
$value = $this->get_filtered_value( $field );
if( ! empty( $value ) ) {
$values[ $field->id ] = $do_hash ? $this->get_value_hash( $value ) : $value;
}
}
return $values;
}
/**
* @param GF_Field $field
*
* @return array
*/
public function get_filtered_value( $field ) {
if( $field->get_input_type() == 'fileupload' && ! $field->multipleFiles ) {
/** @var GF_Field_FileUpload $field */
$value = basename( rgars( $_FILES, sprintf( 'input_%d/name', $field->id ) ) );
} else {
$value = $field->get_value_submission( array() );
}
$value = ! is_array( $value ) ? array( $value ) : $value;
$value = array_filter( $value );
return $value;
}
public function get_value_hash( $value ) {
// Replace values like "1.1" with "x.1" to make it generic for comparison.
if( is_array( $value ) ) {
$old = $value;
foreach( $old as $key => $_value ) {
$ids = explode( '.', $key );
if( count( $ids ) > 1 ) {
$ids[0] = 'x';
}
unset( $value[ $key ] );
$value[ implode( '.', $ids ) ] = $_value;
}
}
return json_encode( $value );
}
public function is_applicable_field( $field ) {
if( ! $this->_args['field_ids'] ) {
return false;
} else if( $this->_args['validate_all_fields'] && $field->id == $this->_args['master_field_id'] ) {
return true;
} else if( ! in_array( $field->id, $this->_args['field_ids'] ) ) {
return false;
}
return true;
}
}
# Configuration
new GW_Require_Unique_Values( array(
'form_id' => 123,
'field_ids' => array( 4, 5 )
) );
<?php
/**
* Gravity Wiz // Gravity Forms // Require Unique Values Between Fields
* http://gravitywiz.com/gravity-forms-require-unique-values-for-different-fields/
*/
# Set Custom Validation Message
new GW_Require_Unique_Values( array(
'form_id' => 12,
'field_ids' => array( 14, 15 ),
'validation_message' => 'My custom validation message!'
) );
# Create Multiple Unique "Groups" on the Same Form
new GW_Require_Unique_Values( array(
'form_id' => 2,
'field_ids' => array( 4, 5 )
) );
new GW_Require_Unique_Values( array(
'form_id' => 2,
'field_ids' => array( 7, 8 )
) );
# Unique Field Compared to ALL Form Fields
new GW_Require_Unique_Values( array(
'form_id' => 2,
'field_ids' => array( 7 )
) );
@spivurno
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment