Skip to content

Notifing Users on Access Change

mcguffin edited this page Sep 20, 2014 · 1 revision

Version 1.3.0 introduces four action hooks, fired each time an access area is given to or taken from a user. You might like to notify your user about the changes of his or her privileges on your blog.

Simply attaching a function to each hook, sending out an email for each operation might not be a good Idea. When you editing a user profile and grant access to lets say some twenty access areas this would result in some twenty emails sent out to your user. Finally this can end up in a vast performance decrease and a bugged user with a crowded inbox, shouting an yelling at you (and you yelling at me, which needs to be avoided at any cost).

A much better way is to aggregate all access changes (all grant and revoke operations) and send your user a list of what has been changed. Through PHP this can be achieved in a pretty straight forward way: Collecting all grants, collecting all revokes, finally compiling them into an email.

Sounds pretty much like three functions, doesn't it? Here they are:

<?php
function wpaa_aggregate_revokes( $user , $wpaa_capability ) {
	// get a global var holding all the revoke and 
	global $wpaa_access_changes;
	
	// checking if all var and array keys are present to avoid PHP notices.
	if ( ! isset( $wpaa_access_changes ) )
		$wpaa_access_changes = array();
		
	if ( ! isset( $wpaa_access_changes[$user->ID] ) )
		$wpaa_access_changes[$user->ID] = array();
	
	if ( ! isset( $wpaa_access_changes[$user->ID]['revokes'] ) )
		$wpaa_access_changes[$user->ID]['revokes'] = array();

	// storing what has just happened
	$wpaa_access_changes[$user->ID]['revokes'][] = $wpaa_capability;
}

function wpaa_aggregate_grants( $user , $wpaa_capability ) {
	// get a global var holding all the revoke and 
	global $wpaa_access_changes;

	// checking if all var and array keys are present to avoid PHP notices.
	if ( ! isset( $wpaa_access_changes ) )
		$wpaa_access_changes = array();

	// checking if all var and array keys are present to avoid PHP notices.
	if ( ! isset( $wpaa_access_changes[$user->ID] ) )
		$wpaa_access_changes[$user->ID] = array();

	if ( ! isset( $wpaa_access_changes[$user->ID]['grants'] ) )
		$wpaa_access_changes[$user->ID]['grants'] = array();
		
	// storing what has just happened
	$wpaa_access_changes[$user->ID]['grants'][] = $wpaa_capability;
}

function wpaa_notify_users() {
	// get our aggegated access changes
	global $wpaa_access_changes;
	
	// loop over them. 
	foreach ( $wpaa_access_changes as $user_id => $changes ) {
		$user = new WP_User( $user_id );
		
		$subject = sprintf( "[%s] Your access settings have changed" , wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ) );
		$message = "Howdy {$user->display_name},\n\n";

		// loop over the grant actions
		if ( isset( $changes['grants'] ) && ! empty( $changes['grants'] ) ) {
			$message .= "\nyou have been granted access to the following Access Areas:\n";
			foreach ( $changes['grants'] as $wpaa_capability ) {
				// append access area title to the list
				$access_area = wpaa_get_access_area( $wpaa_capability );
				$message .= "- {$access_area->cap_title}\n";
			}
			$message .= "\n\n";
		}

		// loop over the revoke actions
		if ( isset( $changes['revokes'] ) && ! empty( $changes['revokes'] ) ) {
			$message .= "\nYou have been revoked access from the following Access Areas:\n";
			foreach ( $changes['revokes'] as $wpaa_capability ) {
				// append access area title to the list
				$access_area = wpaa_get_access_area( $wpaa_capability );
				$message .= "- {$access_area->cap_title}\n";
			}
			$message .= "\n\n";
		}
		// End of mesage, be polite
		$message .= "Stay tuned!";


		// sanitize email subject
		$subject = wp_specialchars_decode( $subject );

		// wp_mail it out to our user!
		wp_mail( $user->user_email , wp_specialchars_decode( $subject ) , $message );
	}
}

// collect all grant and revoke operations for further processing.
add_action( 'wpaa_revoke_access' , 'wpaa_aggregate_revokes' , 10 , 2 );
add_action( 'wpaa_grant_access' , 'wpaa_aggregate_grants'  , 10 , 2 );

// fired when a user profile is updated. Make sure to run this hook very late.
add_action( 'profile_update' , 'wpaa_notify_users' , 99 );

The best place for that feature would be inside a mu-plugin. Just paste the code above in a file named wp-content/mu-plugins/wpaa-access-notifications.php.

Actions

  • [wpaa_create_access_area](Action wpaa_create_access_area)
  • [wpaa_grant_access](Action wpaa_grant_access)
  • [wpaa_grant_{$wpaa_capability}](Action wpaa_grant_{$wpaa_capability})
  • [wpaa_revoke_access](Action wpaa_revoke_access)
  • [wpaa_revoke_{$wpaa_capability}](Action wpaa_revoke_{$wpaa_capability})
  • [wpaa_update_access_area](Action wpaa_update_access_area)
  • [wpaa_view_restricted_post](Action wpaa_view_restricted_post)

Filters

  • [wpaa_restricted_post_redirect](Filter wpaa_restricted_post_redirect)
  • [wpaa_update_access_area_data](Filter wpaa_update_access_area_data)

Functions

  • [wpaa_contained_roles](Function wpaa_contained_roles)
  • [wpaa_get_access_area](Function wpaa_get_access_area)
  • [wpaa_get_local_prefix](Function wpaa_get_local_prefix)
  • [wpaa_get_user_role_caps](Function wpaa_get_user_role_caps)
  • [wpaa_is_access_area](Function wpaa_is_access_area)
  • [wpaa_is_local_cap](Function wpaa_is_local_cap)
  • [wpaa_is_post_public](Function wpaa_is_post_public)
  • [wpaa_role_contains](Function wpaa_role_contains)
  • [wpaa_user_can](Function wpaa_user_can)
  • [wpaa_user_can_accessarea](Function wpaa_user_can_accessarea)
  • [wpaa_user_can_role](Function wpaa_user_can_role)
  • [wpaa_user_contained_roles](Function wpaa_user_contained_roles)
Clone this wiki locally