<?php
defined( 'ABSPATH' ) || exit;

class Exporo {
    /**
	 * The single instance of the class
	 */
	protected static $_instance = null;

    /**
	 * Main Instance
	 */
	public static function instance() {
		if ( is_null( self::$_instance ) ) {
			self::$_instance = new self();
		}
		return self::$_instance;
	}

    /**
	 * Constructor
	 */
    public function __construct() {
		add_action('init', array($this, 'init'));
		add_action('admin_menu', array($this, 'register_page'));
		add_action('admin_enqueue_scripts', array($this, 'admin_scripts'));
		add_action('wp_enqueue_scripts', array($this, 'frontend_scripts') );
		add_action('init', array($this, 'create_pdf'), 99);
		add_action('init', array($this, 'shortcode_output'), 99);
		add_action('wp_ajax_exporoIds', array($this, 'save_ids'));
		add_shortcode('exporo_catalog', array($this, 'catalog_shortcode'));
		add_action('product_cat_add_form_fields', array($this, 'category_cover_add'), 10, 2 );
		add_action('product_cat_edit_form_fields', array($this, 'category_cover_edit'), 10, 2 );
		add_action('edited_product_cat', array($this, 'category_cover_save'), 10, 1 );
		add_action('create_product_cat', array($this, 'category_cover_save'), 10, 1 );
		add_action('wp_ajax_exporoClearCache', array($this, 'clear_cache'));
		add_action('woocommerce_before_shop_loop', array($this, 'before_shop_page_loop'), 5 );
		add_action('woocommerce_before_shop_loop', array($this, 'before_category_loop'), 5 );
		add_action('woocommerce_after_add_to_cart_form', array($this, 'after_cart'), 15 );
		add_filter('cmb2_meta_boxes', array($this, 'single_product_cover') );
    }

    /**
	 * Init
	 */
    public function init() {
        load_plugin_textdomain( 'exporo', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
    }

	/**
	 * Register Admin Page
	 */
    public function register_page(){
		$user_roles =  ExporoSettings::get_option('exporo_user_roles', array());
		if (!current_user_can('administrator') && !self::user_has_one_of_roles( $user_roles )) {
			return;
		}
        add_menu_page( 
            esc_html__( 'PDF Catalog Creator For WooCommerce', 'exporo' ),
            esc_html__( 'Exporo', 'exporo' ),
            'read',
            'exporo',
            array($this, 'admin_page_output'),
            'dashicons-pdf',
            59
        );
    }

	/* Admin Scripts */
    public function admin_scripts($hook){
		wp_enqueue_style('exporo-general', EXPORO_PLUGIN_URL . 'css/admin-general.css', false, EXPORO_VERSION);
		if ( current_user_can( 'upload_files' ) ) {
			wp_enqueue_media();
		}
		wp_enqueue_script('exporo-general', EXPORO_PLUGIN_URL . 'js/admin-general.js', array( 'jquery' ), EXPORO_VERSION, true);
		wp_localize_script(
				'exporo-general',
				'exporoGenParams',
				[
					'ajaxurl' => admin_url( 'admin-ajax.php' ),
					'nonce' => wp_create_nonce('exporo-nonce'),
					'error' => esc_html__('Error', 'exporo'),
					'wrong' => esc_html__('Something went wrong.', 'exporo'),
					'filesDeleted' => esc_html__('The file cache has been cleared.', 'exporo'),
					'submit' => esc_html__('Create PDF', 'exporo'),
					'chooseImage' => esc_html__('Choose Image', 'exporo'),
					'useImage' => esc_html__('Use this image', 'exporo')
				]
			);
		if ('toplevel_page_exporo' == $hook) {
			$table_rows =  ExporoSettings::get_option('exporo_table_rows', '25');

			wp_enqueue_style('datatables', EXPORO_PLUGIN_URL . 'css/datatables.min.css', false, '2.3.4');
            wp_enqueue_style('exporo-admin', EXPORO_PLUGIN_URL . 'css/admin.css', false, EXPORO_VERSION);
            if (is_rtl()) {
                wp_enqueue_style('exporo-rtl-admin', EXPORO_PLUGIN_URL . 'css/admin-rtl.css', false, EXPORO_VERSION);
            }
			wp_enqueue_script('moment', EXPORO_PLUGIN_URL . 'js/moment.min.js', array( 'jquery' ), '2.30.1', true);
			wp_enqueue_script('datatables', EXPORO_PLUGIN_URL . 'js/datatables.min.js', array( 'jquery' ), '2.3.4', true);
			wp_enqueue_script('exporo-admin', EXPORO_PLUGIN_URL . 'js/admin.js', array( 'jquery' ), EXPORO_VERSION, true);
			wp_localize_script(
				'exporo-admin',
				'exporoParams',
				[
					'ajaxurl' => admin_url( 'admin-ajax.php' ),
					'nonce' => wp_create_nonce('exporo-nonce'),
					'error' => esc_html__('Error', 'exporo'),
					'wrong' => esc_html__('Something went wrong.', 'exporo'),
					'selectall' => esc_html__('Select All', 'exporo'),
					'selectnone' => esc_html__('Select None', 'exporo'),
					'searchhere' => esc_html__('Search here...', 'exporo'),
					'wait' => esc_html__('Please wait...', 'exporo'),
					'submit' => esc_html__('Create PDF', 'exporo'),
					'chooseImage' => esc_html__('Choose Image', 'exporo'),
					'useImage' => esc_html__('Use this image', 'exporo'),
					'rows' => $table_rows,
				]
			);
		}
	}

	/* Frontend Scripts */
    public function frontend_scripts(){
		$btn_color = ExporoSettings::get_option('exporo_btn_color', '#FFFFFF');
		$btn_bg = ExporoSettings::get_option('exporo_btn_bg_color', '#000000');
		$font_size = ExporoSettings::get_option('exporo_btn_font_size', 16);
		$font_weight = ExporoSettings::get_option('exporo_font_weight', 'bold');
		$h_padding = ExporoSettings::get_option('exporo_btn_h_padding', 18);
		$v_padding = ExporoSettings::get_option('exporo_btn_v_padding', 12);
		$border_radius = ExporoSettings::get_option('exporo_btn_radius', 5);

		wp_enqueue_style('exporo', EXPORO_PLUGIN_URL . 'css/front.css', false, EXPORO_VERSION);

		$inline_style = '';
		if ($btn_color != '#FFFFFF') {
            $inline_style .= 'button.exporo-btn { color:' . $btn_color . ' !important; }';
        }
		if ($btn_bg != '#000000') {
            $inline_style .= 'button.exporo-btn { background:' . $btn_bg . ' !important; }';
        }
		if ($font_size != 16) {
            $inline_style .= 'button.exporo-btn { font-size:' . $font_size . 'px !important; }';
        }
		if ($font_weight != 'bold') {
            $inline_style .= 'button.exporo-btn { font-weight:' . $font_weight . ' !important; }';
        }
		if ($h_padding != 18) {
            $inline_style .= 'button.exporo-btn { padding-left:' . $h_padding . 'px !important;padding-right:' . $h_padding . 'px !important; }';
        }
		if ($v_padding != 12) {
            $inline_style .= 'button.exporo-btn { padding-top:' . $v_padding . 'px !important;padding-bottom:' . $v_padding . 'px !important; }';
        }
		if ($border_radius != 5) {
            $inline_style .= 'button.exporo-btn { border-radius:' . $border_radius . 'px !important; }';
        }

		wp_add_inline_style( 'exporo', $inline_style );
	}

	/**
	 * Admin Page Output
	 */
    public function admin_page_output() { 
		if ( class_exists( 'WooCommerce' ) ) {
	?>
	<div id="exporo">
		<div id="exporo-header">
			<h2><?php echo esc_html__('PDF Catalog Creator For WooCommerce', 'exporo'); ?></h2>
			<ul>
				<li><a href="https://exporo.website/exporo/documentation/" target="_blank"><?php echo esc_html__( 'Help Docs', 'exporo' ) . ' - v' . EXPORO_VERSION; ?><span class="dashicons dashicons-external"></span></a></li>
			</ul>
		</div>
		<div id="exporo-tabs" class="exporo-tabs">
			<div id="exporo-products" class="exporo-content exporo-tab active">
			<?php
			$product_args = array(
				'limit'    => -1,
				'status'   => 'publish',
				'orderby'  => 'date',
				'order'    => 'DESC'
			);
			$products = wc_get_products( $product_args );
			if ( !empty( $products ) ) {
				$selected_columns =  ExporoSettings::get_option('exporo_table_columns', array('categories', 'tags'));
			?>
			<table id="exporo-table" class="cell-border stripe hover order-column">
				<thead>
					<tr>
						<th><?php echo esc_html__('ID', 'exporo'); ?></th>
						<th><?php echo esc_html__('Name', 'exporo'); ?></th>
						<?php if (in_array("sku", $selected_columns)) {
							echo '<th>' . esc_html__('SKU', 'exporo') . '</th>';
						} ?>
						<?php if (in_array("categories", $selected_columns)) {
							echo '<th>' . esc_html__('Category', 'exporo') . '</th>';
						} ?>
						<?php if (in_array("tags", $selected_columns)) {
							echo '<th>' . esc_html__('Tag', 'exporo') . '</th>';
						} ?>
						<?php if (in_array("brands", $selected_columns)) {
							echo '<th>' . esc_html__('Brand', 'exporo') . '</th>';
						} ?>
						<th><?php echo esc_html__('Date', 'exporo'); ?></th>
					</tr>
				</thead>
				<tbody>
					<?php
					foreach ( $products as $product ) {
						$product_id   = $product->get_id();
						$product_name = $product->get_name();
						$product_sku  = $product->get_sku();
						$publish_date = $product->get_date_created() ? $product->get_date_created()->date( 'Y-m-d H:i:s' ) : 'N/A';
						$category_ids  = $product->get_category_ids();
						$category_names = array();
						foreach ( $category_ids as $id ) {
							$term = get_term( $id, 'product_cat' );
							if ( $term && ! is_wp_error( $term ) ) {
								$category_names[] = $term->name;
							}
						}
						$categories_list = implode( ', ', $category_names );

						$tag_ids = $product->get_tag_ids();
						$tag_names = array();
						foreach ( $tag_ids as $id ) {
							$term = get_term( $id, 'product_tag' );
							if ( $term && ! is_wp_error( $term ) ) {
								$tag_names[] = $term->name;
							}
						}
						$tags_list = implode( ', ', $tag_names );

						$brand_terms = get_the_terms( $product_id, 'product_brand' );
						$brand_names = array();
						if ( ! is_wp_error( $brand_terms ) && $brand_terms ) {
							foreach ( $brand_terms as $term ) {
								$brand_names[] = $term->name;
							}
						}
						$brands_list = implode( ', ', $brand_names );

						echo '<tr>';
						echo '<td>' . esc_html( $product_id ) . '</td>';
						echo '<td>' . esc_html( $product_name ) . '</td>';
						if (in_array("sku", $selected_columns)) {
							echo '<td>' . esc_html( $product_sku ) . '</td>';
						}
						if (in_array("categories", $selected_columns)) {
							echo '<td>' . esc_html( $categories_list ) . '</td>';
						}
						if (in_array("tags", $selected_columns)) {
							echo '<td>' . esc_html( $tags_list ) . '</td>';
						}
						if (in_array("brands", $selected_columns)) {
							echo '<td>' . esc_html( $brands_list ) . '</td>';
						}
						echo '<td>' . esc_html( $publish_date ) . '</td>';
						echo '</tr>';
					}
					wp_reset_postdata();
					?>
				</tbody>
				<tfoot>
					<tr>
						<th><?php echo esc_html__('ID', 'exporo'); ?></th>
						<th><?php echo esc_html__('Name', 'exporo'); ?></th>
						<?php if (in_array("sku", $selected_columns)) {
							echo '<th>' . esc_html__('SKU', 'exporo') . '</th>';
						} ?>
						<?php if (in_array("categories", $selected_columns)) {
							echo '<th>' . esc_html__('Category', 'exporo') . '</th>';
						} ?>
						<?php if (in_array("tags", $selected_columns)) {
							echo '<th>' . esc_html__('Tag', 'exporo') . '</th>';
						} ?>
						<?php if (in_array("brands", $selected_columns)) {
							echo '<th>' . esc_html__('Brand', 'exporo') . '</th>';
						} ?>
						<th><?php echo esc_html__('Date', 'exporo'); ?></th>
					</tr>
				</tfoot>
			</table>
			<div class="exporo-btn-wrapper">
				<button id="exporo-next" data-target="#exporo-settings" type="button" class="exporo-btn exporo-nav" disabled><?php echo esc_html__('Proceed To Continue', 'exporo'); ?><span id="exporo-export-count">0</span><span class="dashicons dashicons-arrow-right-alt"></span></button>
			</div>
			<?php } else {
				echo '<div class="notice notice-warning exporo-nothing"><p>' . esc_html__( 'No products found.', 'exporo' ) . '</p></div>';
			} ?>
			</div>
			<?php
			$title =  ExporoSettings::get_option('exporo_default_title', '');
			$subject =  ExporoSettings::get_option('exporo_default_subject', '');
			$author =  ExporoSettings::get_option('exporo_default_author', '');
			$creator =  ExporoSettings::get_option('exporo_default_creator', '');
			$keywords =  ExporoSettings::get_option('exporo_default_keywords', '');
			$cover_image =  ExporoSettings::get_option('exporo_cover_image', '');
			?>
			<div id="exporo-settings" class="exporo-tab">
				<div class="exporo-row-wrap">
					<div class="exporo-row">
						<div class="exporo-left-column">
							<?php echo esc_html__('Title', 'exporo'); ?>
						</div>
						<div class="exporo-right-column">
							<input id="exporo-title" type="text" class="exporo-form-field" value="<?php echo esc_attr($title); ?>" autocomplete="off"> 
						</div>
					</div>
					<div class="exporo-row">
						<div class="exporo-left-column">
							<?php echo esc_html__('Subject', 'exporo'); ?>
						</div>
						<div class="exporo-right-column">
							<input id="exporo-subject" type="text" class="exporo-form-field" value="<?php echo esc_attr($subject); ?>" autocomplete="off"> 
						</div>
					</div>
					<div class="exporo-row">
						<div class="exporo-left-column">
							<?php echo esc_html__('Author', 'exporo'); ?>
						</div>
						<div class="exporo-right-column">
							<input id="exporo-author" type="text" class="exporo-form-field" value="<?php echo esc_attr($author); ?>" autocomplete="off"> 
						</div>
					</div>
				</div>
				<div class="exporo-row-wrap style-2">
					<div class="exporo-row">
						<div class="exporo-left-column">
							<?php echo esc_html__('Creator', 'exporo'); ?>
						</div>
						<div class="exporo-right-column">
							<input id="exporo-creator" type="text" class="exporo-form-field" value="<?php echo esc_attr($creator); ?>" autocomplete="off"> 
						</div>
					</div>
					<div class="exporo-row">
						<div class="exporo-left-column">
							<?php echo esc_html__('Keywords', 'exporo'); ?>
						</div>
						<div class="exporo-right-column">
							<input id="exporo-keywords" type="text" class="exporo-form-field" value="<?php echo esc_attr($keywords); ?>" autocomplete="off"> 
						</div>
					</div>
				</div>
				<div class="exporo-row exporo-last-row">
					<div class="exporo-left-column">
						<?php echo esc_html__('Cover Image URL', 'exporo'); ?>
					</div>
					<div class="exporo-right-column">
						<div class="exporo-input-group">
							<input type="text" id="exporo-image-url" value="<?php echo esc_url($cover_image); ?>" class="exporo-form-field" autocomplete="off" />
							<?php if ( current_user_can( 'upload_files' ) ) { ?>
							<input type='button' class="button-secondary" id="exporo-upload-button" value="<?php echo esc_attr__('Select Image', 'exporo'); ?>" />
							<?php } ?>
						</div>
						<div class="exporo-desc">
							<?php echo esc_html__('Recommended image dimentions: 841x1189px or 1682x2378px.', 'exporo'); ?>
						</div>
					</div>
				</div>
				<?php
				$default_org = ExporoSettings::get_option('exporo_default_org', 'no');
				$default_bookmarks = ExporoSettings::get_option('exporo_default_bookmarks', 'yes');
				$default_toc = ExporoSettings::get_option('exporo_default_toc', 'no');
				$catalog_style =  ExporoSettings::get_option('exporo_catalog_style', 'default');
				?>
				<div class="exporo-row-wrap multi-only">
					<div class="exporo-row">
						<div class="exporo-left-column">
							<?php echo esc_html__('Organize by Categories', 'exporo'); ?>
						</div>
						<div class="exporo-right-column">
							<ul class="exporo-radio-list">	
								<li>
									<input type="radio" class="cmb2-option" name="exporo-org" id="exporo-org1" value="yes" autocomplete="off" <?php if ($default_org == 'yes') { echo 'checked="checked"'; } ?>> <label for="exporo-org1"><?php echo esc_html__('Yes', 'exporo'); ?></label>
								</li>
								<li>
									<input type="radio" class="cmb2-option" name="exporo-org" id="exporo-org2" value="no" autocomplete="off" <?php if ($default_org == 'no') { echo 'checked="checked"'; } ?>> <label for="exporo-org2"><?php echo esc_html__('No', 'exporo'); ?></label>
								</li>
							</ul>
						</div>
					</div>
					<div class="exporo-row">
						<div class="exporo-left-column">
							<?php echo esc_html__('Bookmarks', 'exporo'); ?>
						</div>
						<div class="exporo-right-column">
							<ul class="exporo-radio-list">	
								<li>
									<input type="radio" class="cmb2-option" name="exporo-bookmarks" id="exporo-bookmarks1" value="yes" autocomplete="off" <?php if ($default_bookmarks == 'yes') { echo 'checked="checked"'; } ?>> <label for="exporo-bookmarks1"><?php echo esc_html__('Enable', 'exporo'); ?></label>
								</li>
								<li>
									<input type="radio" class="cmb2-option" name="exporo-bookmarks" id="exporo-bookmarks2" value="no" autocomplete="off" <?php if ($default_bookmarks == 'no') { echo 'checked="checked"'; } ?>> <label for="exporo-bookmarks2"><?php echo esc_html__('Disable', 'exporo'); ?></label>
								</li>
							</ul>
						</div>
					</div>
					<div class="exporo-row">
						<div class="exporo-left-column">
							<?php echo esc_html__('Table Of Contents', 'exporo'); ?>
						</div>
						<div class="exporo-right-column">
							<ul class="exporo-radio-list">	
								<li>
									<input type="radio" class="cmb2-option" name="exporo-toc" id="exporo-toc1" value="yes" autocomplete="off" <?php if ($default_toc == 'yes') { echo 'checked="checked"'; } ?>> <label for="exporo-toc1"><?php echo esc_html__('Enable', 'exporo'); ?></label>
								</li>
								<li>
									<input type="radio" class="cmb2-option" name="exporo-toc" id="exporo-toc2" value="no" autocomplete="off" <?php if ($default_toc == 'no') { echo 'checked="checked"'; } ?>> <label for="exporo-toc2"><?php echo esc_html__('Disable', 'exporo'); ?></label>
								</li>
							</ul>
						</div>
					</div>
					<div class="exporo-row">
						<div class="exporo-left-column">
							<?php echo esc_html__('Layout', 'exporo'); ?>
						</div>
						<div class="exporo-right-column">
							<ul class="exporo-radio-list">	
								<li>
									<input type="radio" class="cmb2-option" name="exporo-layout" id="exporo-layout1" value="default" autocomplete="off" <?php if ($catalog_style == 'default') { echo 'checked="checked"'; } ?>> <label for="exporo-layout1"><?php echo esc_html__('Default', 'exporo'); ?></label>
								</li>
								<li>
									<input type="radio" class="cmb2-option" name="exporo-layout" id="exporo-layout2" value="table" autocomplete="off" <?php if ($catalog_style == 'table') { echo 'checked="checked"'; } ?>> <label for="exporo-layout2"><?php echo esc_html__('Table', 'exporo'); ?></label>
								</li>
							</ul>
						</div>
					</div>
				</div>
				<form id="exporo-form" action="<?php echo get_site_url(); ?>" method="GET" target="_blank">
					<input name="page" type="hidden" value="pdf-creator">
					<input type="hidden" id="jsArrayInput" name="data">
				</form>	
				<div class="exporo-btn-wrapper exporo-justify-btns">
					<button id="exporo-prev" data-target="#exporo-products" type="button" class="exporo-btn exporo-nav"><span class="dashicons dashicons-arrow-left-alt"></span><?php echo esc_html__('Go Back', 'exporo'); ?></button>
					<button id="exporo-submit" type="button" class="exporo-btn" disabled><?php echo esc_html__('Create PDF', 'exporo'); ?><span class="dashicons dashicons-arrow-right-alt"></span></button>
				</div>
			</div>
		</div>
	</div>
	<?php } else {
		echo '<div id="exporo"><div class="notice notice-warning exporo-nothing"><p>' . esc_html__( 'Exporo requires WooCommerce to be installed and active.', 'exporo' ) . '</p></div></div>';
		}
	}

	/**
	 * Save IDs
	 */
    public function save_ids() {
		if ( ! wp_verify_nonce( $_POST['nonce'], 'exporo-nonce' ) ) {
            wp_die(esc_html__('Security Error!', 'exporo'));
        }
		if (isset($_POST['data']) && !empty($_POST['data'])) {
			$jsonString = $_POST['data'];
			$id_array = json_decode($jsonString);
			$product_ids = array_map('intval', $id_array);
			$product_ids = array_filter($product_ids, function($id) {
				return $id > 0;
			});
			$args = array(
				'title' => sanitize_text_field($_POST['title']),
				'subject' => sanitize_text_field($_POST['subject']),
				'author' => sanitize_text_field($_POST['author']),
				'creator' => sanitize_text_field($_POST['creator']),
				'keywords' => sanitize_text_field($_POST['keywords']),
				'cover' => sanitize_text_field($_POST['cover']),
				'bookmarks' => sanitize_text_field($_POST['bookmarks']),
				'toc' => sanitize_text_field($_POST['toc']),
				'org' => sanitize_text_field($_POST['org']),
				'layout' => sanitize_text_field($_POST['layout'])
			);
			$rand = 'pdf-' . rand();
			set_transient( $rand, array($product_ids, $args), HOUR_IN_SECONDS );
			echo $rand;
		} else {
			echo 'error';
		}
		wp_die();
	}

	/**
	 * Role Check
	 */
	public function user_has_one_of_roles( $roles_to_check ) {
		$user = wp_get_current_user();
		if ( ! $user || ! $user->ID || empty( $user->roles ) ) {
			return false;
		}
		$has_role = (bool) array_intersect( $roles_to_check, $user->roles );
		return $has_role;
	}

	/**
	 * Create PDF Page
	 */
    public function create_pdf() {
		if(!isset($_GET['page']) || empty($_GET['page']) || is_admin() || wp_doing_ajax()) {
            return;
        } else {
			if ($_GET['page'] == 'pdf-creator' && isset($_GET['data']) && !empty($_GET['data']) && function_exists('wc_get_products')) {
				$login_required =  ExporoSettings::get_option('exporo_login_required', 'no');
				$user_roles =  ExporoSettings::get_option('exporo_user_roles', array());
				if ($login_required == 'yes' && !is_user_logged_in()) {
					wp_die(esc_html__('You must login to access the file.', 'exporo'));
				}
				if ($login_required == 'yes' && !current_user_can('administrator') && !self::user_has_one_of_roles( $user_roles )) {
					wp_die(esc_html__('You are not allowed to view this file.', 'exporo'));
				}
				$transient_value = get_transient($_GET['data']);
				if (false === $transient_value){
					wp_die(esc_html__('Something went wrong.', 'exporo'));
				}
				$layout = 'default';
				if (isset($transient_value[1]['layout']) && $transient_value[1]['layout'] == 'table') {
					$layout = 'table';
				}
				$org = 'no';
				if (isset($transient_value[1]['org']) && $transient_value[1]['org'] == 'yes') {
					$org = 'yes';
				}
				$product_ids = $transient_value[0];
				$product_ids = array_map('intval', $product_ids);
				$product_ids = array_filter($product_ids, function($id) {
					return $id > 0;
				});

				$product_args = array(
					'limit'    => -1,
					'status'   => 'publish',
					'orderby'  => 'include',
					'include'  => $product_ids
				);
				$products = wc_get_products( $product_args );

				if ( ! empty( $products ) ) {
					$catalog_fields =  ExporoSettings::get_option('exporo_catalog_fields', array('sku', 'price', 'permalink', 'image', 'desc', 'short_desc', 'cats', 'tags'));
					$exporo_image_size =  ExporoSettings::get_option('exporo_image_size', 'large');
					$exporo_gallery_image_size =  ExporoSettings::get_option('exporo_gallery_image_size', 'full');
					
					$response = array();
					foreach ( $products as $product ) {
						$product_id   = sanitize_text_field($product->get_id());
						$product_name = sanitize_text_field($product->get_name());
						$product_sku  = false;
						if (in_array('sku', $catalog_fields)) {
							$product_sku  = sanitize_text_field($product->get_sku());
						}
						$product_permalink = false;
						if (in_array('permalink', $catalog_fields)) {
							$product_permalink = esc_url(get_permalink($product_id));
						}
						$description = false;
						if (in_array('desc', $catalog_fields)) {
							$description = wp_kses_post($product->get_description());
						}	
						$short_description = false;
						if (in_array('short_desc', $catalog_fields)) {
							$short_description = wp_kses_post($product->get_short_description());
						}	
						$image_url = false;
						if (in_array('image', $catalog_fields)) {
							$image_id = $product->get_image_id();
							if ($image_id) {
								if ( $layout == 'table' && count($product_ids) !== 1 ) {
									$image_url = wp_get_attachment_image_url( $image_id, 'thumbnail' );
								} else {
									$image_url = wp_get_attachment_image_url( $image_id, $exporo_image_size );
								}
							} else {
								$image_url = wc_placeholder_img_src( 'woocommerce_single' );
							}
						}
						$gallery_image_urls = array();
						$gallery_image_ids = $product->get_gallery_image_ids();

						if ( $gallery_image_ids && in_array('gallery', $catalog_fields)) {
							foreach ( $gallery_image_ids as $image_id ) {
								$url = wp_get_attachment_image_url( $image_id, $exporo_gallery_image_size );
								if ( $url ) {
									$gallery_image_urls[] = $url;
								}
							}
						} else {
							$gallery_image_urls = false;
						}

						$categories_list = false;
						if (in_array('cats', $catalog_fields)) {
							$categories_list = wc_get_product_category_list( $product_id, ', ' );
						}
						$tags_list = false;
						if (in_array('tags', $catalog_fields)) {
							$tags_list = wc_get_product_tag_list( $product_id, ', ' );
						}
						$brands_list = false;
						if (in_array('brands', $catalog_fields)) {
							$brands_list = get_the_term_list( $product_id, 'product_brand', '', ', ' );
						}
						$price_output = '';
						if (in_array('price', $catalog_fields)) {
							if ( $product->is_type( 'simple' ) || $product->is_type( 'grouped' ) || $product->is_type( 'external' ) ) {
								$regular_price = $product->get_regular_price();
								$sale_price    = $product->get_sale_price();

								if ( $product->is_on_sale() ) {
									$price_output .= '<span class="regular-price">' . sanitize_text_field(wc_price( $regular_price )) . '</span> - ';
									$price_output .= sanitize_text_field(wc_price( $sale_price ));
									
								} else {
									$price_output = sanitize_text_field(wc_price( $product->get_price() ));
								}

							} else if ( $product->is_type( 'variable' ) ) {
								$min_price = $product->get_variation_price( 'min' );
								$max_price = $product->get_variation_price( 'max' );

								if ( $min_price !== $max_price ) {
									$price_output = sanitize_text_field(wc_price( $min_price ) . ' &ndash; ' . wc_price( $max_price ));
								} else {
									$price_output = sanitize_text_field(wc_price( $min_price ));
								}
							} else {
								$price_output = sanitize_text_field(wc_price( $product->get_price() ));
							}
						}
    					$attributes = $product->get_attributes();

						if (in_array('attr', $catalog_fields) && !empty( $attributes )) {
							$attr_output = '';
							foreach ( $attributes as $attribute ) {
								$attribute_label = wc_attribute_label( $attribute->get_name() );
								if ( $attribute->is_taxonomy() ) {
									$terms = wp_get_post_terms( $product_id, $attribute->get_name(), array( 'fields' => 'names' ) );
									$values = implode( ', ', $terms );
								} else {
									$values = $attribute->get_options();
									if ( is_array( $values ) ) {
										$values = implode( ', ', $values );
									}
								}
								if ( ! empty( $values ) ) {
									$attr_output .= '<p><strong>' . esc_html( $attribute_label ) . ':</strong> ' . esc_html( $values ) . '</p>';
								}
							}
						}

						$reviews = false;
						if (in_array('reviews', $catalog_fields)) {
							$reviews = 'yes';
						}

						$response[$product_id] = array(
							'name' => $product_name, 
							'sku' => $product_sku, 
							'price' => $price_output,
							'permalink' => $product_permalink,
							'image' => $image_url,
							'gallery' => $gallery_image_urls,
							'desc' => $description,
							'short_desc' => $short_description,
							'cats' => $categories_list,
							'tags' => $tags_list,
							'brands' => $brands_list,
							'attr' => $attr_output,
							'reviews' => $reviews
						);
					}
					wp_reset_postdata();

					if ( $org == 'yes' && count($product_ids) !== 1) {
						$categorized_products = [];

						foreach ($response as $response_key => $response_item) {
							$terms = wp_get_post_terms($response_key, 'product_cat');
							if (!empty($terms) && !is_wp_error($terms)) {
								foreach ($terms as $term) {
									$category_id = $term->term_id;
									$category_name = $term->name;
									if (!isset($categorized_products[$category_id])) {
										$categorized_products[$category_id] = [];
									}
									if (!in_array($response_key, $categorized_products[$category_id])) {
										$response_item['category_name'] = $category_name;
										$categorized_products[$category_id][] = $response_item;
									}
								}
							}
						}
						$response = $categorized_products;
					}
				} else {
					wp_die(esc_html__( 'No products found with the specified IDs.', 'exporo' ));
				}

				if (count($product_ids) === 1) {
					self::single_layout($response, $transient_value[1], $product_ids[0], 'direct');
				} else {
					if ( $org == 'yes' ) {
						if ( $layout == 'table' ) {
							self::table_category_layout($response, $transient_value[1], 'direct');
						} else {
							self::category_layout($response, $transient_value[1], 'direct');
						}
					} else {
						if ( $layout == 'table' ) {
							self::table_classic_layout($response, $transient_value[1], 'direct');
						} else {
							self::classic_layout($response, $transient_value[1], 'direct');
						}
					}
				}
			} else {
				return;
			}
		}
	}

	/**
	 * Shortcode Output
	 */
    public function shortcode_output() {
		if(!isset($_GET['page']) || empty($_GET['page']) || is_admin() || wp_doing_ajax()) {
            return;
        } else {
			if ($_GET['page'] == 'pdf' && function_exists('wc_get_products')) {
				$login_required =  ExporoSettings::get_option('exporo_login_required', 'no');
				$user_roles =  ExporoSettings::get_option('exporo_user_roles', array());
				if ($login_required == 'yes' && !is_user_logged_in()) {
					wp_die(esc_html__('You must login to access the file.', 'exporo'));
				}
				if ($login_required == 'yes' && !current_user_can('administrator') && !self::user_has_one_of_roles( $user_roles )) {
					wp_die(esc_html__('You are not allowed to view this file.', 'exporo'));
				}
				$org = 'no';
				if (isset($_GET['exporo_org']) && $_GET['exporo_org'] == 'yes') {
					$org = 'yes';
				}
				$layout = 'default';
				if (isset($_GET['exporo_layout']) && $_GET['exporo_layout'] == 'table') {
					$layout = 'table';
				}

				$product_ids = array();
				$catid = array();
				$products = '';
				$save_key = 'exporo';

				if (isset($_GET['exporo_productid'])) {
					$product_ids = explode(",", $_GET['exporo_productid']);
					$product_ids = array_map('trim', $product_ids);
					$product_ids = array_filter($product_ids);
					$save_string = implode("", $product_ids);
					$product_args = array(
						'limit'    => -1,
						'status'   => 'publish',
						'orderby'  => 'include',
						'include'  => $product_ids
					);
					$save_key = 'p-' . $save_string;
				} else if (isset($_GET['exporo_catid'])) {
					$catid = explode(",", $_GET['exporo_catid']);
					$catid = array_map('trim', $catid);
					$catid = array_filter($catid);
					$save_string = implode("", $catid);
					$product_args = array(
						'limit'    => -1,
						'status'   => 'publish',
						'product_category_id' => $catid
					);
					$save_key = 'c-' . $save_string;
					$org = 'no';
				} else {
					$product_args = array(
						'limit'    => -1,
						'status'   => 'publish',
						'orderby'  => 'include'
					);
					$save_key = 'all';
				}

				$products = wc_get_products( $product_args );

				if ( ! empty( $products ) ) {
					$catalog_fields =  ExporoSettings::get_option('exporo_catalog_fields', array('sku', 'price', 'permalink', 'image', 'desc', 'short_desc', 'cats', 'tags'));
					$exporo_image_size =  ExporoSettings::get_option('exporo_image_size', 'large');
					$exporo_gallery_image_size =  ExporoSettings::get_option('exporo_gallery_image_size', 'full');
					
					$response = array();
					foreach ( $products as $product ) {
						$product_id   = sanitize_text_field($product->get_id());
						$product_name = sanitize_text_field($product->get_name());
						$product_sku  = false;
						if (in_array('sku', $catalog_fields)) {
							$product_sku  = sanitize_text_field($product->get_sku());
						}
						$product_permalink = false;
						if (in_array('permalink', $catalog_fields)) {
							$product_permalink = esc_url(get_permalink($product_id));
						}
						$description = false;
						if (in_array('desc', $catalog_fields)) {
							$description = wp_kses_post($product->get_description());
						}	
						$short_description = false;
						if (in_array('short_desc', $catalog_fields)) {
							$short_description = wp_kses_post($product->get_short_description());
						}	
						$image_url = false;
						if (in_array('image', $catalog_fields)) {
							$image_id = $product->get_image_id();
							if ($image_id) {
								$image_url = wp_get_attachment_image_url( $image_id, $exporo_image_size );
							} else {
								$image_url = wc_placeholder_img_src( 'woocommerce_single' );
							}
						}
						$gallery_image_urls = array();
						$gallery_image_ids = $product->get_gallery_image_ids();

						if ( $gallery_image_ids && in_array('gallery', $catalog_fields)) {
							foreach ( $gallery_image_ids as $image_id ) {
								$url = wp_get_attachment_image_url( $image_id, $exporo_gallery_image_size );
								if ( $url ) {
									$gallery_image_urls[] = $url;
								}
							}
						} else {
							$gallery_image_urls = false;
						}

						$categories_list = false;
						if (in_array('cats', $catalog_fields)) {
							$categories_list = wc_get_product_category_list( $product_id, ', ' );
						}
						$tags_list = false;
						if (in_array('tags', $catalog_fields)) {
							$tags_list = wc_get_product_tag_list( $product_id, ', ' );
						}
						$brands_list = false;
						if (in_array('brands', $catalog_fields)) {
							$brands_list = get_the_term_list( $product_id, 'product_brand', '', ', ' );
						}
						$price_output = '';
						if (in_array('price', $catalog_fields)) {
							if ( $product->is_type( 'simple' ) || $product->is_type( 'grouped' ) || $product->is_type( 'external' ) ) {
								$regular_price = $product->get_regular_price();
								$sale_price    = $product->get_sale_price();

								if ( $product->is_on_sale() ) {
									$price_output .= '<span class="regular-price">' . sanitize_text_field(wc_price( $regular_price )) . '</span> - ';
									$price_output .= sanitize_text_field(wc_price( $sale_price ));
									
								} else {
									$price_output = sanitize_text_field(wc_price( $product->get_price() ));
								}

							} else if ( $product->is_type( 'variable' ) ) {
								$min_price = $product->get_variation_price( 'min' );
								$max_price = $product->get_variation_price( 'max' );

								if ( $min_price !== $max_price ) {
									$price_output = sanitize_text_field(wc_price( $min_price ) . ' &ndash; ' . wc_price( $max_price ));
								} else {
									$price_output = sanitize_text_field(wc_price( $min_price ));
								}
							} else {
								$price_output = sanitize_text_field(wc_price( $product->get_price() ));
							}
						}
    					$attributes = $product->get_attributes();

						if (in_array('attr', $catalog_fields) && !empty( $attributes )) {
							$attr_output = '';
							foreach ( $attributes as $attribute ) {
								$attribute_label = wc_attribute_label( $attribute->get_name() );
								if ( $attribute->is_taxonomy() ) {
									$terms = wp_get_post_terms( $product_id, $attribute->get_name(), array( 'fields' => 'names' ) );
									$values = implode( ', ', $terms );
								} else {
									$values = $attribute->get_options();
									if ( is_array( $values ) ) {
										$values = implode( ', ', $values );
									}
								}
								if ( ! empty( $values ) ) {
									$attr_output .= '<p><strong>' . esc_html( $attribute_label ) . ':</strong> ' . esc_html( $values ) . '</p>';
								}
							}
						}

						$reviews = false;
						if (in_array('reviews', $catalog_fields)) {
							$reviews = 'yes';
						}

						$response[$product_id] = array(
							'name' => $product_name, 
							'sku' => $product_sku, 
							'price' => $price_output,
							'permalink' => $product_permalink,
							'image' => $image_url,
							'gallery' => $gallery_image_urls,
							'desc' => $description,
							'short_desc' => $short_description,
							'cats' => $categories_list,
							'tags' => $tags_list,
							'brands' => $brands_list,
							'attr' => $attr_output,
							'reviews' => $reviews
						);
					}
					wp_reset_postdata();

					if ( $org == 'yes' && count($product_ids) !== 1) {
						$categorized_products = [];

						foreach ($response as $response_key => $response_item) {
							$terms = wp_get_post_terms($response_key, 'product_cat');
							if (!empty($terms) && !is_wp_error($terms)) {
								foreach ($terms as $term) {
									$category_id = $term->term_id;
									$category_name = $term->name;
									if (!isset($categorized_products[$category_id])) {
										$categorized_products[$category_id] = [];
									}
									if (!in_array($response_key, $categorized_products[$category_id])) {
										$response_item['category_name'] = $category_name;
										$categorized_products[$category_id][] = $response_item;
									}
								}
							}
						}
						$response = $categorized_products;
					}
				} else {
					wp_die(esc_html__( 'No products found with the specified IDs.', 'exporo' ));
				}

				$cover_url = '';
				if (isset($_GET['exporo_cover']) && !empty($_GET['exporo_cover'])) {
					$cover_url = esc_url($_GET['exporo_cover']);
				} else if (count($product_ids) === 1) {
					$cover_url = get_post_meta( $product_ids[0], 'exporo_single_cover_img', true );
				} else if (isset($_GET['exporo_catid'])) {
					$cover_url = get_term_meta((int) $_GET['exporo_catid'], 'exporo_cover', true);
				} else {
					$cover_url = ExporoSettings::get_option('exporo_cover_image', '');
				}

				$page_args = array(
					'title' => sanitize_text_field($_GET['exporo_title']),
					'subject' => sanitize_text_field($_GET['exporo_subject']),
					'author' => sanitize_text_field($_GET['exporo_author']),
					'creator' => sanitize_text_field($_GET['exporo_creator']),
					'keywords' => sanitize_text_field($_GET['exporo_keywords']),
					'cover' => sanitize_text_field($cover_url),
					'bookmarks' => sanitize_text_field($_GET['exporo_bookmarks']),
					'toc' => sanitize_text_field($_GET['exporo_toc']),
					'org' => sanitize_text_field($_GET['exporo_org']),
					'layout' => sanitize_text_field($_GET['exporo_layout'])
				);

				$file_cache = ExporoSettings::get_option('exporo_file_cache', 'enable');
				if ($file_cache == 'disable') {
					$save_key = 'direct';
				}

				if (count($product_ids) === 1) {
					self::single_layout($response, $page_args, $product_ids[0], $save_key);
				} else {
					if ( $org == 'yes' ) {
						if ( $layout == 'table' ) {
							self::table_category_layout($response, $page_args, $save_key);
						} else {
							self::category_layout($response, $page_args, $save_key);
						}
					} else {
						if ( $layout == 'table' ) {
							self::table_classic_layout($response, $page_args, $save_key);
						} else {
							self::classic_layout($response, $page_args, $save_key);
						}
					}
				}
			} else {
				return;
			}
		}
	}

	/**
	 * Get Product Reviews
	 */
	public function get_product_reviews( $product_id ) {
		$ratings_enabled = 'yes' === get_option( 'woocommerce_enable_review_rating' );

		$product = wc_get_product( $product_id );
		if ( ! $product || ! $product->get_reviews_allowed() ) {
			return;
		}

		$args = array(
			'post_id'   => $product_id,
			'status'    => 'approve',
			'post_type' => 'product',
			'type'      => 'review'
		);

		$reviews = get_comments( $args );

		if ( $reviews ) {
			$html = '<table class="product-reviews-table">';
			$html .= '<thead><tr><th><h2>' . esc_html__('Reviews') . '</h2></th></tr></thead>';
			$html .= '<tbody>';

			foreach ( $reviews as $review ) {
				$author_name = $review->comment_author;
				$review_content = $review->comment_content;
				$rating_html = '';
				
				if ( $ratings_enabled ) {
					$rating = intval( get_comment_meta( $review->comment_ID, 'rating', true ) );
					$filled_stars = $rating;
					$empty_stars = 5 - $rating;
					$star_html = str_repeat( '&#9733;', $filled_stars ) . str_repeat( '&#9734;', $empty_stars );
					$rating_html = '<span style="color: #FFC107;font-size: 1.2em;line-height: 1;white-space: nowrap;">' . $star_html . '</span>';
				}

				$html .= '<tr>';
				$html .= '<td>';
				$html .= '<div class="review-author-info">';
				$html .= '<strong>' . esc_html( $author_name ) . '</strong> ';
				if ( $ratings_enabled ) {
					$html .= '<span class="ratings">' . $rating_html . '</span>';
				}
				$html .= '</div>';
				$html .= '<br>';
				$html .= '<div class="review-content">' . nl2br( esc_html($review_content) ) . '</div>';
				$html .= '</td>';
				$html .= '</tr>';
			}

			$html .= '</tbody>';
			$html .= '</table>';
			
			return $html;
		}
	}

	/**
	 * mPDF Setup
	 */
	public function mpdf_setup($page_args) {
		$selected_font =  ExporoSettings::get_option('exporo_font_family', 'noto');
		$upload_dir_info = wp_upload_dir();
		$base_upload_dir = $upload_dir_info['basedir'];
		$mpdf_temp_dir = $base_upload_dir . '/pdf_temp/';
		if (!is_dir($mpdf_temp_dir)) {
			mkdir($mpdf_temp_dir, 0755, true);
		}

		if ($selected_font == 'noto' || $selected_font == 'roboto' || $selected_font == 'opensans' || $selected_font == 'lato') {
			$defaultConfig = (new \Mpdf\Config\ConfigVariables())->getDefaults();
			$fontDirs = $defaultConfig['fontDir'];

			$defaultFontConfig = (new \Mpdf\Config\FontVariables())->getDefaults();
			$fontData = $defaultFontConfig['fontdata'];

			$mpdf = new \Mpdf\Mpdf([
				'tempDir' => $mpdf_temp_dir,
				'setAutoTopMargin' => 'stretch',
				'fontDir' => array_merge($fontDirs, [
					__DIR__ . '/fonts',
				]),
				'fontdata' => $fontData + [
					$selected_font => [
						'R' => $selected_font . "regular.ttf",
						'B' => $selected_font . "bold.ttf",
						'I' => $selected_font . "italic.ttf",
						'BI' => $selected_font . "bolditalic.ttf",
					]
				],
				'default_font' => $selected_font
			]);
		} else {
			$mpdf = new \Mpdf\Mpdf([
				'tempDir' => $mpdf_temp_dir,
				'setAutoTopMargin' => 'stretch',
				'default_font' => $selected_font
			]);
		}

		$title = '';
		$subject = '';
		$author = '';
		$creator = '';
		$keywords = '';
		$cover = '';
		$shop_name = sanitize_text_field(get_bloginfo('name'));
		$shop_url = esc_url(get_permalink( wc_get_page_id('shop') ));
		$site_info =  ExporoSettings::get_option('exporo_site_info', 'yes');
		$credits =  ExporoSettings::get_option('exporo_credits', '');

		if (isset($page_args['title'])) {
			$title = $page_args['title'];
		}
		if (isset($page_args['subject'])) {
			$subject = $page_args['subject'];
		}
		if (isset($page_args['author'])) {
			$author = $page_args['author'];
		}
		if (isset($page_args['creator'])) {
			$creator = $page_args['creator'];
		}
		if (isset($page_args['keywords'])) {
			$keywords = $page_args['keywords'];
		}
		if (isset($page_args['cover'])) {
			$cover = $page_args['cover'];
		}
		
		$mpdf->SetTitle($title);
		$mpdf->SetSubject($subject);
		$mpdf->SetAuthor($author);
		$mpdf->SetCreator($creator);
		$mpdf->SetKeywords($keywords);

		$stylesheet = file_get_contents( plugin_dir_url( __FILE__ ) . 'css/mpdf.css' );
		$mpdf->WriteHTML($stylesheet, \Mpdf\HTMLParserMode::HEADER_CSS);

		$font_size = ExporoSettings::get_option('exporo_font_size', 11);
		$heading_color = ExporoSettings::get_option('exporo_heading_color', '#212121');
		$text_color = ExporoSettings::get_option('exporo_text_color', '#424242');
		$link_color = ExporoSettings::get_option('exporo_link_color', '#212121');
		$img_size = ExporoSettings::get_option('exporo_single_layout_size', 215);
		$default_img_size = ExporoSettings::get_option('exporo_default_layout_size', 215);
		$cat_img_size = ExporoSettings::get_option('exporo_cat_layout_size', 200);
		$thumb_size = ExporoSettings::get_option('exporo_thumb_size', 50);

		if (!empty($font_size) && $font_size != 11) {
			$mpdf->WriteHTML('<style>body, p {font-size:' . $font_size . 'pt;}</style>');
		}

		if (!empty($thumb_size) && $thumb_size != 50) {
			$mpdf->WriteHTML('<style>.product-photo-table,.thumb-th {width:' . $thumb_size . 'pt;}</style>');
		}

		if (!empty($img_size) && $img_size != 215) {
			$mpdf->WriteHTML('<style>.product-photo-single,.table-grid td.table-grid-photo-single {width:' . $img_size . 'pt;}</style>');
		}

		if (!empty($default_img_size) && $default_img_size != 215) {
			$mpdf->WriteHTML('<style>.product-photo-default,.table-grid td.table-grid-photo {width:' . $default_img_size . 'pt;}</style>');
		}

		if (!empty($cat_img_size) && $cat_img_size != 200) {
			$mpdf->WriteHTML('<style>.product-photo-cat {width:' . $cat_img_size . 'pt;}</style>');
		}

		if (!empty($text_color) && $text_color != '#424242') {
			$mpdf->WriteHTML('<style>body, p, table, td {color:' . $text_color . ';}</style>');
		}

		if (!empty($heading_color) && $heading_color != '#212121') {
			$mpdf->WriteHTML('<style>h1, h2, h3, h4, h5, h6, div.header {color:' . $heading_color . ';}</style>');
		}

		if (!empty($link_color) && $link_color != '#212121') {
			$mpdf->WriteHTML('<style>a, a.mpdf_toc_a {color:' . $link_color . ';}</style>');
		}

		$header = '<div class="header" width="100%">
				<div class="header-l">' . $title . '</div>
				<div class="header-r"><a href="' . $shop_url . '">' . $shop_name . '</a></div>
			</div><div class="clearfix"></div>';

		if ($site_info == 'no') {
			$header = '<div class="header" width="100%">
				<div class="header-l">' . $title . '</div>
				<div class="header-r"></div>
			</div><div class="clearfix"></div>';
		}

		$mpdf->DefHTMLHeaderByName('Header', $header);

		$mpdf->DefHTMLFooterByName(
		'Footer',
		'<table class="footer" width="100%">
			<tr>
				<td width="50%">' . $credits . '</td>
				<td width="50%" style="text-align: right;">' . esc_html__( 'Page', 'exporo' ) . ': {PAGENO}/{nbpg}</td>
			</tr>
		</table>'
		);

		if (!empty($cover)) {
			$cover = esc_url($cover);
			$mpdf->WriteHTML('<div class="cover-photo">
				<img src="' . $cover . '" style="width: 210mm; height: 297mm; margin: 0;">
			</div>');
			$mpdf->AddPage();
		}

		return $mpdf;
	}

	/**
	 * Single Product Layout
	 */
    public function single_layout($response = array(), $page_args = array(), $product_id = 0, $type = 'direct') {
		$public_url = '';
		$full_path = '';
		if ($type != 'direct') {
			if ( self::cache_folder() ) {
				$upload_dir = wp_upload_dir();
				$pdf_dir = $upload_dir['basedir'] . '/pdf_cache/';
				$pdf_url_base = $upload_dir['baseurl'] . '/pdf_cache/';
				$pdf_filename = sanitize_text_field($type) . '.pdf';
				$full_path = $pdf_dir . $pdf_filename;
				$public_url = $pdf_url_base . $pdf_filename;
				if ( file_exists( $full_path ) ) {
					header('Location: ' . $public_url);
					exit();
				}
			} else {
				wp_die(esc_html__( 'Could not create folder. Check WordPress file permissions and maximum file upload limits or disable file caching from Exporo settings.', 'exporo' ));
			}
		}
		$mpdf = self::mpdf_setup($page_args);
		foreach ($response as $key => $value) {
			if ($value['permalink'] && !empty($value['permalink'])) {
				$mpdf->WriteHTML('<h1 class="subheader"><a href="' . $value['permalink'] . '">' . $value['name'] . '</a></h1>');
			} else {
				$mpdf->WriteHTML('<h1 class="subheader">' . $value['name'] . '</h1>');
			}

			$table_output = '<table class="table-grid">';
			$table_output .= '<tbody>';
			$table_output .= '<tr>';
			if ($value['image'] && !empty($value['image'])) {
				$table_output .= '<td class="table-grid-photo-single">';
				if ($value['permalink'] && !empty($value['permalink'])) {
					$table_output .= '<a href="' . $value['permalink'] . '"><img class="product-photo-single" src="' . $value['image'] . '"></a>';
				} else {
					$table_output .= '<img class="product-photo-single" src="' . $value['image'] . '">';
				}
				$table_output .= '</td>';
			}
			$table_output .= '<td class="table-grid-content">';
			if (isset($page_args['toc']) && $page_args['toc'] == 'yes') {
				$table_output .= '<tocentry content="' . $value['name'] . '" level="0" />';
			}
			if (isset($page_args['bookmarks']) && $page_args['bookmarks'] == 'yes') {
				$table_output .= '<bookmark content="' . $value['name'] . '" level="0" />';
			}
			$table_output .= '<p>' . sanitize_text_field($value['short_desc']) . '</p><br>';
			if ($value['price'] && !empty($value['price'])) {
				$table_output .= '<p><strong>' . esc_html__( 'Price', 'exporo' ) . ':</strong> ' . $value['price'] . '</p>';
			}
			if ($value['sku'] && !empty($value['sku'])) {
				$table_output .= '<p><strong>' . esc_html__( 'SKU', 'exporo' ) . ':</strong> ' . $value['sku'] . '</p>';
			}
			if ($value['cats'] && !empty($value['cats'])) {
				$table_output .= '<p><strong>' . esc_html__( 'Categories', 'exporo' ) . ':</strong> ' . $value['cats'] . '</p>';
			}
			if ($value['tags'] && !empty($value['tags'])) {
				$table_output .= '<p><strong>' . esc_html__( 'Tags', 'exporo' ) . ':</strong> ' . $value['tags'] . '</p>';
			}
			if ($value['brands'] && !empty($value['brands'])) {
				$table_output .= '<p><strong>' . esc_html__( 'Brands', 'exporo' ) . ':</strong> ' . $value['brands'] . '</p>';
			}
			if ($value['attr'] && !empty($value['attr'])) {
				$table_output .= $value['attr'];
			}
			$table_output .= '</td>';
			$table_output .= '</tr>';
			$table_output .= '</tbody>';
			$table_output .= '</table>';

			$mpdf->WriteHTML($table_output);

			$mpdf->WriteHTML('<div class="product-desc"><h2>' . esc_html__( 'Description', 'exporo' ) . '</h2>' . wpautop($value['desc']) . '</div>');

			$reviews_enabled = 'yes' === get_option( 'woocommerce_enable_reviews' );
			if ($reviews_enabled && $value['reviews'] && !empty($value['reviews'])) {
				$reviews = self::get_product_reviews( $product_id );
				if (!empty($reviews)) {
					$mpdf->AddPage();
					$mpdf->WriteHTML('<div class="product-reviews">' . $reviews . '</div>');
				}
			}

			if ($value['gallery'] && !empty($value['gallery']) && is_array($value['gallery'])) {
				$galleryHtml = '<div class="noheader">';
				foreach ($value['gallery'] as $index => $url) {
					$galleryHtml .= '<div class="product-photo-gallery-item"><img class="product-photo-gallery" src="' . htmlspecialchars($url) . '"></div>';
				}
				$galleryHtml .= '</div>';
				$mpdf->WriteHTML($galleryHtml);
			}

			if ($type == 'direct') {
				$download_file = ExporoSettings::get_option('exporo_download_file', 'disable');
				if ($download_file == 'enable') {
					$fileName = rand();
					$mpdf->Output($fileName . '.pdf', \Mpdf\Output\Destination::DOWNLOAD);
				} else {
					$mpdf->Output();
				}
			} else {
				$mpdf->Output( $full_path, 'F' );
    			header('Location: ' . $public_url);
			}
			exit();
		}

	}

	/**
	 * Category Layout
	 */
    public function category_layout($response = array(), $page_args = array(), $type = 'direct') {
		$public_url = '';
		$full_path = '';
		if ($type != 'direct') {
			if ( self::cache_folder() ) {
				$upload_dir = wp_upload_dir();
				$pdf_dir = $upload_dir['basedir'] . '/pdf_cache/';
				$pdf_url_base = $upload_dir['baseurl'] . '/pdf_cache/';
				$pdf_filename = sanitize_text_field($type) . '.pdf';
				$full_path = $pdf_dir . $pdf_filename;
				$public_url = $pdf_url_base . $pdf_filename;
				if ( file_exists( $full_path ) ) {
					header('Location: ' . $public_url);
					exit();
				}
			} else {
				wp_die(esc_html__( 'Could not create folder. Check WordPress file permissions and maximum file upload limits or disable file caching from Exporo settings.', 'exporo' ));
			}
		}
		$mpdf = self::mpdf_setup($page_args);
		if (isset($page_args['toc']) && $page_args['toc'] == 'yes') {
			$mpdf->WriteHTML(' ');
			$mpdf->TOCpagebreakByArray(array(
				'TOCuseLinking' => true,
				'toc_preHTML' => '<h1>' . esc_html__( 'Table Of Contents', 'exporo' ) . '</h1>',
				'toc_bookmarkText' => esc_html__( 'Table Of Contents', 'exporo' )
			));
		}
		$max_chars = (int) ExporoSettings::get_option('exporo_max_chars', 220);
		$first = 0;
		foreach ($response as $key => $val) {
			$first ++;
			if ($first !== 1) {
				$mpdf->AddPage();
			}
			if (isset($page_args['toc']) && $page_args['toc'] == 'yes') {
				$mpdf->TOC_Entry($val[0]['category_name'], 0);
			}
			if (isset($page_args['bookmarks']) && $page_args['bookmarks'] == 'yes') {
				$mpdf->WriteHTML('<bookmark content="' . $val[0]['category_name'] . '" level="0" />');
			}

			$mpdf->WriteHTML('<h1 class="subheader">' . $val[0]['category_name'] . '</h1>');

			$table_output = '<table class="table-grid">';
			$table_output .= '<tbody>';

			foreach ($val as $value) {
				$table_output .= '<tr>';
				if ($value['image'] && !empty($value['image'])) {
					$table_output .= '<td class="table-grid-photo">';
					if ($value['permalink'] && !empty($value['permalink'])) {
						$table_output .= '<a href="' . $value['permalink'] . '"><img class="product-photo-cat" src="' . $value['image'] . '"></a>';
					} else {
						$table_output .= '<img class="product-photo-cat" src="' . $value['image'] . '">';
					}
					$table_output .= '</td>';
				}
				$table_output .= '<td class="table-grid-content">';
				if (isset($page_args['toc']) && $page_args['toc'] == 'yes') {
					$table_output .= '<tocentry content="' . $value['name'] . '" level="1" />';
				}
				if (isset($page_args['bookmarks']) && $page_args['bookmarks'] == 'yes') {
					$table_output .= '<bookmark content="' . $value['name'] . '" level="1" />';
				}
				if ($value['permalink'] && !empty($value['permalink'])) {
					$table_output .= '<h2><a href="' . $value['permalink'] . '">' . $value['name'] . '</a></h2><br>';
				} else {
					$table_output .= '<h2>' . $value['name'] . '</h2><br>';
				}
				if ( strlen( $value['short_desc'] ) > $max_chars ) {
					$limited_string = substr( $value['short_desc'], 0, $max_chars ) . '...';
				} else {
					$limited_string = $value['short_desc'];
				}
				$table_output .= '<p>' . sanitize_text_field($limited_string) . '</p><br>';
				if ($value['price'] && !empty($value['price'])) {
					$table_output .= '<p><strong>' . esc_html__( 'Price', 'exporo' ) . ':</strong> ' . $value['price'] . '</p>';
				}
				if ($value['sku'] && !empty($value['sku'])) {
					$table_output .= '<p><strong>' . esc_html__( 'SKU', 'exporo' ) . ':</strong> ' . $value['sku'] . '</p>';
				}
				if ($value['cats'] && !empty($value['cats'])) {
					$table_output .= '<p><strong>' . esc_html__( 'Categories', 'exporo' ) . ':</strong> ' . $value['cats'] . '</p>';
				}
				if ($value['tags'] && !empty($value['tags'])) {
					$table_output .= '<p><strong>' . esc_html__( 'Tags', 'exporo' ) . ':</strong> ' . $value['tags'] . '</p>';
				}
				if ($value['brands'] && !empty($value['brands'])) {
					$table_output .= '<p><strong>' . esc_html__( 'Brands', 'exporo' ) . ':</strong> ' . $value['brands'] . '</p>';
				}
				$table_output .= '</td>';
				$table_output .= '</tr>';
			}

			$table_output .= '</tbody>';
			$table_output .= '</table>';

			$mpdf->WriteHTML($table_output);
		}

		if ($type == 'direct') {
			$download_file = ExporoSettings::get_option('exporo_download_file', 'disable');
			if ($download_file == 'enable') {
				$fileName = rand();
				$mpdf->Output($fileName . '.pdf', \Mpdf\Output\Destination::DOWNLOAD);
			} else {
				$mpdf->Output();
			}
		} else {
			$mpdf->Output( $full_path, 'F' );
			header('Location: ' . $public_url);
		}
		exit();
	}

	/**
	 * Classic Layout
	 */
    public function classic_layout($response = array(), $page_args = array(), $type = 'direct') {
		$public_url = '';
		$full_path = '';
		if ($type != 'direct') {
			if ( self::cache_folder() ) {
				$upload_dir = wp_upload_dir();
				$pdf_dir = $upload_dir['basedir'] . '/pdf_cache/';
				$pdf_url_base = $upload_dir['baseurl'] . '/pdf_cache/';
				$pdf_filename = sanitize_text_field($type) . '.pdf';
				$full_path = $pdf_dir . $pdf_filename;
				$public_url = $pdf_url_base . $pdf_filename;
				if ( file_exists( $full_path ) ) {
					header('Location: ' . $public_url);
					exit();
				}
			} else {
				wp_die(esc_html__( 'Could not create folder. Check WordPress file permissions and maximum file upload limits or disable file caching from Exporo settings.', 'exporo' ));
			}
		}
		$mpdf = self::mpdf_setup($page_args);
		$max_chars = (int) ExporoSettings::get_option('exporo_max_chars', 220);

		if (isset($page_args['toc']) && $page_args['toc'] == 'yes') {
			$mpdf->WriteHTML(' ');
			$mpdf->TOCpagebreakByArray(array(
				'TOCuseLinking' => true,
				'toc_preHTML' => '<h1>' . esc_html__( 'Table Of Contents', 'exporo' ) . '</h1>',
				'toc_bookmarkText' => esc_html__( 'Table Of Contents', 'exporo' )
			));
		}

		$table_output = '<table class="table-grid">';
		$table_output .= '<tbody>';

		foreach ($response as $key => $value) {
			$table_output .= '<tr>';
			if ($value['image'] && !empty($value['image'])) {
				$table_output .= '<td class="table-grid-photo">';
				if ($value['permalink'] && !empty($value['permalink'])) {
					$table_output .= '<a href="' . $value['permalink'] . '"><img class="product-photo-default" src="' . $value['image'] . '"></a>';
				} else {
					$table_output .= '<img class="product-photo-default" src="' . $value['image'] . '">';
				}
				$table_output .= '</td>';
			}
			$table_output .= '<td class="table-grid-content">';
			if (isset($page_args['toc']) && $page_args['toc'] == 'yes') {
				$table_output .= '<tocentry content="' . $value['name'] . '" level="0" />';
			}
			if (isset($page_args['bookmarks']) && $page_args['bookmarks'] == 'yes') {
				$table_output .= '<bookmark content="' . $value['name'] . '" level="0" />';
			}
			if ($value['permalink'] && !empty($value['permalink'])) {
				$table_output .= '<h2><a href="' . $value['permalink'] . '">' . $value['name'] . '</a></h2><br>';
			} else {
				$table_output .= '<h2>' . $value['name'] . '</h2><br>';
			}
			if ( strlen( $value['short_desc'] ) > $max_chars ) {
				$limited_string = substr( $value['short_desc'], 0, $max_chars ) . '...';
			} else {
				$limited_string = $value['short_desc'];
			}
			$table_output .= '<p>' . sanitize_text_field($limited_string) . '</p><br>';
			if ($value['price'] && !empty($value['price'])) {
				$table_output .= '<p><strong>' . esc_html__( 'Price', 'exporo' ) . ':</strong> ' . $value['price'] . '</p>';
			}
			if ($value['sku'] && !empty($value['sku'])) {
				$table_output .= '<p><strong>' . esc_html__( 'SKU', 'exporo' ) . ':</strong> ' . $value['sku'] . '</p>';
			}
			if ($value['cats'] && !empty($value['cats'])) {
				$table_output .= '<p><strong>' . esc_html__( 'Categories', 'exporo' ) . ':</strong> ' . $value['cats'] . '</p>';
			}
			if ($value['tags'] && !empty($value['tags'])) {
				$table_output .= '<p><strong>' . esc_html__( 'Tags', 'exporo' ) . ':</strong> ' . $value['tags'] . '</p>';
			}
			if ($value['brands'] && !empty($value['brands'])) {
				$table_output .= '<p><strong>' . esc_html__( 'Brands', 'exporo' ) . ':</strong> ' . $value['brands'] . '</p>';
			}
			$table_output .= '</td>';
			$table_output .= '</tr>';
		}

		$table_output .= '</tbody>';
		$table_output .= '</table>';

		$mpdf->WriteHTML($table_output);

		if ($type == 'direct') {
			$download_file = ExporoSettings::get_option('exporo_download_file', 'disable');
			if ($download_file == 'enable') {
				$fileName = rand();
				$mpdf->Output($fileName . '.pdf', \Mpdf\Output\Destination::DOWNLOAD);
			} else {
				$mpdf->Output();
			}
		} else {
			$mpdf->Output( $full_path, 'F' );
			header('Location: ' . $public_url);
		}
		exit();
	}

	/**
	 * Table Category Layout
	 */
    public function table_category_layout($response = array(), $page_args = array(), $type = 'direct') {
		$public_url = '';
		$full_path = '';
		if ($type != 'direct') {
			if ( self::cache_folder() ) {
				$upload_dir = wp_upload_dir();
				$pdf_dir = $upload_dir['basedir'] . '/pdf_cache/';
				$pdf_url_base = $upload_dir['baseurl'] . '/pdf_cache/';
				$pdf_filename = sanitize_text_field($type) . '.pdf';
				$full_path = $pdf_dir . $pdf_filename;
				$public_url = $pdf_url_base . $pdf_filename;
				if ( file_exists( $full_path ) ) {
					header('Location: ' . $public_url);
					exit();
				}
			} else {
				wp_die(esc_html__( 'Could not create folder. Check WordPress file permissions and maximum file upload limits or disable file caching from Exporo settings.', 'exporo' ));
			}
		}
		$mpdf = self::mpdf_setup($page_args);
		if (isset($page_args['toc']) && $page_args['toc'] == 'yes') {
			$mpdf->WriteHTML(' ');
			$mpdf->TOCpagebreakByArray(array(
				'TOCuseLinking' => true,
				'toc_preHTML' => '<h1>' . esc_html__( 'Table Of Contents', 'exporo' ) . '</h1>',
				'toc_bookmarkText' => esc_html__( 'Table Of Contents', 'exporo' )
			));
		}
		$first = 0;
		foreach ($response as $key => $val) {
			$first ++;
			if ($first !== 1) {
				$mpdf->AddPage();
			}
			if (isset($page_args['toc']) && $page_args['toc'] == 'yes') {
				$mpdf->TOC_Entry($val[0]['category_name'], 0);
			}
			if (isset($page_args['bookmarks']) && $page_args['bookmarks'] == 'yes') {
				$mpdf->WriteHTML('<bookmark content="' . $val[0]['category_name'] . '" level="0" />');
			}

			$mpdf->WriteHTML('<h1 class="subheader">' . $val[0]['category_name'] . '</h1>');
			$catalog_fields = ExporoSettings::get_option('exporo_catalog_fields', array('sku', 'price', 'permalink', 'image', 'desc', 'short_desc', 'cats', 'tags'));
			$table_output = '<table class="table-layout">';
			$table_output .= '<thead><tr>';
			if (in_array('image', $catalog_fields)) {
				$table_output .= '<th class="thumb-th"> </th>';
			}
			$table_output .= '<th>' . esc_html__('Name') . '</th>';
			if (in_array('price', $catalog_fields)) {
				$table_output .= '<th><strong>' . esc_html__( 'Price', 'exporo' ) . '</strong></th>';
			}
			if (in_array('sku', $catalog_fields)) {
				$table_output .= '<th><strong>' . esc_html__( 'SKU', 'exporo' ) . '</strong></th>';
			}
			if (in_array('cats', $catalog_fields)) {
				$table_output .= '<th><strong>' . esc_html__( 'Categories', 'exporo' ) . '</strong></th>';
			}
			if (in_array('tags', $catalog_fields)) {
				$table_output .= '<th><strong>' . esc_html__( 'Tags', 'exporo' ) . '</strong></th>';
			}
			if (in_array('brands', $catalog_fields)) {
				$table_output .= '<th><strong>' . esc_html__( 'Brands', 'exporo' ) . '</strong></th>';
			}
			$table_output .= '</tr></thead>';
			$table_output .= '<tbody>';

			foreach ($val as $value) {
				$table_output .= '<tr>';
				if ($value['image']) {
					$table_output .= '<td style="padding:0;">';
					if (!empty($value['image'])) {
						if ($value['permalink'] && !empty($value['permalink'])) {
							$table_output .= '<a href="' . $value['permalink'] . '"><img class="product-photo-table" src="' . $value['image'] . '"></a>';
						} else {
							$table_output .= '<img class="product-photo-table" src="' . $value['image'] . '">';
						}
					}
					$table_output .= '</td>';
				}
				$table_output .= '<td>';
				if (isset($page_args['toc']) && $page_args['toc'] == 'yes') {
					$table_output .= '<tocentry content="' . $value['name'] . '" level="1" />';
				}
				if (isset($page_args['bookmarks']) && $page_args['bookmarks'] == 'yes') {
					$table_output .= '<bookmark content="' . $value['name'] . '" level="1" />';
				}
				if ($value['permalink'] && !empty($value['permalink'])) {
					$table_output .= '<a href="' . $value['permalink'] . '"><strong>' . $value['name'] . '</strong></a>';
				} else {
					$table_output .= '<strong>' . $value['name'] . '</strong>';
				}
				$table_output .= '</td>';
				if (in_array('price', $catalog_fields)) {
					$table_output .= '<td>' . $value['price'] . '</td>';
				}
				if (in_array('sku', $catalog_fields)) {
					$table_output .= '<td>' . $value['sku'] . '</td>';
				}
				if (in_array('cats', $catalog_fields)) {
					$table_output .= '<td>' . $value['cats'] . '</td>';
				}
				if (in_array('tags', $catalog_fields)) {
					$table_output .= '<td>' . $value['tags'] . '</td>';
				}
				if (in_array('brands', $catalog_fields)) {
					$table_output .= '<td>' . $value['brands'] . '</td>';
				}
				$table_output .= '</tr>';
			}

			$table_output .= '</tbody>';
			$table_output .= '</table>';
			
			$mpdf->WriteHTML($table_output);
		}
		if ($type == 'direct') {
			$download_file = ExporoSettings::get_option('exporo_download_file', 'disable');
			if ($download_file == 'enable') {
				$fileName = rand();
				$mpdf->Output($fileName . '.pdf', \Mpdf\Output\Destination::DOWNLOAD);
			} else {
				$mpdf->Output();
			}
		} else {
			$mpdf->Output( $full_path, 'F' );
			header('Location: ' . $public_url);
		}
		exit();
	}

	/**
	 * Table Classic Layout
	 */
    public function table_classic_layout($response = array(), $page_args = array(), $type = 'direct') {
		$public_url = '';
		$full_path = '';
		if ($type != 'direct') {
			if ( self::cache_folder() ) {
				$upload_dir = wp_upload_dir();
				$pdf_dir = $upload_dir['basedir'] . '/pdf_cache/';
				$pdf_url_base = $upload_dir['baseurl'] . '/pdf_cache/';
				$pdf_filename = sanitize_text_field($type) . '.pdf';
				$full_path = $pdf_dir . $pdf_filename;
				$public_url = $pdf_url_base . $pdf_filename;
				if ( file_exists( $full_path ) ) {
					header('Location: ' . $public_url);
					exit();
				}
			} else {
				wp_die(esc_html__( 'Could not create folder. Check WordPress file permissions and maximum file upload limits or disable file caching from Exporo settings.', 'exporo' ));
			}
		}
		$mpdf = self::mpdf_setup($page_args);

		if (isset($page_args['toc']) && $page_args['toc'] == 'yes') {
			$mpdf->WriteHTML(' ');
			$mpdf->TOCpagebreakByArray(array(
				'TOCuseLinking' => true,
				'toc_preHTML' => '<h1>' . esc_html__( 'Table Of Contents', 'exporo' ) . '</h1>',
				'toc_bookmarkText' => esc_html__( 'Table Of Contents', 'exporo' )
			));
		}

		$catalog_fields = ExporoSettings::get_option('exporo_catalog_fields', array('sku', 'price', 'permalink', 'image', 'desc', 'short_desc', 'cats', 'tags'));
		$table_output = '<table class="table-layout">';
		$table_output .= '<thead><tr>';
		if (in_array('image', $catalog_fields)) {
			$table_output .= '<th class="thumb-th"> </th>';
		}
		$table_output .= '<th>' . esc_html__('Name') . '</th>';
		if (in_array('price', $catalog_fields)) {
			$table_output .= '<th><strong>' . esc_html__( 'Price', 'exporo' ) . '</strong></th>';
		}
		if (in_array('sku', $catalog_fields)) {
			$table_output .= '<th><strong>' . esc_html__( 'SKU', 'exporo' ) . '</strong></th>';
		}
		if (in_array('cats', $catalog_fields)) {
			$table_output .= '<th><strong>' . esc_html__( 'Categories', 'exporo' ) . '</strong></th>';
		}
		if (in_array('tags', $catalog_fields)) {
			$table_output .= '<th><strong>' . esc_html__( 'Tags', 'exporo' ) . '</strong></th>';
		}
		if (in_array('brands', $catalog_fields)) {
			$table_output .= '<th><strong>' . esc_html__( 'Brands', 'exporo' ) . '</strong></th>';
		}
		$table_output .= '</tr></thead>';
		$table_output .= '<tbody>';

		foreach ($response as $key => $value) {
			$table_output .= '<tr>';
			if ($value['image']) {
				$table_output .= '<td style="padding:0;">';
				if (!empty($value['image'])) {
					if ($value['permalink'] && !empty($value['permalink'])) {
						$table_output .= '<a href="' . $value['permalink'] . '"><img class="product-photo-table" src="' . $value['image'] . '"></a>';
					} else {
						$table_output .= '<img class="product-photo-table" src="' . $value['image'] . '">';
					}
				}
				$table_output .= '</td>';
			}
			$table_output .= '<td>';
			if (isset($page_args['toc']) && $page_args['toc'] == 'yes') {
				$table_output .= '<tocentry content="' . $value['name'] . '" level="0" />';
			}
			if (isset($page_args['bookmarks']) && $page_args['bookmarks'] == 'yes') {
				$table_output .= '<bookmark content="' . $value['name'] . '" level="0" />';
			}
			if ($value['permalink'] && !empty($value['permalink'])) {
				$table_output .= '<a href="' . $value['permalink'] . '"><strong>' . $value['name'] . '</strong></a>';
			} else {
				$table_output .= '<strong>' . $value['name'] . '</strong>';
			}
			$table_output .= '</td>';
			if (in_array('price', $catalog_fields)) {
				$table_output .= '<td>' . $value['price'] . '</td>';
			}
			if (in_array('sku', $catalog_fields)) {
				$table_output .= '<td>' . $value['sku'] . '</td>';
			}
			if (in_array('cats', $catalog_fields)) {
				$table_output .= '<td>' . $value['cats'] . '</td>';
			}
			if (in_array('tags', $catalog_fields)) {
				$table_output .= '<td>' . $value['tags'] . '</td>';
			}
			if (in_array('brands', $catalog_fields)) {
				$table_output .= '<td>' . $value['brands'] . '</td>';
			}
			$table_output .= '</tr>';
		}

		$table_output .= '</tbody>';
		$table_output .= '</table>';
		
		$mpdf->WriteHTML($table_output);

		if ($type == 'direct') {
			$download_file = ExporoSettings::get_option('exporo_download_file', 'disable');
			if ($download_file == 'enable') {
				$fileName = rand();
				$mpdf->Output($fileName . '.pdf', \Mpdf\Output\Destination::DOWNLOAD);
			} else {
				$mpdf->Output();
			}
		} else {
			$mpdf->Output( $full_path, 'F' );
			header('Location: ' . $public_url);
		}
		exit();
	}

	/**
	 * Catalog Shortcode
	 */
	public function catalog_shortcode( $atts, $content = null ) {
		$title =  ExporoSettings::get_option('exporo_default_title', '');
		$subject =  ExporoSettings::get_option('exporo_default_subject', '');
		$author =  ExporoSettings::get_option('exporo_default_author', '');
		$creator =  ExporoSettings::get_option('exporo_default_creator', '');
		$keywords =  ExporoSettings::get_option('exporo_default_keywords', '');
		$org = ExporoSettings::get_option('exporo_default_org', 'no');
		$bookmarks = ExporoSettings::get_option('exporo_default_bookmarks', 'yes');
		$toc = ExporoSettings::get_option('exporo_default_toc', 'no');
		$layout = ExporoSettings::get_option('exporo_catalog_style', 'default');

		$atts = shortcode_atts(
			array(
				'btntext'   => esc_html__('Complete Catalog (PDF)', 'exporo'),
				'catid' => '',
				'productid' => '',
				'title'   => $title,
				'subject'  => $subject,
				'author'  => $author,
				'creator'  => $creator,
				'keywords'  => $keywords,
				'cover'  => '',
				'org'  => $org,
				'bookmarks'  => $bookmarks,
				'toc'  => $toc,
				'layout'  => $layout
			),
			$atts,
			'exporo_catalog'
		);

		$btntext   = esc_html( $atts['btntext'] );
		$catid   = esc_html( $atts['catid'] );
		$productid   = esc_html( $atts['productid'] );
		$title   = esc_html( $atts['title'] );
		$subject   = esc_html( $atts['subject'] );
		$author   = esc_html( $atts['author'] );
		$creator   = esc_html( $atts['creator'] );
		$keywords   = esc_html( $atts['keywords'] );
		$cover   = esc_html( $atts['cover'] );
		$org   = esc_html( $atts['org'] );
		$bookmarks   = esc_html( $atts['bookmarks'] );
		$toc   = esc_html( $atts['toc'] );
		$layout   = esc_html( $atts['layout'] );
		$output = '';

		$login_required =  ExporoSettings::get_option('exporo_login_required', 'no');
		$user_roles =  ExporoSettings::get_option('exporo_user_roles', array());
		if ($login_required == 'yes' && !is_user_logged_in()) {
			return $output;
		}
		if ($login_required == 'yes' && !current_user_can('administrator') && !self::user_has_one_of_roles( $user_roles )) {
			return $output;
		}

		$output .= '<form id="exporo-form" action="' . get_site_url() . '" method="GET" target="_blank"><input name="page" type="hidden" value="pdf">';
		if (!empty($catid)) {
			$output .= '<input name="exporo_catid" type="hidden" value="' . $catid . '">';
		}
		if (!empty($productid)) {
			$output .= '<input name="exporo_productid" type="hidden" value="' . $productid . '">';
		}
		$output .= '<input name="exporo_title" type="hidden" value="' . $title . '">';
		$output .= '<input name="exporo_subject" type="hidden" value="' . $subject . '">';
		$output .= '<input name="exporo_author" type="hidden" value="' . $author . '">';
		$output .= '<input name="exporo_creator" type="hidden" value="' . $creator . '">';
		$output .= '<input name="exporo_keywords" type="hidden" value="' . $keywords . '">';
		$output .= '<input name="exporo_cover" type="hidden" value="' . $cover . '">';
		$output .= '<input name="exporo_org" type="hidden" value="' . $org . '">';
		$output .= '<input name="exporo_bookmarks" type="hidden" value="' . $bookmarks . '">';
		$output .= '<input name="exporo_toc" type="hidden" value="' . $toc . '">';
		$output .= '<input name="exporo_layout" type="hidden" value="' . $layout . '">';
		$output .= '<button type="submit" class="exporo-btn">' . $btntext . '</button>';
		$output .= '</form>';

		return $output;
	}

	/**
	 * Add Custom Product Category Meta Field
	 */

	public function category_cover_add() {
		?>
		<div class="form-field">
			<label for="term_meta[exporo_cover]"><?php echo esc_html__( 'PDF Cover Image', 'exporo' ); ?></label>
			<div class="exporo-input-group"><input type="text" id="exporo_cover" name="term_meta[exporo_cover]" value="" class="regular-text" />
			<input type='button' class="button-secondary custom-media-upload" id="exporo-cat-upload-button" value="<?php echo esc_attr__( 'Select Image', 'exporo' ); ?>" /></div>
		</div>
		<?php
	}

	public function category_cover_edit($term) {
		$t_id = $term->term_id;
		$exporo_cover = get_term_meta($t_id, 'exporo_cover', true);
		?>
		<tr class="form-field">
			<th scope="row" valign="top">
				<label for="term_meta[exporo_cover]"><?php echo esc_html__( 'PDF Cover Image', 'exporo' ); ?></label>
			</th>
			<td>
				<input type="text" name="term_meta[exporo_cover]" id="exporo_cover" value="<?php echo esc_url( $exporo_cover ); ?>" class="regular-text" />
				<input type='button' class="button-secondary custom-media-upload" id="exporo-cat-upload-button" value="<?php echo esc_attr__( 'Select Image', 'exporo' ); ?>" /></div>
			</td>
		</tr>
		<?php
	}

	public function category_cover_save( $term_id ) {
		if ( isset( $_POST['term_meta'] ) ) {
			$exporo_cover = filter_input(INPUT_POST, 'exporo_cover');
			$exporo_cover_url = isset( $_POST['term_meta']['exporo_cover'] ) ? $_POST['term_meta']['exporo_cover'] : '';
        	update_term_meta($term_id, 'exporo_cover', sanitize_text_field($exporo_cover_url));
		}
	}

	/**
	 * Cache Folder
	 */
	public function cache_folder() {
		$upload_dir = wp_upload_dir();
		$base_dir = $upload_dir['basedir'];
		$new_folder_name = 'pdf_cache';
		$target_dir = $base_dir . '/' . $new_folder_name;
		if ( ! is_dir( $target_dir ) ) {
			$permissions = 0755;
			if ( wp_mkdir_p( $target_dir, $permissions ) ) {
				return true;
			} else {
				return false; 
			}
		}
		return true;
	}

	/**
	 * Clear Cache
	 */
	public function clear_cache() {
		if ( ! wp_verify_nonce( $_POST['nonce'], 'exporo-nonce' ) ) {
			echo 'error';
            exit();
        }
		$clearCache = exporo_delete_directory();
		$cleartempCache = exporo_delete_temp_directory();
		if ($clearCache && $cleartempCache) {
			echo 'done';
		} else {
			echo 'error';
		}
		exit();
	}

	/**
	 * Add Shortcode ONLY to the main Shop Page
	 */
	public function before_shop_page_loop() {
		$shop_btn =  ExporoSettings::get_option('exporo_shop_btn', 'yes');
		if ($shop_btn == 'yes') {
			if ( is_shop() && ! is_product_category()) {
				echo '<div class="exporo-btn-wrap">';
				echo do_shortcode( '[exporo_catalog]' );
				echo '</div>';
			}
		}
	}

	/**
	 * Add Shortcode ONLY to a Product Category Page
	 */
	public function before_category_loop() {
		$cat_btn =  ExporoSettings::get_option('exporo_cat_btn', 'yes');
		$shop_btn =  ExporoSettings::get_option('exporo_shop_btn', 'yes');
		if ($cat_btn == 'yes') {
			if ( is_product_category() ) {
				$current_term = get_queried_object();
				if ( $current_term && is_a( $current_term, 'WP_Term' ) ) {
					$category_id = $current_term->term_id;
					echo '<div class="exporo-btn-wrap">';
					if ($shop_btn == 'yes') {
						echo do_shortcode( '[exporo_catalog]' );
					}
					echo do_shortcode('[exporo_catalog btntext="' . esc_attr__( 'Category Catalog (PDF)', 'exporo' ) . '" catid="' . esc_attr( $category_id ) . '"]');
					echo '</div>';
				}
			}
		}
	}

	/**
	 * Add Shortcode ONLY to single product page
	 */
	public function after_cart() {
		$btn =  ExporoSettings::get_option('exporo_single_btn', 'yes');
		if ($btn == 'yes') {
			global $product;
			$product_id = $product->get_id();
			echo '<div class="exporo-single-btn-wrap">';
			echo do_shortcode('[exporo_catalog btntext="' . esc_attr__( 'Product Catalog (PDF)', 'exporo' ) . '" productid="' . esc_attr( $product_id ) . '"]');
			echo '</div>';
		}
	}

	/**
	 * Add custom cover image metabox to product
	 */
	public function single_product_cover( $meta_boxes ) {
        $prefix = 'exporo_cmb2';
        $exporo_cmb2 = new_cmb2_box( array(
            'id' => 'exporo_single_cover',
            'title' => esc_attr__( 'PDF Cover', 'exporo'),
            'object_types' => array('product'),
            'context' => 'side',
            'priority' => 'default',
            'show_names' => false,
            'cmb_styles' => true
        ));

		$exporo_cmb2->add_field( array(
            'name'    => esc_html__( 'PDF Cover', 'exporo' ),
            'description' => esc_html__( 'Recommended image dimentions: 841x1189px or 1682x2378px.', 'exporo' ),
            'id'      => 'exporo_single_cover_img',
            'type'    => 'file',
            'query_args' => array(
                'type' => array(
                    'image/jpeg',
                    'image/png',
					'image/webp'
                ),
            ),
            'preview_size' => 'medium',
            'default' => ''
        ) );
	}
}

/**
 * Returns the main instance of the class
 */
function Exporo() {  
	return Exporo::instance();
}
// Global for backwards compatibility
$GLOBALS['Exporo'] = Exporo();