Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@spivurno
Last active March 11, 2021 22:03
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spivurno/d8588a9deb9084339afb to your computer and use it in GitHub Desktop.
Save spivurno/d8588a9deb9084339afb to your computer and use it in GitHub Desktop.
Gravity Perks // GP Limit Choices // Share Limits Across Multiple Fields
<?php
/**
* Gravity Perks // GP Limit Choices // Share Limits Across Multiple Fields (and Forms)
*
* NOTE: This snippet only works with Gravity Forms 2.3 or greater.
*
* Adds support for specifying groups of fields which share the same limit. For example, if you had two fields with a
* limit of 10, selections from both fields would contribute to that limit.
*
* @version 2.1
* @author David Smith <david@gravitywiz.com>
* @license GPL-2.0+
* @link http://gravitywiz.com/
*/
class GWLimitChoicesSharedLimits {
public $_args = array();
public function __construct( $args = array() ) {
$this->_args = wp_parse_args( $args, array(
'form_id' => false,
'field_groups' => array(),
'form_groups' => array()
) );
// 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() {
if( ! is_callable( array( 'GFFormsModel', 'get_database_version' ) ) ) {
return;
}
add_filter( 'gwlc_choice_counts_query', array( $this, 'modify_choice_counts_query' ), 10, 2 );
add_filter( 'gplc_requested_count', array( $this, 'modify_requested_count' ), 10, 2 );
}
public function modify_choice_counts_query( $query, $field ) {
if( ! $this->is_applicable_form( $field->formId ) ) {
return $query;
}
if( ! empty( $this->_args['form_groups'] ) ) {
$query = $this->modify_query_for_form_groups( $query, $field );
}
if( ! empty( $this->_args['field_groups'] ) ) {
$query = $this->modify_query_for_field_groups( $query, $field );
}
return $query;
}
public function modify_query_for_field_groups( $query, $field ) {
global $wpdb;
$from_search = $wpdb->prepare( "(em.meta_key = %s OR em.meta_key LIKE %s)", $field['id'], $wpdb->esc_like( $field['id'] ) . '.%' );
$from_replace = array();
foreach( $this->_args['field_groups'] as $field_group ) {
if( ! in_array( $field['id'], $field_group ) ) {
continue;
}
foreach( $field_group as $field_id ) {
$from_replace[] = $wpdb->prepare( "em.meta_key = %s OR em.meta_key LIKE %s", $field_id, $wpdb->esc_like( $field_id ) . '.%' );
}
}
if( ! empty( $from_replace ) ) {
$from_replace = sprintf( '( %s )', implode( ' OR ', $from_replace ) );
$query['from'] = str_replace( $from_search, $from_replace, $query['from'] );
}
return $query;
}
public function modify_query_for_form_groups( $query, $field ) {
global $wpdb;
foreach( $this->_args['form_groups'] as $form_group ) {
if( ! $this->is_form_group_field( $field, $form_group ) ) {
continue;
}
$query['where'] = str_replace( sprintf( 'AND em.form_id = %d', $field->formId ), '', $query['where'] );
$join_conditions = array();
foreach( $form_group as $form_id => $field_id ) {
$join_conditions[] = sprintf( '( em.form_id = %1$d AND ( em.meta_key = \'%2$d\' OR em.meta_key LIKE \'%2$d.%%\' ) )', $form_id, $field_id );
}
$query['from'] = sprintf( "FROM {$wpdb->prefix}gf_entry e INNER JOIN {$wpdb->prefix}gf_entry_meta em ON em.entry_id = e.id AND ( %s )", implode( "\nOR\n", $join_conditions ) );
}
return $query;
}
public function modify_requested_count( $requested_count, $field ) {
if( ! $this->is_applicable_form( $field['formId'] ) ) {
return $requested_count;
}
foreach( $this->_args['field_groups'] as $field_group ) {
if( ! in_array( $field->id, $field_group ) ) {
continue;
}
$selected_choices = gp_limit_choices()->get_selected_choices( $field );
$primary_choice = reset( $selected_choices );
$shared_requested_count = 0;
remove_filter( 'gplc_requested_count', array( $this, 'modify_requested_count' ) );
foreach( $field_group as $field_id ) {
$form = GFAPI::get_form( $field->formId );
$group_field = GFFormsModel::get_field( $form, $field_id );
$selected_choices = gp_limit_choices()->get_selected_choices( $group_field );
$selected_choice = reset( $selected_choices );
if( $selected_choice['value'] == $primary_choice['value'] ) {
$shared_requested_count += gp_limit_choices()->get_requested_count( $group_field );
}
}
add_filter( 'gplc_requested_count', array( $this, 'modify_requested_count' ), 10, 2 );
break;
}
return isset( $shared_requested_count ) ? intval( $shared_requested_count ) : $requested_count;
}
public function is_applicable_form( $form ) {
$form_id = is_array( $form ) ? $form['id'] : $form;
$is_applicable_form = false;
if ( ! empty( $this->_args['form_groups'] ) ) {
foreach( $this->_args['form_groups'] as $form_group ) {
$is_applicable_form = $this->is_form_group_form( $form, $form_group );
if( $is_applicable_form ) {
break;
}
}
} else {
$is_applicable_form = $form_id == $this->_args['form_id'];
}
return $is_applicable_form;
}
public function is_form_group_form( $form, $form_group ) {
$form_id = is_array( $form ) ? $form['id'] : $form;
return in_array( $form_id, array_keys( $form_group ) );
}
public function is_form_group_field( $field, $form_group ) {
return $this->is_form_group_form( $field->formId, $form_group ) && in_array( $field->id, $form_group );
}
}
# Configuration
// Share limits on between two fields on the same form
new GWLimitChoicesSharedLimits( array(
'form_id' => 996,
'field_groups' => array(
array( 1, 2 )
)
) );
// Share limits between fields across multiple forms
new GWLimitChoicesSharedLimits( array(
'form_groups' => array(
array(
996 => 1,
997 => 1
),
array(
996 => 2,
997 => 2
)
)
) );
@spivurno
Copy link
Author

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