patches for wpmem_logged_in shortcode to handle product attribute
<?php
/**
* The WP_Members Shortcodes Class.
*
* This class contains functions
* for the shortcodes used by the plugin.
*
* This file is part of the WP-Members plugin by Chad Butler
* You can find out more about this plugin at https://rocketgeek.com
* Copyright (c) 2006-2018 Chad Butler
* WP-Members(tm) is a trademark of butlerblog.com
*
* @package WP-Members
* @subpackage WP_Members_Shortcodes
* @author Chad Butler
* @copyright 2006-2018
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit();
}
class WP_Members_Shortcodes {
function __construct() {
/**
* Fires before shortcodes load.
*
* @since 3.0.0
* @since 3.1.6 Fires before shortcodes load.
*/
do_action( 'wpmem_load_shortcodes' );
add_shortcode( 'wp-members', 'wpmem_shortcode' );
add_shortcode( 'wpmem_field', array( $this, 'fields' ) );
add_shortcode( 'wpmem_logged_in', array( $this, 'logged_in' ) );
add_shortcode( 'wpmem_logged_out', array( $this, 'logged_out' ) );
add_shortcode( 'wpmem_logout', array( $this, 'logout' ) );
add_shortcode( 'wpmem_form', array( $this, 'forms' ) );
add_shortcode( 'wpmem_show_count', array( $this, 'user_count' ) );
add_shortcode( 'wpmem_profile', array( $this, 'user_profile' ) );
add_shortcode( 'wpmem_loginout', array( $this, 'loginout' ) );
add_shortcode( 'wpmem_tos', array( $this, 'tos' ) );
add_shortcode( 'wpmem_avatar', array( $this, 'avatar' ) );
add_shortcode( 'wpmem_login_link', array( $this, 'login_link' ) );
add_shortcode( 'wpmem_reg_link', array( $this, 'login_link' ) );
/**
* Fires after shortcodes load.
*
* @since 3.0.0
* @since 3.1.6 Was wpmem_load_shortcodes, now wpmem_shortcodes_loaded.
*/
do_action( 'wpmem_shortcodes_loaded' );
}
/**
* Function for forms called by shortcode.
*
* @since 3.0.0
* @since 3.1.3 Added forgot_username shortcode.
* @since 3.2.0 Moved to WP_Members_Shortcodes::forms().
* @since 3.2.0 Added id, exclude_fields, include_fields, and product attributes.
*
* @todo Complete support for id, exlude_fields, include_fields, and product attributes
* May require updates to core functions.
*
* @global object $wpmem The WP_Members object.
* @global string $wpmem_themsg The WP-Members message container.
*
* @param array $atts {
* Possible shortcode attributes (some vary by form).
*
* @type string $id An ID for the form.
* @type string $login Idenifies login form.
* @type string $password Idenifies reset/change password form (login state dependent).
* @type string $user_edit Idenifies user profile edit form.
* @type string $forgot_username Idenifies forgot username form.
* @type string $register Idenifies register form.
* @type string $redirect_to URL to redirect to on form submit.
* @type string $texturize Add/fix texturization for the from HTML.
* @type string $exclude_fields Fields to exclude (register/user_edit forms only).
* @type string $include_fields Fields to include (register/user_edit forms only).
* @type string $product Register for specific product (if products are enabled).
* }
* @param string $content
* @param string $tag
* @return string $content
*/
function forms( $atts, $content = null, $tag = 'wpmem_form' ) {
global $wpmem, $wpmem_themsg;
// Defaults.
$redirect_to = ( isset( $atts['redirect_to'] ) ) ? $atts['redirect_to'] : null;
$texturize = ( isset( $atts['texturize'] ) ) ? $atts['texturize'] : false;
$customizer = ( is_customize_preview() ) ? get_theme_mod( 'show_logged_out_state', false ) : false;
/*
* The [wpmem_form] shortcode requires additional tags (login, register, etc) that
* will be in the $atts array. If $atts is not an array, no additional tags were
* given, so there is nothing to render.
*/
if ( is_array( $atts ) ) {
// If $atts is an array, get the tag from the array so we know what form to render.
switch ( $atts ) {
case in_array( 'login', $atts ):
if ( is_user_logged_in() && '1' != $customizer ) {
/*
* If the user is logged in, return any nested content (if any)
* or the default bullet links if no nested content.
*/
$content = ( $content ) ? $content : wpmem_inc_memberlinks( 'login' );
} else {
/*
* If the user is not logged in, return an error message if a login
* error state exists, or return the login form.
*/
$content = ( $wpmem->regchk == 'loginfailed' ) ? wpmem_inc_loginfailed() : wpmem_inc_login( 'login', $redirect_to );
}
break;
case in_array( 'register', $atts ):
if ( is_user_logged_in() && '1' != $customizer ) {
/*
* If the user is logged in, return any nested content (if any)
* or the default bullet links if no nested content.
*/
$content = ( $content ) ? $content : wpmem_inc_memberlinks( 'register' );
} else {
if ( $wpmem->regchk == 'loginfailed' ) {
$content = wpmem_inc_loginfailed() . wpmem_inc_login( 'login', $redirect_to );
break;
}
// @todo Can this be moved into another function? Should $wpmem get an error message handler?
if ( $wpmem->regchk == 'captcha' ) {
global $wpmem_captcha_err;
$wpmem_themsg = __( 'There was an error with the CAPTCHA form.' ) . '<br /><br />' . $wpmem_captcha_err;
}
$content = ( $wpmem_themsg || $wpmem->regchk == 'success' ) ? wpmem_inc_regmessage( $wpmem->regchk, $wpmem_themsg ) : '';
$content .= ( $wpmem->regchk == 'success' ) ? wpmem_inc_login( 'login', $redirect_to ) : wpmem_inc_registration( 'new', '', $redirect_to );
}
break;
case in_array( 'password', $atts ):
$content = wpmem_page_pwd_reset( $wpmem->regchk, $content );
break;
case in_array( 'user_edit', $atts ):
$content = wpmem_page_user_edit( $wpmem->regchk, $content );
break;
case in_array( 'forgot_username', $atts ):
$content = wpmem_page_forgot_username( $wpmem->regchk, $content );
break;
case in_array( 'customizer_login', $atts ):
$content = wpmem_inc_login( 'login', $redirect_to );
break;
case in_array( 'customizer_register', $atts ):
$content = wpmem_inc_registration( 'new', '', $redirect_to );
break;
}
/*
* This is for texturizing. Need to work it into an argument in the function call as to whether the
* [wpmem_txt] shortcode is even included. @todo - Is this a temporary solution or is there something
* cleaner that can be worked out?
*/
if ( 1 == $wpmem->texturize ) {
if ( array_key_exists( 'texturize', $atts ) && $atts['texturize'] == 'false' ) {
$content = str_replace( array( '[wpmem_txt]', '[/wpmem_txt]' ), array( '', '' ), $content );
}
if ( strstr( $content, '[wpmem_txt]' ) ) {
// Fixes the wptexturize.
remove_filter( 'the_content', 'wpautop' );
remove_filter( 'the_content', 'wptexturize' );
add_filter( 'the_content', array( 'WP_Members', 'texturize' ), 999 );
}
} // End texturize functions
}
return do_shortcode( $content );
}
/**
* Handles the logged in status shortcodes [wpmem_logged_in].
*
* There are several attributes that can be used with the shortcode:
* in|out, sub for subscription only info, id, and role. IDs and roles
* can be comma separated values for multiple users and roles.
*
* @since 3.0.0
* @since 3.2.0 Moved to WP_Members_Shortcodes::logged_in().
* @since 3.2.0 Added attributes for meta key/value pairs.
* @since 3.2.3 Added product attribute.
*
* @global object $wpmem The WP_Members object.
*
* @param array $atts {
* The shortcode attributes.
*
* @type string $status
* @type int $id
* @type string $role
* @type string $sub
* @type string $meta_key
* @type string $meta_value
* }
* @param string $content
* @param string $tag
* @return string $content
*/
function logged_in( $atts, $content = null, $tag = 'wpmem_logged_in' ) {
global $wpmem;
// Handles the 'status' attribute.
if ( ( isset( $atts['status'] ) ) || $tag == 'wpmem_logged_in' ) {
$do_return = false;
// If there is a status attribute of "out" and the user is not logged in.
$do_return = ( isset( $atts['status'] ) && $atts['status'] == 'out' && ! is_user_logged_in() ) ? true : $do_return;
if ( is_user_logged_in() ) {
// In case $current_user is not already global
$current_user = wp_get_current_user();
// If there is a status attribute of "in" and the user is logged in.
$do_return = ( isset( $atts['status'] ) && $atts['status'] == 'in' ) ? true : $do_return;
// If using the wpmem_logged_in tag with no attributes & the user is logged in.
$do_return = ( $tag == 'wpmem_logged_in' && ( ! $atts ) ) ? true : $do_return;
// If there is an "id" attribute and the user ID is in it.
if ( isset( $atts['id'] ) ) {
$ids = explode( ',', $atts['id'] );
foreach ( $ids as $id ) {
if ( trim( $id ) == $current_user->ID ) {
$do_return = true;
}
}
}
// If there is a "role" attribute and the user has a matching role.
if ( isset( $atts['role'] ) ) {
$roles = explode( ',', $atts['role'] );
if ( wpmem_user_has_role( $roles ) ) {
$do_return = true;
}
}
// If there is a status attribute of "sub" and the user is logged in.
if ( ( isset( $atts['status'] ) ) && $atts['status'] == 'sub' ) {
if ( defined( 'WPMEM_EXP_MODULE' ) && $wpmem->use_exp == 1 ) {
if ( ! wpmem_chk_exp() ) {
$do_return = true;
} elseif ( $atts['msg'] == true ) {
$do_return = true;
$content = wpmem_sc_expmessage();
}
}
}
// If there is a meta key attribute.
if ( isset( $atts['meta_key'] ) ) {
$value = ( isset( $atts['meta_value'] ) ) ? $atts['meta_value'] : false;
if ( wpmem_user_has_meta( $atts['meta_key'], $value ) ) {
$do_return = true;
}
}
// If there is a product attribute.
if ( isset( $atts['product'] ) ) {
if ( wpmem_user_has_access( $atts['product'] ) ) {
$do_return = true;
}
}
// Prevents display if the current page is the user profile and an action is being handled.
if ( ( wpmem_current_url( true, false ) == wpmem_profile_url() ) && isset( $_GET['a'] ) ) {
$do_return = false;
}
}
// Return content (or empty content) depending on the result of the above logic.
return ( $do_return ) ? do_shortcode( $content ) : '';
}
}
/**
* Handles the [wpmem_logged_out] shortcode.
*
* @since 3.0.0
* @since 3.2.0 Moved to WP_Members_Shortcodes::logged_out().
*
* @param array $atts
* @param string $content
* @param string $tag
* @return string $content
*/
function logged_out( $atts, $content = null, $tag ) {
return ( ! is_user_logged_in() ) ? do_shortcode( $content ) : '';
}
/**
* User count shortcode [wpmem_show_count].
*
* User count displays a total user count or a count of users by specific
* role (role="some_role"). It also accepts attributes for counting users
* by a meta field (key="meta_key" value="meta_value"). A label can be
* displayed using the attribute label (label="Some label:").
*
* @since 3.0.0
* @since 3.1.5 Added total user count features.
* @since 3.2.0 Moved to WP_Members_Shortcodes::user_count().
*
* @global object $wpdb The WordPress database object.
* @param array $atts {
* The shortcode attributes.
*
* @type string $key
* @type string $value
* @type string $role
* @type string $label
* }
* @param string $content The shortcode content.
* @return string $content
*/
function user_count( $atts, $content = null ) {
if ( isset( $atts['key'] ) && isset( $atts['value'] ) ) {
// If by meta key.
global $wpdb;
$user_count = $wpdb->get_var( $wpdb->prepare(
"SELECT COUNT(*) FROM $wpdb->usermeta WHERE meta_key = %s AND meta_value = %s",
$atts['key'],
$atts['value']
) );
} else {
// If no meta, it's a total count.
$users = count_users();
$user_count = ( isset( $atts['role'] ) ) ? $users['avail_roles'][ $atts['role'] ] : $users['total_users'];
}
// Assemble the output and return.
$content = ( isset( $atts['label'] ) ) ? $atts['label'] . ' ' . $user_count : $content . ' ' . $user_count;
return do_shortcode( $content );
}
/**
* Creates the user profile dashboard area [wpmem_profile].
*
* @since 3.1.0
* @since 3.1.2 Added function arguments.
* @since 3.2.0 Moved to WP_Members_Shortcodes::user_profile().
*
* @global object $wpmem The WP_Members object.
* @global string $wpmem_themsg The WP-Members message container.
* @param string $atts {
* The shortcode attributes.
*
* @type string $redirect_to
* }
* @param string $content
* @param string $tag
* @return string $content
*/
function user_profile( $atts, $content, $tag ) {
// @todo $redirect_to is not currently used in the user profile.
$redirect_to = ( isset( $atts['redirect_to'] ) ) ? $atts['redirect_to'] : null;
$hide_register = ( isset( $atts['register'] ) && 'hide' == $atts['register'] ) ? true : false;
global $wpmem, $wpmem_themsg;
$content = '';
if ( $wpmem->regchk == "captcha" ) {
global $wpmem_captcha_err;
$wpmem_themsg = $wpmem->get_text( 'reg_captcha_err' ) . '<br /><br />' . $wpmem_captcha_err;
}
if ( $wpmem->regchk == "loginfailed" ) {
return wpmem_inc_loginfailed();
}
if ( is_user_logged_in() ) {
/**
* Filter the default heading in User Profile edit mode.
*
* @since 2.7.5
*
* @param string The default edit mode heading.
*/
$heading = apply_filters( 'wpmem_user_edit_heading', $wpmem->get_text( 'profile_heading' ) );
switch( $wpmem->action ) {
case "edit":
$content = $content . wpmem_inc_registration( 'edit', $heading );
break;
case "update":
// Determine if there are any errors/empty fields.
if ( $wpmem->regchk == "updaterr" || $wpmem->regchk == "email" ) {
$content = $content . wpmem_inc_regmessage( $wpmem->regchk, $wpmem_themsg );
$content = $content . wpmem_inc_registration( 'edit', $heading );
} else {
//Case "editsuccess".
$content = $content . wpmem_inc_regmessage( $wpmem->regchk, $wpmem_themsg );
$content = $content . wpmem_inc_memberlinks();
}
break;
case "pwdchange":
$content = wpmem_page_pwd_reset( $wpmem->regchk, $content );
$content = ( 'pwdchangesuccess' == $wpmem->regchk ) ? $content . wpmem_inc_memberlinks() : $content;
break;
case "renew":
$content = wpmem_renew();
break;
default:
$content = wpmem_inc_memberlinks();
break;
}
} else {
if ( $wpmem->action == 'register' && ! $hide_register ) {
switch( $wpmem->regchk ) {
case "success":
$content = wpmem_inc_regmessage( $wpmem->regchk, $wpmem_themsg );
$content = $content . wpmem_inc_login();
break;
default:
$content = wpmem_inc_regmessage( $wpmem->regchk, $wpmem_themsg );
$content = $content . wpmem_inc_registration();
break;
}
} elseif ( $wpmem->action == 'pwdreset' ) {
$content = wpmem_page_pwd_reset( $wpmem->regchk, $content );
} elseif( $wpmem->action == 'getusername' ) {
$content = wpmem_page_forgot_username( $wpmem->regchk, $content );
} else {
$content = $content . wpmem_inc_login( 'members' );
$content = ( ! $hide_register ) ? $content . wpmem_inc_registration() : $content;
}
}
return $content;
}
/**
* Log in/out shortcode [wpmem_loginout].
*
* @since 3.1.1
* @since 3.1.6 Uses wpmem_loginout().
* @since 3.2.0 Moved to WP_Members_Shortcodes::loginout().
*
* @param array $atts {
* The shortcode attributes.
*
* @type string $login_redirect_to The url to redirect to after login (optional).
* @type string $logout_redirect_to The url to redirect to after logout (optional).
* @type string $login_text Text for the login link (optional).
* @type string $logout_text Text for the logout link (optional).
* }
* @param string $content
* @param string $tag
* @return string $content
*/
function loginout( $atts, $content, $tag ) {
$link = wpmem_loginout( $atts );
return do_shortcode( $link );
}
/**
* Function to handle field shortcodes [wpmem_field].
*
* Shortcode to display the data for a given user field. Requires
* that a field meta key be passed as an attribute. Can either of
* the following:
* - [wpmem_field field="meta_key"]
* - [wpmem_field meta_key]
*
* Other attributes:
*
* - id (numeric user ID or "get" to retrieve uid from query string.
* - underscores="true" strips underscores from the displayed value.
* - display="raw" displays the stored value for dropdowns, radios, files.
* - size(thumbnail|medium|large|full|w,h): image field only.
*
* @since 3.1.2
* @since 3.1.4 Changed to display value rather than stored value for dropdown/multicheck/radio.
* @since 3.1.5 Added display attribute, meta key as a direct attribute, and image/file display.
* @since 3.2.0 Moved to WP_Members_Shortcodes::fields().
* @since 3.2.0 Added clickable attribute.
*
* @global object $wpmem The WP_Members object.
* @param array $atts {
* The shortcode attributes.
*
* @type string {meta_key}
* @type string $field
* @type int $id
* @type string $underscores
* @type string $display
* @type string $size
* @type string $clickable default:false
* }
* @param string $content Any content passed with the shortcode (default:null).
* @param string $tag The shortcode tag (wpmem_form).
* @return string $content Content to return.
*/
function fields( $atts, $content = null, $tag ) {
// What field?
$field = ( isset( $atts[0] ) ) ? $atts[0] : $atts['field'];
// What user?
if ( isset( $atts['id'] ) ) {
$the_ID = ( $atts['id'] == 'get' ) ? filter_var( wpmem_get( 'uid', '', 'get' ), FILTER_SANITIZE_NUMBER_INT ) : $atts['id']; // Ultimately, the_ID will be checked to determine if it is numeric by WP_User::get_data_by().
} else {
$the_ID = get_current_user_id();
}
$user_info = get_userdata( $the_ID );
// If there is userdata.
if ( $user_info ) {
global $wpmem;
$fields = wpmem_fields();
$field_type = ( isset( $fields[ $field ]['type'] ) ) ? $fields[ $field ]['type'] : 'native'; // @todo Is this needed? It seems to set the type to "native" if not set.
$result = $user_info->{$field};
// Handle select and radio groups (have single selections).
if ( 'select' == $field_type || 'radio' == $field_type ) {
$result = ( isset( $atts['display'] ) && 'raw' == $atts['display'] ) ? $user_info->{$field} : $fields[ $field ]['options'][ $user_info->{$field} ];
}
// Handle multiple select and multiple checkbox (have multiple selections).
if ( 'multiselect' == $field_type || 'multicheckbox' == $field_type ) {
if ( isset( $atts['display'] ) && 'raw' == $atts['display'] ) {
$result = $user_info->{$field};
} else {
$saved_vals = explode( $fields[ $field ]['delimiter'], $user_info->{$field} );
$result = ''; $x = 1;
foreach ( $saved_vals as $value ) {
$result.= ( $x > 1 ) ? ', ' : ''; $x++;
$result.= $fields[ $field ]['options'][ $value ];
}
}
}
// Handle file/image fields.
if ( isset( $field_type ) && ( 'file' == $field_type || 'image' == $field_type ) ) {
if ( isset( $atts['display'] ) && 'raw' == $atts['display'] ) {
$result = $user_info->{$field};
} else {
if ( 'file' == $field_type ) {
$attachment_url = wp_get_attachment_url( $user_info->{$field} );
$result = ( $attachment_url ) ? '<a href="' . esc_url( $attachment_url ) . '">' . get_the_title( $user_info->{$field} ) . '</a>' : '';
} else {
$size = 'thumbnail';
if ( isset( $atts['size'] ) ) {
$sizes = array( 'thumbnail', 'medium', 'large', 'full' );
$size = ( ! in_array( $atts['size'], $sizes ) ) ? explode( ",", $atts['size'] ) : $atts['size'];
}
$image = wp_get_attachment_image_src( $user_info->{$field}, $size );
$result = ( $image ) ? '<img src="' . esc_url( $image[0] ) . '" width="' . esc_attr( $image[1] ) . '" height="' . esc_attr( $image[2] ) . '" />' : '';
}
}
return do_shortcode( $result );
}
// Handle line breaks for textarea fields
if ( isset( $field_type ) && 'textarea' == $field_type ) {
$result = ( isset( $atts['display'] ) && 'raw' == $atts['display'] ) ? $user_info->{$field} : nl2br( $user_info->{$field} );
}
// Handle date fields.
if ( isset( $field_type ) && 'date' == $field_type ) {
if ( isset( $atts['format'] ) ) {
// Formats date: https://secure.php.net/manual/en/function.date.php
$result = ( '' != $user_info->{$field} ) ? date( $atts['format'], strtotime( $user_info->{$field} ) ) : '';
} else {
// Formats date to whatever the WP setting is.
$result = ( '' != $user_info->{$field} ) ? date_i18n( get_option( 'date_format' ), strtotime( $user_info->{$field} ) ) : '';
}
}
// Remove underscores from value if requested (default: on).
if ( isset( $atts['underscores'] ) && 'off' == $atts['underscores'] && $user_info ) {
$result = str_replace( '_', ' ', $result );
}
$content = ( $content ) ? $result . $content : $result;
// Make it clickable?
$content = ( isset( $atts['clickable'] ) && ( true === $atts['clickable'] || 'true' == $atts['clickable'] ) ) ? make_clickable( $content ) : $content;
return do_shortcode( $content );
}
return;
}
/**
* Logout link shortcode [wpmem_logout].
*
* @since 3.1.2
* @since 3.2.0 Moved to WP_Members_Shortcodes::logout().
*
* @param array $atts {
* The shortcode attributes.
*
* @type string $url
* }
* @param string $content
* @param string $tag
* @retrun string $content
*/
function logout( $atts, $content, $tag ) {
// Logout link shortcode.
if ( is_user_logged_in() && $tag == 'wpmem_logout' ) {
$link = ( isset( $atts['url'] ) ) ? add_query_arg( 'a', 'logout', $atts['url'] ) : add_query_arg( 'a', 'logout' );
$text = ( $content ) ? $content : __( 'Click here to log out.', 'wp-members' );
return do_shortcode( '<a href="' . esc_url( $link ) . '">' . $text . '</a>' );
}
}
/**
* TOS shortcode [wpmem_tos].
*
* @since 3.1.2
* @since 3.2.0 Moved to WP_Members_Shortcodes::tos().
*
* @param array $atts {
* The shortcode attributes.
*
* @type string $url
* }
* @param string $content
* @param string $tag
* @retrun string $content
*/
function tos( $atts, $content, $tag ) {
return do_shortcode( $atts['url'] );
}
/**
* Display user avatar.
*
* @since 3.1.7
* @since 3.2.0 Moved to WP_Members_Shortcodes::avatar().
*
* @param array $atts {
* The shortcode attributes.
*
* @type string $id The user email or id.
* @type int $size Avatar size (square) in pixels.
* }
* @param string $content
* @param string $tag
* @retrun string $content
*/
function avatar( $atts, $content, $tag ) {
$content = '';
$size = ( isset( $atts['size'] ) ) ? $atts['size'] : '';
if ( isset( $atts['id'] ) ) {
$content = get_avatar( $atts['id'], $size );
} elseif ( is_user_logged_in() ) {
// If the user is logged in and this isn't specifying a user ID, return the current user avatar.
global $current_user;
wp_get_current_user();
$content = get_avatar( $current_user->ID, $size );
}
return do_shortcode( $content );
}
/**
* Generates a login link with a return url.
*
* @since 3.1.7
* @since 3.2.0 Moved to WP_Members_Shortcodes::login_link().
*
* @param array $atts {
* The shortcode attributes.
* }
* @param string $content
* @param string $tag
* @retrun string $content
*/
function login_link( $atts, $content, $tag ) {
if ( 'wpmem_reg_link' == $tag ) {
$text = ( $content ) ? $content : __( 'Register' );
$link = add_query_arg( 'redirect_to', wpmem_current_url(), wpmem_register_url() );
} else {
$text = ( $content ) ? $content : __( 'Log In' );
$link = wpmem_login_url( wpmem_current_url() );
}
$content = '<a href="' . $link . '">' . $text . '</a>';
return do_shortcode( $content );
}
}
// End of file.
<?php
/**
* The WP_Members_User Class.
*
* This is the WP_Members User object class. This class contains functions
* for login, logout, registration and other user related methods.
*
* @package WP-Members
* @subpackage WP_Members_User Object Class
* @since 3.0.0
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit();
}
class WP_Members_User {
/**
* Container for reg form data.
*
* @since 3.1.7
* @access public
* @var array
*/
public $post_data = array();
/**
* Container for user access information.
*
* @since 3.2.0
* @access public
* @var array
*/
public $access = array();
/**
* Initilize the User object.
*
* @since 3.1.7
*
* @param object $settings The WP_Members Object
*/
function __construct( $settings ) {
//add_action( 'user_register', array( $this, 'register' ), 9 ); // @todo This need rigorous testing, especially front end processing such as WC.
add_action( 'wpmem_register_redirect', array( $this, 'register_redirect' ) );
// Load anything the user as access to.
if ( 1 == $settings->enable_products ) {
$this->access = $this->get_user_products();
}
}
/**
* Handle user login.
*
* Built from, but replaces, the original wpmem_login() function
* from core.php. wpmem_login() is currently maintained as a
* wrapper and is the direct function called for login.
*
* @since 3.1.7
* @since 3.2.3 Removed wpmem_login_fields filter.
* @since 3.2.3 Replaced form collection with WP script to facilitate login with username OR email.
* @since 3.2.3 Changed to wp_safe_redirect().
*
* @return string Returns "loginfailed" if failed login.
*/
function login() {
global $wpmem;
if ( ! empty( $_POST['log'] ) && ! force_ssl_admin() ) {
$user_name = sanitize_user( $_POST['log'] );
$user = get_user_by( 'login', $user_name );
if ( ! $user && strpos( $user_name, '@' ) ) {
$user = get_user_by( 'email', $user_name );
}
}
$user = wp_signon( array(), is_ssl() );
if ( is_wp_error( $user ) ) {
$wpmem->error = $user->get_error_message();
return "loginfailed";
} else {
$redirect_to = wpmem_get( 'redirect_to', false );
$redirect_to = ( $redirect_to ) ? esc_url_raw( trim( $redirect_to ) ) : esc_url_raw( wpmem_current_url() );
/** This filter defined in wp-login.php */
$redirect_to = apply_filters( 'login_redirect', $redirect_to, '', $user );
/**
* Filter the redirect url.
*
* This is the plugin's original redirect filter. In 3.1.7,
* WP's login_redirect filter hook was added to provide better
* integration support for other plugins and also for users
* who may already be using WP's filter(s). login_redirect
* comes first, then wpmem_login_redirect. So wpmem_login_redirect
* can be used to override a default in login_redirect.
*
* @since 2.7.7
*
* @param string $redirect_to The url to direct to.
* @param int $user->ID The user's primary key ID.
*/
$redirect_to = apply_filters( 'wpmem_login_redirect', $redirect_to, $user->ID );
wp_safe_redirect( $redirect_to );
exit();
}
}
/**
* Handle user logout.
*
* Built from, but replaces, the original wpmem_logout() function
* from core.php. wpmem_logout() is currently maintained as a
* wrapper and is the direct function called for logout.
*
* @since 3.1.7
* @since 3.2.0 Added logout_redirect filter
*
* @param string $redirect_to URL to redirect the user to (default: false).
*/
function logout( $redirect_to = false ) {
// Default redirect URL.
$redirect_to = ( $redirect_to ) ? $redirect_to : home_url();
/** This filter is documented in /wp-login.php */
$redirect_to = apply_filters( 'logout_redirect', $redirect_to, $redirect_to, wp_get_current_user() );
/**
* Filter where the user goes when logged out.
*
* @since 2.7.1
* @since 3.1.7 Moved to WP_Members_Users Class.
*
* @param string The blog home page.
*/
$redirect_to = apply_filters( 'wpmem_logout_redirect', $redirect_to );
wp_destroy_current_session();
wp_clear_auth_cookie();
/** This action is defined in /wp-includes/pluggable.php. */
do_action( 'wp_logout' );
wp_redirect( $redirect_to );
exit();
}
/**
* User registration functions.
*
* @since 3.1.7
*
* @global object $wpmem
* @param int $user_id
*/
function register( $user_id ) {
global $wpmem;
// Put user ID into post_data array.
$wpmem->user->post_data['ID'] = $user_id;
// Set remaining fields to wp_usermeta table.
$new_user_fields_meta = array( 'user_url', 'first_name', 'last_name', 'description', 'jabber', 'aim', 'yim' );
foreach ( $wpmem->fields as $meta_key => $field ) {
// If the field is not excluded, update accordingly.
if ( ! in_array( $meta_key, $wpmem->excluded_meta ) && ! in_array( $meta_key, $new_user_fields_meta ) ) {
if ( $field['register'] && 'user_email' != $meta_key ) {
update_user_meta( $user_id, $meta_key, $this->post_data[ $meta_key ] );
}
}
}
// Capture IP address of user at registration.
update_user_meta( $user_id, 'wpmem_reg_ip', $this->post_data['wpmem_reg_ip'] );
// Store the registration url.
update_user_meta( $user_id, 'wpmem_reg_url', $this->post_data['wpmem_reg_url'] );
// Set user expiration, if used.
if ( $wpmem->use_exp == 1 && $wpmem->mod_reg != 1 ) {
if ( function_exists( 'wpmem_set_exp' ) ) {
wpmem_set_exp( $user_id );
}
}
// Handle file uploads, if any.
if ( ! empty( $_FILES ) ) {
$this->upload_user_files( $user_id, $wpmem->fields );
}
/**
* Fires after user insertion but before email.
*
* @since 2.7.2
*
* @param array $this->post_data The user's submitted registration data.
*/
do_action( 'wpmem_post_register_data', $this->post_data );
// Send a notification email to the user.
$wpmem->email->to_user( $user_id, $this->post_data['password'], $wpmem->mod_reg, $wpmem->fields, $this->post_data );
// Notify admin of new reg, if needed.
if ( $wpmem->notify == 1 ) {
$wpmem->email->notify_admin( $user_id, $wpmem->fields, $this->post_data );
}
/**
* Fires after registration is complete.
*
* @since 2.7.1
* @since 3.1.0 Added $fields
* @since 3.1.7 Changed $fields to $wpmem->user->post_data
*/
do_action( 'wpmem_register_redirect', $this->post_data );
}
/**
* Redirects user on registration.
*
* @since 3.1.7
*/
function register_redirect() {
$redirect_to = wpmem_get( 'redirect_to', false );
if ( $redirect_to ) {
$nonce_url = wp_nonce_url( $redirect_to, 'register_redirect', 'reg_nonce' );
wp_redirect( $nonce_url );
exit();
}
}
/**
* Password change or reset.
*
* @since 3.1.7
*
* @param string $action
* @return string $result
*/
function password_update( $action ) {
if ( isset( $_POST['formsubmit'] ) ) {
$params = ( 'reset' == $action ) ? array( 'user', 'email' ) : array( 'pass1', 'pass2' );
$args = array(
$params[0] => wpmem_get( $params[0], false ),
$params[1] => wpmem_get( $params[1], false ),
);
return ( 'reset' == $action ) ? $this->password_reset( $args ) : $this->password_change( $args );
}
return;
}
/**
* Change a user's password()
*
* @since 3.1.7
*
* @return
*/
function password_change( $args ) {
global $user_ID;
$is_error = false;
// Check for both fields being empty.
$is_error = ( ! $args['pass1'] && ! $args['pass2'] ) ? "pwdchangempty" : $is_error;
// Make sure the fields match.
$is_error = ( $args['pass1'] != $args['pass2'] ) ? "pwdchangerr" : $is_error;
/**
* Filters the password change error.
*
* @since 3.1.5
* @since 3.1.7 Moved to user object.
*
* @param string $is_error
* @param int $user_ID The user's numeric ID.
* @param string $args['pass1'] The user's new plain text password.
*/
$is_error = apply_filters( 'wpmem_pwd_change_error', $is_error, $user_ID, $args['pass1'] );
if ( $is_error ) {
return $is_error;
}
/**
* Fires after password change.
*
* @since 2.9.0
* @since 3.0.5 Added $args['pass1'] to arguments passed.
* @since 3.1.7 Moved to user object.
*
* @param int $user_ID The user's numeric ID.
* @param string $args['pass1'] The user's new plain text password.
*/
do_action( 'wpmem_pwd_change', $user_ID, $args['pass1'] );
return "pwdchangesuccess";
}
/**
* Reset a user's password.
*
* @since 3.1.7
*
*/
function password_reset( $args ) {
global $wpmem;
/**
* Filter the password reset arguments.
*
* @since 2.7.1
* @since 3.1.7 Moved to user object.
*
* @param array The username and email.
*/
$arr = apply_filters( 'wpmem_pwdreset_args', $args );
if ( ! $arr['user'] || ! $arr['email'] ) {
// There was an empty field.
return "pwdreseterr";
} else {
if ( username_exists( $arr['user'] ) ) {
$user = get_user_by( 'login', $arr['user'] );
if ( strtolower( $user->user_email ) !== strtolower( $arr['email'] ) || ( ( $wpmem->mod_reg == 1 ) && ( get_user_meta( $user->ID, 'active', true ) != 1 ) ) ) {
// The username was there, but the email did not match OR the user hasn't been activated.
return "pwdreseterr";
} else {
// Generate a new password.
$new_pass = wp_generate_password();
// Update the users password.
wp_set_password( $new_pass, $user->ID );
// Send it in an email.
$wpmem->email->to_user( $user->ID, $new_pass, 3 );
/**
* Fires after password reset.
*
* @since 2.9.0
* @since 3.0.5 Added $new_pass to arguments passed.
* @since 3.1.7 Moved to user object.
*
* @param int $user_ID The user's numeric ID.
* @param string $new_pass The new plain text password.
*/
do_action( 'wpmem_pwd_reset', $user->ID, $new_pass );
return "pwdresetsuccess";
}
} else {
// Username did not exist.
return "pwdreseterr";
}
}
return;
}
/**
* Handles retrieving a forgotten username.
*
* @since 3.0.8
* @since 3.1.6 Dependencies now loaded by object.
* @since 3.1.8 Moved to user object.
*
* @global object $wpmem
* @return string $regchk The regchk value.
*/
function retrieve_username() {
global $wpmem;
if ( isset( $_POST['formsubmit'] ) ) {
$email = sanitize_email( $_POST['user_email'] );
$user = ( isset( $_POST['user_email'] ) ) ? get_user_by( 'email', $email ) : false;
if ( $user ) {
// Send it in an email.
$wpmem->email->to_user( $user->ID, '', 4 );
/**
* Fires after retrieving username.
*
* @since 3.0.8
*
* @param int $user_ID The user's numeric ID.
*/
do_action( 'wpmem_get_username', $user->ID );
return 'usernamesuccess';
} else {
return 'usernamefailed';
}
}
return;
}
/**
* Handle user file uploads for registration and profile update.
*
* @since 3.1.8
*
* @param string $user_id
* @param array $fields
*/
function upload_user_files( $user_id, $fields ) {
global $wpmem;
foreach ( $fields as $meta_key => $field ) {
if ( ( 'file' == $field['type'] || 'image' == $field['type'] ) && isset( $_FILES[ $meta_key ] ) && is_array( $_FILES[ $meta_key ] ) ) {
if ( ! empty( $_FILES[ $meta_key ]['name'] ) ) {
// Upload the file and save it as an attachment.
$file_post_id = $wpmem->forms->do_file_upload( $_FILES[ $meta_key ], $user_id );
// Save the attachment ID as user meta.
update_user_meta( $user_id, $meta_key, $file_post_id );
}
}
}
}
/**
* Get user data for all fields in WP-Members.
*
* Retrieves user data for all WP-Members fields (and WP default fiels)
* in an array keyed by WP-Members field meta keys.
*
* @since 3.2.0
*
* @param mixed $user_id
* @return array $user_fields
*/
function user_data( $user_id = false ) {
$fields = wpmem_fields();
$user_id = ( $user_id ) ? $user_id : get_current_user_id();
$user_data = get_userdata( $user_id );
$excludes = array( 'first_name', 'last_name', 'description', 'nickname' );
foreach ( $fields as $meta => $field ) {
if ( $field['native'] == 1 && ! in_array( $meta, $excludes ) ) {
$user_fields[ $meta ] = $user_data->data->$meta;
} else {
$user_fields[ $meta ] = get_user_meta( $user_id, $meta, true );
}
}
return $user_fields;
}
/**
* Sets the role for the specified user.
*
* @since 3.2.0
*
* @param integer $user_id
* @param string $role
* @param string $action (set|add|remove)
*/
public function update_user_role( $user_id, $role, $action = 'set' ) {
$user = new WP_User( $user_id );
switch ( $action ) {
case 'add':
$user->add_role( $role );
break;
case 'remove':
$user->remove_role( $role );
break;
default:
$user->set_role( $role );
break;
}
}
/**
* Sets a user's password.
*
* @since 3.2.3
*
* @param int $user_id
* @param string $password
*/
function set_password( $user_id, $password ) {
wp_set_password( $password, $user_id );
}
/**
* Sets user as logged on password change.
*
* (Hooked to wpmem_pwd_change)
*
* @since 3.2.0
*
* @param int $user_id
* @param string $password
*/
function set_as_logged_in( $user_id ) {
$user = get_user_by( 'id', $user_id );
wp_set_current_user( $user_id, $user->user_login );
wp_set_auth_cookie( $user_id );
}
/**
* Validates user access to content.
*
* @since 3.2.0
*
* @global object $wpmem
* @param mixed $product
* @param int $user_id (optional)
* @return bool $access
*/
function has_access( $product, $user_id = false ) {
global $wpmem;
if ( ! is_user_logged_in() ) {
return false;
}
// Product must be an array.
$product_array = ( ! is_array( $product ) ) ? array( $product ) : $product;
// Current user or requested user.
$user_id = ( ! $user_id ) ? get_current_user_id() : $user_id;
// Start by assuming no access.
$access = false;
foreach ( $product_array as $prod ) {
$expiration_product = false;
$role_product = false;
if ( isset( $this->access[ $prod ] ) ) {
// Is this an expiration product?
if ( isset( $wpmem->membership->products[ $prod ]['expires'][0] ) && ! is_bool( $this->access[ $prod ] ) ) {
$expiration_product = true;
if ( $this->is_current( $this->access[ $prod ] ) ) {
$access = true;
break;
}
}
if ( '' != $wpmem->membership->products[ $prod ]['role'] ) {
$role_product = true;
if ( $this->access[ $prod ] && wpmem_user_has_role( $wpmem->membership->products[ $prod ]['role'] ) ) {
$access = true;
break;
}
}
if ( ! $expiration_product && ! $role_product && $this->access[ $prod ] ) {
$access = true;
break;
}
}
}
/**
* Filter the access result.
*
* @since 3.2.0
* @since 3.2.3 Added $product argument.
*
* @param boolean $access
* @param array $product
* @param integer $user_id
* @param array $args
*/
return apply_filters( 'wpmem_user_has_access', $access, $product_array, $user_id );
}
/**
* Loads anything the user has access to.
*
* @since 3.2.0
*
* @param int $user_id
*/
function get_user_products( $user_id = false ) {
$user_id = ( ! $user_id ) ? get_current_user_id() : $user_id;
return get_user_meta( $user_id, '_wpmem_products', true );
}
/**
* Sets a product as active for a user.
*
* If the product expires, it sets an expiration date
* based on the time period. Otherwise the value is
* set to "true" (which does not expire).
*
* @since 3.2.0
*
* @param string $product
* @param int $user_id
*/
function set_user_product( $product, $user_id = false ) {
global $wpmem;
$user_id = ( ! $user_id ) ? get_current_user_id() : $user_id;
$user_products = $this->get_user_products( $user_id );
if ( ! $user_products ) {
$user_products = array();
}
// Convert date to add.
$expires = ( isset( $wpmem->membership->products[ $product ]['expires'] ) ) ? $wpmem->membership->products[ $product ]['expires'] : false;
if ( is_array( $expires ) ) {
$add_date = explode( "|", $wpmem->membership->products[ $product ]['expires'][0] );
$add = ( 1 < $add_date[0] ) ? $add_date[0] . " " . $add_date[1] . "s" : $add_date[0] . " " . $add_date[1];
$user_products[ $product ] = ( isset( $user_products[ $product ] ) ) ? date( 'Y-m-d H:i:s', strtotime( $add, strtotime( $user_products[ $product ] ) ) ) : date( 'Y-m-d H:i:s', strtotime( $add ) );
} else {
$user_products[ $product ] = true;
}
//echo '<pre>'; print_r( $user_products ); echo "</pre>";
// Update product setting.
return update_user_meta( $user_id, '_wpmem_products', $user_products );
}
/**
* Removes a product from a user.
*
* @since 3.2.0
*
* @param string $product
* @param int $user_id
*/
function remove_user_product( $product, $user_id = false ) {
global $wpmem;
$user_id = ( ! $user_id ) ? get_current_user_id() : $user_id;
$user_products = $this->get_user_products( $user_id );
if ( $user_products ) {
unset( $user_products[ $product ] );
update_user_meta( $user_id, '_wpmem_products', $user_products );
}
return;
}
/**
* Utility for expiration validation.
*
* @since 3.2.0
*
* @param date $date
*/
function is_current( $date ) {
return ( time() < strtotime( $date ) ) ? true : false;
}
/**
* Check if a user is activated.
*
* @since 3.2.2
*
* @param int $user_id
* @return bool $active
*/
function is_user_activated( $user_id = false ) {
$user_id = ( ! $user_id ) ? get_current_user_id() : $user_id;
$active = get_user_meta( $user_id, 'active', true );
return ( $active != 1 ) ? false : true;
}
/**
* Checks if a user is activated during user authentication.
*
* @since 2.7.1
* @since 3.2.0 Moved from core to user object.
*
* @param object $user The WordPress User object.
* @param string $username The user's username (user_login).
* @param string $password The user's password.
* @return object $user The WordPress User object.
*/
function check_activated( $user, $username, $password ) {
// Password must be validated.
$pass = ( ( ! is_wp_error( $user ) ) && $password ) ? wp_check_password( $password, $user->user_pass, $user->ID ) : false;
if ( ! $pass ) {
return $user;
}
// Activation flag must be validated.
if ( ! $this->is_user_activated( $user->ID ) ) {
return new WP_Error( 'authentication_failed', __( '<strong>ERROR</strong>: User has not been activated.', 'wp-members' ) );
}
// If the user is validated, return the $user object.
return $user;
}
/**
* Prevents users not activated from resetting their password.
*
* @since 2.5.1
* @since 3.2.0 Moved to user object, renamed no_reset().
*
* @return bool Returns false if the user is not activated, otherwise true.
*/
function no_reset() {
global $wpmem;
$raw_val = wpmem_get( 'user_login', false );
if ( $raw_val ) {
if ( strpos( $raw_val, '@' ) ) {
$user = get_user_by( 'email', sanitize_email( $raw_val ) );
} else {
$username = sanitize_user( $raw_val );
$user = get_user_by( 'login', $username );
}
if ( $wpmem->mod_reg == 1 ) {
if ( get_user_meta( $user->ID, 'active', true ) != 1 ) {
return false;
}
}
}
return true;
}
}