// ==================== TRIBE Q&A SYSTEM - DATABASE TABLES ==================== function create_tribe_tables() { global $wpdb; $charset_collate = $wpdb->get_charset_collate(); $prefix = $wpdb->prefix; // Questions table $sql = "CREATE TABLE IF NOT EXISTS {$prefix}tribe_questions ( id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(500) NOT NULL, content LONGTEXT NOT NULL, category VARCHAR(100) DEFAULT 'general', tags TEXT, created_by INT NOT NULL, is_active TINYINT(1) DEFAULT 1, is_featured TINYINT(1) DEFAULT 0, view_count INT DEFAULT 0, answer_count INT DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_active (is_active), INDEX idx_category (category), INDEX idx_created (created_at DESC), FOREIGN KEY (created_by) REFERENCES {$wpdb->users}(ID) ON DELETE CASCADE ) $charset_collate;"; // Answers table (main answers to questions) $sql .= "CREATE TABLE IF NOT EXISTS {$prefix}tribe_answers ( id INT AUTO_INCREMENT PRIMARY KEY, question_id INT NOT NULL, user_id INT DEFAULT NULL, anonymous_name VARCHAR(100) DEFAULT NULL, content LONGTEXT NOT NULL, upvotes INT DEFAULT 0, downvotes INT DEFAULT 0, is_best_answer TINYINT(1) DEFAULT 0, is_approved TINYINT(1) DEFAULT 1, is_anonymous TINYINT(1) DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_question (question_id), INDEX idx_upvotes (upvotes DESC), INDEX idx_created (created_at DESC), FOREIGN KEY (question_id) REFERENCES {$prefix}tribe_questions(id) ON DELETE CASCADE, FOREIGN KEY (user_id) REFERENCES {$wpdb->users}(ID) ON DELETE SET NULL ) $charset_collate;"; // Replies table (threaded replies to answers) $sql .= "CREATE TABLE IF NOT EXISTS {$prefix}tribe_replies ( id INT AUTO_INCREMENT PRIMARY KEY, answer_id INT NOT NULL, user_id INT DEFAULT NULL, parent_reply_id INT DEFAULT NULL, anonymous_name VARCHAR(100) DEFAULT NULL, content TEXT NOT NULL, upvotes INT DEFAULT 0, downvotes INT DEFAULT 0, is_anonymous TINYINT(1) DEFAULT 0, is_approved TINYINT(1) DEFAULT 1, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_answer (answer_id), INDEX idx_parent (parent_reply_id), INDEX idx_upvotes (upvotes DESC), FOREIGN KEY (answer_id) REFERENCES {$prefix}tribe_answers(id) ON DELETE CASCADE, FOREIGN KEY (user_id) REFERENCES {$wpdb->users}(ID) ON DELETE SET NULL ) $charset_collate;"; // Votes table $sql .= "CREATE TABLE IF NOT EXISTS {$prefix}tribe_votes ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT DEFAULT NULL, user_ip VARCHAR(45) DEFAULT NULL, content_type ENUM('answer', 'reply') NOT NULL, content_id INT NOT NULL, vote_type ENUM('upvote', 'downvote') NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY unique_vote (user_id, user_ip, content_type, content_id), INDEX idx_content (content_type, content_id), FOREIGN KEY (user_id) REFERENCES {$wpdb->users}(ID) ON DELETE SET NULL ) $charset_collate;"; // User points table $sql .= "CREATE TABLE IF NOT EXISTS {$prefix}tribe_user_points ( user_id INT NOT NULL PRIMARY KEY, total_points INT DEFAULT 0, upvote_points INT DEFAULT 0, answer_points INT DEFAULT 0, best_answer_points INT DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES {$wpdb->users}(ID) ON DELETE CASCADE ) $charset_collate;"; // User badges table $sql .= "CREATE TABLE IF NOT EXISTS {$prefix}tribe_badges ( id INT AUTO_INCREMENT PRIMARY KEY, badge_key VARCHAR(50) UNIQUE NOT NULL, name VARCHAR(100) NOT NULL, description TEXT, icon VARCHAR(255), requirement_type ENUM('points', 'answers', 'upvotes', 'best_answers') NOT NULL, requirement_value INT NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ) $charset_collate;"; $sql .= "CREATE TABLE IF NOT EXISTS {$prefix}tribe_user_badges ( user_id INT NOT NULL, badge_id INT NOT NULL, awarded_at DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (user_id, badge_id), FOREIGN KEY (user_id) REFERENCES {$wpdb->users}(ID) ON DELETE CASCADE, FOREIGN KEY (badge_id) REFERENCES {$prefix}tribe_badges(id) ON DELETE CASCADE ) $charset_collate;"; // Notifications table $sql .= "CREATE TABLE IF NOT EXISTS {$prefix}tribe_notifications ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT NOT NULL, type ENUM('upvote', 'reply', 'new_question', 'best_answer', 'badge') NOT NULL, content TEXT NOT NULL, related_id INT DEFAULT NULL, is_read TINYINT(1) DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX idx_user (user_id, is_read), INDEX idx_created (created_at DESC), FOREIGN KEY (user_id) REFERENCES {$wpdb->users}(ID) ON DELETE CASCADE ) $charset_collate;"; // Reports table $sql .= "CREATE TABLE IF NOT EXISTS {$prefix}tribe_reports ( id INT AUTO_INCREMENT PRIMARY KEY, reporter_id INT DEFAULT NULL, content_type ENUM('answer', 'reply') NOT NULL, content_id INT NOT NULL, reason TEXT NOT NULL, status ENUM('pending', 'resolved', 'dismissed') DEFAULT 'pending', created_at DATETIME DEFAULT CURRENT_TIMESTAMP, resolved_at DATETIME DEFAULT NULL, INDEX idx_status (status), FOREIGN KEY (reporter_id) REFERENCES {$wpdb->users}(ID) ON DELETE SET NULL ) $charset_collate;"; // Subscribers table $sql .= "CREATE TABLE IF NOT EXISTS {$prefix}tribe_subscribers ( id INT AUTO_INCREMENT PRIMARY KEY, email VARCHAR(255) NOT NULL UNIQUE, name VARCHAR(100), unsubscribe_token VARCHAR(64) NOT NULL, is_active TINYINT(1) DEFAULT 1, subscribed_at DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX idx_token (unsubscribe_token) ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql); // Insert default badges insert_default_tribe_badges(); } add_action('after_switch_theme', 'create_tribe_tables'); add_action('init', 'create_tribe_tables'); function insert_default_tribe_badges() { global $wpdb; $badges_table = $wpdb->prefix . 'tribe_badges'; $default_badges = [ ['first_question', 'First Question', 'Asked your first question', 'question-circle', 'answers', 1], ['first_answer', 'First Answer', 'Posted your first answer', 'comment', 'answers', 1], ['rising_star', 'Rising Star', 'Received 10 upvotes', 'star', 'upvotes', 10], ['top_contributor', 'Top Contributor', 'Received 50 upvotes', 'trophy', 'upvotes', 50], ['answer_master', 'Answer Master', 'Posted 25 answers', 'medal', 'answers', 25], ['sage', 'The Sage', 'Posted 100 answers', 'crown', 'answers', 100], ['best_answer_hero', 'Best Answer Hero', 'Got 5 best answers', 'check-circle', 'best_answers', 5], ['legend', 'Legend', 'Achieved 500 points', 'diamond', 'points', 500], ['mythic', 'Mythic', 'Achieved 1000 points', 'gem', 'points', 1000], ]; foreach ($default_badges as $badge) { $wpdb->replace($badges_table, [ 'badge_key' => $badge[0], 'name' => $badge[1], 'description' => $badge[2], 'icon' => $badge[3], 'requirement_type' => $badge[4], 'requirement_value' => $badge[5] ]); } } // Create page on theme activation function create_tribe_page() { $page = get_page_by_path('tribe'); if (!$page) { wp_insert_post([ 'post_title' => 'Tribe', 'post_name' => 'tribe', 'post_content' => '', 'post_status' => 'publish', 'post_type' => 'page', 'page_template' => 'page-tribe.php' ]); } } add_action('after_switch_theme', 'create_tribe_page'); https://variabletribe.com/wp-sitemap-posts-post-1.xmlhttps://variabletribe.com/wp-sitemap-posts-page-1.xmlhttps://variabletribe.com/wp-sitemap-posts-product-1.xmlhttps://variabletribe.com/wp-sitemap-posts-graduate-1.xmlhttps://variabletribe.com/wp-sitemap-posts-book-1.xmlhttps://variabletribe.com/wp-sitemap-posts-vocabulary-1.xmlhttps://variabletribe.com/wp-sitemap-posts-vocabulary-2.xmlhttps://variabletribe.com/wp-sitemap-posts-challenge-1.xmlhttps://variabletribe.com/wp-sitemap-posts-audio_podcast-1.xmlhttps://variabletribe.com/wp-sitemap-posts-variable_book-1.xmlhttps://variabletribe.com/wp-sitemap-posts-audio_event-1.xmlhttps://variabletribe.com/wp-sitemap-taxonomies-category-1.xmlhttps://variabletribe.com/wp-sitemap-taxonomies-post_tag-1.xmlhttps://variabletribe.com/wp-sitemap-taxonomies-product_cat-1.xmlhttps://variabletribe.com/wp-sitemap-taxonomies-product_tag-1.xmlhttps://variabletribe.com/wp-sitemap-taxonomies-book_category-1.xmlhttps://variabletribe.com/wp-sitemap-taxonomies-vocab_category-1.xml