|
@@ -252,62 +252,91 @@ class WordPressImport {
|
|
|
$imported = 0;
|
|
$imported = 0;
|
|
|
$skipped = 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();
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ // Get WordPress posts with author info in one query
|
|
|
|
|
+ $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,
|
|
|
|
|
+ u.display_name as author_name
|
|
|
|
|
+ FROM wp_posts p
|
|
|
|
|
+ LEFT JOIN wp_users u ON p.post_author = u.ID
|
|
|
|
|
+ WHERE p.post_type = 'post' AND p.post_status IN ('publish', 'draft')
|
|
|
|
|
+ ORDER BY p.post_date
|
|
|
|
|
+ LIMIT 1000
|
|
|
|
|
+ ");
|
|
|
|
|
+
|
|
|
|
|
+ $posts = $stmt->fetchAll();
|
|
|
|
|
+
|
|
|
|
|
+ // Get all categories for all posts in one query
|
|
|
|
|
+ $postIds = array_column($posts, 'ID');
|
|
|
|
|
+ $categoriesMap = [];
|
|
|
|
|
+
|
|
|
|
|
+ if (!empty($postIds)) {
|
|
|
|
|
+ $placeholders = str_repeat('?,', count($postIds) - 1) . '?';
|
|
|
|
|
+ $categoriesStmt = $this->wpDb->prepare("
|
|
|
|
|
+ SELECT tr.object_id as post_id, t.name as category_name
|
|
|
|
|
+ FROM wp_term_relationships tr
|
|
|
|
|
+ JOIN wp_term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
|
|
|
|
|
+ JOIN wp_terms t ON tt.term_id = t.term_id
|
|
|
|
|
+ WHERE tt.taxonomy = 'category' AND tr.object_id IN ($placeholders)
|
|
|
|
|
+ ");
|
|
|
|
|
+ $categoriesStmt->execute($postIds);
|
|
|
|
|
|
|
|
- // Link categories
|
|
|
|
|
- if (!empty($categories)) {
|
|
|
|
|
- $this->linkPostCategories($publicationId, $categories);
|
|
|
|
|
|
|
+ foreach ($categoriesStmt->fetchAll() as $cat) {
|
|
|
|
|
+ $categoriesMap[$cat['post_id']][] = $cat['category_name'];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($posts as $wpPost) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 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';
|
|
|
|
|
+
|
|
|
|
|
+ // Use author name from query or fallback
|
|
|
|
|
+ $author = $wpPost['author_name'] ?: 'Unknown Author';
|
|
|
|
|
+
|
|
|
|
|
+ // Get categories from preloaded map
|
|
|
|
|
+ $categories = $categoriesMap[$wpPost['ID']] ?? [];
|
|
|
|
|
+
|
|
|
|
|
+ // 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');
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- $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');
|
|
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ } catch (Exception $e) {
|
|
|
|
|
+ $this->errors[] = "Error in posts import: " . $e->getMessage();
|
|
|
|
|
+ $this->log("Error in posts import: " . $e->getMessage(), 'error');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
$this->log("Posts import completed: {$imported} imported, {$skipped} skipped");
|
|
$this->log("Posts import completed: {$imported} imported, {$skipped} skipped");
|
|
@@ -322,77 +351,103 @@ class WordPressImport {
|
|
|
$imported = 0;
|
|
$imported = 0;
|
|
|
$skipped = 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;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ // Get WordPress comments with post info in one query
|
|
|
|
|
+ $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,
|
|
|
|
|
+ p.post_name, p.post_title
|
|
|
|
|
+ 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
|
|
|
|
|
+ LIMIT 2000
|
|
|
|
|
+ ");
|
|
|
|
|
+
|
|
|
|
|
+ $comments = $stmt->fetchAll();
|
|
|
|
|
+
|
|
|
|
|
+ // Build a map of post IDs to publication IDs
|
|
|
|
|
+ $postIds = array_unique(array_column($comments, 'comment_post_ID'));
|
|
|
|
|
+ $publicationMap = [];
|
|
|
|
|
+
|
|
|
|
|
+ if (!empty($postIds)) {
|
|
|
|
|
+ $placeholders = str_repeat('?,', count($postIds) - 1) . '?';
|
|
|
|
|
+ $pubStmt = $this->targetDb->prepare("
|
|
|
|
|
+ SELECT id, slug, title FROM publications
|
|
|
|
|
+ WHERE slug IN ($placeholders) OR title IN ($placeholders)
|
|
|
|
|
+ ");
|
|
|
|
|
|
|
|
- // Map comment status
|
|
|
|
|
- $status = ($wpComment['comment_approved'] === '1') ? 'approved' : 'pending';
|
|
|
|
|
|
|
+ // Duplicate the post IDs for slug and title matching
|
|
|
|
|
+ $allParams = array_merge($postIds, $postIds);
|
|
|
|
|
+ $pubStmt->execute($allParams);
|
|
|
|
|
|
|
|
- // 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'];
|
|
|
|
|
|
|
+ foreach ($pubStmt->fetchAll() as $pub) {
|
|
|
|
|
+ // Map both slug and title for easier lookup
|
|
|
|
|
+ $publicationMap[strtolower($pub['slug'])] = $pub['id'];
|
|
|
|
|
+ $publicationMap[strtolower($pub['title'])] = $pub['id'];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($comments as $wpComment) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // Find corresponding publication using preloaded map
|
|
|
|
|
+ $publicationId = null;
|
|
|
|
|
+ $postSlug = !empty($wpComment['post_name']) ? strtolower($wpComment['post_name']) : null;
|
|
|
|
|
+ $postTitle = strtolower($wpComment['post_title']);
|
|
|
|
|
+
|
|
|
|
|
+ if ($postSlug && isset($publicationMap[$postSlug])) {
|
|
|
|
|
+ $publicationId = $publicationMap[$postSlug];
|
|
|
|
|
+ } elseif (isset($publicationMap[$postTitle])) {
|
|
|
|
|
+ $publicationId = $publicationMap[$postTitle];
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ if (!$publicationId) {
|
|
|
|
|
+ $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 (skip for now to avoid complexity)
|
|
|
|
|
+ $parentId = null;
|
|
|
|
|
+
|
|
|
|
|
+ // Insert comment
|
|
|
|
|
+ $this->targetDb->execute(
|
|
|
|
|
+ "INSERT INTO comments (publication_id, parent_id, name, email, content, status, created_at, admin_reply)
|
|
|
|
|
+ VALUES (?, ?, ?, ?, ?, ?, ?, FALSE)",
|
|
|
|
|
+ [
|
|
|
|
|
+ $publicationId,
|
|
|
|
|
+ $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');
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- // 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');
|
|
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ } catch (Exception $e) {
|
|
|
|
|
+ $this->errors[] = "Error in comments import: " . $e->getMessage();
|
|
|
|
|
+ $this->log("Error in comments import: " . $e->getMessage(), 'error');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
$this->log("Comments import completed: {$imported} imported, {$skipped} skipped");
|
|
$this->log("Comments import completed: {$imported} imported, {$skipped} skipped");
|