I have a callback function for another function that loops through the comments of an article in my blog. I now tried to switch to “threaded/nested” comments and therefore extended the callback function. So far everything works, but i can’t get rid of the feeling, that i didn’t write it according to best php-practice (and performance).
I use a css framework and have to do some math for the .span-xy classes i assign to the single comments. I start with an input value from a global constant and output eg. span-12 for a parent comment. Then i have to reduce/rise the value per +/- (int) 1 for every level of nesting. So i came to building arrays, counting them, iterating through and building temp arrays for every comment.
Question:
Is there an easier way to get around this?
<!-- This is the final html mark-up output: List of comments (threaded/nested) -->
<ul>
<li id="1" class="push-<?php echo $push; ?> span-<?php echo $span; ?>">comment - parent</li>
<li id="2">comment - child of #1
<ul class="children">
<li id="3">comment - child of #2
<li id="4">comment - child of #2
<ul class="children">
<li id="5">comment - child of #4</li>
</ul>
<li id="6">comment - child of #2</li>
</ul>
<li id="7">comment - child of #2
<ul class="children">
<li id="8">comment - child of #7</li>
<li id="9">comment - child of #7</li>
</ul>
</li>
</li>
</ul>
<?php
// This is my callback function
function comment_list_cb( $comment, $args, $depth )
{
// retrieve the data from the globals or make them available
$GLOBALS['comment'] = $comment;
global $post;
static $width = MY_GLOBAL_WIDTH_CONSTANT;
static $ancestors = null;
// is Child/Parent comment
$parent = (int) $comment->comment_parent; // retrieve the ID of the parent
$is_child = false;
if ( $parent > (int) 0 ) // if we got a parent
{
$is_child = true;
if ( ! (array) $ancestors )
$ancestors = array();
if ( ! array_key_exists( $parent, $ancestors ) )
{
$ancestors[$parent] = get_comment_ID();
}
else
{
foreach ( $ancestors as $parent_id => $child_id )
{
if ( $parent_id == $parent )
{
$ancestors_temp[$parent_id] = $child_id;
break;
}
$ancestors_temp[$parent_id] = $child_id;
}
$ancestors = $ancestors_temp;
}
$parent_counter = count( $ancestors );
$span = $width - (int) $parent_counter;
}
else
{
$ancestors = $parent_counter = null;
$span = MY_GLOBAL_WIDTH_CONSTANT;
}
$span_txt = $span - (int) 2; // reduce per `2` because of the span-2 class at the avatar element
// now: build the classes
$push = $parent_counter != (int) 0 ? 'push-1' : '';
$child = $is_child === true ? ' child ' : '';
$list = comment_class( 'span-'.$span.' '.$push.' append-bottom last hreview comment-'.get_comment_ID().' '.$microid, get_comment_ID(), $post->ID, false );
?>
<!-- build the comment -->
<li <?php echo $list; ?>>
<div id="<?php get_comment_ID(); ?>">
<span class="comment-avatar span-2"><!-- display avatar img - width is span-2 --></span>
<span class="comment-meta span-<?php echo $span_txt; ?> last"><!-- display meta data like timestamp, etc. --></span>
<span class="comment-text span-<?php echo $span_txt; ?> last"><!-- display message --></span>
</div>
</li>
<?php
}
Just some general comments after a quick scan. It deals with the coding, irrespective of functionality.
Why are you putting this in global scope? This can overwrite an existing global variable. Passing by reference may be more appropriate here.
Why is this static? Value is never changed so there’s no need to retain.
No need to cast int literal to int. If you want int comparison, it’s the variable you should be casting.
If empty array, make empty array? Just do
!isset($ancestors)