/**

 * WPCode Snippet: Export Page/Post to index.html & Set as Default Page via .htaccess

 * Author: iVista Studio

 * Version: 1.0.8

 */

if (!defined(‘ABSPATH’)) exit;

define(‘IVISTA_EXPORT_VERSION’, ‘1.0.8’);

// 1. Add “Export to HTML” button to Admin Bar & Tools Menu

add_action(‘admin_bar_menu’, ‘ivista_add_export_html_button’, 999);

function ivista_add_export_html_button($wp_admin_bar) {

    if (!current_user_can(‘manage_options’)) return;

    if (is_singular() && !is_admin()) {

        global $post;

        $export_url = add_query_arg([

            ‘export_to_html’ => ‘1’,

            ‘post_id’        => $post->ID,

            ‘_wpnonce’       => wp_create_nonce(‘export_html_nonce_’ . $post->ID)

        ], get_permalink($post->ID));

        $wp_admin_bar->add_node([

            ‘id’    => ‘export_page_to_html’,

            ‘title’ => ‘📄 Save as HTML to Root (v’ . IVISTA_EXPORT_VERSION . ‘)’,

            ‘href’  => $export_url,

            ‘meta’  => [‘title’ => ‘Generates index.html and sets it as the default server page’]

        ]);

    }

}

// 2. Add admin menu entry under Tools

add_action(‘admin_menu’, ‘ivista_add_tools_export_menu’);

function ivista_add_tools_export_menu() {

    add_management_page(

        ‘Export Page to HTML’,

        ‘Export Page to HTML’,

        ‘manage_options’,

        ‘export-page-to-html’,

        ‘ivista_render_tools_page’

    );

}

function ivista_render_tools_page() {

    $pages = get_pages([‘post_status’ => ‘publish’]);

    echo ‘<div class=”wrap”>’;

    echo ‘<h1>📄 Export Page to HTML (v’ . IVISTA_EXPORT_VERSION . ‘)</h1>’;

    echo ‘<p>Select a published page to export as static HTML in your WordPress root directory and set index.html as default.</p>’;

    echo ‘<form method=”GET” action=”‘ . esc_url(home_url(‘/’)) . ‘”>’;

    echo ‘<input type=”hidden” name=”export_to_html” value=”1″>’;

    echo ‘<select name=”post_id” style=”min-width:300px; padding:6px; margin-right:10px;”>’;

    foreach ($pages as $p) {

        echo ‘<option value=”‘ . $p->ID . ‘”>’ . esc_html($p->post_title) . ‘ (/’ . $p->post_name . ‘)</option>’;

    }

    echo ‘</select>’;

    echo ‘<input type=”hidden” name=”_wpnonce” value=”‘ . wp_create_nonce(‘export_html_nonce_’ . $pages[0]->ID) . ‘” id=”export_nonce”>’;

    echo ‘<button type=”submit” class=”button button-primary”>Generate Static HTML</button>’;

    echo ‘</form>’;

    echo ‘</div>’;

}

// Helper Function: Minify raw CSS

function ivista_minify_css($css) {

    $css = preg_replace(‘!/\*.*?\*/!s’, ”, $css); 

    $css = preg_replace(‘/\s+/’, ‘ ‘, $css);        

    $css = str_replace([‘; ‘, ‘ {‘, ‘{ ‘, ‘ }’, ‘} ‘, ‘: ‘, ‘ ,’, ‘, ‘], [‘;’, ‘{‘, ‘{‘, ‘}’, ‘}’, ‘:’, ‘,’, ‘,’], $css);

    return trim($css);

}

// Helper Function: Update .htaccess to prioritize index.html

function ivista_set_index_html_default() {

    $htaccess_path = ABSPATH . ‘.htaccess’;

    $rule = “DirectoryIndex index.html index.php\n”;

    if (file_exists($htaccess_path) && is_writable($htaccess_path)) {

        $content = file_get_contents($htaccess_path);

        // Check if DirectoryIndex is already defined at the top

        if (strpos($content, ‘DirectoryIndex index.html’) === false) {

            $new_content = $rule . $content;

            file_put_contents($htaccess_path, $new_content);

            return true;

        }

    }

    return false;

}

// 3. Capture, Process CSS, Inject Counter Ping, Set .htaccess & Save Output

add_action(‘template_redirect’, ‘ivista_handle_html_export’);

function ivista_handle_html_export() {

    if (isset($_GET[‘export_to_html’]) && $_GET[‘export_to_html’] === ‘1’) {

        if (!current_user_can(‘manage_options’)) {

            wp_die(‘Unauthorized user.’);

        }

        $post_id = isset($_GET[‘post_id’]) ? intval($_GET[‘post_id’]) : 0;

        $post    = get_post($post_id);

        if (!$post) {

            wp_die(‘Invalid Page or Post ID.’);

        }

        // Timestamps

        $current_timestamp = current_time(‘mysql’);

        $formatted_date    = current_time(‘F j, Y – g:i A T’);

        // Determine HTML filename: Front page becomes index.html

        if (get_option(‘page_on_front’) == $post_id) {

            $filename = ‘index.html’; 

        } else {

            $filename = sanitize_file_name($post->post_name) . ‘.html’;

        }

        // Fetch rendered HTML (Guest Mode)

        $page_url = get_permalink($post_id);

        $response = wp_remote_get($page_url, [

            ‘timeout’   => 30,

            ‘sslverify’ => false

        ]);

        if (is_wp_error($response)) {

            wp_die(‘Failed to capture HTML: ‘ . $response->get_error_message());

        }

        $html_content = wp_remote_retrieve_body($response);

        if (empty($html_content)) {

            wp_die(‘Captured HTML content was empty.’);

        }

        // A. Clean Admin Bar Remnants

        $html_content = preg_replace(‘/<div id=”wpadminbar”[^>]*>.*?<\/div>/s’, ”, $html_content);

        $html_content = preg_replace(‘/<style[^>]*>[^<]*#wpadminbar[^<]*<\/style>/i’, ”, $html_content);

        $html_content = str_replace([‘admin-bar’, ‘class=”admin-bar”‘], ”, $html_content);

        $html_content = str_replace(‘margin-top: 32px !important;’, ”, $html_content);

        // B. Extract, Compress, and Link CSS

        $extracted_css = ”;

        if (preg_match_all(‘/<style[^>]*>(.*?)<\/style>/is’, $html_content, $matches)) {

            foreach ($matches[1] as $raw_css) {

                $extracted_css .= ” ” . $raw_css;

            }

            $html_content = preg_replace(‘/<style[^>]*>.*?<\/style>/is’, ”, $html_content);

        }

        // INJECTED CSS FIXES: Header BG + Top Spacing

        $custom_css_overrides = “

            #masthead, .ast-primary-header-bar, .main-header-bar { background-color: #f1f1ed !important; }

            .entry-content > .wp-block-group:first-of-type { margin-top: 20px !important; }

        “;

        $css_filename = ‘optimized-styles.css’;

        $minified_css = ivista_minify_css($extracted_css . $custom_css_overrides);

        file_put_contents(ABSPATH . $css_filename, $minified_css);

        $css_link_tag = “\n    <link rel=\”stylesheet\” href=\”/” . $css_filename . “?v=” . IVISTA_EXPORT_VERSION . “\”>\n”;

        if (stripos($html_content, ‘</head>’) !== false) {

            $html_content = str_ireplace(‘</head>’, $css_link_tag . ‘</head>’, $html_content);

        }

        // C. Inject Hit Counter Sync & Footer Metadata

        $counter_script = “

        <!– Native Hit Counter AJAX Sync –>

        <script>

            document.addEventListener(‘DOMContentLoaded’, function() {

                try {

                    if (typeof ahc_ajax_front !== ‘undefined’ && typeof jQuery !== ‘undefined’) {

                        jQuery.post(ahc_ajax_front.ajax_url, {

                            action: ‘ahc_hit_counter’,

                            page_id: ahc_ajax_front.page_id,

                            visitor_ip: ahc_ajax_front.visitor_ip

                        });

                    }

                } catch(e) {}

            });

        </script>

        <div id=’ivista-footer-metadata’ style=’text-align: center; padding: 15px 10px; color: #b0b0b0; font-size: 11px; font-family: -apple-system, BlinkMacSystemFont, \”Segoe UI\”, Roboto, sans-serif; background: transparent; margin-top: 30px; border-top: 1px dashed #e0e0e0;’>

            Static Page Exported v” . IVISTA_EXPORT_VERSION . ” &bull; Generated on ” . $formatted_date . “

        </div>\n”;

        if (stripos($html_content, ‘</body>’) !== false) {

            $html_content = str_ireplace(‘</body>’, $counter_script . ‘</body>’, $html_content);

        } else {

            $html_content .= $counter_script;

        }

        // D. Automatically set DirectoryIndex in .htaccess

        $htaccess_updated = ivista_set_index_html_default();

        // Save static HTML file to root

        $file_path = ABSPATH . $filename;

        $result    = file_put_contents($file_path, $html_content);

        if ($result !== false) {

            $public_url     = site_url(‘/’ . $filename);

            $css_url        = site_url(‘/’ . $css_filename);

            $htaccess_status = $htaccess_updated ? ‘<span style=”color:#27ae60; font-weight:bold;”>Updated (.htaccess rule added)</span>’ : ‘Active (Already configured in .htaccess)’;

            wp_die(“

                <div style=’font-family: -apple-system, sans-serif; max-width: 600px; margin: 50px auto; padding: 25px; border: 1px solid #1a1a1a; border-radius: 8px; background: #fff;’>

                    <h2 style=’color: #27ae60; margin-top: 0;’>✅ Success! Exported to {$filename} (v1.0.8)</h2>

                    <p><strong>Page Title:</strong> {$post->post_title}</p>

                    <p><strong>Target File:</strong> <code>{$filename}</code></p>

                    <p><strong>Server Default Setting:</strong> {$htaccess_status}</p>

                    <p><strong>App Version:</strong> <code>v” . IVISTA_EXPORT_VERSION . “</code></p>

                    <p><strong>Header Background:</strong> <span style=’color:#27ae60; font-weight:bold;’>Fixed (#f1f1ed)</span></p>

                    <p><strong>Hit Counter Sync:</strong> <span style=’color:#27ae60; font-weight:bold;’>Active</span></p>

                    <p><strong>Export Timestamp:</strong> <code>{$formatted_date}</code></p>

                    <p><strong>HTML File Saved:</strong> <code>{$file_path}</code></p>

                    <p><strong>Minified CSS File:</strong> <code>ABSPATH/{$css_filename}</code></p>

                    <p><strong>Public URL:</strong> <a href='{$public_url}’ target=’_blank’>{$public_url}</a></p>

                    <p><strong>Optimized CSS URL:</strong> <a href='{$css_url}’ target=’_blank’>{$css_url}</a></p>

                    <hr style=’border: none; border-top: 1px solid #eee; margin: 20px 0;’>

                    <a href='{$page_url}’ style=’display:inline-block; padding:10px 18px; background:#011d5d; color:#fff; text-decoration:none; border-radius:4px; font-weight: bold;’>&laquo; Back to Live Page</a>

                </div>

            “);

        } else {

            wp_die(‘Error writing files to root directory. Check server permissions for: ‘ . ABSPATH);

        }

    }

}

Leave a Reply

Your email address will not be published. Required fields are marked *

Recent Posts

Recent Comments

No comments to show.

Archives

Categories