Category Archives: WordPress

Posts and Comments Together, Oh My!

A few days ago, Captain Primate asked:

WordPress doesn’t have something like this built-in I guess because of the different ways that posts and comments are managed and have metadata attached to them. But, if users are logged in when they comment (which you can require in the Settings -> Discussion page) then comments are affiliated with the accounts of anyone who is logged into your site when they comment. The trick is then to display that information.

I did something like this for a jumbo psychology course where the faculty member wanted to get quick summary information of the work students had contributed to the site. I had originally tied the process to the plugin WP-Stats because we were looking at lots of other data (WP-Stats allows you to generate all sorts of stuff… I think D’Arcy Norman originally turned me onto it). But when looking at it today I realized those are separable processes, and it’s really pretty straightforward. I’ve thrown together a child theme of Twenty Eleven that includes the following additions to the author.php file (wrap them in php open and close tags):

At line 29 I added this code which generates a numerical summary of posts and comments by the user whose author archive you’re visiting:

							global $wpdb;
							$user_id = $post->post_author;  //change this if not in a std post loop
							$where = 'WHERE comment_approved = 1 AND user_id = ' . $user_id ;
							$comment_count = $wpdb->get_var(
    						"SELECT COUNT( * ) AS total
							FROM {$wpdb->comments}
							{$where}
							");
							$user = get_userdata($user_id);
							$post_count = get_usernumposts($user->ID);
							echo '<p><h1 class="entry-title">Summary of Activity on this Site</h1></strong><br />Number of Posts: ' . $post_count .' <br/> Number of Comments: ' . $comment_count . '</p>';

At line 71 I added an echo to mark off the POSTS section.

And at line 84 I added this code which pulls and displays a list of comments by that author with a link to the post they commented upon:

				echo '<h1 class="entry-title"><em>Comments:</em></h1>';
				$comment_author = get_the_author_id();
				$comments = get_comments(array(user_id=>$comment_author));
				foreach($comments as $comment) :
				$url = '<a href="' . get_permalink($comment->comment_post_ID) . '">' . get_the_title($comment->comment_post_ID) .'</a>';
				echo ('"' . $comment->comment_content . '" <br><em> posted on ' . get_comment_date('M j, Y') . ', on the post ' . $url .  '</em><br /><br>');
				endforeach;

It is helpful also to be able to generate a list of authors so you can navigate easily to their author archives… the plugin we were using to enable this widget for the past few years — Authors Widget (no longer in the repository) — was ferkakte, so for that function I started using a Samsarin PHP Widget with the following code in it:

function ListTheAuthors() 
{
wp_list_authors('optioncount=1&orderby=name&show_fullname=true');
}
 
function widget_ListAuthors($args) {
  extract($args);
  echo $before_widget;
  echo $before_title;?>Site Authors<?php echo $after_title;
  ListTheAuthors();
  echo $after_widget;
}

A couple months ago Jason Parkhill threw that code into a little plugin to make a very basic List Authors widget (thanks Jason!). You can play with the line ‘optioncount=1&orderby=name&show_fullname=true’ to get the configuration you want for your site. Use this as a guide to making modifications.

Here’s Jason’s List-Authors plugin.

And here’s the TwentyEleven child theme I threw together that displays posts and comments together on an author’s archive page (remember… authors must be logged in when they comment or their comments will not appear on their archive pages; and, of course, you must have Twenty Eleven in your wp-content/themes folder). It’s not elegant (if there are no comments, you just get a blank space below “Comments”), but, it gets the job done. Please hack it and share it to your heart’s content!

Integrating with Active Directory; or, Why it Ain’t All Bad Being Official

This guy’s official.
cc licensed http://www.flickr.com/photos/dkscully/5038201085/

I just completed a major overhaul of the authentication process by which users log in to Blogs@Baruch. Previously, users were able to create accounts on the system as long as they had a Baruch email address. Just over a year ago, however, our CIO requested that we implement Active Directory authentication, and we’ve been working towards this for some time. Now, any user in the college’s Active Directory can simply log into the system, and doing so creates their account.

Several technical issues needed to resolved before we could make the switch. The two biggest were the inadequacy for our purposes of existing ad integration plugins and the process by which existing local WordPress users would be migrated to AD accounts. I worked with my friend Boone Gorges to address these issues, using Glatze’s Active Directory Integration plugin as the base. We had considered using Curtis Grymala’s fork of Glatze’s plugin, and Curtis was very generous in taking the time to explain his modifications to us, but ultimately we concluded Glatze’s plugin seemed to get us closer to where we needed to get.

Boone ultimately wrote a plugin called BLSCI-AD (get it on git) which combines all of the specific functions that we needed for this project. It fixed some problems Glatze’s plugin had working with WordPress multisite, addresses some fallback account assurances we needed (users who were not successfully migrated to AD — about 8% of our 10k+ users — are still able to log into the system using their old credentials), and, most importantly, runs a check of all existing users against the email addresses present in AD. When it finds a match, if the WordPress username and AD username aren’t the same, it changes the user’s WordPress username to the one in AD. While the migration is being performed a record is generated, sortable by successes, failures, and with additional data like user creation date, migration attempted date, and last activity date. The usernames of those whose migrations fail are manually editable through the report page, and every user’s previous ID remains recoverable.

This is really a remarkable bit of code, not least because of the hilarious and helpful PHP comments Boone strews throughout. There’s a lot of justifiable love for Boone on the web, but personally I enjoy working with him because he appreciates the complicated contexts in which we work, gets and supports the mission of our project, and approaches each contract as a collaborative puzzle–solving experience. Thanks, Boone!

I did have some mixed feelings about this transition, and I’ve been struggling to put them into some sort of order over the past few days. Blogs@Baruch began as an independent experiment, resistant to centralization and institutional oversight, and hostile to any outside efforts to control. But as we’ve grown and responded to community need certain pressures have been put upon us: all incoming freshmen do work on our system, and several programs, centers, and projects use us for their web presence. The college sees this as a space worth supporting and building along the trajectory we’ve already established. One goal they’ve had which over time came to implicate us was to simplify access to and unify logins for the various services the college offers. We had some concerns about this as an effort to establish control over Blogs@Baruch, but were satisfied through conversations with BCTC that this wasn’t the case. Tom Harbison (who along with Craig Stone helped us through the migration tremendously) and I have been granted the administrative rights to create Active Directory users. We’ve also been assured that all users who have had access to Blogs@Baruch in the past will continue to have access into the future regardless of their current relationship with the school. These are meaningful choices, especially in a place like CUNY.

So, while I’m a bit skittish about the implications of centralization (and a touch nervous about the performance implications of SSL admin rule now in place), I’m tremendously pleased about this technical accomplishment, and also about its impact on user management. Any user who is currently active in Baruch’s Active Directory can now simply log in to Blogs@Baruch with the same account they use to log into the wifi and into the school’s computers. If they had an account, all their stuff is there; if they didn’t, a user is silently created for them against their AD profile (it feels as though the user already existed).

I know that there’s some resistance to the fetishization of single sign-on out there in the hipster web, and I certainly am sympathetic to those arguments. If the experience is meaningful enough, folks will log in however they can to get it. We have a lot of that on Blogs@Baruch. But we also have users who are completely new to such experiences, who might be resistant for reasons cultural or philosophical, or who have been compelled to use the system by a faculty member. Those users now have zero technical barriers to entering the system, and I’m curious about what kind of serendipity that just might lead to.

A couple other technical notes. We use Boone’s Simple Import Users plugin to allow faculty members to easily bulk add users to individual sites. As part of this project, he wrote an AD check into that plugin so that if users haven’t been created in WordPress yet when their email addresses are entered into the import users field, an account is created for them. I hacked that plugin a bit to change the defaults and simplify the email generation options.

I also wrote a function into our BuddyPress theme to pull in the user’s Active Directory Description:

function DisplayedUserDescription() {
$user_meta = get_userdata(bp_displayed_user_id());
echo '
<div class="bp-widget">' . '
' . '' . 'Active Directory Description: ' . '' . '' . $user_meta->description. '' . '
' . '</div>
';
}

add_action( 'bp_after_profile_field_content', 'DisplayedUserDescription' );

And, finally, I hacked together a file (placed in mu-plugins) that changed the login page across the installation:

/*
Plugin Name: Login Hacks
Plugin URI:
Description:
Author: Luke Waltzer
Version: 1.0.0
Author URI:
*/

//Change Wrong Password Error Text

add_filter('login_errors',
            create_function('$no_login_error',
                            "return '

You now must log in to Blogs@Baruch with your Baruch user name.

If you do not remember your password, please follow the reset link below.

';"));

//Change Login Field Names Text

function wp_field_names_change($translated_text, $text, $domain){

	switch ($text) {
		case 'Username':
			return 'Baruch Username';
		break;
	}

	switch ($text) {
		case 'Password':
			return 'Baruch Password';
		break;
	}

	return $translated_text;
}
add_filter('gettext', 'wp_field_names_change', 1, 3 );

//Remove Register link

function remove_register_text ( $text ) {
         if ($text == 'Register'){$text = '' ;}
                return $text;
         }
add_filter( 'gettext', 'remove_register_text' );

//Change Reset Password Link Below Login Form

function remove_lostpassword_text ( $text ) {
         if ($text == 'Lost your password?'){$text = '
<h3 style="text-align: center;"><a href="https://mypassword.baruch.cuny.edu/" target="_blank">Reset Your Baruch College Password</a>

You now must log into Blogs@Baruch with your Baruch username.

All previous users of Blogs@Baruch will still be able to access their accounts after they are no longer affiliated with the school. We may however need to assist you in creating a new account and affiliating all content you previously produced with that new account.

If you are unable to log in, please email us at <a href="mailto:blsciblogs@baruch.cuny.edu">blsciblogs@baruch.cuny.edu</a> for assistance.</h3>
' ;}
                return $text;
         }
add_filter( 'gettext', 'remove_lostpassword_text' );

}

“Table marked as crashed”

I encountered a pretty scary error on the WordPress Multisite network I manage yesterday, which turned out to be something relatively minor. I thought I’d blog it in case someone else found themselves in a similar situation and began frantically Googling… which is what I was doing last night as my wife (thankfully) handled getting the kids to bed.

We think we’ve been having some brute force attacks on our server over the past few months, and while our server mostly weathers them, we had one yesterday morning that required a manual restart of the virtual machine where our system is housed. We were back online in no time and all looked good. I then had a pretty busy day, and wasn’t spending much time on the system, but got no notices that there were problems (usually I’ll hear from users if something’s amiss).

Towards the end of the day, on either side of my commute, I saw the following symptoms emerge:

  • I noticed that it was taking a long time to access my dashboard even though the site load was normal. I was though still able to eventually get in.
  • On my way out of the office, I noticed that the BuddyPress admin bar was visible even though I had set it to be hidden for logged out users. I noted to take a look at this when I got home. When I did, I found that I couldn’t change that or any other BP setting… when I clicked “save,” the setting reverted to “not hidden.”
  • While going back and forth between the front and back ends, I suddenly lost the super admin capability on my personal account, though I was still able to access the super admin menu with the “admin” user.
  • I then noticed several plugins — including BuddyPress, WP-Super Cache — had been suddenly deactivated, and I couldn’t reactivate them.
  • Then, I noticed that no network themes were available in the Appearance>Themes menu, and that the “enabled” setting on all themes on the wp-admin/ms-themes.php page had been toggled to “no”
  • The home site went white, probably because BuddyPress was no longer enabled and that site runs a BP theme
  • All subdirectory sites seemed fine and were accepting posts.

I’ve never seen this collection of problems before, and began to worry that perhaps the system got hacked…although the pattern of symptoms suggested something was interfering with the database. I first deleted all plugins (except the shar-db plugin), but doing so changed nothing.

Then, I thought, if this is really bad, I need to make sure I have a current MYSQL dump. When running the dump, I got this error:

mysqldump: Got error: 145: Table ‘./wpmu_global/wp_sitemeta’ is marked as crashed and should be repaired when using LOCK TABLES

Ah… crashed database table! I repaired that table via PhpMyAdmin, and, voila, problem resolved.

It seems as though the hard reset that the system required in the morning corrupted the database, and led to the gradual emergence of these symptoms.

Live, learn, and make sure you check your database.