You are viewing a read-only archive of the Blogs.Harvard network. Learn more.

Troubleshooting myself in the foot.

Category: code

who needs documentation when you have the source?

closing comments on wordpress multisite

There are some wordpress plugins out there that close comments on blogs as well as enable the admin of the blog to enable it site-wide. I wasn’t too interested in putting a plugin in place, although I figured if I could just write a code snippit to do this for me I would be happy. The code below is the result of my snippit efforts.

What this does is make a list of all the blogs (assuming your table prefix is wp_) on your multisite install. Then it checks to see if a blog has been blogged on since X months (I have 12 months in here, but you can change that to whatever suits your needs).

Once those conditions are set, the code sets two comment related options. The first is turning on akismet auto-delete of spam. We found that many of the older blogs on our multisite install had multiple tens of thousands of spam comments hanging around – no need for that. The second is enabling auto-closing of comments on posts older than 60 days (again you can change that to suit your needs).

To run it – you need to fill in the db info on the top (hostname, db, user, pw) and then just run it with the php cli. I hope this can help out someone and serve as a starting point where I had to start from scratch.

$mysqli = new mysqli("hostname", "user", "password", "database");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;

# set debug

# get all the blogs
$tables_res = $mysqli->query("show tables like 'wp_%_options'");

while ( $tables_row = $tables_res->fetch_row() ){
list($blog_wpmu,$blog_id,$blog_options) = explode("_", $tables_row[0]);
$bloginfo_res = $mysqli->query("select * from wp_${blog_id}_options where option_name='siteurl'");
$bloginfo_row = $bloginfo_res->fetch_assoc();
$blog_url = $bloginfo_row['option_value'];

# check to see if blog has been updated in the last year
if ($updated_res = $mysqli->query("select id from wp_${blog_id}_posts where post_status = 'publish' and date_add(post_date, interval 12 month) > now() limit 1")) {
$updated_row_cnt = mysqli_num_rows($updated_res);
if ($updated_row_cnt == 0) {

# check and set akismet to auto-delete spam
$akismet_res = $mysqli->query("select * from wp_${blog_id}_options where option_name='akismet_discard_month'");
$akismet_row_cnt = mysqli_num_rows($akismet_res);
if ($akismet_row_cnt == 0) {
# set auto-delete
$mysqli->query("insert into wp_${blog_id}_options (option_name,option_value,autoload) values ('akismet_discard_month','true','yes')");
} else {
$akismet_row = $akismet_res->fetch_assoc();
if ( $akismet_row['option_value'] != "true" || $akismet_row['autoload'] != "yes" ) {
# set auto-delete
$mysqli->query("update wp_${blog_id}_options set option_value='true',autoload='yes' where option_name='akismet_discard_month'");
if ($debug == 1) {
echo "akismet set but not enabled on $blog_url ($blog_id)\n";
# check and set comments to auto-close
$comments_res = $mysqli->query("select * from wp_${blog_id}_options where option_name like 'close_comments_%' order by option_id");
$comments_row_cnt = mysqli_num_rows($comments_res);
if ($comments_row_cnt == 0) {
# set comments to auto-close
$mysqli->query("insert into wp_${blog_id}_options (option_name,option_value,autoload) values ('close_comments_days_old','60','yes')");
$mysqli->query("insert into wp_${blog_id}_options (option_name,option_value,autoload) values ('close_comments_for_old_posts','1','yes')");
} else {
while ( $comments_row = $comments_res->fetch_assoc()) {
if ( $comments_row['option_name'] == "close_comments_days_old" && $comments_row['option_value'] != 60 ) {
# set comments to auto-close in 60 days
$mysqli->query("update wp_${blog_id}_options set option_value='60',autoload='yes' where option_name='close_comments_days_old'");
if ($debug == 1) {
echo "days_old set to ". $comments_row['option_value']." on ".$blog_url." (".$blog_id.")\n";
if ( $comments_row['option_name'] == "close_comments_for_old_posts" && $comments_row['option_value'] == 0 ) {
# set comments to auto-close
$mysqli->query("update wp_${blog_id}_options set option_value='1',autoload='yes' where option_name='close_comments_for_old_posts'");
if ($debug == 1) {
echo "old_posts set but not enabled on $blog_url ($blog_id)\n";



WordPress author list with gravatars – but for WPMU

So this seemed really easy, but apparently it was not, or I guess I would not be writing about it here.  Ok, here is the deal, I wanted a full list of all the authors on one particular blog.  I wanted them all on one page and listed out with links to their blog posts.  I wanted them all to have images next to their names. The standard way to do this seems to be to list out all the user names on your blog, since hey, no harm here, we are only running one blog.

Enter WPMU.  We are not running just one blog, we are running hundreds and have thousands of users.  Listing out all the users via a SQL query would be a huge list, not to mention not at all representative of who is an author on this particular blog.  I did some looking around on the wordpress codex and found a couple of functions that I thought could be helpful.  The first one that came up was wp_list_authors.  This function just lists out all the authors for a particular blog – particularly helpful for WPMU sites.

Now the problem with wp_list_authors is that it just outputs the list of authors as a chunk of links, so you have to chop it up somehow since its not in the loop – yeah, we are doing all this outside of the loop.  The second issue is that this is all that it puts out – links to the author archive page.  No ids, no emails, nothing – its not like the_author_meta which gives you all kinds of nice stuff.

Ok, but at least we have something we can hack up, so I started in on it and this is what I came up with.

$allAuthorNames = explode(',',wp_list_authors('style=0&amp;show_fullname=1&amp;hide_empty=0&amp;echo=0'));
foreach ( $allAuthorNames as $oneAuthorName ) { ?>
  $oneAuthorArray = explode(" ",$oneAuthorName);
  if (count($oneAuthorArray) > 1) {
    $oneAuthorLink = explode("/",$oneAuthorArray[2]);
    $userData = get_userdatabylogin(prev($oneAuthorLink));
  } else {
    $userData = array("user_email" => "None");
echo get_avatar($userData->user_email,$size='96',$default='');
<?php echo ($oneAuthorName); ?>
<?php } ?>

Pardon my PHP, it sucks, but in any case it gets it done here at least.

Notice the nice function that gets it done? Oddly, there is not much documentation to the get_userdatabylogin function, but its a nice one.  Tie together wp_list_authors with get_userdatabylogin and you can get even more info than you can get from the_author_meta.

Now this code is by no means the finished product, but it does work and it is a nice way to get a full list of everything that the author has in their profile in the DB. At the moment I just used it to get the email address of the author I was iterating over, but the function dumps out the entire user DB row object. A bit dangerous I suspect, but useful.

Happy coding,  hope this saves you a bit of time.

© 2023 My pain, your gain.

Theme by Anders NorenUp ↑