<?php
defined( 'ABSPATH' ) or exit;   // show a blank page if try to access this file directly

require_once( EWZ_PLUGIN_DIR . 'classes/ewz-base.php');
require_once( EWZ_PLUGIN_DIR . 'classes/ewz-exception.php' );
require_once( EWZ_PLUGIN_DIR . 'classes/ewz-item.php');
require_once( EWZ_PLUGIN_DIR . 'classes/ewz-user.php');
require_once( EWZ_PLUGIN_DIR . 'classes/ewz-webform.php');
require_once( EWZ_PLUGIN_DIR . 'classes/validation/ewz-webform-data-input.php');
require_once( EWZ_PLUGIN_DIR . 'classes/validation/ewz-webform-set-input.php');
require_once( EWZ_PLUGIN_DIR . 'classes/validation/ewz-layout-set-input.php');
require_once( EWZ_PLUGIN_DIR . 'includes/ewz-admin-layouts.php');
require_once( EWZ_PLUGIN_DIR . 'includes/ewz-admin-webforms.php');
require_once( EWZ_PLUGIN_DIR . 'includes/ewz-admin-permissions.php');
require_once( EWZ_PLUGIN_DIR . 'includes/ewz-admin-settings.php');
require_once( EWZ_PLUGIN_DIR . 'includes/ewz-admin-help.php');
require_once( EWZ_PLUGIN_DIR . 'includes/ewz-admin-list-items.php');

// File that is included with any admin entrywizard call. Delegates all admin code.

/**
 * @param array<mixed> $exporters
 *
 * @return  array<mixed> $exporters
 */
function ewz_export_entrywizard_data( $exporters ){
    $exporters['entrywizard'] = array(
                'exporter_friendly_name' =>  'EntryWizard plugin',
                'callback' => 'Ewz_User::get_user_item_data',
            );
    return $exporters;
}


/* * ****************   Functions to enqueue the scripts and styles ******************* */
/*  Most scripts require data stored in a variable called 'ewzG', which must first be   */
/*      generated. They are not enqueued until we know which are really needed       */

/**
 * @return void
 */
function ewz_enqueue_common_styles( ) {
    // called in ewz_admin_init
    wp_enqueue_style( 'jquery-ui-dialog' );
    wp_enqueue_style( 'ewz-admin-style' );
    wp_enqueue_style( 'ewz-jq-ui-style' );
    wp_enqueue_style( 'ewz-ms-ui-style' );
}

/**
 * @return void
 */
function ewz_enqueue_common_scripts( ) {
    // hooked in ewz_admin_menu
    wp_enqueue_script( 'ewz-admin-common' );
}

/**
 * @return void
 */
function ewz_enqueue_layout_scripts() {
    // hooked in ewz_admin_menu
    wp_enqueue_script( 'ewz-admin-layouts' );
}

/**
 * @return void
 */
function ewz_enqueue_webform_scripts() {
    // hooked in ewz_admin_menu
    wp_enqueue_script( 'ewz-admin-webforms' );
}

/**
 * @return void
 */
function ewz_enqueue_permission_scripts() {
    // hooked in ewz_admin_menu
    wp_enqueue_script( 'ewz-admin-permissions' );
}

/**
 * @return void
 */
function ewz_enqueue_item_list_scripts() {
    // hooked in ewz_admin_menu
    wp_enqueue_script( 'ewz-admin-list-items' );
}


/********************************************************************************/
/**
 * @return void
 */
function ewz_admin_init() {
    wp_register_style( 'jquery-ui-dialog', includes_url() . "/css/jquery-ui-dialog.css" );

    wp_register_style( 'ewz-jq-ui-style', plugins_url( 'styles/ewz-jquery-ui.css', dirname(__FILE__) ), array('jquery-ui-dialog'), EWZ_CURRENT_VERSION );
    wp_register_style( 'ewz-admin-style', plugins_url( 'styles/ewz-admin.css', dirname(__FILE__) ), array('jquery-ui-dialog','ewz-jq-ui-style'), EWZ_CURRENT_VERSION );
    wp_register_style( 'ewz-ms-ui-style', plugins_url( 'styles/ewz-multi-select.css', dirname(__FILE__) ), array(), EWZ_CURRENT_VERSION );

    // need to load it under the old name for a while, to support older versions of ewz-rating
    wp_register_script( 'ewz-common', plugins_url( 'javascript/ewz-admin-common.js', dirname( __FILE__ ) ),
                        array( 'jquery', 'jquery-ui-core', 'jquery-ui-dialog' ),  EWZ_CURRENT_VERSION );

    wp_register_script( 'ewz-admin-common', plugins_url( 'javascript/ewz-admin-common.js', dirname( __FILE__ ) ),
                        array( 'jquery', 'jquery-ui-core', 'jquery-ui-dialog' ),  EWZ_CURRENT_VERSION );


    if( isset( $_REQUEST['page'] ) ){
        if( $_REQUEST['page'] == 'ewzlayouts' ){
            wp_register_script('ewz-admin-layouts',
                               plugins_url( 'javascript/ewz-layouts.js', dirname(__FILE__) ),
                               array( 'jquery', 'jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-dialog',
                                      'jquery-ui-position','ewz-admin-common', 'jquery-ui-sortable' ),
                               EWZ_CURRENT_VERSION,
                               true         // in footer, so $ewzG has been defined
                               );
        } elseif( $_REQUEST['page'] == 'ewzperms' ){
            wp_register_script('ewz-admin-permissions',
                               plugins_url( 'javascript/ewz-permissions.js', dirname(__FILE__) ),
                               array( 'jquery', 'jquery-ui-core', 'jquery-ui-dialog', 'ewz-admin-common' ),
                               EWZ_CURRENT_VERSION,
                               true         // in footer, so $ewzG has been defined
                               );
// currently no javascript for settings page
//        } elseif( $_REQUEST['page'] == 'ewzsettings' ){
//            wp_register_script('ewz-admin-settings',
//                               plugins_url( 'javascript/ewz-settings.js', dirname(__FILE__) ),
//                               array( 'jquery', 'jquery-ui-core', 'jquery-ui-dialog', 'ewz-admin-common' ),
//                               EWZ_CURRENT_VERSION,
//                               true         // in footer, so $ewzG has been defined
//                               );
        } elseif( $_REQUEST['page'] == 'entrywizard' ){
            // multi-select needed for "open for selected users"
            wp_register_script( 'ewz-multiselect',  plugins_url( 'javascript/jquery.multi-select.js', dirname( __FILE__ ) ),
                                 array( 'jquery', 'jquery-ui-core' ),  EWZ_CURRENT_VERSION );

            wp_register_script('ewz-admin-webforms',
                               plugins_url( 'javascript/ewz-webforms.js', dirname(__FILE__) ),
                               array( 'jquery','jquery-ui-core','jquery-ui-dialog','jquery-ui-datepicker','jquery-ui-draggable','ewz-admin-common','jquery-ui-sortable','ewz-multiselect' ),
                               EWZ_CURRENT_VERSION,
                               true         // in footer, so $ewzG has been defined
                               );
        } elseif( $_REQUEST['page'] == 'entrywizlist' ){
            wp_register_script('ewz-admin-list-items',
                               plugins_url( 'javascript/ewz-list-items.js', dirname(__FILE__) ),
                               array( 'jquery', 'jquery-ui-core', 'jquery-ui-widget',
                               'jquery-ui-dialog', 'jquery-ui-position', 'ewz-admin-common' ),
                               EWZ_CURRENT_VERSION,
                               true         // in footer, so $ewzG has been defined
                               );
        }
    }
}
add_action( 'admin_init', 'ewz_admin_init' );

/**
 * Hook in the admin menu pages
 *
 * Add the EntryWizard menu section to the admin menu, with submenu items for
 *     Webforms, Layouts, Permissions, Settings
 * The "EntryWizard" header links to the webforms page, which is the one for managing
 *     open/close and downloads.
 *
 * Hooked to 'admin_menu', adds action to 'admin_print_scripts-....' which comes later
 * Calls Ewz_Permission.
 *
 */

/**
 * @return void
 */
function ewz_admin_menu() {
    /* NB: all slugs must include "entrywiz" to force load of translated strings */
    if ( Ewz_Permission::has_ewz_cap() ) {

        // MENU ITEMS
        // $page_title, $menu_title, $capability,
        // $menu_slug, $function,
        // menu icon
        $menu_hook = add_menu_page(
                                   'EntryWizard',
                                   'EntryWizard',
                                   'read',
                                   'entrywizard',
                                   'ewz_webforms_menu',
                                   plugin_dir_url( __FILE__ ) . '../images/ewz_icon.png'
                                   );

        add_action( 'admin_print_scripts-' . $menu_hook, 'ewz_enqueue_webform_scripts' );
        add_action( 'admin_print_scripts-' . $menu_hook, 'ewz_enqueue_common_scripts' );
        add_action( 'admin_print_styles-' .  $menu_hook, 'ewz_enqueue_common_styles' );

        if ( Ewz_Permission::can_see_webform_page() ) {
            // NB: list page is really part of webform page.
            // $parent_slug, $page_title, $menu_title,
            // $capability, $menu_slug, $function
            $webform_hook_suffix = add_submenu_page(
                                                    'entrywizard', 'EntryWizard Web Forms', 'WebForms', 'read',
                                                    'entrywizard', 'ewz_webforms_menu' );
            add_action( 'admin_print_scripts-' . $webform_hook_suffix, 'ewz_enqueue_webform_scripts' );
            add_action( 'admin_print_scripts-' . $webform_hook_suffix, 'ewz_enqueue_common_scripts' );
            add_action( 'admin_print_styles-' .  $webform_hook_suffix, 'ewz_enqueue_common_styles' );
        }

        if ( Ewz_Permission::can_see_webform_page() ) {
            $help_hook_suffix = add_submenu_page(
                                                    'entrywizard', 'EntryWizard Help', 'EWZ Help', 'read',
                                                    'ewzhelp', 'ewz_help_menu' );
            add_action( 'admin_print_scripts-' . $help_hook_suffix, 'ewz_enqueue_common_scripts' );
            add_action( 'admin_print_styles-' .  $help_hook_suffix, 'ewz_enqueue_common_styles' );
        }

        if ( isset( $_REQUEST['webform_id'] ) &&
             ( Ewz_Base::is_nn_int( $_REQUEST['webform_id'] ) ) &&
             Ewz_Permission::can_manage_webform( intval( $_REQUEST['webform_id'], 10 ), 0 )
        )  {
            // NB: list page is really part of webform page.
            $list_hook_suffix  = add_submenu_page(
                                                  'NULL', 'EntryWizard Item List', 'ItemList',
                                                  'read', 'entrywizlist', 'ewz_list_items' );

            add_action( 'admin_print_scripts-' . $list_hook_suffix, 'ewz_enqueue_item_list_scripts' );
            add_action( 'admin_print_scripts-' . $list_hook_suffix, 'ewz_enqueue_common_scripts' );
            add_action( 'admin_print_styles-' .  $list_hook_suffix, 'ewz_enqueue_common_styles' );
        }

        if ( Ewz_Permission::can_see_layout_page() ) {
            $layout_hook_suffix = add_submenu_page(
                                                   'entrywizard', 'EntryWizard Layouts', 'Layouts',
                                                   'read', 'ewzlayouts', 'ewz_layout_menu' );

            add_action( 'admin_print_scripts-' . $layout_hook_suffix, 'ewz_enqueue_layout_scripts' );
            add_action( 'admin_print_scripts-' . $layout_hook_suffix, 'ewz_enqueue_common_scripts' );
            add_action( 'admin_print_styles-' .  $layout_hook_suffix, 'ewz_enqueue_common_styles' );
        }

        if( current_user_can('manage_options') || current_user_can('edit_users') ){
            $perm_hook_suffix = add_submenu_page(
                                             'entrywizard', 'EntryWizard Permissions', 'Permissions',
                                             'read', 'ewzperms', 'ewz_permissions_menu' );

            add_action( 'admin_print_scripts-' . $perm_hook_suffix, 'ewz_enqueue_permission_scripts' );
            add_action( 'admin_print_scripts-' . $perm_hook_suffix, 'ewz_enqueue_common_scripts' );
            add_action( 'admin_print_styles-' .  $perm_hook_suffix, 'ewz_enqueue_common_styles' );
        }

        if ( Ewz_Permission::can_edit_all_layouts() ) {
            $settings_hook_suffix = add_submenu_page(
                                             'entrywizard', 'EntryWizard Settings', 'EWZ Settings',
                                             'manage_options', 'ewzsettings', 'ewz_settings_menu' );

            // no actual scripts here
            add_action( 'admin_print_scripts-' . $settings_hook_suffix, 'ewz_enqueue_common_scripts' );
            add_action( 'admin_print_styles-' .  $settings_hook_suffix, 'ewz_enqueue_common_styles' );
        }
    }
}

add_action( 'admin_menu', 'ewz_admin_menu' );


/* * ************************  DOWNLOAD ACTIONS *************************** */

/**
 * Output to stdout a .csv summary of the webform data and/or a tar file of the uploaded images
 * Called via the "Download ...." buttons on the Webforms page.
 * Has to be hooked earlier than other stuff to avoid any output before it.
 * Echoes a header followed by the data to stdout, which forces a download dialog
 *
 * @return int 0 if bad data or permissions, otherwise 1
 */
function ewz_echo_data() {
    // Rest is only run if we are in the right mode
    // But note this check is run even if we are doing ajax calls
    if ( isset( $_GET["ewzmode"] ) &&
             ( in_array( $_GET["ewzmode"], array( 'spread', 'stored','zdownload', 'zimages' ) ) ) ) {
        if ( check_admin_referer( 'ewzadmin', 'ewznonce' ) ) {
            try {
                 ewz_wipe_buffers();
                // validate
                $input = new Ewz_Webform_Data_Input( array_merge( $_POST, $_GET ) );
                // 'page' is in GET
                $data = $input->get_input_data();
                $webform = new Ewz_Webform( $data['webform_id'] );

                $items = Ewz_Item::filter_items(
                           $data['fopt'],
                           $data['copt'],
                           array( 'uploaddays' => $data['uploaddays'] ),
                           Ewz_Item::get_items_for_webform( $data['webform_id'], Ewz_Item::GET_ALL_ITEMS )
                        );
                switch ( $data['ewzmode'] ) {
                    case 'zimages':
                        $webform->gen_and_echo_archive( $items, Ewz_Webform::IMAGES );
                        break;
                    case 'stored':
                        $webform->echo_stored_archive( $data['archive_id'] );
                        break;
                    case 'zdownload':
                        $webform->gen_and_echo_archive( $items, Ewz_Webform::BOTH );
                        break;
                    case 'spread':
                        $webform->download_spreadsheet( $items, Ewz_Webform::SPREADSHEET );
                        break;
                    default:
                        throw new EWZ_Exception( "Invalid mode " . $data['ewzmode'] );
                }
            } catch (Exception $e) {
                error_log( "EWZ:  ewz_output_csv " . $e->getMessage() );
                die( $e->getMessage() );
            }
        } else {
            echo "Insufficient permissions - may have expired";
            error_log( "EWZ: ewz_echo_data, check_admin_referer failed" );
        }
    }

    return 1;
}
// need to make sure global constants are defined first
add_action( 'init', 'ewz_echo_data', 30 );


/* * ************************  AJAX CALLS *************************** *
 *
 *  NOTE: The action 'wp_ajax_xxxxxx' is called when the 'xxxxxx'
 *        action is specified in javascript
 *
 *  Each function echoes a return status that is checked in
 *  the javascript and usually alerted to the viewer, then exits.
 *
 */
  /**
  * Save the order of layouts on the layouts page
  * @return void
  */
 function ewz_show_cron_events_callback() {
     if ( check_admin_referer( 'ewzadmin', 'ewznonce' ) ) {
         $output = '';
         try {
             $output = Ewz_Webform::get_cron_events();
         } catch (Exception $e) {
              error_log("EWZ: ewz_show_cron_events_callback exception " . $e->getMessage());
         }
         echo $output;
     } else {
         echo "Insufficient permissions - may have expired";
         error_log( "EWZ: ewz_show_cron_events_callback, check_admin_referer failed" );
     }
     exit();
 }
 add_action( 'wp_ajax_ewz_show_cron_events', 'ewz_show_cron_events_callback' );

/**
 * @return void
 */
function ewz_save_layout_order_callback() {
     if ( check_admin_referer( 'ewzadmin', 'ewznonce' ) ) {
         $num_updated = 0;
         try {
              $input = new Ewz_Layout_Set_Input( $_POST );
              $num_updated = Ewz_Layout::save_layout_order( $input->get_input_data()['lorder'] );
         } catch (Exception $e) {
             error_log("EWZ: ewz_save_layout_order_callback exception ". $e->getMessage());
         }
         echo "$num_updated layouts updated";
     } else {
         echo "Insufficient permissions - may have expired";
         error_log( "EWZ: ewz_save_layout_order_callback, check_admin_referer failed" );
     }
     exit();
 }
 add_action( 'wp_ajax_ewz_save_layout_order', 'ewz_save_layout_order_callback' );

/**
 * Save the order of webforms on the webforms page
 * @return void
 */
function ewz_save_webform_order_callback() {
    if ( check_admin_referer( 'ewzadmin', 'ewznonce' ) ) {
        $num_updated = 0;
        try {
             $input = new Ewz_Webform_Set_Input( $_POST );
             $num_updated = Ewz_Webform::update_webform_order( $input->get_input_data()['wforder'] );
        } catch (Exception $e) {
            error_log("EWZ: ewz_save_webform_order_callback exception " . $e->getMessage());
        }
        echo "$num_updated webforms updated";
    } else {
        echo "Insufficient permissions - may have expired";
        error_log( "EWZ: ewz_save_webform_order_callback, check_admin_referer failed" );
    }
    exit();
}
add_action( 'wp_ajax_ewz_save_webform_order', 'ewz_save_webform_order_callback' );

/**
 * Return the html for the user selection list
 * @return void
 */
function ewz_webform_get_user_list_callback() {
    if ( check_admin_referer( 'ewzadmin', 'ewznonce' ) ) {
        try {
            ewz_wipe_buffers();
            if ( !( isset($_POST['webform_id'])  && is_numeric( $_POST['webform_id']) && strlen($_POST['webform_id']) <= 10 ) )  {
                error_log( 'EWZ: ewz_save_webform_callback, no webform_id or not numeric' );
                wp_send_json_error( "EWZ: Missing or non-numeric webform_id" );
            } else {
                $wform = new Ewz_Webform( (int)$_POST['webform_id'] );
                echo  $wform->get_user_list();
            }
        } catch (Exception $e) {
            error_log("EWZ: ewz_webform_get_user_list_callback exception " . $e->getMessage());
        }
    } else {
        echo "Insufficient permissions - may have expired";
        error_log( "EWZ: ewz_save_webform_order_callback, check_admin_referer failed" );
    }
    exit();
}
add_action( 'wp_ajax_ewz_webform_get_user_list', 'ewz_webform_get_user_list_callback' );




/**
 * Save changes to a single webform
 * @return void
 */
function ewz_save_webform_callback() {
    if ( check_admin_referer( 'ewzadmin', 'ewznonce' ) ) {
        try {
            ewz_wipe_buffers();
            // new webform comes with empty webform_id
            if ( $_POST['webform_id']  && !is_numeric( $_POST['webform_id'] )) {
                error_log( 'EWZ: ewz_save_webform_callback, no webform_id or not numeric' );
                wp_send_json_error( "EWZ: Missing or non-numeric webform_id" );
            } else {
                unset( $_POST['action'] );
                $input = new Ewz_Webform_Input( $_POST );
                $webform = new Ewz_Webform( $input->get_input_data() );
                if( $webform->save() ){
                    $webform->add_display_info();
                    wp_send_json_success( $webform );
                } else {
                    error_log("EWZ: ewz_save_webform_callback error for webform ". $_POST['webform_id']);
                    wp_send_json_error( "EWZ: unknown problem saving webform. Reload page to see current status.");
                }
            }
        } catch (Exception $e) {
            error_log("EWZ: ewz_save_webform_callback exception " . $e->getMessage());
            wp_send_json_error( "EWZ: problem saving webform. "  . $e->getMessage());
        }
    } else {
      echo "Insufficient permissions - may have expired";
      wp_send_json_error( "EWZ: ewz_save_webform_callback, check_admin_referer failed" );
    }
    // exit line should not be reachable -- belt-and-braces
    /** @phpstan-ignore-next-line */
    exit();
}

add_action( 'wp_ajax_ewz_save_webform', 'ewz_save_webform_callback' );

/**
 * Save changes to a single layout
 * @return void
 */
function ewz_save_layout_callback() {
    if ( check_admin_referer( 'ewzadmin', 'ewznonce' ) ) {
        try {
            ewz_wipe_buffers();
            if ( $_POST['layout_id'] && !( is_numeric( $_POST['layout_id'] )) ) {
                error_log( 'EWZ: ewz_save_layout_callback, layout_id not numeric' );
                wp_send_json_error( "EWZ: Saving Layout, invalid layout id");
            } else {
                unset( $_POST['action'] );
                $input = new Ewz_Layout_Input( $_POST );
                $idata = $input->get_input_data();
                $layout = new Ewz_Layout( $idata );
                if( $layout->save() ){
                    if( isset( $_POST['copy_restr_from'] ) && is_numeric( $_POST['copy_restr_from'] ) ){
                        $layout->copy_restrictions_from( $_POST['copy_restr_from'] );
                    }
                    wp_send_json_success( $layout );
                } else {
                    error_log("EWZ: ewz_save_layout_callback error for layout ". $_POST['layout_id']);
                    wp_send_json_error( "EWZ: unknown problem saving layout. Reload page to see current status.");
                }
            }
        } catch (Exception $e) {
            error_log("EWZ: ewz_save_layout_callback exception " . $e->getMessage());
            wp_send_json_error( "Error saving layout: " . $e->getMessage() );
        }
    } else {
        echo "Insufficient permissions - may have expired";
        error_log( "EWZ: ewz_save_layout_callback, check_admin_referer failed" );
    }
    exit();
}
add_action( 'wp_ajax_ewz_save_layout', 'ewz_save_layout_callback' );



/**
 * Generate a zip file of images
 *
 * Called via one of the "Download" buttons on the Webforms page
 * NB: action name is generated from the jQuery post, must match.
 * Returns a string identifying the wp option that holds the url
 * of the zip archive. Used if there is no zip command, or if images
 * need to be renamed on download.
 * @return void
 */
function ewz_gen_zipfile_callback() {
    if ( check_admin_referer( 'ewzadmin', 'ewznonce' ) ) {
        ewz_wipe_buffers();
        if ( !(isset( $_POST['webform_id'] ) && is_numeric( $_POST['webform_id'] )) ) {
            error_log( 'EWZ: ewz_gen_zipfile_callback, no webform_id or not numeric' );
            echo 'Missing or non-numeric webform_id';
        } else {
            try {
                // validate ( 'page' is in GET )
                $input = new Ewz_Webform_Data_Input( array_merge( $_POST, $_GET ) );
                $data = $input->get_input_data();
                $webform = new Ewz_Webform( $data['webform_id'] );

                $items = Ewz_Item::filter_items(
                           $data['fopt'],
                           $data['copt'],
                           array( 'uploaddays' => $data['uploaddays'] ),
                           Ewz_Item::get_items_for_webform( $data['webform_id'], Ewz_Item::GET_ALL_ITEMS )
                        );
                switch ( $data['ewzmode'] ) {
                    case 'images':
                        echo $webform->generate_zip_archive( $items, Ewz_Webform::IMAGES );
                        break;
                    case 'download':
                        echo $webform->generate_zip_archive( $items, Ewz_Webform::BOTH );
                        break;
                    default:
                        throw new EWZ_Exception( "Invalid mode for gen_zipfile " . $data['ewzmode'] );
                }
            } catch (Exception $e) {
                echo $e->getMessage();
                if( isset( $data['webform_id'] ) ){
                    Ewz_Base::delete_ewz_options( $data['webform_id']);
                }
            }
        }
    } else {
        echo "Insufficient permissions - may have expired";
        error_log( "EWZ: ewz_gen_zipfile_callback, check_admin_referer failed" );
    }
    exit();
}
add_action( 'wp_ajax_ewz_gen_zipfile', 'ewz_gen_zipfile_callback' );

/**
 * Delete a Layout - handle ajax call
 *
 * Called via one of the "Delete Layout" buttons on the Layouts page
 * NB: action name is generated from the jQuery post, must match.
 * Javascript caller alerts if response is not "1" (true)
 * @return void
 */
function ewz_del_layout_callback() {
    if ( check_admin_referer( 'ewzadmin', 'ewznonce' ) ) {
        ewz_wipe_buffers();
        if ( !(isset( $_POST['layout_id'] ) && is_numeric( $_POST['layout_id'] )) ) {
            error_log( 'EWZ: ewz_del_layout_callback, no layout_id or not numeric' );
            echo 'Missing or non-numeric  layout_id';
        } else {
            try {
                $layout = new Ewz_Layout( intval( $_POST['layout_id'] ) );
                $layout->delete( Ewz_Layout::DELETE_FORMS );
                echo "1";
            } catch (Exception $e) {
                echo $e->getMessage();
            }
        }
    } else {
        echo "Insufficient permissions - may have expired";
        error_log( "EWZ: ewz_del_layout_callback, check_admin_referer failed" );
    }
    exit();
}

add_action( 'wp_ajax_ewz_del_layout', 'ewz_del_layout_callback' );

/**
 * Delete a Field - handle ajax call
 *
 * Called via one of the "Delete Field" buttons on the Layouts page
 * NB: action name is generated from the jQuery post, must match.
 * Javascript caller alerts if response is not "1" (true)
 * @return void
 */
function ewz_del_field_callback() {
    if ( check_admin_referer( 'ewzadmin', 'ewznonce' ) ) {
        ewz_wipe_buffers();
        if ( !( isset( $_POST['layout_id'] ) && is_numeric( $_POST['layout_id'] ) &&
                isset( $_POST['field_id'] ) && is_numeric( $_POST['field_id'] )) ) {
            error_log( 'EWZ: ewz_del_field_callback, ' .
                    'no layout_id or no field_id or id not numeric' );
            echo 'Missing or non-numeric layout or field ids';
        } else {
            try {
                $layout = new Ewz_Layout( intval( $_POST['layout_id'] ) );
                $layout->delete_field( intval( $_POST['field_id'] ) );
                echo "1";
            } catch (Exception $e) {
                echo $e->getMessage();
            }
        }
    } else {
        echo 'Insufficient permissions - may have expired';
        error_log( "EWZ: ewz_del_field_callback, check_admin_referer failed" );
    }
    exit();
}

add_action( 'wp_ajax_ewz_del_field', 'ewz_del_field_callback' );

/**
 * User Delete an Item - handle ajax call
 *
 * Called via one of the "Delete" buttons on the UPLOAD page
 *     ( dont confuse with admin delete from the list page )
 * NB: action name is generated from the jQuery post, must match.
 *
 * if response is not '1 item deleted.', javascript caller alerts with error message.
 * @return void
 */
function ewz_del_item_callback() {
    if ( isset( $_POST["ewzdelnonce"] ) && wp_verify_nonce( $_POST["ewzdelnonce"], 'ewzupload' ) ) {
        ewz_wipe_buffers();
        if ( !(isset( $_POST['item_id'] ) && is_numeric( $_POST['item_id'] )) ) {
            error_log( 'EWZ:  ewz_del_item_callback - ' .
                    'no item_id or not numeric' );
            echo 'Missing or non-numeric item id';
        } else {
            try {
                $status = ewz_user_delete_item( intval( $_POST['item_id'] ) );
                echo $status;
            } catch (Exception $e) {
                echo $e->getMessage();
            }
        }
    } else {
        echo "No changes made - authorization expired";
        error_log( "EWZ: ewz_del_item_callback, nonce failed" );
    }
    exit();
}
add_action( 'wp_ajax_ewz_del_item', 'ewz_del_item_callback' );


/**
 * Ajax callback for ewz_webforms_batch_delete
 * Delete the specified webforms and/or all attached items and files.
 * @return void
 */
function ewz_webforms_batch_delete_callback(){
    if ( check_admin_referer( 'ewzadmin', 'ewznonce' )  ) {
        ewz_wipe_buffers();
        $n = 0;
        $msg = '';
        try {
            $input = (new Ewz_Webform_Set_Input( $_POST ))->get_input_data();
            if ( !(isset($input['webform_ids']) && is_array($input['webform_ids']) ) ){
                error_log( 'EWZ:  ewz_webforms_batch_delete_callback - ' .  'no webform_ids or not array' );
                echo 'Invalid webform list';
            }
            foreach( $input['webform_ids'] as $wform_id ){
                $del_msg = '';
                $webform = new Ewz_Webform($wform_id  );
                ++$n;
                if( $input['target'] == 'forms' ){
                    $del_msg = $webform->delete( Ewz_Webform::DELETE_ITEMS );
                } elseif( $input['target'] == 'items' ){
                    $del_msg = $webform->delete_all_items();
                } elseif( $input['target'] == 'zipfiles' ){
                     $del_msg = $webform->delete_zipfiles();
                }
                $msg .= $webform->webform_title . ": $del_msg";
            }
            echo "$n Webforms Deleted: $msg";
        } catch (Exception $e) {
            echo "$n Webforms Deleted: $msg" .  $e->getMessage();
        }
        wp_die();
    }
    exit();
}
add_action( 'wp_ajax_ewz_webforms_batch_delete', 'ewz_webforms_batch_delete_callback');

/**
 * Ajax callback for ewz_hide_webforms
 * Set the 'hidden' flag  for the specified webforms.
 * @return void
 */
function ewz_hide_webforms_callback( ){
    if ( check_admin_referer( 'ewzadmin', 'ewznonce' )  ) {
        ewz_wipe_buffers();
        $n = 0;
        $msg = '';
        try {
            $input = (new Ewz_Webform_Set_Input( $_POST ))->get_input_data();
            $hide_action = $input['hide_webform'] ? 'Hidden' : 'UnHidden';
            if ( !(isset($input['webform_ids']) && is_array($input['webform_ids']) ) ){
                error_log( 'EWZ: ewz_hide_webforms_callback  - ' .  'no webform_ids or not array' );
                echo 'Invalid webform list';
            }
            foreach( $input['webform_ids'] as $wform_id ){
                $webform = new Ewz_Webform($wform_id  );
                ++$n;
                $webform->set_hidden_status( $input['hide_webform'] );

                $msg .= "\n". $webform->webform_title;
            }
            echo "$n Webforms $hide_action: $msg";
        } catch (Exception $e) {
            echo "$n Webforms processed: $msg" .  $e->getMessage();
        }
        wp_die();
    }
    exit();
}
add_action( 'wp_ajax_ewz_hide_webforms', 'ewz_hide_webforms_callback');

/**
 * Delete a Webform - handle ajax call
 *
 * Called via one of the "Delete Web Form" buttons on the Webforms page
 * NB: action name is generated from the jQuery post, must match.
 *
 * if response is not '1', javascript caller alerts with error message.
 * @return void
 */
function ewz_del_webform_callback() {
   if ( check_admin_referer( 'ewzadmin', 'ewznonce' ) ) {
        ewz_wipe_buffers();
        if ( !(isset( $_POST['webform_id'] ) && is_numeric( $_POST['webform_id'] )) ) {
            throw new EWZ_Exception( 'Missing or non-numeric webform_id' );
        } else {
            try {
                $webform = new Ewz_Webform( intval( $_POST['webform_id'] ) );
                $webform->delete( Ewz_Webform::DELETE_ITEMS );
                echo "1";
            } catch (Exception $e) {
                echo $e->getMessage();
            }
        }
    } else {
        echo "No deletion - authorization expired";
        error_log( "EWZ: ewz_del_webform_callback verify_nonce failed" );
    }
    exit();
}
add_action( 'wp_ajax_ewz_del_webform', 'ewz_del_webform_callback' );

/**
 * Upload csv file - handle ajax call
 *
 * Called via the Upload .... Data buttons in the Data Management area of the webform.
 * Calling page alerts with output of this function.
 * @return void
 */
function ewz_upload_csv_callback() {
     if ( check_admin_referer( 'ewzadmin', 'ewznonce' ) ) {
        ewz_wipe_buffers();
        if ( !(isset( $_POST['webform_id'] ) && is_numeric( $_POST['webform_id'] )) ) {
            throw new EWZ_Exception( 'Missing or non-numeric webform_id' );
        } else {
            try {
                $ischeck = 'check';
                if( !isset( $_POST['entry_radio'] )|| ( $_POST['entry_radio'] != 'check' )) {
                    $ischeck = '';
                }
                switch($_POST['ewzmode']){
                case 'itmcsvdata':  echo ewz_process_uploaded_admin_data( $_POST['webform_id'] );
                    break;
                case 'imgcsvdata':  echo ewz_process_uploaded_csv( $_POST['webform_id'] );
                    break;
                case 'entrydata':  echo ewz_process_uploaded_entry_data( $_POST['webform_id'],  $ischeck );
                    break;
                default: echo 'Invalid action';
                }
             } catch (Exception $e) {
                echo $e->getMessage();
            }
        }
    } else {
        echo "No upload - authorization expired";
        error_log( "EWZ: ewz_upload_csv_callback verify_nonce failed" );
    }
    exit();
}
add_action( 'wp_ajax_ewz_upload_csv', 'ewz_upload_csv_callback' );


/**
 * Upload data - handle ajax call
 *
 * Called via the Submit button on the Upload page
 * Calling page uses XMLHttpRequest, shows any text other than '1' as an alert
 * @return void
 */
function ewz_upload_callback() {
    require_once( EWZ_PLUGIN_DIR . 'includes/ewz-upload.php');

    if ( isset($_POST["ewzuploadnonce"]) && wp_verify_nonce( $_POST["ewzuploadnonce"], 'ewzupload' ) ) {
        ewz_wipe_buffers();
        // shortcode not defined within admin, need it here
        try {
            add_shortcode( 'ewz_show_webform', 'ewz_show_webform' );
            $errs = ewz_validate_and_upload();
            if( $errs ){
                echo $errs;
            } else {
                echo "1";
            }
        } catch (Exception $e) {
            echo $e->getMessage();
        }
    } else {
        echo "No updates - page may have expired, or upload size may have been over the limit of " . ini_get( 'post_max_size' );
        error_log( "EWZ: ewz_upload_callback verify_nonce failed" );
    }
    exit();
}
add_action( 'wp_ajax_ewz_upload', 'ewz_upload_callback' );



/**
 * Reset Items Per Page - handle ajax call
 *
 * Called via the (items)Apply button on the List page
 * Javascript ajax handler displays the returned message always
 * @return void
 */
function ewz_set_ipp_callback() {
    if ( check_admin_referer( 'ewzadmin', 'ewznonce' ) ) {
        ewz_wipe_buffers();
        try {
            $done = ewz_set_ipp();
            echo $done;
        } catch (Exception $e) {
            error_log( "EWZ: ewz_set_ipp_callback " . $e->getMessage() );
            echo $e->getMessage();
        }
    } else {
        error_log( "EWZ:  ewz_set_ipp_callback check_admin_referer failed" );
        echo "Insufficient permissions - may have expired";
    }
    exit();
}
add_action( 'wp_ajax_ewz_set_ipp', 'ewz_set_ipp_callback' );

/**
 * @return void
 */
function ewz_file_report_callback() {
    if ( check_admin_referer( 'ewzadmin', 'ewznonce' ) ) {
        ewz_wipe_buffers();
        try {
            $done = ewz_do_file_report();
            echo $done;
        } catch (Exception $e) {
            error_log( "EWZ: ewz_filereport_callback " . $e->getMessage() );
            echo $e->getMessage();
        }
    } else {
        error_log( "EWZ:  ewz_filereport_callback check_admin_referer failed" );
        echo "Insufficient permissions - may have expired";
    }
    exit();
}
add_action( 'wp_ajax_ewz_file_report', 'ewz_file_report_callback' );


/**
 * Delete the output buffers and turn off output buffering
 * @return void
 */
function ewz_wipe_buffers(){
    while(ob_get_level() > 0){
       @ob_end_clean();
    }
}
