Last active
February 15, 2019 12:46
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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