Commit 6d18b1a3 authored by Kevin Stover's avatar Kevin Stover

Merge branch 'release/v2.7.6'

parents 32952eaf 8bea0d57
......@@ -4,7 +4,7 @@
Tags: form, forms, contact form, custom form, form builder, form creator, form manager, form creation, contact forms, custom forms, forms builder, forms creator, forms manager, forms creation, form administration,
Requires at least: 3.6
Tested up to: 3.9
Stable tag: 2.6.5
Stable tag: 2.7.6
License: GPLv2 or later
Forms created with a simple drag and drop interface. Contact forms, Email collection forms, or any other form you want on your WordPress site.
......
jQuery(document).ready(function($) {
var progressbar = $( "#progressbar" ),
progressLabel = $( ".progress-label" );
progressbar.progressbar({
value: false,
change: function() {
var value = parseInt( progressbar.progressbar( "value" ) );
if ( value == 90 ) {
nfProgressBar.currentLabel = 1;
} else if ( value % 10 == 0 ) {
nfProgressBar.changeTextLabel();
}
var text = nfProgressBar.getTextLabel();
progressLabel.text( text + " " + progressbar.progressbar( "value" ) + "%" );
},
complete: function() {
progressLabel.text( "Complete!" );
}
});
if ( nfProcessingAction != 'none' ) {
var nfProgressBar = {
labels: {
0: 'Lacing Our Tabis',
1: 'Cleaning The Dojo',
2: 'Doing Splits',
3: 'Buffing Bo Staff',
4: 'Intimidating Gaze',
5: 'Sparring',
6: 'Packing Smoke Bombs',
7: 'Polishing Shuriken',
8: 'Throwing Sais',
9: 'Calling Our Mom',
10: 'Practicing Katas',
11: 'Swinging Nunchucks',
12: 'Sharpening Swords',
13: 'Ironing Ninja Gi',
14: 'Eating Breakfast',
15: 'Cutting Stuff',
16: 'Doing Dishes',
17: 'Climbing Walls'
},
getTextLabel: function() {
var label = this.labels[ this.currentLabel ];
return label;
},
changeTextLabel: function() {
var max = Object.keys( this.labels ).length - 1;
var labelNum = Math.floor( Math.random() * ( max - 2 + 1 ) ) + 2;
this.currentLabel = labelNum;
},
currentLabel: 0
};
var nfProcessing = {
setup: function() {
// Figure out when we're going to change the size of the bar.
this.interval = Math.floor( 100 / parseInt( this.totalSteps ) );
},
process: function() {
$.post( ajaxurl, { step: this.step, total_steps: nfProcessing.totalSteps, args: this.args, action: nfProcessingAction }, function( response ) {
response = $.parseJSON( response );
nfProcessing.step = response.step;
nfProcessing.totalSteps = response.total_steps;
nfProcessing.args = response.args;
if ( nfProcessing.runSetup == 1 ) {
nfProcessing.setup();
nfProcessing.runSetup = 0;
}
if ( ! response.complete ) {
nfProcessing.progress();
nfProcessing.process();
} else {
progressbar.progressbar( "value", 100 );
if ( typeof response.redirect != 'undefined' && response.redirect != '' ) {
document.location.href = response.redirect;
}
}
});
},
progress: function() {
var val = progressbar.progressbar( "value" ) || 0;
progressbar.progressbar( "value", val + this.interval );
},
step: 'loading',
totalSteps: 0,
runSetup: 1,
interval: 0,
args: nfProcessingArgs,
}
nfProcessing.process();
}
});
\ No newline at end of file
<?php
class NF_Download_All_Subs extends NF_Step_Processing {
function __construct() {
$this->action = 'download_all_subs';
parent::__construct();
}
public function loading() {
$form_id = isset( $this->args['form_id'] ) ? absint( $this->args['form_id'] ) : 0;
if ( empty( $form_id ) ) {
return array( 'complete' => true );
}
$sub_count = nf_get_sub_count( $form_id );
if( empty( $this->total_steps ) || $this->total_steps <= 1 ) {
$this->total_steps = round( ( $sub_count / 250 ), 0 ) + 2;
}
$args = array(
'total_steps' => $this->total_steps,
);
$this->args['filename'] = $this->random_filename( 'all-subs' );
update_user_option( get_current_user_id(), 'nf_download_all_subs_filename', $this->args['filename'] );
$this->redirect = add_query_arg( array( 'download_all' => $this->args['filename'] ), $this->args['redirect'] );
return $args;
}
public function step() {
$exported_subs = get_user_option( get_current_user_id(), 'nf_download_all_subs_ids' );
if ( ! is_array( $exported_subs ) ) {
$exported_subs = array();
}
$previous_name = get_user_option( get_current_user_id(), 'nf_download_all_subs_filename' );
if ( $previous_name ) {
$this->args['filename'] = $previous_name;
}
$args = array(
'posts_per_page' => 250,
'paged' => $this->step,
'post_type' => 'nf_sub',
'meta_query' => array(
array(
'key' => '_form_id',
'value' => $this->args['form_id'],
),
),
);
$subs_results = get_posts( $args );
if ( is_array( $subs_results ) && ! empty( $subs_results ) ) {
$upload_dir = wp_upload_dir();
$file_path = trailingslashit( $upload_dir['path'] ) . $this->args['filename'] . '.csv';
$myfile = fopen( $file_path, 'a' ) or die( 'Unable to open file!' );
$x = 0;
$export = '';
foreach ( $subs_results as $sub ) {
$sub_export = Ninja_Forms()->sub( $sub->ID )->export( true );
if ( $x > 0 || $this->step > 1 ) {
$sub_export = substr( $sub_export, strpos( $sub_export, "\n" ) + 1 );
}
if ( ! in_array( $sub->ID, $exported_subs ) ) {
$export .= $sub_export;
$exported_subs[] = $sub->ID;
}
$x++;
}
fwrite( $myfile, $export );
fclose( $myfile );
}
update_user_option( get_current_user_id(), 'nf_download_all_subs_ids', $exported_subs );
}
public function complete() {
delete_user_option( get_current_user_id(), 'nf_download_all_subs_ids' );
delete_user_option( get_current_user_id(), 'nf_download_all_subs_filename' );
}
/**
* Add an integar to the end of our filename to make sure it is unique
*
* @access public
* @since 2.7.6
* @return $filename
*/
public function random_filename( $filename ) {
$upload_dir = wp_upload_dir();
$file_path = trailingslashit( $upload_dir['path'] ) . $filename . '.csv';
if ( file_exists ( $file_path ) ) {
for ($x = 0; $x < 999 ; $x++) {
$tmp_name = $filename . '-' . $x;
$tmp_path = trailingslashit( $upload_dir['path'] );
if ( file_exists( $tmp_path . $tmp_name . '.csv' ) ) {
$this->random_filename( $tmp_name );
break;
} else {
$this->filename = $tmp_name;
break;
}
}
}
return $filename;
}
}
\ No newline at end of file
<?php
/**
* Class for performing actions incrementally. Internally used for converting submissions, exporting submissions, etc.
* Very useful when interacting with large amounts of data.
*
* @package Ninja Forms
* @subpackage Classes/Step Processing
* @copyright Copyright (c) 2014, WPNINJAS
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 2.7.4
*/
class NF_Step_Processing
{
/**
* @var action
*/
var $action = '';
/**
* @var step
*/
var $step = '';
/**
* @var total_steps
*/
var $total_steps = '';
/**
* @var redirect
*/
var $redirect = '';
/**
* @var args
*/
var $args = array();
/**
* Get things rolling
*
* @since 2.7.4
* @return void
*/
function __construct() {
//Bail if we aren't in the admin.
if ( ! is_admin() )
return false;
ignore_user_abort( true );
if ( ! nf_is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) {
set_time_limit( 0 );
}
add_action( 'wp_ajax_nf_' . $this->action, array( $this, 'processing' ) );
}
/**
* Process our request.
* Call the appropriate loading or step functions.
*
* @since 2.7.6
* @return void
*/
public function processing() {
// Get our passed arguments. These come from the querysting of the processing page.
if ( isset ( $_REQUEST['args'] ) ) {
$this->args = $_REQUEST['args'];
if ( isset ( $this->args['redirect'] ) ) {
$this->redirect = $this->args['redirect'];
}
} else {
$this->args = array();
}
// Get our current step.
$this->step = isset ( $_REQUEST['step'] )? $_REQUEST['step'] : 'loading';
// Get our total steps
$this->total_steps = isset ( $_REQUEST['total_steps'] )? $_REQUEST['total_steps'] : 0;
// If our step is loading, then we need to return how many total steps there are along with the next step, which is 1.
if ( 'loading' == $this->step ) {
$return = $this->loading();
if ( ! isset ( $return['step'] ) ) {
$saved_step = get_user_option( 'nf_step_processing_' . $this->action . '_step' );
if ( ! empty ( $saved_step ) ) {
$this->step = $saved_step;
} else {
$this->step = 1;
}
$return['step'] = $this->step;
}
if ( ! isset ( $return['complete'] ) ) {
$return['complete'] = false;
}
} else { // We aren't on the loading step, so do our processing.
$return = $this->step();
if ( ! isset ( $return['step'] ) ) {
$this->step++;
$return['step'] = $this->step;
}
if ( ! isset ( $return['complete'] ) ) {
if ( $this->step > $this->total_steps ) {
$complete = true;
} else {
$complete = false;
}
$return['complete'] = $complete;
}
$return['total_steps'] = $this->total_steps;
}
$user_id = get_current_user_id();
if ( $return['complete'] ) {
// Delete our step option
delete_user_option( $user_id, 'nf_step_processing_' . $this->action . '_step' );
// Set our redirect variable.
$return['redirect'] = $this->redirect;
// Run our complete function
$this->complete();
} else {
// Save our current step so that we can resume if necessary
update_user_option( $user_id, 'nf_step_processing_' . $this->action . '_step', $this->step );
}
if ( isset ( $this->redirect ) && ! empty ( $this->redirect ) ) {
$this->args['redirect'] = $this->redirect;
}
$return['args'] = $this->args;
echo json_encode( $return );
die();
}
/**
* Run our loading process.
* This function should be overwritten in child classes.
*
* @since 2.7.4
* @return array $args
*/
public function loading() {
// This space left intentionally blank.
}
/**
* This function is called for every step.
* This function should be overwritten in child classes.
*
* @since 2.7.4
* @return array $args
*/
public function step() {
// This space left intentionally blank.
}
/**
* This function is called for every step.
* This function should be overwritten in child classes.
*
* @since 2.7.4
* @return array $args
*/
public function complete() {
// This space left intentionally blank.
}
}
\ No newline at end of file
......@@ -16,6 +16,8 @@ class NF_Subs_CPT {
var $screen_options;
var $filename;
/**
* Get things started
*
......@@ -28,9 +30,6 @@ class NF_Subs_CPT {
// Register our submission custom post type.
add_action( 'init', array( $this, 'register_cpt' ), 5 );
// Listen for the "download all" button.
add_action( 'load-edit.php', array( $this, 'export_listen' ) );
// Populate our field settings var
add_action( 'current_screen', array( $this, 'setup_fields' ) );
......@@ -83,6 +82,9 @@ class NF_Subs_CPT {
// Load any custom screen options
add_filter( 'screen_settings', array( $this, 'output_screen_options' ), 10, 2 );
// Listen for our exports button.
add_action( 'load-edit.php', array( $this, 'export_listen' ) );
}
......@@ -178,6 +180,7 @@ class NF_Subs_CPT {
add_action( 'admin_print_styles', array( $this, 'load_css' ) );
// Remove the publish box from the submission editing page.
remove_meta_box( 'submitdiv', 'nf_sub', 'side' );
}
/**
......@@ -536,20 +539,28 @@ class NF_Subs_CPT {
$date_format = $plugin_settings['date_format'];
if ( !empty ( $_GET['begin_date'] ) ) {
$begin_date = nf_get_begin_date( $_GET['begin_date'] );
$begin_date = nf_get_begin_date( $_GET['begin_date'] )->format("Y-m-d G:i:s");
} else {
$begin_date = '';
}
if ( !empty ( $_GET['end_date'] ) ) {
$end_date = nf_get_end_date( $_GET['end_date'] );
$end_date = nf_get_end_date( $_GET['end_date'] )->format("Y-m-d G:i:s");
} else {
$end_date = '';
}
if ( $begin_date > $end_date ) {
$begin_date = '';
$end_date = '';
$begin_date = new DateTime( $begin_date );
$end_date = new DateTime( $end_date );
$end_date_temp = $begin_date;
$begin_date_temp = $end_date;
$begin_date = $begin_date_temp;
$end_date = $end_date_temp;
$_GET['begin_date'] = $begin_date->format('m/d/Y');
$_GET['end_date'] = $end_date->format('m/d/Y');
$begin_date = $begin_date->format("Y-m-d G:i:s");
$end_date = $end_date->format("Y-m-d G:i:s");
}
if ( ! isset ( $qv['date_query'] ) ) {
......@@ -676,7 +687,10 @@ class NF_Subs_CPT {
*/
public function bulk_admin_footer() {
global $post_type;
if ( ! is_admin() )
return false;
if( $post_type == 'nf_sub' && isset ( $_REQUEST['post_status'] ) && $_REQUEST['post_status'] == 'all' ) {
?>
<script type="text/javascript">
......@@ -693,6 +707,24 @@ class NF_Subs_CPT {
},5000);
<?php
}
if ( isset ( $_REQUEST['form_id'] ) && $_REQUEST['form_id'] != '' ) {
$redirect = urlencode( remove_query_arg( array( 'download_all', 'download_file' ) ) );
$url = admin_url( 'admin.php?page=nf-processing&action=download_all_subs&form_id=' . $_REQUEST['form_id'] . '&redirect=' . $redirect );
?>
var button = '<a href="<?php echo $url; ?>" class="button-secondary nf-download-all"><?php echo __( 'Download All Submissions', 'ninja-forms' ); ?></a>';
jQuery( '#doaction2' ).after( button );
<?php
}
if ( isset ( $_REQUEST['download_all'] ) && $_REQUEST['download_all'] != '' ) {
$redirect = add_query_arg( array( 'download_file' => $_REQUEST['download_all'] ) );
$redirect = remove_query_arg( array( 'download_all' ), $redirect );
?>
document.location.href = "<?php echo $redirect; ?>";
<?php
}
?>
});
</script>
......@@ -1124,13 +1156,19 @@ class NF_Subs_CPT {
}
/**
* Download all submissions within a date range
* Listen for exporting subs
*
* @access public
* @since 2.7
* @since 2.7.3
* @return void
*/
public function export_listen() {
// Bail if we aren't in the admin
if ( ! is_admin() )
return false;
if ( ! isset ( $_REQUEST['form_id'] ) || empty ( $_REQUEST['form_id'] ) )
return false;
if ( isset ( $_REQUEST['export_single'] ) && ! empty( $_REQUEST['export_single'] ) )
Ninja_Forms()->sub( $_REQUEST['export_single'] )->export();
......@@ -1138,8 +1176,41 @@ class NF_Subs_CPT {
if ( isset ( $_REQUEST['action'] ) && $_REQUEST['action'] == 'export' )
Ninja_Forms()->subs()->export( $_REQUEST['post'] );
if ( isset ( $_REQUEST['submit'] ) && $_REQUEST['submit'] == __( 'Download All', 'ninja-forms' ) && isset ( $_REQUEST['form_id'] ) ) {
//$subs = Ninja_Forms()->form( 241 )->get_subs();
if ( isset ( $_REQUEST['download_file'] ) && ! empty( $_REQUEST['download_file'] ) ) {
// Open our download all file
$filename = $_REQUEST['download_file'];
$upload_dir = wp_upload_dir();
$file_path = trailingslashit( $upload_dir['path'] ) . $filename . '.csv';
if ( file_exists( $file_path ) ) {
$myfile = file_get_contents ( $file_path );
} else {
$redirect = remove_query_arg( array( 'download_file', 'download_all' ) );
wp_redirect( $redirect );
die();
}
unlink( $file_path );
$form_name = Ninja_Forms()->form( $_REQUEST['form_id'] )->get_setting( 'form_title' );
$form_name = sanitize_title( $form_name );
$today = date( 'Y-m-d', current_time( 'timestamp' ) );
$filename = apply_filters( 'nf_download_all_filename', $form_name . '-all-subs-' . $today );
header( 'Content-type: application/csv');
header( 'Content-Disposition: attachment; filename="'.$filename .'.csv"' );
header( 'Pragma: no-cache');
header( 'Expires: 0' );
echo $myfile;
die();
}
}
}
\ No newline at end of file
......@@ -127,11 +127,11 @@ class NF_Subs {
}
if( isset( $args['begin_date'] ) AND $args['begin_date'] != '') {
$query_args['date_query']['after'] = nf_get_begin_date( $args['begin_date'] );
$query_args['date_query']['after'] = nf_get_begin_date( $args['begin_date'] )->format("Y-m-d G:i:s");
}
if( isset( $args['end_date'] ) AND $args['end_date'] != '' ) {
$query_args['date_query']['before'] = nf_get_end_date( $args['end_date'] );
$query_args['date_query']['before'] = nf_get_end_date( $args['end_date'] )->format("Y-m-d G:i:s");
}
$subs = new WP_Query( $query_args );;
......@@ -173,10 +173,16 @@ class NF_Subs {
$label_array = array();
// Get our Form ID.
$form_id = Ninja_Forms()->sub( $sub_ids[0] )->form_id;
// Get our list of fields.
$fields = nf_get_fields_by_form_id( $form_id );
// Add our sequential number.
$label_array[0]['_seq_num'] = __( '#', 'ninja-forms' );
// Add our "Date" label.
$label_array[0][] = __( 'Date Submitted', 'ninja-forms' );
$label_array[0]['_date_submitted'] = __( 'Date Submitted', 'ninja-forms' );
foreach ( $fields as $field_id => $field ) {
// Get our field type
$field_type = $field['type'];
......@@ -187,6 +193,7 @@ class NF_Subs {
} else {
$process_field = false;
}
// If this field's "process_field" is set to true, then add its label to the array.
if ( $process_field ) {
if ( isset ( $field['data']['admin_label'] ) && $field['data']['admin_label'] != '' ) {
......@@ -208,10 +215,6 @@ class NF_Subs {
$x = 0;
// Loop through our submissions and create a new row for each one.
foreach ( $sub_ids as $sub_id ) {
// Get the date of our submission.
$date = strtotime( Ninja_Forms()->sub( $sub_id )->date_submitted );
// The first item is our date field.
$value_array[ $x ][] = date( $date_format, $date );
foreach ( $label_array[0] as $field_id => $label ) {
// Make sure we aren't working with our date field, which will always have a field id of 0.
if ( $field_id !== 0 ) {
......@@ -219,6 +222,13 @@ class NF_Subs {
if ( is_numeric( $field_id ) ) {
// We're working with a field, grab the value.
$user_value = Ninja_Forms()->sub( $sub_id )->get_field( $field_id );
} else if ( '_date_submitted' == $field_id ) {
// Get the date of our submission.
$date = strtotime( Ninja_Forms()->sub( $sub_id )->date_submitted );
// The first item is our date field.
$user_value = date( $date_format, $date );
} else if ( '_seq_num' == $field_id ) {
$user_value = Ninja_Forms()->sub( $sub_id )->get_seq_num();
} else {
// We're working with a piece of meta, grabe the value.
$user_value = Ninja_Forms()->sub( $sub_id )->get_meta( $field_id );
......
......@@ -25,7 +25,7 @@ function nf_get_actions() {
do_action( 'nf_' . $_GET['nf_action'], $_GET );
}
}
add_action( 'init', 'nf_get_actions' );
add_action( 'init', 'nf_get_actions', 999 );
/**
* Hooks NF actions, when present in the $_POST superglobal. Every nf_action
......@@ -40,4 +40,4 @@ function nf_post_actions() {
do_action( 'nf_' . $_POST['nf_action'], $_POST );
}
}
add_action( 'init', 'nf_post_actions' );
\ No newline at end of file
add_action( 'init', 'nf_post_actions', 999 );
\ No newline at end of file
......@@ -214,6 +214,71 @@ function ninja_forms_tab_addons(){
'plugin' => 'ninja-forms-stripe/stripe.php',
'docs' => 'http://ninjaforms.com/documentation/extension-docs/stripe/',
),
array (
'title' => __( 'PopControl', 'ninja-forms' ),
'image' => 'http://ninjaforms.com/wp-content/uploads/edd/2014/08/popcontrol-300x121.png',
'content' => __( 'Many options to pop your Ninja Forms in a lightbox', 'ninja-forms' ),
'link' => 'http://ninjaforms.com/downloads/popcontrol/',
'plugin' => 'ninja-forms-pop-control/PopControl.php',
'docs' => '',
),
array (
'title' => __( 'Sendy', 'ninja-forms' ),
'image' => 'http://ninjaforms.com/wp-content/uploads/edd/2014/08/sendy-300x121.png',
'content' => __( 'Sendy extension for Ninja Forms lets you subscribe user’s using Ninja Forms.', 'ninja-forms' ),
'link' => 'http://ninjaforms.com/downloads/sendy/',
'plugin' => 'ninja-forms-sendy/ninja-forms-sendy.php',
'docs' => '',
),
array (
'title' => __( 'Batchbook CRM', 'ninja-forms' ),
'image' => 'http://ninjaforms.com/wp-content/uploads/edd/2014/07/batchbook-300x121.png',
'content' => __( 'Connect WordPress to your Batchbook CRM to automatically create contacts and companies.', 'ninja-forms' ),
'link' => 'http://ninjaforms.com/downloads/batchbook-crm/',
'plugin' => 'ninja-forms-batchbook-crm/ninja-forms-batchbook-crm.php',
'docs' => '',
),
array (
'title' => __( 'White Label Forms', 'ninja-forms' ),
'image' => 'http://ninjaforms.com/wp-content/uploads/edd/2014/07/white-label-forms-300x121.png',
'content' => __( 'Brand the amazing Ninja Forms plugin however you like. Change “Ninja Forms” to your name name and remove any reference to Ninja Forms.', 'ninja-forms' ),
'link' => 'http://ninjaforms.com/downloads/white-label-forms/',
'plugin' => 'ninja-forms-white-label/ninja-forms-white-label.php',
'docs' => '',
),
array (
'title' => __( 'PDF Form Submission', 'ninja-forms' ),
'image' => 'http://ninjaforms.com/wp-content/uploads/edd/2014/05/pdf-form-submission-300x121.png',
'content' => __( 'Easily create PDF copies of your form submissions', 'ninja-forms' ),
'link' => 'http://ninjaforms.com/downloads/pdf-form-submissions/',
'plugin' => 'ninja-forms-pdf-submissions/nf-pdf-submissions.php',
'docs' => '',
),
array (
'title' => __( 'Insightly CRM', 'ninja-forms' ),
'image' => 'http://ninjaforms.com/wp-content/uploads/edd/2014/04/insightly-300x121.png',
'content' => __( 'Create contacts, opportunities, projects, tasks, and notes from your form!', 'ninja-forms' ),
'link' => 'http://ninjaforms.com/downloads/insightly-crm/',
'plugin' => 'ninja-forms-insightly-crm/ninja-forms-insightly-crm.php',
'docs' => 'http://ninjaforms.com/documentation/extension-docs/insightly-crm/',
),
array (
'title' => __( 'Secure Form', 'ninja-forms' ),
'image' => 'http://ninjaforms.com/wp-content/uploads/edd/2014/03/secure-form-300x121.png',
'content' => __( 'Control who can see your form based on a password or popular WordPress eCommerce systems.', 'ninja-forms' ),
'link' => 'http://ninjaforms.com/downloads/secure-form/',