<?php
/*
Plugin Name: Posts to PDF - Backend Batch Export
Author: OnoDev
Description: Export posts, pages and content in PDF from your Wordpress admin.
Version: 1.2
Requires at least: 5.0
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: posts-to-pdf-backend-batch-export
*/

// Sicurezza: blocca accesso diretto
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

// Esempio di sanitizzazione GET
$posttopdf_ids = array();

function posttopdf_process_get_ids() {
    global $posttopdf_ids;

    if ( isset( $_GET['ids'] ) ) {
        // Controllo e sanitizzazione del nonce
        $preview_nonce = isset( $_GET['preview_nonce'] ) 
            ? sanitize_text_field( wp_unslash( $_GET['preview_nonce'] ) ) 
            : '';

        if ( empty( $preview_nonce ) || ! wp_verify_nonce( $preview_nonce, 'posttopdf_preview' ) ) {
            wp_die( 'Controllo di sicurezza fallito.' );
        }

        // Sanitizzazione e rimozione slashes di 'ids'
        $ids_raw = isset( $_GET['ids'] ) 
            ? sanitize_text_field( wp_unslash( $_GET['ids'] ) ) 
            : '';

        $posttopdf_ids = array_filter( array_map( 'intval', explode( ',', $ids_raw ) ) );

        if ( empty( $posttopdf_ids ) ) {
            wp_die( 'Nessun ID valido selezionato.' );
        }
    }
}
add_action( 'admin_init', 'posttopdf_process_get_ids' );

if ( ! defined( 'POSTTOPDF_PLUGIN_VERSION' ) ) {
    define( 'POSTTOPDF_PLUGIN_VERSION', '1.1' );
}

class Posts_To_PDF_Full {

    public function __construct() {
        add_action( 'admin_menu', [ $this, 'add_menu' ] );
        add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
        add_action( 'wp_ajax_posttopdf_generate_pdf', [ $this, 'ajax_generate_pdf' ] );
        add_action( 'wp_ajax_posttopdf_load_posts', [ $this, 'ajax_load_posts' ] );
        add_action( 'admin_post_posttopdf_preview_pdf', [ $this, 'preview_pdf_page' ] );
    }

    public function add_menu() {
        add_menu_page(
            'Posts to PDF',
            'Posts to PDF',
            'manage_options',
            'posts-to-pdf-backend-batch-export',
            [ $this, 'render_admin_page' ],
            'dashicons-media-document',
            26
        );
    }

    public function enqueue_assets( $hook ) {
        if ( $hook !== 'toplevel_page_posts-to-pdf-backend-batch-export' ) {
            return;
        }

        wp_enqueue_style(
            'posttopdf-admin',
            plugin_dir_url( __FILE__ ) . 'assets/admin.css',
            array(),
            POSTTOPDF_PLUGIN_VERSION
        );

        wp_enqueue_style(
            'posttopdf-pdf-css',
            plugin_dir_url( __FILE__ ) . 'assets/pdf.css',
            array(),
            POSTTOPDF_PLUGIN_VERSION
        );

        wp_enqueue_script(
            'posttopdf-admin',
            plugin_dir_url( __FILE__ ) . 'assets/admin.js',
            array( 'jquery' ),
            POSTTOPDF_PLUGIN_VERSION,
            true
        );

        wp_localize_script(
            'posttopdf-admin',
            'posttopdf_ajax',
            array(
                'url'           => admin_url( 'admin-ajax.php' ),
                'nonce'         => wp_create_nonce( 'posttopdf_nonce' ),
                'preview_url'   => admin_url( 'admin-post.php?action=posttopdf_preview_pdf&ids=' ),
                'preview_nonce' => wp_create_nonce( 'posttopdf_preview' ),
            )
        );
    }

    public function render_admin_page() {
        $post_types = get_post_types( array( 'public' => true ), 'objects' );
        if ( isset( $post_types['attachment'] ) ) {
            unset( $post_types['attachment'] ); // exclude attachments
        }

        ?>
        <div class="wrap">
            <h1><?php echo esc_html( 'Posts to PDF' ); ?></h1>
            <form id="posttopdf-form" method="post" novalidate>
                <div id="posttopdf-tabs">
                    <?php
                    foreach ( $post_types as $type => $obj ) {
                        printf(
                            '<button type="button" class="posttopdf-tab-btn" data-post-type="%s">%s</button>',
                            esc_attr( $type ),
                            esc_html( $obj->labels->name )
                        );
                    }
                    ?>
                </div>

                <input type="text" id="posttopdf-search" placeholder="<?php echo esc_attr( 'Search posts...' ); ?>" />

                <div id="posttopdf-post-list-container"></div>

                <div id="posttopdf-selected-wrapper">
                    <span id="posttopdf-selected-count"><?php echo esc_html( 'Posts Selected: 0' ); ?></span>
                    <button type="button" id="posttopdf-reset-btn" class="button"><?php echo esc_html( 'Reset All' ); ?></button>
                </div>

                <div class="posttopdf-buttons">
                    <button type="button" id="posttopdf-preview-btn" class="button"><?php echo esc_html( 'PDF Preview' ); ?></button>
                    <button type="button" id="posttopdf-generate-btn" class="button button-primary"><?php echo esc_html( 'Download PDF' ); ?></button>
                </div>
            </form>

            <div id="posttopdf-preview-modal">
                <button id="posttopdf-preview-close"><?php echo esc_html( 'Close Preview' ); ?></button>
                <iframe id="posttopdf-preview-frame"></iframe>
            </div>
        </div>
        <?php
    }

    public function ajax_load_posts() {
        check_ajax_referer( 'posttopdf_nonce', 'nonce' );

        $post_type = isset( $_POST['post_type'] ) ? sanitize_text_field( wp_unslash( $_POST['post_type'] ) ) : '';
        $page      = isset( $_POST['page'] ) ? max( 1, intval( wp_unslash( $_POST['page'] ) ) ) : 1;
        $search    = isset( $_POST['search'] ) ? sanitize_text_field( wp_unslash( $_POST['search'] ) ) : '';

        if ( ! $post_type ) {
            wp_send_json_error( 'Missing post type' );
            wp_die();
        }

        $args = array(
            'post_type'      => $post_type,
            'posts_per_page' => 15,
            'paged'          => $page,
            's'              => $search,
            'post_status'    => 'publish',
        );

        $query = new WP_Query( $args );

        $response = array(
            'posts'         => array(),
            'max_num_pages' => $query->max_num_pages,
        );

        if ( $query->have_posts() ) {
            foreach ( $query->posts as $post ) {
                $response['posts'][] = array(
                    'ID'    => (int) $post->ID,
                    'title' => get_the_title( $post ),
                );
            }
        }

        wp_send_json_success( $response );
        wp_die();
    }

    public function preview_pdf_page() {
        // ? Controllo permessi subito
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_die( esc_html__( 'Permission denied', 'posts-to-pdf-backend-batch-export' ) );
        }

        // ? Controllo nonce (obbligatorio, non opzionale)
        if ( ! isset( $_GET['preview_nonce'] ) || 
             ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['preview_nonce'] ) ), 'posttopdf_preview' ) ) {
            wp_die( esc_html__( 'Security check failed. Invalid nonce.', 'posts-to-pdf-backend-batch-export' ) );
        }

        // ? Sanitizzazione input
        $ids_raw = filter_input( INPUT_GET, 'ids', FILTER_SANITIZE_STRING );
        if ( empty( $ids_raw ) ) {
            wp_die( esc_html__( 'No posts selected.', 'posts-to-pdf-backend-batch-export' ) );
        }

        $ids_unslashed = wp_unslash( $ids_raw );
        $ids_input     = sanitize_text_field( $ids_unslashed );
        $ids           = array_filter( array_map( 'intval', explode( ',', $ids_input ) ) );

        if ( empty( $ids ) ) {
            wp_die( esc_html__( 'No valid posts selected.', 'posts-to-pdf-backend-batch-export' ) );
        }

        // ? Generazione HTML e normalizzazione URL
        $html = $this->build_pdf_html( $ids );
        $html = $this->make_absolute_urls( $html );

        // ? Caricamento Dompdf
        if ( ! class_exists( 'Dompdf\Dompdf' ) ) {
            require_once plugin_dir_path( __FILE__ ) . 'vendor/autoload.php';
        }

if ( class_exists( 'Dompdf\Dompdf' ) ) {
    $dompdf = new Dompdf\Dompdf();
    $dompdf->set_option( 'isRemoteEnabled', true );

    // ? Caricamento CSS locale per margini
    $css_file = plugin_dir_path( __FILE__ ) . 'assets/pdf.css';
    if ( file_exists( $css_file ) ) {
        $html = '<style>' . file_get_contents( $css_file ) . '</style>' . $html;
    }

    $dompdf->loadHtml( $html );
    $dompdf->setPaper( 'A4', 'portrait' );
    $dompdf->render();

    // ? Output PDF con headers sicuri
    $pdf_output = $dompdf->output();

    nocache_headers();
    header( 'Content-Type: application/pdf' );
    header( 'Content-Disposition: inline; filename="preview.pdf"' );
    header( 'Content-Length: ' . strlen( $pdf_output ) );
    // Direct binary output - do NOT escape
    echo $pdf_output;

    exit;
} else {
    wp_die( esc_html__( 'Dompdf not available.', 'posts-to-pdf-backend-batch-export' ) );
}
    }

    public function ajax_generate_pdf() {
        check_ajax_referer( 'posttopdf_nonce', 'nonce' );

        $ids_raw = isset( $_POST['ids'] ) && is_array( $_POST['ids'] ) 
            ? array_map( 'sanitize_text_field', wp_unslash($_POST['ids']) )
            : [];

        $ids_unslashed = array_map( 'wp_unslash', $ids_raw );
        $ids = array_filter( array_map( function( $id ) {
            return intval( sanitize_text_field( $id ) );
        }, $ids_unslashed ) );

        if ( empty( $ids ) ) {
            wp_send_json_error( 'No posts selected.' );
            wp_die();
        }

        $html = $this->build_pdf_html( $ids );
        $html = $this->make_absolute_urls( $html );

        if ( ! class_exists( 'Dompdf\Dompdf' ) ) {
            require_once plugin_dir_path( __FILE__ ) . 'vendor/autoload.php';
        }

if ( class_exists( 'Dompdf\Dompdf' ) ) {
    $dompdf = new Dompdf\Dompdf();
    $dompdf->set_option( 'isRemoteEnabled', true );

    // Carica il CSS direttamente nell'HTML
    $css_file = plugin_dir_path( __FILE__ ) . 'assets/pdf.css';
    if ( file_exists( $css_file ) ) {
        $html = '<style>' . file_get_contents( $css_file ) . '</style>' . $html;
    }

    $dompdf->loadHtml( $html );
    $dompdf->setPaper( 'A4', 'portrait' );
    $dompdf->render();

    // Output PDF con headers sicuri
    $pdf_output = $dompdf->output();
    $filename   = 'export-' . time() . '.pdf';

    nocache_headers();
    header( 'Content-Type: application/pdf' );
    header( 'Content-Disposition: attachment; filename="' . esc_attr( $filename ) . '"' );
    header( 'Content-Length: ' . strlen( $pdf_output ) );

    // Output binario diretto
    echo $pdf_output;
    exit;
}
 else {
            wp_send_json_error( 'Dompdf not available.' );
            wp_die();
        }
    }

    private function build_pdf_html( $ids ) {
        ob_start();

        $first = true;
        foreach ( $ids as $id ) {
            $post = get_post( (int) $id );
            if ( ! $post ) {
                continue;
            }

            if ( ! $first ) {
                echo '<div style="page-break-before: always;"></div>';
            }
            $first = false;

            echo '<h2>' . esc_html( get_the_title( $post ) ) . '</h2>';

            $content = apply_filters( 'the_content', $post->post_content );
            echo '<div>' . wp_kses_post( $content ) . '</div>';

            if ( 'product' === $post->post_type && function_exists( 'wc_get_product' ) ) {
                $product = wc_get_product( $post->ID );
                if ( $product ) {
                    echo '<p>' . wp_kses_post( $product->get_price_html() ) . '</p>';
                    echo '<p>SKU: ' . esc_html( $product->get_sku() ) . '</p>';
                    echo wp_kses_post( $product->get_image() );
                }
            }
        }

        return ob_get_clean();
    }

    private function make_absolute_urls( $html ) {
        $site_url = get_site_url();
        return preg_replace_callback(
            '/<img\s+[^>]*src=["\']([^"\']+)["\']/i',
            function ( $matches ) use ( $site_url ) {
                $src = $matches[1];
                if ( preg_match( '#^(https?:)?//#i', $src ) || strpos( $src, 'data:' ) === 0 ) {
                    return $matches[0];
                }
                $absolute_src = rtrim( $site_url, '/' ) . '/' . ltrim( $src, '/' );
                return str_replace( $src, $absolute_src, $matches[0] );
            },
            $html
        );
    }
}

new Posts_To_PDF_Full();
