Group Announcements tab in BuddyPress

I had a request or two to explain how I built the Group Announcements feature on the CUNY Academic Commons. Here goes.

Brief background: When the Commons was upgraded to BuddyPress 1.2, we got the benefit of interactive activity streams everywhere, including groups. This caused some confusion, however, as users were uncertain where conversation best fit into the Commons’s architecture: in the Forums (where it had been traditionally), or in the activity stream. In some communities this kind of fracturing might be okay or even welcome, but in ours it was confusing. At the same time, we wanted a way for group admins and mods to send important notices to the members of their groups. By taking the group activity updates and repurposing it as a Group Announcements section, I was able to kill two birds with one stone: providing an announcement space for mods, while focusing extended discussion in the forums.

You can download the CAC Group Announcements plugin here.

I’m not putting this in the repo at the moment because I don’t want to build a proper admin UI and support it 🙂 For that reason, here is a primer on how the plugin works – if you want to customize or maintain it, you’re on your own, buster.

  1. The CAC_Group_Announcements class is an instance of the BuddyPress Group Extension API. It is responsible for creating the Announcements tab markup and adding it to the nav. You’ll notice that the majority of the markup is created by including bp-default’s activity-loop.php and post-form.php templates. You could customize this more if you wanted.
  2. bp_is_group_announcements() is a little template tag that can be used to test whether you’re looking at a group announcements page. This is needed for the activity filter, in step 3.
  3. cac_set_announcement_filter() adds a filter to the bp_has_activities query string when you are looking at an announcements page, so that it only displays activity items of the type activity_update. In other words, when you are looking at the regular activity stream for the group, you see all of the associated group activity items (new members, forum posts, etc) but when you’re on the announcements page you only see activity updates (which, remember, have been repurposed as announcements).

As I look at the code, I see that there are things I would definitely change if I were going to make this into a distributed plugin. If you want to make those changes, be my guest. You’re welcome to help each other in the comment section, but I won’t be formally supporting this, as it is a very basic hack that should happen at the theme level anyway. Good luck!

Commons 1.1.7

Happy New Year! I have just released version 1.1.7 of the CUNY Academic Commons. This bugfix release contained a very important security release of WordPress (v3.0.4), as well as a few other small changes:

  • Bugfixes in the Google Calendar widget WP plugin
  • Bugfixes in the Cityscape WP theme
  • Installed the Meebo Me WP plugin

For complete details about the release, visit the 1.1.7 milestone.

Commons 1.1.5

I have just released version 1.1.5 of the CUNY Academic Commons. The main purpose for this release was to fix a recently introduced bug that was preventing users from inviting others to their BuddyPress groups. Several other issues were addresse as well:

  • A plugin WP Resume was included to allow the creation of resumés and CVs on your Commons blog
  • PDF export for MediaWiki pages and categories was activated
  • Some bugs with the way that the Atahualpa theme handles custom headers were fixed
  • See the 1.1.5 milestone for full details on the release.
  • Commons 1.1.4

    I’ve just finished tagging and releasing version 1.1.4 of the CUNY Academic Commons. This bugfix release addresses several issues and requests from the member community, including:

    • Bugfixes in several WordPress plugins (Widgetize Google Gadgets, Media Element HTML 5)
    • Fixed bug that was causing a few members to get email notification from groups they used to be members of
    • Installed the Widget Context WP plugin, which allows blog owners greater control over the way that widgets display on different parts of their sites
    • Improved the layout of the group header and added a Post Topic button to the group forum interface for greater usability

    As always, you can get full details about the release from the 1.1.4 milestone

    Wildcard email whitelists in WordPress and BuddyPress

    WordPress (and before that WPMU) has long had a feature that allows admins to set a whitelist of email domains for registration (Limited Email Registration). On the Commons, we need to account for a lot of different domains, some of which are actually dynamic – but they are all of the form *.cuny.edu. WP doesn’t support this kind of wildcards, but we’ve got it working through a series of customizations.

    These first two functions form the heart of the process. The first one hooks to the end of the BP registration process, looks for email domain errors, and then sends the request to the second function, which does some regex to check against the wildcard domains you’ve specified. This is BP-specific, but I think you could make it work with WPMS just by changing the hook name.

    
    function cac_signup_email_filter( $result ) {
    	global $limited_email_domains;
    
    	if ( !is_array( $limited_email_domains ) )
    		$limited_email_domains = get_site_option( 'limited_email_domains' );
    	
    	$valid_email_domain_check = cac_wildcard_email_domain_check( $result['user_email'] );	
    	
    	if( $valid_email_domain_check ) {
    		if ( isset( $result['errors']->errors['user_email'] ) )
    			unset( $result['errors']->errors['user_email'] );
    	}
    	
    	return $result;
    }
    add_filter( 'bp_core_validate_user_signup', 'cac_signup_email_filter', 8 );
    
    function cac_wildcard_email_domain_check( $user_email ) {
    	global $limited_email_domains;
    	
    	if ( !is_array( $limited_email_domains ) )
    		$limited_email_domains = get_site_option( 'limited_email_domains' );
    
    	if ( is_array( $limited_email_domains ) && empty( $limited_email_domains ) == false ) { 
    		$valid_email_domain_check = false;
    		$emaildomain = substr( $user_email, 1 + strpos( $user_email, '@' ) );
    		foreach ($limited_email_domains as $limited_email_domain) {
    			$limited_email_domain = str_replace( '.', '\.', $limited_email_domain);        // Escape your .s
    			$limited_email_domain = str_replace('*', '[-_\.a-zA-Z0-9]+', $limited_email_domain);     // replace * with REGEX for 1+ occurrence of anything
    			$limited_email_domain = "/^" . $limited_email_domain . "/";   // bracket the email with the necessary pattern markings
    			$valid_email_domain_check = ( $valid_email_domain_check or preg_match( $limited_email_domain, $emaildomain ) );
    		}
    	}	
    
    	return $valid_email_domain_check;
    }
    

    Before WP 3.0, this was enough to make it work. The latest WP does increased sanitization on the input of the limited_email_domains field, however, which makes it reject lines like *.cuny.edu. The following functions add an additional field to the ms-options.php panel that saves the limited domains without doing WP’s core checks. (Beware: bypassing WP’s checks like this means that there are no safeguards in place for well-formedness. Be careful about what you type in the field, or strange things may happen.)

    
    function cac_save_limited_email_domains() {
    	if ( $_POST['cac_limited_email_domains'] != '' ) {
    		$limited_email_domains = str_replace( ' ', "\n", $_POST['cac_limited_email_domains'] );
    		$limited_email_domains = split( "\n", stripslashes( $limited_email_domains ) );
    	
    		$limited_email = array();
    		foreach ( (array) $limited_email_domains as $domain ) {
    				$domain = trim( $domain );
    			//if ( ! preg_match( '/(--|\.\.)/', $domain ) && preg_match( '|^([a-zA-Z0-9-\.])+$|', $domain ) )
    				$limited_email[] = trim( $domain );
    		}
    		update_site_option( 'limited_email_domains', $limited_email );
    	} else {
    		update_site_option( 'limited_email_domains', '' );
    	}
    }
    add_action( 'update_wpmu_options', 'cac_save_limited_email_domains' );
    
    function cac_limited_email_domains_markup() {
    	?>
    	
    	<h3><?php _e( 'Limited Email Domains That Actually Work' ); ?></h3>
    	
    	<table class="form-table">
    	<tr valign="top">
    		<th scope="row"><label for="cac_limited_email_domains"><?php _e( 'Limited Email Registrations' ) ?></label></th>
    		<td>
    			<?php $limited_email_domains = get_site_option( 'limited_email_domains' );
    			$limited_email_domains = str_replace( ' ', "\n", $limited_email_domains ); ?>
    			<textarea name="cac_limited_email_domains" id="limited_email_domains" cols="45" rows="5">< ?php echo wp_htmledit_pre( $limited_email_domains == '' ? '' : implode( "\n", (array) $limited_email_domains ) ); ?>
    			<br />
    			<?php _e( 'If you want to limit site registrations to certain domains. One domain per line.' ) ?>
    		</td>
    	</tr>
    	</table>
    	
    	<?php
    }
    add_action( 'wpmu_options', 'cac_limited_email_domains_markup' );
    

    Commons 1.1.3

    I just released version 1.1.3 of the CUNY Academic Commons. This version was timed to fix a critical bug that was making WordPress ignore the wildcard filters that the Commons uses to restrict membership to *.cuny.edu addresses. Several other small issues were addressed:

    • The new email notification system now sends emails to post authors by default (a setting you can change at Settings > Notifications)
    • Upgraded the popular Atahualpa theme and corrected an error that was making the plugin’s Dashboard menu unavailable. (Blogs using Atahualpa may find that they need to adjust their headers slightly after this upgrade.)
    • Upgraded a large number of plugins and themes to the latest versions

    For full details on the upgrade, see the 1.1.3 milestone.

    Commons 1.1.2

    Another quick release today, CUNY Academic Commons version 1.1.2. As with the previous maintenance release, there were a few issues that needed to be resolved quickly. To wit:

    • Problems with the way that forum attachments were being accessed and stored
    • A WordPress security release (3.0.3)

    I also took the opportunity to sneak in a few small fixes, related to Ron’s Post Gallery Widget and to the External Blogs plugin.

    See the 1.1.2 milestone for details on this release.

    Commons 1.1.1

    I just tagged and released the CUNY Academic Commons version 1.1.1. This is a quick follow-up release to Monday’s big 1.1 release and addresses some important bugs related to that release. A few highlights:

    • Cross-browser appearance of the front page slider improved
    • Email notifications of forum posts now have the full body text and improved formatting
    • Incorrect email notification settings have been cleaned up
    • The time window for the Who’s Online widget is increased

    For a full account of the release, please visit the 1.1.1 milestone

    Commons 1.1

    I just released version 1.1 of the CUNY Academic Commons. 1.1 is our first big feature release since we’ve begun versioning the site, and there’s a lot of new stuff for users to check out. Stay tuned to the Commons news blog over the next few days for details about the new features. In the meantime, I hope this executive summary will tide you over:

    • Upgraded to WP 3.0.2, for an improved Dashboard experience
    • A new email notification system, which allows immediate or digest (daily or weekly) notifications of group activity (plugin)
    • A host of new, high quality blog themes from WooThemes
    • The ability for group admins to pull external RSS feeds into a group activity stream (plugin)
    • The ability for group admins to change the URL slug of a group (plugin)
    • Improvements in the way that the slider images on the site home page are managed, courtesy of a plugin custom developed for the Commons by Ron Rennick (plugin)
    • The ability for group admins to change the URL slug of a group (plugin)
    • Many UI bugs fixed

    For more on what was changed in 1.1, see the 1.1 milestone.