wpConfig = $wpConfig; $this->targetDb = Database::getInstance(); $this->connectWordPress(); } /** * Connect to WordPress database */ private function connectWordPress() { try { $dsn = "mysql:host={$this->wpConfig['host']};dbname={$this->wpConfig['database']};charset=utf8mb4"; $this->wpDb = new PDO($dsn, $this->wpConfig['username'], $this->wpConfig['password']); $this->wpDb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->wpDb->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); $this->log('Connected to WordPress database successfully'); } catch (Exception $e) { throw new Exception("Failed to connect to WordPress database: " . $e->getMessage()); } } /** * Test WordPress connection and verify structure */ public function testConnection() { try { // Check if WordPress tables exist $tables = ['wp_posts', 'wp_users', 'wp_terms', 'wp_term_taxonomy', 'wp_term_relationships', 'wp_comments']; $existingTables = []; foreach ($tables as $table) { $stmt = $this->wpDb->query("SHOW TABLES LIKE '{$table}'"); if ($stmt->rowCount() > 0) { $existingTables[] = $table; } } if (count($existingTables) < 6) { throw new Exception("WordPress database structure incomplete. Missing tables: " . implode(', ', array_diff($tables, $existingTables))); } // Get basic stats $stats = [ 'posts' => $this->getPostCount(), 'pages' => $this->getPageCount(), 'categories' => $this->getCategoryCount(), 'users' => $this->getUserCount(), 'comments' => $this->getCommentCount() ]; return ['success' => true, 'stats' => $stats, 'tables' => $existingTables]; } catch (Exception $e) { return ['success' => false, 'error' => $e->getMessage()]; } } /** * Import all WordPress data */ public function importAll($options = []) { $results = []; try { // Start transaction $this->targetDb->beginTransaction(); // Import categories first (posts depend on them) if ($options['import_categories'] ?? true) { $results['categories'] = $this->importCategories(); } // Import users if ($options['import_users'] ?? true) { $results['users'] = $this->importUsers(); } // Import posts if ($options['import_posts'] ?? true) { $results['posts'] = $this->importPosts(); } // Import comments if ($options['import_comments'] ?? true) { $results['comments'] = $this->importComments(); } // Commit transaction $this->targetDb->commit(); $this->log('Import completed successfully'); return ['success' => true, 'results' => $results, 'log' => $this->importLog]; } catch (Exception $e) { $this->targetDb->rollBack(); $this->errors[] = $e->getMessage(); $this->log('Import failed: ' . $e->getMessage(), 'error'); return ['success' => false, 'error' => $e->getMessage(), 'log' => $this->importLog, 'errors' => $this->errors]; } } /** * Import WordPress categories */ public function importCategories() { $this->log('Starting categories import'); $imported = 0; $skipped = 0; // Get WordPress categories $stmt = $this->wpDb->query(" SELECT t.name, tt.description, tt.term_id FROM wp_terms t JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id WHERE tt.taxonomy = 'category' ORDER BY t.name "); $categories = $stmt->fetchAll(); foreach ($categories as $wpCategory) { try { // Check if category already exists $existing = $this->targetDb->fetch( "SELECT id FROM categories WHERE name = ?", [$wpCategory['name']] ); if ($existing) { $skipped++; $this->log("Category '{$wpCategory['name']}' already exists, skipping"); continue; } // Insert new category $this->targetDb->execute( "INSERT INTO categories (name, description, created_at) VALUES (?, ?, NOW())", [ $wpCategory['name'], $wpCategory['description'] ?? '' ] ); $imported++; $this->log("Imported category: {$wpCategory['name']}"); } catch (Exception $e) { $this->errors[] = "Error importing category '{$wpCategory['name']}': " . $e->getMessage(); $this->log("Error importing category '{$wpCategory['name']}': " . $e->getMessage(), 'error'); } } $this->log("Categories import completed: {$imported} imported, {$skipped} skipped"); return ['imported' => $imported, 'skipped' => $skipped]; } /** * Import WordPress users */ public function importUsers() { $this->log('Starting users import'); $imported = 0; $skipped = 0; // Get WordPress users $stmt = $this->wpDb->query(" SELECT ID, user_login, user_email, user_nicename, user_registered, display_name FROM wp_users WHERE user_status = 0 ORDER BY ID "); $users = $stmt->fetchAll(); foreach ($users as $wpUser) { try { // Check if user already exists $existing = $this->targetDb->fetch( "SELECT id FROM users WHERE username = ?", [$wpUser['user_login']] ); if ($existing) { $skipped++; $this->log("User '{$wpUser['user_login']}' already exists, skipping"); continue; } // Determine user role (WordPress usermeta table) $role = $this->getUserRole($wpUser['ID']); // Insert new user $this->targetDb->execute( "INSERT INTO users (username, email, role, auth_type, created_at) VALUES (?, ?, ?, 'wordpress', ?)", [ $wpUser['user_login'], $wpUser['user_email'], $role, $wpUser['user_registered'] ] ); $imported++; $this->log("Imported user: {$wpUser['user_login']} (role: {$role})"); } catch (Exception $e) { $this->errors[] = "Error importing user '{$wpUser['user_login']}': " . $e->getMessage(); $this->log("Error importing user '{$wpUser['user_login']}': " . $e->getMessage(), 'error'); } } $this->log("Users import completed: {$imported} imported, {$skipped} skipped"); return ['imported' => $imported, 'skipped' => $skipped]; } /** * Import WordPress posts */ public function importPosts() { $this->log('Starting posts import'); $imported = 0; $skipped = 0; // Get WordPress posts (only published posts, not pages) $stmt = $this->wpDb->query(" SELECT p.ID, p.post_title, p.post_content, p.post_excerpt, p.post_date, p.post_modified, p.post_status, p.post_author, p.post_name FROM wp_posts p WHERE p.post_type = 'post' AND p.post_status IN ('publish', 'draft') ORDER BY p.post_date "); $posts = $stmt->fetchAll(); foreach ($posts as $wpPost) { try { // Get author name $author = $this->getAuthorName($wpPost['post_author']); // Get post categories $categories = $this->getPostCategories($wpPost['ID']); // Generate slug from post_name or title $slug = !empty($wpPost['post_name']) ? $wpPost['post_name'] : $this->generateSlug($wpPost['post_title']); // Map WordPress status to our status $status = ($wpPost['post_status'] === 'publish') ? 'published' : 'draft'; // Insert post $this->targetDb->execute( "INSERT INTO publications (title, slug, content, summary, author, status, created_at, updated_at, published_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", [ $wpPost['post_title'], $slug, $this->processContent($wpPost['post_content']), $wpPost['post_excerpt'] ?? '', $author, $status, $wpPost['post_date'], $wpPost['post_modified'], ($status === 'published') ? $wpPost['post_date'] : null ] ); $publicationId = $this->targetDb->lastInsertId(); // Link categories if (!empty($categories)) { $this->linkPostCategories($publicationId, $categories); } $imported++; $this->log("Imported post: '{$wpPost['post_title']}'"); } catch (Exception $e) { $this->errors[] = "Error importing post '{$wpPost['post_title']}': " . $e->getMessage(); $this->log("Error importing post '{$wpPost['post_title']}': " . $e->getMessage(), 'error'); } } $this->log("Posts import completed: {$imported} imported, {$skipped} skipped"); return ['imported' => $imported, 'skipped' => $skipped]; } /** * Import WordPress comments */ public function importComments() { $this->log('Starting comments import'); $imported = 0; $skipped = 0; // Get WordPress comments $stmt = $this->wpDb->query(" SELECT c.comment_ID, c.comment_post_ID, c.comment_author, c.comment_author_email, c.comment_content, c.comment_date, c.comment_approved, c.comment_parent FROM wp_comments c JOIN wp_posts p ON c.comment_post_ID = p.ID WHERE p.post_type = 'post' ORDER BY c.comment_date "); $comments = $stmt->fetchAll(); foreach ($comments as $wpComment) { try { // Find corresponding publication $publication = $this->targetDb->fetch( "SELECT id FROM publications WHERE slug = ? OR title = ? LIMIT 1", [$this->getPostSlugById($wpComment['comment_post_ID']), $this->getPostTitleById($wpComment['comment_post_ID'])] ); if (!$publication) { $skipped++; $this->log("Comment skipped - no matching publication found for post ID {$wpComment['comment_post_ID']}"); continue; } // Map comment status $status = ($wpComment['comment_approved'] === '1') ? 'approved' : 'pending'; // Handle parent comment $parentId = null; if ($wpComment['comment_parent'] > 0) { $parentComment = $this->targetDb->fetch( "SELECT id FROM comments WHERE wp_comment_id = ?", [$wpComment['comment_parent']] ); if ($parentComment) { $parentId = $parentComment['id']; } } // Insert comment $this->targetDb->execute( "INSERT INTO comments (publication_id, parent_id, name, email, content, status, created_at, admin_reply) VALUES (?, ?, ?, ?, ?, ?, ?, FALSE)", [ $publication['id'], $parentId, $wpComment['comment_author'], $wpComment['comment_author_email'], $wpComment['comment_content'], $status, $wpComment['comment_date'] ] ); $commentId = $this->targetDb->lastInsertId(); // Store WordPress comment ID for parent mapping $this->targetDb->execute( "UPDATE comments SET wp_comment_id = ? WHERE id = ?", [$wpComment['comment_ID'], $commentId] ); $imported++; $this->log("Imported comment for post ID {$wpComment['comment_post_ID']}"); } catch (Exception $e) { $this->errors[] = "Error importing comment: " . $e->getMessage(); $this->log("Error importing comment: " . $e->getMessage(), 'error'); } } $this->log("Comments import completed: {$imported} imported, {$skipped} skipped"); return ['imported' => $imported, 'skipped' => $skipped]; } /** * Helper methods */ private function getUserRole($userId) { $stmt = $this->wpDb->prepare(" SELECT meta_value FROM wp_usermeta WHERE user_id = ? AND meta_key = 'wp_capabilities' "); $stmt->execute([$userId]); $capabilities = $stmt->fetchColumn(); if ($capabilities && strpos($capabilities, 'administrator') !== false) { return 'admin'; } return 'editor'; // Default role } private function getAuthorName($authorId) { $stmt = $this->wpDb->prepare("SELECT display_name FROM wp_users WHERE ID = ?"); $stmt->execute([$authorId]); $name = $stmt->fetchColumn(); return $name ?: 'Unknown Author'; } private function getPostCategories($postId) { $stmt = $this->wpDb->prepare(" SELECT t.name FROM wp_terms t JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id WHERE tr.object_id = ? AND tt.taxonomy = 'category' "); $stmt->execute([$postId]); return $stmt->fetchAll(PDO::FETCH_COLUMN); } private function getPostSlugById($postId) { $stmt = $this->wpDb->prepare("SELECT post_name FROM wp_posts WHERE ID = ?"); $stmt->execute([$postId]); return $stmt->fetchColumn() ?: ''; } private function getPostTitleById($postId) { $stmt = $this->wpDb->prepare("SELECT post_title FROM wp_posts WHERE ID = ?"); $stmt->execute([$postId]); return $stmt->fetchColumn() ?: ''; } private function linkPostCategories($publicationId, $categories) { foreach ($categories as $categoryName) { $category = $this->targetDb->fetch( "SELECT id FROM categories WHERE name = ?", [$categoryName] ); if ($category) { $this->targetDb->execute( "INSERT IGNORE INTO publication_categories (publication_id, category_id) VALUES (?, ?)", [$publicationId, $category['id']] ); } } } private function processContent($content) { // Basic WordPress content processing // You can extend this to handle shortcodes, etc. $content = str_replace('[caption]', '', $content); $content = str_replace('[/caption]', '', $content); $content = preg_replace('/\[gallery.*?\]/', '', $content); return $content; } private function generateSlug($title) { $slug = strtolower($title); $slug = preg_replace('/[^a-z0-9]+/', '-', $slug); $slug = trim($slug, '-'); return $slug; } private function log($message, $level = 'info') { $this->importLog[] = [ 'timestamp' => date('Y-m-d H:i:s'), 'level' => $level, 'message' => $message ]; } /** * Get statistics methods */ public function getPostCount() { $stmt = $this->wpDb->query("SELECT COUNT(*) FROM wp_posts WHERE post_type = 'post'"); return $stmt->fetchColumn(); } public function getPageCount() { $stmt = $this->wpDb->query("SELECT COUNT(*) FROM wp_posts WHERE post_type = 'page'"); return $stmt->fetchColumn(); } public function getCategoryCount() { $stmt = $this->wpDb->query(" SELECT COUNT(*) FROM wp_term_taxonomy WHERE taxonomy = 'category' "); return $stmt->fetchColumn(); } public function getUserCount() { $stmt = $this->wpDb->query("SELECT COUNT(*) FROM wp_users"); return $stmt->fetchColumn(); } public function getCommentCount() { $stmt = $this->wpDb->query("SELECT COUNT(*) FROM wp_comments"); return $stmt->fetchColumn(); } /** * Get import log */ public function getLog() { return $this->importLog; } /** * Get errors */ public function getErrors() { return $this->errors; } }