Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save phillipwilhelm/a0cad0fa17fe0a25545ed142b7b201ad to your computer and use it in GitHub Desktop.
Save phillipwilhelm/a0cad0fa17fe0a25545ed142b7b201ad to your computer and use it in GitHub Desktop.
Gravity Wiz // Gravity Forms // Multi-form Entry Exporter
<?php
/**
* Gravity Wiz // Gravity Forms // Multi-form Entry Exporter
*
* Allows you create a custom entry export containing fields from multiple forms. The custom export
* is then displayed in the "Form" drop down menu in a "Multi-form Export" option group.
*
* @version 1.0
* @author David Smith <david@gravitywiz.com>
* @license GPL-2.0+
* @link http://gravitywiz.com/...
* @copyright 2014 Gravity Wiz
*
* Plugin Name: Gravity Forms Multi-form Entry Exporter
* Plugin URI: http://gravitywiz.com/
* Version: 1.0
* Description: Allows you create a custom entry export containing fields from multiple forms.
* Author: David Smith <david@gravitywiz.com>
* Author URI: http://gravitywiz.com/
* License: GPL2
*/
class GW_Multi_Form_Entry_Exporter_Interface {
private $exports = array();
private static $instance = null;
public static function get_instance() {
if( self::$instance === null )
self::$instance = new self;
return self::$instance;
}
protected function __construct() {
add_filter( 'init', array( $this, 'initialize' ), 9 );
}
public function initialize() {
if( empty( $this->exports ) )
return;
add_action( 'admin_footer-forms_page_gf_export', array( $this, 'output_export_markup' ) );
$this->maybe_export();
}
public function register_export( $export ) {
$name = $export->_args['name'];
if( array_key_exists( $name, $this->exports ) )
return new WP_Error( 'name_already_registered', __( 'This export name has already been registered.' ) );
$this->exports[$name] = $export;
return true;
}
public function maybe_export() {
if( ! rgpost( 'gwmfee_flag' ) )
return;
check_admin_referer( 'rg_start_export', 'rg_start_export_nonce' );
$export = rgar( $this->exports, $_POST['export_form'] );
if( ! $export )
return;
if( ! empty( $export->_args['form_ids'] ) ) {
$export->_args['columns'] = $this->get_auto_columns( $export );
}
$filename = sanitize_title_with_dashes( $export->_args['name'] ) . '-' . gmdate( 'Y-m-d', GFCommon::get_local_timestamp( time() ) ) . '.csv';
$charset = get_option( 'blog_charset' );
header( 'Content-Description: File Transfer' );
header( "Content-Disposition: attachment; filename={$filename}" );
header( "Content-Type: text/plain; charset={$charset}", true);
$buffer_length = ob_get_length();
if( $buffer_length > 1 )
ob_clean();
$this->export( $export );
die();
}
public function output_export_markup() {
$export_names = $this->get_exports_arg( 'name' );
?>
<script type="text/javascript">
jQuery( document ).ready( function( $ ) {
var exports = <?php echo json_encode( $export_names ); ?>,
formSelect = $( '#export_form' ),
placeholderOption = formSelect.find( 'option:first-child' ),
optionsString = '';
$.each( exports, function( i, exportName ) {
optionsString += '<option value="' + exportName + '">' + exportName + '</option>';
} );
var placeholderOptionHTML = placeholderOption[0].outerHTML;
placeholderOption.remove();
formSelect.html(
placeholderOptionHTML +
'<optgroup label="Multi-form Exports" id="gwmfee_group">' + optionsString + '</optgroup>' +
'<optgroup label="Forms">' + formSelect.html() + '</optgroup>'
);
formSelect.attr( 'onchange', 'if( ! gwmfeeSelectExport( this ) ) { ' + formSelect.attr( 'onchange' ) + ' };' );
} );
function gwmfeeSelectExport( selectElem ) {
var optionElem = jQuery( selectElem ).find( 'option:selected' ),
isMultiFormExport = optionElem.parents( 'optgroup#gwmfee_group' ).length > 0,
gwmfeeFlag = jQuery( '#gwmfee_flag' ),
exportForm = jQuery( '#gform_export' ),
shimCheckbox = jQuery( '#gwmfee_shim' );
if( ! isMultiFormExport ) {
gwmfeeFlag.remove();
shimCheckbox.remove();
return false;
}
// hide all inputs in case they are already open
jQuery( '#export_field_container, #export_filter_container, #export_date_container, #export_submit_container' ).hide();
// show date and submit inputs
jQuery( '#export_date_container, #export_submit_container' ).show();
if( gwmfeeFlag.length <= 0 ) {
exportForm.append( '<input type="hidden" value="1" name="gwmfee_flag" id="gwmfee_flag" />');
exportForm.append( '<input type="checkbox" value="1" checked="checked" class="gform_export_field" id="gwmfee_shim" style="display:none;" />' );
}
// initialize datepicker functionality for date range inputs
jQuery( '#export_date_start, #export_date_end' ).datepicker( { dateFormat: 'yy-mm-dd', changeMonth: true, changeYear: true } );
return true;
}
</script>
<?php
}
public function export( $export ) {
require_once( GFCommon::get_base_path() . '/export.php' );
$start_date = empty( $_POST['export_date_start'] ) ? '' : GFExport::get_gmt_date( $_POST['export_date_start'] . ' 00:00:00' );
$end_date = empty( $_POST['export_date_end'] ) ? '' : GFExport::get_gmt_date( $_POST['export_date_end'] . ' 23:59:59' );
$search_criteria['status'] = 'active';
$search_criteria['field_filters'] = GFCommon::get_field_filters_from_post();
if( ! empty( $start_date ) )
$search_criteria['start_date'] = $start_date;
if( ! empty( $end_date ) )
$search_criteria['end_date'] = $end_date;
$sorting = array(
'key' => 'date_created',
'direction' => 'DESC',
'type' => 'info'
);
$form_ids = $this->get_export_form_ids( $export );
$columns = $export->_args['columns'];
$data = array();
$entry_count = GFAPI::count_entries( $form_ids, $search_criteria );
$page_size = 100;
$offset = 0;
// adding BOM marker for UTF-8
$lines = chr( 239 ) . chr( 187 ) . chr( 191 );
// set the separater
$separator = apply_filters( 'gform_export_separator', ',', $form_ids[0] );
// only applies to list fields, not currently supported
$field_rows = array(); //self::get_field_row_count( $form, $fields, $entry_count);
// headers
$data[0] = array();
foreach( $columns as $column_name => $fields ) {
$data[0][] = $column_name;
}
// paging through results for memory issues
while( $entry_count > 0 ) {
$paging = array(
'offset' => $offset,
'page_size' => $page_size
);
$entries = GFAPI::get_entries( $form_ids, $search_criteria, $sorting, $paging );
$entries = apply_filters( 'gform_leads_before_export', $entries, array(), $paging );
foreach( $entries as $entry ) {
$row = array();
foreach( $columns as $column_name => $column ) {
$form_id = $entry['form_id'];
$field_id = $this->get_column_field_id( $export, $column_name, $form_id );
$value = '';
$form = GFAPI::get_form( $form_id );
if( ! $form ) {
$row[$column_name] = $value;
continue;
}
switch( $field_id ) {
case 'date_created':
$entry_gmt_time = mysql2date( 'G', $entry['date_created'] );
$entry_local_time = GFCommon::get_local_timestamp( $entry_gmt_time );
$value = date_i18n( 'Y-m-d H:i:s', $entry_local_time, true );
break;
default:
$long_text = '';
if( strlen( rgar( $entry, $field_id ) ) >= ( GFORMS_MAX_FIELD_LENGTH - 10 ) )
$long_text = GFFormsModel::get_field_value_long( $entry, $field_id, $form );
$value = ! empty( $long_text ) ? $long_text : rgar( $entry, $field_id );
$field = GFFormsModel::get_field( $form, $field_id );
$input_type = GFFormsModel::get_input_type( $field );
if($input_type == "checkbox"){
$value = GFFormsModel::is_checkbox_checked( $field_id, GFCommon::get_label( $field, $field_id ), $entry, $form );
if($value === false)
$value = "";
}
else if($input_type == "fileupload" && rgar($field,"multipleFiles") ){
$value = !empty($value) ? implode(" , ", json_decode($value, true)) : "";
}
$value = apply_filters( 'gform_export_field_value', $value, $form_id, $field_id, $entry );
break;
}
$row[$column_name] = $value;
}
$data[] = $row;
}
$offset += $page_size;
$entry_count -= $page_size;
}
foreach( $data as &$row ) {
$row = implode( $separator, array_map( array( $this, 'prepare_export_value' ), $row ) );
}
$output = implode( "\n", $data );
if ( ! seems_utf8( $output ) )
$lines = utf8_encode( $output );
echo $output;
}
public function get_exports_arg( $arg ) {
$args = array();
foreach( $this->exports as $export ) {
$args[] = rgar( $export->_args, $arg );
}
return array_filter( $args );
}
public function get_export_form_ids( $export ) {
$form_ids = array();
foreach( $export->_args['columns'] as $column ) {
foreach( $column as $field_data ) {
list( $form_id, $field_id ) = $field_data;
$form_ids[] = $form_id;
}
}
return array_unique( $form_ids );
}
public function get_column_field_id( $export, $column_name, $form_id ) {
foreach( $export->_args['columns'] as $_column_name => $column ) {
if( $_column_name != $column_name )
continue;
foreach( $column as $field ) {
list( $_form_id, $field_id ) = $field;
if( $_form_id == $form_id )
return $field_id;
}
}
return false;
}
public function prepare_export_value( $value ) {
$value = maybe_unserialize( $value );
if( is_array( $value ) )
$value = implode( '|', $value );
$value = str_replace( '"', '""', $value );
return "\"{$value}\"";
}
public function get_auto_columns( $export ) {
$form_ids = $export->_args['form_ids'];
$columns = array();
foreach( $form_ids as $form_id ) {
$form = GFAPI::get_form( $form_id );
if( ! $form ) {
continue;
}
$current_form_column_names = array();
foreach( $form['fields'] as $field ) {
// @todo: add support for multi-input fields
// field's admin label is default column name, field label used if no admin label provided
$column_name = rgar( $field, 'adminLabel' );
if( ! $column_name ) {
$column_name = GFCommon::get_label( $field );
}
// if multiple fields on the form have the same name, skip them
if( in_array( $column_name, $current_form_column_names ) ) {
continue;
}
$current_form_column_names[] = $column_name;
if( ! isset( $columns[ $column_name ] ) ) {
$columns[ $column_name ] = array();
}
$columns[ $column_name ][] = array( $form_id, $field['id'] );
}
}
return $columns;
}
public function enqueue_admin_scripts() {
if( rgget( 'page' ) != 'gf_export' || rgget( 'view' ) != 'gw_multi_form_entry_exporter' )
return;
wp_enqueue_script( 'jquery-ui-datepicker' );
}
public function add_exporter_menu_item( $menu_items ) {
$menu_items[] = array(
'name' => 'gw_multi_form_entry_exporter',
'label' => __( 'Multi Form Entry Exporter' )
);
return $menu_items;
}
public function display_exporter_page() {
GFExport::page_header();
?>
<style type="text/css">
input,
textarea {
outline-style: none;
font-family: sans-serif;
font-size: inherit;
padding: 3px 5px;
}
</style>
<p class="textleft">
<?php _e( 'You can register a multi form entry export by creating a new instance of the <strong>GW_Multi_Form_Entry_Exporter</strong> class.' ); ?>
</p>
<div class="hr-divider"></div>
<form id="gw_multi_form_entry_exporter" method="post">
<?php echo wp_nonce_field( 'gw_mfee_export', 'gw_mfee_export' ); ?>
<table class="form-table">
<tr>
<th scope="row">
<label for="gwmfee_export"><?php _e( 'Select an Export' ); ?></label>
<?php gform_tooltip( 'gwmfee_export' ); ?>
</th>
<td>
<select id="gwmfee_export" name="gwmfee_export" onchange="gwSelectExport( jQuery( this ).val() );">
<option value=""><?php _e( 'Select an export' ); ?></option>
<?php foreach( $this->exports as $export ): ?>
<option value="<?php echo $export->_args['name']; ?>"><?php echo $export->_args['name']; ?></option>
<?php endforeach; ?>
</select>
</td>
</tr>
<tr id="gwmfee_export_date_container" valign="top" style="display: none;">
<th scope="row">
<label for="gwmfee_export_date_range"><?php _e( 'Select Date Range', 'gravityforms' ); ?></label>
<?php gform_tooltip( 'gwmfee_export_date_range' ) ?>
</th>
<td>
<div>
<span style="width:150px; float:left;">
<input type="text" id="gwmfee_export_date_start" name="gwmfee_export_date_start" style="width:90%" />
<label for="gwmfee_export_date_start" style="display:block;font-size:0.9em;">
<strong><?php _e( 'Start', 'gravityforms' ); ?></strong>
</label>
</span>
<span style="width:150px; float:left;">
<input type="text" id="gwmfee_export_date_end" name="gwmfee_export_date_end" style="width:90%"/>
<label for="gwmfee_export_date_end" style="display:block;font-size:0.9em;">
<strong><?php _e( 'End', 'gravityforms' ); ?></strong>
</label>
</span>
<p class="description" style="clear:both;"><?php _e( 'Date Range is optional, if no date range is selected all entries will be exported.', 'gravityforms' ); ?></p>
</div>
</td>
</tr>
</table>
<input type="submit" name="gwmfee_export_entries" value="<?php _e( 'Download Export File', 'gravityforms' ); ?>" class="button button-large button-primary"/>
</form>
<script type="text/javascript">
function gwSelectExport( exportName ) {
var dateRangeElem = jQuery( '#gwmfee_export_date_container' );
if( exportName != '' ) {
dateRangeElem.show();
} else {
dateRangeElem.hide();
}
}
jQuery( document ).ready( function( $ ) {
$( '#gwmfee_export_date_start, #gwmfee_export_date_end' ).datepicker( { dateFormat: 'yy-mm-dd', changeMonth: true, changeYear: true } );
} );
</script>
<?php
GFExport::page_footer();
}
}
function gw_multi_form_entry_exporter_interface() {
return GW_Multi_Form_Entry_Exporter_Interface::get_instance();
}
class GW_Multi_Form_Entry_Exporter {
public function __construct( $args = array() ) {
// make sure we're running the required minimum version of Gravity Forms
if( ! property_exists( 'GFCommon', 'version' ) || ! version_compare( GFCommon::$version, '1.8', '>=' ) )
return;
// set our default arguments, parse against the provided arguments, and store for use throughout the class
$this->_args = wp_parse_args( $args, array(
'name' => false,
'columns' => array(),
'date_range' => array(),
'form_ids' => array()
) );
gw_multi_form_entry_exporter_interface()->register_export( $this );
}
}
# Configuration
// if you are running as a plugin, add the configuration to your theme's functions.php file
new GW_Multi_Form_Entry_Exporter( array(
'name' => 'Boom Boom',
'columns' => array(
'Big Choice' => array(
array( 525, 1 ),
array( 449, 1 )
),
'Other Choice' => array(
array( 525, 4 ),
array( 449, 4 )
)
)
) );
new GW_Multi_Form_Entry_Exporter( array(
'name' => 'No Love For the Wicked'
) );
new GW_Multi_Form_Entry_Exporter( array(
'name' => 'Auto Boom',
'form_ids' => array( 449, 525 )
) );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment