'Content Taxonomy Tables', // page_title 'menu_title' => 'Taxonomy Tables', // menu_title 'capability' => 'manage_options', // capability 'menu_slug' => 'jvb-taxonomy-table', // menu_slug (will become BASE.'integrations') 'callback' => [$this, 'renderAdminPage'], // callback ]; return $subpages; } /** * Handle admin actions */ public function handleActions(): void { if (!current_user_can('manage_options')) { return; } // Handle individual taxonomy rebuild if (isset($_POST['rebuild_taxonomy']) && wp_verify_nonce($_POST['_wpnonce'], 'rebuild_taxonomy')) { $taxonomy = sanitize_text_field($_POST['taxonomy']); $registrar = Registrar::getInstance($taxonomy); if ($registrar && $registrar->hasFeature('is_content')) { $results = $this->rebuildCustomTable($taxonomy); // Store results in transient to display after redirect set_transient('jvb_rebuild_results_' . $taxonomy, $results, 300); // 5 minutes wp_redirect(add_query_arg('rebuilt', $taxonomy, wp_get_referer())); exit; } // Display results if available $results = get_transient('jvb_rebuild_results_' . $this->slug); if ($results) { delete_transient('jvb_rebuild_results_' . $this->slug); add_action('admin_notices', function() use ($results) { $class = $results['errors'] > 0 ? 'notice-warning' : 'notice-success'; echo '
'; echo '

Taxonomy Rebuild Results:

'; echo ''; echo '
'; }); } } // Handle rebuild all if (isset($_POST['rebuild_all']) && wp_verify_nonce($_POST['_wpnonce'], 'rebuild_all')) { $results = $this->rebuildAllContentTaxonomies(); $this->storeResults('rebuild_all', $results); wp_redirect(add_query_arg('rebuilt', 'all', wp_get_referer())); exit; } } /** * Store results in transient for display */ protected function storeResults(string $key, array $results): void { set_transient("jvb_admin_results_{$key}", $results, 300); } /** * Render admin page */ public function renderAdminPage(): void { // Display any stored results $this->displayResults(); ?>

Content Tables Management

Content Taxonomies

These taxonomies have custom content tables that can be rebuilt from existing term data.

getTableInfo($slug); $term_count = wp_count_terms($taxonomy, ['hide_empty' => false]); ?>
Taxonomy Table Status Term Count Table Count Actions
getPlural()) ?>
Table exists Table missing terms records N/A
Create table first via plugin activation

Table Information

Content tables store frequently accessed data from taxonomies for improved performance.

When to Rebuild:

WP-CLI Commands:

wp jvb rebuild-content-tables - Rebuild all content tables
wp jvb rebuild-content-tables <taxonomy> - Rebuild specific taxonomy table
prefix . BASE . 'content_' . $slug; $exists = $wpdb->get_var("SHOW TABLES LIKE '{$table}'") === $table; $count = 0; if ($exists) { $count = (int) $wpdb->get_var("SELECT COUNT(*) FROM {$table}"); } return [ 'exists' => $exists, 'count' => $count, 'table' => $table ]; } /** * Display results from previous actions */ protected function displayResults(): void { // Check for rebuild completion if (isset($_GET['rebuilt'])) { $rebuilt = sanitize_text_field($_GET['rebuilt']); if ($rebuilt === 'all') { $results = get_transient('jvb_admin_results_rebuild_all'); if ($results) { delete_transient('jvb_admin_results_rebuild_all'); $this->displayAllRebuildResults($results); } } else { $results = get_transient("jvb_admin_results_rebuild_{$rebuilt}"); if ($results) { delete_transient("jvb_admin_results_rebuild_{$rebuilt}"); $this->displaySingleRebuildResults($rebuilt, $results); } } } } /** * Display results for single taxonomy rebuild */ protected function displaySingleRebuildResults(string $taxonomy, array $results): void { $class = $results['errors'] > 0 ? 'notice-warning' : 'notice-success'; ?>

Rebuild Results:

0 ? 'notice-warning' : 'notice-success'; ?>

Rebuild All Results

Summary: taxonomies processed, successful, failed

$detail): ?>
✓ Success errors
0, 'errors' => 0, 'total' => 0, 'messages' => [] ]; // Check if this is a content taxonomy $registrar = Registrar::getInstance($taxonomy); if (!$registrar->hasFeature('is_content')) { $results['messages'][] = "Taxonomy {$taxonomy} is not a content taxonomy"; return $results; } global $wpdb; $table = $wpdb->prefix . BASE . 'content_' . $taxonomy; // Check if table exists if ($wpdb->get_var("SHOW TABLES LIKE '{$table}'") !== $table) { $results['messages'][] = "Custom table {$table} does not exist"; return $results; } // Clear existing data $wpdb->query("TRUNCATE TABLE {$table}"); $results['messages'][] = "Cleared existing data from {$table}"; // Get all terms for this taxonomy $terms = get_terms([ 'taxonomy' => jvbCheckBase($taxonomy), 'hide_empty'=> false, 'number' => 0, // Get all terms 'fields' => 'ids' ]); if (is_wp_error($terms)) { $results['messages'][] = "Error fetching terms: " . $terms->get_error_message(); return $results; } $results['total'] = count($terms); $results['messages'][] = "Found {$results['total']} terms to process"; JVB()->queue()->queueOperation( 'sync_content_taxonomy_tables', 0, [ 'terms' => $terms, 'taxonomy' => $taxonomy ], [ 'chunk_key' => 'terms', 'chunk_size' => 10, ] ); $results['messages'][] = 'Added to queue!'; return $results; } public function processOperation(WP_Error $result, object $operation, array $data):WP_Error|array { switch ($operation->type) { case 'sync_content_taxonomy_tables': return $this->processContentTaxonomyTableSync($operation, $data); default: return $result; } } public function processContentTaxonomyTableSync(object $operation, array $data):array { $taxonomy = $data['taxonomy']; $registrar = new TaxonomyRegistrar($taxonomy, JVB_TAXONOMY[$taxonomy]); $results = ['errors' => 0, 'success' => 0]; foreach ($data['terms'] as $term) { try { $registrar->syncTermToCustomTable($term); $results['success']++; } catch (Exception $e) { $results['errors']++; $results['messages'][] = "Error processing term {$term->term_id} ({$term->name}): " . $e->getMessage(); } } $results['messages'][] = "Rebuild complete: {$results['success']} successful, {$results['errors']} errors"; return [ 'success' => true, 'result' => $results ]; } } new ContentTaxonomy();