Files
2026-03-18 14:21:32 -07:00

287 lines
8.8 KiB
PHP

<?php
/**
* Bulk Conversion Class
*
* Handles bulk conversion of pages and posts to static HTML.
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
class WP_To_HTML_Bulk {
/**
* Single instance
*/
private static $instance = null;
/**
* Batch size for processing
*/
const BATCH_SIZE = 10;
/**
* Get singleton instance
*/
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*/
private function __construct() {
add_action('wp_ajax_wp_to_html_bulk_convert', array($this, 'ajax_bulk_convert'));
add_action('wp_ajax_wp_to_html_clear_cache', array($this, 'ajax_clear_cache'));
add_action('wp_ajax_wp_to_html_get_posts_count', array($this, 'ajax_get_posts_count'));
}
/**
* AJAX handler for getting total posts count
*/
public function ajax_get_posts_count() {
check_ajax_referer('wp_to_html_bulk', 'nonce');
if (!current_user_can('manage_options')) {
wp_send_json_error(__('Permission denied', 'wp-to-html'));
}
$count = $this->get_eligible_posts_count();
// Set initial status for bulk conversion
WP_To_HTML_Cron::set_regeneration_status(array(
'status' => 'running',
'source' => 'settings_page',
'started' => time(),
'total' => $count,
'processed' => 0,
'converted' => 0,
'skipped' => 0,
'errors' => 0,
));
wp_send_json_success(array(
'total' => $count,
));
}
/**
* AJAX handler for bulk conversion
*/
public function ajax_bulk_convert() {
check_ajax_referer('wp_to_html_bulk', 'nonce');
if (!current_user_can('manage_options')) {
wp_send_json_error(__('Permission denied', 'wp-to-html'));
}
$offset = isset($_POST['offset']) ? intval($_POST['offset']) : 0;
$result = $this->process_batch($offset);
// Get current status to accumulate totals
$current_status = WP_To_HTML_Cron::get_regeneration_status();
$converted = isset($current_status['converted']) ? $current_status['converted'] : 0;
$skipped = isset($current_status['skipped']) ? $current_status['skipped'] : 0;
$errors = isset($current_status['errors']) ? $current_status['errors'] : 0;
$processed = isset($current_status['processed']) ? $current_status['processed'] : 0;
// Update status with accumulated progress
$new_status = array(
'source' => 'settings_page',
'started' => isset($current_status['started']) ? $current_status['started'] : time(),
'total' => $result['total'],
'processed' => $processed + $result['processed'],
'converted' => $converted + $result['converted'],
'skipped' => $skipped + $result['skipped'],
'errors' => $errors + $result['errors'],
);
if ($result['has_more']) {
$new_status['status'] = 'running';
} else {
$new_status['status'] = 'complete';
$new_status['completed'] = time();
}
WP_To_HTML_Cron::set_regeneration_status($new_status);
wp_send_json_success($result);
}
/**
* AJAX handler for clearing cache
*/
public function ajax_clear_cache() {
check_ajax_referer('wp_to_html_bulk', 'nonce');
if (!current_user_can('manage_options')) {
wp_send_json_error(__('Permission denied', 'wp-to-html'));
}
$generator = WP_To_HTML_Generator::get_instance();
$generator->clear_all_cache();
wp_send_json_success(array(
'message' => __('Cache cleared successfully', 'wp-to-html'),
));
}
/**
* Get count of eligible posts
*/
private function get_eligible_posts_count() {
$post_types = $this->get_eligible_post_types();
$args = array(
'post_type' => $post_types,
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids',
);
$query = new WP_Query($args);
return $query->post_count;
}
/**
* Process a batch of posts
*/
private function process_batch($offset) {
$post_types = $this->get_eligible_post_types();
$args = array(
'post_type' => $post_types,
'post_status' => 'publish',
'posts_per_page' => self::BATCH_SIZE,
'offset' => $offset,
'orderby' => 'ID',
'order' => 'ASC',
);
$query = new WP_Query($args);
$generator = WP_To_HTML_Generator::get_instance();
$results = array(
'processed' => 0,
'converted' => 0,
'skipped' => 0,
'errors' => 0,
'details' => array(),
'has_more' => false,
'next_offset' => $offset + self::BATCH_SIZE,
);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
$post_id = get_the_ID();
$post_title = get_the_title();
$results['processed']++;
$generation_result = $generator->generate($post_id);
if (is_wp_error($generation_result)) {
if ($generation_result->get_error_code() === 'excluded') {
$results['skipped']++;
$results['details'][] = array(
'id' => $post_id,
'title' => $post_title,
'status' => 'skipped',
'message' => $generation_result->get_error_message(),
);
} else {
$results['errors']++;
$results['details'][] = array(
'id' => $post_id,
'title' => $post_title,
'status' => 'error',
'message' => $generation_result->get_error_message(),
);
}
} else {
$results['converted']++;
$results['details'][] = array(
'id' => $post_id,
'title' => $post_title,
'status' => 'converted',
'message' => __('Successfully converted', 'wp-to-html'),
);
}
}
wp_reset_postdata();
}
// Check if there are more posts
$total = $this->get_eligible_posts_count();
$results['has_more'] = ($offset + self::BATCH_SIZE) < $total;
$results['total'] = $total;
return $results;
}
/**
* Get eligible post types
*/
private function get_eligible_post_types() {
$post_types = get_post_types(array('public' => true), 'names');
$excluded = array('attachment', 'product', 'product_variation');
return array_values(array_diff($post_types, $excluded));
}
/**
* Bulk convert all eligible posts (CLI method)
*/
public function convert_all() {
$post_types = $this->get_eligible_post_types();
$args = array(
'post_type' => $post_types,
'post_status' => 'publish',
'posts_per_page' => -1,
);
$query = new WP_Query($args);
$generator = WP_To_HTML_Generator::get_instance();
$results = array(
'total' => $query->post_count,
'converted' => 0,
'skipped' => 0,
'errors' => 0,
);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
$post_id = get_the_ID();
$generation_result = $generator->generate($post_id);
if (is_wp_error($generation_result)) {
if ($generation_result->get_error_code() === 'excluded') {
$results['skipped']++;
} else {
$results['errors']++;
}
} else {
$results['converted']++;
}
}
wp_reset_postdata();
}
return $results;
}
}