That works well. It also led to a third way. As a result, to put it into a larger context, I now have a working script which can access MySQL tables from a defunct WordPress instance and produce static HTML in a file system hierarchy matching the structure in the original WordPress URLs. That's not generic enough to package, but might get shown to the public later this year.
Going slightly off-topic, one hard part was that WordPress comments are nested and SQL is not as suited for that as a regular key-value database. So a recursive query was needed. I had to cargo cult that, but creating a matching Perl routine to process the recursive query (once I had the query) was rather easy.
. . .
my $query = qq(
with recursive cte (comment_ID, comment_post_ID, comment_author
+, comment_parent,
comment_date_gmt, comment_type, comment_con
+tent) as (
select comment_ID,
comment_post_ID,
comment_author,
comment_parent,
comment_date_gmt,
comment_type,
comment_content
from wp_comments
where comment_ID = ? AND comment_approved = 1
union all
select p.comment_ID,
p.comment_post_ID,
p.comment_author,
p.comment_parent,
p.comment_date_gmt,
p.comment_type,
p.comment_content
from wp_comments p
inner join cte
on p.comment_parent = cte.comment_ID
)
SELECT *
FROM cte ORDER BY comment_date_gmt;
);
my $sth = $dbh->prepare($query);
$sth->execute($id);
while(my $row = $sth->fetchrow_hashref) {
my $cid = $row->{comment_ID};
my $parent_id = $row->{comment_parent};
my $post_id = $row->{comment_post_ID};
if ($parent_id eq 0) {
push(@{$posts{$post_id}}, $cid);
}
$comments{$cid}->{comment_post_ID} = $row->{comment_post_ID};
$comments{$cid}->{comment_parent} = $row->{comment_parent};
$comments{$cid}->{comment_author} = $row->{comment_author};
$comments{$cid}->{comment_date_gmt} = $row->{comment_date_gmt}
+;
my $content = $row->{comment_content};
$content =~ s|(\s*)\n(\s*)\n|$1<br />\n$2<br />\n|gm;
$comments{$cid}->{comment_content} = $content;
push (@{$hierarchy{$parent_id}}, $cid);
}
$sth->finish();
. . .
The matching subroutine has to be recursive:
sub render {
my ($layer, $k, $comments, $hierarchy) = (@_);
my $comment = $hierarchy{$k};
if (!defined($comment)){
return(0);
}
$layer++;
my $ul = HTML::Element->new('ul');
my $count = 0;
foreach my $c (@{$comment}) {
my $li = HTML::Element->new('li');
$li->attr('id', "comment$c");
my $p1 = HTML::Element->new('p');
$p1->attr('class','author');
$p1->push_content($comments{$c}->{comment_author} );
$li->push_content($p1);
my $p2 = HTML::Element->new('p');
$p2->attr('class','date');
$p2->push_content($comments{$c}->{comment_date_gmt});
$li->push_content($p2);
my $div = HTML::Element->new('div');
$div->attr('class','words');
$div->push_content($comments{$c}->{comment_content});
$li->push_content($div);
$ul->push_content($li);
print "."x$layer,$c,"\n" if ($VERBOSE);
my $html = &render($layer, $c, $comments, $hierarchy);
if ($html) {
$ul->push_content($html);
$count++;
}
}
return($ul);
}
The stringification now happens higher up in the work flow.
Thanks, and thanks to all who read and or replied.
|