GW User Progress // Store WP user form progress as they fill out the form. Currently limited to checkboxes.
<?php
/**
* GW User Progress
*
* Store WP user form progress as they fill out the form. Currently limited to checkboxes.
*
*/
class GWUserProgress {
private $_args;
private static $_is_script_output;
public static $user_progress_key = 'gwup_user_progress';
public function __construct() {
add_action( 'gform_field_advanced_settings', array( $this, 'field_settings_ui' ), 10, 2 );
add_action( 'gform_editor_js', array( $this, 'field_settings_js' ) );
if( ! is_user_logged_in() )
return;
add_filter( 'gform_pre_render', array( $this, 'pre_render' ) );
add_action( 'wp_ajax_gwup_update_user_progress', array( $this, 'ajax_update_user_progress' ) );
add_action( 'wp_ajax_nopriv_gwup_update_user_progress', array( $this, 'ajax_update_user_progress' ) );
}
public function field_settings_ui( $position ) {
if( $position != 450 )
return;
?>
<li class="gwup-enable-setting field_setting">
<input type="checkbox" id="gwup-enable" value="1" onclick="SetFieldProperty( 'gwupEnable', this.checked )">
<label class="inline" for="gwup-enable">
<?php _e( 'Enable User Progress Tracking' ); ?>
</label>
</li>
<?php
}
public function field_settings_js() {
?>
<script type="text/javascript">
(function($) {
$(document).bind('gform_load_field_settings', function(event, field, form) {
$("#gwup-enable").attr( 'checked', field.gwupEnable == true );
});
fieldSettings['checkbox'] += ', .gwup-enable-setting';
})(jQuery);
</script>
<?php
}
public function pre_render( $form ) {
if( ! self::has_user_progress_enabled( $form ) )
return $form;
add_filter( 'gform_register_init_scripts', array( $this, 'register_init_script' ) );
$user_id = get_current_user_id();
foreach( $form['fields'] as &$field ) {
if( ! rgar( $field, 'gwupEnable' ) )
continue;
if( ! empty( $field['inputs'] ) ) {
foreach( $field['inputs'] as $index => &$input ) {
if( self::get_user_progress( $user_id, $form['id'], $input['id'] ) )
$field['choices'][$index]['isSelected'] = true;
}
} else {
// @TODO: add support for other field types
}
}
if( ! self::$_is_script_output )
$this->output_script();
return $form;
}
public function output_script() {
?>
<script type="text/javascript">
var gwup = {};
(function($){
window.gwup = function( args ) {
this.formId = args.formId;
this.inputIds = args.inputIds;
this.ajaxUrl = args.ajaxUrl;
this.userId = args.userId;
this.nonce = args.nonce;
this.init = function() {
var gwup = this;
for( i in this.inputIds ) {
var inputId = String( this.inputIds[i] ),
inputIdBits = inputId.split('.'),
inputHtmlId = '';
if( inputIdBits.length > 1 ) {
inputHtmlId = '#choice_' + inputIdBits[0] + '_' + inputIdBits[1];
} else {
// @TODO: untested...
inputHtmlId = '#input_' + this.formId + '_' + inputId;
}
$(inputHtmlId).data( 'inputId', inputId );
// @TODO: 'click' only supports checkboxes
$(document).on( 'click', inputHtmlId, function(){
var spinner = gwup.ajaxSpinner( $(this), gf_global.base_url + '/images/spinner.gif', 'border: 0 none !important;border-radius: 0 0 0 0;box-shadow: 0 0 0 0;float: left;margin: 2px 0 0 2px;' ),
elem = $(this);
elem.hide();
$.post( gwup.ajaxUrl, {
user_id: gwup.userId,
form_id: gwup.formId,
input_id: $(this).data( 'inputId' ),
value: $(this).is(':checked') ? 1 : 0, // @TODO: only supports checkboxes
action: 'gwup_update_user_progress',
nonce: gwup.nonce
}, function( response ) {
spinner.destroy();
elem.show();
} );
});
}
}
this.ajaxSpinner = function(elem, imageSrc, inlineStyles) {
var imageSrc = typeof imageSrc == 'undefined' ? '/images/ajax-loader.gif': imageSrc;
var inlineStyles = typeof inlineStyles != 'undefined' ? inlineStyles : '';
this.elem = elem;
this.image = '<img class="gfspinner" src="' + imageSrc + '" style="' + inlineStyles + '" />';
this.init = function() {
this.spinner = jQuery(this.image);
jQuery(this.elem).after(this.spinner);
return this;
}
this.destroy = function() {
jQuery(this.spinner).remove();
}
return this.init();
}
this.init();
}
})(jQuery);
</script>
<?php
self::$_is_script_output = true;
}
public function register_init_script( $form ) {
// remove this function from the filter otherwise it will be called for every other form on the page
remove_filter( 'gform_register_init_scripts', array( $this, 'register_init_script' ) );
$args = array(
'formId' => $form['id'],
'inputIds' => self::get_input_ids( $form ),
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'userId' => get_current_user_id(),
'nonce' => wp_create_nonce( 'gwup_update_user_progress' )
);
$script = "new gwup(" . json_encode( $args ) . ");";
GFFormDisplay::add_init_script( $form['id'], 'gwup_' . $this->_args['form_id'], GFFormDisplay::ON_PAGE_RENDER, $script );
}
public function ajax_update_user_progress() {
$user_id = rgpost( 'user_id' );
$form_id = rgpost( 'form_id' );
$input_id = rgpost( 'input_id' );
$value = rgpost( 'value' );
if( ! wp_verify_nonce( rgpost( 'nonce' ), 'gwup_update_user_progress' ) || get_current_user_id() != $user_id )
die();
die( self::update_user_progress( $user_id, $form_id, $input_id, $value ) );
}
public static function has_user_progress_enabled( $form ) {
foreach( $form['fields'] as $field ) {
if( rgar( $field, 'gwupEnable' ) )
return true;
}
return false;
}
public static function get_user_progress( $user_id, $form_id = false, $input_id = false ) {
$cache_key = self::$user_progress_key . '-' . $user_id;
$user_progress = wp_cache_get( $cache_key, 'gwup' );
if( empty( $user_progress ) ) {
$user_progress = get_user_meta( $user_id, self::$user_progress_key, true );
wp_cache_set( $cache_key, $user_progress, 'gwup' );
}
if( $input_id ) {
$user_progress = rgars( $user_progress, "{$form_id}/{$input_id}" );
} else if( $form_id ) {
$user_progress = rgar( $user_progress, $form_id );
}
return $user_progress;
}
public static function update_user_progress( $user_id, $form_id, $input_id, $value ) {
$user_progress = self::get_user_progress( $user_id );
if( ! is_array( $user_progress ) )
$user_progress = array();
if( ! isset( $user_progress[$form_id] ) )
$user_progress[$form_id] = array();
$user_progress[$form_id][$input_id] = $value;
$result = update_user_meta( $user_id, self::$user_progress_key, $user_progress );
return $result;
}
public static function get_input_ids( $form ) {
$input_ids = array();
foreach( $form['fields'] as $field ) {
if( ! rgar( $field, 'gwupEnable' ) )
continue;
if( ! empty( $field['inputs'] ) ) {
foreach( $field['inputs'] as $input ) {
$input_ids[] = $input['id'];
}
} else {
$input_ids[] = $field['id'];
}
}
return $input_ids;
}
}
new GWUserProgress();