spivurno
11/18/2015 - 2:58 PM

Craig Udit // Gravity Forms // Value Assignment

Craig Udit // Gravity Forms // Value Assignment

<?php
/**
 * Craig Udit // Gravity Forms // Value Assignment
 *
 * Populate a value into a field by a list of conditions provided via CSV.
 *
 * @version	  1.0
 * @author    David Smith <david@gravitywiz.com>
 * @license   GPL-2.0+
 * @link      http://gravitywiz.com/...
 * @copyright 2015 Gravity Wiz
 */
class CU_Value_Assignment {

    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,
            'target_field_id' => false,
            'columns'         => 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() {

        // make sure we're running the required minimum version of Gravity Forms
        if( ! property_exists( 'GFCommon', 'version' ) || ! version_compare( GFCommon::$version, '1.8', '>=' ) ) {
            return;
        }

		add_action( 'gform_pre_submission_' . $this->_args['form_id'], array( $this, 'assign_value' ) );
	    add_filter( 'gform_merge_tag_filter', array( $this, 'replace_merge_tags' ), 10, 5 );

    }

	public function assign_value( $form ) {

		$data = $this->get_source_data();
		$value = $this->get_value_assignment( $data );

		$_POST[ sprintf( 'input_%d', $this->_args['target_field_id'] ) ] = $value;

		return $value;
	}

	public function get_source_data() {

		$csv        = array_map( 'str_getcsv', file( $this->_args['source'] ) );
		$headers    = array_shift( $csv );

		return $csv;
	}

	public function get_value_assignment( $data ) {

		$values = array();

		foreach( $data as $row ) {
			if( $this->is_row_match( $row ) ) {
				$orig_row = $row;
				$values[] = apply_filters( 'cuva_value', array_pop( $row ), $orig_row );
			}
		}

		return implode( ',', $values );
	}

	public function is_row_match( $row, $column = 0 ) {

		$column_value = $row[ $column ];
		$next_column  = $column + 1;
		$is_match     = false;
		$next_is_last = $next_column >= count( $this->_args['source_map'] );

		// progress to next column if current column is empty
		if( ! $column_value ) {

			if( $next_is_last ) {
				$is_match = true;
			} else {
				$is_match = $this->is_row_match( $row, $next_column );
			}

		} else {

			$field_ids = $this->get_column_field_ids( $column );

			if( ! is_array( $field_ids ) ) {
				$field_ids = array( $field_ids );
			}

			foreach( $field_ids as $field_id ) {

				$field_value = $this->get_field_id_value( $field_id );
				if( $this->is_value_match( $field_value, $column_value, $column ) ) {
					if( ! $next_is_last ) {
						$is_match = $this->is_row_match( $row, $next_column );
					} else {
						$is_match = true;
					}
				}

			}

		}

		return $is_match;
	}

	public function get_field_id_value( $field_id ) {

		foreach( $_POST as $key => $value ) {
			if( strpos( $key, sprintf( 'input_%d', $field_id ) ) !== false ) {
				$explode = explode( '|', rgpost( $key ) );
				$value   = array_shift( $explode );
				break;
			}
		}

		return $value;
	}

	public function is_value_match( $field_value, $column_value, $column ) {

		if( empty( $field_value ) ) {
			return false;
		}

		$operator = $this->get_column_operator( $column );

		switch( $operator ) {
			case 'range':
				$range = explode( '-', $column_value );
				list( $min, $max ) = array_pad( $range, 2, null );
				$is_match = $field_value >= $min && $field_value <= $max;
				break;
			default:
				$is_match = GFFormsModel::matches_operation( $field_value, $column_value, $operator );
		}

		return $is_match;
	}

	public function get_column_field_ids( $column ) {
		return $this->get_column_prop( $column, 'field_ids' );
	}

	public function get_column_operator( $column ) {
		return $this->get_column_prop( $column, 'operator' );
	}

	public function get_column_prop( $column, $prop ) {
		$columns = wp_list_pluck( $this->_args['source_map'], $prop );
		$columns = array_values( $columns );
		return $columns[ $column ];
	}

	public function replace_merge_tags( $value, $merge_tag, $modifier, $field, $raw_value ) {

		// right form, right field, not {all_fields}
		if ( $field->formId != $this->_args['form_id'] || $field->id != $this->_args['target_field_id'] || $merge_tag == 'all_fields' || ! is_numeric( $modifier ) ) {
			return $value;
		}

		$index  = intval( $modifier ) - 1;
		$values = explode( ',', $value );

		return rgar( $values, $index );
	}

}

# Configuration

new CU_Value_Assignment( array(
    'form_id' => 1081,
    'target_field_id' => 88,
    'source' => 'http://localhost/wp-content/uploads/2015/11/CLASS-LOGIC-SAMPLE-testdivisions.csv',
    'source_map' => array(
        'Sport and Division' => array(
	        'field_ids' => array( 38, 75, 39, 40, 44, 41, 87 ),
	        'operator'  => 'is'
        ),
        'Height' => array(
	        'field_ids' => 10,
	        'operator'  => 'range'
        ),
        'Weight' => array(
	        'field_ids' => 12,
	        'operator'  => 'range'
        )
    )
) );

// example for modifying value
add_filter( 'cuva_value', function( $value, $row ) {
	return sprintf( '%s (%s)', $row[0], $value );
}, 10, 2 );