<?php
/**
 * Export section of the plugin
 *
 * @link            
 *
 * @package  Wt_Import_Export_For_Woo
 */
if (!defined('ABSPATH')) {
    exit;
}
if(!class_exists('Wt_Import_Export_For_Woo_Basic_Export')){
class Wt_Import_Export_For_Woo_Basic_Export
{
	public $module_id='';
	public static $module_id_static='';
	public $module_base='export';

	public static $export_dir=WP_CONTENT_DIR.'/webtoffee_export';
	public static $export_dir_name='/webtoffee_export';
	public $steps=array();
	public $allowed_export_file_type=array();
	
	private $to_export='';
	private $to_export_id='';
	private $rerun_id=0;
	public $export_method='';
	public $export_methods=array();
	public $selected_template=0;
	public $default_batch_count=0; /* configure this value in `advanced_setting_fields` method */
	public $selected_template_data=array();
	public $default_export_method='';  /* configure this value in `advanced_setting_fields` method */
	public $use_bom = true;
	public $form_data=array();
        public $validation_rule = array();
        public $step_need_validation_filter = array();        

	public function __construct()
	{
		$this->module_id=Wt_Import_Export_For_Woo_Basic::get_module_id($this->module_base);
		self::$module_id_static=$this->module_id;

		/* allowed file types */
		$this->allowed_export_file_type=array(
			'csv'=>__('CSV', 'product-import-export-for-woo'),
			'xml'=>__('XML', 'product-import-export-for-woo')
		);

		/* default step list */
		$this->steps=array
		(
			'post_type'=>array(
				'title'=>__('Select a post type', 'product-import-export-for-woo'),
				'description'=>__('Export and download the data for the respective post type into a CSV file. As per the selected post type, we can use this exported CSV file to import data to your site.', 'product-import-export-for-woo'),
			),
			'method_export'=>array(
				'title'=>__('Select an export method', 'product-import-export-for-woo'),
				'description'=>__('Choose from the options below to continue with your export: quick export from DB, based on a pre-saved template or a new export with advanced options.', 'product-import-export-for-woo'),
			),
			'filter'=>array(
				'title'=>__('Filter data', 'product-import-export-for-woo'),
				'description'=>__('Filter data that needs to be exported as per the below criteria.', 'product-import-export-for-woo'),
			), 
			'mapping'=>array(
				'title'=>__('Map and reorder export columns', 'product-import-export-for-woo'),
				'description'=>__('The default export column names can be edited from the screen below, if required. If you have chosen a pre-saved template you can see the preferred names and choices that were last saved. You may also drag the columns accordingly to reorder them within the output file.', 'product-import-export-for-woo'),
			),
			'advanced'=>array(
				'title'=>__('Advanced options/Batch export', 'product-import-export-for-woo'),
				'description'=>__('You can save the template file for future exports or proceed with the export.', 'product-import-export-for-woo'),
			),
		);


		$this->validation_rule=array(
			'post_type'=>array(), /* no validation rule. So default sanitization text */
			'method_export'=>array(
				'mapping_enabled_fields' => array('type'=>'text_arr') //in case of quick export
			)
		);

		$this->step_need_validation_filter=array('filter', 'advanced');


		$this->export_methods=array(
			'quick'=>array('title'=>__('Quick export', 'product-import-export-for-woo'), 'description'=> __('Exports all the basic fields.', 'product-import-export-for-woo')),
			'template'=>array('title'=>__('Pre-saved template', 'product-import-export-for-woo'), 'description'=> __('Exports data as per the specifications(filters,selective column,mapping etc) from the previously saved file.', 'product-import-export-for-woo')),
			'new'=>array('title'=>__('Advanced export', 'product-import-export-for-woo'), 'description'=> __('Exports data after a detailed process of filtration, column selection and advanced options. The configured settings can be saved as a template for future exports.', 'product-import-export-for-woo')),
		);

		/* advanced plugin settings */
		add_filter('wt_iew_advanced_setting_fields_basic', array($this, 'advanced_setting_fields'), 11);

		/* setting default values, this method must be below of advanced setting filter */
		$this->get_defaults();

		/* main ajax hook. The callback function will decide which is to execute. */
		add_action('wp_ajax_iew_export_ajax_basic', array($this, 'ajax_main'), 11);

		/* Admin menu for export */
		add_filter('wt_iew_admin_menu_basic', array($this, 'add_admin_pages'), 10, 1);

		/* Download export file via nonce URL */
		add_action('admin_init', array($this, 'download_file'), 11);
		
		/* The ad banner will be dismissed permenantly */
		add_action('wp_ajax_iew_export_dismiss_adbanner', array($this, 'iew_export_dismiss_adbanner'), 10);
		
	}
	
	
		/**
		 * 	Dismiss pro ad banner after exporting download
		 */
		public function iew_export_dismiss_adbanner() {

			if (Wt_Iew_Sh::check_write_access(WT_IEW_PLUGIN_ID_BASIC)) {
				update_option('wt_ier_pro_banner_dismissed', true);
			}
		}

		public function get_defaults()
	{	
		$this->default_export_method= Wt_Import_Export_For_Woo_Basic_Common_Helper::get_advanced_settings('default_export_method');
		$this->default_batch_count=Wt_Import_Export_For_Woo_Basic_Common_Helper::get_advanced_settings('default_export_batch');
		$this->use_bom = (bool)Wt_Import_Export_For_Woo_Basic_Common_Helper::get_advanced_settings('include_bom');
	}

	/**
	*	Fields for advanced settings
	*
	*/
	public function advanced_setting_fields($fields)
	{
		$export_methods=array_map(function($vl){ return $vl['title']; }, $this->export_methods);
		$fields['default_export_method']=array(
			'label'=>__("Default Export method", 'product-import-export-for-woo'),
			'type'=>'select',
			'sele_vals'=>$export_methods,
            'value' =>'new',
			'field_name'=>'default_export_method',
			'field_group'=>'advanced_field',
			'help_text'=>__('Select the default method of export.', 'product-import-export-for-woo'),
		);
		
		$fields['include_bom'] = array(
			'label'=>__( "Include BOM in export file", 'product-import-export-for-woo' ),
			'value'=>1,
			'checkbox_fields' => array( 1 => __( 'Enable', 'product-import-export-for-woo' ) ),
			'type'=>'checkbox',
			'field_name'=>'include_bom',
			'field_group'=>'advanced_field',
			'help_text'=>__( "The BOM will help some programs like Microsoft Excel read your export file if it includes non-English characters.", 'product-import-export-for-woo' ),
		);
		
		$fields['default_export_batch']=array(
			'label'=>__("Default Export batch count", 'product-import-export-for-woo'),
			'type'=>'number',
                        'value' =>30,
			'field_name'=>'default_export_batch',
			'help_text'=>__('Provide the default count for the records to be exported in a batch.', 'product-import-export-for-woo'),
			'validation_rule'=>array('type'=>'absint'),
			'attr' => array('min' => 1, 'max' => 200),
		);
                
		$fields['enable_chatgpt'] = array(
			'label'=>__( "Enable ChatGPT", 'product-import-export-for-woo' ),
			'value'=>0,
			'checkbox_fields' => array( 1 => __( 'Enable', 'product-import-export-for-woo' ) ),
			'type'=>'checkbox',
			'field_name'=>'enable_chatgpt',
			'field_group'=>'advanced_field',
			'help_text'=>__( 'Automatically generate product descriptions from product titles using ChatGPT API for products without descriptions in the importing CSV.', 'product-import-export-for-woo' ),
                    	'form_toggler'=>array(
				'type'=>'parent',
				'target'=>'wt_iew_enable_chatgpt',
			),
		);                
		$fields['chatgpt_api_key'] = array(
                        'label' => __("Chat GPT API key", 'product-import-export-for-woo'),
                        'type' => 'text',
                        'value' => '',
                        'field_name' => 'chatgpt_api_key',
                        'field_group' => 'advanced_field',
                        // translators: %1$s is opening link tag, %2$s is closing link tag
                        'help_text' => sprintf(__('Input the ChatGPT API key to enable the automatic generation of product descriptions. %1$s Where do I get my API Keys? %2$s ', 'product-import-export-for-woo'), '<a href="https://help.openai.com/en/articles/4936850-where-do-i-find-my-secret-api-key" target="_blank">', '</a>'),                        
                        'validation_rule' => array('type' => 'text'),
                    	'form_toggler'=>array(
				'type'=>'child',
				'id'=>'wt_iew_enable_chatgpt',
				'val'=>1,
				'chk'=>'true'
			),
                );

            return $fields;
	}

	/**
	* Adding admin menus
	*/
	public function add_admin_pages($menus)
	{		
		$menu_temp=array(
			$this->module_base=>array(
				'menu',
				__('Export', 'product-import-export-for-woo'),
				__('WebToffee Import Export (Basic)', 'product-import-export-for-woo'),
				apply_filters('wt_import_export_allowed_capability', 'import'),
				$this->module_id,
				array($this,'admin_settings_page'),
				'dashicons-controls-repeat',
				56
			),
			$this->module_base.'-sub'=>array(
				'submenu',
				$this->module_id,
				__('Export', 'product-import-export-for-woo'),
				__('Export', 'product-import-export-for-woo'), 
				apply_filters('wt_import_export_allowed_capability', 'import'),
				$this->module_id,
				array($this, 'admin_settings_page')
			),
		);
		unset($menus['general-settings']);
		$menus=array_merge($menu_temp, $menus);
		return $menus;
	}

	/**
	* 	Export page
	*/
	public function admin_settings_page()
	{
		/**
		*	Check it is a rerun call
		*/
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification handled by admin interface
		$requested_rerun_id=(isset($_GET['wt_iew_rerun']) ? absint($_GET['wt_iew_rerun']) : 0);
		$this->_process_rerun($requested_rerun_id);

		$this->enqueue_assets();
		include plugin_dir_path(__FILE__).'views/main.php';
	}

	/**
	* 	Main ajax hook to handle all export related requests
	*/
	public function ajax_main()
	{       

		include_once plugin_dir_path(__FILE__).'classes/class-export-ajax.php';
		if(Wt_Iew_Sh::check_write_access(WT_IEW_PLUGIN_ID_BASIC))
		{
			/**
			*	Check it is a rerun call
			*/
			// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification is handled by Wt_Iew_Sh::check_write_access() above
			if(!$this->_process_rerun((isset($_POST['rerun_id']) ? absint($_POST['rerun_id']) : 0)))
			{	
				// phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce verified above, input is sanitized via Wt_Iew_Sh::sanitize_item()
				$this->export_method=(isset($_POST['export_method']) ? Wt_Iew_Sh::sanitize_item(wp_unslash($_POST['export_method']), 'text') : '');
				// phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce verified above, input is sanitized via Wt_Iew_Sh::sanitize_item()
				$this->to_export=(isset($_POST['to_export']) ? Wt_Iew_Sh::sanitize_item(wp_unslash($_POST['to_export']), 'text') : '');
				// phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce verified above, input is sanitized via Wt_Iew_Sh::sanitize_item()
				$this->selected_template=(isset($_POST['selected_template']) ? Wt_Iew_Sh::sanitize_item(wp_unslash($_POST['selected_template']), 'int') : 0);
			}		
			
			$this->get_steps();

			$ajax_obj=new Wt_Import_Export_For_Woo_Basic_Export_Ajax($this, $this->to_export, $this->steps, $this->export_method, $this->selected_template, $this->rerun_id);
			
			// phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotValidated,WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce verified above, input is sanitized via Wt_Iew_Sh::sanitize_item()
			$export_action=Wt_Iew_Sh::sanitize_item(isset($_POST['export_action']) ? wp_unslash($_POST['export_action']) : '', 'text');
			// phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotValidated,WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce verified above, input is sanitized via Wt_Iew_Sh::sanitize_item()
			$data_type=Wt_Iew_Sh::sanitize_item(isset($_POST['data_type']) ? wp_unslash($_POST['data_type']) : '', 'text');
			
			$allowed_ajax_actions=array('get_steps', 'get_meta_mapping_fields', 'save_template', 'save_template_as', 'update_template', 'upload', 'export', 'export_image');

			$out=array(
				'status'=>0,
				'msg'=>__('Error', 'product-import-export-for-woo'),
			);

			if(method_exists($ajax_obj, $export_action) && in_array($export_action, $allowed_ajax_actions))
			{
				$out=$ajax_obj->{$export_action}($out);
			}

			if($data_type=='json')
			{
				echo json_encode($out);
			}
		}
		exit();
	}

	public function get_filter_screen_fields($filter_form_data) {
            $filter_screen_fields = array(
                'limit' => array(
                    'label' => __("Limit", 'product-import-export-for-woo'),
                    'value' => '',
                    'type' => 'number',
                    'field_name' => 'limit',
                    'placeholder' => 'Unlimited',
                    'help_text' => __('The actual number of records you want to export. e.g. A limit of 500 with an offset 10 will export records from 11th to 510th position.', 'product-import-export-for-woo'),
                    'attr' => array('step' => 1, 'min' => 0),
                    'validation_rule' => array('type' => 'absint')
                ),
                'offset' => array(
                    'label' => __("Offset", 'product-import-export-for-woo'),
                    'value' => '',
                    'field_name' => 'offset',
                    'placeholder' => __('0', 'product-import-export-for-woo'),
                    'help_text' => __('Specify the number of records that should be skipped from the beginning of the database. e.g. An offset of 10 skips the first 10 records.', 'product-import-export-for-woo'),
                    'type' => 'number',
                    'attr' => array('step' => 1, 'min' => 0),
                    'validation_rule' => array('type' => 'absint')
                ),
            );
            $filter_screen_fields = apply_filters('wt_iew_exporter_alter_filter_fields_basic', $filter_screen_fields, $this->to_export, $filter_form_data);
            return $filter_screen_fields;
        }

        public function get_advanced_screen_fields($advanced_form_data)
	{
		$file_into_arr=array('local'=>__('Local', 'product-import-export-for-woo'));

		/* taking available remote adapters */
		$remote_adapter_names=array();
		$remote_adapter_names=apply_filters('wt_iew_exporter_remote_adapter_names_basic', $remote_adapter_names);
		if($remote_adapter_names && is_array($remote_adapter_names))
		{
			foreach($remote_adapter_names as $remote_adapter_key => $remote_adapter_vl)
			{
				$file_into_arr[$remote_adapter_key]=$remote_adapter_vl;
			}
		}

		$delimiter_default = isset($advanced_form_data['wt_iew_delimiter']) ? $advanced_form_data['wt_iew_delimiter'] : ",";
		$advanced_screen_fields=array(
			'file_name'=>array(
				'label'=>__("Export file name", 'product-import-export-for-woo'),
				'type'=>'text',
				'field_name'=>'file_name',
				'help_text'=>__('Specify a filename for the exported file. If left blank, the system generates the name automatically.', 'product-import-export-for-woo'),
				'after_form_field_html'=>'<div class="wt_iew_file_ext_info_basic">.csv</div>',//Always pass safe data.
				'td_class3'=>'wt_iew_file_ext_info_td',
				'validation_rule'=>array('type'=>'file_name'),
			),
			'batch_count'=>array(
				'label'=>__("Export in batches of", 'product-import-export-for-woo'),
				'type'=>'text',
                                'merge_right'=>true,
				'value'=>$this->default_batch_count,
				'field_name'=>'batch_count',
				// translators: %d is the default number of records
				'help_text'=>sprintf(__('The number of records that the server will process for every iteration within the configured timeout interval. If the export fails due to timeout you can lower this number accordingly and try again. Defaulted to %d records.', 'product-import-export-for-woo'), 30),
				'validation_rule'=>array('type'=>'absint'),
			),
			'delimiter'=>array(
				'label'=>__( 'Delimiter', 'product-import-export-for-woo' ),
				'type'=>'select',
				'value'=>",",
				'css_class'=>"wt_iew_delimiter_preset",
				'tr_id'=>'delimiter_tr',
				'field_name'=>'delimiter_preset',
				'sele_vals'=>Wt_Iew_IE_Basic_Helper::_get_csv_delimiters(),
				'help_text'=>__( 'Separator for differentiating the columns in the CSV file. Assumes comma by default.', 'product-import-export-for-woo' ),
				'validation_rule'=>array('type'=>'skip'),
				'after_form_field'=>'<input type="text" class="wt_iew_custom_delimiter" name="wt_iew_delimiter" value="'.esc_attr($delimiter_default).'" maxlength = "1" />',//Always pass safe data.
			)
		);

		/* taking advanced fields from post type modules */
		$advanced_screen_fields=apply_filters('wt_iew_exporter_alter_advanced_fields_basic', $advanced_screen_fields, $this->to_export, $advanced_form_data);
		return $advanced_screen_fields;
	}

	/**
	* Get steps
	*
	*/
	public function get_steps()
	{
		if($this->export_method=='quick') /* if quick export then remove some steps */
		{
			$out=array(
				'post_type'=>$this->steps['post_type'],
				'method_export'=>$this->steps['method_export'],
				'advanced'=>$this->steps['advanced'],
			);
			$this->steps=$out;
		}
		$this->steps=apply_filters('wt_iew_exporter_steps_basic', $this->steps, $this->to_export);
		return $this->steps;
	}
	

	/**
	*	Validating and Processing rerun action
	*/
	protected function _process_rerun($rerun_id)
	{
		if($rerun_id>0)
		{
			/* check the history module is available */
			$history_module_obj=Wt_Import_Export_For_Woo_Basic::load_modules('history');
			if(!is_null($history_module_obj))
			{
				/* check the history entry is for export and also has form_data */
				$history_data=$history_module_obj->get_history_entry_by_id($rerun_id);
				if($history_data && $history_data['template_type']==$this->module_base)
				{
					$form_data_raw = wp_unslash($history_data['data']);
					$form_data = is_array($form_data_raw) ? 
							array_map(function($item) {
								return is_string($item) ? json_decode($item, true) : $item;
							}, $form_data_raw) : 
							json_decode($form_data_raw, true);
					if($form_data && is_array($form_data))
					{
						$this->to_export=(isset($form_data['post_type_form_data']) && isset($form_data['post_type_form_data']['item_type']) ? $form_data['post_type_form_data']['item_type'] : '');
						if($this->to_export!="")
						{
							$this->export_method=(isset($form_data['method_export_form_data']) && isset($form_data['method_export_form_data']['method_export']) && $form_data['method_export_form_data']['method_export']!="" ?  $form_data['method_export_form_data']['method_export'] : $this->default_export_method);
							$this->rerun_id=$rerun_id;
							$this->form_data=$form_data;
							//process steps based on the export method in the history entry
							$this->get_steps();

							return true;
						}
					}
				}
			}
		}
		return false;
	}

	protected function enqueue_assets()
	{
            if(Wt_Import_Export_For_Woo_Basic_Common_Helper::wt_is_screen_allowed()){
		wp_enqueue_script($this->module_id, plugin_dir_url(__FILE__).'assets/js/main.js', array('jquery', 'jquery-ui-sortable', 'jquery-ui-datepicker'), WT_P_IEW_VERSION, true);
		wp_enqueue_style('jquery-ui-datepicker');
		wp_enqueue_style(WT_IEW_PLUGIN_ID_BASIC.'-jquery-ui', WT_P_IEW_PLUGIN_URL.'admin/css/jquery-ui.css', array(), WT_P_IEW_VERSION, 'all');
        $params=array(
			'item_type'=>'',
			'steps'=>$this->steps,
			'rerun_id'=>$this->rerun_id,
			// phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.MissingUnslash -- GET parameter for UI state, nonce not required
			'to_export'=> isset( $_GET['wt_to_export'] ) ? sanitize_text_field( wp_unslash( $_GET['wt_to_export'] ) ) : $this->to_export,
			'export_method'=>$this->export_method,
			'msgs'=>array(
				'choosed_template'=>__('Choosed template:', 'product-import-export-for-woo'),
				'choose_export_method'=>__('Please select an export method.', 'product-import-export-for-woo'),
				'choose_template'=>__('Please select an export template.', 'product-import-export-for-woo'),
				'step'=>__('Step', 'product-import-export-for-woo'),
				'choose_ftp_profile'=>__('Please select an FTP profile.', 'product-import-export-for-woo'),
				//localized strings for filename validation
				'filename_title' => __('Only letters, numbers and hyphens are allowed', 'product-import-export-for-woo'),
				'filename_placeholder' => __('Enter file name (letters, numbers, hyphens only)', 'product-import-export-for-woo'),
			),
		);
		wp_localize_script($this->module_id, 'wt_iew_export_basic_params', $params);

		$this->add_select2_lib(); //adding select2 JS, It checks the availibility of woocommerce
            }
	}

	/**
	* 
	* Enqueue select2 library, if woocommerce available use that
	*/
	protected function add_select2_lib()
	{
		/* enqueue scripts */
		if(!function_exists('is_plugin_active'))
		{
			include_once(ABSPATH.'wp-admin/includes/plugin.php');
		}
		if ( class_exists( 'WooCommerce' ) )
		{ 
			wp_enqueue_script('wc-enhanced-select');
			wp_enqueue_style('woocommerce_admin_styles', WC()->plugin_url().'/assets/css/admin.css', array(), WC()->version);
		}else
		{
			wp_enqueue_style(WT_IEW_PLUGIN_ID_BASIC.'-select2', WT_P_IEW_PLUGIN_URL. 'admin/css/select2.css', array(), WT_P_IEW_VERSION, 'all' );
			wp_enqueue_script(WT_IEW_PLUGIN_ID_BASIC.'-select2', WT_P_IEW_PLUGIN_URL.'admin/js/select2.js', array('jquery'), WT_P_IEW_VERSION, false );
		}
	}


	/**
	* Upload data to the user choosed remote method (Eg: FTP)
	* @param   string   $step       the action to perform, here 'upload'
	*
	* @return array 
	*/
	public function process_upload($step, $export_id, $to_export)
	{
		$out=array(
			'response'=>false,
			'export_id'=>0,
			'history_id'=>0, //same as that of export id
			'finished'=>0,
			'file_url'=>'',
			'msg'=>'',
		);

		if($export_id==0) //it may be an error
		{
			return $out;
		}

		//take history data by export_id
		$export_data=Wt_Import_Export_For_Woo_Basic_History::get_history_entry_by_id($export_id);
		if(is_null($export_data)) //no record found so it may be an error
		{
			return $out;
		}

		$form_data_raw = wp_unslash($export_data['data']);
		$form_data = is_array($form_data_raw) ? 
				array_map(function($item) {
					return is_string($item) ? json_decode($item, true) : $item;
				}, $form_data_raw) : 
				json_decode($form_data_raw, true);

		//taking file name
		$file_name=(isset($export_data['file_name']) ? $export_data['file_name'] : '');
		
		$file_path=$this->get_file_path($file_name);
		if($file_path===false)
		{
			$update_data=array(
				'status'=>Wt_Import_Export_For_Woo_Basic_History::$status_arr['failed'],
				'status_text'=>'File not found.' //no need to add translation function
			);
			$update_data_type=array(
				'%d',
				'%s',
			);
			Wt_Import_Export_For_Woo_Basic_History::update_history_entry($export_id, $update_data, $update_data_type);

            return $out;
		}

		/* updating output parameters */
		$out['export_id']=$export_id;
		$out['history_id']=$export_id;
		$out['file_url']='';

		//check where to copy the files
		$file_into='local';
		if(isset($form_data['advanced_form_data']))
		{
			$file_into=(isset($form_data['advanced_form_data']['wt_iew_file_into']) ? $form_data['advanced_form_data']['wt_iew_file_into'] : 'local');
		}

		if('local' != $file_into) /* file not save to local. Initiate the choosed remote profile */
		{
			$remote_adapter=Wt_Import_Export_For_Woo_Basic::get_remote_adapters('export', $file_into);
			if(is_null($remote_adapter)) /* adapter object not found */
			{
				$msg=sprintf('Unable to initailize %s', $file_into);
				Wt_Import_Export_For_Woo_Basic_History::record_failure($export_id, $msg);
				$out['msg'] = esc_html($msg);
				return $out;
			}

			/* upload the file */
			$upload_out_format = array('response'=>true, 'msg'=>'');

			$advanced_form_data=(isset($form_data['advanced_form_data']) ? $form_data['advanced_form_data'] : array());

			$upload_data = $remote_adapter->upload($file_path, $file_name, $advanced_form_data, $upload_out_format);
			$out['response'] = (isset($upload_data['response']) ? $upload_data['response'] : false);
			$out['msg'] = (isset($upload_data['msg']) ? $upload_data['msg'] : __('Error', 'product-import-export-for-woo'));

			//unlink the local file
			@unlink($file_path);
		}else
		{
			$out['response']=true;
			$out['file_url']=html_entity_decode($this->get_file_url($file_name));
		}

		$out['finished']=1;  //if any error then also its finished, but with errors
		if($out['response'] === true) //success
		{
			$out['msg']=__('Finished', 'product-import-export-for-woo');
			
			/* updating finished status */
			$update_data=array(
				'status'=>1  //success
			);
			$update_data_type=array(
				'%d'
			);
			Wt_Import_Export_For_Woo_Basic_History::update_history_entry($export_id, $update_data, $update_data_type);

		}else //failed
		{
			//no need to add translation function in message
			Wt_Import_Export_For_Woo_Basic_History::record_failure($export_id, 'Failed while uploading');
		}
		return $out;
	}


	/**
	* 	Do the export process
	*/
	public function process_action($form_data, $step, $to_process, $file_name='', $export_id=0, $offset=0)
	{
		$out=array(
			'response'=>false,
			'new_offset'=>0,
			'export_id'=>0,
			'history_id'=>0, //same as that of export id
			'total_records'=>0,
			'finished'=>0,
			'file_url'=>'',
			'msg'=>'',
		);

		/* prepare form_data, If this was not first batch */
		if($export_id>0)
		{
			//take history data by export_id
			$export_data=Wt_Import_Export_For_Woo_Basic_History::get_history_entry_by_id($export_id);
			if(is_null($export_data)) //no record found so it may be an error
			{
				return $out;
			}

			//processing form data
			$form_data_raw = wp_unslash($export_data['data']);
			$unserialized_data = is_array($form_data_raw) ? 
					array_map(function($item) {
						return is_string($item) ? json_decode($item, true) : $item;
					}, $form_data_raw) : 
					json_decode($form_data_raw, true);
			$form_data = (isset($unserialized_data) ? $unserialized_data : array()); 
		}
		$this->to_export=$to_process;
		$default_batch_count=$this->_get_default_batch_count($form_data);
		$batch_count=$default_batch_count;		
		$file_as='csv';
		$csv_delimiter=',';
		$total_records=0;
		if(isset($form_data['advanced_form_data']))
		{
			$batch_count=(isset($form_data['advanced_form_data']['wt_iew_batch_count']) ? $form_data['advanced_form_data']['wt_iew_batch_count'] : $batch_count);
			$file_as=(isset($form_data['advanced_form_data']['wt_iew_file_as']) ? $form_data['advanced_form_data']['wt_iew_file_as'] : 'csv');
			$csv_delimiter=(isset($form_data['advanced_form_data']['wt_iew_delimiter']) ? $form_data['advanced_form_data']['wt_iew_delimiter'] : ',');
			$csv_delimiter=($csv_delimiter=="" ? ',' : $csv_delimiter);
		}		
		$file_as=(isset($this->allowed_export_file_type[$file_as]) ? $file_as : 'csv');

		
		$generated_file_name=$this->to_export.'_export_'.current_time('Y-m-d-h-i-s').'.'.$file_as;

		if($export_id==0) //first batch then create a history entry
		{
			$file_name=($file_name=="" ? $generated_file_name : sanitize_file_name($file_name.'.'.$file_as));
			$export_id=Wt_Import_Export_For_Woo_Basic_History::create_history_entry($file_name, $form_data, $this->to_export, $step);
			$offset=0;
		}else
		{
			//taking file name from export data
			$file_name=(isset($export_data['file_name']) ? $export_data['file_name'] : $generated_file_name);		
			$total_records=(isset($export_data['total']) ? $export_data['total'] : 0);
		}

		/* setting history_id in Log section */
		Wt_Import_Export_For_Woo_Basic_Log::$history_id=$export_id;


		$file_path=$this->get_file_path($file_name);
		if($file_path===false)
		{
			$msg='Unable to create backup directory. Please grant write permission for `wp-content` folder.';		
			
			//no need to add translation function in message
			Wt_Import_Export_For_Woo_Basic_History::record_failure($export_id, $msg);

			//phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText
            $out['msg']= __( $msg, 'product-import-export-for-woo');
            return $out;
		}

		/* giving full data */
		$form_data=apply_filters('wt_iew_export_full_form_data_basic', $form_data, $to_process, $step, $this->selected_template_data);

		/* hook to get data from corresponding module. Eg: product, order */
		$export_data=array(
			'total'=>100,
			'head_data'=>array("abc"=>"hd1", "bcd"=>"hd2", "cde"=>"hd3", "def"=>"hd4"),
			'body_data'=>array(
				array("abc"=>"Abc1", "bcd"=>"Bcd1", "cde"=>"Cde1", "def"=>"Def1"),
  				array("abc"=>"Abc2", "bcd"=>"Bcd2", "cde"=>"Cde2", "def"=>"Def2")
			),
		); 		

		/* in scheduled export. The export method will not available so we need to take it from form_data */
		$form_data_export_method=(isset($form_data['method_export_form_data']) && isset($form_data['method_export_form_data']['method_export']) ?  $form_data['method_export_form_data']['method_export'] : $this->default_export_method);
		$this->export_method=($this->export_method=="" ? $form_data_export_method : $this->export_method);

		$export_data=apply_filters('wt_iew_exporter_do_export_basic', $export_data, $to_process, $step, $form_data, $this->selected_template_data, $this->export_method, $offset);
		if($offset==0)
		{
			$total_records=intval(isset($export_data['total']) ? $export_data['total'] : 0);
		}
		$this->_update_history_after_export($export_id, $offset, $total_records, $export_data);

		/* checking action is finshed */
		$is_last_offset=false;
		$new_offset=$offset+$batch_count; //increase the offset
		if($new_offset>=$total_records) //finished
		{
			$is_last_offset=true;
		}


		/* no data from corresponding module */
		if(!$export_data) //error !!!
		{
			//return $out;
		}else
		{

				include_once WT_P_IEW_PLUGIN_PATH.'admin/classes/class-csvwriter.php';
				$writer=new Wt_Import_Export_For_Woo_Basic_Csvwriter($file_path, $offset, $csv_delimiter, $this->use_bom);

                                                
                        /**
			*	Alter export data before writing to file.
			*	@param 	array 	$export_data  		data to export
			*	@param 	int 	$offset  			current offset
			*	@param 	boolean $is_last_offset 	is current offset is last one
			*	@param 	string 	$file_as 			file type to write Eg: XML, CSV
			*	@param 	string 	$to_export 			Post type
			*	@param 	string 	$csv_delimiter 		CSV delimiter. In case of CSV export
			*	@return array 	$export_data 		Altered export data
			*/
			$export_data=apply_filters('wt_iew_alter_export_data_basic', $export_data, $offset, $is_last_offset, $file_as, $this->to_export, $csv_delimiter);                        
			$writer->write_to_file($export_data, $offset, $is_last_offset, $this->to_export);
		}
		
		/* updating output parameters */
		$out['total_records']=$total_records;
		$out['export_id']=$export_id;
		$out['history_id']=$export_id;
		$out['file_url']='';
		$out['response']=true;

		/* updating action is finshed */	
		if($is_last_offset) //finished
		{
			//check where to copy the files
			$file_into='local';
			if(isset($form_data['advanced_form_data']))
			{
				$file_into=(isset($form_data['advanced_form_data']['wt_iew_file_into']) ? $form_data['advanced_form_data']['wt_iew_file_into'] : 'local');
			}
			if('local' != $file_into) /* file not save to local. Initiate the choosed remote profile */
			{
				$out['finished']=2; //file created, next upload it

				// translators: %s is the upload destination name
				$out['msg']=sprintf(__('Uploading to %s', 'product-import-export-for-woo'), $file_into);
			}else
			{
				$out['file_url']=html_entity_decode($this->get_file_url($file_name));
				$out['finished']=1; //finished

				$msg = __('Export file processing completed', 'product-import-export-for-woo');
                                $msg.='<span class="wt_iew_popup_close" style="line-height:10px;width:auto" onclick="wt_iew_basic_export.hide_export_info_box();">X</span>';
                                
                                $msg.='<span class="wt_iew_info_box_finished_text" style="font-size: 10px; display:block">';
                                if(Wt_Import_Export_For_Woo_Admin_Basic::module_exists('history'))
                                {
                                        $history_module_id= Wt_Import_Export_For_Woo_Basic::get_module_id('history');
                                        $history_page_url=admin_url('admin.php?page='.$history_module_id);
                                        $msg.=__('You can manage exports from History section.', 'product-import-export-for-woo');
                                }
                                
                                $msg.='<a class="button button-secondary" style="margin-top:10px;" onclick="wt_iew_basic_export.hide_export_info_box();" target="_blank" href="'.$out['file_url'].'" >'.__('Download file', 'product-import-export-for-woo').'</a></span>';
				if( 0 == $total_records && isset( $export_data['no_post'] ) ){
					
					$out['no_post'] = true;
					$msg = $export_data['no_post'];                    
				}
				$out['msg']=$msg;
				
				/* updating finished status */
				$update_data=array(
					'status'=>Wt_Import_Export_For_Woo_Basic_History::$status_arr['finished'],
					'status_text'=>'Finished' //translation function not needed
				);
				$update_data_type=array(
					'%d',
					'%s',
				);
				Wt_Import_Export_For_Woo_Basic_History::update_history_entry($export_id,$update_data,$update_data_type);
			}

		}else
		{
			$out['new_offset']=$new_offset;
			// translators: %1$d is current offset, %2$d is total records
			$out['msg']=sprintf(__('Exporting...(%1$d out of %2$d)', 'product-import-export-for-woo'), $new_offset, $total_records);
		}
		return $out;
	}


	public static function get_file_path($file_name)
	{
		global $wp_filesystem;
	
		// Initialize WP_Filesystem
		if (!function_exists('WP_Filesystem')) {
			require_once(ABSPATH . 'wp-admin/includes/file.php');
		}
		WP_Filesystem();
		
		// Create directory using WP_Filesystem
		if (!$wp_filesystem->is_dir(self::$export_dir)) {
			if (!$wp_filesystem->mkdir(self::$export_dir, FS_CHMOD_DIR)) {
				return false;
			}
		}
		
		// Ensure proper permissions and add index.php for security
		$wp_filesystem->chmod(self::$export_dir, FS_CHMOD_DIR);
		
		// Add security files to prevent directory listing and direct access
		$security_files = array(
			'index.php' => '<?php' . PHP_EOL . '// Silence is golden',
			'.htaccess' => 'deny from all'
		);
		
		foreach ($security_files as $file => $content) {
			if (!$wp_filesystem->exists(self::$export_dir . '/' . $file)) {
				$wp_filesystem->put_contents(
					self::$export_dir . '/' . $file,
					$content
				);
			}
		}
		return self::$export_dir.'/'.$file_name;
	}

	/**
	*  	Download file via a nonce URL
	*/
	public function download_file()
	{
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is handled by check_write_access()
		if(isset($_GET['wt_iew_export_download'])) {

			if(Wt_Iew_Sh::check_write_access(WT_IEW_PLUGIN_ID_BASIC)) { /* check nonce and role */
			
				// phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.MissingUnslash -- Nonce verified above
				$file_name = isset($_GET['file']) ? sanitize_file_name(wp_unslash($_GET['file'])) : '';
				if($file_name != "") {
					$file_arr = explode(".", $file_name);
					$file_ext = strtolower(end($file_arr));
					if(isset($this->allowed_export_file_type[$file_ext]) || $file_ext == 'zip') { /* Only allowed files. Zip file in image export */
					
						$file_path = realpath(self::$export_dir . '/' . $file_name);
						
						// Get the allowed export directory and its real path
						$export_dir = realpath(WP_CONTENT_DIR.'/webtoffee_export');
						
						// Verify file is within allowed export directory
						if($file_path && $export_dir && strpos($file_path, $export_dir) === 0 && file_exists($file_path) && is_file($file_path)) { /* check existence of file and verify path */
							//  Clear previous output before downloading
							while ( ob_get_level() > 0 ) {
								@ob_end_clean();
							}
							@ob_start();
							header('Pragma: public');
						    header('Expires: 0');
						    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
						    header('Cache-Control: private', false);
						    header('Content-Transfer-Encoding: binary');
						    header('Content-Disposition: attachment; filename="'.$file_name.'";');
						    header('Content-Description: File Transfer');
						    header('Content-Type: application/octet-stream');
						    //header('Content-Length: '.filesize($file_path));

						    $chunk_size = 1024 * 1024;
						    // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen -- Direct filesystem operation needed for file download
						    $handle=@fopen($file_path, 'rb');
						    while(!feof($handle))
						    {
						        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fread -- Direct filesystem operation needed for file download
						        $buffer = fread($handle, $chunk_size);
						        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Binary file output for download, escaping not applicable
						        echo $buffer;
						        ob_flush();
						        flush();
						    }
						    // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- Direct filesystem operation needed for file download
						    fclose($handle);
						    exit();
						}
					}
				}	
			}
		}
	}

	private function _update_history_after_export($export_id, $offset, $total_records, $export_data)
	{
		/* we need to update total record count on first batch */
		if($offset==0)
		{
			$update_data=array(
				'total'=>$total_records
			);			
		}else
		{
			/* updating completed offset */
			$update_data=array(
				'offset'=>$offset
			);
		}
		$update_data_type=array(
			'%d'
		);
		Wt_Import_Export_For_Woo_Basic_History::update_history_entry($export_id, $update_data, $update_data_type);
	}

	private function _get_default_batch_count($form_data)
	{
		$default_batch_count=absint(apply_filters('wt_iew_exporter_alter_default_batch_count_basic', $this->default_batch_count, $this->to_export, $form_data));
		$form_data=null;
		unset($form_data);
		return ($default_batch_count==0 ? $this->default_batch_count : $default_batch_count);
	}

	/**
	*	Generating downloadable URL for a file
	*/
	private function get_file_url($file_name)
	{
		return wp_nonce_url(admin_url('admin.php?wt_iew_export_download=true&file='.$file_name), WT_IEW_PLUGIN_ID_BASIC);
	}
}
}
Wt_Import_Export_For_Woo_Basic::$loaded_modules['export']=new Wt_Import_Export_For_Woo_Basic_Export();