Skip to content

Instantly share code, notes, and snippets.

@wturnerharris
Last active February 15, 2019 12:46
Show Gist options
  • Save wturnerharris/7408110 to your computer and use it in GitHub Desktop.
Save wturnerharris/7408110 to your computer and use it in GitHub Desktop.
Class to make things members-only in WordPress.--This class depends on a custom capability called 'is_approved_member' for user member access and the custom post meta key '_members_only' as a post-level custom field.
<?php
/**
* Custom class for WP_Membership routines.
*
*
* @package WP_Membership
* @since WP_Membership 0.1
*/
if(realpath(__FILE__) === realpath($_SERVER["SCRIPT_FILENAME"]))
exit("Do not access this file directly.");
if ( !function_exists('is_member')) {
/**
* Wrapper for class method that will check if user is registered member
*
* @return boolean
*/
function is_member(){
return WP_Membership::is_member();
}
}
if ( !class_exists('WP_Membership')) {
/**
* WP_Membership Custom Admin Page Class
*/
class WP_Membership {
var $allowed_post_types = array( 'post', 'page', 'attachment' );
var $reset_roles = false;
static $member_type_meta = "member_type";
function __construct() {
if ( ! function_exists( 'admin_url' ) ) return false; // older than WP 3.0
if ( is_admin() ) {
add_action( 'set_user_role', array(&$this, 'update_member_role_meta'), 10, 2 );
} else {
add_filter('wp_get_nav_menu_items', array(&$this, 'nav_item_filter'));
add_action('get_header', array(&$this, 'is_members_only'));
add_filter('post_type_link', array(&$this, 'the_download_link'), 10, 2);
add_filter('the_permalink', array(&$this, 'the_download_link'));
}
add_action( 'init', array(&$this, 'rolescheck') );
add_filter( 'authenticate', array(&$this, 'auth_email_username'), 20, 3 );
}
function rolescheck() {
if ( $this->reset_roles === TRUE ) {
remove_role('standard');
remove_role('premium');
remove_role('pending');
}
$default_caps = array(
'read' => false,
'upload_files' => false,
'manage_options' => false,
'manage_members' => false,
'is_premium_member' => false,
'is_approved_member' => false,
);
if ( current_user_can('administrator') && $admin = get_role('administrator') ) {
// upgrade admin user for theme
if (! current_user_can('manage_options') ) $admin->add_cap('manage_options');
if (! current_user_can('manage_members') ) $admin->add_cap('manage_members');
if (! current_user_can('is_approved_member') ) $admin->add_cap('is_approved_member');
if (! current_user_can('is_premium_member') ) $admin->add_cap('is_premium_member');
}
if (! get_role( 'pending' ) ) {
add_role('pending', 'Pending Approval', $default_caps);
}
$default_caps['read'] = true;
$default_caps['is_approved_member'] = true;
$default_caps['upload_files'] = true;
if (! get_role( 'standard' ) ) {
add_role('standard', 'Standard', $default_caps);
}
$default_caps['is_premium_member'] = true;
if (! get_role( 'premium' ) ) {
add_role('premium', 'Premium', $default_caps);
}
}
function update_member_role_meta( $user_id, $role ) {
$type = self::$member_type_meta;
$prev_value = get_user_meta($user_id, $type, true);
$role = strtolower($role);
$update = ($role != "pending") ? update_user_meta($user_id, $type, $role, $prev_value) : true;
$role_changed = self::change_member_type( $user_id, $role );
return $update&&$role_changed;
}
private function change_member_type( $user_id, $role = null ) {
$roles = array( 'standard', 'premium' );
$user = new WP_User($user_id);
$new_role = is_null($role)?$user->get(self::$member_type_meta):$role;
if ( in_array($new_role, $roles) ) {
$user->set_role($new_role);
$target_role = get_role($new_role);
foreach($target_role->capabilities as $cap => $grant){
$user->add_cap($cap, $grant);
}
return $user->has_cap($new_role);
}
return false;
}
private function handle_payment( $user_id ) {
// check to see if member is paying by credit card
if ( "by_card" == ($payment_type = get_user_meta($user_id, "payment_type", true)) ) {
$member_type = get_user_meta( $user_id, self::$member_type_meta, true);
// handle payment api here
if ( isset($args) ) {
$response = (object)array('success'=>false);
// response and result is gateway-api-specific
$result = $response->success == true;
if( $result ){
// success email here
return true;
} else {
$this->do_error(__("Transaction was not processed. Error: {data}.", 'the_theme'));
return false;
}
}
} else {
// payment by check or no payment handle
if ( 'by_check' !== $payment ) {
// success email here
}
return true;
}
}
/**
* Filter nav menu items that are members_only.
*
* @return array
*/
public function nav_item_filter($items){
foreach($items as $key => $post) $items[$key]->url = $this->the_download_link($post->url, $post->object_id);
return $items;
}
/**
* Check if post if members only content and redirects if necessary.
*
* @return bool
*/
public function is_members_only() {
global $post;
$post_check = $this->allowed_post_types; // desired post types to restrict
$members_only = get_post_meta($post->ID, '_members_only', true);
if ( !in_array(get_post_type(), $post_check) ) return;
if ( !is_member() && !headers_sent() && (is_single() || is_page()) ) {
// not an approved or logged in user
if ( $members_only && 'get_header' == current_filter()) {
wp_redirect( site_url() );
exit;
} else return $members_only;
} else {
return $members_only;
}
}
/**
* Filter the permalink based on the post type.
*
* @return string
*/
function the_download_link($url, $post = null) {
if ( is_null($post)) {
global $post;
}
$members_only = is_object($post) ? $post->_members_only : get_post_meta($post, "_members_only", true);
if ($members_only && !is_member()) return "#login";
$post_type = get_post_type( $post );
switch( $post_type ) {
default: return $url;
}
}
/**
* Authenticates by username or email and only allow members to login
*
* @param user
* @param username
* @param password
* @return bool
*/
function auth_email_username( $user, $username, $password ) {
$field = is_email($username) ? 'email' : 'login';
$user = get_user_by($field, $username);
if ( $user && !is_wp_error($user) )
$username = $user->user_login;
if ( user_can($user, 'administrator') || user_can($user, 'is_approved_member')) {
return wp_authenticate_username_password( null, $username, $password );
}
return new WP_Error('login', __('You do not have permission to login at this time.'));
}
/**
* Check if user is registered member
*
* @return boolean
*/
public static function is_member(){
return current_user_can('is_approved_member');
}
static function get_username_from_email($email) {
$user = get_user_by('email', $email);
return ($user?$user->user_login:$user);
}
static function add_pending_user($input = null) {
// return false if is not a valid post array or is null
if ( is_null($input) || !is_array($input) ) return false;
// start with email
$email = sanitize_email( $input['contact']['email'] );
$username = self::get_username_from_email( $email );
$first_name = sanitize_text_field($input['basic']['first_name']);
$last_name = sanitize_text_field($input['basic']['last_name']);
$description = sanitize_text_field($input['basic']['description']);
$registered = date('Y-m-d H:i:s');
// check if email and/or username already occupied
if (!username_exists( $username ) && !email_exists($email)){
// generate random password
$random_password = wp_generate_password( $length=12, $include_standard_special_chars=false );
// create user with pending permissions
$new_user_id = wp_insert_user( array (
'user_pass' => $random_password,
'user_login' => $username,
'user_nicename' => $username,
'user_url' => esc_url( @$input['basic']['user_url'] ),
'user_email' => $email,
'first_name' => $first_name,
'last_name' => $last_name,
'description' => $description,
'user_registered' => $registered,
'role' => 'pending',
) );
// add all the meta data
if (! is_wp_error($new_user_id) && $new_user_id > 0) {
// unset previously registered fields
unset($input['basic']['user_email'], $input['basic']['user_url'], $input['basic']['first_name'], $input['basic']['last_name'], $input['basic']['description']);
$total = $count = 0;
foreach( $input as $key => $array ) {
if ( is_array($array) ) {
foreach( $array as $meta_key => $meta_value ) {
$count++;
if ( $meta_key == "payment_code" ) continue;
if ( !is_array($meta_value) ) $meta_value = sanitize_text_field($meta_value);
else array_walk_recursive($meta_value, 'sanitize_text_field');
$success = add_user_meta( $new_user_id, $meta_key, $meta_value, true );
if ( $success ) $total++;
}
} else {
if ($key == self::$member_type_meta) {
$count++;
$success = add_user_meta( $new_user_id, $key, $array, true );
if ( $success ) $total++;
}
}
}
return $new_user_id;
}
} else {
// user already exists
set_message("This user already exists; try using a different email address.");
return false;
}
return false;
}
}
}
new WP_Membership();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment