HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/BOoms/pro-oils.be/wwwroot/wp-content/plugins/ppom-pro-fout/ppom.php
<?php
/*
 Plugin Name: N-Media WooCommerce PPOM PRO
Plugin URI: http://najeebmedia.com/wordpress-plugin/woocommerce-personalized-product-option/
Description: This plugin allow WooCommerce Store Admin to create unlimited input fields and files to attach with Product Page
Version: 18.16
Author: Najeeb Ahmad
Text Domain: ppom
Domain Path: /languages
Author URI: http://www.najeebmedia.com/
WC requires at least: 3.0.0
WC tested up to: 5.3.0
*/


/**
 * Changelog being added for PRO version 
 * 
 * Version 18.16
 * Bug fixed: Warnings removed when order status udpated: https://clients.najeebmedia.com/forums/topic/multiple-php-errors-in-ppom-php-file/
 **/


// Authencation checking
if( ! class_exists('NM_Auth') ) {
	$_auth_class = dirname(__FILE__).'/Auth/auth.php';
	if( file_exists($_auth_class))
		include_once($_auth_class);
	else
		die('Reen, Reen, BUMP! not found '.$_auth_class);
}

/**
 * Plugin API Validation
 * *** DO NOT REMOVE These Lines
 * */
define('PPOM_PLUGIN_PATH', "ppom-pro/ppom.php");
define('PPOM_REDIRECT_URL', admin_url( 'admin.php?page=ppom' ));
define('PPOM_PLUGIN_ID', 2235);
NM_AUTH(PPOM_PLUGIN_PATH, PPOM_REDIRECT_URL, PPOM_PLUGIN_ID);

define('PPOM_PRO_PATH', untrailingslashit(plugin_dir_path( __FILE__ )) );
define('PPOM_PRO_URL', untrailingslashit(plugin_dir_url( __FILE__ )) );
define('PPOM_PRO_VERSION', '18.16' );

include_once( PPOM_PRO_PATH.'/auto-update.php');

class PPOM_PRO {
    
    private static $ins = null;
    
    function __construct() {
        
        if( ! $this->is_ppom_installed() ) {
            add_action( 'admin_notices', array($this, 'ppom_notice_not_installed') );
            return '';
        }
        
        if( ! $this->is_ppom_validated() ) {
            add_action( 'admin_notices', array($this, 'ppom_notice_not_validated') );
            return '';
        }
        
        // Remove Get pro notice from admin
        remove_action('ppom_after_ppom_field_admin', 'ppom_admin_pro_version_notice', 10);
        
        // Loading some fields scripts
        add_action('ppom_hooks_inputs', array($this, 'hook_input_scripts'), 10, 2 );
        
        // Loading all input in PRO
        add_filter('ppom_all_inputs', array($this, 'load_all_inputs'), 10, 2);
        
        // Adding PRO Scripts
        add_action('ppom_after_scripts_loaded', array($this, 'load_ppom_scripts'), 15, 2);
        
        // Show description tooltip
        add_filter('ppom_field_description', array($this, 'show_tooltip'), 15, 2);
        
        // Multiple meta selection
        // @since 15.0
        // add_filter('ppom_select_meta_in_product', array($this, 'ppom_product_meta_box_legacy'), 99, 3);
        add_filter('ppom_select_meta_in_product', array($this, 'ppom_product_meta_box_table'), 99, 3);
        
        // Order Again
        add_filter('woocommerce_order_again_cart_item_data', array($this, 'order_again'), 99, 3);
        
        global $pagenow;
		if (! empty($pagenow) && ('post-new.php' === $pagenow || 'post.php' === $pagenow ))
		    add_action('admin_enqueue_scripts', array($this, 'product_page_script'));
		    
	    
	    // PPOM Settings via filters
	    add_filter('woocommerce_get_price_html', array($this, 'hide_product_price'), 99, 2);
	    add_filter('woocommerce_show_variation_price', array($this, 'hide_variable_product_price'), 99, 3);
	    add_filter('ppom_option_label', array($this, 'hide_option_price'), 99, 4);
	    add_filter('ppom_select_option_text', array($this, 'ppom_select_option_label'), 99, 2);
	    add_filter('ppom_retain_after_add_to_cart', array($this, 'ppom_clear_fields'), 99, 1);
	    add_filter('ppom_menu_capability', array($this, 'ppom_menu_capability'), 99, 1);
	    add_filter('ppom_wcfm_tab_title', array($this, 'ppom_wcfm_tab_title'), 99, 1);
	    add_filter('ppom_meta_overrides', array($this, 'ppom_meta_overrides'), 99, 1);
	    add_filter('ppom_meta_priority', array($this, 'ppom_meta_priority'), 99, 1);
	    add_filter('ppom_price_js_version', array($this, 'ppom_price_js_version'), 99, 1);
	    
	    // PPOM Admin UI
	    remove_action('ppom_pdf_setting_action', 'ppom_admin_update_pro_notice',10);
	    add_action('ppom_pdf_setting_action', array($this, 'ppom_admin_settings_view'));
	    
	    // PPOM Settings Filter
		add_filter( 'ppom_settings_data', array($this, 'ppom_admin_settings'), 10, 1);
		
		// Compatible with currency switcher for option prices
	    add_filter('ppom_option_price', 'ppom_hooks_convert_price', 99, 1); 
	    // WPML
	    add_filter('ppom_option_price', array($this, 'option_price_wpml'), 100, 1);
	    // WPML on cart prices
	    add_filter('ppom_fields_prices', array($this, 'convert_cart_wpml'), 10, 3);
	    
	    // Export/Import PPOM Meta via CSV
    	add_filter( 'woocommerce_product_export_column_names', array($this, 'add_export_column') );
		add_filter( 'woocommerce_product_export_product_default_columns', array($this, 'add_export_column') );
		
		// Filter you want to hook into will be: 'woocommerce_product_export_product_column_{$column_slug}'.
		add_filter( 'woocommerce_product_export_product_column_ppom_meta', array($this, 'add_export_data'), 10, 2 );
		
		add_filter( 'woocommerce_csv_product_import_mapping_options', array($this, 'add_column_to_importer') );
		add_filter( 'woocommerce_csv_product_import_mapping_default_columns', array($this, 'add_column_to_mapping_screen') );
		add_filter( 'woocommerce_product_import_pre_insert_product_object', array($this, 'process_import'), 10, 2 );
		
		
		// Export & Import Meta
		// add_action( 'admin_post_ppom_import_meta', array($this, 'ppom_import_meta') );
		add_action( 'admin_post_ppom_import_meta', array($this, 'ppom_import_csv') );
		add_action( 'admin_post_ppom_export_meta', array($this, 'ppom_export_csv') );


        add_filter( 'ppom_field_visibility_options', array($this, 'visibility_options'), 10, 1 );
        
        // PRO Feature Stock checking
        add_filter('ppom_before_fields_validation', array($this, 'check_field_stock'), 99, 4);
        add_action( 'woocommerce_order_status_completed', array($this,'reduce_ppom_option_stock'), 10, 1 );
        
        if( ppom_get_option('ppom_disable_meta_paypal_invoice') == 'yes' ){
        	add_filter( 'woocommerce_paypal_get_order_item_names', array($this, 'change_paypal_item_name_single_line'), 99, 2 );
        	add_filter( 'woocommerce_paypal_get_order_item_name', array($this, 'change_paypal_item_name'), 99, 3 );
        }
        
        // search in order for PPOM meta
        add_filter( 'woocommerce_shop_order_search_fields', 'ppom_hooks_search_in_order');
        
        // Settings Panel Framework
    	if( function_exists('PPOMSETTINGS') ) {
        	$this->load_settings();
        }
    }
    
    
	public static function get_instance()
	{
		// create a new object if it doesn't exist.
		is_null(self::$ins) && self::$ins = new self;
		return self::$ins;
	}
	
	// Admin notices if PPOM is not installed
	function ppom_notice_not_installed() {
	    
	    $ppom_install_url = admin_url( 'plugin-install.php?s=ppom&tab=search&type=term' );
        ?>
        <div class="notice notice-error is-dismissible">
            <p><?php _e( 'PPOM Basic Version is NOT installed, please download it first.', 'ppom' ); ?>
            <a class="button" href="<?php echo esc_url($ppom_install_url)?>"><?php _e('Install Plugin','ppom')?></a></p>
        </div>
        <?php
    }
    
    // Admin notices if PPOM is not validated
	function ppom_notice_not_validated() {
	    
	    $ppom_install_url = admin_url( 'admin.php?page=ppom_auth' );
        ?>
        <div class="notice notice-error is-dismissible">
            <p><?php _e( 'PPOM PRO version is validated, please provide valid api key to unlock all fields.', 'ppom' ); ?>
            <a class="button" href="<?php echo esc_url($ppom_install_url)?>"><?php _e('Add API Key','ppom')?></a></p>
        </div>
        <?php
    }


    function visibility_options($options){

        $options['none'] = __('None', 'ppom');

        return $options;
    }
    
    function check_field_stock($passed, $field, $posted_fields, $product_id) {
    	
    	if( ! $passed ) return $passed;
    	
    	if( ! isset($posted_fields['ppom']['fields']) ) return '';
    	
    	$ppom_fields = $posted_fields['ppom']['fields'];
    	
    	foreach($ppom_fields as $key => $value ) {
    		
    		if( $key !== $field['data_name'] || $field['type'] == 'quantities' ) continue;
    		
    		
    		$stocks_found = ppom_field_has_stock($field, $value);
    		
    		if( count($stocks_found) == 0 ) continue;
    		
    		foreach($stocks_found as $stock_found) {
    			
    			if( ! isset($stock_found['stock']) ) continue;
    		
	    		$in_stock = intval($stock_found['stock']);
	    		$cart_quantity = intval($posted_fields['quantity']);
	    		
	    		if( $in_stock < $cart_quantity ) {
	    			$option_lable = stripslashes($stock_found['option']);
	    			$outof_stock_msg = apply_filters('ppom_outof_stock_msg', sprintf(__('%s is out of stock', 'ppom'), $option_lable), $stock_found, $field, $product_id);
	    			ppom_wc_add_notice( $outof_stock_msg );
	    			$passed = false;
	    		}
    		}
    		
    	}
    	
    	return $passed;
    }
    
    // Reduce PPOM option stock
    function reduce_ppom_option_stock($order_id){

        $wc_order = wc_get_order($order_id);
        $order_paid = $wc_order->is_paid();

        foreach ($wc_order->get_items() as $order_item) {

            $product_id = version_compare( WC_VERSION, '3.0', '<' ) ? $order_item['product_id'] : $order_item->get_product_id();

            $item_meta = $order_item->get_meta('_ppom_fields');
            if( ! $item_meta ) continue;
            
            $select_input = ppom_has_field_by_type( $product_id,  'select');
            
            $ppom_fields = $item_meta['fields'];
            // ppom_pa($ppom_fields); exit;

            foreach ($ppom_fields as $data_name => $value) {
            	
            	if( $data_name == 'id' ) continue;
            	
            	$saved_meta = ppom_get_field_meta_by_dataname($product_id, $data_name);
            	$type = $type = isset($saved_meta['type']) ? $saved_meta['type'] : null;
            	
            	$stocks_found = ppom_field_has_stock($saved_meta, $value);
            	// ppom_pa($stocks_found); exit;
                if( count($stocks_found) == 0 ) continue;
                
                switch($type) {
                	
                	case 'select':
                	case 'radio':
                	case 'checkbox':
    					foreach($stocks_found as $stock_found) {
		                	// var_dump($stock_found);
		                	if( ! isset($stock_found['stock']) ) continue;
		                
			                $order_quantity = $order_item->get_quantity();
			                // Reduce the stock
			                $saved_meta['options'] = array_map(function($a) use ($stock_found, $order_quantity, $wc_order) {
			                	if( $a['id'] === $stock_found['id'] ) {
			                		$a['stock'] = floatval($stock_found['stock']) - $order_quantity;
			                		
			                		// order note
			                		if( apply_filters('ppom_add_order_note_stock_reduced', true, $wc_order) ) {
			                			$wc_order->add_order_note( sprintf(__('%s is reduced to %d', 'ppom'), $a['option'], $a['stock']) );
			                		}
			                	}
			                	return $a;
			                }, $saved_meta['options']);
			                
			            	
			                $this->ppom_update_meta_settings( $saved_meta );
    					}
	                break;
	                
	                case 'image':
	                	
	                		foreach($stocks_found as $stock_found) {
		                	// var_dump($stock_found);
		                	if( ! isset($stock_found['stock']) ) continue;
		                
			                $order_quantity = $order_item->get_quantity();
			                // Reduce the stock
			                $saved_meta['images'] = array_map(function($a) use ($stock_found, $order_quantity, $wc_order) {
			                	if( $a['id'] === $stock_found['id'] ) {
			                		$a['stock'] = floatval($stock_found['stock']) - $order_quantity;
			                		
			                		// order note
			                		if( apply_filters('ppom_add_order_note_stock_reduced', true, $wc_order) ) {
			                			$wc_order->add_order_note( sprintf(__('%s is reduced to %d', 'ppom'), $a['title'], $a['stock']) );
			                		}
			                	}
			                	return $a;
			                }, $saved_meta['images']);
			                
			            	// ppom_pa($saved_meta); exit;
			                $this->ppom_update_meta_settings( $saved_meta );
    					}
	                	break;
	                	
	                case 'quantities':
		                	// ppom_pa($stocks_found);
	                	foreach($stocks_found as $stock_found) {
		                	if( ! isset($stock_found['stock']) ) continue;
		                
			                // Reduce the stock
			                $saved_meta['options'] = array_map(function($a) use ($stock_found, $wc_order) {
			                	if( $a['id'] === $stock_found['id'] ) {
			                		$a['stock'] = $stock_found['stock'];
			                		if( apply_filters('ppom_add_order_note_stock_reduced', true, $wc_order) ) {
			                			$wc_order->add_order_note( sprintf(__('%s is reduced to %d', 'ppom'), $a['option'], $a['stock']) );
			                		}
			                	}
			                	return $a;
			                }, $saved_meta['options']);
			                
			                $this->ppom_update_meta_settings( $saved_meta );
    					}
		            	// ppom_pa($saved_meta); exit;
    					break;
	                
                }
            }
        }
        
        // exit;
    }
    
    
    function change_paypal_item_name_single_line( $item_names, $order ) {
    	
    	$item_names = array();

		foreach ( $order->get_items() as $item ) {
			$item_name = $item->get_name();
			$item_names[] = apply_filters('ppom_paypal_invoice_title', $item_name . ' x ' . $item->get_quantity(), $item, $order);
		}
    	
		// var_dump($item_names); exit;
    	return implode( ', ', $item_names );
	}
	
	function change_paypal_item_name( $item_name, $order, $item ) {
    	
    	$item_name = $item->get_name();
		return apply_filters('ppom_paypal_invoice_title', $item_name, $item, $order);
	}
    

    /*
    **============= Update Calendar Meta After Cart  ================ 
    */
    function ppom_update_meta_settings( $ppom_updated_meta ) {
        
        if( !isset($ppom_updated_meta['ppom_id']) ) return;
        
        $product_id = null;
        
        if( intval(PPOM_VERSION) >= 22 ){
        	
        	$ppom      = PPOM_Meta::get_instance( $product_id );
        } else {
        	$ppom      = new PPOM_Meta( $product_id );
        }

        // Getting ppom_id inside save meta
        $ppom_id = $ppom_updated_meta['ppom_id'];
        $ppom_fields = $ppom->get_fields_by_id($ppom_id);
        
        $found_index = '';
        foreach($ppom_fields as $index => $field_meta) {
            
            if( $field_meta['data_name'] == $ppom_updated_meta['data_name'] ) {
                
                $found_index = $index;
            }
        }
        
        $ppom_fields[$found_index] = $ppom_updated_meta;

        ppom_admin_update_ppom_meta_only( $ppom_id, $ppom_fields);
    }
	
	// Checking if PPOM Basic version is installed
	function is_ppom_installed() {
	    
	    $return = false;
	    
	    if( class_exists('NM_PersonalizedProduct') ) 
	        $return = true;
	   
	   return $return;
	}
	
	// Checking if PPOM not validated
	function is_ppom_validated() {
	    
	    $return = false;
	   
	   if( NM_AUTH(PPOM_PLUGIN_PATH, PPOM_REDIRECT_URL, PPOM_PLUGIN_ID) -> api_key_found() ) 
	        $return = true;
	    
	    return $return;
	}
	
	
	function hook_input_scripts($field, $data_name) {

        switch( $field['type'] ) {
            
            case 'daterange':
            
                wp_enqueue_script( 'ppom-moment-js', 'https://cdn.jsdelivr.net/momentjs/latest/moment.min.js', array('jquery'), PPOM_VERSION, true);
                wp_enqueue_script( 'ppom-daterangepicker-js', 'https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js', array('jquery'), PPOM_DB_VERSION, true);
                wp_enqueue_style( 'ppom-daterangepicker-js', 'https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css');
                break;
        }
	}
	
	// Loading all PRO inputs
	function load_all_inputs( $inputs_array, $inputObj) {
	    
	   // ppom_pa($inputs_array);
	    $inputs_array['number'] 	= $inputObj->get_input ( 'number' );
		$inputs_array['email'] 	    = $inputObj->get_input ( 'email' );
		$inputs_array['date'] 		= $inputObj->get_input ( 'date' );
		$inputs_array['daterange']  = $inputObj->get_input ( 'daterange' );
	    $inputs_array['color']      = $inputObj->get_input ( 'color' );				
		$inputs_array['file']   	= $inputObj->get_input ( 'file' );
		$inputs_array['cropper']    = $inputObj->get_input ( 'cropper' );
		$inputs_array['timezone']   = $inputObj->get_input ( 'timezone' );
		$inputs_array['quantities'] = $inputObj->get_input ( 'quantities' );
		$inputs_array['image']  	= $inputObj->get_input ( 'image' );
		$inputs_array['facebook']   = $inputObj->get_addon ( 'facebook' );	//Addon
		$inputs_array['pricematrix']= $inputObj->get_input ( 'pricematrix' );
		$inputs_array['section']    = $inputObj->get_input ( 'section' );
		$inputs_array['palettes']   = $inputObj->get_input ( 'palettes' );
		$inputs_array['audio']  	= $inputObj->get_input ( 'audio' );
		$inputs_array['measure']  	= $inputObj->get_input ( 'measure' );
		
		$inputs_array['divider']  	= $inputObj->get_input ( 'divider' );
		
		// checking event calendar addon is enable
		include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
		if ( is_plugin_active( 'ppom-addon-eventcalendar/ppom-addon-eventcalendar.php' ) ) {
			$inputs_array['eventcalendar'] = $inputObj->get_input ( 'eventcalendar' );
		}
		
		
		return $inputs_array;
	}
	
	function load_ppom_scripts( $ppom_meta_id, $product ) {
		
        
	}
	
	function show_tooltip( $description, $meta ) {
		
		$show_tooltip = (isset($meta['desc_tooltip']) && $meta['desc_tooltip'] == 'on') ? true : false;
		$input_desc	  = (isset($meta['description']) && $meta['description'] != '') ? $meta['description'] : '';
		$input_desc   = apply_filters( 'ppom_description_content', stripslashes($input_desc), $meta );
		
	
		if( $show_tooltip ) {
			
			$description = ( !empty($meta['description']) ) ? ' <span data-ppom-tooltip="ppom_tooltip" class="ppom-tooltip" title="'.esc_attr($input_desc).'"><svg width="13px" height="13px" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zM262.655 90c-54.497 0-89.255 22.957-116.549 63.758-3.536 5.286-2.353 12.415 2.715 16.258l34.699 26.31c5.205 3.947 12.621 3.008 16.665-2.122 17.864-22.658 30.113-35.797 57.303-35.797 20.429 0 45.698 13.148 45.698 32.958 0 14.976-12.363 22.667-32.534 33.976C247.128 238.528 216 254.941 216 296v4c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12v-1.333c0-28.462 83.186-29.647 83.186-106.667 0-58.002-60.165-102-116.531-102zM256 338c-25.365 0-46 20.635-46 46 0 25.364 20.635 46 46 46s46-20.636 46-46c0-25.365-20.635-46-46-46z"></path></svg></span>' : '';
		}
		
		return $description;
	}
	
	/**
     * @param $html - not used
     * @param $ppom - our meta object for the product
     * @param array $all_meta - array of meta items
     * @return string - html for ul list of meta groups, each with checkbox to select
     */
    function ppom_product_meta_box_table($html, $ppom, $all_meta)
    {
        /** CHANGES: add drag/drop capability to enable re-ordering of the meta groups by the user.
         * The selected meta WILL then be saved in the list display order (top to bottom) to wp_postmeta
         * When loaded, we have added code to show the selected meta first, in same order as saved, with unselected below.
         */
		$output = []; //build the meta id's and names in the correct order, selected first, then the rest

        $selected = ($ppom->has_multiple_meta ? $ppom->meta_id : $ppom->single_meta_id);
        // NOTE: $selected can be an array e.g. [ 0=>'9',1='15',2='6'], OR numeric id (single-meta),
        // NOTE: OR null (if no meta-group selected at all)

        // if selected is string then conver into array with intval
        $selected = is_array($selected) ? $selected : array( intval($selected) );

        $ppom_setting = admin_url('admin.php?page=ppom');
        
        // build all selected groups into $output array
        // ppom_pa($ppom);

        if ( is_array($selected) ) { // multiple_meta
            foreach ($selected as $id) {  // step through the array of selected ID's
                foreach ($all_meta as $meta) {
                    if ($id==$meta->productmeta_id) { // push onto end of array
                    	$meta_name = isset($ppom->category_meta) && in_array($id, $ppom->category_meta) ? $meta->productmeta_name.' (by category)' : $meta->productmeta_name;
                        array_push($output, array('productmeta_id' => $meta->productmeta_id,
                                                  'productmeta_name' => $meta_name));
                    }
                }
            }
        }else{
            if (is_numeric($selected)) // single_meta
            	$meta_name = isset($ppom->category_meta) && in_array($selected, $ppom->category_meta) ? $meta->productmeta_name.' (by category)' : $meta->productmeta_name;
                array_push($output, array('productmeta_id' => $selected,
                'productmeta_name' => $ppom->productmeta_name));
        }
        
        // Add all groups NOT selected onto the _end_ of the $output array.
        foreach ($all_meta as $meta) {

            if ( is_null($selected) || !in_array($meta->productmeta_id, $selected))
            array_push($output, array('productmeta_id' => $meta->productmeta_id, 'productmeta_name' => $meta->productmeta_name));
        }
        // ppom_pa($output);
        
        // return $this->render_metabox_panel( $output, $selected );

        // create the html for list of all meta groups in the sidebar meta box, including attributes for 'sortable' javascript to work
        // and Edit link for each group as well!
        
        $html = '<div class="options_group" style="max-height:375px; overflow:scroll">';
        $html .= '<table id="ppom_meta_sortable" class="wp-list-table widefat fixed striped">';

        $html .= '<div class="ppom-search-meta" style="padding: 7px;text-align: right;">';
            $html .= '<input type="text" class="ppom-search-meta-js" placeholder="Search Meta">';
            $html .= '<a target="_blank" class="button button-primary" href="'.esc_url($ppom_setting).'">Create New Meta</a>';
        $html .= '</div>';

        $html .= '<thead><tr>';
        $html .= '<th>'.__('Select Meta', 'ppom').'</th>';
        $html .= '<th>'.__('Meta ID', 'ppom').'</th>';
        $html .= '<th>'.__('Meta Name', 'ppom').'</th>';
        $html .= '<th>'.__('Edit', 'ppom').'</th>';
        $html .= '</tr></thead>';
        
        foreach ($output as $meta) {
            // $html .= '<tr class="ui-state-default ui-sortable">';
            $search_key = sanitize_key($meta['productmeta_name']);
            $html .= '<tr data-ppom-search="'.esc_attr($search_key).'" style="cursor: move;">';
            
            // Select/Checkbox
            $html .= '<td width="5%"><input name="ppom_product_meta[]" type="checkbox" style="cursor:auto;-webkit-appearance:checkbox" value="' . esc_attr($meta['productmeta_id']) . '" ';
            if ( !is_null($selected) && in_array($meta['productmeta_id'], $selected) && isset($ppom->category_meta) && !in_array($meta['productmeta_id'], $ppom->category_meta)) {
                $html .= ' checked ';
            }
            $html .= 'id="ppom-' . esc_attr($meta['productmeta_id']) . '">';
            $html .= '</td>';
            
            // ID
            $html .= '<td width="5%">'.$meta['productmeta_id'].'</td>';
            
            //
            // $html .= '<span class="hndle ui-sortable-handle">';
            // $html .= '<label for="ppom-' . esc_attr($meta['productmeta_id']) . '">';
                
            // Meta Name
            $html .= '<td width="50%">'.stripslashes($meta['productmeta_name']).'</td>';
            
            // Edit Meta
            $url_edit = add_query_arg(array('productmeta_id'=> $meta['productmeta_id'], 'do_meta'=>'edit'), $ppom_setting);

            $html .= '<td width="5%"><a target="_blank" style="font-weight:600; color:#0073aa" href="'.esc_url($url_edit).'">';
            $html .= '<span class="dashicons dashicons-edit"></span>';
            $html .= '</a></td>';
            
            $html .= '</tr>';
        }

        $html .= '</table>';
        $html .= '</div>';
        
        ?>
        <script type="text/javascript">
            jQuery(function($){
                jQuery(document).on('keyup', '.ppom-search-meta-js', function(e){
                    e.preventDefault();

                    var div = $(this).parent().parent();
                    var search_val = $(this).val().toLowerCase();
                    if ( search_val != '' ) {
                        div.find('#ppom_meta_sortable tbody tr').hide();
                        div.find('#ppom_meta_sortable tbody tr[data-ppom-search*="'+search_val+'"]').show();
                    } else {
                        div.find('#ppom_meta_sortable tbody tr:hidden').show();
                    }
                });

                $("#ppom_meta_sortable tbody").sortable();
            });
        </script>
        <?php

        return $html;
    }
    
    function ppom_product_meta_box_legacy($html, $ppom, $all_meta)
    {
        /** CHANGES: add drag/drop capability to enable re-ordering of the meta groups by the user.
         * The selected meta WILL then be saved in the list display order (top to bottom) to wp_postmeta
         * When loaded, we have added code to show the selected meta first, in same order as saved, with unselected below.
         */
		$output = []; //build the meta id's and names in the correct order, selected first, then the rest

        $selected = ($ppom->has_multiple_meta ? $ppom->meta_id : $ppom->single_meta_id);
        // NOTE: $selected can be an array e.g. [ 0=>'9',1='15',2='6'], OR numeric id (single-meta),
        // NOTE: OR null (if no meta-group selected at all)
        
        // if selected is string then conver into array with intval
        $selected = is_array($selected) ? $selected : array( intval($selected) );

        // build all selected groups into $output array
        // ppom_pa($all_meta);

        if ( is_array($selected) ) { // multiple_meta
            foreach ($selected as $id) {  // step through the array of selected ID's
                foreach ($all_meta as $meta) {
                    if ($id==$meta->productmeta_id) { // push onto end of array
                        array_push($output, array('productmeta_id' => $meta->productmeta_id,
                                                  'productmeta_name' => $meta->productmeta_name));
                    }
                }
            }
        }else{
            if (is_numeric($selected)) // single_meta
                array_push($output, array('productmeta_id' => $selected,
                'productmeta_name' => $ppom->productmeta_name));
        }

        // Add all groups NOT selected onto the _end_ of the $output array.
        foreach ($all_meta as $meta) {

            if ( is_null($selected) || !in_array($meta->productmeta_id, $selected))
            array_push($output, array('productmeta_id' => $meta->productmeta_id, 'productmeta_name' => $meta->productmeta_name));
        }
        
        // return $this->render_metabox_panel( $output, $selected );

        // create the html for list of all meta groups in the sidebar meta box, including attributes for 'sortable' javascript to work
        // and Edit link for each group as well!
        $html = '<div class="options_group" style="max-height:375px; overflow:scroll">';
        $html .= '<ul id="ppom_meta_sortable" class="ui-sortable">';

        foreach ($output as $meta) {
            $html .= '<li class="ui-state-default ui-sortable ui-sortable-handle"><span class="hndle">';
            $html .= '<label for="ppom-' . esc_attr($meta['productmeta_id']) . '">';
            $html .= '<input name="ppom_product_meta[]" type="checkbox" style="cursor:auto;-webkit-appearance:checkbox" value="' . esc_attr($meta['productmeta_id']) . '" ';

            if ( !is_null($selected) AND in_array($meta['productmeta_id'], $selected)) {
                $html .= ' checked ';
            }
            $html .= 'id="ppom-' . esc_attr($meta['productmeta_id']) . '">';

            $html .= $meta['productmeta_id'] . ' -' . stripslashes($meta['productmeta_name']);

            // add Edit link as original
            //@TODO Note it requires extra style to color the link, as jquery-ui overrides the link color

            $ppom_setting = admin_url('admin.php?page=ppom');
            $url_edit = add_query_arg(array('productmeta_id'=> $meta['productmeta_id'], 'do_meta'=>'edit'), $ppom_setting);

            $html .= ' - <a style="font-weight:600; color:#0073aa" href="'.esc_url($url_edit).'">';
            $html .= __('Edit', 'ppom');
            $html .= '</a>';

            $html .= '</label></span>';


            $html .= '</li>';
        }

        $html .= '</ul>';
        $html .= '</div>';
        
        ?>
        
        <script type="text/javascript">
            jQuery(function($){
               $("#ppom_meta_sortable").sortable();
            });
        </script>
        
        <?php
        
        return $html;
    }
    
    
   
	function order_again( $cart_item_meta, $item, $order ) {
		
		$ppom_fields = wc_get_order_item_meta( $item->get_id(), '_ppom_fields');
		
		if( ! $ppom_fields ) return $cart_item_meta;
		
		$cart_item_meta['ppom'] = $ppom_fields;
		return $cart_item_meta;
	}
	
	
	function product_page_script() {
		global $post;
		
		if( !empty($post) && $post->post_type == 'product' ) {
			$ppom_sortable = PPOM_PRO_URL.'/js/ppom-sortable.js';
			wp_enqueue_script('ppom-sortable', $ppom_sortable, array('jquery'));
		}
	}
	
	
	function hide_product_price( $price, $product ) {
	    
	    if( ! is_product() && !is_shop() && !is_product_category() ) return $price;
	    
	    $product_id = ppom_get_product_id( $product ); 
    	
    	if( intval(PPOM_VERSION) >= 22 ){
    		
    		$ppom		= PPOM_Meta::get_instance( $product_id );
    	} else {
    		$ppom		= new PPOM_Meta( $product_id );
    	}
    	if( ! $ppom->fields ) return $price;
    
        if( ppom_get_option('ppom_hide_product_price') == 'yes' ){
    	    
    		$price = '';
    	}
    	
    	return $price;
	}
	
	function hide_variable_product_price( $show, $parent, $variation ) {
	    
	    if( ! is_product() ) return $show;
	    
	    $product_id = ppom_get_product_id( $parent ); 
    	
    	if( intval(PPOM_VERSION) >= 22 ){
    		
    		$ppom		= PPOM_Meta::get_instance( $product_id );
    	} else {
    		$ppom		= new PPOM_Meta( $product_id );
    	}
    	if( ! $ppom->fields ) return $show;
    
        if( ppom_get_option('ppom_hide_variable_product_price') == 'yes' ){
    	    
    		$show = false;
    	}
    	
    	return $show;
	}
	
	function hide_option_price($label, $option, $meta, $product) {
	    
	    $type = isset($meta['type']) ? $meta['type'] : '';
	    if( ppom_get_option('ppom_hide_option_price') == 'yes' ){
    	    
    	    if(isset($option['option'])){
    			$label = !empty($option['label']) ? $option['label'] : $option['option'];
    	    }elseif(isset($option['title'])){
    	    	$label = !empty($option['label']) ? $option['label'] : $option['title'];
    	    }
    	}
    	
    	// Price Matrix then hide price as well
    	if( $type == 'pricematrix' ) {
    	    $label = !empty($option['label']) ? $option['label'] : $option['option'];
    	}
    	
    	
    	return $label;
	}
	
	function ppom_select_option_label($label, $product) {
	    
	    $select_option_label = ppom_wpml_translate(ppom_get_option('ppom_label_select_option', 'Select Option'), 'PPOM');
	    
	    $label = $select_option_label;
    	
    	return $label;
	    
	}
	
	function ppom_clear_fields( $retain_fields ) {
	    
	    if( ppom_get_option('ppom_hide_clear_fields') == 'yes' ){
    	    
    		$retain_fields = false;
    	}
    	
    	return $retain_fields;
	}
	
	
	function ppom_menu_capability( $menu_cap ) {
	    
	    if( ppom_get_option('ppom_wcfm_allow_vendors') == 'yes' ){
    	    
    		$menu_cap = 'read';
    	}
    	
    	return $menu_cap;
	}
	
	function ppom_wcfm_tab_title( $label ) {
	    
	    $tab_label = ppom_get_option('ppom_label_wcfm');
	    
	    $label = !empty($tab_label) ? $tab_label : $label;
    	return $label;
	}
	
	function ppom_meta_overrides( $override ) {
		
		$override = ppom_get_option('ppom_meta_overrides', 'default');
		return $override;
	}
	
	function ppom_meta_priority( $priority ) {
		
		$priority = ppom_get_option('ppom_meta_priority', 'default');
		return $priority;
	}
	
	function ppom_price_js_version( $ppom_price_js ) {
		
		$ppom_price_js = 'ppom-price-v2.js';	//ppom_get_option('ppom_meta_priority', 'default');
		return $ppom_price_js;
	}
	
	function ppom_admin_settings_view() {
	    
	    echo '<div class="ppom-more-plugins-block">';
    	    // PPOM Addons details in modal
    	    ppom_load_template ( 'admin/ppom-nm-plugins.php' );
    	    
    	    echo '<a class="btn btn-yellow ppom-import-export-btn" href=""><span class="dashicons dashicons-download"></span> ' . __ ( 'Import Meta', "ppom" ) . '</a>';
            echo '<a class="btn btn-yellow ppom-nm-plugins" href="#"  data-modal-id="ppom-nm-plugins-modal">PPOM Addons</a>';
    	    
        echo '</div>';
        
        // Import meta/More Addons Button
	    $this->ppom_load_template( 'ppom-import.php' );
	}
	
	function ppom_admin_settings( $ppom_settings ) {
	    
	    // Check if WCFM is installed/active
	    
	    if( $this->is_plugin_active('wcfm') ) {
    	
        	// Settings meta
    		$ppom_settings[] = array(
                'title'     => __( 'WCFM Vendros', 'ppom' ),
                'type'     => 'title',
                'desc'     => '',
                'id'       => 'ppom_wcfm_support'
            );
            
            $ppom_settings[] = array(
    				'title'             => __( 'Allow Vendors To Create/Edit PPOM Fields', 'ppom' ),
    				'type'              => 'checkbox',
    				'label'             => __( 'Yes', 'ppom' ),
    				'default'           => 'no',
    				'id'    			=> 'ppom_wcfm_allow_vendors',
    				'desc'      		=> __( 'Enable (These will be Global)', 'ppom' ),
    		);
    		
    		$ppom_settings[] = array(
                'title'		=> __( 'Store Title', 'ppom' ),
                'type'		=> 'text',
                'desc'		=> __( 'Label in Product Edit Page', 'ppom' ),
                'default'	=> __('Custom Fields', 'ppom'),
                'id'		=> 'ppom_label_wcfm',
                'css'   	=> 'min-width:300px;',
    			'desc_tip'	=> true,
        );
    		
    		$ppom_settings[] = array(
    				'type' => 'sectionend',
    				'id'   => 'ppom_wcfm_support',
    			);
	    }
		
		return $ppom_settings;
		
	}
	
	function add_export_column( $columns ) {

		// column slug => column name
		$columns['ppom_meta'] = 'PPOM Fields';
	
		return $columns;
	}
	
	/**
	 * Provide the data to be exported for one item in the column.
	 *
	 * @param mixed $value (default: '')
	 * @param WC_Product $product
	 * @return mixed $value - Should be in a format that can be output into a text file (string, numeric, etc).
	 */
	function add_export_data( $value, $product ) {
		$value = $product->get_meta( '_product_meta_id', true, 'edit' );
		if( is_array($value) ) {
			$value = implode(',', $value);
		}
		// var_dump($value);
		return $value;
	}
	
	/**
	 * Register the 'Custom Column' column in the importer.
	 *
	 * @param array $options
	 * @return array $options
	 */
	function add_column_to_importer( $options ) {
	
		// column slug => column name
		$options['ppom_meta'] = 'PPOM Fields';
	
		return $options;
	}
	
	/**
	 * Add automatic mapping support for 'Custom Column'. 
	 * This will automatically select the correct mapping for columns named 'Custom Column' or 'custom column'.
	 *
	 * @param array $columns
	 * @return array $columns
	 */
	function add_column_to_mapping_screen( $columns ) {
		
		// potential column name => column slug
		$columns['PPOM Fields'] = 'ppom_meta';
		// $columns['custom column'] = 'ppom_meta';
	
		return $columns;
	}
	
	/**
	 * Process the data read from the CSV file.
	 * This just saves the value in meta data, but you can do anything you want here with the data.
	 *
	 * @param WC_Product $object - Product being imported or updated.
	 * @param array $data - CSV data read for the product.
	 * @return WC_Product $object
	 */
	function process_import( $object, $data ) {
		
		if ( ! empty( $data['ppom_meta'] ) ) {
			//making meta into array
			$ppom_meta = explode(',', $data['ppom_meta']);
			$object->update_meta_data( '_product_meta_id', $ppom_meta );
		}
	
		return $object;
	}
	
	// import from csv
	function ppom_import_csv(){
	    
	    if( ! current_user_can('administrator') ) {
    		wp_die ( __("Sorry, you are not allowed to perform this action", 'ppom') );
    	}
    	
    	if( empty($_FILES['ppom_csv']['tmp_name']) ) {
    	    $args = array('back_link' => true);
    	    $title = __("PPOM Meta Not Found", 'ppom');
    	    wp_die( __("File not found/selected, selected PPOM meta file and import",'ppom'), $title, $args);
    	}
		
		global $wpdb;
		//get the csv file
	    $file = $_FILES['ppom_csv']['tmp_name'];
	    $handle = fopen($file,"r");
	    
	    $row = 1;
	    $meta_keys = [];
	    $skip_head = true;
	    $ppom_metas = [];
	    $the_metas	= [];
	    if( $handle !== FALSE ) {
	    	
	    	while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
	    		$meta_keys = $row == 1 ? $data : $meta_keys;
	    		
	    		/**
	    		 * sometime exported CVS has leading space
	    		 * removing extra spaces in header
	    		 * Fixed by: Najeeb Ahmad
	    		 * Date: August 1, 2021
	    		 * */
	    		$meta_keys = array_map('trim', $meta_keys);
	    		
		        $row++;
		        
		        $ppom_id = array_search('ppom_id', $meta_keys);
		        $name = array_search('productmeta_name', $meta_keys);
		        $price_display = array_search('dynamic_price_display', $meta_keys);
		        $styles = array_search('productmeta_style', $meta_keys);
		        $categories = array_search('productmeta_categories', $meta_keys);
		        
	        	$ppom_metas[$data[$ppom_id]]['productmeta_name'] = $data[$name];
	        	$ppom_metas[$data[$ppom_id]]['dynamic_price_display'] = $data[$price_display];
	        	$ppom_metas[$data[$ppom_id]]['productmeta_style'] = $data[$styles];
	        	$ppom_metas[$data[$ppom_id]]['productmeta_categories'] = $data[$categories];
	        	$ppom_metas[$data[$ppom_id]]['productmeta_created'] = current_time ( 'mysql' );
	        	$ppom_metas[$data[$ppom_id]]['send_file_attachment'] = '';
	        	
	        	$the_meta = array_combine($meta_keys, $data);
	        	
	        	// removing the setting keys
	        	$remove_keys = ['productmeta_name','productmeta_categories','dynamic_price_display','productmeta_style'];
	        	$the_meta = array_diff_key($the_meta, array_flip($remove_keys));
	        	
	        	// removing the nulled/empty meta values
	        	$the_meta = array_filter($the_meta, function($value) { return !is_null($value) && $value !== ''; });
	        	
	        	// turning options/conditions back to simple array
	        	if( isset($the_meta['options']) ){
					$the_meta['options'] = json_decode($the_meta['options'], true);
				}
				if( isset($the_meta['conditions']) ){
					$the_meta['conditions'] = json_decode($the_meta['conditions'], true);
				}
				if( isset($the_meta['html']) ){
					$the_meta['html'] = esc_html($the_meta['html']);
				}
				
				// $the_meta = array_map(function($m){ return esc_html($m); }, $the_meta);
				
				// ppom_pa($the_meta);
	        	
	        	// $the_metas[$ppom_id][] = $the_meta;
	        	$ppom_metas[$data[$ppom_id]]['the_meta'][] = $the_meta;
		   
		    }
		    
		    fclose($handle);
	    }
	    
	    // $ppom_metas = PPOM()->ppom_decode_entities($ppom_metas);
	    // ppom_pa($ppom_metas); exit;
	    $meta_count = 0;
	    foreach($ppom_metas as $key => $meta) {
	    	
	    	if( $key == 'ppom_id' ) continue;
	    	
	    	$table = $wpdb->prefix . PPOM_TABLE_META;
	    	$meta_count++;
    		$dt = array (
					'productmeta_name'          => $meta['productmeta_name'],
		            'dynamic_price_display'     => $meta['dynamic_price_display'],
		            'send_file_attachment'		=> '',
					'productmeta_style'         => $meta['productmeta_style'],
					'productmeta_categories'    => $meta['productmeta_categories'],
					'the_meta'                  => json_encode ( $meta['the_meta'] ),
					'productmeta_created'       => current_time ( 'mysql' )
			);
			
			$format = array (
					'%s',
					'%s',
					'%s',
		            '%s',
					'%s',
					'%s',
					'%s' 
			);
			
			// ppom_pa($dt); exit;
			$wpdb->insert($table, $dt, $format);
			
			$product_meta = apply_filters('ppom_meta_data_saving', $meta['the_meta'], $wpdb->insert_id);
			// Updating PPOM Meta with ppom_id in each meta array
			ppom_admin_update_ppom_meta_only( $wpdb->insert_id, $product_meta );
    		
		    // $wpdb->show_errors();
		    // $wpdb->print_error();
		    // exit;
	    }
	    
	    
	    $response = array('class'=>'updated', 'message'=> sprintf(__("%d meta(s) imported successfully.", "ppom"),$meta_count));
	    set_transient("ppom_meta_imported", $response, 30);
	    wp_redirect(  admin_url( 'admin.php?page=ppom' ) );
   		exit;
	}
	
	function ppom_import_meta(){
	    
	    if( ! current_user_can('administrator') ) {
    		wp_die ( __("Sorry, you are not allowed to perform this action", 'ppom') );
    	}
    	
    	if( empty($_FILES['ppom_csv']['tmp_name']) ) {
    	    $args = array('back_link' => true);
    	    $title = __("PPOM Meta Not Found", 'ppom');
    	    wp_die( __("File not found/selected, selected PPOM meta file and import",'ppom'), $title, $args);
    	}
		
		global $wpdb;
		//get the csv file
	    $file = $_FILES['ppom_csv']['tmp_name'];
	    $handle = fopen($file,"r");
	    
	    $ppom_meta = '';
		if ($handle) {
		    while (!feof($handle)) {
		      $ppom_meta .= fgetss($handle, 50000);
		    }
		
		    fclose($handle);
		}
		
		$ppom_meta = json_decode($ppom_meta);
		$ppom_meta = PPOM()->ppom_decode_entities($ppom_meta);
		// ppom_pa( $ppom_meta ); exit;
	    
	    $meta_count = 0;
	    foreach($ppom_meta as $meta) {
	    	
	    	$table = $wpdb->prefix . PPOM_TABLE_META;
	    	$qry = "INSERT INTO {$table} SET ";
	    	$meta_count++;
	    	
	    		foreach($meta as $key => $val) {
	    			
	    			if( $key == 'productmeta_id' ) continue;
	    			
	    			$val = apply_filters('ppom_imported_meta_name', $val, $meta);
	    			
	    			$qry .= "{$key}='{$val}',";
	    		}
	    		
	    		$qry = substr($qry, 0, -1);
	   // 		print $qry; exit;
	    		$res = $wpdb->query( $qry );
	    
			    /*$wpdb->show_errors();
			    $wpdb->print_error();
			    exit;*/
	    }
	    
	    
	    $response = array('class'=>'updated', 'message'=> sprintf(__("%d meta(s) imported successfully.", "ppom"),$meta_count));
	    set_transient("ppom_meta_imported", $response, 30);
	    wp_redirect(  admin_url( 'admin.php?page=ppom' ) );
   		exit;
	}
	
	function ppom_export_csv(){
		
		if( !empty($_POST['ppom_meta']) ){
			
			global $wpdb;
		
			$meta_in = implode(",", $_POST['ppom_meta']);
			$qry = "SELECT * FROM ". $wpdb->prefix . PPOM_TABLE_META." WHERE productmeta_id IN (".$meta_in.");";
			$all_meta = $wpdb->get_results ( $qry, ARRAY_A );
			
			if( ! $all_meta){
				die( __("No meta found, make sure you selected meta and then export", "ppom") );
			}
			
			
			$table_head = [];
			$ppom_metas	= [];
			$ppom_settings	= [];
			foreach($all_meta as $meta){
				$the_meta = json_decode($meta['the_meta'], true);
				$ppom_metas[] = $the_meta;
				$ppom_settings[] = [$meta['productmeta_name'],$meta['dynamic_price_display'],
									$meta['productmeta_style'],$meta['productmeta_categories']];
									
				$table_head = array_merge($table_head, $this->array_keys_multi($the_meta));
			}
			
			// productmeta_name, dynamic_price_display, productmeta_style, productmeta_categories
			// Merging the meta setting
			$settings_head = ['productmeta_name','dynamic_price_display','productmeta_style','productmeta_categories'];
			$table_head = array_merge($table_head, $settings_head);
			
			// Meta setting values
			// $meta_values = [$]
			$table_head = array_unique($table_head);
			// var_dump($table_head); exit;
			
			
			// ppom_pa( $table_head); exit;
			$file = fopen('php://output', 'w');
            fputcsv($file, $table_head);
            
			// creating the body
			$table_body = [];
			foreach($ppom_metas as $index => $pm){
				foreach($pm as $m){
					$table_row = [];
					
					// ppom_pa($m);
					foreach( $table_head as $column ) {
						if( in_array($column, $settings_head) ) continue;
						$table_row[] = isset($m[$column]) ? is_array($m[$column]) ? json_encode($m[$column]) : stripslashes($m[$column]) : '';
					}
					
					$table_row = array_merge($table_row, $ppom_settings[$index]);
					
					fputcsv($file, $table_row);
					// $table_body[] = $table_row;
				}
			}
			
			
    		$filename = 'ppom-meta-'.time().'.csv';    
		    header( 'Content-Type: text/csv' ); // tells browser to download
		    header( 'Content-Disposition: attachment; filename="' . $filename .'"' );
		    header( 'Pragma: no-cache' ); // no cache
		    header( "Expires: Sat, 26 Jul 1997 05:00:00 GMT" ); // expire date
		
		    // echo $file;
		    fclose($file);
			
		}
		exit;
	}
	
	
	function array_keys_multi(array $array)
	{
	    $keys = array();
	
	    foreach ($array as $key => $value) {
	        // $keys[] = array_keys($value);
	
            $keys = array_merge($keys, array_keys($value));
	    }
	
	    return $keys;
	}
	
	function ppom_export_meta(){
		
		
		if( !empty($_POST['ppom_meta']) ){
			
			global $wpdb;
		
			$meta_in = implode(",", $_POST['ppom_meta']);
			$qry = "SELECT * FROM ". $wpdb->prefix . PPOM_TABLE_META." WHERE productmeta_id IN (".$meta_in.");";
			$all_meta = $wpdb->get_results ( $qry, ARRAY_A );
			
			if( ! $all_meta){
				die( __("No meta found, make sure you selected meta and then export", "ppom") );
			}
			
			$all_meta = $this -> add_slashes_array($all_meta);
			// $all_meta = esc_html($all_meta);
			// ppom_pa($all_meta); exit;
			$postfix = time();
			$filename = "ppom-export-{$postfix}.json";
			
			 // tell the browser it's going to be a csv file
		    header('Content-Type: application/json');
		    // tell the browser we want to save it instead of displaying it
		    header('Content-Disposition: attachement; filename="'.$filename.'";');
		    
			// open raw memory as file so no temp files needed, you might run out of memory though
		    $f = fopen('php://output', 'w'); 
		    
		    fwrite($f, json_encode($all_meta));
		    // rewrind the "file" with the csv lines
		    @fseek($f, 0);
		   
		    // make php send the generated csv lines to the browser
		    fpassthru($f);
		    
			die(0);
		} else {
			
			wp_die( __("No meta found, make sure you selected meta and then export", "ppom") );
		}
	}
	
	function add_slashes_array($arr){
		asort($arr);
		$ReturnArray = array();
		foreach ($arr as $k => $v)
	        $ReturnArray[$k] = (is_array($v)) ? $this->add_slashes_array($v) : addslashes( esc_html($v) );
	    return $ReturnArray;
	}
	
	// Check if given plugin is installed/active
	function is_plugin_active( $plugin ) {
	    
	    $is_active = true;
	    
	    switch( $plugin ) {
	        
	        case 'wcfm':
	            
	            if( is_plugin_active( 'wc-frontend-manager/wc_frontend_manager.php') )
	                $is_active = true;
	       break;
	    }
	    
	    return $is_active;
	}
	
	
	function convert_cart_wpml($field_prices, $ppom_fields_post, $product_id){
	
		$temp_prices = array();
		if( $field_prices ) {
			
			foreach($field_prices as $price){
				if( isset($price['price']) ) {
					$price['price'] = apply_filters('wcml_raw_price_amount', $price['price']);
				}
				
				$temp_prices[] = $price;
			}
		}
		
		return $temp_prices;
	}
	
	// Convert option price if WPML currency swithcer found
	function option_price_wpml( $option_price ) {
		
		return apply_filters('wcml_raw_price_amount', $option_price);
	}
	
	
	function ppom_load_template($file_name, $variables=array('')){

    	if( is_array($variables))
        extract( $variables );
        
       $file_path =  PPOM_PRO_PATH . '/templates/'.$file_name;
       $file_path = apply_filters('ppom_pro_load_template', $file_path, $file_name, $variables);
        
       if( file_exists($file_path))
       	include ($file_path);
       else
       	die('File not found'.$file_path);
    }
    
    
    function load_settings() {
    	
    	$pro_settings = array(
			'ppom_hide_clear_fields' => array(
				'type'          => 'checkbox',
				'title'         => __( 'Clear Fields after Add to Cart?', 'ppom' ),
				'desc'          => __( 'Empty all fields on Product page after to cart.', 'ppom' ),
				'label'         => __( 'Yes', 'ppom' ),
			),
			'ppom_disable_meta_paypal_invoice' => array(
				'type'       => 'checkbox',
				'title'      => __( 'Do not send Product Meta to PayPal Invoice', 'ppom' ),
				'desc'       => __( 'Product meta will not be sent to PayPal invoice, only the Item name will be sent to invoice', 'ppom' ),
			),
			'ppom_label_select_option' => array(
		        'type'		=> 'text',
		        'title'		=> __( 'Shop Add to Cart Label', 'ppom' ),
		        'desc'		=> __( 'When PPOM attached, the add to cart button label can be set here.', 'ppom' ),
		        'default'	=> __('Select Options', 'ppom'),
		    ),
		    'ppom_remove_unused_images_schedule' => array(
		        'type'      => 'select',
		        'title'     => __( 'Delete Un-used images', 'ppom' ),
		        'desc'      => __( 'Set duration to uploaded images of abandoned cart. Re-activate plugin to when update this option', 'ppom' ),
		        'default'   => 'daily',
		        'options'   => array( 
		        	'daily'   => __('Daily','ppom'),
		            'weekly'  => __('Weekly','ppom'),
		            'monthly' => __('Monthly','ppom'),
		        ),
		    ),
		    'ppom_meta_overrides' => array(
		        'type'        => 'select',
		        'title'       => __( 'Meta Group Overrides', 'ppom' ),
		        'desc'        => __( 'Leave if default if not sure.', 'ppom' ),
		        'default'     => 'default',
		        'options'     => array( 
		        	'default'=>__('Default','ppom'),
		            'category_override'=> __('Category Overrides Individual Assignment','ppom'),
		            'individual_override'=> __('Individual Overrides Category Assignment','ppom'),
		        ),
		    ),
		    'ppom_meta_priority' => array(
		        'type'       => 'select',
		        'title'      => __( 'Meta Group Priority', 'ppom' ),
		        'desc'       => __( 'Leave if default if not sure.', 'ppom' ),
		        'default'    => 'default',
		        'options'	 => array(
		        	'category_first'   => __('Category First','ppom'),
		            'individual_first' => __('Individual First','ppom'),
		        ),
		    ),
		);
        
        $restapi = array(
		    'ppom_api_enable' => array(
				'type'     => 'checkbox',
				'title'    => __( 'PPOM REST API', 'ppom' ),
				'desc'     => __( 'Check this option to enable PPOM REST API.', 'ppom' ),
			),
        	'ppom_rest_secret_key' => array(
		        'type'     => 'text',
		        'title'    => __( 'Secret Key', 'ppom' ),
		        'desc'     => __( 'Enter any characters to create a secret key. This key must be set while requesting to API.', 'ppom' ),
		    ),
        );
        
        $price = array(
		    'ppom_hide_product_price' => array(
				'type'          => 'checkbox',
				'title'         => __( 'Hide Product Price?', 'ppom' ),
				'desc'          => __( 'Hides Product core price under price Title (When PPOM Fields attached)', 'ppom' ),
				'label'         => __( 'Yes', 'ppom' ),
			),
			'ppom_hide_variable_product_price' => array(
				'type'          => 'checkbox',
				'title'         => __( 'Hide Variable Product Price?', 'ppom' ),
				'desc'          => __( 'Hides Variable Product core price under price Title (When PPOM Fields attached)', 'ppom' ),
				'label'         => __( 'Yes', 'ppom' ),
			),
			'ppom_hide_option_price' => array(
				'type'          => 'checkbox',
				'title'         => __( 'Hide Options Price?', 'ppom' ),
				'desc'          => __( 'Hides options price in Selec/Radio/Checkbox/Image display prices with label', 'ppom' ),
				'label'         => __( 'Yes', 'ppom' ),
			),
			'ppom_taxable_option_price' => array(
				'type'          => 'checkbox',
				'title'         => __( 'Taxable Options Price?', 'ppom' ),
				'desc'          => __( 'Apply tax settings on option prices from WooCommerce->Tax', 'ppom' ),
				'label'         => __( 'Yes', 'ppom' ),
			),
			'ppom_taxable_fixed_price' => array(
				'type'          => 'checkbox',
				'title'         => __( 'Apply Tax on fixed/cart fee?', 'ppom' ),
				'desc'          => __( 'Option enabled for fixed fee will be taxable.', 'ppom' ),
				'label'         => __( 'Yes', 'ppom' ),
			),
			'ppom_price_table_location' => array(
		        'type'       => 'select',
		        'title'      => __( 'Price Table Position', 'ppom' ),
		        'desc'       => __( 'Set the location to render Price Table on Front-end', 'ppom' ),
		        'default'    => 'after',
		        'options'    => array( 
		        	'after'  => __('After PPOM Fields','ppom'),
		            'before' => __('Before  PPOM Fields','ppom'),
		         ),
		    ),
        );
        
        $style_settings = array(
		    'ppom_styles_general_section' => array(
		        'type'      => 'section',
		        'title'     => __( 'General Settings', 'ppom' ),
		    ),
		    'ppom_input_label_style' => array(
		        'type'      => 'typography',
		        'title'     => __( 'Field Label', 'ppom' ),
		        'desc'      => __( 'Set the fields label settings.', 'ppom' ),
		        'output'    => '.ppom-wrapper label.form-control-label',
		    ),
		    'ppom_input_desc_style' => array(
		        'type'      => 'typography',
		        'title'     => __( 'Field Description', 'ppom' ),
		        'desc'      => __( 'Set the fields description settings.', 'ppom' ),
		        'output'    => '.ppom-wrapper .ppom-input-desc',
		    ),
		    'ppom_input_option_label_style' => array(
		        'type'      => 'typography',
		        'title'     => __( 'Options Label', 'ppom' ),
		        'desc'      => __( 'Set the fields option label settings.', 'ppom' ),
		        'output'    => '.ppom-wrapper .ppom-input-option-label',
		    ),
		    'ppom_input_option_price_label_style' => array(
		        'type'      => 'typography',
		        'title'     => __( 'Options Price Label', 'ppom' ),
		        'desc'      => __( 'Set the fields option price label settings.', 'ppom' ),
		        'output'    => '.ppom-wrapper .ppom-option-label-price',
		    ),
		    'ppom_styles_advance_section' => array(
		        'type'      => 'section',
		        'title'     => __( 'Input Box Settings', 'ppom' ),
		        'desc'      => __( 'PPOM frontend elements can be styled from these settings.', 'ppom' ),
		    ),
		    'ppom_input_box_bgclr' => array(
				'type'     => 'color',
				'title'    => __( 'Background Color', 'ppom' ),
				'output'   => array('background-color' => '.ppom-wrapper input, .ppom-wrapper select, .ppom-wrapper textarea'),
			),
			'ppom_input_box_txtclr' => array(
				'type'     => 'color',
				'title'    => __( 'Text Color', 'ppom' ),
				'output'   => array('color' => '.ppom-wrapper input, .ppom-wrapper select, .ppom-wrapper textarea'),
			),
		    'ppom_input_box_border' => array(
		        'type'     => 'css_editor',
		        'title'    => __( 'Border Style', 'ppom' ),
		        'desc'     => __( 'Set the input border style.', 'ppom' ),
		        'mode'     => 'border',
		        'output'   => '.ppom-wrapper input, .ppom-wrapper select, .ppom-wrapper textarea',
		    ),
		    'ppom_input_box_border_focus' => array(
		        'type'     => 'css_editor',
		        'title'    => __( 'Border Focus Style', 'ppom' ),
		        'desc'     => __( 'Set the input border style on focus.', 'ppom' ),
		        'mode'     => 'border',
		        'output'   => '.ppom-wrapper input:focus, .ppom-wrapper select:focus, .ppom-wrapper textarea:focus',
		    ),
		    'ppom_input_box_border_shadow_focus' => array(
				'type'       => 'text',
				'title'      => __( 'Box Shodow Focus', 'ppom' ),
				'desc'       => __( "Provide the input box shadow on fucus style. If you don't want to apply then simply add 'none'.", 'ppom' ),
				'hint'       => '0 0 0 0.2rem rgb(0 123 255 / 25%)',
				'reference' => array(
				    'ref_title'       => __( 'See reference', 'ppom' ),
				    'ref_link'        => 'https://www.w3schools.com/cssref/css3_pr_box-shadow.asp',
				),
			),
			'ppom_styles_price_table_section' => array(
		        'type'      => 'section',
		        'title'     => __( 'Price Table Settings', 'ppom' ),
		    ),
			'ppom_price_table_txtclr' => array(
				'type'          => 'color',
				'title'          => __( 'Text Color', 'ppom' ),
				'output'   => array('color' => '.ppom-wrapper #ppom-price-container table th, .ppom-wrapper #ppom-price-container table td'),
			),
		    'ppom_price_table_bgclr' => array(
				'type'          => 'color',
				'title'          => __( 'Background Color', 'ppom' ),
				'output'   => array('background-color' => '.ppom-wrapper #ppom-price-container table'),
			),
			'ppom_styles_tooltip_section' => array(
		        'type'      => 'section',
		        'title'     => __( 'Tooltip Settings', 'ppom' ),
		    ),
		    'ppom_input_tooltip_iconclr' => array(
				'type'          => 'color',
				'title'          => __( 'Icon Color', 'ppom' ),
				'output'   => array('color' => '.ppom-wrapper .ppom-tooltip '),
			),
			'ppom_input_tooltip_maxwidth' => array(
				'type'   => 'text',
				'title'  => __( 'Max. Width', 'ppom' ),
				'desc'   => __( "Set a maximum width for the tooltip in pixel. Default: 500", 'ppom' ),
			),
		    'ppom_input_tooltip_txtclr' => array(
				'type'          => 'color',
				'title'          => __( 'Text Color', 'ppom' ),
			),
			'ppom_input_tooltip_bgclr' => array(
				'type'          => 'color',
				'title'          => __( 'Background Color', 'ppom' ),
			),
			'ppom_input_tooltip_borderclr' => array(
				'type'          => 'color',
				'title'          => __( 'Border Color', 'ppom' ),
			),
			'ppom_input_tooltip_position' => array(
				'type'          => 'select',
				'title'          => __( 'Position', 'ppom' ),
				'options' => array(
				    'top'          => __('Top','ppom'),
				    'bottom'       => __('Bottom','ppom'),
				    'left'         => __('Left','ppom'),
				    'right'        => __('Right','ppom'),
		        ),
			),
			'ppom_input_tooltip_animation' => array(
				'type'          => 'select',
				'title'          => __( 'Animation', 'ppom' ),
				'options' => array(
				    'fade'          => __('Fade','ppom'),
				    'grow'       => __('Grow','ppom'),
				    'swing'         => __('Swing','ppom'),
				    'slide'        => __('Slide','ppom'),
		            'fall'    => __('Fall','ppom'),
		        ),
			),
			'ppom_input_tooltip_interactive' => array(
				'type'          => 'checkbox',
				'title'          => __( 'Interactive', 'ppom' ),
				'desc'          => __( 'Give users the possibility to interact with the tooltip.', 'ppom' ),
			),
			'ppom_input_tooltip_trigger' => array(
				'type'          => 'checkbox',
				'title'          => __( 'Open Tooltip on click', 'ppom' ),
				'desc'          => __( 'Give users the possibility to open the tooltip by click. Default: Hover', 'ppom' ),
			),
		);
		
		$panels = array(
            'ppom_admin_pro_settings' => array(
		        'id'    => 'ppom_admin_pro_settings',
		        'title' => 'Pro Settings',
		        'desc'      => __( 'It will render the ppom pro settings.', 'ppom' ),
		        'is_sabpanel' => true,
		    ),
            'ppom_general_restapi' => array(
                'id'          => 'ppom_general_restapi',
                'title'		  => __( 'PPOM REST', 'ppom' ),
                'is_sabpanel' => true,
            ),
            'ppom_general_price' => array(
                'id'           => 'ppom_general_price',
                'title'		   => __( 'PPOM Price', 'ppom' ),
                'is_sabpanel'  => true,
            ),
		    'ppom_admin_style_settings' => array(
		        'id'    => 'ppom_admin_style_settings',
		        'title' => 'Style Settings',
		        'desc'      => __( 'It will render the ppom style settings.', 'ppom' ),
		        'is_sabpanel' => true,
		    ),
        );
        
        PPOMSETTINGS()->register_panel('ppom_general_tab', $panels);
        
        if( $this->is_plugin_active('wcfm') ) {
    	
	    	$wcfm_settings = array(
	    		'ppom_wcfm_allow_vendors' => array(
    				'type'              => 'checkbox',
    				'desc'      		=> __( 'Enable (These will be Global)', 'ppom' ),
    				'title'             => __( 'Allow Vendors To Create/Edit PPOM Fields', 'ppom' ),
    				'label'             => __( 'Yes', 'ppom' ),
	    		),
	    		'ppom_label_wcfm' => array(
	                'type'		=> 'text',
	                'title'		=> __( 'Store Title', 'ppom' ),
	                'desc'		=> __( 'Label in Product Edit Page', 'ppom' ),
	                'default'	=> __('Custom Fields', 'ppom'),
	                // 'conditions' => array(
	                //     array('ppom_wcfm_allow_vendors' , '==', array('true')),
	                // )
		        )
	        );
	        
	        $panels['ppom_wcfm_support'] = array(
	    		'id'          => 'ppom_wcfm_support',
	    		'title'		   => __( 'WCFM Vendros', 'ppom' ),
		        'is_sabpanel' => true,
	        );
	        
	        PPOMSETTINGS()->register_panel('ppom_general_tab', $panels)->register_setting('ppom_wcfm_support', $wcfm_settings);
	    }
		
		PPOMSETTINGS()->register_setting('ppom_general_restapi', $restapi);	    
        PPOMSETTINGS()->register_setting('ppom_general_price', $price);
        PPOMSETTINGS()->register_setting('ppom_admin_pro_settings', $pro_settings);
        PPOMSETTINGS()->register_setting('ppom_admin_style_settings', $style_settings);
        
    }
}

add_action('plugins_loaded', 'PPOM_PRO');
function PPOM_PRO(){
	return PPOM_PRO::get_instance();
}