Tag Archives: BuddyPress

WordPress/BuddyPress registration and the Office 365 email filter

Just tore through the following problem on a client site (independently discovered by Martha Burtis here). WordPress/BuddyPress sites that allow for self-registration send out emails with activation links of the form: http://example.com/activate/?key=12345 (for BuddyPress) and http://example.com/wp-activate.php?key=12345 (for WordPress multisite). This format trips up the link filter that Microsoft’s Office 365 email service uses. After some experimentation, I figured out that the problem is the word ‘key’ in a URL parameter – once this term is removed from the URL, it passes right through the filter.

So, you can fix the problem by changing the URL parameter in the activation emails. That means (a) changing the text of the email, and (b) changing the server-side logic to expect something other than ‘key’. Here’s how to do it in BuddyPress:

function bbg_activation_email_content( $message ) {
	return str_replace( '?key=', '?activationk=', $message );
}
add_filter( 'bp_core_activation_signup_user_notification_message', 'bbg_activation_email_content' );

function bbg_screen_activation() {
	global $bp;

if ( !bp_is_current_component( 'activate' ) )
		return false;

// Check if an activation key has been passed
	if ( isset( $_GET['activationk'] ) ) {

// Activate the signup
		$user = apply_filters( 'bp_core_activate_account', bp_core_activate_signup( $_GET['activationk'] ) );

// If there were errors, add a message and redirect
		if ( !empty( $user->errors ) ) {
			bp_core_add_message( $user->get_error_message(), 'error' );
			bp_core_redirect( trailingslashit( bp_get_root_domain() . '/' . $bp->pages->activate->slug ) );
		}

// Check for an uploaded avatar and move that to the correct user folder
		if ( is_multisite() )
			$hashed_key = wp_hash( $_GET['activationk'] );
		else
			$hashed_key = wp_hash( $user );

// Check if the avatar folder exists. If it does, move rename it, move
		// it and delete the signup avatar dir
		if ( file_exists( bp_core_avatar_upload_path() . '/avatars/signups/' . $hashed_key ) )
			@rename( bp_core_avatar_upload_path() . '/avatars/signups/' . $hashed_key, bp_core_avatar_upload_path() . '/avatars/' . $user );

bp_core_add_message( __( 'Your account is now active!', 'buddypress' ) );

$bp->activation_complete = true;
	}

bp_core_load_template( apply_filters( 'bp_core_template_activate', array( 'activate', 'registration/activate' ) ) );
}
remove_action( 'bp_screens', 'bp_core_screen_activation' );
add_action( 'bp_screens', 'bbg_screen_activation' );

You’d have to do something in the same spirit when not using BuddyPress. For the email, filter ‘wpmu_signup_user_notification_email’. Catching the request and overriding ‘key’ will be trickier. I haven’t experimented with it, but maybe you can hook to ‘activate_header’, detect the presence of $_GET['activationk'], and then redirect to the ‘key=’ URL that wp-activate.php expects.

Hopefully this is enough to help if you’re having the problem.

BuddyPress Docs 1.4 and attachment support

I’ve just released version 1.4 of BuddyPress Docs, my collaborative editing plugin for BuddyPress. The big new feature is the one that users have been asking for since the plugin was first released: file attachments. I’m using a nifty trick (involving the autogeneration of .htaccess files) to ensure that Doc privacy levels are extended to their attachments. I think it’s going to be useful to a lot of people.

In the future, I plan to write a tool to migrate content created by the abandoned BP Group Documents to this new system. Stay tuned.

This round of development was generously sponsored by the Center for Applied Research and Environmental Systems at the University of Missouri. They are long-time users of BuddyPress, and they were pleased to support the development of this feature for the community. Special thanks to David Cavins, who set up the connection between me and CARES, and also contributed huge amounts of technical, conceptual, and design help to Docs 1.4. (He also builds beautiful guitars.) Thanks to CARES and to David!

Get your Boone fix

Mostly for my own records, here are a few recent Boone-related videos and interviews from around the web:

  • Code Poet interview – April 18, 2013. In which I speak at length (ramble?) about BuddyPress, the university, and the value of free software
  • WordSesh panel – April 13, 2013. A livestreamed discussion about BuddyPress with John, Paul, Ray, and Tammie.
  • BuddyCamp Miami presentation – April 5, 2013. A brief talk where I talk about how to use BuddyPress’s Group Extension API to add BP features to a WordPress plugin. The slides are at blo.so/bcmia.
  • WPNYC presentation – January 15, 2013. A talk I gave on the big new features in BuddyPress 1.7

Anthologize automated tests now run using WP’s unit test suite

Anthologize, I haven’t forgotten about you! I have some very cool stuff in the works, but for now, a quick update on the progress of the campaign-funded work.

Back in 2011, Patrick Murray-John added some unit tests to Anthologize, covering a number of public methods in the TeiApi class. A number of the major refactoring jobs I’m currently undertaking will require additional test coverage, but they are (unlike TeiApi) dependent on WordPress being initalized. So I’ve migrated Anthologize’s tests to use the WP test suite. I’ve used the scaffold provided by the dope and phatte wp-cli (incidentally, I hope that their scaffold becomes the de facto standard for WP plugin tests).

This change means that, in addition to requiring PHPUnit, you’ll also need to have the WP test suite installed. You can install it manually, but I recommend using wp-cli to get the job done in just a command or two. In brief:


$ wp core init-tests /path/to/wp-tests --dbname=wp_test --dbuser=root --dbpass=asd
$ mysql -u'root' -p'asd' -e 'CREATE DATABASE IF NOT EXISTS wp_test'

To run the tests,


$ cd /path/to/wp/wp-content/plugins/anthologize
$ WP_TESTS_DIR=~/path/to/wp-tests phpunit

You can define WP_TESTS_DIR in your .bashrc file for quicker use in the future.

This post is brought to you by Anthologize campaign supporter Demokratie & Dialog. D&D, a Major Sponsor of Anthologize (woo hoo!), is using WordPress and BuddyPress in amazing ways both to study the way that government policy affects youth and to get youth themselves involved in the development of said policy. I had a chance to get to know the very excellent Andreas Karsten of D&D at BuddyCamp Vancouver last year, and we have big plans to start a BuddyPress jazz band. Many thanks for your support of WP, BP, and Anthologize!

BuddyPress Docs 1.3, featuring theme compatibility on BP 1.7

I’ve just released version 1.3 of BuddyPress Docs, my WordPress plugin that powers collaborative document editing on a BuddyPress site. The main feature of Docs 1.3 is theme compatibility, which means that top-level Docs templates (archives, single docs, and the Create screen) are no longer necessarily top-level. Using the theme compat feature of BuddyPress 1.7 (currently in beta), this top-level content is put directly into the content area of your theme’s page.php template, ensuring that Docs pages will keep your header, footer, sidebar, and other global elements.

The theme compatibility feature only kicks in if you’re running BP 1.7. Existing installations of Docs on BP < 1.7 will continue to work as before.

Are you a BP Docs user? Are you already testing BuddyPress 1.7? I'd be glad to get your feedback on Docs 1.3. Report any problems on the issue tracker.

Dynamically add items to a wp_nav_menu() list

WordPress’s wp_nav_menu() fetches a custom menu, as built using the Menus GUI, for display in a theme. I had a project where I needed to add some items to this menu dynamically – the links would be different for each user, and wouldn’t appear for logged-out users, so they couldn’t really be added using the GUI. After a bit of futzing, I was able to insert my menu items, tricking WP into thinking that they were native.

Details: For logged-in users, I needed to add three subnav items underneath the top-level ‘Activity’ item, if it was present. So at the beginning of the function, you’ll see that I’m doing some BuddyPress-specific stuff, to find the Activity menu. If you need to use a menu_item_parent like I did, you’ll have to supply your own method for finding it (or just hardcode it). The heavy lifting is done in the second foreach loop, where I build stdClass objects just robust enough that WordPress will interpret them as true nav menu items.

Circle back to those who refer work to you

I get a lot of requests to do BuddyPress and WordPress dev work, and I can only take a fraction of that work myself. So I end up referring a lot of work to other developers. Sometimes I hear back from the client that one of the referrals worked out (or didn’t). Unfortunately, it’s very rare that I hear from the developer himself about it.

It’s unfortunate not because I need the gratification (although it’s nice to hear “thanks for the referrals” sometimes). It’s unfortunate because I want to be a good referer. I read every job inquiry carefully, and I try to make good matches between inquiries and what I know about the developers on my list. I look at how big the job will be, what kind of work it is (plugin dev, theme work, troubleshooting, etc), what field the client comes from (education, journalism, retail, etc), and other stuff like that, and match it up with the devs I think would be best for (and would most enjoy) that particular referral. When I never hear back from these friends, I don’t have the data I need. Stuff like: If you refused the job, why? Too busy? Not the kind of work you generally like to do? Did the referral make your lousy-client-sense tingle? If you took the job, how did it go? Was the client good to work with? Should I continue to send work like this?

So please: if you know that one of your client inquiries came from a friend’s referral, ping that friend at some point down the road. The more info you share, the better the referrals you’ll get from me.

As a side note, I’ve been chatting privately with David Bisset about coming up with systematic solutions to the kinds of problems I’ve described here (among others). But in the meantime, an occasional email will do the trick :)

Commons In A Box, ready to unbox

It’s been a long time coming, but it’s here: Commons In A Box. Today we’re releasing version 1.0-beta1, the first public release. For some background on Commons In A Box, here’s today’s press release, my Commons Dev Blog post explaining some of the features of Commons In A Box, and the 2011 press release announcing the project.

The primary goal of Commons In A Box, in my view, is to reduce the barrier of entry to setting up BuddyPress community sites. BuddyPress is an extremely powerful and flexible platform for developing social WordPress sites, but getting a BP site right takes knowledge (which plugins are worth installing, which ones work best together, etc) and elbow-grease (customizing your theme, keeping a complex system up to date). These practical requirements have made BuddyPress seem imposing to many users – including, and perhaps especially, the users that need free community software the most, such as educational institutions. Commons In A Box lowers these barriers in a serious way, by helping with plugin selection and installation, and by providing a beautiful and flexible default theme. My hope is that Commons In A Box will serve as a gateway for a swath of potential users into the world of BuddyPress, WordPress, and free software more generally.

The process of pitching, planning, and producing Commons In A Box has been interesting, frustrating, and rewarding. In the upcoming weeks and months, I may write more about this process, and what I’ll personally take away from it. In the meantime, I’ll say that I’m very pleased to be ending this first stage of development, and pushing it into the wild, since software – even imperfect software – is infinitely more valuable when it’s out there, being used, than when it’s mouldering on a developer’s machine. Shipping FTW!

Learn more about Commons In A Box.