spivurno
6/24/2014 - 1:42 AM

Gravity Wiz // Gravity Forms // Populate Field With Users

Gravity Wiz // Gravity Forms // Populate Field With Users

<?php
/**
 * ============================================================================================
 * STOP! There's a better way.
 * 
 * The functionality provided by this snippet is available via Gravity Forms Populate Anything. 
 * 
 * Don't get your hands dirty mucking about with code. Populate Anything provides a seamlessly
 * integrated interface for filtering exactly which users are populated and what data from 
 * those users is displayed.
 * 
 * https://gravitywiz.com/documentation/gravity-forms-populate-anything/
 * ============================================================================================
 *
 * Gravity Wiz // Gravity Forms // Populate Field With Users
 *
 * Populate choice-based fields (i.e. drop downs, radios, checkboxes) with data from WordPress users.
 *
 * The "query_args" parameter accepts any parameter accepted by WordPress' get_user() function. For a
 * full list of those parameters, please see:
 *
 *   http://codex.wordpress.org/Function_Reference/get_users
 *
 * The "choice_value" and "choice_label" parameters accept any WP User object property and any user
 * meta key wrapped in curly braces. A few examples:
 *
 * '{last_name}, {first_name}'           -> 'Smith, David'
 * '{user_login} / {ID}'     -> 'David Smith / 1'
 * '{user_email} - {my_custom_meta_key}' -> 'david@email.com - My Custom Meta Value'
 *
 * More details on WP User and default properties available here:
 *
 *   http://codex.wordpress.org/Class_Reference/WP_User
 *
 * @version	 1.0
 * @author    David Smith <david@gravitywiz.com>
 * @license   GPL-2.0+
 * @link      http://gravitywiz.com/...
 * @copyright 2013 Gravity Wiz
 */
class GW_Populate_Users {

    public function __construct( $args = array() ) {

        // make sure we're running the required minimum version of Gravity Forms
        if( ! property_exists( 'GFCommon', 'version' ) )
            return;

        // 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_id'             => false, // must be a choice-based field (drop down, radio, checkbox)
            'choice_value'         => '{ID}',
            'choice_label'         => '{display_name}',
            'query_args'           => array(),
            'default_current_user' => false
        ) );

        // time for hooks
        add_action( "gform_pre_render_{$this->_args['form_id']}",            array( $this, 'populate' ) );
        add_action( "gform_pre_submission_filter_{$this->_args['form_id']}", array( $this, 'populate' ) );

    }

    public function populate( $form ) {

        foreach( $form['fields'] as &$field ) {

            if( $field['id'] != $this->_args['field_id'] )
                continue;

            $users = $this->get_users( $this->_args['query_args'] );
            $choices = array();

            foreach( $users as $user ) {

                $value = $this->get_user_value( $user, $this->_args['choice_value'] );
                $label = $this->_args['choice_value'] != $this->_args['choice_label'] ? $this->get_user_value( $user, $this->_args['choice_label'] ) : $value;
                $selected = $this->_args['default_current_user'] == true && get_current_user_id() == $user->ID;

                $choices[] = array(
                    'text' => $label,
                    'value' => $value,
                    'isSelected' => $selected
                );

            }

            if( empty( $choices ) ) {
                $choices[] = array(
                    'text' => __( 'There are no options available currently.' ),
                    'value' => ''
                );
            }

            $field['choices'] = $choices;

            if( GFFormsModel::get_input_type( $field ) != 'checkbox' )
                continue;

            $field['inputs'] = array();

            foreach( $choices as $id => $choice ) {
                $field['inputs'][] = array(
                    'id' => sprintf( '%d.%d', $field['id'], $id + 1 ),
                    'label' => $choice['text'],
                    'name' => ''
                );
            }

        }

        return $form;
    }

    public function get_user_value( $user, $template ) {

        preg_match_all( '/{(.+?)}/', $template, $matches, PREG_SET_ORDER );
        foreach( $matches as $match ) {

            list( $tag, $property ) = $match;

            $template = str_replace( $tag, $user->get( $property ), $template );

        }

        return $template;
    }

    public function get_users( $query_args ) {

        $users = array();

        $roles = rgar( $query_args, 'role' );
        if( ! $roles ) {
            $roles = array( '' );
        } else if( ! is_array( $roles ) ) {
            $roles = array( $roles );
        }

        foreach( $roles as $role ) {

            $query_args['role'] = $role;
            $users = array_merge( $users, get_users( $query_args ) );

        }

        $orderby = rgar( $query_args, 'orderby' );
        if( $orderby && ! $this->is_default_orderby( $orderby ) )
            usort( $users, create_function( '$a, $b', 'return strnatcasecmp( $a->get( "' . $orderby . '" ), $b->get( "' . $orderby . '" ) );' ) );

        return $users;
    }

    public function is_default_orderby( $orderby ) {
        $default_orderby = array( 'ID', 'login', 'nicename', 'email', 'url', 'registered', 'display_name', 'post_count', 'meta_value' );
        return in_array( $orderby, $default_orderby );
    }

}

# Basic Configuration

new GW_Populate_Users( array(
    'form_id' => 535,
    'field_id' => 1
) );

# Full Configuration

new GW_Populate_Users( array(
    'form_id' => 535,
    'field_id' => 2,
    'choice_value' => '{user_login}', // i.e. dsmith
    'choice_label' => '{last_name}, {first_name}', // i.e. Smith, David
    'default_current_user' => true,
    'query_args' => array(
        'role' => array( 'Administrator', 'Author' ),
        'orderby' => 'last_name'
    )
) );