: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
<?php if ( ! defined( 'ABSPATH' ) ) exit;
* Class NF_Admin_Menus_Submissions
final class NF_Admin_Menus_Submissions extends NF_Abstracts_Submenu
public $parent_slug = 'ninja-forms';
public $page_title = 'Submissions';
public $menu_slug = 'nf-submissions';
public function __construct()
$this->load_legacy = intval( Ninja_Forms()->get_setting( 'load_legacy_submissions' ) );
if ( $this->load_legacy )
$this->menu_slug = 'edit.php?post_type=nf_sub';
add_filter( 'manage_nf_sub_posts_columns', array( $this, 'change_columns' ) );
add_action( 'manage_posts_custom_column', array( $this, 'custom_columns' ), 10, 2 );
add_filter('months_dropdown_results', array( $this, 'remove_filter_show_all_dates' ), 9999 );
add_action( 'restrict_manage_posts', array( $this, 'add_filters' ) );
add_filter( 'parse_query', array( $this, 'table_filter' ) );
add_filter( 'posts_clauses', array( $this, 'search' ), 20, 1 );
add_filter( 'bulk_actions-edit-nf_sub', array( $this, 'remove_bulk_edit' ) );
add_action( 'admin_footer-edit.php', array( $this, 'bulk_admin_footer' ) );
add_action( 'load-edit.php', array( $this, 'export_listen' ) );
add_action('admin_head', array( $this, 'hide_page_title_action' ) );
// This will only run on our post type.
add_action( 'views_edit-nf_sub', array( $this, 'change_views' ) );
// add_action( 'admin_init', array( $this, 'nf_upgrade_redirect' ) );
//Add bulk actions on the Submissions interface
add_filter( 'bulk_actions-edit-nf_sub', [ $this, 'manage_bulk_actions' ] );
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_legacy_scripts' ) );
add_action( 'admin_body_class', array( $this, 'body_class' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
add_action('current_screen', [$this, 'remove_legacy_submissions_page']);
* Remove the old Submissions page link when legacy mode is not enabled
* @param $screen object of current screen details
public function remove_legacy_submissions_page( $screen ) {
if ( "nf_sub" === $screen->post_type && $screen->id === "edit-nf_sub") {
$form_id = !empty($_GET["form_id"]) ? "&form_id=" . $_GET["form_id"] : "";
wp_safe_redirect( admin_url( "admin.php?page=nf-submissions" . $form_id ), 302, "Ninja Forms");
* Add an option in the bulk action select field
public function manage_bulk_actions($bulk_actions) {
$bulk_actions['trigger-email-action'] = __('Trigger Email Action', 'ninja-forms');
* If we have required updates, redirect to the main Ninja Forms page
public function nf_upgrade_redirect() {
if( "1" == get_option( 'ninja_forms_needs_updates' ) ) {
// remove_submenu_page( $this->parent_slug, $this->menu_slug );
// if( 'edit.php' == $pagenow && 'nf_sub' == $_GET[ 'post_type' ] ) {
// wp_safe_redirect( admin_url( 'admin.php?page=ninja-forms' ), 301 );
* WordPress hook that modifies the links on our submissions CPT to allow
* users to switch between completed and trashed submissions.
* @param $views The views that are associated with this CPT.
* @return array Returns modified views to allow our users access to the trash.
public function change_views( $views )
// Remove our unused views.
unset( $views[ 'mine' ] );
unset( $views[ 'publish' ] );
// If the Form ID is not empty and IS a number...
if( ! empty( $_GET[ 'form_id' ] ) && ctype_digit( $_GET[ 'form_id' ] ) ) {
// ...populate the rest of the query string.
$form_id = '&form_id=' . absint($_GET[ 'form_id' ]) . '&nf_form_filter&paged=1';
// ...otherwise send in an empty string.
$views[ 'all' ] = '<a href="' . admin_url( 'edit.php?post_status=all&post_type=nf_sub' ) . $form_id . '">'
. esc_html__( 'Completed', 'ninja-forms' ) . '</a>';
$views[ 'trash' ] = '<a href="' . admin_url( 'edit.php?post_status=trash&post_type=nf_sub' ) . $form_id . '">'
. esc_html__( 'Trashed', 'ninja-forms' ) . '</a>';
// Checks to make sure we have a post status.
if( ! empty( $_GET[ 'post_status' ] ) ) {
// Depending on the domain set the value to plain text.
if ( 'all' == $_GET[ 'post_status' ] ) {
$views[ 'all' ] = esc_html__( 'Completed', 'ninja-forms' );
} else if ( 'trash' == $_GET[ 'post_status' ] ) {
$views[ 'trash' ] = esc_html__( 'Trashed', 'ninja-forms' );
public function change_columns()
// if the form_id isset and ID a number
$form_id = ( isset( $_GET['form_id'] ) && ctype_digit( $_GET[ 'form_id' ] ) ) ? absint($_GET['form_id']) : FALSE;
if( ! $form_id ) return array();
if( $cols ) return $cols;
'cb' => '<input type="checkbox" />',
'seq_num' => esc_html__( '#', 'ninja-forms' ),
$fields = Ninja_Forms()->form( $form_id )->get_fields();
$hidden_field_types = apply_filters( 'ninja_forms_sub_hidden_field_types', array() );
foreach( $fields as $field ){
if ( is_null( $field ) ) continue;
if( in_array( $field->get_setting( 'type' ), $hidden_field_types ) ) continue;
if ( $field->get_setting( 'admin_label' ) ) {
$cols[ 'field_' . $field->get_id() ] = $field->get_setting( 'admin_label' );
$cols[ 'field_' . $field->get_id() ] = $field->get_setting( 'label' );
$cols[ 'sub_date' ] = esc_html__( 'Date', 'ninja-forms' );
public function custom_columns( $column, $sub_id )
if ( 'nf_sub' !== $post_type ) return false;
$sub = Ninja_Forms()->form()->get_sub( $sub_id );
echo $this->custom_columns_seq_num( $sub );
echo $this->custom_columns_sub_date( $sub );
echo $this->custom_columns_field( $sub, $column );
* Remove Filter: Show All Dates
public function remove_filter_show_all_dates( $months )
if( ! isset( $_GET[ 'post_type' ] ) || 'nf_sub' != $_GET[ 'post_type' ] ) return $months;
// Returning an empty array should hide the dropdown.
public function add_filters()
// Bail if we aren't in our submission custom post type.
if ( $typenow != 'nf_sub' ) return false;
$forms = Ninja_Forms()->form()->get_forms();
foreach( $forms as $form ){
$form_options[ $form->get_id() ] = $form->get_setting( 'title' );
$form_options = apply_filters( 'ninja_forms_submission_filter_form_options', $form_options );
// make sure form_id isset and is a number
if( isset( $_GET[ 'form_id' ] ) && ctype_digit( $_GET[ 'form_id' ] ) ) {
$form_selected = intval($_GET[ 'form_id' ]);
if( isset( $_GET[ 'begin_date' ] ) ) {
// check for bad characters(possible xss vulnerability)
$beg_date_sep = preg_replace('/[0-9]+/', '', WPN_Helper::sanitize_text_field($_GET[ 'begin_date' ]));
if ( 1 !== count( array_unique( str_split( $beg_date_sep ) ) ) ) {// We got bad data.
$begin_date = WPN_Helper::sanitize_text_field($_GET['begin_date']);
if( isset( $_GET[ 'end_date' ] ) ) {
// check for bad characters(possible xss vulnerability)
$end_date_sep = preg_replace('/[0-9]+/', '', WPN_Helper::sanitize_text_field($_GET[ 'end_date' ]));
if ( 1 !== count( array_unique( str_split( $end_date_sep ) ) ) ) {// We got bad data.
$end_date = WPN_Helper::sanitize_text_field($_GET['end_date']);
Ninja_Forms::template( 'admin-menu-subs-filter.html.php', compact( 'form_options', 'form_selected', 'begin_date', 'end_date' ) );
wp_enqueue_script('jquery-ui-datepicker');
wp_enqueue_style( 'jquery-ui-datepicker', Ninja_Forms::$url .'lib/Legacy/jquery-ui-fresh.min.css' );
public function table_filter( $query )
if( $pagenow != 'edit.php' || ! is_admin() || ! isset( $query->query['post_type'] ) || 'nf_sub' != $query->query['post_type'] || ! is_main_query() ) return;
$vars = &$query->query_vars;
// make sure form_id is not empty and is a number
$form_id = ( ! empty( $_GET['form_id'] ) && ctype_digit( $_GET[ 'form_id' ] ) ) ? intval($_GET['form_id']) : 0;
$vars = $this->table_filter_by_form( $vars, $form_id );
$vars = $this->table_filter_by_date( $vars );
$vars = apply_filters( 'ninja_forms_sub_table_qv', $vars, $form_id );
public function search( $pieces ) {
// filter to select search query
if ( isset ( $_GET['s'] ) && $typenow == 'nf_sub' && is_search() && is_admin() ) {
$keywords = explode(' ', get_query_var('s'));
foreach ($keywords as $word) {
$wpdb->escape_by_ref( $word );
$query .= " (mypm1.meta_value LIKE '%{$word}%') OR ";
// Escape place holders for the where clause.
$pieces[ 'where' ] = $wpdb->remove_placeholder_escape( $pieces[ 'where' ] );
$pieces[ 'where' ] = str_replace("((({$wpdb->posts}.post_title LIKE '%", "({$query}(({$wpdb->posts}.post_title LIKE '%", $pieces[ 'where' ]);
$pieces[ 'join' ] = $pieces[ 'join' ] . " INNER JOIN {$wpdb->postmeta} AS mypm1 ON ({$wpdb->posts}.ID = mypm1.post_id)";
public function remove_bulk_edit( $actions ) {
unset( $actions['edit'] );
public function bulk_admin_footer() {
if( $post_type == 'nf_sub' && isset ( $_REQUEST['post_status'] ) && $_REQUEST['post_status'] == 'all' ) {
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery('<option>').val('export').text('<?php esc_html_e('Export', 'ninja-forms')?>').appendTo("select[name='action']");
jQuery('<option>').val('export').text('<?php esc_html_e('Export', 'ninja-forms')?>').appendTo("select[name='action2']");
if ( ( isset ( $_POST['action'] ) && $_POST['action'] == 'export' ) || ( isset ( $_POST['action2'] ) && $_POST['action2'] == 'export' ) ) {
jQuery( "select[name='action'" ).val( '-1' );
jQuery( "select[name='action2'" ).val( '-1' );
jQuery( '#posts-filter' ).submit();
if ( isset ( $_REQUEST['form_id'] ) && ! empty ( $_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=' . absint( $_REQUEST['form_id'] ) . '&redirect=' . $redirect . '&security=' . wp_create_nonce( 'ninja_forms_batch_nonce' ) );
var button = '<a href="<?php echo $url; ?>" class="button-secondary nf-download-all"><?php echo esc_html__( 'Download All Submissions', 'ninja-forms' ); ?></a>';
if ( isset ( $_REQUEST['download_all'] ) && $_REQUEST['download_all'] != '' ) {
$redirect = esc_url_raw( add_query_arg( array( 'download_file' => esc_html( $_REQUEST['download_all'] ) ) ) );
$redirect = remove_query_arg( array( 'download_all' ), $redirect );
document.location.href = "<?php echo $redirect; ?>";
public function export_listen()
$current_user_can_get_nf_submissions = apply_filters( 'ninja_forms_api_allow_get_submissions', current_user_can( 'manage_options' ) );
// Ensure that we are in admin and user has permission to export
!$current_user_can_get_nf_submissions
if (!isset ($_REQUEST['form_id']) || empty ($_REQUEST['form_id'])) {
if (isset ($_REQUEST['export_single']) && !empty($_REQUEST['export_single'])) {
Ninja_Forms()->sub(esc_html($_REQUEST['export_single']))->export();
if ((isset ($_REQUEST['action']) && $_REQUEST['action'] == 'export') || (isset ($_REQUEST['action2']) && $_REQUEST['action2'] == 'export')) {
if (isset($_REQUEST['post'])) {
$sub_ids = WPN_Helper::esc_html($_REQUEST['post']);
Ninja_Forms()->form( absint( $_REQUEST['form_id'] ) )->export_subs( $sub_ids );
if (isset ($_REQUEST['download_file']) && !empty($_REQUEST['download_file'])) {
// Open our download all file
$filename = esc_html($_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);
$redirect = esc_url_raw(remove_query_arg(array('download_file', 'download_all')));
$form_name = Ninja_Forms()->form(absint($_REQUEST['form_id']))->get()->get_setting('title');
$form_name = sanitize_title($form_name);
$today = date('Y-m-d', current_time('timestamp'));
$filename = apply_filters('ninja_forms_download_all_filename', $form_name . '-all-subs-' . $today);
header('Content-type: application/csv');
header('Content-Disposition: attachment; filename="' . $filename . '.csv"');
header('Pragma: no-cache');
public function hide_page_title_action()
// If we are on our the nf_sub post type then....
if( ( isset( $_GET[ 'post_type' ] ) && 'nf_sub' == $_GET[ 'post_type'] ) ||
'nf_sub' == get_post_type() ) {
// ...then hiding the "Add New" button on the CPT page.
echo '<style type="text/css">.page-title-action, .view-mode{display: none;}</style>';
private function custom_columns_seq_num( $sub )