<?php
/**
 * The common functionality of the plugin.
 *
 * @link       https://wpswings.com/
 * @since      1.0.0
 *
 * @package    Pdf_Generator_For_Wp
 * @subpackage Pdf_Generator_For_Wp/common
 */

use Dompdf\Dompdf;
use Dompdf\Options;
use Dompdf\FontMetrics;
use Automattic\WooCommerce\Utilities\OrderUtil;
/**
 * The common functionality of the plugin.
 *
 * Defines the plugin name, version, and two examples hooks for how to
 * enqueue the common stylesheet and JavaScript.
 * namespace pdf_generator_for_wp_common.
 *
 * @package    Pdf_Generator_For_Wp
 * @subpackage Pdf_Generator_For_Wp/common
 * @author     WP Swings <webmaster@wpswings.com>
 */
class Pdf_Generator_For_Wp_Common {
	/**
	 * The ID of this plugin.
	 *
	 * @since    1.0.0
	 * @var      string    $plugin_name    The ID of this plugin.
	 */
	private $plugin_name;

	/**
	 * The version of this plugin.
	 *
	 * @since 1.0.0
	 * @var   string    $version    The current version of this plugin.
	 */
	private $version;

	/**
	 * Initialize the class and set its properties.
	 *
	 * @since  1.0.0
	 * @param  string $plugin_name       The name of the plugin.
	 * @param  string $version    The version of this plugin.
	 */
	public function __construct( $plugin_name, $version ) {

		$this->plugin_name = $plugin_name;
		$this->version     = $version;
	}

	/**
	 * Get cached general settings for the current request.
	 *
	 * @return array
	 */
	private function pgfw_get_general_settings() {
		$settings = wps_pgfw_get_option_cached( 'pgfw_general_settings_save', array() );
		return is_array( $settings ) ? $settings : array();
	}

	/**
	 * Get cached display settings for the current request.
	 *
	 * @return array
	 */
	private function pgfw_get_display_settings() {
		$settings = wps_pgfw_get_option_cached( 'pgfw_save_admin_display_settings', array() );
		return is_array( $settings ) ? $settings : array();
	}

	/**
	 * Get cached advanced settings for the current request.
	 *
	 * @return array
	 */
	private function pgfw_get_advanced_settings() {
		$settings = wps_pgfw_get_option_cached( 'pgfw_advanced_save_settings', array() );
		return is_array( $settings ) ? $settings : array();
	}

	/**
	 * Determine whether common front-end assets are needed for the current request.
	 *
	 * @return bool
	 */
	private function pgfw_should_enqueue_common_assets() {
		$general_settings = $this->pgfw_get_general_settings();
		if ( 'yes' !== ( $general_settings['pgfw_enable_plugin'] ?? '' ) ) {
			return false;
		}

		if ( is_singular() ) {
			return true;
		}

		if ( is_front_page() || is_home() ) {
			$post_id = get_queried_object_id();
			if ( $post_id ) {
				$post = get_post( $post_id );
				if ( $post && isset( $post->post_content ) ) {
					if ( has_shortcode( $post->post_content, 'WORDPRESS_PDF' ) || has_shortcode( $post->post_content, 'flipbook' ) ) {
						return true;
					}
				}

				$advanced_settings   = $this->pgfw_get_advanced_settings();
				$enabled_post_types = $advanced_settings['pgfw_advanced_show_post_type_icons'] ?? array();
				if ( is_array( $enabled_post_types ) && in_array( get_post_type( $post_id ), $enabled_post_types, true ) ) {
					return true;
				}
			}
		}

		return false;
	}

	/**
	 * Determine whether flipbook runtime assets are needed on the current request.
	 *
	 * @return bool
	 */
	private function pgfw_should_enqueue_flipbook_assets() {
		$general_settings = $this->pgfw_get_general_settings();
		if ( 'yes' !== ( $general_settings['pgfw_enable_plugin'] ?? '' ) || 'yes' !== ( $general_settings['pgfw_flipbook_enable'] ?? '' ) || ! is_singular() ) {
			return false;
		}

		$post_id = get_queried_object_id();
		$post    = $post_id ? get_post( $post_id ) : null;

		return $post && isset( $post->post_content ) && has_shortcode( $post->post_content, 'flipbook' );
	}

	/**
	 * Register the stylesheets for the common side of the site.
	 *
	 * @since    1.0.0
	 */
	public function pgfw_common_enqueue_styles() {
		if ( ! $this->pgfw_should_enqueue_common_assets() ) {
			return;
		}

		wp_enqueue_style( $this->plugin_name . 'common', PDF_GENERATOR_FOR_WP_DIR_URL . 'common/src/scss/pdf-generator-for-wp-common.css', array(), $this->version, 'all' );
	}

	/**
	 * Register the JavaScript for the common side of the site.
	 *
	 * @since    1.0.0
	 */
	public function pgfw_common_enqueue_scripts() {
		if ( ! $this->pgfw_should_enqueue_common_assets() ) {
			return;
		}

		wp_register_script( $this->plugin_name . 'common', PDF_GENERATOR_FOR_WP_DIR_URL . 'common/src/js/pdf-generator-for-wp-common.js', array( 'jquery' ), $this->version, true );
		wp_localize_script(
			$this->plugin_name . 'common',
			'pgfw_common_param',
			array(
				'ajaxurl'            => admin_url( 'admin-ajax.php' ),
				'nonce'              => wp_create_nonce( 'pgfw_common_nonce' ),
				'loader'             => PDF_GENERATOR_FOR_WP_DIR_URL . 'admin/src/images/loader.gif',
				'processing_html'    => '<span style="color:#1e73be;">' . esc_html__( 'Please wait....', 'pdf-generator-for-wp' ) . '</span>',
				'email_submit_error' => '<span style="color:#8e4b86;">' . esc_html__( 'Some unexpected error occurred. Kindly Resubmit again', 'pdf-generator-for-wp' ) . '</span>',
			)
		);
		wp_enqueue_script( $this->plugin_name . 'common' );

		if ( $this->pgfw_should_enqueue_flipbook_assets() ) {
			wp_enqueue_style( $this->plugin_name . '-flipbook', PDF_GENERATOR_FOR_WP_DIR_URL . 'common/src/scss/pdf-generator-for-wp-flipbook.css', array(), $this->version, 'all' );
			wp_enqueue_script( $this->plugin_name . '-flipbook', PDF_GENERATOR_FOR_WP_DIR_URL . 'common/src/js/pdf-generator-for-wp-flipbook.js', array( 'jquery' ), $this->version, true );
			wp_register_script( 'flipbook-bundle', PDF_GENERATOR_FOR_WP_DIR_URL . 'common/src/js/flipbook.bundle.js', array( 'jquery', $this->plugin_name . '-flipbook' ), $this->version, true );
			wp_enqueue_script( 'flipbook-bundle' );
		}
	}
	/**
	 * Catching link for pdf generation user.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function pgfw_generate_pdf_link_catching_user() {
		$display_setings_arr = $this->pgfw_get_display_settings();
		$user_access_pdf     = array_key_exists( 'pgfw_user_access', $display_setings_arr ) ? $display_setings_arr['pgfw_user_access'] : '';
		$guest_access_pdf    = array_key_exists( 'pgfw_guest_access', $display_setings_arr ) ? $display_setings_arr['pgfw_guest_access'] : '';
		if ( isset( $_GET['action'] ) ) { // phpcs:ignore
			$prod_id = array_key_exists( 'id', $_GET ) ? sanitize_text_field( wp_unslash( $_GET['id'] ) ) : ''; // phpcs:ignore
			if ( ( 'genpdf' === $_GET['action'] ) && ( $prod_id ) ) { // phpcs:ignore
				if ( ( 'yes' === $guest_access_pdf ) && ( 'yes' === $user_access_pdf ) ) {
					$this->pgfw_generate_pdf( $prod_id );
				} elseif ( ( 'yes' === $guest_access_pdf ) && ! is_user_logged_in() ) {
					$this->pgfw_generate_pdf( $prod_id );
				} elseif ( ( 'yes' === $user_access_pdf ) && is_user_logged_in() ) {
					$this->pgfw_generate_pdf( $prod_id );
				}
			}
		}
	}
	/**
	 * This will generate pdf from the inputted html and data.
	 *
	 * @param int $prod_id post id.
	 * @since 1.0.0
	 *
	 * @return void
	 */
	public function pgfw_generate_pdf( $prod_id ) {
		$general_settings_arr = $this->pgfw_get_general_settings();
		$pgfw_generate_mode   = array_key_exists( 'pgfw_general_pdf_generate_mode', $general_settings_arr ) ? $general_settings_arr['pgfw_general_pdf_generate_mode'] : 'download_locally';
		$this->pgfw_generate_pdf_from_library( $prod_id, $pgfw_generate_mode );
	}
	/**
	 * Email single PDF.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function wps_pgfw_generate_pdf_single_and_mail() {
		check_ajax_referer( 'pgfw_common_nonce', 'nonce' );
		$email   = array_key_exists( 'email', $_POST ) ? sanitize_text_field( wp_unslash( $_POST['email'] ) ) : '';
		$post_id = array_key_exists( 'post_id', $_POST ) ? sanitize_text_field( wp_unslash( $_POST['post_id'] ) ) : '';
		if ( 'use_account_email' === $email ) {
			$current_user = wp_get_current_user();
			$email        = $current_user->user_email;
		}
		if ( ! is_email( $email ) ) {
			$color   = 'color:#8e4b86;';
			$message = __( 'Please Enter Valid Email Address to Receive Attachment.', 'pdf-generator-for-wp' );
			require_once PDF_GENERATOR_FOR_WP_DIR_PATH . 'common/templates/pdf-generator-for-wp-common-email-notice-template.php';
		} else {
			$this->pgfw_generate_pdf_from_library( $post_id, 'upload_on_server_and_mail', '', $email );
			$color   = 'color:green;';
			$message = __( 'Email Submitted Successfully.', 'pdf-generator-for-wp' );
			require_once PDF_GENERATOR_FOR_WP_DIR_PATH . 'common/templates/pdf-generator-for-wp-common-email-notice-template.php';
		}
		wp_die();
	}
	/**
	 * Generating pdf using dompdf library.
	 *
	 * @since 1.0.0
	 * @param array  $prod_id product id.
	 * @param string $pgfw_generate_mode mode to generate pdf : download_locally, open_window, upload_on_server.
	 * @param string $mode mode to update either zip or continuation.
	 * @param string $email email to send attachment.
	 * @param string $template template to use for pdf generation in case of preview.
	 * @param string $template_name template name to preview for.
	 * @return string
	 */
	public function pgfw_generate_pdf_from_library( $prod_id, $pgfw_generate_mode, $mode = '', $email = '', $template = '', $template_name = '' ) {
		require_once PDF_GENERATOR_FOR_WP_DIR_PATH . 'package/lib/dompdf/vendor/autoload.php';

		$pgfw_meta_settings = wps_pgfw_get_option_cached( 'pgfw_meta_fields_save_settings', array() );
		 // unknow image file handler.
		$pgfw_meta_fields_show_unknown_image_format = array_key_exists( 'pgfw_meta_fields_show_unknown_image_format', $pgfw_meta_settings ) ? $pgfw_meta_settings['pgfw_meta_fields_show_unknown_image_format'] : '';
		// footer .
		$pgfw_footer_settings   = wps_pgfw_get_option_cached( 'pgfw_footer_setting_submit', array() );
		$pgfw_general_pdf_show_pageno = array_key_exists( 'pgfw_general_pdf_show_pageno', $pgfw_footer_settings ) ? $pgfw_footer_settings['pgfw_general_pdf_show_pageno'] : '';
		$pgfw_pageno_position_left    = array_key_exists( 'pgfw_pageno_position_left', $pgfw_footer_settings ) ? $pgfw_footer_settings['pgfw_pageno_position_left'] : '';
		$pgfw_pageno_position_top    = array_key_exists( 'pgfw_pageno_position_top', $pgfw_footer_settings ) ? $pgfw_footer_settings['pgfw_pageno_position_top'] : '';

		// end footer .
		$body_settings_arr       = wps_pgfw_get_option_cached( 'pgfw_body_save_settings', array() );
		$pgfw_body_custom_page_size_height        = array_key_exists( 'pgfw_body_custom_page_size_height', $body_settings_arr ) ? $body_settings_arr['pgfw_body_custom_page_size_height'] : '';
		$pgfw_body_custom_page_size_width        = array_key_exists( 'pgfw_body_custom_page_size_width', $body_settings_arr ) ? $body_settings_arr['pgfw_body_custom_page_size_width'] : '';
		$pgfw_body_page_template = array_key_exists( 'pgfw_body_page_template', $body_settings_arr ) ? $body_settings_arr['pgfw_body_page_template'] : 'template1';
		$pgfw_body_post_template = array_key_exists( 'pgfw_body_post_template', $body_settings_arr ) ? $body_settings_arr['pgfw_body_post_template'] : 'template1';
		$pgfw_body_spcl_char_support = array_key_exists( 'pgfw_body_spcl_char_support', $body_settings_arr ) ? $body_settings_arr['pgfw_body_spcl_char_support'] : '';
		$post_id                 = is_array( $prod_id ) ? $prod_id[0] : $prod_id;
		if ( 'preview' === $pgfw_generate_mode ) {
			require_once $template;
		} elseif ( 'page' === get_post_type( $post_id ) ) {
				$template_file_name = PDF_GENERATOR_FOR_WP_DIR_PATH . 'admin/partials/pdf_templates/pdf-generator-for-wp-admin-' . $pgfw_body_page_template . '.php';
				$template_file_name = apply_filters( 'pgfw_load_templates_for_pdf_html', $template_file_name, $pgfw_body_page_template, $post_id );
				require_once $template_file_name;
		} else {
			$template_file_name = PDF_GENERATOR_FOR_WP_DIR_PATH . 'admin/partials/pdf_templates/pdf-generator-for-wp-admin-' . $pgfw_body_post_template . '.php';
			$template_file_name = apply_filters( 'pgfw_load_templates_for_pdf_html', $template_file_name, $pgfw_body_post_template, $post_id );
			require_once $template_file_name;
		}
		$general_settings_arr = $this->pgfw_get_general_settings();
		$pdf_file_name        = array_key_exists( 'pgfw_general_pdf_file_name', $general_settings_arr ) ? $general_settings_arr['pgfw_general_pdf_file_name'] : 'post_name';
		$body_add_watermark   = array_key_exists( 'pgfw_body_add_watermark', $body_settings_arr ) ? $body_settings_arr['pgfw_body_add_watermark'] : '#000000';
		$body_watermark_color = array_key_exists( 'pgfw_body_watermark_color', $body_settings_arr ) ? $body_settings_arr['pgfw_body_watermark_color'] : '';
		$body_watermark_text  = array_key_exists( 'pgfw_body_watermark_text', $body_settings_arr ) ? $body_settings_arr['pgfw_body_watermark_text'] : '';
		$body_page_size       = array_key_exists( 'pgfw_body_page_size', $body_settings_arr ) ? $body_settings_arr['pgfw_body_page_size'] : 'a4';
		$page_orientation     = array_key_exists( 'pgfw_body_page_orientation', $body_settings_arr ) ? $body_settings_arr['pgfw_body_page_orientation'] : 'portrait';
		$document_name        = '';
		$post                 = get_post( $post_id );
		if ( 'custom' === $pdf_file_name ) {
			$pdf_file_name_custom = array_key_exists( 'pgfw_custom_pdf_file_name', $general_settings_arr ) ? $general_settings_arr['pgfw_custom_pdf_file_name'] : '';
			$document_name        = ( ( '' !== $pdf_file_name_custom ) && ( $post ) ) ? $pdf_file_name_custom . '_' . $post->ID : 'document';
		} elseif ( 'post_name' === $pdf_file_name ) {
			$document_name = ( $post ) ? wp_strip_all_tags( $post->post_title ) : 'document';
		} else {
			$document_name = ( $post ) ? 'document_' . $post->ID : 'document';
		}
		if ( 'continuous_on_same_page' === $mode ) {
			$html = '';
			$html = apply_filters( 'wps_pgfw_add_cover_page_template_to_bulk_pdf', $html );
			foreach ( $prod_id as $id ) {
				$html .= return_ob_html( $id );
			}
		} else {
			$html  = '';
			$html  = apply_filters( 'wps_pgfw_add_cover_page_template_to_single_pdf', $html );
			$html .= return_ob_html( $prod_id, $template_name );
		}
		$html        = str_replace( '[WORDPRESS_PDF]', '', $html );
		$paper_sizes = array(
			'4a0'                      => array( 0, 0, 4767.87, 6740.79 ),
			'2a0'                      => array( 0, 0, 3370.39, 4767.87 ),
			'a0'                       => array( 0, 0, 2383.94, 3370.39 ),
			'a1'                       => array( 0, 0, 1683.78, 2383.94 ),
			'a2'                       => array( 0, 0, 1190.55, 1683.78 ),
			'a3'                       => array( 0, 0, 841.89, 1190.55 ),
			'a4'                       => array( 0, 0, 595.28, 841.89 ),
			'a5'                       => array( 0, 0, 419.53, 595.28 ),
			'a6'                       => array( 0, 0, 297.64, 419.53 ),
			'b0'                       => array( 0, 0, 2834.65, 4008.19 ),
			'b1'                       => array( 0, 0, 2004.09, 2834.65 ),
			'b2'                       => array( 0, 0, 1417.32, 2004.09 ),
			'b3'                       => array( 0, 0, 1000.63, 1417.32 ),
			'b4'                       => array( 0, 0, 708.66, 1000.63 ),
			'b5'                       => array( 0, 0, 498.90, 708.66 ),
			'b6'                       => array( 0, 0, 354.33, 498.90 ),
			'c0'                       => array( 0, 0, 2599.37, 3676.54 ),
			'c1'                       => array( 0, 0, 1836.85, 2599.37 ),
			'c2'                       => array( 0, 0, 1298.27, 1836.85 ),
			'c3'                       => array( 0, 0, 918.43, 1298.27 ),
			'c4'                       => array( 0, 0, 649.13, 918.43 ),
			'c5'                       => array( 0, 0, 459.21, 649.13 ),
			'c6'                       => array( 0, 0, 323.15, 459.21 ),
			'ra0'                      => array( 0, 0, 2437.80, 3458.27 ),
			'ra1'                      => array( 0, 0, 1729.13, 2437.80 ),
			'ra2'                      => array( 0, 0, 1218.90, 1729.13 ),
			'ra3'                      => array( 0, 0, 864.57, 1218.90 ),
			'ra4'                      => array( 0, 0, 609.45, 864.57 ),
			'sra0'                     => array( 0, 0, 2551.18, 3628.35 ),
			'sra1'                     => array( 0, 0, 1814.17, 2551.18 ),
			'sra2'                     => array( 0, 0, 1275.59, 1814.17 ),
			'sra3'                     => array( 0, 0, 907.09, 1275.59 ),
			'sra4'                     => array( 0, 0, 637.80, 907.09 ),
			'letter'                   => array( 0, 0, 612.00, 792.00 ),
			'legal'                    => array( 0, 0, 612.00, 1008.00 ),
			'ledger'                   => array( 0, 0, 1224.00, 792.00 ),
			'tabloid'                  => array( 0, 0, 792.00, 1224.00 ),
			'executive'                => array( 0, 0, 521.86, 756.00 ),
			'folio'                    => array( 0, 0, 612.00, 936.00 ),
			'commercial #10 envelope'  => array( 0, 0, 684, 297 ),
			'catalog #10 1/2 envelope' => array( 0, 0, 648, 864 ),
			'8.5x11'                   => array( 0, 0, 612.00, 792.00 ),
			'8.5x14'                   => array( 0, 0, 612.00, 1008.0 ),
			'11x17'                    => array( 0, 0, 792.00, 1224.00 ),
		);

		$upload_dir     = wp_upload_dir();
		$html = mb_convert_encoding( $html, 'HTML-ENTITIES', 'UTF-8' );
			// Webp Image Start Fixes ///////////////////////////////////////////////////////////
			// Load HTML content into DOMDocument.
			$dom = new DOMDocument();
			libxml_use_internal_errors( true );
			$dom->loadHTML( $html );
			libxml_clear_errors();

			// Find all img tags.
			$imgs = $dom->getElementsByTagName( 'img' );

			// Loop through each img tag and modify the src attribute.
		foreach ( $imgs as $img ) {

			// Get the current src attribute value.
			$src = $img->getAttribute( 'src' );

			if ( isset( $src ) && ! empty( $src ) && pathinfo( $src, PATHINFO_EXTENSION ) === 'webp' ) {
				$src = str_replace( $upload_dir['baseurl'], $upload_dir['basedir'], $src );

				// Path to the WebP image.
				$webp_image_path = $src;

				// Create image resource from WebP image.
				$webp_image = imagecreatefromwebp( $webp_image_path );

				$parts = explode( '.', $src );

				// Modify the content after the dot.
				$extension = end( $parts );
				$new_extension = 'jpeg';

				$new_src = str_replace( '.' . $extension, '.' . $new_extension, $src );
				// Path to save JPEG image.
				$jpeg_image_path = $new_src;

				// Save JPEG image with 100% quality.
				imagejpeg( $webp_image, $jpeg_image_path, 100 );
				$img_url = str_replace( $upload_dir['basedir'], $upload_dir['baseurl'], $jpeg_image_path );
				$html = '<img src="' . $img_url . '" alt="Converted Image">';

				// Free up memory.
				imagedestroy( $webp_image );
				$img->setAttribute( 'src', $img_url );
			}
		}

			// Get the updated HTML content.
			$updated_html = $dom->saveHTML();

			// Output the updated HTML content.
			$html = $updated_html;
			// Webp Image End Fixes.

			$html .= '<style>
				.wps-no-print {
					display: none !important;
				}
			</style>';

		if ( 'custom_page' == $body_page_size && ! empty( $pgfw_body_custom_page_size_width ) && ! empty( $pgfw_body_custom_page_size_height ) ) {
			$paper_size = array( 0, 0, $pgfw_body_custom_page_size_width * 2.834, $pgfw_body_custom_page_size_height * 2.834 );
		} else {
			$paper_size = array_key_exists( $body_page_size, $paper_sizes ) ? $paper_sizes[ $body_page_size ] : 'a4';
		}
		if ( 'yes' == $pgfw_meta_fields_show_unknown_image_format ) {
			$options = new Options();
			$options->set( 'isRemoteEnabled', true );
			$options->set( 'isHtml5ParserEnabled', true );
			$dompdf = new Dompdf( $options );

			$contxt = stream_context_create(
				array(
					'ssl' => array(
						'verify_peer' => false,
						'verify_peer_name' => false,
						'allow_self_signed' => true,
					),
				)
			);

			$dompdf->setHttpContext( $contxt );
		} else {
			$options = new Options();
			$options->set( 'isRemoteEnabled', true );
			$dompdf = new Dompdf( $options );

			$contxt = stream_context_create(
				array(
					'http' => array(
						'header'     => "Content-type: application/x-www-form-urlencoded\r\n",
						'method'     => 'GET',
						'user_agent' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
					),
					'ssl' => array(
						'verify_peer'       => false,
						'verify_peer_name'  => false,
						'allow_self_signed' => true,
					),
				)
			);

			$dompdf->setHttpContext( $contxt );
		}
		//Relative Link to Absolute link.
		$site_url = trailingslashit( get_site_url() );
		$dompdf->setBasePath( $site_url );
		$html = preg_replace(
			'/(href|src)=\"\/(?!\/)/i',
			'$1="' . $site_url,
			$html
		);
		$dompdf->loadHtml( $html, 'UTF-8' );
		$dompdf->set_option( 'isRemoteEnabled', true );

		/* addedcode end */

		$dompdf->setPaper( $paper_size, $page_orientation );

		@ob_end_clean(); // phpcs:ignore
		$dompdf->render();
		if ( 'yes' === $body_add_watermark ) {
			$options = new Options();
			$options->set( 'isPhpEnabled', 'true' );
			$canvas       = $dompdf->getCanvas();
			$fontmetrices = new FontMetrics( $canvas, $options );
			$w            = $canvas->get_width();
			$h            = $canvas->get_height();
			$font         = $fontmetrices->getFont( 'times' );
			$text         = $body_watermark_text;
			$textheight   = $fontmetrices->getFontHeight( $font, 150 );
			$textwidth    = $fontmetrices->getTextWidth( $text, $font, 40 );
			$x               = ( ( $w - $textwidth ) / 2 );
			$y               = ( ( $h - $textheight ) / 2 );
			$hex             = $body_watermark_color;
			list($r, $g, $b) = sscanf( $hex, '#%02x%02x%02x' );

		}

		if ( 'yes' == $pgfw_general_pdf_show_pageno ) {
			$canvas       = $dompdf->getCanvas();
			if ( ! empty( $pgfw_pageno_position_left ) && ! empty( $pgfw_pageno_position_top ) ) {
				$canvas->page_text( $pgfw_pageno_position_left, $pgfw_pageno_position_top, '{PAGE_NUM}/{PAGE_COUNT}', $font, 8, array( 0, 0, 0 ) );
			} else {
				$canvas->page_text( 100, 100, '{PAGE_NUM}/{PAGE_COUNT}', $font, 8, array( 0, 0, 0 ) );
			}
		}
		$upload_dir     = wp_upload_dir();
		$upload_basedir = $upload_dir['basedir'] . '/post_to_pdf/';
		if ( ! file_exists( $upload_basedir ) ) {
			wp_mkdir_p( $upload_basedir );
		}
		$current_user = wp_get_current_user();
		$user_name    = ( $current_user && $current_user->exists() && $current_user->display_name ) ? $current_user->display_name : __( 'Guest', 'pdf-generator-for-wp' );
		$user_id      = ( $current_user && $current_user->exists() ) ? $current_user->ID : 0;
		$email        = ( '' !== $email ) ? $email : ( ( $current_user && $current_user->exists() ) ? $current_user->user_email : '' );
		$client_ip    = $this->pgfw_get_client_ip();
		$output       = $dompdf->output();

		$log_context = array(
			'pdf_type'     => is_array( $prod_id ) ? 'bulk' : 'single',
			'context'      => $pgfw_generate_mode,
			'file_name'    => $document_name,
			'source'       => is_admin() ? 'admin' : 'frontend',
			'user_name'    => $user_name,
			'user_id'      => $user_id,
			'user_email'   => $email,
			'ip_address'   => $client_ip,
			'geo_location' => '',
			'geo_city'     => '',
			'geo_region'   => '',
			'geo_country'  => '',
			'open_counts'  => array(),
			'user_open_counts' => array(),
		);
		$log_download = function() use ( $prod_id, $user_name, $email, $log_context ) {
			$log_context['ip_address']   = $log_context['ip_address'] ? $log_context['ip_address'] : $this->pgfw_get_client_ip();
			$geo_details                 = $this->pgfw_get_geo_location_from_ip( $log_context['ip_address'], true );
			$log_context['geo_location'] = isset( $geo_details['label'] ) ? $geo_details['label'] : '';
			$log_context['geo_city']     = isset( $geo_details['city'] ) ? $geo_details['city'] : '';
			$log_context['geo_region']   = isset( $geo_details['region'] ) ? $geo_details['region'] : '';
			$log_context['geo_country']  = isset( $geo_details['country'] ) ? $geo_details['country'] : '';
			$log_context['open_counts'] = $this->pgfw_increment_pdf_open_counts( $prod_id );
			$log_context['user_open_counts'] = $this->pgfw_get_user_pdf_open_counts( $prod_id );
			$this->pgfw_record_pdf_open_event( $prod_id, $log_context );
			do_action( 'wps_pgfw_update_pdf_details_indb', $prod_id, $user_name, $email, $log_context );
		};

		if ( 'download_locally' === $pgfw_generate_mode ) {
			$path = $upload_basedir . $document_name . '.pdf';
			$log_download();
			$dompdf->stream(
				$document_name . '.pdf',
				array(
					'Attachment' => 1,
				)
			);
		} elseif ( 'open_window' === $pgfw_generate_mode ) {
			$path = $upload_basedir . $document_name . '.pdf';
					@ob_end_clean(); // phpcs:ignore
			$log_download();
			$dompdf->stream(
				$document_name . '.pdf',
				array(
					'compress'   => 0,
					'Attachment' => 0,
				)
			);
		} elseif ( 'upload_on_server_and_mail' === $pgfw_generate_mode ) {
			$output = $dompdf->output();
			$path   = $upload_basedir . $document_name . '.pdf';
			if ( file_exists( $path ) ) {
				@unlink( $path ); // phpcs:ignore
			}
			@file_put_contents( $path, $output ); // phpcs:ignore
			$log_download();
			$file_url   = $upload_dir['baseurl'] . '/post_to_pdf/' . rawurlencode( $document_name ) . '.pdf';
			$email_body = sprintf(
				/* translators: %s: pdf link */
				__( 'Please find the PDF attached. You can also view it here: %s', 'pdf-generator-for-wp' ),
				$file_url
			);
			$email_body = apply_filters( 'pgfw_pdf_email_body_with_link', $email_body, $file_url, $prod_id, $document_name );
			wp_mail( $email, __( 'document form site', 'pdf-generator-for-wp' ), $email_body, '', array( $path ) );
		} elseif ( 'bulk' === $pgfw_generate_mode ) {
			if ( 'continuous_on_same_page' === $mode ) {
				$document_name = 'bulk_post_to_pdf_' . strtotime( gmdate( 'y-m-d H:i:s' ) );
				$path          = $upload_basedir . $document_name . '.pdf';
			} elseif ( 'bulk_zip' === $mode ) {
				$path = $upload_basedir . $document_name . '.pdf';
			}
			if ( ! file_exists( $path ) ) {
				@file_put_contents( $path, $output ); // phpcs:ignore
			}
			$log_download();
			return $document_name;
		} elseif ( 'preview' === $pgfw_generate_mode ) {
			@ob_end_clean(); // phpcs:ignore.
			$dompdf->stream(
				$document_name . '.pdf',
				array(
					'compress'   => 0,
					'Attachment' => 0,
				)
			);
			return;
		}
	}

	/**
	 * Get client ip address considering forwarded headers.
	 *
	 * @since 1.0.0
	 * @return string
	 */
	private function pgfw_get_client_ip() {
		$ip_keys = array( 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR' );
		foreach ( $ip_keys as $key ) {
			if ( empty( $_SERVER[ $key ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.
				continue;
			}
			$server_ip_value = sanitize_text_field( wp_unslash( $_SERVER[ $key ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.
			$ip_list         = explode( ',', $server_ip_value );
			$ip              = trim( $ip_list[0] );
			if ( filter_var( $ip, FILTER_VALIDATE_IP ) ) {
				return $ip;
			}
		}
		return '';
	}

	/**
	 * Resolve geo location of the given ip.
	 *
	 * @since 1.0.0
	 * @param string $ip Client ip address.
	 * @param bool   $return_parts Whether to return array with parts instead of label.
	 * @return string|array
	 */
	private function pgfw_get_geo_location_from_ip( $ip, $return_parts = false ) {
		$unknown_label = __( 'Unknown', 'pdf-generator-for-wp' );
		$unknown_data  = array(
			'label'        => $unknown_label,
			'city'         => '',
			'region'       => '',
			'country'      => '',
			'country_code' => '',
		);

		if ( empty( $ip ) || '127.0.0.1' === $ip || '::1' === $ip ) {
			return $return_parts ? $unknown_data : $unknown_label;
		}

		$cache_key = 'pgfw_geo_' . md5( $ip );
		$cached    = get_transient( $cache_key );
		if ( false !== $cached ) {
			if ( is_array( $cached ) ) {
				return $return_parts ? $cached : ( isset( $cached['label'] ) ? $cached['label'] : $unknown_label );
			}
			return $return_parts ? array_merge( $unknown_data, array( 'label' => $cached ) ) : $cached; // backward compatibility.
		}

		$response = wp_remote_get( 'https://ipapi.co/' . rawurlencode( $ip ) . '/json/' );
		if ( is_wp_error( $response ) ) {
			return $return_parts ? $unknown_data : $unknown_label;
		}

		$body = json_decode( wp_remote_retrieve_body( $response ), true );
		if ( ! is_array( $body ) ) {
			return $return_parts ? $unknown_data : $unknown_label;
		}

		$geo_data = array(
			'city'         => isset( $body['city'] ) ? $body['city'] : '',
			'region'       => isset( $body['region'] ) ? $body['region'] : '',
			'country'      => isset( $body['country_name'] ) ? $body['country_name'] : ( isset( $body['country'] ) ? $body['country'] : '' ),
			'country_code' => isset( $body['country'] ) ? $body['country'] : '',
		);

		$parts           = array_filter( array( $geo_data['city'], $geo_data['region'], $geo_data['country'] ) );
		$geo_data['label'] = ! empty( $parts ) ? implode( ', ', $parts ) : $unknown_label;

		set_transient( $cache_key, $geo_data, DAY_IN_SECONDS );

		return $return_parts ? $geo_data : $geo_data['label'];
	}

	/**
	 * Increment the pdf open count for a single post or bulk posts.
	 *
	 * @since 1.0.0
	 * @param int|array $prod_id Post id or array of ids.
	 * @return array
	 */
	private function pgfw_increment_pdf_open_counts( $prod_id ) {
		$post_ids    = is_array( $prod_id ) ? $prod_id : array( $prod_id );
		$open_counts = array();

		foreach ( $post_ids as $post_id ) {
			$post_id = absint( $post_id );
			if ( ! $post_id ) {
				continue;
			}

			$current_count = (int) get_post_meta( $post_id, '_pgfw_pdf_open_count', true );
			$current_count++;
			update_post_meta( $post_id, '_pgfw_pdf_open_count', $current_count );
			$open_counts[ $post_id ] = $current_count;

			if ( is_user_logged_in() ) {
				$current_user_id = get_current_user_id();
				if ( $current_user_id ) {
					$user_counts = get_user_meta( $current_user_id, '_pgfw_pdf_open_counts', true );
					if ( ! is_array( $user_counts ) ) {
						$user_counts = array();
					}
					$user_counts[ $post_id ] = isset( $user_counts[ $post_id ] ) ? ( (int) $user_counts[ $post_id ] + 1 ) : 1;
					update_user_meta( $current_user_id, '_pgfw_pdf_open_counts', $user_counts );
				}
			}
		}

		return $open_counts;
	}

	/**
	 * Fetch per-user pdf open counts for the current user.
	 *
	 * @since 1.0.0
	 * @param int|array $prod_id Post id or array of ids.
	 * @return array
	 */
	private function pgfw_get_user_pdf_open_counts( $prod_id ) {
		$post_ids    = is_array( $prod_id ) ? $prod_id : array( $prod_id );
		$user_counts = array();

		if ( ! is_user_logged_in() ) {
			return $user_counts;
		}

		$current_user_id = get_current_user_id();
		if ( ! $current_user_id ) {
			return $user_counts;
		}

		$saved_counts = get_user_meta( $current_user_id, '_pgfw_pdf_open_counts', true );
		if ( ! is_array( $saved_counts ) ) {
			$saved_counts = array();
		}

		foreach ( $post_ids as $post_id ) {
			$post_id = absint( $post_id );
			if ( ! $post_id ) {
				continue;
			}
			$user_counts[ $post_id ] = isset( $saved_counts[ $post_id ] ) ? (int) $saved_counts[ $post_id ] : 0;
		}

		return $user_counts;
	}

	/**
	 * Store a short log of the latest pdf open event.
	 *
	 * @since 1.0.0
	 * @param int|array $prod_id Post id or array of ids.
	 * @param array     $log_context Context data.
	 * @return void
	 */
	private function pgfw_record_pdf_open_event( $prod_id, $log_context ) {
		$post_ids  = is_array( $prod_id ) ? $prod_id : array( $prod_id );
		$timestamp = current_time( 'mysql' );

		foreach ( $post_ids as $post_id ) {
			$post_id = absint( $post_id );
			if ( ! $post_id ) {
				continue;
			}

			$event_data = array(
				'timestamp'    => $timestamp,
				'user_name'    => isset( $log_context['user_name'] ) ? $log_context['user_name'] : '',
				'user_id'      => isset( $log_context['user_id'] ) ? $log_context['user_id'] : 0,
				'user_email'   => isset( $log_context['user_email'] ) ? $log_context['user_email'] : '',
				'ip_address'   => isset( $log_context['ip_address'] ) ? $log_context['ip_address'] : '',
				'geo_location' => isset( $log_context['geo_location'] ) ? $log_context['geo_location'] : '',
				'geo_city'     => isset( $log_context['geo_city'] ) ? $log_context['geo_city'] : '',
				'geo_region'   => isset( $log_context['geo_region'] ) ? $log_context['geo_region'] : '',
				'geo_country'  => isset( $log_context['geo_country'] ) ? $log_context['geo_country'] : '',
				'source'       => isset( $log_context['source'] ) ? $log_context['source'] : '',
				'context'      => isset( $log_context['context'] ) ? $log_context['context'] : '',
				'pdf_type'     => isset( $log_context['pdf_type'] ) ? $log_context['pdf_type'] : '',
				'open_count'   => isset( $log_context['open_counts'][ $post_id ] ) ? (int) $log_context['open_counts'][ $post_id ] : 0,
				'user_open_count' => ( isset( $log_context['user_open_counts'][ $post_id ] ) ? (int) $log_context['user_open_counts'][ $post_id ] : 0 ),
			);

			update_post_meta( $post_id, '_pgfw_last_pdf_view', $event_data );

			$existing_logs = get_post_meta( $post_id, '_pgfw_pdf_view_logs', true );
			if ( ! is_array( $existing_logs ) ) {
				$existing_logs = array();
			}

			$existing_logs[] = $event_data;
			if ( count( $existing_logs ) > 50 ) {
				$existing_logs = array_slice( $existing_logs, -50 );
			}
			update_post_meta( $post_id, '_pgfw_pdf_view_logs', $existing_logs );
		}
	}
	/**
	 * Download button for posters as shortcode callback.
	 *
	 * @since 1.0.0
	 * @param string $atts attributes for shortcodes for downloading posters.
	 * @return string
	 */
	public function pgfw_download_button_posters( $atts ) {
		$atts = shortcode_atts(
			array(
				'id' => 0,
			),
			$atts
		);

		$pgfw_pdf_upload_settings = get_option( 'pgfw_pdf_upload_save_settings', array() );
		$pgfw_poster_user_access  = array_key_exists( 'pgfw_poster_user_access', $pgfw_pdf_upload_settings ) ? $pgfw_pdf_upload_settings['pgfw_poster_user_access'] : '';
		$pgfw_poster_guest_access = array_key_exists( 'pgfw_poster_guest_access', $pgfw_pdf_upload_settings ) ? $pgfw_pdf_upload_settings['pgfw_poster_guest_access'] : '';
		$_pgfw_poster_uploaded    = array_key_exists( 'sub_pgfw_poster_image_upload', $pgfw_pdf_upload_settings ) ? json_decode( $pgfw_pdf_upload_settings['sub_pgfw_poster_image_upload'], true ) : array();
		$poster_image_url         = get_the_guid( $atts['id'] );
		$doc_type                 = get_post_type( $atts['id'] );
		$html                     = '';
		if ( ! is_array( $_pgfw_poster_uploaded ) || ! in_array( $atts['id'], $_pgfw_poster_uploaded ) ) {
			return;
		}
		if ( ( 'yes' === $pgfw_poster_user_access && is_user_logged_in() ) || ( 'yes' === $pgfw_poster_guest_access && ! is_user_logged_in() ) ) {
			if ( '' !== $poster_image_url && 'attachment' === $doc_type ) {
				require_once PDF_GENERATOR_FOR_WP_DIR_PATH . 'common/templates/pdf-generator-for-wp-common-poster-download-template.php';
				$html = pgfw_poster_download_button_for_shortcode( $poster_image_url );
			}
		}
		return $html;
	}
	/**
	 * Shortcode for link generation of poster download.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function pgfw_poster_download_shortcode() {
		add_shortcode( 'PGFW_DOWNLOAD_POSTER', array( $this, 'pgfw_download_button_posters' ) );
	}
	/**
	 * Export pdf in bulk.
	 */
	public function pgfw_aspose_pdf_exporter_bulk_action() {
		require_once PDF_GENERATOR_FOR_WP_DIR_PATH . 'package/lib/dompdf/vendor/autoload.php';
		$general_settings_arr = get_option( 'pgfw_general_settings_save', array() );
		$pgfw_generate_mode   = array_key_exists( 'pgfw_general_pdf_generate_mode', $general_settings_arr ) ? $general_settings_arr['pgfw_general_pdf_generate_mode'] : 'download_locally';
		$body_settings_arr       = get_option( 'pgfw_body_save_settings', array() );
		$pgfw_body_custom_page_size_height        = array_key_exists( 'pgfw_body_custom_page_size_height', $body_settings_arr ) ? $body_settings_arr['pgfw_body_custom_page_size_height'] : '';
		$pgfw_body_custom_page_size_width        = array_key_exists( 'pgfw_body_custom_page_size_width', $body_settings_arr ) ? $body_settings_arr['pgfw_body_custom_page_size_width'] : '';
		$page_orientation     = array_key_exists( 'pgfw_body_page_orientation', $body_settings_arr ) ? $body_settings_arr['pgfw_body_page_orientation'] : 'portrait';
		$body_page_size       = array_key_exists( 'pgfw_body_page_size', $body_settings_arr ) ? $body_settings_arr['pgfw_body_page_size'] : 'a4';
		$paper_sizes = array(
			'4a0'                      => array( 0, 0, 4767.87, 6740.79 ),
			'2a0'                      => array( 0, 0, 3370.39, 4767.87 ),
			'a0'                       => array( 0, 0, 2383.94, 3370.39 ),
			'a1'                       => array( 0, 0, 1683.78, 2383.94 ),
			'a2'                       => array( 0, 0, 1190.55, 1683.78 ),
			'a3'                       => array( 0, 0, 841.89, 1190.55 ),
			'a4'                       => array( 0, 0, 595.28, 841.89 ),
			'a5'                       => array( 0, 0, 419.53, 595.28 ),
			'a6'                       => array( 0, 0, 297.64, 419.53 ),
			'b0'                       => array( 0, 0, 2834.65, 4008.19 ),
			'b1'                       => array( 0, 0, 2004.09, 2834.65 ),
			'b2'                       => array( 0, 0, 1417.32, 2004.09 ),
			'b3'                       => array( 0, 0, 1000.63, 1417.32 ),
			'b4'                       => array( 0, 0, 708.66, 1000.63 ),
			'b5'                       => array( 0, 0, 498.90, 708.66 ),
			'b6'                       => array( 0, 0, 354.33, 498.90 ),
			'c0'                       => array( 0, 0, 2599.37, 3676.54 ),
			'c1'                       => array( 0, 0, 1836.85, 2599.37 ),
			'c2'                       => array( 0, 0, 1298.27, 1836.85 ),
			'c3'                       => array( 0, 0, 918.43, 1298.27 ),
			'c4'                       => array( 0, 0, 649.13, 918.43 ),
			'c5'                       => array( 0, 0, 459.21, 649.13 ),
			'c6'                       => array( 0, 0, 323.15, 459.21 ),
			'ra0'                      => array( 0, 0, 2437.80, 3458.27 ),
			'ra1'                      => array( 0, 0, 1729.13, 2437.80 ),
			'ra2'                      => array( 0, 0, 1218.90, 1729.13 ),
			'ra3'                      => array( 0, 0, 864.57, 1218.90 ),
			'ra4'                      => array( 0, 0, 609.45, 864.57 ),
			'sra0'                     => array( 0, 0, 2551.18, 3628.35 ),
			'sra1'                     => array( 0, 0, 1814.17, 2551.18 ),
			'sra2'                     => array( 0, 0, 1275.59, 1814.17 ),
			'sra3'                     => array( 0, 0, 907.09, 1275.59 ),
			'sra4'                     => array( 0, 0, 637.80, 907.09 ),
			'letter'                   => array( 0, 0, 612.00, 792.00 ),
			'legal'                    => array( 0, 0, 612.00, 1008.00 ),
			'ledger'                   => array( 0, 0, 1224.00, 792.00 ),
			'tabloid'                  => array( 0, 0, 792.00, 1224.00 ),
			'executive'                => array( 0, 0, 521.86, 756.00 ),
			'folio'                    => array( 0, 0, 612.00, 936.00 ),
			'commercial #10 envelope'  => array( 0, 0, 684, 297 ),
			'catalog #10 1/2 envelope' => array( 0, 0, 648, 864 ),
			'8.5x11'                   => array( 0, 0, 612.00, 792.00 ),
			'8.5x14'                   => array( 0, 0, 612.00, 1008.0 ),
			'11x17'                    => array( 0, 0, 792.00, 1224.00 ),
		);
		if ( 'custom_page' == $body_page_size && ! empty( $pgfw_body_custom_page_size_width ) && ! empty( $pgfw_body_custom_page_size_height ) ) {
			$paper_size = array( 0, 0, $pgfw_body_custom_page_size_width * 2.834, $pgfw_body_custom_page_size_height * 2.834 );
		} else {
			$paper_size = array_key_exists( $body_page_size, $paper_sizes ) ? $paper_sizes[ $body_page_size ] : 'a4';
		}
		$upload_dir = wp_upload_dir();
		$upload_path = $upload_dir['path'] . '/';

		$html_file = $upload_path . 'outpuut.html';
		$pdf_file = $upload_path . 'outpuut.pdf';

		global $typenow;
		$post_type = $typenow;

		// get the action.
		$wp_list_table = _get_list_table( 'WP_Posts_List_Table' );  // depending on your resource type this could be WP_Users_List_Table, WP_Comments_List_Table, etc.
		$action = $wp_list_table->current_action();

		$allowed_actions = array( 'export' );

		if ( ! in_array( $action, $allowed_actions ) ) {
			return;
		}

		// security check.
		check_admin_referer( 'bulk-posts' );

		// make sure ids are submitted.  depending on the resource type, this may be 'media' or 'ids'.
		if ( isset( $_REQUEST['post'] ) ) {
			$post_ids = array_map( 'intval', $_REQUEST['post'] );
		}

		if ( empty( $post_ids ) ) {
			return;
		}

		// this is based on wp-admin/edit.php.
		$sendback = remove_query_arg( array( 'exported', 'untrashed', 'deleted', 'ids' ), wp_get_referer() );

		if ( ! $sendback ) {
			$sendback = admin_url( "edit.php?post_type=$post_type" );
		}

		$pagenum = $wp_list_table->get_pagenum();

		$sendback = add_query_arg( 'paged', $pagenum, $sendback );

		switch ( $action ) {
			case 'export':
				$exported = count( $post_ids );
				$file_name = '';
				if ( is_array( $post_ids ) && count( $post_ids ) > 0 ) {
					$file_name1 = $this->pgfw_aspose_pdf_exporter_array_to_html( $post_ids );
					$template_name = apply_filters( 'wps_pgfw_product_post_ids_in_pdf_filter_hook', $file_name1, $post_ids );
					if ( 'template1' == $template_name ) {
						$file_name .= apply_filters( 'wps_pgfw_add_cover_page_template_to_bulk_pdf', $html );
						$file_name .= $this->pgfw_aspose_pdf_exporter_array_to_html( $post_ids );
					} else {
						$file_name .= apply_filters( 'wps_pgfw_add_cover_page_template_to_bulk_pdf', $html );
						$file_name .= apply_filters( 'wps_pgfw_product_post_ids_in_pdf_filter_hook', $file_name1, $post_ids );
					}
					header( 'Content-Type: application/pdf' );
					$options = new Options();
					$options->set( 'isRemoteEnabled', true );
					$dompdf = new Dompdf( $options );
					$contxt = stream_context_create(
						array(
							'http' => array(
								'header'     => "Content-type: application/x-www-form-urlencoded\r\n",
								'method'     => 'GET',
								'user_agent' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
							),
							'ssl' => array(
								'verify_peer'       => false,
								'verify_peer_name'  => false,
								'allow_self_signed' => true,
							),
						)
					);
					$dompdf->setHttpContext( $contxt );
					$dompdf->loadHtml( $file_name );
					$dompdf->set_option( 'isRemoteEnabled', true );
					$dompdf->setPaper( $paper_size, $page_orientation );
					/* addedcode end */
					$document_name = 'bulk_post_to_pdf_' . strtotime( gmdate( 'y-m-d H:i:s' ) );
					@ob_end_clean(); // phpcs:ignore.
					$dompdf->render();
					if ( 'download_locally' === $pgfw_generate_mode ) {
						@ob_end_clean(); // phpcs:ignore.
						$dompdf->stream(
							$document_name . '.pdf',
							array(
								'compress'   => 0,
								'Attachment' => 1,
							)
						);
					} elseif ( 'open_window' === $pgfw_generate_mode ) {

								@ob_end_clean(); // phpcs:ignore
						$dompdf->stream(
							$document_name . '.pdf',
							array(
								'compress'   => 0,
								'Attachment' => 0,
							)
						);
					}
				}
		}
	}
	/**
	 * Bulk export button for posts.
	 *
	 * @param string $bulk_actions $bulk_actions.
	 */
	public function wpg_add_custom_bulk_action_post( $bulk_actions ) {
		$bulk_actions['export'] = __( 'Export', 'pdf-generator-for-wp' );
		return $bulk_actions;
	}
	/**
	 * Bulk export button for pages.
	 *
	 * @param string $bulk_actions $bulk_actions.
	 */
	public function wpg_add_custom_bulk_actions_page( $bulk_actions ) {
		$bulk_actions['export'] = __( 'Export', 'pdf-generator-for-wp' );
		return $bulk_actions;
	}
	/**
	 * Bulk export button for products.
	 *
	 * @param string $bulk_actions $bulk_actions.
	 */
	public function wpg_add_custom_bulk_actionss_product( $bulk_actions ) {
		$bulk_actions['export'] = __( 'Export', 'pdf-generator-for-wp' );
		return $bulk_actions;
	}
	/**
	 * Getting template data for post ids.
	 *
	 * @param array $post_ids postids.
	 */
	public function pgfw_aspose_pdf_exporter_array_to_html( $post_ids ) {

		$ids = $post_ids;
		$body_settings_arr       = get_option( 'pgfw_body_save_settings', array() );
		$pgfw_body_page_template = array_key_exists( 'pgfw_body_page_template', $body_settings_arr ) ? $body_settings_arr['pgfw_body_page_template'] : 'template1';
		$pgfw_body_post_template = array_key_exists( 'pgfw_body_post_template', $body_settings_arr ) ? $body_settings_arr['pgfw_body_post_template'] : 'template1';
		$template_file_name = PDF_GENERATOR_FOR_WP_DIR_PATH . 'common/templates/bulk-pdf-template.php';
		require_once $template_file_name;
		return bulk_pdf_exporter_html( $ids );
	}
	// invoice .

	/**
	 * Reset invoice number.
	 *
	 * @since 1.0.1
	 * @return void
	 */
	public function wpg_reset_invoice_number() {
		$month = get_option( 'wpg_invoice_number_renew_month' );
		$date  = get_option( 'wpg_invoice_number_renew_date' );
		if ( '' !== $month && 'never' !== $month ) {
			if ( ( (int) current_time( 'm' ) === (int) $month ) && ( (int) current_time( 'd' ) === (int) $date ) ) {
				update_option( 'wpg_current_invoice_id', 0 );
			}
		}
	}
	/**
	 * Generate Invoice Number.
	 *
	 * @param int $order_id order ID to generate invoice number for.
	 * @since 1.0.0
	 * @return string
	 */
	public function wpg_invoice_number( $order_id ) {
		$digit  = get_option( 'wpg_invoice_number_digit' );
		$prefix = get_option( 'wpg_invoice_number_prefix' );
		$suffix = get_option( 'wpg_invoice_number_suffix' );
		$digit  = ( $digit ) ? $digit : 4;
		$order = wc_get_order( $order_id );
		// get_post_meta.
		if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
			// HPOS usage is enabled.
			$in_id = $order->get_meta( 'wpg_order_invoice_id', true );
		} else {
			$in_id  = get_post_meta( $order_id, 'wpg_order_invoice_id', true );
		}
		if ( $in_id ) {
			$invoice_id = $in_id;
		} else {
			$prev_invoice_id = get_option( 'wpg_current_invoice_id' );
			if ( $prev_invoice_id ) {
				$curr_invoice_id = $prev_invoice_id + 1;
			} else {
				$curr_invoice_id = 1;
			}
			update_option( 'wpg_current_invoice_id', $curr_invoice_id );
			$invoice_number = str_pad( $curr_invoice_id, $digit, '0', STR_PAD_LEFT );
			$invoice_id     = $prefix . $invoice_number . $suffix;

			// update_post_meta.
			if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
				// HPOS usage is enabled.
				$order->update_meta_data( 'wpg_order_invoice_id', $invoice_id );
				$order->save();

			} else {
				update_post_meta( $order_id, 'wpg_order_invoice_id', $invoice_id );
			}
		}
		return $invoice_id;
	}
	/**
	 * Invoice name for the file to be stored or downloaded.
	 *
	 * @param string $type invoice or packing slip.
	 * @param int    $order_id order id to generate invoice for.
	 * @return string
	 */
	public function wpg_invoice_name_for_file( $type, $order_id ) {
		$invoice_name_option = get_option( 'wps_wpg_invoice_name' );
		$invoice_id          = $this->wpg_invoice_number( $order_id );
		if ( 'invoice' === $type ) {
			if ( 'custom' === $invoice_name_option ) {
				$custom_invoice_name = get_option( 'wps_wpg_custom_invoice_name' );
				$invoice_name        = $custom_invoice_name . '_' . $order_id;
			} elseif ( 'invoice_orderid' === $invoice_name_option ) {
				$invoice_name = 'invoice_' . $order_id;
			} elseif ( 'invoice_id' === $invoice_name_option ) {
				$invoice_name = $invoice_id;
			} else {
				$invoice_name = $type . '_' . $order_id;
			}
		} else {
			$invoice_name = $type . '_' . $order_id;
		}
		return $invoice_name;
	}

	/**
	 * Download file by passing file url.
	 *
	 * @param string $file_url url of the file to download.
	 * @return void
	 */
	public function wpg_download_already_existing_invoice_file( $file_url ) {
		@ob_end_clean(); // phpcs:ignore
		header( 'Content-Type: application/octet-stream' );
		header( 'Content-Transfer-Encoding: Binary' );
		header( 'Content-disposition: attachment; filename="' . basename( $file_url ) . '"' );
		readfile( $file_url ); // phpcs:ignore WordPress
		exit;
	}
	/**
	 * Common method for generating pdf.
	 *
	 * @param int    $order_id order id to print invoice for.
	 * @param string $type type invoice or packing slip.
	 * @param string $action either download locally or on server.
	 * @return string
	 */
	public function wpg_common_generate_pdf( $order_id, $type, $action ) {
		require_once PDF_GENERATOR_FOR_WP_DIR_PATH . 'package/lib/dompdf/vendor/autoload.php';
		$pgfw_invoice_template            = get_option( 'wpg_invoice_template' );
		$pgfw_generate_invoice_from_cache = get_option( 'wpg_generate_invoice_from_cache' );
		$invoice_id   = $this->wpg_invoice_number( $order_id );
		$invoice_name = $this->wpg_invoice_name_for_file( $type, $order_id );

		$upload_dir = wp_upload_dir();
		if ( ! empty( $upload_dir['error'] ) || empty( $upload_dir['basedir'] ) || empty( $upload_dir['baseurl'] ) ) {
			return ''; // Abort if uploads not available.
		}

		$upload_basedir = trailingslashit( $upload_dir['basedir'] ) . 'invoices/';
		$upload_baseurl = trailingslashit( $upload_dir['baseurl'] ) . 'invoices/';

		if ( ! file_exists( $upload_basedir ) ) {
			wp_mkdir_p( $upload_basedir );
		}

		$path     = $upload_basedir . $invoice_name . '.pdf';
		$file_url = $upload_baseurl . rawurlencode( $invoice_name ) . '.pdf';

		if ( ( 'yes' === $pgfw_generate_invoice_from_cache ) && file_exists( $path ) ) {
			if ( 'download_locally' === $action ) {
				$this->wpg_download_already_existing_invoice_file( $file_url );
			} elseif ( 'download_on_server' === $action ) {
				return $path;
			}
		} else {
			if ( $pgfw_invoice_template ) {
				$template = $pgfw_invoice_template;
			} else {
				$template = 'one';
			}
			
			if ( 'one' === $template ) {
				$template_path = PDF_GENERATOR_FOR_WP_DIR_PATH . 'admin/partials/pdf_templates/pdf-generator-for-wp-invoice-pdflayout1.php';
			} else if ( 'two' === $template ) {
				$template_path = PDF_GENERATOR_FOR_WP_DIR_PATH . 'admin/partials/pdf_templates/pdf-generator-for-wp-invoice-pdflayout2.php';
			} else if ( 'three' === $template ) {
				$template_path = PDF_GENERATOR_FOR_WP_DIR_PATH . 'admin/partials/pdf_templates/pdf-generator-for-wp-invoice-pdflayout3.php';
			}
			$template_path = apply_filters( 'wpg_load_template_for_invoice_generation', $template_path );
			require_once $template_path;
			$html   = return_ob_value( $order_id, $type, $invoice_id, $file_url );

			$dompdf = new Dompdf( array( 'enable_remote' => true ) );

			// Webp Image Start Fixes ///////////////////////////////////////////////////////////
			// Load HTML content into DOMDocument.
			$dom = new DOMDocument();
			$dom->loadHTML( $html );

			// Find all img tags.
			$imgs = $dom->getElementsByTagName( 'img' );

			// Loop through each img tag and modify the src attribute.
			foreach ( $imgs as $img ) {

				// Get the current src attribute value.
				$src = $img->getAttribute( 'src' );

				if ( isset( $src ) && ! empty( $src ) && pathinfo( $src, PATHINFO_EXTENSION ) === 'webp' ) {
					$src = str_replace( $upload_dir['baseurl'], $upload_dir['basedir'], $src );

					// Path to the WebP image.
					$webp_image_path = $src;

					// Create image resource from WebP image.
					$webp_image = imagecreatefromwebp( $webp_image_path );

					$parts = explode( '.', $src );

					// Modify the content after the dot.
					$extension = end( $parts );
					$new_extension = 'jpeg';

					$new_src = str_replace( '.' . $extension, '.' . $new_extension, $src );
					// Path to save JPEG image.
					$jpeg_image_path = $new_src;

					// Save JPEG image with 100% quality.
					imagejpeg( $webp_image, $jpeg_image_path, 100 );
					$img_url = str_replace( $upload_dir['basedir'], $upload_dir['baseurl'], $jpeg_image_path );
					$html = '<img src="' . $img_url . '" alt="Converted Image">';

					// Free up memory.
					imagedestroy( $webp_image );
					$img->setAttribute( 'src', $img_url );
				}
			}

			// Get the updated HTML content.
			$updated_html = $dom->saveHTML();

			// Output the updated HTML content.
			$html = $updated_html;
			// Webp Image End Fixes.
			$dompdf->loadHtml( $html );
			$dompdf->setPaper( 'A4' );
			@ob_end_clean(); // phpcs:ignore
			$dompdf->render();
			if ( ! file_exists( $upload_basedir ) ) {
				wp_mkdir_p( $upload_basedir );
			}

			if ( 'download_locally' === $action ) {
				$output = $dompdf->output();
				if ( file_exists( $path ) ) {
					@unlink( $path ); // phpcs:ignore
				}
				if ( ! file_exists( $path ) ) {
					@file_put_contents( $path, $output ); // phpcs:ignore
				}
				if ( 'invoice' === $type ) {
					do_action( 'mwb_wpg_upload_invoice_in_storage', $path, $file_url, $order_id, $invoice_name );
				}
				$dompdf->stream( $invoice_name . '.pdf', array( 'Attachment' => 1 ) );
			}
			if ( 'open_window' === $action ) {
				$output = $dompdf->output();
				$dompdf->stream( $invoice_name . '.pdf', array( 'Attachment' => 0 ) );
				if ('yes' == get_option('wpg_attach_invoice_shareable_link')) {
				$output = $dompdf->output();
				if ( file_exists( $path ) ) {
					@unlink( $path ); // phpcs:ignore
				}
				if ( ! file_exists( $path ) ) {
					@file_put_contents( $path, $output ); // phpcs:ignore
				}
				}
			}
			if ( 'download_on_server' === $action ) {
				$output = $dompdf->output();
				if ( file_exists( $path ) ) {
					@unlink( $path ); // phpcs:ignore
				}
				if ( ! file_exists( $path ) ) {
					@file_put_contents( $path, $output ); // phpcs:ignore
				}
				if ( 'invoice' === $type ) {
					do_action( 'mwb_wpg_upload_invoice_in_storage', $path, $file_url, $order_id, $invoice_name );
				}
				return $path;
			}
		}
	}
	/**
	 * Adding shortcodes for fetching order details.
	 *
	 * @return void
	 */
	public function wpg_fetch_order_details_shortcode() {
		add_shortcode( 'WPG_FETCH_ORDER', array( $this, 'wpg_fetch_order_details' ) );
	}
	/**
	 * Fetching all order details and storing in array.
	 *
	 * @param array $atts attributes which are passed while using shortcode.
	 * @return array
	 */
	public function wpg_fetch_order_details( $atts = array() ) {
		$atts  = shortcode_atts(
			array(
				'order_id' => '',
			),
			$atts
		);
		$order = wc_get_order( $atts['order_id'] );
		if ( is_a( $order, 'WC_Order_Refund' ) ) {
			$order = wc_get_order( $order->get_parent_id() );
		}
		if ( $order ) {
			$order_subtotal     = preg_replace( '/[^0-9,.]/', '', $order->get_subtotal() );
			$decimal_separator  = wc_get_price_decimal_separator();
			$thousand_separator = wc_get_price_thousand_separator();
			$decimals           = wc_get_price_decimals();
			$pgfw_coupon_fee    = array();
			$coupon_fees        = $order->get_fees();
			if ( is_array( $coupon_fees ) ) {
				foreach ( $coupon_fees as $item_fee ) {
					$fee_name                     = $item_fee->get_name();
					$fee_total                    = $item_fee->get_total();
					$pgfw_coupon_fee[ $fee_name ] = $fee_total;
				}
			}
			$order_product_details = array();
			foreach ( $order->get_items() as  $item_key => $item_values ) {
				$_tax                    = new WC_Tax();
				$item_data               = $item_values->get_data();
				$product_tax             = $_tax->get_rates( $item_data['tax_class'] );
				$product_tax             = is_array( $product_tax ) ? array_shift( $product_tax ) : $product_tax;
				$product_tax             = is_array( $product_tax ) ? array_shift( $product_tax ) : $product_tax;
				$product_tax             = ( $product_tax ) ? $product_tax : 0;
				$order_product_details[] = array(
					'product_id'       => get_post_meta( $item_data['product_id'], '_sku', true ),
					'id'               => $item_data['product_id'],
					'item_meta'        => $item_values->get_formatted_meta_data(),
					'product_name'     => $item_data['name'],
					'product_quantity' => $item_data['quantity'],
					'product_price'    => ( 0 !== (int) $item_data['quantity'] ) ? number_format( ( preg_replace( '/,/', '.', $item_data['total'] ) / $item_data['quantity'] ), $decimals, $decimal_separator, $thousand_separator ) : 0,
					'product_tax'      => number_format( preg_replace( '/,/', '.', $item_data['total_tax'] ), $decimals, $decimal_separator, $thousand_separator ),
					'product_total'    => number_format( ( preg_replace( '/,/', '.', $item_data['total'] ) + preg_replace( '/,/', '.', $item_data['total_tax'] ) ), $decimals, $decimal_separator, $thousand_separator ),
					'tax_percent'      => number_format( $product_tax, $decimals, $decimal_separator, $thousand_separator ),
				);
			}
			$shipping_total          = preg_replace( '/[^0-9,.]/', '', $order->get_shipping_total() );
			$shipping_total_format   = ( $shipping_total ) ? number_format( $shipping_total, $decimals, $decimal_separator, $thousand_separator ) : 0;
			$shipping_tax            = preg_replace( '/[^0-9,.]/', '', $order->get_shipping_tax() );
			$shipping_total_with_tax = ( $shipping_total ) ? number_format( ( $shipping_total + $shipping_tax ), $decimals, $decimal_separator, $thousand_separator ) : number_format( $shipping_tax, $decimals, $decimal_separator, $thousand_separator );
			$shipping_details        = array(
				'shipping_first_name'     => $order->get_shipping_first_name(),
				'shipping_last_name'      => $order->get_shipping_last_name(),
				'shipping_address_1'      => $order->get_shipping_address_1(),
				'shipping_address_2'      => $order->get_shipping_address_2(),
				'shipping_city'           => $order->get_shipping_city(),
				'shipping_company'        => $order->get_shipping_company(),
				'shipping_state'          => $order->get_shipping_state(),
				'shipping_postcode'       => $order->get_shipping_postcode(),
				'shipping_country'        => $order->get_shipping_country(),
				'shipping_method'         => $order->get_shipping_method(),
				'shipping_total'          => $shipping_total_format,
				'shipping_tax'            => $shipping_tax,
				'shipping_total_with_tax' => $shipping_total_with_tax,
				'order_status'            => $order->get_status(),
			);
			$cart_total              = preg_replace( '/[^0-9,.]/', '', $order->get_total() );
			$tax_total               = preg_replace( '/[^0-9,.]/', '', $order->get_total_tax() );
			$billing_details         = array(
				'coupon_details'     => $pgfw_coupon_fee,
				'customer_id'        => $order->get_customer_id(),
				'billing_email'      => $order->get_billing_email(),
				'billing_phone'      => $order->get_billing_phone(),
				'billing_first_name' => $order->get_billing_first_name(),
				'billing_last_name'  => $order->get_billing_last_name(),
				'billing_company'    => $order->get_billing_company(),
				'billing_address_1'  => $order->get_billing_address_1(),
				'billing_address_2'  => $order->get_billing_address_2(),
				'billing_city'       => $order->get_billing_city(),
				'billing_state'      => $order->get_billing_state(),
				'billing_postcode'   => $order->get_billing_postcode(),
				'billing_country'    => $order->get_billing_country(),
				'payment_method'     => $order->get_payment_method_title(),
				'order_subtotal'     => number_format( $order_subtotal, $decimals, $decimal_separator, $thousand_separator ),
				'order_currency'     => get_woocommerce_currency_symbol( $order->get_currency() ),
				'cart_total'         => number_format( $cart_total, $decimals, $decimal_separator, $thousand_separator ),
				'tax_totals'         => ( $tax_total ) ? number_format( $tax_total, $decimals, $decimal_separator, $thousand_separator ) : 0,
				'order_created_date' => $order->get_date_created()->format( get_option( 'date_format', 'd-m-Y' ) ),
			);
			$payment = $order->get_checkout_payment_url();
			$order_details_arr       = array(
				'shipping_details' => $shipping_details,
				'billing_details'  => $billing_details,
				'product_details'  => $order_product_details,
				'payment_url' => $payment,
			);
			return wp_json_encode( $order_details_arr );
		}
		return false;
	}

	/**
	 * AJAX: save assigned posts and post types for custom templates.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function wpg_save_template_items_callbck() {
		check_ajax_referer( 'wps_wpg_embed_ajax_nonce', 'nonce' );

		$template   = isset( $_POST['template'] ) ? sanitize_text_field( wp_unslash( $_POST['template'] ) ) : '';
		$items      = isset( $_POST['items'] ) && is_array( $_POST['items'] ) ? array_map( 'intval', $_POST['items'] ) : array();
		$post_types = isset( $_POST['post_types'] ) && is_array( $_POST['post_types'] ) ? array_map( 'sanitize_key', $_POST['post_types'] ) : array();

		if ( ! $template ) {
			wp_send_json_error( __( 'Invalid template name', 'pdf-generator-for-wp' ) );
		}

		update_option( 'wpg_template_items_' . $template, $items );
		update_option( 'wpg_template_post_types_' . $template, $post_types );

		wp_send_json_success();
	}

	/**
	 * Choose custom template for a post based on assigned posts/post types.
	 *
	 * @since 1.0.0
	 * @param string $template_file_path default template path.
	 * @param string $template_file_name default template slug.
	 * @param int    $post_id            post id.
	 * @return string
	 */
	public function wpg_load_custom_template_for_pdf_generation( $template_file_path, $template_file_name, $post_id ) {

		$custom_template_data = get_option( 'wpg_custom_templates_list', array() );
		$active_templates     = get_option( 'wpg_use_template_to_generate_pdf', array() );

		if ( ! is_array( $active_templates ) ) {
			$active_templates = array();
		}

		$post_type         = get_post_type( $post_id );
		$matched_template  = false;

		foreach ( $custom_template_data as $template_key => $parts ) {
			$assigned_posts      = get_option( 'wpg_template_items_' . $template_key, array() );
			$assigned_post_types = get_option( 'wpg_template_post_types_' . $template_key, array() );

			$matches_post      = in_array( (int) $post_id, $assigned_posts, true );
			$matches_post_type = ( $post_type && in_array( $post_type, (array) $assigned_post_types, true ) );

			if ( $matches_post || $matches_post_type ) {
				if ( in_array( $template_key, $active_templates, true ) ) {
					$matched_template = $template_key;
					break;
				}
			}
		}

		if ( $matched_template && isset( $custom_template_data[ $matched_template ] ) ) {
			$custom_template_path = PDF_GENERATOR_FOR_WP_DIR_PATH . 'admin/partials/pdf_templates/pdf-generator-for-wp-custom-template.php';
			// Fall back to pro template file if available in Pro directory.
			if ( ! file_exists( $custom_template_path ) ) {
				$pro_path = WP_PLUGIN_DIR . '/wordpress-pdf-generator/admin/partials/pdf_templates/wordpress-pdf-generator-custom-template.php';
				if ( file_exists( $pro_path ) ) {
					$custom_template_path = $pro_path;
				}
			}
			if ( file_exists( $custom_template_path ) ) {
				return $custom_template_path;
			}
		}

		return $template_file_path;
	}
	// .
	/**
	 * Function that generate the pdf url's when weekly cron runs.
	 *
	 * @param int    $prod_id $prod_id.
	 * @param string $type $type.
	 * @param string $action $action.
	 */
	public function cron_job_wpg_common_generate_pdf( $prod_id, $type, $action ) {

		require_once PDF_GENERATOR_FOR_WP_DIR_PATH . 'package/lib/dompdf/vendor/autoload.php';
		$upload_dir                       = wp_upload_dir();
		$upload_basedir                   = $upload_dir['basedir'] . '/bulk_pdf/';
		$path                             = $upload_basedir . get_the_title( $prod_id ) . '.pdf';
		$file_url                         = $upload_dir['baseurl'] . '/bulk_pdf/' . get_the_title( $prod_id ) . '.pdf';
		$body_settings_arr       = get_option( 'pgfw_body_save_settings', array() );
		$pgfw_body_custom_page_size_height        = array_key_exists( 'pgfw_body_custom_page_size_height', $body_settings_arr ) ? $body_settings_arr['pgfw_body_custom_page_size_height'] : '';
		$pgfw_body_custom_page_size_width        = array_key_exists( 'pgfw_body_custom_page_size_width', $body_settings_arr ) ? $body_settings_arr['pgfw_body_custom_page_size_width'] : '';
		$pgfw_body_page_template = array_key_exists( 'pgfw_body_page_template', $body_settings_arr ) ? $body_settings_arr['pgfw_body_page_template'] : 'template1';
		$pgfw_body_post_template = array_key_exists( 'pgfw_body_post_template', $body_settings_arr ) ? $body_settings_arr['pgfw_body_post_template'] : 'template1';
		$general_settings_arr = get_option( 'pgfw_general_settings_save', array() );
		$pdf_file_name        = array_key_exists( 'pgfw_general_pdf_file_name', $general_settings_arr ) ? $general_settings_arr['pgfw_general_pdf_file_name'] : 'post_name';
		$body_add_watermark   = array_key_exists( 'pgfw_body_add_watermark', $body_settings_arr ) ? $body_settings_arr['pgfw_body_add_watermark'] : '#000000';
		$body_watermark_color = array_key_exists( 'pgfw_body_watermark_color', $body_settings_arr ) ? $body_settings_arr['pgfw_body_watermark_color'] : '';
		$body_watermark_text  = array_key_exists( 'pgfw_body_watermark_text', $body_settings_arr ) ? $body_settings_arr['pgfw_body_watermark_text'] : '';
		$body_page_size       = array_key_exists( 'pgfw_body_page_size', $body_settings_arr ) ? $body_settings_arr['pgfw_body_page_size'] : 'a4';
		$page_orientation     = array_key_exists( 'pgfw_body_page_orientation', $body_settings_arr ) ? $body_settings_arr['pgfw_body_page_orientation'] : 'portrait';
		$document_name        = '';

		if ( 'page' === get_post_type( $prod_id ) ) {
			$template_file_name = PDF_GENERATOR_FOR_WP_DIR_PATH . 'admin/partials/pdf_templates/pdf-generator-for-wp-admin-' . $pgfw_body_page_template . '.php';
			$template_file_name = apply_filters( 'pgfw_load_templates_for_pdf_html', $template_file_name, $pgfw_body_page_template, $prod_id );
			require_once $template_file_name;
		} else {
			$template_file_name = PDF_GENERATOR_FOR_WP_DIR_PATH . 'admin/partials/pdf_templates/pdf-generator-for-wp-admin-' . $pgfw_body_post_template . '.php';
			$template_file_name = apply_filters( 'pgfw_load_templates_for_pdf_html', $template_file_name, $pgfw_body_post_template, $prod_id );
			require_once $template_file_name;
		}

		$post                 = get_post( $prod_id );
		if ( 'custom' === $pdf_file_name ) {
			$pdf_file_name_custom = array_key_exists( 'pgfw_custom_pdf_file_name', $general_settings_arr ) ? $general_settings_arr['pgfw_custom_pdf_file_name'] : '';
			$document_name        = ( ( '' !== $pdf_file_name_custom ) && ( $post ) ) ? $pdf_file_name_custom . '_' . $post->ID : 'document';
		} elseif ( 'post_name' === $pdf_file_name ) {
			$document_name = ( $post ) ? wp_strip_all_tags( $post->post_title ) : 'document';
		} else {
			$document_name = ( $post ) ? 'document_' . $post->ID : 'document';
		}

		$html  = '';
		$html  .= apply_filters( 'wps_pgfw_add_cover_page_template_to_single_pdf', $html );
		$html .= return_ob_html( $prod_id, $template = '' );

		$dompdf = new Dompdf( array( 'enable_remote' => true ) );

		// Webp Image Start Fixes. ///////////////////////////////////////////////////////////
		// Load HTML content into DOMDocument.
		$dom = new DOMDocument();
		$dom->loadHTML( $html );

		// Find all img tags.
		$imgs = $dom->getElementsByTagName( 'img' );

		// Loop through each img tag and modify the src attribute.
		foreach ( $imgs as $img ) {

			// Get the current src attribute value.
			$src = $img->getAttribute( 'src' );

			if ( isset( $src ) && ! empty( $src ) && pathinfo( $src, PATHINFO_EXTENSION ) === 'webp' ) {
				$src = str_replace( $upload_dir['baseurl'], $upload_dir['basedir'], $src );

				// Path to the WebP image.
				$webp_image_path = $src;

				// Create image resource from WebP image.
				$webp_image = imagecreatefromwebp( $webp_image_path );

				$parts = explode( '.', $src );

				// Modify the content after the dot.
				$extension = end( $parts );
				$new_extension = 'jpeg';

				$new_src = str_replace( '.' . $extension, '.' . $new_extension, $src );
				// Path to save JPEG image.
				$jpeg_image_path = $new_src;

				// Save JPEG image with 100% quality.
				imagejpeg( $webp_image, $jpeg_image_path, 100 );
				$img_url = str_replace( $upload_dir['basedir'], $upload_dir['baseurl'], $jpeg_image_path );
				$html = '<img src="' . $img_url . '" alt="Converted Image">';

				// Free up memory.
				imagedestroy( $webp_image );
				$img->setAttribute( 'src', $img_url );
			}
		}

		// Get the updated HTML content.
		$updated_html = $dom->saveHTML();

		// Output the updated HTML content.
		$html = $updated_html;
		// Webp Image End Fixes.

		$dompdf->loadHtml( $html );
		$dompdf->setPaper( 'A4' );
		@ob_end_clean(); // phpcs:ignore
		$dompdf->render();

		if ( ! file_exists( $upload_basedir ) ) {
			wp_mkdir_p( $upload_basedir );
		}

		if ( 'download_on_server' === $action ) {
			$output = $dompdf->output();
			if ( ! file_exists( $path ) ) {
				@unlink( $path ); // phpcs:ignore
			}
			if ( ! file_exists( $path ) ) {
				@file_put_contents( $path, $output ); // phpcs:ignore
			}

			return $path;
		}
	}
}
