I talked earlier about landing a deal with “b5media”:http://www.b5media.com to implement a migration script to move their 32 new blogs into WordPress. I thought the deal would be straightforward enough but I ran into a number of issues with the importer.
I wanted to give you a window into the process of debugging for one MAJOR issue. For reference, here is “the original nucleus.php file”:http://www.technosailor.com/nucleus.phps I began debugging with this afternoon.
h3. Issue Reported: Not all comments Seemed to be imported
As a first run, we imported a blog called “The Beauty Blog”:http://www.aboutweblogs.com/beauty/. It was noted that it did not appear all comments were imported as there were some missing. As a point of reference, one entry on the original blog entitled “My Solution for Buildup”:http://www.aboutweblogs.com/beauty/?itemid=2608 had 4 distinct comments from 2 users.
However, upon import and viewing in the new WordPress blog, only 2 comments showed up by the same user
h3. How I figured things out
I will let you dissect the script to find out the basis of what happens. However, we know that the problem seemed to be happening on the execution of the import_comments() function.
From the code, this function looks like this:
[php]function import_comments()
{
// Comment Import
$comments = $this->get_nuc_comments();
$this->comments2wp($comments);
_e(’<form action=”admin.php?import=nucleus&step=6″ method=”post”>’);
_e(’<input type=”submit” name=”submit” value=”Import Links” />’);
_e(’</form>’);
}
[/php]
This bit of code tells us that first we are going to run the get_nuc_comments() function which will gather all the comment data from Nucleus into an associative array and return the data to a variable $comments. We will then pass $comments to comments2wp() where the data will be passed to the WordPress API and inserted into the new WordPress blog.
We know something is going wrong in this process so let’s start at the top… get_nuc_comments(). This function looks like this:
[php]
function get_nuc_comments()
{
// General Housekeeping
global $nucdb;
set_magic_quotes_runtime(0);
$nuc_com = array();
$prefix = get_option(’npre’);
$blog_id = get_option(’blog_id’);
$storedUsers = $nucdb->get_results(”SELECT cmember FROM nucleus_comment”);
foreach($storedUsers as $su)
{
if(0 d;d; $su->cmember)
{
return $nucdb->get_results(’SELECT
cnumber,
cbody,
cuser,
cemail,
citem,
ctime,
chost,
cip
FROM nucleus_comment
WHERE cblog = ‘.$blog_id,
ARRAY_A);
}
else
{
return $nucdb->get_results(’SELECT
cnumber,
cbody,
mname AS cuser,
memail AS cemail,
murl AS curl,
citem,
ctime,
chost,
cip
FROM nucleus_comment, nucleus_member
WHERE cmember=mnumber
AND cblog = ‘.$blog_id,
ARRAY_A);
}
}
return false;
}[/php]
Now, most of this function is direct database queries from the Nucleus database. The schema of the two tables referenced (nucleus_comment and nucleus_member) are as follows:
nD@0,IrW&nܞz]M93T,rz{[ܭ{M93T,ˬzڭZyT,ɚ[ڭZ]4uں[MPۯ&zfޮ)W^}-r+^)SNL-ןjmmzٺrئy֭zئxӓ5Buں[|^M4M4M4ٺr,rG^}-r*oj!jy4Py6V]M93T,^}͵O6fڶ)){x4Py6<ۍ `r{mۯ!(Fz'fޭ(Fצr+^BLE(Fnrqɺш4
Nucleus has a feature similar to WordPress in that if a member exists as a result of signing up for an account, they are stored in the nucleus_member database. However, having a membership is not required to comment on a Nucleus blog. As a result, Nucleus stores comments with all the standard comment information (email, name, IP address, etc) and stores a 0 in the cmember field if the user is NOT a Nucleus member. However, if the member *is* a member, cmember stores their member ID number and leaves the name and email fields blank because it will get the stored member information in nucleus_member.
Make sense? It did to me too until I started debugging! The get_nuc_comments(), in theory, worked like this:
# Get the cmember field for all the comments
# Loop through the cmember fields
# If the cmember field was equal to 0 (not a member), then perform a direct query only on the nucleus_comment table
# If the cmember field was NOT equal to 0 (is a member commenting), then perform a query getting the comment data from the nucleus_comment table and the associated member information from the nucleus_member table.
# return the data for use in the comments2wp() function
Looking over my code for errors, the first thing I noticed was that in my first query, I used a field “cemail” when, from the schema, that field should be “cmail”. I changed the alias name in the second query as well for consistency, but knew that that second query should not fail because we were actually selecting “memail” from the members table and that field _did_ exist!
I figured this was the solution to the problem. This query was failing because the field name was incorrect and somewhere along the line, it was _failing silently!_ Saved the file and re-ran the import. No errors reported, however that post that should have 4 comments, still only had the same 2.
Sigh. Back to the drawing board. Let’s look back at that code.
Ahha! Do you see what I see? I’m returning both of those queries. In PHP, Perl, C++ and most languages of similar syntax, a return means that the function is completed and the data that is being returned is what should be kicked back out. Only one query should be getting run, right?
So I made the following change to the code:
[php]
function get_nuc_comments()
{
// General Housekeeping
global $nucdb;
set_magic_quotes_runtime(0);
$nuc_com = array();
$prefix = get_option(’npre’);
$blog_id = get_option(’blog_id’);
$storedUsers = $nucdb->get_results(”SELECT cmember FROM nucleus_comment”);
foreach($storedUsers as $su)
{
if(0 == $su->cmember)
{
$com = $nucdb->get_results(’SELECT
cnumber,
cbody,
cuser,
cemail,
citem,
ctime,
chost,
cip
FROM nucleus_comment
WHERE cblog = ‘.$blog_id,
ARRAY_A);
}
array_push($nuc_com, $com);
else
{
$com = $nucdb->get_results(’SELECT
cnumber,
cbody,
mname AS cuser,
memail AS cemail,
murl AS curl,
citem,
ctime,
chost,
cip
FROM nucleus_comment, nucleus_member
WHERE cmember=mnumber
AND cblog = ‘.$blog_id,
ARRAY_A);
array_push($nuc_com, $com);
}
return $nuc_com;
}
return false;
}[/php]
This change would assign each query result to a variable, $com and then use the "array_push()":http://www.php.net/array_push function to push the resulting array onto the end of the $nuc_com array.
Save. Load. Execute. Failure.
Now I’m getting pissed. This should work.
Let’s see what the $nuc_com array contains. Drop this right before the return $nuc_com; and reload.
[php]
echo’<pre>’;
print_r($nuc_com);
echo’</pre>’;
exit;
[/php]
Kicked out is a long nested array looking similar to (changing details to protect the innocent):
nnۯ
Well this is not very useful on it’s face because I need to know how many of these commenters have a cmember value of 0 or non-zero. This will tell me if only one of the queries is being executed or if both are. I added “cmember” to both of the SELECT queries and re-executed.
nnۯ
Scanning the resulting output, I see that all of the results have non-zero cmember values. Not good. Obviosuly, only the second query is being executed. When this happens, the first place I look to is the conditional — the if/else statement. IF something is true, then run this code, OTHERWISE run that code. In our case _that_ code was running and _this_ code never was.
To be continued…


Add New Comment
Viewing 6 Comments
Thanks. Your comment is awaiting approval by a moderator.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
I usually use PEAR's Log class, and I have xdebug installed (and profiling enabled).
It's a great help :)
Do you already have an account? Log in and claim this comment.
My brain. :-)
Do you already have an account? Log in and claim this comment.
You obviously don't stare at php code for 60+ hours a week ;P
BTW, fix those code blocks... the double spacing is making me go blind :P
Do you already have an account? Log in and claim this comment.
I get parse errors every time I submit a comment, however they are submitted anyways :)
-- eric
Do you already have an account? Log in and claim this comment.
kidding, of course.
YEah it's the Subscribe to Comments plugin. I need to address it but, as you pointed out, it doesn't prevent commenting or subscibing so it's not at the top of the priority list at the moment. Thanks though.
Add New Comment